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/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/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/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/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/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/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 271066f58..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, @@ -46,6 +51,23 @@ class CryptoCurrency extends EnumerableItem with Serializable { 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); @@ -97,10 +119,27 @@ class CryptoCurrency extends EnumerableItem with Serializable { 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 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({int raw}) { + static CryptoCurrency deserialize({required int raw}) { switch (raw) { case 0: return CryptoCurrency.xmr; @@ -194,8 +233,42 @@ class CryptoCurrency extends EnumerableItem with Serializable { 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'); } } @@ -293,8 +366,42 @@ class CryptoCurrency extends EnumerableItem with Serializable { 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..1f2cfe7d2 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; + late String uriRaw; @HiveField(1) - String login; + String? login; @HiveField(2) - String password; + String? password; @HiveField(3) - int typeRaw; + 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..420517939 100644 --- a/cw_core/lib/unspent_coins_info.dart +++ b/cw_core/lib/unspent_coins_info.dart @@ -5,11 +5,11 @@ 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'; @@ -28,5 +28,9 @@ class UnspentCoinsInfo extends HiveObject { 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..66ed1e932 100644 --- a/cw_core/lib/wallet_info.dart +++ b/cw_core/lib/wallet_info.dart @@ -13,20 +13,20 @@ 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); } @@ -61,18 +61,18 @@ class WalletInfo extends HiveObject { 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..f8f120bd6 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,26 +230,25 @@ 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 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..b53a3ebd1 100644 --- a/lib/anypay/anypay_api.dart +++ b/lib/anypay/anypay_api.dart @@ -33,15 +33,15 @@ 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': '*/*',}; @@ -50,20 +50,20 @@ class AnyPayApi { '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': '*/*',}; @@ -71,7 +71,7 @@ class AnyPayApi { '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..ff6fd7531 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; 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..16dfbb4e0 100644 --- a/lib/buy/order.dart +++ b/lib/buy/order.dart @@ -8,18 +8,23 @@ 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'; @@ -32,13 +37,13 @@ class Order extends HiveObject { String transferId; @HiveField(2) - String from; + String? from; @HiveField(3) - String to; + String? to; @HiveField(4) - String stateRaw; + late String stateRaw; TradeState get state => TradeState.deserialize(raw: stateRaw); @@ -55,7 +60,7 @@ class Order extends HiveObject { String walletId; @HiveField(9) - int providerRaw; + 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 9ef8d3340..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), @@ -17,39 +17,25 @@ class AddressValidator extends TextValidator { 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.ape: - return '0x[0-9a-zA-Z]'; - case CryptoCurrency.avaxc: - return '0x[0-9a-zA-Z]'; - 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 '0x[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.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.usdt: - return '[0-9a-zA-Z]'; - case CryptoCurrency.usdterc20: - return '[0-9a-zA-Z]'; - case CryptoCurrency.xlm: - return '[0-9a-zA-Z]'; case CryptoCurrency.xrp: return '^[0-9a-zA-Z]{34}\$|^X[0-9a-zA-Z]{46}\$'; case CryptoCurrency.xhv: @@ -67,6 +53,16 @@ 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.]'; @@ -74,12 +70,28 @@ class AddressValidator extends TextValidator { 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 null; @@ -160,6 +172,30 @@ class AddressValidator extends TextValidator { 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