diff --git a/analysis_options.yaml b/analysis_options.yaml index 56738f471..524f70011 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -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 \ No newline at end of file + + +# 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 \ No newline at end of file diff --git a/android/app/build.gradle b/android/app/build.gradle index eec79a3f2..74cd0f8f7 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -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 { diff --git a/android/build.gradle b/android/build.gradle index 39e58da44..04c2af566 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -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" } } diff --git a/assets/faq/faq_fr.json b/assets/faq/faq_fr.json index f1e3585bc..cc4e52873 100644 --- a/assets/faq/faq_fr.json +++ b/assets/faq/faq_fr.json @@ -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 ?", diff --git a/assets/images/ape_icon.png b/assets/images/ape_icon.png new file mode 100644 index 000000000..b9c3d9c34 Binary files /dev/null and b/assets/images/ape_icon.png differ diff --git a/assets/images/avaxc_icon.png b/assets/images/avaxc_icon.png new file mode 100644 index 000000000..728b19fc3 Binary files /dev/null and b/assets/images/avaxc_icon.png differ diff --git a/assets/images/btt_icon.png b/assets/images/btt_icon.png new file mode 100644 index 000000000..253c01d1c Binary files /dev/null and b/assets/images/btt_icon.png differ diff --git a/assets/images/bttbsc_icon.png b/assets/images/bttbsc_icon.png new file mode 100644 index 000000000..253c01d1c Binary files /dev/null and b/assets/images/bttbsc_icon.png differ diff --git a/assets/images/dcr_icon.png b/assets/images/dcr_icon.png new file mode 100644 index 000000000..609873611 Binary files /dev/null and b/assets/images/dcr_icon.png differ diff --git a/assets/images/doge_icon.png b/assets/images/doge_icon.png new file mode 100644 index 000000000..b6292c16c Binary files /dev/null and b/assets/images/doge_icon.png differ diff --git a/assets/images/firo_icon.png b/assets/images/firo_icon.png new file mode 100644 index 000000000..076d8421b Binary files /dev/null and b/assets/images/firo_icon.png differ diff --git a/assets/images/hbar_icon.png b/assets/images/hbar_icon.png new file mode 100644 index 000000000..ad21e7384 Binary files /dev/null and b/assets/images/hbar_icon.png differ diff --git a/assets/images/husd_icon.png b/assets/images/husd_icon.png new file mode 100644 index 000000000..071027099 Binary files /dev/null and b/assets/images/husd_icon.png differ diff --git a/assets/images/kmd_icon.png b/assets/images/kmd_icon.png new file mode 100644 index 000000000..dc07f5802 Binary files /dev/null and b/assets/images/kmd_icon.png differ diff --git a/assets/images/mana_icon.png b/assets/images/mana_icon.png new file mode 100644 index 000000000..ad9d7b1b1 Binary files /dev/null and b/assets/images/mana_icon.png differ diff --git a/assets/images/matic_icon.png b/assets/images/matic_icon.png new file mode 100644 index 000000000..7f5493343 Binary files /dev/null and b/assets/images/matic_icon.png differ diff --git a/assets/images/mkr_icon.png b/assets/images/mkr_icon.png new file mode 100644 index 000000000..66c06446d Binary files /dev/null and b/assets/images/mkr_icon.png differ diff --git a/assets/images/nano_icon.png b/assets/images/nano_icon.png new file mode 100644 index 000000000..8937b8ed2 Binary files /dev/null and b/assets/images/nano_icon.png differ diff --git a/assets/images/near_icon.png b/assets/images/near_icon.png new file mode 100644 index 000000000..667ea45c3 Binary files /dev/null and b/assets/images/near_icon.png differ diff --git a/assets/images/oxt_icon.png b/assets/images/oxt_icon.png new file mode 100644 index 000000000..43228e189 Binary files /dev/null and b/assets/images/oxt_icon.png differ diff --git a/assets/images/paxg_icon.png b/assets/images/paxg_icon.png new file mode 100644 index 000000000..17f093303 Binary files /dev/null and b/assets/images/paxg_icon.png differ diff --git a/assets/images/pivx_icon.png b/assets/images/pivx_icon.png new file mode 100644 index 000000000..0b3b80eb1 Binary files /dev/null and b/assets/images/pivx_icon.png differ diff --git a/assets/images/rune_icon.png b/assets/images/rune_icon.png new file mode 100644 index 000000000..96d8bf40c Binary files /dev/null and b/assets/images/rune_icon.png differ diff --git a/assets/images/rvn_icon.png b/assets/images/rvn_icon.png new file mode 100644 index 000000000..24c5c1d41 Binary files /dev/null and b/assets/images/rvn_icon.png differ diff --git a/assets/images/sc_icon.png b/assets/images/sc_icon.png new file mode 100644 index 000000000..5ff4b2e21 Binary files /dev/null and b/assets/images/sc_icon.png differ diff --git a/assets/images/scrt_icon.png b/assets/images/scrt_icon.png new file mode 100644 index 000000000..ce38dcc58 Binary files /dev/null and b/assets/images/scrt_icon.png differ diff --git a/assets/images/sol_icon.png b/assets/images/sol_icon.png new file mode 100644 index 000000000..c9a9f3b6a Binary files /dev/null and b/assets/images/sol_icon.png differ diff --git a/assets/images/stx_icon.png b/assets/images/stx_icon.png new file mode 100644 index 000000000..76571a7c8 Binary files /dev/null and b/assets/images/stx_icon.png differ diff --git a/assets/images/uni_icon.png b/assets/images/uni_icon.png new file mode 100644 index 000000000..01ffcf726 Binary files /dev/null and b/assets/images/uni_icon.png differ diff --git a/assets/images/usdc_icon.png b/assets/images/usdc_icon.png new file mode 100644 index 000000000..283533b42 Binary files /dev/null and b/assets/images/usdc_icon.png differ diff --git a/assets/images/usdcsol_icon.png b/assets/images/usdcsol_icon.png new file mode 100644 index 000000000..283533b42 Binary files /dev/null and b/assets/images/usdcsol_icon.png differ diff --git a/assets/images/usdttrc20_icon.png b/assets/images/usdttrc20_icon.png new file mode 100644 index 000000000..4d3f15688 Binary files /dev/null and b/assets/images/usdttrc20_icon.png differ diff --git a/assets/images/xvg_icon.png b/assets/images/xvg_icon.png new file mode 100644 index 000000000..2e415ecf1 Binary files /dev/null and b/assets/images/xvg_icon.png differ diff --git a/assets/images/zaddr_icon.png b/assets/images/zaddr_icon.png index 139acf84c..095ad2c56 100644 Binary files a/assets/images/zaddr_icon.png and b/assets/images/zaddr_icon.png differ diff --git a/assets/images/zec_icon.png b/assets/images/zec_icon.png index 139acf84c..095ad2c56 100644 Binary files a/assets/images/zec_icon.png and b/assets/images/zec_icon.png differ diff --git a/assets/images/zen_icon.png b/assets/images/zen_icon.png new file mode 100644 index 000000000..2060a0d22 Binary files /dev/null and b/assets/images/zen_icon.png differ diff --git a/cw_bitcoin/lib/address_from_output.dart b/cw_bitcoin/lib/address_from_output.dart index 6aa90e883..d06ffe402 100644 --- a/cw_bitcoin/lib/address_from_output.dart +++ b/cw_bitcoin/lib/address_from_output.dart @@ -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 ''; } \ No newline at end of file diff --git a/cw_bitcoin/lib/bitcoin_address_record.dart b/cw_bitcoin/lib/bitcoin_address_record.dart index 5210604ef..392771ab0 100644 --- a/cw_bitcoin/lib/bitcoin_address_record.dart +++ b/cw_bitcoin/lib/bitcoin_address_record.dart @@ -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 diff --git a/cw_bitcoin/lib/bitcoin_amount_format.dart b/cw_bitcoin/lib/bitcoin_amount_format.dart index 0c846596f..c72d21960 100644 --- a/cw_bitcoin/lib/bitcoin_amount_format.dart +++ b/cw_bitcoin/lib/bitcoin_amount_format.dart @@ -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) { diff --git a/cw_bitcoin/lib/bitcoin_mnemonic.dart b/cw_bitcoin/lib/bitcoin_mnemonic.dart index 65f4ae0df..f4ebd7e5d 100644 --- a/cw_bitcoin/lib/bitcoin_mnemonic.dart +++ b/cw_bitcoin/lib/bitcoin_mnemonic.dart @@ -106,15 +106,18 @@ Future generateMnemonic( return result; } -Uint8List mnemonicToSeedBytes(String mnemonic, {String prefix = segwit}) { +Future 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) => diff --git a/cw_bitcoin/lib/bitcoin_transaction_credentials.dart b/cw_bitcoin/lib/bitcoin_transaction_credentials.dart index 7df93400a..bd8f1763c 100644 --- a/cw_bitcoin/lib/bitcoin_transaction_credentials.dart +++ b/cw_bitcoin/lib/bitcoin_transaction_credentials.dart @@ -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 outputs; - final BitcoinTransactionPriority priority; - final int feeRate; + final BitcoinTransactionPriority? priority; + final int? feeRate; } diff --git a/cw_bitcoin/lib/bitcoin_transaction_priority.dart b/cw_bitcoin/lib/bitcoin_transaction_priority.dart index f006e25e4..d82ea429e 100644 --- a/cw_bitcoin/lib/bitcoin_transaction_priority.dart +++ b/cw_bitcoin/lib/bitcoin_transaction_priority.dart @@ -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 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 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'); } } diff --git a/cw_bitcoin/lib/bitcoin_wallet.dart b/cw_bitcoin/lib/bitcoin_wallet.dart index 243e342b7..c4675df1c 100644 --- a/cw_bitcoin/lib/bitcoin_wallet.dart +++ b/cw_bitcoin/lib/bitcoin_wallet.dart @@ -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, - List initialAddresses, - ElectrumBalance initialBalance, + {required String mnemonic, + required String password, + required WalletInfo walletInfo, + required Box unspentCoinsInfo, + required Uint8List seedBytes, + List? 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 open({ - @required String name, - @required WalletInfo walletInfo, - @required Box unspentCoinsInfo, - @required String password, + static Future create({ + required String mnemonic, + required String password, + required WalletInfo walletInfo, + required Box unspentCoinsInfo, + List? 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 open({ + required String name, + required WalletInfo walletInfo, + required Box 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); } diff --git a/cw_bitcoin/lib/bitcoin_wallet_addresses.dart b/cw_bitcoin/lib/bitcoin_wallet_addresses.dart index 33e79c102..de3fdfbca 100644 --- a/cw_bitcoin/lib/bitcoin_wallet_addresses.dart +++ b/cw_bitcoin/lib/bitcoin_wallet_addresses.dart @@ -16,13 +16,13 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses with Store { BitcoinWalletAddressesBase( WalletInfo walletInfo, - {@required List initialAddresses, + {required bitcoin.HDWallet mainHd, + required bitcoin.HDWallet sideHd, + required bitcoin.NetworkType networkType, + required ElectrumClient electrumClient, + List? 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); } \ No newline at end of file diff --git a/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart b/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart index d3ade5c5e..82173b2d2 100644 --- a/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart +++ b/cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart @@ -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; diff --git a/cw_bitcoin/lib/bitcoin_wallet_keys.dart b/cw_bitcoin/lib/bitcoin_wallet_keys.dart index 74212c74c..0a4afc10d 100644 --- a/cw_bitcoin/lib/bitcoin_wallet_keys.dart +++ b/cw_bitcoin/lib/bitcoin_wallet_keys.dart @@ -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; diff --git a/cw_bitcoin/lib/bitcoin_wallet_service.dart b/cw_bitcoin/lib/bitcoin_wallet_service.dart index 300f4daa9..398d68fc2 100644 --- a/cw_bitcoin/lib/bitcoin_wallet_service.dart +++ b/cw_bitcoin/lib/bitcoin_wallet_service.dart @@ -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 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 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(); diff --git a/cw_bitcoin/lib/electrum.dart b/cw_bitcoin/lib/electrum.dart index 8a8894fb8..afbc199a5 100644 --- a/cw_bitcoin/lib/electrum.dart +++ b/cw_bitcoin/lib/electrum.dart @@ -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 params) { final _params = params?.map((val) => '"${val.toString()}"')?.join(','); @@ -14,14 +15,20 @@ String jsonrpcparams(List params) { } String jsonrpc( - {String method, List params, int id, double version = 2.0}) => + {required String method, + required List 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? completer; + final BehaviorSubject? 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 _tasks; bool _isConnected; - Timer _aliveTimer; + Timer? _aliveTimer; String unterminatedString; Future connectToUri(Uri uri) async => await connect(host: uri.host, port: uri.port); - Future connect({@required String host, @required int port}) async { + Future 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; + json.decode(msg) as Map; _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; + json.decode(unterminatedString) as Map; _handleResponse(response); unterminatedString = ''; } } on TypeError catch (e) { - if (!e.toString().contains('Map')) { + if (!e.toString().contains('Map') || !e.toString().contains('Map')) { return; } @@ -89,9 +97,10 @@ class ElectrumClient { if (isJSONStringCorrect(unterminatedString)) { final response = - json.decode(unterminatedString) as Map; + json.decode(unterminatedString) as Map; _handleResponse(response); - unterminatedString = null; + // unterminatedString = null; + unterminatedString = ''; } } catch (e) { print(e.toString()); @@ -128,14 +137,14 @@ class ElectrumClient { return []; }); - Future> getBalance(String scriptHash) => + Future> getBalance(String scriptHash) => call(method: 'blockchain.scripthash.get_balance', params: [scriptHash]) .then((dynamic result) { - if (result is Map) { + if (result is Map) { return result; } - return {}; + return {}; }); Future>> 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) { + if (val is Map) { return val; } - return {}; + return {}; }).toList(); } @@ -162,12 +171,12 @@ class ElectrumClient { .then((dynamic result) { if (result is List) { return result.map((dynamic val) { - if (val is Map) { + if (val is Map) { val['address'] = address; return val; } - return {}; + return {}; }).toList(); } @@ -179,11 +188,11 @@ class ElectrumClient { .then((dynamic result) { if (result is List) { return result.map((dynamic val) { - if (val is Map) { + if (val is Map) { return val; } - return {}; + return {}; }).toList(); } @@ -195,30 +204,30 @@ class ElectrumClient { .then((dynamic result) { if (result is List) { return result.map((dynamic val) { - if (val is Map) { + if (val is Map) { return val; } - return {}; + return {}; }).toList(); } return []; }); - Future> getTransactionRaw( - {@required String hash}) async => + Future> getTransactionRaw( + {required String hash}) async => call(method: 'blockchain.transaction.get', params: [hash, true]) .then((dynamic result) { - if (result is Map) { + if (result is Map) { return result; } - return {}; + return {}; }); Future 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 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> 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; - Future> getHeader({@required int height}) async => + Future> getHeader({required int height}) async => await call(method: 'blockchain.block.get_header', params: [height]) as Map; - Future estimatefee({@required int p}) => + Future estimatefee({required int p}) => call(method: 'blockchain.estimatefee', params: [p]) .then((dynamic result) { if (result is double) { @@ -266,13 +275,26 @@ class ElectrumClient { Future>> 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 = >[]; + for (final e in result) { + if (e is List) { + final eee = []; + 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 scripthashUpdate(String scripthash) { + BehaviorSubject? scripthashUpdate(String scripthash) { _id += 1; return subscribe( id: 'blockchain.scripthash.subscribe:$scripthash', @@ -307,14 +329,14 @@ class ElectrumClient { params: [scripthash]); } - BehaviorSubject subscribe( - {@required String id, - @required String method, + BehaviorSubject? subscribe( + {required String id, + required String method, List params = const []}) { try { final subscription = BehaviorSubject(); _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 call({String method, List params = const []}) async { + Future call({required String method, List params = const []}) async { final completer = Completer(); _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 callWithTimeout( - {String method, + {required String method, List 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 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 completer) => _tasks[id.toString()] = SocketTask(completer: completer, isSubscription: false); - void _regisrySubscription(String id, BehaviorSubject subject) => + void _regisrySubscription(String id, BehaviorSubject 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 request}) { + {required String method, required Map request}) { switch (method) { case 'blockchain.scripthash.subscribe': final params = request['params'] as List; @@ -406,7 +428,7 @@ class ElectrumClient { _isConnected = isConnected; } - void _handleResponse(Map response) { + void _handleResponse(Map response) { final method = response['method']; final id = response['id'] as String; final result = response['result']; diff --git a/cw_bitcoin/lib/electrum_balance.dart b/cw_bitcoin/lib/electrum_balance.dart index ec71977ad..a26b79ddb 100644 --- a/cw_bitcoin/lib/electrum_balance.dart +++ b/cw_bitcoin/lib/electrum_balance.dart @@ -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; diff --git a/cw_bitcoin/lib/electrum_transaction_history.dart b/cw_bitcoin/lib/electrum_transaction_history.dart index 94f328900..f8662eb95 100644 --- a/cw_bitcoin/lib/electrum_transaction_history.dart +++ b/cw_bitcoin/lib/electrum_transaction_history.dart @@ -17,7 +17,7 @@ class ElectrumTransactionHistory = ElectrumTransactionHistoryBase abstract class ElectrumTransactionHistoryBase extends TransactionHistoryBase with Store { ElectrumTransactionHistoryBase( - {@required this.walletInfo, @required String password}) + {required this.walletInfo, required String password}) : _password = password, _height = 0 { transactions = ObservableMap(); @@ -56,18 +56,18 @@ abstract class ElectrumTransactionHistoryBase await save(); } - Future> _read() async { + Future> _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; + return json.decode(content) as Map; } Future _load() async { try { final content = await _read(); - final txs = content['transactions'] as Map ?? {}; + final txs = content['transactions'] as Map ?? {}; 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; } } } diff --git a/cw_bitcoin/lib/electrum_transaction_info.dart b/cw_bitcoin/lib/electrum_transaction_info.dart index 491ebddfb..6e85a2f88 100644 --- a/cw_bitcoin/lib/electrum_transaction_info.dart +++ b/cw_bitcoin/lib/electrum_transaction_info.dart @@ -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 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 obj, WalletType type, - {@required List addresses, @required int height}) { + {required List addresses, required int height}) { final addressesSet = addresses.map((addr) => addr.address).toSet(); final id = obj['txid'] as String; - final vins = obj['vin'] as List ?? []; - final vout = (obj['vout'] as List ?? []); + final vins = obj['vin'] as List? ?? []; + final vout = (obj['vout'] as List? ?? []); 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)?.toSet(); + (out['scriptPubKey']['addresses'] as List?)?.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 ?? []; + out['scriptPubKey']['addresses'] as List? ?? []; 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 addresses, - int height}) { + {required Set 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 addresses, int height, int timestamp, int confirmations}) { + {List? 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; diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index a4db681f3..7abed8c07 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -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 with Store { ElectrumWalletBase( - {@required String password, - @required WalletInfo walletInfo, - @required Box unspentCoinsInfo, - @required List 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, + required this.networkType, + required this.mnemonic, + required Uint8List seedBytes, + List? initialAddresses, + ElectrumClient? electrumClient, + ElectrumBalance? initialBalance, + CryptoCurrency? currency}) + : hd = bitcoin.HDWallet.fromSeed(seedBytes, network: networkType) .derivePath("m/0'/0"), syncStatus = NotConnectedSyncStatus(), _password = password, _feeRates = [], _isTransactionUpdating = false, + unspentCoins = [], + _scripthashesUpdateSubject = {}, + balance = ObservableMap.of( + currency != null + ? {currency: initialBalance ?? const ElectrumBalance(confirmed: 0, unconfirmed: 0)} + : {}), + this.unspentCoinsInfo = unspentCoinsInfo, super(walletInfo) { - balance = ObservableMap.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 unspentCoinsInfo; @override - ElectrumWalletAddresses walletAddresses; + late ElectrumWalletAddresses walletAddresses; @override @observable - ObservableMap balance; + late ObservableMap balance; @override @observable @@ -98,7 +102,7 @@ abstract class ElectrumWalletBase extends WalletBase 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 BitcoinWalletKeys( - wif: hd.wif, privateKey: hd.privKey, publicKey: hd.pubKey); + wif: hd.wif!, privateKey: hd.privKey!, publicKey: hd.pubKey!); String _password; List unspentCoins; List _feeRates; - Map> _scripthashesUpdateSubject; + Map?> _scripthashesUpdateSubject; bool _isTransactionUpdating; Future init() async { @@ -137,7 +141,8 @@ abstract class ElectrumWalletBase extends WalletBase _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 connectToNode({@required Node node}) async { + Future connectToNode({required Node node}) async { try { syncStatus = ConnectingSyncStatus(); await electrumClient.connectToUri(node.uri); @@ -187,7 +192,7 @@ abstract class ElectrumWalletBase extends WalletBase 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 allAmount) { @@ -233,7 +238,7 @@ abstract class ElectrumWalletBase extends WalletBase balance[currency].confirmed || totalAmount > allInputsAmount) { + if (totalAmount > balance[currency]!.confirmed || totalAmount > allInputsAmount) { throw BitcoinTransactionWrongBalanceException(currency); } @@ -298,11 +303,11 @@ abstract class ElectrumWalletBase extends WalletBase + bitcoin.ECPair keyPairFor({required int index}) => generateKeyPair(hd: hd, index: index, network: networkType); @override - Future rescan({int height}) async => throw UnimplementedError(); + Future rescan({required int height}) async => throw UnimplementedError(); @override Future close() async { try { - await electrumClient?.close(); + await electrumClient.close(); } catch (_) {} } @@ -450,7 +455,13 @@ abstract class ElectrumWalletBase extends WalletBase 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 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 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 fetchTransactionInfo( - {@required String hash, @required int height}) async { + Future 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 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>( {}, (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 initialAddresses, + {required this.mainHd, + required this.sideHd, + required this.electrumClient, + required this.networkType, + List? initialAddresses, int initialRegularAddressIndex = 0, - int initialChangeAddressIndex = 0, - this.mainHd, - this.sideHd, - this.electrumClient, - this.networkType}) + int initialChangeAddressIndex = 0}) : addresses = ObservableList.of( (initialAddresses ?? []).toSet()), receiveAddresses = ObservableList.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 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 updateAddressesInBox() async { @@ -239,7 +238,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store { } Future> _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 = []; for (var i = startIndex; i < count + startIndex; i++) { diff --git a/cw_bitcoin/lib/electrum_wallet_snapshot.dart b/cw_bitcoin/lib/electrum_wallet_snapshot.dart index 3bc1f0607..3755e7d18 100644 --- a/cw_bitcoin/lib/electrum_wallet_snapshot.dart +++ b/cw_bitcoin/lib/electrum_wallet_snapshot.dart @@ -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 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 ?? []; - mnemonic = data['mnemonic'] as String; - addresses = addressesTmp - .whereType() - .map((addr) => BitcoinAddressRecord.fromJSON(addr)) - .toList(); - balance = ElectrumBalance.fromJSON(data['balance'] as String) ?? - ElectrumBalance(confirmed: 0, unconfirmed: 0); - regularAddressIndex = 0; - changeAddressIndex = 0; + static Future 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? ?? []; + final mnemonic = data['mnemonic'] as String; + final addresses = addressesTmp + .whereType() + .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); } } diff --git a/cw_bitcoin/lib/file.dart b/cw_bitcoin/lib/file.dart index e046e74fe..8fd236ec3 100644 --- a/cw_bitcoin/lib/file.dart +++ b/cw_bitcoin/lib/file.dart @@ -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 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 write( } Future 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 writeData( f.writeAsStringSync(encrypted); } -Future read({@required String path, @required String password}) async { +Future read({required String path, required String password}) async { final file = File(path); if (!file.existsSync()) { diff --git a/cw_bitcoin/lib/litecoin_wallet.dart b/cw_bitcoin/lib/litecoin_wallet.dart index 6f6ba3880..6bf1c5735 100644 --- a/cw_bitcoin/lib/litecoin_wallet.dart +++ b/cw_bitcoin/lib/litecoin_wallet.dart @@ -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, - List initialAddresses, - ElectrumBalance initialBalance, + {required String mnemonic, + required String password, + required WalletInfo walletInfo, + required Box unspentCoinsInfo, + required Uint8List seedBytes, + List? 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 open({ - @required String name, - @required WalletInfo walletInfo, - @required Box unspentCoinsInfo, - @required String password, + static Future create({ + required String mnemonic, + required String password, + required WalletInfo walletInfo, + required Box unspentCoinsInfo, + List? 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 open({ + required String name, + required WalletInfo walletInfo, + required Box 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); } diff --git a/cw_bitcoin/lib/litecoin_wallet_addresses.dart b/cw_bitcoin/lib/litecoin_wallet_addresses.dart index 1a39b8452..a317fa9f2 100644 --- a/cw_bitcoin/lib/litecoin_wallet_addresses.dart +++ b/cw_bitcoin/lib/litecoin_wallet_addresses.dart @@ -16,13 +16,13 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with Store { LitecoinWalletAddressesBase( WalletInfo walletInfo, - {@required List initialAddresses, + {required bitcoin.HDWallet mainHd, + required bitcoin.HDWallet sideHd, + required bitcoin.NetworkType networkType, + required ElectrumClient electrumClient, + List? 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); } \ No newline at end of file diff --git a/cw_bitcoin/lib/litecoin_wallet_service.dart b/cw_bitcoin/lib/litecoin_wallet_service.dart index f0b3f1693..2093647fd 100644 --- a/cw_bitcoin/lib/litecoin_wallet_service.dart +++ b/cw_bitcoin/lib/litecoin_wallet_service.dart @@ -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 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 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(); diff --git a/cw_bitcoin/lib/pending_bitcoin_transaction.dart b/cw_bitcoin/lib/pending_bitcoin_transaction.dart index b9f754c72..e2dc10bfb 100644 --- a/cw_bitcoin/lib/pending_bitcoin_transaction.dart +++ b/cw_bitcoin/lib/pending_bitcoin_transaction.dart @@ -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 = []; final WalletType type; diff --git a/cw_bitcoin/lib/script_hash.dart b/cw_bitcoin/lib/script_hash.dart index b1025f66b..76a1bfcf0 100644 --- a/cw_bitcoin/lib/script_hash.dart +++ b/cw_bitcoin/lib/script_hash.dart @@ -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(''); diff --git a/cw_bitcoin/lib/utils.dart b/cw_bitcoin/lib/utils.dart index 3a638555a..0d5a413b3 100644 --- a/cw_bitcoin/lib/utils.dart +++ b/cw_bitcoin/lib/utils.dart @@ -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!; diff --git a/cw_bitcoin/pubspec.lock b/cw_bitcoin/pubspec.lock index 504c92fab..9207fc209 100644 --- a/cw_bitcoin/pubspec.lock +++ b/cw_bitcoin/pubspec.lock @@ -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" diff --git a/cw_bitcoin/pubspec.yaml b/cw_bitcoin/pubspec.yaml index d7c324775..455ceb4a7 100644 --- a/cw_bitcoin/pubspec.yaml +++ b/cw_bitcoin/pubspec.yaml @@ -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 diff --git a/cw_core/lib/account.dart b/cw_core/lib/account.dart index 5bb002945..1633ee189 100644 --- a/cw_core/lib/account.dart +++ b/cw_core/lib/account.dart @@ -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 map) : this.id = map['id'] == null ? 0 : int.parse(map['id'] as String), this.label = (map['label'] ?? '') as String; diff --git a/cw_core/lib/account_list.dart b/cw_core/lib/account_list.dart index 4ac5faa3e..f49f69aa9 100644 --- a/cw_core/lib/account_list.dart +++ b/cw_core/lib/account_list.dart @@ -8,9 +8,9 @@ abstract class AccountList { List getAll(); - Future addAccount({String label}); + Future addAccount({required String label}); - Future setLabelAccount({int accountIndex, String label}); + Future setLabelAccount({required int accountIndex, required String label}); void refresh(); } diff --git a/lib/core/amount_converter.dart b/cw_core/lib/amount_converter.dart similarity index 97% rename from lib/core/amount_converter.dart rename to cw_core/lib/amount_converter.dart index b3c976e25..a11907ef2 100644 --- a/lib/core/amount_converter.dart +++ b/cw_core/lib/amount_converter.dart @@ -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( diff --git a/cw_core/lib/crypto_amount_format.dart b/cw_core/lib/crypto_amount_format.dart index 649ac45f5..a5c06e485 100644 --- a/cw_core/lib/crypto_amount_format.dart +++ b/cw_core/lib/crypto_amount_format.dart @@ -1 +1 @@ -double cryptoAmountToDouble({num amount, num divider}) => amount / divider; \ No newline at end of file +double cryptoAmountToDouble({required num amount, required num divider}) => amount / divider; \ No newline at end of file diff --git a/cw_core/lib/crypto_currency.dart b/cw_core/lib/crypto_currency.dart index fead230d9..c6e0c02c2 100644 --- a/cw_core/lib/crypto_currency.dart +++ b/cw_core/lib/crypto_currency.dart @@ -5,12 +5,17 @@ part 'crypto_currency.g.dart'; @HiveType(typeId: 0) class CryptoCurrency extends EnumerableItem with Serializable { - 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 with Serializable { 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 with Serializable { 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 with Serializable { 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 with Serializable { 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 with Serializable { 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 with Serializable { 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'); } } diff --git a/cw_core/lib/currency_for_wallet_type.dart b/cw_core/lib/currency_for_wallet_type.dart index b6d1f18c0..3904fc049 100644 --- a/cw_core/lib/currency_for_wallet_type.dart +++ b/cw_core/lib/currency_for_wallet_type.dart @@ -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'); } } diff --git a/cw_core/lib/enumerable_item.dart b/cw_core/lib/enumerable_item.dart index e9deb3056..e7a863909 100644 --- a/cw_core/lib/enumerable_item.dart +++ b/cw_core/lib/enumerable_item.dart @@ -1,7 +1,7 @@ import 'package:flutter/foundation.dart'; abstract class EnumerableItem { - 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 { } mixin Serializable on EnumerableItem { - static Serializable deserialize({T raw}) => null; + static Serializable deserialize({required T raw}) => throw Exception('Unimplemented'); T serialize() => raw; } diff --git a/cw_core/lib/get_height_by_date.dart b/cw_core/lib/get_height_by_date.dart index 99e834c58..e350a19cb 100644 --- a/cw_core/lib/get_height_by_date.dart +++ b/cw_core/lib/get_height_by_date.dart @@ -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(); diff --git a/cw_core/lib/key.dart b/cw_core/lib/key.dart index bdabe7852..6973b7a68 100644 --- a/cw_core/lib/key.dart +++ b/cw_core/lib/key.dart @@ -16,14 +16,14 @@ List extractKeys(String key) { return [_key, iv]; } -Future encode({encrypt.Key key, encrypt.IV iv, String data}) async { +Future 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 decode({String password, String data}) async { +Future 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); diff --git a/cw_core/lib/monero_amount_format.dart b/cw_core/lib/monero_amount_format.dart index 92bf0da25..912527b4e 100644 --- a/cw_core/lib/monero_amount_format.dart +++ b/cw_core/lib/monero_amount_format.dart @@ -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(); diff --git a/cw_core/lib/monero_balance.dart b/cw_core/lib/monero_balance.dart index 8f0ae610e..7d569ef2f 100644 --- a/cw_core/lib/monero_balance.dart +++ b/cw_core/lib/monero_balance.dart @@ -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), diff --git a/cw_core/lib/monero_transaction_priority.dart b/cw_core/lib/monero_transaction_priority.dart index fe937cb1f..cca887398 100644 --- a/cw_core/lib/monero_transaction_priority.dart +++ b/cw_core/lib/monero_transaction_priority.dart @@ -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: diff --git a/cw_core/lib/monero_wallet_keys.dart b/cw_core/lib/monero_wallet_keys.dart index f0a96bfd3..1435002a8 100644 --- a/cw_core/lib/monero_wallet_keys.dart +++ b/cw_core/lib/monero_wallet_keys.dart @@ -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; diff --git a/cw_core/lib/node.dart b/cw_core/lib/node.dart index 7de2e84b6..886add3cd 100644 --- a/cw_core/lib/node.dart +++ b/cw_core/lib/node.dart @@ -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 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 requestMoneroNode() async { - final path = '/json_rpc'; final rpcUri = isSSL ? Uri.https(uri.authority, path) : Uri.http(uri.authority, path); final realm = 'monero-rpc'; diff --git a/cw_core/lib/output_info.dart b/cw_core/lib/output_info.dart index 2c5a2ba5b..e2b1201a8 100644 --- a/cw_core/lib/output_info.dart +++ b/cw_core/lib/output_info.dart @@ -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; } \ No newline at end of file diff --git a/cw_core/lib/pathForWallet.dart b/cw_core/lib/pathForWallet.dart index bd05892ab..af4838ffa 100644 --- a/cw_core/lib/pathForWallet.dart +++ b/cw_core/lib/pathForWallet.dart @@ -3,7 +3,7 @@ import 'package:cw_core/wallet_type.dart'; import 'package:flutter/foundation.dart'; import 'package:path_provider/path_provider.dart'; -Future pathForWalletDir({@required String name, @required WalletType type}) async { +Future 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 pathForWalletDir({@required String name, @required WalletType ty return walletDire.path; } -Future pathForWallet({@required String name, @required WalletType type}) async => +Future pathForWallet({required String name, required WalletType type}) async => await pathForWalletDir(name: name, type: type) .then((path) => path + '/$name'); -Future outdatedAndroidPathForWalletDir({String name}) async { +Future outdatedAndroidPathForWalletDir({required String name}) async { final directory = await getApplicationDocumentsDirectory(); final pathDir = directory.path + '/$name'; diff --git a/cw_core/lib/sec_random_native.dart b/cw_core/lib/sec_random_native.dart index b9800fd71..ce251efc0 100644 --- a/cw_core/lib/sec_random_native.dart +++ b/cw_core/lib/sec_random_native.dart @@ -6,7 +6,7 @@ const utils = const MethodChannel('com.cake_wallet/native_utils'); Future secRandom(int count) async { try { - return await utils.invokeMethod('sec_random', {'count': count}); + return await utils.invokeMethod('sec_random', {'count': count}) ?? Uint8List.fromList([]); } on PlatformException catch (_) { return Uint8List.fromList([]); } diff --git a/cw_core/lib/subaddress.dart b/cw_core/lib/subaddress.dart index 0f884dfa4..8571544a9 100644 --- a/cw_core/lib/subaddress.dart +++ b/cw_core/lib/subaddress.dart @@ -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 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; diff --git a/cw_core/lib/transaction_direction.dart b/cw_core/lib/transaction_direction.dart index a82420e2c..8d1ddfe02 100644 --- a/cw_core/lib/transaction_direction.dart +++ b/cw_core/lib/transaction_direction.dart @@ -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'); } } \ No newline at end of file diff --git a/cw_core/lib/transaction_history.dart b/cw_core/lib/transaction_history.dart index 0011cd811..508f3aeca 100644 --- a/cw_core/lib/transaction_history.dart +++ b/cw_core/lib/transaction_history.dart @@ -1,10 +1,9 @@ -import 'package:flutter/foundation.dart'; import 'package:mobx/mobx.dart'; import 'package:cw_core/transaction_info.dart'; abstract class TransactionHistoryBase { - TransactionHistoryBase(); - // : _isUpdating = false; + TransactionHistoryBase() + : transactions = ObservableMap(); @observable ObservableMap transactions; diff --git a/cw_core/lib/transaction_info.dart b/cw_core/lib/transaction_info.dart index ae6bddbe2..b8e4a5e0c 100644 --- a/cw_core/lib/transaction_info.dart +++ b/cw_core/lib/transaction_info.dart @@ -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 additionalInfo; + late Map additionalInfo; } \ No newline at end of file diff --git a/cw_core/lib/transaction_priority.dart b/cw_core/lib/transaction_priority.dart index fe34bf629..c173f1ddd 100644 --- a/cw_core/lib/transaction_priority.dart +++ b/cw_core/lib/transaction_priority.dart @@ -2,5 +2,5 @@ import 'package:cw_core/enumerable_item.dart'; abstract class TransactionPriority extends EnumerableItem with Serializable { - const TransactionPriority({String title, int raw}) : super(title: title, raw: raw); + const TransactionPriority({required String title, required int raw}) : super(title: title, raw: raw); } diff --git a/cw_core/lib/unspent_coins_info.dart b/cw_core/lib/unspent_coins_info.dart index 6ce647dce..d825db279 100644 --- a/cw_core/lib/unspent_coins_info.dart +++ b/cw_core/lib/unspent_coins_info.dart @@ -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; } \ No newline at end of file diff --git a/cw_core/lib/wallet_addresses.dart b/cw_core/lib/wallet_addresses.dart index 85f9d0b8e..a34101a88 100644 --- a/cw_core/lib/wallet_addresses.dart +++ b/cw_core/lib/wallet_addresses.dart @@ -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 saveAddressesInBox() async { try { - if (walletInfo == null) { - return; - } - walletInfo.address = address; walletInfo.addresses = addressesMap; diff --git a/cw_core/lib/wallet_addresses_with_account.dart b/cw_core/lib/wallet_addresses_with_account.dart index 5691ad320..0dcf88de0 100644 --- a/cw_core/lib/wallet_addresses_with_account.dart +++ b/cw_core/lib/wallet_addresses_with_account.dart @@ -5,9 +5,9 @@ import 'package:cw_core/wallet_info.dart'; abstract class WalletAddressesWithAccount extends WalletAddresses { WalletAddressesWithAccount(WalletInfo walletInfo) : super(walletInfo); - T get account; + // T get account; - set account(T account); + // set account(T account); AccountList get accountList; } \ No newline at end of file diff --git a/cw_core/lib/wallet_base.dart b/cw_core/lib/wallet_base.dart index 173ba8155..1983e62b7 100644 --- a/cw_core/lib/wallet_base.dart +++ b/cw_core/lib/wallet_base.dart @@ -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 connectToNode({@required Node node}); + Future connectToNode({required Node node}); Future startSync(); Future 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 save(); - Future rescan({int height}); + Future rescan({required int height}); void close(); diff --git a/cw_core/lib/wallet_credentials.dart b/cw_core/lib/wallet_credentials.dart index 69c07bfda..e028232e8 100644 --- a/cw_core/lib/wallet_credentials.dart +++ b/cw_core/lib/wallet_credentials.dart @@ -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; } diff --git a/cw_core/lib/wallet_info.dart b/cw_core/lib/wallet_info.dart index 4e614811e..a25702cf7 100644 --- a/cw_core/lib/wallet_info.dart +++ b/cw_core/lib/wallet_info.dart @@ -13,66 +13,66 @@ class WalletInfo extends HiveObject { : _yatLastUsedAddressController = StreamController.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 addresses; + Map? 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); diff --git a/cw_core/lib/wallet_type.dart b/cw_core/lib/wallet_type.dart index 6a39fa63f..e76e4539e 100644 --- a/cw_core/lib/wallet_type.dart +++ b/cw_core/lib/wallet_type.dart @@ -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'); } } diff --git a/cw_core/pubspec.lock b/cw_core/pubspec.lock index 9858511de..951a97ffb 100644 --- a/cw_core/pubspec.lock +++ b/cw_core/pubspec.lock @@ -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" diff --git a/cw_core/pubspec.yaml b/cw_core/pubspec.yaml index 4caa92e11..50503361c 100644 --- a/cw_core/pubspec.yaml +++ b/cw_core/pubspec.yaml @@ -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 diff --git a/cw_haven/lib/api/account_list.dart b/cw_haven/lib/api/account_list.dart index 96bf3d654..a05446c8e 100644 --- a/cw_haven/lib/api/account_list.dart +++ b/cw_haven/lib/api/account_list.dart @@ -50,16 +50,16 @@ List 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 args) { setLabelForAccountSync(label: label, accountIndex: accountIndex); } -Future addAccount({String label}) async { +Future addAccount({required String label}) async { await compute(_addAccount, label); await store(); } -Future setLabelForAccount({int accountIndex, String label}) async { +Future setLabelForAccount({required int accountIndex, required String label}) async { await compute( _setLabelForAccount, {'accountIndex': accountIndex, 'label': label}); await store(); diff --git a/cw_haven/lib/api/convert_utf8_to_string.dart b/cw_haven/lib/api/convert_utf8_to_string.dart index 7fa5a68df..41a6b648a 100644 --- a/cw_haven/lib/api/convert_utf8_to_string.dart +++ b/cw_haven/lib/api/convert_utf8_to_string.dart @@ -1,8 +1,8 @@ import 'dart:ffi'; import 'package:ffi/ffi.dart'; -String convertUTF8ToString({Pointer pointer}) { - final str = Utf8.fromUtf8(pointer); - free(pointer); +String convertUTF8ToString({required Pointer pointer}) { + final str = pointer.toDartString(); + calloc.free(pointer); return str; } \ No newline at end of file diff --git a/cw_haven/lib/api/cw_haven.dart b/cw_haven/lib/api/cw_haven.dart index 1d3726e17..0e48276d9 100644 --- a/cw_haven/lib/api/cw_haven.dart +++ b/cw_haven/lib/api/cw_haven.dart @@ -8,7 +8,7 @@ class CwHaven { const MethodChannel('cw_haven'); static Future get platformVersion async { - final String version = await _channel.invokeMethod('getPlatformVersion'); + final String version = await _channel.invokeMethod('getPlatformVersion') ?? ''; return version; } } diff --git a/cw_haven/lib/api/exceptions/connection_to_node_exception.dart b/cw_haven/lib/api/exceptions/connection_to_node_exception.dart index 6ee272b89..483b0a174 100644 --- a/cw_haven/lib/api/exceptions/connection_to_node_exception.dart +++ b/cw_haven/lib/api/exceptions/connection_to_node_exception.dart @@ -1,5 +1,5 @@ class ConnectionToNodeException implements Exception { - ConnectionToNodeException({this.message}); + ConnectionToNodeException({required this.message}); final String message; } \ No newline at end of file diff --git a/cw_haven/lib/api/exceptions/creation_transaction_exception.dart b/cw_haven/lib/api/exceptions/creation_transaction_exception.dart index bb477d673..7b55ec074 100644 --- a/cw_haven/lib/api/exceptions/creation_transaction_exception.dart +++ b/cw_haven/lib/api/exceptions/creation_transaction_exception.dart @@ -1,5 +1,5 @@ class CreationTransactionException implements Exception { - CreationTransactionException({this.message}); + CreationTransactionException({required this.message}); final String message; diff --git a/cw_haven/lib/api/exceptions/setup_wallet_exception.dart b/cw_haven/lib/api/exceptions/setup_wallet_exception.dart index ce43c0ec6..b6e0c1f18 100644 --- a/cw_haven/lib/api/exceptions/setup_wallet_exception.dart +++ b/cw_haven/lib/api/exceptions/setup_wallet_exception.dart @@ -1,5 +1,5 @@ class SetupWalletException implements Exception { - SetupWalletException({this.message}); + SetupWalletException({required this.message}); final String message; } \ No newline at end of file diff --git a/cw_haven/lib/api/exceptions/wallet_creation_exception.dart b/cw_haven/lib/api/exceptions/wallet_creation_exception.dart index 6b00445ad..6052366b9 100644 --- a/cw_haven/lib/api/exceptions/wallet_creation_exception.dart +++ b/cw_haven/lib/api/exceptions/wallet_creation_exception.dart @@ -1,5 +1,5 @@ class WalletCreationException implements Exception { - WalletCreationException({this.message}); + WalletCreationException({required this.message}); final String message; diff --git a/cw_haven/lib/api/exceptions/wallet_opening_exception.dart b/cw_haven/lib/api/exceptions/wallet_opening_exception.dart index 8d84b0f7e..df7a850a4 100644 --- a/cw_haven/lib/api/exceptions/wallet_opening_exception.dart +++ b/cw_haven/lib/api/exceptions/wallet_opening_exception.dart @@ -1,5 +1,5 @@ class WalletOpeningException implements Exception { - WalletOpeningException({this.message}); + WalletOpeningException({required this.message}); final String message; diff --git a/cw_haven/lib/api/exceptions/wallet_restore_from_keys_exception.dart b/cw_haven/lib/api/exceptions/wallet_restore_from_keys_exception.dart index 5f08437d4..c6b6c6ef7 100644 --- a/cw_haven/lib/api/exceptions/wallet_restore_from_keys_exception.dart +++ b/cw_haven/lib/api/exceptions/wallet_restore_from_keys_exception.dart @@ -1,5 +1,5 @@ class WalletRestoreFromKeysException implements Exception { - WalletRestoreFromKeysException({this.message}); + WalletRestoreFromKeysException({required this.message}); final String message; } \ No newline at end of file diff --git a/cw_haven/lib/api/exceptions/wallet_restore_from_seed_exception.dart b/cw_haven/lib/api/exceptions/wallet_restore_from_seed_exception.dart index fd89e4161..004cd7958 100644 --- a/cw_haven/lib/api/exceptions/wallet_restore_from_seed_exception.dart +++ b/cw_haven/lib/api/exceptions/wallet_restore_from_seed_exception.dart @@ -1,5 +1,5 @@ class WalletRestoreFromSeedException implements Exception { - WalletRestoreFromSeedException({this.message}); + WalletRestoreFromSeedException({required this.message}); final String message; } \ No newline at end of file diff --git a/cw_haven/lib/api/monero_output.dart b/cw_haven/lib/api/monero_output.dart index 831ee1f22..a6d735bd3 100644 --- a/cw_haven/lib/api/monero_output.dart +++ b/cw_haven/lib/api/monero_output.dart @@ -1,7 +1,7 @@ import 'package:flutter/foundation.dart'; class MoneroOutput { - MoneroOutput({@required this.address, @required this.amount}); + MoneroOutput({required this.address, required this.amount}); final String address; final String amount; diff --git a/cw_haven/lib/api/signatures.dart b/cw_haven/lib/api/signatures.dart index 9dd1c8dac..774a303d7 100644 --- a/cw_haven/lib/api/signatures.dart +++ b/cw_haven/lib/api/signatures.dart @@ -39,7 +39,7 @@ typedef get_node_height = Int64 Function(); typedef is_connected = Int8 Function(); typedef setup_node = Int8 Function( - Pointer, Pointer, Pointer, Int8, Int8, Pointer); + Pointer, Pointer?, Pointer?, Int8, Int8, Pointer); typedef start_refresh = Void Function(); @@ -86,7 +86,7 @@ typedef account_set_label = Void Function( typedef transactions_refresh = Void Function(); -typedef get_tx_key = Pointer Function(Pointer txId); +typedef get_tx_key = Pointer? Function(Pointer txId); typedef transactions_count = Int64 Function(); diff --git a/cw_haven/lib/api/structs/account_row.dart b/cw_haven/lib/api/structs/account_row.dart index c3fc22de1..aa492ee0f 100644 --- a/cw_haven/lib/api/structs/account_row.dart +++ b/cw_haven/lib/api/structs/account_row.dart @@ -3,9 +3,10 @@ import 'package:ffi/ffi.dart'; class AccountRow extends Struct { @Int64() - int id; - Pointer label; + external int id; + + external Pointer label; - String getLabel() => Utf8.fromUtf8(label); + String getLabel() => label.toDartString(); int getId() => id; } diff --git a/cw_haven/lib/api/structs/haven_balance_row.dart b/cw_haven/lib/api/structs/haven_balance_row.dart index 4b68a7bb6..b0f657bca 100644 --- a/cw_haven/lib/api/structs/haven_balance_row.dart +++ b/cw_haven/lib/api/structs/haven_balance_row.dart @@ -3,9 +3,10 @@ import 'package:ffi/ffi.dart'; class HavenBalanceRow extends Struct { @Int64() - int amount; - Pointer assetType; + external int amount; + + external Pointer assetType; int getAmount() => amount; - String getAssetType() => Utf8.fromUtf8(assetType); + String getAssetType() => assetType.toDartString(); } diff --git a/cw_haven/lib/api/structs/haven_rate.dart b/cw_haven/lib/api/structs/haven_rate.dart index 818615559..48f188135 100644 --- a/cw_haven/lib/api/structs/haven_rate.dart +++ b/cw_haven/lib/api/structs/haven_rate.dart @@ -3,9 +3,10 @@ import 'package:ffi/ffi.dart'; class HavenRate extends Struct { @Int64() - int rate; - Pointer assetType; + external int rate; + + external Pointer assetType; int getRate() => rate; - String getAssetType() => Utf8.fromUtf8(assetType); + String getAssetType() => assetType.toDartString(); } diff --git a/cw_haven/lib/api/structs/pending_transaction.dart b/cw_haven/lib/api/structs/pending_transaction.dart index b492f28a0..12e5233f1 100644 --- a/cw_haven/lib/api/structs/pending_transaction.dart +++ b/cw_haven/lib/api/structs/pending_transaction.dart @@ -3,18 +3,22 @@ import 'package:ffi/ffi.dart'; class PendingTransactionRaw extends Struct { @Int64() - int amount; + external int amount; @Int64() - int fee; + external int fee; - Pointer hash; + external Pointer hash; - String getHash() => Utf8.fromUtf8(hash); + String getHash() => hash.toDartString(); } class PendingTransactionDescription { - PendingTransactionDescription({this.amount, this.fee, this.hash, this.pointerAddress}); + PendingTransactionDescription({ + required this.amount, + required this.fee, + required this.hash, + required this.pointerAddress}); final int amount; final int fee; diff --git a/cw_haven/lib/api/structs/subaddress_row.dart b/cw_haven/lib/api/structs/subaddress_row.dart index 1673e00c7..d593a793d 100644 --- a/cw_haven/lib/api/structs/subaddress_row.dart +++ b/cw_haven/lib/api/structs/subaddress_row.dart @@ -3,11 +3,13 @@ import 'package:ffi/ffi.dart'; class SubaddressRow extends Struct { @Int64() - int id; - Pointer address; - Pointer label; + external int id; + + external Pointer address; + + external Pointer label; - String getLabel() => Utf8.fromUtf8(label); - String getAddress() => Utf8.fromUtf8(address); + String getLabel() => label.toDartString(); + String getAddress() => address.toDartString(); int getId() => id; } \ No newline at end of file diff --git a/cw_haven/lib/api/structs/transaction_info_row.dart b/cw_haven/lib/api/structs/transaction_info_row.dart index 68a84e0a2..177cdfde7 100644 --- a/cw_haven/lib/api/structs/transaction_info_row.dart +++ b/cw_haven/lib/api/structs/transaction_info_row.dart @@ -3,42 +3,42 @@ import 'package:ffi/ffi.dart'; class TransactionInfoRow extends Struct { @Uint64() - int amount; + external int amount; @Uint64() - int fee; + external int fee; @Uint64() - int blockHeight; + external int blockHeight; @Uint64() - int confirmations; + external int confirmations; @Uint32() - int subaddrAccount; + external int subaddrAccount; @Int8() - int direction; + external int direction; @Int8() - int isPending; + external int isPending; @Uint32() - int subaddrIndex; + external int subaddrIndex; - Pointer hash; + external Pointer hash; - Pointer paymentId; + external Pointer paymentId; - Pointer assetType; + external Pointer assetType; @Int64() - int datetime; + external int datetime; int getDatetime() => datetime; int getAmount() => amount >= 0 ? amount : amount * -1; bool getIsPending() => isPending != 0; - String getHash() => Utf8.fromUtf8(hash); - String getPaymentId() => Utf8.fromUtf8(paymentId); - String getAssetType() => Utf8.fromUtf8(assetType); + String getHash() => hash.toDartString(); + String getPaymentId() => paymentId.toDartString(); + String getAssetType() => assetType.toDartString(); } diff --git a/cw_haven/lib/api/structs/ut8_box.dart b/cw_haven/lib/api/structs/ut8_box.dart index a6f41bc75..53e678c88 100644 --- a/cw_haven/lib/api/structs/ut8_box.dart +++ b/cw_haven/lib/api/structs/ut8_box.dart @@ -2,7 +2,7 @@ import 'dart:ffi'; import 'package:ffi/ffi.dart'; class Utf8Box extends Struct { - Pointer value; + external Pointer value; - String getValue() => Utf8.fromUtf8(value); + String getValue() => value.toDartString(); } diff --git a/cw_haven/lib/api/subaddress_list.dart b/cw_haven/lib/api/subaddress_list.dart index c735400ec..39dbeab78 100644 --- a/cw_haven/lib/api/subaddress_list.dart +++ b/cw_haven/lib/api/subaddress_list.dart @@ -29,7 +29,7 @@ final subaddrressSetLabelNative = havenApi bool isUpdating = false; -void refreshSubaddresses({@required int accountIndex}) { +void refreshSubaddresses({required int accountIndex}) { try { isUpdating = true; subaddressRefreshNative(accountIndex); @@ -50,18 +50,18 @@ List getAllSubaddresses() { .toList(); } -void addSubaddressSync({int accountIndex, String label}) { - final labelPointer = Utf8.toUtf8(label); +void addSubaddressSync({required int accountIndex, required String label}) { + final labelPointer = label.toNativeUtf8(); subaddrressAddNewNative(accountIndex, labelPointer); - free(labelPointer); + calloc.free(labelPointer); } void setLabelForSubaddressSync( - {int accountIndex, int addressIndex, String label}) { - final labelPointer = Utf8.toUtf8(label); + {required int accountIndex, required int addressIndex, required String label}) { + final labelPointer = label.toNativeUtf8(); subaddrressSetLabelNative(accountIndex, addressIndex, labelPointer); - free(labelPointer); + calloc.free(labelPointer); } void _addSubaddress(Map args) { @@ -80,14 +80,14 @@ void _setLabelForSubaddress(Map args) { accountIndex: accountIndex, addressIndex: addressIndex, label: label); } -Future addSubaddress({int accountIndex, String label}) async { +Future addSubaddress({required int accountIndex, required String label}) async { await compute, void>( _addSubaddress, {'accountIndex': accountIndex, 'label': label}); await store(); } Future setLabelForSubaddress( - {int accountIndex, int addressIndex, String label}) async { + {required int accountIndex, required int addressIndex, required String label}) async { await compute, void>(_setLabelForSubaddress, { 'accountIndex': accountIndex, 'addressIndex': addressIndex, diff --git a/cw_haven/lib/api/transaction_history.dart b/cw_haven/lib/api/transaction_history.dart index 185207941..f658133e1 100644 --- a/cw_haven/lib/api/transaction_history.dart +++ b/cw_haven/lib/api/transaction_history.dart @@ -40,16 +40,16 @@ final getTxKeyNative = havenApi .asFunction(); String getTxKey(String txId) { - final txIdPointer = Utf8.toUtf8(txId); + final txIdPointer = txId.toNativeUtf8(); final keyPointer = getTxKeyNative(txIdPointer); - free(txIdPointer); + calloc.free(txIdPointer); if (keyPointer != null) { return convertUTF8ToString(pointer: keyPointer); } - return null; + return ''; } void refreshTransactions() => transactionsRefreshNative(); @@ -67,18 +67,18 @@ List getAllTransations() { } PendingTransactionDescription createTransactionSync( - {String address, - String assetType, - String paymentId, - String amount, - int priorityRaw, + {required String address, + required String assetType, + required String paymentId, + required int priorityRaw, + String? amount, int accountIndex = 0}) { - final addressPointer = Utf8.toUtf8(address); - final assetTypePointer = Utf8.toUtf8(assetType); - final paymentIdPointer = Utf8.toUtf8(paymentId); - final amountPointer = amount != null ? Utf8.toUtf8(amount) : nullptr; - final errorMessagePointer = allocate(); - final pendingTransactionRawPointer = allocate(); + final addressPointer = address.toNativeUtf8(); + final assetTypePointer = assetType.toNativeUtf8(); + final paymentIdPointer = paymentId.toNativeUtf8(); + final amountPointer = amount != null ? amount.toNativeUtf8() : nullptr; + final errorMessagePointer = calloc(); + final pendingTransactionRawPointer = calloc(); final created = transactionCreateNative( addressPointer, assetTypePointer, @@ -90,17 +90,17 @@ PendingTransactionDescription createTransactionSync( pendingTransactionRawPointer) != 0; - free(addressPointer); - free(assetTypePointer); - free(paymentIdPointer); + calloc.free(addressPointer); + calloc.free(assetTypePointer); + calloc.free(paymentIdPointer); if (amountPointer != nullptr) { - free(amountPointer); + calloc.free(amountPointer); } if (!created) { final message = errorMessagePointer.ref.getValue(); - free(errorMessagePointer); + calloc.free(errorMessagePointer); throw CreationTransactionException(message: message); } @@ -112,28 +112,28 @@ PendingTransactionDescription createTransactionSync( } PendingTransactionDescription createTransactionMultDestSync( - {List outputs, - String assetType, - String paymentId, - int priorityRaw, + {required List outputs, + required String assetType, + required String paymentId, + required int priorityRaw, int accountIndex = 0}) { final int size = outputs.length; final List> addressesPointers = outputs.map((output) => - Utf8.toUtf8(output.address)).toList(); - final Pointer> addressesPointerPointer = allocate(count: size); + output.address.toNativeUtf8()).toList(); + final Pointer> addressesPointerPointer = calloc(size); final List> amountsPointers = outputs.map((output) => - Utf8.toUtf8(output.amount)).toList(); - final Pointer> amountsPointerPointer = allocate(count: size); + output.amount.toNativeUtf8()).toList(); + final Pointer> amountsPointerPointer = calloc( size); for (int i = 0; i < size; i++) { addressesPointerPointer[i] = addressesPointers[i]; amountsPointerPointer[i] = amountsPointers[i]; } - final assetTypePointer = Utf8.toUtf8(assetType); - final paymentIdPointer = Utf8.toUtf8(paymentId); - final errorMessagePointer = allocate(); - final pendingTransactionRawPointer = allocate(); + final assetTypePointer = assetType.toNativeUtf8(); + final paymentIdPointer = paymentId.toNativeUtf8(); + final errorMessagePointer = calloc(); + final pendingTransactionRawPointer = calloc(); final created = transactionCreateMultDestNative( addressesPointerPointer, assetTypePointer, @@ -146,18 +146,18 @@ PendingTransactionDescription createTransactionMultDestSync( pendingTransactionRawPointer) != 0; - free(addressesPointerPointer); - free(assetTypePointer); - free(amountsPointerPointer); + calloc.free(addressesPointerPointer); + calloc.free(assetTypePointer); + calloc.free(amountsPointerPointer); - addressesPointers.forEach((element) => free(element)); - amountsPointers.forEach((element) => free(element)); + addressesPointers.forEach((element) => calloc.free(element)); + amountsPointers.forEach((element) => calloc.free(element)); - free(paymentIdPointer); + calloc.free(paymentIdPointer); if (!created) { final message = errorMessagePointer.ref.getValue(); - free(errorMessagePointer); + calloc.free(errorMessagePointer); throw CreationTransactionException(message: message); } @@ -168,17 +168,17 @@ PendingTransactionDescription createTransactionMultDestSync( pointerAddress: pendingTransactionRawPointer.address); } -void commitTransactionFromPointerAddress({int address}) => commitTransaction( +void commitTransactionFromPointerAddress({required int address}) => commitTransaction( transactionPointer: Pointer.fromAddress(address)); -void commitTransaction({Pointer transactionPointer}) { - final errorMessagePointer = allocate(); +void commitTransaction({required Pointer transactionPointer}) { + final errorMessagePointer = calloc(); final isCommited = transactionCommitNative(transactionPointer, errorMessagePointer) != 0; if (!isCommited) { final message = errorMessagePointer.ref.getValue(); - free(errorMessagePointer); + calloc.free(errorMessagePointer); throw CreationTransactionException(message: message); } } @@ -216,11 +216,11 @@ PendingTransactionDescription _createTransactionMultDestSync(Map args) { } Future createTransaction( - {String address, - String assetType, + {required String address, + required String assetType, + required int priorityRaw, + String? amount, String paymentId = '', - String amount, - int priorityRaw, int accountIndex = 0}) => compute(_createTransactionSync, { 'address': address, @@ -232,10 +232,10 @@ Future createTransaction( }); Future createTransactionMultDest( - {List outputs, - String assetType, + {required List outputs, + required int priorityRaw, + String? assetType, String paymentId = '', - int priorityRaw, int accountIndex = 0}) => compute(_createTransactionMultDestSync, { 'outputs': outputs, diff --git a/cw_haven/lib/api/types.dart b/cw_haven/lib/api/types.dart index 878297501..f1dc0e26b 100644 --- a/cw_haven/lib/api/types.dart +++ b/cw_haven/lib/api/types.dart @@ -39,7 +39,7 @@ typedef GetNodeHeight = int Function(); typedef IsConnected = int Function(); typedef SetupNode = int Function( - Pointer, Pointer, Pointer, int, int, Pointer); + Pointer, Pointer?, Pointer?, int, int, Pointer); typedef StartRefresh = void Function(); @@ -84,7 +84,7 @@ typedef AccountSetLabel = void Function(int accountIndex, Pointer label); typedef TransactionsRefresh = void Function(); -typedef GetTxKey = Pointer Function(Pointer txId); +typedef GetTxKey = Pointer? Function(Pointer txId); typedef TransactionsCount = int Function(); diff --git a/cw_haven/lib/api/wallet.dart b/cw_haven/lib/api/wallet.dart index 3370fd3e0..2b85f60e2 100644 --- a/cw_haven/lib/api/wallet.dart +++ b/cw_haven/lib/api/wallet.dart @@ -142,24 +142,24 @@ int getNodeHeightSync() => getNodeHeightNative(); bool isConnectedSync() => isConnectedNative() != 0; bool setupNodeSync( - {String address, - String login, - String password, + {required String address, + String? login, + String? password, bool useSSL = false, bool isLightWallet = false}) { - final addressPointer = Utf8.toUtf8(address); - Pointer loginPointer; - Pointer passwordPointer; + final addressPointer = address.toNativeUtf8(); + Pointer? loginPointer; + Pointer? passwordPointer; if (login != null) { - loginPointer = Utf8.toUtf8(login); + loginPointer = login.toNativeUtf8(); } if (password != null) { - passwordPointer = Utf8.toUtf8(password); + passwordPointer = password.toNativeUtf8(); } - final errorMessagePointer = allocate(); + final errorMessagePointer = ''.toNativeUtf8(); final isSetupNode = setupNodeNative( addressPointer, loginPointer, @@ -169,9 +169,15 @@ bool setupNodeSync( errorMessagePointer) != 0; - free(addressPointer); - free(loginPointer); - free(passwordPointer); + calloc.free(addressPointer); + + if (loginPointer != null) { + calloc.free(loginPointer); + } + + if (passwordPointer != null) { + calloc.free(passwordPointer); + } if (!isSetupNode) { throw SetupWalletException( @@ -185,31 +191,31 @@ void startRefreshSync() => startRefreshNative(); Future connectToNode() async => connecToNodeNative() != 0; -void setRefreshFromBlockHeight({int height}) => +void setRefreshFromBlockHeight({required int height}) => setRefreshFromBlockHeightNative(height); -void setRecoveringFromSeed({bool isRecovery}) => +void setRecoveringFromSeed({required bool isRecovery}) => setRecoveringFromSeedNative(_boolToInt(isRecovery)); void storeSync() { - final pathPointer = Utf8.toUtf8(''); + final pathPointer = ''.toNativeUtf8(); storeNative(pathPointer); - free(pathPointer); + calloc.free(pathPointer); } void setPasswordSync(String password) { - final passwordPointer = Utf8.toUtf8(password); - final errorMessagePointer = allocate(); + final passwordPointer = password.toNativeUtf8(); + final errorMessagePointer = calloc(); final changed = setPasswordNative(passwordPointer, errorMessagePointer) != 0; - free(passwordPointer); + calloc.free(passwordPointer); if (!changed) { final message = errorMessagePointer.ref.getValue(); - free(errorMessagePointer); + calloc.free(errorMessagePointer); throw Exception(message); } - free(errorMessagePointer); + calloc.free(errorMessagePointer); } void closeCurrentWallet() => closeCurrentWalletNative(); @@ -227,16 +233,15 @@ String getPublicSpendKey() => convertUTF8ToString(pointer: getPublicSpendKeyNative()); class SyncListener { - SyncListener(this.onNewBlock, this.onNewTransaction) { - _cachedBlockchainHeight = 0; - _lastKnownBlockHeight = 0; - _initialSyncHeight = 0; - } + SyncListener(this.onNewBlock, this.onNewTransaction) + : _cachedBlockchainHeight = 0, + _lastKnownBlockHeight = 0, + _initialSyncHeight = 0; void Function(int, int, double) onNewBlock; void Function() onNewTransaction; - Timer _updateSyncInfoTimer; + Timer? _updateSyncInfoTimer; int _cachedBlockchainHeight; int _lastKnownBlockHeight; int _initialSyncHeight; @@ -325,13 +330,13 @@ int _getNodeHeight(Object _) => getNodeHeightSync(); void startRefresh() => startRefreshSync(); -Future setupNode( - {String address, - String login, - String password, +Future setupNode( + {required String address, + String? login, + String? password, bool useSSL = false, bool isLightWallet = false}) => - compute, void>(_setupNodeSync, { + compute, void>(_setupNodeSync, { 'address': address, 'login': login, 'password': password, @@ -339,7 +344,7 @@ Future setupNode( 'isLightWallet': isLightWallet }); -Future store() => compute(_storeSync, 0); +Future store() => compute(_storeSync, 0); Future isConnected() => compute(_isConnected, 0); diff --git a/cw_haven/lib/api/wallet_manager.dart b/cw_haven/lib/api/wallet_manager.dart index d134dcbb4..627fc226a 100644 --- a/cw_haven/lib/api/wallet_manager.dart +++ b/cw_haven/lib/api/wallet_manager.dart @@ -38,18 +38,18 @@ final errorStringNative = havenApi .asFunction(); void createWalletSync( - {String path, String password, String language, int nettype = 0}) { - final pathPointer = Utf8.toUtf8(path); - final passwordPointer = Utf8.toUtf8(password); - final languagePointer = Utf8.toUtf8(language); - final errorMessagePointer = allocate(); + {required String path, required String password, required String language, int nettype = 0}) { + final pathPointer = path.toNativeUtf8(); + final passwordPointer = password.toNativeUtf8(); + final languagePointer = language.toNativeUtf8(); + final errorMessagePointer = ''.toNativeUtf8(); final isWalletCreated = createWalletNative(pathPointer, passwordPointer, languagePointer, nettype, errorMessagePointer) != 0; - free(pathPointer); - free(passwordPointer); - free(languagePointer); + calloc.free(pathPointer); + calloc.free(passwordPointer); + calloc.free(languagePointer); if (!isWalletCreated) { throw WalletCreationException( @@ -59,25 +59,25 @@ void createWalletSync( // setupNodeSync(address: "node.moneroworld.com:18089"); } -bool isWalletExistSync({String path}) { - final pathPointer = Utf8.toUtf8(path); +bool isWalletExistSync({required String path}) { + final pathPointer = path.toNativeUtf8(); final isExist = isWalletExistNative(pathPointer) != 0; - free(pathPointer); + calloc.free(pathPointer); return isExist; } void restoreWalletFromSeedSync( - {String path, - String password, - String seed, + {required String path, + required String password, + required String seed, int nettype = 0, int restoreHeight = 0}) { - final pathPointer = Utf8.toUtf8(path); - final passwordPointer = Utf8.toUtf8(password); - final seedPointer = Utf8.toUtf8(seed); - final errorMessagePointer = allocate(); + final pathPointer = path.toNativeUtf8(); + final passwordPointer = password.toNativeUtf8(); + final seedPointer = seed.toNativeUtf8(); + final errorMessagePointer = ''.toNativeUtf8(); final isWalletRestored = restoreWalletFromSeedNative( pathPointer, passwordPointer, @@ -87,9 +87,9 @@ void restoreWalletFromSeedSync( errorMessagePointer) != 0; - free(pathPointer); - free(passwordPointer); - free(seedPointer); + calloc.free(pathPointer); + calloc.free(passwordPointer); + calloc.free(seedPointer); if (!isWalletRestored) { throw WalletRestoreFromSeedException( @@ -98,21 +98,21 @@ void restoreWalletFromSeedSync( } void restoreWalletFromKeysSync( - {String path, - String password, - String language, - String address, - String viewKey, - String spendKey, + {required String path, + required String password, + required String language, + required String address, + required String viewKey, + required String spendKey, int nettype = 0, int restoreHeight = 0}) { - final pathPointer = Utf8.toUtf8(path); - final passwordPointer = Utf8.toUtf8(password); - final languagePointer = Utf8.toUtf8(language); - final addressPointer = Utf8.toUtf8(address); - final viewKeyPointer = Utf8.toUtf8(viewKey); - final spendKeyPointer = Utf8.toUtf8(spendKey); - final errorMessagePointer = allocate(); + final pathPointer = path.toNativeUtf8(); + final passwordPointer = password.toNativeUtf8(); + final languagePointer = language.toNativeUtf8(); + final addressPointer = address.toNativeUtf8(); + final viewKeyPointer = viewKey.toNativeUtf8(); + final spendKeyPointer = spendKey.toNativeUtf8(); + final errorMessagePointer = ''.toNativeUtf8(); final isWalletRestored = restoreWalletFromKeysNative( pathPointer, passwordPointer, @@ -125,12 +125,12 @@ void restoreWalletFromKeysSync( errorMessagePointer) != 0; - free(pathPointer); - free(passwordPointer); - free(languagePointer); - free(addressPointer); - free(viewKeyPointer); - free(spendKeyPointer); + calloc.free(pathPointer); + calloc.free(passwordPointer); + calloc.free(languagePointer); + calloc.free(addressPointer); + calloc.free(viewKeyPointer); + calloc.free(spendKeyPointer); if (!isWalletRestored) { throw WalletRestoreFromKeysException( @@ -138,12 +138,12 @@ void restoreWalletFromKeysSync( } } -void loadWallet({String path, String password, int nettype = 0}) { - final pathPointer = Utf8.toUtf8(path); - final passwordPointer = Utf8.toUtf8(password); +void loadWallet({required String path, required String password, int nettype = 0}) { + final pathPointer = path.toNativeUtf8(); + final passwordPointer = password.toNativeUtf8(); final loaded = loadWalletNative(pathPointer, passwordPointer, nettype) != 0; - free(pathPointer); - free(passwordPointer); + calloc.free(pathPointer); + calloc.free(passwordPointer); if (!loaded) { throw WalletOpeningException( @@ -189,20 +189,20 @@ void _restoreFromKeys(Map args) { } Future _openWallet(Map args) async => - loadWallet(path: args['path'], password: args['password']); + loadWallet(path: args['path'] as String, password: args['password'] as String); bool _isWalletExist(String path) => isWalletExistSync(path: path); -void openWallet({String path, String password, int nettype = 0}) async => +void openWallet({required String path, required String password, int nettype = 0}) async => loadWallet(path: path, password: password, nettype: nettype); Future openWalletAsync(Map args) async => compute(_openWallet, args); Future createWallet( - {String path, - String password, - String language, + {required String path, + required String password, + required String language, int nettype = 0}) async => compute(_createWallet, { 'path': path, @@ -211,10 +211,10 @@ Future createWallet( 'nettype': nettype }); -Future restoreFromSeed( - {String path, - String password, - String seed, +Future restoreFromSeed( + {required String path, + required String password, + required String seed, int nettype = 0, int restoreHeight = 0}) async => compute, void>(_restoreFromSeed, { @@ -225,13 +225,13 @@ Future restoreFromSeed( 'restoreHeight': restoreHeight }); -Future restoreFromKeys( - {String path, - String password, - String language, - String address, - String viewKey, - String spendKey, +Future restoreFromKeys( + {required String path, + required String password, + required String language, + required String address, + required String viewKey, + required String spendKey, int nettype = 0, int restoreHeight = 0}) async => compute, void>(_restoreFromKeys, { @@ -245,4 +245,4 @@ Future restoreFromKeys( 'restoreHeight': restoreHeight }); -Future isWalletExist({String path}) => compute(_isWalletExist, path); +Future isWalletExist({required String path}) => compute(_isWalletExist, path); diff --git a/cw_haven/lib/haven_account_list.dart b/cw_haven/lib/haven_account_list.dart index ad1cd2a7b..9399efc27 100644 --- a/cw_haven/lib/haven_account_list.dart +++ b/cw_haven/lib/haven_account_list.dart @@ -53,13 +53,13 @@ abstract class HavenAccountListBase extends AccountList with Store { .toList(); @override - Future addAccount({String label}) async { + Future addAccount({required String label}) async { await account_list.addAccount(label: label); update(); } @override - Future setLabelAccount({int accountIndex, String label}) async { + Future setLabelAccount({required int accountIndex, required String label}) async { await account_list.setLabelForAccount( accountIndex: accountIndex, label: label); update(); diff --git a/cw_haven/lib/haven_balance.dart b/cw_haven/lib/haven_balance.dart index 17172fa9c..7d257ded9 100644 --- a/cw_haven/lib/haven_balance.dart +++ b/cw_haven/lib/haven_balance.dart @@ -9,7 +9,7 @@ const inactiveBalances = [ CryptoCurrency.xnok, CryptoCurrency.xnzd]; -Map getHavenBalance({int accountIndex}) { +Map getHavenBalance({required int accountIndex}) { final fullBalances = getHavenFullBalance(accountIndex: accountIndex); final unlockedBalances = getHavenUnlockedBalance(accountIndex: accountIndex); final havenBalances = {}; diff --git a/cw_haven/lib/haven_subaddress_list.dart b/cw_haven/lib/haven_subaddress_list.dart index b6213d784..b40b3484c 100644 --- a/cw_haven/lib/haven_subaddress_list.dart +++ b/cw_haven/lib/haven_subaddress_list.dart @@ -10,11 +10,10 @@ class HavenSubaddressList = HavenSubaddressListBase with _$HavenSubaddressList; abstract class HavenSubaddressListBase with Store { - HavenSubaddressListBase() { - _isRefreshing = false; - _isUpdating = false; + HavenSubaddressListBase() + : _isRefreshing = false, + _isUpdating = false, subaddresses = ObservableList(); - } @observable ObservableList subaddresses; @@ -22,7 +21,7 @@ abstract class HavenSubaddressListBase with Store { bool _isRefreshing; bool _isUpdating; - void update({int accountIndex}) { + void update({required int accountIndex}) { if (_isUpdating) { return; } @@ -56,20 +55,20 @@ abstract class HavenSubaddressListBase with Store { .toList(); } - Future addSubaddress({int accountIndex, String label}) async { + Future addSubaddress({required int accountIndex, required String label}) async { await subaddress_list.addSubaddress( accountIndex: accountIndex, label: label); update(accountIndex: accountIndex); } - Future setLabelSubaddress( - {int accountIndex, int addressIndex, String label}) async { + Future setLabelSubaddress( + {required int accountIndex, required int addressIndex, required String label}) async { await subaddress_list.setLabelForSubaddress( accountIndex: accountIndex, addressIndex: addressIndex, label: label); update(accountIndex: accountIndex); } - void refresh({int accountIndex}) { + void refresh({required int accountIndex}) { if (_isRefreshing) { return; } diff --git a/cw_haven/lib/haven_transaction_creation_credentials.dart b/cw_haven/lib/haven_transaction_creation_credentials.dart index 88525f0fd..4de41a504 100644 --- a/cw_haven/lib/haven_transaction_creation_credentials.dart +++ b/cw_haven/lib/haven_transaction_creation_credentials.dart @@ -2,7 +2,10 @@ import 'package:cw_core/monero_transaction_priority.dart'; import 'package:cw_core/output_info.dart'; class HavenTransactionCreationCredentials { - HavenTransactionCreationCredentials({this.outputs, this.priority, this.assetType}); + HavenTransactionCreationCredentials({ + required this.outputs, + required this.priority, + required this.assetType}); final List outputs; final MoneroTransactionPriority priority; diff --git a/cw_haven/lib/haven_transaction_info.dart b/cw_haven/lib/haven_transaction_info.dart index 16f032541..277370467 100644 --- a/cw_haven/lib/haven_transaction_info.dart +++ b/cw_haven/lib/haven_transaction_info.dart @@ -10,20 +10,20 @@ class HavenTransactionInfo extends TransactionInfo { HavenTransactionInfo(this.id, this.height, this.direction, this.date, this.isPending, this.amount, this.accountIndex, this.addressIndex, this.fee); - HavenTransactionInfo.fromMap(Map map) + HavenTransactionInfo.fromMap(Map map) : id = (map['hash'] ?? '') as String, height = (map['height'] ?? 0) as int, direction = parseTransactionDirectionFromNumber(map['direction'] as String) ?? TransactionDirection.incoming, date = DateTime.fromMillisecondsSinceEpoch( - (int.parse(map['timestamp'] as String) ?? 0) * 1000), + int.parse(map['timestamp'] as String? ?? '0') * 1000), isPending = parseBoolFromString(map['isPending'] as String), amount = map['amount'] as int, accountIndex = int.parse(map['accountIndex'] as String), addressIndex = map['addressIndex'] as int, key = getTxKey((map['hash'] ?? '') as String), - fee = map['fee'] as int ?? 0; + fee = map['fee'] as int? ?? 0; HavenTransactionInfo.fromRow(TransactionInfoRow row) : id = row.getHash(), @@ -48,11 +48,10 @@ class HavenTransactionInfo extends TransactionInfo { final int amount; final int fee; final int addressIndex; - String recipientAddress; - String key; - String assetType; - - String _fiatAmount; + late String recipientAddress; + late String assetType; + String? _fiatAmount; + String? key; @override String amountFormatted() => diff --git a/cw_haven/lib/haven_wallet.dart b/cw_haven/lib/haven_wallet.dart index c107d2f52..4f360bdff 100644 --- a/cw_haven/lib/haven_wallet.dart +++ b/cw_haven/lib/haven_wallet.dart @@ -37,15 +37,19 @@ class HavenWallet = HavenWalletBase with _$HavenWallet; abstract class HavenWalletBase extends WalletBase with Store { - HavenWalletBase({WalletInfo walletInfo}) - : super(walletInfo) { + HavenWalletBase({required WalletInfo walletInfo}) + : balance = ObservableMap.of(getHavenBalance(accountIndex: 0)), + _isTransactionUpdating = false, + _hasSyncAfterStartup = false, + walletAddresses = HavenWalletAddresses(walletInfo), + syncStatus = NotConnectedSyncStatus(), + super(walletInfo) { transactionHistory = HavenTransactionHistory(); - balance = ObservableMap.of(getHavenBalance(accountIndex: 0)); - _isTransactionUpdating = false; - _hasSyncAfterStartup = false; - walletAddresses = HavenWalletAddresses(walletInfo); _onAccountChangeReaction = reaction((_) => walletAddresses.account, - (Account account) { + (Account? account) { + if (account == null) { + return; + } balance.addAll(getHavenBalance(accountIndex: account.id)); walletAddresses.updateSubaddressList(accountIndex: account.id); }); @@ -74,15 +78,15 @@ abstract class HavenWalletBase extends WalletBase init() async { await walletAddresses.init(); - balance.addAll(getHavenBalance(accountIndex: walletAddresses.account.id ?? 0)); + balance.addAll(getHavenBalance(accountIndex: walletAddresses.account?.id ?? 0)); _setListeners(); await updateTransactions(); @@ -103,19 +107,19 @@ abstract class HavenWalletBase extends WalletBase connectToNode({@required Node node}) async { + Future connectToNode({required Node node}) async { try { syncStatus = ConnectingSyncStatus(); await haven_wallet.setupNode( address: node.uriRaw, login: node.login, password: node.password, - useSSL: node.useSSL, + useSSL: node.useSSL ?? false, isLightWallet: false); // FIXME: hardcoded value syncStatus = ConnectedSyncStatus(); } catch (e) { @@ -148,8 +152,8 @@ abstract class HavenWalletBase extends WalletBase 1; final assetType = CryptoCurrency.fromString(_credentials.assetType.toLowerCase()); - final balances = getHavenBalance(accountIndex: walletAddresses.account.id); - final unlockedBalance = balances[assetType].unlockedBalance; + final balances = getHavenBalance(accountIndex: walletAddresses.account!.id); + final unlockedBalance = balances[assetType]!.unlockedBalance; PendingTransactionDescription pendingTransactionDescription; @@ -159,12 +163,12 @@ abstract class HavenWalletBase extends WalletBase item.sendAll - || item.formattedCryptoAmount <= 0)) { + || (item.formattedCryptoAmount ?? 0) <= 0)) { throw HavenTransactionCreationException('Wrong balance. Not enough XMR on your balance.'); } final int totalAmount = outputs.fold(0, (acc, value) => - acc + value.formattedCryptoAmount); + acc + (value.formattedCryptoAmount ?? 0)); if (unlockedBalance < totalAmount) { throw HavenTransactionCreationException('Wrong balance. Not enough XMR on your balance.'); @@ -173,21 +177,23 @@ abstract class HavenWalletBase extends WalletBase MoneroOutput( address: output.address, - amount: output.cryptoAmount.replaceAll(',', '.'))) + amount: output.cryptoAmount!.replaceAll(',', '.'))) .toList(); pendingTransactionDescription = await transaction_history.createTransactionMultDest( outputs: moneroOutputs, priorityRaw: _credentials.priority.serialize(), - accountIndex: walletAddresses.account.id); + accountIndex: walletAddresses.account!.id); } else { final output = outputs.first; - final address = output.address; + final address = output.isParsedAddress && (output.extractedAddress?.isNotEmpty ?? false) + ? output.extractedAddress! + : output.address; final amount = output.sendAll ? null - : output.cryptoAmount.replaceAll(',', '.'); - final formattedAmount = output.sendAll + : output.cryptoAmount!.replaceAll(',', '.'); + final int? formattedAmount = output.sendAll ? null : output.formattedCryptoAmount; @@ -205,21 +211,21 @@ abstract class HavenWalletBase extends WalletBase rescan({int height}) async { + Future rescan({required int height}) async { walletInfo.restoreHeight = height; walletInfo.isRecovery = true; haven_wallet.setRefreshFromBlockHeight(height: height); @@ -346,7 +352,7 @@ abstract class HavenWalletBase extends WalletBase - balance.addAll(getHavenBalance(accountIndex: walletAddresses.account.id)); + balance.addAll(getHavenBalance(accountIndex: walletAddresses.account!.id)); Future _askForUpdateTransactionHistory() async => await updateTransactions(); diff --git a/cw_haven/lib/haven_wallet_addresses.dart b/cw_haven/lib/haven_wallet_addresses.dart index 7afad6205..ff6b6aa3f 100644 --- a/cw_haven/lib/haven_wallet_addresses.dart +++ b/cw_haven/lib/haven_wallet_addresses.dart @@ -12,21 +12,22 @@ class HavenWalletAddresses = HavenWalletAddressesBase with _$HavenWalletAddresses; abstract class HavenWalletAddressesBase extends WalletAddressesWithAccount with Store { - HavenWalletAddressesBase(WalletInfo walletInfo) : super(walletInfo) { - accountList = HavenAccountList(); - subaddressList = HavenSubaddressList(); - } + HavenWalletAddressesBase(WalletInfo walletInfo) + : accountList = HavenAccountList(), + subaddressList = HavenSubaddressList(), + address = '', + super(walletInfo); @override @observable String address; - @override + // @override @observable - Account account; + Account? account; @observable - Subaddress subaddress; + Subaddress? subaddress; HavenSubaddressList subaddressList; @@ -36,7 +37,7 @@ abstract class HavenWalletAddressesBase extends WalletAddressesWithAccount init() async { accountList.update(); account = accountList.accounts.first; - updateSubaddressList(accountIndex: account.id ?? 0); + updateSubaddressList(accountIndex: account?.id ?? 0); await updateAddressesInBox(); } @@ -62,14 +63,14 @@ abstract class HavenWalletAddressesBase extends WalletAddressesWithAccount info.id == WalletBase.idFor(name, getType()), - orElse: () => null); + final walletInfo = walletInfoSource.values.firstWhereOrNull( + (info) => info.id == WalletBase.idFor(name, getType()))!; final wallet = HavenWallet(walletInfo: walletInfo); final isValid = wallet.walletAddresses.validate(); @@ -155,13 +158,13 @@ class HavenWalletService extends WalletService< final path = await pathForWallet(name: credentials.name, type: getType()); await haven_wallet_manager.restoreFromKeys( path: path, - password: credentials.password, + password: credentials.password!, language: credentials.language, - restoreHeight: credentials.height, + restoreHeight: credentials.height!, address: credentials.address, viewKey: credentials.viewKey, spendKey: credentials.spendKey); - final wallet = HavenWallet(walletInfo: credentials.walletInfo); + final wallet = HavenWallet(walletInfo: credentials.walletInfo!); await wallet.init(); return wallet; @@ -179,10 +182,10 @@ class HavenWalletService extends WalletService< final path = await pathForWallet(name: credentials.name, type: getType()); await haven_wallet_manager.restoreFromSeed( path: path, - password: credentials.password, + password: credentials.password!, seed: credentials.mnemonic, - restoreHeight: credentials.height); - final wallet = HavenWallet(walletInfo: credentials.walletInfo); + restoreHeight: credentials.height!); + final wallet = HavenWallet(walletInfo: credentials.walletInfo!); await wallet.init(); return wallet; diff --git a/cw_haven/lib/pending_haven_transaction.dart b/cw_haven/lib/pending_haven_transaction.dart index d56b5096c..1d95de08c 100644 --- a/cw_haven/lib/pending_haven_transaction.dart +++ b/cw_haven/lib/pending_haven_transaction.dart @@ -2,7 +2,7 @@ import 'package:cw_haven/api/structs/pending_transaction.dart'; import 'package:cw_haven/api/transaction_history.dart' as haven_transaction_history; import 'package:cw_core/crypto_currency.dart'; -import 'package:cake_wallet/core/amount_converter.dart'; +import 'package:cw_core/amount_converter.dart'; import 'package:cw_core/pending_transaction.dart'; class DoubleSpendException implements Exception { diff --git a/cw_haven/lib/update_haven_rate.dart b/cw_haven/lib/update_haven_rate.dart index 967247af5..a7d5b2c77 100644 --- a/cw_haven/lib/update_haven_rate.dart +++ b/cw_haven/lib/update_haven_rate.dart @@ -1,7 +1,7 @@ //import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart'; import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/monero_amount_format.dart'; -import 'package:cw_haven/balance_list.dart'; +import 'package:cw_haven/api/balance_list.dart'; //Future updateHavenRate(FiatConversionStore fiatConversionStore) async { // final rate = getRate(); diff --git a/cw_haven/pubspec.lock b/cw_haven/pubspec.lock index f9b6c4890..6d741c268 100644 --- a/cw_haven/pubspec.lock +++ b/cw_haven/pubspec.lock @@ -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,63 +105,49 @@ 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" cw_core: dependency: "direct main" description: @@ -175,35 +161,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: transitive 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: "direct main" description: name: ffi url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" + version: "1.2.1" file: dependency: transitive description: @@ -229,12 +208,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: @@ -248,42 +234,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: @@ -297,7 +283,7 @@ packages: name: io url: "https://pub.dartlang.org" source: hosted - version: "0.3.5" + version: "1.0.3" js: dependency: transitive description: @@ -311,7 +297,7 @@ packages: name: json_annotation url: "https://pub.dartlang.org" source: hosted - version: "4.0.1" + version: "4.6.0" logging: dependency: transitive description: @@ -325,14 +311,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: @@ -346,63 +339,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.4+3" + version: "2.0.7" pedantic: dependency: transitive description: @@ -423,14 +430,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: @@ -458,21 +465,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 @@ -484,14 +491,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: @@ -519,35 +533,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: @@ -561,7 +568,7 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.2" watcher: dependency: transitive description: @@ -575,21 +582,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: "1.7.4+1" + version: "2.6.1" 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: @@ -598,5 +605,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: ">=2.8.1" diff --git a/cw_haven/pubspec.yaml b/cw_haven/pubspec.yaml index a8d8417be..28f2c315e 100644 --- a/cw_haven/pubspec.yaml +++ b/cw_haven/pubspec.yaml @@ -6,17 +6,17 @@ author: Cake Wallet homepage: https://cakewallet.com environment: - sdk: ">=2.7.0 <3.0.0" + sdk: ">=2.17.5 <3.0.0" flutter: ">=1.20.0" dependencies: flutter: sdk: flutter - ffi: ^0.1.3 - path_provider: ^1.4.0 - http: ^0.12.0+2 - mobx: ^1.2.1+2 - flutter_mobx: ^1.1.0+2 + ffi: ^1.1.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 cw_core: path: ../cw_core @@ -24,10 +24,10 @@ dependencies: 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 + mobx_codegen: ^2.0.7 + build_resolvers: ^2.0.9 + 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 diff --git a/cw_monero/lib/api/account_list.dart b/cw_monero/lib/api/account_list.dart index b8f717d0f..451ba5033 100644 --- a/cw_monero/lib/api/account_list.dart +++ b/cw_monero/lib/api/account_list.dart @@ -50,16 +50,16 @@ List 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 args) { setLabelForAccountSync(label: label, accountIndex: accountIndex); } -Future addAccount({String label}) async { +Future addAccount({required String label}) async { await compute(_addAccount, label); await store(); } -Future setLabelForAccount({int accountIndex, String label}) async { +Future setLabelForAccount({required int accountIndex, required String label}) async { await compute( _setLabelForAccount, {'accountIndex': accountIndex, 'label': label}); await store(); diff --git a/cw_monero/lib/api/convert_utf8_to_string.dart b/cw_monero/lib/api/convert_utf8_to_string.dart index 7fa5a68df..41a6b648a 100644 --- a/cw_monero/lib/api/convert_utf8_to_string.dart +++ b/cw_monero/lib/api/convert_utf8_to_string.dart @@ -1,8 +1,8 @@ import 'dart:ffi'; import 'package:ffi/ffi.dart'; -String convertUTF8ToString({Pointer pointer}) { - final str = Utf8.fromUtf8(pointer); - free(pointer); +String convertUTF8ToString({required Pointer pointer}) { + final str = pointer.toDartString(); + calloc.free(pointer); return str; } \ No newline at end of file diff --git a/cw_monero/lib/api/exceptions/connection_to_node_exception.dart b/cw_monero/lib/api/exceptions/connection_to_node_exception.dart index 6ee272b89..483b0a174 100644 --- a/cw_monero/lib/api/exceptions/connection_to_node_exception.dart +++ b/cw_monero/lib/api/exceptions/connection_to_node_exception.dart @@ -1,5 +1,5 @@ class ConnectionToNodeException implements Exception { - ConnectionToNodeException({this.message}); + ConnectionToNodeException({required this.message}); final String message; } \ No newline at end of file diff --git a/cw_monero/lib/api/exceptions/creation_transaction_exception.dart b/cw_monero/lib/api/exceptions/creation_transaction_exception.dart index bb477d673..7b55ec074 100644 --- a/cw_monero/lib/api/exceptions/creation_transaction_exception.dart +++ b/cw_monero/lib/api/exceptions/creation_transaction_exception.dart @@ -1,5 +1,5 @@ class CreationTransactionException implements Exception { - CreationTransactionException({this.message}); + CreationTransactionException({required this.message}); final String message; diff --git a/cw_monero/lib/api/exceptions/setup_wallet_exception.dart b/cw_monero/lib/api/exceptions/setup_wallet_exception.dart index ce43c0ec6..b6e0c1f18 100644 --- a/cw_monero/lib/api/exceptions/setup_wallet_exception.dart +++ b/cw_monero/lib/api/exceptions/setup_wallet_exception.dart @@ -1,5 +1,5 @@ class SetupWalletException implements Exception { - SetupWalletException({this.message}); + SetupWalletException({required this.message}); final String message; } \ No newline at end of file diff --git a/cw_monero/lib/api/exceptions/wallet_creation_exception.dart b/cw_monero/lib/api/exceptions/wallet_creation_exception.dart index 6b00445ad..6052366b9 100644 --- a/cw_monero/lib/api/exceptions/wallet_creation_exception.dart +++ b/cw_monero/lib/api/exceptions/wallet_creation_exception.dart @@ -1,5 +1,5 @@ class WalletCreationException implements Exception { - WalletCreationException({this.message}); + WalletCreationException({required this.message}); final String message; diff --git a/cw_monero/lib/api/exceptions/wallet_opening_exception.dart b/cw_monero/lib/api/exceptions/wallet_opening_exception.dart index 8d84b0f7e..df7a850a4 100644 --- a/cw_monero/lib/api/exceptions/wallet_opening_exception.dart +++ b/cw_monero/lib/api/exceptions/wallet_opening_exception.dart @@ -1,5 +1,5 @@ class WalletOpeningException implements Exception { - WalletOpeningException({this.message}); + WalletOpeningException({required this.message}); final String message; diff --git a/cw_monero/lib/api/exceptions/wallet_restore_from_keys_exception.dart b/cw_monero/lib/api/exceptions/wallet_restore_from_keys_exception.dart index 5f08437d4..c6b6c6ef7 100644 --- a/cw_monero/lib/api/exceptions/wallet_restore_from_keys_exception.dart +++ b/cw_monero/lib/api/exceptions/wallet_restore_from_keys_exception.dart @@ -1,5 +1,5 @@ class WalletRestoreFromKeysException implements Exception { - WalletRestoreFromKeysException({this.message}); + WalletRestoreFromKeysException({required this.message}); final String message; } \ No newline at end of file diff --git a/cw_monero/lib/api/exceptions/wallet_restore_from_seed_exception.dart b/cw_monero/lib/api/exceptions/wallet_restore_from_seed_exception.dart index fd89e4161..004cd7958 100644 --- a/cw_monero/lib/api/exceptions/wallet_restore_from_seed_exception.dart +++ b/cw_monero/lib/api/exceptions/wallet_restore_from_seed_exception.dart @@ -1,5 +1,5 @@ class WalletRestoreFromSeedException implements Exception { - WalletRestoreFromSeedException({this.message}); + WalletRestoreFromSeedException({required this.message}); final String message; } \ No newline at end of file diff --git a/cw_monero/lib/api/monero_output.dart b/cw_monero/lib/api/monero_output.dart index 831ee1f22..5b468cb48 100644 --- a/cw_monero/lib/api/monero_output.dart +++ b/cw_monero/lib/api/monero_output.dart @@ -1,7 +1,5 @@ -import 'package:flutter/foundation.dart'; - class MoneroOutput { - MoneroOutput({@required this.address, @required this.amount}); + MoneroOutput({required this.address, required this.amount}); final String address; final String amount; diff --git a/cw_monero/lib/api/signatures.dart b/cw_monero/lib/api/signatures.dart index 16f983480..f9e88153e 100644 --- a/cw_monero/lib/api/signatures.dart +++ b/cw_monero/lib/api/signatures.dart @@ -35,7 +35,7 @@ typedef get_node_height = Int64 Function(); typedef is_connected = Int8 Function(); typedef setup_node = Int8 Function( - Pointer, Pointer, Pointer, Int8, Int8, Pointer); + Pointer, Pointer?, Pointer?, Int8, Int8, Pointer); typedef start_refresh = Void Function(); @@ -82,7 +82,7 @@ typedef account_set_label = Void Function( typedef transactions_refresh = Void Function(); -typedef get_tx_key = Pointer Function(Pointer txId); +typedef get_tx_key = Pointer? Function(Pointer txId); typedef transactions_count = Int64 Function(); diff --git a/cw_monero/lib/api/structs/account_row.dart b/cw_monero/lib/api/structs/account_row.dart index c3fc22de1..aa492ee0f 100644 --- a/cw_monero/lib/api/structs/account_row.dart +++ b/cw_monero/lib/api/structs/account_row.dart @@ -3,9 +3,10 @@ import 'package:ffi/ffi.dart'; class AccountRow extends Struct { @Int64() - int id; - Pointer label; + external int id; + + external Pointer label; - String getLabel() => Utf8.fromUtf8(label); + String getLabel() => label.toDartString(); int getId() => id; } diff --git a/cw_monero/lib/api/structs/pending_transaction.dart b/cw_monero/lib/api/structs/pending_transaction.dart index edbd2d0ff..656ed333f 100644 --- a/cw_monero/lib/api/structs/pending_transaction.dart +++ b/cw_monero/lib/api/structs/pending_transaction.dart @@ -3,32 +3,32 @@ import 'package:ffi/ffi.dart'; class PendingTransactionRaw extends Struct { @Int64() - int amount; + external int amount; @Int64() - int fee; + external int fee; - Pointer hash; + external Pointer hash; - Pointer hex; + external Pointer hex; - Pointer txKey; + external Pointer txKey; - String getHash() => Utf8.fromUtf8(hash); + String getHash() => hash.toDartString(); - String getHex() => Utf8.fromUtf8(hex); + String getHex() => hex.toDartString(); - String getKey() => Utf8.fromUtf8(txKey); + String getKey() => txKey.toDartString(); } class PendingTransactionDescription { PendingTransactionDescription({ - this.amount, - this.fee, - this.hash, - this.hex, - this.txKey, - this.pointerAddress}); + required this.amount, + required this.fee, + required this.hash, + required this.hex, + required this.txKey, + required this.pointerAddress}); final int amount; final int fee; diff --git a/cw_monero/lib/api/structs/subaddress_row.dart b/cw_monero/lib/api/structs/subaddress_row.dart index 1673e00c7..d593a793d 100644 --- a/cw_monero/lib/api/structs/subaddress_row.dart +++ b/cw_monero/lib/api/structs/subaddress_row.dart @@ -3,11 +3,13 @@ import 'package:ffi/ffi.dart'; class SubaddressRow extends Struct { @Int64() - int id; - Pointer address; - Pointer label; + external int id; + + external Pointer address; + + external Pointer label; - String getLabel() => Utf8.fromUtf8(label); - String getAddress() => Utf8.fromUtf8(address); + String getLabel() => label.toDartString(); + String getAddress() => address.toDartString(); int getId() => id; } \ No newline at end of file diff --git a/cw_monero/lib/api/structs/transaction_info_row.dart b/cw_monero/lib/api/structs/transaction_info_row.dart index 37b0d02e8..bdcc64d3f 100644 --- a/cw_monero/lib/api/structs/transaction_info_row.dart +++ b/cw_monero/lib/api/structs/transaction_info_row.dart @@ -3,39 +3,39 @@ import 'package:ffi/ffi.dart'; class TransactionInfoRow extends Struct { @Uint64() - int amount; + external int amount; @Uint64() - int fee; + external int fee; @Uint64() - int blockHeight; + external int blockHeight; @Uint64() - int confirmations; + external int confirmations; @Uint32() - int subaddrAccount; + external int subaddrAccount; @Int8() - int direction; + external int direction; @Int8() - int isPending; + external int isPending; @Uint32() - int subaddrIndex; + external int subaddrIndex; - Pointer hash; + external Pointer hash; - Pointer paymentId; + external Pointer paymentId; @Int64() - int datetime; + external int datetime; int getDatetime() => datetime; int getAmount() => amount >= 0 ? amount : amount * -1; bool getIsPending() => isPending != 0; - String getHash() => Utf8.fromUtf8(hash); - String getPaymentId() => Utf8.fromUtf8(paymentId); + String getHash() => hash.toDartString(); + String getPaymentId() => paymentId.toDartString(); } diff --git a/cw_monero/lib/api/structs/ut8_box.dart b/cw_monero/lib/api/structs/ut8_box.dart index a6f41bc75..53e678c88 100644 --- a/cw_monero/lib/api/structs/ut8_box.dart +++ b/cw_monero/lib/api/structs/ut8_box.dart @@ -2,7 +2,7 @@ import 'dart:ffi'; import 'package:ffi/ffi.dart'; class Utf8Box extends Struct { - Pointer value; + external Pointer value; - String getValue() => Utf8.fromUtf8(value); + String getValue() => value.toDartString(); } diff --git a/cw_monero/lib/api/subaddress_list.dart b/cw_monero/lib/api/subaddress_list.dart index 88acb743a..1c1f1253f 100644 --- a/cw_monero/lib/api/subaddress_list.dart +++ b/cw_monero/lib/api/subaddress_list.dart @@ -29,7 +29,7 @@ final subaddrressSetLabelNative = moneroApi bool isUpdating = false; -void refreshSubaddresses({@required int accountIndex}) { +void refreshSubaddresses({required int accountIndex}) { try { isUpdating = true; subaddressRefreshNative(accountIndex); @@ -50,18 +50,18 @@ List getAllSubaddresses() { .toList(); } -void addSubaddressSync({int accountIndex, String label}) { - final labelPointer = Utf8.toUtf8(label); +void addSubaddressSync({required int accountIndex, required String label}) { + final labelPointer = label.toNativeUtf8(); subaddrressAddNewNative(accountIndex, labelPointer); - free(labelPointer); + calloc.free(labelPointer); } void setLabelForSubaddressSync( - {int accountIndex, int addressIndex, String label}) { - final labelPointer = Utf8.toUtf8(label); + {required int accountIndex, required int addressIndex, required String label}) { + final labelPointer = label.toNativeUtf8(); subaddrressSetLabelNative(accountIndex, addressIndex, labelPointer); - free(labelPointer); + calloc.free(labelPointer); } void _addSubaddress(Map args) { @@ -80,14 +80,14 @@ void _setLabelForSubaddress(Map args) { accountIndex: accountIndex, addressIndex: addressIndex, label: label); } -Future addSubaddress({int accountIndex, String label}) async { +Future addSubaddress({required int accountIndex, required String label}) async { await compute, void>( _addSubaddress, {'accountIndex': accountIndex, 'label': label}); await store(); } -Future setLabelForSubaddress( - {int accountIndex, int addressIndex, String label}) async { +Future setLabelForSubaddress( + {required int accountIndex, required int addressIndex, required String label}) async { await compute, void>(_setLabelForSubaddress, { 'accountIndex': accountIndex, 'addressIndex': addressIndex, diff --git a/cw_monero/lib/api/transaction_history.dart b/cw_monero/lib/api/transaction_history.dart index 9546a93d3..0fc507500 100644 --- a/cw_monero/lib/api/transaction_history.dart +++ b/cw_monero/lib/api/transaction_history.dart @@ -40,16 +40,16 @@ final getTxKeyNative = moneroApi .asFunction(); String getTxKey(String txId) { - final txIdPointer = Utf8.toUtf8(txId); + final txIdPointer = txId.toNativeUtf8(); final keyPointer = getTxKeyNative(txIdPointer); - free(txIdPointer); + calloc.free(txIdPointer); if (keyPointer != null) { return convertUTF8ToString(pointer: keyPointer); } - return null; + return ''; } void refreshTransactions() => transactionsRefreshNative(); @@ -67,16 +67,16 @@ List getAllTransations() { } PendingTransactionDescription createTransactionSync( - {String address, - String paymentId, - String amount, - int priorityRaw, + {required String address, + required String paymentId, + required int priorityRaw, + String? amount, int accountIndex = 0}) { - final addressPointer = Utf8.toUtf8(address); - final paymentIdPointer = Utf8.toUtf8(paymentId); - final amountPointer = amount != null ? Utf8.toUtf8(amount) : nullptr; - final errorMessagePointer = allocate(); - final pendingTransactionRawPointer = allocate(); + final addressPointer = address.toNativeUtf8(); + final paymentIdPointer = paymentId.toNativeUtf8(); + final amountPointer = amount != null ? amount.toNativeUtf8() : nullptr; + final errorMessagePointer = calloc(); + final pendingTransactionRawPointer = calloc(); final created = transactionCreateNative( addressPointer, paymentIdPointer, @@ -87,16 +87,16 @@ PendingTransactionDescription createTransactionSync( pendingTransactionRawPointer) != 0; - free(addressPointer); - free(paymentIdPointer); + calloc.free(addressPointer); + calloc.free(paymentIdPointer); if (amountPointer != nullptr) { - free(amountPointer); + calloc.free(amountPointer); } if (!created) { final message = errorMessagePointer.ref.getValue(); - free(errorMessagePointer); + calloc.free(errorMessagePointer); throw CreationTransactionException(message: message); } @@ -110,26 +110,26 @@ PendingTransactionDescription createTransactionSync( } PendingTransactionDescription createTransactionMultDestSync( - {List outputs, - String paymentId, - int priorityRaw, + {required List outputs, + required String paymentId, + required int priorityRaw, int accountIndex = 0}) { final int size = outputs.length; final List> addressesPointers = outputs.map((output) => - Utf8.toUtf8(output.address)).toList(); - final Pointer> addressesPointerPointer = allocate(count: size); + output.address.toNativeUtf8()).toList(); + final Pointer> addressesPointerPointer = calloc(size); final List> amountsPointers = outputs.map((output) => - Utf8.toUtf8(output.amount)).toList(); - final Pointer> amountsPointerPointer = allocate(count: size); + output.amount.toNativeUtf8()).toList(); + final Pointer> amountsPointerPointer = calloc(size); for (int i = 0; i < size; i++) { addressesPointerPointer[i] = addressesPointers[i]; amountsPointerPointer[i] = amountsPointers[i]; } - final paymentIdPointer = Utf8.toUtf8(paymentId); - final errorMessagePointer = allocate(); - final pendingTransactionRawPointer = allocate(); + final paymentIdPointer = paymentId.toNativeUtf8(); + final errorMessagePointer = calloc(); + final pendingTransactionRawPointer = calloc(); final created = transactionCreateMultDestNative( addressesPointerPointer, paymentIdPointer, @@ -141,17 +141,17 @@ PendingTransactionDescription createTransactionMultDestSync( pendingTransactionRawPointer) != 0; - free(addressesPointerPointer); - free(amountsPointerPointer); + calloc.free(addressesPointerPointer); + calloc.free(amountsPointerPointer); - addressesPointers.forEach((element) => free(element)); - amountsPointers.forEach((element) => free(element)); + addressesPointers.forEach((element) => calloc.free(element)); + amountsPointers.forEach((element) => calloc.free(element)); - free(paymentIdPointer); + calloc.free(paymentIdPointer); if (!created) { final message = errorMessagePointer.ref.getValue(); - free(errorMessagePointer); + calloc.free(errorMessagePointer); throw CreationTransactionException(message: message); } @@ -164,17 +164,17 @@ PendingTransactionDescription createTransactionMultDestSync( pointerAddress: pendingTransactionRawPointer.address); } -void commitTransactionFromPointerAddress({int address}) => commitTransaction( +void commitTransactionFromPointerAddress({required int address}) => commitTransaction( transactionPointer: Pointer.fromAddress(address)); -void commitTransaction({Pointer transactionPointer}) { - final errorMessagePointer = allocate(); +void commitTransaction({required Pointer transactionPointer}) { + final errorMessagePointer = calloc(); final isCommited = transactionCommitNative(transactionPointer, errorMessagePointer) != 0; if (!isCommited) { final message = errorMessagePointer.ref.getValue(); - free(errorMessagePointer); + calloc.free(errorMessagePointer); throw CreationTransactionException(message: message); } } @@ -182,7 +182,7 @@ void commitTransaction({Pointer transactionPointer}) { PendingTransactionDescription _createTransactionSync(Map args) { final address = args['address'] as String; final paymentId = args['paymentId'] as String; - final amount = args['amount'] as String; + final amount = args['amount'] as String?; final priorityRaw = args['priorityRaw'] as int; final accountIndex = args['accountIndex'] as int; @@ -208,10 +208,10 @@ PendingTransactionDescription _createTransactionMultDestSync(Map args) { } Future createTransaction( - {String address, + {required String address, + required int priorityRaw, + String? amount, String paymentId = '', - String amount, - int priorityRaw, int accountIndex = 0}) => compute(_createTransactionSync, { 'address': address, @@ -222,9 +222,9 @@ Future createTransaction( }); Future createTransactionMultDest( - {List outputs, + {required List outputs, + required int priorityRaw, String paymentId = '', - int priorityRaw, int accountIndex = 0}) => compute(_createTransactionMultDestSync, { 'outputs': outputs, diff --git a/cw_monero/lib/api/types.dart b/cw_monero/lib/api/types.dart index 3438b89fc..468ce93e2 100644 --- a/cw_monero/lib/api/types.dart +++ b/cw_monero/lib/api/types.dart @@ -35,7 +35,7 @@ typedef GetNodeHeight = int Function(); typedef IsConnected = int Function(); typedef SetupNode = int Function( - Pointer, Pointer, Pointer, int, int, Pointer); + Pointer, Pointer?, Pointer?, int, int, Pointer); typedef StartRefresh = void Function(); @@ -80,7 +80,7 @@ typedef AccountSetLabel = void Function(int accountIndex, Pointer label); typedef TransactionsRefresh = void Function(); -typedef GetTxKey = Pointer Function(Pointer txId); +typedef GetTxKey = Pointer? Function(Pointer txId); typedef TransactionsCount = int Function(); diff --git a/cw_monero/lib/api/wallet.dart b/cw_monero/lib/api/wallet.dart index 9e84d7865..5c2f1bd27 100644 --- a/cw_monero/lib/api/wallet.dart +++ b/cw_monero/lib/api/wallet.dart @@ -146,24 +146,24 @@ int getNodeHeightSync() => getNodeHeightNative(); bool isConnectedSync() => isConnectedNative() != 0; bool setupNodeSync( - {String address, - String login, - String password, + {required String address, + String? login, + String? password, bool useSSL = false, bool isLightWallet = false}) { - final addressPointer = Utf8.toUtf8(address); - Pointer loginPointer; - Pointer passwordPointer; + final addressPointer = address.toNativeUtf8(); + Pointer? loginPointer; + Pointer? passwordPointer; if (login != null) { - loginPointer = Utf8.toUtf8(login); + loginPointer = login.toNativeUtf8(); } if (password != null) { - passwordPointer = Utf8.toUtf8(password); + passwordPointer = password.toNativeUtf8(); } - final errorMessagePointer = allocate(); + final errorMessagePointer = ''.toNativeUtf8(); final isSetupNode = setupNodeNative( addressPointer, loginPointer, @@ -173,9 +173,15 @@ bool setupNodeSync( errorMessagePointer) != 0; - free(addressPointer); - free(loginPointer); - free(passwordPointer); + calloc.free(addressPointer); + + if (loginPointer != null) { + calloc.free(loginPointer); + } + + if (passwordPointer != null) { + calloc.free(passwordPointer); + } if (!isSetupNode) { throw SetupWalletException( @@ -189,31 +195,31 @@ void startRefreshSync() => startRefreshNative(); Future connectToNode() async => connecToNodeNative() != 0; -void setRefreshFromBlockHeight({int height}) => +void setRefreshFromBlockHeight({required int height}) => setRefreshFromBlockHeightNative(height); -void setRecoveringFromSeed({bool isRecovery}) => +void setRecoveringFromSeed({required bool isRecovery}) => setRecoveringFromSeedNative(_boolToInt(isRecovery)); void storeSync() { - final pathPointer = Utf8.toUtf8(''); + final pathPointer = ''.toNativeUtf8(); storeNative(pathPointer); - free(pathPointer); + calloc.free(pathPointer); } void setPasswordSync(String password) { - final passwordPointer = Utf8.toUtf8(password); - final errorMessagePointer = allocate(); + final passwordPointer = password.toNativeUtf8(); + final errorMessagePointer = calloc(); final changed = setPasswordNative(passwordPointer, errorMessagePointer) != 0; - free(passwordPointer); + calloc.free(passwordPointer); if (!changed) { final message = errorMessagePointer.ref.getValue(); - free(errorMessagePointer); + calloc.free(errorMessagePointer); throw Exception(message); } - free(errorMessagePointer); + calloc.free(errorMessagePointer); } void closeCurrentWallet() => closeCurrentWalletNative(); @@ -231,16 +237,16 @@ String getPublicSpendKey() => convertUTF8ToString(pointer: getPublicSpendKeyNative()); class SyncListener { - SyncListener(this.onNewBlock, this.onNewTransaction) { - _cachedBlockchainHeight = 0; - _lastKnownBlockHeight = 0; + SyncListener(this.onNewBlock, this.onNewTransaction) + : _cachedBlockchainHeight = 0, + _lastKnownBlockHeight = 0, _initialSyncHeight = 0; - } + void Function(int, int, double) onNewBlock; void Function() onNewTransaction; - Timer _updateSyncInfoTimer; + Timer? _updateSyncInfoTimer; int _cachedBlockchainHeight; int _lastKnownBlockHeight; int _initialSyncHeight; @@ -260,7 +266,7 @@ class SyncListener { _updateSyncInfoTimer ??= Timer.periodic(Duration(milliseconds: 1200), (_) async { if (isNewTransactionExist()) { - onNewTransaction?.call(); + onNewTransaction(); } var syncHeight = getSyncingHeight(); @@ -308,7 +314,7 @@ void onStartup() => onStartupNative(); void _storeSync(Object _) => storeSync(); -bool _setupNodeSync(Map args) { +bool _setupNodeSync(Map args) { final address = args['address'] as String; final login = (args['login'] ?? '') as String; final password = (args['password'] ?? '') as String; @@ -329,21 +335,21 @@ int _getNodeHeight(Object _) => getNodeHeightSync(); void startRefresh() => startRefreshSync(); -Future setupNode( - {String address, - String login, - String password, +Future setupNode( + {required String address, + String? login, + String? password, bool useSSL = false, bool isLightWallet = false}) => - compute, void>(_setupNodeSync, { + compute, void>(_setupNodeSync, { 'address': address, - 'login': login, + 'login': login , 'password': password, 'useSSL': useSSL, 'isLightWallet': isLightWallet }); -Future store() => compute(_storeSync, 0); +Future store() => compute(_storeSync, 0); Future isConnected() => compute(_isConnected, 0); diff --git a/cw_monero/lib/api/wallet_manager.dart b/cw_monero/lib/api/wallet_manager.dart index b414c8b0a..093d7e63b 100644 --- a/cw_monero/lib/api/wallet_manager.dart +++ b/cw_monero/lib/api/wallet_manager.dart @@ -38,18 +38,21 @@ final errorStringNative = moneroApi .asFunction(); void createWalletSync( - {String path, String password, String language, int nettype = 0}) { - final pathPointer = Utf8.toUtf8(path); - final passwordPointer = Utf8.toUtf8(password); - final languagePointer = Utf8.toUtf8(language); - final errorMessagePointer = allocate(); + {required String path, + required String password, + required String language, + int nettype = 0}) { + final pathPointer = path.toNativeUtf8(); + final passwordPointer = password.toNativeUtf8(); + final languagePointer = language.toNativeUtf8(); + final errorMessagePointer = ''.toNativeUtf8(); final isWalletCreated = createWalletNative(pathPointer, passwordPointer, languagePointer, nettype, errorMessagePointer) != 0; - free(pathPointer); - free(passwordPointer); - free(languagePointer); + calloc.free(pathPointer); + calloc.free(passwordPointer); + calloc.free(languagePointer); if (!isWalletCreated) { throw WalletCreationException( @@ -59,25 +62,25 @@ void createWalletSync( // setupNodeSync(address: "node.moneroworld.com:18089"); } -bool isWalletExistSync({String path}) { - final pathPointer = Utf8.toUtf8(path); +bool isWalletExistSync({required String path}) { + final pathPointer = path.toNativeUtf8(); final isExist = isWalletExistNative(pathPointer) != 0; - free(pathPointer); + calloc.free(pathPointer); return isExist; } void restoreWalletFromSeedSync( - {String path, - String password, - String seed, + {required String path, + required String password, + required String seed, int nettype = 0, int restoreHeight = 0}) { - final pathPointer = Utf8.toUtf8(path); - final passwordPointer = Utf8.toUtf8(password); - final seedPointer = Utf8.toUtf8(seed); - final errorMessagePointer = allocate(); + final pathPointer = path.toNativeUtf8(); + final passwordPointer = password.toNativeUtf8(); + final seedPointer = seed.toNativeUtf8(); + final errorMessagePointer = ''.toNativeUtf8(); final isWalletRestored = restoreWalletFromSeedNative( pathPointer, passwordPointer, @@ -87,9 +90,9 @@ void restoreWalletFromSeedSync( errorMessagePointer) != 0; - free(pathPointer); - free(passwordPointer); - free(seedPointer); + calloc.free(pathPointer); + calloc.free(passwordPointer); + calloc.free(seedPointer); if (!isWalletRestored) { throw WalletRestoreFromSeedException( @@ -98,21 +101,21 @@ void restoreWalletFromSeedSync( } void restoreWalletFromKeysSync( - {String path, - String password, - String language, - String address, - String viewKey, - String spendKey, + {required String path, + required String password, + required String language, + required String address, + required String viewKey, + required String spendKey, int nettype = 0, int restoreHeight = 0}) { - final pathPointer = Utf8.toUtf8(path); - final passwordPointer = Utf8.toUtf8(password); - final languagePointer = Utf8.toUtf8(language); - final addressPointer = Utf8.toUtf8(address); - final viewKeyPointer = Utf8.toUtf8(viewKey); - final spendKeyPointer = Utf8.toUtf8(spendKey); - final errorMessagePointer = allocate(); + final pathPointer = path.toNativeUtf8(); + final passwordPointer = password.toNativeUtf8(); + final languagePointer = language.toNativeUtf8(); + final addressPointer = address.toNativeUtf8(); + final viewKeyPointer = viewKey.toNativeUtf8(); + final spendKeyPointer = spendKey.toNativeUtf8(); + final errorMessagePointer = ''.toNativeUtf8(); final isWalletRestored = restoreWalletFromKeysNative( pathPointer, passwordPointer, @@ -125,12 +128,12 @@ void restoreWalletFromKeysSync( errorMessagePointer) != 0; - free(pathPointer); - free(passwordPointer); - free(languagePointer); - free(addressPointer); - free(viewKeyPointer); - free(spendKeyPointer); + calloc.free(pathPointer); + calloc.free(passwordPointer); + calloc.free(languagePointer); + calloc.free(addressPointer); + calloc.free(viewKeyPointer); + calloc.free(spendKeyPointer); if (!isWalletRestored) { throw WalletRestoreFromKeysException( @@ -138,12 +141,15 @@ void restoreWalletFromKeysSync( } } -void loadWallet({String path, String password, int nettype = 0}) { - final pathPointer = Utf8.toUtf8(path); - final passwordPointer = Utf8.toUtf8(password); +void loadWallet({ + required String path, + required String password, + int nettype = 0}) { + final pathPointer = path.toNativeUtf8(); + final passwordPointer = password.toNativeUtf8(); final loaded = loadWalletNative(pathPointer, passwordPointer, nettype) != 0; - free(pathPointer); - free(passwordPointer); + calloc.free(pathPointer); + calloc.free(passwordPointer); if (!loaded) { throw WalletOpeningException( @@ -189,20 +195,20 @@ void _restoreFromKeys(Map args) { } Future _openWallet(Map args) async => - loadWallet(path: args['path'], password: args['password']); + loadWallet(path: args['path'] as String, password: args['password'] as String); bool _isWalletExist(String path) => isWalletExistSync(path: path); -void openWallet({String path, String password, int nettype = 0}) async => +void openWallet({required String path, required String password, int nettype = 0}) async => loadWallet(path: path, password: password, nettype: nettype); Future openWalletAsync(Map args) async => compute(_openWallet, args); Future createWallet( - {String path, - String password, - String language, + {required String path, + required String password, + required String language, int nettype = 0}) async => compute(_createWallet, { 'path': path, @@ -211,10 +217,10 @@ Future createWallet( 'nettype': nettype }); -Future restoreFromSeed( - {String path, - String password, - String seed, +Future restoreFromSeed( + {required String path, + required String password, + required String seed, int nettype = 0, int restoreHeight = 0}) async => compute, void>(_restoreFromSeed, { @@ -225,13 +231,13 @@ Future restoreFromSeed( 'restoreHeight': restoreHeight }); -Future restoreFromKeys( - {String path, - String password, - String language, - String address, - String viewKey, - String spendKey, +Future restoreFromKeys( + {required String path, + required String password, + required String language, + required String address, + required String viewKey, + required String spendKey, int nettype = 0, int restoreHeight = 0}) async => compute, void>(_restoreFromKeys, { @@ -245,4 +251,4 @@ Future restoreFromKeys( 'restoreHeight': restoreHeight }); -Future isWalletExist({String path}) => compute(_isWalletExist, path); +Future isWalletExist({required String path}) => compute(_isWalletExist, path); diff --git a/cw_monero/lib/monero_account_list.dart b/cw_monero/lib/monero_account_list.dart index 12cda5680..f618cf57a 100644 --- a/cw_monero/lib/monero_account_list.dart +++ b/cw_monero/lib/monero_account_list.dart @@ -12,7 +12,6 @@ abstract class MoneroAccountListBase with Store { _isRefreshing = false, _isUpdating = false { refresh(); - print(account_list.accountSizeNative()); } @observable @@ -49,12 +48,12 @@ abstract class MoneroAccountListBase with Store { label: accountRow.getLabel())) .toList(); - Future addAccount({String label}) async { + Future addAccount({required String label}) async { await account_list.addAccount(label: label); update(); } - Future setLabelAccount({int accountIndex, String label}) async { + Future setLabelAccount({required int accountIndex, required String label}) async { await account_list.setLabelForAccount( accountIndex: accountIndex, label: label); update(); diff --git a/cw_monero/lib/monero_subaddress_list.dart b/cw_monero/lib/monero_subaddress_list.dart index e59052207..8d8eeb469 100644 --- a/cw_monero/lib/monero_subaddress_list.dart +++ b/cw_monero/lib/monero_subaddress_list.dart @@ -10,11 +10,10 @@ class MoneroSubaddressList = MoneroSubaddressListBase with _$MoneroSubaddressList; abstract class MoneroSubaddressListBase with Store { - MoneroSubaddressListBase() { - _isRefreshing = false; - _isUpdating = false; - subaddresses = ObservableList(); - } + MoneroSubaddressListBase() + : _isRefreshing = false, + _isUpdating = false, + subaddresses = ObservableList(); @observable ObservableList subaddresses; @@ -22,7 +21,7 @@ abstract class MoneroSubaddressListBase with Store { bool _isRefreshing; bool _isUpdating; - void update({int accountIndex}) { + void update({required int accountIndex}) { if (_isUpdating) { return; } @@ -59,20 +58,20 @@ abstract class MoneroSubaddressListBase with Store { .toList(); } - Future addSubaddress({int accountIndex, String label}) async { + Future addSubaddress({required int accountIndex, required String label}) async { await subaddress_list.addSubaddress( accountIndex: accountIndex, label: label); update(accountIndex: accountIndex); } - Future setLabelSubaddress( - {int accountIndex, int addressIndex, String label}) async { + Future setLabelSubaddress( + {required int accountIndex, required int addressIndex, required String label}) async { await subaddress_list.setLabelForSubaddress( accountIndex: accountIndex, addressIndex: addressIndex, label: label); update(accountIndex: accountIndex); } - void refresh({int accountIndex}) { + void refresh({required int accountIndex}) { if (_isRefreshing) { return; } diff --git a/cw_monero/lib/monero_transaction_creation_credentials.dart b/cw_monero/lib/monero_transaction_creation_credentials.dart index 3f0051046..96f2b1637 100644 --- a/cw_monero/lib/monero_transaction_creation_credentials.dart +++ b/cw_monero/lib/monero_transaction_creation_credentials.dart @@ -2,7 +2,7 @@ import 'package:cw_core/monero_transaction_priority.dart'; import 'package:cw_core/output_info.dart'; class MoneroTransactionCreationCredentials { - MoneroTransactionCreationCredentials({this.outputs, this.priority}); + MoneroTransactionCreationCredentials({required this.outputs, required this.priority}); final List outputs; final MoneroTransactionPriority priority; diff --git a/cw_monero/lib/monero_transaction_info.dart b/cw_monero/lib/monero_transaction_info.dart index db393497a..2dfdaf408 100644 --- a/cw_monero/lib/monero_transaction_info.dart +++ b/cw_monero/lib/monero_transaction_info.dart @@ -10,7 +10,7 @@ class MoneroTransactionInfo extends TransactionInfo { MoneroTransactionInfo(this.id, this.height, this.direction, this.date, this.isPending, this.amount, this.accountIndex, this.addressIndex, this.fee); - MoneroTransactionInfo.fromMap(Map map) + MoneroTransactionInfo.fromMap(Map map) : id = (map['hash'] ?? '') as String, height = (map['height'] ?? 0) as int, direction = @@ -24,7 +24,7 @@ class MoneroTransactionInfo extends TransactionInfo { addressIndex = map['addressIndex'] as int, key = getTxKey((map['hash'] ?? '') as String), fee = map['fee'] as int ?? 0 { - additionalInfo = { + additionalInfo = { 'key': key, 'accountIndex': accountIndex, 'addressIndex': addressIndex @@ -43,7 +43,7 @@ class MoneroTransactionInfo extends TransactionInfo { addressIndex = row.subaddrIndex, key = getTxKey(row.getHash()), fee = row.fee { - additionalInfo = { + additionalInfo = { 'key': key, 'accountIndex': accountIndex, 'addressIndex': addressIndex @@ -59,10 +59,9 @@ class MoneroTransactionInfo extends TransactionInfo { final int amount; final int fee; final int addressIndex; - String recipientAddress; - String key; - - String _fiatAmount; + String? recipientAddress; + String? key; + String? _fiatAmount; @override String amountFormatted() => diff --git a/cw_monero/lib/monero_wallet.dart b/cw_monero/lib/monero_wallet.dart index 175bd96f5..404d8bad0 100644 --- a/cw_monero/lib/monero_wallet.dart +++ b/cw_monero/lib/monero_wallet.dart @@ -36,19 +36,24 @@ class MoneroWallet = MoneroWalletBase with _$MoneroWallet; abstract class MoneroWalletBase extends WalletBase with Store { - MoneroWalletBase({WalletInfo walletInfo}) - : super(walletInfo) { + MoneroWalletBase({required WalletInfo walletInfo}) + : balance = ObservableMap.of({ + CryptoCurrency.xmr: MoneroBalance( + fullBalance: monero_wallet.getFullBalance(accountIndex: 0), + unlockedBalance: monero_wallet.getFullBalance(accountIndex: 0)) + }), + _isTransactionUpdating = false, + _hasSyncAfterStartup = false, + walletAddresses = MoneroWalletAddresses(walletInfo), + syncStatus = NotConnectedSyncStatus(), + super(walletInfo) { transactionHistory = MoneroTransactionHistory(); - balance = ObservableMap.of({ - CryptoCurrency.xmr: MoneroBalance( - fullBalance: monero_wallet.getFullBalance(accountIndex: 0), - unlockedBalance: monero_wallet.getFullBalance(accountIndex: 0)) - }); - _isTransactionUpdating = false; - _hasSyncAfterStartup = false; - walletAddresses = MoneroWalletAddresses(walletInfo); _onAccountChangeReaction = reaction((_) => walletAddresses.account, - (Account account) { + (Account? account) { + if (account == null) { + return; + } + balance = ObservableMap.of( { currency: MoneroBalance( @@ -83,19 +88,19 @@ abstract class MoneroWalletBase extends WalletBase init() async { await walletAddresses.init(); balance = ObservableMap.of( { currency: MoneroBalance( - fullBalance: monero_wallet.getFullBalance(accountIndex: walletAddresses.account.id), - unlockedBalance: monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account.id)) + fullBalance: monero_wallet.getFullBalance(accountIndex: walletAddresses.account!.id), + unlockedBalance: monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account!.id)) }); _setListeners(); await updateTransactions(); @@ -117,12 +122,12 @@ abstract class MoneroWalletBase extends WalletBase connectToNode({@required Node node}) async { + Future connectToNode({required Node node}) async { try { syncStatus = ConnectingSyncStatus(); await monero_wallet.setupNode( @@ -162,7 +167,7 @@ abstract class MoneroWalletBase extends WalletBase 1; final unlockedBalance = - monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account.id); + monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account!.id); PendingTransactionDescription pendingTransactionDescription; @@ -172,32 +177,32 @@ abstract class MoneroWalletBase extends WalletBase item.sendAll - || item.formattedCryptoAmount <= 0)) { + || (item.formattedCryptoAmount ?? 0) <= 0)) { throw MoneroTransactionCreationException('Wrong balance. Not enough XMR on your balance.'); } final int totalAmount = outputs.fold(0, (acc, value) => - acc + value.formattedCryptoAmount); + acc + (value.formattedCryptoAmount ?? 0)); if (unlockedBalance < totalAmount) { throw MoneroTransactionCreationException('Wrong balance. Not enough XMR on your balance.'); } final moneroOutputs = outputs.map((output) { - final outputAddress = output.isParsedAddress - ? output.extractedAddress - : output.address; + final outputAddress = output.isParsedAddress + ? output.extractedAddress + : output.address; - return MoneroOutput( - address: outputAddress, - amount: output.cryptoAmount.replaceAll(',', '.')); + return MoneroOutput( + address: outputAddress!, + amount: output.cryptoAmount!.replaceAll(',', '.')); }).toList(); pendingTransactionDescription = await transaction_history.createTransactionMultDest( outputs: moneroOutputs, priorityRaw: _credentials.priority.serialize(), - accountIndex: walletAddresses.account.id); + accountIndex: walletAddresses.account!.id); } else { final output = outputs.first; final address = output.isParsedAddress @@ -205,7 +210,7 @@ abstract class MoneroWalletBase extends WalletBase rescan({int height}) async { + Future rescan({required int height}) async { walletInfo.restoreHeight = height; walletInfo.isRecovery = true; monero_wallet.setRefreshFromBlockHeight(height: height); @@ -372,8 +377,8 @@ abstract class MoneroWalletBase extends WalletBase - monero_wallet.getFullBalance(accountIndex: walletAddresses.account.id); + monero_wallet.getFullBalance(accountIndex: walletAddresses.account!.id); int _getUnlockedBalance() => - monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account.id); + monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account!.id); void _onNewBlock(int height, int blocksLeft, double ptc) async { try { diff --git a/cw_monero/lib/monero_wallet_addresses.dart b/cw_monero/lib/monero_wallet_addresses.dart index c84e8c8e4..2002e789a 100644 --- a/cw_monero/lib/monero_wallet_addresses.dart +++ b/cw_monero/lib/monero_wallet_addresses.dart @@ -12,20 +12,21 @@ class MoneroWalletAddresses = MoneroWalletAddressesBase with _$MoneroWalletAddresses; abstract class MoneroWalletAddressesBase extends WalletAddresses with Store { - MoneroWalletAddressesBase(WalletInfo walletInfo) : super(walletInfo) { - accountList = MoneroAccountList(); - subaddressList = MoneroSubaddressList(); - } + MoneroWalletAddressesBase(WalletInfo walletInfo) + : accountList = MoneroAccountList(), + subaddressList = MoneroSubaddressList(), + address = '', + super(walletInfo); @override @observable String address; + + @observable + Account? account; @observable - Account account; - - @observable - Subaddress subaddress; + Subaddress? subaddress; MoneroSubaddressList subaddressList; @@ -35,7 +36,7 @@ abstract class MoneroWalletAddressesBase extends WalletAddresses with Store { Future init() async { accountList.update(); account = accountList.accounts.first; - updateSubaddressList(accountIndex: account.id ?? 0); + updateSubaddressList(accountIndex: account?.id ?? 0); await updateAddressesInBox(); } @@ -61,14 +62,14 @@ abstract class MoneroWalletAddressesBase extends WalletAddresses with Store { bool validate() { accountList.update(); - final accountListLength = accountList.accounts?.length ?? 0; + final accountListLength = accountList.accounts.length ?? 0; if (accountListLength <= 0) { return false; } subaddressList.update(accountIndex: accountList.accounts.first.id); - final subaddressListLength = subaddressList.subaddresses?.length ?? 0; + final subaddressListLength = subaddressList.subaddresses.length ?? 0; if (subaddressListLength <= 0) { return false; @@ -77,9 +78,9 @@ abstract class MoneroWalletAddressesBase extends WalletAddresses with Store { return true; } - void updateSubaddressList({int accountIndex}) { + void updateSubaddressList({required int accountIndex}) { subaddressList.update(accountIndex: accountIndex); subaddress = subaddressList.subaddresses.first; - address = subaddress.address; + address = subaddress!.address; } } \ No newline at end of file diff --git a/cw_monero/lib/monero_wallet_service.dart b/cw_monero/lib/monero_wallet_service.dart index d0461de72..095fe83bb 100644 --- a/cw_monero/lib/monero_wallet_service.dart +++ b/cw_monero/lib/monero_wallet_service.dart @@ -13,7 +13,7 @@ import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_type.dart'; class MoneroNewWalletCredentials extends WalletCredentials { - MoneroNewWalletCredentials({String name, String password, this.language}) + MoneroNewWalletCredentials({required String name, required this.language, String? password}) : super(name: name, password: password); final String language; @@ -21,7 +21,7 @@ class MoneroNewWalletCredentials extends WalletCredentials { class MoneroRestoreWalletFromSeedCredentials extends WalletCredentials { MoneroRestoreWalletFromSeedCredentials( - {String name, String password, int height, this.mnemonic}) + {required String name, required this.mnemonic, int height = 0, String? password}) : super(name: name, password: password, height: height); final String mnemonic; @@ -34,13 +34,13 @@ class MoneroWalletLoadingException implements Exception { class MoneroRestoreWalletFromKeysCredentials extends WalletCredentials { MoneroRestoreWalletFromKeysCredentials( - {String name, - String password, - this.language, - this.address, - this.viewKey, - this.spendKey, - int height}) + {required String name, + required String password, + required this.language, + required this.address, + required this.viewKey, + required this.spendKey, + int height = 0}) : super(name: name, password: password, height: height); final String language; @@ -69,9 +69,9 @@ class MoneroWalletService extends WalletService< final path = await pathForWallet(name: credentials.name, type: getType()); await monero_wallet_manager.createWallet( path: path, - password: credentials.password, + password: credentials.password!, language: credentials.language); - final wallet = MoneroWallet(walletInfo: credentials.walletInfo); + final wallet = MoneroWallet(walletInfo: credentials.walletInfo!); await wallet.init(); return wallet; @@ -106,8 +106,7 @@ class MoneroWalletService extends WalletService< await monero_wallet_manager .openWalletAsync({'path': path, 'password': password}); final walletInfo = walletInfoSource.values.firstWhere( - (info) => info.id == WalletBase.idFor(name, getType()), - orElse: () => null); + (info) => info.id == WalletBase.idFor(name, getType())); final wallet = MoneroWallet(walletInfo: walletInfo); final isValid = wallet.walletAddresses.validate(); @@ -156,13 +155,13 @@ class MoneroWalletService extends WalletService< final path = await pathForWallet(name: credentials.name, type: getType()); await monero_wallet_manager.restoreFromKeys( path: path, - password: credentials.password, + password: credentials.password!, language: credentials.language, - restoreHeight: credentials.height, + restoreHeight: credentials.height!, address: credentials.address, viewKey: credentials.viewKey, spendKey: credentials.spendKey); - final wallet = MoneroWallet(walletInfo: credentials.walletInfo); + final wallet = MoneroWallet(walletInfo: credentials.walletInfo!); await wallet.init(); return wallet; @@ -180,10 +179,10 @@ class MoneroWalletService extends WalletService< final path = await pathForWallet(name: credentials.name, type: getType()); await monero_wallet_manager.restoreFromSeed( path: path, - password: credentials.password, + password: credentials.password!, seed: credentials.mnemonic, - restoreHeight: credentials.height); - final wallet = MoneroWallet(walletInfo: credentials.walletInfo); + restoreHeight: credentials.height!); + final wallet = MoneroWallet(walletInfo: credentials.walletInfo!); await wallet.init(); return wallet; diff --git a/cw_monero/lib/pending_monero_transaction.dart b/cw_monero/lib/pending_monero_transaction.dart index d32bab2ce..2a75fc26b 100644 --- a/cw_monero/lib/pending_monero_transaction.dart +++ b/cw_monero/lib/pending_monero_transaction.dart @@ -2,7 +2,7 @@ import 'package:cw_monero/api/structs/pending_transaction.dart'; import 'package:cw_monero/api/transaction_history.dart' as monero_transaction_history; import 'package:cw_core/crypto_currency.dart'; -import 'package:cake_wallet/core/amount_converter.dart'; +import 'package:cw_core/amount_converter.dart'; import 'package:cw_core/pending_transaction.dart'; diff --git a/cw_monero/pubspec.lock b/cw_monero/pubspec.lock index 82c5f78f1..557550754 100644 --- a/cw_monero/pubspec.lock +++ b/cw_monero/pubspec.lock @@ -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,63 +105,49 @@ 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" cw_core: dependency: "direct main" description: @@ -175,35 +161,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: transitive + 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: "direct main" description: name: ffi url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" + version: "1.2.1" file: dependency: transitive description: @@ -229,12 +208,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: @@ -248,42 +234,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: @@ -297,7 +283,7 @@ packages: name: io url: "https://pub.dartlang.org" source: hosted - version: "0.3.5" + version: "1.0.3" js: dependency: transitive description: @@ -311,7 +297,7 @@ packages: name: json_annotation url: "https://pub.dartlang.org" source: hosted - version: "4.0.1" + version: "4.6.0" logging: dependency: transitive description: @@ -325,14 +311,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: @@ -346,35 +339,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.4.0" + 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: "2.1.7" + path_provider_macos: + dependency: transitive + description: + name: path_provider_macos + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.6" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.4" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.7" pedantic: dependency: transitive description: @@ -388,14 +423,21 @@ packages: name: platform url: "https://pub.dartlang.org" source: hosted - version: "2.2.1" + version: "3.1.0" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + 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: @@ -403,6 +445,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.5.0" + process: + dependency: transitive + description: + name: process + url: "https://pub.dartlang.org" + source: hosted + version: "4.2.4" pub_semver: dependency: transitive description: @@ -416,21 +465,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 @@ -442,14 +491,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: @@ -477,35 +533,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: @@ -519,7 +568,7 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.2" watcher: dependency: transitive description: @@ -533,7 +582,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.6.1" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0+2" yaml: dependency: transitive description: @@ -542,5 +605,5 @@ packages: source: hosted version: "3.1.0" sdks: - dart: ">=2.12.0 <3.0.0" - flutter: ">=1.17.0" + dart: ">=2.17.5 <3.0.0" + flutter: ">=2.8.1" diff --git a/cw_monero/pubspec.yaml b/cw_monero/pubspec.yaml index 29584e194..23e8782cb 100644 --- a/cw_monero/pubspec.yaml +++ b/cw_monero/pubspec.yaml @@ -6,27 +6,29 @@ author: Cake Wallet homepage: https://cakewallet.com environment: - sdk: ">=2.6.0 <3.0.0" + sdk: ">=2.17.5 <3.0.0" + flutter: ">=1.20.0" dependencies: flutter: sdk: flutter - ffi: ^0.1.3 - path_provider: ^1.4.0 - http: ^0.12.0+2 - mobx: ^1.2.1+2 - flutter_mobx: ^1.1.0+2 + ffi: ^1.1.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: ^5.0.1 cw_core: path: ../cw_core 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 diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 66762582e..3a810430d 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,5 +1,5 @@ PODS: - - barcode_scan (0.0.1): + - barcode_scan2 (0.0.1): - Flutter - MTBBarcodeScanner - SwiftProtobuf @@ -98,22 +98,20 @@ PODS: - DKPhotoGallery/Resource (0.0.17): - SDWebImage - SwiftyGif - - esys_flutter_share (0.0.1): - - Flutter - file_picker (0.0.1): - DKImagePickerController/PhotoGallery - Flutter - Flutter (1.0.0) - flutter_secure_storage (3.3.1): - Flutter - - local_auth (0.0.1): + - local_auth_ios (0.0.1): - Flutter - MTBBarcodeScanner (5.0.11) - package_info (0.0.1): - Flutter - - path_provider (0.0.1): + - path_provider_ios (0.0.1): - Flutter - - "permission_handler (5.1.0+2)": + - permission_handler_apple (9.0.4): - Flutter - platform_device_id (0.0.1): - Flutter @@ -121,24 +119,24 @@ PODS: - SDWebImage (5.9.1): - SDWebImage/Core (= 5.9.1) - SDWebImage/Core (5.9.1) - - share (0.0.1): + - share_plus (0.0.1): - Flutter - - shared_preferences (0.0.1): + - shared_preferences_ios (0.0.1): - Flutter - - SwiftProtobuf (1.12.0) + - SwiftProtobuf (1.18.0) - SwiftyGif (5.3.0) - uni_links (0.0.1): - Flutter - UnstoppableDomainsResolution (4.0.0): - BigInt - CryptoSwift - - url_launcher (0.0.1): + - url_launcher_ios (0.0.1): - Flutter - - webview_flutter (0.0.1): + - webview_flutter_wkwebview (0.0.1): - Flutter DEPENDENCIES: - - barcode_scan (from `.symlinks/plugins/barcode_scan/ios`) + - barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`) - connectivity (from `.symlinks/plugins/connectivity/ios`) - CryptoSwift - cw_haven (from `.symlinks/plugins/cw_haven/ios`) @@ -147,21 +145,20 @@ DEPENDENCIES: - device_display_brightness (from `.symlinks/plugins/device_display_brightness/ios`) - device_info (from `.symlinks/plugins/device_info/ios`) - devicelocale (from `.symlinks/plugins/devicelocale/ios`) - - esys_flutter_share (from `.symlinks/plugins/esys_flutter_share/ios`) - file_picker (from `.symlinks/plugins/file_picker/ios`) - Flutter (from `Flutter`) - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) - - local_auth (from `.symlinks/plugins/local_auth/ios`) + - local_auth_ios (from `.symlinks/plugins/local_auth_ios/ios`) - package_info (from `.symlinks/plugins/package_info/ios`) - - path_provider (from `.symlinks/plugins/path_provider/ios`) - - permission_handler (from `.symlinks/plugins/permission_handler/ios`) + - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`) + - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) - platform_device_id (from `.symlinks/plugins/platform_device_id/ios`) - - share (from `.symlinks/plugins/share/ios`) - - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) + - share_plus (from `.symlinks/plugins/share_plus/ios`) + - shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`) - uni_links (from `.symlinks/plugins/uni_links/ios`) - UnstoppableDomainsResolution (~> 4.0.0) - - url_launcher (from `.symlinks/plugins/url_launcher/ios`) - - webview_flutter (from `.symlinks/plugins/webview_flutter/ios`) + - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) + - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`) SPEC REPOS: https://github.com/CocoaPods/Specs.git: @@ -177,8 +174,8 @@ SPEC REPOS: - UnstoppableDomainsResolution EXTERNAL SOURCES: - barcode_scan: - :path: ".symlinks/plugins/barcode_scan/ios" + barcode_scan2: + :path: ".symlinks/plugins/barcode_scan2/ios" connectivity: :path: ".symlinks/plugins/connectivity/ios" cw_haven: @@ -193,37 +190,35 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/device_info/ios" devicelocale: :path: ".symlinks/plugins/devicelocale/ios" - esys_flutter_share: - :path: ".symlinks/plugins/esys_flutter_share/ios" file_picker: :path: ".symlinks/plugins/file_picker/ios" Flutter: :path: Flutter flutter_secure_storage: :path: ".symlinks/plugins/flutter_secure_storage/ios" - local_auth: - :path: ".symlinks/plugins/local_auth/ios" + local_auth_ios: + :path: ".symlinks/plugins/local_auth_ios/ios" package_info: :path: ".symlinks/plugins/package_info/ios" - path_provider: - :path: ".symlinks/plugins/path_provider/ios" - permission_handler: - :path: ".symlinks/plugins/permission_handler/ios" + path_provider_ios: + :path: ".symlinks/plugins/path_provider_ios/ios" + permission_handler_apple: + :path: ".symlinks/plugins/permission_handler_apple/ios" platform_device_id: :path: ".symlinks/plugins/platform_device_id/ios" - share: - :path: ".symlinks/plugins/share/ios" - shared_preferences: - :path: ".symlinks/plugins/shared_preferences/ios" + share_plus: + :path: ".symlinks/plugins/share_plus/ios" + shared_preferences_ios: + :path: ".symlinks/plugins/shared_preferences_ios/ios" uni_links: :path: ".symlinks/plugins/uni_links/ios" - url_launcher: - :path: ".symlinks/plugins/url_launcher/ios" - webview_flutter: - :path: ".symlinks/plugins/webview_flutter/ios" + url_launcher_ios: + :path: ".symlinks/plugins/url_launcher_ios/ios" + webview_flutter_wkwebview: + :path: ".symlinks/plugins/webview_flutter_wkwebview/ios" SPEC CHECKSUMS: - barcode_scan: a5c27959edfafaa0c771905bad0b29d6d39e4479 + barcode_scan2: 0af2bb63c81b4565aab6cd78278e4c0fa136dbb0 BigInt: f668a80089607f521586bbe29513d708491ef2f7 connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467 CryptoSwift: 093499be1a94b0cae36e6c26b70870668cb56060 @@ -235,27 +230,26 @@ SPEC CHECKSUMS: devicelocale: b22617f40038496deffba44747101255cee005b0 DKImagePickerController: b5eb7f7a388e4643264105d648d01f727110fc3d DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179 - esys_flutter_share: 403498dab005b36ce1f8d7aff377e81f0621b0b4 - file_picker: 3e6c3790de664ccf9b882732d9db5eaf6b8d4eb1 - Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c + file_picker: 817ab1d8cd2da9d2da412a417162deee3500fc95 + Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec - local_auth: 25938960984c3a7f6e3253e3f8d962fdd16852bd + local_auth_ios: 0d333dde7780f669e66f19d2ff6005f3ea84008d MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 - path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c - permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0 + path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02 + permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce platform_device_id: 81b3e2993881f87d0c82ef151dc274df4869aef5 Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96 SDWebImage: a990c053fff71e388a10f3357edb0be17929c9c5 - share: 0b2c3e82132f5888bccca3351c504d0003b3b410 - shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d - SwiftProtobuf: 4ef85479c18ca85b5482b343df9c319c62bda699 + share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68 + shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad + SwiftProtobuf: c3c12645230d9b09c72267e0de89468c5543bd86 SwiftyGif: e466e86c660d343357ab944a819a101c4127cb40 uni_links: d97da20c7701486ba192624d99bffaaffcfc298a UnstoppableDomainsResolution: c3c67f4d0a5e2437cb00d4bd50c2e00d6e743841 - url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef - webview_flutter: 3603125dfd3bcbc9d8d418c3f80aeecf331c068b + url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de + webview_flutter_wkwebview: b7e70ef1ddded7e69c796c7390ee74180182971f PODFILE CHECKSUM: ae71bdf0eb731a1ffc399c122f6aa4dea0cb5f6f -COCOAPODS: 1.11.2 +COCOAPODS: 1.11.3 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index a0808e686..8d62665c3 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -162,7 +162,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1020; + LastUpgradeCheck = 1300; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -368,6 +368,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = 32J6BB6VUS; + DISABLED_ARCHS = x86_64; ENABLE_BITCODE = NO; EXCLUDED_SOURCE_FILE_NAMES = ""; FRAMEWORK_SEARCH_PATHS = ( @@ -390,6 +391,7 @@ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; + VALID_ARCHS = arm64; VERSIONING_SYSTEM = "apple-generic"; }; name = Profile; @@ -512,6 +514,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = 32J6BB6VUS; + DISABLED_ARCHS = x86_64; ENABLE_BITCODE = NO; EXCLUDED_SOURCE_FILE_NAMES = ""; FRAMEWORK_SEARCH_PATHS = ( @@ -535,6 +538,7 @@ SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; + VALID_ARCHS = arm64; VERSIONING_SYSTEM = "apple-generic"; }; name = Debug; @@ -548,6 +552,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = 3; DEVELOPMENT_TEAM = 32J6BB6VUS; + DISABLED_ARCHS = x86_64; ENABLE_BITCODE = NO; EXCLUDED_SOURCE_FILE_NAMES = ""; FRAMEWORK_SEARCH_PATHS = ( @@ -570,6 +575,7 @@ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; + VALID_ARCHS = arm64; VERSIONING_SYSTEM = "apple-generic"; }; name = Release; diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index fb2dffc49..c87d15a33 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ obj) { final instructions = (obj['instructions'] as List) @@ -45,13 +45,13 @@ class AnyPayPayment { .fold(0, (int outAcc, out) => outAcc + out.amount)); switch (chain) { case AnyPayChain.xmr: - return monero.formatterMoneroAmountToString(amount: total); + return monero!.formatterMoneroAmountToString(amount: total); case AnyPayChain.btc: - return bitcoin.formatterBitcoinAmountToString(amount: total); + return bitcoin!.formatterBitcoinAmountToString(amount: total); case AnyPayChain.ltc: - return bitcoin.formatterBitcoinAmountToString(amount: total); + return bitcoin!.formatterBitcoinAmountToString(amount: total); default: - return null; + return ''; } } diff --git a/lib/anypay/any_pay_payment_committed_info.dart b/lib/anypay/any_pay_payment_committed_info.dart index 126b3d92e..12adea003 100644 --- a/lib/anypay/any_pay_payment_committed_info.dart +++ b/lib/anypay/any_pay_payment_committed_info.dart @@ -3,11 +3,11 @@ import 'package:cake_wallet/anypay/any_pay_trasnaction.dart'; class AnyPayPaymentCommittedInfo { const AnyPayPaymentCommittedInfo({ - @required this.uri, - @required this.currency, - @required this.chain, - @required this.transactions, - @required this.memo}); + required this.uri, + required this.currency, + required this.chain, + required this.transactions, + required this.memo}); final String uri; final String currency; diff --git a/lib/anypay/any_pay_payment_instruction.dart b/lib/anypay/any_pay_payment_instruction.dart index 41d2ee82d..5181cad75 100644 --- a/lib/anypay/any_pay_payment_instruction.dart +++ b/lib/anypay/any_pay_payment_instruction.dart @@ -3,11 +3,11 @@ import 'package:cake_wallet/anypay/any_pay_payment_instruction_output.dart'; class AnyPayPaymentInstruction { AnyPayPaymentInstruction({ - @required this.type, - @required this.requiredFeeRate, - @required this.txKey, - @required this.txHash, - @required this.outputs}); + required this.type, + required this.requiredFeeRate, + required this.txKey, + required this.txHash, + required this.outputs}); factory AnyPayPaymentInstruction.fromMap(Map obj) { final outputs = (obj['outputs'] as List) @@ -17,8 +17,8 @@ class AnyPayPaymentInstruction { return AnyPayPaymentInstruction( type: obj['type'] as String, requiredFeeRate: obj['requiredFeeRate'] as int, - txKey: obj['tx_key'] as bool, - txHash: obj['tx_hash'] as bool, + txKey: obj['tx_key'] as bool? ?? false, + txHash: obj['tx_hash'] as bool? ?? false, outputs: outputs); } diff --git a/lib/anypay/any_pay_trasnaction.dart b/lib/anypay/any_pay_trasnaction.dart index 29f8a0152..af736cbf6 100644 --- a/lib/anypay/any_pay_trasnaction.dart +++ b/lib/anypay/any_pay_trasnaction.dart @@ -1,9 +1,7 @@ -import 'package:flutter/foundation.dart'; - class AnyPayTransaction { - const AnyPayTransaction(this.tx, {@required this.id, @required this.key}); + const AnyPayTransaction(this.tx, {required this.id, required this.key}); final String tx; final String id; - final String key; + final String? key; } \ No newline at end of file diff --git a/lib/anypay/anypay_api.dart b/lib/anypay/anypay_api.dart index c0727bc29..5eb9e460b 100644 --- a/lib/anypay/anypay_api.dart +++ b/lib/anypay/anypay_api.dart @@ -5,11 +5,13 @@ import 'package:http/http.dart'; import 'package:cw_core/crypto_currency.dart'; import 'package:cake_wallet/anypay/any_pay_payment.dart'; import 'package:cake_wallet/anypay/any_pay_trasnaction.dart'; +import 'package:cake_wallet/.secrets.g.dart' as secrets; class AnyPayApi { static const contentTypePaymentRequest = 'application/payment-request'; static const contentTypePayment = 'application/payment'; static const xPayproVersion = '2'; + static const anypayToken = secrets.anypayToken; static String chainByScheme(String scheme) { switch (scheme.toLowerCase()) { @@ -33,45 +35,49 @@ class AnyPayApi { case 'litecoin': return CryptoCurrency.ltc; default: - return null; + throw Exception('Unexpected scheme: ${scheme}'); } } Future paymentRequest(String uri) async { final fragments = uri.split(':?r='); final scheme = fragments.first; - final url = fragments[1]; - final headers = { + final url = Uri.parse(fragments[1]); + final headers = { 'Content-Type': contentTypePaymentRequest, 'X-Paypro-Version': xPayproVersion, - 'Accept': '*/*',}; + 'Accept': '*/*', + 'x-wallet': 'cake', + 'x-wallet-token': anypayToken,}; final body = { 'chain': chainByScheme(scheme), 'currency': currencyByScheme(scheme).title}; final response = await post(url, headers: headers, body: utf8.encode(json.encode(body))); - if (response.statusCode != 200) { - return null; + if (response.statusCode != 200) { + throw Exception('Unexpected response http code: ${response.statusCode}'); } - final decodedBody = json.decode(response.body) as Map; - return AnyPayPayment.fromMap(decodedBody); + final decodedBody = json.decode(response.body) as Map; + return AnyPayPayment.fromMap(decodedBody); } Future payment( String uri, - {@required String chain, - @required String currency, - @required List transactions}) async { - final headers = { + {required String chain, + required String currency, + required List transactions}) async { + final headers = { 'Content-Type': contentTypePayment, 'X-Paypro-Version': xPayproVersion, - 'Accept': '*/*',}; + 'Accept': '*/*', + 'x-wallet': 'cake', + 'x-wallet-token': anypayToken,}; final body = { 'chain': chain, 'currency': currency, 'transactions': transactions.map((tx) => {'tx': tx.tx, 'tx_hash': tx.id, 'tx_key': tx.key}).toList()}; - final response = await post(uri, headers: headers, body: utf8.encode(json.encode(body))); + final response = await post(Uri.parse(uri), headers: headers, body: utf8.encode(json.encode(body))); if (response.statusCode == 400) { final decodedBody = json.decode(response.body) as Map; throw Exception(decodedBody['message'] as String); diff --git a/lib/bitcoin/cw_bitcoin.dart b/lib/bitcoin/cw_bitcoin.dart index 46ef89172..f224efde6 100644 --- a/lib/bitcoin/cw_bitcoin.dart +++ b/lib/bitcoin/cw_bitcoin.dart @@ -5,15 +5,24 @@ class CWBitcoin extends Bitcoin { TransactionPriority getMediumTransactionPriority() => BitcoinTransactionPriority.medium; @override - WalletCredentials createBitcoinRestoreWalletFromSeedCredentials({String name, String mnemonic, String password}) + WalletCredentials createBitcoinRestoreWalletFromSeedCredentials({ + required String name, + required String mnemonic, + required String password}) => BitcoinRestoreWalletFromSeedCredentials(name: name, mnemonic: mnemonic, password: password); @override - WalletCredentials createBitcoinRestoreWalletFromWIFCredentials({String name, String password, String wif, WalletInfo walletInfo}) + WalletCredentials createBitcoinRestoreWalletFromWIFCredentials({ + required String name, + required String password, + required String wif, + WalletInfo? walletInfo}) => BitcoinRestoreWalletFromWIFCredentials(name: name, password: password, wif: wif, walletInfo: walletInfo); @override - WalletCredentials createBitcoinNewWalletCredentials({String name, WalletInfo walletInfo}) + WalletCredentials createBitcoinNewWalletCredentials({ + required String name, + WalletInfo? walletInfo}) => BitcoinNewWalletCredentials(name: name, walletInfo: walletInfo); @override @@ -55,7 +64,7 @@ class CWBitcoin extends Bitcoin { } @override - Object createBitcoinTransactionCredentials(List outputs, {TransactionPriority priority, int feeRate}) + Object createBitcoinTransactionCredentials(List outputs, {required TransactionPriority priority, int? feeRate}) => BitcoinTransactionCredentials( outputs.map((out) => OutputInfo( fiatAmount: out.fiatAmount, @@ -71,7 +80,7 @@ class CWBitcoin extends Bitcoin { feeRate: feeRate); @override - Object createBitcoinTransactionCredentialsRaw(List outputs, {TransactionPriority priority, int feeRate}) + Object createBitcoinTransactionCredentialsRaw(List outputs, {TransactionPriority? priority, required int feeRate}) => BitcoinTransactionCredentials( outputs, priority: priority != null ? priority as BitcoinTransactionPriority : null, @@ -92,17 +101,21 @@ class CWBitcoin extends Bitcoin { } @override - String formatterBitcoinAmountToString({int amount}) + String formatterBitcoinAmountToString({required int amount}) => bitcoinAmountToString(amount: amount); @override - double formatterBitcoinAmountToDouble({int amount}) + double formatterBitcoinAmountToDouble({required int amount}) => bitcoinAmountToDouble(amount: amount); @override int formatterStringDoubleToBitcoinAmount(String amount) => stringDoubleToBitcoinAmount(amount); + @override + String bitcoinTransactionPriorityWithLabel(TransactionPriority priority, int rate) + => (priority as BitcoinTransactionPriority).labelWithRate(rate); + @override List getUnspents(Object wallet) { final bitcoinWallet = wallet as ElectrumWallet; @@ -127,4 +140,20 @@ class CWBitcoin extends Bitcoin { WalletService createLitecoinWalletService(Box walletInfoSource, Box unspentCoinSource) { return LitecoinWalletService(walletInfoSource, unspentCoinSource); } + + @override + TransactionPriority getBitcoinTransactionPriorityMedium() + => BitcoinTransactionPriority.medium; + + @override + TransactionPriority getLitecoinTransactionPriorityMedium() + => LitecoinTransactionPriority.medium; + + @override + TransactionPriority getBitcoinTransactionPrioritySlow() + => BitcoinTransactionPriority.slow; + + @override + TransactionPriority getLitecoinTransactionPrioritySlow() + => LitecoinTransactionPriority.slow; } \ No newline at end of file diff --git a/lib/buy/buy_amount.dart b/lib/buy/buy_amount.dart index 1a1b3ae28..e41bb1148 100644 --- a/lib/buy/buy_amount.dart +++ b/lib/buy/buy_amount.dart @@ -2,13 +2,13 @@ import 'package:flutter/foundation.dart'; class BuyAmount { BuyAmount({ - @required this.sourceAmount, - @required this.destAmount, + required this.sourceAmount, + required this.destAmount, this.achSourceAmount, this.minAmount = 0}); final double sourceAmount; final double destAmount; - final double achSourceAmount; + final double? achSourceAmount; final int minAmount; } \ No newline at end of file diff --git a/lib/buy/buy_exception.dart b/lib/buy/buy_exception.dart index 28064fdfc..edc6a7db0 100644 --- a/lib/buy/buy_exception.dart +++ b/lib/buy/buy_exception.dart @@ -2,7 +2,7 @@ import 'package:flutter/foundation.dart'; import 'package:cake_wallet/buy/buy_provider_description.dart'; class BuyException implements Exception { - BuyException({@required this.description, @required this.text}); + BuyException({required this.description, required this.text}); final BuyProviderDescription description; final String text; diff --git a/lib/buy/buy_provider.dart b/lib/buy/buy_provider.dart index 0f496bad2..10a13ed94 100644 --- a/lib/buy/buy_provider.dart +++ b/lib/buy/buy_provider.dart @@ -5,7 +5,7 @@ import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_type.dart'; abstract class BuyProvider { - BuyProvider({this.wallet, this.isTestEnvironment}); + BuyProvider({required this.wallet, required this.isTestEnvironment}); final WalletBase wallet; final bool isTestEnvironment; diff --git a/lib/buy/buy_provider_description.dart b/lib/buy/buy_provider_description.dart index bcb581d05..07c7ff08b 100644 --- a/lib/buy/buy_provider_description.dart +++ b/lib/buy/buy_provider_description.dart @@ -2,20 +2,20 @@ import 'package:cw_core/enumerable_item.dart'; class BuyProviderDescription extends EnumerableItem with Serializable { - const BuyProviderDescription({String title, int raw}) + const BuyProviderDescription({required String title, required int raw}) : super(title: title, raw: raw); static const wyre = BuyProviderDescription(title: 'Wyre', raw: 0); static const moonPay = BuyProviderDescription(title: 'MoonPay', raw: 1); - static BuyProviderDescription deserialize({int raw}) { + static BuyProviderDescription deserialize({required int raw}) { switch (raw) { case 0: return wyre; case 1: return moonPay; default: - return null; + throw Exception('Incorrect token $raw for BuyProviderDescription deserialize'); } } } \ No newline at end of file diff --git a/lib/buy/get_buy_provider_icon.dart b/lib/buy/get_buy_provider_icon.dart index 672dfdd9d..c755d9615 100644 --- a/lib/buy/get_buy_provider_icon.dart +++ b/lib/buy/get_buy_provider_icon.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:cake_wallet/buy/buy_provider_description.dart'; -Image getBuyProviderIcon(BuyProviderDescription providerDescription, +Image? getBuyProviderIcon(BuyProviderDescription providerDescription, {Color iconColor = Colors.black}) { final _wyreIcon = diff --git a/lib/buy/moonpay/moonpay_buy_provider.dart b/lib/buy/moonpay/moonpay_buy_provider.dart index 4248df483..4ff3fb04c 100644 --- a/lib/buy/moonpay/moonpay_buy_provider.dart +++ b/lib/buy/moonpay/moonpay_buy_provider.dart @@ -23,7 +23,7 @@ class MoonPaySellProvider { final bool isTest; final String baseUrl; - Future requestUrl({CryptoCurrency currency, String refundWalletAddress}) async { + Future requestUrl({required CryptoCurrency currency, required String refundWalletAddress}) async { final originalUri = Uri.https( baseUrl, '', { 'apiKey': _apiKey, @@ -48,10 +48,9 @@ class MoonPaySellProvider { } class MoonPayBuyProvider extends BuyProvider { - MoonPayBuyProvider({WalletBase wallet, bool isTestEnvironment = false}) - : super(wallet: wallet, isTestEnvironment: isTestEnvironment) { - baseUrl = isTestEnvironment ? _baseTestUrl : _baseProductUrl; - } + MoonPayBuyProvider({required WalletBase wallet, bool isTestEnvironment = false}) + : baseUrl = isTestEnvironment ? _baseTestUrl : _baseProductUrl, + super(wallet: wallet, isTestEnvironment: isTestEnvironment); static const _baseTestUrl = 'https://buy-staging.moonpay.com'; static const _baseProductUrl = 'https://buy.moonpay.com'; @@ -109,8 +108,8 @@ class MoonPayBuyProvider extends BuyProvider { _quoteSuffix + '/?apiKey=' + _apiKey + '&baseCurrencyAmount=' + amount + '&baseCurrencyCode=' + sourceCurrency.toLowerCase(); - - final response = await get(url); + final uri = Uri.parse(url); + final response = await get(uri); if (response.statusCode != 200) { throw BuyException( @@ -133,8 +132,8 @@ class MoonPayBuyProvider extends BuyProvider { Future findOrderById(String id) async { final url = _apiUrl + _transactionsSuffix + '/$id' + '?apiKey=' + _apiKey; - - final response = await get(url); + final uri = Uri.parse(url); + final response = await get(uri); if (response.statusCode != 200) { throw BuyException( @@ -164,8 +163,8 @@ class MoonPayBuyProvider extends BuyProvider { static Future onEnabled() async { final url = _apiUrl + _ipAddressSuffix + '?apiKey=' + _apiKey; var isBuyEnable = false; - - final response = await get(url); + final uri = Uri.parse(url); + final response = await get(uri); try { final responseJSON = json.decode(response.body) as Map; diff --git a/lib/buy/order.dart b/lib/buy/order.dart index 24c5f58db..387fbcd34 100644 --- a/lib/buy/order.dart +++ b/lib/buy/order.dart @@ -8,54 +8,59 @@ part 'order.g.dart'; @HiveType(typeId: Order.typeId) class Order extends HiveObject { Order( - {this.id, - BuyProviderDescription provider, - this.transferId, + {required this.id, + required this.transferId, + required this.createdAt, + required this.amount, + required this.receiveAddress, + required this.walletId, + BuyProviderDescription? provider, + TradeState? state, this.from, - this.to, - TradeState state, - this.createdAt, - this.amount, - this.receiveAddress, - this.walletId}) - : providerRaw = provider?.raw, - stateRaw = state?.raw; + this.to}) { + if (provider != null) { + providerRaw = provider.raw; + } + if (state != null) { + stateRaw = state.raw; + } + } static const typeId = 8; static const boxName = 'Orders'; static const boxKey = 'ordersBoxKey'; - @HiveField(0) + @HiveField(0, defaultValue: '') String id; - @HiveField(1) + @HiveField(1, defaultValue: '') String transferId; @HiveField(2) - String from; + String? from; @HiveField(3) - String to; + String? to; - @HiveField(4) - String stateRaw; + @HiveField(4, defaultValue: '') + late String stateRaw; TradeState get state => TradeState.deserialize(raw: stateRaw); @HiveField(5) DateTime createdAt; - @HiveField(6) + @HiveField(6, defaultValue: '') String amount; - @HiveField(7) + @HiveField(7, defaultValue: '') String receiveAddress; - @HiveField(8) + @HiveField(8, defaultValue: '') String walletId; - @HiveField(9) - int providerRaw; + @HiveField(9, defaultValue: 0) + late int providerRaw; BuyProviderDescription get provider => BuyProviderDescription.deserialize(raw: providerRaw); diff --git a/lib/buy/wyre/wyre_buy_provider.dart b/lib/buy/wyre/wyre_buy_provider.dart index aac8c3db6..652c92f58 100644 --- a/lib/buy/wyre/wyre_buy_provider.dart +++ b/lib/buy/wyre/wyre_buy_provider.dart @@ -11,12 +11,11 @@ import 'package:cake_wallet/exchange/trade_state.dart'; import 'package:cake_wallet/.secrets.g.dart' as secrets; class WyreBuyProvider extends BuyProvider { - WyreBuyProvider({WalletBase wallet, bool isTestEnvironment = false}) - : super(wallet: wallet, isTestEnvironment: isTestEnvironment) { - baseApiUrl = isTestEnvironment + WyreBuyProvider({required WalletBase wallet, bool isTestEnvironment = false}) + : baseApiUrl = isTestEnvironment ? _baseTestApiUrl - : _baseProductApiUrl; - } + : _baseProductApiUrl, + super(wallet: wallet, isTestEnvironment: isTestEnvironment); static const _baseTestApiUrl = 'https://api.testwyre.com'; static const _baseProductApiUrl = 'https://api.sendwyre.com'; @@ -50,6 +49,7 @@ class WyreBuyProvider extends BuyProvider { final timestamp = DateTime.now().millisecondsSinceEpoch.toString(); final url = baseApiUrl + _ordersSuffix + _reserveSuffix + _timeStampSuffix + timestamp; + final uri = Uri.parse(url); final body = { 'amount': amount, 'sourceCurrency': sourceCurrency, @@ -58,8 +58,7 @@ class WyreBuyProvider extends BuyProvider { 'referrerAccountId': _accountId, 'lockFields': ['amount', 'sourceCurrency', 'destCurrency', 'dest'] }; - - final response = await post(url, + final response = await post(uri, headers: { 'Authorization': 'Bearer $_secretKey', 'Content-Type': 'application/json', @@ -89,8 +88,8 @@ class WyreBuyProvider extends BuyProvider { 'accountId': _accountId, 'country': _countryCode }; - - final response = await post(quoteUrl, + final uri = Uri.parse(quoteUrl); + final response = await post(uri, headers: { 'Authorization': 'Bearer $_secretKey', 'Content-Type': 'application/json', @@ -115,7 +114,8 @@ class WyreBuyProvider extends BuyProvider { @override Future findOrderById(String id) async { final orderUrl = baseApiUrl + _ordersSuffix + '/$id'; - final orderResponse = await get(orderUrl); + final orderUri = Uri.parse(orderUrl); + final orderResponse = await get(orderUri); if (orderResponse.statusCode != 200) { throw BuyException( @@ -136,7 +136,8 @@ class WyreBuyProvider extends BuyProvider { final transferUrl = baseApiUrl + _transferSuffix + transferId + _trackSuffix; - final transferResponse = await get(transferUrl); + final transferUri = Uri.parse(transferUrl); + final transferResponse = await get(transferUri); if (transferResponse.statusCode != 200) { throw BuyException( diff --git a/lib/core/address_label_validator.dart b/lib/core/address_label_validator.dart index 2b30272db..908e3a2e8 100644 --- a/lib/core/address_label_validator.dart +++ b/lib/core/address_label_validator.dart @@ -3,7 +3,7 @@ import 'package:cake_wallet/generated/i18n.dart'; import 'package:cw_core/wallet_type.dart'; class AddressLabelValidator extends TextValidator { - AddressLabelValidator({WalletType type}) + AddressLabelValidator({WalletType? type}) : super( errorMessage: S.current.error_text_subaddress_name, pattern: '''^[^`,'"]{1,20}\$''', diff --git a/lib/core/address_validator.dart b/lib/core/address_validator.dart index fec250a08..9d7b0e3b5 100644 --- a/lib/core/address_validator.dart +++ b/lib/core/address_validator.dart @@ -4,7 +4,7 @@ import 'package:cake_wallet/core/validator.dart'; import 'package:cw_core/crypto_currency.dart'; class AddressValidator extends TextValidator { - AddressValidator({@required CryptoCurrency type}) + AddressValidator({required CryptoCurrency type}) : super( errorMessage: S.current.error_text_address, pattern: getPattern(type), @@ -13,37 +13,29 @@ class AddressValidator extends TextValidator { static String getPattern(CryptoCurrency type) { switch (type) { case CryptoCurrency.xmr: - return '[0-9a-zA-Z]'; + return '^4[0-9a-zA-Z]{94}\$|^8[0-9a-zA-Z]{94}\$|^[0-9a-zA-Z]{106}\$'; case CryptoCurrency.ada: return '^[0-9a-zA-Z]{59}\$|^[0-9a-zA-Z]{92}\$|^[0-9a-zA-Z]{104}\$' '|^[0-9a-zA-Z]{105}\$|^addr1[0-9a-zA-Z]{98}\$'; - case CryptoCurrency.bch: - return '[0-9a-zA-Z]'; - case CryptoCurrency.bnb: - return '[0-9a-zA-Z]'; case CryptoCurrency.btc: return '^1[0-9a-zA-Z]{32}\$|^1[0-9a-zA-Z]{33}\$|^3[0-9a-zA-Z]{32}\$' '|^3[0-9a-zA-Z]{33}\$|^bc1[0-9a-zA-Z]{39}\$|^bc1[0-9a-zA-Z]{59}\$'; - case CryptoCurrency.dai: - return '[0-9a-zA-Z]'; - case CryptoCurrency.dash: - return '[0-9a-zA-Z]'; - case CryptoCurrency.eos: - return '[0-9a-zA-Z]'; - case CryptoCurrency.eth: - return '[0-9a-zA-Z]'; - case CryptoCurrency.ltc: - return '[0-9a-zA-Z]'; case CryptoCurrency.nano: return '[0-9a-zA-Z_]'; - case CryptoCurrency.trx: - return '[0-9a-zA-Z]'; - case CryptoCurrency.usdt: - return '[0-9a-zA-Z]'; - case CryptoCurrency.usdterc20: - return '[0-9a-zA-Z]'; - case CryptoCurrency.xlm: - return '[0-9a-zA-Z]'; + case CryptoCurrency.usdc: + case CryptoCurrency.usdcpoly: + case CryptoCurrency.husd: + case CryptoCurrency.ape: + case CryptoCurrency.avaxc: + case CryptoCurrency.eth: + case CryptoCurrency.mana: + case CryptoCurrency.matic: + case CryptoCurrency.maticpoly: + case CryptoCurrency.mkr: + case CryptoCurrency.oxt: + case CryptoCurrency.paxg: + case CryptoCurrency.uni: + return '0x[0-9a-zA-Z]'; case CryptoCurrency.xrp: return '^[0-9a-zA-Z]{34}\$|^X[0-9a-zA-Z]{46}\$'; case CryptoCurrency.xhv: @@ -61,18 +53,54 @@ class AddressValidator extends TextValidator { case CryptoCurrency.xnok: case CryptoCurrency.xnzd: case CryptoCurrency.xusd: + case CryptoCurrency.usdt: + case CryptoCurrency.usdterc20: + case CryptoCurrency.xlm: + case CryptoCurrency.trx: + case CryptoCurrency.dai: + case CryptoCurrency.dash: + case CryptoCurrency.eos: + case CryptoCurrency.ltc: + case CryptoCurrency.bch: + case CryptoCurrency.bnb: return '[0-9a-zA-Z]'; + case CryptoCurrency.hbar: + return '[0-9a-zA-Z.]'; + case CryptoCurrency.zaddr: + return '^zs[0-9a-zA-Z]{75}'; + case CryptoCurrency.zec: + return '^t1[0-9a-zA-Z]{33}\$|^t3[0-9a-zA-Z]{33}\$'; + case CryptoCurrency.dcr: + return 'D[ksecS]([0-9a-zA-Z])+'; + case CryptoCurrency.rvn: + return '[Rr]([1-9a-km-zA-HJ-NP-Z]){33}'; + case CryptoCurrency.near: + return '[0-9a-f]{64}'; + case CryptoCurrency.rune: + return 'thor1[0-9a-z]{38}'; + case CryptoCurrency.scrt: + return 'secret1[0-9a-z]{38}'; + case CryptoCurrency.stx: + return 'S[MP][0-9a-zA-Z]+'; + case CryptoCurrency.kmd: + return 'R[0-9a-zA-Z]{33}'; + case CryptoCurrency.pivx: + return 'D([1-9a-km-zA-HJ-NP-Z]){33}'; default: return '[0-9a-zA-Z]'; } } - static List getLength(CryptoCurrency type) { + static List? getLength(CryptoCurrency type) { switch (type) { case CryptoCurrency.xmr: - return [95, 106]; + return null; case CryptoCurrency.ada: return null; + case CryptoCurrency.ape: + return [42]; + case CryptoCurrency.avaxc: + return [42]; case CryptoCurrency.bch: return [42]; case CryptoCurrency.bnb: @@ -91,12 +119,22 @@ class AddressValidator extends TextValidator { return [34, 43]; case CryptoCurrency.nano: return [64, 65]; + case CryptoCurrency.sc: + return [76]; + case CryptoCurrency.sol: + return [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44]; case CryptoCurrency.trx: return [34]; + case CryptoCurrency.usdc: + return [42]; + case CryptoCurrency.usdcsol: + return [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44]; case CryptoCurrency.usdt: return [34]; case CryptoCurrency.usdterc20: return [42]; + case CryptoCurrency.usdttrc20: + return [34]; case CryptoCurrency.xlm: return [56]; case CryptoCurrency.xrp: @@ -116,6 +154,48 @@ class AddressValidator extends TextValidator { case CryptoCurrency.xnzd: case CryptoCurrency.xusd: return [98, 99, 106]; + case CryptoCurrency.btt: + return [34]; + case CryptoCurrency.bttbsc: + return [34]; + case CryptoCurrency.doge: + return [34]; + case CryptoCurrency.firo: + return [34]; + case CryptoCurrency.hbar: + return [4, 5, 6, 7, 8, 9, 10, 11]; + case CryptoCurrency.xvg: + return [34]; + case CryptoCurrency.zen: + return [35]; + case CryptoCurrency.zaddr: + return null; + case CryptoCurrency.zec: + return null; + case CryptoCurrency.kmd: + case CryptoCurrency.pivx: + case CryptoCurrency.rvn: + return [34]; + case CryptoCurrency.dcr: + return [35]; + case CryptoCurrency.stx: + return [40, 41, 42]; + case CryptoCurrency.usdcpoly: + case CryptoCurrency.husd: + case CryptoCurrency.mana: + case CryptoCurrency.matic: + case CryptoCurrency.maticpoly: + case CryptoCurrency.mkr: + case CryptoCurrency.oxt: + case CryptoCurrency.paxg: + case CryptoCurrency.uni: + return [42]; + case CryptoCurrency.rune: + return [43]; + case CryptoCurrency.scrt: + return [45]; + case CryptoCurrency.near: + return [64]; default: return []; } diff --git a/lib/core/amount.dart b/lib/core/amount.dart index 62e59db18..3d64f1d66 100644 --- a/lib/core/amount.dart +++ b/lib/core/amount.dart @@ -1,37 +1,37 @@ -abstract class Amount { - Amount(this.value); +// abstract class Amount { +// Amount(this.value); - int value; +// int value; - int minorDigits; +// int minorDigits; - String code; +// String code; - String formatted(); -} +// String formatted(); +// } -class MoneroAmount extends Amount { - MoneroAmount(int value) : super(value) { - minorDigits = 12; - code = 'XMR'; - } +// class MoneroAmount extends Amount { +// MoneroAmount(int value) : super(value) { +// minorDigits = 12; +// code = 'XMR'; +// } - // const moneroAmountLength = 12; - // const moneroAmountDivider = 1000000000000; - // final moneroAmountFormat = NumberFormat() - // ..maximumFractionDigits = moneroAmountLength - // ..minimumFractionDigits = 1; +// // const moneroAmountLength = 12; +// // const moneroAmountDivider = 1000000000000; +// // final moneroAmountFormat = NumberFormat() +// // ..maximumFractionDigits = moneroAmountLength +// // ..minimumFractionDigits = 1; - // String moneroAmountToString({int amount}) => - // moneroAmountFormat.format(cryptoAmountToDouble(amount: amount, divider: moneroAmountDivider)); +// // String moneroAmountToString({int amount}) => +// // moneroAmountFormat.format(cryptoAmountToDouble(amount: amount, divider: moneroAmountDivider)); - // double moneroAmountToDouble({int amount}) => cryptoAmountToDouble(amount: amount, divider: moneroAmountDivider); +// // double moneroAmountToDouble({int amount}) => cryptoAmountToDouble(amount: amount, divider: moneroAmountDivider); - // int moneroParseAmount({String amount}) => moneroAmountFormat.parse(amount).toInt(); +// // int moneroParseAmount({String amount}) => moneroAmountFormat.parse(amount).toInt(); - @override - String formatted() { - // TODO: implement formatted - throw UnimplementedError(); - } -} +// @override +// String formatted() { +// // TODO: implement formatted +// throw UnimplementedError(); +// } +// } diff --git a/lib/core/amount_validator.dart b/lib/core/amount_validator.dart index 52e75969f..3b14b0832 100644 --- a/lib/core/amount_validator.dart +++ b/lib/core/amount_validator.dart @@ -3,7 +3,7 @@ import 'package:cake_wallet/generated/i18n.dart'; import 'package:cw_core/wallet_type.dart'; class AmountValidator extends TextValidator { - AmountValidator({WalletType type, bool isAutovalidate = false}) + AmountValidator({required WalletType type, bool isAutovalidate = false}) : super( errorMessage: S.current.error_text_amount, pattern: _pattern(type), diff --git a/lib/core/auth_service.dart b/lib/core/auth_service.dart index f2c07d265..2ae37e2b0 100644 --- a/lib/core/auth_service.dart +++ b/lib/core/auth_service.dart @@ -6,12 +6,12 @@ import 'package:cake_wallet/entities/secret_store_key.dart'; import 'package:cake_wallet/entities/encrypt.dart'; class AuthService with Store { - AuthService({this.secureStorage, this.sharedPreferences}); + AuthService({required this.secureStorage, required this.sharedPreferences}); final FlutterSecureStorage secureStorage; final SharedPreferences sharedPreferences; - Future setPassword(String password) async { + Future setPassword(String password) async { final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword); final encodedPassword = encodedPinCode(pin: password); await secureStorage.write(key: key, value: encodedPassword); @@ -24,7 +24,7 @@ class AuthService with Store { var password = ''; try { - password = await secureStorage.read(key: key); + password = await secureStorage.read(key: key) ?? ''; } catch (e) { print(e); } @@ -35,7 +35,7 @@ class AuthService with Store { Future authenticate(String pin) async { final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword); final encodedPin = await secureStorage.read(key: key); - final decodedPin = decodedPinCode(pin: encodedPin); + final decodedPin = decodedPinCode(pin: encodedPin!); return decodedPin == pin; } diff --git a/lib/core/auth_state.dart b/lib/core/auth_state.dart index 01e4c2576..44d83eb33 100644 --- a/lib/core/auth_state.dart +++ b/lib/core/auth_state.dart @@ -7,13 +7,13 @@ class AuthenticationInProgress extends AuthState {} class AuthenticatedSuccessfully extends AuthState {} class AuthenticationFailure extends AuthState { - AuthenticationFailure({this.error}); + AuthenticationFailure({required this.error}); final String error; } class AuthenticationBanned extends AuthState { - AuthenticationBanned({this.error}); + AuthenticationBanned({required this.error}); final String error; } diff --git a/lib/core/backup_service.dart b/lib/core/backup_service.dart index 227af2d6c..999b67120 100644 --- a/lib/core/backup_service.dart +++ b/lib/core/backup_service.dart @@ -16,15 +16,18 @@ import 'package:cake_wallet/entities/secret_store_key.dart'; import 'package:cw_core/wallet_info.dart'; import 'package:cake_wallet/.secrets.g.dart' as secrets; import 'package:cake_wallet/wallet_types.g.dart'; +import 'package:cake_backup/backup.dart' as cake_backup; class BackupService { BackupService(this._flutterSecureStorage, this._walletInfoSource, this._keyService, this._sharedPreferences) - : _cipher = chacha20Poly1305Aead; + : _cipher = Cryptography.instance.chacha20Poly1305Aead(), + _correctWallets = []; - static const currentVersion = _v1; + static const currentVersion = _v2; static const _v1 = 1; + static const _v2 = 2; final Cipher _cipher; final FlutterSecureStorage _flutterSecureStorage; @@ -36,13 +39,16 @@ class BackupService { Future importBackup(Uint8List data, String password, {String nonce = secrets.backupSalt}) async { final version = getVersion(data); - final backupBytes = data.toList()..removeAt(0); - final backupData = Uint8List.fromList(backupBytes); switch (version) { case _v1: + final backupBytes = data.toList()..removeAt(0); + final backupData = Uint8List.fromList(backupBytes); await _importBackupV1(backupData, password, nonce: nonce); break; + case _v2: + await _importBackupV2(data, password); + break; default: break; } @@ -53,20 +59,26 @@ class BackupService { switch (version) { case _v1: return await _exportBackupV1(password, nonce: nonce); + case _v2: + return await _exportBackupV2(password); default: - return null; + throw Exception('Incorrect version: $version for exportBackup'); } } + @Deprecated('Use v2 instead') Future _exportBackupV1(String password, - {String nonce = secrets.backupSalt}) async { + {String nonce = secrets.backupSalt}) async + => throw Exception('Deprecated. Export for backups v1 is deprecated. Please use export v2.'); + + Future _exportBackupV2(String password) async { final zipEncoder = ZipFileEncoder(); final appDir = await getApplicationDocumentsDirectory(); final now = DateTime.now(); final tmpDir = Directory('${appDir.path}/~_BACKUP_TMP'); final archivePath = '${tmpDir.path}/backup_${now.toString()}.zip'; final fileEntities = appDir.listSync(recursive: false); - final keychainDump = await _exportKeychainDump(password, nonce: nonce); + final keychainDump = await _exportKeychainDumpV2(password); final preferencesDump = await _exportPreferencesJSON(); final preferencesDumpFile = File('${tmpDir.path}/~_preferences_dump_TMP'); final keychainDumpFile = File('${tmpDir.path}/~_keychain_dump_TMP'); @@ -91,21 +103,19 @@ class BackupService { }); await keychainDumpFile.writeAsBytes(keychainDump.toList()); await preferencesDumpFile.writeAsString(preferencesDump); - zipEncoder.addFile(preferencesDumpFile, '~_preferences_dump'); - zipEncoder.addFile(keychainDumpFile, '~_keychain_dump'); + await zipEncoder.addFile(preferencesDumpFile, '~_preferences_dump'); + await zipEncoder.addFile(keychainDumpFile, '~_keychain_dump'); zipEncoder.close(); final content = File(archivePath).readAsBytesSync(); tmpDir.deleteSync(recursive: true); - final encryptedData = await _encrypt(content, password, nonce); - - return setVersion(encryptedData, currentVersion); + return await _encryptV2(content, password); } Future _importBackupV1(Uint8List data, String password, - {@required String nonce}) async { + {required String nonce}) async { final appDir = await getApplicationDocumentsDirectory(); - final decryptedData = await _decrypt(data, password, nonce); + final decryptedData = await _decryptV1(data, password, nonce); final zip = ZipDecoder().decodeBytes(decryptedData); zip.files.forEach((file) { @@ -122,7 +132,30 @@ class BackupService { }); await _verifyWallets(); - await _importKeychainDump(password, nonce: nonce); + await _importKeychainDumpV1(password, nonce: nonce); + await _importPreferencesDump(); + } + + Future _importBackupV2(Uint8List data, String password) async { + final appDir = await getApplicationDocumentsDirectory(); + final decryptedData = await _decryptV2(data, password); + final zip = ZipDecoder().decodeBytes(decryptedData); + + zip.files.forEach((file) { + final filename = file.name; + + if (file.isFile) { + final content = file.content as List; + File('${appDir.path}/' + filename) + ..createSync(recursive: true) + ..writeAsBytesSync(content); + } else { + Directory('${appDir.path}/' + filename)..create(recursive: true); + } + }); + + await _verifyWallets(); + await _importKeychainDumpV2(password); await _importPreferencesDump(); } @@ -159,7 +192,7 @@ class BackupService { } final data = - json.decode(preferencesFile.readAsStringSync()) as Map; + json.decode(preferencesFile.readAsStringSync()) as Map; String currentWalletName = data[PreferencesKey.currentWalletName] as String; int currentWalletType = data[PreferencesKey.currentWalletType] as int; @@ -172,53 +205,97 @@ class BackupService { currentWalletType = serializeToInt(_correctWallets.first.type); } + final currentNodeId = data[PreferencesKey.currentNodeIdKey] as int?; + final currentBalanceDisplayMode = data[PreferencesKey.currentBalanceDisplayModeKey] as int?; + final currentFiatCurrency = data[PreferencesKey.currentFiatCurrencyKey] as String?; + final shouldSaveRecipientAddress = data[PreferencesKey.shouldSaveRecipientAddressKey] as bool?; + final currentTransactionPriorityKeyLegacy = data[PreferencesKey.currentTransactionPriorityKeyLegacy] as int?; + final allowBiometricalAuthentication = data[PreferencesKey.allowBiometricalAuthenticationKey] as bool?; + final currentBitcoinElectrumSererId = data[PreferencesKey.currentBitcoinElectrumSererIdKey] as int?; + final currentLanguageCode = data[PreferencesKey.currentLanguageCode] as String?; + final displayActionListMode = data[PreferencesKey.displayActionListModeKey] as int?; + final currentPinLength = data[PreferencesKey.currentPinLength] as int?; + final currentTheme = data[PreferencesKey.currentTheme] as int?; + final currentDefaultSettingsMigrationVersion = data[PreferencesKey.currentDefaultSettingsMigrationVersion] as int?; + final moneroTransactionPriority = data[PreferencesKey.moneroTransactionPriority] as int?; + final bitcoinTransactionPriority = data[PreferencesKey.bitcoinTransactionPriority] as int?; + await _sharedPreferences.setString(PreferencesKey.currentWalletName, currentWalletName); - await _sharedPreferences.setInt(PreferencesKey.currentNodeIdKey, - data[PreferencesKey.currentNodeIdKey] as int); - await _sharedPreferences.setInt(PreferencesKey.currentBalanceDisplayModeKey, - data[PreferencesKey.currentBalanceDisplayModeKey] as int); + + if (currentNodeId != null) + await _sharedPreferences.setInt(PreferencesKey.currentNodeIdKey, + currentNodeId); + + if (currentBalanceDisplayMode != null) + await _sharedPreferences.setInt(PreferencesKey.currentBalanceDisplayModeKey, + currentBalanceDisplayMode); + await _sharedPreferences.setInt(PreferencesKey.currentWalletType, currentWalletType); - await _sharedPreferences.setString(PreferencesKey.currentFiatCurrencyKey, - data[PreferencesKey.currentFiatCurrencyKey] as String); - await _sharedPreferences.setBool( + + if (currentFiatCurrency != null) + await _sharedPreferences.setString(PreferencesKey.currentFiatCurrencyKey, + currentFiatCurrency); + + if (shouldSaveRecipientAddress != null) + await _sharedPreferences.setBool( PreferencesKey.shouldSaveRecipientAddressKey, - data[PreferencesKey.shouldSaveRecipientAddressKey] as bool); - await _sharedPreferences.setInt( + shouldSaveRecipientAddress); + + if (currentTransactionPriorityKeyLegacy != null) + await _sharedPreferences.setInt( PreferencesKey.currentTransactionPriorityKeyLegacy, - data[PreferencesKey.currentTransactionPriorityKeyLegacy] as int); - await _sharedPreferences.setBool( + currentTransactionPriorityKeyLegacy); + + if (allowBiometricalAuthentication != null) + await _sharedPreferences.setBool( PreferencesKey.allowBiometricalAuthenticationKey, - data[PreferencesKey.allowBiometricalAuthenticationKey] as bool); - await _sharedPreferences.setInt( + allowBiometricalAuthentication); + + if (currentBitcoinElectrumSererId != null) + await _sharedPreferences.setInt( PreferencesKey.currentBitcoinElectrumSererIdKey, - data[PreferencesKey.currentBitcoinElectrumSererIdKey] as int); - await _sharedPreferences.setString(PreferencesKey.currentLanguageCode, - data[PreferencesKey.currentLanguageCode] as String); - await _sharedPreferences.setInt(PreferencesKey.displayActionListModeKey, - data[PreferencesKey.displayActionListModeKey] as int); - await _sharedPreferences.setInt(PreferencesKey.currentPinLength, - data[PreferencesKey.currentPinLength] as int); - await _sharedPreferences.setInt( - PreferencesKey.currentTheme, data[PreferencesKey.currentTheme] as int); - await _sharedPreferences.setInt( + currentBitcoinElectrumSererId); + + if (currentLanguageCode != null) + await _sharedPreferences.setString(PreferencesKey.currentLanguageCode, + currentLanguageCode); + + if (displayActionListMode != null) + await _sharedPreferences.setInt(PreferencesKey.displayActionListModeKey, + displayActionListMode); + + if (currentPinLength != null) + await _sharedPreferences.setInt(PreferencesKey.currentPinLength, + currentPinLength); + + if (currentTheme != null) + await _sharedPreferences.setInt( + PreferencesKey.currentTheme, currentTheme); + + if (currentDefaultSettingsMigrationVersion != null) + await _sharedPreferences.setInt( PreferencesKey.currentDefaultSettingsMigrationVersion, - data[PreferencesKey.currentDefaultSettingsMigrationVersion] as int); - await _sharedPreferences.setInt(PreferencesKey.moneroTransactionPriority, - data[PreferencesKey.moneroTransactionPriority] as int); - await _sharedPreferences.setInt(PreferencesKey.bitcoinTransactionPriority, - data[PreferencesKey.bitcoinTransactionPriority] as int); + currentDefaultSettingsMigrationVersion); + + if (moneroTransactionPriority != null) + await _sharedPreferences.setInt(PreferencesKey.moneroTransactionPriority, + moneroTransactionPriority); + + if (bitcoinTransactionPriority != null) + await _sharedPreferences.setInt(PreferencesKey.bitcoinTransactionPriority, + bitcoinTransactionPriority); await preferencesFile.delete(); } - Future _importKeychainDump(String password, - {@required String nonce, + Future _importKeychainDumpV1(String password, + {required String nonce, String keychainSalt = secrets.backupKeychainSalt}) async { final appDir = await getApplicationDocumentsDirectory(); final keychainDumpFile = File('${appDir.path}/~_keychain_dump'); - final decryptedKeychainDumpFileData = await _decrypt( + final decryptedKeychainDumpFileData = await _decryptV1( keychainDumpFile.readAsBytesSync(), '$keychainSalt$password', nonce); final keychainJSON = json.decode(utf8.decode(decryptedKeychainDumpFileData)) as Map; @@ -243,6 +320,35 @@ class BackupService { keychainDumpFile.deleteSync(); } + Future _importKeychainDumpV2(String password, + {String keychainSalt = secrets.backupKeychainSalt}) async { + final appDir = await getApplicationDocumentsDirectory(); + final keychainDumpFile = File('${appDir.path}/~_keychain_dump'); + final decryptedKeychainDumpFileData = await _decryptV2( + keychainDumpFile.readAsBytesSync(), '$keychainSalt$password'); + final keychainJSON = json.decode(utf8.decode(decryptedKeychainDumpFileData)) + as Map; + final keychainWalletsInfo = keychainJSON['wallets'] as List; + final decodedPin = keychainJSON['pin'] as String; + final pinCodeKey = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword); + final backupPasswordKey = + generateStoreKeyFor(key: SecretStoreKey.backupPassword); + final backupPassword = keychainJSON[backupPasswordKey] as String; + + await _flutterSecureStorage.write( + key: backupPasswordKey, value: backupPassword); + + keychainWalletsInfo.forEach((dynamic rawInfo) async { + final info = rawInfo as Map; + await importWalletKeychainInfo(info); + }); + + await _flutterSecureStorage.write( + key: pinCodeKey, value: encodedPinCode(pin: decodedPin)); + + keychainDumpFile.deleteSync(); + } + Future importWalletKeychainInfo(Map info) async { final name = info['name'] as String; final password = info['password'] as String; @@ -250,12 +356,17 @@ class BackupService { await _keyService.saveWalletPassword(walletName: name, password: password); } - Future _exportKeychainDump(String password, - {@required String nonce, - String keychainSalt = secrets.backupKeychainSalt}) async { + @Deprecated('Use v2 instead') + Future _exportKeychainDumpV1(String password, + {required String nonce, + String keychainSalt = secrets.backupKeychainSalt}) async + => throw Exception('Deprecated'); + + Future _exportKeychainDumpV2(String password, + {String keychainSalt = secrets.backupKeychainSalt}) async { final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword); final encodedPin = await _flutterSecureStorage.read(key: key); - final decodedPin = decodedPinCode(pin: encodedPin); + final decodedPin = decodedPinCode(pin: encodedPin!); final wallets = await Future.wait(_walletInfoSource.values.map((walletInfo) async { return { @@ -274,14 +385,14 @@ class BackupService { 'wallets': wallets, backupPasswordKey: backupPassword })); - final encrypted = await _encrypt( - Uint8List.fromList(data), '$keychainSalt$password', nonce); + final encrypted = await _encryptV2( + Uint8List.fromList(data), '$keychainSalt$password'); return encrypted; } Future _exportPreferencesJSON() async { - final preferences = { + final preferences = { PreferencesKey.currentWalletName: _sharedPreferences.getString(PreferencesKey.currentWalletName), PreferencesKey.currentNodeIdKey: @@ -328,19 +439,29 @@ class BackupService { return Uint8List.fromList(bytes); } - Future _encrypt( - Uint8List data, String secretKeySource, String nonceBase64) async { - final secretKeyHash = await sha256.hash(utf8.encode(secretKeySource)); + @Deprecated('Use v2 instead') + Future _encryptV1( + Uint8List data, String secretKeySource, String nonceBase64) async + => throw Exception('Deprecated'); + + Future _decryptV1( + Uint8List data, String secretKeySource, String nonceBase64, {int macLength = 16}) async { + final secretKeyHash = await Cryptography.instance.sha256().hash(utf8.encode(secretKeySource)); final secretKey = SecretKey(secretKeyHash.bytes); - final nonce = Nonce(base64.decode(nonceBase64)); - return await _cipher.encrypt(data, secretKey: secretKey, nonce: nonce); + final nonce = base64.decode(nonceBase64).toList(); + final box = SecretBox( + Uint8List.sublistView(data, 0, data.lengthInBytes - macLength).toList(), + nonce: nonce, + mac: Mac(Uint8List.sublistView(data, data.lengthInBytes - macLength))); + final plainData = await _cipher.decrypt(box, secretKey: secretKey); + return Uint8List.fromList(plainData); } - Future _decrypt( - Uint8List data, String secretKeySource, String nonceBase64) async { - final secretKeyHash = await sha256.hash(utf8.encode(secretKeySource)); - final secretKey = SecretKey(secretKeyHash.bytes); - final nonce = Nonce(base64.decode(nonceBase64)); - return await _cipher.decrypt(data, secretKey: secretKey, nonce: nonce); - } + Future _encryptV2( + Uint8List data, String passphrase) async + => cake_backup.encrypt(passphrase, data, version: _v2); + + Future _decryptV2( + Uint8List data, String passphrase) async + => cake_backup.decrypt(passphrase, data); } diff --git a/lib/core/fiat_conversion_service.dart b/lib/core/fiat_conversion_service.dart index 7a0513d5c..f4ec3775b 100644 --- a/lib/core/fiat_conversion_service.dart +++ b/lib/core/fiat_conversion_service.dart @@ -16,7 +16,7 @@ Future _fetchPrice(Map args) async { final fiatStringified = fiat.toString(); final uri = Uri.https(fiatApiAuthority, fiatApiPath, {'convert': fiatStringified}); - final response = await get(uri.toString()); + final response = await get(uri); if (response.statusCode != 200) { return 0.0; diff --git a/lib/core/key_service.dart b/lib/core/key_service.dart index eafca2b0a..1fe99623e 100644 --- a/lib/core/key_service.dart +++ b/lib/core/key_service.dart @@ -7,15 +7,14 @@ class KeyService { final FlutterSecureStorage _secureStorage; - Future getWalletPassword({String walletName}) async { + Future getWalletPassword({required String walletName}) async { final key = generateStoreKeyFor( key: SecretStoreKey.moneroWalletPassword, walletName: walletName); final encodedPassword = await _secureStorage.read(key: key); - - return decodeWalletPassword(password: encodedPassword); + return decodeWalletPassword(password: encodedPassword!); } - Future saveWalletPassword({String walletName, String password}) async { + Future saveWalletPassword({required String walletName, required String password}) async { final key = generateStoreKeyFor( key: SecretStoreKey.moneroWalletPassword, walletName: walletName); final encodedPassword = encodeWalletPassword(password: password); diff --git a/lib/core/monero_account_label_validator.dart b/lib/core/monero_account_label_validator.dart index 7e287959b..ef4cf0f9a 100644 --- a/lib/core/monero_account_label_validator.dart +++ b/lib/core/monero_account_label_validator.dart @@ -4,7 +4,7 @@ import 'package:cake_wallet/core/validator.dart'; import 'package:cw_core/crypto_currency.dart'; class MoneroLabelValidator extends TextValidator { - MoneroLabelValidator({@required CryptoCurrency type}) + MoneroLabelValidator() : super( errorMessage: S.current.error_text_account_name, pattern: '^[a-zA-Z0-9_ ]{1,15}\$', diff --git a/lib/core/seed_validator.dart b/lib/core/seed_validator.dart index e1e5920fd..fe9a25f85 100644 --- a/lib/core/seed_validator.dart +++ b/lib/core/seed_validator.dart @@ -7,23 +7,24 @@ import 'package:cake_wallet/monero/monero.dart'; import 'package:cake_wallet/utils/language_list.dart'; class SeedValidator extends Validator { - SeedValidator({this.type, this.language}) - : _words = getWordList(type: type, language: language); + SeedValidator({required this.type, required this.language}) + : _words = getWordList(type: type, language: language), + super(errorMessage: 'Wrong seed mnemonic'); final WalletType type; final String language; final List _words; - static List getWordList({WalletType type, String language}) { + static List getWordList({required WalletType type, required String language}) { switch (type) { case WalletType.bitcoin: return getBitcoinWordList(language); case WalletType.litecoin: return getBitcoinWordList(language); case WalletType.monero: - return monero.getMoneroWordList(language); + return monero!.getMoneroWordList(language); case WalletType.haven: - return haven.getMoneroWordList(language); + return haven!.getMoneroWordList(language); default: return []; } @@ -31,9 +32,9 @@ class SeedValidator extends Validator { static List getBitcoinWordList(String language) { assert(language.toLowerCase() == LanguageList.english.toLowerCase()); - return bitcoin.getWordList(); + return bitcoin!.getWordList(); } @override - bool isValid(MnemonicItem value) => _words.contains(value.text); + bool isValid(MnemonicItem? value) => _words.contains(value?.text); } diff --git a/lib/core/sync_status_title.dart b/lib/core/sync_status_title.dart index e6b04c245..e46ec2490 100644 --- a/lib/core/sync_status_title.dart +++ b/lib/core/sync_status_title.dart @@ -33,4 +33,6 @@ String syncStatusTitle(SyncStatus syncStatus) { if (syncStatus is LostConnectionSyncStatus) { return S.current.sync_status_failed_connect; } + + return ''; } \ No newline at end of file diff --git a/lib/core/validator.dart b/lib/core/validator.dart index 055439347..96c382b7d 100644 --- a/lib/core/validator.dart +++ b/lib/core/validator.dart @@ -1,13 +1,13 @@ import 'package:flutter/foundation.dart'; abstract class Validator { - Validator({@required this.errorMessage}); + Validator({required this.errorMessage}); final String errorMessage; - bool isValid(T value); + bool isValid(T? value); - String call(T value) => !isValid(value) ? errorMessage : null; + String? call(T? value) => !isValid(value) ? errorMessage : null; } class TextValidator extends Validator { @@ -15,28 +15,28 @@ class TextValidator extends Validator { {this.minLength, this.maxLength, this.pattern, + String errorMessage = '', this.length, - this.isAutovalidate = false, - String errorMessage}) + this.isAutovalidate = false}) : super(errorMessage: errorMessage); - final int minLength; - final int maxLength; - final List length; + final int? minLength; + final int? maxLength; + final List? length; final bool isAutovalidate; - String pattern; + String? pattern; @override - bool isValid(String value) { + bool isValid(String? value) { if (value == null || value.isEmpty) { return isAutovalidate ? true : false; } return value.length > (minLength ?? 0) && (length?.contains(value.length) ?? true) && - ((maxLength ?? 0) > 0 ? (value.length <= maxLength) : true) && + ((maxLength ?? 0) > 0 ? (value.length <= maxLength!) : true) && (pattern != null ? match(value) : true); } - bool match(String value) => RegExp(pattern).hasMatch(value); + bool match(String value) => pattern != null ? RegExp(pattern!).hasMatch(value) : false; } diff --git a/lib/core/wallet_creation_service.dart b/lib/core/wallet_creation_service.dart index 1fe36f374..3b28f36c3 100644 --- a/lib/core/wallet_creation_service.dart +++ b/lib/core/wallet_creation_service.dart @@ -14,15 +14,13 @@ import 'package:cw_core/wallet_type.dart'; class WalletCreationService { WalletCreationService( - {WalletType initialType, - this.secureStorage, - this.keyService, - this.sharedPreferences, - this.walletInfoSource}) + {required WalletType initialType, + required this.secureStorage, + required this.keyService, + required this.sharedPreferences, + required this.walletInfoSource}) : type = initialType { - if (type != null) { - changeWalletType(type: type); - } + changeWalletType(type: type); } WalletType type; @@ -30,11 +28,11 @@ class WalletCreationService { final SharedPreferences sharedPreferences; final KeyService keyService; final Box walletInfoSource; - WalletService _service; + WalletService? _service; static const _isNewMoneroWalletPasswordUpdated = true; - void changeWalletType({@required WalletType type}) { + void changeWalletType({required WalletType type}) { this.type = type; _service = getIt.get(param1: type); } @@ -64,7 +62,7 @@ class WalletCreationService { credentials.password = password; await keyService.saveWalletPassword( password: password, walletName: credentials.name); - final wallet = await _service.create(credentials); + final wallet = await _service!.create(credentials); if (wallet.type == WalletType.monero) { await sharedPreferences @@ -82,7 +80,7 @@ class WalletCreationService { credentials.password = password; await keyService.saveWalletPassword( password: password, walletName: credentials.name); - final wallet = await _service.restoreFromKeys(credentials); + final wallet = await _service!.restoreFromKeys(credentials); if (wallet.type == WalletType.monero) { await sharedPreferences @@ -100,7 +98,7 @@ class WalletCreationService { credentials.password = password; await keyService.saveWalletPassword( password: password, walletName: credentials.name); - final wallet = await _service.restoreFromSeed(credentials); + final wallet = await _service!.restoreFromSeed(credentials); if (wallet.type == WalletType.monero) { await sharedPreferences diff --git a/lib/core/wallet_creation_state.dart b/lib/core/wallet_creation_state.dart index c732a1899..728bc477f 100644 --- a/lib/core/wallet_creation_state.dart +++ b/lib/core/wallet_creation_state.dart @@ -7,7 +7,7 @@ class WalletCreating extends WalletCreationState {} class WalletCreatedSuccessfully extends WalletCreationState {} class WalletCreationFailure extends WalletCreationState { - WalletCreationFailure({@required this.error}); + WalletCreationFailure({required this.error}); final String error; } \ No newline at end of file diff --git a/lib/core/wallet_loading_service.dart b/lib/core/wallet_loading_service.dart index 844e5c1ca..5bae5b346 100644 --- a/lib/core/wallet_loading_service.dart +++ b/lib/core/wallet_loading_service.dart @@ -17,18 +17,15 @@ class WalletLoadingService { final WalletService Function(WalletType type) walletServiceFactory; Future load(WalletType type, String name) async { - if (walletServiceFactory == null) { - throw Exception('WalletLoadingService.walletServiceFactory is not set'); - } - final walletService = walletServiceFactory?.call(type); + final walletService = walletServiceFactory.call(type); final password = await keyService.getWalletPassword(walletName: name); - final wallet = await walletService.openWallet(name, password); + final wallet = await walletService.openWallet(name, password); - if (type == WalletType.monero) { - await upateMoneroWalletPassword(wallet); - } + if (type == WalletType.monero) { + await upateMoneroWalletPassword(wallet); + } - return wallet; + return wallet; } Future upateMoneroWalletPassword(WalletBase wallet) async { diff --git a/lib/di.dart b/lib/di.dart index 5cc698d27..7ce2ff6d9 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -4,6 +4,7 @@ import 'package:cake_wallet/entities/wake_lock.dart'; import 'package:cake_wallet/ionia/ionia_anypay.dart'; import 'package:cake_wallet/ionia/ionia_gift_card.dart'; import 'package:cake_wallet/ionia/ionia_tip.dart'; +import 'package:cake_wallet/src/screens/buy/onramper_page.dart'; import 'package:cake_wallet/src/screens/ionia/cards/ionia_custom_redeem_page.dart'; import 'package:cake_wallet/src/screens/ionia/cards/ionia_gift_card_detail_page.dart'; import 'package:cake_wallet/src/screens/ionia/cards/ionia_more_options_page.dart'; @@ -156,26 +157,26 @@ import 'package:cake_wallet/core/wallet_loading_service.dart'; final getIt = GetIt.instance; var _isSetupFinished = false; -Box _walletInfoSource; -Box _nodeSource; -Box _contactSource; -Box _tradesSource; -Box