Merge branch 'main' of https://github.com/cake-tech/cake_wallet into CW-166-cake-pay-accepts-tip-filtering
|
@ -1,51 +1,73 @@
|
|||
include: package:lints/recommended.yaml
|
||||
|
||||
analyzer:
|
||||
strong-mode:
|
||||
implicit-casts: false
|
||||
implicit-dynamic: false
|
||||
exclude: [build/**, lib/generated/*.dart, lib/**.g.dart, cw_monero/ios/External/**, cw_shared_external/**, shared_external/**]
|
||||
exclude: [
|
||||
build/**,
|
||||
lib/**.g.dart,
|
||||
cw_core/lib/**.g.dart,
|
||||
cw_haven/lib/**.g.dart,
|
||||
cw_monero/lib/**.g.dart,
|
||||
lib/generated/*.dart,
|
||||
cw_monero/ios/External/**,
|
||||
cw_shared_external/**,
|
||||
shared_external/**]
|
||||
language:
|
||||
strict-casts: true
|
||||
strict-raw-types: true
|
||||
|
||||
linter:
|
||||
rules:
|
||||
- always_declare_return_types
|
||||
- annotate_overrides
|
||||
- avoid_empty_else
|
||||
- avoid_init_to_null
|
||||
- avoid_return_types_on_setters
|
||||
- await_only_futures
|
||||
- camel_case_types
|
||||
- cancel_subscriptions
|
||||
- close_sinks
|
||||
- comment_references
|
||||
- constant_identifier_names
|
||||
- control_flow_in_finally
|
||||
- empty_catches
|
||||
- empty_constructor_bodies
|
||||
- empty_statements
|
||||
- hash_and_equals
|
||||
- invariant_booleans
|
||||
- iterable_contains_unrelated_type
|
||||
- library_names
|
||||
- library_prefixes
|
||||
- list_remove_unrelated_type
|
||||
- literal_only_boolean_expressions
|
||||
- non_constant_identifier_names
|
||||
- one_member_abstracts
|
||||
- only_throw_errors
|
||||
- overridden_fields
|
||||
- package_api_docs
|
||||
- package_names
|
||||
- package_prefixed_library_names
|
||||
- parameter_assignments
|
||||
- prefer_final_fields
|
||||
- prefer_final_locals
|
||||
- prefer_is_not_empty
|
||||
- slash_for_doc_comments
|
||||
- sort_constructors_first
|
||||
- sort_unnamed_constructors_first
|
||||
- test_types_in_equals
|
||||
- throw_in_finally
|
||||
- type_init_formals
|
||||
- unawaited_futures
|
||||
- unnecessary_getters_setters
|
||||
- unrelated_type_equality_checks
|
||||
- valid_regexps
|
||||
|
||||
|
||||
# analyzer:
|
||||
# strong-mode:
|
||||
# implicit-casts: false
|
||||
# implicit-dynamic: false
|
||||
# exclude: [build/**, lib/generated/*.dart, lib/**.g.dart, cw_monero/ios/External/**, cw_shared_external/**, shared_external/**]
|
||||
|
||||
# linter:
|
||||
# rules:
|
||||
# - always_declare_return_types
|
||||
# - annotate_overrides
|
||||
# - avoid_empty_else
|
||||
# - avoid_init_to_null
|
||||
# - avoid_return_types_on_setters
|
||||
# - await_only_futures
|
||||
# - camel_case_types
|
||||
# - cancel_subscriptions
|
||||
# - close_sinks
|
||||
# - comment_references
|
||||
# - constant_identifier_names
|
||||
# - control_flow_in_finally
|
||||
# - empty_catches
|
||||
# - empty_constructor_bodies
|
||||
# - empty_statements
|
||||
# - hash_and_equals
|
||||
# - invariant_booleans
|
||||
# - iterable_contains_unrelated_type
|
||||
# - library_names
|
||||
# - library_prefixes
|
||||
# - list_remove_unrelated_type
|
||||
# - literal_only_boolean_expressions
|
||||
# - non_constant_identifier_names
|
||||
# - one_member_abstracts
|
||||
# - only_throw_errors
|
||||
# - overridden_fields
|
||||
# - package_api_docs
|
||||
# - package_names
|
||||
# - package_prefixed_library_names
|
||||
# - parameter_assignments
|
||||
# - prefer_final_fields
|
||||
# - prefer_final_locals
|
||||
# - prefer_is_not_empty
|
||||
# - slash_for_doc_comments
|
||||
# - sort_constructors_first
|
||||
# - sort_unnamed_constructors_first
|
||||
# - test_types_in_equals
|
||||
# - throw_in_finally
|
||||
# - type_init_formals
|
||||
# - unawaited_futures
|
||||
# - unnecessary_getters_setters
|
||||
# - unrelated_type_equality_checks
|
||||
# - valid_regexps
|
|
@ -37,7 +37,7 @@ if (appPropertiesFile.exists()) {
|
|||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
compileSdkVersion 33
|
||||
|
||||
lintOptions {
|
||||
disable 'InvalidPackage'
|
||||
|
@ -80,6 +80,8 @@ android {
|
|||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
ndkVersion "25.1.8937393"
|
||||
}
|
||||
|
||||
flutter {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
buildscript {
|
||||
ext.kotlin_version = '1.5.10'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
|
@ -7,6 +8,7 @@ buildscript {
|
|||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.1.3'
|
||||
classpath 'com.google.gms:google-services:4.3.8'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,31 +5,31 @@
|
|||
},
|
||||
{
|
||||
"question" : "Comment envoyer des Monero vers une plateforme d'échange qui nécessite un ID de paiement ?",
|
||||
"answer" : "Appuyez sur le bouton envoyer de l'écran du Wallet. Ensuite, copiez l'adresse de dépôt de la plateforme d'échange et collez là dans le champ adresse. Puis, copiez l'ID de paiement fourni par la plateforme d'échange et copiez le dans le champ ID de paiement. Enfin, entrez le montant que vous souhaitez envoyer et vous êtes fin prêt !\n"
|
||||
"answer" : "Appuyez sur le bouton envoyer de l'écran du Portefeuille (Wallet). Ensuite, copiez l'adresse de dépôt de la plateforme d'échange et collez là dans le champ adresse. Puis, copiez l'ID de paiement fourni par la plateforme d'échange et copiez le dans le champ ID de paiement. Enfin, entrez le montant que vous souhaitez envoyer et vous êtes fin prêt !\n"
|
||||
},
|
||||
{
|
||||
"question" : "Que faire si j'oublie d'entrer l'ID de paiement quand j'envoie des Monero vers une plateforme d'échange ?",
|
||||
"answer" : "Bien que notre service de support ne puisse pas vous aider directement pour ce type de souci, c'est un problème très courant que la plupart des plateformes d'échange ont l'habitude de gérer. Contactez simplement le support de la plateforme d'échange, expliquez que vous avez oublié d'inclure l'ID de paiement et envoyez leur l'ID de transaction comme preuve. Vous pouvez visualiser l'ID de transaction en tapant sur transaction sur l'écran de votre wallet.\n"
|
||||
"answer" : "Bien que notre service de support ne puisse pas vous aider directement pour ce type de souci, c'est un problème très courant que la plupart des plateformes d'échange ont l'habitude de gérer. Contactez simplement le support de la plateforme d'échange, expliquez que vous avez oublié d'inclure l'ID de paiement et envoyez leur l'ID de transaction comme preuve. Vous pouvez visualiser l'ID de transaction en tapant sur transaction sur l'écran de votre portefeuille (wallet).\n"
|
||||
},
|
||||
{
|
||||
"question" : "Que signifient \"seed\" et \"clefs\" ?",
|
||||
"answer" : "Vos clefs encodent l'information privée de votre wallet, ce sont elles qui permettent de dépenser vos fonds et de visualiser les transactions entrantes.\nVotre seed est simplement une version de votre clef privée sous une forme plus simple à recopier. Votre seed et vos clefs sont la même chose, juste sous des formes différentes !\nNE DONNEZ JAMAIS votre seed ou vos clefs à quiconque. Vos fonds seront dérobés si vous donner votre seed ou vos clefs. Merci d'écrire cependant votre seed et de le stocker en lieu sûr (afin de vous permettre de restaurer votre wallet si vous perdez votre téléphone.)\n"
|
||||
"question" : "Que signifient \"phrase secrète (seed)\" et \"clefs\" ?",
|
||||
"answer" : "Vos clefs encodent l'information privée de votre portefeuille (wallet), ce sont elles qui permettent de dépenser vos fonds et de visualiser les transactions entrantes.\nVotre phrase secrète (seed) est simplement une version de votre clef privée sous une forme plus simple à recopier. Votre phrase secrète et vos clefs sont la même chose, juste sous des formes différentes !\nNE DONNEZ JAMAIS votre phrase secrète ou vos clefs à quiconque. Vos fonds seront dérobés si vous donnez votre phrase secrète ou vos clefs. Merci d'écrire cependant votre phrase secrète et de la stocker en lieu sûr (afin de vous permettre de restaurer votre portefeuille si vous perdez votre téléphone.)\n"
|
||||
},
|
||||
{
|
||||
"question" : "Combien de wallets puis-je créer ?",
|
||||
"answer" : "Il n'y a pas de limite ! Vous pouvez créer autant de wallets que vous le souhaitez.\n"
|
||||
"question" : "Combien de portefeuilles (wallets) puis-je créer ?",
|
||||
"answer" : "Il n'y a pas de limite ! Vous pouvez créer autant de portefeuilles (wallets) que vous le souhaitez.\n"
|
||||
},
|
||||
{
|
||||
"question" : "Commen puis-je restarurer mon wallet ?",
|
||||
"answer" : "Appuyez sur le menu •••, sélectionnez Wallets, puis choisissez Restaurer un Wallet. Entrez alors votre seed (ou vos clefs), et de façon optionnelle une date antérieure à la première transaction de votre wallet (cela permettra d'accélérer le processus de synchronisation). Vous pourrez avoir besoin de maintenir l'application ouverte pendant 15 à 30 minutes afin de restaurer complètement votre wallet.\n"
|
||||
"question" : "Commen puis-je restarurer mon portefeuille (wallet) ?",
|
||||
"answer" : "Appuyez sur le menu •••, sélectionnez Portefeuilles (Wallets), puis choisissez Restaurer un Portefeuille. Entrez alors votre phrase secrète (seed) (ou vos clefs), et de façon optionnelle une date antérieure à la première transaction de votre portefeuille (cela permettra d'accélérer le processus de synchronisation). Vous pourrez avoir besoin de maintenir l'application ouverte pendant 15 à 30 minutes afin de restaurer complètement votre portefeuille.\n"
|
||||
},
|
||||
{
|
||||
"question" : "Que puis-je faire si je perds mon seed ?",
|
||||
"answer" : "Si vous oubliez votre seed, il y a des chances que vous l'ayez inscrit quelque part. Vérifiez vos notes et regardez sur votre ordinateur. Si vous ne parvenez pas à le retrouver, il est possible que vous ayez effectué une sauvegarde de Cake Wallet (dans ce cas vous pourrez restaurer d'après cette sauvegarde). Si aucune des ces options ne convient, malheureusement il n'y a plus rien à faire, vos fonds sont définitivement perdus.\n"
|
||||
"question" : "Que puis-je faire si je perds ma phrase secrète (seed) ?",
|
||||
"answer" : "Si vous oubliez votre phrase secrète (seed), il y a des chances que vous l'ayez inscrite quelque part. Vérifiez vos notes et regardez sur votre ordinateur. Si vous ne parvenez pas à la retrouver, il est possible que vous ayez effectué une sauvegarde de Cake Wallet (dans ce cas vous pourrez restaurer d'après cette sauvegarde). Si aucune des ces options ne convient, malheureusement il n'y a plus rien à faire, vos fonds sont définitivement perdus.\n"
|
||||
},
|
||||
{
|
||||
"question" : "Collectez vous des informations à propos de mon wallet ?",
|
||||
"answer" : "Cake Wallet NE COLLECTE PAS d'informations à propos de votre wallet. Nous sommes respectueux de votre intimité.\n"
|
||||
"question" : "Collectez vous des informations à propos de mon portefeuille (wallet) ?",
|
||||
"answer" : "Cake Wallet NE COLLECTE PAS d'informations à propos de votre portefeuille (wallet). Nous sommes respectueux de votre intimité.\n"
|
||||
},
|
||||
{
|
||||
"question" : "Est il possible d'annuler une transaction ?",
|
||||
|
@ -37,11 +37,11 @@
|
|||
},
|
||||
{
|
||||
"question" : "Que sont les sous-adresses, et comment s'en servir ?",
|
||||
"answer" : "Une sous-adresse est une adresse unique que vous pouvez générer à tout moment. Les montants envoyés vers cette adresse arrivent toujours dans votre wallet principal, mais la personne qui vous envoie les fonds ne peut pas déterminer votre adresse principale. Les sous-adresses commencent par un 8.\nVous pouvez créer une nouvelle sous-adresse dans l'écran Réception en appuyant sur le + à côté du bouton Sous-Adresses. Entrez un nom pour la sous-adresse et appuyez sur Ajouter. Ensuite appuyez sur le nom de la sous-adresse quand vous souhaitez l'utiliser !\nSi vous êtres paranoïaque, vous devriez créer une nouvelle sous-adresse à chaque fois que vous voulez recevoir des Monero.\n"
|
||||
"answer" : "Une sous-adresse est une adresse unique que vous pouvez générer à tout moment. Les montants envoyés vers cette adresse arrivent toujours dans votre portefeuille (wallet) principal, mais la personne qui vous envoie les fonds ne peut pas déterminer votre adresse principale. Les sous-adresses commencent par un 8.\nVous pouvez créer une nouvelle sous-adresse dans l'écran Réception en appuyant sur le + à côté du bouton Sous-Adresses. Entrez un nom pour la sous-adresse et appuyez sur Ajouter. Ensuite appuyez sur le nom de la sous-adresse quand vous souhaitez l'utiliser !\nSi vous êtres paranoïaque, vous devriez créer une nouvelle sous-adresse à chaque fois que vous voulez recevoir des Monero.\n"
|
||||
},
|
||||
{
|
||||
"question" : "Qu'est-ce que l'ID de transaction ?",
|
||||
"answer" : "Une empreinte (hash) de transaction, ou ID de transaction, est un moyen unique d'identifier une transaction. Chaque transaction a sa propre empreinte. Si vous deve fournir une empreinte de transaction à quelque'un, allez simplement sur l'écran principal du Wallet, appuyez sur la transaction puis appuyez longuement sur la section du haut et sélectionnez Copier.\n"
|
||||
"answer" : "Une empreinte (hash) de transaction, ou ID de transaction, est un moyen unique d'identifier une transaction. Chaque transaction a sa propre empreinte. Si vous deve fournir une empreinte de transaction à quelque'un, allez simplement sur l'écran principal du Portefeuille (Wallet), appuyez sur la transaction puis appuyez longuement sur la section du haut et sélectionnez Copier.\n"
|
||||
},
|
||||
{
|
||||
"question" : "Je n'ai pas reçu mes XMR ! Que puis-je faire ?",
|
||||
|
|
BIN
assets/images/ape_icon.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
assets/images/avaxc_icon.png
Normal file
After Width: | Height: | Size: 4.1 KiB |
BIN
assets/images/btt_icon.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
assets/images/bttbsc_icon.png
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
assets/images/dcr_icon.png
Normal file
After Width: | Height: | Size: 115 KiB |
BIN
assets/images/doge_icon.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
assets/images/firo_icon.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
BIN
assets/images/hbar_icon.png
Normal file
After Width: | Height: | Size: 3.6 KiB |
BIN
assets/images/husd_icon.png
Normal file
After Width: | Height: | Size: 68 KiB |
BIN
assets/images/kmd_icon.png
Normal file
After Width: | Height: | Size: 129 KiB |
BIN
assets/images/mana_icon.png
Normal file
After Width: | Height: | Size: 125 KiB |
BIN
assets/images/matic_icon.png
Normal file
After Width: | Height: | Size: 76 KiB |
BIN
assets/images/mkr_icon.png
Normal file
After Width: | Height: | Size: 69 KiB |
BIN
assets/images/nano_icon.png
Normal file
After Width: | Height: | Size: 4.9 KiB |
BIN
assets/images/near_icon.png
Normal file
After Width: | Height: | Size: 64 KiB |
BIN
assets/images/oxt_icon.png
Normal file
After Width: | Height: | Size: 76 KiB |
BIN
assets/images/paxg_icon.png
Normal file
After Width: | Height: | Size: 127 KiB |
BIN
assets/images/pivx_icon.png
Normal file
After Width: | Height: | Size: 100 KiB |
BIN
assets/images/rune_icon.png
Normal file
After Width: | Height: | Size: 89 KiB |
BIN
assets/images/rvn_icon.png
Normal file
After Width: | Height: | Size: 242 KiB |
BIN
assets/images/sc_icon.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
assets/images/scrt_icon.png
Normal file
After Width: | Height: | Size: 164 KiB |
BIN
assets/images/sol_icon.png
Normal file
After Width: | Height: | Size: 6.6 KiB |
BIN
assets/images/stx_icon.png
Normal file
After Width: | Height: | Size: 71 KiB |
BIN
assets/images/uni_icon.png
Normal file
After Width: | Height: | Size: 117 KiB |
BIN
assets/images/usdc_icon.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
assets/images/usdcsol_icon.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
assets/images/usdttrc20_icon.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
assets/images/xvg_icon.png
Normal file
After Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 6 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 6 KiB |
BIN
assets/images/zen_icon.png
Normal file
After Width: | Height: | Size: 10 KiB |
|
@ -8,7 +8,7 @@ String addressFromOutput(Uint8List script, bitcoin.NetworkType networkType) {
|
|||
data: PaymentData(output: script),
|
||||
network: networkType)
|
||||
.data
|
||||
.address;
|
||||
.address!;
|
||||
} catch (_) {}
|
||||
|
||||
try {
|
||||
|
@ -16,8 +16,8 @@ String addressFromOutput(Uint8List script, bitcoin.NetworkType networkType) {
|
|||
data: PaymentData(output: script),
|
||||
network: networkType)
|
||||
.data
|
||||
.address;
|
||||
.address!;
|
||||
} catch(_) {}
|
||||
|
||||
return null;
|
||||
return '';
|
||||
}
|
|
@ -2,7 +2,7 @@ import 'dart:convert';
|
|||
|
||||
class BitcoinAddressRecord {
|
||||
BitcoinAddressRecord(this.address,
|
||||
{this.index, this.isHidden = false, bool isUsed = false})
|
||||
{required this.index, this.isHidden = false, bool isUsed = false})
|
||||
: _isUsed = isUsed;
|
||||
|
||||
factory BitcoinAddressRecord.fromJSON(String jsonSource) {
|
||||
|
@ -11,8 +11,8 @@ class BitcoinAddressRecord {
|
|||
return BitcoinAddressRecord(
|
||||
decoded['address'] as String,
|
||||
index: decoded['index'] as int,
|
||||
isHidden: decoded['isHidden'] as bool ?? false,
|
||||
isUsed: decoded['isUsed'] as bool ?? false);
|
||||
isHidden: decoded['isHidden'] as bool? ?? false,
|
||||
isUsed: decoded['isUsed'] as bool? ?? false);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
|
@ -7,10 +7,10 @@ final bitcoinAmountFormat = NumberFormat()
|
|||
..maximumFractionDigits = bitcoinAmountLength
|
||||
..minimumFractionDigits = 1;
|
||||
|
||||
String bitcoinAmountToString({int amount}) => bitcoinAmountFormat.format(
|
||||
String bitcoinAmountToString({required int amount}) => bitcoinAmountFormat.format(
|
||||
cryptoAmountToDouble(amount: amount, divider: bitcoinAmountDivider));
|
||||
|
||||
double bitcoinAmountToDouble({int amount}) =>
|
||||
double bitcoinAmountToDouble({required int amount}) =>
|
||||
cryptoAmountToDouble(amount: amount, divider: bitcoinAmountDivider);
|
||||
|
||||
int stringDoubleToBitcoinAmount(String amount) {
|
||||
|
|
|
@ -106,15 +106,18 @@ Future<String> generateMnemonic(
|
|||
return result;
|
||||
}
|
||||
|
||||
Uint8List mnemonicToSeedBytes(String mnemonic, {String prefix = segwit}) {
|
||||
Future<Uint8List> mnemonicToSeedBytes(String mnemonic, {String prefix = segwit}) async {
|
||||
final pbkdf2 = cryptography.Pbkdf2(
|
||||
macAlgorithm: cryptography.Hmac(cryptography.sha512),
|
||||
macAlgorithm: cryptography.Hmac.sha512(),
|
||||
iterations: 2048,
|
||||
bits: 512);
|
||||
final text = normalizeText(mnemonic);
|
||||
|
||||
return pbkdf2.deriveBitsSync(text.codeUnits,
|
||||
nonce: cryptography.Nonce('electrum'.codeUnits));
|
||||
// pbkdf2.deriveKey(secretKey: secretKey, nonce: nonce)
|
||||
final key = await pbkdf2.deriveKey(
|
||||
secretKey: cryptography.SecretKey(text.codeUnits),
|
||||
nonce: 'electrum'.codeUnits);
|
||||
final bytes = await key.extractBytes();
|
||||
return Uint8List.fromList(bytes);
|
||||
}
|
||||
|
||||
bool matchesAnyPrefix(String mnemonic) =>
|
||||
|
|
|
@ -2,9 +2,9 @@ import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
|
|||
import 'package:cw_core/output_info.dart';
|
||||
|
||||
class BitcoinTransactionCredentials {
|
||||
BitcoinTransactionCredentials(this.outputs, {this.priority, this.feeRate});
|
||||
BitcoinTransactionCredentials(this.outputs, {required this.priority, this.feeRate});
|
||||
|
||||
final List<OutputInfo> outputs;
|
||||
final BitcoinTransactionPriority priority;
|
||||
final int feeRate;
|
||||
final BitcoinTransactionPriority? priority;
|
||||
final int? feeRate;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import 'package:cw_core/transaction_priority.dart';
|
|||
//import 'package:cake_wallet/generated/i18n.dart';
|
||||
|
||||
class BitcoinTransactionPriority extends TransactionPriority {
|
||||
const BitcoinTransactionPriority({String title, int raw})
|
||||
const BitcoinTransactionPriority({required String title, required int raw})
|
||||
: super(title: title, raw: raw);
|
||||
|
||||
static const List<BitcoinTransactionPriority> all = [fast, medium, slow];
|
||||
|
@ -13,7 +13,7 @@ class BitcoinTransactionPriority extends TransactionPriority {
|
|||
static const BitcoinTransactionPriority fast =
|
||||
BitcoinTransactionPriority(title: 'Fast', raw: 2);
|
||||
|
||||
static BitcoinTransactionPriority deserialize({int raw}) {
|
||||
static BitcoinTransactionPriority deserialize({required int raw}) {
|
||||
switch (raw) {
|
||||
case 0:
|
||||
return slow;
|
||||
|
@ -22,7 +22,7 @@ class BitcoinTransactionPriority extends TransactionPriority {
|
|||
case 2:
|
||||
return fast;
|
||||
default:
|
||||
return null;
|
||||
throw Exception('Unexpected token: $raw for BitcoinTransactionPriority deserialize');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ class BitcoinTransactionPriority extends TransactionPriority {
|
|||
}
|
||||
|
||||
class LitecoinTransactionPriority extends BitcoinTransactionPriority {
|
||||
const LitecoinTransactionPriority({String title, int raw})
|
||||
const LitecoinTransactionPriority({required String title, required int raw})
|
||||
: super(title: title, raw: raw);
|
||||
|
||||
static const List<LitecoinTransactionPriority> all = [fast, medium, slow];
|
||||
|
@ -64,7 +64,7 @@ class LitecoinTransactionPriority extends BitcoinTransactionPriority {
|
|||
static const LitecoinTransactionPriority fast =
|
||||
LitecoinTransactionPriority(title: 'Fast', raw: 2);
|
||||
|
||||
static LitecoinTransactionPriority deserialize({int raw}) {
|
||||
static LitecoinTransactionPriority deserialize({required int raw}) {
|
||||
switch (raw) {
|
||||
case 0:
|
||||
return slow;
|
||||
|
@ -73,7 +73,7 @@ class LitecoinTransactionPriority extends BitcoinTransactionPriority {
|
|||
case 2:
|
||||
return fast;
|
||||
default:
|
||||
return null;
|
||||
throw Exception('Unexpected token: $raw for LitecoinTransactionPriority deserialize');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/unspent_coins_info.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
@ -17,12 +18,13 @@ class BitcoinWallet = BitcoinWalletBase with _$BitcoinWallet;
|
|||
|
||||
abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
||||
BitcoinWalletBase(
|
||||
{@required String mnemonic,
|
||||
@required String password,
|
||||
@required WalletInfo walletInfo,
|
||||
@required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
List<BitcoinAddressRecord> initialAddresses,
|
||||
ElectrumBalance initialBalance,
|
||||
{required String mnemonic,
|
||||
required String password,
|
||||
required WalletInfo walletInfo,
|
||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
required Uint8List seedBytes,
|
||||
List<BitcoinAddressRecord>? initialAddresses,
|
||||
ElectrumBalance? initialBalance,
|
||||
int initialRegularAddressIndex = 0,
|
||||
int initialChangeAddressIndex = 0})
|
||||
: super(
|
||||
|
@ -32,7 +34,9 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
|||
unspentCoinsInfo: unspentCoinsInfo,
|
||||
networkType: bitcoin.bitcoin,
|
||||
initialAddresses: initialAddresses,
|
||||
initialBalance: initialBalance) {
|
||||
initialBalance: initialBalance,
|
||||
seedBytes: seedBytes,
|
||||
currency: CryptoCurrency.btc) {
|
||||
walletAddresses = BitcoinWalletAddresses(
|
||||
walletInfo,
|
||||
electrumClient: electrumClient,
|
||||
|
@ -40,20 +44,40 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
|||
initialRegularAddressIndex: initialRegularAddressIndex,
|
||||
initialChangeAddressIndex: initialChangeAddressIndex,
|
||||
mainHd: hd,
|
||||
sideHd: bitcoin.HDWallet.fromSeed(
|
||||
mnemonicToSeedBytes(mnemonic), network: networkType)
|
||||
sideHd: bitcoin.HDWallet.fromSeed(seedBytes, network: networkType)
|
||||
.derivePath("m/0'/1"),
|
||||
networkType: networkType);
|
||||
}
|
||||
|
||||
static Future<BitcoinWallet> open({
|
||||
@required String name,
|
||||
@required WalletInfo walletInfo,
|
||||
@required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
@required String password,
|
||||
static Future<BitcoinWallet> create({
|
||||
required String mnemonic,
|
||||
required String password,
|
||||
required WalletInfo walletInfo,
|
||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
List<BitcoinAddressRecord>? initialAddresses,
|
||||
ElectrumBalance? initialBalance,
|
||||
int initialRegularAddressIndex = 0,
|
||||
int initialChangeAddressIndex = 0
|
||||
}) async {
|
||||
final snp = ElectrumWallletSnapshot(name, walletInfo.type, password);
|
||||
await snp.load();
|
||||
return BitcoinWallet(
|
||||
mnemonic: mnemonic,
|
||||
password: password,
|
||||
walletInfo: walletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfo,
|
||||
initialAddresses: initialAddresses,
|
||||
initialBalance: initialBalance,
|
||||
seedBytes: await mnemonicToSeedBytes(mnemonic),
|
||||
initialRegularAddressIndex: initialRegularAddressIndex,
|
||||
initialChangeAddressIndex: initialChangeAddressIndex);
|
||||
}
|
||||
|
||||
static Future<BitcoinWallet> open({
|
||||
required String name,
|
||||
required WalletInfo walletInfo,
|
||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
required String password,
|
||||
}) async {
|
||||
final snp = await ElectrumWallletSnapshot.load(name, walletInfo.type, password);
|
||||
return BitcoinWallet(
|
||||
mnemonic: snp.mnemonic,
|
||||
password: password,
|
||||
|
@ -61,6 +85,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
|||
unspentCoinsInfo: unspentCoinsInfo,
|
||||
initialAddresses: snp.addresses,
|
||||
initialBalance: snp.balance,
|
||||
seedBytes: await mnemonicToSeedBytes(snp.mnemonic),
|
||||
initialRegularAddressIndex: snp.regularAddressIndex,
|
||||
initialChangeAddressIndex: snp.changeAddressIndex);
|
||||
}
|
||||
|
|
|
@ -16,13 +16,13 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses
|
|||
with Store {
|
||||
BitcoinWalletAddressesBase(
|
||||
WalletInfo walletInfo,
|
||||
{@required List<BitcoinAddressRecord> initialAddresses,
|
||||
{required bitcoin.HDWallet mainHd,
|
||||
required bitcoin.HDWallet sideHd,
|
||||
required bitcoin.NetworkType networkType,
|
||||
required ElectrumClient electrumClient,
|
||||
List<BitcoinAddressRecord>? initialAddresses,
|
||||
int initialRegularAddressIndex = 0,
|
||||
int initialChangeAddressIndex = 0,
|
||||
ElectrumClient electrumClient,
|
||||
@required bitcoin.HDWallet mainHd,
|
||||
@required bitcoin.HDWallet sideHd,
|
||||
@required bitcoin.NetworkType networkType})
|
||||
int initialChangeAddressIndex = 0})
|
||||
: super(
|
||||
walletInfo,
|
||||
initialAddresses: initialAddresses,
|
||||
|
@ -34,6 +34,6 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses
|
|||
networkType: networkType);
|
||||
|
||||
@override
|
||||
String getAddress({@required int index, @required bitcoin.HDWallet hd}) =>
|
||||
String getAddress({required int index, required bitcoin.HDWallet hd}) =>
|
||||
generateP2WPKHAddress(hd: hd, index: index, networkType: networkType);
|
||||
}
|
|
@ -2,13 +2,13 @@ import 'package:cw_core/wallet_credentials.dart';
|
|||
import 'package:cw_core/wallet_info.dart';
|
||||
|
||||
class BitcoinNewWalletCredentials extends WalletCredentials {
|
||||
BitcoinNewWalletCredentials({String name, WalletInfo walletInfo})
|
||||
BitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo})
|
||||
: super(name: name, walletInfo: walletInfo);
|
||||
}
|
||||
|
||||
class BitcoinRestoreWalletFromSeedCredentials extends WalletCredentials {
|
||||
BitcoinRestoreWalletFromSeedCredentials(
|
||||
{String name, String password, this.mnemonic, WalletInfo walletInfo})
|
||||
{required String name, required String password, required this.mnemonic, WalletInfo? walletInfo})
|
||||
: super(name: name, password: password, walletInfo: walletInfo);
|
||||
|
||||
final String mnemonic;
|
||||
|
@ -16,7 +16,7 @@ class BitcoinRestoreWalletFromSeedCredentials extends WalletCredentials {
|
|||
|
||||
class BitcoinRestoreWalletFromWIFCredentials extends WalletCredentials {
|
||||
BitcoinRestoreWalletFromWIFCredentials(
|
||||
{String name, String password, this.wif, WalletInfo walletInfo})
|
||||
{required String name, required String password, required this.wif, WalletInfo? walletInfo})
|
||||
: super(name: name, password: password, walletInfo: walletInfo);
|
||||
|
||||
final String wif;
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
|
||||
class BitcoinWalletKeys {
|
||||
const BitcoinWalletKeys({@required this.wif, @required this.privateKey, @required this.publicKey});
|
||||
const BitcoinWalletKeys({required this.wif, required this.privateKey, required this.publicKey});
|
||||
|
||||
final String wif;
|
||||
final String privateKey;
|
||||
|
|
|
@ -10,6 +10,7 @@ import 'package:cw_core/pathForWallet.dart';
|
|||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
class BitcoinWalletService extends WalletService<
|
||||
BitcoinNewWalletCredentials,
|
||||
|
@ -25,10 +26,10 @@ class BitcoinWalletService extends WalletService<
|
|||
|
||||
@override
|
||||
Future<BitcoinWallet> create(BitcoinNewWalletCredentials credentials) async {
|
||||
final wallet = BitcoinWallet(
|
||||
final wallet = await BitcoinWalletBase.create(
|
||||
mnemonic: await generateMnemonic(),
|
||||
password: credentials.password,
|
||||
walletInfo: credentials.walletInfo,
|
||||
password: credentials.password!,
|
||||
walletInfo: credentials.walletInfo!,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
await wallet.save();
|
||||
await wallet.init();
|
||||
|
@ -41,9 +42,8 @@ class BitcoinWalletService extends WalletService<
|
|||
|
||||
@override
|
||||
Future<BitcoinWallet> openWallet(String name, String password) async {
|
||||
final walletInfo = walletInfoSource.values.firstWhere(
|
||||
(info) => info.id == WalletBase.idFor(name, getType()),
|
||||
orElse: () => null);
|
||||
final walletInfo = walletInfoSource.values.firstWhereOrNull(
|
||||
(info) => info.id == WalletBase.idFor(name, getType()))!;
|
||||
final wallet = await BitcoinWalletBase.open(
|
||||
password: password, name: name, walletInfo: walletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
|
@ -68,10 +68,10 @@ class BitcoinWalletService extends WalletService<
|
|||
throw BitcoinMnemonicIsIncorrectException();
|
||||
}
|
||||
|
||||
final wallet = BitcoinWallet(
|
||||
password: credentials.password,
|
||||
final wallet = await BitcoinWalletBase.create(
|
||||
password: credentials.password!,
|
||||
mnemonic: credentials.mnemonic,
|
||||
walletInfo: credentials.walletInfo,
|
||||
walletInfo: credentials.walletInfo!,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
await wallet.save();
|
||||
await wallet.init();
|
||||
|
|
|
@ -7,6 +7,7 @@ import 'package:cw_bitcoin/bitcoin_amount_format.dart';
|
|||
import 'package:cw_bitcoin/script_hash.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
String jsonrpcparams(List<Object> params) {
|
||||
final _params = params?.map((val) => '"${val.toString()}"')?.join(',');
|
||||
|
@ -14,14 +15,20 @@ String jsonrpcparams(List<Object> params) {
|
|||
}
|
||||
|
||||
String jsonrpc(
|
||||
{String method, List<Object> params, int id, double version = 2.0}) =>
|
||||
{required String method,
|
||||
required List<Object> params,
|
||||
required int id,
|
||||
double version = 2.0}) =>
|
||||
'{"jsonrpc": "$version", "method": "$method", "id": "$id", "params": ${json.encode(params)}}\n';
|
||||
|
||||
class SocketTask {
|
||||
SocketTask({this.completer, this.isSubscription, this.subject});
|
||||
SocketTask({
|
||||
required this.isSubscription,
|
||||
this.completer,
|
||||
this.subject});
|
||||
|
||||
final Completer completer;
|
||||
final BehaviorSubject subject;
|
||||
final Completer<dynamic>? completer;
|
||||
final BehaviorSubject<dynamic>? subject;
|
||||
final bool isSubscription;
|
||||
}
|
||||
|
||||
|
@ -36,18 +43,18 @@ class ElectrumClient {
|
|||
static const aliveTimerDuration = Duration(seconds: 2);
|
||||
|
||||
bool get isConnected => _isConnected;
|
||||
Socket socket;
|
||||
void Function(bool) onConnectionStatusChange;
|
||||
Socket? socket;
|
||||
void Function(bool)? onConnectionStatusChange;
|
||||
int _id;
|
||||
final Map<String, SocketTask> _tasks;
|
||||
bool _isConnected;
|
||||
Timer _aliveTimer;
|
||||
Timer? _aliveTimer;
|
||||
String unterminatedString;
|
||||
|
||||
Future<void> connectToUri(Uri uri) async =>
|
||||
await connect(host: uri.host, port: uri.port);
|
||||
|
||||
Future<void> connect({@required String host, @required int port}) async {
|
||||
Future<void> connect({required String host, required int port}) async {
|
||||
try {
|
||||
await socket?.close();
|
||||
} catch (_) {}
|
||||
|
@ -56,10 +63,11 @@ class ElectrumClient {
|
|||
timeout: connectionTimeout, onBadCertificate: (_) => true);
|
||||
_setIsConnected(true);
|
||||
|
||||
socket.listen((Uint8List event) {
|
||||
socket!.listen((Uint8List event) {
|
||||
try {
|
||||
final msg = utf8.decode(event.toList());
|
||||
final response =
|
||||
json.decode(utf8.decode(event.toList())) as Map<String, Object>;
|
||||
json.decode(msg) as Map<String, dynamic>;
|
||||
_handleResponse(response);
|
||||
} on FormatException catch (e) {
|
||||
final msg = e.message.toLowerCase();
|
||||
|
@ -75,12 +83,12 @@ class ElectrumClient {
|
|||
|
||||
if (isJSONStringCorrect(unterminatedString)) {
|
||||
final response =
|
||||
json.decode(unterminatedString) as Map<String, Object>;
|
||||
json.decode(unterminatedString) as Map<String, dynamic>;
|
||||
_handleResponse(response);
|
||||
unterminatedString = '';
|
||||
}
|
||||
} on TypeError catch (e) {
|
||||
if (!e.toString().contains('Map<String, Object>')) {
|
||||
if (!e.toString().contains('Map<String, Object>') || !e.toString().contains('Map<String, dynamic>')) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -89,9 +97,10 @@ class ElectrumClient {
|
|||
|
||||
if (isJSONStringCorrect(unterminatedString)) {
|
||||
final response =
|
||||
json.decode(unterminatedString) as Map<String, Object>;
|
||||
json.decode(unterminatedString) as Map<String, dynamic>;
|
||||
_handleResponse(response);
|
||||
unterminatedString = null;
|
||||
// unterminatedString = null;
|
||||
unterminatedString = '';
|
||||
}
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
|
@ -128,14 +137,14 @@ class ElectrumClient {
|
|||
return [];
|
||||
});
|
||||
|
||||
Future<Map<String, Object>> getBalance(String scriptHash) =>
|
||||
Future<Map<String, dynamic>> getBalance(String scriptHash) =>
|
||||
call(method: 'blockchain.scripthash.get_balance', params: [scriptHash])
|
||||
.then((dynamic result) {
|
||||
if (result is Map<String, Object>) {
|
||||
if (result is Map<String, dynamic>) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return <String, Object>{};
|
||||
return <String, dynamic>{};
|
||||
});
|
||||
|
||||
Future<List<Map<String, dynamic>>> getHistory(String scriptHash) =>
|
||||
|
@ -143,11 +152,11 @@ class ElectrumClient {
|
|||
.then((dynamic result) {
|
||||
if (result is List) {
|
||||
return result.map((dynamic val) {
|
||||
if (val is Map<String, Object>) {
|
||||
if (val is Map<String, dynamic>) {
|
||||
return val;
|
||||
}
|
||||
|
||||
return <String, Object>{};
|
||||
return <String, dynamic>{};
|
||||
}).toList();
|
||||
}
|
||||
|
||||
|
@ -162,12 +171,12 @@ class ElectrumClient {
|
|||
.then((dynamic result) {
|
||||
if (result is List) {
|
||||
return result.map((dynamic val) {
|
||||
if (val is Map<String, Object>) {
|
||||
if (val is Map<String, dynamic>) {
|
||||
val['address'] = address;
|
||||
return val;
|
||||
}
|
||||
|
||||
return <String, Object>{};
|
||||
return <String, dynamic>{};
|
||||
}).toList();
|
||||
}
|
||||
|
||||
|
@ -179,11 +188,11 @@ class ElectrumClient {
|
|||
.then((dynamic result) {
|
||||
if (result is List) {
|
||||
return result.map((dynamic val) {
|
||||
if (val is Map<String, Object>) {
|
||||
if (val is Map<String, dynamic>) {
|
||||
return val;
|
||||
}
|
||||
|
||||
return <String, Object>{};
|
||||
return <String, dynamic>{};
|
||||
}).toList();
|
||||
}
|
||||
|
||||
|
@ -195,30 +204,30 @@ class ElectrumClient {
|
|||
.then((dynamic result) {
|
||||
if (result is List) {
|
||||
return result.map((dynamic val) {
|
||||
if (val is Map<String, Object>) {
|
||||
if (val is Map<String, dynamic>) {
|
||||
return val;
|
||||
}
|
||||
|
||||
return <String, Object>{};
|
||||
return <String, dynamic>{};
|
||||
}).toList();
|
||||
}
|
||||
|
||||
return [];
|
||||
});
|
||||
|
||||
Future<Map<String, Object>> getTransactionRaw(
|
||||
{@required String hash}) async =>
|
||||
Future<Map<String, dynamic>> getTransactionRaw(
|
||||
{required String hash}) async =>
|
||||
call(method: 'blockchain.transaction.get', params: [hash, true])
|
||||
.then((dynamic result) {
|
||||
if (result is Map<String, Object>) {
|
||||
if (result is Map<String, dynamic>) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return <String, Object>{};
|
||||
return <String, dynamic>{};
|
||||
});
|
||||
|
||||
Future<String> getTransactionHex(
|
||||
{@required String hash}) async =>
|
||||
{required String hash}) async =>
|
||||
call(method: 'blockchain.transaction.get', params: [hash, false])
|
||||
.then((dynamic result) {
|
||||
if (result is String) {
|
||||
|
@ -229,7 +238,7 @@ class ElectrumClient {
|
|||
});
|
||||
|
||||
Future<String> broadcastTransaction(
|
||||
{@required String transactionRaw}) async =>
|
||||
{required String transactionRaw}) async =>
|
||||
call(method: 'blockchain.transaction.broadcast', params: [transactionRaw])
|
||||
.then((dynamic result) {
|
||||
if (result is String) {
|
||||
|
@ -240,16 +249,16 @@ class ElectrumClient {
|
|||
});
|
||||
|
||||
Future<Map<String, dynamic>> getMerkle(
|
||||
{@required String hash, @required int height}) async =>
|
||||
{required String hash, required int height}) async =>
|
||||
await call(
|
||||
method: 'blockchain.transaction.get_merkle',
|
||||
params: [hash, height]) as Map<String, dynamic>;
|
||||
|
||||
Future<Map<String, dynamic>> getHeader({@required int height}) async =>
|
||||
Future<Map<String, dynamic>> getHeader({required int height}) async =>
|
||||
await call(method: 'blockchain.block.get_header', params: [height])
|
||||
as Map<String, dynamic>;
|
||||
|
||||
Future<double> estimatefee({@required int p}) =>
|
||||
Future<double> estimatefee({required int p}) =>
|
||||
call(method: 'blockchain.estimatefee', params: [p])
|
||||
.then((dynamic result) {
|
||||
if (result is double) {
|
||||
|
@ -266,13 +275,26 @@ class ElectrumClient {
|
|||
Future<List<List<int>>> feeHistogram() =>
|
||||
call(method: 'mempool.get_fee_histogram').then((dynamic result) {
|
||||
if (result is List) {
|
||||
return result.map((dynamic e) {
|
||||
if (e is List) {
|
||||
return e.map((dynamic ee) => ee is int ? ee : null).toList();
|
||||
}
|
||||
// return result.map((dynamic e) {
|
||||
// if (e is List) {
|
||||
// return e.map((dynamic ee) => ee is int ? ee : null).toList();
|
||||
// }
|
||||
|
||||
return null;
|
||||
}).toList();
|
||||
// return null;
|
||||
// }).toList();
|
||||
final histogram = <List<int>>[];
|
||||
for (final e in result) {
|
||||
if (e is List) {
|
||||
final eee = <int>[];
|
||||
for (final ee in e) {
|
||||
if (ee is int) {
|
||||
eee.add(ee);
|
||||
}
|
||||
}
|
||||
histogram.add(eee);
|
||||
}
|
||||
}
|
||||
return histogram;
|
||||
}
|
||||
|
||||
return [];
|
||||
|
@ -299,7 +321,7 @@ class ElectrumClient {
|
|||
}
|
||||
}
|
||||
|
||||
BehaviorSubject<Object> scripthashUpdate(String scripthash) {
|
||||
BehaviorSubject<Object>? scripthashUpdate(String scripthash) {
|
||||
_id += 1;
|
||||
return subscribe<Object>(
|
||||
id: 'blockchain.scripthash.subscribe:$scripthash',
|
||||
|
@ -307,14 +329,14 @@ class ElectrumClient {
|
|||
params: [scripthash]);
|
||||
}
|
||||
|
||||
BehaviorSubject<T> subscribe<T>(
|
||||
{@required String id,
|
||||
@required String method,
|
||||
BehaviorSubject<T>? subscribe<T>(
|
||||
{required String id,
|
||||
required String method,
|
||||
List<Object> params = const []}) {
|
||||
try {
|
||||
final subscription = BehaviorSubject<T>();
|
||||
_regisrySubscription(id, subscription);
|
||||
socket.write(jsonrpc(method: method, id: _id, params: params));
|
||||
socket!.write(jsonrpc(method: method, id: _id, params: params));
|
||||
|
||||
return subscription;
|
||||
} catch(e) {
|
||||
|
@ -323,18 +345,18 @@ class ElectrumClient {
|
|||
}
|
||||
}
|
||||
|
||||
Future<dynamic> call({String method, List<Object> params = const []}) async {
|
||||
Future<dynamic> call({required String method, List<Object> params = const []}) async {
|
||||
final completer = Completer<dynamic>();
|
||||
_id += 1;
|
||||
final id = _id;
|
||||
_registryTask(id, completer);
|
||||
socket.write(jsonrpc(method: method, id: id, params: params));
|
||||
socket!.write(jsonrpc(method: method, id: id, params: params));
|
||||
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
Future<dynamic> callWithTimeout(
|
||||
{String method,
|
||||
{required String method,
|
||||
List<Object> params = const [],
|
||||
int timeout = 2000}) async {
|
||||
try {
|
||||
|
@ -342,7 +364,7 @@ class ElectrumClient {
|
|||
_id += 1;
|
||||
final id = _id;
|
||||
_registryTask(id, completer);
|
||||
socket.write(jsonrpc(method: method, id: id, params: params));
|
||||
socket!.write(jsonrpc(method: method, id: id, params: params));
|
||||
Timer(Duration(milliseconds: timeout), () {
|
||||
if (!completer.isCompleted) {
|
||||
completer.completeError(RequestFailedTimeoutException(method, id));
|
||||
|
@ -356,35 +378,35 @@ class ElectrumClient {
|
|||
}
|
||||
|
||||
Future<void> close() async {
|
||||
_aliveTimer.cancel();
|
||||
await socket.close();
|
||||
_aliveTimer?.cancel();
|
||||
await socket?.close();
|
||||
onConnectionStatusChange = null;
|
||||
}
|
||||
|
||||
void _registryTask(int id, Completer completer) => _tasks[id.toString()] =
|
||||
void _registryTask(int id, Completer<dynamic> completer) => _tasks[id.toString()] =
|
||||
SocketTask(completer: completer, isSubscription: false);
|
||||
|
||||
void _regisrySubscription(String id, BehaviorSubject subject) =>
|
||||
void _regisrySubscription(String id, BehaviorSubject<dynamic> subject) =>
|
||||
_tasks[id] = SocketTask(subject: subject, isSubscription: true);
|
||||
|
||||
void _finish(String id, Object data) {
|
||||
void _finish(String id, Object? data) {
|
||||
if (_tasks[id] == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(_tasks[id]?.completer?.isCompleted ?? false)) {
|
||||
_tasks[id]?.completer?.complete(data);
|
||||
_tasks[id]?.completer!.complete(data);
|
||||
}
|
||||
|
||||
if (!(_tasks[id]?.isSubscription ?? false)) {
|
||||
_tasks[id] = null;
|
||||
_tasks.remove(id);
|
||||
} else {
|
||||
_tasks[id].subject.add(data);
|
||||
_tasks[id]?.subject?.add(data);
|
||||
}
|
||||
}
|
||||
|
||||
void _methodHandler(
|
||||
{@required String method, @required Map<String, Object> request}) {
|
||||
{required String method, required Map<String, dynamic> request}) {
|
||||
switch (method) {
|
||||
case 'blockchain.scripthash.subscribe':
|
||||
final params = request['params'] as List<dynamic>;
|
||||
|
@ -406,7 +428,7 @@ class ElectrumClient {
|
|||
_isConnected = isConnected;
|
||||
}
|
||||
|
||||
void _handleResponse(Map<String, Object> response) {
|
||||
void _handleResponse(Map<String, dynamic> response) {
|
||||
final method = response['method'];
|
||||
final id = response['id'] as String;
|
||||
final result = response['result'];
|
||||
|
|
|
@ -4,10 +4,10 @@ import 'package:cw_bitcoin/bitcoin_amount_format.dart';
|
|||
import 'package:cw_core/balance.dart';
|
||||
|
||||
class ElectrumBalance extends Balance {
|
||||
const ElectrumBalance({@required this.confirmed, @required this.unconfirmed})
|
||||
const ElectrumBalance({required this.confirmed, required this.unconfirmed})
|
||||
: super(confirmed, unconfirmed);
|
||||
|
||||
factory ElectrumBalance.fromJSON(String jsonSource) {
|
||||
static ElectrumBalance? fromJSON(String? jsonSource) {
|
||||
if (jsonSource == null) {
|
||||
return null;
|
||||
}
|
||||
|
@ -15,8 +15,8 @@ class ElectrumBalance extends Balance {
|
|||
final decoded = json.decode(jsonSource) as Map;
|
||||
|
||||
return ElectrumBalance(
|
||||
confirmed: decoded['confirmed'] as int ?? 0,
|
||||
unconfirmed: decoded['unconfirmed'] as int ?? 0);
|
||||
confirmed: decoded['confirmed'] as int? ?? 0,
|
||||
unconfirmed: decoded['unconfirmed'] as int? ?? 0);
|
||||
}
|
||||
|
||||
final int confirmed;
|
||||
|
|
|
@ -17,7 +17,7 @@ class ElectrumTransactionHistory = ElectrumTransactionHistoryBase
|
|||
abstract class ElectrumTransactionHistoryBase
|
||||
extends TransactionHistoryBase<ElectrumTransactionInfo> with Store {
|
||||
ElectrumTransactionHistoryBase(
|
||||
{@required this.walletInfo, @required String password})
|
||||
{required this.walletInfo, required String password})
|
||||
: _password = password,
|
||||
_height = 0 {
|
||||
transactions = ObservableMap<String, ElectrumTransactionInfo>();
|
||||
|
@ -56,18 +56,18 @@ abstract class ElectrumTransactionHistoryBase
|
|||
await save();
|
||||
}
|
||||
|
||||
Future<Map<String, Object>> _read() async {
|
||||
Future<Map<String, dynamic>> _read() async {
|
||||
final dirPath =
|
||||
await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
|
||||
final path = '$dirPath/$_transactionsHistoryFileName';
|
||||
final content = await read(path: path, password: _password);
|
||||
return json.decode(content) as Map<String, Object>;
|
||||
return json.decode(content) as Map<String, dynamic>;
|
||||
}
|
||||
|
||||
Future<void> _load() async {
|
||||
try {
|
||||
final content = await _read();
|
||||
final txs = content['transactions'] as Map<String, Object> ?? {};
|
||||
final txs = content['transactions'] as Map<String, dynamic> ?? {};
|
||||
|
||||
txs.entries.forEach((entry) {
|
||||
final val = entry.value;
|
||||
|
@ -93,11 +93,11 @@ abstract class ElectrumTransactionHistoryBase
|
|||
transactions[transaction.id] = transaction;
|
||||
} else {
|
||||
final originalTx = transactions[transaction.id];
|
||||
originalTx.confirmations = transaction.confirmations;
|
||||
originalTx.amount = transaction.amount;
|
||||
originalTx.height = transaction.height;
|
||||
originalTx.date ??= transaction.date;
|
||||
originalTx.isPending = transaction.isPending;
|
||||
originalTx?.confirmations = transaction.confirmations;
|
||||
originalTx?.amount = transaction.amount;
|
||||
originalTx?.height = transaction.height;
|
||||
originalTx?.date ??= transaction.date;
|
||||
originalTx?.isPending = transaction.isPending;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,23 +10,26 @@ import 'package:cw_core/format_amount.dart';
|
|||
import 'package:cw_core/wallet_type.dart';
|
||||
|
||||
class ElectrumTransactionBundle {
|
||||
ElectrumTransactionBundle(this.originalTransaction, {this.ins, this.time, this.confirmations});
|
||||
ElectrumTransactionBundle(this.originalTransaction,
|
||||
{required this.ins,
|
||||
required this.confirmations,
|
||||
this.time});
|
||||
final bitcoin.Transaction originalTransaction;
|
||||
final List<bitcoin.Transaction> ins;
|
||||
final int time;
|
||||
final int? time;
|
||||
final int confirmations;
|
||||
}
|
||||
|
||||
class ElectrumTransactionInfo extends TransactionInfo {
|
||||
ElectrumTransactionInfo(this.type,
|
||||
{@required String id,
|
||||
@required int height,
|
||||
@required int amount,
|
||||
@required int fee,
|
||||
@required TransactionDirection direction,
|
||||
@required bool isPending,
|
||||
@required DateTime date,
|
||||
@required int confirmations}) {
|
||||
{required String id,
|
||||
required int height,
|
||||
required int amount,
|
||||
int? fee,
|
||||
required TransactionDirection direction,
|
||||
required bool isPending,
|
||||
required DateTime date,
|
||||
required int confirmations}) {
|
||||
this.id = id;
|
||||
this.height = height;
|
||||
this.amount = amount;
|
||||
|
@ -39,15 +42,15 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
|||
|
||||
factory ElectrumTransactionInfo.fromElectrumVerbose(
|
||||
Map<String, Object> obj, WalletType type,
|
||||
{@required List<BitcoinAddressRecord> addresses, @required int height}) {
|
||||
{required List<BitcoinAddressRecord> addresses, required int height}) {
|
||||
final addressesSet = addresses.map((addr) => addr.address).toSet();
|
||||
final id = obj['txid'] as String;
|
||||
final vins = obj['vin'] as List<Object> ?? [];
|
||||
final vout = (obj['vout'] as List<Object> ?? []);
|
||||
final vins = obj['vin'] as List<Object>? ?? [];
|
||||
final vout = (obj['vout'] as List<Object>? ?? []);
|
||||
final date = obj['time'] is int
|
||||
? DateTime.fromMillisecondsSinceEpoch((obj['time'] as int) * 1000)
|
||||
: DateTime.now();
|
||||
final confirmations = obj['confirmations'] as int ?? 0;
|
||||
final confirmations = obj['confirmations'] as int? ?? 0;
|
||||
var direction = TransactionDirection.incoming;
|
||||
var inputsAmount = 0;
|
||||
var amount = 0;
|
||||
|
@ -57,21 +60,21 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
|||
final vout = vin['vout'] as int;
|
||||
final out = vin['tx']['vout'][vout] as Map;
|
||||
final outAddresses =
|
||||
(out['scriptPubKey']['addresses'] as List<Object>)?.toSet();
|
||||
(out['scriptPubKey']['addresses'] as List<Object>?)?.toSet();
|
||||
inputsAmount +=
|
||||
stringDoubleToBitcoinAmount((out['value'] as double ?? 0).toString());
|
||||
stringDoubleToBitcoinAmount((out['value'] as double? ?? 0).toString());
|
||||
|
||||
if (outAddresses?.intersection(addressesSet)?.isNotEmpty ?? false) {
|
||||
if (outAddresses?.intersection(addressesSet).isNotEmpty ?? false) {
|
||||
direction = TransactionDirection.outgoing;
|
||||
}
|
||||
}
|
||||
|
||||
for (dynamic out in vout) {
|
||||
final outAddresses =
|
||||
out['scriptPubKey']['addresses'] as List<Object> ?? [];
|
||||
out['scriptPubKey']['addresses'] as List<Object>? ?? [];
|
||||
final ntrs = outAddresses.toSet().intersection(addressesSet);
|
||||
final value = stringDoubleToBitcoinAmount(
|
||||
(out['value'] as double ?? 0.0).toString());
|
||||
(out['value'] as double? ?? 0.0).toString());
|
||||
totalOutAmount += value;
|
||||
|
||||
if ((direction == TransactionDirection.incoming && ntrs.isNotEmpty) ||
|
||||
|
@ -97,10 +100,10 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
|||
ElectrumTransactionBundle bundle,
|
||||
WalletType type,
|
||||
bitcoin.NetworkType networkType,
|
||||
{@required Set<String> addresses,
|
||||
int height}) {
|
||||
{required Set<String> addresses,
|
||||
required int height}) {
|
||||
final date = bundle.time != null
|
||||
? DateTime.fromMillisecondsSinceEpoch(bundle.time * 1000)
|
||||
? DateTime.fromMillisecondsSinceEpoch(bundle.time! * 1000)
|
||||
: DateTime.now();
|
||||
var direction = TransactionDirection.incoming;
|
||||
var amount = 0;
|
||||
|
@ -111,21 +114,21 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
|||
final input = bundle.originalTransaction.ins[i];
|
||||
final inputTransaction = bundle.ins[i];
|
||||
final vout = input.index;
|
||||
final outTransaction = inputTransaction.outs[vout];
|
||||
final address = addressFromOutput(outTransaction.script, networkType);
|
||||
inputAmount += outTransaction.value;
|
||||
final outTransaction = inputTransaction.outs[vout!];
|
||||
final address = addressFromOutput(outTransaction.script!, networkType);
|
||||
inputAmount += outTransaction.value!;
|
||||
if (addresses.contains(address)) {
|
||||
direction = TransactionDirection.outgoing;
|
||||
}
|
||||
}
|
||||
|
||||
for (final out in bundle.originalTransaction.outs) {
|
||||
totalOutAmount += out.value;
|
||||
final address = addressFromOutput(out.script, networkType);
|
||||
totalOutAmount += out.value!;
|
||||
final address = addressFromOutput(out.script!, networkType);
|
||||
final addressExists = addresses.contains(address);
|
||||
if ((direction == TransactionDirection.incoming && addressExists) ||
|
||||
(direction == TransactionDirection.outgoing && !addressExists)) {
|
||||
amount += out.value;
|
||||
amount += out.value!;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,7 +145,7 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
|||
}
|
||||
|
||||
factory ElectrumTransactionInfo.fromHexAndHeader(WalletType type, String hex,
|
||||
{List<String> addresses, int height, int timestamp, int confirmations}) {
|
||||
{List<String>? addresses, required int height, int? timestamp, required int confirmations}) {
|
||||
final tx = bitcoin.Transaction.fromHex(hex);
|
||||
var exist = false;
|
||||
var amount = 0;
|
||||
|
@ -155,7 +158,7 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
|||
exist = addresses.contains(p2pkh.data.address);
|
||||
|
||||
if (exist) {
|
||||
amount += out.value;
|
||||
amount += out.value!;
|
||||
}
|
||||
} catch (_) {}
|
||||
});
|
||||
|
@ -191,15 +194,15 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
|||
|
||||
final WalletType type;
|
||||
|
||||
String _fiatAmount;
|
||||
String? _fiatAmount;
|
||||
|
||||
@override
|
||||
String amountFormatted() =>
|
||||
'${formatAmount(bitcoinAmountToString(amount: amount))} ${walletTypeToCryptoCurrency(type).title}';
|
||||
|
||||
@override
|
||||
String feeFormatted() => fee != null
|
||||
? '${formatAmount(bitcoinAmountToString(amount: fee))} ${walletTypeToCryptoCurrency(type).title}'
|
||||
String? feeFormatted() => fee != null
|
||||
? '${formatAmount(bitcoinAmountToString(amount: fee!))} ${walletTypeToCryptoCurrency(type).title}'
|
||||
: '';
|
||||
|
||||
@override
|
||||
|
@ -225,7 +228,9 @@ class ElectrumTransactionInfo extends TransactionInfo {
|
|||
m['id'] = id;
|
||||
m['height'] = height;
|
||||
m['amount'] = amount;
|
||||
m['direction'] = direction.index;
|
||||
// FIX-ME: Hardcoded value
|
||||
// m['direction'] = direction.index;
|
||||
m['direction'] = 0;
|
||||
m['date'] = date.millisecondsSinceEpoch;
|
||||
m['isPending'] = isPending;
|
||||
m['confirmations'] = confirmations;
|
||||
|
|
|
@ -34,6 +34,7 @@ import 'package:cw_core/wallet_info.dart';
|
|||
import 'package:cw_bitcoin/electrum.dart';
|
||||
import 'package:hex/hex.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
part 'electrum_wallet.g.dart';
|
||||
|
||||
|
@ -42,31 +43,34 @@ class ElectrumWallet = ElectrumWalletBase with _$ElectrumWallet;
|
|||
abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
||||
ElectrumTransactionHistory, ElectrumTransactionInfo> with Store {
|
||||
ElectrumWalletBase(
|
||||
{@required String password,
|
||||
@required WalletInfo walletInfo,
|
||||
@required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
@required List<BitcoinAddressRecord> initialAddresses,
|
||||
@required this.networkType,
|
||||
@required this.mnemonic,
|
||||
ElectrumClient electrumClient,
|
||||
ElectrumBalance initialBalance})
|
||||
: hd = bitcoin.HDWallet.fromSeed(mnemonicToSeedBytes(mnemonic),
|
||||
network: networkType)
|
||||
{required String password,
|
||||
required WalletInfo walletInfo,
|
||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
required this.networkType,
|
||||
required this.mnemonic,
|
||||
required Uint8List seedBytes,
|
||||
List<BitcoinAddressRecord>? initialAddresses,
|
||||
ElectrumClient? electrumClient,
|
||||
ElectrumBalance? initialBalance,
|
||||
CryptoCurrency? currency})
|
||||
: hd = bitcoin.HDWallet.fromSeed(seedBytes, network: networkType)
|
||||
.derivePath("m/0'/0"),
|
||||
syncStatus = NotConnectedSyncStatus(),
|
||||
_password = password,
|
||||
_feeRates = <int>[],
|
||||
_isTransactionUpdating = false,
|
||||
unspentCoins = [],
|
||||
_scripthashesUpdateSubject = {},
|
||||
balance = ObservableMap<CryptoCurrency, ElectrumBalance>.of(
|
||||
currency != null
|
||||
? {currency: initialBalance ?? const ElectrumBalance(confirmed: 0, unconfirmed: 0)}
|
||||
: {}),
|
||||
this.unspentCoinsInfo = unspentCoinsInfo,
|
||||
super(walletInfo) {
|
||||
balance = ObservableMap<CryptoCurrency, ElectrumBalance>.of({
|
||||
currency: initialBalance ?? const ElectrumBalance(confirmed: 0, unconfirmed: 0)});
|
||||
this.electrumClient = electrumClient ?? ElectrumClient();
|
||||
this.walletInfo = walletInfo;
|
||||
this.unspentCoinsInfo = unspentCoinsInfo;
|
||||
transactionHistory =
|
||||
ElectrumTransactionHistory(walletInfo: walletInfo, password: password);
|
||||
unspentCoins = [];
|
||||
_scripthashesUpdateSubject = {};
|
||||
}
|
||||
|
||||
static int estimatedTransactionSize(int inputsCount, int outputsCounts) =>
|
||||
|
@ -75,15 +79,15 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
final bitcoin.HDWallet hd;
|
||||
final String mnemonic;
|
||||
|
||||
ElectrumClient electrumClient;
|
||||
late ElectrumClient electrumClient;
|
||||
Box<UnspentCoinsInfo> unspentCoinsInfo;
|
||||
|
||||
@override
|
||||
ElectrumWalletAddresses walletAddresses;
|
||||
late ElectrumWalletAddresses walletAddresses;
|
||||
|
||||
@override
|
||||
@observable
|
||||
ObservableMap<CryptoCurrency, ElectrumBalance> balance;
|
||||
late ObservableMap<CryptoCurrency, ElectrumBalance> balance;
|
||||
|
||||
@override
|
||||
@observable
|
||||
|
@ -98,7 +102,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
.map((addr) => scriptHash(addr.address, networkType: networkType))
|
||||
.toList();
|
||||
|
||||
String get xpub => hd.base58;
|
||||
String get xpub => hd.base58!;
|
||||
|
||||
@override
|
||||
String get seed => mnemonic;
|
||||
|
@ -107,12 +111,12 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
|
||||
@override
|
||||
BitcoinWalletKeys get keys => BitcoinWalletKeys(
|
||||
wif: hd.wif, privateKey: hd.privKey, publicKey: hd.pubKey);
|
||||
wif: hd.wif!, privateKey: hd.privKey!, publicKey: hd.pubKey!);
|
||||
|
||||
String _password;
|
||||
List<BitcoinUnspent> unspentCoins;
|
||||
List<int> _feeRates;
|
||||
Map<String, BehaviorSubject<Object>> _scripthashesUpdateSubject;
|
||||
Map<String, BehaviorSubject<Object>?> _scripthashesUpdateSubject;
|
||||
bool _isTransactionUpdating;
|
||||
|
||||
Future<void> init() async {
|
||||
|
@ -137,7 +141,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
(timer) async => _feeRates = await electrumClient.feeRates());
|
||||
|
||||
syncStatus = SyncedSyncStatus();
|
||||
} catch (e) {
|
||||
} catch (e, stacktrace) {
|
||||
print(stacktrace);
|
||||
print(e.toString());
|
||||
syncStatus = FailedSyncStatus();
|
||||
}
|
||||
|
@ -145,7 +150,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
|
||||
@action
|
||||
@override
|
||||
Future<void> connectToNode({@required Node node}) async {
|
||||
Future<void> connectToNode({required Node node}) async {
|
||||
try {
|
||||
syncStatus = ConnectingSyncStatus();
|
||||
await electrumClient.connectToUri(node.uri);
|
||||
|
@ -187,7 +192,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
}
|
||||
|
||||
final allAmountFee = feeAmountForPriority(
|
||||
transactionCredentials.priority, inputs.length, outputs.length);
|
||||
transactionCredentials.priority!, inputs.length, outputs.length);
|
||||
final allAmount = allInputsAmount - allAmountFee;
|
||||
|
||||
var credentialsAmount = 0;
|
||||
|
@ -196,12 +201,12 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
|
||||
if (hasMultiDestination) {
|
||||
if (outputs.any((item) => item.sendAll
|
||||
|| item.formattedCryptoAmount <= 0)) {
|
||||
|| item.formattedCryptoAmount! <= 0)) {
|
||||
throw BitcoinTransactionWrongBalanceException(currency);
|
||||
}
|
||||
|
||||
credentialsAmount = outputs.fold(0, (acc, value) =>
|
||||
acc + value.formattedCryptoAmount);
|
||||
acc + value.formattedCryptoAmount!);
|
||||
|
||||
if (allAmount - credentialsAmount < minAmount) {
|
||||
throw BitcoinTransactionWrongBalanceException(currency);
|
||||
|
@ -210,7 +215,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
amount = credentialsAmount;
|
||||
|
||||
if (transactionCredentials.feeRate != null) {
|
||||
fee = calculateEstimatedFeeWithFeeRate(transactionCredentials.feeRate, amount,
|
||||
fee = calculateEstimatedFeeWithFeeRate(transactionCredentials.feeRate!, amount,
|
||||
outputsCount: outputs.length + 1);
|
||||
} else {
|
||||
fee = calculateEstimatedFee(transactionCredentials.priority, amount,
|
||||
|
@ -219,7 +224,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
} else {
|
||||
final output = outputs.first;
|
||||
credentialsAmount = !output.sendAll
|
||||
? output.formattedCryptoAmount
|
||||
? output.formattedCryptoAmount!
|
||||
: 0;
|
||||
|
||||
if (credentialsAmount > allAmount) {
|
||||
|
@ -233,7 +238,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
if (output.sendAll || amount == allAmount) {
|
||||
fee = allAmountFee;
|
||||
} else if (transactionCredentials.feeRate != null) {
|
||||
fee = calculateEstimatedFeeWithFeeRate(transactionCredentials.feeRate, amount);
|
||||
fee = calculateEstimatedFeeWithFeeRate(transactionCredentials.feeRate!, amount);
|
||||
} else {
|
||||
fee = calculateEstimatedFee(transactionCredentials.priority, amount);
|
||||
}
|
||||
|
@ -245,7 +250,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
|
||||
final totalAmount = amount + fee;
|
||||
|
||||
if (totalAmount > balance[currency].confirmed || totalAmount > allInputsAmount) {
|
||||
if (totalAmount > balance[currency]!.confirmed || totalAmount > allInputsAmount) {
|
||||
throw BitcoinTransactionWrongBalanceException(currency);
|
||||
}
|
||||
|
||||
|
@ -298,11 +303,11 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
? item.formattedCryptoAmount
|
||||
: amount;
|
||||
final outputAddress = item.isParsedAddress
|
||||
? item.extractedAddress
|
||||
? item.extractedAddress!
|
||||
: item.address;
|
||||
txb.addOutput(
|
||||
addressToOutputScript(outputAddress, networkType),
|
||||
outputAmount);
|
||||
outputAmount!);
|
||||
});
|
||||
|
||||
final estimatedSize =
|
||||
|
@ -310,9 +315,9 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
var feeAmount = 0;
|
||||
|
||||
if (transactionCredentials.feeRate != null) {
|
||||
feeAmount = transactionCredentials.feeRate * estimatedSize;
|
||||
feeAmount = transactionCredentials.feeRate! * estimatedSize;
|
||||
} else {
|
||||
feeAmount = feeRate(transactionCredentials.priority) * estimatedSize;
|
||||
feeAmount = feeRate(transactionCredentials.priority!) * estimatedSize;
|
||||
}
|
||||
|
||||
final changeValue = totalInputAmount - amount - feeAmount;
|
||||
|
@ -369,8 +374,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
feeRate * estimatedTransactionSize(inputsCount, outputsCount);
|
||||
|
||||
@override
|
||||
int calculateEstimatedFee(TransactionPriority priority, int amount,
|
||||
{int outputsCount}) {
|
||||
int calculateEstimatedFee(TransactionPriority? priority, int? amount,
|
||||
{int? outputsCount}) {
|
||||
if (priority is BitcoinTransactionPriority) {
|
||||
return calculateEstimatedFeeWithFeeRate(
|
||||
feeRate(priority),
|
||||
|
@ -381,8 +386,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int calculateEstimatedFeeWithFeeRate(int feeRate, int amount,
|
||||
{int outputsCount}) {
|
||||
int calculateEstimatedFeeWithFeeRate(int feeRate, int? amount,
|
||||
{int? outputsCount}) {
|
||||
int inputsCount = 0;
|
||||
|
||||
if (amount != null) {
|
||||
|
@ -429,16 +434,16 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
await transactionHistory.changePassword(password);
|
||||
}
|
||||
|
||||
bitcoin.ECPair keyPairFor({@required int index}) =>
|
||||
bitcoin.ECPair keyPairFor({required int index}) =>
|
||||
generateKeyPair(hd: hd, index: index, network: networkType);
|
||||
|
||||
@override
|
||||
Future<void> rescan({int height}) async => throw UnimplementedError();
|
||||
Future<void> rescan({required int height}) async => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
Future<void> close() async {
|
||||
try {
|
||||
await electrumClient?.close();
|
||||
await electrumClient.close();
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
|
@ -450,7 +455,13 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
.addresses.map((address) => electrumClient
|
||||
.getListUnspentWithAddress(address.address, networkType)
|
||||
.then((unspent) => unspent
|
||||
.map((unspent) => BitcoinUnspent.fromJSON(address, unspent)))));
|
||||
.map((unspent) {
|
||||
try {
|
||||
return BitcoinUnspent.fromJSON(address, unspent);
|
||||
} catch(_) {
|
||||
return null;
|
||||
}
|
||||
}).whereNotNull())));
|
||||
unspentCoins = unspent.expand((e) => e).toList();
|
||||
|
||||
if (unspentCoinsInfo.isEmpty) {
|
||||
|
@ -484,7 +495,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
hash: coin.hash,
|
||||
isFrozen: coin.isFrozen,
|
||||
isSending: coin.isSending,
|
||||
note: coin.note
|
||||
noteRaw: coin.note
|
||||
);
|
||||
|
||||
await unspentCoinsInfo.add(newInfo);
|
||||
|
@ -498,10 +509,9 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
|
||||
if (currentWalletUnspentCoins.isNotEmpty) {
|
||||
currentWalletUnspentCoins.forEach((element) {
|
||||
final existUnspentCoins = unspentCoins
|
||||
?.where((coin) => element.hash.contains(coin?.hash));
|
||||
final existUnspentCoins = unspentCoins.where((coin) => element.hash.contains(coin.hash));
|
||||
|
||||
if (existUnspentCoins?.isEmpty ?? true) {
|
||||
if (existUnspentCoins.isEmpty) {
|
||||
keys.add(element.key);
|
||||
}
|
||||
});
|
||||
|
@ -516,7 +526,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
}
|
||||
|
||||
Future<ElectrumTransactionBundle> getTransactionExpanded(
|
||||
{@required String hash, @required int height}) async {
|
||||
{required String hash, required int height}) async {
|
||||
final verboseTransaction = await electrumClient.getTransactionRaw(hash: hash);
|
||||
final transactionHex = verboseTransaction['hex'] as String;
|
||||
final original = bitcoin.Transaction.fromHex(transactionHex);
|
||||
|
@ -525,7 +535,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
final confirmations = verboseTransaction['confirmations'] as int ?? 0;
|
||||
|
||||
for (final vin in original.ins) {
|
||||
final id = HEX.encode(vin.hash.reversed.toList());
|
||||
final id = HEX.encode(vin.hash!.reversed.toList());
|
||||
final txHex = await electrumClient.getTransactionHex(hash: id);
|
||||
final tx = bitcoin.Transaction.fromHex(txHex);
|
||||
ins.add(tx);
|
||||
|
@ -538,8 +548,9 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
confirmations: confirmations);
|
||||
}
|
||||
|
||||
Future<ElectrumTransactionInfo> fetchTransactionInfo(
|
||||
{@required String hash, @required int height}) async {
|
||||
Future<ElectrumTransactionInfo?> fetchTransactionInfo(
|
||||
{required String hash, required int height}) async {
|
||||
try {
|
||||
final tx = await getTransactionExpanded(hash: hash, height: height);
|
||||
final addresses = walletAddresses.addresses.map((addr) => addr.address).toSet();
|
||||
return ElectrumTransactionInfo.fromElectrumBundle(
|
||||
|
@ -548,6 +559,9 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
networkType,
|
||||
addresses: addresses,
|
||||
height: height);
|
||||
} catch(_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -567,19 +581,27 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
history.entries.forEach((historyItem) {
|
||||
if (historyItem.value.isNotEmpty) {
|
||||
final address = addressHashes[historyItem.key];
|
||||
address.setAsUsed();
|
||||
address?.setAsUsed();
|
||||
normalizedHistories.addAll(historyItem.value);
|
||||
}
|
||||
});
|
||||
});
|
||||
final historiesWithDetails = await Future.wait(
|
||||
normalizedHistories
|
||||
.map((transaction) => fetchTransactionInfo(
|
||||
hash: transaction['tx_hash'] as String,
|
||||
height: transaction['height'] as int)));
|
||||
|
||||
.map((transaction) {
|
||||
try {
|
||||
return fetchTransactionInfo(
|
||||
hash: transaction['tx_hash'] as String,
|
||||
height: transaction['height'] as int);
|
||||
} catch(_) {
|
||||
return Future.value(null);
|
||||
}
|
||||
}));
|
||||
return historiesWithDetails.fold<Map<String, ElectrumTransactionInfo>>(
|
||||
<String, ElectrumTransactionInfo>{}, (acc, tx) {
|
||||
if (tx == null) {
|
||||
return acc;
|
||||
}
|
||||
acc[tx.id] = acc[tx.id]?.updated(tx) ?? tx;
|
||||
return acc;
|
||||
});
|
||||
|
@ -597,7 +619,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
walletAddresses.updateReceiveAddresses();
|
||||
await transactionHistory.save();
|
||||
_isTransactionUpdating = false;
|
||||
} catch (e) {
|
||||
} catch (e, stacktrace) {
|
||||
print(stacktrace);
|
||||
print(e);
|
||||
_isTransactionUpdating = false;
|
||||
}
|
||||
|
@ -637,8 +660,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
|
|||
for (var i = 0; i < balances.length; i++) {
|
||||
final addressRecord = addresses[i];
|
||||
final balance = balances[i];
|
||||
final confirmed = balance['confirmed'] as int ?? 0;
|
||||
final unconfirmed = balance['unconfirmed'] as int ?? 0;
|
||||
final confirmed = balance['confirmed'] as int? ?? 0;
|
||||
final unconfirmed = balance['unconfirmed'] as int? ?? 0;
|
||||
totalConfirmed += confirmed;
|
||||
totalUnconfirmed += unconfirmed;
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ import 'package:cw_bitcoin/electrum.dart';
|
|||
import 'package:cw_bitcoin/script_hash.dart';
|
||||
import 'package:cw_core/wallet_addresses.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
part 'electrum_wallet_addresses.g.dart';
|
||||
|
@ -14,13 +13,13 @@ class ElectrumWalletAddresses = ElectrumWalletAddressesBase
|
|||
|
||||
abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||
ElectrumWalletAddressesBase(WalletInfo walletInfo,
|
||||
{@required List<BitcoinAddressRecord> initialAddresses,
|
||||
{required this.mainHd,
|
||||
required this.sideHd,
|
||||
required this.electrumClient,
|
||||
required this.networkType,
|
||||
List<BitcoinAddressRecord>? initialAddresses,
|
||||
int initialRegularAddressIndex = 0,
|
||||
int initialChangeAddressIndex = 0,
|
||||
this.mainHd,
|
||||
this.sideHd,
|
||||
this.electrumClient,
|
||||
this.networkType})
|
||||
int initialChangeAddressIndex = 0})
|
||||
: addresses = ObservableList<BitcoinAddressRecord>.of(
|
||||
(initialAddresses ?? []).toSet()),
|
||||
receiveAddresses = ObservableList<BitcoinAddressRecord>.of(
|
||||
|
@ -31,10 +30,9 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
|||
(initialAddresses ?? [])
|
||||
.where((addressRecord) => addressRecord.isHidden && !addressRecord.isUsed)
|
||||
.toSet()),
|
||||
super(walletInfo) {
|
||||
currentReceiveAddressIndex = initialRegularAddressIndex;
|
||||
currentChangeAddressIndex = initialChangeAddressIndex;
|
||||
}
|
||||
currentReceiveAddressIndex = initialRegularAddressIndex,
|
||||
currentChangeAddressIndex = initialChangeAddressIndex,
|
||||
super(walletInfo);
|
||||
|
||||
static const defaultReceiveAddressesCount = 22;
|
||||
static const defaultChangeAddressesCount = 17;
|
||||
|
@ -124,17 +122,18 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
|||
}
|
||||
|
||||
Future<BitcoinAddressRecord> generateNewAddress(
|
||||
{bool isHidden = false, bitcoin.HDWallet hd}) async {
|
||||
{bitcoin.HDWallet? hd, bool isHidden = false}) async {
|
||||
currentReceiveAddressIndex += 1;
|
||||
// FIX-ME: Check logic for whichi HD should be used here ???
|
||||
final address = BitcoinAddressRecord(
|
||||
getAddress(index: currentReceiveAddressIndex, hd: hd),
|
||||
getAddress(index: currentReceiveAddressIndex, hd: hd ?? sideHd),
|
||||
index: currentReceiveAddressIndex,
|
||||
isHidden: isHidden);
|
||||
addresses.add(address);
|
||||
return address;
|
||||
}
|
||||
|
||||
String getAddress({@required int index, @required bitcoin.HDWallet hd}) => '';
|
||||
String getAddress({required int index, required bitcoin.HDWallet hd}) => '';
|
||||
|
||||
@override
|
||||
Future<void> updateAddressesInBox() async {
|
||||
|
@ -239,7 +238,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
|||
}
|
||||
|
||||
Future<List<BitcoinAddressRecord>> _createNewAddresses(int count,
|
||||
{int startIndex = 0, bitcoin.HDWallet hd, bool isHidden = false}) async {
|
||||
{required bitcoin.HDWallet hd, int startIndex = 0, bool isHidden = false}) async {
|
||||
final list = <BitcoinAddressRecord>[];
|
||||
|
||||
for (var i = startIndex; i < count + startIndex; i++) {
|
||||
|
|
|
@ -6,7 +6,15 @@ import 'package:cw_core/pathForWallet.dart';
|
|||
import 'package:cw_core/wallet_type.dart';
|
||||
|
||||
class ElectrumWallletSnapshot {
|
||||
ElectrumWallletSnapshot(this.name, this.type, this.password);
|
||||
ElectrumWallletSnapshot({
|
||||
required this.name,
|
||||
required this.type,
|
||||
required this.password,
|
||||
required this.mnemonic,
|
||||
required this.addresses,
|
||||
required this.balance,
|
||||
required this.regularAddressIndex,
|
||||
required this.changeAddressIndex});
|
||||
|
||||
final String name;
|
||||
final String password;
|
||||
|
@ -18,28 +26,34 @@ class ElectrumWallletSnapshot {
|
|||
int regularAddressIndex;
|
||||
int changeAddressIndex;
|
||||
|
||||
Future<void> load() async {
|
||||
try {
|
||||
final path = await pathForWallet(name: name, type: type);
|
||||
final jsonSource = await read(path: path, password: password);
|
||||
final data = json.decode(jsonSource) as Map;
|
||||
final addressesTmp = data['addresses'] as List ?? <Object>[];
|
||||
mnemonic = data['mnemonic'] as String;
|
||||
addresses = addressesTmp
|
||||
.whereType<String>()
|
||||
.map((addr) => BitcoinAddressRecord.fromJSON(addr))
|
||||
.toList();
|
||||
balance = ElectrumBalance.fromJSON(data['balance'] as String) ??
|
||||
ElectrumBalance(confirmed: 0, unconfirmed: 0);
|
||||
regularAddressIndex = 0;
|
||||
changeAddressIndex = 0;
|
||||
static Future<ElectrumWallletSnapshot> load(String name, WalletType type, String password) async {
|
||||
final path = await pathForWallet(name: name, type: type);
|
||||
final jsonSource = await read(path: path, password: password);
|
||||
final data = json.decode(jsonSource) as Map;
|
||||
final addressesTmp = data['addresses'] as List? ?? <Object>[];
|
||||
final mnemonic = data['mnemonic'] as String;
|
||||
final addresses = addressesTmp
|
||||
.whereType<String>()
|
||||
.map((addr) => BitcoinAddressRecord.fromJSON(addr))
|
||||
.toList();
|
||||
final balance = ElectrumBalance.fromJSON(data['balance'] as String) ??
|
||||
ElectrumBalance(confirmed: 0, unconfirmed: 0);
|
||||
var regularAddressIndex = 0;
|
||||
var changeAddressIndex = 0;
|
||||
|
||||
try {
|
||||
regularAddressIndex = int.parse(data['account_index'] as String);
|
||||
changeAddressIndex = int.parse(data['change_address_index'] as String);
|
||||
} catch (_) {}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
try {
|
||||
regularAddressIndex = int.parse(data['account_index'] as String? ?? '0');
|
||||
changeAddressIndex = int.parse(data['change_address_index'] as String? ?? '0');
|
||||
} catch (_) {}
|
||||
|
||||
return ElectrumWallletSnapshot(
|
||||
name: name,
|
||||
type: type,
|
||||
password: password,
|
||||
mnemonic: mnemonic,
|
||||
addresses: addresses,
|
||||
balance: balance,
|
||||
regularAddressIndex: regularAddressIndex,
|
||||
changeAddressIndex: changeAddressIndex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import 'dart:io';
|
||||
import 'package:cw_core/key.dart';
|
||||
import 'package:encrypt/encrypt.dart' as encrypt;
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
Future<void> write(
|
||||
{@required String path,
|
||||
@required String password,
|
||||
@required String data}) async {
|
||||
{required String path,
|
||||
required String password,
|
||||
required String data}) async {
|
||||
final keys = extractKeys(password);
|
||||
final key = encrypt.Key.fromBase64(keys.first);
|
||||
final iv = encrypt.IV.fromBase64(keys.last);
|
||||
|
@ -16,9 +15,9 @@ Future<void> write(
|
|||
}
|
||||
|
||||
Future<void> writeData(
|
||||
{@required String path,
|
||||
@required String password,
|
||||
@required String data}) async {
|
||||
{required String path,
|
||||
required String password,
|
||||
required String data}) async {
|
||||
final keys = extractKeys(password);
|
||||
final key = encrypt.Key.fromBase64(keys.first);
|
||||
final iv = encrypt.IV.fromBase64(keys.last);
|
||||
|
@ -27,7 +26,7 @@ Future<void> writeData(
|
|||
f.writeAsStringSync(encrypted);
|
||||
}
|
||||
|
||||
Future<String> read({@required String path, @required String password}) async {
|
||||
Future<String> read({required String path, required String password}) async {
|
||||
final file = File(path);
|
||||
|
||||
if (!file.existsSync()) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
|
||||
import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/unspent_coins_info.dart';
|
||||
import 'package:cw_bitcoin/litecoin_wallet_addresses.dart';
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
|
@ -20,12 +21,13 @@ class LitecoinWallet = LitecoinWalletBase with _$LitecoinWallet;
|
|||
|
||||
abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
||||
LitecoinWalletBase(
|
||||
{@required String mnemonic,
|
||||
@required String password,
|
||||
@required WalletInfo walletInfo,
|
||||
@required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
List<BitcoinAddressRecord> initialAddresses,
|
||||
ElectrumBalance initialBalance,
|
||||
{required String mnemonic,
|
||||
required String password,
|
||||
required WalletInfo walletInfo,
|
||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
required Uint8List seedBytes,
|
||||
List<BitcoinAddressRecord>? initialAddresses,
|
||||
ElectrumBalance? initialBalance,
|
||||
int initialRegularAddressIndex = 0,
|
||||
int initialChangeAddressIndex = 0})
|
||||
: super(
|
||||
|
@ -35,7 +37,9 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
|||
unspentCoinsInfo: unspentCoinsInfo,
|
||||
networkType: litecoinNetwork,
|
||||
initialAddresses: initialAddresses,
|
||||
initialBalance: initialBalance) {
|
||||
initialBalance: initialBalance,
|
||||
seedBytes: seedBytes,
|
||||
currency: CryptoCurrency.ltc) {
|
||||
walletAddresses = LitecoinWalletAddresses(
|
||||
walletInfo,
|
||||
electrumClient: electrumClient,
|
||||
|
@ -44,19 +48,40 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
|||
initialChangeAddressIndex: initialChangeAddressIndex,
|
||||
mainHd: hd,
|
||||
sideHd: bitcoin.HDWallet
|
||||
.fromSeed(mnemonicToSeedBytes(mnemonic), network: networkType)
|
||||
.fromSeed(seedBytes, network: networkType)
|
||||
.derivePath("m/0'/1"),
|
||||
networkType: networkType,);
|
||||
}
|
||||
|
||||
static Future<LitecoinWallet> open({
|
||||
@required String name,
|
||||
@required WalletInfo walletInfo,
|
||||
@required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
@required String password,
|
||||
static Future<LitecoinWallet> create({
|
||||
required String mnemonic,
|
||||
required String password,
|
||||
required WalletInfo walletInfo,
|
||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
List<BitcoinAddressRecord>? initialAddresses,
|
||||
ElectrumBalance? initialBalance,
|
||||
int initialRegularAddressIndex = 0,
|
||||
int initialChangeAddressIndex = 0
|
||||
}) async {
|
||||
final snp = ElectrumWallletSnapshot(name, walletInfo.type, password);
|
||||
await snp.load();
|
||||
return LitecoinWallet(
|
||||
mnemonic: mnemonic,
|
||||
password: password,
|
||||
walletInfo: walletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfo,
|
||||
initialAddresses: initialAddresses,
|
||||
initialBalance: initialBalance,
|
||||
seedBytes: await mnemonicToSeedBytes(mnemonic),
|
||||
initialRegularAddressIndex: initialRegularAddressIndex,
|
||||
initialChangeAddressIndex: initialChangeAddressIndex);
|
||||
}
|
||||
|
||||
static Future<LitecoinWallet> open({
|
||||
required String name,
|
||||
required WalletInfo walletInfo,
|
||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||
required String password,
|
||||
}) async {
|
||||
final snp = await ElectrumWallletSnapshot.load (name, walletInfo.type, password);
|
||||
return LitecoinWallet(
|
||||
mnemonic: snp.mnemonic,
|
||||
password: password,
|
||||
|
@ -64,6 +89,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
|
|||
unspentCoinsInfo: unspentCoinsInfo,
|
||||
initialAddresses: snp.addresses,
|
||||
initialBalance: snp.balance,
|
||||
seedBytes: await mnemonicToSeedBytes(snp.mnemonic),
|
||||
initialRegularAddressIndex: snp.regularAddressIndex,
|
||||
initialChangeAddressIndex: snp.changeAddressIndex);
|
||||
}
|
||||
|
|
|
@ -16,13 +16,13 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses
|
|||
with Store {
|
||||
LitecoinWalletAddressesBase(
|
||||
WalletInfo walletInfo,
|
||||
{@required List<BitcoinAddressRecord> initialAddresses,
|
||||
{required bitcoin.HDWallet mainHd,
|
||||
required bitcoin.HDWallet sideHd,
|
||||
required bitcoin.NetworkType networkType,
|
||||
required ElectrumClient electrumClient,
|
||||
List<BitcoinAddressRecord>? initialAddresses,
|
||||
int initialRegularAddressIndex = 0,
|
||||
int initialChangeAddressIndex = 0,
|
||||
ElectrumClient electrumClient,
|
||||
@required bitcoin.HDWallet mainHd,
|
||||
@required bitcoin.HDWallet sideHd,
|
||||
@required bitcoin.NetworkType networkType})
|
||||
int initialChangeAddressIndex = 0})
|
||||
: super(
|
||||
walletInfo,
|
||||
initialAddresses: initialAddresses,
|
||||
|
@ -34,6 +34,6 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses
|
|||
networkType: networkType);
|
||||
|
||||
@override
|
||||
String getAddress({@required int index, @required bitcoin.HDWallet hd}) =>
|
||||
String getAddress({required int index, required bitcoin.HDWallet hd}) =>
|
||||
generateP2WPKHAddress(hd: hd, index: index, networkType: networkType);
|
||||
}
|
|
@ -10,6 +10,7 @@ import 'package:cw_core/pathForWallet.dart';
|
|||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
class LitecoinWalletService extends WalletService<
|
||||
BitcoinNewWalletCredentials,
|
||||
|
@ -25,10 +26,10 @@ class LitecoinWalletService extends WalletService<
|
|||
|
||||
@override
|
||||
Future<LitecoinWallet> create(BitcoinNewWalletCredentials credentials) async {
|
||||
final wallet = LitecoinWallet(
|
||||
final wallet = await LitecoinWalletBase.create(
|
||||
mnemonic: await generateMnemonic(),
|
||||
password: credentials.password,
|
||||
walletInfo: credentials.walletInfo,
|
||||
password: credentials.password!,
|
||||
walletInfo: credentials.walletInfo!,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
await wallet.save();
|
||||
await wallet.init();
|
||||
|
@ -42,9 +43,8 @@ class LitecoinWalletService extends WalletService<
|
|||
|
||||
@override
|
||||
Future<LitecoinWallet> openWallet(String name, String password) async {
|
||||
final walletInfo = walletInfoSource.values.firstWhere(
|
||||
(info) => info.id == WalletBase.idFor(name, getType()),
|
||||
orElse: () => null);
|
||||
final walletInfo = walletInfoSource.values.firstWhereOrNull(
|
||||
(info) => info.id == WalletBase.idFor(name, getType()))!;
|
||||
final wallet = await LitecoinWalletBase.open(
|
||||
password: password, name: name, walletInfo: walletInfo,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
|
@ -69,10 +69,10 @@ class LitecoinWalletService extends WalletService<
|
|||
throw BitcoinMnemonicIsIncorrectException();
|
||||
}
|
||||
|
||||
final wallet = LitecoinWallet(
|
||||
password: credentials.password,
|
||||
final wallet = await LitecoinWalletBase.create(
|
||||
password: credentials.password!,
|
||||
mnemonic: credentials.mnemonic,
|
||||
walletInfo: credentials.walletInfo,
|
||||
walletInfo: credentials.walletInfo!,
|
||||
unspentCoinsInfo: unspentCoinsInfoSource);
|
||||
await wallet.save();
|
||||
await wallet.init();
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:cw_bitcoin/bitcoin_commit_transaction_exception.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
|
||||
import 'package:cw_core/pending_transaction.dart';
|
||||
import 'package:cw_bitcoin/electrum.dart';
|
||||
|
@ -10,9 +9,9 @@ import 'package:cw_core/wallet_type.dart';
|
|||
|
||||
class PendingBitcoinTransaction with PendingTransaction {
|
||||
PendingBitcoinTransaction(this._tx, this.type,
|
||||
{@required this.electrumClient,
|
||||
@required this.amount,
|
||||
@required this.fee})
|
||||
{required this.electrumClient,
|
||||
required this.amount,
|
||||
required this.fee})
|
||||
: _listeners = <void Function(ElectrumTransactionInfo transaction)>[];
|
||||
|
||||
final WalletType type;
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
|
||||
import 'package:crypto/crypto.dart';
|
||||
|
||||
String scriptHash(String address, {@required bitcoin.NetworkType networkType}) {
|
||||
String scriptHash(String address, {required bitcoin.NetworkType networkType}) {
|
||||
final outputScript =
|
||||
bitcoin.Address.addressToOutputScript(address, networkType);
|
||||
final parts = sha256.convert(outputScript).toString().split('');
|
||||
|
|
|
@ -5,51 +5,51 @@ import 'package:bitcoin_flutter/src/payments/index.dart' show PaymentData;
|
|||
import 'package:hex/hex.dart';
|
||||
|
||||
bitcoin.PaymentData generatePaymentData(
|
||||
{@required bitcoin.HDWallet hd, @required int index}) =>
|
||||
{required bitcoin.HDWallet hd, required int index}) =>
|
||||
PaymentData(
|
||||
pubkey: Uint8List.fromList(HEX.decode(hd.derive(index).pubKey)));
|
||||
pubkey: Uint8List.fromList(HEX.decode(hd.derive(index).pubKey!)));
|
||||
|
||||
bitcoin.ECPair generateKeyPair(
|
||||
{@required bitcoin.HDWallet hd,
|
||||
@required int index,
|
||||
bitcoin.NetworkType network}) =>
|
||||
bitcoin.ECPair.fromWIF(hd.derive(index).wif, network: network);
|
||||
{required bitcoin.HDWallet hd,
|
||||
required int index,
|
||||
required bitcoin.NetworkType network}) =>
|
||||
bitcoin.ECPair.fromWIF(hd.derive(index).wif!, network: network);
|
||||
|
||||
String generateP2WPKHAddress(
|
||||
{@required bitcoin.HDWallet hd,
|
||||
@required int index,
|
||||
bitcoin.NetworkType networkType}) =>
|
||||
{required bitcoin.HDWallet hd,
|
||||
required int index,
|
||||
required bitcoin.NetworkType networkType}) =>
|
||||
bitcoin
|
||||
.P2WPKH(
|
||||
data: PaymentData(
|
||||
pubkey:
|
||||
Uint8List.fromList(HEX.decode(hd.derive(index).pubKey))),
|
||||
Uint8List.fromList(HEX.decode(hd.derive(index).pubKey!))),
|
||||
network: networkType)
|
||||
.data
|
||||
.address;
|
||||
.address!;
|
||||
|
||||
String generateP2WPKHAddressByPath(
|
||||
{@required bitcoin.HDWallet hd,
|
||||
@required String path,
|
||||
bitcoin.NetworkType networkType}) =>
|
||||
{required bitcoin.HDWallet hd,
|
||||
required String path,
|
||||
required bitcoin.NetworkType networkType}) =>
|
||||
bitcoin
|
||||
.P2WPKH(
|
||||
data: PaymentData(
|
||||
pubkey:
|
||||
Uint8List.fromList(HEX.decode(hd.derivePath(path).pubKey))),
|
||||
Uint8List.fromList(HEX.decode(hd.derivePath(path).pubKey!))),
|
||||
network: networkType)
|
||||
.data
|
||||
.address;
|
||||
.address!;
|
||||
|
||||
String generateP2PKHAddress(
|
||||
{@required bitcoin.HDWallet hd,
|
||||
@required int index,
|
||||
bitcoin.NetworkType networkType}) =>
|
||||
{required bitcoin.HDWallet hd,
|
||||
required int index,
|
||||
required bitcoin.NetworkType networkType}) =>
|
||||
bitcoin
|
||||
.P2PKH(
|
||||
data: PaymentData(
|
||||
pubkey:
|
||||
Uint8List.fromList(HEX.decode(hd.derive(index).pubKey))),
|
||||
Uint8List.fromList(HEX.decode(hd.derive(index).pubKey!))),
|
||||
network: networkType)
|
||||
.data
|
||||
.address;
|
||||
.address!;
|
||||
|
|
|
@ -7,64 +7,64 @@ packages:
|
|||
name: _fe_analyzer_shared
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "14.0.0"
|
||||
version: "47.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.41.2"
|
||||
version: "4.7.0"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.0"
|
||||
version: "2.3.1"
|
||||
asn1lib:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: asn1lib
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.6.5"
|
||||
version: "1.1.1"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.5.0"
|
||||
version: "2.9.0"
|
||||
bech32:
|
||||
dependency: transitive
|
||||
description:
|
||||
path: "."
|
||||
ref: cake
|
||||
resolved-ref: "02fef082f20af13de00b4e64efb93a2c1e5e1cf2"
|
||||
ref: "cake-0.2.1"
|
||||
resolved-ref: cafd1c270641e95017d57d69f55cca9831d4db56
|
||||
url: "https://github.com/cake-tech/bech32.git"
|
||||
source: git
|
||||
version: "0.2.0"
|
||||
version: "0.2.1"
|
||||
bip32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: bip32
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.7"
|
||||
version: "2.0.0"
|
||||
bip39:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: bip39
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
version: "1.0.6"
|
||||
bitcoin_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: cake
|
||||
resolved-ref: cbabfd87b6ce3cae6051a3e86ddb56e7a934e188
|
||||
ref: cake-update-v2
|
||||
resolved-ref: "8f86453761c0c26e368392d0ff2c6f12f3b7397b"
|
||||
url: "https://github.com/cake-tech/bitcoin_flutter.git"
|
||||
source: git
|
||||
version: "2.0.2"
|
||||
|
@ -81,133 +81,119 @@ packages:
|
|||
name: bs58check
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
version: "1.0.2"
|
||||
build:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.2"
|
||||
version: "2.3.1"
|
||||
build_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.6"
|
||||
version: "1.1.0"
|
||||
build_daemon:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_daemon
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.10"
|
||||
version: "3.1.0"
|
||||
build_resolvers:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_resolvers
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.5.3"
|
||||
version: "2.0.10"
|
||||
build_runner:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_runner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.11.5"
|
||||
version: "2.2.1"
|
||||
build_runner_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_runner_core
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.10"
|
||||
version: "7.2.4"
|
||||
built_collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: built_collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.3.2"
|
||||
version: "5.1.1"
|
||||
built_value:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: built_value
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "7.1.0"
|
||||
version: "8.4.1"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.2.1"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: checked_yaml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
cli_util:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cli_util
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.5"
|
||||
version: "2.0.1"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
code_builder:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: code_builder
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.7.0"
|
||||
version: "4.3.0"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.15.0"
|
||||
version: "1.16.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "3.0.2"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
version: "3.0.2"
|
||||
cryptography:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: cryptography
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
version: "2.0.5"
|
||||
cw_core:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -221,35 +207,28 @@ packages:
|
|||
name: dart_style
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.12"
|
||||
dartx:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dartx
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.5.0"
|
||||
version: "2.2.4"
|
||||
encrypt:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: encrypt
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.3"
|
||||
version: "5.0.1"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.3.1"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffi
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
version: "2.0.1"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -263,7 +242,7 @@ packages:
|
|||
name: fixnum
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.10.11"
|
||||
version: "1.0.1"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
|
@ -275,12 +254,19 @@ packages:
|
|||
name: flutter_mobx
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0+2"
|
||||
version: "2.0.6+4"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
frontend_server_client:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: frontend_server_client
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -294,49 +280,49 @@ packages:
|
|||
name: graphs
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
version: "2.1.0"
|
||||
hex:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: hex
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.2"
|
||||
version: "0.2.0"
|
||||
hive:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: hive
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.4+1"
|
||||
version: "2.2.3"
|
||||
hive_generator:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: hive_generator
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.8.2"
|
||||
version: "1.1.3"
|
||||
http:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.2"
|
||||
version: "0.13.5"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
version: "3.2.1"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.4"
|
||||
version: "4.0.1"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -350,7 +336,7 @@ packages:
|
|||
name: io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.5"
|
||||
version: "1.0.3"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -364,7 +350,7 @@ packages:
|
|||
name: json_annotation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.1"
|
||||
version: "4.7.0"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -378,14 +364,21 @@ packages:
|
|||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.10"
|
||||
version: "0.12.12"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.5"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "1.8.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -399,63 +392,77 @@ packages:
|
|||
name: mobx
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.1+4"
|
||||
version: "2.1.0"
|
||||
mobx_codegen:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: mobx_codegen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
version: "2.0.7+3"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.3"
|
||||
version: "2.1.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
version: "1.8.2"
|
||||
path_provider:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: path_provider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.28"
|
||||
version: "2.0.11"
|
||||
path_provider_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.20"
|
||||
path_provider_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_ios
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.11"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.1+2"
|
||||
version: "2.1.7"
|
||||
path_provider_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_macos
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.4+8"
|
||||
version: "2.0.6"
|
||||
path_provider_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
version: "2.0.5"
|
||||
path_provider_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.5"
|
||||
version: "2.1.3"
|
||||
pedantic:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -476,14 +483,14 @@ packages:
|
|||
name: plugin_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
version: "2.1.3"
|
||||
pointycastle:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pointycastle
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
version: "3.6.2"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -511,35 +518,28 @@ packages:
|
|||
name: pubspec_parse
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.8"
|
||||
quiver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quiver
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
version: "1.2.1"
|
||||
rxdart:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: rxdart
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.26.0"
|
||||
version: "0.27.5"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.7.9"
|
||||
version: "1.4.0"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.4+1"
|
||||
version: "1.0.2"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
|
@ -551,14 +551,21 @@ packages:
|
|||
name: source_gen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.10+3"
|
||||
version: "1.2.5"
|
||||
source_helper:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_helper
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.3"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
version: "1.9.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -586,35 +593,28 @@ packages:
|
|||
name: string_scanner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.2.1"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.19"
|
||||
time:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: time
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
version: "0.4.12"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: timing
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.1+3"
|
||||
version: "1.0.0"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -635,7 +635,7 @@ packages:
|
|||
name: vector_math
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.2"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -649,21 +649,21 @@ packages:
|
|||
name: web_socket_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "2.2.0"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.5"
|
||||
version: "3.0.0"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xdg_directories
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.2"
|
||||
version: "0.2.0+2"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -672,5 +672,5 @@ packages:
|
|||
source: hosted
|
||||
version: "3.1.0"
|
||||
sdks:
|
||||
dart: ">=2.12.0 <3.0.0"
|
||||
flutter: ">=1.20.0"
|
||||
dart: ">=2.17.5 <3.0.0"
|
||||
flutter: ">=3.0.0"
|
||||
|
|
|
@ -6,35 +6,35 @@ author: Cake Wallet
|
|||
homepage: https://cakewallet.com
|
||||
|
||||
environment:
|
||||
sdk: ">=2.7.0 <3.0.0"
|
||||
flutter: ">=1.17.0"
|
||||
sdk: ">=2.17.5 <3.0.0"
|
||||
flutter: ">=1.20.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
path_provider: ^1.4.0
|
||||
http: ^0.12.0+2
|
||||
mobx: ^1.2.1+2
|
||||
flutter_mobx: ^1.1.0+2
|
||||
path_provider: ^2.0.11
|
||||
http: ^0.13.4
|
||||
mobx: ^2.0.7+4
|
||||
flutter_mobx: ^2.0.6+1
|
||||
intl: ^0.17.0
|
||||
cw_core:
|
||||
path: ../cw_core
|
||||
bitcoin_flutter:
|
||||
git:
|
||||
url: https://github.com/cake-tech/bitcoin_flutter.git
|
||||
ref: cake
|
||||
rxdart: ^0.26.0
|
||||
ref: cake-update-v2
|
||||
rxdart: ^0.27.5
|
||||
unorm_dart: ^0.2.0
|
||||
cryptography: ^1.4.0
|
||||
encrypt: ^4.0.0
|
||||
cryptography: ^2.0.5
|
||||
encrypt: ^5.0.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
build_runner: ^1.10.3
|
||||
build_resolvers: ^1.3.10
|
||||
mobx_codegen: ^1.1.0+1
|
||||
hive_generator: ^0.8.1
|
||||
build_runner: ^2.1.11
|
||||
build_resolvers: ^2.0.9
|
||||
mobx_codegen: ^2.0.7
|
||||
hive_generator: ^1.1.3
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class Account {
|
||||
Account({this.id, this.label});
|
||||
Account({required this.id, required this.label});
|
||||
|
||||
Account.fromMap(Map map)
|
||||
Account.fromMap(Map<String, Object> map)
|
||||
: this.id = map['id'] == null ? 0 : int.parse(map['id'] as String),
|
||||
this.label = (map['label'] ?? '') as String;
|
||||
|
||||
|
|
|
@ -8,9 +8,9 @@ abstract class AccountList<T> {
|
|||
|
||||
List<T> getAll();
|
||||
|
||||
Future addAccount({String label});
|
||||
Future<void> addAccount({required String label});
|
||||
|
||||
Future setLabelAccount({int accountIndex, String label});
|
||||
Future<void> setLabelAccount({required int accountIndex, required String label});
|
||||
|
||||
void refresh();
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ class AmountConverter {
|
|||
case CryptoCurrency.xusd:
|
||||
return _moneroAmountToDouble(amount);
|
||||
default:
|
||||
return null;
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ class AmountConverter {
|
|||
case CryptoCurrency.xusd:
|
||||
return _moneroParseAmount(amount);
|
||||
default:
|
||||
return null;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,11 +97,11 @@ class AmountConverter {
|
|||
case CryptoCurrency.xusd:
|
||||
return _moneroAmountToString(amount);
|
||||
default:
|
||||
return null;
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
static double cryptoAmountToDouble({num amount, num divider}) =>
|
||||
static double cryptoAmountToDouble({required num amount, required num divider}) =>
|
||||
amount / divider;
|
||||
|
||||
static String _moneroAmountToString(int amount) => _moneroAmountFormat.format(
|
|
@ -1 +1 @@
|
|||
double cryptoAmountToDouble({num amount, num divider}) => amount / divider;
|
||||
double cryptoAmountToDouble({required num amount, required num divider}) => amount / divider;
|
|
@ -5,12 +5,17 @@ part 'crypto_currency.g.dart';
|
|||
|
||||
@HiveType(typeId: 0)
|
||||
class CryptoCurrency extends EnumerableItem<int> with Serializable<int> {
|
||||
const CryptoCurrency({final String title, this.tag, this.name, this.iconPath, final int raw})
|
||||
const CryptoCurrency({
|
||||
String title = '',
|
||||
int raw = -1,
|
||||
this.name,
|
||||
this.iconPath,
|
||||
this.tag,})
|
||||
: super(title: title, raw: raw);
|
||||
|
||||
final String tag;
|
||||
final String name;
|
||||
final String iconPath;
|
||||
final String? tag;
|
||||
final String? name;
|
||||
final String? iconPath;
|
||||
|
||||
static const all = [
|
||||
CryptoCurrency.xmr,
|
||||
|
@ -23,16 +28,49 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> {
|
|||
CryptoCurrency.eos,
|
||||
CryptoCurrency.eth,
|
||||
CryptoCurrency.ltc,
|
||||
CryptoCurrency.nano,
|
||||
CryptoCurrency.trx,
|
||||
CryptoCurrency.usdt,
|
||||
CryptoCurrency.usdterc20,
|
||||
CryptoCurrency.xlm,
|
||||
CryptoCurrency.xrp,
|
||||
CryptoCurrency.xhv,
|
||||
//CryptoCurrency.zaddr,
|
||||
//CryptoCurrency.zec
|
||||
CryptoCurrency.ape,
|
||||
CryptoCurrency.avaxc,
|
||||
CryptoCurrency.btt,
|
||||
CryptoCurrency.bttbsc,
|
||||
CryptoCurrency.doge,
|
||||
CryptoCurrency.firo,
|
||||
CryptoCurrency.usdttrc20,
|
||||
CryptoCurrency.hbar,
|
||||
CryptoCurrency.sc,
|
||||
CryptoCurrency.sol,
|
||||
CryptoCurrency.usdc,
|
||||
CryptoCurrency.usdcsol,
|
||||
CryptoCurrency.zaddr,
|
||||
CryptoCurrency.zec,
|
||||
CryptoCurrency.zen,
|
||||
CryptoCurrency.xvg,
|
||||
CryptoCurrency.usdcpoly,
|
||||
CryptoCurrency.dcr,
|
||||
CryptoCurrency.husd,
|
||||
CryptoCurrency.kmd,
|
||||
CryptoCurrency.mana,
|
||||
CryptoCurrency.maticpoly,
|
||||
CryptoCurrency.matic,
|
||||
CryptoCurrency.mkr,
|
||||
CryptoCurrency.near,
|
||||
CryptoCurrency.oxt,
|
||||
CryptoCurrency.paxg,
|
||||
CryptoCurrency.pivx,
|
||||
CryptoCurrency.rune,
|
||||
CryptoCurrency.rvn,
|
||||
CryptoCurrency.scrt,
|
||||
CryptoCurrency.uni,
|
||||
CryptoCurrency.stx,
|
||||
];
|
||||
static const xmr = CryptoCurrency(title: 'XMR', iconPath: 'assets/images/monero_icon.png', name: 'Monero', raw: 0);
|
||||
|
||||
static const xmr = CryptoCurrency(title: 'XMR', iconPath: 'assets/images/monero_icon.png', name: 'Monero', raw: 0);
|
||||
static const ada = CryptoCurrency(title: 'ADA', iconPath: 'assets/images/ada_icon.png', name: 'Cardano', raw: 1);
|
||||
static const bch = CryptoCurrency(title: 'BCH', iconPath: 'assets/images/bch_icon.png',name: 'Bitcoin Cash', raw: 2);
|
||||
static const bnb = CryptoCurrency(title: 'BNB', iconPath: 'assets/images/bnb_icon.png', tag: 'BSC', name: 'Binance Coin', raw: 3);
|
||||
|
@ -41,7 +79,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> {
|
|||
static const dash = CryptoCurrency(title: 'DASH', iconPath: 'assets/images/dash_icon.png', name: 'Dash', raw: 6);
|
||||
static const eos = CryptoCurrency(title: 'EOS', iconPath: 'assets/images/eos_icon.png', name: 'EOS', raw: 7);
|
||||
static const eth = CryptoCurrency(title: 'ETH', iconPath: 'assets/images/eth_icon.png', name: 'Ethereum', raw: 8);
|
||||
static const ltc = CryptoCurrency(title: 'LTC', iconPath: 'assets/images/litecoin-ltc_icon.png', name: 'Litecoin',raw: 9);
|
||||
static const ltc = CryptoCurrency(title: 'LTC', iconPath: 'assets/images/litecoin-ltc_icon.png', name: 'Litecoin', raw: 9);
|
||||
static const nano = CryptoCurrency(title: 'NANO', raw: 10);
|
||||
static const trx = CryptoCurrency(title: 'TRX', iconPath: 'assets/images/trx_icon.png', name: 'TRON', raw: 11);
|
||||
static const usdt = CryptoCurrency(title: 'USDT', iconPath: 'assets/images/usdt_icon.png', tag: 'OMNI', name: 'USDT', raw: 12);
|
||||
|
@ -64,10 +102,44 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> {
|
|||
static const xnzd = CryptoCurrency(title: 'XNZD', tag: 'XHV', raw: 28);
|
||||
static const xusd = CryptoCurrency(title: 'XUSD', tag: 'XHV', raw: 29);
|
||||
|
||||
static const zaddr = CryptoCurrency(title: 'ZZEC', tag: 'ZEC', name: 'Shielded Zcash', iconPath: 'assets/images/zaddr_icon.png', raw: 30);
|
||||
static const zec = CryptoCurrency(title: 'TZEC', tag: 'ZEC', name: 'Transparent Zcash', iconPath: 'assets/images/zec_icon.png', raw: 31);
|
||||
static const ape = CryptoCurrency(title: 'APE', iconPath: 'assets/images/ape_icon.png', tag: 'ETH', raw: 30);
|
||||
static const avaxc = CryptoCurrency(title: 'AVAX', iconPath: 'assets/images/avaxc_icon.png', tag: 'C-CHAIN', raw: 31);
|
||||
static const btt = CryptoCurrency(title: 'BTT', iconPath: 'assets/images/btt_icon.png', raw: 32);
|
||||
static const bttbsc = CryptoCurrency(title: 'BTT', iconPath: 'assets/images/bttbsc_icon.png', tag: 'BSC', raw: 33);
|
||||
static const doge = CryptoCurrency(title: 'DOGE', iconPath: 'assets/images/doge_icon.png', raw: 34);
|
||||
static const firo = CryptoCurrency(title: 'FIRO', iconPath: 'assets/images/firo_icon.png', raw: 35);
|
||||
static const usdttrc20 = CryptoCurrency(title: 'USDT', iconPath: 'assets/images/usdttrc20_icon.png', tag: 'TRX', raw: 36);
|
||||
static const hbar = CryptoCurrency(title: 'HBAR', iconPath: 'assets/images/hbar_icon.png', raw: 37);
|
||||
static const sc = CryptoCurrency(title: 'SC', iconPath: 'assets/images/sc_icon.png', raw: 38);
|
||||
static const sol = CryptoCurrency(title: 'SOL', iconPath: 'assets/images/sol_icon.png', raw: 39);
|
||||
static const usdc = CryptoCurrency(title: 'USDC', iconPath: 'assets/images/usdc_icon.png', tag: 'ETH', raw: 40);
|
||||
static const usdcsol = CryptoCurrency(title: 'USDC', iconPath: 'assets/images/usdcsol_icon.png', tag: 'SOL', raw: 41);
|
||||
static const zaddr = CryptoCurrency(title: 'ZZEC', tag: 'ZEC', name: 'Shielded Zcash', iconPath: 'assets/images/zaddr_icon.png', raw: 42);
|
||||
static const zec = CryptoCurrency(title: 'TZEC', tag: 'ZEC', name: 'Transparent Zcash', iconPath: 'assets/images/zec_icon.png', raw: 43);
|
||||
static const zen = CryptoCurrency(title: 'ZEN', iconPath: 'assets/images/zen_icon.png', raw: 44);
|
||||
static const xvg = CryptoCurrency(title: 'XVG', name: 'Verge', iconPath: 'assets/images/xvg_icon.png', raw: 45);
|
||||
|
||||
static CryptoCurrency deserialize({int raw}) {
|
||||
static const usdcpoly = CryptoCurrency(title: 'USDC', iconPath: 'assets/images/usdc_icon.png', tag: 'POLY', raw: 46);
|
||||
static const dcr = CryptoCurrency(title: 'DCR', iconPath: 'assets/images/dcr_icon.png', raw: 47);
|
||||
static const husd = CryptoCurrency(title: 'HUSD', iconPath: 'assets/images/husd_icon.png', tag: 'ETH', raw: 48);
|
||||
static const kmd = CryptoCurrency(title: 'KMD', iconPath: 'assets/images/kmd_icon.png', raw: 49);
|
||||
static const mana = CryptoCurrency(title: 'MANA', iconPath: 'assets/images/mana_icon.png', tag: 'ETH', raw: 50);
|
||||
static const maticpoly = CryptoCurrency(title: 'MATIC', iconPath: 'assets/images/matic_icon.png', tag: 'POLY', raw: 51);
|
||||
static const matic = CryptoCurrency(title: 'MATIC', iconPath: 'assets/images/matic_icon.png', tag: 'ETH', raw: 52);
|
||||
static const mkr = CryptoCurrency(title: 'MKR', iconPath: 'assets/images/mkr_icon.png', tag: 'ETH', raw: 53);
|
||||
static const near = CryptoCurrency(title: 'NEAR', iconPath: 'assets/images/near_icon.png', raw: 54);
|
||||
static const oxt = CryptoCurrency(title: 'OXT', iconPath: 'assets/images/oxt_icon.png', tag: 'ETH', raw: 55);
|
||||
static const paxg = CryptoCurrency(title: 'PAXG', iconPath: 'assets/images/paxg_icon.png', tag: 'ETH', raw: 56);
|
||||
static const pivx = CryptoCurrency(title: 'PIVX', iconPath: 'assets/images/pivx_icon.png', raw: 57);
|
||||
static const rune = CryptoCurrency(title: 'RUNE', iconPath: 'assets/images/rune_icon.png', raw: 58);
|
||||
static const rvn = CryptoCurrency(title: 'RVN', iconPath: 'assets/images/rvn_icon.png', raw: 59);
|
||||
static const scrt = CryptoCurrency(title: 'SCRT', iconPath: 'assets/images/scrt_icon.png', raw: 60);
|
||||
static const uni = CryptoCurrency(title: 'UNI', iconPath: 'assets/images/uni_icon.png', tag: 'ETH', raw: 61);
|
||||
static const stx = CryptoCurrency(title: 'STX', iconPath: 'assets/images/stx_icon.png', raw: 62);
|
||||
|
||||
|
||||
|
||||
static CryptoCurrency deserialize({required int raw}) {
|
||||
switch (raw) {
|
||||
case 0:
|
||||
return CryptoCurrency.xmr;
|
||||
|
@ -130,11 +202,73 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> {
|
|||
case 29:
|
||||
return CryptoCurrency.xusd;
|
||||
case 30:
|
||||
return CryptoCurrency.zaddr;
|
||||
return CryptoCurrency.ape;
|
||||
case 31:
|
||||
return CryptoCurrency.avaxc;
|
||||
case 32:
|
||||
return CryptoCurrency.btt;
|
||||
case 33:
|
||||
return CryptoCurrency.bttbsc;
|
||||
case 34:
|
||||
return CryptoCurrency.doge;
|
||||
case 35:
|
||||
return CryptoCurrency.firo;
|
||||
case 36:
|
||||
return CryptoCurrency.usdttrc20;
|
||||
case 37:
|
||||
return CryptoCurrency.hbar;
|
||||
case 38:
|
||||
return CryptoCurrency.sc;
|
||||
case 39:
|
||||
return CryptoCurrency.sol;
|
||||
case 40:
|
||||
return CryptoCurrency.usdc;
|
||||
case 41:
|
||||
return CryptoCurrency.usdcsol;
|
||||
case 42:
|
||||
return CryptoCurrency.zaddr;
|
||||
case 43:
|
||||
return CryptoCurrency.zec;
|
||||
case 44:
|
||||
return CryptoCurrency.zen;
|
||||
case 45:
|
||||
return CryptoCurrency.xvg;
|
||||
case 46:
|
||||
return CryptoCurrency.usdcpoly;
|
||||
case 47:
|
||||
return CryptoCurrency.dcr;
|
||||
case 48:
|
||||
return CryptoCurrency.husd;
|
||||
case 49:
|
||||
return CryptoCurrency.kmd;
|
||||
case 50:
|
||||
return CryptoCurrency.mana;
|
||||
case 51:
|
||||
return CryptoCurrency.maticpoly;
|
||||
case 52:
|
||||
return CryptoCurrency.matic;
|
||||
case 53:
|
||||
return CryptoCurrency.mkr;
|
||||
case 54:
|
||||
return CryptoCurrency.near;
|
||||
case 55:
|
||||
return CryptoCurrency.oxt;
|
||||
case 56:
|
||||
return CryptoCurrency.paxg;
|
||||
case 57:
|
||||
return CryptoCurrency.pivx;
|
||||
case 58:
|
||||
return CryptoCurrency.rune;
|
||||
case 59:
|
||||
return CryptoCurrency.rvn;
|
||||
case 60:
|
||||
return CryptoCurrency.scrt;
|
||||
case 61:
|
||||
return CryptoCurrency.uni;
|
||||
case 62:
|
||||
return CryptoCurrency.stx;
|
||||
default:
|
||||
return null;
|
||||
throw Exception('Unexpected token: $raw for CryptoCurrency deserialize');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,8 +298,8 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> {
|
|||
return CryptoCurrency.nano;
|
||||
case 'trx':
|
||||
return CryptoCurrency.trx;
|
||||
case 'usdt':
|
||||
return CryptoCurrency.usdt;
|
||||
case 'usdc':
|
||||
return CryptoCurrency.usdc;
|
||||
case 'usdterc20':
|
||||
return CryptoCurrency.usdterc20;
|
||||
case 'xlm':
|
||||
|
@ -200,12 +334,74 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> {
|
|||
return CryptoCurrency.xnzd;
|
||||
case 'xusd':
|
||||
return CryptoCurrency.xusd;
|
||||
case 'ape':
|
||||
return CryptoCurrency.ape;
|
||||
case 'avax':
|
||||
return CryptoCurrency.avaxc;
|
||||
case 'btt':
|
||||
return CryptoCurrency.btt;
|
||||
case 'bttbsc':
|
||||
return CryptoCurrency.bttbsc;
|
||||
case 'doge':
|
||||
return CryptoCurrency.doge;
|
||||
case 'firo':
|
||||
return CryptoCurrency.firo;
|
||||
case 'usdttrc20':
|
||||
return CryptoCurrency.usdttrc20;
|
||||
case 'hbar':
|
||||
return CryptoCurrency.hbar;
|
||||
case 'sc':
|
||||
return CryptoCurrency.sc;
|
||||
case 'sol':
|
||||
return CryptoCurrency.sol;
|
||||
case 'usdt':
|
||||
return CryptoCurrency.usdt;
|
||||
case 'usdcsol':
|
||||
return CryptoCurrency.usdcsol;
|
||||
case 'zaddr':
|
||||
return CryptoCurrency.zaddr;
|
||||
case 'zec':
|
||||
return CryptoCurrency.zec;
|
||||
case 'zen':
|
||||
return CryptoCurrency.zen;
|
||||
case 'xvg':
|
||||
return CryptoCurrency.xvg;
|
||||
case 'usdcpoly':
|
||||
return CryptoCurrency.usdcpoly;
|
||||
case 'dcr':
|
||||
return CryptoCurrency.dcr;
|
||||
case 'husd':
|
||||
return CryptoCurrency.husd;
|
||||
case 'kmd':
|
||||
return CryptoCurrency.kmd;
|
||||
case 'mana':
|
||||
return CryptoCurrency.mana;
|
||||
case 'maticpoly':
|
||||
return CryptoCurrency.maticpoly;
|
||||
case 'matic':
|
||||
return CryptoCurrency.matic;
|
||||
case 'mkr':
|
||||
return CryptoCurrency.mkr;
|
||||
case 'near':
|
||||
return CryptoCurrency.near;
|
||||
case 'oxt':
|
||||
return CryptoCurrency.oxt;
|
||||
case 'paxg':
|
||||
return CryptoCurrency.paxg;
|
||||
case 'pivx':
|
||||
return CryptoCurrency.pivx;
|
||||
case 'rune':
|
||||
return CryptoCurrency.rune;
|
||||
case 'rvn':
|
||||
return CryptoCurrency.rvn;
|
||||
case 'scrt':
|
||||
return CryptoCurrency.scrt;
|
||||
case 'uni':
|
||||
return CryptoCurrency.uni;
|
||||
case 'stx':
|
||||
return CryptoCurrency.stx;
|
||||
default:
|
||||
return null;
|
||||
throw Exception('Unexpected token: $raw for CryptoCurrency fromString');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,6 @@ CryptoCurrency currencyForWalletType(WalletType type) {
|
|||
case WalletType.haven:
|
||||
return CryptoCurrency.xhv;
|
||||
default:
|
||||
return null;
|
||||
throw Exception('Unexpected wallet type: ${type.toString()} for CryptoCurrency currencyForWalletType');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
|
||||
abstract class EnumerableItem<T> {
|
||||
const EnumerableItem({@required this.title, @required this.raw});
|
||||
const EnumerableItem({required this.title, required this.raw});
|
||||
|
||||
final T raw;
|
||||
final String title;
|
||||
|
@ -11,6 +11,6 @@ abstract class EnumerableItem<T> {
|
|||
}
|
||||
|
||||
mixin Serializable<T> on EnumerableItem<T> {
|
||||
static Serializable deserialize<T>({T raw}) => null;
|
||||
static Serializable deserialize<T>({required T raw}) => throw Exception('Unimplemented');
|
||||
T serialize() => raw;
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ final dates = {
|
|||
"2020-11": 2220000
|
||||
};
|
||||
|
||||
int getMoneroHeigthByDate({DateTime date}) {
|
||||
int getMoneroHeigthByDate({required DateTime date}) {
|
||||
final raw = '${date.year}' + '-' + '${date.month}';
|
||||
final lastHeight = dates.values.last;
|
||||
int startHeight;
|
||||
|
@ -105,7 +105,7 @@ int getMoneroHeigthByDate({DateTime date}) {
|
|||
final daysHeight = (differenceInDays * heightPerDay).round();
|
||||
height = endHeight + daysHeight;
|
||||
} else {
|
||||
startHeight = dates[raw];
|
||||
startHeight = dates[raw]!;
|
||||
final index = dates.values.toList().indexOf(startHeight);
|
||||
endHeight = dates.values.toList()[index + 1];
|
||||
final heightPerDay = ((endHeight - startHeight) / 31).round();
|
||||
|
|
|
@ -16,14 +16,14 @@ List<String> extractKeys(String key) {
|
|||
return [_key, iv];
|
||||
}
|
||||
|
||||
Future<String> encode({encrypt.Key key, encrypt.IV iv, String data}) async {
|
||||
Future<String> encode({required encrypt.Key key, required encrypt.IV iv, required String data}) async {
|
||||
final encrypter = encrypt.Encrypter(encrypt.Salsa20(key));
|
||||
final encrypted = encrypter.encrypt(data, iv: iv);
|
||||
|
||||
return encrypted.base64;
|
||||
}
|
||||
|
||||
Future<String> decode({String password, String data}) async {
|
||||
Future<String> decode({required String password, required String data}) async {
|
||||
final keys = extractKeys(password);
|
||||
final key = encrypt.Key.fromBase64(keys.first);
|
||||
final iv = encrypt.IV.fromBase64(keys.last);
|
||||
|
|
|
@ -7,12 +7,12 @@ final moneroAmountFormat = NumberFormat()
|
|||
..maximumFractionDigits = moneroAmountLength
|
||||
..minimumFractionDigits = 1;
|
||||
|
||||
String moneroAmountToString({int amount}) => moneroAmountFormat
|
||||
String moneroAmountToString({required int amount}) => moneroAmountFormat
|
||||
.format(cryptoAmountToDouble(amount: amount, divider: moneroAmountDivider))
|
||||
.replaceAll(',', '');
|
||||
|
||||
double moneroAmountToDouble({int amount}) =>
|
||||
double moneroAmountToDouble({required int amount}) =>
|
||||
cryptoAmountToDouble(amount: amount, divider: moneroAmountDivider);
|
||||
|
||||
int moneroParseAmount({String amount}) =>
|
||||
int moneroParseAmount({required String amount}) =>
|
||||
(double.parse(amount) * moneroAmountDivider).toInt();
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
import 'package:cw_core/balance.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:cw_core/monero_amount_format.dart';
|
||||
|
||||
class MoneroBalance extends Balance {
|
||||
MoneroBalance({@required this.fullBalance, @required this.unlockedBalance})
|
||||
MoneroBalance({required this.fullBalance, required this.unlockedBalance})
|
||||
: formattedFullBalance = moneroAmountToString(amount: fullBalance),
|
||||
formattedUnlockedBalance =
|
||||
moneroAmountToString(amount: unlockedBalance),
|
||||
super(unlockedBalance, fullBalance);
|
||||
|
||||
MoneroBalance.fromString(
|
||||
{@required this.formattedFullBalance,
|
||||
@required this.formattedUnlockedBalance})
|
||||
{required this.formattedFullBalance,
|
||||
required this.formattedUnlockedBalance})
|
||||
: fullBalance = moneroParseAmount(amount: formattedFullBalance),
|
||||
unlockedBalance = moneroParseAmount(amount: formattedUnlockedBalance),
|
||||
super(moneroParseAmount(amount: formattedUnlockedBalance),
|
||||
|
|
|
@ -4,18 +4,18 @@ import 'package:cw_core/wallet_type.dart';
|
|||
import 'package:cw_core/enumerable_item.dart';
|
||||
|
||||
class MoneroTransactionPriority extends TransactionPriority {
|
||||
const MoneroTransactionPriority({String title, int raw})
|
||||
const MoneroTransactionPriority({required String title, required int raw})
|
||||
: super(title: title, raw: raw);
|
||||
|
||||
static const all = [
|
||||
MoneroTransactionPriority.slow,
|
||||
MoneroTransactionPriority.regular,
|
||||
MoneroTransactionPriority.automatic,
|
||||
MoneroTransactionPriority.medium,
|
||||
MoneroTransactionPriority.fast,
|
||||
MoneroTransactionPriority.fastest
|
||||
];
|
||||
static const slow = MoneroTransactionPriority(title: 'Slow', raw: 0);
|
||||
static const regular = MoneroTransactionPriority(title: 'Regular', raw: 1);
|
||||
static const automatic = MoneroTransactionPriority(title: 'Automatic', raw: 1);
|
||||
static const medium = MoneroTransactionPriority(title: 'Medium', raw: 2);
|
||||
static const fast = MoneroTransactionPriority(title: 'Fast', raw: 3);
|
||||
static const fastest = MoneroTransactionPriority(title: 'Fastest', raw: 4);
|
||||
|
@ -29,7 +29,7 @@ class MoneroTransactionPriority extends TransactionPriority {
|
|||
case WalletType.bitcoin:
|
||||
return [
|
||||
MoneroTransactionPriority.slow,
|
||||
MoneroTransactionPriority.regular,
|
||||
MoneroTransactionPriority.automatic,
|
||||
MoneroTransactionPriority.fast
|
||||
];
|
||||
default:
|
||||
|
@ -37,12 +37,12 @@ class MoneroTransactionPriority extends TransactionPriority {
|
|||
}
|
||||
}
|
||||
|
||||
static MoneroTransactionPriority deserialize({int raw}) {
|
||||
static MoneroTransactionPriority deserialize({required int raw}) {
|
||||
switch (raw) {
|
||||
case 0:
|
||||
return slow;
|
||||
case 1:
|
||||
return regular;
|
||||
return automatic;
|
||||
case 2:
|
||||
return medium;
|
||||
case 3:
|
||||
|
@ -50,7 +50,7 @@ class MoneroTransactionPriority extends TransactionPriority {
|
|||
case 4:
|
||||
return fastest;
|
||||
default:
|
||||
return null;
|
||||
throw Exception('Unexpected token: $raw for MoneroTransactionPriority deserialize');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -59,8 +59,8 @@ class MoneroTransactionPriority extends TransactionPriority {
|
|||
switch (this) {
|
||||
case MoneroTransactionPriority.slow:
|
||||
return 'Slow'; // S.current.transaction_priority_slow;
|
||||
case MoneroTransactionPriority.regular:
|
||||
return 'Regular'; // S.current.transaction_priority_regular;
|
||||
case MoneroTransactionPriority.automatic:
|
||||
return 'Automatic'; // S.current.transaction_priority_regular;
|
||||
case MoneroTransactionPriority.medium:
|
||||
return 'Medium'; // S.current.transaction_priority_medium;
|
||||
case MoneroTransactionPriority.fast:
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
class MoneroWalletKeys {
|
||||
const MoneroWalletKeys(
|
||||
{this.privateSpendKey,
|
||||
this.privateViewKey,
|
||||
this.publicSpendKey,
|
||||
this.publicViewKey});
|
||||
{required this.privateSpendKey,
|
||||
required this.privateViewKey,
|
||||
required this.publicSpendKey,
|
||||
required this.publicViewKey});
|
||||
|
||||
final String publicViewKey;
|
||||
final String privateViewKey;
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:cw_core/keyable.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'dart:convert';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:hive/hive.dart';
|
||||
|
@ -11,44 +9,47 @@ import 'package:http/io_client.dart' as ioc;
|
|||
part 'node.g.dart';
|
||||
|
||||
Uri createUriFromElectrumAddress(String address) =>
|
||||
Uri.tryParse('tcp://$address');
|
||||
Uri.tryParse('tcp://$address')!;
|
||||
|
||||
@HiveType(typeId: Node.typeId)
|
||||
class Node extends HiveObject with Keyable {
|
||||
Node(
|
||||
{@required String uri,
|
||||
@required WalletType type,
|
||||
this.login,
|
||||
{this.login,
|
||||
this.password,
|
||||
this.useSSL}) {
|
||||
uriRaw = uri;
|
||||
this.type = type;
|
||||
this.useSSL,
|
||||
String? uri,
|
||||
WalletType? type,}) {
|
||||
if (uri != null) {
|
||||
uriRaw = uri;
|
||||
}
|
||||
if (type != null) {
|
||||
this.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
Node.fromMap(Map map)
|
||||
: uriRaw = map['uri'] as String ?? '',
|
||||
login = map['login'] as String,
|
||||
password = map['password'] as String,
|
||||
typeRaw = map['typeRaw'] as int,
|
||||
useSSL = map['useSSL'] as bool;
|
||||
Node.fromMap(Map<String, Object?> map)
|
||||
: uriRaw = map['uri'] as String? ?? '',
|
||||
login = map['login'] as String?,
|
||||
password = map['password'] as String?,
|
||||
useSSL = map['useSSL'] as bool?;
|
||||
|
||||
static const typeId = 1;
|
||||
static const boxName = 'Nodes';
|
||||
|
||||
@HiveField(0)
|
||||
String uriRaw;
|
||||
@HiveField(0, defaultValue: '')
|
||||
late String uriRaw;
|
||||
|
||||
@HiveField(1)
|
||||
String login;
|
||||
String? login;
|
||||
|
||||
@HiveField(2)
|
||||
String password;
|
||||
String? password;
|
||||
|
||||
@HiveField(3)
|
||||
int typeRaw;
|
||||
@HiveField(3, defaultValue: 0)
|
||||
late int typeRaw;
|
||||
|
||||
@HiveField(4)
|
||||
bool useSSL;
|
||||
bool? useSSL;
|
||||
|
||||
bool get isSSL => useSSL ?? false;
|
||||
|
||||
|
@ -63,7 +64,7 @@ class Node extends HiveObject with Keyable {
|
|||
case WalletType.haven:
|
||||
return Uri.http(uriRaw, '');
|
||||
default:
|
||||
return null;
|
||||
throw Exception('Unexpected type ${type.toString()} for Node uri');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -99,7 +100,6 @@ class Node extends HiveObject with Keyable {
|
|||
}
|
||||
|
||||
Future<bool> requestMoneroNode() async {
|
||||
|
||||
final path = '/json_rpc';
|
||||
final rpcUri = isSSL ? Uri.https(uri.authority, path) : Uri.http(uri.authority, path);
|
||||
final realm = 'monero-rpc';
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
class OutputInfo {
|
||||
const OutputInfo(
|
||||
{this.fiatAmount,
|
||||
this.cryptoAmount,
|
||||
this.address,
|
||||
this.note,
|
||||
this.sendAll,
|
||||
this.extractedAddress,
|
||||
this.isParsedAddress,
|
||||
this.formattedCryptoAmount});
|
||||
{required this.address,
|
||||
required this.sendAll,
|
||||
required this.isParsedAddress,
|
||||
this.cryptoAmount,
|
||||
this.formattedCryptoAmount,
|
||||
this.fiatAmount,
|
||||
this.note,
|
||||
this.extractedAddress,});
|
||||
|
||||
final String fiatAmount;
|
||||
final String cryptoAmount;
|
||||
final String? fiatAmount;
|
||||
final String? cryptoAmount;
|
||||
final String address;
|
||||
final String note;
|
||||
final String extractedAddress;
|
||||
final String? note;
|
||||
final String? extractedAddress;
|
||||
final bool sendAll;
|
||||
final bool isParsedAddress;
|
||||
final int formattedCryptoAmount;
|
||||
final int? formattedCryptoAmount;
|
||||
}
|
|
@ -3,7 +3,7 @@ import 'package:cw_core/wallet_type.dart';
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
Future<String> pathForWalletDir({@required String name, @required WalletType type}) async {
|
||||
Future<String> pathForWalletDir({required String name, required WalletType type}) async {
|
||||
final root = await getApplicationDocumentsDirectory();
|
||||
final prefix = walletTypeToString(type).toLowerCase();
|
||||
final walletsDir = Directory('${root.path}/wallets');
|
||||
|
@ -16,11 +16,11 @@ Future<String> pathForWalletDir({@required String name, @required WalletType ty
|
|||
return walletDire.path;
|
||||
}
|
||||
|
||||
Future<String> pathForWallet({@required String name, @required WalletType type}) async =>
|
||||
Future<String> pathForWallet({required String name, required WalletType type}) async =>
|
||||
await pathForWalletDir(name: name, type: type)
|
||||
.then((path) => path + '/$name');
|
||||
|
||||
Future<String> outdatedAndroidPathForWalletDir({String name}) async {
|
||||
Future<String> outdatedAndroidPathForWalletDir({required String name}) async {
|
||||
final directory = await getApplicationDocumentsDirectory();
|
||||
final pathDir = directory.path + '/$name';
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ const utils = const MethodChannel('com.cake_wallet/native_utils');
|
|||
|
||||
Future<Uint8List> secRandom(int count) async {
|
||||
try {
|
||||
return await utils.invokeMethod<Uint8List>('sec_random', {'count': count});
|
||||
return await utils.invokeMethod<Uint8List>('sec_random', {'count': count}) ?? Uint8List.fromList([]);
|
||||
} on PlatformException catch (_) {
|
||||
return Uint8List.fromList([]);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class Subaddress {
|
||||
Subaddress({this.id, this.address, this.label});
|
||||
Subaddress({required this.id, required this.address, required this.label});
|
||||
|
||||
Subaddress.fromMap(Map map)
|
||||
Subaddress.fromMap(Map<String, Object?> map)
|
||||
: this.id = map['id'] == null ? 0 : int.parse(map['id'] as String),
|
||||
this.address = (map['address'] ?? '') as String,
|
||||
this.label = (map['label'] ?? '') as String;
|
||||
|
|
|
@ -2,16 +2,22 @@ enum TransactionDirection { incoming, outgoing }
|
|||
|
||||
TransactionDirection parseTransactionDirectionFromInt(int raw) {
|
||||
switch (raw) {
|
||||
case 0: return TransactionDirection.incoming;
|
||||
case 1: return TransactionDirection.outgoing;
|
||||
default: return null;
|
||||
case 0:
|
||||
return TransactionDirection.incoming;
|
||||
case 1:
|
||||
return TransactionDirection.outgoing;
|
||||
default:
|
||||
throw Exception('Unexpected token: raw for TransactionDirection parseTransactionDirectionFromInt');
|
||||
}
|
||||
}
|
||||
|
||||
TransactionDirection parseTransactionDirectionFromNumber(String raw) {
|
||||
switch (raw) {
|
||||
case "0": return TransactionDirection.incoming;
|
||||
case "1": return TransactionDirection.outgoing;
|
||||
default: return null;
|
||||
case "0":
|
||||
return TransactionDirection.incoming;
|
||||
case "1":
|
||||
return TransactionDirection.outgoing;
|
||||
default:
|
||||
throw Exception('Unexpected token: raw for TransactionDirection parseTransactionDirectionFromNumber');
|
||||
}
|
||||
}
|
|
@ -1,10 +1,9 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_core/transaction_info.dart';
|
||||
|
||||
abstract class TransactionHistoryBase<TransactionType extends TransactionInfo> {
|
||||
TransactionHistoryBase();
|
||||
// : _isUpdating = false;
|
||||
TransactionHistoryBase()
|
||||
: transactions = ObservableMap<String, TransactionType>();
|
||||
|
||||
@observable
|
||||
ObservableMap<String, TransactionType> transactions;
|
||||
|
|
|
@ -2,21 +2,21 @@ import 'package:cw_core/transaction_direction.dart';
|
|||
import 'package:cw_core/keyable.dart';
|
||||
|
||||
abstract class TransactionInfo extends Object with Keyable {
|
||||
String id;
|
||||
int amount;
|
||||
int fee;
|
||||
TransactionDirection direction;
|
||||
bool isPending;
|
||||
DateTime date;
|
||||
int height;
|
||||
int confirmations;
|
||||
late String id;
|
||||
late int amount;
|
||||
int? fee;
|
||||
late TransactionDirection direction;
|
||||
late bool isPending;
|
||||
late DateTime date;
|
||||
late int height;
|
||||
late int confirmations;
|
||||
String amountFormatted();
|
||||
String fiatAmount();
|
||||
String feeFormatted();
|
||||
String? feeFormatted();
|
||||
void changeFiatAmount(String amount);
|
||||
|
||||
@override
|
||||
dynamic get keyIndex => id;
|
||||
|
||||
Map<String, dynamic> additionalInfo;
|
||||
late Map<String, dynamic> additionalInfo;
|
||||
}
|
|
@ -2,5 +2,5 @@ import 'package:cw_core/enumerable_item.dart';
|
|||
|
||||
abstract class TransactionPriority extends EnumerableItem<int>
|
||||
with Serializable<int> {
|
||||
const TransactionPriority({String title, int raw}) : super(title: title, raw: raw);
|
||||
const TransactionPriority({required String title, required int raw}) : super(title: title, raw: raw);
|
||||
}
|
||||
|
|
|
@ -5,28 +5,32 @@ part 'unspent_coins_info.g.dart';
|
|||
@HiveType(typeId: UnspentCoinsInfo.typeId)
|
||||
class UnspentCoinsInfo extends HiveObject {
|
||||
UnspentCoinsInfo({
|
||||
this.walletId,
|
||||
this.hash,
|
||||
this.isFrozen,
|
||||
this.isSending,
|
||||
this.note});
|
||||
required this.walletId,
|
||||
required this.hash,
|
||||
required this.isFrozen,
|
||||
required this.isSending,
|
||||
required this.noteRaw});
|
||||
|
||||
static const typeId = 9;
|
||||
static const boxName = 'Unspent';
|
||||
static const boxKey = 'unspentBoxKey';
|
||||
|
||||
@HiveField(0)
|
||||
@HiveField(0, defaultValue: '')
|
||||
String walletId;
|
||||
|
||||
@HiveField(1)
|
||||
@HiveField(1, defaultValue: '')
|
||||
String hash;
|
||||
|
||||
@HiveField(2)
|
||||
@HiveField(2, defaultValue: false)
|
||||
bool isFrozen;
|
||||
|
||||
@HiveField(3)
|
||||
@HiveField(3, defaultValue: false)
|
||||
bool isSending;
|
||||
|
||||
@HiveField(4)
|
||||
String note;
|
||||
String? noteRaw;
|
||||
|
||||
String get note => noteRaw ?? '';
|
||||
|
||||
set note(String value) => noteRaw = value;
|
||||
}
|
|
@ -1,9 +1,8 @@
|
|||
import 'package:cw_core/wallet_info.dart';
|
||||
|
||||
abstract class WalletAddresses {
|
||||
WalletAddresses(this.walletInfo) {
|
||||
addressesMap = {};
|
||||
}
|
||||
WalletAddresses(this.walletInfo)
|
||||
: addressesMap = {};
|
||||
|
||||
final WalletInfo walletInfo;
|
||||
|
||||
|
@ -19,10 +18,6 @@ abstract class WalletAddresses {
|
|||
|
||||
Future<void> saveAddressesInBox() async {
|
||||
try {
|
||||
if (walletInfo == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
walletInfo.address = address;
|
||||
walletInfo.addresses = addressesMap;
|
||||
|
||||
|
|
|
@ -5,9 +5,9 @@ import 'package:cw_core/wallet_info.dart';
|
|||
abstract class WalletAddressesWithAccount<T> extends WalletAddresses {
|
||||
WalletAddressesWithAccount(WalletInfo walletInfo) : super(walletInfo);
|
||||
|
||||
T get account;
|
||||
// T get account;
|
||||
|
||||
set account(T account);
|
||||
// set account(T account);
|
||||
|
||||
AccountList<T> get accountList;
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_core/balance.dart';
|
||||
import 'package:cw_core/transaction_info.dart';
|
||||
import 'package:cw_core/transaction_history.dart';
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
import 'package:cw_core/wallet_addresses.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/pending_transaction.dart';
|
||||
import 'package:cw_core/transaction_history.dart';
|
||||
import 'package:cw_core/currency_for_wallet_type.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/sync_status.dart';
|
||||
|
@ -48,15 +48,15 @@ abstract class WalletBase<
|
|||
|
||||
WalletAddresses get walletAddresses;
|
||||
|
||||
HistoryType transactionHistory;
|
||||
late HistoryType transactionHistory;
|
||||
|
||||
Future<void> connectToNode({@required Node node});
|
||||
Future<void> connectToNode({required Node node});
|
||||
|
||||
Future<void> startSync();
|
||||
|
||||
Future<PendingTransaction> createTransaction(Object credentials);
|
||||
|
||||
int calculateEstimatedFee(TransactionPriority priority, int amount);
|
||||
int calculateEstimatedFee(TransactionPriority priority, int? amount);
|
||||
|
||||
// void fetchTransactionsAsync(
|
||||
// void Function(TransactionType transaction) onTransactionLoaded,
|
||||
|
@ -66,7 +66,7 @@ abstract class WalletBase<
|
|||
|
||||
Future<void> save();
|
||||
|
||||
Future<void> rescan({int height});
|
||||
Future<void> rescan({required int height});
|
||||
|
||||
void close();
|
||||
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
import 'package:cw_core/wallet_info.dart';
|
||||
|
||||
abstract class WalletCredentials {
|
||||
WalletCredentials({this.name, this.password, this.height, this.walletInfo});
|
||||
WalletCredentials({
|
||||
required this.name,
|
||||
this.height,
|
||||
this.walletInfo,
|
||||
this.password});
|
||||
|
||||
final String name;
|
||||
final int height;
|
||||
String password;
|
||||
WalletInfo walletInfo;
|
||||
final int? height;
|
||||
String? password;
|
||||
WalletInfo? walletInfo;
|
||||
}
|
||||
|
|
|
@ -13,66 +13,66 @@ class WalletInfo extends HiveObject {
|
|||
: _yatLastUsedAddressController = StreamController<String>.broadcast();
|
||||
|
||||
factory WalletInfo.external(
|
||||
{@required String id,
|
||||
@required String name,
|
||||
@required WalletType type,
|
||||
@required bool isRecovery,
|
||||
@required int restoreHeight,
|
||||
@required DateTime date,
|
||||
@required String dirPath,
|
||||
@required String path,
|
||||
@required String address,
|
||||
{required String id,
|
||||
required String name,
|
||||
required WalletType type,
|
||||
required bool isRecovery,
|
||||
required int restoreHeight,
|
||||
required DateTime date,
|
||||
required String dirPath,
|
||||
required String path,
|
||||
required String address,
|
||||
bool? showIntroCakePayCard,
|
||||
String yatEid ='',
|
||||
String yatLastUsedAddressRaw = '',
|
||||
bool showIntroCakePayCard}) {
|
||||
String yatLastUsedAddressRaw = ''}) {
|
||||
return WalletInfo(id, name, type, isRecovery, restoreHeight,
|
||||
date.millisecondsSinceEpoch ?? 0, dirPath, path, address,
|
||||
date.millisecondsSinceEpoch, dirPath, path, address,
|
||||
yatEid, yatLastUsedAddressRaw, showIntroCakePayCard);
|
||||
}
|
||||
|
||||
static const typeId = 4;
|
||||
static const boxName = 'WalletInfo';
|
||||
|
||||
@HiveField(0)
|
||||
@HiveField(0, defaultValue: '')
|
||||
String id;
|
||||
|
||||
@HiveField(1)
|
||||
@HiveField(1, defaultValue: '')
|
||||
String name;
|
||||
|
||||
@HiveField(2)
|
||||
WalletType type;
|
||||
|
||||
@HiveField(3)
|
||||
@HiveField(3, defaultValue: false)
|
||||
bool isRecovery;
|
||||
|
||||
@HiveField(4)
|
||||
@HiveField(4, defaultValue: 0)
|
||||
int restoreHeight;
|
||||
|
||||
@HiveField(5)
|
||||
@HiveField(5, defaultValue: 0)
|
||||
int timestamp;
|
||||
|
||||
@HiveField(6)
|
||||
@HiveField(6, defaultValue: '')
|
||||
String dirPath;
|
||||
|
||||
@HiveField(7)
|
||||
@HiveField(7, defaultValue: '')
|
||||
String path;
|
||||
|
||||
@HiveField(8)
|
||||
@HiveField(8, defaultValue: '')
|
||||
String address;
|
||||
|
||||
@HiveField(10)
|
||||
Map<String, String> addresses;
|
||||
Map<String, String>? addresses;
|
||||
|
||||
@HiveField(11)
|
||||
String yatEid;
|
||||
String? yatEid;
|
||||
|
||||
@HiveField(12)
|
||||
String yatLastUsedAddressRaw;
|
||||
String? yatLastUsedAddressRaw;
|
||||
|
||||
@HiveField(13)
|
||||
bool showIntroCakePayCard;
|
||||
bool? showIntroCakePayCard;
|
||||
|
||||
String get yatLastUsedAddress => yatLastUsedAddressRaw;
|
||||
String get yatLastUsedAddress => yatLastUsedAddressRaw ?? '';
|
||||
|
||||
set yatLastUsedAddress(String address) {
|
||||
yatLastUsedAddressRaw = address;
|
||||
|
@ -85,7 +85,7 @@ class WalletInfo extends HiveObject {
|
|||
if(showIntroCakePayCard == null) {
|
||||
return type != WalletType.haven;
|
||||
}
|
||||
return showIntroCakePayCard;
|
||||
return showIntroCakePayCard!;
|
||||
}
|
||||
|
||||
DateTime get date => DateTime.fromMillisecondsSinceEpoch(timestamp);
|
||||
|
|
|
@ -55,7 +55,7 @@ WalletType deserializeFromInt(int raw) {
|
|||
case 3:
|
||||
return WalletType.haven;
|
||||
default:
|
||||
return null;
|
||||
throw Exception('Unexpected token: $raw for WalletType deserializeFromInt');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,6 +100,6 @@ CryptoCurrency walletTypeToCryptoCurrency(WalletType type) {
|
|||
case WalletType.haven:
|
||||
return CryptoCurrency.xhv;
|
||||
default:
|
||||
return null;
|
||||
throw Exception('Unexpected wallet type: ${type.toString()} for CryptoCurrency walletTypeToCryptoCurrency');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,35 +7,35 @@ packages:
|
|||
name: _fe_analyzer_shared
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "14.0.0"
|
||||
version: "47.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.41.2"
|
||||
version: "4.7.0"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.0"
|
||||
version: "2.3.1"
|
||||
asn1lib:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: asn1lib
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.8.1"
|
||||
version: "1.1.1"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.5.0"
|
||||
version: "2.9.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -49,42 +49,42 @@ packages:
|
|||
name: build
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.2"
|
||||
version: "2.3.1"
|
||||
build_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.6"
|
||||
version: "1.1.0"
|
||||
build_daemon:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_daemon
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.10"
|
||||
version: "3.1.0"
|
||||
build_resolvers:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_resolvers
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.5.3"
|
||||
version: "2.0.10"
|
||||
build_runner:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_runner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.11.5"
|
||||
version: "2.2.1"
|
||||
build_runner_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_runner_core
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "6.1.10"
|
||||
version: "7.2.4"
|
||||
built_collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -105,98 +105,77 @@ packages:
|
|||
name: characters
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.2.1"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: checked_yaml
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
cli_util:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cli_util
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.5"
|
||||
version: "2.0.1"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
code_builder:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: code_builder
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.7.0"
|
||||
version: "4.3.0"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.15.0"
|
||||
version: "1.16.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "3.0.2"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
version: "3.0.2"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dart_style
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.12"
|
||||
dartx:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dartx
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.5.0"
|
||||
version: "2.2.4"
|
||||
encrypt:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: encrypt
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.1.0"
|
||||
version: "5.0.1"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.3.1"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffi
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
version: "2.0.1"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -222,12 +201,19 @@ packages:
|
|||
name: flutter_mobx
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0+2"
|
||||
version: "2.0.6+4"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
frontend_server_client:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: frontend_server_client
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -241,42 +227,42 @@ packages:
|
|||
name: graphs
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
version: "2.1.0"
|
||||
hive:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: hive
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.4+1"
|
||||
version: "2.2.3"
|
||||
hive_generator:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: hive_generator
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.8.2"
|
||||
version: "1.1.3"
|
||||
http:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.2"
|
||||
version: "0.13.5"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
version: "3.2.1"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.4"
|
||||
version: "4.0.1"
|
||||
intl:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -290,7 +276,7 @@ packages:
|
|||
name: io
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.3.5"
|
||||
version: "1.0.3"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -304,7 +290,7 @@ packages:
|
|||
name: json_annotation
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.1"
|
||||
version: "4.6.0"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -318,14 +304,21 @@ packages:
|
|||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.10"
|
||||
version: "0.12.12"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.5"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "1.8.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -339,63 +332,77 @@ packages:
|
|||
name: mobx
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.1+4"
|
||||
version: "2.1.0"
|
||||
mobx_codegen:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: mobx_codegen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
version: "2.0.7+3"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.3"
|
||||
version: "2.1.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
version: "1.8.2"
|
||||
path_provider:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: path_provider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.6.28"
|
||||
version: "2.0.11"
|
||||
path_provider_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.20"
|
||||
path_provider_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_ios
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.11"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_linux
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.1+2"
|
||||
version: "2.1.7"
|
||||
path_provider_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_macos
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.4+8"
|
||||
version: "2.0.6"
|
||||
path_provider_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.4"
|
||||
version: "2.0.4"
|
||||
path_provider_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_windows
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.0.5"
|
||||
version: "2.1.3"
|
||||
pedantic:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -416,14 +423,14 @@ packages:
|
|||
name: plugin_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
version: "2.1.3"
|
||||
pointycastle:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pointycastle
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
version: "3.6.2"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -451,21 +458,21 @@ packages:
|
|||
name: pubspec_parse
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.8"
|
||||
version: "1.2.1"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.7.9"
|
||||
version: "1.3.2"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.4+1"
|
||||
version: "1.0.2"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
|
@ -477,14 +484,21 @@ packages:
|
|||
name: source_gen
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.9.10+3"
|
||||
version: "1.2.3"
|
||||
source_helper:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_helper
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.3"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
version: "1.9.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -512,35 +526,28 @@ packages:
|
|||
name: string_scanner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.1.1"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "1.2.1"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.2.19"
|
||||
time:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: time
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
version: "0.4.12"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: timing
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.1+3"
|
||||
version: "1.0.0"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -554,7 +561,7 @@ packages:
|
|||
name: vector_math
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
version: "2.1.2"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -568,21 +575,21 @@ packages:
|
|||
name: web_socket_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "2.2.0"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.5"
|
||||
version: "3.0.0"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xdg_directories
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.2"
|
||||
version: "0.2.0+2"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -591,5 +598,5 @@ packages:
|
|||
source: hosted
|
||||
version: "3.1.0"
|
||||
sdks:
|
||||
dart: ">=2.12.0 <3.0.0"
|
||||
flutter: ">=1.20.0"
|
||||
dart: ">=2.17.5 <3.0.0"
|
||||
flutter: ">=3.0.0"
|
||||
|
|
|
@ -6,26 +6,26 @@ author: Cake Wallet
|
|||
homepage: https://cakewallet.com
|
||||
|
||||
environment:
|
||||
sdk: ">=2.7.0 <3.0.0"
|
||||
flutter: ">=1.17.0"
|
||||
sdk: ">=2.17.5 <3.0.0"
|
||||
flutter: ">=1.20.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
http: ^0.12.0+2
|
||||
path_provider: ^1.3.0
|
||||
mobx: ^1.2.1+2
|
||||
flutter_mobx: ^1.1.0+2
|
||||
http: ^0.13.4
|
||||
path_provider: ^2.0.11
|
||||
mobx: ^2.0.7+4
|
||||
flutter_mobx: ^2.0.6+1
|
||||
intl: ^0.17.0
|
||||
encrypt: ^4.0.0
|
||||
encrypt: ^5.0.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
build_runner: ^1.10.3
|
||||
build_resolvers: ^1.3.10
|
||||
mobx_codegen: ^1.1.0+1
|
||||
hive_generator: ^0.8.1
|
||||
build_runner: ^2.1.11
|
||||
build_resolvers: ^2.0.9
|
||||
mobx_codegen: ^2.0.7
|
||||
hive_generator: ^1.1.3
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
|
|
@ -50,16 +50,16 @@ List<AccountRow> getAllAccount() {
|
|||
.toList();
|
||||
}
|
||||
|
||||
void addAccountSync({String label}) {
|
||||
final labelPointer = Utf8.toUtf8(label);
|
||||
void addAccountSync({required String label}) {
|
||||
final labelPointer = label.toNativeUtf8();
|
||||
accountAddNewNative(labelPointer);
|
||||
free(labelPointer);
|
||||
calloc.free(labelPointer);
|
||||
}
|
||||
|
||||
void setLabelForAccountSync({int accountIndex, String label}) {
|
||||
final labelPointer = Utf8.toUtf8(label);
|
||||
void setLabelForAccountSync({required int accountIndex, required String label}) {
|
||||
final labelPointer = label.toNativeUtf8();
|
||||
accountSetLabelNative(accountIndex, labelPointer);
|
||||
free(labelPointer);
|
||||
calloc.free(labelPointer);
|
||||
}
|
||||
|
||||
void _addAccount(String label) => addAccountSync(label: label);
|
||||
|
@ -71,12 +71,12 @@ void _setLabelForAccount(Map<String, dynamic> args) {
|
|||
setLabelForAccountSync(label: label, accountIndex: accountIndex);
|
||||
}
|
||||
|
||||
Future<void> addAccount({String label}) async {
|
||||
Future<void> addAccount({required String label}) async {
|
||||
await compute(_addAccount, label);
|
||||
await store();
|
||||
}
|
||||
|
||||
Future<void> setLabelForAccount({int accountIndex, String label}) async {
|
||||
Future<void> setLabelForAccount({required int accountIndex, required String label}) async {
|
||||
await compute(
|
||||
_setLabelForAccount, {'accountIndex': accountIndex, 'label': label});
|
||||
await store();
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import 'dart:ffi';
|
||||
import 'package:ffi/ffi.dart';
|
||||
|
||||
String convertUTF8ToString({Pointer<Utf8> pointer}) {
|
||||
final str = Utf8.fromUtf8(pointer);
|
||||
free(pointer);
|
||||
String convertUTF8ToString({required Pointer<Utf8> pointer}) {
|
||||
final str = pointer.toDartString();
|
||||
calloc.free(pointer);
|
||||
return str;
|
||||
}
|
|
@ -8,7 +8,7 @@ class CwHaven {
|
|||
const MethodChannel('cw_haven');
|
||||
|
||||
static Future<String> get platformVersion async {
|
||||
final String version = await _channel.invokeMethod('getPlatformVersion');
|
||||
final String version = await _channel.invokeMethod<String>('getPlatformVersion') ?? '';
|
||||
return version;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class ConnectionToNodeException implements Exception {
|
||||
ConnectionToNodeException({this.message});
|
||||
ConnectionToNodeException({required this.message});
|
||||
|
||||
final String message;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
class CreationTransactionException implements Exception {
|
||||
CreationTransactionException({this.message});
|
||||
CreationTransactionException({required this.message});
|
||||
|
||||
final String message;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
class SetupWalletException implements Exception {
|
||||
SetupWalletException({this.message});
|
||||
SetupWalletException({required this.message});
|
||||
|
||||
final String message;
|
||||
}
|