Flutter upgrade

M committed Oct 12, 2022 at 13:09 UTC 1beb18b04575d2e0735ec52f2592f0bb330800db
505 files changed +6658 -5876
analysis_options.yaml
+68 -46
@@ -1,51 +1,73 @@
1 +include: package:lints/recommended.yaml
2 +
3 analyzer:
2 - strong-mode:
3 - implicit-casts: false
4 - implicit-dynamic: false
5 - exclude: [build/**, lib/generated/*.dart, lib/**.g.dart, cw_monero/ios/External/**, cw_shared_external/**, shared_external/**]
4 + exclude: [
5 + build/**,
6 + lib/**.g.dart,
7 + cw_core/lib/**.g.dart,
8 + cw_haven/lib/**.g.dart,
9 + cw_monero/lib/**.g.dart,
10 + lib/generated/*.dart,
11 + cw_monero/ios/External/**,
12 + cw_shared_external/**,
13 + shared_external/**]
14 + language:
15 + strict-casts: true
16 + strict-raw-types: true
17
18 linter:
19 rules:
9 - - always_declare_return_types
10 - - annotate_overrides
11 - - avoid_empty_else
12 - - avoid_init_to_null
13 - - avoid_return_types_on_setters
14 - - await_only_futures
15 - - camel_case_types
20 - cancel_subscriptions
17 - - close_sinks
18 - - comment_references
19 - - constant_identifier_names
20 - - control_flow_in_finally
21 - - empty_catches
22 - - empty_constructor_bodies
23 - - empty_statements
24 - - hash_and_equals
25 - - invariant_booleans
26 - - iterable_contains_unrelated_type
27 - - library_names
28 - - library_prefixes
29 - - list_remove_unrelated_type
30 - - literal_only_boolean_expressions
31 - - non_constant_identifier_names
32 - - one_member_abstracts
33 - - only_throw_errors
34 - - overridden_fields
35 - - package_api_docs
36 - - package_names
37 - - package_prefixed_library_names
38 - - parameter_assignments
39 - - prefer_final_fields
40 - - prefer_final_locals
41 - - prefer_is_not_empty
42 - - slash_for_doc_comments
43 - - sort_constructors_first
44 - - sort_unnamed_constructors_first
45 - - test_types_in_equals
46 - - throw_in_finally
47 - - type_init_formals
48 - - unawaited_futures
49 - - unnecessary_getters_setters
50 - - unrelated_type_equality_checks
51 - - valid_regexps
\ No newline at end of file
21 +
22 +
23 +# analyzer:
24 +# strong-mode:
25 +# implicit-casts: false
26 +# implicit-dynamic: false
27 +# exclude: [build/**, lib/generated/*.dart, lib/**.g.dart, cw_monero/ios/External/**, cw_shared_external/**, shared_external/**]
28 +
29 +# linter:
30 +# rules:
31 +# - always_declare_return_types
32 +# - annotate_overrides
33 +# - avoid_empty_else
34 +# - avoid_init_to_null
35 +# - avoid_return_types_on_setters
36 +# - await_only_futures
37 +# - camel_case_types
38 +# - cancel_subscriptions
39 +# - close_sinks
40 +# - comment_references
41 +# - constant_identifier_names
42 +# - control_flow_in_finally
43 +# - empty_catches
44 +# - empty_constructor_bodies
45 +# - empty_statements
46 +# - hash_and_equals
47 +# - invariant_booleans
48 +# - iterable_contains_unrelated_type
49 +# - library_names
50 +# - library_prefixes
51 +# - list_remove_unrelated_type
52 +# - literal_only_boolean_expressions
53 +# - non_constant_identifier_names
54 +# - one_member_abstracts
55 +# - only_throw_errors
56 +# - overridden_fields
57 +# - package_api_docs
58 +# - package_names
59 +# - package_prefixed_library_names
60 +# - parameter_assignments
61 +# - prefer_final_fields
62 +# - prefer_final_locals
63 +# - prefer_is_not_empty
64 +# - slash_for_doc_comments
65 +# - sort_constructors_first
66 +# - sort_unnamed_constructors_first
67 +# - test_types_in_equals
68 +# - throw_in_finally
69 +# - type_init_formals
70 +# - unawaited_futures
71 +# - unnecessary_getters_setters
72 +# - unrelated_type_equality_checks
73 +# - valid_regexps
\ No newline at end of file
cw_bitcoin/lib/address_from_output.dart
+3 -3
@@ -8,7 +8,7 @@ String addressFromOutput(Uint8List script, bitcoin.NetworkType networkType) {
8 data: PaymentData(output: script),
9 network: networkType)
10 .data
11 - .address;
11 + .address!;
12 } catch (_) {}
13
14 try {
@@ -16,8 +16,8 @@ String addressFromOutput(Uint8List script, bitcoin.NetworkType networkType) {
16 data: PaymentData(output: script),
17 network: networkType)
18 .data
19 - .address;
19 + .address!;
20 } catch(_) {}
21
22 - return null;
22 + return '';
23 }
\ No newline at end of file
cw_bitcoin/lib/bitcoin_address_record.dart
+3 -3
@@ -2,7 +2,7 @@ import 'dart:convert';
2
3 class BitcoinAddressRecord {
4 BitcoinAddressRecord(this.address,
5 - {this.index, this.isHidden = false, bool isUsed = false})
5 + {required this.index, this.isHidden = false, bool isUsed = false})
6 : _isUsed = isUsed;
7
8 factory BitcoinAddressRecord.fromJSON(String jsonSource) {
@@ -11,8 +11,8 @@ class BitcoinAddressRecord {
11 return BitcoinAddressRecord(
12 decoded['address'] as String,
13 index: decoded['index'] as int,
14 - isHidden: decoded['isHidden'] as bool ?? false,
15 - isUsed: decoded['isUsed'] as bool ?? false);
14 + isHidden: decoded['isHidden'] as bool? ?? false,
15 + isUsed: decoded['isUsed'] as bool? ?? false);
16 }
17
18 @override
cw_bitcoin/lib/bitcoin_amount_format.dart
+2 -2
@@ -7,10 +7,10 @@ final bitcoinAmountFormat = NumberFormat()
7 ..maximumFractionDigits = bitcoinAmountLength
8 ..minimumFractionDigits = 1;
9
10 -String bitcoinAmountToString({int amount}) => bitcoinAmountFormat.format(
10 +String bitcoinAmountToString({required int amount}) => bitcoinAmountFormat.format(
11 cryptoAmountToDouble(amount: amount, divider: bitcoinAmountDivider));
12
13 -double bitcoinAmountToDouble({int amount}) =>
13 +double bitcoinAmountToDouble({required int amount}) =>
14 cryptoAmountToDouble(amount: amount, divider: bitcoinAmountDivider);
15
16 int stringDoubleToBitcoinAmount(String amount) {
cw_bitcoin/lib/bitcoin_mnemonic.dart
+8 -5
@@ -106,15 +106,18 @@ Future<String> generateMnemonic(
106 return result;
107 }
108
109 -Uint8List mnemonicToSeedBytes(String mnemonic, {String prefix = segwit}) {
109 +Future<Uint8List> mnemonicToSeedBytes(String mnemonic, {String prefix = segwit}) async {
110 final pbkdf2 = cryptography.Pbkdf2(
111 - macAlgorithm: cryptography.Hmac(cryptography.sha512),
111 + macAlgorithm: cryptography.Hmac.sha512(),
112 iterations: 2048,
113 bits: 512);
114 final text = normalizeText(mnemonic);
115 -
116 - return pbkdf2.deriveBitsSync(text.codeUnits,
117 - nonce: cryptography.Nonce('electrum'.codeUnits));
115 + // pbkdf2.deriveKey(secretKey: secretKey, nonce: nonce)
116 + final key = await pbkdf2.deriveKey(
117 + secretKey: cryptography.SecretKey(text.codeUnits),
118 + nonce: 'electrum'.codeUnits);
119 + final bytes = await key.extractBytes();
120 + return Uint8List.fromList(bytes);
121 }
122
123 bool matchesAnyPrefix(String mnemonic) =>
cw_bitcoin/lib/bitcoin_transaction_credentials.dart
+3 -3
@@ -2,9 +2,9 @@ import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
2 import 'package:cw_core/output_info.dart';
3
4 class BitcoinTransactionCredentials {
5 - BitcoinTransactionCredentials(this.outputs, {this.priority, this.feeRate});
5 + BitcoinTransactionCredentials(this.outputs, {required this.priority, this.feeRate});
6
7 final List<OutputInfo> outputs;
8 - final BitcoinTransactionPriority priority;
9 - final int feeRate;
8 + final BitcoinTransactionPriority? priority;
9 + final int? feeRate;
10 }
cw_bitcoin/lib/bitcoin_transaction_priority.dart
+6 -6
@@ -2,7 +2,7 @@ import 'package:cw_core/transaction_priority.dart';
2 //import 'package:cake_wallet/generated/i18n.dart';
3
4 class BitcoinTransactionPriority extends TransactionPriority {
5 - const BitcoinTransactionPriority({String title, int raw})
5 + const BitcoinTransactionPriority({required String title, required int raw})
6 : super(title: title, raw: raw);
7
8 static const List<BitcoinTransactionPriority> all = [fast, medium, slow];
@@ -13,7 +13,7 @@ class BitcoinTransactionPriority extends TransactionPriority {
13 static const BitcoinTransactionPriority fast =
14 BitcoinTransactionPriority(title: 'Fast', raw: 2);
15
16 - static BitcoinTransactionPriority deserialize({int raw}) {
16 + static BitcoinTransactionPriority deserialize({required int raw}) {
17 switch (raw) {
18 case 0:
19 return slow;
@@ -22,7 +22,7 @@ class BitcoinTransactionPriority extends TransactionPriority {
22 case 2:
23 return fast;
24 default:
25 - return null;
25 + throw Exception('Unexpected token: $raw for BitcoinTransactionPriority deserialize');
26 }
27 }
28
@@ -53,7 +53,7 @@ class BitcoinTransactionPriority extends TransactionPriority {
53 }
54
55 class LitecoinTransactionPriority extends BitcoinTransactionPriority {
56 - const LitecoinTransactionPriority({String title, int raw})
56 + const LitecoinTransactionPriority({required String title, required int raw})
57 : super(title: title, raw: raw);
58
59 static const List<LitecoinTransactionPriority> all = [fast, medium, slow];
@@ -64,7 +64,7 @@ class LitecoinTransactionPriority extends BitcoinTransactionPriority {
64 static const LitecoinTransactionPriority fast =
65 LitecoinTransactionPriority(title: 'Fast', raw: 2);
66
67 - static LitecoinTransactionPriority deserialize({int raw}) {
67 + static LitecoinTransactionPriority deserialize({required int raw}) {
68 switch (raw) {
69 case 0:
70 return slow;
@@ -73,7 +73,7 @@ class LitecoinTransactionPriority extends BitcoinTransactionPriority {
73 case 2:
74 return fast;
75 default:
76 - return null;
76 + throw Exception('Unexpected token: $raw for LitecoinTransactionPriority deserialize');
77 }
78 }
79
cw_bitcoin/lib/bitcoin_wallet.dart
+40 -15
@@ -1,4 +1,5 @@
1 import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
2 +import 'package:cw_core/crypto_currency.dart';
3 import 'package:cw_core/unspent_coins_info.dart';
4 import 'package:hive/hive.dart';
5 import 'package:mobx/mobx.dart';
@@ -17,12 +18,13 @@ class BitcoinWallet = BitcoinWalletBase with _$BitcoinWallet;
18
19 abstract class BitcoinWalletBase extends ElectrumWallet with Store {
20 BitcoinWalletBase(
20 - {@required String mnemonic,
21 - @required String password,
22 - @required WalletInfo walletInfo,
23 - @required Box<UnspentCoinsInfo> unspentCoinsInfo,
24 - List<BitcoinAddressRecord> initialAddresses,
25 - ElectrumBalance initialBalance,
21 + {required String mnemonic,
22 + required String password,
23 + required WalletInfo walletInfo,
24 + required Box<UnspentCoinsInfo> unspentCoinsInfo,
25 + required Uint8List seedBytes,
26 + List<BitcoinAddressRecord>? initialAddresses,
27 + ElectrumBalance? initialBalance,
28 int initialRegularAddressIndex = 0,
29 int initialChangeAddressIndex = 0})
30 : super(
@@ -32,7 +34,9 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
34 unspentCoinsInfo: unspentCoinsInfo,
35 networkType: bitcoin.bitcoin,
36 initialAddresses: initialAddresses,
35 - initialBalance: initialBalance) {
37 + initialBalance: initialBalance,
38 + seedBytes: seedBytes,
39 + currency: CryptoCurrency.btc) {
40 walletAddresses = BitcoinWalletAddresses(
41 walletInfo,
42 electrumClient: electrumClient,
@@ -40,20 +44,40 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
44 initialRegularAddressIndex: initialRegularAddressIndex,
45 initialChangeAddressIndex: initialChangeAddressIndex,
46 mainHd: hd,
43 - sideHd: bitcoin.HDWallet.fromSeed(
44 - mnemonicToSeedBytes(mnemonic), network: networkType)
47 + sideHd: bitcoin.HDWallet.fromSeed(seedBytes, network: networkType)
48 .derivePath("m/0'/1"),
49 networkType: networkType);
50 }
51
52 + static Future<BitcoinWallet> create({
53 + required String mnemonic,
54 + required String password,
55 + required WalletInfo walletInfo,
56 + required Box<UnspentCoinsInfo> unspentCoinsInfo,
57 + List<BitcoinAddressRecord>? initialAddresses,
58 + ElectrumBalance? initialBalance,
59 + int initialRegularAddressIndex = 0,
60 + int initialChangeAddressIndex = 0
61 + }) async {
62 + return BitcoinWallet(
63 + mnemonic: mnemonic,
64 + password: password,
65 + walletInfo: walletInfo,
66 + unspentCoinsInfo: unspentCoinsInfo,
67 + initialAddresses: initialAddresses,
68 + initialBalance: initialBalance,
69 + seedBytes: await mnemonicToSeedBytes(mnemonic),
70 + initialRegularAddressIndex: initialRegularAddressIndex,
71 + initialChangeAddressIndex: initialChangeAddressIndex);
72 + }
73 +
74 static Future<BitcoinWallet> open({
50 - @required String name,
51 - @required WalletInfo walletInfo,
52 - @required Box<UnspentCoinsInfo> unspentCoinsInfo,
53 - @required String password,
75 + required String name,
76 + required WalletInfo walletInfo,
77 + required Box<UnspentCoinsInfo> unspentCoinsInfo,
78 + required String password,
79 }) async {
55 - final snp = ElectrumWallletSnapshot(name, walletInfo.type, password);
56 - await snp.load();
80 + final snp = await ElectrumWallletSnapshot.load(name, walletInfo.type, password);
81 return BitcoinWallet(
82 mnemonic: snp.mnemonic,
83 password: password,
@@ -61,6 +85,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
85 unspentCoinsInfo: unspentCoinsInfo,
86 initialAddresses: snp.addresses,
87 initialBalance: snp.balance,
88 + seedBytes: await mnemonicToSeedBytes(snp.mnemonic),
89 initialRegularAddressIndex: snp.regularAddressIndex,
90 initialChangeAddressIndex: snp.changeAddressIndex);
91 }
cw_bitcoin/lib/bitcoin_wallet_addresses.dart
+7 -7
@@ -16,13 +16,13 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses
16 with Store {
17 BitcoinWalletAddressesBase(
18 WalletInfo walletInfo,
19 - {@required List<BitcoinAddressRecord> initialAddresses,
19 + {required bitcoin.HDWallet mainHd,
20 + required bitcoin.HDWallet sideHd,
21 + required bitcoin.NetworkType networkType,
22 + required ElectrumClient electrumClient,
23 + List<BitcoinAddressRecord>? initialAddresses,
24 int initialRegularAddressIndex = 0,
21 - int initialChangeAddressIndex = 0,
22 - ElectrumClient electrumClient,
23 - @required bitcoin.HDWallet mainHd,
24 - @required bitcoin.HDWallet sideHd,
25 - @required bitcoin.NetworkType networkType})
25 + int initialChangeAddressIndex = 0})
26 : super(
27 walletInfo,
28 initialAddresses: initialAddresses,
@@ -34,6 +34,6 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses
34 networkType: networkType);
35
36 @override
37 - String getAddress({@required int index, @required bitcoin.HDWallet hd}) =>
37 + String getAddress({required int index, required bitcoin.HDWallet hd}) =>
38 generateP2WPKHAddress(hd: hd, index: index, networkType: networkType);
39 }
\ No newline at end of file
cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart
+3 -3
@@ -2,13 +2,13 @@ import 'package:cw_core/wallet_credentials.dart';
2 import 'package:cw_core/wallet_info.dart';
3
4 class BitcoinNewWalletCredentials extends WalletCredentials {
5 - BitcoinNewWalletCredentials({String name, WalletInfo walletInfo})
5 + BitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo})
6 : super(name: name, walletInfo: walletInfo);
7 }
8
9 class BitcoinRestoreWalletFromSeedCredentials extends WalletCredentials {
10 BitcoinRestoreWalletFromSeedCredentials(
11 - {String name, String password, this.mnemonic, WalletInfo walletInfo})
11 + {required String name, required String password, required this.mnemonic, WalletInfo? walletInfo})
12 : super(name: name, password: password, walletInfo: walletInfo);
13
14 final String mnemonic;
@@ -16,7 +16,7 @@ class BitcoinRestoreWalletFromSeedCredentials extends WalletCredentials {
16
17 class BitcoinRestoreWalletFromWIFCredentials extends WalletCredentials {
18 BitcoinRestoreWalletFromWIFCredentials(
19 - {String name, String password, this.wif, WalletInfo walletInfo})
19 + {required String name, required String password, required this.wif, WalletInfo? walletInfo})
20 : super(name: name, password: password, walletInfo: walletInfo);
21
22 final String wif;
cw_bitcoin/lib/bitcoin_wallet_keys.dart
+1 -3
@@ -1,7 +1,5 @@
1 -import 'package:flutter/foundation.dart';
2 -
1 class BitcoinWalletKeys {
4 - const BitcoinWalletKeys({@required this.wif, @required this.privateKey, @required this.publicKey});
2 + const BitcoinWalletKeys({required this.wif, required this.privateKey, required this.publicKey});
3
4 final String wif;
5 final String privateKey;
cw_bitcoin/lib/bitcoin_wallet_service.dart
+9 -9
@@ -10,6 +10,7 @@ import 'package:cw_core/pathForWallet.dart';
10 import 'package:cw_core/wallet_info.dart';
11 import 'package:cw_core/wallet_type.dart';
12 import 'package:hive/hive.dart';
13 +import 'package:collection/collection.dart';
14
15 class BitcoinWalletService extends WalletService<
16 BitcoinNewWalletCredentials,
@@ -25,10 +26,10 @@ class BitcoinWalletService extends WalletService<
26
27 @override
28 Future<BitcoinWallet> create(BitcoinNewWalletCredentials credentials) async {
28 - final wallet = BitcoinWallet(
29 + final wallet = await BitcoinWalletBase.create(
30 mnemonic: await generateMnemonic(),
30 - password: credentials.password,
31 - walletInfo: credentials.walletInfo,
31 + password: credentials.password!,
32 + walletInfo: credentials.walletInfo!,
33 unspentCoinsInfo: unspentCoinsInfoSource);
34 await wallet.save();
35 await wallet.init();
@@ -41,9 +42,8 @@ class BitcoinWalletService extends WalletService<
42
43 @override
44 Future<BitcoinWallet> openWallet(String name, String password) async {
44 - final walletInfo = walletInfoSource.values.firstWhere(
45 - (info) => info.id == WalletBase.idFor(name, getType()),
46 - orElse: () => null);
45 + final walletInfo = walletInfoSource.values.firstWhereOrNull(
46 + (info) => info.id == WalletBase.idFor(name, getType()))!;
47 final wallet = await BitcoinWalletBase.open(
48 password: password, name: name, walletInfo: walletInfo,
49 unspentCoinsInfo: unspentCoinsInfoSource);
@@ -68,10 +68,10 @@ class BitcoinWalletService extends WalletService<
68 throw BitcoinMnemonicIsIncorrectException();
69 }
70
71 - final wallet = BitcoinWallet(
72 - password: credentials.password,
71 + final wallet = await BitcoinWalletBase.create(
72 + password: credentials.password!,
73 mnemonic: credentials.mnemonic,
74 - walletInfo: credentials.walletInfo,
74 + walletInfo: credentials.walletInfo!,
75 unspentCoinsInfo: unspentCoinsInfoSource);
76 await wallet.save();
77 await wallet.init();
cw_bitcoin/lib/electrum.dart
+65 -44
@@ -7,6 +7,7 @@ import 'package:cw_bitcoin/bitcoin_amount_format.dart';
7 import 'package:cw_bitcoin/script_hash.dart';
8 import 'package:flutter/foundation.dart';
9 import 'package:rxdart/rxdart.dart';
10 +import 'package:collection/collection.dart';
11
12 String jsonrpcparams(List<Object> params) {
13 final _params = params?.map((val) => '"${val.toString()}"')?.join(',');
@@ -14,14 +15,20 @@ String jsonrpcparams(List<Object> params) {
15 }
16
17 String jsonrpc(
17 - {String method, List<Object> params, int id, double version = 2.0}) =>
18 + {required String method,
19 + required List<Object> params,
20 + required int id,
21 + double version = 2.0}) =>
22 '{"jsonrpc": "$version", "method": "$method", "id": "$id", "params": ${json.encode(params)}}\n';
23
24 class SocketTask {
21 - SocketTask({this.completer, this.isSubscription, this.subject});
25 + SocketTask({
26 + required this.isSubscription,
27 + this.completer,
28 + this.subject});
29
23 - final Completer completer;
24 - final BehaviorSubject subject;
30 + final Completer<dynamic>? completer;
31 + final BehaviorSubject<dynamic>? subject;
32 final bool isSubscription;
33 }
34
@@ -36,18 +43,18 @@ class ElectrumClient {
43 static const aliveTimerDuration = Duration(seconds: 2);
44
45 bool get isConnected => _isConnected;
39 - Socket socket;
40 - void Function(bool) onConnectionStatusChange;
46 + Socket? socket;
47 + void Function(bool)? onConnectionStatusChange;
48 int _id;
49 final Map<String, SocketTask> _tasks;
50 bool _isConnected;
44 - Timer _aliveTimer;
51 + Timer? _aliveTimer;
52 String unterminatedString;
53
54 Future<void> connectToUri(Uri uri) async =>
55 await connect(host: uri.host, port: uri.port);
56
50 - Future<void> connect({@required String host, @required int port}) async {
57 + Future<void> connect({required String host, required int port}) async {
58 try {
59 await socket?.close();
60 } catch (_) {}
@@ -56,10 +63,10 @@ class ElectrumClient {
63 timeout: connectionTimeout, onBadCertificate: (_) => true);
64 _setIsConnected(true);
65
59 - socket.listen((Uint8List event) {
66 + socket!.listen((Uint8List event) {
67 try {
68 final response =
62 - json.decode(utf8.decode(event.toList())) as Map<String, Object>;
69 + json.decode(utf8.decode(event.toList())) as Map<String, dynamic>;
70 _handleResponse(response);
71 } on FormatException catch (e) {
72 final msg = e.message.toLowerCase();
@@ -75,12 +82,12 @@ class ElectrumClient {
82
83 if (isJSONStringCorrect(unterminatedString)) {
84 final response =
78 - json.decode(unterminatedString) as Map<String, Object>;
85 + json.decode(unterminatedString) as Map<String, dynamic>;
86 _handleResponse(response);
87 unterminatedString = '';
88 }
89 } on TypeError catch (e) {
83 - if (!e.toString().contains('Map<String, Object>')) {
90 + if (!e.toString().contains('Map<String, Object>') || !e.toString().contains('Map<String, dynamic>')) {
91 return;
92 }
93
@@ -89,9 +96,10 @@ class ElectrumClient {
96
97 if (isJSONStringCorrect(unterminatedString)) {
98 final response =
92 - json.decode(unterminatedString) as Map<String, Object>;
99 + json.decode(unterminatedString) as Map<String, dynamic>;
100 _handleResponse(response);
94 - unterminatedString = null;
101 + // unterminatedString = null;
102 + unterminatedString = '';
103 }
104 } catch (e) {
105 print(e.toString());
@@ -207,7 +215,7 @@ class ElectrumClient {
215 });
216
217 Future<Map<String, Object>> getTransactionRaw(
210 - {@required String hash}) async =>
218 + {required String hash}) async =>
219 call(method: 'blockchain.transaction.get', params: [hash, true])
220 .then((dynamic result) {
221 if (result is Map<String, Object>) {
@@ -218,7 +226,7 @@ class ElectrumClient {
226 });
227
228 Future<String> getTransactionHex(
221 - {@required String hash}) async =>
229 + {required String hash}) async =>
230 call(method: 'blockchain.transaction.get', params: [hash, false])
231 .then((dynamic result) {
232 if (result is String) {
@@ -229,7 +237,7 @@ class ElectrumClient {
237 });
238
239 Future<String> broadcastTransaction(
232 - {@required String transactionRaw}) async =>
240 + {required String transactionRaw}) async =>
241 call(method: 'blockchain.transaction.broadcast', params: [transactionRaw])
242 .then((dynamic result) {
243 if (result is String) {
@@ -240,16 +248,16 @@ class ElectrumClient {
248 });
249
250 Future<Map<String, dynamic>> getMerkle(
243 - {@required String hash, @required int height}) async =>
251 + {required String hash, required int height}) async =>
252 await call(
253 method: 'blockchain.transaction.get_merkle',
254 params: [hash, height]) as Map<String, dynamic>;
255
248 - Future<Map<String, dynamic>> getHeader({@required int height}) async =>
256 + Future<Map<String, dynamic>> getHeader({required int height}) async =>
257 await call(method: 'blockchain.block.get_header', params: [height])
258 as Map<String, dynamic>;
259
252 - Future<double> estimatefee({@required int p}) =>
260 + Future<double> estimatefee({required int p}) =>
261 call(method: 'blockchain.estimatefee', params: [p])
262 .then((dynamic result) {
263 if (result is double) {
@@ -266,13 +274,26 @@ class ElectrumClient {
274 Future<List<List<int>>> feeHistogram() =>
275 call(method: 'mempool.get_fee_histogram').then((dynamic result) {
276 if (result is List) {
269 - return result.map((dynamic e) {
277 + // return result.map((dynamic e) {
278 + // if (e is List) {
279 + // return e.map((dynamic ee) => ee is int ? ee : null).toList();
280 + // }
281 +
282 + // return null;
283 + // }).toList();
284 + final histogram = <List<int>>[];
285 + for (final e in result) {
286 if (e is List) {
271 - return e.map((dynamic ee) => ee is int ? ee : null).toList();
287 + final eee = <int>[];
288 + for (final ee in e) {
289 + if (ee is int) {
290 + eee.add(ee);
291 + }
292 + }
293 + histogram.add(eee);
294 }
273 -
274 - return null;
275 - }).toList();
295 + }
296 + return histogram;
297 }
298
299 return [];
@@ -299,7 +320,7 @@ class ElectrumClient {
320 }
321 }
322
302 - BehaviorSubject<Object> scripthashUpdate(String scripthash) {
323 + BehaviorSubject<Object>? scripthashUpdate(String scripthash) {
324 _id += 1;
325 return subscribe<Object>(
326 id: 'blockchain.scripthash.subscribe:$scripthash',
@@ -307,14 +328,14 @@ class ElectrumClient {
328 params: [scripthash]);
329 }
330
310 - BehaviorSubject<T> subscribe<T>(
311 - {@required String id,
312 - @required String method,
331 + BehaviorSubject<T>? subscribe<T>(
332 + {required String id,
333 + required String method,
334 List<Object> params = const []}) {
335 try {
336 final subscription = BehaviorSubject<T>();
337 _regisrySubscription(id, subscription);
317 - socket.write(jsonrpc(method: method, id: _id, params: params));
338 + socket!.write(jsonrpc(method: method, id: _id, params: params));
339
340 return subscription;
341 } catch(e) {
@@ -323,18 +344,18 @@ class ElectrumClient {
344 }
345 }
346
326 - Future<dynamic> call({String method, List<Object> params = const []}) async {
347 + Future<dynamic> call({required String method, List<Object> params = const []}) async {
348 final completer = Completer<dynamic>();
349 _id += 1;
350 final id = _id;
351 _registryTask(id, completer);
331 - socket.write(jsonrpc(method: method, id: id, params: params));
352 + socket!.write(jsonrpc(method: method, id: id, params: params));
353
354 return completer.future;
355 }
356
357 Future<dynamic> callWithTimeout(
337 - {String method,
358 + {required String method,
359 List<Object> params = const [],
360 int timeout = 2000}) async {
361 try {
@@ -342,7 +363,7 @@ class ElectrumClient {
363 _id += 1;
364 final id = _id;
365 _registryTask(id, completer);
345 - socket.write(jsonrpc(method: method, id: id, params: params));
366 + socket!.write(jsonrpc(method: method, id: id, params: params));
367 Timer(Duration(milliseconds: timeout), () {
368 if (!completer.isCompleted) {
369 completer.completeError(RequestFailedTimeoutException(method, id));
@@ -356,35 +377,35 @@ class ElectrumClient {
377 }
378
379 Future<void> close() async {
359 - _aliveTimer.cancel();
360 - await socket.close();
380 + _aliveTimer?.cancel();
381 + await socket?.close();
382 onConnectionStatusChange = null;
383 }
384
364 - void _registryTask(int id, Completer completer) => _tasks[id.toString()] =
385 + void _registryTask(int id, Completer<dynamic> completer) => _tasks[id.toString()] =
386 SocketTask(completer: completer, isSubscription: false);
387
367 - void _regisrySubscription(String id, BehaviorSubject subject) =>
388 + void _regisrySubscription(String id, BehaviorSubject<dynamic> subject) =>
389 _tasks[id] = SocketTask(subject: subject, isSubscription: true);
390
370 - void _finish(String id, Object data) {
391 + void _finish(String id, Object? data) {
392 if (_tasks[id] == null) {
393 return;
394 }
395
396 if (!(_tasks[id]?.completer?.isCompleted ?? false)) {
376 - _tasks[id]?.completer?.complete(data);
397 + _tasks[id]?.completer!.complete(data);
398 }
399
400 if (!(_tasks[id]?.isSubscription ?? false)) {
380 - _tasks[id] = null;
401 + _tasks.remove(id);
402 } else {
382 - _tasks[id].subject.add(data);
403 + _tasks[id]?.subject?.add(data);
404 }
405 }
406
407 void _methodHandler(
387 - {@required String method, @required Map<String, Object> request}) {
408 + {required String method, required Map<String, dynamic> request}) {
409 switch (method) {
410 case 'blockchain.scripthash.subscribe':
411 final params = request['params'] as List<dynamic>;
@@ -406,7 +427,7 @@ class ElectrumClient {
427 _isConnected = isConnected;
428 }
429
409 - void _handleResponse(Map<String, Object> response) {
430 + void _handleResponse(Map<String, dynamic> response) {
431 final method = response['method'];
432 final id = response['id'] as String;
433 final result = response['result'];
cw_bitcoin/lib/electrum_balance.dart
+4 -4
@@ -4,10 +4,10 @@ import 'package:cw_bitcoin/bitcoin_amount_format.dart';
4 import 'package:cw_core/balance.dart';
5
6 class ElectrumBalance extends Balance {
7 - const ElectrumBalance({@required this.confirmed, @required this.unconfirmed})
7 + const ElectrumBalance({required this.confirmed, required this.unconfirmed})
8 : super(confirmed, unconfirmed);
9
10 - factory ElectrumBalance.fromJSON(String jsonSource) {
10 + static ElectrumBalance? fromJSON(String? jsonSource) {
11 if (jsonSource == null) {
12 return null;
13 }
@@ -15,8 +15,8 @@ class ElectrumBalance extends Balance {
15 final decoded = json.decode(jsonSource) as Map;
16
17 return ElectrumBalance(
18 - confirmed: decoded['confirmed'] as int ?? 0,
19 - unconfirmed: decoded['unconfirmed'] as int ?? 0);
18 + confirmed: decoded['confirmed'] as int? ?? 0,
19 + unconfirmed: decoded['unconfirmed'] as int? ?? 0);
20 }
21
22 final int confirmed;
cw_bitcoin/lib/electrum_transaction_history.dart
+9 -9
@@ -17,7 +17,7 @@ class ElectrumTransactionHistory = ElectrumTransactionHistoryBase
17 abstract class ElectrumTransactionHistoryBase
18 extends TransactionHistoryBase<ElectrumTransactionInfo> with Store {
19 ElectrumTransactionHistoryBase(
20 - {@required this.walletInfo, @required String password})
20 + {required this.walletInfo, required String password})
21 : _password = password,
22 _height = 0 {
23 transactions = ObservableMap<String, ElectrumTransactionInfo>();
@@ -56,18 +56,18 @@ abstract class ElectrumTransactionHistoryBase
56 await save();
57 }
58
59 - Future<Map<String, Object>> _read() async {
59 + Future<Map<String, dynamic>> _read() async {
60 final dirPath =
61 await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
62 final path = '$dirPath/$_transactionsHistoryFileName';
63 final content = await read(path: path, password: _password);
64 - return json.decode(content) as Map<String, Object>;
64 + return json.decode(content) as Map<String, dynamic>;
65 }
66
67 Future<void> _load() async {
68 try {
69 final content = await _read();
70 - final txs = content['transactions'] as Map<String, Object> ?? {};
70 + final txs = content['transactions'] as Map<String, dynamic> ?? {};
71
72 txs.entries.forEach((entry) {
73 final val = entry.value;
@@ -93,11 +93,11 @@ abstract class ElectrumTransactionHistoryBase
93 transactions[transaction.id] = transaction;
94 } else {
95 final originalTx = transactions[transaction.id];
96 - originalTx.confirmations = transaction.confirmations;
97 - originalTx.amount = transaction.amount;
98 - originalTx.height = transaction.height;
99 - originalTx.date ??= transaction.date;
100 - originalTx.isPending = transaction.isPending;
96 + originalTx?.confirmations = transaction.confirmations;
97 + originalTx?.amount = transaction.amount;
98 + originalTx?.height = transaction.height;
99 + originalTx?.date ??= transaction.date;
100 + originalTx?.isPending = transaction.isPending;
101 }
102 }
103 }
cw_bitcoin/lib/electrum_transaction_info.dart
+39 -34
@@ -10,23 +10,26 @@ import 'package:cw_core/format_amount.dart';
10 import 'package:cw_core/wallet_type.dart';
11
12 class ElectrumTransactionBundle {
13 - ElectrumTransactionBundle(this.originalTransaction, {this.ins, this.time, this.confirmations});
13 + ElectrumTransactionBundle(this.originalTransaction,
14 + {required this.ins,
15 + required this.confirmations,
16 + this.time});
17 final bitcoin.Transaction originalTransaction;
18 final List<bitcoin.Transaction> ins;
16 - final int time;
19 + final int? time;
20 final int confirmations;
21 }
22
23 class ElectrumTransactionInfo extends TransactionInfo {
24 ElectrumTransactionInfo(this.type,
22 - {@required String id,
23 - @required int height,
24 - @required int amount,
25 - @required int fee,
26 - @required TransactionDirection direction,
27 - @required bool isPending,
28 - @required DateTime date,
29 - @required int confirmations}) {
25 + {required String id,
26 + required int height,
27 + required int amount,
28 + int? fee,
29 + required TransactionDirection direction,
30 + required bool isPending,
31 + required DateTime date,
32 + required int confirmations}) {
33 this.id = id;
34 this.height = height;
35 this.amount = amount;
@@ -39,15 +42,15 @@ class ElectrumTransactionInfo extends TransactionInfo {
42
43 factory ElectrumTransactionInfo.fromElectrumVerbose(
44 Map<String, Object> obj, WalletType type,
42 - {@required List<BitcoinAddressRecord> addresses, @required int height}) {
45 + {required List<BitcoinAddressRecord> addresses, required int height}) {
46 final addressesSet = addresses.map((addr) => addr.address).toSet();
47 final id = obj['txid'] as String;
45 - final vins = obj['vin'] as List<Object> ?? [];
46 - final vout = (obj['vout'] as List<Object> ?? []);
48 + final vins = obj['vin'] as List<Object>? ?? [];
49 + final vout = (obj['vout'] as List<Object>? ?? []);
50 final date = obj['time'] is int
51 ? DateTime.fromMillisecondsSinceEpoch((obj['time'] as int) * 1000)
52 : DateTime.now();
50 - final confirmations = obj['confirmations'] as int ?? 0;
53 + final confirmations = obj['confirmations'] as int? ?? 0;
54 var direction = TransactionDirection.incoming;
55 var inputsAmount = 0;
56 var amount = 0;
@@ -57,21 +60,21 @@ class ElectrumTransactionInfo extends TransactionInfo {
60 final vout = vin['vout'] as int;
61 final out = vin['tx']['vout'][vout] as Map;
62 final outAddresses =
60 - (out['scriptPubKey']['addresses'] as List<Object>)?.toSet();
63 + (out['scriptPubKey']['addresses'] as List<Object>?)?.toSet();
64 inputsAmount +=
62 - stringDoubleToBitcoinAmount((out['value'] as double ?? 0).toString());
65 + stringDoubleToBitcoinAmount((out['value'] as double? ?? 0).toString());
66
64 - if (outAddresses?.intersection(addressesSet)?.isNotEmpty ?? false) {
67 + if (outAddresses?.intersection(addressesSet).isNotEmpty ?? false) {
68 direction = TransactionDirection.outgoing;
69 }
70 }
71
72 for (dynamic out in vout) {
73 final outAddresses =
71 - out['scriptPubKey']['addresses'] as List<Object> ?? [];
74 + out['scriptPubKey']['addresses'] as List<Object>? ?? [];
75 final ntrs = outAddresses.toSet().intersection(addressesSet);
76 final value = stringDoubleToBitcoinAmount(
74 - (out['value'] as double ?? 0.0).toString());
77 + (out['value'] as double? ?? 0.0).toString());
78 totalOutAmount += value;
79
80 if ((direction == TransactionDirection.incoming && ntrs.isNotEmpty) ||
@@ -97,10 +100,10 @@ class ElectrumTransactionInfo extends TransactionInfo {
100 ElectrumTransactionBundle bundle,
101 WalletType type,
102 bitcoin.NetworkType networkType,
100 - {@required Set<String> addresses,
101 - int height}) {
103 + {required Set<String> addresses,
104 + required int height}) {
105 final date = bundle.time != null
103 - ? DateTime.fromMillisecondsSinceEpoch(bundle.time * 1000)
106 + ? DateTime.fromMillisecondsSinceEpoch(bundle.time! * 1000)
107 : DateTime.now();
108 var direction = TransactionDirection.incoming;
109 var amount = 0;
@@ -111,21 +114,21 @@ class ElectrumTransactionInfo extends TransactionInfo {
114 final input = bundle.originalTransaction.ins[i];
115 final inputTransaction = bundle.ins[i];
116 final vout = input.index;
114 - final outTransaction = inputTransaction.outs[vout];
115 - final address = addressFromOutput(outTransaction.script, networkType);
116 - inputAmount += outTransaction.value;
117 + final outTransaction = inputTransaction.outs[vout!];
118 + final address = addressFromOutput(outTransaction.script!, networkType);
119 + inputAmount += outTransaction.value!;
120 if (addresses.contains(address)) {
121 direction = TransactionDirection.outgoing;
122 }
123 }
124
125 for (final out in bundle.originalTransaction.outs) {
123 - totalOutAmount += out.value;
124 - final address = addressFromOutput(out.script, networkType);
126 + totalOutAmount += out.value!;
127 + final address = addressFromOutput(out.script!, networkType);
128 final addressExists = addresses.contains(address);
129 if ((direction == TransactionDirection.incoming && addressExists) ||
130 (direction == TransactionDirection.outgoing && !addressExists)) {
128 - amount += out.value;
131 + amount += out.value!;
132 }
133 }
134
@@ -142,7 +145,7 @@ class ElectrumTransactionInfo extends TransactionInfo {
145 }
146
147 factory ElectrumTransactionInfo.fromHexAndHeader(WalletType type, String hex,
145 - {List<String> addresses, int height, int timestamp, int confirmations}) {
148 + {List<String>? addresses, required int height, int? timestamp, required int confirmations}) {
149 final tx = bitcoin.Transaction.fromHex(hex);
150 var exist = false;
151 var amount = 0;
@@ -155,7 +158,7 @@ class ElectrumTransactionInfo extends TransactionInfo {
158 exist = addresses.contains(p2pkh.data.address);
159
160 if (exist) {
158 - amount += out.value;
161 + amount += out.value!;
162 }
163 } catch (_) {}
164 });
@@ -191,15 +194,15 @@ class ElectrumTransactionInfo extends TransactionInfo {
194
195 final WalletType type;
196
194 - String _fiatAmount;
197 + String? _fiatAmount;
198
199 @override
200 String amountFormatted() =>
201 '${formatAmount(bitcoinAmountToString(amount: amount))} ${walletTypeToCryptoCurrency(type).title}';
202
203 @override
201 - String feeFormatted() => fee != null
202 - ? '${formatAmount(bitcoinAmountToString(amount: fee))} ${walletTypeToCryptoCurrency(type).title}'
204 + String? feeFormatted() => fee != null
205 + ? '${formatAmount(bitcoinAmountToString(amount: fee!))} ${walletTypeToCryptoCurrency(type).title}'
206 : '';
207
208 @override
@@ -225,7 +228,9 @@ class ElectrumTransactionInfo extends TransactionInfo {
228 m['id'] = id;
229 m['height'] = height;
230 m['amount'] = amount;
228 - m['direction'] = direction.index;
231 + // FIX-ME: Hardcoded value
232 + // m['direction'] = direction.index;
233 + m['direction'] = 0;
234 m['date'] = date.millisecondsSinceEpoch;
235 m['isPending'] = isPending;
236 m['confirmations'] = confirmations;
cw_bitcoin/lib/electrum_wallet.dart
+54 -50
@@ -34,6 +34,7 @@ import 'package:cw_core/wallet_info.dart';
34 import 'package:cw_bitcoin/electrum.dart';
35 import 'package:hex/hex.dart';
36 import 'package:cw_core/crypto_currency.dart';
37 +import 'package:collection/collection.dart';
38
39 part 'electrum_wallet.g.dart';
40
@@ -42,31 +43,34 @@ class ElectrumWallet = ElectrumWalletBase with _$ElectrumWallet;
43 abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
44 ElectrumTransactionHistory, ElectrumTransactionInfo> with Store {
45 ElectrumWalletBase(
45 - {@required String password,
46 - @required WalletInfo walletInfo,
47 - @required Box<UnspentCoinsInfo> unspentCoinsInfo,
48 - @required List<BitcoinAddressRecord> initialAddresses,
49 - @required this.networkType,
50 - @required this.mnemonic,
51 - ElectrumClient electrumClient,
52 - ElectrumBalance initialBalance})
53 - : hd = bitcoin.HDWallet.fromSeed(mnemonicToSeedBytes(mnemonic),
54 - network: networkType)
46 + {required String password,
47 + required WalletInfo walletInfo,
48 + required Box<UnspentCoinsInfo> unspentCoinsInfo,
49 + required this.networkType,
50 + required this.mnemonic,
51 + required Uint8List seedBytes,
52 + List<BitcoinAddressRecord>? initialAddresses,
53 + ElectrumClient? electrumClient,
54 + ElectrumBalance? initialBalance,
55 + CryptoCurrency? currency})
56 + : hd = bitcoin.HDWallet.fromSeed(seedBytes, network: networkType)
57 .derivePath("m/0'/0"),
58 syncStatus = NotConnectedSyncStatus(),
59 _password = password,
60 _feeRates = <int>[],
61 _isTransactionUpdating = false,
62 + unspentCoins = [],
63 + _scripthashesUpdateSubject = {},
64 + balance = ObservableMap<CryptoCurrency, ElectrumBalance>.of(
65 + currency != null
66 + ? {currency: initialBalance ?? const ElectrumBalance(confirmed: 0, unconfirmed: 0)}
67 + : {}),
68 + this.unspentCoinsInfo = unspentCoinsInfo,
69 super(walletInfo) {
61 - balance = ObservableMap<CryptoCurrency, ElectrumBalance>.of({
62 - currency: initialBalance ?? const ElectrumBalance(confirmed: 0, unconfirmed: 0)});
70 this.electrumClient = electrumClient ?? ElectrumClient();
71 this.walletInfo = walletInfo;
65 - this.unspentCoinsInfo = unspentCoinsInfo;
72 transactionHistory =
73 ElectrumTransactionHistory(walletInfo: walletInfo, password: password);
68 - unspentCoins = [];
69 - _scripthashesUpdateSubject = {};
74 }
75
76 static int estimatedTransactionSize(int inputsCount, int outputsCounts) =>
@@ -75,15 +79,15 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
79 final bitcoin.HDWallet hd;
80 final String mnemonic;
81
78 - ElectrumClient electrumClient;
82 + late ElectrumClient electrumClient;
83 Box<UnspentCoinsInfo> unspentCoinsInfo;
84
85 @override
82 - ElectrumWalletAddresses walletAddresses;
86 + late ElectrumWalletAddresses walletAddresses;
87
88 @override
89 @observable
86 - ObservableMap<CryptoCurrency, ElectrumBalance> balance;
90 + late ObservableMap<CryptoCurrency, ElectrumBalance> balance;
91
92 @override
93 @observable
@@ -98,7 +102,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
102 .map((addr) => scriptHash(addr.address, networkType: networkType))
103 .toList();
104
101 - String get xpub => hd.base58;
105 + String get xpub => hd.base58!;
106
107 @override
108 String get seed => mnemonic;
@@ -107,12 +111,12 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
111
112 @override
113 BitcoinWalletKeys get keys => BitcoinWalletKeys(
110 - wif: hd.wif, privateKey: hd.privKey, publicKey: hd.pubKey);
114 + wif: hd.wif!, privateKey: hd.privKey!, publicKey: hd.pubKey!);
115
116 String _password;
117 List<BitcoinUnspent> unspentCoins;
118 List<int> _feeRates;
115 - Map<String, BehaviorSubject<Object>> _scripthashesUpdateSubject;
119 + Map<String, BehaviorSubject<Object>?> _scripthashesUpdateSubject;
120 bool _isTransactionUpdating;
121
122 Future<void> init() async {
@@ -137,7 +141,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
141 (timer) async => _feeRates = await electrumClient.feeRates());
142
143 syncStatus = SyncedSyncStatus();
140 - } catch (e) {
144 + } catch (e, stacktrace) {
145 + print(stacktrace);
146 print(e.toString());
147 syncStatus = FailedSyncStatus();
148 }
@@ -145,7 +150,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
150
151 @action
152 @override
148 - Future<void> connectToNode({@required Node node}) async {
153 + Future<void> connectToNode({required Node node}) async {
154 try {
155 syncStatus = ConnectingSyncStatus();
156 await electrumClient.connectToUri(node.uri);
@@ -187,7 +192,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
192 }
193
194 final allAmountFee = feeAmountForPriority(
190 - transactionCredentials.priority, inputs.length, outputs.length);
195 + transactionCredentials.priority!, inputs.length, outputs.length);
196 final allAmount = allInputsAmount - allAmountFee;
197
198 var credentialsAmount = 0;
@@ -196,12 +201,12 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
201
202 if (hasMultiDestination) {
203 if (outputs.any((item) => item.sendAll
199 - || item.formattedCryptoAmount <= 0)) {
204 + || item.formattedCryptoAmount! <= 0)) {
205 throw BitcoinTransactionWrongBalanceException(currency);
206 }
207
208 credentialsAmount = outputs.fold(0, (acc, value) =>
204 - acc + value.formattedCryptoAmount);
209 + acc + value.formattedCryptoAmount!);
210
211 if (allAmount - credentialsAmount < minAmount) {
212 throw BitcoinTransactionWrongBalanceException(currency);
@@ -210,7 +215,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
215 amount = credentialsAmount;
216
217 if (transactionCredentials.feeRate != null) {
213 - fee = calculateEstimatedFeeWithFeeRate(transactionCredentials.feeRate, amount,
218 + fee = calculateEstimatedFeeWithFeeRate(transactionCredentials.feeRate!, amount,
219 outputsCount: outputs.length + 1);
220 } else {
221 fee = calculateEstimatedFee(transactionCredentials.priority, amount,
@@ -219,7 +224,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
224 } else {
225 final output = outputs.first;
226 credentialsAmount = !output.sendAll
222 - ? output.formattedCryptoAmount
227 + ? output.formattedCryptoAmount!
228 : 0;
229
230 if (credentialsAmount > allAmount) {
@@ -233,7 +238,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
238 if (output.sendAll || amount == allAmount) {
239 fee = allAmountFee;
240 } else if (transactionCredentials.feeRate != null) {
236 - fee = calculateEstimatedFeeWithFeeRate(transactionCredentials.feeRate, amount);
241 + fee = calculateEstimatedFeeWithFeeRate(transactionCredentials.feeRate!, amount);
242 } else {
243 fee = calculateEstimatedFee(transactionCredentials.priority, amount);
244 }
@@ -245,7 +250,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
250
251 final totalAmount = amount + fee;
252
248 - if (totalAmount > balance[currency].confirmed || totalAmount > allInputsAmount) {
253 + if (totalAmount > balance[currency]!.confirmed || totalAmount > allInputsAmount) {
254 throw BitcoinTransactionWrongBalanceException(currency);
255 }
256
@@ -298,11 +303,11 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
303 ? item.formattedCryptoAmount
304 : amount;
305 final outputAddress = item.isParsedAddress
301 - ? item.extractedAddress
306 + ? item.extractedAddress!
307 : item.address;
308 txb.addOutput(
309 addressToOutputScript(outputAddress, networkType),
305 - outputAmount);
310 + outputAmount!);
311 });
312
313 final estimatedSize =
@@ -310,9 +315,9 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
315 var feeAmount = 0;
316
317 if (transactionCredentials.feeRate != null) {
313 - feeAmount = transactionCredentials.feeRate * estimatedSize;
318 + feeAmount = transactionCredentials.feeRate! * estimatedSize;
319 } else {
315 - feeAmount = feeRate(transactionCredentials.priority) * estimatedSize;
320 + feeAmount = feeRate(transactionCredentials.priority!) * estimatedSize;
321 }
322
323 final changeValue = totalInputAmount - amount - feeAmount;
@@ -369,8 +374,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
374 feeRate * estimatedTransactionSize(inputsCount, outputsCount);
375
376 @override
372 - int calculateEstimatedFee(TransactionPriority priority, int amount,
373 - {int outputsCount}) {
377 + int calculateEstimatedFee(TransactionPriority? priority, int? amount,
378 + {int? outputsCount}) {
379 if (priority is BitcoinTransactionPriority) {
380 return calculateEstimatedFeeWithFeeRate(
381 feeRate(priority),
@@ -381,8 +386,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
386 return 0;
387 }
388
384 - int calculateEstimatedFeeWithFeeRate(int feeRate, int amount,
385 - {int outputsCount}) {
389 + int calculateEstimatedFeeWithFeeRate(int feeRate, int? amount,
390 + {int? outputsCount}) {
391 int inputsCount = 0;
392
393 if (amount != null) {
@@ -429,16 +434,16 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
434 await transactionHistory.changePassword(password);
435 }
436
432 - bitcoin.ECPair keyPairFor({@required int index}) =>
437 + bitcoin.ECPair keyPairFor({required int index}) =>
438 generateKeyPair(hd: hd, index: index, network: networkType);
439
440 @override
436 - Future<void> rescan({int height}) async => throw UnimplementedError();
441 + Future<void> rescan({required int height}) async => throw UnimplementedError();
442
443 @override
444 Future<void> close() async {
445 try {
441 - await electrumClient?.close();
446 + await electrumClient.close();
447 } catch (_) {}
448 }
449
@@ -498,10 +503,9 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
503
504 if (currentWalletUnspentCoins.isNotEmpty) {
505 currentWalletUnspentCoins.forEach((element) {
501 - final existUnspentCoins = unspentCoins
502 - ?.where((coin) => element.hash.contains(coin?.hash));
506 + final existUnspentCoins = unspentCoins.where((coin) => element.hash.contains(coin.hash));
507
504 - if (existUnspentCoins?.isEmpty ?? true) {
508 + if (existUnspentCoins.isEmpty) {
509 keys.add(element.key);
510 }
511 });
@@ -516,7 +520,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
520 }
521
522 Future<ElectrumTransactionBundle> getTransactionExpanded(
519 - {@required String hash, @required int height}) async {
523 + {required String hash, required int height}) async {
524 final verboseTransaction = await electrumClient.getTransactionRaw(hash: hash);
525 final transactionHex = verboseTransaction['hex'] as String;
526 final original = bitcoin.Transaction.fromHex(transactionHex);
@@ -525,7 +529,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
529 final confirmations = verboseTransaction['confirmations'] as int ?? 0;
530
531 for (final vin in original.ins) {
528 - final id = HEX.encode(vin.hash.reversed.toList());
532 + final id = HEX.encode(vin.hash!.reversed.toList());
533 final txHex = await electrumClient.getTransactionHex(hash: id);
534 final tx = bitcoin.Transaction.fromHex(txHex);
535 ins.add(tx);
@@ -539,7 +543,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
543 }
544
545 Future<ElectrumTransactionInfo> fetchTransactionInfo(
542 - {@required String hash, @required int height}) async {
546 + {required String hash, required int height}) async {
547 final tx = await getTransactionExpanded(hash: hash, height: height);
548 final addresses = walletAddresses.addresses.map((addr) => addr.address).toSet();
549 return ElectrumTransactionInfo.fromElectrumBundle(
@@ -567,7 +571,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
571 history.entries.forEach((historyItem) {
572 if (historyItem.value.isNotEmpty) {
573 final address = addressHashes[historyItem.key];
570 - address.setAsUsed();
574 + address?.setAsUsed();
575 normalizedHistories.addAll(historyItem.value);
576 }
577 });
@@ -637,8 +641,8 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
641 for (var i = 0; i < balances.length; i++) {
642 final addressRecord = addresses[i];
643 final balance = balances[i];
640 - final confirmed = balance['confirmed'] as int ?? 0;
641 - final unconfirmed = balance['unconfirmed'] as int ?? 0;
644 + final confirmed = balance['confirmed'] as int? ?? 0;
645 + final unconfirmed = balance['unconfirmed'] as int? ?? 0;
646 totalConfirmed += confirmed;
647 totalUnconfirmed += unconfirmed;
648
cw_bitcoin/lib/electrum_wallet_addresses.dart
+14 -15
@@ -4,7 +4,6 @@ import 'package:cw_bitcoin/electrum.dart';
4 import 'package:cw_bitcoin/script_hash.dart';
5 import 'package:cw_core/wallet_addresses.dart';
6 import 'package:cw_core/wallet_info.dart';
7 -import 'package:flutter/foundation.dart';
7 import 'package:mobx/mobx.dart';
8
9 part 'electrum_wallet_addresses.g.dart';
@@ -14,13 +13,13 @@ class ElectrumWalletAddresses = ElectrumWalletAddressesBase
13
14 abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
15 ElectrumWalletAddressesBase(WalletInfo walletInfo,
17 - {@required List<BitcoinAddressRecord> initialAddresses,
16 + {required this.mainHd,
17 + required this.sideHd,
18 + required this.electrumClient,
19 + required this.networkType,
20 + List<BitcoinAddressRecord>? initialAddresses,
21 int initialRegularAddressIndex = 0,
19 - int initialChangeAddressIndex = 0,
20 - this.mainHd,
21 - this.sideHd,
22 - this.electrumClient,
23 - this.networkType})
22 + int initialChangeAddressIndex = 0})
23 : addresses = ObservableList<BitcoinAddressRecord>.of(
24 (initialAddresses ?? []).toSet()),
25 receiveAddresses = ObservableList<BitcoinAddressRecord>.of(
@@ -31,10 +30,9 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
30 (initialAddresses ?? [])
31 .where((addressRecord) => addressRecord.isHidden && !addressRecord.isUsed)
32 .toSet()),
34 - super(walletInfo) {
35 - currentReceiveAddressIndex = initialRegularAddressIndex;
36 - currentChangeAddressIndex = initialChangeAddressIndex;
37 - }
33 + currentReceiveAddressIndex = initialRegularAddressIndex,
34 + currentChangeAddressIndex = initialChangeAddressIndex,
35 + super(walletInfo);
36
37 static const defaultReceiveAddressesCount = 22;
38 static const defaultChangeAddressesCount = 17;
@@ -124,17 +122,18 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
122 }
123
124 Future<BitcoinAddressRecord> generateNewAddress(
127 - {bool isHidden = false, bitcoin.HDWallet hd}) async {
125 + {bitcoin.HDWallet? hd, bool isHidden = false}) async {
126 currentReceiveAddressIndex += 1;
127 + // FIX-ME: Check logic for whichi HD should be used here ???
128 final address = BitcoinAddressRecord(
130 - getAddress(index: currentReceiveAddressIndex, hd: hd),
129 + getAddress(index: currentReceiveAddressIndex, hd: hd ?? sideHd),
130 index: currentReceiveAddressIndex,
131 isHidden: isHidden);
132 addresses.add(address);
133 return address;
134 }
135
137 - String getAddress({@required int index, @required bitcoin.HDWallet hd}) => '';
136 + String getAddress({required int index, required bitcoin.HDWallet hd}) => '';
137
138 @override
139 Future<void> updateAddressesInBox() async {
@@ -239,7 +238,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
238 }
239
240 Future<List<BitcoinAddressRecord>> _createNewAddresses(int count,
242 - {int startIndex = 0, bitcoin.HDWallet hd, bool isHidden = false}) async {
241 + {required bitcoin.HDWallet hd, int startIndex = 0, bool isHidden = false}) async {
242 final list = <BitcoinAddressRecord>[];
243
244 for (var i = startIndex; i < count + startIndex; i++) {
cw_bitcoin/lib/electrum_wallet_snapshot.dart
+36 -22
@@ -6,7 +6,15 @@ import 'package:cw_core/pathForWallet.dart';
6 import 'package:cw_core/wallet_type.dart';
7
8 class ElectrumWallletSnapshot {
9 - ElectrumWallletSnapshot(this.name, this.type, this.password);
9 + ElectrumWallletSnapshot({
10 + required this.name,
11 + required this.type,
12 + required this.password,
13 + required this.mnemonic,
14 + required this.addresses,
15 + required this.balance,
16 + required this.regularAddressIndex,
17 + required this.changeAddressIndex});
18
19 final String name;
20 final String password;
@@ -18,28 +26,34 @@ class ElectrumWallletSnapshot {
26 int regularAddressIndex;
27 int changeAddressIndex;
28
21 - Future<void> load() async {
29 + static Future<ElectrumWallletSnapshot> load(String name, WalletType type, String password) async {
30 + final path = await pathForWallet(name: name, type: type);
31 + final jsonSource = await read(path: path, password: password);
32 + final data = json.decode(jsonSource) as Map;
33 + final addressesTmp = data['addresses'] as List? ?? <Object>[];
34 + final mnemonic = data['mnemonic'] as String;
35 + final addresses = addressesTmp
36 + .whereType<String>()
37 + .map((addr) => BitcoinAddressRecord.fromJSON(addr))
38 + .toList();
39 + final balance = ElectrumBalance.fromJSON(data['balance'] as String) ??
40 + ElectrumBalance(confirmed: 0, unconfirmed: 0);
41 + var regularAddressIndex = 0;
42 + var changeAddressIndex = 0;
43 +
44 try {
23 - final path = await pathForWallet(name: name, type: type);
24 - final jsonSource = await read(path: path, password: password);
25 - final data = json.decode(jsonSource) as Map;
26 - final addressesTmp = data['addresses'] as List ?? <Object>[];
27 - mnemonic = data['mnemonic'] as String;
28 - addresses = addressesTmp
29 - .whereType<String>()
30 - .map((addr) => BitcoinAddressRecord.fromJSON(addr))
31 - .toList();
32 - balance = ElectrumBalance.fromJSON(data['balance'] as String) ??
33 - ElectrumBalance(confirmed: 0, unconfirmed: 0);
34 - regularAddressIndex = 0;
35 - changeAddressIndex = 0;
45 + regularAddressIndex = int.parse(data['account_index'] as String? ?? '0');
46 + changeAddressIndex = int.parse(data['change_address_index'] as String? ?? '0');
47 + } catch (_) {}
48
37 - try {
38 - regularAddressIndex = int.parse(data['account_index'] as String);
39 - changeAddressIndex = int.parse(data['change_address_index'] as String);
40 - } catch (_) {}
41 - } catch (e) {
42 - print(e);
43 - }
49 + return ElectrumWallletSnapshot(
50 + name: name,
51 + type: type,
52 + password: password,
53 + mnemonic: mnemonic,
54 + addresses: addresses,
55 + balance: balance,
56 + regularAddressIndex: regularAddressIndex,
57 + changeAddressIndex: changeAddressIndex);
58 }
59 }
cw_bitcoin/lib/file.dart
+7 -8
@@ -1,12 +1,11 @@
1 import 'dart:io';
2 import 'package:cw_core/key.dart';
3 import 'package:encrypt/encrypt.dart' as encrypt;
4 -import 'package:flutter/foundation.dart';
4
5 Future<void> write(
7 - {@required String path,
8 - @required String password,
9 - @required String data}) async {
6 + {required String path,
7 + required String password,
8 + required String data}) async {
9 final keys = extractKeys(password);
10 final key = encrypt.Key.fromBase64(keys.first);
11 final iv = encrypt.IV.fromBase64(keys.last);
@@ -16,9 +15,9 @@ Future<void> write(
15 }
16
17 Future<void> writeData(
19 - {@required String path,
20 - @required String password,
21 - @required String data}) async {
18 + {required String path,
19 + required String password,
20 + required String data}) async {
21 final keys = extractKeys(password);
22 final key = encrypt.Key.fromBase64(keys.first);
23 final iv = encrypt.IV.fromBase64(keys.last);
@@ -27,7 +26,7 @@ Future<void> writeData(
26 f.writeAsStringSync(encrypted);
27 }
28
30 -Future<String> read({@required String path, @required String password}) async {
29 +Future<String> read({required String path, required String password}) async {
30 final file = File(path);
31
32 if (!file.existsSync()) {
cw_bitcoin/lib/litecoin_wallet.dart
+40 -14
@@ -1,5 +1,6 @@
1 import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
2 import 'package:cw_bitcoin/bitcoin_transaction_priority.dart';
3 +import 'package:cw_core/crypto_currency.dart';
4 import 'package:cw_core/unspent_coins_info.dart';
5 import 'package:cw_bitcoin/litecoin_wallet_addresses.dart';
6 import 'package:cw_core/transaction_priority.dart';
@@ -20,12 +21,13 @@ class LitecoinWallet = LitecoinWalletBase with _$LitecoinWallet;
21
22 abstract class LitecoinWalletBase extends ElectrumWallet with Store {
23 LitecoinWalletBase(
23 - {@required String mnemonic,
24 - @required String password,
25 - @required WalletInfo walletInfo,
26 - @required Box<UnspentCoinsInfo> unspentCoinsInfo,
27 - List<BitcoinAddressRecord> initialAddresses,
28 - ElectrumBalance initialBalance,
24 + {required String mnemonic,
25 + required String password,
26 + required WalletInfo walletInfo,
27 + required Box<UnspentCoinsInfo> unspentCoinsInfo,
28 + required Uint8List seedBytes,
29 + List<BitcoinAddressRecord>? initialAddresses,
30 + ElectrumBalance? initialBalance,
31 int initialRegularAddressIndex = 0,
32 int initialChangeAddressIndex = 0})
33 : super(
@@ -35,7 +37,9 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
37 unspentCoinsInfo: unspentCoinsInfo,
38 networkType: litecoinNetwork,
39 initialAddresses: initialAddresses,
38 - initialBalance: initialBalance) {
40 + initialBalance: initialBalance,
41 + seedBytes: seedBytes,
42 + currency: CryptoCurrency.ltc) {
43 walletAddresses = LitecoinWalletAddresses(
44 walletInfo,
45 electrumClient: electrumClient,
@@ -44,19 +48,40 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
48 initialChangeAddressIndex: initialChangeAddressIndex,
49 mainHd: hd,
50 sideHd: bitcoin.HDWallet
47 - .fromSeed(mnemonicToSeedBytes(mnemonic), network: networkType)
51 + .fromSeed(seedBytes, network: networkType)
52 .derivePath("m/0'/1"),
53 networkType: networkType,);
54 }
55
56 + static Future<LitecoinWallet> create({
57 + required String mnemonic,
58 + required String password,
59 + required WalletInfo walletInfo,
60 + required Box<UnspentCoinsInfo> unspentCoinsInfo,
61 + List<BitcoinAddressRecord>? initialAddresses,
62 + ElectrumBalance? initialBalance,
63 + int initialRegularAddressIndex = 0,
64 + int initialChangeAddressIndex = 0
65 + }) async {
66 + return LitecoinWallet(
67 + mnemonic: mnemonic,
68 + password: password,
69 + walletInfo: walletInfo,
70 + unspentCoinsInfo: unspentCoinsInfo,
71 + initialAddresses: initialAddresses,
72 + initialBalance: initialBalance,
73 + seedBytes: await mnemonicToSeedBytes(mnemonic),
74 + initialRegularAddressIndex: initialRegularAddressIndex,
75 + initialChangeAddressIndex: initialChangeAddressIndex);
76 + }
77 +
78 static Future<LitecoinWallet> open({
53 - @required String name,
54 - @required WalletInfo walletInfo,
55 - @required Box<UnspentCoinsInfo> unspentCoinsInfo,
56 - @required String password,
79 + required String name,
80 + required WalletInfo walletInfo,
81 + required Box<UnspentCoinsInfo> unspentCoinsInfo,
82 + required String password,
83 }) async {
58 - final snp = ElectrumWallletSnapshot(name, walletInfo.type, password);
59 - await snp.load();
84 + final snp = await ElectrumWallletSnapshot.load (name, walletInfo.type, password);
85 return LitecoinWallet(
86 mnemonic: snp.mnemonic,
87 password: password,
@@ -64,6 +89,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
89 unspentCoinsInfo: unspentCoinsInfo,
90 initialAddresses: snp.addresses,
91 initialBalance: snp.balance,
92 + seedBytes: await mnemonicToSeedBytes(snp.mnemonic),
93 initialRegularAddressIndex: snp.regularAddressIndex,
94 initialChangeAddressIndex: snp.changeAddressIndex);
95 }
cw_bitcoin/lib/litecoin_wallet_addresses.dart
+7 -7
@@ -16,13 +16,13 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses
16 with Store {
17 LitecoinWalletAddressesBase(
18 WalletInfo walletInfo,
19 - {@required List<BitcoinAddressRecord> initialAddresses,
19 + {required bitcoin.HDWallet mainHd,
20 + required bitcoin.HDWallet sideHd,
21 + required bitcoin.NetworkType networkType,
22 + required ElectrumClient electrumClient,
23 + List<BitcoinAddressRecord>? initialAddresses,
24 int initialRegularAddressIndex = 0,
21 - int initialChangeAddressIndex = 0,
22 - ElectrumClient electrumClient,
23 - @required bitcoin.HDWallet mainHd,
24 - @required bitcoin.HDWallet sideHd,
25 - @required bitcoin.NetworkType networkType})
25 + int initialChangeAddressIndex = 0})
26 : super(
27 walletInfo,
28 initialAddresses: initialAddresses,
@@ -34,6 +34,6 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses
34 networkType: networkType);
35
36 @override
37 - String getAddress({@required int index, @required bitcoin.HDWallet hd}) =>
37 + String getAddress({required int index, required bitcoin.HDWallet hd}) =>
38 generateP2WPKHAddress(hd: hd, index: index, networkType: networkType);
39 }
\ No newline at end of file
cw_bitcoin/lib/litecoin_wallet_service.dart
+9 -9
@@ -10,6 +10,7 @@ import 'package:cw_core/pathForWallet.dart';
10 import 'package:cw_core/wallet_type.dart';
11 import 'package:cw_core/wallet_info.dart';
12 import 'package:cw_core/wallet_base.dart';
13 +import 'package:collection/collection.dart';
14
15 class LitecoinWalletService extends WalletService<
16 BitcoinNewWalletCredentials,
@@ -25,10 +26,10 @@ class LitecoinWalletService extends WalletService<
26
27 @override
28 Future<LitecoinWallet> create(BitcoinNewWalletCredentials credentials) async {
28 - final wallet = LitecoinWallet(
29 + final wallet = await LitecoinWalletBase.create(
30 mnemonic: await generateMnemonic(),
30 - password: credentials.password,
31 - walletInfo: credentials.walletInfo,
31 + password: credentials.password!,
32 + walletInfo: credentials.walletInfo!,
33 unspentCoinsInfo: unspentCoinsInfoSource);
34 await wallet.save();
35 await wallet.init();
@@ -42,9 +43,8 @@ class LitecoinWalletService extends WalletService<
43
44 @override
45 Future<LitecoinWallet> openWallet(String name, String password) async {
45 - final walletInfo = walletInfoSource.values.firstWhere(
46 - (info) => info.id == WalletBase.idFor(name, getType()),
47 - orElse: () => null);
46 + final walletInfo = walletInfoSource.values.firstWhereOrNull(
47 + (info) => info.id == WalletBase.idFor(name, getType()))!;
48 final wallet = await LitecoinWalletBase.open(
49 password: password, name: name, walletInfo: walletInfo,
50 unspentCoinsInfo: unspentCoinsInfoSource);
@@ -69,10 +69,10 @@ class LitecoinWalletService extends WalletService<
69 throw BitcoinMnemonicIsIncorrectException();
70 }
71
72 - final wallet = LitecoinWallet(
73 - password: credentials.password,
72 + final wallet = await LitecoinWalletBase.create(
73 + password: credentials.password!,
74 mnemonic: credentials.mnemonic,
75 - walletInfo: credentials.walletInfo,
75 + walletInfo: credentials.walletInfo!,
76 unspentCoinsInfo: unspentCoinsInfoSource);
77 await wallet.save();
78 await wallet.init();
cw_bitcoin/lib/pending_bitcoin_transaction.dart
+3 -4
@@ -1,5 +1,4 @@
1 import 'package:cw_bitcoin/bitcoin_commit_transaction_exception.dart';
2 -import 'package:flutter/foundation.dart';
2 import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
3 import 'package:cw_core/pending_transaction.dart';
4 import 'package:cw_bitcoin/electrum.dart';
@@ -10,9 +9,9 @@ import 'package:cw_core/wallet_type.dart';
9
10 class PendingBitcoinTransaction with PendingTransaction {
11 PendingBitcoinTransaction(this._tx, this.type,
13 - {@required this.electrumClient,
14 - @required this.amount,
15 - @required this.fee})
12 + {required this.electrumClient,
13 + required this.amount,
14 + required this.fee})
15 : _listeners = <void Function(ElectrumTransactionInfo transaction)>[];
16
17 final WalletType type;
cw_bitcoin/lib/script_hash.dart
+1 -2
@@ -1,8 +1,7 @@
1 -import 'package:flutter/foundation.dart';
1 import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
2 import 'package:crypto/crypto.dart';
3
5 -String scriptHash(String address, {@required bitcoin.NetworkType networkType}) {
4 +String scriptHash(String address, {required bitcoin.NetworkType networkType}) {
5 final outputScript =
6 bitcoin.Address.addressToOutputScript(address, networkType);
7 final parts = sha256.convert(outputScript).toString().split('');
cw_bitcoin/lib/utils.dart
+21 -21
@@ -5,51 +5,51 @@ import 'package:bitcoin_flutter/src/payments/index.dart' show PaymentData;
5 import 'package:hex/hex.dart';
6
7 bitcoin.PaymentData generatePaymentData(
8 - {@required bitcoin.HDWallet hd, @required int index}) =>
8 + {required bitcoin.HDWallet hd, required int index}) =>
9 PaymentData(
10 - pubkey: Uint8List.fromList(HEX.decode(hd.derive(index).pubKey)));
10 + pubkey: Uint8List.fromList(HEX.decode(hd.derive(index).pubKey!)));
11
12 bitcoin.ECPair generateKeyPair(
13 - {@required bitcoin.HDWallet hd,
14 - @required int index,
15 - bitcoin.NetworkType network}) =>
16 - bitcoin.ECPair.fromWIF(hd.derive(index).wif, network: network);
13 + {required bitcoin.HDWallet hd,
14 + required int index,
15 + required bitcoin.NetworkType network}) =>
16 + bitcoin.ECPair.fromWIF(hd.derive(index).wif!, network: network);
17
18 String generateP2WPKHAddress(
19 - {@required bitcoin.HDWallet hd,
20 - @required int index,
21 - bitcoin.NetworkType networkType}) =>
19 + {required bitcoin.HDWallet hd,
20 + required int index,
21 + required bitcoin.NetworkType networkType}) =>
22 bitcoin
23 .P2WPKH(
24 data: PaymentData(
25 pubkey:
26 - Uint8List.fromList(HEX.decode(hd.derive(index).pubKey))),
26 + Uint8List.fromList(HEX.decode(hd.derive(index).pubKey!))),
27 network: networkType)
28 .data
29 - .address;
29 + .address!;
30
31 String generateP2WPKHAddressByPath(
32 - {@required bitcoin.HDWallet hd,
33 - @required String path,
34 - bitcoin.NetworkType networkType}) =>
32 + {required bitcoin.HDWallet hd,
33 + required String path,
34 + required bitcoin.NetworkType networkType}) =>
35 bitcoin
36 .P2WPKH(
37 data: PaymentData(
38 pubkey:
39 - Uint8List.fromList(HEX.decode(hd.derivePath(path).pubKey))),
39 + Uint8List.fromList(HEX.decode(hd.derivePath(path).pubKey!))),
40 network: networkType)
41 .data
42 - .address;
42 + .address!;
43
44 String generateP2PKHAddress(
45 - {@required bitcoin.HDWallet hd,
46 - @required int index,
47 - bitcoin.NetworkType networkType}) =>
45 + {required bitcoin.HDWallet hd,
46 + required int index,
47 + required bitcoin.NetworkType networkType}) =>
48 bitcoin
49 .P2PKH(
50 data: PaymentData(
51 pubkey:
52 - Uint8List.fromList(HEX.decode(hd.derive(index).pubKey))),
52 + Uint8List.fromList(HEX.decode(hd.derive(index).pubKey!))),
53 network: networkType)
54 .data
55 - .address;
55 + .address!;
cw_bitcoin/pubspec.lock
+108 -108
@@ -7,64 +7,64 @@ packages:
7 name: _fe_analyzer_shared
8 url: "https://pub.dartlang.org"
9 source: hosted
10 - version: "14.0.0"
10 + version: "47.0.0"
11 analyzer:
12 dependency: transitive
13 description:
14 name: analyzer
15 url: "https://pub.dartlang.org"
16 source: hosted
17 - version: "0.41.2"
17 + version: "4.7.0"
18 args:
19 dependency: transitive
20 description:
21 name: args
22 url: "https://pub.dartlang.org"
23 source: hosted
24 - version: "1.6.0"
24 + version: "2.3.1"
25 asn1lib:
26 dependency: transitive
27 description:
28 name: asn1lib
29 url: "https://pub.dartlang.org"
30 source: hosted
31 - version: "0.6.5"
31 + version: "1.1.1"
32 async:
33 dependency: transitive
34 description:
35 name: async
36 url: "https://pub.dartlang.org"
37 source: hosted
38 - version: "2.5.0"
38 + version: "2.9.0"
39 bech32:
40 dependency: transitive
41 description:
42 path: "."
43 - ref: cake
44 - resolved-ref: "02fef082f20af13de00b4e64efb93a2c1e5e1cf2"
43 + ref: "cake-0.2.1"
44 + resolved-ref: cafd1c270641e95017d57d69f55cca9831d4db56
45 url: "https://github.com/cake-tech/bech32.git"
46 source: git
47 - version: "0.2.0"
47 + version: "0.2.1"
48 bip32:
49 dependency: transitive
50 description:
51 name: bip32
52 url: "https://pub.dartlang.org"
53 source: hosted
54 - version: "1.0.7"
54 + version: "2.0.0"
55 bip39:
56 dependency: transitive
57 description:
58 name: bip39
59 url: "https://pub.dartlang.org"
60 source: hosted
61 - version: "1.0.3"
61 + version: "1.0.6"
62 bitcoin_flutter:
63 dependency: "direct main"
64 description:
65 path: "."
66 - ref: cake
67 - resolved-ref: cbabfd87b6ce3cae6051a3e86ddb56e7a934e188
66 + ref: cake-update-v2
67 + resolved-ref: "8f86453761c0c26e368392d0ff2c6f12f3b7397b"
68 url: "https://github.com/cake-tech/bitcoin_flutter.git"
69 source: git
70 version: "2.0.2"
@@ -81,133 +81,119 @@ packages:
81 name: bs58check
82 url: "https://pub.dartlang.org"
83 source: hosted
84 - version: "1.0.1"
84 + version: "1.0.2"
85 build:
86 dependency: transitive
87 description:
88 name: build
89 url: "https://pub.dartlang.org"
90 source: hosted
91 - version: "1.6.2"
91 + version: "2.3.1"
92 build_config:
93 dependency: transitive
94 description:
95 name: build_config
96 url: "https://pub.dartlang.org"
97 source: hosted
98 - version: "0.4.6"
98 + version: "1.1.0"
99 build_daemon:
100 dependency: transitive
101 description:
102 name: build_daemon
103 url: "https://pub.dartlang.org"
104 source: hosted
105 - version: "2.1.10"
105 + version: "3.1.0"
106 build_resolvers:
107 dependency: "direct dev"
108 description:
109 name: build_resolvers
110 url: "https://pub.dartlang.org"
111 source: hosted
112 - version: "1.5.3"
112 + version: "2.0.10"
113 build_runner:
114 dependency: "direct dev"
115 description:
116 name: build_runner
117 url: "https://pub.dartlang.org"
118 source: hosted
119 - version: "1.11.5"
119 + version: "2.2.1"
120 build_runner_core:
121 dependency: transitive
122 description:
123 name: build_runner_core
124 url: "https://pub.dartlang.org"
125 source: hosted
126 - version: "6.1.10"
126 + version: "7.2.4"
127 built_collection:
128 dependency: transitive
129 description:
130 name: built_collection
131 url: "https://pub.dartlang.org"
132 source: hosted
133 - version: "4.3.2"
133 + version: "5.1.1"
134 built_value:
135 dependency: transitive
136 description:
137 name: built_value
138 url: "https://pub.dartlang.org"
139 source: hosted
140 - version: "7.1.0"
140 + version: "8.4.1"
141 characters:
142 dependency: transitive
143 description:
144 name: characters
145 url: "https://pub.dartlang.org"
146 source: hosted
147 - version: "1.1.0"
148 - charcode:
149 - dependency: transitive
150 - description:
151 - name: charcode
152 - url: "https://pub.dartlang.org"
153 - source: hosted
154 - version: "1.2.0"
147 + version: "1.2.1"
148 checked_yaml:
149 dependency: transitive
150 description:
151 name: checked_yaml
152 url: "https://pub.dartlang.org"
153 source: hosted
161 - version: "1.0.4"
162 - cli_util:
163 - dependency: transitive
164 - description:
165 - name: cli_util
166 - url: "https://pub.dartlang.org"
167 - source: hosted
168 - version: "0.3.5"
154 + version: "2.0.1"
155 clock:
156 dependency: transitive
157 description:
158 name: clock
159 url: "https://pub.dartlang.org"
160 source: hosted
175 - version: "1.1.0"
161 + version: "1.1.1"
162 code_builder:
163 dependency: transitive
164 description:
165 name: code_builder
166 url: "https://pub.dartlang.org"
167 source: hosted
182 - version: "3.7.0"
168 + version: "4.3.0"
169 collection:
170 dependency: transitive
171 description:
172 name: collection
173 url: "https://pub.dartlang.org"
174 source: hosted
189 - version: "1.15.0"
175 + version: "1.16.0"
176 convert:
177 dependency: transitive
178 description:
179 name: convert
180 url: "https://pub.dartlang.org"
181 source: hosted
196 - version: "2.1.1"
182 + version: "3.0.2"
183 crypto:
184 dependency: transitive
185 description:
186 name: crypto
187 url: "https://pub.dartlang.org"
188 source: hosted
203 - version: "2.1.5"
189 + version: "3.0.2"
190 cryptography:
191 dependency: "direct main"
192 description:
193 name: cryptography
194 url: "https://pub.dartlang.org"
195 source: hosted
210 - version: "1.4.1"
196 + version: "2.0.5"
197 cw_core:
198 dependency: "direct main"
199 description:
@@ -221,35 +207,28 @@ packages:
207 name: dart_style
208 url: "https://pub.dartlang.org"
209 source: hosted
224 - version: "1.3.12"
225 - dartx:
226 - dependency: transitive
227 - description:
228 - name: dartx
229 - url: "https://pub.dartlang.org"
230 - source: hosted
231 - version: "0.5.0"
210 + version: "2.2.4"
211 encrypt:
212 dependency: "direct main"
213 description:
214 name: encrypt
215 url: "https://pub.dartlang.org"
216 source: hosted
238 - version: "4.0.3"
217 + version: "5.0.1"
218 fake_async:
219 dependency: transitive
220 description:
221 name: fake_async
222 url: "https://pub.dartlang.org"
223 source: hosted
245 - version: "1.2.0"
224 + version: "1.3.1"
225 ffi:
226 dependency: transitive
227 description:
228 name: ffi
229 url: "https://pub.dartlang.org"
230 source: hosted
252 - version: "1.1.2"
231 + version: "2.0.1"
232 file:
233 dependency: transitive
234 description:
@@ -263,7 +242,7 @@ packages:
242 name: fixnum
243 url: "https://pub.dartlang.org"
244 source: hosted
266 - version: "0.10.11"
245 + version: "1.0.1"
246 flutter:
247 dependency: "direct main"
248 description: flutter
@@ -275,12 +254,19 @@ packages:
254 name: flutter_mobx
255 url: "https://pub.dartlang.org"
256 source: hosted
278 - version: "1.1.0+2"
257 + version: "2.0.6+4"
258 flutter_test:
259 dependency: "direct dev"
260 description: flutter
261 source: sdk
262 version: "0.0.0"
263 + frontend_server_client:
264 + dependency: transitive
265 + description:
266 + name: frontend_server_client
267 + url: "https://pub.dartlang.org"
268 + source: hosted
269 + version: "2.1.3"
270 glob:
271 dependency: transitive
272 description:
@@ -294,49 +280,49 @@ packages:
280 name: graphs
281 url: "https://pub.dartlang.org"
282 source: hosted
297 - version: "0.2.0"
283 + version: "2.1.0"
284 hex:
285 dependency: transitive
286 description:
287 name: hex
288 url: "https://pub.dartlang.org"
289 source: hosted
304 - version: "0.1.2"
290 + version: "0.2.0"
291 hive:
292 dependency: transitive
293 description:
294 name: hive
295 url: "https://pub.dartlang.org"
296 source: hosted
311 - version: "1.4.4+1"
297 + version: "2.2.3"
298 hive_generator:
299 dependency: "direct dev"
300 description:
301 name: hive_generator
302 url: "https://pub.dartlang.org"
303 source: hosted
318 - version: "0.8.2"
304 + version: "1.1.3"
305 http:
306 dependency: "direct main"
307 description:
308 name: http
309 url: "https://pub.dartlang.org"
310 source: hosted
325 - version: "0.12.2"
311 + version: "0.13.5"
312 http_multi_server:
313 dependency: transitive
314 description:
315 name: http_multi_server
316 url: "https://pub.dartlang.org"
317 source: hosted
332 - version: "2.2.0"
318 + version: "3.2.1"
319 http_parser:
320 dependency: transitive
321 description:
322 name: http_parser
323 url: "https://pub.dartlang.org"
324 source: hosted
339 - version: "3.1.4"
325 + version: "4.0.1"
326 intl:
327 dependency: "direct main"
328 description:
@@ -350,7 +336,7 @@ packages:
336 name: io
337 url: "https://pub.dartlang.org"
338 source: hosted
353 - version: "0.3.5"
339 + version: "1.0.3"
340 js:
341 dependency: transitive
342 description:
@@ -364,7 +350,7 @@ packages:
350 name: json_annotation
351 url: "https://pub.dartlang.org"
352 source: hosted
367 - version: "4.0.1"
353 + version: "4.7.0"
354 logging:
355 dependency: transitive
356 description:
@@ -378,14 +364,21 @@ packages:
364 name: matcher
365 url: "https://pub.dartlang.org"
366 source: hosted
381 - version: "0.12.10"
367 + version: "0.12.12"
368 + material_color_utilities:
369 + dependency: transitive
370 + description:
371 + name: material_color_utilities
372 + url: "https://pub.dartlang.org"
373 + source: hosted
374 + version: "0.1.5"
375 meta:
376 dependency: transitive
377 description:
378 name: meta
379 url: "https://pub.dartlang.org"
380 source: hosted
388 - version: "1.3.0"
381 + version: "1.8.0"
382 mime:
383 dependency: transitive
384 description:
@@ -399,63 +392,77 @@ packages:
392 name: mobx
393 url: "https://pub.dartlang.org"
394 source: hosted
402 - version: "1.2.1+4"
395 + version: "2.1.0"
396 mobx_codegen:
397 dependency: "direct dev"
398 description:
399 name: mobx_codegen
400 url: "https://pub.dartlang.org"
401 source: hosted
409 - version: "1.1.2"
402 + version: "2.0.7+3"
403 package_config:
404 dependency: transitive
405 description:
406 name: package_config
407 url: "https://pub.dartlang.org"
408 source: hosted
416 - version: "1.9.3"
409 + version: "2.1.0"
410 path:
411 dependency: transitive
412 description:
413 name: path
414 url: "https://pub.dartlang.org"
415 source: hosted
423 - version: "1.8.0"
416 + version: "1.8.2"
417 path_provider:
418 dependency: "direct main"
419 description:
420 name: path_provider
421 url: "https://pub.dartlang.org"
422 source: hosted
430 - version: "1.6.28"
423 + version: "2.0.11"
424 + path_provider_android:
425 + dependency: transitive
426 + description:
427 + name: path_provider_android
428 + url: "https://pub.dartlang.org"
429 + source: hosted
430 + version: "2.0.20"
431 + path_provider_ios:
432 + dependency: transitive
433 + description:
434 + name: path_provider_ios
435 + url: "https://pub.dartlang.org"
436 + source: hosted
437 + version: "2.0.11"
438 path_provider_linux:
439 dependency: transitive
440 description:
441 name: path_provider_linux
442 url: "https://pub.dartlang.org"
443 source: hosted
437 - version: "0.0.1+2"
444 + version: "2.1.7"
445 path_provider_macos:
446 dependency: transitive
447 description:
448 name: path_provider_macos
449 url: "https://pub.dartlang.org"
450 source: hosted
444 - version: "0.0.4+8"
451 + version: "2.0.6"
452 path_provider_platform_interface:
453 dependency: transitive
454 description:
455 name: path_provider_platform_interface
456 url: "https://pub.dartlang.org"
457 source: hosted
451 - version: "1.0.4"
458 + version: "2.0.5"
459 path_provider_windows:
460 dependency: transitive
461 description:
462 name: path_provider_windows
463 url: "https://pub.dartlang.org"
464 source: hosted
458 - version: "0.0.5"
465 + version: "2.1.3"
466 pedantic:
467 dependency: transitive
468 description:
@@ -476,14 +483,14 @@ packages:
483 name: plugin_platform_interface
484 url: "https://pub.dartlang.org"
485 source: hosted
479 - version: "1.0.3"
486 + version: "2.1.3"
487 pointycastle:
488 dependency: transitive
489 description:
490 name: pointycastle
491 url: "https://pub.dartlang.org"
492 source: hosted
486 - version: "1.0.2"
493 + version: "3.6.2"
494 pool:
495 dependency: transitive
496 description:
@@ -511,35 +518,28 @@ packages:
518 name: pubspec_parse
519 url: "https://pub.dartlang.org"
520 source: hosted
514 - version: "0.1.8"
515 - quiver:
516 - dependency: transitive
517 - description:
518 - name: quiver
519 - url: "https://pub.dartlang.org"
520 - source: hosted
521 - version: "2.1.5"
521 + version: "1.2.1"
522 rxdart:
523 dependency: "direct main"
524 description:
525 name: rxdart
526 url: "https://pub.dartlang.org"
527 source: hosted
528 - version: "0.26.0"
528 + version: "0.27.5"
529 shelf:
530 dependency: transitive
531 description:
532 name: shelf
533 url: "https://pub.dartlang.org"
534 source: hosted
535 - version: "0.7.9"
535 + version: "1.4.0"
536 shelf_web_socket:
537 dependency: transitive
538 description:
539 name: shelf_web_socket
540 url: "https://pub.dartlang.org"
541 source: hosted
542 - version: "0.2.4+1"
542 + version: "1.0.2"
543 sky_engine:
544 dependency: transitive
545 description: flutter
@@ -551,14 +551,21 @@ packages:
551 name: source_gen
552 url: "https://pub.dartlang.org"
553 source: hosted
554 - version: "0.9.10+3"
554 + version: "1.2.5"
555 + source_helper:
556 + dependency: transitive
557 + description:
558 + name: source_helper
559 + url: "https://pub.dartlang.org"
560 + source: hosted
561 + version: "1.3.3"
562 source_span:
563 dependency: transitive
564 description:
565 name: source_span
566 url: "https://pub.dartlang.org"
567 source: hosted
561 - version: "1.8.0"
568 + version: "1.9.0"
569 stack_trace:
570 dependency: transitive
571 description:
@@ -586,35 +593,28 @@ packages:
593 name: string_scanner
594 url: "https://pub.dartlang.org"
595 source: hosted
589 - version: "1.1.0"
596 + version: "1.1.1"
597 term_glyph:
598 dependency: transitive
599 description:
600 name: term_glyph
601 url: "https://pub.dartlang.org"
602 source: hosted
596 - version: "1.2.0"
603 + version: "1.2.1"
604 test_api:
605 dependency: transitive
606 description:
607 name: test_api
608 url: "https://pub.dartlang.org"
609 source: hosted
603 - version: "0.2.19"
604 - time:
605 - dependency: transitive
606 - description:
607 - name: time
608 - url: "https://pub.dartlang.org"
609 - source: hosted
610 - version: "1.4.1"
610 + version: "0.4.12"
611 timing:
612 dependency: transitive
613 description:
614 name: timing
615 url: "https://pub.dartlang.org"
616 source: hosted
617 - version: "0.1.1+3"
617 + version: "1.0.0"
618 typed_data:
619 dependency: transitive
620 description:
@@ -635,7 +635,7 @@ packages:
635 name: vector_math
636 url: "https://pub.dartlang.org"
637 source: hosted
638 - version: "2.1.0"
638 + version: "2.1.2"
639 watcher:
640 dependency: transitive
641 description:
@@ -649,21 +649,21 @@ packages:
649 name: web_socket_channel
650 url: "https://pub.dartlang.org"
651 source: hosted
652 - version: "1.2.0"
652 + version: "2.2.0"
653 win32:
654 dependency: transitive
655 description:
656 name: win32
657 url: "https://pub.dartlang.org"
658 source: hosted
659 - version: "2.0.5"
659 + version: "3.0.0"
660 xdg_directories:
661 dependency: transitive
662 description:
663 name: xdg_directories
664 url: "https://pub.dartlang.org"
665 source: hosted
666 - version: "0.1.2"
666 + version: "0.2.0+2"
667 yaml:
668 dependency: transitive
669 description:
@@ -672,5 +672,5 @@ packages:
672 source: hosted
673 version: "3.1.0"
674 sdks:
675 - dart: ">=2.12.0 <3.0.0"
676 - flutter: ">=1.20.0"
675 + dart: ">=2.17.5 <3.0.0"
676 + flutter: ">=3.0.0"
cw_bitcoin/pubspec.yaml
+14 -14
@@ -6,35 +6,35 @@ author: Cake Wallet
6 homepage: https://cakewallet.com
7
8 environment:
9 - sdk: ">=2.7.0 <3.0.0"
10 - flutter: ">=1.17.0"
9 + sdk: ">=2.17.5 <3.0.0"
10 + flutter: ">=1.20.0"
11
12 dependencies:
13 flutter:
14 sdk: flutter
15 - path_provider: ^1.4.0
16 - http: ^0.12.0+2
17 - mobx: ^1.2.1+2
18 - flutter_mobx: ^1.1.0+2
15 + path_provider: ^2.0.11
16 + http: ^0.13.4
17 + mobx: ^2.0.7+4
18 + flutter_mobx: ^2.0.6+1
19 intl: ^0.17.0
20 cw_core:
21 path: ../cw_core
22 bitcoin_flutter:
23 git:
24 url: https://github.com/cake-tech/bitcoin_flutter.git
25 - ref: cake
26 - rxdart: ^0.26.0
25 + ref: cake-update-v2
26 + rxdart: ^0.27.5
27 unorm_dart: ^0.2.0
28 - cryptography: ^1.4.0
29 - encrypt: ^4.0.0
28 + cryptography: ^2.0.5
29 + encrypt: ^5.0.1
30
31 dev_dependencies:
32 flutter_test:
33 sdk: flutter
34 - build_runner: ^1.10.3
35 - build_resolvers: ^1.3.10
36 - mobx_codegen: ^1.1.0+1
37 - hive_generator: ^0.8.1
34 + build_runner: ^2.1.11
35 + build_resolvers: ^2.0.9
36 + mobx_codegen: ^2.0.7
37 + hive_generator: ^1.1.3
38
39 # For information on the generic Dart part of this file, see the
40 # following page: https://dart.dev/tools/pub/pubspec
cw_core/lib/account.dart
+2 -2
@@ -1,7 +1,7 @@
1 class Account {
2 - Account({this.id, this.label});
2 + Account({required this.id, required this.label});
3
4 - Account.fromMap(Map map)
4 + Account.fromMap(Map<String, Object> map)
5 : this.id = map['id'] == null ? 0 : int.parse(map['id'] as String),
6 this.label = (map['label'] ?? '') as String;
7
cw_core/lib/account_list.dart
+2 -2
@@ -8,9 +8,9 @@ abstract class AccountList<T> {
8
9 List<T> getAll();
10
11 - Future addAccount({String label});
11 + Future<void> addAccount({required String label});
12
13 - Future setLabelAccount({int accountIndex, String label});
13 + Future<void> setLabelAccount({required int accountIndex, required String label});
14
15 void refresh();
16 }
cw_core/lib/crypto_amount_format.dart
+1 -1
@@ -1 +1 @@
1 -double cryptoAmountToDouble({num amount, num divider}) => amount / divider;
\ No newline at end of file
1 +double cryptoAmountToDouble({required num amount, required num divider}) => amount / divider;
\ No newline at end of file
cw_core/lib/crypto_currency.dart
+12 -10
@@ -5,12 +5,17 @@ part 'crypto_currency.g.dart';
5
6 @HiveType(typeId: 0)
7 class CryptoCurrency extends EnumerableItem<int> with Serializable<int> {
8 - const CryptoCurrency({final String title, this.tag, this.name, this.iconPath, final int raw})
8 + const CryptoCurrency({
9 + String title = '',
10 + int raw = -1,
11 + this.name,
12 + this.iconPath,
13 + this.tag,})
14 : super(title: title, raw: raw);
15
11 - final String tag;
12 - final String name;
13 - final String iconPath;
16 + final String? tag;
17 + final String? name;
18 + final String? iconPath;
19
20 static const all = [
21 CryptoCurrency.xmr,
@@ -97,10 +102,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> {
102 static const zen = CryptoCurrency(title: 'ZEN', iconPath: 'assets/images/zen_icon.png', raw: 44);
103 static const xvg = CryptoCurrency(title: 'XVG', name: 'Verge', iconPath: 'assets/images/xvg_icon.png', raw: 45);
104
100 -
101 -
102 -
103 - static CryptoCurrency deserialize({int raw}) {
105 + static CryptoCurrency deserialize({required int raw}) {
106 switch (raw) {
107 case 0:
108 return CryptoCurrency.xmr;
@@ -195,7 +197,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> {
197 case 45:
198 return CryptoCurrency.xvg;
199 default:
198 - return null;
200 + throw Exception('Unexpected token: $raw for CryptoCurrency deserialize');
201 }
202 }
203
@@ -294,7 +296,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> {
296 case 'xvg':
297 return CryptoCurrency.xvg;
298 default:
297 - return null;
299 + throw Exception('Unexpected token: $raw for CryptoCurrency fromString');
300 }
301 }
302
cw_core/lib/currency_for_wallet_type.dart
+1 -1
@@ -12,6 +12,6 @@ CryptoCurrency currencyForWalletType(WalletType type) {
12 case WalletType.haven:
13 return CryptoCurrency.xhv;
14 default:
15 - return null;
15 + throw Exception('Unexpected wallet type: ${type.toString()} for CryptoCurrency currencyForWalletType');
16 }
17 }
cw_core/lib/enumerable_item.dart
+2 -2
@@ -1,7 +1,7 @@
1 import 'package:flutter/foundation.dart';
2
3 abstract class EnumerableItem<T> {
4 - const EnumerableItem({@required this.title, @required this.raw});
4 + const EnumerableItem({required this.title, required this.raw});
5
6 final T raw;
7 final String title;
@@ -11,6 +11,6 @@ abstract class EnumerableItem<T> {
11 }
12
13 mixin Serializable<T> on EnumerableItem<T> {
14 - static Serializable deserialize<T>({T raw}) => null;
14 + static Serializable deserialize<T>({required T raw}) => throw Exception('Unimplemented');
15 T serialize() => raw;
16 }
cw_core/lib/get_height_by_date.dart
+2 -2
@@ -85,7 +85,7 @@ final dates = {
85 "2020-11": 2220000
86 };
87
88 -int getMoneroHeigthByDate({DateTime date}) {
88 +int getMoneroHeigthByDate({required DateTime date}) {
89 final raw = '${date.year}' + '-' + '${date.month}';
90 final lastHeight = dates.values.last;
91 int startHeight;
@@ -105,7 +105,7 @@ int getMoneroHeigthByDate({DateTime date}) {
105 final daysHeight = (differenceInDays * heightPerDay).round();
106 height = endHeight + daysHeight;
107 } else {
108 - startHeight = dates[raw];
108 + startHeight = dates[raw]!;
109 final index = dates.values.toList().indexOf(startHeight);
110 endHeight = dates.values.toList()[index + 1];
111 final heightPerDay = ((endHeight - startHeight) / 31).round();
cw_core/lib/key.dart
+2 -2
@@ -16,14 +16,14 @@ List<String> extractKeys(String key) {
16 return [_key, iv];
17 }
18
19 -Future<String> encode({encrypt.Key key, encrypt.IV iv, String data}) async {
19 +Future<String> encode({required encrypt.Key key, required encrypt.IV iv, required String data}) async {
20 final encrypter = encrypt.Encrypter(encrypt.Salsa20(key));
21 final encrypted = encrypter.encrypt(data, iv: iv);
22
23 return encrypted.base64;
24 }
25
26 -Future<String> decode({String password, String data}) async {
26 +Future<String> decode({required String password, required String data}) async {
27 final keys = extractKeys(password);
28 final key = encrypt.Key.fromBase64(keys.first);
29 final iv = encrypt.IV.fromBase64(keys.last);
cw_core/lib/monero_amount_format.dart
+3 -3
@@ -7,12 +7,12 @@ final moneroAmountFormat = NumberFormat()
7 ..maximumFractionDigits = moneroAmountLength
8 ..minimumFractionDigits = 1;
9
10 -String moneroAmountToString({int amount}) => moneroAmountFormat
10 +String moneroAmountToString({required int amount}) => moneroAmountFormat
11 .format(cryptoAmountToDouble(amount: amount, divider: moneroAmountDivider))
12 .replaceAll(',', '');
13
14 -double moneroAmountToDouble({int amount}) =>
14 +double moneroAmountToDouble({required int amount}) =>
15 cryptoAmountToDouble(amount: amount, divider: moneroAmountDivider);
16
17 -int moneroParseAmount({String amount}) =>
17 +int moneroParseAmount({required String amount}) =>
18 (double.parse(amount) * moneroAmountDivider).toInt();
cw_core/lib/monero_balance.dart
+3 -4
@@ -1,17 +1,16 @@
1 import 'package:cw_core/balance.dart';
2 -import 'package:flutter/foundation.dart';
2 import 'package:cw_core/monero_amount_format.dart';
3
4 class MoneroBalance extends Balance {
6 - MoneroBalance({@required this.fullBalance, @required this.unlockedBalance})
5 + MoneroBalance({required this.fullBalance, required this.unlockedBalance})
6 : formattedFullBalance = moneroAmountToString(amount: fullBalance),
7 formattedUnlockedBalance =
8 moneroAmountToString(amount: unlockedBalance),
9 super(unlockedBalance, fullBalance);
10
11 MoneroBalance.fromString(
13 - {@required this.formattedFullBalance,
14 - @required this.formattedUnlockedBalance})
12 + {required this.formattedFullBalance,
13 + required this.formattedUnlockedBalance})
14 : fullBalance = moneroParseAmount(amount: formattedFullBalance),
15 unlockedBalance = moneroParseAmount(amount: formattedUnlockedBalance),
16 super(moneroParseAmount(amount: formattedUnlockedBalance),
cw_core/lib/monero_transaction_priority.dart
+3 -3
@@ -4,7 +4,7 @@ import 'package:cw_core/wallet_type.dart';
4 import 'package:cw_core/enumerable_item.dart';
5
6 class MoneroTransactionPriority extends TransactionPriority {
7 - const MoneroTransactionPriority({String title, int raw})
7 + const MoneroTransactionPriority({required String title, required int raw})
8 : super(title: title, raw: raw);
9
10 static const all = [
@@ -37,7 +37,7 @@ class MoneroTransactionPriority extends TransactionPriority {
37 }
38 }
39
40 - static MoneroTransactionPriority deserialize({int raw}) {
40 + static MoneroTransactionPriority deserialize({required int raw}) {
41 switch (raw) {
42 case 0:
43 return slow;
@@ -50,7 +50,7 @@ class MoneroTransactionPriority extends TransactionPriority {
50 case 4:
51 return fastest;
52 default:
53 - return null;
53 + throw Exception('Unexpected token: $raw for MoneroTransactionPriority deserialize');
54 }
55 }
56
cw_core/lib/monero_wallet_keys.dart
+4 -4
@@ -1,9 +1,9 @@
1 class MoneroWalletKeys {
2 const MoneroWalletKeys(
3 - {this.privateSpendKey,
4 - this.privateViewKey,
5 - this.publicSpendKey,
6 - this.publicViewKey});
3 + {required this.privateSpendKey,
4 + required this.privateViewKey,
5 + required this.publicSpendKey,
6 + required this.publicViewKey});
7
8 final String publicViewKey;
9 final String privateViewKey;
cw_core/lib/node.dart
+19 -18
@@ -1,7 +1,5 @@
1 import 'dart:io';
2 -
2 import 'package:cw_core/keyable.dart';
4 -import 'package:flutter/foundation.dart';
3 import 'dart:convert';
4 import 'package:http/http.dart' as http;
5 import 'package:hive/hive.dart';
@@ -11,22 +9,26 @@ import 'package:http/io_client.dart' as ioc;
9 part 'node.g.dart';
10
11 Uri createUriFromElectrumAddress(String address) =>
14 - Uri.tryParse('tcp://$address');
12 + Uri.tryParse('tcp://$address')!;
13
14 @HiveType(typeId: Node.typeId)
15 class Node extends HiveObject with Keyable {
16 Node(
19 - {@required String uri,
20 - @required WalletType type,
21 - this.login,
17 + {this.login,
18 this.password,
23 - this.useSSL}) {
24 - uriRaw = uri;
25 - this.type = type;
19 + this.useSSL,
20 + String? uri,
21 + WalletType? type,}) {
22 + if (uri != null) {
23 + uriRaw = uri;
24 + }
25 + if (type != null) {
26 + this.type = type;
27 + }
28 }
29
28 - Node.fromMap(Map map)
29 - : uriRaw = map['uri'] as String ?? '',
30 + Node.fromMap(Map<String, Object?> map)
31 + : uriRaw = map['uri'] as String? ?? '',
32 login = map['login'] as String,
33 password = map['password'] as String,
34 typeRaw = map['typeRaw'] as int,
@@ -36,19 +38,19 @@ class Node extends HiveObject with Keyable {
38 static const boxName = 'Nodes';
39
40 @HiveField(0)
39 - String uriRaw;
41 + late String uriRaw;
42
43 @HiveField(1)
42 - String login;
44 + String? login;
45
46 @HiveField(2)
45 - String password;
47 + String? password;
48
49 @HiveField(3)
48 - int typeRaw;
50 + late int typeRaw;
51
52 @HiveField(4)
51 - bool useSSL;
53 + bool? useSSL;
54
55 bool get isSSL => useSSL ?? false;
56
@@ -63,7 +65,7 @@ class Node extends HiveObject with Keyable {
65 case WalletType.haven:
66 return Uri.http(uriRaw, '');
67 default:
66 - return null;
68 + throw Exception('Unexpected type ${type.toString()} for Node uri');
69 }
70 }
71
@@ -99,7 +101,6 @@ class Node extends HiveObject with Keyable {
101 }
102
103 Future<bool> requestMoneroNode() async {
102 -
104 final path = '/json_rpc';
105 final rpcUri = isSSL ? Uri.https(uri.authority, path) : Uri.http(uri.authority, path);
106 final realm = 'monero-rpc';
cw_core/lib/output_info.dart
+13 -13
@@ -1,20 +1,20 @@
1 class OutputInfo {
2 const OutputInfo(
3 - {this.fiatAmount,
4 - this.cryptoAmount,
5 - this.address,
6 - this.note,
7 - this.sendAll,
8 - this.extractedAddress,
9 - this.isParsedAddress,
10 - this.formattedCryptoAmount});
3 + {required this.address,
4 + required this.sendAll,
5 + required this.isParsedAddress,
6 + this.cryptoAmount,
7 + this.formattedCryptoAmount,
8 + this.fiatAmount,
9 + this.note,
10 + this.extractedAddress,});
11
12 - final String fiatAmount;
13 - final String cryptoAmount;
12 + final String? fiatAmount;
13 + final String? cryptoAmount;
14 final String address;
15 - final String note;
16 - final String extractedAddress;
15 + final String? note;
16 + final String? extractedAddress;
17 final bool sendAll;
18 final bool isParsedAddress;
19 - final int formattedCryptoAmount;
19 + final int? formattedCryptoAmount;
20 }
\ No newline at end of file
cw_core/lib/pathForWallet.dart
+3 -3
@@ -3,7 +3,7 @@ import 'package:cw_core/wallet_type.dart';
3 import 'package:flutter/foundation.dart';
4 import 'package:path_provider/path_provider.dart';
5
6 -Future<String> pathForWalletDir({@required String name, @required WalletType type}) async {
6 +Future<String> pathForWalletDir({required String name, required WalletType type}) async {
7 final root = await getApplicationDocumentsDirectory();
8 final prefix = walletTypeToString(type).toLowerCase();
9 final walletsDir = Directory('${root.path}/wallets');
@@ -16,11 +16,11 @@ Future<String> pathForWalletDir({@required String name, @required WalletType ty
16 return walletDire.path;
17 }
18
19 -Future<String> pathForWallet({@required String name, @required WalletType type}) async =>
19 +Future<String> pathForWallet({required String name, required WalletType type}) async =>
20 await pathForWalletDir(name: name, type: type)
21 .then((path) => path + '/$name');
22
23 -Future<String> outdatedAndroidPathForWalletDir({String name}) async {
23 +Future<String> outdatedAndroidPathForWalletDir({required String name}) async {
24 final directory = await getApplicationDocumentsDirectory();
25 final pathDir = directory.path + '/$name';
26
cw_core/lib/sec_random_native.dart
+1 -1
@@ -6,7 +6,7 @@ const utils = const MethodChannel('com.cake_wallet/native_utils');
6
7 Future<Uint8List> secRandom(int count) async {
8 try {
9 - return await utils.invokeMethod<Uint8List>('sec_random', {'count': count});
9 + return await utils.invokeMethod<Uint8List>('sec_random', {'count': count}) ?? Uint8List.fromList([]);
10 } on PlatformException catch (_) {
11 return Uint8List.fromList([]);
12 }
cw_core/lib/subaddress.dart
+2 -2
@@ -1,7 +1,7 @@
1 class Subaddress {
2 - Subaddress({this.id, this.address, this.label});
2 + Subaddress({required this.id, required this.address, required this.label});
3
4 - Subaddress.fromMap(Map map)
4 + Subaddress.fromMap(Map<String, Object?> map)
5 : this.id = map['id'] == null ? 0 : int.parse(map['id'] as String),
6 this.address = (map['address'] ?? '') as String,
7 this.label = (map['label'] ?? '') as String;
cw_core/lib/transaction_direction.dart
+12 -6
@@ -2,16 +2,22 @@ enum TransactionDirection { incoming, outgoing }
2
3 TransactionDirection parseTransactionDirectionFromInt(int raw) {
4 switch (raw) {
5 - case 0: return TransactionDirection.incoming;
6 - case 1: return TransactionDirection.outgoing;
7 - default: return null;
5 + case 0:
6 + return TransactionDirection.incoming;
7 + case 1:
8 + return TransactionDirection.outgoing;
9 + default:
10 + throw Exception('Unexpected token: raw for TransactionDirection parseTransactionDirectionFromInt');
11 }
12 }
13
14 TransactionDirection parseTransactionDirectionFromNumber(String raw) {
15 switch (raw) {
13 - case "0": return TransactionDirection.incoming;
14 - case "1": return TransactionDirection.outgoing;
15 - default: return null;
16 + case "0":
17 + return TransactionDirection.incoming;
18 + case "1":
19 + return TransactionDirection.outgoing;
20 + default:
21 + throw Exception('Unexpected token: raw for TransactionDirection parseTransactionDirectionFromNumber');
22 }
23 }
\ No newline at end of file
cw_core/lib/transaction_history.dart
+2 -3
@@ -1,10 +1,9 @@
1 -import 'package:flutter/foundation.dart';
1 import 'package:mobx/mobx.dart';
2 import 'package:cw_core/transaction_info.dart';
3
4 abstract class TransactionHistoryBase<TransactionType extends TransactionInfo> {
6 - TransactionHistoryBase();
7 - // : _isUpdating = false;
5 + TransactionHistoryBase()
6 + : transactions = ObservableMap<String, TransactionType>();
7
8 @observable
9 ObservableMap<String, TransactionType> transactions;
cw_core/lib/transaction_info.dart
+10 -10
@@ -2,21 +2,21 @@ import 'package:cw_core/transaction_direction.dart';
2 import 'package:cw_core/keyable.dart';
3
4 abstract class TransactionInfo extends Object with Keyable {
5 - String id;
6 - int amount;
7 - int fee;
8 - TransactionDirection direction;
9 - bool isPending;
10 - DateTime date;
11 - int height;
12 - int confirmations;
5 + late String id;
6 + late int amount;
7 + int? fee;
8 + late TransactionDirection direction;
9 + late bool isPending;
10 + late DateTime date;
11 + late int height;
12 + late int confirmations;
13 String amountFormatted();
14 String fiatAmount();
15 - String feeFormatted();
15 + String? feeFormatted();
16 void changeFiatAmount(String amount);
17
18 @override
19 dynamic get keyIndex => id;
20
21 - Map<String, dynamic> additionalInfo;
21 + late Map<String, dynamic> additionalInfo;
22 }
\ No newline at end of file
cw_core/lib/transaction_priority.dart
+1 -1
@@ -2,5 +2,5 @@ import 'package:cw_core/enumerable_item.dart';
2
3 abstract class TransactionPriority extends EnumerableItem<int>
4 with Serializable<int> {
5 - const TransactionPriority({String title, int raw}) : super(title: title, raw: raw);
5 + const TransactionPriority({required String title, required int raw}) : super(title: title, raw: raw);
6 }
cw_core/lib/unspent_coins_info.dart
+5 -5
@@ -5,11 +5,11 @@ part 'unspent_coins_info.g.dart';
5 @HiveType(typeId: UnspentCoinsInfo.typeId)
6 class UnspentCoinsInfo extends HiveObject {
7 UnspentCoinsInfo({
8 - this.walletId,
9 - this.hash,
10 - this.isFrozen,
11 - this.isSending,
12 - this.note});
8 + required this.walletId,
9 + required this.hash,
10 + required this.isFrozen,
11 + required this.isSending,
12 + required this.note});
13
14 static const typeId = 9;
15 static const boxName = 'Unspent';
cw_core/lib/wallet_addresses.dart
+2 -7
@@ -1,9 +1,8 @@
1 import 'package:cw_core/wallet_info.dart';
2
3 abstract class WalletAddresses {
4 - WalletAddresses(this.walletInfo) {
5 - addressesMap = {};
6 - }
4 + WalletAddresses(this.walletInfo)
5 + : addressesMap = {};
6
7 final WalletInfo walletInfo;
8
@@ -19,10 +18,6 @@ abstract class WalletAddresses {
18
19 Future<void> saveAddressesInBox() async {
20 try {
22 - if (walletInfo == null) {
23 - return;
24 - }
25 -
21 walletInfo.address = address;
22 walletInfo.addresses = addressesMap;
23
cw_core/lib/wallet_addresses_with_account.dart
+2 -2
@@ -5,9 +5,9 @@ import 'package:cw_core/wallet_info.dart';
5 abstract class WalletAddressesWithAccount<T> extends WalletAddresses {
6 WalletAddressesWithAccount(WalletInfo walletInfo) : super(walletInfo);
7
8 - T get account;
8 + // T get account;
9
10 - set account(T account);
10 + // set account(T account);
11
12 AccountList<T> get accountList;
13 }
\ No newline at end of file
cw_core/lib/wallet_base.dart
+5 -5
@@ -1,12 +1,12 @@
1 import 'package:mobx/mobx.dart';
2 import 'package:cw_core/balance.dart';
3 import 'package:cw_core/transaction_info.dart';
4 +import 'package:cw_core/transaction_history.dart';
5 import 'package:cw_core/transaction_priority.dart';
6 import 'package:cw_core/wallet_addresses.dart';
7 import 'package:flutter/foundation.dart';
8 import 'package:cw_core/wallet_info.dart';
9 import 'package:cw_core/pending_transaction.dart';
9 -import 'package:cw_core/transaction_history.dart';
10 import 'package:cw_core/currency_for_wallet_type.dart';
11 import 'package:cw_core/crypto_currency.dart';
12 import 'package:cw_core/sync_status.dart';
@@ -48,15 +48,15 @@ abstract class WalletBase<
48
49 WalletAddresses get walletAddresses;
50
51 - HistoryType transactionHistory;
51 + late HistoryType transactionHistory;
52
53 - Future<void> connectToNode({@required Node node});
53 + Future<void> connectToNode({required Node node});
54
55 Future<void> startSync();
56
57 Future<PendingTransaction> createTransaction(Object credentials);
58
59 - int calculateEstimatedFee(TransactionPriority priority, int amount);
59 + int calculateEstimatedFee(TransactionPriority priority, int? amount);
60
61 // void fetchTransactionsAsync(
62 // void Function(TransactionType transaction) onTransactionLoaded,
@@ -66,7 +66,7 @@ abstract class WalletBase<
66
67 Future<void> save();
68
69 - Future<void> rescan({int height});
69 + Future<void> rescan({required int height});
70
71 void close();
72
cw_core/lib/wallet_credentials.dart
+8 -4
@@ -1,10 +1,14 @@
1 import 'package:cw_core/wallet_info.dart';
2
3 abstract class WalletCredentials {
4 - WalletCredentials({this.name, this.password, this.height, this.walletInfo});
4 + WalletCredentials({
5 + required this.name,
6 + this.height,
7 + this.walletInfo,
8 + this.password});
9
10 final String name;
7 - final int height;
8 - String password;
9 - WalletInfo walletInfo;
11 + final int? height;
12 + String? password;
13 + WalletInfo? walletInfo;
14 }
cw_core/lib/wallet_info.dart
+15 -15
@@ -13,20 +13,20 @@ class WalletInfo extends HiveObject {
13 : _yatLastUsedAddressController = StreamController<String>.broadcast();
14
15 factory WalletInfo.external(
16 - {@required String id,
17 - @required String name,
18 - @required WalletType type,
19 - @required bool isRecovery,
20 - @required int restoreHeight,
21 - @required DateTime date,
22 - @required String dirPath,
23 - @required String path,
24 - @required String address,
16 + {required String id,
17 + required String name,
18 + required WalletType type,
19 + required bool isRecovery,
20 + required int restoreHeight,
21 + required DateTime date,
22 + required String dirPath,
23 + required String path,
24 + required String address,
25 + bool? showIntroCakePayCard,
26 String yatEid ='',
26 - String yatLastUsedAddressRaw = '',
27 - bool showIntroCakePayCard}) {
27 + String yatLastUsedAddressRaw = ''}) {
28 return WalletInfo(id, name, type, isRecovery, restoreHeight,
29 - date.millisecondsSinceEpoch ?? 0, dirPath, path, address,
29 + date.millisecondsSinceEpoch, dirPath, path, address,
30 yatEid, yatLastUsedAddressRaw, showIntroCakePayCard);
31 }
32
@@ -61,7 +61,7 @@ class WalletInfo extends HiveObject {
61 String address;
62
63 @HiveField(10)
64 - Map<String, String> addresses;
64 + Map<String, String>? addresses;
65
66 @HiveField(11)
67 String yatEid;
@@ -70,7 +70,7 @@ class WalletInfo extends HiveObject {
70 String yatLastUsedAddressRaw;
71
72 @HiveField(13)
73 - bool showIntroCakePayCard;
73 + bool? showIntroCakePayCard;
74
75 String get yatLastUsedAddress => yatLastUsedAddressRaw;
76
@@ -85,7 +85,7 @@ class WalletInfo extends HiveObject {
85 if(showIntroCakePayCard == null) {
86 return type != WalletType.haven;
87 }
88 - return showIntroCakePayCard;
88 + return showIntroCakePayCard!;
89 }
90
91 DateTime get date => DateTime.fromMillisecondsSinceEpoch(timestamp);
cw_core/lib/wallet_type.dart
+2 -2
@@ -55,7 +55,7 @@ WalletType deserializeFromInt(int raw) {
55 case 3:
56 return WalletType.haven;
57 default:
58 - return null;
58 + throw Exception('Unexpected token: $raw for WalletType deserializeFromInt');
59 }
60 }
61
@@ -100,6 +100,6 @@ CryptoCurrency walletTypeToCryptoCurrency(WalletType type) {
100 case WalletType.haven:
101 return CryptoCurrency.xhv;
102 default:
103 - return null;
103 + throw Exception('Unexpected wallet type: ${type.toString()} for CryptoCurrency walletTypeToCryptoCurrency');
104 }
105 }
cw_core/pubspec.lock
+94 -87
@@ -7,35 +7,35 @@ packages:
7 name: _fe_analyzer_shared
8 url: "https://pub.dartlang.org"
9 source: hosted
10 - version: "14.0.0"
10 + version: "47.0.0"
11 analyzer:
12 dependency: transitive
13 description:
14 name: analyzer
15 url: "https://pub.dartlang.org"
16 source: hosted
17 - version: "0.41.2"
17 + version: "4.7.0"
18 args:
19 dependency: transitive
20 description:
21 name: args
22 url: "https://pub.dartlang.org"
23 source: hosted
24 - version: "1.6.0"
24 + version: "2.3.1"
25 asn1lib:
26 dependency: transitive
27 description:
28 name: asn1lib
29 url: "https://pub.dartlang.org"
30 source: hosted
31 - version: "0.8.1"
31 + version: "1.1.1"
32 async:
33 dependency: transitive
34 description:
35 name: async
36 url: "https://pub.dartlang.org"
37 source: hosted
38 - version: "2.5.0"
38 + version: "2.9.0"
39 boolean_selector:
40 dependency: transitive
41 description:
@@ -49,42 +49,42 @@ packages:
49 name: build
50 url: "https://pub.dartlang.org"
51 source: hosted
52 - version: "1.6.2"
52 + version: "2.3.1"
53 build_config:
54 dependency: transitive
55 description:
56 name: build_config
57 url: "https://pub.dartlang.org"
58 source: hosted
59 - version: "0.4.6"
59 + version: "1.1.0"
60 build_daemon:
61 dependency: transitive
62 description:
63 name: build_daemon
64 url: "https://pub.dartlang.org"
65 source: hosted
66 - version: "2.1.10"
66 + version: "3.1.0"
67 build_resolvers:
68 dependency: "direct dev"
69 description:
70 name: build_resolvers
71 url: "https://pub.dartlang.org"
72 source: hosted
73 - version: "1.5.3"
73 + version: "2.0.10"
74 build_runner:
75 dependency: "direct dev"
76 description:
77 name: build_runner
78 url: "https://pub.dartlang.org"
79 source: hosted
80 - version: "1.11.5"
80 + version: "2.2.1"
81 build_runner_core:
82 dependency: transitive
83 description:
84 name: build_runner_core
85 url: "https://pub.dartlang.org"
86 source: hosted
87 - version: "6.1.10"
87 + version: "7.2.4"
88 built_collection:
89 dependency: transitive
90 description:
@@ -105,98 +105,77 @@ packages:
105 name: characters
106 url: "https://pub.dartlang.org"
107 source: hosted
108 - version: "1.1.0"
109 - charcode:
110 - dependency: transitive
111 - description:
112 - name: charcode
113 - url: "https://pub.dartlang.org"
114 - source: hosted
115 - version: "1.2.0"
108 + version: "1.2.1"
109 checked_yaml:
110 dependency: transitive
111 description:
112 name: checked_yaml
113 url: "https://pub.dartlang.org"
114 source: hosted
122 - version: "1.0.4"
123 - cli_util:
124 - dependency: transitive
125 - description:
126 - name: cli_util
127 - url: "https://pub.dartlang.org"
128 - source: hosted
129 - version: "0.3.5"
115 + version: "2.0.1"
116 clock:
117 dependency: transitive
118 description:
119 name: clock
120 url: "https://pub.dartlang.org"
121 source: hosted
136 - version: "1.1.0"
122 + version: "1.1.1"
123 code_builder:
124 dependency: transitive
125 description:
126 name: code_builder
127 url: "https://pub.dartlang.org"
128 source: hosted
143 - version: "3.7.0"
129 + version: "4.3.0"
130 collection:
131 dependency: transitive
132 description:
133 name: collection
134 url: "https://pub.dartlang.org"
135 source: hosted
150 - version: "1.15.0"
136 + version: "1.16.0"
137 convert:
138 dependency: transitive
139 description:
140 name: convert
141 url: "https://pub.dartlang.org"
142 source: hosted
157 - version: "2.1.1"
143 + version: "3.0.2"
144 crypto:
145 dependency: transitive
146 description:
147 name: crypto
148 url: "https://pub.dartlang.org"
149 source: hosted
164 - version: "2.1.5"
150 + version: "3.0.2"
151 dart_style:
152 dependency: transitive
153 description:
154 name: dart_style
155 url: "https://pub.dartlang.org"
156 source: hosted
171 - version: "1.3.12"
172 - dartx:
173 - dependency: transitive
174 - description:
175 - name: dartx
176 - url: "https://pub.dartlang.org"
177 - source: hosted
178 - version: "0.5.0"
157 + version: "2.2.4"
158 encrypt:
159 dependency: "direct main"
160 description:
161 name: encrypt
162 url: "https://pub.dartlang.org"
163 source: hosted
185 - version: "4.1.0"
164 + version: "5.0.1"
165 fake_async:
166 dependency: transitive
167 description:
168 name: fake_async
169 url: "https://pub.dartlang.org"
170 source: hosted
192 - version: "1.2.0"
171 + version: "1.3.1"
172 ffi:
173 dependency: transitive
174 description:
175 name: ffi
176 url: "https://pub.dartlang.org"
177 source: hosted
199 - version: "1.1.2"
178 + version: "2.0.1"
179 file:
180 dependency: transitive
181 description:
@@ -222,12 +201,19 @@ packages:
201 name: flutter_mobx
202 url: "https://pub.dartlang.org"
203 source: hosted
225 - version: "1.1.0+2"
204 + version: "2.0.6+4"
205 flutter_test:
206 dependency: "direct dev"
207 description: flutter
208 source: sdk
209 version: "0.0.0"
210 + frontend_server_client:
211 + dependency: transitive
212 + description:
213 + name: frontend_server_client
214 + url: "https://pub.dartlang.org"
215 + source: hosted
216 + version: "2.1.3"
217 glob:
218 dependency: transitive
219 description:
@@ -241,42 +227,42 @@ packages:
227 name: graphs
228 url: "https://pub.dartlang.org"
229 source: hosted
244 - version: "0.2.0"
230 + version: "2.1.0"
231 hive:
232 dependency: transitive
233 description:
234 name: hive
235 url: "https://pub.dartlang.org"
236 source: hosted
251 - version: "1.4.4+1"
237 + version: "2.2.3"
238 hive_generator:
239 dependency: "direct dev"
240 description:
241 name: hive_generator
242 url: "https://pub.dartlang.org"
243 source: hosted
258 - version: "0.8.2"
244 + version: "1.1.3"
245 http:
246 dependency: "direct main"
247 description:
248 name: http
249 url: "https://pub.dartlang.org"
250 source: hosted
265 - version: "0.12.2"
251 + version: "0.13.5"
252 http_multi_server:
253 dependency: transitive
254 description:
255 name: http_multi_server
256 url: "https://pub.dartlang.org"
257 source: hosted
272 - version: "2.2.0"
258 + version: "3.2.1"
259 http_parser:
260 dependency: transitive
261 description:
262 name: http_parser
263 url: "https://pub.dartlang.org"
264 source: hosted
279 - version: "3.1.4"
265 + version: "4.0.1"
266 intl:
267 dependency: "direct main"
268 description:
@@ -290,7 +276,7 @@ packages:
276 name: io
277 url: "https://pub.dartlang.org"
278 source: hosted
293 - version: "0.3.5"
279 + version: "1.0.3"
280 js:
281 dependency: transitive
282 description:
@@ -304,7 +290,7 @@ packages:
290 name: json_annotation
291 url: "https://pub.dartlang.org"
292 source: hosted
307 - version: "4.0.1"
293 + version: "4.6.0"
294 logging:
295 dependency: transitive
296 description:
@@ -318,14 +304,21 @@ packages:
304 name: matcher
305 url: "https://pub.dartlang.org"
306 source: hosted
321 - version: "0.12.10"
307 + version: "0.12.12"
308 + material_color_utilities:
309 + dependency: transitive
310 + description:
311 + name: material_color_utilities
312 + url: "https://pub.dartlang.org"
313 + source: hosted
314 + version: "0.1.5"
315 meta:
316 dependency: transitive
317 description:
318 name: meta
319 url: "https://pub.dartlang.org"
320 source: hosted
328 - version: "1.3.0"
321 + version: "1.8.0"
322 mime:
323 dependency: transitive
324 description:
@@ -339,63 +332,77 @@ packages:
332 name: mobx
333 url: "https://pub.dartlang.org"
334 source: hosted
342 - version: "1.2.1+4"
335 + version: "2.1.0"
336 mobx_codegen:
337 dependency: "direct dev"
338 description:
339 name: mobx_codegen
340 url: "https://pub.dartlang.org"
341 source: hosted
349 - version: "1.1.2"
342 + version: "2.0.7+3"
343 package_config:
344 dependency: transitive
345 description:
346 name: package_config
347 url: "https://pub.dartlang.org"
348 source: hosted
356 - version: "1.9.3"
349 + version: "2.1.0"
350 path:
351 dependency: transitive
352 description:
353 name: path
354 url: "https://pub.dartlang.org"
355 source: hosted
363 - version: "1.8.0"
356 + version: "1.8.2"
357 path_provider:
358 dependency: "direct main"
359 description:
360 name: path_provider
361 url: "https://pub.dartlang.org"
362 source: hosted
370 - version: "1.6.28"
363 + version: "2.0.11"
364 + path_provider_android:
365 + dependency: transitive
366 + description:
367 + name: path_provider_android
368 + url: "https://pub.dartlang.org"
369 + source: hosted
370 + version: "2.0.20"
371 + path_provider_ios:
372 + dependency: transitive
373 + description:
374 + name: path_provider_ios
375 + url: "https://pub.dartlang.org"
376 + source: hosted
377 + version: "2.0.11"
378 path_provider_linux:
379 dependency: transitive
380 description:
381 name: path_provider_linux
382 url: "https://pub.dartlang.org"
383 source: hosted
377 - version: "0.0.1+2"
384 + version: "2.1.7"
385 path_provider_macos:
386 dependency: transitive
387 description:
388 name: path_provider_macos
389 url: "https://pub.dartlang.org"
390 source: hosted
384 - version: "0.0.4+8"
391 + version: "2.0.6"
392 path_provider_platform_interface:
393 dependency: transitive
394 description:
395 name: path_provider_platform_interface
396 url: "https://pub.dartlang.org"
397 source: hosted
391 - version: "1.0.4"
398 + version: "2.0.4"
399 path_provider_windows:
400 dependency: transitive
401 description:
402 name: path_provider_windows
403 url: "https://pub.dartlang.org"
404 source: hosted
398 - version: "0.0.5"
405 + version: "2.1.3"
406 pedantic:
407 dependency: transitive
408 description:
@@ -416,14 +423,14 @@ packages:
423 name: plugin_platform_interface
424 url: "https://pub.dartlang.org"
425 source: hosted
419 - version: "1.0.3"
426 + version: "2.1.3"
427 pointycastle:
428 dependency: transitive
429 description:
430 name: pointycastle
431 url: "https://pub.dartlang.org"
432 source: hosted
426 - version: "2.0.1"
433 + version: "3.6.2"
434 pool:
435 dependency: transitive
436 description:
@@ -451,21 +458,21 @@ packages:
458 name: pubspec_parse
459 url: "https://pub.dartlang.org"
460 source: hosted
454 - version: "0.1.8"
461 + version: "1.2.1"
462 shelf:
463 dependency: transitive
464 description:
465 name: shelf
466 url: "https://pub.dartlang.org"
467 source: hosted
461 - version: "0.7.9"
468 + version: "1.3.2"
469 shelf_web_socket:
470 dependency: transitive
471 description:
472 name: shelf_web_socket
473 url: "https://pub.dartlang.org"
474 source: hosted
468 - version: "0.2.4+1"
475 + version: "1.0.2"
476 sky_engine:
477 dependency: transitive
478 description: flutter
@@ -477,14 +484,21 @@ packages:
484 name: source_gen
485 url: "https://pub.dartlang.org"
486 source: hosted
480 - version: "0.9.10+3"
487 + version: "1.2.3"
488 + source_helper:
489 + dependency: transitive
490 + description:
491 + name: source_helper
492 + url: "https://pub.dartlang.org"
493 + source: hosted
494 + version: "1.3.3"
495 source_span:
496 dependency: transitive
497 description:
498 name: source_span
499 url: "https://pub.dartlang.org"
500 source: hosted
487 - version: "1.8.0"
501 + version: "1.9.0"
502 stack_trace:
503 dependency: transitive
504 description:
@@ -512,35 +526,28 @@ packages:
526 name: string_scanner
527 url: "https://pub.dartlang.org"
528 source: hosted
515 - version: "1.1.0"
529 + version: "1.1.1"
530 term_glyph:
531 dependency: transitive
532 description:
533 name: term_glyph
534 url: "https://pub.dartlang.org"
535 source: hosted
522 - version: "1.2.0"
536 + version: "1.2.1"
537 test_api:
538 dependency: transitive
539 description:
540 name: test_api
541 url: "https://pub.dartlang.org"
542 source: hosted
529 - version: "0.2.19"
530 - time:
531 - dependency: transitive
532 - description:
533 - name: time
534 - url: "https://pub.dartlang.org"
535 - source: hosted
536 - version: "1.4.1"
543 + version: "0.4.12"
544 timing:
545 dependency: transitive
546 description:
547 name: timing
548 url: "https://pub.dartlang.org"
549 source: hosted
543 - version: "0.1.1+3"
550 + version: "1.0.0"
551 typed_data:
552 dependency: transitive
553 description:
@@ -554,7 +561,7 @@ packages:
561 name: vector_math
562 url: "https://pub.dartlang.org"
563 source: hosted
557 - version: "2.1.0"
564 + version: "2.1.2"
565 watcher:
566 dependency: transitive
567 description:
@@ -568,21 +575,21 @@ packages:
575 name: web_socket_channel
576 url: "https://pub.dartlang.org"
577 source: hosted
571 - version: "1.2.0"
578 + version: "2.2.0"
579 win32:
580 dependency: transitive
581 description:
582 name: win32
583 url: "https://pub.dartlang.org"
584 source: hosted
578 - version: "2.0.5"
585 + version: "3.0.0"
586 xdg_directories:
587 dependency: transitive
588 description:
589 name: xdg_directories
590 url: "https://pub.dartlang.org"
591 source: hosted
585 - version: "0.1.2"
592 + version: "0.2.0+2"
593 yaml:
594 dependency: transitive
595 description:
@@ -591,5 +598,5 @@ packages:
598 source: hosted
599 version: "3.1.0"
600 sdks:
594 - dart: ">=2.12.0 <3.0.0"
595 - flutter: ">=1.20.0"
601 + dart: ">=2.17.5 <3.0.0"
602 + flutter: ">=3.0.0"
cw_core/pubspec.yaml
+11 -11
@@ -6,26 +6,26 @@ author: Cake Wallet
6 homepage: https://cakewallet.com
7
8 environment:
9 - sdk: ">=2.7.0 <3.0.0"
10 - flutter: ">=1.17.0"
9 + sdk: ">=2.17.5 <3.0.0"
10 + flutter: ">=1.20.0"
11
12 dependencies:
13 flutter:
14 sdk: flutter
15 - http: ^0.12.0+2
16 - path_provider: ^1.3.0
17 - mobx: ^1.2.1+2
18 - flutter_mobx: ^1.1.0+2
15 + http: ^0.13.4
16 + path_provider: ^2.0.11
17 + mobx: ^2.0.7+4
18 + flutter_mobx: ^2.0.6+1
19 intl: ^0.17.0
20 - encrypt: ^4.0.0
20 + encrypt: ^5.0.1
21
22 dev_dependencies:
23 flutter_test:
24 sdk: flutter
25 - build_runner: ^1.10.3
26 - build_resolvers: ^1.3.10
27 - mobx_codegen: ^1.1.0+1
28 - hive_generator: ^0.8.1
25 + build_runner: ^2.1.11
26 + build_resolvers: ^2.0.9
27 + mobx_codegen: ^2.0.7
28 + hive_generator: ^1.1.3
29
30 # For information on the generic Dart part of this file, see the
31 # following page: https://dart.dev/tools/pub/pubspec
cw_haven/lib/api/account_list.dart
+8 -8
@@ -50,16 +50,16 @@ List<AccountRow> getAllAccount() {
50 .toList();
51 }
52
53 -void addAccountSync({String label}) {
54 - final labelPointer = Utf8.toUtf8(label);
53 +void addAccountSync({required String label}) {
54 + final labelPointer = label.toNativeUtf8();
55 accountAddNewNative(labelPointer);
56 - free(labelPointer);
56 + calloc.free(labelPointer);
57 }
58
59 -void setLabelForAccountSync({int accountIndex, String label}) {
60 - final labelPointer = Utf8.toUtf8(label);
59 +void setLabelForAccountSync({required int accountIndex, required String label}) {
60 + final labelPointer = label.toNativeUtf8();
61 accountSetLabelNative(accountIndex, labelPointer);
62 - free(labelPointer);
62 + calloc.free(labelPointer);
63 }
64
65 void _addAccount(String label) => addAccountSync(label: label);
@@ -71,12 +71,12 @@ void _setLabelForAccount(Map<String, dynamic> args) {
71 setLabelForAccountSync(label: label, accountIndex: accountIndex);
72 }
73
74 -Future<void> addAccount({String label}) async {
74 +Future<void> addAccount({required String label}) async {
75 await compute(_addAccount, label);
76 await store();
77 }
78
79 -Future<void> setLabelForAccount({int accountIndex, String label}) async {
79 +Future<void> setLabelForAccount({required int accountIndex, required String label}) async {
80 await compute(
81 _setLabelForAccount, {'accountIndex': accountIndex, 'label': label});
82 await store();
cw_haven/lib/api/convert_utf8_to_string.dart
+3 -3
@@ -1,8 +1,8 @@
1 import 'dart:ffi';
2 import 'package:ffi/ffi.dart';
3
4 -String convertUTF8ToString({Pointer<Utf8> pointer}) {
5 - final str = Utf8.fromUtf8(pointer);
6 - free(pointer);
4 +String convertUTF8ToString({required Pointer<Utf8> pointer}) {
5 + final str = pointer.toDartString();
6 + calloc.free(pointer);
7 return str;
8 }
\ No newline at end of file
cw_haven/lib/api/cw_haven.dart
+1 -1
@@ -8,7 +8,7 @@ class CwHaven {
8 const MethodChannel('cw_haven');
9
10 static Future<String> get platformVersion async {
11 - final String version = await _channel.invokeMethod('getPlatformVersion');
11 + final String version = await _channel.invokeMethod<String>('getPlatformVersion') ?? '';
12 return version;
13 }
14 }
cw_haven/lib/api/exceptions/connection_to_node_exception.dart
+1 -1
@@ -1,5 +1,5 @@
1 class ConnectionToNodeException implements Exception {
2 - ConnectionToNodeException({this.message});
2 + ConnectionToNodeException({required this.message});
3
4 final String message;
5 }
\ No newline at end of file
cw_haven/lib/api/exceptions/creation_transaction_exception.dart
+1 -1
@@ -1,5 +1,5 @@
1 class CreationTransactionException implements Exception {
2 - CreationTransactionException({this.message});
2 + CreationTransactionException({required this.message});
3
4 final String message;
5
cw_haven/lib/api/exceptions/setup_wallet_exception.dart
+1 -1
@@ -1,5 +1,5 @@
1 class SetupWalletException implements Exception {
2 - SetupWalletException({this.message});
2 + SetupWalletException({required this.message});
3
4 final String message;
5 }
\ No newline at end of file
cw_haven/lib/api/exceptions/wallet_creation_exception.dart
+1 -1
@@ -1,5 +1,5 @@
1 class WalletCreationException implements Exception {
2 - WalletCreationException({this.message});
2 + WalletCreationException({required this.message});
3
4 final String message;
5
cw_haven/lib/api/exceptions/wallet_opening_exception.dart
+1 -1
@@ -1,5 +1,5 @@
1 class WalletOpeningException implements Exception {
2 - WalletOpeningException({this.message});
2 + WalletOpeningException({required this.message});
3
4 final String message;
5
cw_haven/lib/api/exceptions/wallet_restore_from_keys_exception.dart
+1 -1
@@ -1,5 +1,5 @@
1 class WalletRestoreFromKeysException implements Exception {
2 - WalletRestoreFromKeysException({this.message});
2 + WalletRestoreFromKeysException({required this.message});
3
4 final String message;
5 }
\ No newline at end of file
cw_haven/lib/api/exceptions/wallet_restore_from_seed_exception.dart
+1 -1
@@ -1,5 +1,5 @@
1 class WalletRestoreFromSeedException implements Exception {
2 - WalletRestoreFromSeedException({this.message});
2 + WalletRestoreFromSeedException({required this.message});
3
4 final String message;
5 }
\ No newline at end of file
cw_haven/lib/api/monero_output.dart
+1 -1
@@ -1,7 +1,7 @@
1 import 'package:flutter/foundation.dart';
2
3 class MoneroOutput {
4 - MoneroOutput({@required this.address, @required this.amount});
4 + MoneroOutput({required this.address, required this.amount});
5
6 final String address;
7 final String amount;
cw_haven/lib/api/signatures.dart
+2 -2
@@ -39,7 +39,7 @@ typedef get_node_height = Int64 Function();
39 typedef is_connected = Int8 Function();
40
41 typedef setup_node = Int8 Function(
42 - Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Int8, Int8, Pointer<Utf8>);
42 + Pointer<Utf8>, Pointer<Utf8>?, Pointer<Utf8>?, Int8, Int8, Pointer<Utf8>);
43
44 typedef start_refresh = Void Function();
45
@@ -86,7 +86,7 @@ typedef account_set_label = Void Function(
86
87 typedef transactions_refresh = Void Function();
88
89 -typedef get_tx_key = Pointer<Utf8> Function(Pointer<Utf8> txId);
89 +typedef get_tx_key = Pointer<Utf8>? Function(Pointer<Utf8> txId);
90
91 typedef transactions_count = Int64 Function();
92
cw_haven/lib/api/structs/account_row.dart
+4 -3
@@ -3,9 +3,10 @@ import 'package:ffi/ffi.dart';
3
4 class AccountRow extends Struct {
5 @Int64()
6 - int id;
7 - Pointer<Utf8> label;
6 + external int id;
7 +
8 + external Pointer<Utf8> label;
9
9 - String getLabel() => Utf8.fromUtf8(label);
10 + String getLabel() => label.toDartString();
11 int getId() => id;
12 }
cw_haven/lib/api/structs/haven_balance_row.dart
+4 -3
@@ -3,9 +3,10 @@ import 'package:ffi/ffi.dart';
3
4 class HavenBalanceRow extends Struct {
5 @Int64()
6 - int amount;
7 - Pointer<Utf8> assetType;
6 + external int amount;
7 +
8 + external Pointer<Utf8> assetType;
9
10 int getAmount() => amount;
10 - String getAssetType() => Utf8.fromUtf8(assetType);
11 + String getAssetType() => assetType.toDartString();
12 }
cw_haven/lib/api/structs/haven_rate.dart
+4 -3
@@ -3,9 +3,10 @@ import 'package:ffi/ffi.dart';
3
4 class HavenRate extends Struct {
5 @Int64()
6 - int rate;
7 - Pointer<Utf8> assetType;
6 + external int rate;
7 +
8 + external Pointer<Utf8> assetType;
9
10 int getRate() => rate;
10 - String getAssetType() => Utf8.fromUtf8(assetType);
11 + String getAssetType() => assetType.toDartString();
12 }
cw_haven/lib/api/structs/pending_transaction.dart
+9 -5
@@ -3,18 +3,22 @@ import 'package:ffi/ffi.dart';
3
4 class PendingTransactionRaw extends Struct {
5 @Int64()
6 - int amount;
6 + external int amount;
7
8 @Int64()
9 - int fee;
9 + external int fee;
10
11 - Pointer<Utf8> hash;
11 + external Pointer<Utf8> hash;
12
13 - String getHash() => Utf8.fromUtf8(hash);
13 + String getHash() => hash.toDartString();
14 }
15
16 class PendingTransactionDescription {
17 - PendingTransactionDescription({this.amount, this.fee, this.hash, this.pointerAddress});
17 + PendingTransactionDescription({
18 + required this.amount,
19 + required this.fee,
20 + required this.hash,
21 + required this.pointerAddress});
22
23 final int amount;
24 final int fee;
cw_haven/lib/api/structs/subaddress_row.dart
+7 -5
@@ -3,11 +3,13 @@ import 'package:ffi/ffi.dart';
3
4 class SubaddressRow extends Struct {
5 @Int64()
6 - int id;
7 - Pointer<Utf8> address;
8 - Pointer<Utf8> label;
6 + external int id;
7 +
8 + external Pointer<Utf8> address;
9 +
10 + external Pointer<Utf8> label;
11
10 - String getLabel() => Utf8.fromUtf8(label);
11 - String getAddress() => Utf8.fromUtf8(address);
12 + String getLabel() => label.toDartString();
13 + String getAddress() => address.toDartString();
14 int getId() => id;
15 }
\ No newline at end of file
cw_haven/lib/api/structs/transaction_info_row.dart
+15 -15
@@ -3,42 +3,42 @@ import 'package:ffi/ffi.dart';
3
4 class TransactionInfoRow extends Struct {
5 @Uint64()
6 - int amount;
6 + external int amount;
7
8 @Uint64()
9 - int fee;
9 + external int fee;
10
11 @Uint64()
12 - int blockHeight;
12 + external int blockHeight;
13
14 @Uint64()
15 - int confirmations;
15 + external int confirmations;
16
17 @Uint32()
18 - int subaddrAccount;
18 + external int subaddrAccount;
19
20 @Int8()
21 - int direction;
21 + external int direction;
22
23 @Int8()
24 - int isPending;
24 + external int isPending;
25
26 @Uint32()
27 - int subaddrIndex;
27 + external int subaddrIndex;
28
29 - Pointer<Utf8> hash;
29 + external Pointer<Utf8> hash;
30
31 - Pointer<Utf8> paymentId;
31 + external Pointer<Utf8> paymentId;
32
33 - Pointer<Utf8> assetType;
33 + external Pointer<Utf8> assetType;
34
35 @Int64()
36 - int datetime;
36 + external int datetime;
37
38 int getDatetime() => datetime;
39 int getAmount() => amount >= 0 ? amount : amount * -1;
40 bool getIsPending() => isPending != 0;
41 - String getHash() => Utf8.fromUtf8(hash);
42 - String getPaymentId() => Utf8.fromUtf8(paymentId);
43 - String getAssetType() => Utf8.fromUtf8(assetType);
41 + String getHash() => hash.toDartString();
42 + String getPaymentId() => paymentId.toDartString();
43 + String getAssetType() => assetType.toDartString();
44 }
cw_haven/lib/api/structs/ut8_box.dart
+2 -2
@@ -2,7 +2,7 @@ import 'dart:ffi';
2 import 'package:ffi/ffi.dart';
3
4 class Utf8Box extends Struct {
5 - Pointer<Utf8> value;
5 + external Pointer<Utf8> value;
6
7 - String getValue() => Utf8.fromUtf8(value);
7 + String getValue() => value.toDartString();
8 }
cw_haven/lib/api/subaddress_list.dart
+9 -9
@@ -29,7 +29,7 @@ final subaddrressSetLabelNative = havenApi
29
30 bool isUpdating = false;
31
32 -void refreshSubaddresses({@required int accountIndex}) {
32 +void refreshSubaddresses({required int accountIndex}) {
33 try {
34 isUpdating = true;
35 subaddressRefreshNative(accountIndex);
@@ -50,18 +50,18 @@ List<SubaddressRow> getAllSubaddresses() {
50 .toList();
51 }
52
53 -void addSubaddressSync({int accountIndex, String label}) {
54 - final labelPointer = Utf8.toUtf8(label);
53 +void addSubaddressSync({required int accountIndex, required String label}) {
54 + final labelPointer = label.toNativeUtf8();
55 subaddrressAddNewNative(accountIndex, labelPointer);
56 - free(labelPointer);
56 + calloc.free(labelPointer);
57 }
58
59 void setLabelForSubaddressSync(
60 - {int accountIndex, int addressIndex, String label}) {
61 - final labelPointer = Utf8.toUtf8(label);
60 + {required int accountIndex, required int addressIndex, required String label}) {
61 + final labelPointer = label.toNativeUtf8();
62
63 subaddrressSetLabelNative(accountIndex, addressIndex, labelPointer);
64 - free(labelPointer);
64 + calloc.free(labelPointer);
65 }
66
67 void _addSubaddress(Map<String, dynamic> args) {
@@ -80,14 +80,14 @@ void _setLabelForSubaddress(Map<String, dynamic> args) {
80 accountIndex: accountIndex, addressIndex: addressIndex, label: label);
81 }
82
83 -Future addSubaddress({int accountIndex, String label}) async {
83 +Future addSubaddress({required int accountIndex, required String label}) async {
84 await compute<Map<String, Object>, void>(
85 _addSubaddress, {'accountIndex': accountIndex, 'label': label});
86 await store();
87 }
88
89 Future setLabelForSubaddress(
90 - {int accountIndex, int addressIndex, String label}) async {
90 + {required int accountIndex, required int addressIndex, required String label}) async {
91 await compute<Map<String, Object>, void>(_setLabelForSubaddress, {
92 'accountIndex': accountIndex,
93 'addressIndex': addressIndex,
cw_haven/lib/api/transaction_history.dart
+49 -49
@@ -40,16 +40,16 @@ final getTxKeyNative = havenApi
40 .asFunction<GetTxKey>();
41
42 String getTxKey(String txId) {
43 - final txIdPointer = Utf8.toUtf8(txId);
43 + final txIdPointer = txId.toNativeUtf8();
44 final keyPointer = getTxKeyNative(txIdPointer);
45
46 - free(txIdPointer);
46 + calloc.free(txIdPointer);
47
48 if (keyPointer != null) {
49 return convertUTF8ToString(pointer: keyPointer);
50 }
51
52 - return null;
52 + return '';
53 }
54
55 void refreshTransactions() => transactionsRefreshNative();
@@ -67,18 +67,18 @@ List<TransactionInfoRow> getAllTransations() {
67 }
68
69 PendingTransactionDescription createTransactionSync(
70 - {String address,
71 - String assetType,
72 - String paymentId,
73 - String amount,
74 - int priorityRaw,
70 + {required String address,
71 + required String assetType,
72 + required String paymentId,
73 + required int priorityRaw,
74 + String? amount,
75 int accountIndex = 0}) {
76 - final addressPointer = Utf8.toUtf8(address);
77 - final assetTypePointer = Utf8.toUtf8(assetType);
78 - final paymentIdPointer = Utf8.toUtf8(paymentId);
79 - final amountPointer = amount != null ? Utf8.toUtf8(amount) : nullptr;
80 - final errorMessagePointer = allocate<Utf8Box>();
81 - final pendingTransactionRawPointer = allocate<PendingTransactionRaw>();
76 + final addressPointer = address.toNativeUtf8();
77 + final assetTypePointer = assetType.toNativeUtf8();
78 + final paymentIdPointer = paymentId.toNativeUtf8();
79 + final amountPointer = amount != null ? amount.toNativeUtf8() : nullptr;
80 + final errorMessagePointer = calloc<Utf8Box>();
81 + final pendingTransactionRawPointer = calloc<PendingTransactionRaw>();
82 final created = transactionCreateNative(
83 addressPointer,
84 assetTypePointer,
@@ -90,17 +90,17 @@ PendingTransactionDescription createTransactionSync(
90 pendingTransactionRawPointer) !=
91 0;
92
93 - free(addressPointer);
94 - free(assetTypePointer);
95 - free(paymentIdPointer);
93 + calloc.free(addressPointer);
94 + calloc.free(assetTypePointer);
95 + calloc.free(paymentIdPointer);
96
97 if (amountPointer != nullptr) {
98 - free(amountPointer);
98 + calloc.free(amountPointer);
99 }
100
101 if (!created) {
102 final message = errorMessagePointer.ref.getValue();
103 - free(errorMessagePointer);
103 + calloc.free(errorMessagePointer);
104 throw CreationTransactionException(message: message);
105 }
106
@@ -112,28 +112,28 @@ PendingTransactionDescription createTransactionSync(
112 }
113
114 PendingTransactionDescription createTransactionMultDestSync(
115 - {List<MoneroOutput> outputs,
116 - String assetType,
117 - String paymentId,
118 - int priorityRaw,
115 + {required List<MoneroOutput> outputs,
116 + required String assetType,
117 + required String paymentId,
118 + required int priorityRaw,
119 int accountIndex = 0}) {
120 final int size = outputs.length;
121 final List<Pointer<Utf8>> addressesPointers = outputs.map((output) =>
122 - Utf8.toUtf8(output.address)).toList();
123 - final Pointer<Pointer<Utf8>> addressesPointerPointer = allocate(count: size);
122 + output.address.toNativeUtf8()).toList();
123 + final Pointer<Pointer<Utf8>> addressesPointerPointer = calloc(size);
124 final List<Pointer<Utf8>> amountsPointers = outputs.map((output) =>
125 - Utf8.toUtf8(output.amount)).toList();
126 - final Pointer<Pointer<Utf8>> amountsPointerPointer = allocate(count: size);
125 + output.amount.toNativeUtf8()).toList();
126 + final Pointer<Pointer<Utf8>> amountsPointerPointer = calloc( size);
127
128 for (int i = 0; i < size; i++) {
129 addressesPointerPointer[i] = addressesPointers[i];
130 amountsPointerPointer[i] = amountsPointers[i];
131 }
132
133 - final assetTypePointer = Utf8.toUtf8(assetType);
134 - final paymentIdPointer = Utf8.toUtf8(paymentId);
135 - final errorMessagePointer = allocate<Utf8Box>();
136 - final pendingTransactionRawPointer = allocate<PendingTransactionRaw>();
133 + final assetTypePointer = assetType.toNativeUtf8();
134 + final paymentIdPointer = paymentId.toNativeUtf8();
135 + final errorMessagePointer = calloc<Utf8Box>();
136 + final pendingTransactionRawPointer = calloc<PendingTransactionRaw>();
137 final created = transactionCreateMultDestNative(
138 addressesPointerPointer,
139 assetTypePointer,
@@ -146,18 +146,18 @@ PendingTransactionDescription createTransactionMultDestSync(
146 pendingTransactionRawPointer) !=
147 0;
148
149 - free(addressesPointerPointer);
150 - free(assetTypePointer);
151 - free(amountsPointerPointer);
149 + calloc.free(addressesPointerPointer);
150 + calloc.free(assetTypePointer);
151 + calloc.free(amountsPointerPointer);
152
153 - addressesPointers.forEach((element) => free(element));
154 - amountsPointers.forEach((element) => free(element));
153 + addressesPointers.forEach((element) => calloc.free(element));
154 + amountsPointers.forEach((element) => calloc.free(element));
155
156 - free(paymentIdPointer);
156 + calloc.free(paymentIdPointer);
157
158 if (!created) {
159 final message = errorMessagePointer.ref.getValue();
160 - free(errorMessagePointer);
160 + calloc.free(errorMessagePointer);
161 throw CreationTransactionException(message: message);
162 }
163
@@ -168,17 +168,17 @@ PendingTransactionDescription createTransactionMultDestSync(
168 pointerAddress: pendingTransactionRawPointer.address);
169 }
170
171 -void commitTransactionFromPointerAddress({int address}) => commitTransaction(
171 +void commitTransactionFromPointerAddress({required int address}) => commitTransaction(
172 transactionPointer: Pointer<PendingTransactionRaw>.fromAddress(address));
173
174 -void commitTransaction({Pointer<PendingTransactionRaw> transactionPointer}) {
175 - final errorMessagePointer = allocate<Utf8Box>();
174 +void commitTransaction({required Pointer<PendingTransactionRaw> transactionPointer}) {
175 + final errorMessagePointer = calloc<Utf8Box>();
176 final isCommited =
177 transactionCommitNative(transactionPointer, errorMessagePointer) != 0;
178
179 if (!isCommited) {
180 final message = errorMessagePointer.ref.getValue();
181 - free(errorMessagePointer);
181 + calloc.free(errorMessagePointer);
182 throw CreationTransactionException(message: message);
183 }
184 }
@@ -216,11 +216,11 @@ PendingTransactionDescription _createTransactionMultDestSync(Map args) {
216 }
217
218 Future<PendingTransactionDescription> createTransaction(
219 - {String address,
220 - String assetType,
219 + {required String address,
220 + required String assetType,
221 + required int priorityRaw,
222 + String? amount,
223 String paymentId = '',
222 - String amount,
223 - int priorityRaw,
224 int accountIndex = 0}) =>
225 compute(_createTransactionSync, {
226 'address': address,
@@ -232,10 +232,10 @@ Future<PendingTransactionDescription> createTransaction(
232 });
233
234 Future<PendingTransactionDescription> createTransactionMultDest(
235 - {List<MoneroOutput> outputs,
236 - String assetType,
235 + {required List<MoneroOutput> outputs,
236 + required int priorityRaw,
237 + String? assetType,
238 String paymentId = '',
238 - int priorityRaw,
239 int accountIndex = 0}) =>
240 compute(_createTransactionMultDestSync, {
241 'outputs': outputs,
cw_haven/lib/api/types.dart
+2 -2
@@ -39,7 +39,7 @@ typedef GetNodeHeight = int Function();
39 typedef IsConnected = int Function();
40
41 typedef SetupNode = int Function(
42 - Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, int, int, Pointer<Utf8>);
42 + Pointer<Utf8>, Pointer<Utf8>?, Pointer<Utf8>?, int, int, Pointer<Utf8>);
43
44 typedef StartRefresh = void Function();
45
@@ -84,7 +84,7 @@ typedef AccountSetLabel = void Function(int accountIndex, Pointer<Utf8> label);
84
85 typedef TransactionsRefresh = void Function();
86
87 -typedef GetTxKey = Pointer<Utf8> Function(Pointer<Utf8> txId);
87 +typedef GetTxKey = Pointer<Utf8>? Function(Pointer<Utf8> txId);
88
89 typedef TransactionsCount = int Function();
90
cw_haven/lib/api/wallet.dart
+38 -33
@@ -142,24 +142,24 @@ int getNodeHeightSync() => getNodeHeightNative();
142 bool isConnectedSync() => isConnectedNative() != 0;
143
144 bool setupNodeSync(
145 - {String address,
146 - String login,
147 - String password,
145 + {required String address,
146 + String? login,
147 + String? password,
148 bool useSSL = false,
149 bool isLightWallet = false}) {
150 - final addressPointer = Utf8.toUtf8(address);
151 - Pointer<Utf8> loginPointer;
152 - Pointer<Utf8> passwordPointer;
150 + final addressPointer = address.toNativeUtf8();
151 + Pointer<Utf8>? loginPointer;
152 + Pointer<Utf8>? passwordPointer;
153
154 if (login != null) {
155 - loginPointer = Utf8.toUtf8(login);
155 + loginPointer = login.toNativeUtf8();
156 }
157
158 if (password != null) {
159 - passwordPointer = Utf8.toUtf8(password);
159 + passwordPointer = password.toNativeUtf8();
160 }
161
162 - final errorMessagePointer = allocate<Utf8>();
162 + final errorMessagePointer = ''.toNativeUtf8();
163 final isSetupNode = setupNodeNative(
164 addressPointer,
165 loginPointer,
@@ -169,9 +169,15 @@ bool setupNodeSync(
169 errorMessagePointer) !=
170 0;
171
172 - free(addressPointer);
173 - free(loginPointer);
174 - free(passwordPointer);
172 + calloc.free(addressPointer);
173 +
174 + if (loginPointer != null) {
175 + calloc.free(loginPointer);
176 + }
177 +
178 + if (passwordPointer != null) {
179 + calloc.free(passwordPointer);
180 + }
181
182 if (!isSetupNode) {
183 throw SetupWalletException(
@@ -185,31 +191,31 @@ void startRefreshSync() => startRefreshNative();
191
192 Future<bool> connectToNode() async => connecToNodeNative() != 0;
193
188 -void setRefreshFromBlockHeight({int height}) =>
194 +void setRefreshFromBlockHeight({required int height}) =>
195 setRefreshFromBlockHeightNative(height);
196
191 -void setRecoveringFromSeed({bool isRecovery}) =>
197 +void setRecoveringFromSeed({required bool isRecovery}) =>
198 setRecoveringFromSeedNative(_boolToInt(isRecovery));
199
200 void storeSync() {
195 - final pathPointer = Utf8.toUtf8('');
201 + final pathPointer = ''.toNativeUtf8();
202 storeNative(pathPointer);
197 - free(pathPointer);
203 + calloc.free(pathPointer);
204 }
205
206 void setPasswordSync(String password) {
201 - final passwordPointer = Utf8.toUtf8(password);
202 - final errorMessagePointer = allocate<Utf8Box>();
207 + final passwordPointer = password.toNativeUtf8();
208 + final errorMessagePointer = calloc<Utf8Box>();
209 final changed = setPasswordNative(passwordPointer, errorMessagePointer) != 0;
204 - free(passwordPointer);
210 + calloc.free(passwordPointer);
211
212 if (!changed) {
213 final message = errorMessagePointer.ref.getValue();
208 - free(errorMessagePointer);
214 + calloc.free(errorMessagePointer);
215 throw Exception(message);
216 }
217
212 - free(errorMessagePointer);
218 + calloc.free(errorMessagePointer);
219 }
220
221 void closeCurrentWallet() => closeCurrentWalletNative();
@@ -227,16 +233,15 @@ String getPublicSpendKey() =>
233 convertUTF8ToString(pointer: getPublicSpendKeyNative());
234
235 class SyncListener {
230 - SyncListener(this.onNewBlock, this.onNewTransaction) {
231 - _cachedBlockchainHeight = 0;
232 - _lastKnownBlockHeight = 0;
233 - _initialSyncHeight = 0;
234 - }
236 + SyncListener(this.onNewBlock, this.onNewTransaction)
237 + : _cachedBlockchainHeight = 0,
238 + _lastKnownBlockHeight = 0,
239 + _initialSyncHeight = 0;
240
241 void Function(int, int, double) onNewBlock;
242 void Function() onNewTransaction;
243
239 - Timer _updateSyncInfoTimer;
244 + Timer? _updateSyncInfoTimer;
245 int _cachedBlockchainHeight;
246 int _lastKnownBlockHeight;
247 int _initialSyncHeight;
@@ -325,13 +330,13 @@ int _getNodeHeight(Object _) => getNodeHeightSync();
330
331 void startRefresh() => startRefreshSync();
332
328 -Future setupNode(
329 - {String address,
330 - String login,
331 - String password,
333 +Future<void> setupNode(
334 + {required String address,
335 + String? login,
336 + String? password,
337 bool useSSL = false,
338 bool isLightWallet = false}) =>
334 - compute<Map<String, Object>, void>(_setupNodeSync, {
339 + compute<Map<String, Object?>, void>(_setupNodeSync, {
340 'address': address,
341 'login': login,
342 'password': password,
@@ -339,7 +344,7 @@ Future setupNode(
344 'isLightWallet': isLightWallet
345 });
346
342 -Future store() => compute<int, void>(_storeSync, 0);
347 +Future<void> store() => compute<int, void>(_storeSync, 0);
348
349 Future<bool> isConnected() => compute(_isConnected, 0);
350
cw_haven/lib/api/wallet_manager.dart
+62 -62
@@ -38,18 +38,18 @@ final errorStringNative = havenApi
38 .asFunction<ErrorString>();
39
40 void createWalletSync(
41 - {String path, String password, String language, int nettype = 0}) {
42 - final pathPointer = Utf8.toUtf8(path);
43 - final passwordPointer = Utf8.toUtf8(password);
44 - final languagePointer = Utf8.toUtf8(language);
45 - final errorMessagePointer = allocate<Utf8>();
41 + {required String path, required String password, required String language, int nettype = 0}) {
42 + final pathPointer = path.toNativeUtf8();
43 + final passwordPointer = password.toNativeUtf8();
44 + final languagePointer = language.toNativeUtf8();
45 + final errorMessagePointer = ''.toNativeUtf8();
46 final isWalletCreated = createWalletNative(pathPointer, passwordPointer,
47 languagePointer, nettype, errorMessagePointer) !=
48 0;
49
50 - free(pathPointer);
51 - free(passwordPointer);
52 - free(languagePointer);
50 + calloc.free(pathPointer);
51 + calloc.free(passwordPointer);
52 + calloc.free(languagePointer);
53
54 if (!isWalletCreated) {
55 throw WalletCreationException(
@@ -59,25 +59,25 @@ void createWalletSync(
59 // setupNodeSync(address: "node.moneroworld.com:18089");
60 }
61
62 -bool isWalletExistSync({String path}) {
63 - final pathPointer = Utf8.toUtf8(path);
62 +bool isWalletExistSync({required String path}) {
63 + final pathPointer = path.toNativeUtf8();
64 final isExist = isWalletExistNative(pathPointer) != 0;
65
66 - free(pathPointer);
66 + calloc.free(pathPointer);
67
68 return isExist;
69 }
70
71 void restoreWalletFromSeedSync(
72 - {String path,
73 - String password,
74 - String seed,
72 + {required String path,
73 + required String password,
74 + required String seed,
75 int nettype = 0,
76 int restoreHeight = 0}) {
77 - final pathPointer = Utf8.toUtf8(path);
78 - final passwordPointer = Utf8.toUtf8(password);
79 - final seedPointer = Utf8.toUtf8(seed);
80 - final errorMessagePointer = allocate<Utf8>();
77 + final pathPointer = path.toNativeUtf8();
78 + final passwordPointer = password.toNativeUtf8();
79 + final seedPointer = seed.toNativeUtf8();
80 + final errorMessagePointer = ''.toNativeUtf8();
81 final isWalletRestored = restoreWalletFromSeedNative(
82 pathPointer,
83 passwordPointer,
@@ -87,9 +87,9 @@ void restoreWalletFromSeedSync(
87 errorMessagePointer) !=
88 0;
89
90 - free(pathPointer);
91 - free(passwordPointer);
92 - free(seedPointer);
90 + calloc.free(pathPointer);
91 + calloc.free(passwordPointer);
92 + calloc.free(seedPointer);
93
94 if (!isWalletRestored) {
95 throw WalletRestoreFromSeedException(
@@ -98,21 +98,21 @@ void restoreWalletFromSeedSync(
98 }
99
100 void restoreWalletFromKeysSync(
101 - {String path,
102 - String password,
103 - String language,
104 - String address,
105 - String viewKey,
106 - String spendKey,
101 + {required String path,
102 + required String password,
103 + required String language,
104 + required String address,
105 + required String viewKey,
106 + required String spendKey,
107 int nettype = 0,
108 int restoreHeight = 0}) {
109 - final pathPointer = Utf8.toUtf8(path);
110 - final passwordPointer = Utf8.toUtf8(password);
111 - final languagePointer = Utf8.toUtf8(language);
112 - final addressPointer = Utf8.toUtf8(address);
113 - final viewKeyPointer = Utf8.toUtf8(viewKey);
114 - final spendKeyPointer = Utf8.toUtf8(spendKey);
115 - final errorMessagePointer = allocate<Utf8>();
109 + final pathPointer = path.toNativeUtf8();
110 + final passwordPointer = password.toNativeUtf8();
111 + final languagePointer = language.toNativeUtf8();
112 + final addressPointer = address.toNativeUtf8();
113 + final viewKeyPointer = viewKey.toNativeUtf8();
114 + final spendKeyPointer = spendKey.toNativeUtf8();
115 + final errorMessagePointer = ''.toNativeUtf8();
116 final isWalletRestored = restoreWalletFromKeysNative(
117 pathPointer,
118 passwordPointer,
@@ -125,12 +125,12 @@ void restoreWalletFromKeysSync(
125 errorMessagePointer) !=
126 0;
127
128 - free(pathPointer);
129 - free(passwordPointer);
130 - free(languagePointer);
131 - free(addressPointer);
132 - free(viewKeyPointer);
133 - free(spendKeyPointer);
128 + calloc.free(pathPointer);
129 + calloc.free(passwordPointer);
130 + calloc.free(languagePointer);
131 + calloc.free(addressPointer);
132 + calloc.free(viewKeyPointer);
133 + calloc.free(spendKeyPointer);
134
135 if (!isWalletRestored) {
136 throw WalletRestoreFromKeysException(
@@ -138,12 +138,12 @@ void restoreWalletFromKeysSync(
138 }
139 }
140
141 -void loadWallet({String path, String password, int nettype = 0}) {
142 - final pathPointer = Utf8.toUtf8(path);
143 - final passwordPointer = Utf8.toUtf8(password);
141 +void loadWallet({required String path, required String password, int nettype = 0}) {
142 + final pathPointer = path.toNativeUtf8();
143 + final passwordPointer = password.toNativeUtf8();
144 final loaded = loadWalletNative(pathPointer, passwordPointer, nettype) != 0;
145 - free(pathPointer);
146 - free(passwordPointer);
145 + calloc.free(pathPointer);
146 + calloc.free(passwordPointer);
147
148 if (!loaded) {
149 throw WalletOpeningException(
@@ -189,20 +189,20 @@ void _restoreFromKeys(Map<String, dynamic> args) {
189 }
190
191 Future<void> _openWallet(Map<String, String> args) async =>
192 - loadWallet(path: args['path'], password: args['password']);
192 + loadWallet(path: args['path'] as String, password: args['password'] as String);
193
194 bool _isWalletExist(String path) => isWalletExistSync(path: path);
195
196 -void openWallet({String path, String password, int nettype = 0}) async =>
196 +void openWallet({required String path, required String password, int nettype = 0}) async =>
197 loadWallet(path: path, password: password, nettype: nettype);
198
199 Future<void> openWalletAsync(Map<String, String> args) async =>
200 compute(_openWallet, args);
201
202 Future<void> createWallet(
203 - {String path,
204 - String password,
205 - String language,
203 + {required String path,
204 + required String password,
205 + required String language,
206 int nettype = 0}) async =>
207 compute(_createWallet, {
208 'path': path,
@@ -211,10 +211,10 @@ Future<void> createWallet(
211 'nettype': nettype
212 });
213
214 -Future restoreFromSeed(
215 - {String path,
216 - String password,
217 - String seed,
214 +Future<void> restoreFromSeed(
215 + {required String path,
216 + required String password,
217 + required String seed,
218 int nettype = 0,
219 int restoreHeight = 0}) async =>
220 compute<Map<String, Object>, void>(_restoreFromSeed, {
@@ -225,13 +225,13 @@ Future restoreFromSeed(
225 'restoreHeight': restoreHeight
226 });
227
228 -Future restoreFromKeys(
229 - {String path,
230 - String password,
231 - String language,
232 - String address,
233 - String viewKey,
234 - String spendKey,
228 +Future<void> restoreFromKeys(
229 + {required String path,
230 + required String password,
231 + required String language,
232 + required String address,
233 + required String viewKey,
234 + required String spendKey,
235 int nettype = 0,
236 int restoreHeight = 0}) async =>
237 compute<Map<String, Object>, void>(_restoreFromKeys, {
@@ -245,4 +245,4 @@ Future restoreFromKeys(
245 'restoreHeight': restoreHeight
246 });
247
248 -Future<bool> isWalletExist({String path}) => compute(_isWalletExist, path);
248 +Future<bool> isWalletExist({required String path}) => compute(_isWalletExist, path);
cw_haven/lib/haven_account_list.dart
+2 -2
@@ -53,13 +53,13 @@ abstract class HavenAccountListBase extends AccountList<Account> with Store {
53 .toList();
54
55 @override
56 - Future addAccount({String label}) async {
56 + Future<void> addAccount({required String label}) async {
57 await account_list.addAccount(label: label);
58 update();
59 }
60
61 @override
62 - Future setLabelAccount({int accountIndex, String label}) async {
62 + Future<void> setLabelAccount({required int accountIndex, required String label}) async {
63 await account_list.setLabelForAccount(
64 accountIndex: accountIndex, label: label);
65 update();
cw_haven/lib/haven_balance.dart
+1 -1
@@ -9,7 +9,7 @@ const inactiveBalances = [
9 CryptoCurrency.xnok,
10 CryptoCurrency.xnzd];
11
12 -Map<CryptoCurrency, MoneroBalance> getHavenBalance({int accountIndex}) {
12 +Map<CryptoCurrency, MoneroBalance> getHavenBalance({required int accountIndex}) {
13 final fullBalances = getHavenFullBalance(accountIndex: accountIndex);
14 final unlockedBalances = getHavenUnlockedBalance(accountIndex: accountIndex);
15 final havenBalances = <CryptoCurrency, MoneroBalance>{};
cw_haven/lib/haven_subaddress_list.dart
+8 -9
@@ -10,11 +10,10 @@ class HavenSubaddressList = HavenSubaddressListBase
10 with _$HavenSubaddressList;
11
12 abstract class HavenSubaddressListBase with Store {
13 - HavenSubaddressListBase() {
14 - _isRefreshing = false;
15 - _isUpdating = false;
13 + HavenSubaddressListBase()
14 + : _isRefreshing = false,
15 + _isUpdating = false,
16 subaddresses = ObservableList<Subaddress>();
17 - }
17
18 @observable
19 ObservableList<Subaddress> subaddresses;
@@ -22,7 +21,7 @@ abstract class HavenSubaddressListBase with Store {
21 bool _isRefreshing;
22 bool _isUpdating;
23
25 - void update({int accountIndex}) {
24 + void update({required int accountIndex}) {
25 if (_isUpdating) {
26 return;
27 }
@@ -56,20 +55,20 @@ abstract class HavenSubaddressListBase with Store {
55 .toList();
56 }
57
59 - Future addSubaddress({int accountIndex, String label}) async {
58 + Future<void> addSubaddress({required int accountIndex, required String label}) async {
59 await subaddress_list.addSubaddress(
60 accountIndex: accountIndex, label: label);
61 update(accountIndex: accountIndex);
62 }
63
65 - Future setLabelSubaddress(
66 - {int accountIndex, int addressIndex, String label}) async {
64 + Future<void> setLabelSubaddress(
65 + {required int accountIndex, required int addressIndex, required String label}) async {
66 await subaddress_list.setLabelForSubaddress(
67 accountIndex: accountIndex, addressIndex: addressIndex, label: label);
68 update(accountIndex: accountIndex);
69 }
70
72 - void refresh({int accountIndex}) {
71 + void refresh({required int accountIndex}) {
72 if (_isRefreshing) {
73 return;
74 }
cw_haven/lib/haven_transaction_creation_credentials.dart
+4 -1
@@ -2,7 +2,10 @@ import 'package:cw_core/monero_transaction_priority.dart';
2 import 'package:cw_core/output_info.dart';
3
4 class HavenTransactionCreationCredentials {
5 - HavenTransactionCreationCredentials({this.outputs, this.priority, this.assetType});
5 + HavenTransactionCreationCredentials({
6 + required this.outputs,
7 + required this.priority,
8 + required this.assetType});
9
10 final List<OutputInfo> outputs;
11 final MoneroTransactionPriority priority;
cw_haven/lib/haven_transaction_info.dart
+7 -8
@@ -10,20 +10,20 @@ class HavenTransactionInfo extends TransactionInfo {
10 HavenTransactionInfo(this.id, this.height, this.direction, this.date,
11 this.isPending, this.amount, this.accountIndex, this.addressIndex, this.fee);
12
13 - HavenTransactionInfo.fromMap(Map map)
13 + HavenTransactionInfo.fromMap(Map<String, Object> map)
14 : id = (map['hash'] ?? '') as String,
15 height = (map['height'] ?? 0) as int,
16 direction =
17 parseTransactionDirectionFromNumber(map['direction'] as String) ??
18 TransactionDirection.incoming,
19 date = DateTime.fromMillisecondsSinceEpoch(
20 - (int.parse(map['timestamp'] as String) ?? 0) * 1000),
20 + int.parse(map['timestamp'] as String? ?? '0') * 1000),
21 isPending = parseBoolFromString(map['isPending'] as String),
22 amount = map['amount'] as int,
23 accountIndex = int.parse(map['accountIndex'] as String),
24 addressIndex = map['addressIndex'] as int,
25 key = getTxKey((map['hash'] ?? '') as String),
26 - fee = map['fee'] as int ?? 0;
26 + fee = map['fee'] as int? ?? 0;
27
28 HavenTransactionInfo.fromRow(TransactionInfoRow row)
29 : id = row.getHash(),
@@ -48,11 +48,10 @@ class HavenTransactionInfo extends TransactionInfo {
48 final int amount;
49 final int fee;
50 final int addressIndex;
51 - String recipientAddress;
52 - String key;
53 - String assetType;
54 -
55 - String _fiatAmount;
51 + late String recipientAddress;
52 + late String assetType;
53 + String? _fiatAmount;
54 + String? key;
55
56 @override
57 String amountFormatted() =>
cw_haven/lib/haven_wallet.dart
+30 -26
@@ -37,15 +37,19 @@ class HavenWallet = HavenWalletBase with _$HavenWallet;
37
38 abstract class HavenWalletBase extends WalletBase<MoneroBalance,
39 HavenTransactionHistory, HavenTransactionInfo> with Store {
40 - HavenWalletBase({WalletInfo walletInfo})
41 - : super(walletInfo) {
40 + HavenWalletBase({required WalletInfo walletInfo})
41 + : balance = ObservableMap.of(getHavenBalance(accountIndex: 0)),
42 + _isTransactionUpdating = false,
43 + _hasSyncAfterStartup = false,
44 + walletAddresses = HavenWalletAddresses(walletInfo),
45 + syncStatus = NotConnectedSyncStatus(),
46 + super(walletInfo) {
47 transactionHistory = HavenTransactionHistory();
43 - balance = ObservableMap.of(getHavenBalance(accountIndex: 0));
44 - _isTransactionUpdating = false;
45 - _hasSyncAfterStartup = false;
46 - walletAddresses = HavenWalletAddresses(walletInfo);
48 _onAccountChangeReaction = reaction((_) => walletAddresses.account,
48 - (Account account) {
49 + (Account? account) {
50 + if (account == null) {
51 + return;
52 + }
53 balance.addAll(getHavenBalance(accountIndex: account.id));
54 walletAddresses.updateSubaddressList(accountIndex: account.id);
55 });
@@ -74,15 +78,15 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
78 publicSpendKey: haven_wallet.getPublicSpendKey(),
79 publicViewKey: haven_wallet.getPublicViewKey());
80
77 - haven_wallet.SyncListener _listener;
78 - ReactionDisposer _onAccountChangeReaction;
81 + haven_wallet.SyncListener? _listener;
82 + ReactionDisposer? _onAccountChangeReaction;
83 bool _isTransactionUpdating;
84 bool _hasSyncAfterStartup;
81 - Timer _autoSaveTimer;
85 + Timer? _autoSaveTimer;
86
87 Future<void> init() async {
88 await walletAddresses.init();
85 - balance.addAll(getHavenBalance(accountIndex: walletAddresses.account.id ?? 0));
89 + balance.addAll(getHavenBalance(accountIndex: walletAddresses.account?.id ?? 0));
90 _setListeners();
91 await updateTransactions();
92
@@ -103,19 +107,19 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
107 @override
108 void close() {
109 _listener?.stop();
106 - _onAccountChangeReaction?.reaction?.dispose();
110 + _onAccountChangeReaction?.reaction.dispose();
111 _autoSaveTimer?.cancel();
112 }
113
114 @override
111 - Future<void> connectToNode({@required Node node}) async {
115 + Future<void> connectToNode({required Node node}) async {
116 try {
117 syncStatus = ConnectingSyncStatus();
118 await haven_wallet.setupNode(
119 address: node.uriRaw,
120 login: node.login,
121 password: node.password,
118 - useSSL: node.useSSL,
122 + useSSL: node.useSSL ?? false,
123 isLightWallet: false); // FIXME: hardcoded value
124 syncStatus = ConnectedSyncStatus();
125 } catch (e) {
@@ -148,8 +152,8 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
152 final outputs = _credentials.outputs;
153 final hasMultiDestination = outputs.length > 1;
154 final assetType = CryptoCurrency.fromString(_credentials.assetType.toLowerCase());
151 - final balances = getHavenBalance(accountIndex: walletAddresses.account.id);
152 - final unlockedBalance = balances[assetType].unlockedBalance;
155 + final balances = getHavenBalance(accountIndex: walletAddresses.account!.id);
156 + final unlockedBalance = balances[assetType]!.unlockedBalance;
157
158 PendingTransactionDescription pendingTransactionDescription;
159
@@ -159,12 +163,12 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
163
164 if (hasMultiDestination) {
165 if (outputs.any((item) => item.sendAll
162 - || item.formattedCryptoAmount <= 0)) {
166 + || (item.formattedCryptoAmount ?? 0) <= 0)) {
167 throw HavenTransactionCreationException('Wrong balance. Not enough XMR on your balance.');
168 }
169
170 final int totalAmount = outputs.fold(0, (acc, value) =>
167 - acc + value.formattedCryptoAmount);
171 + acc + (value.formattedCryptoAmount ?? 0));
172
173 if (unlockedBalance < totalAmount) {
174 throw HavenTransactionCreationException('Wrong balance. Not enough XMR on your balance.');
@@ -173,21 +177,21 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
177 final moneroOutputs = outputs.map((output) =>
178 MoneroOutput(
179 address: output.address,
176 - amount: output.cryptoAmount.replaceAll(',', '.')))
180 + amount: output.cryptoAmount!.replaceAll(',', '.')))
181 .toList();
182
183 pendingTransactionDescription =
184 await transaction_history.createTransactionMultDest(
185 outputs: moneroOutputs,
186 priorityRaw: _credentials.priority.serialize(),
183 - accountIndex: walletAddresses.account.id);
187 + accountIndex: walletAddresses.account!.id);
188 } else {
189 final output = outputs.first;
190 final address = output.address;
191 final amount = output.sendAll
192 ? null
189 - : output.cryptoAmount.replaceAll(',', '.');
190 - final formattedAmount = output.sendAll
193 + : output.cryptoAmount!.replaceAll(',', '.');
194 + final int? formattedAmount = output.sendAll
195 ? null
196 : output.formattedCryptoAmount;
197
@@ -205,14 +209,14 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
209 assetType: _credentials.assetType,
210 amount: amount,
211 priorityRaw: _credentials.priority.serialize(),
208 - accountIndex: walletAddresses.account.id);
212 + accountIndex: walletAddresses.account!.id);
213 }
214
215 return PendingHavenTransaction(pendingTransactionDescription, assetType);
216 }
217
218 @override
215 - int calculateEstimatedFee(TransactionPriority priority, int amount) {
219 + int calculateEstimatedFee(TransactionPriority priority, int? amount) {
220 // FIXME: hardcoded value;
221
222 if (priority is MoneroTransactionPriority) {
@@ -255,7 +259,7 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
259 }
260
261 @override
258 - Future<void> rescan({int height}) async {
262 + Future<void> rescan({required int height}) async {
263 walletInfo.restoreHeight = height;
264 walletInfo.isRecovery = true;
265 haven_wallet.setRefreshFromBlockHeight(height: height);
@@ -346,7 +350,7 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
350 }
351
352 void _askForUpdateBalance() =>
349 - balance.addAll(getHavenBalance(accountIndex: walletAddresses.account.id));
353 + balance.addAll(getHavenBalance(accountIndex: walletAddresses.account!.id));
354
355 Future<void> _askForUpdateTransactionHistory() async =>
356 await updateTransactions();
cw_haven/lib/haven_wallet_addresses.dart
+13 -12
@@ -12,21 +12,22 @@ class HavenWalletAddresses = HavenWalletAddressesBase
12 with _$HavenWalletAddresses;
13
14 abstract class HavenWalletAddressesBase extends WalletAddressesWithAccount<Account> with Store {
15 - HavenWalletAddressesBase(WalletInfo walletInfo) : super(walletInfo) {
16 - accountList = HavenAccountList();
17 - subaddressList = HavenSubaddressList();
18 - }
15 + HavenWalletAddressesBase(WalletInfo walletInfo)
16 + : accountList = HavenAccountList(),
17 + subaddressList = HavenSubaddressList(),
18 + address = '',
19 + super(walletInfo);
20
21 @override
22 @observable
23 String address;
24
24 - @override
25 + // @override
26 @observable
26 - Account account;
27 + Account? account;
28
29 @observable
29 - Subaddress subaddress;
30 + Subaddress? subaddress;
31
32 HavenSubaddressList subaddressList;
33
@@ -36,7 +37,7 @@ abstract class HavenWalletAddressesBase extends WalletAddressesWithAccount<Accou
37 Future<void> init() async {
38 accountList.update();
39 account = accountList.accounts.first;
39 - updateSubaddressList(accountIndex: account.id ?? 0);
40 + updateSubaddressList(accountIndex: account?.id ?? 0);
41 await updateAddressesInBox();
42 }
43
@@ -62,14 +63,14 @@ abstract class HavenWalletAddressesBase extends WalletAddressesWithAccount<Accou
63
64 bool validate() {
65 accountList.update();
65 - final accountListLength = accountList.accounts?.length ?? 0;
66 + final accountListLength = accountList.accounts.length ?? 0;
67
68 if (accountListLength <= 0) {
69 return false;
70 }
71
72 subaddressList.update(accountIndex: accountList.accounts.first.id);
72 - final subaddressListLength = subaddressList.subaddresses?.length ?? 0;
73 + final subaddressListLength = subaddressList.subaddresses.length ?? 0;
74
75 if (subaddressListLength <= 0) {
76 return false;
@@ -78,9 +79,9 @@ abstract class HavenWalletAddressesBase extends WalletAddressesWithAccount<Accou
79 return true;
80 }
81
81 - void updateSubaddressList({int accountIndex}) {
82 + void updateSubaddressList({required int accountIndex}) {
83 subaddressList.update(accountIndex: accountIndex);
84 subaddress = subaddressList.subaddresses.first;
84 - address = subaddress.address;
85 + address = subaddress!.address;
86 }
87 }
\ No newline at end of file
cw_haven/lib/haven_wallet_service.dart
+23 -20
@@ -1,4 +1,5 @@
1 import 'dart:io';
2 +import 'package:collection/collection.dart';
3 import 'package:cw_core/wallet_base.dart';
4 import 'package:cw_core/monero_wallet_utils.dart';
5 import 'package:hive/hive.dart';
@@ -13,7 +14,7 @@ import 'package:cw_core/wallet_info.dart';
14 import 'package:cw_core/wallet_type.dart';
15
16 class HavenNewWalletCredentials extends WalletCredentials {
16 - HavenNewWalletCredentials({String name, String password, this.language})
17 + HavenNewWalletCredentials({required String name, required this.language, String? password})
18 : super(name: name, password: password);
19
20 final String language;
@@ -21,7 +22,10 @@ class HavenNewWalletCredentials extends WalletCredentials {
22
23 class HavenRestoreWalletFromSeedCredentials extends WalletCredentials {
24 HavenRestoreWalletFromSeedCredentials(
24 - {String name, String password, int height, this.mnemonic})
25 + {required String name,
26 + required String password,
27 + required int height,
28 + required this.mnemonic})
29 : super(name: name, password: password, height: height);
30
31 final String mnemonic;
@@ -34,13 +38,13 @@ class HavenWalletLoadingException implements Exception {
38
39 class HavenRestoreWalletFromKeysCredentials extends WalletCredentials {
40 HavenRestoreWalletFromKeysCredentials(
37 - {String name,
38 - String password,
39 - this.language,
40 - this.address,
41 - this.viewKey,
42 - this.spendKey,
43 - int height})
41 + {required String name,
42 + required String password,
43 + required this.language,
44 + required this.address,
45 + required this.viewKey,
46 + required this.spendKey,
47 + required int height})
48 : super(name: name, password: password, height: height);
49
50 final String language;
@@ -69,9 +73,9 @@ class HavenWalletService extends WalletService<
73 final path = await pathForWallet(name: credentials.name, type: getType());
74 await haven_wallet_manager.createWallet(
75 path: path,
72 - password: credentials.password,
76 + password: credentials.password!,
77 language: credentials.language);
74 - final wallet = HavenWallet(walletInfo: credentials.walletInfo);
78 + final wallet = HavenWallet(walletInfo: credentials.walletInfo!);
79 await wallet.init();
80 return wallet;
81 } catch (e) {
@@ -104,9 +108,8 @@ class HavenWalletService extends WalletService<
108
109 await haven_wallet_manager
110 .openWalletAsync({'path': path, 'password': password});
107 - final walletInfo = walletInfoSource.values.firstWhere(
108 - (info) => info.id == WalletBase.idFor(name, getType()),
109 - orElse: () => null);
111 + final walletInfo = walletInfoSource.values.firstWhereOrNull(
112 + (info) => info.id == WalletBase.idFor(name, getType()))!;
113 final wallet = HavenWallet(walletInfo: walletInfo);
114 final isValid = wallet.walletAddresses.validate();
115
@@ -155,13 +158,13 @@ class HavenWalletService extends WalletService<
158 final path = await pathForWallet(name: credentials.name, type: getType());
159 await haven_wallet_manager.restoreFromKeys(
160 path: path,
158 - password: credentials.password,
161 + password: credentials.password!,
162 language: credentials.language,
160 - restoreHeight: credentials.height,
163 + restoreHeight: credentials.height!,
164 address: credentials.address,
165 viewKey: credentials.viewKey,
166 spendKey: credentials.spendKey);
164 - final wallet = HavenWallet(walletInfo: credentials.walletInfo);
167 + final wallet = HavenWallet(walletInfo: credentials.walletInfo!);
168 await wallet.init();
169
170 return wallet;
@@ -179,10 +182,10 @@ class HavenWalletService extends WalletService<
182 final path = await pathForWallet(name: credentials.name, type: getType());
183 await haven_wallet_manager.restoreFromSeed(
184 path: path,
182 - password: credentials.password,
185 + password: credentials.password!,
186 seed: credentials.mnemonic,
184 - restoreHeight: credentials.height);
185 - final wallet = HavenWallet(walletInfo: credentials.walletInfo);
187 + restoreHeight: credentials.height!);
188 + final wallet = HavenWallet(walletInfo: credentials.walletInfo!);
189 await wallet.init();
190
191 return wallet;
cw_haven/lib/pending_haven_transaction.dart
+9 -5
@@ -2,7 +2,7 @@ import 'package:cw_haven/api/structs/pending_transaction.dart';
2 import 'package:cw_haven/api/transaction_history.dart'
3 as haven_transaction_history;
4 import 'package:cw_core/crypto_currency.dart';
5 -import 'package:cake_wallet/core/amount_converter.dart';
5 +// import 'package:cake_wallet/core/amount_converter.dart';
6 import 'package:cw_core/pending_transaction.dart';
7
8 class DoubleSpendException implements Exception {
@@ -25,13 +25,17 @@ class PendingHavenTransaction with PendingTransaction {
25 @override
26 String get hex => '';
27
28 + // FIX-ME: AmountConverter
29 @override
29 - String get amountFormatted => AmountConverter.amountIntToString(
30 - cryptoCurrency, pendingTransactionDescription.amount);
30 + String get amountFormatted => '';
31 + // AmountConverter.amountIntToString(
32 + // cryptoCurrency, pendingTransactionDescription.amount);
33
34 + // FIX-ME: AmountConverter
35 @override
33 - String get feeFormatted => AmountConverter.amountIntToString(
34 - cryptoCurrency, pendingTransactionDescription.fee);
36 + String get feeFormatted => '';
37 + // AmountConverter.amountIntToString(
38 + // cryptoCurrency, pendingTransactionDescription.fee);
39
40 @override
41 Future<void> commit() async {
cw_haven/lib/update_haven_rate.dart
+1 -1
@@ -1,7 +1,7 @@
1 //import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
2 import 'package:cw_core/crypto_currency.dart';
3 import 'package:cw_core/monero_amount_format.dart';
4 -import 'package:cw_haven/balance_list.dart';
4 +import 'package:cw_haven/api/balance_list.dart';
5
6 //Future<void> updateHavenRate(FiatConversionStore fiatConversionStore) async {
7 // final rate = getRate();
cw_haven/pubspec.lock
+94 -87
@@ -7,35 +7,35 @@ packages:
7 name: _fe_analyzer_shared
8 url: "https://pub.dartlang.org"
9 source: hosted
10 - version: "14.0.0"
10 + version: "47.0.0"
11 analyzer:
12 dependency: transitive
13 description:
14 name: analyzer
15 url: "https://pub.dartlang.org"
16 source: hosted
17 - version: "0.41.2"
17 + version: "4.7.0"
18 args:
19 dependency: transitive
20 description:
21 name: args
22 url: "https://pub.dartlang.org"
23 source: hosted
24 - version: "1.6.0"
24 + version: "2.3.1"
25 asn1lib:
26 dependency: transitive
27 description:
28 name: asn1lib
29 url: "https://pub.dartlang.org"
30 source: hosted
31 - version: "0.8.1"
31 + version: "1.1.1"
32 async:
33 dependency: transitive
34 description:
35 name: async
36 url: "https://pub.dartlang.org"
37 source: hosted
38 - version: "2.5.0"
38 + version: "2.9.0"
39 boolean_selector:
40 dependency: transitive
41 description:
@@ -49,42 +49,42 @@ packages:
49 name: build
50 url: "https://pub.dartlang.org"
51 source: hosted
52 - version: "1.6.2"
52 + version: "2.3.1"
53 build_config:
54 dependency: transitive
55 description:
56 name: build_config
57 url: "https://pub.dartlang.org"
58 source: hosted
59 - version: "0.4.6"
59 + version: "1.1.0"
60 build_daemon:
61 dependency: transitive
62 description:
63 name: build_daemon
64 url: "https://pub.dartlang.org"
65 source: hosted
66 - version: "2.1.10"
66 + version: "3.1.0"
67 build_resolvers:
68 dependency: "direct dev"
69 description:
70 name: build_resolvers
71 url: "https://pub.dartlang.org"
72 source: hosted
73 - version: "1.5.3"
73 + version: "2.0.10"
74 build_runner:
75 dependency: "direct dev"
76 description:
77 name: build_runner
78 url: "https://pub.dartlang.org"
79 source: hosted
80 - version: "1.11.5"
80 + version: "2.2.1"
81 build_runner_core:
82 dependency: transitive
83 description:
84 name: build_runner_core
85 url: "https://pub.dartlang.org"
86 source: hosted
87 - version: "6.1.10"
87 + version: "7.2.4"
88 built_collection:
89 dependency: transitive
90 description:
@@ -105,63 +105,49 @@ packages:
105 name: characters
106 url: "https://pub.dartlang.org"
107 source: hosted
108 - version: "1.1.0"
109 - charcode:
110 - dependency: transitive
111 - description:
112 - name: charcode
113 - url: "https://pub.dartlang.org"
114 - source: hosted
115 - version: "1.2.0"
108 + version: "1.2.1"
109 checked_yaml:
110 dependency: transitive
111 description:
112 name: checked_yaml
113 url: "https://pub.dartlang.org"
114 source: hosted
122 - version: "1.0.4"
123 - cli_util:
124 - dependency: transitive
125 - description:
126 - name: cli_util
127 - url: "https://pub.dartlang.org"
128 - source: hosted
129 - version: "0.3.5"
115 + version: "2.0.1"
116 clock:
117 dependency: transitive
118 description:
119 name: clock
120 url: "https://pub.dartlang.org"
121 source: hosted
136 - version: "1.1.0"
122 + version: "1.1.1"
123 code_builder:
124 dependency: transitive
125 description:
126 name: code_builder
127 url: "https://pub.dartlang.org"
128 source: hosted
143 - version: "3.7.0"
129 + version: "4.3.0"
130 collection:
131 dependency: transitive
132 description:
133 name: collection
134 url: "https://pub.dartlang.org"
135 source: hosted
150 - version: "1.15.0"
136 + version: "1.16.0"
137 convert:
138 dependency: transitive
139 description:
140 name: convert
141 url: "https://pub.dartlang.org"
142 source: hosted
157 - version: "2.1.1"
143 + version: "3.0.2"
144 crypto:
145 dependency: transitive
146 description:
147 name: crypto
148 url: "https://pub.dartlang.org"
149 source: hosted
164 - version: "2.1.5"
150 + version: "3.0.2"
151 cw_core:
152 dependency: "direct main"
153 description:
@@ -175,35 +161,28 @@ packages:
161 name: dart_style
162 url: "https://pub.dartlang.org"
163 source: hosted
178 - version: "1.3.12"
179 - dartx:
180 - dependency: transitive
181 - description:
182 - name: dartx
183 - url: "https://pub.dartlang.org"
184 - source: hosted
185 - version: "0.5.0"
164 + version: "2.2.4"
165 encrypt:
166 dependency: transitive
167 description:
168 name: encrypt
169 url: "https://pub.dartlang.org"
170 source: hosted
192 - version: "4.1.0"
171 + version: "5.0.1"
172 fake_async:
173 dependency: transitive
174 description:
175 name: fake_async
176 url: "https://pub.dartlang.org"
177 source: hosted
199 - version: "1.2.0"
178 + version: "1.3.1"
179 ffi:
180 dependency: "direct main"
181 description:
182 name: ffi
183 url: "https://pub.dartlang.org"
184 source: hosted
206 - version: "0.1.3"
185 + version: "1.2.1"
186 file:
187 dependency: transitive
188 description:
@@ -229,12 +208,19 @@ packages:
208 name: flutter_mobx
209 url: "https://pub.dartlang.org"
210 source: hosted
232 - version: "1.1.0+2"
211 + version: "2.0.6+4"
212 flutter_test:
213 dependency: "direct dev"
214 description: flutter
215 source: sdk
216 version: "0.0.0"
217 + frontend_server_client:
218 + dependency: transitive
219 + description:
220 + name: frontend_server_client
221 + url: "https://pub.dartlang.org"
222 + source: hosted
223 + version: "2.1.3"
224 glob:
225 dependency: transitive
226 description:
@@ -248,42 +234,42 @@ packages:
234 name: graphs
235 url: "https://pub.dartlang.org"
236 source: hosted
251 - version: "0.2.0"
237 + version: "2.1.0"
238 hive:
239 dependency: transitive
240 description:
241 name: hive
242 url: "https://pub.dartlang.org"
243 source: hosted
258 - version: "1.4.4+1"
244 + version: "2.2.3"
245 hive_generator:
246 dependency: "direct dev"
247 description:
248 name: hive_generator
249 url: "https://pub.dartlang.org"
250 source: hosted
265 - version: "0.8.2"
251 + version: "1.1.3"
252 http:
253 dependency: "direct main"
254 description:
255 name: http
256 url: "https://pub.dartlang.org"
257 source: hosted
272 - version: "0.12.2"
258 + version: "0.13.5"
259 http_multi_server:
260 dependency: transitive
261 description:
262 name: http_multi_server
263 url: "https://pub.dartlang.org"
264 source: hosted
279 - version: "2.2.0"
265 + version: "3.2.1"
266 http_parser:
267 dependency: transitive
268 description:
269 name: http_parser
270 url: "https://pub.dartlang.org"
271 source: hosted
286 - version: "3.1.4"
272 + version: "4.0.1"
273 intl:
274 dependency: "direct main"
275 description:
@@ -297,7 +283,7 @@ packages:
283 name: io
284 url: "https://pub.dartlang.org"
285 source: hosted
300 - version: "0.3.5"
286 + version: "1.0.3"
287 js:
288 dependency: transitive
289 description:
@@ -311,7 +297,7 @@ packages:
297 name: json_annotation
298 url: "https://pub.dartlang.org"
299 source: hosted
314 - version: "4.0.1"
300 + version: "4.6.0"
301 logging:
302 dependency: transitive
303 description:
@@ -325,14 +311,21 @@ packages:
311 name: matcher
312 url: "https://pub.dartlang.org"
313 source: hosted
328 - version: "0.12.10"
314 + version: "0.12.12"
315 + material_color_utilities:
316 + dependency: transitive
317 + description:
318 + name: material_color_utilities
319 + url: "https://pub.dartlang.org"
320 + source: hosted
321 + version: "0.1.5"
322 meta:
323 dependency: transitive
324 description:
325 name: meta
326 url: "https://pub.dartlang.org"
327 source: hosted
335 - version: "1.3.0"
328 + version: "1.8.0"
329 mime:
330 dependency: transitive
331 description:
@@ -346,63 +339,77 @@ packages:
339 name: mobx
340 url: "https://pub.dartlang.org"
341 source: hosted
349 - version: "1.2.1+4"
342 + version: "2.1.0"
343 mobx_codegen:
344 dependency: "direct dev"
345 description:
346 name: mobx_codegen
347 url: "https://pub.dartlang.org"
348 source: hosted
356 - version: "1.1.2"
349 + version: "2.0.7+3"
350 package_config:
351 dependency: transitive
352 description:
353 name: package_config
354 url: "https://pub.dartlang.org"
355 source: hosted
363 - version: "1.9.3"
356 + version: "2.1.0"
357 path:
358 dependency: transitive
359 description:
360 name: path
361 url: "https://pub.dartlang.org"
362 source: hosted
370 - version: "1.8.0"
363 + version: "1.8.2"
364 path_provider:
365 dependency: "direct main"
366 description:
367 name: path_provider
368 url: "https://pub.dartlang.org"
369 source: hosted
377 - version: "1.6.28"
370 + version: "2.0.11"
371 + path_provider_android:
372 + dependency: transitive
373 + description:
374 + name: path_provider_android
375 + url: "https://pub.dartlang.org"
376 + source: hosted
377 + version: "2.0.20"
378 + path_provider_ios:
379 + dependency: transitive
380 + description:
381 + name: path_provider_ios
382 + url: "https://pub.dartlang.org"
383 + source: hosted
384 + version: "2.0.11"
385 path_provider_linux:
386 dependency: transitive
387 description:
388 name: path_provider_linux
389 url: "https://pub.dartlang.org"
390 source: hosted
384 - version: "0.0.1+2"
391 + version: "2.1.7"
392 path_provider_macos:
393 dependency: transitive
394 description:
395 name: path_provider_macos
396 url: "https://pub.dartlang.org"
397 source: hosted
391 - version: "0.0.4+8"
398 + version: "2.0.6"
399 path_provider_platform_interface:
400 dependency: transitive
401 description:
402 name: path_provider_platform_interface
403 url: "https://pub.dartlang.org"
404 source: hosted
398 - version: "1.0.4"
405 + version: "2.0.4"
406 path_provider_windows:
407 dependency: transitive
408 description:
409 name: path_provider_windows
410 url: "https://pub.dartlang.org"
411 source: hosted
405 - version: "0.0.4+3"
412 + version: "2.0.7"
413 pedantic:
414 dependency: transitive
415 description:
@@ -423,14 +430,14 @@ packages:
430 name: plugin_platform_interface
431 url: "https://pub.dartlang.org"
432 source: hosted
426 - version: "1.0.3"
433 + version: "2.1.3"
434 pointycastle:
435 dependency: transitive
436 description:
437 name: pointycastle
438 url: "https://pub.dartlang.org"
439 source: hosted
433 - version: "2.0.1"
440 + version: "3.6.2"
441 pool:
442 dependency: transitive
443 description:
@@ -458,21 +465,21 @@ packages:
465 name: pubspec_parse
466 url: "https://pub.dartlang.org"
467 source: hosted
461 - version: "0.1.8"
468 + version: "1.2.1"
469 shelf:
470 dependency: transitive
471 description:
472 name: shelf
473 url: "https://pub.dartlang.org"
474 source: hosted
468 - version: "0.7.9"
475 + version: "1.3.2"
476 shelf_web_socket:
477 dependency: transitive
478 description:
479 name: shelf_web_socket
480 url: "https://pub.dartlang.org"
481 source: hosted
475 - version: "0.2.4+1"
482 + version: "1.0.2"
483 sky_engine:
484 dependency: transitive
485 description: flutter
@@ -484,14 +491,21 @@ packages:
491 name: source_gen
492 url: "https://pub.dartlang.org"
493 source: hosted
487 - version: "0.9.10+3"
494 + version: "1.2.3"
495 + source_helper:
496 + dependency: transitive
497 + description:
498 + name: source_helper
499 + url: "https://pub.dartlang.org"
500 + source: hosted
501 + version: "1.3.3"
502 source_span:
503 dependency: transitive
504 description:
505 name: source_span
506 url: "https://pub.dartlang.org"
507 source: hosted
494 - version: "1.8.0"
508 + version: "1.9.0"
509 stack_trace:
510 dependency: transitive
511 description:
@@ -519,35 +533,28 @@ packages:
533 name: string_scanner
534 url: "https://pub.dartlang.org"
535 source: hosted
522 - version: "1.1.0"
536 + version: "1.1.1"
537 term_glyph:
538 dependency: transitive
539 description:
540 name: term_glyph
541 url: "https://pub.dartlang.org"
542 source: hosted
529 - version: "1.2.0"
543 + version: "1.2.1"
544 test_api:
545 dependency: transitive
546 description:
547 name: test_api
548 url: "https://pub.dartlang.org"
549 source: hosted
536 - version: "0.2.19"
537 - time:
538 - dependency: transitive
539 - description:
540 - name: time
541 - url: "https://pub.dartlang.org"
542 - source: hosted
543 - version: "1.4.1"
550 + version: "0.4.12"
551 timing:
552 dependency: transitive
553 description:
554 name: timing
555 url: "https://pub.dartlang.org"
556 source: hosted
550 - version: "0.1.1+3"
557 + version: "1.0.0"
558 typed_data:
559 dependency: transitive
560 description:
@@ -561,7 +568,7 @@ packages:
568 name: vector_math
569 url: "https://pub.dartlang.org"
570 source: hosted
564 - version: "2.1.0"
571 + version: "2.1.2"
572 watcher:
573 dependency: transitive
574 description:
@@ -575,21 +582,21 @@ packages:
582 name: web_socket_channel
583 url: "https://pub.dartlang.org"
584 source: hosted
578 - version: "1.2.0"
585 + version: "2.2.0"
586 win32:
587 dependency: transitive
588 description:
589 name: win32
590 url: "https://pub.dartlang.org"
591 source: hosted
585 - version: "1.7.4+1"
592 + version: "2.6.1"
593 xdg_directories:
594 dependency: transitive
595 description:
596 name: xdg_directories
597 url: "https://pub.dartlang.org"
598 source: hosted
592 - version: "0.1.2"
599 + version: "0.2.0+2"
600 yaml:
601 dependency: transitive
602 description:
@@ -598,5 +605,5 @@ packages:
605 source: hosted
606 version: "3.1.0"
607 sdks:
601 - dart: ">=2.12.0 <3.0.0"
602 - flutter: ">=1.20.0"
608 + dart: ">=2.17.5 <3.0.0"
609 + flutter: ">=2.8.1"
cw_haven/pubspec.yaml
+10 -10
@@ -6,17 +6,17 @@ author: Cake Wallet
6 homepage: https://cakewallet.com
7
8 environment:
9 - sdk: ">=2.7.0 <3.0.0"
9 + sdk: ">=2.17.5 <3.0.0"
10 flutter: ">=1.20.0"
11
12 dependencies:
13 flutter:
14 sdk: flutter
15 - ffi: ^0.1.3
16 - path_provider: ^1.4.0
17 - http: ^0.12.0+2
18 - mobx: ^1.2.1+2
19 - flutter_mobx: ^1.1.0+2
15 + ffi: ^1.1.2
16 + http: ^0.13.4
17 + path_provider: ^2.0.11
18 + mobx: ^2.0.7+4
19 + flutter_mobx: ^2.0.6+1
20 intl: ^0.17.0
21 cw_core:
22 path: ../cw_core
@@ -24,10 +24,10 @@ dependencies:
24 dev_dependencies:
25 flutter_test:
26 sdk: flutter
27 - build_runner: ^1.10.3
28 - build_resolvers: ^1.3.10
29 - mobx_codegen: ^1.1.0+1
30 - hive_generator: ^0.8.1
27 + build_runner: ^2.1.11
28 + mobx_codegen: ^2.0.7
29 + build_resolvers: ^2.0.9
30 + hive_generator: ^1.1.3
31
32 # For information on the generic Dart part of this file, see the
33 # following page: https://dart.dev/tools/pub/pubspec
cw_monero/lib/api/account_list.dart
+8 -8
@@ -50,16 +50,16 @@ List<AccountRow> getAllAccount() {
50 .toList();
51 }
52
53 -void addAccountSync({String label}) {
54 - final labelPointer = Utf8.toUtf8(label);
53 +void addAccountSync({required String label}) {
54 + final labelPointer = label.toNativeUtf8();
55 accountAddNewNative(labelPointer);
56 - free(labelPointer);
56 + calloc.free(labelPointer);
57 }
58
59 -void setLabelForAccountSync({int accountIndex, String label}) {
60 - final labelPointer = Utf8.toUtf8(label);
59 +void setLabelForAccountSync({required int accountIndex, required String label}) {
60 + final labelPointer = label.toNativeUtf8();
61 accountSetLabelNative(accountIndex, labelPointer);
62 - free(labelPointer);
62 + calloc.free(labelPointer);
63 }
64
65 void _addAccount(String label) => addAccountSync(label: label);
@@ -71,12 +71,12 @@ void _setLabelForAccount(Map<String, dynamic> args) {
71 setLabelForAccountSync(label: label, accountIndex: accountIndex);
72 }
73
74 -Future<void> addAccount({String label}) async {
74 +Future<void> addAccount({required String label}) async {
75 await compute(_addAccount, label);
76 await store();
77 }
78
79 -Future<void> setLabelForAccount({int accountIndex, String label}) async {
79 +Future<void> setLabelForAccount({required int accountIndex, required String label}) async {
80 await compute(
81 _setLabelForAccount, {'accountIndex': accountIndex, 'label': label});
82 await store();
cw_monero/lib/api/convert_utf8_to_string.dart
+3 -3
@@ -1,8 +1,8 @@
1 import 'dart:ffi';
2 import 'package:ffi/ffi.dart';
3
4 -String convertUTF8ToString({Pointer<Utf8> pointer}) {
5 - final str = Utf8.fromUtf8(pointer);
6 - free(pointer);
4 +String convertUTF8ToString({required Pointer<Utf8> pointer}) {
5 + final str = pointer.toDartString();
6 + calloc.free(pointer);
7 return str;
8 }
\ No newline at end of file
cw_monero/lib/api/exceptions/connection_to_node_exception.dart
+1 -1
@@ -1,5 +1,5 @@
1 class ConnectionToNodeException implements Exception {
2 - ConnectionToNodeException({this.message});
2 + ConnectionToNodeException({required this.message});
3
4 final String message;
5 }
\ No newline at end of file
cw_monero/lib/api/exceptions/creation_transaction_exception.dart
+1 -1
@@ -1,5 +1,5 @@
1 class CreationTransactionException implements Exception {
2 - CreationTransactionException({this.message});
2 + CreationTransactionException({required this.message});
3
4 final String message;
5
cw_monero/lib/api/exceptions/setup_wallet_exception.dart
+1 -1
@@ -1,5 +1,5 @@
1 class SetupWalletException implements Exception {
2 - SetupWalletException({this.message});
2 + SetupWalletException({required this.message});
3
4 final String message;
5 }
\ No newline at end of file
cw_monero/lib/api/exceptions/wallet_creation_exception.dart
+1 -1
@@ -1,5 +1,5 @@
1 class WalletCreationException implements Exception {
2 - WalletCreationException({this.message});
2 + WalletCreationException({required this.message});
3
4 final String message;
5
cw_monero/lib/api/exceptions/wallet_opening_exception.dart
+1 -1
@@ -1,5 +1,5 @@
1 class WalletOpeningException implements Exception {
2 - WalletOpeningException({this.message});
2 + WalletOpeningException({required this.message});
3
4 final String message;
5
cw_monero/lib/api/exceptions/wallet_restore_from_keys_exception.dart
+1 -1
@@ -1,5 +1,5 @@
1 class WalletRestoreFromKeysException implements Exception {
2 - WalletRestoreFromKeysException({this.message});
2 + WalletRestoreFromKeysException({required this.message});
3
4 final String message;
5 }
\ No newline at end of file
cw_monero/lib/api/exceptions/wallet_restore_from_seed_exception.dart
+1 -1
@@ -1,5 +1,5 @@
1 class WalletRestoreFromSeedException implements Exception {
2 - WalletRestoreFromSeedException({this.message});
2 + WalletRestoreFromSeedException({required this.message});
3
4 final String message;
5 }
\ No newline at end of file
cw_monero/lib/api/monero_output.dart
+1 -3
@@ -1,7 +1,5 @@
1 -import 'package:flutter/foundation.dart';
2 -
1 class MoneroOutput {
4 - MoneroOutput({@required this.address, @required this.amount});
2 + MoneroOutput({required this.address, required this.amount});
3
4 final String address;
5 final String amount;
cw_monero/lib/api/signatures.dart
+2 -2
@@ -35,7 +35,7 @@ typedef get_node_height = Int64 Function();
35 typedef is_connected = Int8 Function();
36
37 typedef setup_node = Int8 Function(
38 - Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, Int8, Int8, Pointer<Utf8>);
38 + Pointer<Utf8>, Pointer<Utf8>?, Pointer<Utf8>?, Int8, Int8, Pointer<Utf8>);
39
40 typedef start_refresh = Void Function();
41
@@ -82,7 +82,7 @@ typedef account_set_label = Void Function(
82
83 typedef transactions_refresh = Void Function();
84
85 -typedef get_tx_key = Pointer<Utf8> Function(Pointer<Utf8> txId);
85 +typedef get_tx_key = Pointer<Utf8>? Function(Pointer<Utf8> txId);
86
87 typedef transactions_count = Int64 Function();
88
cw_monero/lib/api/structs/account_row.dart
+4 -3
@@ -3,9 +3,10 @@ import 'package:ffi/ffi.dart';
3
4 class AccountRow extends Struct {
5 @Int64()
6 - int id;
7 - Pointer<Utf8> label;
6 + external int id;
7 +
8 + external Pointer<Utf8> label;
9
9 - String getLabel() => Utf8.fromUtf8(label);
10 + String getLabel() => label.toDartString();
11 int getId() => id;
12 }
cw_monero/lib/api/structs/pending_transaction.dart
+14 -14
@@ -3,32 +3,32 @@ import 'package:ffi/ffi.dart';
3
4 class PendingTransactionRaw extends Struct {
5 @Int64()
6 - int amount;
6 + external int amount;
7
8 @Int64()
9 - int fee;
9 + external int fee;
10
11 - Pointer<Utf8> hash;
11 + external Pointer<Utf8> hash;
12
13 - Pointer<Utf8> hex;
13 + external Pointer<Utf8> hex;
14
15 - Pointer<Utf8> txKey;
15 + external Pointer<Utf8> txKey;
16
17 - String getHash() => Utf8.fromUtf8(hash);
17 + String getHash() => hash.toDartString();
18
19 - String getHex() => Utf8.fromUtf8(hex);
19 + String getHex() => hex.toDartString();
20
21 - String getKey() => Utf8.fromUtf8(txKey);
21 + String getKey() => txKey.toDartString();
22 }
23
24 class PendingTransactionDescription {
25 PendingTransactionDescription({
26 - this.amount,
27 - this.fee,
28 - this.hash,
29 - this.hex,
30 - this.txKey,
31 - this.pointerAddress});
26 + required this.amount,
27 + required this.fee,
28 + required this.hash,
29 + required this.hex,
30 + required this.txKey,
31 + required this.pointerAddress});
32
33 final int amount;
34 final int fee;
cw_monero/lib/api/structs/subaddress_row.dart
+7 -5
@@ -3,11 +3,13 @@ import 'package:ffi/ffi.dart';
3
4 class SubaddressRow extends Struct {
5 @Int64()
6 - int id;
7 - Pointer<Utf8> address;
8 - Pointer<Utf8> label;
6 + external int id;
7 +
8 + external Pointer<Utf8> address;
9 +
10 + external Pointer<Utf8> label;
11
10 - String getLabel() => Utf8.fromUtf8(label);
11 - String getAddress() => Utf8.fromUtf8(address);
12 + String getLabel() => label.toDartString();
13 + String getAddress() => address.toDartString();
14 int getId() => id;
15 }
\ No newline at end of file
cw_monero/lib/api/structs/transaction_info_row.dart
+13 -13
@@ -3,39 +3,39 @@ import 'package:ffi/ffi.dart';
3
4 class TransactionInfoRow extends Struct {
5 @Uint64()
6 - int amount;
6 + external int amount;
7
8 @Uint64()
9 - int fee;
9 + external int fee;
10
11 @Uint64()
12 - int blockHeight;
12 + external int blockHeight;
13
14 @Uint64()
15 - int confirmations;
15 + external int confirmations;
16
17 @Uint32()
18 - int subaddrAccount;
18 + external int subaddrAccount;
19
20 @Int8()
21 - int direction;
21 + external int direction;
22
23 @Int8()
24 - int isPending;
24 + external int isPending;
25
26 @Uint32()
27 - int subaddrIndex;
27 + external int subaddrIndex;
28
29 - Pointer<Utf8> hash;
29 + external Pointer<Utf8> hash;
30
31 - Pointer<Utf8> paymentId;
31 + external Pointer<Utf8> paymentId;
32
33 @Int64()
34 - int datetime;
34 + external int datetime;
35
36 int getDatetime() => datetime;
37 int getAmount() => amount >= 0 ? amount : amount * -1;
38 bool getIsPending() => isPending != 0;
39 - String getHash() => Utf8.fromUtf8(hash);
40 - String getPaymentId() => Utf8.fromUtf8(paymentId);
39 + String getHash() => hash.toDartString();
40 + String getPaymentId() => paymentId.toDartString();
41 }
cw_monero/lib/api/structs/ut8_box.dart
+2 -2
@@ -2,7 +2,7 @@ import 'dart:ffi';
2 import 'package:ffi/ffi.dart';
3
4 class Utf8Box extends Struct {
5 - Pointer<Utf8> value;
5 + external Pointer<Utf8> value;
6
7 - String getValue() => Utf8.fromUtf8(value);
7 + String getValue() => value.toDartString();
8 }
cw_monero/lib/api/subaddress_list.dart
+10 -10
@@ -29,7 +29,7 @@ final subaddrressSetLabelNative = moneroApi
29
30 bool isUpdating = false;
31
32 -void refreshSubaddresses({@required int accountIndex}) {
32 +void refreshSubaddresses({required int accountIndex}) {
33 try {
34 isUpdating = true;
35 subaddressRefreshNative(accountIndex);
@@ -50,18 +50,18 @@ List<SubaddressRow> getAllSubaddresses() {
50 .toList();
51 }
52
53 -void addSubaddressSync({int accountIndex, String label}) {
54 - final labelPointer = Utf8.toUtf8(label);
53 +void addSubaddressSync({required int accountIndex, required String label}) {
54 + final labelPointer = label.toNativeUtf8();
55 subaddrressAddNewNative(accountIndex, labelPointer);
56 - free(labelPointer);
56 + calloc.free(labelPointer);
57 }
58
59 void setLabelForSubaddressSync(
60 - {int accountIndex, int addressIndex, String label}) {
61 - final labelPointer = Utf8.toUtf8(label);
60 + {required int accountIndex, required int addressIndex, required String label}) {
61 + final labelPointer = label.toNativeUtf8();
62
63 subaddrressSetLabelNative(accountIndex, addressIndex, labelPointer);
64 - free(labelPointer);
64 + calloc.free(labelPointer);
65 }
66
67 void _addSubaddress(Map<String, dynamic> args) {
@@ -80,14 +80,14 @@ void _setLabelForSubaddress(Map<String, dynamic> args) {
80 accountIndex: accountIndex, addressIndex: addressIndex, label: label);
81 }
82
83 -Future addSubaddress({int accountIndex, String label}) async {
83 +Future<void> addSubaddress({required int accountIndex, required String label}) async {
84 await compute<Map<String, Object>, void>(
85 _addSubaddress, {'accountIndex': accountIndex, 'label': label});
86 await store();
87 }
88
89 -Future setLabelForSubaddress(
90 - {int accountIndex, int addressIndex, String label}) async {
89 +Future<void> setLabelForSubaddress(
90 + {required int accountIndex, required int addressIndex, required String label}) async {
91 await compute<Map<String, Object>, void>(_setLabelForSubaddress, {
92 'accountIndex': accountIndex,
93 'addressIndex': addressIndex,
cw_monero/lib/api/transaction_history.dart
+41 -41
@@ -40,16 +40,16 @@ final getTxKeyNative = moneroApi
40 .asFunction<GetTxKey>();
41
42 String getTxKey(String txId) {
43 - final txIdPointer = Utf8.toUtf8(txId);
43 + final txIdPointer = txId.toNativeUtf8();
44 final keyPointer = getTxKeyNative(txIdPointer);
45
46 - free(txIdPointer);
46 + calloc.free(txIdPointer);
47
48 if (keyPointer != null) {
49 return convertUTF8ToString(pointer: keyPointer);
50 }
51
52 - return null;
52 + return '';
53 }
54
55 void refreshTransactions() => transactionsRefreshNative();
@@ -67,16 +67,16 @@ List<TransactionInfoRow> getAllTransations() {
67 }
68
69 PendingTransactionDescription createTransactionSync(
70 - {String address,
71 - String paymentId,
72 - String amount,
73 - int priorityRaw,
70 + {required String address,
71 + required String paymentId,
72 + required int priorityRaw,
73 + String? amount,
74 int accountIndex = 0}) {
75 - final addressPointer = Utf8.toUtf8(address);
76 - final paymentIdPointer = Utf8.toUtf8(paymentId);
77 - final amountPointer = amount != null ? Utf8.toUtf8(amount) : nullptr;
78 - final errorMessagePointer = allocate<Utf8Box>();
79 - final pendingTransactionRawPointer = allocate<PendingTransactionRaw>();
75 + final addressPointer = address.toNativeUtf8();
76 + final paymentIdPointer = paymentId.toNativeUtf8();
77 + final amountPointer = amount != null ? amount.toNativeUtf8() : nullptr;
78 + final errorMessagePointer = calloc<Utf8Box>();
79 + final pendingTransactionRawPointer = calloc<PendingTransactionRaw>();
80 final created = transactionCreateNative(
81 addressPointer,
82 paymentIdPointer,
@@ -87,16 +87,16 @@ PendingTransactionDescription createTransactionSync(
87 pendingTransactionRawPointer) !=
88 0;
89
90 - free(addressPointer);
91 - free(paymentIdPointer);
90 + calloc.free(addressPointer);
91 + calloc.free(paymentIdPointer);
92
93 if (amountPointer != nullptr) {
94 - free(amountPointer);
94 + calloc.free(amountPointer);
95 }
96
97 if (!created) {
98 final message = errorMessagePointer.ref.getValue();
99 - free(errorMessagePointer);
99 + calloc.free(errorMessagePointer);
100 throw CreationTransactionException(message: message);
101 }
102
@@ -110,26 +110,26 @@ PendingTransactionDescription createTransactionSync(
110 }
111
112 PendingTransactionDescription createTransactionMultDestSync(
113 - {List<MoneroOutput> outputs,
114 - String paymentId,
115 - int priorityRaw,
113 + {required List<MoneroOutput> outputs,
114 + required String paymentId,
115 + required int priorityRaw,
116 int accountIndex = 0}) {
117 final int size = outputs.length;
118 final List<Pointer<Utf8>> addressesPointers = outputs.map((output) =>
119 - Utf8.toUtf8(output.address)).toList();
120 - final Pointer<Pointer<Utf8>> addressesPointerPointer = allocate(count: size);
119 + output.address.toNativeUtf8()).toList();
120 + final Pointer<Pointer<Utf8>> addressesPointerPointer = calloc(size);
121 final List<Pointer<Utf8>> amountsPointers = outputs.map((output) =>
122 - Utf8.toUtf8(output.amount)).toList();
123 - final Pointer<Pointer<Utf8>> amountsPointerPointer = allocate(count: size);
122 + output.amount.toNativeUtf8()).toList();
123 + final Pointer<Pointer<Utf8>> amountsPointerPointer = calloc(size);
124
125 for (int i = 0; i < size; i++) {
126 addressesPointerPointer[i] = addressesPointers[i];
127 amountsPointerPointer[i] = amountsPointers[i];
128 }
129
130 - final paymentIdPointer = Utf8.toUtf8(paymentId);
131 - final errorMessagePointer = allocate<Utf8Box>();
132 - final pendingTransactionRawPointer = allocate<PendingTransactionRaw>();
130 + final paymentIdPointer = paymentId.toNativeUtf8();
131 + final errorMessagePointer = calloc<Utf8Box>();
132 + final pendingTransactionRawPointer = calloc<PendingTransactionRaw>();
133 final created = transactionCreateMultDestNative(
134 addressesPointerPointer,
135 paymentIdPointer,
@@ -141,17 +141,17 @@ PendingTransactionDescription createTransactionMultDestSync(
141 pendingTransactionRawPointer) !=
142 0;
143
144 - free(addressesPointerPointer);
145 - free(amountsPointerPointer);
144 + calloc.free(addressesPointerPointer);
145 + calloc.free(amountsPointerPointer);
146
147 - addressesPointers.forEach((element) => free(element));
148 - amountsPointers.forEach((element) => free(element));
147 + addressesPointers.forEach((element) => calloc.free(element));
148 + amountsPointers.forEach((element) => calloc.free(element));
149
150 - free(paymentIdPointer);
150 + calloc.free(paymentIdPointer);
151
152 if (!created) {
153 final message = errorMessagePointer.ref.getValue();
154 - free(errorMessagePointer);
154 + calloc.free(errorMessagePointer);
155 throw CreationTransactionException(message: message);
156 }
157
@@ -164,17 +164,17 @@ PendingTransactionDescription createTransactionMultDestSync(
164 pointerAddress: pendingTransactionRawPointer.address);
165 }
166
167 -void commitTransactionFromPointerAddress({int address}) => commitTransaction(
167 +void commitTransactionFromPointerAddress({required int address}) => commitTransaction(
168 transactionPointer: Pointer<PendingTransactionRaw>.fromAddress(address));
169
170 -void commitTransaction({Pointer<PendingTransactionRaw> transactionPointer}) {
171 - final errorMessagePointer = allocate<Utf8Box>();
170 +void commitTransaction({required Pointer<PendingTransactionRaw> transactionPointer}) {
171 + final errorMessagePointer = calloc<Utf8Box>();
172 final isCommited =
173 transactionCommitNative(transactionPointer, errorMessagePointer) != 0;
174
175 if (!isCommited) {
176 final message = errorMessagePointer.ref.getValue();
177 - free(errorMessagePointer);
177 + calloc.free(errorMessagePointer);
178 throw CreationTransactionException(message: message);
179 }
180 }
@@ -208,10 +208,10 @@ PendingTransactionDescription _createTransactionMultDestSync(Map args) {
208 }
209
210 Future<PendingTransactionDescription> createTransaction(
211 - {String address,
211 + {required String address,
212 + required int priorityRaw,
213 + String? amount,
214 String paymentId = '',
213 - String amount,
214 - int priorityRaw,
215 int accountIndex = 0}) =>
216 compute(_createTransactionSync, {
217 'address': address,
@@ -222,9 +222,9 @@ Future<PendingTransactionDescription> createTransaction(
222 });
223
224 Future<PendingTransactionDescription> createTransactionMultDest(
225 - {List<MoneroOutput> outputs,
225 + {required List<MoneroOutput> outputs,
226 + required int priorityRaw,
227 String paymentId = '',
227 - int priorityRaw,
228 int accountIndex = 0}) =>
229 compute(_createTransactionMultDestSync, {
230 'outputs': outputs,
cw_monero/lib/api/types.dart
+2 -2
@@ -35,7 +35,7 @@ typedef GetNodeHeight = int Function();
35 typedef IsConnected = int Function();
36
37 typedef SetupNode = int Function(
38 - Pointer<Utf8>, Pointer<Utf8>, Pointer<Utf8>, int, int, Pointer<Utf8>);
38 + Pointer<Utf8>, Pointer<Utf8>?, Pointer<Utf8>?, int, int, Pointer<Utf8>);
39
40 typedef StartRefresh = void Function();
41
@@ -80,7 +80,7 @@ typedef AccountSetLabel = void Function(int accountIndex, Pointer<Utf8> label);
80
81 typedef TransactionsRefresh = void Function();
82
83 -typedef GetTxKey = Pointer<Utf8> Function(Pointer<Utf8> txId);
83 +typedef GetTxKey = Pointer<Utf8>? Function(Pointer<Utf8> txId);
84
85 typedef TransactionsCount = int Function();
86
cw_monero/lib/api/wallet.dart
+41 -35
@@ -146,24 +146,24 @@ int getNodeHeightSync() => getNodeHeightNative();
146 bool isConnectedSync() => isConnectedNative() != 0;
147
148 bool setupNodeSync(
149 - {String address,
150 - String login,
151 - String password,
149 + {required String address,
150 + String? login,
151 + String? password,
152 bool useSSL = false,
153 bool isLightWallet = false}) {
154 - final addressPointer = Utf8.toUtf8(address);
155 - Pointer<Utf8> loginPointer;
156 - Pointer<Utf8> passwordPointer;
154 + final addressPointer = address.toNativeUtf8();
155 + Pointer<Utf8>? loginPointer;
156 + Pointer<Utf8>? passwordPointer;
157
158 if (login != null) {
159 - loginPointer = Utf8.toUtf8(login);
159 + loginPointer = login.toNativeUtf8();
160 }
161
162 if (password != null) {
163 - passwordPointer = Utf8.toUtf8(password);
163 + passwordPointer = password.toNativeUtf8();
164 }
165
166 - final errorMessagePointer = allocate<Utf8>();
166 + final errorMessagePointer = ''.toNativeUtf8();
167 final isSetupNode = setupNodeNative(
168 addressPointer,
169 loginPointer,
@@ -173,9 +173,15 @@ bool setupNodeSync(
173 errorMessagePointer) !=
174 0;
175
176 - free(addressPointer);
177 - free(loginPointer);
178 - free(passwordPointer);
176 + calloc.free(addressPointer);
177 +
178 + if (loginPointer != null) {
179 + calloc.free(loginPointer);
180 + }
181 +
182 + if (passwordPointer != null) {
183 + calloc.free(passwordPointer);
184 + }
185
186 if (!isSetupNode) {
187 throw SetupWalletException(
@@ -189,31 +195,31 @@ void startRefreshSync() => startRefreshNative();
195
196 Future<bool> connectToNode() async => connecToNodeNative() != 0;
197
192 -void setRefreshFromBlockHeight({int height}) =>
198 +void setRefreshFromBlockHeight({required int height}) =>
199 setRefreshFromBlockHeightNative(height);
200
195 -void setRecoveringFromSeed({bool isRecovery}) =>
201 +void setRecoveringFromSeed({required bool isRecovery}) =>
202 setRecoveringFromSeedNative(_boolToInt(isRecovery));
203
204 void storeSync() {
199 - final pathPointer = Utf8.toUtf8('');
205 + final pathPointer = ''.toNativeUtf8();
206 storeNative(pathPointer);
201 - free(pathPointer);
207 + calloc.free(pathPointer);
208 }
209
210 void setPasswordSync(String password) {
205 - final passwordPointer = Utf8.toUtf8(password);
206 - final errorMessagePointer = allocate<Utf8Box>();
211 + final passwordPointer = password.toNativeUtf8();
212 + final errorMessagePointer = calloc<Utf8Box>();
213 final changed = setPasswordNative(passwordPointer, errorMessagePointer) != 0;
208 - free(passwordPointer);
214 + calloc.free(passwordPointer);
215
216 if (!changed) {
217 final message = errorMessagePointer.ref.getValue();
212 - free(errorMessagePointer);
218 + calloc.free(errorMessagePointer);
219 throw Exception(message);
220 }
221
216 - free(errorMessagePointer);
222 + calloc.free(errorMessagePointer);
223 }
224
225 void closeCurrentWallet() => closeCurrentWalletNative();
@@ -231,16 +237,16 @@ String getPublicSpendKey() =>
237 convertUTF8ToString(pointer: getPublicSpendKeyNative());
238
239 class SyncListener {
234 - SyncListener(this.onNewBlock, this.onNewTransaction) {
235 - _cachedBlockchainHeight = 0;
236 - _lastKnownBlockHeight = 0;
240 + SyncListener(this.onNewBlock, this.onNewTransaction)
241 + : _cachedBlockchainHeight = 0,
242 + _lastKnownBlockHeight = 0,
243 _initialSyncHeight = 0;
238 - }
244 +
245
246 void Function(int, int, double) onNewBlock;
247 void Function() onNewTransaction;
248
243 - Timer _updateSyncInfoTimer;
249 + Timer? _updateSyncInfoTimer;
250 int _cachedBlockchainHeight;
251 int _lastKnownBlockHeight;
252 int _initialSyncHeight;
@@ -260,7 +266,7 @@ class SyncListener {
266 _updateSyncInfoTimer ??=
267 Timer.periodic(Duration(milliseconds: 1200), (_) async {
268 if (isNewTransactionExist()) {
263 - onNewTransaction?.call();
269 + onNewTransaction();
270 }
271
272 var syncHeight = getSyncingHeight();
@@ -308,7 +314,7 @@ void onStartup() => onStartupNative();
314
315 void _storeSync(Object _) => storeSync();
316
311 -bool _setupNodeSync(Map args) {
317 +bool _setupNodeSync(Map<String, Object?> args) {
318 final address = args['address'] as String;
319 final login = (args['login'] ?? '') as String;
320 final password = (args['password'] ?? '') as String;
@@ -329,21 +335,21 @@ int _getNodeHeight(Object _) => getNodeHeightSync();
335
336 void startRefresh() => startRefreshSync();
337
332 -Future setupNode(
333 - {String address,
334 - String login,
335 - String password,
338 +Future<void> setupNode(
339 + {required String address,
340 + String? login,
341 + String? password,
342 bool useSSL = false,
343 bool isLightWallet = false}) =>
338 - compute<Map<String, Object>, void>(_setupNodeSync, {
344 + compute<Map<String, Object?>, void>(_setupNodeSync, {
345 'address': address,
340 - 'login': login,
346 + 'login': login ,
347 'password': password,
348 'useSSL': useSSL,
349 'isLightWallet': isLightWallet
350 });
351
346 -Future store() => compute<int, void>(_storeSync, 0);
352 +Future<void> store() => compute<int, void>(_storeSync, 0);
353
354 Future<bool> isConnected() => compute(_isConnected, 0);
355
cw_monero/lib/api/wallet_manager.dart
+68 -62
@@ -38,18 +38,21 @@ final errorStringNative = moneroApi
38 .asFunction<ErrorString>();
39
40 void createWalletSync(
41 - {String path, String password, String language, int nettype = 0}) {
42 - final pathPointer = Utf8.toUtf8(path);
43 - final passwordPointer = Utf8.toUtf8(password);
44 - final languagePointer = Utf8.toUtf8(language);
45 - final errorMessagePointer = allocate<Utf8>();
41 + {required String path,
42 + required String password,
43 + required String language,
44 + int nettype = 0}) {
45 + final pathPointer = path.toNativeUtf8();
46 + final passwordPointer = password.toNativeUtf8();
47 + final languagePointer = language.toNativeUtf8();
48 + final errorMessagePointer = ''.toNativeUtf8();
49 final isWalletCreated = createWalletNative(pathPointer, passwordPointer,
50 languagePointer, nettype, errorMessagePointer) !=
51 0;
52
50 - free(pathPointer);
51 - free(passwordPointer);
52 - free(languagePointer);
53 + calloc.free(pathPointer);
54 + calloc.free(passwordPointer);
55 + calloc.free(languagePointer);
56
57 if (!isWalletCreated) {
58 throw WalletCreationException(
@@ -59,25 +62,25 @@ void createWalletSync(
62 // setupNodeSync(address: "node.moneroworld.com:18089");
63 }
64
62 -bool isWalletExistSync({String path}) {
63 - final pathPointer = Utf8.toUtf8(path);
65 +bool isWalletExistSync({required String path}) {
66 + final pathPointer = path.toNativeUtf8();
67 final isExist = isWalletExistNative(pathPointer) != 0;
68
66 - free(pathPointer);
69 + calloc.free(pathPointer);
70
71 return isExist;
72 }
73
74 void restoreWalletFromSeedSync(
72 - {String path,
73 - String password,
74 - String seed,
75 + {required String path,
76 + required String password,
77 + required String seed,
78 int nettype = 0,
79 int restoreHeight = 0}) {
77 - final pathPointer = Utf8.toUtf8(path);
78 - final passwordPointer = Utf8.toUtf8(password);
79 - final seedPointer = Utf8.toUtf8(seed);
80 - final errorMessagePointer = allocate<Utf8>();
80 + final pathPointer = path.toNativeUtf8();
81 + final passwordPointer = password.toNativeUtf8();
82 + final seedPointer = seed.toNativeUtf8();
83 + final errorMessagePointer = ''.toNativeUtf8();
84 final isWalletRestored = restoreWalletFromSeedNative(
85 pathPointer,
86 passwordPointer,
@@ -87,9 +90,9 @@ void restoreWalletFromSeedSync(
90 errorMessagePointer) !=
91 0;
92
90 - free(pathPointer);
91 - free(passwordPointer);
92 - free(seedPointer);
93 + calloc.free(pathPointer);
94 + calloc.free(passwordPointer);
95 + calloc.free(seedPointer);
96
97 if (!isWalletRestored) {
98 throw WalletRestoreFromSeedException(
@@ -98,21 +101,21 @@ void restoreWalletFromSeedSync(
101 }
102
103 void restoreWalletFromKeysSync(
101 - {String path,
102 - String password,
103 - String language,
104 - String address,
105 - String viewKey,
106 - String spendKey,
104 + {required String path,
105 + required String password,
106 + required String language,
107 + required String address,
108 + required String viewKey,
109 + required String spendKey,
110 int nettype = 0,
111 int restoreHeight = 0}) {
109 - final pathPointer = Utf8.toUtf8(path);
110 - final passwordPointer = Utf8.toUtf8(password);
111 - final languagePointer = Utf8.toUtf8(language);
112 - final addressPointer = Utf8.toUtf8(address);
113 - final viewKeyPointer = Utf8.toUtf8(viewKey);
114 - final spendKeyPointer = Utf8.toUtf8(spendKey);
115 - final errorMessagePointer = allocate<Utf8>();
112 + final pathPointer = path.toNativeUtf8();
113 + final passwordPointer = password.toNativeUtf8();
114 + final languagePointer = language.toNativeUtf8();
115 + final addressPointer = address.toNativeUtf8();
116 + final viewKeyPointer = viewKey.toNativeUtf8();
117 + final spendKeyPointer = spendKey.toNativeUtf8();
118 + final errorMessagePointer = ''.toNativeUtf8();
119 final isWalletRestored = restoreWalletFromKeysNative(
120 pathPointer,
121 passwordPointer,
@@ -125,12 +128,12 @@ void restoreWalletFromKeysSync(
128 errorMessagePointer) !=
129 0;
130
128 - free(pathPointer);
129 - free(passwordPointer);
130 - free(languagePointer);
131 - free(addressPointer);
132 - free(viewKeyPointer);
133 - free(spendKeyPointer);
131 + calloc.free(pathPointer);
132 + calloc.free(passwordPointer);
133 + calloc.free(languagePointer);
134 + calloc.free(addressPointer);
135 + calloc.free(viewKeyPointer);
136 + calloc.free(spendKeyPointer);
137
138 if (!isWalletRestored) {
139 throw WalletRestoreFromKeysException(
@@ -138,12 +141,15 @@ void restoreWalletFromKeysSync(
141 }
142 }
143
141 -void loadWallet({String path, String password, int nettype = 0}) {
142 - final pathPointer = Utf8.toUtf8(path);
143 - final passwordPointer = Utf8.toUtf8(password);
144 +void loadWallet({
145 + required String path,
146 + required String password,
147 + int nettype = 0}) {
148 + final pathPointer = path.toNativeUtf8();
149 + final passwordPointer = password.toNativeUtf8();
150 final loaded = loadWalletNative(pathPointer, passwordPointer, nettype) != 0;
145 - free(pathPointer);
146 - free(passwordPointer);
151 + calloc.free(pathPointer);
152 + calloc.free(passwordPointer);
153
154 if (!loaded) {
155 throw WalletOpeningException(
@@ -189,20 +195,20 @@ void _restoreFromKeys(Map<String, dynamic> args) {
195 }
196
197 Future<void> _openWallet(Map<String, String> args) async =>
192 - loadWallet(path: args['path'], password: args['password']);
198 + loadWallet(path: args['path'] as String, password: args['password'] as String);
199
200 bool _isWalletExist(String path) => isWalletExistSync(path: path);
201
196 -void openWallet({String path, String password, int nettype = 0}) async =>
202 +void openWallet({required String path, required String password, int nettype = 0}) async =>
203 loadWallet(path: path, password: password, nettype: nettype);
204
205 Future<void> openWalletAsync(Map<String, String> args) async =>
206 compute(_openWallet, args);
207
208 Future<void> createWallet(
203 - {String path,
204 - String password,
205 - String language,
209 + {required String path,
210 + required String password,
211 + required String language,
212 int nettype = 0}) async =>
213 compute(_createWallet, {
214 'path': path,
@@ -211,10 +217,10 @@ Future<void> createWallet(
217 'nettype': nettype
218 });
219
214 -Future restoreFromSeed(
215 - {String path,
216 - String password,
217 - String seed,
220 +Future<void> restoreFromSeed(
221 + {required String path,
222 + required String password,
223 + required String seed,
224 int nettype = 0,
225 int restoreHeight = 0}) async =>
226 compute<Map<String, Object>, void>(_restoreFromSeed, {
@@ -225,13 +231,13 @@ Future restoreFromSeed(
231 'restoreHeight': restoreHeight
232 });
233
228 -Future restoreFromKeys(
229 - {String path,
230 - String password,
231 - String language,
232 - String address,
233 - String viewKey,
234 - String spendKey,
234 +Future<void> restoreFromKeys(
235 + {required String path,
236 + required String password,
237 + required String language,
238 + required String address,
239 + required String viewKey,
240 + required String spendKey,
241 int nettype = 0,
242 int restoreHeight = 0}) async =>
243 compute<Map<String, Object>, void>(_restoreFromKeys, {
@@ -245,4 +251,4 @@ Future restoreFromKeys(
251 'restoreHeight': restoreHeight
252 });
253
248 -Future<bool> isWalletExist({String path}) => compute(_isWalletExist, path);
254 +Future<bool> isWalletExist({required String path}) => compute(_isWalletExist, path);
cw_monero/lib/monero_account_list.dart
+2 -3
@@ -12,7 +12,6 @@ abstract class MoneroAccountListBase with Store {
12 _isRefreshing = false,
13 _isUpdating = false {
14 refresh();
15 - print(account_list.accountSizeNative());
15 }
16
17 @observable
@@ -49,12 +48,12 @@ abstract class MoneroAccountListBase with Store {
48 label: accountRow.getLabel()))
49 .toList();
50
52 - Future addAccount({String label}) async {
51 + Future<void> addAccount({required String label}) async {
52 await account_list.addAccount(label: label);
53 update();
54 }
55
57 - Future setLabelAccount({int accountIndex, String label}) async {
56 + Future<void> setLabelAccount({required int accountIndex, required String label}) async {
57 await account_list.setLabelForAccount(
58 accountIndex: accountIndex, label: label);
59 update();
cw_monero/lib/monero_subaddress_list.dart
+9 -10
@@ -10,11 +10,10 @@ class MoneroSubaddressList = MoneroSubaddressListBase
10 with _$MoneroSubaddressList;
11
12 abstract class MoneroSubaddressListBase with Store {
13 - MoneroSubaddressListBase() {
14 - _isRefreshing = false;
15 - _isUpdating = false;
16 - subaddresses = ObservableList<Subaddress>();
17 - }
13 + MoneroSubaddressListBase()
14 + : _isRefreshing = false,
15 + _isUpdating = false,
16 + subaddresses = ObservableList<Subaddress>();
17
18 @observable
19 ObservableList<Subaddress> subaddresses;
@@ -22,7 +21,7 @@ abstract class MoneroSubaddressListBase with Store {
21 bool _isRefreshing;
22 bool _isUpdating;
23
25 - void update({int accountIndex}) {
24 + void update({required int accountIndex}) {
25 if (_isUpdating) {
26 return;
27 }
@@ -59,20 +58,20 @@ abstract class MoneroSubaddressListBase with Store {
58 .toList();
59 }
60
62 - Future addSubaddress({int accountIndex, String label}) async {
61 + Future<void> addSubaddress({required int accountIndex, required String label}) async {
62 await subaddress_list.addSubaddress(
63 accountIndex: accountIndex, label: label);
64 update(accountIndex: accountIndex);
65 }
66
68 - Future setLabelSubaddress(
69 - {int accountIndex, int addressIndex, String label}) async {
67 + Future<void> setLabelSubaddress(
68 + {required int accountIndex, required int addressIndex, required String label}) async {
69 await subaddress_list.setLabelForSubaddress(
70 accountIndex: accountIndex, addressIndex: addressIndex, label: label);
71 update(accountIndex: accountIndex);
72 }
73
75 - void refresh({int accountIndex}) {
74 + void refresh({required int accountIndex}) {
75 if (_isRefreshing) {
76 return;
77 }
cw_monero/lib/monero_transaction_creation_credentials.dart
+1 -1
@@ -2,7 +2,7 @@ import 'package:cw_core/monero_transaction_priority.dart';
2 import 'package:cw_core/output_info.dart';
3
4 class MoneroTransactionCreationCredentials {
5 - MoneroTransactionCreationCredentials({this.outputs, this.priority});
5 + MoneroTransactionCreationCredentials({required this.outputs, required this.priority});
6
7 final List<OutputInfo> outputs;
8 final MoneroTransactionPriority priority;
cw_monero/lib/monero_transaction_info.dart
+6 -7
@@ -10,7 +10,7 @@ class MoneroTransactionInfo extends TransactionInfo {
10 MoneroTransactionInfo(this.id, this.height, this.direction, this.date,
11 this.isPending, this.amount, this.accountIndex, this.addressIndex, this.fee);
12
13 - MoneroTransactionInfo.fromMap(Map map)
13 + MoneroTransactionInfo.fromMap(Map<String, Object?> map)
14 : id = (map['hash'] ?? '') as String,
15 height = (map['height'] ?? 0) as int,
16 direction =
@@ -24,7 +24,7 @@ class MoneroTransactionInfo extends TransactionInfo {
24 addressIndex = map['addressIndex'] as int,
25 key = getTxKey((map['hash'] ?? '') as String),
26 fee = map['fee'] as int ?? 0 {
27 - additionalInfo = {
27 + additionalInfo = <String, dynamic>{
28 'key': key,
29 'accountIndex': accountIndex,
30 'addressIndex': addressIndex
@@ -43,7 +43,7 @@ class MoneroTransactionInfo extends TransactionInfo {
43 addressIndex = row.subaddrIndex,
44 key = getTxKey(row.getHash()),
45 fee = row.fee {
46 - additionalInfo = {
46 + additionalInfo = <String, dynamic>{
47 'key': key,
48 'accountIndex': accountIndex,
49 'addressIndex': addressIndex
@@ -59,10 +59,9 @@ class MoneroTransactionInfo extends TransactionInfo {
59 final int amount;
60 final int fee;
61 final int addressIndex;
62 - String recipientAddress;
63 - String key;
64 -
65 - String _fiatAmount;
62 + String? recipientAddress;
63 + String? key;
64 + String? _fiatAmount;
65
66 @override
67 String amountFormatted() =>
cw_monero/lib/monero_wallet.dart
+42 -37
@@ -36,19 +36,24 @@ class MoneroWallet = MoneroWalletBase with _$MoneroWallet;
36
37 abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
38 MoneroTransactionHistory, MoneroTransactionInfo> with Store {
39 - MoneroWalletBase({WalletInfo walletInfo})
40 - : super(walletInfo) {
39 + MoneroWalletBase({required WalletInfo walletInfo})
40 + : balance = ObservableMap<CryptoCurrency, MoneroBalance>.of({
41 + CryptoCurrency.xmr: MoneroBalance(
42 + fullBalance: monero_wallet.getFullBalance(accountIndex: 0),
43 + unlockedBalance: monero_wallet.getFullBalance(accountIndex: 0))
44 + }),
45 + _isTransactionUpdating = false,
46 + _hasSyncAfterStartup = false,
47 + walletAddresses = MoneroWalletAddresses(walletInfo),
48 + syncStatus = NotConnectedSyncStatus(),
49 + super(walletInfo) {
50 transactionHistory = MoneroTransactionHistory();
42 - balance = ObservableMap<CryptoCurrency, MoneroBalance>.of({
43 - CryptoCurrency.xmr: MoneroBalance(
44 - fullBalance: monero_wallet.getFullBalance(accountIndex: 0),
45 - unlockedBalance: monero_wallet.getFullBalance(accountIndex: 0))
46 - });
47 - _isTransactionUpdating = false;
48 - _hasSyncAfterStartup = false;
49 - walletAddresses = MoneroWalletAddresses(walletInfo);
51 _onAccountChangeReaction = reaction((_) => walletAddresses.account,
51 - (Account account) {
52 + (Account? account) {
53 + if (account == null) {
54 + return;
55 + }
56 +
57 balance = ObservableMap<CryptoCurrency, MoneroBalance>.of(
58 <CryptoCurrency, MoneroBalance>{
59 currency: MoneroBalance(
@@ -83,19 +88,19 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
88 publicSpendKey: monero_wallet.getPublicSpendKey(),
89 publicViewKey: monero_wallet.getPublicViewKey());
90
86 - SyncListener _listener;
87 - ReactionDisposer _onAccountChangeReaction;
91 + SyncListener? _listener;
92 + ReactionDisposer? _onAccountChangeReaction;
93 bool _isTransactionUpdating;
94 bool _hasSyncAfterStartup;
90 - Timer _autoSaveTimer;
95 + Timer? _autoSaveTimer;
96
97 Future<void> init() async {
98 await walletAddresses.init();
99 balance = ObservableMap<CryptoCurrency, MoneroBalance>.of(
100 <CryptoCurrency, MoneroBalance>{
101 currency: MoneroBalance(
97 - fullBalance: monero_wallet.getFullBalance(accountIndex: walletAddresses.account.id),
98 - unlockedBalance: monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account.id))
102 + fullBalance: monero_wallet.getFullBalance(accountIndex: walletAddresses.account!.id),
103 + unlockedBalance: monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account!.id))
104 });
105 _setListeners();
106 await updateTransactions();
@@ -117,12 +122,12 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
122 @override
123 void close() {
124 _listener?.stop();
120 - _onAccountChangeReaction?.reaction?.dispose();
125 + _onAccountChangeReaction?.reaction.dispose();
126 _autoSaveTimer?.cancel();
127 }
128
129 @override
125 - Future<void> connectToNode({@required Node node}) async {
130 + Future<void> connectToNode({required Node node}) async {
131 try {
132 syncStatus = ConnectingSyncStatus();
133 await monero_wallet.setupNode(
@@ -162,7 +167,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
167 final outputs = _credentials.outputs;
168 final hasMultiDestination = outputs.length > 1;
169 final unlockedBalance =
165 - monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account.id);
170 + monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account!.id);
171
172 PendingTransactionDescription pendingTransactionDescription;
173
@@ -172,32 +177,32 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
177
178 if (hasMultiDestination) {
179 if (outputs.any((item) => item.sendAll
175 - || item.formattedCryptoAmount <= 0)) {
180 + || (item.formattedCryptoAmount ?? 0) <= 0)) {
181 throw MoneroTransactionCreationException('Wrong balance. Not enough XMR on your balance.');
182 }
183
184 final int totalAmount = outputs.fold(0, (acc, value) =>
180 - acc + value.formattedCryptoAmount);
185 + acc + (value.formattedCryptoAmount ?? 0));
186
187 if (unlockedBalance < totalAmount) {
188 throw MoneroTransactionCreationException('Wrong balance. Not enough XMR on your balance.');
189 }
190
191 final moneroOutputs = outputs.map((output) {
187 - final outputAddress = output.isParsedAddress
188 - ? output.extractedAddress
189 - : output.address;
192 + final outputAddress = output.isParsedAddress
193 + ? output.extractedAddress
194 + : output.address;
195
191 - return MoneroOutput(
192 - address: outputAddress,
193 - amount: output.cryptoAmount.replaceAll(',', '.'));
196 + return MoneroOutput(
197 + address: outputAddress!,
198 + amount: output.cryptoAmount!.replaceAll(',', '.'));
199 }).toList();
200
201 pendingTransactionDescription =
202 await transaction_history.createTransactionMultDest(
203 outputs: moneroOutputs,
204 priorityRaw: _credentials.priority.serialize(),
200 - accountIndex: walletAddresses.account.id);
205 + accountIndex: walletAddresses.account!.id);
206 } else {
207 final output = outputs.first;
208 final address = output.isParsedAddress
@@ -205,7 +210,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
210 : output.address;
211 final amount = output.sendAll
212 ? null
208 - : output.cryptoAmount.replaceAll(',', '.');
213 + : output.cryptoAmount!.replaceAll(',', '.');
214 final formattedAmount = output.sendAll
215 ? null
216 : output.formattedCryptoAmount;
@@ -220,17 +225,17 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
225
226 pendingTransactionDescription =
227 await transaction_history.createTransaction(
223 - address: address,
228 + address: address!,
229 amount: amount,
230 priorityRaw: _credentials.priority.serialize(),
226 - accountIndex: walletAddresses.account.id);
231 + accountIndex: walletAddresses.account!.id);
232 }
233
234 return PendingMoneroTransaction(pendingTransactionDescription);
235 }
236
237 @override
233 - int calculateEstimatedFee(TransactionPriority priority, int amount) {
238 + int calculateEstimatedFee(TransactionPriority priority, int? amount) {
239 // FIXME: hardcoded value;
240
241 if (priority is MoneroTransactionPriority) {
@@ -273,7 +278,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
278 }
279
280 @override
276 - Future<void> rescan({int height}) async {
281 + Future<void> rescan({required int height}) async {
282 walletInfo.restoreHeight = height;
283 walletInfo.isRecovery = true;
284 monero_wallet.setRefreshFromBlockHeight(height: height);
@@ -372,8 +377,8 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
377 final unlockedBalance = _getUnlockedBalance();
378 final fullBalance = _getFullBalance();
379
375 - if (balance[currency].fullBalance != fullBalance ||
376 - balance[currency].unlockedBalance != unlockedBalance) {
380 + if (balance[currency]!.fullBalance != fullBalance ||
381 + balance[currency]!.unlockedBalance != unlockedBalance) {
382 balance[currency] = MoneroBalance(
383 fullBalance: fullBalance, unlockedBalance: unlockedBalance);
384 }
@@ -383,10 +388,10 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
388 await updateTransactions();
389
390 int _getFullBalance() =>
386 - monero_wallet.getFullBalance(accountIndex: walletAddresses.account.id);
391 + monero_wallet.getFullBalance(accountIndex: walletAddresses.account!.id);
392
393 int _getUnlockedBalance() =>
389 - monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account.id);
394 + monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account!.id);
395
396 void _onNewBlock(int height, int blocksLeft, double ptc) async {
397 try {
cw_monero/lib/monero_wallet_addresses.dart
+13 -12
@@ -12,20 +12,21 @@ class MoneroWalletAddresses = MoneroWalletAddressesBase
12 with _$MoneroWalletAddresses;
13
14 abstract class MoneroWalletAddressesBase extends WalletAddresses with Store {
15 - MoneroWalletAddressesBase(WalletInfo walletInfo) : super(walletInfo) {
16 - accountList = MoneroAccountList();
17 - subaddressList = MoneroSubaddressList();
18 - }
15 + MoneroWalletAddressesBase(WalletInfo walletInfo)
16 + : accountList = MoneroAccountList(),
17 + subaddressList = MoneroSubaddressList(),
18 + address = '',
19 + super(walletInfo);
20
21 @override
22 @observable
23 String address;
23 -
24 +
25 @observable
25 - Account account;
26 + Account? account;
27
28 @observable
28 - Subaddress subaddress;
29 + Subaddress? subaddress;
30
31 MoneroSubaddressList subaddressList;
32
@@ -35,7 +36,7 @@ abstract class MoneroWalletAddressesBase extends WalletAddresses with Store {
36 Future<void> init() async {
37 accountList.update();
38 account = accountList.accounts.first;
38 - updateSubaddressList(accountIndex: account.id ?? 0);
39 + updateSubaddressList(accountIndex: account?.id ?? 0);
40 await updateAddressesInBox();
41 }
42
@@ -61,14 +62,14 @@ abstract class MoneroWalletAddressesBase extends WalletAddresses with Store {
62
63 bool validate() {
64 accountList.update();
64 - final accountListLength = accountList.accounts?.length ?? 0;
65 + final accountListLength = accountList.accounts.length ?? 0;
66
67 if (accountListLength <= 0) {
68 return false;
69 }
70
71 subaddressList.update(accountIndex: accountList.accounts.first.id);
71 - final subaddressListLength = subaddressList.subaddresses?.length ?? 0;
72 + final subaddressListLength = subaddressList.subaddresses.length ?? 0;
73
74 if (subaddressListLength <= 0) {
75 return false;
@@ -77,9 +78,9 @@ abstract class MoneroWalletAddressesBase extends WalletAddresses with Store {
78 return true;
79 }
80
80 - void updateSubaddressList({int accountIndex}) {
81 + void updateSubaddressList({required int accountIndex}) {
82 subaddressList.update(accountIndex: accountIndex);
83 subaddress = subaddressList.subaddresses.first;
83 - address = subaddress.address;
84 + address = subaddress!.address;
85 }
86 }
\ No newline at end of file
cw_monero/lib/monero_wallet_service.dart
+18 -19
@@ -13,7 +13,7 @@ import 'package:cw_core/wallet_info.dart';
13 import 'package:cw_core/wallet_type.dart';
14
15 class MoneroNewWalletCredentials extends WalletCredentials {
16 - MoneroNewWalletCredentials({String name, String password, this.language})
16 + MoneroNewWalletCredentials({required String name, required this.language, String? password})
17 : super(name: name, password: password);
18
19 final String language;
@@ -21,7 +21,7 @@ class MoneroNewWalletCredentials extends WalletCredentials {
21
22 class MoneroRestoreWalletFromSeedCredentials extends WalletCredentials {
23 MoneroRestoreWalletFromSeedCredentials(
24 - {String name, String password, int height, this.mnemonic})
24 + {required String name, required this.mnemonic, int height = 0, String? password})
25 : super(name: name, password: password, height: height);
26
27 final String mnemonic;
@@ -34,13 +34,13 @@ class MoneroWalletLoadingException implements Exception {
34
35 class MoneroRestoreWalletFromKeysCredentials extends WalletCredentials {
36 MoneroRestoreWalletFromKeysCredentials(
37 - {String name,
38 - String password,
39 - this.language,
40 - this.address,
41 - this.viewKey,
42 - this.spendKey,
43 - int height})
37 + {required String name,
38 + required String password,
39 + required this.language,
40 + required this.address,
41 + required this.viewKey,
42 + required this.spendKey,
43 + int height = 0})
44 : super(name: name, password: password, height: height);
45
46 final String language;
@@ -69,9 +69,9 @@ class MoneroWalletService extends WalletService<
69 final path = await pathForWallet(name: credentials.name, type: getType());
70 await monero_wallet_manager.createWallet(
71 path: path,
72 - password: credentials.password,
72 + password: credentials.password!,
73 language: credentials.language);
74 - final wallet = MoneroWallet(walletInfo: credentials.walletInfo);
74 + final wallet = MoneroWallet(walletInfo: credentials.walletInfo!);
75 await wallet.init();
76
77 return wallet;
@@ -106,8 +106,7 @@ class MoneroWalletService extends WalletService<
106 await monero_wallet_manager
107 .openWalletAsync({'path': path, 'password': password});
108 final walletInfo = walletInfoSource.values.firstWhere(
109 - (info) => info.id == WalletBase.idFor(name, getType()),
110 - orElse: () => null);
109 + (info) => info.id == WalletBase.idFor(name, getType()));
110 final wallet = MoneroWallet(walletInfo: walletInfo);
111 final isValid = wallet.walletAddresses.validate();
112
@@ -156,13 +155,13 @@ class MoneroWalletService extends WalletService<
155 final path = await pathForWallet(name: credentials.name, type: getType());
156 await monero_wallet_manager.restoreFromKeys(
157 path: path,
159 - password: credentials.password,
158 + password: credentials.password!,
159 language: credentials.language,
161 - restoreHeight: credentials.height,
160 + restoreHeight: credentials.height!,
161 address: credentials.address,
162 viewKey: credentials.viewKey,
163 spendKey: credentials.spendKey);
165 - final wallet = MoneroWallet(walletInfo: credentials.walletInfo);
164 + final wallet = MoneroWallet(walletInfo: credentials.walletInfo!);
165 await wallet.init();
166
167 return wallet;
@@ -180,10 +179,10 @@ class MoneroWalletService extends WalletService<
179 final path = await pathForWallet(name: credentials.name, type: getType());
180 await monero_wallet_manager.restoreFromSeed(
181 path: path,
183 - password: credentials.password,
182 + password: credentials.password!,
183 seed: credentials.mnemonic,
185 - restoreHeight: credentials.height);
186 - final wallet = MoneroWallet(walletInfo: credentials.walletInfo);
184 + restoreHeight: credentials.height!);
185 + final wallet = MoneroWallet(walletInfo: credentials.walletInfo!);
186 await wallet.init();
187
188 return wallet;
cw_monero/lib/pending_monero_transaction.dart
+9 -5
@@ -2,7 +2,7 @@ import 'package:cw_monero/api/structs/pending_transaction.dart';
2 import 'package:cw_monero/api/transaction_history.dart'
3 as monero_transaction_history;
4 import 'package:cw_core/crypto_currency.dart';
5 -import 'package:cake_wallet/core/amount_converter.dart';
5 +// import 'package:cake_wallet/core/amount_converter.dart';
6
7 import 'package:cw_core/pending_transaction.dart';
8
@@ -27,13 +27,17 @@ class PendingMoneroTransaction with PendingTransaction {
27
28 String get txKey => pendingTransactionDescription.txKey;
29
30 + // FIX-ME: AmountConverter
31 @override
31 - String get amountFormatted => AmountConverter.amountIntToString(
32 - CryptoCurrency.xmr, pendingTransactionDescription.amount);
32 + String get amountFormatted => '';
33 + // AmountConverter.amountIntToString(
34 + // CryptoCurrency.xmr, pendingTransactionDescription.amount);
35
36 + // FIX-ME: AmountConverter
37 @override
35 - String get feeFormatted => AmountConverter.amountIntToString(
36 - CryptoCurrency.xmr, pendingTransactionDescription.fee);
38 + String get feeFormatted => '';
39 + // AmountConverter.amountIntToString(
40 + // CryptoCurrency.xmr, pendingTransactionDescription.fee);
41
42 @override
43 Future<void> commit() async {
cw_monero/pubspec.lock
+145 -82
@@ -7,35 +7,35 @@ packages:
7 name: _fe_analyzer_shared
8 url: "https://pub.dartlang.org"
9 source: hosted
10 - version: "14.0.0"
10 + version: "47.0.0"
11 analyzer:
12 dependency: transitive
13 description:
14 name: analyzer
15 url: "https://pub.dartlang.org"
16 source: hosted
17 - version: "0.41.2"
17 + version: "4.7.0"
18 args:
19 dependency: transitive
20 description:
21 name: args
22 url: "https://pub.dartlang.org"
23 source: hosted
24 - version: "1.6.0"
24 + version: "2.3.1"
25 asn1lib:
26 dependency: transitive
27 description:
28 name: asn1lib
29 url: "https://pub.dartlang.org"
30 source: hosted
31 - version: "0.8.1"
31 + version: "1.1.1"
32 async:
33 dependency: transitive
34 description:
35 name: async
36 url: "https://pub.dartlang.org"
37 source: hosted
38 - version: "2.5.0"
38 + version: "2.9.0"
39 boolean_selector:
40 dependency: transitive
41 description:
@@ -49,42 +49,42 @@ packages:
49 name: build
50 url: "https://pub.dartlang.org"
51 source: hosted
52 - version: "1.6.2"
52 + version: "2.3.1"
53 build_config:
54 dependency: transitive
55 description:
56 name: build_config
57 url: "https://pub.dartlang.org"
58 source: hosted
59 - version: "0.4.6"
59 + version: "1.1.0"
60 build_daemon:
61 dependency: transitive
62 description:
63 name: build_daemon
64 url: "https://pub.dartlang.org"
65 source: hosted
66 - version: "2.1.10"
66 + version: "3.1.0"
67 build_resolvers:
68 dependency: "direct dev"
69 description:
70 name: build_resolvers
71 url: "https://pub.dartlang.org"
72 source: hosted
73 - version: "1.5.3"
73 + version: "2.0.10"
74 build_runner:
75 dependency: "direct dev"
76 description:
77 name: build_runner
78 url: "https://pub.dartlang.org"
79 source: hosted
80 - version: "1.11.5"
80 + version: "2.2.1"
81 build_runner_core:
82 dependency: transitive
83 description:
84 name: build_runner_core
85 url: "https://pub.dartlang.org"
86 source: hosted
87 - version: "6.1.10"
87 + version: "7.2.4"
88 built_collection:
89 dependency: transitive
90 description:
@@ -105,63 +105,49 @@ packages:
105 name: characters
106 url: "https://pub.dartlang.org"
107 source: hosted
108 - version: "1.1.0"
109 - charcode:
110 - dependency: transitive
111 - description:
112 - name: charcode
113 - url: "https://pub.dartlang.org"
114 - source: hosted
115 - version: "1.2.0"
108 + version: "1.2.1"
109 checked_yaml:
110 dependency: transitive
111 description:
112 name: checked_yaml
113 url: "https://pub.dartlang.org"
114 source: hosted
122 - version: "1.0.4"
123 - cli_util:
124 - dependency: transitive
125 - description:
126 - name: cli_util
127 - url: "https://pub.dartlang.org"
128 - source: hosted
129 - version: "0.3.5"
115 + version: "2.0.1"
116 clock:
117 dependency: transitive
118 description:
119 name: clock
120 url: "https://pub.dartlang.org"
121 source: hosted
136 - version: "1.1.0"
122 + version: "1.1.1"
123 code_builder:
124 dependency: transitive
125 description:
126 name: code_builder
127 url: "https://pub.dartlang.org"
128 source: hosted
143 - version: "3.7.0"
129 + version: "4.3.0"
130 collection:
131 dependency: transitive
132 description:
133 name: collection
134 url: "https://pub.dartlang.org"
135 source: hosted
150 - version: "1.15.0"
136 + version: "1.16.0"
137 convert:
138 dependency: transitive
139 description:
140 name: convert
141 url: "https://pub.dartlang.org"
142 source: hosted
157 - version: "2.1.1"
143 + version: "3.0.2"
144 crypto:
145 dependency: transitive
146 description:
147 name: crypto
148 url: "https://pub.dartlang.org"
149 source: hosted
164 - version: "2.1.5"
150 + version: "3.0.2"
151 cw_core:
152 dependency: "direct main"
153 description:
@@ -175,35 +161,28 @@ packages:
161 name: dart_style
162 url: "https://pub.dartlang.org"
163 source: hosted
178 - version: "1.3.12"
179 - dartx:
180 - dependency: transitive
181 - description:
182 - name: dartx
183 - url: "https://pub.dartlang.org"
184 - source: hosted
185 - version: "0.5.0"
164 + version: "2.2.4"
165 encrypt:
187 - dependency: transitive
166 + dependency: "direct main"
167 description:
168 name: encrypt
169 url: "https://pub.dartlang.org"
170 source: hosted
192 - version: "4.1.0"
171 + version: "5.0.1"
172 fake_async:
173 dependency: transitive
174 description:
175 name: fake_async
176 url: "https://pub.dartlang.org"
177 source: hosted
199 - version: "1.2.0"
178 + version: "1.3.1"
179 ffi:
180 dependency: "direct main"
181 description:
182 name: ffi
183 url: "https://pub.dartlang.org"
184 source: hosted
206 - version: "0.1.3"
185 + version: "1.2.1"
186 file:
187 dependency: transitive
188 description:
@@ -229,12 +208,19 @@ packages:
208 name: flutter_mobx
209 url: "https://pub.dartlang.org"
210 source: hosted
232 - version: "1.1.0+2"
211 + version: "2.0.6+4"
212 flutter_test:
213 dependency: "direct dev"
214 description: flutter
215 source: sdk
216 version: "0.0.0"
217 + frontend_server_client:
218 + dependency: transitive
219 + description:
220 + name: frontend_server_client
221 + url: "https://pub.dartlang.org"
222 + source: hosted
223 + version: "2.1.3"
224 glob:
225 dependency: transitive
226 description:
@@ -248,42 +234,42 @@ packages:
234 name: graphs
235 url: "https://pub.dartlang.org"
236 source: hosted
251 - version: "0.2.0"
237 + version: "2.1.0"
238 hive:
239 dependency: transitive
240 description:
241 name: hive
242 url: "https://pub.dartlang.org"
243 source: hosted
258 - version: "1.4.4+1"
244 + version: "2.2.3"
245 hive_generator:
246 dependency: "direct dev"
247 description:
248 name: hive_generator
249 url: "https://pub.dartlang.org"
250 source: hosted
265 - version: "0.8.2"
251 + version: "1.1.3"
252 http:
253 dependency: "direct main"
254 description:
255 name: http
256 url: "https://pub.dartlang.org"
257 source: hosted
272 - version: "0.12.2"
258 + version: "0.13.5"
259 http_multi_server:
260 dependency: transitive
261 description:
262 name: http_multi_server
263 url: "https://pub.dartlang.org"
264 source: hosted
279 - version: "2.2.0"
265 + version: "3.2.1"
266 http_parser:
267 dependency: transitive
268 description:
269 name: http_parser
270 url: "https://pub.dartlang.org"
271 source: hosted
286 - version: "3.1.4"
272 + version: "4.0.1"
273 intl:
274 dependency: "direct main"
275 description:
@@ -297,7 +283,7 @@ packages:
283 name: io
284 url: "https://pub.dartlang.org"
285 source: hosted
300 - version: "0.3.5"
286 + version: "1.0.3"
287 js:
288 dependency: transitive
289 description:
@@ -311,7 +297,7 @@ packages:
297 name: json_annotation
298 url: "https://pub.dartlang.org"
299 source: hosted
314 - version: "4.0.1"
300 + version: "4.6.0"
301 logging:
302 dependency: transitive
303 description:
@@ -325,14 +311,21 @@ packages:
311 name: matcher
312 url: "https://pub.dartlang.org"
313 source: hosted
328 - version: "0.12.10"
314 + version: "0.12.12"
315 + material_color_utilities:
316 + dependency: transitive
317 + description:
318 + name: material_color_utilities
319 + url: "https://pub.dartlang.org"
320 + source: hosted
321 + version: "0.1.5"
322 meta:
323 dependency: transitive
324 description:
325 name: meta
326 url: "https://pub.dartlang.org"
327 source: hosted
335 - version: "1.3.0"
328 + version: "1.8.0"
329 mime:
330 dependency: transitive
331 description:
@@ -346,35 +339,77 @@ packages:
339 name: mobx
340 url: "https://pub.dartlang.org"
341 source: hosted
349 - version: "1.2.1+4"
342 + version: "2.1.0"
343 mobx_codegen:
344 dependency: "direct dev"
345 description:
346 name: mobx_codegen
347 url: "https://pub.dartlang.org"
348 source: hosted
356 - version: "1.1.2"
349 + version: "2.0.7+3"
350 package_config:
351 dependency: transitive
352 description:
353 name: package_config
354 url: "https://pub.dartlang.org"
355 source: hosted
363 - version: "1.9.3"
356 + version: "2.1.0"
357 path:
358 dependency: transitive
359 description:
360 name: path
361 url: "https://pub.dartlang.org"
362 source: hosted
370 - version: "1.8.0"
363 + version: "1.8.2"
364 path_provider:
365 dependency: "direct main"
366 description:
367 name: path_provider
368 url: "https://pub.dartlang.org"
369 source: hosted
377 - version: "1.4.0"
370 + version: "2.0.11"
371 + path_provider_android:
372 + dependency: transitive
373 + description:
374 + name: path_provider_android
375 + url: "https://pub.dartlang.org"
376 + source: hosted
377 + version: "2.0.20"
378 + path_provider_ios:
379 + dependency: transitive
380 + description:
381 + name: path_provider_ios
382 + url: "https://pub.dartlang.org"
383 + source: hosted
384 + version: "2.0.11"
385 + path_provider_linux:
386 + dependency: transitive
387 + description:
388 + name: path_provider_linux
389 + url: "https://pub.dartlang.org"
390 + source: hosted
391 + version: "2.1.7"
392 + path_provider_macos:
393 + dependency: transitive
394 + description:
395 + name: path_provider_macos
396 + url: "https://pub.dartlang.org"
397 + source: hosted
398 + version: "2.0.6"
399 + path_provider_platform_interface:
400 + dependency: transitive
401 + description:
402 + name: path_provider_platform_interface
403 + url: "https://pub.dartlang.org"
404 + source: hosted
405 + version: "2.0.4"
406 + path_provider_windows:
407 + dependency: transitive
408 + description:
409 + name: path_provider_windows
410 + url: "https://pub.dartlang.org"
411 + source: hosted
412 + version: "2.0.7"
413 pedantic:
414 dependency: transitive
415 description:
@@ -388,14 +423,21 @@ packages:
423 name: platform
424 url: "https://pub.dartlang.org"
425 source: hosted
391 - version: "2.2.1"
426 + version: "3.1.0"
427 + plugin_platform_interface:
428 + dependency: transitive
429 + description:
430 + name: plugin_platform_interface
431 + url: "https://pub.dartlang.org"
432 + source: hosted
433 + version: "2.1.3"
434 pointycastle:
435 dependency: transitive
436 description:
437 name: pointycastle
438 url: "https://pub.dartlang.org"
439 source: hosted
398 - version: "2.0.1"
440 + version: "3.6.2"
441 pool:
442 dependency: transitive
443 description:
@@ -403,6 +445,13 @@ packages:
445 url: "https://pub.dartlang.org"
446 source: hosted
447 version: "1.5.0"
448 + process:
449 + dependency: transitive
450 + description:
451 + name: process
452 + url: "https://pub.dartlang.org"
453 + source: hosted
454 + version: "4.2.4"
455 pub_semver:
456 dependency: transitive
457 description:
@@ -416,21 +465,21 @@ packages:
465 name: pubspec_parse
466 url: "https://pub.dartlang.org"
467 source: hosted
419 - version: "0.1.8"
468 + version: "1.2.1"
469 shelf:
470 dependency: transitive
471 description:
472 name: shelf
473 url: "https://pub.dartlang.org"
474 source: hosted
426 - version: "0.7.9"
475 + version: "1.3.2"
476 shelf_web_socket:
477 dependency: transitive
478 description:
479 name: shelf_web_socket
480 url: "https://pub.dartlang.org"
481 source: hosted
433 - version: "0.2.4+1"
482 + version: "1.0.2"
483 sky_engine:
484 dependency: transitive
485 description: flutter
@@ -442,14 +491,21 @@ packages:
491 name: source_gen
492 url: "https://pub.dartlang.org"
493 source: hosted
445 - version: "0.9.10+3"
494 + version: "1.2.3"
495 + source_helper:
496 + dependency: transitive
497 + description:
498 + name: source_helper
499 + url: "https://pub.dartlang.org"
500 + source: hosted
501 + version: "1.3.3"
502 source_span:
503 dependency: transitive
504 description:
505 name: source_span
506 url: "https://pub.dartlang.org"
507 source: hosted
452 - version: "1.8.0"
508 + version: "1.9.0"
509 stack_trace:
510 dependency: transitive
511 description:
@@ -477,35 +533,28 @@ packages:
533 name: string_scanner
534 url: "https://pub.dartlang.org"
535 source: hosted
480 - version: "1.1.0"
536 + version: "1.1.1"
537 term_glyph:
538 dependency: transitive
539 description:
540 name: term_glyph
541 url: "https://pub.dartlang.org"
542 source: hosted
487 - version: "1.2.0"
543 + version: "1.2.1"
544 test_api:
545 dependency: transitive
546 description:
547 name: test_api
548 url: "https://pub.dartlang.org"
549 source: hosted
494 - version: "0.2.19"
495 - time:
496 - dependency: transitive
497 - description:
498 - name: time
499 - url: "https://pub.dartlang.org"
500 - source: hosted
501 - version: "1.4.1"
550 + version: "0.4.12"
551 timing:
552 dependency: transitive
553 description:
554 name: timing
555 url: "https://pub.dartlang.org"
556 source: hosted
508 - version: "0.1.1+3"
557 + version: "1.0.0"
558 typed_data:
559 dependency: transitive
560 description:
@@ -519,7 +568,7 @@ packages:
568 name: vector_math
569 url: "https://pub.dartlang.org"
570 source: hosted
522 - version: "2.1.0"
571 + version: "2.1.2"
572 watcher:
573 dependency: transitive
574 description:
@@ -533,7 +582,21 @@ packages:
582 name: web_socket_channel
583 url: "https://pub.dartlang.org"
584 source: hosted
536 - version: "1.2.0"
585 + version: "2.2.0"
586 + win32:
587 + dependency: transitive
588 + description:
589 + name: win32
590 + url: "https://pub.dartlang.org"
591 + source: hosted
592 + version: "2.6.1"
593 + xdg_directories:
594 + dependency: transitive
595 + description:
596 + name: xdg_directories
597 + url: "https://pub.dartlang.org"
598 + source: hosted
599 + version: "0.2.0+2"
600 yaml:
601 dependency: transitive
602 description:
@@ -542,5 +605,5 @@ packages:
605 source: hosted
606 version: "3.1.0"
607 sdks:
545 - dart: ">=2.12.0 <3.0.0"
546 - flutter: ">=1.17.0"
608 + dart: ">=2.17.5 <3.0.0"
609 + flutter: ">=2.8.1"
cw_monero/pubspec.yaml
+12 -10
@@ -6,27 +6,29 @@ author: Cake Wallet
6 homepage: https://cakewallet.com
7
8 environment:
9 - sdk: ">=2.6.0 <3.0.0"
9 + sdk: ">=2.17.5 <3.0.0"
10 + flutter: ">=1.20.0"
11
12 dependencies:
13 flutter:
14 sdk: flutter
14 - ffi: ^0.1.3
15 - path_provider: ^1.4.0
16 - http: ^0.12.0+2
17 - mobx: ^1.2.1+2
18 - flutter_mobx: ^1.1.0+2
15 + ffi: ^1.1.2
16 + http: ^0.13.4
17 + path_provider: ^2.0.11
18 + mobx: ^2.0.7+4
19 + flutter_mobx: ^2.0.6+1
20 intl: ^0.17.0
21 + encrypt: ^5.0.1
22 cw_core:
23 path: ../cw_core
24
25 dev_dependencies:
26 flutter_test:
27 sdk: flutter
26 - build_runner: ^1.10.3
27 - build_resolvers: ^1.3.10
28 - mobx_codegen: ^1.1.0+1
29 - hive_generator: ^0.8.1
28 + build_runner: ^2.1.11
29 + build_resolvers: ^2.0.9
30 + mobx_codegen: ^2.0.7
31 + hive_generator: ^1.1.3
32
33 # For information on the generic Dart part of this file, see the
34 # following page: https://dart.dev/tools/pub/pubspec
ios/Podfile.lock
+39 -45
@@ -1,5 +1,5 @@
1 PODS:
2 - - barcode_scan (0.0.1):
2 + - barcode_scan2 (0.0.1):
3 - Flutter
4 - MTBBarcodeScanner
5 - SwiftProtobuf
@@ -98,22 +98,20 @@ PODS:
98 - DKPhotoGallery/Resource (0.0.17):
99 - SDWebImage
100 - SwiftyGif
101 - - esys_flutter_share (0.0.1):
102 - - Flutter
101 - file_picker (0.0.1):
102 - DKImagePickerController/PhotoGallery
103 - Flutter
104 - Flutter (1.0.0)
105 - flutter_secure_storage (3.3.1):
106 - Flutter
109 - - local_auth (0.0.1):
107 + - local_auth_ios (0.0.1):
108 - Flutter
109 - MTBBarcodeScanner (5.0.11)
110 - package_info (0.0.1):
111 - Flutter
114 - - path_provider (0.0.1):
112 + - path_provider_ios (0.0.1):
113 - Flutter
116 - - "permission_handler (5.1.0+2)":
114 + - permission_handler_apple (9.0.4):
115 - Flutter
116 - platform_device_id (0.0.1):
117 - Flutter
@@ -123,22 +121,22 @@ PODS:
121 - SDWebImage/Core (5.9.1)
122 - share (0.0.1):
123 - Flutter
126 - - shared_preferences (0.0.1):
124 + - shared_preferences_ios (0.0.1):
125 - Flutter
128 - - SwiftProtobuf (1.12.0)
126 + - SwiftProtobuf (1.18.0)
127 - SwiftyGif (5.3.0)
128 - uni_links (0.0.1):
129 - Flutter
130 - UnstoppableDomainsResolution (4.0.0):
131 - BigInt
132 - CryptoSwift
135 - - url_launcher (0.0.1):
133 + - url_launcher_ios (0.0.1):
134 - Flutter
137 - - webview_flutter (0.0.1):
135 + - webview_flutter_wkwebview (0.0.1):
136 - Flutter
137
138 DEPENDENCIES:
141 - - barcode_scan (from `.symlinks/plugins/barcode_scan/ios`)
139 + - barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`)
140 - connectivity (from `.symlinks/plugins/connectivity/ios`)
141 - CryptoSwift
142 - cw_haven (from `.symlinks/plugins/cw_haven/ios`)
@@ -147,21 +145,20 @@ DEPENDENCIES:
145 - device_display_brightness (from `.symlinks/plugins/device_display_brightness/ios`)
146 - device_info (from `.symlinks/plugins/device_info/ios`)
147 - devicelocale (from `.symlinks/plugins/devicelocale/ios`)
150 - - esys_flutter_share (from `.symlinks/plugins/esys_flutter_share/ios`)
148 - file_picker (from `.symlinks/plugins/file_picker/ios`)
149 - Flutter (from `Flutter`)
150 - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
154 - - local_auth (from `.symlinks/plugins/local_auth/ios`)
151 + - local_auth_ios (from `.symlinks/plugins/local_auth_ios/ios`)
152 - package_info (from `.symlinks/plugins/package_info/ios`)
156 - - path_provider (from `.symlinks/plugins/path_provider/ios`)
157 - - permission_handler (from `.symlinks/plugins/permission_handler/ios`)
153 + - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
154 + - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
155 - platform_device_id (from `.symlinks/plugins/platform_device_id/ios`)
156 - share (from `.symlinks/plugins/share/ios`)
160 - - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
157 + - shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`)
158 - uni_links (from `.symlinks/plugins/uni_links/ios`)
159 - UnstoppableDomainsResolution (~> 4.0.0)
163 - - url_launcher (from `.symlinks/plugins/url_launcher/ios`)
164 - - webview_flutter (from `.symlinks/plugins/webview_flutter/ios`)
160 + - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
161 + - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`)
162
163 SPEC REPOS:
164 https://github.com/CocoaPods/Specs.git:
@@ -177,8 +174,8 @@ SPEC REPOS:
174 - UnstoppableDomainsResolution
175
176 EXTERNAL SOURCES:
180 - barcode_scan:
181 - :path: ".symlinks/plugins/barcode_scan/ios"
177 + barcode_scan2:
178 + :path: ".symlinks/plugins/barcode_scan2/ios"
179 connectivity:
180 :path: ".symlinks/plugins/connectivity/ios"
181 cw_haven:
@@ -193,37 +190,35 @@ EXTERNAL SOURCES:
190 :path: ".symlinks/plugins/device_info/ios"
191 devicelocale:
192 :path: ".symlinks/plugins/devicelocale/ios"
196 - esys_flutter_share:
197 - :path: ".symlinks/plugins/esys_flutter_share/ios"
193 file_picker:
194 :path: ".symlinks/plugins/file_picker/ios"
195 Flutter:
196 :path: Flutter
197 flutter_secure_storage:
198 :path: ".symlinks/plugins/flutter_secure_storage/ios"
204 - local_auth:
205 - :path: ".symlinks/plugins/local_auth/ios"
199 + local_auth_ios:
200 + :path: ".symlinks/plugins/local_auth_ios/ios"
201 package_info:
202 :path: ".symlinks/plugins/package_info/ios"
208 - path_provider:
209 - :path: ".symlinks/plugins/path_provider/ios"
210 - permission_handler:
211 - :path: ".symlinks/plugins/permission_handler/ios"
203 + path_provider_ios:
204 + :path: ".symlinks/plugins/path_provider_ios/ios"
205 + permission_handler_apple:
206 + :path: ".symlinks/plugins/permission_handler_apple/ios"
207 platform_device_id:
208 :path: ".symlinks/plugins/platform_device_id/ios"
209 share:
210 :path: ".symlinks/plugins/share/ios"
216 - shared_preferences:
217 - :path: ".symlinks/plugins/shared_preferences/ios"
211 + shared_preferences_ios:
212 + :path: ".symlinks/plugins/shared_preferences_ios/ios"
213 uni_links:
214 :path: ".symlinks/plugins/uni_links/ios"
220 - url_launcher:
221 - :path: ".symlinks/plugins/url_launcher/ios"
222 - webview_flutter:
223 - :path: ".symlinks/plugins/webview_flutter/ios"
215 + url_launcher_ios:
216 + :path: ".symlinks/plugins/url_launcher_ios/ios"
217 + webview_flutter_wkwebview:
218 + :path: ".symlinks/plugins/webview_flutter_wkwebview/ios"
219
220 SPEC CHECKSUMS:
226 - barcode_scan: a5c27959edfafaa0c771905bad0b29d6d39e4479
221 + barcode_scan2: 0af2bb63c81b4565aab6cd78278e4c0fa136dbb0
222 BigInt: f668a80089607f521586bbe29513d708491ef2f7
223 connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467
224 CryptoSwift: 093499be1a94b0cae36e6c26b70870668cb56060
@@ -235,26 +230,25 @@ SPEC CHECKSUMS:
230 devicelocale: b22617f40038496deffba44747101255cee005b0
231 DKImagePickerController: b5eb7f7a388e4643264105d648d01f727110fc3d
232 DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
238 - esys_flutter_share: 403498dab005b36ce1f8d7aff377e81f0621b0b4
239 - file_picker: 3e6c3790de664ccf9b882732d9db5eaf6b8d4eb1
240 - Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
233 + file_picker: 817ab1d8cd2da9d2da412a417162deee3500fc95
234 + Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
235 flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
242 - local_auth: 25938960984c3a7f6e3253e3f8d962fdd16852bd
236 + local_auth_ios: 0d333dde7780f669e66f19d2ff6005f3ea84008d
237 MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
238 package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
245 - path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
246 - permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0
239 + path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02
240 + permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
241 platform_device_id: 81b3e2993881f87d0c82ef151dc274df4869aef5
242 Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
243 SDWebImage: a990c053fff71e388a10f3357edb0be17929c9c5
244 share: 0b2c3e82132f5888bccca3351c504d0003b3b410
251 - shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
252 - SwiftProtobuf: 4ef85479c18ca85b5482b343df9c319c62bda699
245 + shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad
246 + SwiftProtobuf: c3c12645230d9b09c72267e0de89468c5543bd86
247 SwiftyGif: e466e86c660d343357ab944a819a101c4127cb40
248 uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
249 UnstoppableDomainsResolution: c3c67f4d0a5e2437cb00d4bd50c2e00d6e743841
256 - url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef
257 - webview_flutter: 3603125dfd3bcbc9d8d418c3f80aeecf331c068b
250 + url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de
251 + webview_flutter_wkwebview: b7e70ef1ddded7e69c796c7390ee74180182971f
252
253 PODFILE CHECKSUM: ae71bdf0eb731a1ffc399c122f6aa4dea0cb5f6f
254
ios/Runner.xcodeproj/project.pbxproj
+7 -1
@@ -162,7 +162,7 @@
162 97C146E61CF9000F007C117D /* Project object */ = {
163 isa = PBXProject;
164 attributes = {
165 - LastUpgradeCheck = 1020;
165 + LastUpgradeCheck = 1300;
166 ORGANIZATIONNAME = "";
167 TargetAttributes = {
168 97C146ED1CF9000F007C117D = {
@@ -368,6 +368,7 @@
368 CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
369 CURRENT_PROJECT_VERSION = 3;
370 DEVELOPMENT_TEAM = 32J6BB6VUS;
371 + DISABLED_ARCHS = x86_64;
372 ENABLE_BITCODE = NO;
373 EXCLUDED_SOURCE_FILE_NAMES = "";
374 FRAMEWORK_SEARCH_PATHS = (
@@ -390,6 +391,7 @@
391 SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
392 SWIFT_VERSION = 5.0;
393 TARGETED_DEVICE_FAMILY = 1;
394 + VALID_ARCHS = arm64;
395 VERSIONING_SYSTEM = "apple-generic";
396 };
397 name = Profile;
@@ -512,6 +514,7 @@
514 CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
515 CURRENT_PROJECT_VERSION = 3;
516 DEVELOPMENT_TEAM = 32J6BB6VUS;
517 + DISABLED_ARCHS = x86_64;
518 ENABLE_BITCODE = NO;
519 EXCLUDED_SOURCE_FILE_NAMES = "";
520 FRAMEWORK_SEARCH_PATHS = (
@@ -535,6 +538,7 @@
538 SWIFT_OPTIMIZATION_LEVEL = "-Onone";
539 SWIFT_VERSION = 5.0;
540 TARGETED_DEVICE_FAMILY = 1;
541 + VALID_ARCHS = arm64;
542 VERSIONING_SYSTEM = "apple-generic";
543 };
544 name = Debug;
@@ -548,6 +552,7 @@
552 CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
553 CURRENT_PROJECT_VERSION = 3;
554 DEVELOPMENT_TEAM = 32J6BB6VUS;
555 + DISABLED_ARCHS = x86_64;
556 ENABLE_BITCODE = NO;
557 EXCLUDED_SOURCE_FILE_NAMES = "";
558 FRAMEWORK_SEARCH_PATHS = (
@@ -570,6 +575,7 @@
575 SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
576 SWIFT_VERSION = 5.0;
577 TARGETED_DEVICE_FAMILY = 1;
578 + VALID_ARCHS = arm64;
579 VERSIONING_SYSTEM = "apple-generic";
580 };
581 name = Release;
ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
+1 -1
@@ -1,6 +1,6 @@
1 <?xml version="1.0" encoding="UTF-8"?>
2 <Scheme
3 - LastUpgradeVersion = "1020"
3 + LastUpgradeVersion = "1300"
4 version = "1.3">
5 <BuildAction
6 parallelizeBuildables = "YES"
lib/anypay/any_pay_payment.dart
+12 -12
@@ -6,14 +6,14 @@ import 'package:cake_wallet/monero/monero.dart';
6
7 class AnyPayPayment {
8 AnyPayPayment({
9 - @required this.time,
10 - @required this.expires,
11 - @required this.memo,
12 - @required this.paymentUrl,
13 - @required this.paymentId,
14 - @required this.chain,
15 - @required this.network,
16 - @required this.instructions});
9 + required this.time,
10 + required this.expires,
11 + required this.memo,
12 + required this.paymentUrl,
13 + required this.paymentId,
14 + required this.chain,
15 + required this.network,
16 + required this.instructions});
17
18 factory AnyPayPayment.fromMap(Map<String, dynamic> obj) {
19 final instructions = (obj['instructions'] as List<dynamic>)
@@ -45,13 +45,13 @@ class AnyPayPayment {
45 .fold<int>(0, (int outAcc, out) => outAcc + out.amount));
46 switch (chain) {
47 case AnyPayChain.xmr:
48 - return monero.formatterMoneroAmountToString(amount: total);
48 + return monero!.formatterMoneroAmountToString(amount: total);
49 case AnyPayChain.btc:
50 - return bitcoin.formatterBitcoinAmountToString(amount: total);
50 + return bitcoin!.formatterBitcoinAmountToString(amount: total);
51 case AnyPayChain.ltc:
52 - return bitcoin.formatterBitcoinAmountToString(amount: total);
52 + return bitcoin!.formatterBitcoinAmountToString(amount: total);
53 default:
54 - return null;
54 + return '';
55 }
56 }
57
lib/anypay/any_pay_payment_committed_info.dart
+5 -5
@@ -3,11 +3,11 @@ import 'package:cake_wallet/anypay/any_pay_trasnaction.dart';
3
4 class AnyPayPaymentCommittedInfo {
5 const AnyPayPaymentCommittedInfo({
6 - @required this.uri,
7 - @required this.currency,
8 - @required this.chain,
9 - @required this.transactions,
10 - @required this.memo});
6 + required this.uri,
7 + required this.currency,
8 + required this.chain,
9 + required this.transactions,
10 + required this.memo});
11
12 final String uri;
13 final String currency;
lib/anypay/any_pay_payment_instruction.dart
+5 -5
@@ -3,11 +3,11 @@ import 'package:cake_wallet/anypay/any_pay_payment_instruction_output.dart';
3
4 class AnyPayPaymentInstruction {
5 AnyPayPaymentInstruction({
6 - @required this.type,
7 - @required this.requiredFeeRate,
8 - @required this.txKey,
9 - @required this.txHash,
10 - @required this.outputs});
6 + required this.type,
7 + required this.requiredFeeRate,
8 + required this.txKey,
9 + required this.txHash,
10 + required this.outputs});
11
12 factory AnyPayPaymentInstruction.fromMap(Map<String, dynamic> obj) {
13 final outputs = (obj['outputs'] as List<dynamic>)
lib/anypay/any_pay_trasnaction.dart
+2 -4
@@ -1,9 +1,7 @@
1 -import 'package:flutter/foundation.dart';
2 -
1 class AnyPayTransaction {
4 - const AnyPayTransaction(this.tx, {@required this.id, @required this.key});
2 + const AnyPayTransaction(this.tx, {required this.id, required this.key});
3
4 final String tx;
5 final String id;
8 - final String key;
6 + final String? key;
7 }
\ No newline at end of file
lib/anypay/anypay_api.dart
+12 -12
@@ -33,15 +33,15 @@ class AnyPayApi {
33 case 'litecoin':
34 return CryptoCurrency.ltc;
35 default:
36 - return null;
36 + throw Exception('Unexpected scheme: ${scheme}');
37 }
38 }
39
40 Future<AnyPayPayment> paymentRequest(String uri) async {
41 final fragments = uri.split(':?r=');
42 final scheme = fragments.first;
43 - final url = fragments[1];
44 - final headers = <String, String>{
43 + final url = Uri.parse(fragments[1]);
44 + final headers = <String, String>{
45 'Content-Type': contentTypePaymentRequest,
46 'X-Paypro-Version': xPayproVersion,
47 'Accept': '*/*',};
@@ -50,20 +50,20 @@ class AnyPayApi {
50 'currency': currencyByScheme(scheme).title};
51 final response = await post(url, headers: headers, body: utf8.encode(json.encode(body)));
52
53 - if (response.statusCode != 200) {
54 - return null;
53 + if (response.statusCode != 200) {
54 + throw Exception('Unexpected response http code: ${response.statusCode}');
55 }
56
57 - final decodedBody = json.decode(response.body) as Map<String, dynamic>;
58 - return AnyPayPayment.fromMap(decodedBody);
57 + final decodedBody = json.decode(response.body) as Map<String, dynamic>;
58 + return AnyPayPayment.fromMap(decodedBody);
59 }
60
61 Future<AnyPayPaymentCommittedInfo> payment(
62 String uri,
63 - {@required String chain,
64 - @required String currency,
65 - @required List<AnyPayTransaction> transactions}) async {
66 - final headers = <String, String>{
63 + {required String chain,
64 + required String currency,
65 + required List<AnyPayTransaction> transactions}) async {
66 + final headers = <String, String>{
67 'Content-Type': contentTypePayment,
68 'X-Paypro-Version': xPayproVersion,
69 'Accept': '*/*',};
@@ -71,7 +71,7 @@ class AnyPayApi {
71 'chain': chain,
72 'currency': currency,
73 'transactions': transactions.map((tx) => {'tx': tx.tx, 'tx_hash': tx.id, 'tx_key': tx.key}).toList()};
74 - final response = await post(uri, headers: headers, body: utf8.encode(json.encode(body)));
74 + final response = await post(Uri.parse(uri), headers: headers, body: utf8.encode(json.encode(body)));
75 if (response.statusCode == 400) {
76 final decodedBody = json.decode(response.body) as Map<String, dynamic>;
77 throw Exception(decodedBody['message'] as String);
lib/bitcoin/cw_bitcoin.dart
+16 -7
@@ -5,15 +5,24 @@ class CWBitcoin extends Bitcoin {
5 TransactionPriority getMediumTransactionPriority() => BitcoinTransactionPriority.medium;
6
7 @override
8 - WalletCredentials createBitcoinRestoreWalletFromSeedCredentials({String name, String mnemonic, String password})
8 + WalletCredentials createBitcoinRestoreWalletFromSeedCredentials({
9 + required String name,
10 + required String mnemonic,
11 + required String password})
12 => BitcoinRestoreWalletFromSeedCredentials(name: name, mnemonic: mnemonic, password: password);
13
14 @override
12 - WalletCredentials createBitcoinRestoreWalletFromWIFCredentials({String name, String password, String wif, WalletInfo walletInfo})
15 + WalletCredentials createBitcoinRestoreWalletFromWIFCredentials({
16 + required String name,
17 + required String password,
18 + required String wif,
19 + WalletInfo? walletInfo})
20 => BitcoinRestoreWalletFromWIFCredentials(name: name, password: password, wif: wif, walletInfo: walletInfo);
21
22 @override
16 - WalletCredentials createBitcoinNewWalletCredentials({String name, WalletInfo walletInfo})
23 + WalletCredentials createBitcoinNewWalletCredentials({
24 + required String name,
25 + WalletInfo? walletInfo})
26 => BitcoinNewWalletCredentials(name: name, walletInfo: walletInfo);
27
28 @override
@@ -55,7 +64,7 @@ class CWBitcoin extends Bitcoin {
64 }
65
66 @override
58 - Object createBitcoinTransactionCredentials(List<Output> outputs, {TransactionPriority priority, int feeRate})
67 + Object createBitcoinTransactionCredentials(List<Output> outputs, {required TransactionPriority priority, int? feeRate})
68 => BitcoinTransactionCredentials(
69 outputs.map((out) => OutputInfo(
70 fiatAmount: out.fiatAmount,
@@ -71,7 +80,7 @@ class CWBitcoin extends Bitcoin {
80 feeRate: feeRate);
81
82 @override
74 - Object createBitcoinTransactionCredentialsRaw(List<OutputInfo> outputs, {TransactionPriority priority, int feeRate})
83 + Object createBitcoinTransactionCredentialsRaw(List<OutputInfo> outputs, {TransactionPriority? priority, required int feeRate})
84 => BitcoinTransactionCredentials(
85 outputs,
86 priority: priority != null ? priority as BitcoinTransactionPriority : null,
@@ -92,11 +101,11 @@ class CWBitcoin extends Bitcoin {
101 }
102
103 @override
95 - String formatterBitcoinAmountToString({int amount})
104 + String formatterBitcoinAmountToString({required int amount})
105 => bitcoinAmountToString(amount: amount);
106
107 @override
99 - double formatterBitcoinAmountToDouble({int amount})
108 + double formatterBitcoinAmountToDouble({required int amount})
109 => bitcoinAmountToDouble(amount: amount);
110
111 @override
lib/buy/buy_amount.dart
+3 -3
@@ -2,13 +2,13 @@ import 'package:flutter/foundation.dart';
2
3 class BuyAmount {
4 BuyAmount({
5 - @required this.sourceAmount,
6 - @required this.destAmount,
5 + required this.sourceAmount,
6 + required this.destAmount,
7 this.achSourceAmount,
8 this.minAmount = 0});
9
10 final double sourceAmount;
11 final double destAmount;
12 - final double achSourceAmount;
12 + final double? achSourceAmount;
13 final int minAmount;
14 }
\ No newline at end of file
lib/buy/buy_exception.dart
+1 -1
@@ -2,7 +2,7 @@ import 'package:flutter/foundation.dart';
2 import 'package:cake_wallet/buy/buy_provider_description.dart';
3
4 class BuyException implements Exception {
5 - BuyException({@required this.description, @required this.text});
5 + BuyException({required this.description, required this.text});
6
7 final BuyProviderDescription description;
8 final String text;
lib/buy/buy_provider.dart
+1 -1
@@ -5,7 +5,7 @@ import 'package:cw_core/wallet_base.dart';
5 import 'package:cw_core/wallet_type.dart';
6
7 abstract class BuyProvider {
8 - BuyProvider({this.wallet, this.isTestEnvironment});
8 + BuyProvider({required this.wallet, required this.isTestEnvironment});
9
10 final WalletBase wallet;
11 final bool isTestEnvironment;
lib/buy/buy_provider_description.dart
+3 -3
@@ -2,20 +2,20 @@ import 'package:cw_core/enumerable_item.dart';
2
3 class BuyProviderDescription extends EnumerableItem<int>
4 with Serializable<int> {
5 - const BuyProviderDescription({String title, int raw})
5 + const BuyProviderDescription({required String title, required int raw})
6 : super(title: title, raw: raw);
7
8 static const wyre = BuyProviderDescription(title: 'Wyre', raw: 0);
9 static const moonPay = BuyProviderDescription(title: 'MoonPay', raw: 1);
10
11 - static BuyProviderDescription deserialize({int raw}) {
11 + static BuyProviderDescription deserialize({required int raw}) {
12 switch (raw) {
13 case 0:
14 return wyre;
15 case 1:
16 return moonPay;
17 default:
18 - return null;
18 + throw Exception('Incorrect token $raw for BuyProviderDescription deserialize');
19 }
20 }
21 }
\ No newline at end of file
lib/buy/get_buy_provider_icon.dart
+1 -1
@@ -1,7 +1,7 @@
1 import 'package:flutter/material.dart';
2 import 'package:cake_wallet/buy/buy_provider_description.dart';
3
4 -Image getBuyProviderIcon(BuyProviderDescription providerDescription,
4 +Image? getBuyProviderIcon(BuyProviderDescription providerDescription,
5 {Color iconColor = Colors.black}) {
6
7 final _wyreIcon =
lib/buy/moonpay/moonpay_buy_provider.dart
+10 -11
@@ -23,7 +23,7 @@ class MoonPaySellProvider {
23 final bool isTest;
24 final String baseUrl;
25
26 - Future<String> requestUrl({CryptoCurrency currency, String refundWalletAddress}) async {
26 + Future<String> requestUrl({required CryptoCurrency currency, required String refundWalletAddress}) async {
27 final originalUri = Uri.https(
28 baseUrl, '', <String, dynamic>{
29 'apiKey': _apiKey,
@@ -48,10 +48,9 @@ class MoonPaySellProvider {
48 }
49
50 class MoonPayBuyProvider extends BuyProvider {
51 - MoonPayBuyProvider({WalletBase wallet, bool isTestEnvironment = false})
52 - : super(wallet: wallet, isTestEnvironment: isTestEnvironment) {
53 - baseUrl = isTestEnvironment ? _baseTestUrl : _baseProductUrl;
54 - }
51 + MoonPayBuyProvider({required WalletBase wallet, bool isTestEnvironment = false})
52 + : baseUrl = isTestEnvironment ? _baseTestUrl : _baseProductUrl,
53 + super(wallet: wallet, isTestEnvironment: isTestEnvironment);
54
55 static const _baseTestUrl = 'https://buy-staging.moonpay.com';
56 static const _baseProductUrl = 'https://buy.moonpay.com';
@@ -109,8 +108,8 @@ class MoonPayBuyProvider extends BuyProvider {
108 _quoteSuffix + '/?apiKey=' + _apiKey +
109 '&baseCurrencyAmount=' + amount +
110 '&baseCurrencyCode=' + sourceCurrency.toLowerCase();
112 -
113 - final response = await get(url);
111 + final uri = Uri.parse(url);
112 + final response = await get(uri);
113
114 if (response.statusCode != 200) {
115 throw BuyException(
@@ -133,8 +132,8 @@ class MoonPayBuyProvider extends BuyProvider {
132 Future<Order> findOrderById(String id) async {
133 final url = _apiUrl + _transactionsSuffix + '/$id' +
134 '?apiKey=' + _apiKey;
136 -
137 - final response = await get(url);
135 + final uri = Uri.parse(url);
136 + final response = await get(uri);
137
138 if (response.statusCode != 200) {
139 throw BuyException(
@@ -164,8 +163,8 @@ class MoonPayBuyProvider extends BuyProvider {
163 static Future<bool> onEnabled() async {
164 final url = _apiUrl + _ipAddressSuffix + '?apiKey=' + _apiKey;
165 var isBuyEnable = false;
167 -
168 - final response = await get(url);
166 + final uri = Uri.parse(url);
167 + final response = await get(uri);
168
169 try {
170 final responseJSON = json.decode(response.body) as Map<String, dynamic>;
lib/buy/order.dart
+20 -15
@@ -8,18 +8,23 @@ part 'order.g.dart';
8 @HiveType(typeId: Order.typeId)
9 class Order extends HiveObject {
10 Order(
11 - {this.id,
12 - BuyProviderDescription provider,
13 - this.transferId,
11 + {required this.id,
12 + required this.transferId,
13 + required this.createdAt,
14 + required this.amount,
15 + required this.receiveAddress,
16 + required this.walletId,
17 + BuyProviderDescription? provider,
18 + TradeState? state,
19 this.from,
15 - this.to,
16 - TradeState state,
17 - this.createdAt,
18 - this.amount,
19 - this.receiveAddress,
20 - this.walletId})
21 - : providerRaw = provider?.raw,
22 - stateRaw = state?.raw;
20 + this.to}) {
21 + if (provider != null) {
22 + providerRaw = provider.raw;
23 + }
24 + if (state != null) {
25 + stateRaw = state.raw;
26 + }
27 + }
28
29 static const typeId = 8;
30 static const boxName = 'Orders';
@@ -32,13 +37,13 @@ class Order extends HiveObject {
37 String transferId;
38
39 @HiveField(2)
35 - String from;
40 + String? from;
41
42 @HiveField(3)
38 - String to;
43 + String? to;
44
45 @HiveField(4)
41 - String stateRaw;
46 + late String stateRaw;
47
48 TradeState get state => TradeState.deserialize(raw: stateRaw);
49
@@ -55,7 +60,7 @@ class Order extends HiveObject {
60 String walletId;
61
62 @HiveField(9)
58 - int providerRaw;
63 + late int providerRaw;
64
65 BuyProviderDescription get provider =>
66 BuyProviderDescription.deserialize(raw: providerRaw);
lib/buy/wyre/wyre_buy_provider.dart
+12 -11
@@ -11,12 +11,11 @@ import 'package:cake_wallet/exchange/trade_state.dart';
11 import 'package:cake_wallet/.secrets.g.dart' as secrets;
12
13 class WyreBuyProvider extends BuyProvider {
14 - WyreBuyProvider({WalletBase wallet, bool isTestEnvironment = false})
15 - : super(wallet: wallet, isTestEnvironment: isTestEnvironment) {
16 - baseApiUrl = isTestEnvironment
14 + WyreBuyProvider({required WalletBase wallet, bool isTestEnvironment = false})
15 + : baseApiUrl = isTestEnvironment
16 ? _baseTestApiUrl
18 - : _baseProductApiUrl;
19 - }
17 + : _baseProductApiUrl,
18 + super(wallet: wallet, isTestEnvironment: isTestEnvironment);
19
20 static const _baseTestApiUrl = 'https://api.testwyre.com';
21 static const _baseProductApiUrl = 'https://api.sendwyre.com';
@@ -50,6 +49,7 @@ class WyreBuyProvider extends BuyProvider {
49 final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
50 final url = baseApiUrl + _ordersSuffix + _reserveSuffix +
51 _timeStampSuffix + timestamp;
52 + final uri = Uri.parse(url);
53 final body = {
54 'amount': amount,
55 'sourceCurrency': sourceCurrency,
@@ -58,8 +58,7 @@ class WyreBuyProvider extends BuyProvider {
58 'referrerAccountId': _accountId,
59 'lockFields': ['amount', 'sourceCurrency', 'destCurrency', 'dest']
60 };
61 -
62 - final response = await post(url,
61 + final response = await post(uri,
62 headers: {
63 'Authorization': 'Bearer $_secretKey',
64 'Content-Type': 'application/json',
@@ -89,8 +88,8 @@ class WyreBuyProvider extends BuyProvider {
88 'accountId': _accountId,
89 'country': _countryCode
90 };
92 -
93 - final response = await post(quoteUrl,
91 + final uri = Uri.parse(quoteUrl);
92 + final response = await post(uri,
93 headers: {
94 'Authorization': 'Bearer $_secretKey',
95 'Content-Type': 'application/json',
@@ -115,7 +114,8 @@ class WyreBuyProvider extends BuyProvider {
114 @override
115 Future<Order> findOrderById(String id) async {
116 final orderUrl = baseApiUrl + _ordersSuffix + '/$id';
118 - final orderResponse = await get(orderUrl);
117 + final orderUri = Uri.parse(orderUrl);
118 + final orderResponse = await get(orderUri);
119
120 if (orderResponse.statusCode != 200) {
121 throw BuyException(
@@ -136,7 +136,8 @@ class WyreBuyProvider extends BuyProvider {
136
137 final transferUrl =
138 baseApiUrl + _transferSuffix + transferId + _trackSuffix;
139 - final transferResponse = await get(transferUrl);
139 + final transferUri = Uri.parse(transferUrl);
140 + final transferResponse = await get(transferUri);
141
142 if (transferResponse.statusCode != 200) {
143 throw BuyException(
lib/core/address_label_validator.dart
+1 -1
@@ -3,7 +3,7 @@ import 'package:cake_wallet/generated/i18n.dart';
3 import 'package:cw_core/wallet_type.dart';
4
5 class AddressLabelValidator extends TextValidator {
6 - AddressLabelValidator({WalletType type})
6 + AddressLabelValidator({WalletType? type})
7 : super(
8 errorMessage: S.current.error_text_subaddress_name,
9 pattern: '''^[^`,'"]{1,20}\$''',
lib/core/address_validator.dart
+2 -2
@@ -4,7 +4,7 @@ import 'package:cake_wallet/core/validator.dart';
4 import 'package:cw_core/crypto_currency.dart';
5
6 class AddressValidator extends TextValidator {
7 - AddressValidator({@required CryptoCurrency type})
7 + AddressValidator({required CryptoCurrency type})
8 : super(
9 errorMessage: S.current.error_text_address,
10 pattern: getPattern(type),
@@ -79,7 +79,7 @@ class AddressValidator extends TextValidator {
79 }
80 }
81
82 - static List<int> getLength(CryptoCurrency type) {
82 + static List<int>? getLength(CryptoCurrency type) {
83 switch (type) {
84 case CryptoCurrency.xmr:
85 return null;
lib/core/amount.dart
+27 -27
@@ -1,37 +1,37 @@
1 -abstract class Amount {
2 - Amount(this.value);
1 +// abstract class Amount {
2 +// Amount(this.value);
3
4 - int value;
4 +// int value;
5
6 - int minorDigits;
6 +// int minorDigits;
7
8 - String code;
8 +// String code;
9
10 - String formatted();
11 -}
10 +// String formatted();
11 +// }
12
13 -class MoneroAmount extends Amount {
14 - MoneroAmount(int value) : super(value) {
15 - minorDigits = 12;
16 - code = 'XMR';
17 - }
13 +// class MoneroAmount extends Amount {
14 +// MoneroAmount(int value) : super(value) {
15 +// minorDigits = 12;
16 +// code = 'XMR';
17 +// }
18
19 - // const moneroAmountLength = 12;
20 - // const moneroAmountDivider = 1000000000000;
21 - // final moneroAmountFormat = NumberFormat()
22 - // ..maximumFractionDigits = moneroAmountLength
23 - // ..minimumFractionDigits = 1;
19 +// // const moneroAmountLength = 12;
20 +// // const moneroAmountDivider = 1000000000000;
21 +// // final moneroAmountFormat = NumberFormat()
22 +// // ..maximumFractionDigits = moneroAmountLength
23 +// // ..minimumFractionDigits = 1;
24
25 - // String moneroAmountToString({int amount}) =>
26 - // moneroAmountFormat.format(cryptoAmountToDouble(amount: amount, divider: moneroAmountDivider));
25 +// // String moneroAmountToString({int amount}) =>
26 +// // moneroAmountFormat.format(cryptoAmountToDouble(amount: amount, divider: moneroAmountDivider));
27
28 - // double moneroAmountToDouble({int amount}) => cryptoAmountToDouble(amount: amount, divider: moneroAmountDivider);
28 +// // double moneroAmountToDouble({int amount}) => cryptoAmountToDouble(amount: amount, divider: moneroAmountDivider);
29
30 - // int moneroParseAmount({String amount}) => moneroAmountFormat.parse(amount).toInt();
30 +// // int moneroParseAmount({String amount}) => moneroAmountFormat.parse(amount).toInt();
31
32 - @override
33 - String formatted() {
34 - // TODO: implement formatted
35 - throw UnimplementedError();
36 - }
37 -}
32 +// @override
33 +// String formatted() {
34 +// // TODO: implement formatted
35 +// throw UnimplementedError();
36 +// }
37 +// }
lib/core/amount_converter.dart
+4 -4
@@ -47,7 +47,7 @@ class AmountConverter {
47 case CryptoCurrency.xusd:
48 return _moneroAmountToDouble(amount);
49 default:
50 - return null;
50 + return 0.0;
51 }
52 }
53
@@ -71,7 +71,7 @@ class AmountConverter {
71 case CryptoCurrency.xusd:
72 return _moneroParseAmount(amount);
73 default:
74 - return null;
74 + return 0;
75 }
76 }
77
@@ -97,11 +97,11 @@ class AmountConverter {
97 case CryptoCurrency.xusd:
98 return _moneroAmountToString(amount);
99 default:
100 - return null;
100 + return '';
101 }
102 }
103
104 - static double cryptoAmountToDouble({num amount, num divider}) =>
104 + static double cryptoAmountToDouble({required num amount, required num divider}) =>
105 amount / divider;
106
107 static String _moneroAmountToString(int amount) => _moneroAmountFormat.format(
lib/core/amount_validator.dart
+1 -1
@@ -3,7 +3,7 @@ import 'package:cake_wallet/generated/i18n.dart';
3 import 'package:cw_core/wallet_type.dart';
4
5 class AmountValidator extends TextValidator {
6 - AmountValidator({WalletType type, bool isAutovalidate = false})
6 + AmountValidator({required WalletType type, bool isAutovalidate = false})
7 : super(
8 errorMessage: S.current.error_text_amount,
9 pattern: _pattern(type),
lib/core/auth_service.dart
+4 -4
@@ -6,12 +6,12 @@ import 'package:cake_wallet/entities/secret_store_key.dart';
6 import 'package:cake_wallet/entities/encrypt.dart';
7
8 class AuthService with Store {
9 - AuthService({this.secureStorage, this.sharedPreferences});
9 + AuthService({required this.secureStorage, required this.sharedPreferences});
10
11 final FlutterSecureStorage secureStorage;
12 final SharedPreferences sharedPreferences;
13
14 - Future setPassword(String password) async {
14 + Future<void> setPassword(String password) async {
15 final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
16 final encodedPassword = encodedPinCode(pin: password);
17 await secureStorage.write(key: key, value: encodedPassword);
@@ -24,7 +24,7 @@ class AuthService with Store {
24 var password = '';
25
26 try {
27 - password = await secureStorage.read(key: key);
27 + password = await secureStorage.read(key: key) ?? '';
28 } catch (e) {
29 print(e);
30 }
@@ -35,7 +35,7 @@ class AuthService with Store {
35 Future<bool> authenticate(String pin) async {
36 final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
37 final encodedPin = await secureStorage.read(key: key);
38 - final decodedPin = decodedPinCode(pin: encodedPin);
38 + final decodedPin = decodedPinCode(pin: encodedPin!);
39
40 return decodedPin == pin;
41 }
lib/core/auth_state.dart
+2 -2
@@ -7,13 +7,13 @@ class AuthenticationInProgress extends AuthState {}
7 class AuthenticatedSuccessfully extends AuthState {}
8
9 class AuthenticationFailure extends AuthState {
10 - AuthenticationFailure({this.error});
10 + AuthenticationFailure({required this.error});
11
12 final String error;
13 }
14
15 class AuthenticationBanned extends AuthState {
16 - AuthenticationBanned({this.error});
16 + AuthenticationBanned({required this.error});
17
18 final String error;
19 }
lib/core/backup_service.dart
+43 -32
@@ -20,7 +20,8 @@ import 'package:cake_wallet/wallet_types.g.dart';
20 class BackupService {
21 BackupService(this._flutterSecureStorage, this._walletInfoSource,
22 this._keyService, this._sharedPreferences)
23 - : _cipher = chacha20Poly1305Aead;
23 + : _cipher = Cryptography.instance.chacha20Poly1305Aead(),
24 + _correctWallets = <WalletInfo>[];
25
26 static const currentVersion = _v1;
27
@@ -54,7 +55,7 @@ class BackupService {
55 case _v1:
56 return await _exportBackupV1(password, nonce: nonce);
57 default:
57 - return null;
58 + throw Exception('Incorrect version: $version for exportBackup');
59 }
60 }
61
@@ -91,8 +92,8 @@ class BackupService {
92 });
93 await keychainDumpFile.writeAsBytes(keychainDump.toList());
94 await preferencesDumpFile.writeAsString(preferencesDump);
94 - zipEncoder.addFile(preferencesDumpFile, '~_preferences_dump');
95 - zipEncoder.addFile(keychainDumpFile, '~_keychain_dump');
95 + await zipEncoder.addFile(preferencesDumpFile, '~_preferences_dump');
96 + await zipEncoder.addFile(keychainDumpFile, '~_keychain_dump');
97 zipEncoder.close();
98
99 final content = File(archivePath).readAsBytesSync();
@@ -103,7 +104,7 @@ class BackupService {
104 }
105
106 Future<void> _importBackupV1(Uint8List data, String password,
106 - {@required String nonce}) async {
107 + {required String nonce}) async {
108 final appDir = await getApplicationDocumentsDirectory();
109 final decryptedData = await _decrypt(data, password, nonce);
110 final zip = ZipDecoder().decodeBytes(decryptedData);
@@ -214,7 +215,7 @@ class BackupService {
215 }
216
217 Future<void> _importKeychainDump(String password,
217 - {@required String nonce,
218 + {required String nonce,
219 String keychainSalt = secrets.backupKeychainSalt}) async {
220 final appDir = await getApplicationDocumentsDirectory();
221 final keychainDumpFile = File('${appDir.path}/~_keychain_dump');
@@ -251,11 +252,11 @@ class BackupService {
252 }
253
254 Future<Uint8List> _exportKeychainDump(String password,
254 - {@required String nonce,
255 + {required String nonce,
256 String keychainSalt = secrets.backupKeychainSalt}) async {
257 final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
258 final encodedPin = await _flutterSecureStorage.read(key: key);
258 - final decodedPin = decodedPinCode(pin: encodedPin);
259 + final decodedPin = decodedPinCode(pin: encodedPin!);
260 final wallets =
261 await Future.wait(_walletInfoSource.values.map((walletInfo) async {
262 return {
@@ -281,41 +282,42 @@ class BackupService {
282 }
283
284 Future<String> _exportPreferencesJSON() async {
285 + // FIX-ME: Force unwrap
286 final preferences = <String, Object>{
287 PreferencesKey.currentWalletName:
286 - _sharedPreferences.getString(PreferencesKey.currentWalletName),
288 + _sharedPreferences.getString(PreferencesKey.currentWalletName)!,
289 PreferencesKey.currentNodeIdKey:
288 - _sharedPreferences.getInt(PreferencesKey.currentNodeIdKey),
290 + _sharedPreferences.getInt(PreferencesKey.currentNodeIdKey)!,
291 PreferencesKey.currentBalanceDisplayModeKey: _sharedPreferences
290 - .getInt(PreferencesKey.currentBalanceDisplayModeKey),
292 + .getInt(PreferencesKey.currentBalanceDisplayModeKey)!,
293 PreferencesKey.currentWalletType:
292 - _sharedPreferences.getInt(PreferencesKey.currentWalletType),
294 + _sharedPreferences.getInt(PreferencesKey.currentWalletType)!,
295 PreferencesKey.currentFiatCurrencyKey:
294 - _sharedPreferences.getString(PreferencesKey.currentFiatCurrencyKey),
296 + _sharedPreferences.getString(PreferencesKey.currentFiatCurrencyKey)!,
297 PreferencesKey.shouldSaveRecipientAddressKey: _sharedPreferences
296 - .getBool(PreferencesKey.shouldSaveRecipientAddressKey),
298 + .getBool(PreferencesKey.shouldSaveRecipientAddressKey)!,
299 PreferencesKey.isDarkThemeLegacy:
298 - _sharedPreferences.getBool(PreferencesKey.isDarkThemeLegacy),
300 + _sharedPreferences.getBool(PreferencesKey.isDarkThemeLegacy)!,
301 PreferencesKey.currentPinLength:
300 - _sharedPreferences.getInt(PreferencesKey.currentPinLength),
302 + _sharedPreferences.getInt(PreferencesKey.currentPinLength)!,
303 PreferencesKey.currentTransactionPriorityKeyLegacy: _sharedPreferences
302 - .getInt(PreferencesKey.currentTransactionPriorityKeyLegacy),
304 + .getInt(PreferencesKey.currentTransactionPriorityKeyLegacy)!,
305 PreferencesKey.allowBiometricalAuthenticationKey: _sharedPreferences
304 - .getBool(PreferencesKey.allowBiometricalAuthenticationKey),
306 + .getBool(PreferencesKey.allowBiometricalAuthenticationKey)!,
307 PreferencesKey.currentBitcoinElectrumSererIdKey: _sharedPreferences
306 - .getInt(PreferencesKey.currentBitcoinElectrumSererIdKey),
308 + .getInt(PreferencesKey.currentBitcoinElectrumSererIdKey)!,
309 PreferencesKey.currentLanguageCode:
308 - _sharedPreferences.getString(PreferencesKey.currentLanguageCode),
310 + _sharedPreferences.getString(PreferencesKey.currentLanguageCode)!,
311 PreferencesKey.displayActionListModeKey:
310 - _sharedPreferences.getInt(PreferencesKey.displayActionListModeKey),
312 + _sharedPreferences.getInt(PreferencesKey.displayActionListModeKey)!,
313 PreferencesKey.currentTheme:
312 - _sharedPreferences.getInt(PreferencesKey.currentTheme),
314 + _sharedPreferences.getInt(PreferencesKey.currentTheme)!,
315 PreferencesKey.currentDefaultSettingsMigrationVersion: _sharedPreferences
314 - .getInt(PreferencesKey.currentDefaultSettingsMigrationVersion),
316 + .getInt(PreferencesKey.currentDefaultSettingsMigrationVersion)!,
317 PreferencesKey.bitcoinTransactionPriority:
316 - _sharedPreferences.getInt(PreferencesKey.bitcoinTransactionPriority),
318 + _sharedPreferences.getInt(PreferencesKey.bitcoinTransactionPriority)!,
319 PreferencesKey.moneroTransactionPriority:
318 - _sharedPreferences.getInt(PreferencesKey.moneroTransactionPriority),
320 + _sharedPreferences.getInt(PreferencesKey.moneroTransactionPriority)!,
321 };
322
323 return json.encode(preferences);
@@ -330,17 +332,26 @@ class BackupService {
332
333 Future<Uint8List> _encrypt(
334 Uint8List data, String secretKeySource, String nonceBase64) async {
333 - final secretKeyHash = await sha256.hash(utf8.encode(secretKeySource));
335 + final secretKeyHash = await Cryptography.instance.sha256().hash(utf8.encode(secretKeySource));
336 final secretKey = SecretKey(secretKeyHash.bytes);
335 - final nonce = Nonce(base64.decode(nonceBase64));
336 - return await _cipher.encrypt(data, secretKey: secretKey, nonce: nonce);
337 + final nonce = base64.decode(nonceBase64).toList();
338 + final box = await _cipher.encrypt(data.toList(), secretKey: secretKey, nonce: nonce);
339 + return Uint8List.fromList(box.cipherText);
340 }
341
342 Future<Uint8List> _decrypt(
343 Uint8List data, String secretKeySource, String nonceBase64) async {
341 - final secretKeyHash = await sha256.hash(utf8.encode(secretKeySource));
342 - final secretKey = SecretKey(secretKeyHash.bytes);
343 - final nonce = Nonce(base64.decode(nonceBase64));
344 - return await _cipher.decrypt(data, secretKey: secretKey, nonce: nonce);
344 + throw Exception('Unimplemented');
345 + //final secretKeyHash = await sha256.hash(utf8.encode(secretKeySource));
346 + //final secretKey = SecretKey(secretKeyHash.bytes);
347 + //final nonce = Nonce(base64.decode(nonceBase64));
348 + //return await _cipher.decrypt(data, secretKey: secretKey, nonce: nonce);
349 +
350 + // final secretKeyHash = await Cryptography.instance.sha256().hash(utf8.encode(secretKeySource));
351 + // final secretKey = SecretKey(secretKeyHash.bytes);
352 + // final nonce = base64.decode(nonceBase64).toList();
353 + // final box = SecretBox(data.toList(), nonce: nonce, mac: Mac);
354 + // final plainData = await _cipher.decrypt(box, secretKey: secretKey);
355 + // return Uint8List.fromList(plainData);
356 }
357 }
lib/core/fiat_conversion_service.dart
+1 -1
@@ -16,7 +16,7 @@ Future<double> _fetchPrice(Map<String, dynamic> args) async {
16 final fiatStringified = fiat.toString();
17 final uri = Uri.https(fiatApiAuthority, fiatApiPath,
18 <String, String>{'convert': fiatStringified});
19 - final response = await get(uri.toString());
19 + final response = await get(uri);
20
21 if (response.statusCode != 200) {
22 return 0.0;
lib/core/key_service.dart
+3 -4
@@ -7,15 +7,14 @@ class KeyService {
7
8 final FlutterSecureStorage _secureStorage;
9
10 - Future<String> getWalletPassword({String walletName}) async {
10 + Future<String> getWalletPassword({required String walletName}) async {
11 final key = generateStoreKeyFor(
12 key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
13 final encodedPassword = await _secureStorage.read(key: key);
14 -
15 - return decodeWalletPassword(password: encodedPassword);
14 + return decodeWalletPassword(password: encodedPassword!);
15 }
16
18 - Future<void> saveWalletPassword({String walletName, String password}) async {
17 + Future<void> saveWalletPassword({required String walletName, required String password}) async {
18 final key = generateStoreKeyFor(
19 key: SecretStoreKey.moneroWalletPassword, walletName: walletName);
20 final encodedPassword = encodeWalletPassword(password: password);
lib/core/monero_account_label_validator.dart
+1 -1
@@ -4,7 +4,7 @@ import 'package:cake_wallet/core/validator.dart';
4 import 'package:cw_core/crypto_currency.dart';
5
6 class MoneroLabelValidator extends TextValidator {
7 - MoneroLabelValidator({@required CryptoCurrency type})
7 + MoneroLabelValidator()
8 : super(
9 errorMessage: S.current.error_text_account_name,
10 pattern: '^[a-zA-Z0-9_ ]{1,15}\$',
lib/core/seed_validator.dart
+8 -7
@@ -7,23 +7,24 @@ import 'package:cake_wallet/monero/monero.dart';
7 import 'package:cake_wallet/utils/language_list.dart';
8
9 class SeedValidator extends Validator<MnemonicItem> {
10 - SeedValidator({this.type, this.language})
11 - : _words = getWordList(type: type, language: language);
10 + SeedValidator({required this.type, required this.language})
11 + : _words = getWordList(type: type, language: language),
12 + super(errorMessage: 'Wrong seed mnemonic');
13
14 final WalletType type;
15 final String language;
16 final List<String> _words;
17
17 - static List<String> getWordList({WalletType type, String language}) {
18 + static List<String> getWordList({required WalletType type, required String language}) {
19 switch (type) {
20 case WalletType.bitcoin:
21 return getBitcoinWordList(language);
22 case WalletType.litecoin:
23 return getBitcoinWordList(language);
24 case WalletType.monero:
24 - return monero.getMoneroWordList(language);
25 + return monero!.getMoneroWordList(language);
26 case WalletType.haven:
26 - return haven.getMoneroWordList(language);
27 + return haven!.getMoneroWordList(language);
28 default:
29 return [];
30 }
@@ -31,9 +32,9 @@ class SeedValidator extends Validator<MnemonicItem> {
32
33 static List<String> getBitcoinWordList(String language) {
34 assert(language.toLowerCase() == LanguageList.english.toLowerCase());
34 - return bitcoin.getWordList();
35 + return bitcoin!.getWordList();
36 }
37
38 @override
38 - bool isValid(MnemonicItem value) => _words.contains(value.text);
39 + bool isValid(MnemonicItem? value) => _words.contains(value?.text);
40 }
lib/core/sync_status_title.dart
+2
@@ -33,4 +33,6 @@ String syncStatusTitle(SyncStatus syncStatus) {
33 if (syncStatus is LostConnectionSyncStatus) {
34 return S.current.sync_status_failed_connect;
35 }
36 +
37 + return '';
38 }
\ No newline at end of file
lib/core/validator.dart
+12 -12
@@ -1,13 +1,13 @@
1 import 'package:flutter/foundation.dart';
2
3 abstract class Validator<T> {
4 - Validator({@required this.errorMessage});
4 + Validator({required this.errorMessage});
5
6 final String errorMessage;
7
8 - bool isValid(T value);
8 + bool isValid(T? value);
9
10 - String call(T value) => !isValid(value) ? errorMessage : null;
10 + String? call(T? value) => !isValid(value) ? errorMessage : null;
11 }
12
13 class TextValidator extends Validator<String> {
@@ -15,28 +15,28 @@ class TextValidator extends Validator<String> {
15 {this.minLength,
16 this.maxLength,
17 this.pattern,
18 + String errorMessage = '',
19 this.length,
19 - this.isAutovalidate = false,
20 - String errorMessage})
20 + this.isAutovalidate = false})
21 : super(errorMessage: errorMessage);
22
23 - final int minLength;
24 - final int maxLength;
25 - final List<int> length;
23 + final int? minLength;
24 + final int? maxLength;
25 + final List<int>? length;
26 final bool isAutovalidate;
27 - String pattern;
27 + String? pattern;
28
29 @override
30 - bool isValid(String value) {
30 + bool isValid(String? value) {
31 if (value == null || value.isEmpty) {
32 return isAutovalidate ? true : false;
33 }
34
35 return value.length > (minLength ?? 0) &&
36 (length?.contains(value.length) ?? true) &&
37 - ((maxLength ?? 0) > 0 ? (value.length <= maxLength) : true) &&
37 + ((maxLength ?? 0) > 0 ? (value.length <= maxLength!) : true) &&
38 (pattern != null ? match(value) : true);
39 }
40
41 - bool match(String value) => RegExp(pattern).hasMatch(value);
41 + bool match(String value) => pattern != null ? RegExp(pattern!).hasMatch(value) : false;
42 }
lib/core/wallet_creation_service.dart
+11 -13
@@ -14,15 +14,13 @@ import 'package:cw_core/wallet_type.dart';
14
15 class WalletCreationService {
16 WalletCreationService(
17 - {WalletType initialType,
18 - this.secureStorage,
19 - this.keyService,
20 - this.sharedPreferences,
21 - this.walletInfoSource})
17 + {required WalletType initialType,
18 + required this.secureStorage,
19 + required this.keyService,
20 + required this.sharedPreferences,
21 + required this.walletInfoSource})
22 : type = initialType {
23 - if (type != null) {
24 - changeWalletType(type: type);
25 - }
23 + changeWalletType(type: type);
24 }
25
26 WalletType type;
@@ -30,11 +28,11 @@ class WalletCreationService {
28 final SharedPreferences sharedPreferences;
29 final KeyService keyService;
30 final Box<WalletInfo> walletInfoSource;
33 - WalletService _service;
31 + WalletService? _service;
32
33 static const _isNewMoneroWalletPasswordUpdated = true;
34
37 - void changeWalletType({@required WalletType type}) {
35 + void changeWalletType({required WalletType type}) {
36 this.type = type;
37 _service = getIt.get<WalletService>(param1: type);
38 }
@@ -64,7 +62,7 @@ class WalletCreationService {
62 credentials.password = password;
63 await keyService.saveWalletPassword(
64 password: password, walletName: credentials.name);
67 - final wallet = await _service.create(credentials);
65 + final wallet = await _service!.create(credentials);
66
67 if (wallet.type == WalletType.monero) {
68 await sharedPreferences
@@ -82,7 +80,7 @@ class WalletCreationService {
80 credentials.password = password;
81 await keyService.saveWalletPassword(
82 password: password, walletName: credentials.name);
85 - final wallet = await _service.restoreFromKeys(credentials);
83 + final wallet = await _service!.restoreFromKeys(credentials);
84
85 if (wallet.type == WalletType.monero) {
86 await sharedPreferences
@@ -100,7 +98,7 @@ class WalletCreationService {
98 credentials.password = password;
99 await keyService.saveWalletPassword(
100 password: password, walletName: credentials.name);
103 - final wallet = await _service.restoreFromSeed(credentials);
101 + final wallet = await _service!.restoreFromSeed(credentials);
102
103 if (wallet.type == WalletType.monero) {
104 await sharedPreferences
lib/core/wallet_creation_state.dart
+1 -1
@@ -7,7 +7,7 @@ class WalletCreating extends WalletCreationState {}
7 class WalletCreatedSuccessfully extends WalletCreationState {}
8
9 class WalletCreationFailure extends WalletCreationState {
10 - WalletCreationFailure({@required this.error});
10 + WalletCreationFailure({required this.error});
11
12 final String error;
13 }
\ No newline at end of file
lib/core/wallet_loading_service.dart
+6 -9
@@ -17,18 +17,15 @@ class WalletLoadingService {
17 final WalletService Function(WalletType type) walletServiceFactory;
18
19 Future<WalletBase> load(WalletType type, String name) async {
20 - if (walletServiceFactory == null) {
21 - throw Exception('WalletLoadingService.walletServiceFactory is not set');
22 - }
23 - final walletService = walletServiceFactory?.call(type);
20 + final walletService = walletServiceFactory.call(type);
21 final password = await keyService.getWalletPassword(walletName: name);
25 - final wallet = await walletService.openWallet(name, password);
22 + final wallet = await walletService.openWallet(name, password);
23
27 - if (type == WalletType.monero) {
28 - await upateMoneroWalletPassword(wallet);
29 - }
24 + if (type == WalletType.monero) {
25 + await upateMoneroWalletPassword(wallet);
26 + }
27
31 - return wallet;
28 + return wallet;
29 }
30
31 Future<void> upateMoneroWalletPassword(WalletBase wallet) async {
lib/di.dart
+56 -58
@@ -156,26 +156,26 @@ import 'package:cake_wallet/core/wallet_loading_service.dart';
156 final getIt = GetIt.instance;
157
158 var _isSetupFinished = false;
159 -Box<WalletInfo> _walletInfoSource;
160 -Box<Node> _nodeSource;
161 -Box<Contact> _contactSource;
162 -Box<Trade> _tradesSource;
163 -Box<Template> _templates;
164 -Box<ExchangeTemplate> _exchangeTemplates;
165 -Box<TransactionDescription> _transactionDescriptionBox;
166 -Box<Order> _ordersSource;
167 -Box<UnspentCoinsInfo> _unspentCoinsInfoSource;
159 +late Box<WalletInfo> _walletInfoSource;
160 +late Box<Node> _nodeSource;
161 +late Box<Contact> _contactSource;
162 +late Box<Trade> _tradesSource;
163 +late Box<Template> _templates;
164 +late Box<ExchangeTemplate> _exchangeTemplates;
165 +late Box<TransactionDescription> _transactionDescriptionBox;
166 +late Box<Order> _ordersSource;
167 +late Box<UnspentCoinsInfo>? _unspentCoinsInfoSource;
168
169 Future setup(
170 - {Box<WalletInfo> walletInfoSource,
171 - Box<Node> nodeSource,
172 - Box<Contact> contactSource,
173 - Box<Trade> tradesSource,
174 - Box<Template> templates,
175 - Box<ExchangeTemplate> exchangeTemplates,
176 - Box<TransactionDescription> transactionDescriptionBox,
177 - Box<Order> ordersSource,
178 - Box<UnspentCoinsInfo> unspentCoinsInfoSource}) async {
170 + {required Box<WalletInfo> walletInfoSource,
171 + required Box<Node> nodeSource,
172 + required Box<Contact> contactSource,
173 + required Box<Trade> tradesSource,
174 + required Box<Template> templates,
175 + required Box<ExchangeTemplate> exchangeTemplates,
176 + required Box<TransactionDescription> transactionDescriptionBox,
177 + required Box<Order> ordersSource,
178 + Box<UnspentCoinsInfo>? unspentCoinsInfoSource}) async {
179 _walletInfoSource = walletInfoSource;
180 _nodeSource = nodeSource;
181 _contactSource = contactSource;
@@ -328,9 +328,9 @@ Future setup(
328 .changeProcessText('ERROR: ${loginError.toString()}');
329 }
330
331 - ReactionDisposer _reaction;
332 - _reaction = reaction((_) => appStore.wallet, (Object _) {
333 - _reaction?.reaction?.dispose();
331 + ReactionDisposer? _reaction;
332 + _reaction = reaction((_) => appStore.wallet, (Object? _) {
333 + _reaction?.reaction.dispose();
334 authStore.allowed();
335 });
336 }, closable: false),
@@ -354,7 +354,7 @@ Future setup(
354
355 getIt.registerFactoryParam<WalletAddressEditOrCreateViewModel, dynamic, void>(
356 (dynamic item, _) => WalletAddressEditOrCreateViewModel(
357 - wallet: getIt.get<AppStore>().wallet, item: item));
357 + wallet: getIt.get<AppStore>().wallet!, item: item));
358
359 getIt.registerFactoryParam<AddressEditOrCreatePage, dynamic, void>(
360 (dynamic item, _) => AddressEditOrCreatePage(
@@ -362,13 +362,13 @@ Future setup(
362 getIt.get<WalletAddressEditOrCreateViewModel>(param1: item)));
363
364 getIt.registerFactory<SendTemplateViewModel>(() => SendTemplateViewModel(
365 - getIt.get<AppStore>().wallet,
365 + getIt.get<AppStore>().wallet!,
366 getIt.get<AppStore>().settingsStore,
367 getIt.get<SendTemplateStore>(),
368 getIt.get<FiatConversionStore>()));
369
370 getIt.registerFactory<SendViewModel>(() => SendViewModel(
371 - getIt.get<AppStore>().wallet,
371 + getIt.get<AppStore>().wallet!,
372 getIt.get<AppStore>().settingsStore,
373 getIt.get<SendTemplateViewModel>(),
374 getIt.get<FiatConversionStore>(),
@@ -391,14 +391,13 @@ Future setup(
391 WalletListPage(walletListViewModel: getIt.get<WalletListViewModel>()));
392
393 getIt.registerFactory(() {
394 - final wallet = getIt.get<AppStore>().wallet;
394 + final wallet = getIt.get<AppStore>().wallet!;
395
396 if (wallet.type == WalletType.monero || wallet.type == WalletType.haven) {
397 return MoneroAccountListViewModel(wallet);
398 }
399
400 - // FIXME: throw exception.
401 - return null;
400 + throw Exception('Unexpected wallet type: ${wallet.type} for generate MoneroAccountListViewModel');
401 });
402
403 getIt.registerFactory(() => MoneroAccountListPage(
@@ -422,9 +421,9 @@ Future setup(
421 getIt.registerFactoryParam<MoneroAccountEditOrCreateViewModel,
422 AccountListItem, void>(
423 (AccountListItem account, _) => MoneroAccountEditOrCreateViewModel(
425 - monero.getAccountList(getIt.get<AppStore>().wallet),
426 - haven?.getAccountList(getIt.get<AppStore>().wallet),
427 - wallet: getIt.get<AppStore>().wallet,
424 + monero!.getAccountList(getIt.get<AppStore>().wallet!),
425 + haven?.getAccountList(getIt.get<AppStore>().wallet!),
426 + wallet: getIt.get<AppStore>().wallet!,
427 accountListItem: account));
428
429 getIt.registerFactoryParam<MoneroAccountEditOrCreatePage, AccountListItem,
@@ -436,13 +435,13 @@ Future setup(
435 getIt.registerFactory(() {
436 final appStore = getIt.get<AppStore>();
437 final yatStore = getIt.get<YatStore>();
439 - return SettingsViewModel(appStore.settingsStore, yatStore, appStore.wallet);
438 + return SettingsViewModel(appStore.settingsStore, yatStore, appStore.wallet!);
439 });
440
441 getIt.registerFactory(() => SettingsPage(getIt.get<SettingsViewModel>()));
442
443 getIt
445 - .registerFactory(() => WalletSeedViewModel(getIt.get<AppStore>().wallet));
444 + .registerFactory(() => WalletSeedViewModel(getIt.get<AppStore>().wallet!));
445
446 getIt.registerFactoryParam<WalletSeedPage, bool, void>(
447 (bool isWalletCreated, _) => WalletSeedPage(
@@ -450,12 +449,12 @@ Future setup(
449 isNewWalletCreated: isWalletCreated));
450
451 getIt
453 - .registerFactory(() => WalletKeysViewModel(getIt.get<AppStore>().wallet));
452 + .registerFactory(() => WalletKeysViewModel(getIt.get<AppStore>().wallet!));
453
454 getIt.registerFactory(() => WalletKeysPage(getIt.get<WalletKeysViewModel>()));
455
457 - getIt.registerFactoryParam<ContactViewModel, ContactRecord, void>(
458 - (ContactRecord contact, _) =>
456 + getIt.registerFactoryParam<ContactViewModel, ContactRecord?, void>(
457 + (ContactRecord? contact, _) =>
458 ContactViewModel(_contactSource, contact: contact));
459
460 getIt.registerFactory(
@@ -465,26 +464,26 @@ Future setup(
464 (bool isEditable, _) => ContactListPage(getIt.get<ContactListViewModel>(),
465 isEditable: isEditable));
466
468 - getIt.registerFactoryParam<ContactPage, ContactRecord, void>(
469 - (ContactRecord contact, _) =>
467 + getIt.registerFactoryParam<ContactPage, ContactRecord?, void>(
468 + (ContactRecord? contact, _) =>
469 ContactPage(getIt.get<ContactViewModel>(param1: contact)));
470
471 getIt.registerFactory(() {
472 final appStore = getIt.get<AppStore>();
473 return NodeListViewModel(
475 - _nodeSource, appStore.wallet, appStore.settingsStore);
474 + _nodeSource, appStore.wallet!, appStore.settingsStore);
475 });
476
477 getIt.registerFactory(() => NodeListPage(getIt.get<NodeListViewModel>()));
478
479 getIt.registerFactory(() =>
481 - NodeCreateOrEditViewModel(_nodeSource, getIt.get<AppStore>().wallet));
480 + NodeCreateOrEditViewModel(_nodeSource, getIt.get<AppStore>().wallet!));
481
482 getIt.registerFactory(
483 () => NodeCreateOrEditPage(getIt.get<NodeCreateOrEditViewModel>()));
484
485 getIt.registerFactory(() => ExchangeViewModel(
487 - getIt.get<AppStore>().wallet,
486 + getIt.get<AppStore>().wallet!,
487 _tradesSource,
488 getIt.get<ExchangeTemplateStore>(),
489 getIt.get<TradesStore>(),
@@ -493,7 +492,7 @@ Future setup(
492 ));
493
494 getIt.registerFactory(() => ExchangeTradeViewModel(
496 - wallet: getIt.get<AppStore>().wallet,
495 + wallet: getIt.get<AppStore>().wallet!,
496 trades: _tradesSource,
497 tradesStore: getIt.get<TradesStore>(),
498 sendViewModel: getIt.get<SendViewModel>()));
@@ -513,17 +512,17 @@ Future setup(
512 (WalletType param1, __) {
513 switch (param1) {
514 case WalletType.haven:
516 - return haven.createHavenWalletService(_walletInfoSource);
515 + return haven!.createHavenWalletService(_walletInfoSource);
516 case WalletType.monero:
518 - return monero.createMoneroWalletService(_walletInfoSource);
517 + return monero!.createMoneroWalletService(_walletInfoSource);
518 case WalletType.bitcoin:
520 - return bitcoin.createBitcoinWalletService(
521 - _walletInfoSource, _unspentCoinsInfoSource);
519 + return bitcoin!.createBitcoinWalletService(
520 + _walletInfoSource, _unspentCoinsInfoSource!);
521 case WalletType.litecoin:
523 - return bitcoin.createLitecoinWalletService(
524 - _walletInfoSource, _unspentCoinsInfoSource);
522 + return bitcoin!.createLitecoinWalletService(
523 + _walletInfoSource, _unspentCoinsInfoSource!);
524 default:
526 - return null;
525 + throw Exception('Unexpected token: ${param1.toString()} for generating of WalletService');
526 }
527 });
528
@@ -536,7 +535,7 @@ Future setup(
535 getIt.get<SetupPinCodeViewModel>(),
536 onSuccessfulPinSetup: onSuccessfulPinSetup));
537
539 - getIt.registerFactory(() => RescanViewModel(getIt.get<AppStore>().wallet));
538 + getIt.registerFactory(() => RescanViewModel(getIt.get<AppStore>().wallet!));
539
540 getIt.registerFactory(() => RescanPage(getIt.get<RescanViewModel>()));
541
@@ -553,7 +552,7 @@ Future setup(
552 getIt
553 .registerFactoryParam<TransactionDetailsViewModel, TransactionInfo, void>(
554 (TransactionInfo transactionInfo, _) {
556 - final wallet = getIt.get<AppStore>().wallet;
555 + final wallet = getIt.get<AppStore>().wallet!;
556 return TransactionDetailsViewModel(
557 transactionInfo: transactionInfo,
558 transactionDescriptionBox: _transactionDescriptionBox,
@@ -567,9 +566,8 @@ Future setup(
566 getIt.get<TransactionDetailsViewModel>(param1: transactionInfo)));
567
568 getIt.registerFactoryParam<NewWalletTypePage,
570 - void Function(BuildContext, WalletType), bool>(
571 - (para1, param2) => NewWalletTypePage(getIt.get<WalletNewVM>(),
572 - onTypeSelected: para1, isNewWallet: param2));
569 + void Function(BuildContext, WalletType), void>(
570 + (param1, _) => NewWalletTypePage(onTypeSelected: param1));
571
572 getIt.registerFactoryParam<PreSeedPage, WalletType, void>(
573 (WalletType type, _) => PreSeedPage(type));
@@ -610,7 +608,7 @@ Future setup(
608
609 return BuyViewModel(_ordersSource, getIt.get<OrdersStore>(),
610 getIt.get<SettingsStore>(), getIt.get<BuyAmountViewModel>(),
613 - wallet: wallet);
611 + wallet: wallet!);
612 });
613
614 getIt.registerFactory(() {
@@ -627,7 +625,7 @@ Future setup(
625 getIt.registerFactoryParam<OrderDetailsViewModel, Order, void>((order, _) {
626 final wallet = getIt.get<AppStore>().wallet;
627
630 - return OrderDetailsViewModel(wallet: wallet, orderForDetails: order);
628 + return OrderDetailsViewModel(wallet: wallet!, orderForDetails: order);
629 });
630
631 getIt.registerFactoryParam<OrderDetailsPage, Order, void>((Order order, _) =>
@@ -641,7 +639,7 @@ Future setup(
639 final wallet = getIt.get<AppStore>().wallet;
640
641 return UnspentCoinsListViewModel(
644 - wallet: wallet, unspentCoinsInfo: _unspentCoinsInfoSource);
642 + wallet: wallet!, unspentCoinsInfo: _unspentCoinsInfoSource!);
643 });
644
645 getIt.registerFactory(() => UnspentCoinsListPage(
@@ -667,7 +665,7 @@ Future setup(
665 getIt.registerFactory(() => YatService());
666
667 getIt.registerFactory(() => AddressResolver(yatService: getIt.get<YatService>(),
670 - walletType: getIt.get<AppStore>().wallet.type));
668 + walletType: getIt.get<AppStore>().wallet!.type));
669
670 getIt.registerFactoryParam<FullscreenQRPage, String, bool>(
671 (String qrData, bool isLight) => FullscreenQRPage(qrData: qrData, isLight: isLight,));
@@ -683,7 +681,7 @@ Future setup(
681 () => IoniaAnyPay(
682 getIt.get<IoniaService>(),
683 getIt.get<AnyPayApi>(),
686 - getIt.get<AppStore>().wallet));
684 + getIt.get<AppStore>().wallet!));
685
686 getIt.registerFactory(() => IoniaGiftCardsListViewModel(ioniaService: getIt.get<IoniaService>()));
687
lib/entities/action_list_display_mode.dart
+1 -1
@@ -18,7 +18,7 @@ int serializeActionlistDisplayModes(List<ActionListDisplayMode> modes) {
18 }
19
20 List<ActionListDisplayMode> deserializeActionlistDisplayModes(int raw) {
21 - final modes = List<ActionListDisplayMode>();
21 + final modes = <ActionListDisplayMode>[];
22
23 if (raw == 1 || raw - 10 == 1) {
24 modes.add(ActionListDisplayMode.trades);
lib/entities/balance_display_mode.dart
+3 -3
@@ -3,7 +3,7 @@ import 'package:cake_wallet/generated/i18n.dart';
3 import 'package:cw_core/enumerable_item.dart';
4
5 class BalanceDisplayMode extends EnumerableItem<int> with Serializable<int> {
6 - const BalanceDisplayMode({@required String title, @required int raw})
6 + const BalanceDisplayMode({required String title, required int raw})
7 : super(title: title, raw: raw);
8
9 static const all = [
@@ -18,7 +18,7 @@ class BalanceDisplayMode extends EnumerableItem<int> with Serializable<int> {
18 static const displayableBalance =
19 BalanceDisplayMode(raw: 3, title: 'Displayable Balance');
20
21 - static BalanceDisplayMode deserialize({int raw}) {
21 + static BalanceDisplayMode deserialize({required int raw}) {
22 switch (raw) {
23 case 0:
24 return fullBalance;
@@ -29,7 +29,7 @@ class BalanceDisplayMode extends EnumerableItem<int> with Serializable<int> {
29 case 3:
30 return displayableBalance;
31 default:
32 - return null;
32 + throw Exception('Unexpected token: $raw for BalanceDisplayMode deserialize');
33 }
34 }
35
lib/entities/biometric_auth.dart
+3 -2
@@ -9,8 +9,9 @@ class BiometricAuth {
9 try {
10 return await _localAuth.authenticate(
11 localizedReason: S.current.biometric_auth_reason,
12 - useErrorDialogs: true,
13 - stickyAuth: false);
12 + options: AuthenticationOptions(
13 + useErrorDialogs: true,
14 + stickyAuth: false));
15 } on PlatformException catch (e) {
16 print(e);
17 }
lib/entities/calculate_fiat_amount.dart
+1 -1
@@ -1,4 +1,4 @@
1 -String calculateFiatAmount({double price, String cryptoAmount}) {
1 +String calculateFiatAmount({double? price, String? cryptoAmount}) {
2 if (price == null || cryptoAmount == null) {
3 return '0.00';
4 }
lib/entities/calculate_fiat_amount_raw.dart
+1 -1
@@ -1,4 +1,4 @@
1 -String calculateFiatAmountRaw({double price, double cryptoAmount}) {
1 +String calculateFiatAmountRaw({required double cryptoAmount, double? price}) {
2 if (price == null) {
3 return '0.00';
4 }
lib/entities/contact.dart
+7 -4
@@ -8,8 +8,11 @@ part 'contact.g.dart';
8
9 @HiveType(typeId: Contact.typeId)
10 class Contact extends HiveObject with Keyable {
11 - Contact({@required this.name, @required this.address, CryptoCurrency type})
12 - : raw = type?.raw;
11 + Contact({required this.name, required this.address, CryptoCurrency? type}) {
12 + if (type != null) {
13 + raw = type.raw;
14 + }
15 + }
16
17 static const typeId = 0;
18 static const boxName = 'Contacts';
@@ -21,7 +24,7 @@ class Contact extends HiveObject with Keyable {
24 String address;
25
26 @HiveField(2)
24 - int raw;
27 + late int raw;
28
29 CryptoCurrency get type => CryptoCurrency.deserialize(raw: raw);
30
@@ -34,6 +37,6 @@ class Contact extends HiveObject with Keyable {
37 @override
38 int get hashCode => key.hashCode;
39
37 - void updateCryptoCurrency({@required CryptoCurrency currency}) =>
40 + void updateCryptoCurrency({required CryptoCurrency currency}) =>
41 raw = currency.raw;
42 }
lib/entities/contact_base.dart
+2
@@ -1,6 +1,8 @@
1 import 'package:cw_core/crypto_currency.dart';
2
3 abstract class ContactBase {
4 + ContactBase(this.name, this.address, this.type);
5 +
6 String name;
7
8 String address;
lib/entities/contact_record.dart
+4 -1
@@ -13,7 +13,10 @@ abstract class ContactRecordBase extends Record<Contact>
13 with Store
14 implements ContactBase {
15 ContactRecordBase(Box<Contact> source, Contact original)
16 - : super(source, original);
16 + : name = original.name,
17 + address = original.address,
18 + type = original.type,
19 + super(source, original);
20
21 @override
22 @observable
lib/entities/default_settings_migration.dart
+60 -68
@@ -18,6 +18,7 @@ import 'package:cake_wallet/entities/fs_migration.dart';
18 import 'package:cw_core/wallet_info.dart';
19 import 'package:cake_wallet/exchange/trade.dart';
20 import 'package:encrypt/encrypt.dart' as encrypt;
21 +import 'package:collection/collection.dart';
22
23 const newCakeWalletMoneroUri = 'xmr-node.cakewallet.com:18081';
24 const cakeWalletBitcoinElectrumUri = 'electrum.cakewallet.com:50002';
@@ -25,13 +26,13 @@ const cakeWalletLitecoinElectrumUri = 'ltc-electrum.cakewallet.com:50002';
26 const havenDefaultNodeUri = 'nodes.havenprotocol.org:443';
27
28 Future defaultSettingsMigration(
28 - {@required int version,
29 - @required SharedPreferences sharedPreferences,
30 - @required FlutterSecureStorage secureStorage,
31 - @required Box<Node> nodes,
32 - @required Box<WalletInfo> walletInfoSource,
33 - @required Box<Trade> tradeSource,
34 - @required Box<Contact> contactSource}) async {
29 + {required int version,
30 + required SharedPreferences sharedPreferences,
31 + required FlutterSecureStorage secureStorage,
32 + required Box<Node> nodes,
33 + required Box<WalletInfo> walletInfoSource,
34 + required Box<Trade> tradeSource,
35 + required Box<Contact> contactSource}) async {
36 if (Platform.isIOS) {
37 await ios_migrate_v1(walletInfoSource, tradeSource, contactSource);
38 }
@@ -56,7 +57,7 @@ Future defaultSettingsMigration(
57 FiatCurrency.usd.toString());
58 await sharedPreferences.setInt(
59 PreferencesKey.currentTransactionPriorityKeyLegacy,
59 - monero.getDefaultTransactionPriority().raw);
60 + monero!.getDefaultTransactionPriority().raw);
61 await sharedPreferences.setInt(
62 PreferencesKey.currentBalanceDisplayModeKey,
63 BalanceDisplayMode.availableBalance.raw);
@@ -147,7 +148,7 @@ Future defaultSettingsMigration(
148 'current_default_settings_migration_version', version);
149 }
150
150 -Future<void> replaceNodesMigration({@required Box<Node> nodes}) async {
151 +Future<void> replaceNodesMigration({required Box<Node> nodes}) async {
152 final replaceNodes = <String, Node>{
153 'eu-node.cakewallet.io:18081':
154 Node(uri: 'xmr-node-eu.cakewallet.com:18081', type: WalletType.monero),
@@ -170,39 +171,33 @@ Future<void> replaceNodesMigration({@required Box<Node> nodes}) async {
171 }
172
173 Future<void> changeMoneroCurrentNodeToDefault(
173 - {@required SharedPreferences sharedPreferences,
174 - @required Box<Node> nodes}) async {
174 + {required SharedPreferences sharedPreferences,
175 + required Box<Node> nodes}) async {
176 final node = getMoneroDefaultNode(nodes: nodes);
177 final nodeId = node?.key as int ?? 0; // 0 - England
178
179 await sharedPreferences.setInt('current_node_id', nodeId);
180 }
181
181 -Node getBitcoinDefaultElectrumServer({@required Box<Node> nodes}) {
182 - return nodes.values.firstWhere(
183 - (Node node) => node.uri == cakeWalletBitcoinElectrumUri,
184 - orElse: () => null) ??
185 - nodes.values.firstWhere((node) => node.type == WalletType.bitcoin,
186 - orElse: () => null);
182 +Node? getBitcoinDefaultElectrumServer({required Box<Node> nodes}) {
183 + return nodes.values.firstWhereOrNull(
184 + (Node node) => node.uriRaw == cakeWalletBitcoinElectrumUri)
185 + ?? nodes.values.firstWhereOrNull((node) => node.type == WalletType.bitcoin);
186 }
187
189 -Node getLitecoinDefaultElectrumServer({@required Box<Node> nodes}) {
190 - return nodes.values.firstWhere(
191 - (Node node) => node.uri == cakeWalletLitecoinElectrumUri,
192 - orElse: () => null) ??
193 - nodes.values.firstWhere((node) => node.type == WalletType.litecoin,
194 - orElse: () => null);
188 +Node? getLitecoinDefaultElectrumServer({required Box<Node> nodes}) {
189 + return nodes.values.firstWhereOrNull(
190 + (Node node) => node.uriRaw == cakeWalletLitecoinElectrumUri)
191 + ?? nodes.values.firstWhereOrNull((node) => node.type == WalletType.litecoin);
192 }
193
197 -Node getHavenDefaultNode({@required Box<Node> nodes}) {
198 - return nodes.values.firstWhere(
199 - (Node node) => node.uriRaw == havenDefaultNodeUri,
200 - orElse: () => null) ??
201 - nodes.values.firstWhere((node) => node.type == WalletType.haven,
202 - orElse: () => null);
194 +Node? getHavenDefaultNode({required Box<Node> nodes}) {
195 + return nodes.values.firstWhereOrNull(
196 + (Node node) => node.uriRaw == havenDefaultNodeUri)
197 + ?? nodes.values.firstWhereOrNull((node) => node.type == WalletType.haven);
198 }
199
205 -Node getMoneroDefaultNode({@required Box<Node> nodes}) {
200 +Node getMoneroDefaultNode({required Box<Node> nodes}) {
201 final timeZone = DateTime.now().timeZoneOffset.inHours;
202 var nodeUri = '';
203
@@ -214,14 +209,17 @@ Node getMoneroDefaultNode({@required Box<Node> nodes}) {
209 nodeUri = 'xmr-node-usa-east.cakewallet.com:18081';
210 }
211
217 - return nodes.values
218 - .firstWhere((Node node) => node.uri == nodeUri, orElse: () => null) ??
219 - nodes.values.first;
212 + try {
213 + return nodes.values
214 + .firstWhere((Node node) => node.uriRaw == nodeUri);
215 + } catch(_) {
216 + return nodes.values.first;
217 + }
218 }
219
220 Future<void> changeBitcoinCurrentElectrumServerToDefault(
223 - {@required SharedPreferences sharedPreferences,
224 - @required Box<Node> nodes}) async {
221 + {required SharedPreferences sharedPreferences,
222 + required Box<Node> nodes}) async {
223 final server = getBitcoinDefaultElectrumServer(nodes: nodes);
224 final serverId = server?.key as int ?? 0;
225
@@ -229,8 +227,8 @@ Future<void> changeBitcoinCurrentElectrumServerToDefault(
227 }
228
229 Future<void> changeLitecoinCurrentElectrumServerToDefault(
232 - {@required SharedPreferences sharedPreferences,
233 - @required Box<Node> nodes}) async {
230 + {required SharedPreferences sharedPreferences,
231 + required Box<Node> nodes}) async {
232 final server = getLitecoinDefaultElectrumServer(nodes: nodes);
233 final serverId = server?.key as int ?? 0;
234
@@ -238,8 +236,8 @@ Future<void> changeLitecoinCurrentElectrumServerToDefault(
236 }
237
238 Future<void> changeHavenCurrentNodeToDefault(
241 - {@required SharedPreferences sharedPreferences,
242 - @required Box<Node> nodes}) async {
239 + {required SharedPreferences sharedPreferences,
240 + required Box<Node> nodes}) async {
241 final node = getHavenDefaultNode(nodes: nodes);
242 final nodeId = node?.key as int ?? 0;
243
@@ -247,8 +245,8 @@ Future<void> changeHavenCurrentNodeToDefault(
245 }
246
247 Future<void> replaceDefaultNode(
250 - {@required SharedPreferences sharedPreferences,
251 - @required Box<Node> nodes}) async {
248 + {required SharedPreferences sharedPreferences,
249 + required Box<Node> nodes}) async {
250 const nodesForReplace = <String>[
251 'xmr-node-uk.cakewallet.com:18081',
252 'eu-node.cakewallet.io:18081',
@@ -256,9 +254,9 @@ Future<void> replaceDefaultNode(
254 ];
255 final currentNodeId = sharedPreferences.getInt('current_node_id');
256 final currentNode =
259 - nodes.values.firstWhere((Node node) => node.key == currentNodeId);
257 + nodes.values.firstWhereOrNull((Node node) => node.key == currentNodeId);
258 final needToReplace =
261 - currentNode == null ? true : nodesForReplace.contains(currentNode.uri);
259 + currentNode == null ? true : nodesForReplace.contains(currentNode.uriRaw);
260
261 if (!needToReplace) {
262 return;
@@ -268,7 +266,7 @@ Future<void> replaceDefaultNode(
266 sharedPreferences: sharedPreferences, nodes: nodes);
267 }
268
271 -Future<void> updateNodeTypes({@required Box<Node> nodes}) async {
269 +Future<void> updateNodeTypes({required Box<Node> nodes}) async {
270 nodes.values.forEach((node) async {
271 if (node.type == null) {
272 node.type = WalletType.monero;
@@ -277,17 +275,17 @@ Future<void> updateNodeTypes({@required Box<Node> nodes}) async {
275 });
276 }
277
280 -Future<void> addBitcoinElectrumServerList({@required Box<Node> nodes}) async {
278 +Future<void> addBitcoinElectrumServerList({required Box<Node> nodes}) async {
279 final serverList = await loadBitcoinElectrumServerList();
280 await nodes.addAll(serverList);
281 }
282
285 -Future<void> addLitecoinElectrumServerList({@required Box<Node> nodes}) async {
283 +Future<void> addLitecoinElectrumServerList({required Box<Node> nodes}) async {
284 final serverList = await loadLitecoinElectrumServerList();
285 await nodes.addAll(serverList);
286 }
287
290 -Future<void> addHavenNodeList({@required Box<Node> nodes}) async {
288 +Future<void> addHavenNodeList({required Box<Node> nodes}) async {
289 final nodeList = await loadDefaultHavenNodes();
290 await nodes.addAll(nodeList);
291 }
@@ -318,7 +316,7 @@ Future<void> addAddressesForMoneroWallets(
316
317 Future<void> updateDisplayModes(SharedPreferences sharedPreferences) async {
318 final currentBalanceDisplayMode =
321 - sharedPreferences.getInt(PreferencesKey.currentBalanceDisplayModeKey);
319 + sharedPreferences.getInt(PreferencesKey.currentBalanceDisplayModeKey) ?? -1;
320 final balanceDisplayMode = currentBalanceDisplayMode < 2 ? 3 : 2;
321 await sharedPreferences.setInt(
322 PreferencesKey.currentBalanceDisplayModeKey, balanceDisplayMode);
@@ -338,11 +336,11 @@ Future<void> generateBackupPassword(FlutterSecureStorage secureStorage) async {
336 Future<void> changeTransactionPriorityAndFeeRateKeys(
337 SharedPreferences sharedPreferences) async {
338 final legacyTransactionPriority = sharedPreferences
341 - .getInt(PreferencesKey.currentTransactionPriorityKeyLegacy);
339 + .getInt(PreferencesKey.currentTransactionPriorityKeyLegacy)!;
340 await sharedPreferences.setInt(
341 PreferencesKey.moneroTransactionPriority, legacyTransactionPriority);
342 await sharedPreferences.setInt(PreferencesKey.bitcoinTransactionPriority,
345 - bitcoin.getMediumTransactionPriority().serialize());
343 + bitcoin!.getMediumTransactionPriority().serialize());
344 }
345
346 Future<void> changeDefaultMoneroNode(
@@ -383,18 +381,14 @@ Future<void> checkCurrentNodes(
381 .getInt(PreferencesKey.currentLitecoinElectrumSererIdKey);
382 final currentHavenNodeId = sharedPreferences
383 .getInt(PreferencesKey.currentHavenNodeIdKey);
386 - final currentMoneroNode = nodeSource.values.firstWhere(
387 - (node) => node.key == currentMoneroNodeId,
388 - orElse: () => null);
389 - final currentBitcoinElectrumServer = nodeSource.values.firstWhere(
390 - (node) => node.key == currentBitcoinElectrumSeverId,
391 - orElse: () => null);
392 - final currentLitecoinElectrumServer = nodeSource.values.firstWhere(
393 - (node) => node.key == currentLitecoinElectrumSeverId,
394 - orElse: () => null);
395 - final currentHavenNodeServer = nodeSource.values.firstWhere(
396 - (node) => node.key == currentHavenNodeId,
397 - orElse: () => null);
384 + final currentMoneroNode = nodeSource.values.firstWhereOrNull(
385 + (node) => node.key == currentMoneroNodeId);
386 + final currentBitcoinElectrumServer = nodeSource.values.firstWhereOrNull(
387 + (node) => node.key == currentBitcoinElectrumSeverId);
388 + final currentLitecoinElectrumServer = nodeSource.values.firstWhereOrNull(
389 + (node) => node.key == currentLitecoinElectrumSeverId);
390 + final currentHavenNodeServer = nodeSource.values.firstWhereOrNull(
391 + (node) => node.key == currentHavenNodeId);
392
393 if (currentMoneroNode == null) {
394 final newCakeWalletNode =
@@ -435,12 +429,10 @@ Future<void> resetBitcoinElectrumServer(
429 Box<Node> nodeSource, SharedPreferences sharedPreferences) async {
430 final currentElectrumSeverId =
431 sharedPreferences.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey);
438 - final oldElectrumServer = nodeSource.values.firstWhere(
439 - (node) => node.uri.toString().contains('electrumx.cakewallet.com'),
440 - orElse: () => null);
441 - var cakeWalletNode = nodeSource.values.firstWhere(
442 - (node) => node.uri.toString() == cakeWalletBitcoinElectrumUri,
443 - orElse: () => null);
432 + final oldElectrumServer = nodeSource.values.firstWhereOrNull(
433 + (node) => node.uri.toString().contains('electrumx.cakewallet.com'));
434 + var cakeWalletNode = nodeSource.values.firstWhereOrNull(
435 + (node) => node.uri.toString() == cakeWalletBitcoinElectrumUri);
436
437 if (cakeWalletNode == null) {
438 cakeWalletNode =
lib/entities/encrypt.dart
+13 -11
@@ -1,8 +1,8 @@
1 import 'package:encrypt/encrypt.dart';
2 -import 'package:password/password.dart';
2 +// import 'package:password/password.dart';
3 import 'package:cake_wallet/.secrets.g.dart' as secrets;
4
5 -String encrypt({String source, String key, int keyLength = 16}) {
5 +String encrypt({required String source, required String key, int keyLength = 16}) {
6 final _key = Key.fromUtf8(key);
7 final iv = IV.fromLength(keyLength);
8 final encrypter = Encrypter(AES(_key));
@@ -11,7 +11,7 @@ String encrypt({String source, String key, int keyLength = 16}) {
11 return encrypted.base64;
12 }
13
14 -String decrypt({String source, String key, int keyLength = 16}) {
14 +String decrypt({required String source, required String key, int keyLength = 16}) {
15 final _key = Key.fromUtf8(key);
16 final iv = IV.fromLength(keyLength);
17 final encrypter = Encrypter(AES(_key));
@@ -20,33 +20,35 @@ String decrypt({String source, String key, int keyLength = 16}) {
20 return decrypted;
21 }
22
23 -String hash({String source}) {
24 - final algorithm = PBKDF2();
25 - final hash = Password.hash(source, algorithm);
23 +String hash({required String source}) {
24 + // FIX-ME: Uninplemented
25 + throw Exception('Unimplemented');
26 + // final algorithm = PBKDF2();
27 + // final hash = Password.hash(source, algorithm);
28
27 - return hash;
29 + // return hash;
30 }
31
30 -String encodedPinCode({String pin}) {
32 +String encodedPinCode({required String pin}) {
33 final source = '${secrets.salt}$pin';
34
35 return encrypt(source: source, key: secrets.key);
36 }
37
36 -String decodedPinCode({String pin}) {
38 +String decodedPinCode({required String pin}) {
39 final decrypted = decrypt(source: pin, key: secrets.key);
40
41 return decrypted.substring(secrets.key.length, decrypted.length);
42 }
43
42 -String encodeWalletPassword({String password}) {
44 +String encodeWalletPassword({required String password}) {
45 final source = password;
46 final _key = secrets.shortKey + secrets.walletSalt;
47
48 return encrypt(source: source, key: _key);
49 }
50
49 -String decodeWalletPassword({String password}) {
51 +String decodeWalletPassword({required String password}) {
52 final source = password;
53 final _key = secrets.shortKey + secrets.walletSalt;
54
lib/entities/fiat_currency.dart
+2 -2
@@ -1,7 +1,7 @@
1 import 'package:cw_core/enumerable_item.dart';
2
3 class FiatCurrency extends EnumerableItem<String> with Serializable<String> {
4 - const FiatCurrency({String symbol, this.countryCode, this.fullName}) : super(title: symbol, raw: symbol);
4 + const FiatCurrency({required String symbol, required this.countryCode, required this.fullName}) : super(title: symbol, raw: symbol);
5
6 final String countryCode;
7 final String fullName;
@@ -81,7 +81,7 @@ class FiatCurrency extends EnumerableItem<String> with Serializable<String> {
81 FiatCurrency.vef.raw: FiatCurrency.vef
82 };
83
84 - static FiatCurrency deserialize({String raw}) => _all[raw];
84 + static FiatCurrency deserialize({required String raw}) => _all[raw]!;
85
86 @override
87 bool operator ==(Object other) => other is FiatCurrency && other.raw == raw;
lib/entities/fio_address_provider.dart
+1 -1
@@ -46,7 +46,7 @@ class FioAddressProvider {
46 }
47
48 if (response.statusCode != 200) {
49 - return null;
49 + throw Exception('Unexpected response http status: ${response.statusCode}');
50 }
51
52 final responseJSON = json.decode(response.body) as Map<String, dynamic>;
lib/entities/fs_migration.dart
+53 -26
@@ -1,5 +1,6 @@
1 import 'dart:io';
2 import 'dart:convert';
3 +import 'package:collection/collection.dart';
4 import 'package:flutter_secure_storage/flutter_secure_storage.dart';
5 import 'package:shared_preferences/shared_preferences.dart';
6 import 'package:hive/hive.dart';
@@ -61,31 +62,45 @@ Future<void> ios_migrate_user_defaults() async {
62
63 //should we provide default btc node key?
64 final activeCurrency = await ios_legacy_helper.getInt('currency');
64 - final convertedCurrency = convertFiatLegacy(activeCurrency);
65
66 - if (convertedCurrency != null) {
67 - await prefs.setString(
66 + if (activeCurrency != null) {
67 + final convertedCurrency = convertFiatLegacy(activeCurrency);
68 +
69 + if (convertedCurrency != null) {
70 + await prefs.setString(
71 'current_fiat_currency', convertedCurrency.serialize());
72 + }
73 }
74
75 //translate fee priority
76 final activeFeeTier = await ios_legacy_helper.getInt('saved_fee_priority');
73 - await prefs.setInt('current_fee_priority', activeFeeTier);
77 +
78 + if (activeFeeTier != null) {
79 + await prefs.setInt('current_fee_priority', activeFeeTier);
80 + }
81
82 //translate current balance mode
83 final currentBalanceMode =
84 await ios_legacy_helper.getInt('display_balance_mode');
78 - await prefs.setInt('current_balance_display_mode', currentBalanceMode);
85 + if (currentBalanceMode != null) {
86 + await prefs.setInt('current_balance_display_mode', currentBalanceMode);
87 + }
88
89 //translate should save recipient address
90 final shouldSave =
91 await ios_legacy_helper.getBool('should_save_recipient_address');
83 - await prefs.setBool('save_recipient_address', shouldSave);
92 +
93 + if (shouldSave != null) {
94 + await prefs.setBool('save_recipient_address', shouldSave);
95 + }
96
97 //translate biometric
98 final biometricOn =
99 await ios_legacy_helper.getBool('biometric_authentication_on');
88 - await prefs.setBool('allow_biometrical_authentication', biometricOn);
100 +
101 + if (biometricOn != null) {
102 + await prefs.setBool('allow_biometrical_authentication', biometricOn);
103 + }
104
105 //read the current theme as integer, write it back as a bool
106 final currentTheme = prefs.getInt('current-theme');
@@ -97,11 +112,17 @@ Future<void> ios_migrate_user_defaults() async {
112
113 //assign the pin length
114 final pinLength = await ios_legacy_helper.getInt('pin-length');
100 - await prefs.setInt(PreferencesKey.currentPinLength, pinLength);
115 +
116 + if (pinLength != null) {
117 + await prefs.setInt(PreferencesKey.currentPinLength, pinLength);
118 + }
119
120 //default value for display list key?
121 final walletName = await ios_legacy_helper.getString('current_wallet_name');
104 - await prefs.setString('current_wallet_name', walletName);
122 +
123 + if (walletName != null) {
124 + await prefs.setString('current_wallet_name', walletName);
125 + }
126
127 await prefs.setInt('current_wallet_type', serializeToInt(WalletType.monero));
128
@@ -117,7 +138,13 @@ Future<void> ios_migrate_pin() async {
138
139 final flutterSecureStorage = FlutterSecureStorage();
140 final pinPassword = await flutterSecureStorage.read(
120 - key: 'pin_password', iOptions: IOSOptions(syncFlag: "syna"));
141 + key: 'pin_password', iOptions: IOSOptions());
142 + // No pin
143 + if (pinPassword == null) {
144 + await prefs.setBool('ios_migration_pin_completed', true);
145 + return;
146 + }
147 +
148 final key = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
149 final encodedPassword = encodedPinCode(pin: pinPassword);
150 await flutterSecureStorage.write(key: key, value: encodedPassword);
@@ -148,9 +175,9 @@ Future<void> ios_migrate_wallet_passwords() async {
175 final name = item.path.split('/').last;
176 final oldKey = 'wallet_monero_' + name + '_password';
177 final password = await flutterSecureStorage.read(
151 - key: oldKey, iOptions: IOSOptions(syncFlag: "syna"));
178 + key: oldKey, iOptions: IOSOptions());
179 await keyService.saveWalletPassword(
153 - walletName: name, password: password);
180 + walletName: name, password: password!);
181 }
182 } catch (e) {
183 print(e.toString());
@@ -197,14 +224,14 @@ FiatCurrency convertFiatLegacy(int raw) {
224 32: 'zar',
225 33: 'vef'
226 };
200 - final fiatAsString = _map[raw];
227 + final fiatAsString = _map[raw]!;
228
229 return FiatCurrency.deserialize(raw: fiatAsString.toUpperCase());
230 }
231
205 -Future<void> android_migrate_hives({Directory appDocDir}) async {
232 +Future<void> android_migrate_hives({required Directory appDocDir}) async {
233 final dbDir = Directory('${appDocDir.path}/db');
207 - final files = List<File>();
234 + final files = <File>[];
235
236 appDocDir.listSync().forEach((FileSystemEntity item) {
237 final ext = item.path.split('.').last;
@@ -225,10 +252,10 @@ Future<void> android_migrate_hives({Directory appDocDir}) async {
252 });
253 }
254
228 -Future<void> android_migrate_wallets({Directory appDocDir}) async {
255 +Future<void> android_migrate_wallets({required Directory appDocDir}) async {
256 final walletsDir = Directory('${appDocDir.path}/wallets');
257 final moneroWalletsDir = Directory('${walletsDir.path}/monero');
231 - final dirs = List<Directory>();
258 + final dirs = <Directory>[];
259
260 appDocDir.listSync().forEach((FileSystemEntity item) {
261 final name = item.path.split('/').last;
@@ -292,9 +319,8 @@ Future<void> ios_migrate_wallet_info(Box<WalletInfo> walletsInfoSource) async {
319 '_' +
320 name;
321 final exist = walletsInfoSource.values
295 - .firstWhere((el) => el.id == id, orElse: () => null) !=
296 - null;
297 -
322 + .firstWhereOrNull((el) => el.id == id) != null;
323 +
324 if (exist) {
325 return null;
326 }
@@ -307,7 +333,8 @@ Future<void> ios_migrate_wallet_info(Box<WalletInfo> walletsInfoSource) async {
333 restoreHeight: 0,
334 date: date,
335 dirPath: item.path,
310 - path: '${item.path}/$name');
336 + path: '${item.path}/$name',
337 + address: '');
338
339 return walletInfo;
340 }
@@ -317,8 +344,8 @@ Future<void> ios_migrate_wallet_info(Box<WalletInfo> walletsInfoSource) async {
344 }
345 })
346 .where((el) => el != null)
347 + .whereType<WalletInfo>()
348 .toList();
321 - print(infoRecords);
349 await walletsInfoSource.addAll(infoRecords);
350 await prefs.setBool('ios_migration_wallet_info_completed', true);
351 } catch (e) {
@@ -346,8 +373,8 @@ Future<void> ios_migrate_trades_list(Box<Trade> tradeSource) async {
373 final content = file.readAsBytesSync();
374 final flutterSecureStorage = FlutterSecureStorage();
375 final masterPassword = await flutterSecureStorage.read(
349 - key: 'master_password', iOptions: IOSOptions(syncFlag: "syna"));
350 - final key = masterPassword.replaceAll('-', '');
376 + key: 'master_password', iOptions: IOSOptions());
377 + final key = masterPassword!.replaceAll('-', '');
378 final decoded =
379 await ios_legacy_helper.decrypt(content, key: key, salt: secrets.salt);
380 final decodedJson = json.decode(decoded) as List<dynamic>;
@@ -362,7 +389,7 @@ Future<void> ios_migrate_trades_list(Box<Trade> tradeSource) async {
389 final from = CryptoCurrency.fromString(fromAsString);
390 final timestamp = dateAsDouble.toInt() * 1000;
391 final date = DateTime.fromMillisecondsSinceEpoch(timestamp);
365 - ExchangeProviderDescription provider;
392 + ExchangeProviderDescription? provider;
393
394 switch (providerAsString.toLowerCase()) {
395 case 'changenow':
@@ -379,7 +406,7 @@ Future<void> ios_migrate_trades_list(Box<Trade> tradeSource) async {
406 }
407
408 return Trade(
382 - id: tradeId, provider: provider, from: from, to: to, createdAt: date);
409 + id: tradeId, provider: provider!, from: from, to: to, createdAt: date, amount: '');
410 });
411 await tradeSource.addAll(trades);
412 await prefs.setBool('ios_migration_trade_list_completed', true);
lib/entities/get_encryption_key.dart
+1 -1
@@ -2,7 +2,7 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart';
2 import 'package:hive/hive.dart';
3
4 Future<List<int>> getEncryptionKey(
5 - {String forKey, FlutterSecureStorage secureStorage}) async {
5 + {required String forKey, required FlutterSecureStorage secureStorage}) async {
6 final stringifiedKey =
7 await secureStorage.read(key: 'transactionDescriptionsBoxKey');
8 List<int> key;
lib/entities/ios_legacy_helper.dart
+10 -10
@@ -7,19 +7,19 @@ const platform =
7 const MethodChannel('com.cakewallet.cakewallet/legacy_wallet_migration');
8
9 Future<String> decrypt(Uint8List bytes,
10 - {@required String key, @required String salt}) async =>
11 - await platform
12 - .invokeMethod('decrypt', {'bytes': bytes, 'key': key, 'salt': salt});
10 + {required String key, required String salt}) async =>
11 + (await platform
12 + .invokeMethod<String>('decrypt', {'bytes': bytes, 'key': key, 'salt': salt}))!;
13
14 -Future<dynamic> readUserDefaults(String key, {@required String type}) async =>
14 +Future<dynamic> readUserDefaults(String key, {required String type}) async =>
15 await platform
16 .invokeMethod<dynamic>('read_user_defaults', {'key': key, 'type': type});
17
18 -Future<String> getString(String key) async =>
19 - await readUserDefaults(key, type: 'string') as String;
18 +Future<String?> getString(String key) async =>
19 + await readUserDefaults(key, type: 'string') as String?;
20
21 -Future<bool> getBool(String key) async =>
22 - await readUserDefaults(key, type: 'bool') as bool;
21 +Future<bool?> getBool(String key) async =>
22 + await readUserDefaults(key, type: 'bool') as bool?;
23
24 -Future<int> getInt(String key) async =>
25 - await readUserDefaults(key, type: 'int') as int;
24 +Future<int?> getInt(String key) async =>
25 + await readUserDefaults(key, type: 'int') as int?;
lib/entities/language_service.dart
+1 -1
@@ -50,7 +50,7 @@ class LanguageService {
50 }
51
52 static Future<String> localeDetection() async {
53 - var locale = await Devicelocale.currentLocale;
53 + var locale = await Devicelocale.currentLocale ?? '';
54 locale = Intl.shortLocale(locale);
55
56 return list.keys.contains(locale) ? locale : 'en';
lib/entities/load_current_wallet.dart
+5
@@ -15,6 +15,11 @@ Future<void> loadCurrentWallet() async {
15 final typeRaw =
16 getIt.get<SharedPreferences>().getInt(PreferencesKey.currentWalletType) ??
17 0;
18 +
19 + if (name == null) {
20 + throw Exception('Incorrect current wallet name: $name');
21 + }
22 +
23 final type = deserializeFromInt(typeRaw);
24 final walletLoadingService = getIt.get<WalletLoadingService>();
25 final wallet = await walletLoadingService.load(type, name);
lib/entities/mnemonic_item.dart
+1 -1
@@ -1,5 +1,5 @@
1 class MnemonicItem {
2 - MnemonicItem({String text}) : _text = text;
2 + MnemonicItem({required String text}) : _text = text;
3
4 String get text => _text;
5 String _text;
lib/entities/node_list.dart
+35 -35
@@ -6,68 +6,68 @@ import 'package:cw_core/wallet_type.dart';
6
7 Future<List<Node>> loadDefaultNodes() async {
8 final nodesRaw = await rootBundle.loadString('assets/node_list.yml');
9 - final nodes = loadYaml(nodesRaw) as YamlList;
9 + final loadedNodes = loadYaml(nodesRaw) as YamlList;
10 + final nodes = <Node>[];
11
11 - return nodes.map((dynamic raw) {
12 + for (final raw in loadedNodes) {
13 if (raw is Map) {
13 - final node = Node.fromMap(raw);
14 - node?.type = WalletType.monero;
15 -
16 - return node;
14 + final node = Node.fromMap(raw as Map<String, Object>);
15 + node.type = WalletType.monero;
16 + nodes.add(node);
17 }
18 + }
19
19 - return null;
20 - }).toList();
20 + return nodes;
21 }
22
23 Future<List<Node>> loadBitcoinElectrumServerList() async {
24 final serverListRaw =
25 await rootBundle.loadString('assets/bitcoin_electrum_server_list.yml');
26 - final serverList = loadYaml(serverListRaw) as YamlList;
27 -
28 - return serverList.map((dynamic raw) {
29 - if (raw is Map) {
30 - final node = Node.fromMap(raw);
31 - node?.type = WalletType.bitcoin;
32 -
33 - return node;
26 + final loadedServerList = loadYaml(serverListRaw) as YamlList;
27 + final serverList = <Node>[];
28 +
29 + for (final raw in loadedServerList) {
30 + if (raw is Map) {
31 + final node = Node.fromMap(raw as Map<String, Object>);
32 + node.type = WalletType.bitcoin;
33 + serverList.add(node);
34 }
35 + }
36
36 - return null;
37 - }).toList();
37 + return serverList;
38 }
39
40 Future<List<Node>> loadLitecoinElectrumServerList() async {
41 final serverListRaw =
42 await rootBundle.loadString('assets/litecoin_electrum_server_list.yml');
43 - final serverList = loadYaml(serverListRaw) as YamlList;
43 + final loadedServerList = loadYaml(serverListRaw) as YamlList;
44 + final serverList = <Node>[];
45
45 - return serverList.map((dynamic raw) {
46 + for (final raw in loadedServerList) {
47 if (raw is Map) {
47 - final node = Node.fromMap(raw);
48 - node?.type = WalletType.litecoin;
49 -
50 - return node;
48 + final node = Node.fromMap(raw as Map<String, Object>);
49 + node.type = WalletType.litecoin;
50 + serverList.add(node);
51 }
52 + }
53
53 - return null;
54 - }).toList();
54 + return serverList;
55 }
56
57 Future<List<Node>> loadDefaultHavenNodes() async {
58 final nodesRaw = await rootBundle.loadString('assets/haven_node_list.yml');
59 - final nodes = loadYaml(nodesRaw) as YamlList;
59 + final loadedNodes = loadYaml(nodesRaw) as YamlList;
60 + final nodes = <Node>[];
61
61 - return nodes.map((dynamic raw) {
62 + for (final raw in loadedNodes) {
63 if (raw is Map) {
63 - final node = Node.fromMap(raw);
64 - node?.type = WalletType.haven;
65 -
66 - return node;
64 + final node = Node.fromMap(raw as Map<String, Object>);
65 + node.type = WalletType.haven;
66 + nodes.add(node);
67 }
68 -
69 - return null;
70 - }).toList();
68 + }
69 +
70 + return nodes;
71 }
72
73 Future resetToDefault(Box<Node> nodeSource) async {
lib/entities/openalias_record.dart
+5 -6
@@ -1,12 +1,11 @@
1 import 'package:basic_utils/basic_utils.dart';
2 import 'package:cw_core/wallet_type.dart';
3 -import 'package:flutter/material.dart';
3
4 class OpenaliasRecord {
5 OpenaliasRecord({
7 - this.address,
8 - this.name,
9 - this.description,
6 + required this.address,
7 + required this.name,
8 + required this.description,
9 });
10
11 final String name;
@@ -24,8 +23,8 @@ class OpenaliasRecord {
23 }
24
25 static Future<OpenaliasRecord> fetchAddressAndName({
27 - @required String formattedName,
28 - @required String ticker,
26 + required String formattedName,
27 + required String ticker,
28 }) async {
29 String address = formattedName;
30 String name = formattedName;
lib/entities/parse_address_from_domain.dart
+1 -1
@@ -9,7 +9,7 @@ import 'package:cake_wallet/entities/fio_address_provider.dart';
9
10 class AddressResolver {
11
12 - AddressResolver({@required this.yatService, this.walletType});
12 + AddressResolver({required this.yatService, required this.walletType});
13
14 final YatService yatService;
15 final WalletType walletType;
lib/entities/parsed_address.dart
+16 -17
@@ -6,47 +6,42 @@ enum ParseFrom { unstoppableDomains, openAlias, yatRecord, fio, notParsed }
6
7 class ParsedAddress {
8 ParsedAddress({
9 - this.addresses,
9 + required this.addresses,
10 this.name = '',
11 this.description = '',
12 this.parseFrom = ParseFrom.notParsed,
13 });
14 -
15 - final List<String> addresses;
16 - final String name;
17 - final String description;
18 - final ParseFrom parseFrom;
14
15 factory ParsedAddress.fetchEmojiAddress({
21 - @required List<YatRecord> addresses,
22 - @required String name,
16 + List<YatRecord>? addresses,
17 + required String name,
18 }){
19 if (addresses?.isEmpty ?? true) {
20 return ParsedAddress(
21 addresses: [name], parseFrom: ParseFrom.yatRecord);
27 - }
22 + }
23 return ParsedAddress(
29 - addresses: addresses.map((e) => e.address).toList(),
24 + addresses: addresses!.map((e) => e.address).toList(),
25 name: name,
26 parseFrom: ParseFrom.yatRecord,
27 );
28 }
29
30 factory ParsedAddress.fetchUnstoppableDomainAddress({
36 - @required String address,
37 - @required String name,
31 + String? address,
32 + required String name,
33 }){
39 - if (address?.isEmpty ?? true) {
34 + if (address?.isEmpty ?? true) {
35 return ParsedAddress(addresses: [name]);
36 }
37 return ParsedAddress(
43 - addresses: [address],
38 + addresses: [address!],
39 name: name,
40 parseFrom: ParseFrom.unstoppableDomains,
41 );
42 }
43
49 - factory ParsedAddress.fetchOpenAliasAddress({@required OpenaliasRecord record, @required String name}){
44 + factory ParsedAddress.fetchOpenAliasAddress({OpenaliasRecord? record, required String name}){
45 final formattedName = OpenaliasRecord.formatDomainName(name);
46 if (record == null || record.address.contains(formattedName)) {
47 return ParsedAddress(addresses: [name]);
@@ -59,12 +54,16 @@ class ParsedAddress {
54 );
55 }
56
62 - factory ParsedAddress.fetchFioAddress({@required String address, @required String name}){
63 -
57 + factory ParsedAddress.fetchFioAddress({required String address, required String name}){
58 return ParsedAddress(
59 addresses: [address],
60 name: name,
61 parseFrom: ParseFrom.fio,
62 );
63 }
64 +
65 + final List<String> addresses;
66 + final String name;
67 + final String description;
68 + final ParseFrom parseFrom;
69 }
lib/entities/qr_scanner.dart
+11 -9
@@ -1,15 +1,17 @@
1 -import 'package:barcode_scan/barcode_scan.dart';
1 +// import 'package:barcode_scan/barcode_scan.dart';
2
3 var isQrScannerShown = false;
4
5 Future<String> presentQRScanner() async {
6 isQrScannerShown = true;
7 - try {
8 - final result = await BarcodeScanner.scan();
9 - isQrScannerShown = false;
10 - return result.rawContent;
11 - } catch (e) {
12 - isQrScannerShown = false;
13 - rethrow;
14 - }
7 + // FIX-ME: BarcodeScanner
8 + throw Exception('Unimplemented');
9 + // try {
10 + // final result = await BarcodeScanner.scan();
11 + // isQrScannerShown = false;
12 + // return result.rawContent;
13 + // } catch (e) {
14 + // isQrScannerShown = false;
15 + // rethrow;
16 + // }
17 }
lib/entities/record.dart
+1 -1
@@ -27,7 +27,7 @@ abstract class Record<T extends HiveObject> with Keyable {
27
28 final Box<T> _source;
29
30 - StreamSubscription<BoxEvent> _listener;
30 + StreamSubscription<BoxEvent>? _listener;
31
32 void fromBind(T original);
33
lib/entities/secret_store_key.dart
+1 -1
@@ -5,7 +5,7 @@ const pinCodePassword = "PIN_CODE_PASSWORD";
5 const backupPassword = "BACKUP_CODE_PASSWORD";
6
7 String generateStoreKeyFor({
8 - SecretStoreKey key,
8 + required SecretStoreKey key,
9 String walletName = "",
10 }) {
11 var _key = "";
lib/entities/template.dart
+8 -1
@@ -4,7 +4,14 @@ part 'template.g.dart';
4
5 @HiveType(typeId: Template.typeId)
6 class Template extends HiveObject {
7 - Template({this.name,this.isCurrencySelected, this.address, this.cryptoCurrency, this.amount, this.fiatCurrency, this.amountFiat});
7 + Template({
8 + required this.name,
9 + required this.isCurrencySelected,
10 + required this.address,
11 + required this.cryptoCurrency,
12 + required this.amount,
13 + required this.fiatCurrency,
14 + required this.amountFiat});
15
16 static const typeId = 6;
17 static const boxName = 'Template';
lib/entities/transaction_description.dart
+3 -3
@@ -4,7 +4,7 @@ part 'transaction_description.g.dart';
4
5 @HiveType(typeId: TransactionDescription.typeId)
6 class TransactionDescription extends HiveObject {
7 - TransactionDescription({this.id, this.recipientAddress, this.transactionNote});
7 + TransactionDescription({required this.id, this.recipientAddress, this.transactionNote});
8
9 static const typeId = 2;
10 static const boxName = 'TransactionDescriptions';
@@ -14,10 +14,10 @@ class TransactionDescription extends HiveObject {
14 String id;
15
16 @HiveField(1)
17 - String recipientAddress;
17 + String? recipientAddress;
18
19 @HiveField(2)
20 - String transactionNote;
20 + String? transactionNote;
21
22 String get note => transactionNote ?? '';
23 }
lib/entities/transaction_history.dart
+3
@@ -2,6 +2,9 @@ import 'package:mobx/mobx.dart';
2 import 'package:cw_core/transaction_info.dart';
3
4 abstract class TransactionHistory {
5 + TransactionHistory()
6 + : transactions = Observable<List<TransactionInfo>>([]);
7 +
8 Observable<List<TransactionInfo>> transactions;
9 Future<List<TransactionInfo>> getAll();
10 Future update();
lib/entities/unstoppable_domain_address.dart
+2 -2
@@ -6,13 +6,13 @@ Future<String> fetchUnstoppableDomainAddress(String domain, String ticker) async
6 var address = '';
7
8 try {
9 - address = await channel.invokeMethod(
9 + address = await channel.invokeMethod<String>(
10 'getUnstoppableDomainAddress',
11 <String, String> {
12 'domain' : domain,
13 'ticker' : ticker
14 }
15 - );
15 + ) ?? '';
16 } catch (e) {
17 print('Unstoppable domain error: ${e.toString()}');
18 address = '';
lib/entities/update_haven_rate.dart
+17 -12
@@ -4,18 +4,23 @@ import 'package:cw_core/monero_amount_format.dart';
4 import 'package:cake_wallet/haven/haven.dart';
5
6 Future<void> updateHavenRate(FiatConversionStore fiatConversionStore) async {
7 - final rate = haven.getAssetRate();
8 - final base = rate.firstWhere((row) => row.asset == 'XUSD', orElse: () => null);
9 - rate.forEach((row) {
10 - final cur = CryptoCurrency.fromString(row.asset);
11 - final baseRate = moneroAmountToDouble(amount: base.rate);
12 - final rowRate = moneroAmountToDouble(amount: row.rate);
7 + try {
8 + final rate = haven!.getAssetRate();
9 + final base = rate.firstWhere((row) => row.asset == 'XUSD');
10
14 - if (cur == CryptoCurrency.xusd) {
15 - fiatConversionStore.prices[cur] = 1.0;
16 - return;
17 - }
11 + rate.forEach((row) {
12 + final cur = CryptoCurrency.fromString(row.asset);
13 + final baseRate = moneroAmountToDouble(amount: base.rate);
14 + final rowRate = moneroAmountToDouble(amount: row.rate);
15
19 - fiatConversionStore.prices[cur] = baseRate / rowRate;
20 - });
16 + if (cur == CryptoCurrency.xusd) {
17 + fiatConversionStore.prices[cur] = 1.0;
18 + return;
19 + }
20 +
21 + fiatConversionStore.prices[cur] = baseRate / rowRate;
22 + });
23 + } catch(_) {
24 + // FIX-ME: handle exception
25 + }
26 }
\ No newline at end of file
lib/entities/wallet_contact.dart
+1
@@ -3,6 +3,7 @@ import 'package:cw_core/crypto_currency.dart';
3
4 class WalletContact implements ContactBase {
5 WalletContact(this.address, this.name, this.type);
6 + //: super(name, address, type);
7
8 @override
9 String address;
lib/entities/wallet_description.dart
+1 -1
@@ -1,7 +1,7 @@
1 import 'package:cw_core/wallet_type.dart';
2
3 class WalletDescription {
4 - WalletDescription({this.name, this.type});
4 + WalletDescription({required this.name, required this.type});
5
6 final String name;
7 final WalletType type;
lib/entities/yat_record.dart
+7 -10
@@ -1,16 +1,13 @@
1 class YatRecord {
2 - String category;
3 - String address;
4 -
2 YatRecord({
6 - this.category,
7 - this.address,
3 + required this.category,
4 + required this.address,
5 });
6
10 - YatRecord.fromJson(Map<String, dynamic> json) {
11 - address = json['address'] as String;
12 - category = json['category'] as String;
13 - }
7 + YatRecord.fromJson(Map<String, dynamic> json)
8 + : address = json['address'] as String,
9 + category = json['category'] as String;
10
15 -
11 + String category;
12 + String address;
13 }
lib/exchange/changenow/changenow_exchange_provider.dart
+15 -14
@@ -1,6 +1,5 @@
1 import 'dart:convert';
2 import 'package:cake_wallet/exchange/trade_not_found_exeption.dart';
3 -import 'package:flutter/foundation.dart';
3 import 'package:http/http.dart';
4 import 'package:cake_wallet/.secrets.g.dart' as secrets;
5 import 'package:cw_core/crypto_currency.dart';
@@ -56,8 +55,10 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
55 static String getFlow(bool isFixedRate) => isFixedRate ? 'fixed-rate' : 'standard';
56
57 @override
59 - Future<Limits> fetchLimits({CryptoCurrency from, CryptoCurrency to,
60 - bool isFixedRateMode}) async {
58 + Future<Limits> fetchLimits({
59 + required CryptoCurrency from,
60 + required CryptoCurrency to,
61 + required bool isFixedRateMode}) async {
62 final headers = {apiHeaderKey: apiKey};
63 final normalizedFrom = normalizeCryptoCurrency(from);
64 final normalizedTo = normalizeCryptoCurrency(to);
@@ -79,7 +80,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
80 }
81
82 if (response.statusCode != 200) {
82 - return null;
83 + throw Exception('Unexpected http status: ${response.statusCode}');
84 }
85
86 final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -89,7 +90,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
90 }
91
92 @override
92 - Future<Trade> createTrade({TradeRequest request, bool isFixedRateMode}) async {
93 + Future<Trade> createTrade({required TradeRequest request, required bool isFixedRateMode}) async {
94 final _request = request as ChangeNowRequest;
95 final headers = {
96 apiHeaderKey: apiKey,
@@ -122,7 +123,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
123 }
124
125 if (response.statusCode != 200) {
125 - return null;
126 + throw Exception('Unexpected http status: ${response.statusCode}');
127 }
128
129 final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -145,7 +146,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
146 }
147
148 @override
148 - Future<Trade> findTradeById({@required String id}) async {
149 + Future<Trade> findTradeById({required String id}) async {
150 final headers = {apiHeaderKey: apiKey};
151 final params = <String, String>{'id': id};
152 final uri = Uri.https(apiAuthority,findTradeByIdPath, params);
@@ -164,7 +165,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
165 }
166
167 if (response.statusCode != 200) {
167 - return null;
168 + throw Exception('Unexpected http status: ${response.statusCode}');
169 }
170
171 final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -198,11 +199,11 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
199
200 @override
201 Future<double> calculateAmount(
201 - {CryptoCurrency from,
202 - CryptoCurrency to,
203 - double amount,
204 - bool isFixedRateMode,
205 - bool isReceiveAmount}) async {
202 + {required CryptoCurrency from,
203 + required CryptoCurrency to,
204 + required double amount,
205 + required bool isFixedRateMode,
206 + required bool isReceiveAmount}) async {
207 try {
208 if (amount == 0) {
209 return 0.0;
@@ -250,7 +251,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
251 return CryptoCurrency.btc.title.toLowerCase();
252 default:
253 return currency.tag != null
253 - ? currency.tag.toLowerCase()
254 + ? currency.tag!.toLowerCase()
255 : currency.title.toLowerCase();
256 }
257 }
lib/exchange/changenow/changenow_request.dart
+7 -7
@@ -4,13 +4,13 @@ import 'package:cake_wallet/exchange/trade_request.dart';
4
5 class ChangeNowRequest extends TradeRequest {
6 ChangeNowRequest(
7 - {@required this.from,
8 - @required this.to,
9 - @required this.address,
10 - @required this.fromAmount,
11 - @required this.toAmount,
12 - @required this.refundAddress,
13 - @required this.isReverse});
7 + {required this.from,
8 + required this.to,
9 + required this.address,
10 + required this.fromAmount,
11 + required this.toAmount,
12 + required this.refundAddress,
13 + required this.isReverse});
14
15 CryptoCurrency from;
16 CryptoCurrency to;
lib/exchange/exchange_pair.dart
+4 -1
@@ -1,7 +1,10 @@
1 import 'package:cw_core/crypto_currency.dart';
2
3 class ExchangePair {
4 - ExchangePair({this.from, this.to, this.reverse = true});
4 + ExchangePair({
5 + required this.from,
6 + required this.to,
7 + this.reverse = true});
8
9 final CryptoCurrency from;
10 final CryptoCurrency to;
lib/exchange/exchange_provider.dart
+15 -7
@@ -7,11 +7,11 @@ import 'package:cake_wallet/exchange/trade.dart';
7 import 'package:cake_wallet/exchange/exchange_provider_description.dart';
8
9 abstract class ExchangeProvider {
10 - ExchangeProvider({this.pairList});
10 + ExchangeProvider({required this.pairList});
11
12 String get title;
13 List<ExchangePair> pairList;
14 - ExchangeProviderDescription description;
14 + ExchangeProviderDescription get description;
15 bool get isAvailable;
16 bool get isEnabled;
17
@@ -19,10 +19,18 @@ abstract class ExchangeProvider {
19 String toString() => title;
20
21 Future<Limits> fetchLimits(
22 - {CryptoCurrency from, CryptoCurrency to, bool isFixedRateMode});
23 - Future<Trade> createTrade({TradeRequest request, bool isFixedRateMode});
24 - Future<Trade> findTradeById({@required String id});
25 - Future<double> calculateAmount({CryptoCurrency from, CryptoCurrency to,
26 - double amount, bool isFixedRateMode, bool isReceiveAmount});
22 + {required CryptoCurrency from,
23 + required CryptoCurrency to,
24 + required bool isFixedRateMode});
25 + Future<Trade> createTrade({
26 + required TradeRequest request,
27 + required bool isFixedRateMode});
28 + Future<Trade> findTradeById({required String id});
29 + Future<double> calculateAmount({
30 + required CryptoCurrency from,
31 + required CryptoCurrency to,
32 + required double amount,
33 + required bool isFixedRateMode,
34 + required bool isReceiveAmount});
35 Future<bool> checkIsAvailable();
36 }
lib/exchange/exchange_provider_description.dart
+7 -3
@@ -2,7 +2,11 @@ import 'package:cw_core/enumerable_item.dart';
2
3 class ExchangeProviderDescription extends EnumerableItem<int>
4 with Serializable<int> {
5 - const ExchangeProviderDescription({String title, int raw, this.horizontalLogo = false, this.image})
5 + const ExchangeProviderDescription({
6 + required String title,
7 + required int raw,
8 + required this.image,
9 + this.horizontalLogo = false})
10 : super(title: title, raw: raw);
11
12 final bool horizontalLogo;
@@ -20,7 +24,7 @@ class ExchangeProviderDescription extends EnumerableItem<int>
24 static const simpleSwap =
25 ExchangeProviderDescription(title: 'SimpleSwap', raw: 4, image: 'assets/images/simpleSwap.png');
26
23 - static ExchangeProviderDescription deserialize({int raw}) {
27 + static ExchangeProviderDescription deserialize({required int raw}) {
28 switch (raw) {
29 case 0:
30 return xmrto;
@@ -33,7 +37,7 @@ class ExchangeProviderDescription extends EnumerableItem<int>
37 case 4:
38 return simpleSwap;
39 default:
36 - return null;
40 + throw Exception('Unexpected token: $raw for ExchangeProviderDescription deserialize');
41 }
42 }
43 }
lib/exchange/exchange_template.dart
+6 -6
@@ -5,12 +5,12 @@ part 'exchange_template.g.dart';
5 @HiveType(typeId: ExchangeTemplate.typeId)
6 class ExchangeTemplate extends HiveObject {
7 ExchangeTemplate({
8 - this.amount,
9 - this.depositCurrency,
10 - this.receiveCurrency,
11 - this.provider,
12 - this.depositAddress,
13 - this.receiveAddress
8 + required this.amount,
9 + required this.depositCurrency,
10 + required this.receiveCurrency,
11 + required this.provider,
12 + required this.depositAddress,
13 + required this.receiveAddress
14 });
15
16 static const typeId = 7;
lib/exchange/exchange_trade_state.dart
+2 -2
@@ -8,13 +8,13 @@ class ExchangeTradeStateInitial extends ExchangeTradeState {}
8 class TradeIsCreating extends ExchangeTradeState {}
9
10 class TradeIsCreatedSuccessfully extends ExchangeTradeState {
11 - TradeIsCreatedSuccessfully({@required this.trade});
11 + TradeIsCreatedSuccessfully({required this.trade});
12
13 final Trade trade;
14 }
15
16 class TradeIsCreatedFailure extends ExchangeTradeState {
17 - TradeIsCreatedFailure({@required this.title, @required this.error});
17 + TradeIsCreatedFailure({required this.title, required this.error});
18
19 final String title;
20 final String error;
lib/exchange/limits.dart
+2 -2
@@ -1,6 +1,6 @@
1 class Limits {
2 const Limits({this.min, this.max});
3
4 - final double min;
5 - final double max;
4 + final double? min;
5 + final double? max;
6 }
\ No newline at end of file
lib/exchange/limits_state.dart
+2 -2
@@ -8,13 +8,13 @@ class LimitsInitialState extends LimitsState {}
8 class LimitsIsLoading extends LimitsState {}
9
10 class LimitsLoadedSuccessfully extends LimitsState {
11 - LimitsLoadedSuccessfully({@required this.limits});
11 + LimitsLoadedSuccessfully({required this.limits});
12
13 final Limits limits;
14 }
15
16 class LimitsLoadedFailure extends LimitsState {
17 - LimitsLoadedFailure({@required this.error});
17 + LimitsLoadedFailure({required this.error});
18
19 final String error;
20 }
lib/exchange/morphtoken/morphtoken_exchange_provider.dart
+26 -15
@@ -16,7 +16,7 @@ import 'package:cake_wallet/exchange/exchange_provider_description.dart';
16 import 'package:cake_wallet/exchange/trade_not_created_exeption.dart';
17
18 class MorphTokenExchangeProvider extends ExchangeProvider {
19 - MorphTokenExchangeProvider({@required this.trades})
19 + MorphTokenExchangeProvider({required this.trades})
20 : super(pairList: [
21 ExchangePair(from: CryptoCurrency.xmr, to: CryptoCurrency.eth),
22 ExchangePair(from: CryptoCurrency.xmr, to: CryptoCurrency.bch),
@@ -74,8 +74,12 @@ class MorphTokenExchangeProvider extends ExchangeProvider {
74 Future<bool> checkIsAvailable() async => true;
75
76 @override
77 - Future<Limits> fetchLimits({CryptoCurrency from, CryptoCurrency to, bool isFixedRateMode}) async {
77 + Future<Limits> fetchLimits({
78 + required CryptoCurrency from,
79 + required CryptoCurrency to,
80 + required bool isFixedRateMode}) async {
81 final url = apiUri + _limitsURISuffix;
82 + final uri = Uri.parse(url);
83 final headers = {'Content-type': 'application/json'};
84 final body = json.encode({
85 "input": {"asset": from.toString()},
@@ -83,11 +87,11 @@ class MorphTokenExchangeProvider extends ExchangeProvider {
87 {"asset": to.toString(), "weight": weight}
88 ]
89 });
86 - final response = await post(url, headers: headers, body: body);
90 + final response = await post(uri, headers: headers, body: body);
91 final responseJSON = json.decode(response.body) as Map<String, dynamic>;
92
93 final min = responseJSON['input']['limits']['min'] as int;
90 - int max;
94 + int max = 0;
95 double ethMax;
96
97 if (from == CryptoCurrency.eth) {
@@ -96,14 +100,16 @@ class MorphTokenExchangeProvider extends ExchangeProvider {
100 max = responseJSON['input']['limits']['max'] as int;
101 }
102
99 - double minFormatted = AmountConverter.amountIntToDouble(from, min);
100 - double maxFormatted = AmountConverter.amountIntToDouble(from, max);
103 + final minFormatted = AmountConverter.amountIntToDouble(from, min);
104 + final maxFormatted = AmountConverter.amountIntToDouble(from, max);
105
106 return Limits(min: minFormatted, max: maxFormatted);
107 }
108
109 @override
106 - Future<Trade> createTrade({TradeRequest request, bool isFixedRateMode}) async {
110 + Future<Trade> createTrade({
111 + required TradeRequest request,
112 + required bool isFixedRateMode}) async {
113 const url = apiUri + _morphURISuffix;
114 final _request = request as MorphTokenRequest;
115 final body = {
@@ -120,8 +126,8 @@ class MorphTokenExchangeProvider extends ExchangeProvider {
126 ],
127 "tag": "cakewallet"
128 };
123 -
124 - final response = await post(url,
129 + final uri = Uri.parse(url);
130 + final response = await post(uri,
131 headers: {'Content-Type': 'application/json'}, body: json.encode(body));
132
133 if (response.statusCode != 200) {
@@ -149,9 +155,10 @@ class MorphTokenExchangeProvider extends ExchangeProvider {
155 }
156
157 @override
152 - Future<Trade> findTradeById({@required String id}) async {
158 + Future<Trade> findTradeById({required String id}) async {
159 final url = apiUri + _morphURISuffix + '/' + id;
154 - final response = await get(url);
160 + final uri = Uri.parse(url);
161 + final response = await get(uri);
162
163 if (response.statusCode != 200) {
164 if (response.statusCode == 400) {
@@ -194,17 +201,21 @@ class MorphTokenExchangeProvider extends ExchangeProvider {
201
202 @override
203 Future<double> calculateAmount(
197 - {CryptoCurrency from, CryptoCurrency to, double amount, bool isFixedRateMode,
198 - bool isReceiveAmount}) async {
204 + {required CryptoCurrency from,
205 + required CryptoCurrency to,
206 + required double amount,
207 + required bool isFixedRateMode,
208 + required bool isReceiveAmount}) async {
209 final url = apiUri + _ratesURISuffix;
200 - final response = await get(url);
210 + final uri = Uri.parse(url);
211 + final response = await get(uri);
212 final responseJSON = json.decode(response.body) as Map<String, dynamic>;
213 final rate = responseJSON['data'][from.toString()][to.toString()] as String;
214
215 try {
216 final estimatedAmount = double.parse(rate) * amount;
217 return estimatedAmount;
207 - } catch (e) {
218 + } catch (_) {
219 return 0.0;
220 }
221 }
lib/exchange/morphtoken/morphtoken_request.dart
+5 -5
@@ -4,11 +4,11 @@ import 'package:cake_wallet/exchange/trade_request.dart';
4
5 class MorphTokenRequest extends TradeRequest {
6 MorphTokenRequest(
7 - {@required this.from,
8 - @required this.to,
9 - @required this.address,
10 - @required this.amount,
11 - @required this.refundAddress});
7 + {required this.from,
8 + required this.to,
9 + required this.address,
10 + required this.amount,
11 + required this.refundAddress});
12
13 CryptoCurrency from;
14 CryptoCurrency to;
lib/exchange/sideshift/sideshift_exchange_provider.dart
+27 -19
@@ -40,11 +40,11 @@ class SideShiftExchangeProvider extends ExchangeProvider {
40
41 @override
42 Future<double> calculateAmount(
43 - {CryptoCurrency from,
44 - CryptoCurrency to,
45 - double amount,
46 - bool isFixedRateMode,
47 - bool isReceiveAmount}) async {
43 + {required CryptoCurrency from,
44 + required CryptoCurrency to,
45 + required double amount,
46 + required bool isFixedRateMode,
47 + required bool isReceiveAmount}) async {
48 try {
49 if (amount == 0) {
50 return 0.0;
@@ -53,7 +53,8 @@ class SideShiftExchangeProvider extends ExchangeProvider {
53 final toCurrency = _normalizeCryptoCurrency(to);
54 final url =
55 apiBaseUrl + rangePath + '/' + fromCurrency + '/' + toCurrency;
56 - final response = await get(url);
56 + final uri = Uri.parse(url);
57 + final response = await get(uri);
58 final responseJSON = json.decode(response.body) as Map<String, dynamic>;
59 final rate = double.parse(responseJSON['rate'] as String);
60 final max = double.parse(responseJSON['max'] as String);
@@ -71,7 +72,8 @@ class SideShiftExchangeProvider extends ExchangeProvider {
72 @override
73 Future<bool> checkIsAvailable() async {
74 const url = apiBaseUrl + permissionPath;
74 - final response = await get(url);
75 + final uri = Uri.parse(url);
76 + final response = await get(uri);
77
78 if (response.statusCode == 500) {
79 final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -92,7 +94,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
94
95 @override
96 Future<Trade> createTrade(
95 - {TradeRequest request, bool isFixedRateMode}) async {
97 + {required TradeRequest request, required bool isFixedRateMode}) async {
98 final _request = request as SideShiftRequest;
99 final quoteId = await _createQuote(_request);
100 final url = apiBaseUrl + orderPath;
@@ -104,7 +106,8 @@ class SideShiftExchangeProvider extends ExchangeProvider {
106 'settleAddress': _request.settleAddress,
107 'refundAddress': _request.refundAddress
108 };
107 - final response = await post(url, headers: headers, body: json.encode(body));
109 + final uri = Uri.parse(url);
110 + final response = await post(uri, headers: headers, body: json.encode(body));
111
112 if (response.statusCode != 201) {
113 if (response.statusCode == 400) {
@@ -146,7 +149,8 @@ class SideShiftExchangeProvider extends ExchangeProvider {
149 'affiliateId': affiliateId,
150 'depositAmount': request.depositAmount,
151 };
149 - final response = await post(url, headers: headers, body: json.encode(body));
152 + final uri = Uri.parse(url);
153 + final response = await post(uri, headers: headers, body: json.encode(body));
154
155 if (response.statusCode != 201) {
156 if (response.statusCode == 400) {
@@ -167,11 +171,14 @@ class SideShiftExchangeProvider extends ExchangeProvider {
171
172 @override
173 Future<Limits> fetchLimits(
170 - {CryptoCurrency from, CryptoCurrency to, bool isFixedRateMode}) async {
174 + {required CryptoCurrency from,
175 + required CryptoCurrency to,
176 + required bool isFixedRateMode}) async {
177 final fromCurrency = _normalizeCryptoCurrency(from);
178 final toCurrency = _normalizeCryptoCurrency(to);
179 final url = apiBaseUrl + rangePath + '/' + fromCurrency + '/' + toCurrency;
174 - final response = await get(url);
180 + final uri = Uri.parse(url);
181 + final response = await get(uri);
182
183 if (response.statusCode == 500) {
184 final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -181,7 +188,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
188 }
189
190 if (response.statusCode != 200) {
184 - return null;
191 + throw Exception('Unexpected http status: ${response.statusCode}');
192 }
193
194 final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -192,9 +199,10 @@ class SideShiftExchangeProvider extends ExchangeProvider {
199 }
200
201 @override
195 - Future<Trade> findTradeById({@required String id}) async {
202 + Future<Trade> findTradeById({required String id}) async {
203 final url = apiBaseUrl + orderPath + '/' + id;
197 - final response = await get(url);
204 + final uri = Uri.parse(url);
205 + final response = await get(uri);
206
207 if (response.statusCode == 404) {
208 throw TradeNotFoundException(id, provider: description);
@@ -209,7 +217,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
217 }
218
219 if (response.statusCode != 200) {
212 - return null;
220 + throw Exception('Unexpected http status: ${response.statusCode}');
221 }
222
223 final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -219,8 +227,8 @@ class SideShiftExchangeProvider extends ExchangeProvider {
227 final to = CryptoCurrency.fromString(toCurrency);
228 final inputAddress = responseJSON['depositAddress']['address'] as String;
229 final expectedSendAmount = responseJSON['depositAmount'].toString();
222 - final deposits = responseJSON['deposits'] as List;
223 - TradeState state;
230 + final deposits = responseJSON['deposits'] as List?;
231 + TradeState? state;
232
233 if (deposits != null && deposits.isNotEmpty) {
234 final status = deposits[0]['status'] as String;
@@ -259,7 +267,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
267 case CryptoCurrency.zec:
268 return 'zec';
269 case CryptoCurrency.bnb:
262 - return currency.tag.toLowerCase();
270 + return currency.tag!.toLowerCase();
271 case CryptoCurrency.usdterc20:
272 return 'usdtErc20';
273 default:
lib/exchange/sideshift/sideshift_request.dart
+7 -7
@@ -2,16 +2,16 @@ import 'package:cake_wallet/exchange/trade_request.dart';
2 import 'package:cw_core/crypto_currency.dart';
3
4 class SideShiftRequest extends TradeRequest {
5 + SideShiftRequest(
6 + {required this.depositMethod,
7 + required this.settleMethod,
8 + required this.depositAmount,
9 + required this.settleAddress,
10 + required this.refundAddress});
11 +
12 final CryptoCurrency depositMethod;
13 final CryptoCurrency settleMethod;
14 final String depositAmount;
15 final String settleAddress;
16 final String refundAddress;
10 -
11 - SideShiftRequest(
12 - {this.depositMethod,
13 - this.settleMethod,
14 - this.depositAmount,
15 - this.settleAddress,
16 - this.refundAddress,});
17 }
lib/exchange/simpleswap/simpleswap_exchange_provider.dart
+15 -10
@@ -1,5 +1,4 @@
1 import 'dart:convert';
2 -
2 import 'package:cake_wallet/exchange/exchange_pair.dart';
3 import 'package:cake_wallet/exchange/exchange_provider.dart';
4 import 'package:cake_wallet/exchange/exchange_provider_description.dart';
@@ -36,7 +35,11 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
35
36 @override
37 Future<double> calculateAmount(
39 - {CryptoCurrency from, CryptoCurrency to, double amount, bool isFixedRateMode, bool isReceiveAmount}) async {
38 + {required CryptoCurrency from,
39 + required CryptoCurrency to,
40 + required double amount,
41 + required bool isFixedRateMode,
42 + required bool isReceiveAmount}) async {
43 try {
44 if (amount == 0) {
45 return 0.0;
@@ -51,7 +54,6 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
54 'fixed': isFixedRateMode.toString()
55 };
56 final uri = Uri.https(apiAuthority, getEstimatePath, params);
54 -
57 final response = await get(uri);
58
59 if (response.body == null) return 0.00;
@@ -68,11 +70,11 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
70 final uri = Uri.https(apiAuthority, getEstimatePath, <String, String>{'api_key': apiKey});
71 final response = await get(uri);
72
71 - return !(response.statusCode == 403);
73 + return !(response.statusCode == 403);
74 }
75
76 @override
75 - Future<Trade> createTrade({TradeRequest request, bool isFixedRateMode}) async {
77 + Future<Trade> createTrade({required TradeRequest request, required bool isFixedRateMode}) async {
78 final _request = request as SimpleSwapRequest;
79 final headers = {
80 'Content-Type': 'application/json'};
@@ -121,7 +123,10 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
123 }
124
125 @override
124 - Future<Limits> fetchLimits({CryptoCurrency from, CryptoCurrency to, bool isFixedRateMode}) async {
126 + Future<Limits> fetchLimits({
127 + required CryptoCurrency from,
128 + required CryptoCurrency to,
129 + required bool isFixedRateMode}) async {
130 final fromCurrency = _normalizeCryptoCurrency(from);
131 final toCurrency = _normalizeCryptoCurrency(to);
132 final params = <String, dynamic>{
@@ -142,7 +147,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
147 }
148
149 if (response.statusCode != 200) {
145 - return null;
150 + throw Exception('Unexpected http status: ${response.statusCode}');
151 }
152
153 final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -153,7 +158,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
158 }
159
160 @override
156 - Future<Trade> findTradeById({String id}) async {
161 + Future<Trade> findTradeById({required String id}) async {
162 final params = {'api_key': apiKey, 'id': id};
163 final uri = Uri.https(apiAuthority, getExchangePath, params);
164 final response = await get(uri);
@@ -170,7 +175,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
175 }
176
177 if (response.statusCode != 200) {
173 - return null;
178 + throw Exception('Unexpected http status: ${response.statusCode}');
179 }
180
181 final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -210,7 +215,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
215 case CryptoCurrency.zec:
216 return 'zec';
217 case CryptoCurrency.bnb:
213 - return currency.tag.toLowerCase();
218 + return currency.tag!.toLowerCase();
219 case CryptoCurrency.usdterc20:
220 return 'usdterc';
221 default:
lib/exchange/simpleswap/simpleswap_request.dart
+6 -5
@@ -4,11 +4,12 @@ import 'package:flutter/material.dart';
4
5 class SimpleSwapRequest extends TradeRequest {
6 SimpleSwapRequest({
7 - @required this.from,
8 - @required this.to,
9 - @required this.address,
10 - @required this.amount,
11 - @required this.refundAddress,
7 + required this.from,
8 + required this.to,
9 + required this.address,
10 + required this.amount,
11 + required this.refundAddress,
12 + this.toAmount = ''
13 });
14
15 CryptoCurrency from;
lib/exchange/trade.dart
+33 -24
@@ -9,23 +9,32 @@ part 'trade.g.dart';
9 @HiveType(typeId: Trade.typeId)
10 class Trade extends HiveObject {
11 Trade(
12 - {this.id,
13 - ExchangeProviderDescription provider,
14 - CryptoCurrency from,
15 - CryptoCurrency to,
16 - TradeState state,
12 + {required this.id,
13 + required this.amount,
14 + ExchangeProviderDescription? provider,
15 + CryptoCurrency? from,
16 + CryptoCurrency? to,
17 + TradeState? state,
18 this.createdAt,
19 this.expiredAt,
19 - this.amount,
20 this.inputAddress,
21 this.extraId,
22 this.outputTransaction,
23 this.refundAddress,
24 - this.walletId})
25 - : providerRaw = provider?.raw,
26 - fromRaw = from?.raw,
27 - toRaw = to?.raw,
28 - stateRaw = state?.raw;
24 + this.walletId}) {
25 + if (provider != null) {
26 + providerRaw = provider.raw;
27 + }
28 + if (from != null) {
29 + fromRaw = from.raw;
30 + }
31 + if (to != null) {
32 + toRaw = to.raw;
33 + }
34 + if (state != null) {
35 + stateRaw = state.raw;
36 + }
37 + }
38
39 static const typeId = 3;
40 static const boxName = 'Trades';
@@ -35,51 +44,51 @@ class Trade extends HiveObject {
44 String id;
45
46 @HiveField(1)
38 - int providerRaw;
47 + late int providerRaw;
48
49 ExchangeProviderDescription get provider =>
50 ExchangeProviderDescription.deserialize(raw: providerRaw);
51
52 @HiveField(2)
44 - int fromRaw;
53 + late int fromRaw;
54
55 CryptoCurrency get from => CryptoCurrency.deserialize(raw: fromRaw);
56
57 @HiveField(3)
49 - int toRaw;
58 + late int toRaw;
59
60 CryptoCurrency get to => CryptoCurrency.deserialize(raw: toRaw);
61
62 @HiveField(4)
54 - String stateRaw;
63 + late String stateRaw;
64
65 TradeState get state => TradeState.deserialize(raw: stateRaw);
66
67 @HiveField(5)
59 - DateTime createdAt;
68 + DateTime? createdAt;
69
70 @HiveField(6)
62 - DateTime expiredAt;
71 + DateTime? expiredAt;
72
73 @HiveField(7)
74 String amount;
75
76 @HiveField(8)
68 - String inputAddress;
77 + String? inputAddress;
78
79 @HiveField(9)
71 - String extraId;
80 + String? extraId;
81
82 @HiveField(10)
74 - String outputTransaction;
83 + String? outputTransaction;
84
85 @HiveField(11)
77 - String refundAddress;
86 + String? refundAddress;
87
88 @HiveField(12)
80 - String walletId;
89 + String? walletId;
90
82 - static Trade fromMap(Map map) {
91 + static Trade fromMap(Map<String, Object?> map) {
92 return Trade(
93 id: map['id'] as String,
94 provider: ExchangeProviderDescription.deserialize(
@@ -99,7 +108,7 @@ class Trade extends HiveObject {
108 'provider': provider.serialize(),
109 'input': from.serialize(),
110 'output': to.serialize(),
102 - 'date': createdAt != null ? createdAt.millisecondsSinceEpoch : null,
111 + 'date': createdAt != null ? createdAt!.millisecondsSinceEpoch : null,
112 'amount': amount,
113 'wallet_id': walletId
114 };
lib/exchange/trade_not_found_exeption.dart
+3 -3
@@ -4,14 +4,14 @@ import 'package:cake_wallet/generated/i18n.dart';
4 class TradeNotFoundException implements Exception {
5 TradeNotFoundException(this.tradeId, {this.provider, this.description = ''});
6
7 - String tradeId;
8 - ExchangeProviderDescription provider;
7 + String? tradeId;
8 + ExchangeProviderDescription? provider;
9 String description;
10
11 @override
12 String toString() {
13 var text = tradeId != null && provider != null
14 - ? S.current.trade_id_not_found(tradeId, provider.title)
14 + ? S.current.trade_id_not_found(tradeId!, provider!.title)
15 : S.current.trade_not_found;
16 text += ' $description';
17
lib/exchange/trade_state.dart
+3 -3
@@ -2,7 +2,7 @@ import 'package:flutter/foundation.dart';
2 import 'package:cw_core/enumerable_item.dart';
3
4 class TradeState extends EnumerableItem<String> with Serializable<String> {
5 - const TradeState({@required String raw, @required String title})
5 + const TradeState({required String raw, required String title})
6 : super(raw: raw, title: title);
7
8 @override
@@ -35,7 +35,7 @@ class TradeState extends EnumerableItem<String> with Serializable<String> {
35 static const completed = TradeState(raw: 'completed', title: 'Completed');
36 static const settling = TradeState(raw: 'settling', title: 'Settlement in progress');
37 static const settled = TradeState(raw: 'settled', title: 'Settlement completed');
38 - static TradeState deserialize({String raw}) {
38 + static TradeState deserialize({required String raw}) {
39 switch (raw) {
40 case 'pending':
41 return pending;
@@ -78,7 +78,7 @@ class TradeState extends EnumerableItem<String> with Serializable<String> {
78 case 'completed':
79 return completed;
80 default:
81 - return null;
81 + throw Exception('Unexpected token: $raw in TradeState deserialize');
82 }
83 }
84
lib/exchange/xmrto/xmrto_exchange_provider.dart
+23 -18
@@ -34,7 +34,8 @@ class XMRTOExchangeProvider extends ExchangeProvider {
34
35 static Future<bool> _checkIsAvailable() async {
36 const url = originalApiUri + _orderParameterUriSuffix;
37 - final response = await get(url, headers: _headers);
37 + final uri = Uri.parse(url);
38 + final response = await get(uri, headers: _headers);
39 return !(response.statusCode == 403);
40 }
41
@@ -61,9 +62,13 @@ class XMRTOExchangeProvider extends ExchangeProvider {
62 }
63
64 @override
64 - Future<Limits> fetchLimits({CryptoCurrency from, CryptoCurrency to, bool isFixedRateMode}) async {
65 + Future<Limits> fetchLimits({
66 + required CryptoCurrency from,
67 + required CryptoCurrency to,
68 + required bool isFixedRateMode}) async {
69 final url = originalApiUri + _orderParameterUriSuffix;
66 - final response = await get(url);
70 + final uri = Uri.parse(url);
71 + final response = await get(uri);
72 final correction = 0.001;
73
74 if (response.statusCode != 200) {
@@ -94,16 +99,14 @@ class XMRTOExchangeProvider extends ExchangeProvider {
99 }
100
101 @override
97 - Future<Trade> createTrade({TradeRequest request, bool isFixedRateMode}) async {
102 + Future<Trade> createTrade({required TradeRequest request, required bool isFixedRateMode}) async {
103 final _request = request as XMRTOTradeRequest;
104 final url = originalApiUri + _orderCreateUriSuffix;
105 final _amount =
106 _request.isBTCRequest ? _request.receiveAmount : _request.amount;
102 -
107 final _amountCurrency = _request.isBTCRequest
108 ? _request.to.toString()
109 : _request.from.toString();
106 -
110 final pattern = '^([0-9]+([.\,][0-9]{0,8})?|[.\,][0-9]{1,8})\$';
111 final isValid = RegExp(pattern).hasMatch(_amount);
112
@@ -115,10 +118,10 @@ class XMRTOExchangeProvider extends ExchangeProvider {
118 final body = {
119 'amount': _amount,
120 'amount_currency': _amountCurrency,
118 - 'btc_dest_address': _request.address
119 - };
121 + 'btc_dest_address': _request.address};
122 + final uri = Uri.parse(url);
123 final response =
121 - await post(url, headers: _headers, body: json.encode(body));
124 + await post(uri, headers: _headers, body: json.encode(body));
125
126 if (response.statusCode != 201) {
127 if (response.statusCode == 400) {
@@ -145,11 +148,12 @@ class XMRTOExchangeProvider extends ExchangeProvider {
148 }
149
150 @override
148 - Future<Trade> findTradeById({@required String id}) async {
151 + Future<Trade> findTradeById({required String id}) async {
152 final url = originalApiUri + _orderStatusUriSuffix;
153 + final uri = Uri.parse(url);
154 final body = {'uuid': id};
155 final response =
152 - await post(url, headers: _headers, body: json.encode(body));
156 + await post(uri, headers: _headers, body: json.encode(body));
157
158 if (response.statusCode != 200) {
159 if (response.statusCode == 400) {
@@ -188,16 +192,16 @@ class XMRTOExchangeProvider extends ExchangeProvider {
192
193 @override
194 Future<double> calculateAmount(
191 - {CryptoCurrency from,
192 - CryptoCurrency to,
193 - double amount,
194 - bool isFixedRateMode,
195 - bool isReceiveAmount}) async {
195 + {required CryptoCurrency from,
196 + required CryptoCurrency to,
197 + required double amount,
198 + required bool isFixedRateMode,
199 + required bool isReceiveAmount}) async {
200 if (from != CryptoCurrency.xmr && to != CryptoCurrency.btc) {
201 return 0;
202 }
203
200 - if (_rate == null || _rate == 0) {
204 + if (_rate == 0) {
205 _rate = await _fetchRates();
206 }
207
@@ -213,7 +217,8 @@ class XMRTOExchangeProvider extends ExchangeProvider {
217 Future<double> _fetchRates() async {
218 try {
219 final url = originalApiUri + _orderParameterUriSuffix;
216 - final response = await get(url, headers: _headers);
220 + final uri = Uri.parse(url);
221 + final response = await get(uri, headers: _headers);
222 final responseJSON = json.decode(response.body) as Map<String, dynamic>;
223 final price = double.parse(responseJSON['price'] as String);
224
lib/exchange/xmrto/xmrto_trade_request.dart
+7 -7
@@ -4,13 +4,13 @@ import 'package:cake_wallet/exchange/trade_request.dart';
4
5 class XMRTOTradeRequest extends TradeRequest {
6 XMRTOTradeRequest(
7 - {@required this.from,
8 - @required this.to,
9 - @required this.amount,
10 - @required this.receiveAmount,
11 - @required this.address,
12 - @required this.refundAddress,
13 - @required this.isBTCRequest});
7 + {required this.from,
8 + required this.to,
9 + required this.amount,
10 + required this.receiveAmount,
11 + required this.address,
12 + required this.refundAddress,
13 + required this.isBTCRequest});
14
15 final CryptoCurrency from;
16 final CryptoCurrency to;
lib/haven/cw_haven.dart
+66 -29
@@ -2,7 +2,7 @@ part of 'haven.dart';
2
3 class CWHavenAccountList extends HavenAccountList {
4 CWHavenAccountList(this._wallet);
5 - Object _wallet;
5 + final Object _wallet;
6
7 @override
8 @computed
@@ -37,13 +37,13 @@ class CWHavenAccountList extends HavenAccountList {
37 }
38
39 @override
40 - Future<void> addAccount(Object wallet, {String label}) async {
40 + Future<void> addAccount(Object wallet, {required String label}) async {
41 final havenWallet = wallet as HavenWallet;
42 await havenWallet.walletAddresses.accountList.addAccount(label: label);
43 }
44
45 @override
46 - Future<void> setLabelAccount(Object wallet, {int accountIndex, String label}) async {
46 + Future<void> setLabelAccount(Object wallet, {required int accountIndex, required String label}) async {
47 final havenWallet = wallet as HavenWallet;
48 await havenWallet.walletAddresses.accountList
49 .setLabelAccount(
@@ -54,7 +54,7 @@ class CWHavenAccountList extends HavenAccountList {
54
55 class CWHavenSubaddressList extends MoneroSubaddressList {
56 CWHavenSubaddressList(this._wallet);
57 - Object _wallet;
57 + final Object _wallet;
58
59 @override
60 @computed
@@ -71,13 +71,13 @@ class CWHavenSubaddressList extends MoneroSubaddressList {
71 }
72
73 @override
74 - void update(Object wallet, {int accountIndex}) {
74 + void update(Object wallet, {required int accountIndex}) {
75 final havenWallet = wallet as HavenWallet;
76 havenWallet.walletAddresses.subaddressList.update(accountIndex: accountIndex);
77 }
78
79 @override
80 - void refresh(Object wallet, {int accountIndex}) {
80 + void refresh(Object wallet, {required int accountIndex}) {
81 final havenWallet = wallet as HavenWallet;
82 havenWallet.walletAddresses.subaddressList.refresh(accountIndex: accountIndex);
83 }
@@ -93,7 +93,7 @@ class CWHavenSubaddressList extends MoneroSubaddressList {
93 }
94
95 @override
96 - Future<void> addSubaddress(Object wallet, {int accountIndex, String label}) async {
96 + Future<void> addSubaddress(Object wallet, {required int accountIndex, required String label}) async {
97 final havenWallet = wallet as HavenWallet;
98 await havenWallet.walletAddresses.subaddressList
99 .addSubaddress(
@@ -103,7 +103,7 @@ class CWHavenSubaddressList extends MoneroSubaddressList {
103
104 @override
105 Future<void> setLabelSubaddress(Object wallet,
106 - {int accountIndex, int addressIndex, String label}) async {
106 + {required int accountIndex, required int addressIndex, required String label}) async {
107 final havenWallet = wallet as HavenWallet;
108 await havenWallet.walletAddresses.subaddressList
109 .setLabelSubaddress(
@@ -115,9 +115,10 @@ class CWHavenSubaddressList extends MoneroSubaddressList {
115
116 class CWHavenWalletDetails extends HavenWalletDetails {
117 CWHavenWalletDetails(this._wallet);
118 - Object _wallet;
118 + final Object _wallet;
119
120 @computed
121 + @override
122 Account get account {
123 final havenWallet = _wallet as HavenWallet;
124 final acc = havenWallet.walletAddresses.account as monero_account.Account;
@@ -125,10 +126,11 @@ class CWHavenWalletDetails extends HavenWalletDetails {
126 }
127
128 @computed
129 + @override
130 HavenBalance get balance {
131 final havenWallet = _wallet as HavenWallet;
132 final balance = havenWallet.balance;
131 - return null;
133 + throw Exception('Unimplemented');
134 //return HavenBalance(
135 // fullBalance: balance.fullBalance,
136 // unlockedBalance: balance.unlockedBalance);
@@ -136,39 +138,48 @@ class CWHavenWalletDetails extends HavenWalletDetails {
138 }
139
140 class CWHaven extends Haven {
139 - HavenAccountList getAccountList(Object wallet) {
141 + @override
142 + HavenAccountList getAccountList(Object wallet) {
143 return CWHavenAccountList(wallet);
144 }
142 -
145 +
146 + @override
147 MoneroSubaddressList getSubaddressList(Object wallet) {
148 return CWHavenSubaddressList(wallet);
149 }
150
151 + @override
152 TransactionHistoryBase getTransactionHistory(Object wallet) {
153 final havenWallet = wallet as HavenWallet;
154 return havenWallet.transactionHistory;
155 }
156
157 + @override
158 HavenWalletDetails getMoneroWalletDetails(Object wallet) {
159 return CWHavenWalletDetails(wallet);
160 }
161
156 - int getHeigthByDate({DateTime date}) {
162 + @override
163 + int getHeigthByDate({required DateTime date}) {
164 return getMoneroHeigthByDate(date: date);
165 }
166
167 + @override
168 TransactionPriority getDefaultTransactionPriority() {
169 return MoneroTransactionPriority.slow;
170 }
171
164 - TransactionPriority deserializeMoneroTransactionPriority({int raw}) {
172 + @override
173 + TransactionPriority deserializeMoneroTransactionPriority({required int raw}) {
174 return MoneroTransactionPriority.deserialize(raw: raw);
175 }
176
177 + @override
178 List<TransactionPriority> getTransactionPriorities() {
179 return MoneroTransactionPriority.all;
180 }
181
182 + @override
183 List<String> getMoneroWordList(String language) {
184 switch (language.toLowerCase()) {
185 case 'english':
@@ -196,14 +207,15 @@ class CWHaven extends Haven {
207 }
208 }
209
210 + @override
211 WalletCredentials createHavenRestoreWalletFromKeysCredentials({
200 - String name,
201 - String spendKey,
202 - String viewKey,
203 - String address,
204 - String password,
205 - String language,
206 - int height}) {
212 + required String name,
213 + required String spendKey,
214 + required String viewKey,
215 + required String address,
216 + required String password,
217 + required String language,
218 + required int height}) {
219 return HavenRestoreWalletFromKeysCredentials(
220 name: name,
221 spendKey: spendKey,
@@ -213,8 +225,13 @@ class CWHaven extends Haven {
225 language: language,
226 height: height);
227 }
216 -
217 - WalletCredentials createHavenRestoreWalletFromSeedCredentials({String name, String password, int height, String mnemonic}) {
228 +
229 + @override
230 + WalletCredentials createHavenRestoreWalletFromSeedCredentials({
231 + required String name,
232 + required String password,
233 + required int height,
234 + required String mnemonic}) {
235 return HavenRestoreWalletFromSeedCredentials(
236 name: name,
237 password: password,
@@ -222,13 +239,18 @@ class CWHaven extends Haven {
239 mnemonic: mnemonic);
240 }
241
225 - WalletCredentials createHavenNewWalletCredentials({String name, String password, String language}) {
242 + @override
243 + WalletCredentials createHavenNewWalletCredentials({
244 + required String name,
245 + required String language,
246 + String? password}) {
247 return HavenNewWalletCredentials(
248 name: name,
249 password: password,
250 language: language);
251 }
252
253 + @override
254 Map<String, String> getKeys(Object wallet) {
255 final havenWallet = wallet as HavenWallet;
256 final keys = havenWallet.keys;
@@ -239,7 +261,11 @@ class CWHaven extends Haven {
261 'publicViewKey': keys.publicViewKey};
262 }
263
242 - Object createHavenTransactionCreationCredentials({List<Output> outputs, TransactionPriority priority, String assetType}) {
264 + @override
265 + Object createHavenTransactionCreationCredentials({
266 + required List<Output> outputs,
267 + required TransactionPriority priority,
268 + required String assetType}) {
269 return HavenTransactionCreationCredentials(
270 outputs: outputs.map((out) => OutputInfo(
271 fiatAmount: out.fiatAmount,
@@ -255,53 +281,64 @@ class CWHaven extends Haven {
281 assetType: assetType);
282 }
283
258 - String formatterMoneroAmountToString({int amount}) {
284 + @override
285 + String formatterMoneroAmountToString({required int amount}) {
286 return moneroAmountToString(amount: amount);
287 }
261 -
262 - double formatterMoneroAmountToDouble({int amount}) {
288 +
289 + @override
290 + double formatterMoneroAmountToDouble({required int amount}) {
291 return moneroAmountToDouble(amount: amount);
292 }
293
266 - int formatterMoneroParseAmount({String amount}) {
294 + @override
295 + int formatterMoneroParseAmount({required String amount}) {
296 return moneroParseAmount(amount: amount);
297 }
298
299 + @override
300 Account getCurrentAccount(Object wallet) {
301 final havenWallet = wallet as HavenWallet;
302 final acc = havenWallet.walletAddresses.account as monero_account.Account;
303 return Account(id: acc.id, label: acc.label);
304 }
305
306 + @override
307 void setCurrentAccount(Object wallet, int id, String label) {
308 final havenWallet = wallet as HavenWallet;
309 havenWallet.walletAddresses.account = monero_account.Account(id: id, label: label);
310 }
311
312 + @override
313 void onStartup() {
314 monero_wallet_api.onStartup();
315 }
316
317 + @override
318 int getTransactionInfoAccountId(TransactionInfo tx) {
319 final havenTransactionInfo = tx as HavenTransactionInfo;
320 return havenTransactionInfo.accountIndex;
321 }
322
323 + @override
324 WalletService createHavenWalletService(Box<WalletInfo> walletInfoSource) {
325 return HavenWalletService(walletInfoSource);
326 }
327
328 + @override
329 String getTransactionAddress(Object wallet, int accountIndex, int addressIndex) {
330 final havenWallet = wallet as HavenWallet;
331 return havenWallet.getTransactionAddress(accountIndex, addressIndex);
332 }
333
334 + @override
335 CryptoCurrency assetOfTransaction(TransactionInfo tx) {
336 final transaction = tx as HavenTransactionInfo;
337 final asset = CryptoCurrency.fromString(transaction.assetType);
338 return asset;
339 }
340
341 + @override
342 List<AssetRate> getAssetRate()
343 => getRate()
344 .map((rate) => AssetRate(rate.getAssetType(), rate.getRate()))
lib/ionia/ionia_anypay.dart
+7 -9
@@ -1,4 +1,3 @@
1 -import 'package:flutter/foundation.dart';
1 import 'package:cw_core/monero_amount_format.dart';
2 import 'package:cw_core/monero_transaction_priority.dart';
3 import 'package:cw_core/output_info.dart';
@@ -14,7 +13,6 @@ import 'package:cake_wallet/bitcoin/bitcoin.dart';
13 import 'package:cake_wallet/monero/monero.dart';
14 import 'package:cake_wallet/anypay/any_pay_payment_committed_info.dart';
15 import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart';
17 -import 'package:cake_wallet/ionia/ionia_order.dart';
16
17 class IoniaAnyPay {
18 IoniaAnyPay(this.ioniaService, this.anyPayApi, this.wallet);
@@ -24,8 +22,8 @@ class IoniaAnyPay {
22 final WalletBase wallet;
23
24 Future<IoniaAnyPayPaymentInfo> purchase({
27 - @required String merchId,
28 - @required double amount}) async {
25 + required String merchId,
26 + required double amount}) async {
27 final invoice = await ioniaService.purchaseGiftCard(
28 merchId: merchId,
29 amount: amount,
@@ -40,7 +38,7 @@ class IoniaAnyPay {
38 .map((AnyPayPaymentInstruction instruction) {
39 switch(payment.chain.toUpperCase()) {
40 case AnyPayChain.xmr:
43 - return monero.createMoneroTransactionCreationCredentialsRaw(
41 + return monero!.createMoneroTransactionCreationCredentialsRaw(
42 outputs: instruction.outputs.map((out) =>
43 OutputInfo(
44 isParsedAddress: false,
@@ -50,7 +48,7 @@ class IoniaAnyPay {
48 sendAll: false)).toList(),
49 priority: MoneroTransactionPriority.medium); // FIXME: HARDCODED PRIORITY
50 case AnyPayChain.btc:
53 - return bitcoin.createBitcoinTransactionCredentialsRaw(
51 + return bitcoin!.createBitcoinTransactionCredentialsRaw(
52 instruction.outputs.map((out) =>
53 OutputInfo(
54 isParsedAddress: false,
@@ -59,7 +57,7 @@ class IoniaAnyPay {
57 sendAll: false)).toList(),
58 feeRate: instruction.requiredFeeRate);
59 case AnyPayChain.ltc:
62 - return bitcoin.createBitcoinTransactionCredentialsRaw(
60 + return bitcoin!.createBitcoinTransactionCredentialsRaw(
61 instruction.outputs.map((out) =>
62 OutputInfo(
63 isParsedAddress: false,
@@ -76,8 +74,8 @@ class IoniaAnyPay {
74 .map((PendingTransaction pendingTransaction) {
75 switch (payment.chain.toUpperCase()){
76 case AnyPayChain.xmr:
79 - final ptx = monero.pendingTransactionInfo(pendingTransaction);
80 - return AnyPayTransaction(ptx['hex'], id: ptx['id'], key: ptx['key']);
77 + final ptx = monero!.pendingTransactionInfo(pendingTransaction);
78 + return AnyPayTransaction(ptx['hex'] ?? '', id: ptx['id'] ?? '', key: ptx['key']);
79 default:
80 return AnyPayTransaction(pendingTransaction.hex, id: pendingTransaction.id, key: null);
81 }
lib/ionia/ionia_api.dart
+88 -91
@@ -1,7 +1,6 @@
1 import 'dart:convert';
2 import 'package:cake_wallet/ionia/ionia_merchant.dart';
3 import 'package:cake_wallet/ionia/ionia_order.dart';
4 -import 'package:flutter/foundation.dart';
4 import 'package:http/http.dart';
5 import 'package:cake_wallet/ionia/ionia_user_credentials.dart';
6 import 'package:cake_wallet/ionia/ionia_virtual_card.dart';
@@ -27,15 +26,14 @@ class IoniaApi {
26
27 // Create user
28
30 - Future<String> createUser(String email, {@required String clientId}) async {
29 + Future<String> createUser(String email, {required String clientId}) async {
30 final headers = <String, String>{'clientId': clientId};
31 final query = <String, String>{'emailAddress': email};
32 final uri = createUserUri.replace(queryParameters: query);
33 final response = await put(uri, headers: headers);
34
35 if (response.statusCode != 200) {
37 - // throw exception
38 - return null;
36 + throw Exception('Unexpected http status: ${response.statusCode}');
37 }
38
39 final bodyJson = json.decode(response.body) as Map<String, Object>;
@@ -52,10 +50,10 @@ class IoniaApi {
50 // Verify email
51
52 Future<IoniaUserCredentials> verifyEmail({
55 - @required String username,
56 - @required String email,
57 - @required String code,
58 - @required String clientId}) async {
53 + required String username,
54 + required String email,
55 + required String code,
56 + required String clientId}) async {
57 final headers = <String, String>{
58 'clientId': clientId,
59 'username': username,
@@ -65,8 +63,7 @@ class IoniaApi {
63 final response = await put(uri, headers: headers);
64
65 if (response.statusCode != 200) {
68 - // throw exception
69 - return null;
66 + throw Exception('Unexpected http status: ${response.statusCode}');
67 }
68
69 final bodyJson = json.decode(response.body) as Map<String, Object>;
@@ -84,15 +81,14 @@ class IoniaApi {
81
82 // Sign In
83
87 - Future<String> signIn(String email, {@required String clientId}) async {
84 + Future<String> signIn(String email, {required String clientId}) async {
85 final headers = <String, String>{'clientId': clientId};
86 final query = <String, String>{'emailAddress': email};
87 final uri = signInUri.replace(queryParameters: query);
88 final response = await put(uri, headers: headers);
89
90 if (response.statusCode != 200) {
94 - // throw exception
95 - return null;
91 + throw Exception('Unexpected http status: ${response.statusCode}');
92 }
93
94 final bodyJson = json.decode(response.body) as Map<String, Object>;
@@ -109,9 +105,9 @@ class IoniaApi {
105 // Get virtual card
106
107 Future<IoniaVirtualCard> getCards({
112 - @required String username,
113 - @required String password,
114 - @required String clientId}) async {
108 + required String username,
109 + required String password,
110 + required String clientId}) async {
111 final headers = <String, String>{
112 'clientId': clientId,
113 'username': username,
@@ -119,8 +115,7 @@ class IoniaApi {
115 final response = await post(getCardsUri, headers: headers);
116
117 if (response.statusCode != 200) {
122 - // throw exception
123 - return null;
118 + throw Exception('Unexpected http status: ${response.statusCode}');
119 }
120
121 final bodyJson = json.decode(response.body) as Map<String, Object>;
@@ -138,9 +133,9 @@ class IoniaApi {
133 // Create virtual card
134
135 Future<IoniaVirtualCard> createCard({
141 - @required String username,
142 - @required String password,
143 - @required String clientId}) async {
136 + required String username,
137 + required String password,
138 + required String clientId}) async {
139 final headers = <String, String>{
140 'clientId': clientId,
141 'username': username,
@@ -148,13 +143,12 @@ class IoniaApi {
143 final response = await post(createCardUri, headers: headers);
144
145 if (response.statusCode != 200) {
151 - // throw exception
152 - return null;
146 + throw Exception('Unexpected http status: ${response.statusCode}');
147 }
148
149 final bodyJson = json.decode(response.body) as Map<String, Object>;
150 final data = bodyJson['Data'] as Map<String, Object>;
157 - final isSuccessful = bodyJson['Successful'] as bool;
151 + final isSuccessful = bodyJson['Successful'] as bool? ?? false;
152
153 if (!isSuccessful) {
154 throw Exception(data['message'] as String);
@@ -166,9 +160,9 @@ class IoniaApi {
160 // Get Merchants
161
162 Future<List<IoniaMerchant>> getMerchants({
169 - @required String username,
170 - @required String password,
171 - @required String clientId}) async {
163 + required String username,
164 + required String password,
165 + required String clientId}) async {
166 final headers = <String, String>{
167 'clientId': clientId,
168 'username': username,
@@ -180,32 +174,33 @@ class IoniaApi {
174 }
175
176 final decodedBody = json.decode(response.body) as Map<String, dynamic>;
183 - final isSuccessful = decodedBody['Successful'] as bool ?? false;
177 + final isSuccessful = decodedBody['Successful'] as bool? ?? false;
178
179 if (!isSuccessful) {
180 return [];
181 }
182
183 final data = decodedBody['Data'] as List<dynamic>;
190 - return data.map((dynamic e) {
191 - try {
192 - final element = e as Map<String, dynamic>;
193 - return IoniaMerchant.fromJsonMap(element);
194 - } catch(_) {
195 - return null;
196 - }
197 - }).where((e) => e != null)
198 - .toList();
184 + final merch = <IoniaMerchant>[];
185 +
186 + for (final item in data) {
187 + try {
188 + final element = item as Map<String, dynamic>;
189 + merch.add(IoniaMerchant.fromJsonMap(element));
190 + } catch(_) {}
191 + }
192 +
193 + return merch;
194 }
195
196 // Get Merchants By Filter
197
198 Future<List<IoniaMerchant>> getMerchantsByFilter({
204 - @required String username,
205 - @required String password,
206 - @required String clientId,
207 - String search,
208 - List<IoniaCategory> categories,
199 + required String username,
200 + required String password,
201 + required String clientId,
202 + String? search,
203 + List<IoniaCategory>? categories,
204 int merchantFilterType = 0}) async {
205 // MerchantFilterType: {All = 0, Nearby = 1, Popular = 2, Online = 3, MyFaves = 4, Search = 5}
206
@@ -234,34 +229,35 @@ class IoniaApi {
229 }
230
231 final decodedBody = json.decode(response.body) as Map<String, dynamic>;
237 - final isSuccessful = decodedBody['Successful'] as bool ?? false;
232 + final isSuccessful = decodedBody['Successful'] as bool? ?? false;
233
234 if (!isSuccessful) {
235 return [];
236 }
237
238 final data = decodedBody['Data'] as List<dynamic>;
244 - return data.map((dynamic e) {
245 - try {
246 - final element = e['Merchant'] as Map<String, dynamic>;
247 - return IoniaMerchant.fromJsonMap(element);
248 - } catch(_) {
249 - return null;
250 - }
251 - }).where((e) => e != null)
252 - .toList();
239 + final merch = <IoniaMerchant>[];
240 +
241 + for (final item in data) {
242 + try {
243 + final element = item['Merchant'] as Map<String, dynamic>;
244 + merch.add(IoniaMerchant.fromJsonMap(element));
245 + } catch(_) {}
246 + }
247 +
248 + return merch;
249 }
250
251 // Purchase Gift Card
252
253 Future<IoniaOrder> purchaseGiftCard({
258 - @required String requestedUUID,
259 - @required String merchId,
260 - @required double amount,
261 - @required String currency,
262 - @required String username,
263 - @required String password,
264 - @required String clientId}) async {
254 + required String requestedUUID,
255 + required String merchId,
256 + required double amount,
257 + required String currency,
258 + required String username,
259 + required String password,
260 + required String clientId}) async {
261 final headers = <String, String>{
262 'clientId': clientId,
263 'username': username,
@@ -279,7 +275,7 @@ class IoniaApi {
275 }
276
277 final decodedBody = json.decode(response.body) as Map<String, dynamic>;
282 - final isSuccessful = decodedBody['Successful'] as bool ?? false;
278 + final isSuccessful = decodedBody['Successful'] as bool? ?? false;
279
280 if (!isSuccessful) {
281 throw Exception(decodedBody['ErrorMessage'] as String);
@@ -292,9 +288,9 @@ class IoniaApi {
288 // Get Current User Gift Card Summaries
289
290 Future<List<IoniaGiftCard>> getCurrentUserGiftCardSummaries({
295 - @required String username,
296 - @required String password,
297 - @required String clientId}) async {
291 + required String username,
292 + required String password,
293 + required String clientId}) async {
294 final headers = <String, String>{
295 'clientId': clientId,
296 'username': username,
@@ -306,32 +302,33 @@ class IoniaApi {
302 }
303
304 final decodedBody = json.decode(response.body) as Map<String, dynamic>;
309 - final isSuccessful = decodedBody['Successful'] as bool ?? false;
305 + final isSuccessful = decodedBody['Successful'] as bool? ?? false;
306
307 if (!isSuccessful) {
308 return [];
309 }
310
311 final data = decodedBody['Data'] as List<dynamic>;
316 - return data.map((dynamic e) {
317 - try {
318 - final element = e as Map<String, dynamic>;
319 - return IoniaGiftCard.fromJsonMap(element);
320 - } catch(e) {
321 - return null;
322 - }
323 - }).where((e) => e != null)
324 - .toList();
312 + final cards = <IoniaGiftCard>[];
313 +
314 + for (final item in data) {
315 + try {
316 + final element = item as Map<String, dynamic>;
317 + cards.add(IoniaGiftCard.fromJsonMap(element));
318 + } catch(_) {}
319 + }
320 +
321 + return cards;
322 }
323
324 // Charge Gift Card
325
326 Future<void> chargeGiftCard({
330 - @required String username,
331 - @required String password,
332 - @required String clientId,
333 - @required int giftCardId,
334 - @required double amount}) async {
327 + required String username,
328 + required String password,
329 + required String clientId,
330 + required int giftCardId,
331 + required double amount}) async {
332 final headers = <String, String>{
333 'clientId': clientId,
334 'username': username,
@@ -350,11 +347,11 @@ class IoniaApi {
347 }
348
349 final decodedBody = json.decode(response.body) as Map<String, dynamic>;
353 - final isSuccessful = decodedBody['Successful'] as bool ?? false;
350 + final isSuccessful = decodedBody['Successful'] as bool? ?? false;
351
352 if (!isSuccessful) {
353 final data = decodedBody['Data'] as Map<String, dynamic>;
357 - final msg = data['Message'] as String ?? '';
354 + final msg = data['Message'] as String? ?? '';
355
356 if (msg.isNotEmpty) {
357 throw Exception(msg);
@@ -367,10 +364,10 @@ class IoniaApi {
364 // Get Gift Card
365
366 Future<IoniaGiftCard> getGiftCard({
370 - @required String username,
371 - @required String password,
372 - @required String clientId,
373 - @required int id}) async {
367 + required String username,
368 + required String password,
369 + required String clientId,
370 + required int id}) async {
371 final headers = <String, String>{
372 'clientId': clientId,
373 'username': username,
@@ -387,7 +384,7 @@ class IoniaApi {
384 }
385
386 final decodedBody = json.decode(response.body) as Map<String, dynamic>;
390 - final isSuccessful = decodedBody['Successful'] as bool ?? false;
387 + final isSuccessful = decodedBody['Successful'] as bool? ?? false;
388
389 if (!isSuccessful) {
390 final msg = decodedBody['ErrorMessage'] as String ?? '';
@@ -406,11 +403,11 @@ class IoniaApi {
403 // Payment Status
404
405 Future<int> getPaymentStatus({
409 - @required String username,
410 - @required String password,
411 - @required String clientId,
412 - @required String orderId,
413 - @required String paymentId}) async {
406 + required String username,
407 + required String password,
408 + required String clientId,
409 + required String orderId,
410 + required String paymentId}) async {
411 final headers = <String, String>{
412 'clientId': clientId,
413 'username': username,
@@ -429,7 +426,7 @@ class IoniaApi {
426 }
427
428 final decodedBody = json.decode(response.body) as Map<String, dynamic>;
432 - final isSuccessful = decodedBody['Successful'] as bool ?? false;
429 + final isSuccessful = decodedBody['Successful'] as bool? ?? false;
430
431 if (!isSuccessful) {
432 final msg = decodedBody['ErrorMessage'] as String ?? '';
lib/ionia/ionia_category.dart
+5 -1
@@ -1,5 +1,9 @@
1 class IoniaCategory {
2 - const IoniaCategory({this.index, this.title, this.ids, this.iconPath});
2 + const IoniaCategory({
3 + required this.index,
4 + required this.title,
5 + required this.ids,
6 + required this.iconPath});
7
8 static const allCategories = <IoniaCategory>[all, apparel, onlineOnly, food, entertainment, delivery, travel];
9 static const all = IoniaCategory(index: 0, title: 'All', ids: [], iconPath: 'assets/images/category.png');
lib/ionia/ionia_create_state.dart
+6 -4
@@ -10,7 +10,7 @@ class IoniaCreateStateSuccess extends IoniaCreateAccountState {}
10 class IoniaCreateStateLoading extends IoniaCreateAccountState {}
11
12 class IoniaCreateStateFailure extends IoniaCreateAccountState {
13 - IoniaCreateStateFailure({@required this.error});
13 + IoniaCreateStateFailure({required this.error});
14
15 final String error;
16 }
@@ -26,7 +26,7 @@ class IoniaOtpSendDisabled extends IoniaOtpState {}
26 class IoniaOtpSendEnabled extends IoniaOtpState {}
27
28 class IoniaOtpFailure extends IoniaOtpState {
29 - IoniaOtpFailure({@required this.error});
29 + IoniaOtpFailure({required this.error});
30
31 final String error;
32 }
@@ -38,7 +38,7 @@ class IoniaCreateCardSuccess extends IoniaCreateCardState {}
38 class IoniaCreateCardLoading extends IoniaCreateCardState {}
39
40 class IoniaCreateCardFailure extends IoniaCreateCardState {
41 - IoniaCreateCardFailure({@required this.error});
41 + IoniaCreateCardFailure({required this.error});
42
43 final String error;
44 }
@@ -52,13 +52,15 @@ class IoniaFetchingCard extends IoniaFetchCardState {}
52 class IoniaFetchCardFailure extends IoniaFetchCardState {}
53
54 class IoniaCardSuccess extends IoniaFetchCardState {
55 - IoniaCardSuccess({@required this.card});
55 + IoniaCardSuccess({required this.card});
56
57 final IoniaVirtualCard card;
58 }
59
60 abstract class IoniaMerchantState {}
61
62 +class InitialIoniaMerchantLoadingState extends IoniaMerchantState {}
63 +
64 class IoniaLoadingMerchantState extends IoniaMerchantState {}
65
66 class IoniaLoadedMerchantState extends IoniaMerchantState {}
lib/ionia/ionia_gift_card.dart
+19 -19
@@ -4,25 +4,25 @@ import 'package:flutter/foundation.dart';
4
5 class IoniaGiftCard {
6 IoniaGiftCard({
7 - @required this.id,
8 - @required this.merchantId,
9 - @required this.legalName,
10 - @required this.systemName,
11 - @required this.barcodeUrl,
12 - @required this.cardNumber,
13 - @required this.cardPin,
14 - @required this.instructions,
15 - @required this.tip,
16 - @required this.purchaseAmount,
17 - @required this.actualAmount,
18 - @required this.totalTransactionAmount,
19 - @required this.totalDashTransactionAmount,
20 - @required this.remainingAmount,
21 - @required this.createdDateFormatted,
22 - @required this.lastTransactionDateFormatted,
23 - @required this.isActive,
24 - @required this.isEmpty,
25 - @required this.logoUrl});
7 + required this.id,
8 + required this.merchantId,
9 + required this.legalName,
10 + required this.systemName,
11 + required this.barcodeUrl,
12 + required this.cardNumber,
13 + required this.cardPin,
14 + required this.instructions,
15 + required this.tip,
16 + required this.purchaseAmount,
17 + required this.actualAmount,
18 + required this.totalTransactionAmount,
19 + required this.totalDashTransactionAmount,
20 + required this.remainingAmount,
21 + required this.createdDateFormatted,
22 + required this.lastTransactionDateFormatted,
23 + required this.isActive,
24 + required this.isEmpty,
25 + required this.logoUrl});
26
27 factory IoniaGiftCard.fromJsonMap(Map<String, dynamic> element) {
28 return IoniaGiftCard(
lib/ionia/ionia_gift_card_instruction.dart
+1 -1
@@ -6,7 +6,7 @@ class IoniaGiftCardInstruction {
6
7 factory IoniaGiftCardInstruction.fromJsonMap(Map<String, dynamic> element) {
8 return IoniaGiftCardInstruction(
9 - toBeginningOfSentenceCase(element['title'] as String ?? ''),
9 + toBeginningOfSentenceCase(element['title'] as String? ?? '') ?? '',
10 element['description'] as String);
11 }
12
lib/ionia/ionia_merchant.dart
+35 -129
@@ -1,63 +1,31 @@
1 -import 'package:flutter/foundation.dart';
1 import 'package:cake_wallet/ionia/ionia_gift_card_instruction.dart';
2 import 'package:cake_wallet/generated/i18n.dart';
3
4 class IoniaMerchant {
5 IoniaMerchant({
7 - @required this.id,
8 - @required this.legalName,
9 - @required this.systemName,
10 - @required this.description,
11 - @required this.website,
12 - @required this.termsAndConditions,
13 - @required this.logoUrl,
14 - @required this.cardImageUrl,
15 - @required this.cardholderAgreement,
16 - @required this.purchaseFee,
17 - @required this.revenueShare,
18 - @required this.marketingFee,
19 - @required this.minimumDiscount,
20 - @required this.level1,
21 - @required this.level2,
22 - @required this.level3,
23 - @required this.level4,
24 - @required this.level5,
25 - @required this.level6,
26 - @required this.level7,
27 - @required this.isActive,
28 - @required this.isDeleted,
29 - @required this.isOnline,
30 - @required this.isPhysical,
31 - @required this.isVariablePurchase,
32 - @required this.minimumCardPurchase,
33 - @required this.maximumCardPurchase,
34 - @required this.acceptsTips,
35 - @required this.createdDateFormatted,
36 - @required this.createdBy,
37 - @required this.isRegional,
38 - @required this.modifiedDateFormatted,
39 - @required this.modifiedBy,
40 - @required this.usageInstructions,
41 - @required this.usageInstructionsBak,
42 - @required this.paymentGatewayId,
43 - @required this.giftCardGatewayId,
44 - @required this.isHtmlDescription,
45 - @required this.purchaseInstructions,
46 - @required this.balanceInstructions,
47 - @required this.amountPerCard,
48 - @required this.processingMessage,
49 - @required this.hasBarcode,
50 - @required this.hasInventory,
51 - @required this.isVoidable,
52 - @required this.receiptMessage,
53 - @required this.cssBorderCode,
54 - @required this.instructions,
55 - @required this.alderSku,
56 - @required this.ngcSku,
57 - @required this.acceptedCurrency,
58 - @required this.deepLink,
59 - @required this.isPayLater,
60 - @required this.savingsPercentage});
6 + required this.id,
7 + required this.legalName,
8 + required this.systemName,
9 + required this.description,
10 + required this.website,
11 + required this.termsAndConditions,
12 + required this.logoUrl,
13 + required this.cardImageUrl,
14 + required this.cardholderAgreement,
15 + required this.isActive,
16 + required this.isOnline,
17 + required this.isPhysical,
18 + required this.isVariablePurchase,
19 + required this.minimumCardPurchase,
20 + required this.maximumCardPurchase,
21 + required this.acceptsTips,
22 + required this.createdDateFormatted,
23 + required this.modifiedDateFormatted,
24 + required this.usageInstructions,
25 + required this.usageInstructionsBak,
26 + required this.hasBarcode,
27 + required this.instructions,
28 + required this.savingsPercentage});
29
30 factory IoniaMerchant.fromJsonMap(Map<String, dynamic> element) {
31 return IoniaMerchant(
@@ -70,50 +38,19 @@ class IoniaMerchant {
38 logoUrl: element["LogoUrl"] as String,
39 cardImageUrl: element["CardImageUrl"] as String,
40 cardholderAgreement: element["CardholderAgreement"] as String,
73 - purchaseFee: element["PurchaseFee"] as double,
74 - revenueShare: element["RevenueShare"] as double,
75 - marketingFee: element["MarketingFee"] as double,
76 - minimumDiscount: element["MinimumDiscount"] as double,
77 - level1: element["Level1"] as double,
78 - level2: element["Level2"] as double,
79 - level3: element["Level3"] as double,
80 - level4: element["Level4"] as double,
81 - level5: element["Level5"] as double,
82 - level6: element["Level6"] as double,
83 - level7: element["Level7"] as double,
84 - isActive: element["IsActive"] as bool,
85 - isDeleted: element["IsDeleted"] as bool,
41 + isActive: element["IsActive"] as bool?,
42 isOnline: element["IsOnline"] as bool,
43 isPhysical: element["IsPhysical"] as bool,
44 isVariablePurchase: element["IsVariablePurchase"] as bool,
45 minimumCardPurchase: element["MinimumCardPurchase"] as double,
46 maximumCardPurchase: element["MaximumCardPurchase"] as double,
47 acceptsTips: element["AcceptsTips"] as bool,
92 - createdDateFormatted: element["CreatedDate"] as String,
93 - createdBy: element["CreatedBy"] as int,
94 - isRegional: element["IsRegional"] as bool,
95 - modifiedDateFormatted: element["ModifiedDate"] as String,
96 - modifiedBy: element["ModifiedBy"] as int,
97 - usageInstructions: element["UsageInstructions"] as String,
98 - usageInstructionsBak: element["UsageInstructionsBak"] as String,
99 - paymentGatewayId: element["PaymentGatewayId"] as int,
100 - giftCardGatewayId: element["GiftCardGatewayId"] as int ,
101 - isHtmlDescription: element["IsHtmlDescription"] as bool,
102 - purchaseInstructions: element["PurchaseInstructions"] as String,
103 - balanceInstructions: element["BalanceInstructions"] as String,
104 - amountPerCard: element["AmountPerCard"] as double,
105 - processingMessage: element["ProcessingMessage"] as String,
48 + createdDateFormatted: element["CreatedDate"] as String?,
49 + modifiedDateFormatted: element["ModifiedDate"] as String?,
50 + usageInstructions: element["UsageInstructions"] as String?,
51 + usageInstructionsBak: element["UsageInstructionsBak"] as String?,
52 hasBarcode: element["HasBarcode"] as bool,
107 - hasInventory: element["HasInventory"] as bool,
108 - isVoidable: element["IsVoidable"] as bool,
109 - receiptMessage: element["ReceiptMessage"] as String,
110 - cssBorderCode: element["CssBorderCode"] as String,
53 instructions: IoniaGiftCardInstruction.parseListOfInstructions(element['PaymentInstructions'] as String),
112 - alderSku: element["AlderSku"] as String,
113 - ngcSku: element["NgcSku"] as String,
114 - acceptedCurrency: element["AcceptedCurrency"] as String,
115 - deepLink: element["DeepLink"] as String,
116 - isPayLater: element["IsPayLater"] as bool,
54 savingsPercentage: element["SavingsPercentage"] as double);
55 }
56
@@ -126,50 +63,19 @@ class IoniaMerchant {
63 final String logoUrl;
64 final String cardImageUrl;
65 final String cardholderAgreement;
129 - final double purchaseFee;
130 - final double revenueShare;
131 - final double marketingFee;
132 - final double minimumDiscount;
133 - final double level1;
134 - final double level2;
135 - final double level3;
136 - final double level4;
137 - final double level5;
138 - final double level6;
139 - final double level7;
140 - final bool isActive;
141 - final bool isDeleted;
66 + final bool? isActive;
67 final bool isOnline;
143 - final bool isPhysical;
68 + final bool? isPhysical;
69 final bool isVariablePurchase;
70 final double minimumCardPurchase;
71 final double maximumCardPurchase;
72 final bool acceptsTips;
148 - final String createdDateFormatted;
149 - final int createdBy;
150 - final bool isRegional;
151 - final String modifiedDateFormatted;
152 - final int modifiedBy;
153 - final String usageInstructions;
154 - final String usageInstructionsBak;
155 - final int paymentGatewayId;
156 - final int giftCardGatewayId;
157 - final bool isHtmlDescription;
158 - final String purchaseInstructions;
159 - final String balanceInstructions;
160 - final double amountPerCard;
161 - final String processingMessage;
73 + final String? createdDateFormatted;
74 + final String? modifiedDateFormatted;
75 + final String? usageInstructions;
76 + final String? usageInstructionsBak;
77 final bool hasBarcode;
163 - final bool hasInventory;
164 - final bool isVoidable;
165 - final String receiptMessage;
166 - final String cssBorderCode;
78 final List<IoniaGiftCardInstruction> instructions;
168 - final String alderSku;
169 - final String ngcSku;
170 - final String acceptedCurrency;
171 - final String deepLink;
172 - final bool isPayLater;
79 final double savingsPercentage;
80
81 double get discount => savingsPercentage;
@@ -181,7 +87,7 @@ class IoniaMerchant {
87 status += S.current.online;
88 }
89
184 - if (isPhysical) {
90 + if (isPhysical ?? false) {
91 if (status.isNotEmpty) {
92 status = '$status & ';
93 }
lib/ionia/ionia_order.dart
+5 -5
@@ -1,11 +1,11 @@
1 import 'package:flutter/foundation.dart';
2
3 class IoniaOrder {
4 - IoniaOrder({@required this.id,
5 - @required this.uri,
6 - @required this.currency,
7 - @required this.amount,
8 - @required this.paymentId});
4 + IoniaOrder({required this.id,
5 + required this.uri,
6 + required this.currency,
7 + required this.amount,
8 + required this.paymentId});
9 factory IoniaOrder.fromMap(Map<String, dynamic> obj) {
10 return IoniaOrder(
11 id: obj['order_id'] as String,
lib/ionia/ionia_service.dart
+32 -33
@@ -1,7 +1,6 @@
1 import 'package:cake_wallet/ionia/ionia_merchant.dart';
2 import 'package:cake_wallet/ionia/ionia_order.dart';
3 import 'package:cake_wallet/ionia/ionia_virtual_card.dart';
4 -import 'package:flutter/foundation.dart';
4 import 'package:flutter_secure_storage/flutter_secure_storage.dart';
5 import 'package:cake_wallet/.secrets.g.dart' as secrets;
6 import 'package:cake_wallet/ionia/ionia_api.dart';
@@ -32,8 +31,8 @@ class IoniaService {
31 // Verify email
32
33 Future<void> verifyEmail(String code) async {
35 - final username = await secureStorage.read(key: ioniaUsernameStorageKey);
36 - final email = await secureStorage.read(key: ioniaEmailStorageKey);
34 + final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
35 + final email = (await secureStorage.read(key: ioniaEmailStorageKey))!;
36 final credentials = await ioniaApi.verifyEmail(email: email, username: username, code: code, clientId: clientId);
37 await secureStorage.write(key: ioniaPasswordStorageKey, value: credentials.password);
38 await secureStorage.write(key: ioniaUsernameStorageKey, value: credentials.username);
@@ -48,7 +47,7 @@ class IoniaService {
47 }
48
49 Future<String> getUserEmail() async {
51 - return secureStorage.read(key: ioniaEmailStorageKey);
50 + return (await secureStorage.read(key: ioniaEmailStorageKey))!;
51 }
52
53 // Check is user logined
@@ -69,35 +68,35 @@ class IoniaService {
68 // Create virtual card
69
70 Future<IoniaVirtualCard> createCard() async {
72 - final username = await secureStorage.read(key: ioniaUsernameStorageKey);
73 - final password = await secureStorage.read(key: ioniaPasswordStorageKey);
71 + final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
72 + final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
73 return ioniaApi.createCard(username: username, password: password, clientId: clientId);
74 }
75
76 // Get virtual card
77
78 Future<IoniaVirtualCard> getCard() async {
80 - final username = await secureStorage.read(key: ioniaUsernameStorageKey);
81 - final password = await secureStorage.read(key: ioniaPasswordStorageKey);
79 + final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
80 + final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
81 return ioniaApi.getCards(username: username, password: password, clientId: clientId);
82 }
83
84 // Get Merchants
85
86 Future<List<IoniaMerchant>> getMerchants() async {
88 - final username = await secureStorage.read(key: ioniaUsernameStorageKey);
89 - final password = await secureStorage.read(key: ioniaPasswordStorageKey);
87 + final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
88 + final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
89 return ioniaApi.getMerchants(username: username, password: password, clientId: clientId);
90 }
91
92 // Get Merchants By Filter
93
94 Future<List<IoniaMerchant>> getMerchantsByFilter({
96 - String search,
97 - List<IoniaCategory> categories,
95 + String? search,
96 + List<IoniaCategory>? categories,
97 int merchantFilterType = 0}) async {
99 - final username = await secureStorage.read(key: ioniaUsernameStorageKey);
100 - final password = await secureStorage.read(key: ioniaPasswordStorageKey);
98 + final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
99 + final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
100 return ioniaApi.getMerchantsByFilter(
101 username: username,
102 password: password,
@@ -110,14 +109,14 @@ class IoniaService {
109 // Purchase Gift Card
110
111 Future<IoniaOrder> purchaseGiftCard({
113 - @required String merchId,
114 - @required double amount,
115 - @required String currency}) async {
116 - final username = await secureStorage.read(key: ioniaUsernameStorageKey);
117 - final password = await secureStorage.read(key: ioniaPasswordStorageKey);
112 + required String merchId,
113 + required double amount,
114 + required String currency}) async {
115 + final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
116 + final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
117 final deviceId = await PlatformDeviceId.getDeviceId;
118 return ioniaApi.purchaseGiftCard(
120 - requestedUUID: deviceId,
119 + requestedUUID: deviceId!,
120 merchId: merchId,
121 amount: amount,
122 currency: currency,
@@ -129,18 +128,18 @@ class IoniaService {
128 // Get Current User Gift Card Summaries
129
130 Future<List<IoniaGiftCard>> getCurrentUserGiftCardSummaries() async {
132 - final username = await secureStorage.read(key: ioniaUsernameStorageKey);
133 - final password = await secureStorage.read(key: ioniaPasswordStorageKey);
131 + final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
132 + final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
133 return ioniaApi.getCurrentUserGiftCardSummaries(username: username, password: password, clientId: clientId);
134 }
135
136 // Charge Gift Card
137
138 Future<void> chargeGiftCard({
140 - @required int giftCardId,
141 - @required double amount}) async {
142 - final username = await secureStorage.read(key: ioniaUsernameStorageKey);
143 - final password = await secureStorage.read(key: ioniaPasswordStorageKey);
139 + required int giftCardId,
140 + required double amount}) async {
141 + final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
142 + final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
143 await ioniaApi.chargeGiftCard(
144 username: username,
145 password: password,
@@ -157,19 +156,19 @@ class IoniaService {
156
157 // Get Gift Card
158
160 - Future<IoniaGiftCard> getGiftCard({@required int id}) async {
161 - final username = await secureStorage.read(key: ioniaUsernameStorageKey);
162 - final password = await secureStorage.read(key: ioniaPasswordStorageKey);
159 + Future<IoniaGiftCard> getGiftCard({required int id}) async {
160 + final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
161 + final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
162 return ioniaApi.getGiftCard(username: username, password: password, clientId: clientId,id: id);
163 }
164
165 // Payment Status
166
167 Future<int> getPaymentStatus({
169 - @required String orderId,
170 - @required String paymentId}) async {
171 - final username = await secureStorage.read(key: ioniaUsernameStorageKey);
172 - final password = await secureStorage.read(key: ioniaPasswordStorageKey);
168 + required String orderId,
169 + required String paymentId}) async {
170 + final username = (await secureStorage.read(key: ioniaUsernameStorageKey))!;
171 + final password = (await secureStorage.read(key: ioniaPasswordStorageKey))!;
172 return ioniaApi.getPaymentStatus(username: username, password: password, clientId: clientId, orderId: orderId, paymentId: paymentId);
173 }
174 }
\ No newline at end of file
lib/ionia/ionia_tip.dart
+6 -1
@@ -1,8 +1,13 @@
1 class IoniaTip {
2 - const IoniaTip({this.originalAmount, this.percentage, this.isCustom = false});
2 + const IoniaTip({
3 + required this.originalAmount,
4 + required this.percentage,
5 + this.isCustom = false});
6 +
7 final double originalAmount;
8 final double percentage;
9 final bool isCustom;
10 +
11 double get additionalAmount => double.parse((originalAmount * percentage / 100).toStringAsFixed(2));
12
13 static const tipList = [
lib/ionia/ionia_token_data.dart
+1 -1
@@ -2,7 +2,7 @@ import 'package:flutter/foundation.dart';
2 import 'dart:convert';
3
4 class IoniaTokenData {
5 - IoniaTokenData({@required this.accessToken, @required this.tokenType, @required this.expiredAt});
5 + IoniaTokenData({required this.accessToken, required this.tokenType, required this.expiredAt});
6
7 factory IoniaTokenData.fromJson(String source) {
8 final decoded = json.decode(source) as Map<String, dynamic>;
lib/ionia/ionia_virtual_card.dart
+11 -13
@@ -1,17 +1,15 @@
1 -import 'package:flutter/foundation.dart';
2 -
1 class IoniaVirtualCard {
2 IoniaVirtualCard({
5 - @required this.token,
6 - @required this.createdAt,
7 - @required this.lastFour,
8 - @required this.state,
9 - @required this.pan,
10 - @required this.cvv,
11 - @required this.expirationMonth,
12 - @required this.expirationYear,
13 - @required this.fundsLimit,
14 - @required this.spendLimit});
3 + required this.token,
4 + required this.createdAt,
5 + required this.lastFour,
6 + required this.state,
7 + required this.pan,
8 + required this.cvv,
9 + required this.expirationMonth,
10 + required this.expirationYear,
11 + required this.fundsLimit,
12 + required this.spendLimit});
13
14 factory IoniaVirtualCard.fromMap(Map<String, Object> source) {
15 final created = source['created'] as String;
@@ -37,7 +35,7 @@ class IoniaVirtualCard {
35 final String cvv;
36 final String expirationMonth;
37 final String expirationYear;
40 - final DateTime createdAt;
38 + final DateTime? createdAt;
39 final double fundsLimit;
40 final double spendLimit;
41 }
\ No newline at end of file
lib/main.dart
+20 -18
@@ -109,7 +109,7 @@ Future<void> main() async {
109 final templates = await Hive.openBox<Template>(Template.boxName);
110 final exchangeTemplates =
111 await Hive.openBox<ExchangeTemplate>(ExchangeTemplate.boxName);
112 - Box<UnspentCoinsInfo> unspentCoinsInfoSource;
112 + Box<UnspentCoinsInfo>? unspentCoinsInfoSource;
113
114 if (!isMoneroOnly) {
115 unspentCoinsInfoSource = await Hive.openBox<UnspentCoinsInfo>(UnspentCoinsInfo.boxName);
@@ -145,18 +145,18 @@ Future<void> main() async {
145 }
146
147 Future<void> initialSetup(
148 - {@required SharedPreferences sharedPreferences,
149 - @required Box<Node> nodes,
150 - @required Box<WalletInfo> walletInfoSource,
151 - @required Box<Contact> contactSource,
152 - @required Box<Trade> tradesSource,
153 - @required Box<Order> ordersSource,
154 - // @required FiatConvertationService fiatConvertationService,
155 - @required Box<Template> templates,
156 - @required Box<ExchangeTemplate> exchangeTemplates,
157 - @required Box<TransactionDescription> transactionDescriptions,
158 - @required Box<UnspentCoinsInfo> unspentCoinsInfoSource,
159 - FlutterSecureStorage secureStorage,
148 + {required SharedPreferences sharedPreferences,
149 + required Box<Node> nodes,
150 + required Box<WalletInfo> walletInfoSource,
151 + required Box<Contact> contactSource,
152 + required Box<Trade> tradesSource,
153 + required Box<Order> ordersSource,
154 + // required FiatConvertationService fiatConvertationService,
155 + required Box<Template> templates,
156 + required Box<ExchangeTemplate> exchangeTemplates,
157 + required Box<TransactionDescription> transactionDescriptions,
158 + required FlutterSecureStorage secureStorage,
159 + Box<UnspentCoinsInfo>? unspentCoinsInfoSource,
160 int initialMigrationVersion = 15}) async {
161 LanguageService.loadLocaleList();
162 await defaultSettingsMigration(
@@ -188,14 +188,14 @@ class App extends StatefulWidget {
188 }
189
190 class AppState extends State<App> with SingleTickerProviderStateMixin {
191 - AppState() {
192 - yatStore = getIt.get<YatStore>();
191 + AppState()
192 + : yatStore = getIt.get<YatStore>() {
193 SystemChrome.setPreferredOrientations(
194 [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
195 }
196
197 YatStore yatStore;
198 - StreamSubscription stream;
198 + StreamSubscription? stream;
199
200 @override
201 void initState() {
@@ -227,7 +227,7 @@ class AppState extends State<App> with SingleTickerProviderStateMixin {
227
228 void _handleIncomingLinks() {
229 if (!kIsWeb) {
230 - stream = getUriLinksStream().listen((Uri uri) {
230 + stream = getUriLinksStream().listen((Uri? uri) {
231 print('uri: $uri');
232 if (!mounted) return;
233 //_fetchEmojiFromUri(uri);
@@ -256,7 +256,8 @@ class AppState extends State<App> with SingleTickerProviderStateMixin {
256 @override
257 Widget build(BuildContext context) {
258 return Observer(builder: (BuildContext context) {
259 - final settingsStore = getIt.get<AppStore>().settingsStore;
259 + final appStore = getIt.get<AppStore>();
260 + final settingsStore = appStore.settingsStore;
261 final statusBarColor = Colors.transparent;
262 final authenticationStore = getIt.get<AuthenticationStore>();
263 final initialRoute =
@@ -277,6 +278,7 @@ class AppState extends State<App> with SingleTickerProviderStateMixin {
278
279 return Root(
280 key: rootKey,
281 + appStore: appStore,
282 authenticationStore: authenticationStore,
283 navigatorKey: navigatorKey,
284 child: MaterialApp(
lib/monero/cw_monero.dart
+42 -27
@@ -37,13 +37,13 @@ class CWMoneroAccountList extends MoneroAccountList {
37 }
38
39 @override
40 - Future<void> addAccount(Object wallet, {String label}) async {
40 + Future<void> addAccount(Object wallet, {required String label}) async {
41 final moneroWallet = wallet as MoneroWallet;
42 await moneroWallet.walletAddresses.accountList.addAccount(label: label);
43 }
44
45 @override
46 - Future<void> setLabelAccount(Object wallet, {int accountIndex, String label}) async {
46 + Future<void> setLabelAccount(Object wallet, {required int accountIndex, required String label}) async {
47 final moneroWallet = wallet as MoneroWallet;
48 await moneroWallet.walletAddresses.accountList
49 .setLabelAccount(
@@ -54,7 +54,7 @@ class CWMoneroAccountList extends MoneroAccountList {
54
55 class CWMoneroSubaddressList extends MoneroSubaddressList {
56 CWMoneroSubaddressList(this._wallet);
57 - Object _wallet;
57 + final Object _wallet;
58
59 @override
60 @computed
@@ -71,13 +71,13 @@ class CWMoneroSubaddressList extends MoneroSubaddressList {
71 }
72
73 @override
74 - void update(Object wallet, {int accountIndex}) {
74 + void update(Object wallet, {required int accountIndex}) {
75 final moneroWallet = wallet as MoneroWallet;
76 moneroWallet.walletAddresses.subaddressList.update(accountIndex: accountIndex);
77 }
78
79 @override
80 - void refresh(Object wallet, {int accountIndex}) {
80 + void refresh(Object wallet, {required int accountIndex}) {
81 final moneroWallet = wallet as MoneroWallet;
82 moneroWallet.walletAddresses.subaddressList.refresh(accountIndex: accountIndex);
83 }
@@ -93,7 +93,7 @@ class CWMoneroSubaddressList extends MoneroSubaddressList {
93 }
94
95 @override
96 - Future<void> addSubaddress(Object wallet, {int accountIndex, String label}) async {
96 + Future<void> addSubaddress(Object wallet, {required int accountIndex, required String label}) async {
97 final moneroWallet = wallet as MoneroWallet;
98 await moneroWallet.walletAddresses.subaddressList
99 .addSubaddress(
@@ -103,7 +103,7 @@ class CWMoneroSubaddressList extends MoneroSubaddressList {
103
104 @override
105 Future<void> setLabelSubaddress(Object wallet,
106 - {int accountIndex, int addressIndex, String label}) async {
106 + {required int accountIndex, required int addressIndex, required String label}) async {
107 final moneroWallet = wallet as MoneroWallet;
108 await moneroWallet.walletAddresses.subaddressList
109 .setLabelSubaddress(
@@ -115,20 +115,23 @@ class CWMoneroSubaddressList extends MoneroSubaddressList {
115
116 class CWMoneroWalletDetails extends MoneroWalletDetails {
117 CWMoneroWalletDetails(this._wallet);
118 - Object _wallet;
118 + final Object _wallet;
119
120 @computed
121 + @override
122 Account get account {
123 final moneroWallet = _wallet as MoneroWallet;
124 final acc = moneroWallet.walletAddresses.account;
124 - return Account(id: acc.id, label: acc.label);
125 + return Account(id: acc!.id, label: acc.label);
126 }
127
128 @computed
129 + @override
130 MoneroBalance get balance {
131 final moneroWallet = _wallet as MoneroWallet;
132 final balance = moneroWallet.balance;
131 - return MoneroBalance();
133 + throw Exception('Unimplemented');
134 + // return MoneroBalance();
135 //return MoneroBalance(
136 // fullBalance: balance.fullBalance,
137 // unlockedBalance: balance.unlockedBalance);
@@ -136,6 +139,7 @@ class CWMoneroWalletDetails extends MoneroWalletDetails {
139 }
140
141 class CWMonero extends Monero {
142 + @override
143 MoneroAccountList getAccountList(Object wallet) {
144 return CWMoneroAccountList(wallet);
145 }
@@ -157,7 +161,7 @@ class CWMonero extends Monero {
161 }
162
163 @override
160 - int getHeigthByDate({DateTime date}) {
164 + int getHeigthByDate({required DateTime date}) {
165 return getMoneroHeigthByDate(date: date);
166 }
167
@@ -167,7 +171,7 @@ class CWMonero extends Monero {
171 }
172
173 @override
170 - TransactionPriority deserializeMoneroTransactionPriority({int raw}) {
174 + TransactionPriority deserializeMoneroTransactionPriority({required int raw}) {
175 return MoneroTransactionPriority.deserialize(raw: raw);
176 }
177
@@ -206,13 +210,13 @@ class CWMonero extends Monero {
210
211 @override
212 WalletCredentials createMoneroRestoreWalletFromKeysCredentials({
209 - String name,
210 - String spendKey,
211 - String viewKey,
212 - String address,
213 - String password,
214 - String language,
215 - int height}) {
213 + required String name,
214 + required String spendKey,
215 + required String viewKey,
216 + required String address,
217 + required String password,
218 + required String language,
219 + required int height}) {
220 return MoneroRestoreWalletFromKeysCredentials(
221 name: name,
222 spendKey: spendKey,
@@ -224,7 +228,11 @@ class CWMonero extends Monero {
228 }
229
230 @override
227 - WalletCredentials createMoneroRestoreWalletFromSeedCredentials({String name, String password, int height, String mnemonic}) {
231 + WalletCredentials createMoneroRestoreWalletFromSeedCredentials({
232 + required String name,
233 + required String password,
234 + required int height,
235 + required String mnemonic}) {
236 return MoneroRestoreWalletFromSeedCredentials(
237 name: name,
238 password: password,
@@ -233,7 +241,10 @@ class CWMonero extends Monero {
241 }
242
243 @override
236 - WalletCredentials createMoneroNewWalletCredentials({String name, String password, String language}) {
244 + WalletCredentials createMoneroNewWalletCredentials({
245 + required String name,
246 + required String language,
247 + String? password,}) {
248 return MoneroNewWalletCredentials(
249 name: name,
250 password: password,
@@ -252,7 +263,9 @@ class CWMonero extends Monero {
263 }
264
265 @override
255 - Object createMoneroTransactionCreationCredentials({List<Output> outputs, TransactionPriority priority}) {
266 + Object createMoneroTransactionCreationCredentials({
267 + required List<Output> outputs,
268 + required TransactionPriority priority}) {
269 return MoneroTransactionCreationCredentials(
270 outputs: outputs.map((out) => OutputInfo(
271 fiatAmount: out.fiatAmount,
@@ -268,24 +281,26 @@ class CWMonero extends Monero {
281 }
282
283 @override
271 - Object createMoneroTransactionCreationCredentialsRaw({List<OutputInfo> outputs, TransactionPriority priority}) {
284 + Object createMoneroTransactionCreationCredentialsRaw({
285 + required List<OutputInfo> outputs,
286 + required TransactionPriority priority}) {
287 return MoneroTransactionCreationCredentials(
288 outputs: outputs,
289 priority: priority as MoneroTransactionPriority);
290 }
291
292 @override
278 - String formatterMoneroAmountToString({int amount}) {
293 + String formatterMoneroAmountToString({required int amount}) {
294 return moneroAmountToString(amount: amount);
295 }
296
297 @override
283 - double formatterMoneroAmountToDouble({int amount}) {
298 + double formatterMoneroAmountToDouble({required int amount}) {
299 return moneroAmountToDouble(amount: amount);
300 }
301
302 @override
288 - int formatterMoneroParseAmount({String amount}) {
303 + int formatterMoneroParseAmount({required String amount}) {
304 return moneroParseAmount(amount: amount);
305 }
306
@@ -293,7 +308,7 @@ class CWMonero extends Monero {
308 Account getCurrentAccount(Object wallet) {
309 final moneroWallet = wallet as MoneroWallet;
310 final acc = moneroWallet.walletAddresses.account;
296 - return Account(id: acc.id, label: acc.label);
311 + return Account(id: acc!.id, label: acc.label);
312 }
313
314 @override
lib/reactions/check_connection.dart
+1 -1
@@ -5,7 +5,7 @@ import 'package:cw_core/sync_status.dart';
5 import 'package:cake_wallet/store/settings_store.dart';
6 import 'package:connectivity/connectivity.dart';
7
8 -Timer _checkConnectionTimer;
8 +Timer? _checkConnectionTimer;
9
10 void startCheckConnectionReaction(
11 WalletBase wallet, SettingsStore settingsStore,
lib/reactions/fiat_rate_update.dart
+8 -6
@@ -6,7 +6,7 @@ import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
6 import 'package:cake_wallet/store/settings_store.dart';
7 import 'package:cw_core/wallet_type.dart';
8
9 -Timer _timer;
9 +Timer? _timer;
10
11 Future<void> startFiatRateUpdate(AppStore appStore, SettingsStore settingsStore,
12 FiatConversionStore fiatConversionStore) async {
@@ -14,19 +14,21 @@ Future<void> startFiatRateUpdate(AppStore appStore, SettingsStore settingsStore,
14 return;
15 }
16
17 - fiatConversionStore.prices[appStore.wallet.currency] =
17 + if (appStore.wallet != null) {
18 + fiatConversionStore.prices[appStore.wallet!.currency] =
19 await FiatConversionService.fetchPrice(
19 - appStore.wallet.currency, settingsStore.fiatCurrency);
20 + appStore.wallet!.currency, settingsStore.fiatCurrency);
21 + }
22
23 _timer = Timer.periodic(
24 Duration(seconds: 30),
25 (_) async {
26 try {
25 - if (appStore.wallet.type == WalletType.haven) {
27 + if (appStore.wallet!.type == WalletType.haven) {
28 await updateHavenRate(fiatConversionStore);
29 } else {
28 - fiatConversionStore.prices[appStore.wallet.currency] = await FiatConversionService.fetchPrice(
29 - appStore.wallet.currency, settingsStore.fiatCurrency);
30 + fiatConversionStore.prices[appStore.wallet!.currency] = await FiatConversionService.fetchPrice(
31 + appStore.wallet!.currency, settingsStore.fiatCurrency);
32 }
33 } catch(e) {
34 print(e);
lib/reactions/on_authentication_state_change.dart
+3 -6
@@ -1,11 +1,10 @@
1 import 'package:cake_wallet/routes.dart';
2 import 'package:flutter/widgets.dart';
3 import 'package:mobx/mobx.dart';
4 -import 'package:cake_wallet/router.dart';
4 import 'package:cake_wallet/entities/load_current_wallet.dart';
5 import 'package:cake_wallet/store/authentication_store.dart';
6
8 -ReactionDisposer _onAuthenticationStateChange;
7 +ReactionDisposer? _onAuthenticationStateChange;
8
9 dynamic loginError;
10
@@ -24,14 +23,12 @@ void startAuthenticationStateChange(AuthenticationStore authenticationStore,
23 }
24
25 if (state == AuthenticationState.allowed) {
27 - await navigatorKey.currentState
28 - .pushNamedAndRemoveUntil(Routes.dashboard, (route) => false);
26 + await navigatorKey.currentState!.pushNamedAndRemoveUntil(Routes.dashboard, (route) => false);
27 return;
28 }
29
30 if (state == AuthenticationState.denied) {
33 - await navigatorKey.currentState
34 - .pushNamedAndRemoveUntil(Routes.welcome, (_) => false);
31 + await navigatorKey.currentState!.pushNamedAndRemoveUntil(Routes.welcome, (_) => false);
32 return;
33 }
34 });
lib/reactions/on_current_fiat_change.dart
+8 -4
@@ -5,15 +5,19 @@ import 'package:cake_wallet/store/settings_store.dart';
5 import 'package:cake_wallet/store/app_store.dart';
6 import 'package:cake_wallet/entities/fiat_currency.dart';
7
8 -ReactionDisposer _onCurrentFiatCurrencyChangeDisposer;
8 +ReactionDisposer? _onCurrentFiatCurrencyChangeDisposer;
9
10 void startCurrentFiatChangeReaction(AppStore appStore,
11 SettingsStore settingsStore, FiatConversionStore fiatConversionStore) {
12 - _onCurrentFiatCurrencyChangeDisposer?.reaction?.dispose();
12 + _onCurrentFiatCurrencyChangeDisposer?.reaction.dispose();
13 _onCurrentFiatCurrencyChangeDisposer = reaction(
14 (_) => settingsStore.fiatCurrency, (FiatCurrency fiatCurrency) async {
15 - final cryptoCurrency = appStore.wallet.currency;
16 - fiatConversionStore.prices[appStore.wallet.currency] =
15 + if (appStore.wallet == null) {
16 + return;
17 + }
18 +
19 + final cryptoCurrency = appStore.wallet!.currency;
20 + fiatConversionStore.prices[appStore.wallet!.currency] =
21 await FiatConversionService.fetchPrice(cryptoCurrency, fiatCurrency);
22 });
23 }
lib/reactions/on_current_node_change.dart
+3 -3
@@ -2,13 +2,13 @@ import 'package:mobx/mobx.dart';
2 import 'package:cw_core/node.dart';
3 import 'package:cake_wallet/store/app_store.dart';
4
5 -ReactionDisposer _onCurrentNodeChangeReaction;
5 +ReactionDisposer? _onCurrentNodeChangeReaction;
6
7 void startOnCurrentNodeChangeReaction(AppStore appStore) {
8 - _onCurrentNodeChangeReaction?.reaction?.dispose();
8 + _onCurrentNodeChangeReaction?.reaction.dispose();
9 appStore.settingsStore.nodes.observe((change) async {
10 try {
11 - await appStore.wallet.connectToNode(node: change.newValue);
11 + await appStore.wallet!.connectToNode(node: change.newValue!);
12 } catch (e) {
13 print(e.toString());
14 }
lib/reactions/on_current_wallet_change.dart
+15 -8
@@ -15,17 +15,16 @@ import 'package:cake_wallet/store/settings_store.dart';
15 import 'package:cake_wallet/core/fiat_conversion_service.dart';
16 import 'package:cw_core/wallet_base.dart';
17 import 'package:cw_core/wallet_type.dart';
18 -import 'package:cake_wallet/store/yat/yat_store.dart';
18
20 -ReactionDisposer _onCurrentWalletChangeReaction;
21 -ReactionDisposer _onCurrentWalletChangeFiatRateUpdateReaction;
19 +ReactionDisposer? _onCurrentWalletChangeReaction;
20 +ReactionDisposer? _onCurrentWalletChangeFiatRateUpdateReaction;
21 //ReactionDisposer _onCurrentWalletAddressChangeReaction;
22
23 void startCurrentWalletChangeReaction(AppStore appStore,
24 SettingsStore settingsStore, FiatConversionStore fiatConversionStore) {
26 - _onCurrentWalletChangeReaction?.reaction?.dispose();
27 - _onCurrentWalletChangeFiatRateUpdateReaction?.reaction?.dispose();
28 - //_onCurrentWalletAddressChangeReaction?.reaction?.dispose();
25 + _onCurrentWalletChangeReaction?.reaction.dispose();
26 + _onCurrentWalletChangeFiatRateUpdateReaction?.reaction.dispose();
27 + //_onCurrentWalletAddressChangeReaction?.reaction?dispose();
28
29 //_onCurrentWalletAddressChangeReaction = reaction((_) => appStore.wallet.walletAddresses.address,
30 //(String address) async {
@@ -49,9 +48,13 @@ void startCurrentWalletChangeReaction(AppStore appStore,
48 //});
49
50 _onCurrentWalletChangeReaction = reaction((_) => appStore.wallet, (WalletBase<
52 - Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>
51 + Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>?
52 wallet) async {
53 try {
54 + if (wallet == null) {
55 + return;
56 + }
57 +
58 final node = settingsStore.getCurrentNode(wallet.type);
59 startWalletSyncStatusChangeReaction(wallet, fiatConversionStore);
60 startCheckConnectionReaction(wallet, settingsStore);
@@ -81,9 +84,13 @@ void startCurrentWalletChangeReaction(AppStore appStore,
84
85 _onCurrentWalletChangeFiatRateUpdateReaction =
86 reaction((_) => appStore.wallet, (WalletBase<Balance,
84 - TransactionHistoryBase<TransactionInfo>, TransactionInfo>
87 + TransactionHistoryBase<TransactionInfo>, TransactionInfo>?
88 wallet) async {
89 try {
90 + if (wallet == null) {
91 + return;
92 + }
93 +
94 fiatConversionStore.prices[wallet.currency] = 0;
95 fiatConversionStore.prices[wallet.currency] =
96 await FiatConversionService.fetchPrice(
lib/reactions/on_wallet_sync_status_change.dart
+2 -2
@@ -11,14 +11,14 @@ import 'package:cw_core/transaction_info.dart';
11 import 'package:cw_core/sync_status.dart';
12 import 'package:flutter/services.dart';
13
14 -ReactionDisposer _onWalletSyncStatusChangeReaction;
14 +ReactionDisposer? _onWalletSyncStatusChangeReaction;
15
16 void startWalletSyncStatusChangeReaction(
17 WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
18 TransactionInfo> wallet,
19 FiatConversionStore fiatConversionStore) {
20 final _wakeLock = getIt.get<WakeLock>();
21 - _onWalletSyncStatusChangeReaction?.reaction?.dispose();
21 + _onWalletSyncStatusChangeReaction?.reaction.dispose();
22 _onWalletSyncStatusChangeReaction =
23 reaction((_) => wallet.syncStatus, (SyncStatus status) async {
24 if (status is ConnectedSyncStatus) {
lib/router.dart
+8 -8
@@ -74,7 +74,7 @@ import 'package:cake_wallet/src/screens/ionia/cards/ionia_payment_status_page.da
74 import 'package:cake_wallet/anypay/any_pay_payment_committed_info.dart';
75 import 'package:cake_wallet/ionia/ionia_any_pay_payment_info.dart';
76
77 -RouteSettings currentRouteSettings;
77 +late RouteSettings currentRouteSettings;
78
79 Route<dynamic> createRoute(RouteSettings settings) {
80 currentRouteSettings = settings;
@@ -100,8 +100,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
100 builder: (_) => getIt.get<NewWalletTypePage>(
101 param1: (BuildContext context, WalletType type) =>
102 Navigator.of(context)
103 - .pushNamed(Routes.newWallet, arguments: type),
104 - param2: false));
103 + .pushNamed(Routes.newWallet, arguments: type)));
104
105 case Routes.newWallet:
106 final type = settings.arguments as WalletType;
@@ -111,7 +110,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
110 builder: (_) => NewWalletPage(walletNewVM));
111
112 case Routes.setupPin:
114 - Function(PinCodeState<PinCodeWidget>, String) callback;
113 + Function(PinCodeState<PinCodeWidget>, String)? callback;
114
115 if (settings.arguments is Function(PinCodeState<PinCodeWidget>, String)) {
116 callback =
@@ -286,8 +285,9 @@ Route<dynamic> createRoute(RouteSettings settings) {
285 return CupertinoPageRoute<void>(
286 builder: (context) => WillPopScope(
287 child: getIt.get<AuthPage>(instanceName: 'login'),
289 - onWillPop: () =>
290 - SystemChannels.platform.invokeMethod('SystemNavigator.pop')),
288 + onWillPop: () async =>
289 + // FIX-ME: Additional check does it works correctly
290 + (await SystemChannels.platform.invokeMethod<bool>('SystemNavigator.pop') ?? false)),
291 fullscreenDialog: true);
292
293 case Routes.accountCreation:
@@ -306,7 +306,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
306 case Routes.addressBookAddContact:
307 return CupertinoPageRoute<void>(
308 builder: (_) => getIt.get<ContactPage>(
309 - param1: settings.arguments as ContactRecord));
309 + param1: settings.arguments as ContactRecord?));
310
311 case Routes.showKeys:
312 return MaterialPageRoute<void>(
@@ -475,6 +475,6 @@ Route<dynamic> createRoute(RouteSettings settings) {
475 return MaterialPageRoute<void>(
476 builder: (_) => Scaffold(
477 body: Center(
478 - child: Text(S.current.router_no_route(settings.name)))));
478 + child: Text(S.current.router_no_route(settings.name ?? 'No route')))));
479 }
480 }
lib/src/screens/auth/auth_page.dart
+38 -32
@@ -1,5 +1,5 @@
1 import 'package:cake_wallet/utils/show_bar.dart';
2 -import 'package:flushbar/flushbar.dart';
2 +// import 'package:flushbar/flushbar.dart';
3 import 'package:mobx/mobx.dart';
4 import 'package:flutter/material.dart';
5 import 'package:flutter/cupertino.dart';
@@ -8,14 +8,14 @@ import 'package:cake_wallet/view_model/auth_state.dart';
8 import 'package:cake_wallet/view_model/auth_view_model.dart';
9 import 'package:cake_wallet/src/screens/pin_code/pin_code.dart';
10 import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
11 -import 'package:cake_wallet/entities/biometric_auth.dart';
11 import 'package:cake_wallet/core/execution_state.dart';
12
13 typedef OnAuthenticationFinished = void Function(bool, AuthPageState);
14
15 class AuthPage extends StatefulWidget {
16 AuthPage(this.authViewModel,
18 - {this.onAuthenticationFinished, this.closable = true});
17 + {required this.onAuthenticationFinished,
18 + this.closable = true});
19
20 final AuthViewModel authViewModel;
21 final OnAuthenticationFinished onAuthenticationFinished;
@@ -30,9 +30,10 @@ class AuthPageState extends State<AuthPage> {
30 final _pinCodeKey = GlobalKey<PinCodeState>();
31 final _backArrowImageDarkTheme =
32 Image.asset('assets/images/close_button.png');
33 - ReactionDisposer _reaction;
34 - Flushbar<void> _authBar;
35 - Flushbar<void> _progressBar;
33 + ReactionDisposer? _reaction;
34 + // FIX-ME: replace Flushbar
35 + // Flushbar<void>? _authBar;
36 + // Flushbar<void>? _progressBar;
37
38 @override
39 void initState() {
@@ -40,28 +41,27 @@ class AuthPageState extends State<AuthPage> {
41 reaction((_) => widget.authViewModel.state, (ExecutionState state) {
42 if (state is ExecutedSuccessfullyState) {
43 WidgetsBinding.instance.addPostFrameCallback((_) {
43 - _authBar?.dismiss();
44 - if (widget.onAuthenticationFinished != null) {
45 - widget.onAuthenticationFinished(true, this);
46 - } else {
47 - showBar<void>(context, S.of(context).authenticated);
48 - }
44 + widget.onAuthenticationFinished(true, this);
45 });
46 setState(() {});
47 }
48
49 if (state is IsExecutingState) {
50 WidgetsBinding.instance.addPostFrameCallback((_) {
55 - _authBar =
56 - createBar<void>(S.of(context).authentication, duration: null)
57 - ..show(context);
51 + // FIX-ME: Changes related to flutter upgreade.
52 + // Could be incorrect value for duration of auth bar
53 + // _authBar =
54 + // createBar<void>(S.of(context).authentication, duration: Duration())
55 + // ..show(context);
56 });
57 }
58
59 if (state is FailureState) {
60 + print('X');
61 + print(state.error);
62 WidgetsBinding.instance.addPostFrameCallback((_) {
63 - _pinCodeKey.currentState.clear();
64 - _authBar?.dismiss();
63 + _pinCodeKey.currentState?.clear();
64 + // _authBar?.dismiss();
65 showBar<void>(
66 context, S.of(context).failed_authentication(state.error));
67
@@ -73,8 +73,8 @@ class AuthPageState extends State<AuthPage> {
73
74 if (state is AuthenticationBanned) {
75 WidgetsBinding.instance.addPostFrameCallback((_) {
76 - _pinCodeKey.currentState.clear();
77 - _authBar?.dismiss();
76 + _pinCodeKey.currentState?.clear();
77 + // _authBar?.dismiss();
78 showBar<void>(
79 context, S.of(context).failed_authentication(state.error));
80
@@ -97,25 +97,31 @@ class AuthPageState extends State<AuthPage> {
97
98 @override
99 void dispose() {
100 - _reaction.reaction.dispose();
100 + _reaction?.reaction.dispose();
101 super.dispose();
102 }
103
104 void changeProcessText(String text) {
105 - _authBar?.dismiss();
106 - _progressBar = createBar<void>(text, duration: null)
107 - ..show(_key.currentContext);
105 + // _authBar?.dismiss();
106 + // FIX-ME: Changes related to flutter upgreade.
107 + // Could be incorrect value for duration of auth bar
108 + // _progressBar = createBar<void>(text, duration: Duration())
109 + // ..show(_key.currentContext);
110 }
111
112 void hideProgressText() {
111 - _progressBar?.dismiss();
112 - _progressBar = null;
113 + // _progressBar?.dismiss();
114 + // _progressBar = null;
115 }
116
117 void close() {
116 - _authBar?.dismiss();
117 - _progressBar?.dismiss();
118 - Navigator.of(_key.currentContext).pop();
118 + if (_key.currentContext == null) {
119 + throw Exception('Key context is null. Should be not happened');
120 + }
121 +
122 + // _authBar?.dismiss();
123 + // _progressBar?.dismiss();
124 + Navigator.of(_key.currentContext!).pop();
125 }
126
127 @override
@@ -131,10 +137,10 @@ class AuthPageState extends State<AuthPage> {
137 width: 37,
138 child: ButtonTheme(
139 minWidth: double.minPositive,
134 - child: FlatButton(
135 - highlightColor: Colors.transparent,
136 - splashColor: Colors.transparent,
137 - padding: EdgeInsets.all(0),
140 + child: TextButton(
141 + //highlightColor: Colors.transparent,
142 + //splashColor: Colors.transparent,
143 + //padding: EdgeInsets.all(0),
144 onPressed: () => Navigator.of(context).pop(),
145 child: _backArrowImageDarkTheme),
146 ),
lib/src/screens/backup/backup_page.dart
+9 -7
@@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
4 import 'package:flutter/cupertino.dart';
5 import 'package:flutter/services.dart';
6 import 'package:flutter_mobx/flutter_mobx.dart';
7 -import 'package:esys_flutter_share/esys_flutter_share.dart';
7 +// import 'package:esys_flutter_share/esys_flutter_share.dart';
8 import 'package:cake_wallet/utils/show_bar.dart';
9 import 'package:cake_wallet/routes.dart';
10 import 'package:cake_wallet/generated/i18n.dart';
@@ -80,7 +80,7 @@ class BackupPage extends BasePage {
80 isLoading: backupViewModelBase.state is IsExecutingState,
81 onPressed: () => onExportBackup(context),
82 text: S.of(context).export_backup,
83 - color: Theme.of(context).accentTextTheme.body2.color,
83 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
84 textColor: Colors.white)),
85 bottom: 24,
86 left: 24,
@@ -104,10 +104,11 @@ class BackupPage extends BasePage {
104 final backup = await backupViewModelBase.exportBackup();
105
106 if (Platform.isAndroid) {
107 - onExportAndroid(context, backup);
107 + onExportAndroid(context, backup!);
108 } else {
109 - await Share.file(S.of(context).backup_file, backup.name,
110 - backup.content, 'application/*');
109 + // FIX-ME: Share esys_flutter_share.dart
110 + // await Share.file(S.of(context).backup_file, backup.name,
111 + // backup.content, 'application/*');
112 }
113 },
114 actionLeftButton: () => Navigator.of(dialogContext).pop());
@@ -137,8 +138,9 @@ class BackupPage extends BasePage {
138 },
139 actionLeftButton: () {
140 Navigator.of(dialogContext).pop();
140 - Share.file(S.of(context).backup_file, backup.name,
141 - backup.content, 'application/*');
141 + // FIX-ME: Share esys_flutter_share.dart
142 + // Share.file(S.of(context).backup_file, backup.name,
143 + // backup.content, 'application/*');
144 });
145 });
146 }
lib/src/screens/backup/edit_backup_password_page.dart
+2 -2
@@ -39,13 +39,13 @@ class EditBackupPasswordPage extends BasePage {
39 controller: textEditingController,
40 style: TextStyle(
41 fontSize: 26,
42 - color: Theme.of(context).primaryTextTheme.title.color)))),
42 + color: Theme.of(context).primaryTextTheme!.headline6!.color!)))),
43 Positioned(
44 child: Observer(
45 builder: (_) => PrimaryButton(
46 onPressed: () => onSave(context),
47 text: S.of(context).save,
48 - color: Theme.of(context).accentTextTheme.body2.color,
48 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
49 textColor: Colors.white,
50 isDisabled: !editBackupPasswordViewModel.canSave)),
51 bottom: 24,
lib/src/screens/base_page.dart
+24 -20
@@ -18,7 +18,7 @@ abstract class BasePage extends StatelessWidget {
18 final Image closeButtonImageDarkTheme =
19 Image.asset('assets/images/close_button_dark_theme.png');
20
21 - String get title => null;
21 + String? get title => null;
22
23 bool get isModalBackButton => false;
24
@@ -26,31 +26,31 @@ abstract class BasePage extends StatelessWidget {
26
27 Color get backgroundDarkColor => PaletteDark.backgroundColor;
28
29 - Color get titleColor => null;
29 + Color? get titleColor => null;
30
31 bool get resizeToAvoidBottomInset => true;
32
33 bool get extendBodyBehindAppBar => false;
34
35 - Widget get endDrawer => null;
35 + Widget? get endDrawer => null;
36
37 AppBarStyle get appBarStyle => AppBarStyle.regular;
38
39 - Widget Function(BuildContext, Widget) get rootWrapper => null;
39 + Widget Function(BuildContext, Widget)? get rootWrapper => null;
40
41 ThemeBase get currentTheme => getIt.get<SettingsStore>().currentTheme;
42
43 - void onOpenEndDrawer() => _scaffoldKey.currentState.openEndDrawer();
43 + void onOpenEndDrawer() => _scaffoldKey.currentState!.openEndDrawer();
44
45 void onClose(BuildContext context) => Navigator.of(context).pop();
46
47 - Widget leading(BuildContext context) {
48 - if (ModalRoute.of(context).isFirst) {
47 + Widget? leading(BuildContext context) {
48 + if (ModalRoute.of(context)?.isFirst ?? true) {
49 return null;
50 }
51
52 final _backButton = Icon(Icons.arrow_back_ios,
53 - color: titleColor ?? Theme.of(context).primaryTextTheme.title.color,
53 + color: titleColor ?? Theme.of(context).primaryTextTheme!.headline6!.color!,
54 size: 16,);
55 final _closeButton = currentTheme.type == ThemeType.dark
56 ? closeButtonImageDarkTheme : closeButtonImage;
@@ -60,33 +60,34 @@ abstract class BasePage extends StatelessWidget {
60 width: 37,
61 child: ButtonTheme(
62 minWidth: double.minPositive,
63 - child: FlatButton(
64 - highlightColor: Colors.transparent,
65 - splashColor: Colors.transparent,
66 - padding: EdgeInsets.all(0),
63 + child: TextButton(
64 + // FIX-ME: Style
65 + //highlightColor: Colors.transparent,
66 + //splashColor: Colors.transparent,
67 + //padding: EdgeInsets.all(0),
68 onPressed: () => onClose(context),
69 child: isModalBackButton ? _closeButton : _backButton),
70 ),
71 );
72 }
73
73 - Widget middle(BuildContext context) {
74 + Widget? middle(BuildContext context) {
75 return title == null
76 ? null
77 : Text(
77 - title,
78 + title!,
79 style: TextStyle(
80 fontSize: 18.0,
81 fontWeight: FontWeight.bold,
82 fontFamily: 'Lato',
83 color: titleColor ??
83 - Theme.of(context).primaryTextTheme.title.color),
84 + Theme.of(context).primaryTextTheme!.headline6!.color!),
85 );
86 }
87
87 - Widget trailing(BuildContext context) => null;
88 + Widget? trailing(BuildContext context) => null;
89
89 - Widget floatingActionButton(BuildContext context) => null;
90 + Widget? floatingActionButton(BuildContext context) => null;
91
92 ObstructingPreferredSizeWidget appBar(BuildContext context) {
93 final appBarColor = currentTheme.type == ThemeType.dark
@@ -94,16 +95,18 @@ abstract class BasePage extends StatelessWidget {
95
96 switch (appBarStyle) {
97 case AppBarStyle.regular:
98 + // FIX-ME: NavBar no context
99 return NavBar(
98 - context: context,
100 + // context: context,
101 leading: leading(context),
102 middle: middle(context),
103 trailing: trailing(context),
104 backgroundColor: appBarColor);
105
106 case AppBarStyle.withShadow:
107 + // FIX-ME: NavBar no context
108 return NavBar.withShadow(
106 - context: context,
109 + // context: context,
110 leading: leading(context),
111 middle: middle(context),
112 trailing: trailing(context),
@@ -119,8 +122,9 @@ abstract class BasePage extends StatelessWidget {
122 );
123
124 default:
125 + // FIX-ME: NavBar no context
126 return NavBar(
123 - context: context,
127 + // context: context,
128 leading: leading(context),
129 middle: middle(context),
130 trailing: trailing(context),
lib/src/screens/buy/buy_webview_page.dart
+21 -14
@@ -12,8 +12,8 @@ import 'package:flutter/material.dart';
12 import 'package:webview_flutter/webview_flutter.dart';
13
14 class BuyWebViewPage extends BasePage {
15 - BuyWebViewPage({@required this.buyViewModel,
16 - @required this.ordersStore, @required this.url});
15 + BuyWebViewPage({required this.buyViewModel,
16 + required this.ordersStore, required this.url});
17
18 final OrdersStore ordersStore;
19 final String url;
@@ -34,10 +34,10 @@ class BuyWebViewPage extends BasePage {
34 }
35
36 class BuyWebViewPageBody extends StatefulWidget {
37 - BuyWebViewPageBody(this.buyViewModel, {this.ordersStore, this.url});
37 + BuyWebViewPageBody(this.buyViewModel, {required this.ordersStore, this.url});
38
39 final OrdersStore ordersStore;
40 - final String url;
40 + final String? url;
41 final BuyViewModel buyViewModel;
42
43 @override
@@ -45,12 +45,16 @@ class BuyWebViewPageBody extends StatefulWidget {
45 }
46
47 class BuyWebViewPageBodyState extends State<BuyWebViewPageBody> {
48 + BuyWebViewPageBodyState()
49 + : _webViewkey = GlobalKey(),
50 + _isSaving = false,
51 + orderId = '';
52 +
53 String orderId;
49 - WebViewController _webViewController;
54 + WebViewController? _webViewController;
55 GlobalKey _webViewkey;
51 - Timer _timer;
56 + Timer? _timer;
57 bool _isSaving;
53 - BuyProvider _provider;
58
59 @override
60 void initState() {
@@ -58,15 +62,14 @@ class BuyWebViewPageBodyState extends State<BuyWebViewPageBody> {
62 _webViewkey = GlobalKey();
63 _isSaving = false;
64 widget.ordersStore.orderId = '';
61 - _provider = widget.buyViewModel.selectedProvider;
65
66 if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
67
65 - if (_provider is WyreBuyProvider) {
68 + if (widget.buyViewModel.selectedProvider is WyreBuyProvider) {
69 _saveOrder(keyword: 'completed', splitSymbol: '/');
70 }
71
69 - if (_provider is MoonPayBuyProvider) {
72 + if (widget.buyViewModel.selectedProvider is MoonPayBuyProvider) {
73 _saveOrder(keyword: 'transactionId', splitSymbol: '=');
74 }
75 }
@@ -81,7 +84,7 @@ class BuyWebViewPageBodyState extends State<BuyWebViewPageBody> {
84 setState(() => _webViewController = controller));
85 }
86
84 - void _saveOrder({String keyword, String splitSymbol}) {
87 + void _saveOrder({required String keyword, required String splitSymbol}) {
88 _timer?.cancel();
89 _timer = Timer.periodic(Duration(seconds: 1), (timer) async {
90
@@ -90,10 +93,14 @@ class BuyWebViewPageBodyState extends State<BuyWebViewPageBody> {
93 return;
94 }
95
93 - final url = await _webViewController.currentUrl();
96 + final url = await _webViewController!.currentUrl();
97 +
98 + if (url == null) {
99 + throw Exception('_saveOrder: Url is null');
100 + }
101
95 - if (url.contains(keyword)) {
96 - final urlParts = url.split(splitSymbol);
102 + if (url!.contains(keyword)) {
103 + final urlParts = url!.split(splitSymbol);
104 orderId = urlParts.last;
105 widget.ordersStore.orderId = orderId;
106
lib/src/screens/buy/pre_order_page.dart
+21 -23
@@ -1,4 +1,3 @@
1 -import 'dart:ui';
1 import 'package:cake_wallet/buy/buy_amount.dart';
2 import 'package:cake_wallet/buy/buy_provider.dart';
3 import 'package:cake_wallet/buy/moonpay/moonpay_buy_provider.dart';
@@ -10,7 +9,6 @@ import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
9 import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
10 import 'package:cake_wallet/utils/show_pop_up.dart';
11 import 'package:cake_wallet/view_model/buy/buy_view_model.dart';
13 -import 'package:flutter/cupertino.dart';
12 import 'package:flutter/material.dart';
13 import 'package:flutter/services.dart';
14 import 'package:flutter_mobx/flutter_mobx.dart';
@@ -26,7 +24,7 @@ import 'package:mobx/mobx.dart';
24 import 'package:url_launcher/url_launcher.dart';
25
26 class PreOrderPage extends BasePage {
29 - PreOrderPage({@required this.buyViewModel})
27 + PreOrderPage({required this.buyViewModel})
28 : _amountFocus = FocusNode(),
29 _amountController = TextEditingController() {
30 _amountController.addListener(() {
@@ -82,8 +80,8 @@ class PreOrderPage extends BasePage {
80 return KeyboardActions(
81 config: KeyboardActionsConfig(
82 keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
85 - keyboardBarColor: Theme.of(context).accentTextTheme.body2
86 - .backgroundColor,
83 + keyboardBarColor: Theme.of(context).accentTextTheme!.bodyText1!
84 + .backgroundColor!,
85 nextFocus: false,
86 actions: [
87 KeyboardActionsItem(
@@ -104,11 +102,11 @@ class PreOrderPage extends BasePage {
102 bottomLeft: Radius.circular(24),
103 bottomRight: Radius.circular(24)),
104 gradient: LinearGradient(colors: [
107 - Theme.of(context).primaryTextTheme.subhead.color,
105 + Theme.of(context).primaryTextTheme!.subtitle1!.color!,
106 Theme.of(context)
109 - .primaryTextTheme
110 - .subhead
111 - .decorationColor,
107 + .primaryTextTheme!
108 + .subtitle1!
109 + .decorationColor!,
110 ], begin: Alignment.topLeft, end: Alignment.bottomRight),
111 ),
112 child: Padding(
@@ -163,11 +161,11 @@ class PreOrderPage extends BasePage {
161 ),
162 ),
163 hintText: '0.00',
166 - borderColor: Theme.of(context).primaryTextTheme.body2.decorationColor,
164 + borderColor: Theme.of(context).primaryTextTheme!.bodyText1!.decorationColor!,
165 borderWidth: 0.5,
166 textStyle: TextStyle(fontSize: 36, fontWeight: FontWeight.w500, color: Colors.white),
167 placeholderTextStyle: TextStyle(
170 - color: Theme.of(context).primaryTextTheme.headline.decorationColor,
168 + color: Theme.of(context).primaryTextTheme!.headline5!.decorationColor!,
169 fontWeight: FontWeight.w500,
170 fontSize: 36,
171 ),
@@ -182,7 +180,7 @@ class PreOrderPage extends BasePage {
180 S.of(context).buy_with + ':',
181 textAlign: TextAlign.center,
182 style: TextStyle(
185 - color: Theme.of(context).primaryTextTheme.title.color,
183 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
184 fontSize: 18,
185 fontWeight: FontWeight.bold
186 ),
@@ -200,14 +198,15 @@ class PreOrderPage extends BasePage {
198 int minAmount;
199
200 if (snapshot.hasData) {
203 - sourceAmount = snapshot.data.sourceAmount;
204 - destAmount = snapshot.data.destAmount;
205 - minAmount = snapshot.data.minAmount;
206 - achAmount = snapshot.data.achSourceAmount;
201 + sourceAmount = snapshot.data!.sourceAmount;
202 + destAmount = snapshot.data!.destAmount;
203 + minAmount = snapshot.data!.minAmount;
204 + achAmount = snapshot.data!.achSourceAmount!;
205 } else {
206 sourceAmount = 0.0;
207 destAmount = 0.0;
208 minAmount = 0;
209 + achAmount = 0;
210 }
211
212 return Padding(
@@ -216,7 +215,7 @@ class PreOrderPage extends BasePage {
215 child: Observer(builder: (_) {
216 return BuyListItem(
217 selectedProvider:
219 - buyViewModel.selectedProvider,
218 + buyViewModel.selectedProvider!,
219 provider: item.provider,
220 sourceAmount: sourceAmount,
221 sourceCurrency: buyViewModel.fiatCurrency,
@@ -247,9 +246,8 @@ class PreOrderPage extends BasePage {
246 text: buyViewModel.selectedProvider == null
247 ? S.of(context).buy
248 : S.of(context).buy_with +
250 - ' ${buyViewModel.selectedProvider
251 - .description.title}',
252 - color: Theme.of(context).accentTextTheme.body2.color,
249 + ' ${buyViewModel.selectedProvider!.description.title}',
250 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
251 textColor: Colors.white,
252 isLoading: buyViewModel.isRunning,
253 isDisabled: (buyViewModel.selectedProvider == null) ||
@@ -261,8 +259,8 @@ class PreOrderPage extends BasePage {
259 );
260 }
261
264 - void onSelectBuyProvider({BuildContext context, BuyProvider provider,
265 - double sourceAmount, int minAmount}) {
262 + void onSelectBuyProvider({required BuildContext context, required BuyProvider provider,
263 + required double sourceAmount, required int minAmount}) {
264
265 if ((provider is MoonPayBuyProvider)&&
266 (buyViewModel.buyAmountViewModel.doubleAmount < minAmount)) {
@@ -285,7 +283,7 @@ class PreOrderPage extends BasePage {
283 : buyViewModel.isDisabled = true;
284 }
285
288 - Future<void> onPresentProvider({BuildContext context}) async {
286 + Future<void> onPresentProvider({required BuildContext context}) async {
287 if (buyViewModel.isRunning) {
288 return;
289 }
lib/src/screens/buy/widgets/buy_list_item.dart
+11 -11
@@ -8,14 +8,14 @@ import 'package:flutter/material.dart';
8
9 class BuyListItem extends StatelessWidget {
10 BuyListItem({
11 - @required this.selectedProvider,
12 - @required this.provider,
13 - @required this.sourceAmount,
14 - @required this.sourceCurrency,
15 - @required this.destAmount,
16 - @required this.destCurrency,
17 - @required this.achSourceAmount,
18 - @required this.onTap
11 + required this.selectedProvider,
12 + required this.provider,
13 + required this.sourceAmount,
14 + required this.sourceCurrency,
15 + required this.destAmount,
16 + required this.destCurrency,
17 + required this.achSourceAmount,
18 + this.onTap
19 });
20
21 final BuyProvider selectedProvider;
@@ -25,7 +25,7 @@ class BuyListItem extends StatelessWidget {
25 final double destAmount;
26 final CryptoCurrency destCurrency;
27 final double achSourceAmount;
28 - final void Function() onTap;
28 + final VoidCallback? onTap;
29
30 @override
31 Widget build(BuildContext context) {
@@ -33,7 +33,7 @@ class BuyListItem extends StatelessWidget {
33 final iconColor = isSelected ? Colors.white : Colors.black;
34
35 final providerIcon = getBuyProviderIcon(provider.description,
36 - iconColor: iconColor);
36 + iconColor: iconColor)!;
37
38 final backgroundColor = isSelected
39 ? Palette.greyBlueCraiola
@@ -48,7 +48,7 @@ class BuyListItem extends StatelessWidget {
48 : Palette.darkBlueCraiola;
49
50 return GestureDetector(
51 - onTap: () => onTap?.call(),
51 + onTap: onTap,
52 child: Container(
53 padding: EdgeInsets.only(
54 left: 20,
lib/src/screens/contact/contact_list_page.dart
+46 -43
@@ -24,7 +24,7 @@ class ContactListPage extends BasePage {
24 String get title => S.current.address_book;
25
26 @override
27 - Widget trailing(BuildContext context) {
27 + Widget? trailing(BuildContext context) {
28 if (!isEditable) {
29 return null;
30 }
@@ -34,18 +34,19 @@ class ContactListPage extends BasePage {
34 height: 32.0,
35 decoration: BoxDecoration(
36 shape: BoxShape.circle,
37 - color: Theme.of(context).accentTextTheme.caption.color),
37 + color: Theme.of(context).accentTextTheme!.caption!.color!),
38 child: Stack(
39 alignment: Alignment.center,
40 children: <Widget>[
41 Icon(Icons.add,
42 - color: Theme.of(context).primaryTextTheme.title.color,
42 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
43 size: 22.0),
44 ButtonTheme(
45 minWidth: 32.0,
46 height: 32.0,
47 - child: FlatButton(
48 - shape: CircleBorder(),
47 + child: TextButton(
48 + // FIX-ME: Style
49 + //shape: CircleBorder(),
50 onPressed: () async {
51 await Navigator.of(context)
52 .pushNamed(Routes.addressBookAddContact);
@@ -65,9 +66,9 @@ class ContactListPage extends BasePage {
66 return CollapsibleSectionList(
67 context: context,
68 sectionCount: 2,
68 - themeColor: Theme.of(context).primaryTextTheme.title.color,
69 + themeColor: Theme.of(context).primaryTextTheme!.headline6!.color!,
70 dividerThemeColor:
70 - Theme.of(context).primaryTextTheme.caption.decorationColor,
71 + Theme.of(context).primaryTextTheme!.caption!.decorationColor!,
72 sectionTitleBuilder: (_, int sectionIndex) {
73 var title = 'Contacts';
74
@@ -90,36 +91,37 @@ class ContactListPage extends BasePage {
91
92 final contact = contactListViewModel.contacts[index];
93 final content = generateRaw(context, contact);
94 + // FIX-ME: Slidable
95 + return content;
96 + // return !isEditable
97 + // ? content
98 + // : Slidable(
99 + // key: Key('${contact.key}'),
100 + // actionPane: SlidableDrawerActionPane(),
101 + // child: content,
102 + // secondaryActions: <Widget>[
103 + // IconSlideAction(
104 + // caption: S.of(context).edit,
105 + // color: Colors.blue,
106 + // icon: Icons.edit,
107 + // onTap: () async => await Navigator.of(context)
108 + // .pushNamed(Routes.addressBookAddContact,
109 + // arguments: contact),
110 + // ),
111 + // IconSlideAction(
112 + // caption: S.of(context).delete,
113 + // color: Colors.red,
114 + // icon: CupertinoIcons.delete,
115 + // onTap: () async {
116 + // final isDelete =
117 + // await showAlertDialog(context) ?? false;
118
94 - return !isEditable
95 - ? content
96 - : Slidable(
97 - key: Key('${contact.key}'),
98 - actionPane: SlidableDrawerActionPane(),
99 - child: content,
100 - secondaryActions: <Widget>[
101 - IconSlideAction(
102 - caption: S.of(context).edit,
103 - color: Colors.blue,
104 - icon: Icons.edit,
105 - onTap: () async => await Navigator.of(context)
106 - .pushNamed(Routes.addressBookAddContact,
107 - arguments: contact),
108 - ),
109 - IconSlideAction(
110 - caption: S.of(context).delete,
111 - color: Colors.red,
112 - icon: CupertinoIcons.delete,
113 - onTap: () async {
114 - final isDelete =
115 - await showAlertDialog(context) ?? false;
116 -
117 - if (isDelete) {
118 - await contactListViewModel.delete(contact);
119 - }
120 - },
121 - ),
122 - ]);
119 + // if (isDelete) {
120 + // await contactListViewModel.delete(contact);
121 + // }
122 + // },
123 + // ),
124 + // ]);
125 },
126 );
127 },
@@ -163,7 +165,7 @@ class ContactListPage extends BasePage {
165 style: TextStyle(
166 fontSize: 14,
167 fontWeight: FontWeight.normal,
166 - color: Theme.of(context).primaryTextTheme.title.color),
168 + color: Theme.of(context).primaryTextTheme!.headline6!.color!),
169 ),
170 )
171 )
@@ -173,8 +175,9 @@ class ContactListPage extends BasePage {
175 );
176 }
177
176 - Image _getCurrencyImage(CryptoCurrency currency) {
177 - Image image;
178 + Image? _getCurrencyImage(CryptoCurrency currency) {
179 + Image? image;
180 +
181 switch (currency) {
182 case CryptoCurrency.xmr:
183 image =
@@ -236,7 +239,7 @@ class ContactListPage extends BasePage {
239 }
240
241 Future<bool> showAlertDialog(BuildContext context) async {
239 - return await showPopUp(
242 + return await showPopUp<bool>(
243 context: context,
244 builder: (BuildContext context) {
245 return AlertWithTwoActions(
@@ -246,12 +249,12 @@ class ContactListPage extends BasePage {
249 leftButtonText: S.of(context).cancel,
250 actionRightButton: () => Navigator.of(context).pop(true),
251 actionLeftButton: () => Navigator.of(context).pop(false));
249 - });
252 + }) ?? false;
253 }
254
255 Future<bool> showNameAndAddressDialog(
256 BuildContext context, String name, String address) async {
254 - return await showPopUp(
257 + return await showPopUp<bool>(
258 context: context,
259 builder: (BuildContext context) {
260 return AlertWithTwoActions(
@@ -261,6 +264,6 @@ class ContactListPage extends BasePage {
264 leftButtonText: S.of(context).cancel,
265 actionRightButton: () => Navigator.of(context).pop(true),
266 actionLeftButton: () => Navigator.of(context).pop(false));
264 - });
267 + }) ?? false;
268 }
269 }
lib/src/screens/contact/contact_page.dart
+8 -6
@@ -48,7 +48,7 @@ class ContactPage extends BasePage {
48 @override
49 Widget body(BuildContext context) {
50 final downArrow = Image.asset('assets/images/arrow_bottom_purple_icon.png',
51 - color: Theme.of(context).primaryTextTheme.overline.color, height: 8);
51 + color: Theme.of(context).primaryTextTheme!.overline!.color!, height: 8);
52
53 reaction((_) => contactViewModel.state, (ExecutionState state) {
54 if (state is FailureState) {
@@ -98,9 +98,9 @@ class ContactPage extends BasePage {
98 AddressTextFieldOption.paste,
99 AddressTextFieldOption.qrCode,
100 ],
101 - buttonColor: Theme.of(context).accentTextTheme.display2.color,
101 + buttonColor: Theme.of(context).accentTextTheme!.headline3!.color!,
102 iconColor: PaletteDark.gray,
103 - borderColor: Theme.of(context).primaryTextTheme.title.backgroundColor,
103 + borderColor: Theme.of(context).primaryTextTheme!.headline6!.backgroundColor!,
104 validator: TextValidator()
105 // AddressValidator(
106 // type: contactViewModel.currency),
@@ -129,14 +129,14 @@ class ContactPage extends BasePage {
129 child: Observer(
130 builder: (_) => PrimaryButton(
131 onPressed: () async {
132 - if (!_formKey.currentState.validate()) {
132 + if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
133 return;
134 }
135
136 await contactViewModel.save();
137 },
138 text: S.of(context).save,
139 - color: Theme.of(context).accentTextTheme.body2.color,
139 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
140 textColor: Colors.white,
141 isDisabled: !contactViewModel.isReady)))
142 ],
@@ -147,7 +147,9 @@ class ContactPage extends BasePage {
147 showPopUp<void>(
148 builder: (_) => CurrencyPicker(
149 selectedAtIndex:
150 - contactViewModel.currencies.indexOf(contactViewModel.currency),
150 + contactViewModel.currency != null
151 + ? contactViewModel.currencies.indexOf(contactViewModel.currency!)
152 + : 0,
153 items: contactViewModel.currencies,
154 title: S.of(context).please_select,
155 hintText: S.of(context).search_currency,
lib/src/screens/dashboard/dashboard_page.dart
+39 -38
@@ -26,9 +26,9 @@ import 'package:url_launcher/url_launcher.dart';
26
27 class DashboardPage extends BasePage {
28 DashboardPage({
29 - @required this.balancePage,
30 - @required this.walletViewModel,
31 - @required this.addressListViewModel,
29 + required this.balancePage,
30 + required this.walletViewModel,
31 + required this.addressListViewModel,
32 });
33 final BalancePage balancePage;
34
@@ -66,15 +66,16 @@ class DashboardPage extends BasePage {
66 @override
67 Widget trailing(BuildContext context) {
68 final menuButton = Image.asset('assets/images/menu.png',
69 - color: Theme.of(context).accentTextTheme.display3.backgroundColor);
69 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!);
70
71 return Container(
72 alignment: Alignment.centerRight,
73 width: 40,
74 - child: FlatButton(
75 - highlightColor: Colors.transparent,
76 - splashColor: Colors.transparent,
77 - padding: EdgeInsets.all(0),
74 + child: TextButton(
75 + // FIX-ME: Style
76 + //highlightColor: Colors.transparent,
77 + //splashColor: Colors.transparent,
78 + //padding: EdgeInsets.all(0),
79 onPressed: () => onOpenEndDrawer(),
80 child: menuButton));
81 }
@@ -85,18 +86,18 @@ class DashboardPage extends BasePage {
86
87 var pages = <Widget>[];
88 bool _isEffectsInstalled = false;
88 - StreamSubscription<bool> _onInactiveSub;
89 + StreamSubscription<bool>? _onInactiveSub;
90
91 @override
92 Widget body(BuildContext context) {
93 final sendImage = Image.asset('assets/images/upload.png',
94 height: 24,
95 width: 24,
95 - color: Theme.of(context).accentTextTheme.display3.backgroundColor);
96 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!);
97 final receiveImage = Image.asset('assets/images/received.png',
98 height: 24,
99 width: 24,
99 - color: Theme.of(context).accentTextTheme.display3.backgroundColor);
100 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!);
101 _setEffects(context);
102
103 return SafeArea(
@@ -121,9 +122,9 @@ class DashboardPage extends BasePage {
122 dotHeight: 6.0,
123 dotColor: Theme.of(context).indicatorColor,
124 activeDotColor: Theme.of(context)
124 - .accentTextTheme
125 - .display1
126 - .backgroundColor),
125 + .accentTextTheme!
126 + .headline4!
127 + .backgroundColor!),
128 )),
129 Observer(builder: (_) {
130 return ClipRect(
@@ -133,7 +134,7 @@ class DashboardPage extends BasePage {
134 decoration: BoxDecoration(
135 borderRadius: BorderRadius.circular(50.0),
136 border: Border.all(color: currentTheme.type == ThemeType.bright ? Color.fromRGBO(255, 255, 255, 0.2): Colors.transparent, width: 1, ),
136 - color:Theme.of(context).textTheme.title.backgroundColor),
137 + color:Theme.of(context).textTheme!.headline6!.backgroundColor!),
138 child: Container(
139 padding: EdgeInsets.only(left: 32, right: 32),
140 child: Row(
@@ -146,17 +147,17 @@ class DashboardPage extends BasePage {
147 width: 24,
148 color: !walletViewModel.isEnabledBuyAction
149 ? Theme.of(context)
149 - .accentTextTheme
150 - .display2
151 - .backgroundColor
152 - : Theme.of(context).accentTextTheme.display3.backgroundColor),
150 + .accentTextTheme!
151 + .headline3!
152 + .backgroundColor!
153 + : Theme.of(context).accentTextTheme!.headline2!.backgroundColor!),
154 title: S.of(context).buy,
155 onClick: () async => await _onClickBuyButton(context),
156 textColor: !walletViewModel.isEnabledBuyAction
157 ? Theme.of(context)
157 - .accentTextTheme
158 - .display2
159 - .backgroundColor
158 + .accentTextTheme!
159 + .headline3!
160 + .backgroundColor!
161 : null),
162 ActionButton(
163 image: receiveImage,
@@ -169,17 +170,17 @@ class DashboardPage extends BasePage {
170 width: 24,
171 color: !walletViewModel.isEnabledExchangeAction
172 ? Theme.of(context)
172 - .accentTextTheme
173 - .display2
174 - .backgroundColor
175 - : Theme.of(context).accentTextTheme.display3.backgroundColor),
173 + .accentTextTheme!
174 + .headline3!
175 + .backgroundColor!
176 + : Theme.of(context).accentTextTheme!.headline2!.backgroundColor!),
177 title: S.of(context).exchange,
178 onClick: () async => _onClickExchangeButton(context),
179 textColor: !walletViewModel.isEnabledExchangeAction
180 ? Theme.of(context)
180 - .accentTextTheme
181 - .display2
182 - .backgroundColor
181 + .accentTextTheme!
182 + .headline3!
183 + .backgroundColor!
184 : null),
185 ActionButton(
186 image: sendImage,
@@ -192,17 +193,17 @@ class DashboardPage extends BasePage {
193 width: 24,
194 color: !walletViewModel.isEnabledSellAction
195 ? Theme.of(context)
195 - .accentTextTheme
196 - .display2
197 - .backgroundColor
198 - : Theme.of(context).accentTextTheme.display3.backgroundColor),
196 + .accentTextTheme!
197 + .headline3!
198 + .backgroundColor!
199 + : Theme.of(context).accentTextTheme!.headline2!.backgroundColor!),
200 title: S.of(context).sell,
201 onClick: () async => await _onClickSellButton(context),
202 textColor: !walletViewModel.isEnabledSellAction
203 ? Theme.of(context)
203 - .accentTextTheme
204 - .display2
205 - .backgroundColor
204 + .accentTextTheme!
205 + .headline3!
206 + .backgroundColor!
207 : null),
208 ],
209 ),),
@@ -243,13 +244,13 @@ class DashboardPage extends BasePage {
244 var needToPresentYat = false;
245 var isInactive = false;
246
246 - _onInactiveSub = rootKey.currentState.isInactive.listen((inactive) {
247 + _onInactiveSub = rootKey.currentState!.isInactive.listen((inactive) {
248 isInactive = inactive;
249
250 if (needToPresentYat) {
251 Future<void>.delayed(Duration(milliseconds: 500)).then((_) {
252 showPopUp<void>(
252 - context: navigatorKey.currentContext,
253 + context: navigatorKey.currentContext!,
254 builder: (_) => YatEmojiId(walletViewModel.yatStore.emoji));
255 needToPresentYat = false;
256 });
lib/src/screens/dashboard/wallet_menu_item.dart
+3 -3
@@ -2,9 +2,9 @@ import 'package:flutter/material.dart';
2
3 class WalletMenuItem {
4 WalletMenuItem({
5 - @required this.title,
6 - @required this.image,
7 - @required this.handler});
5 + required this.title,
6 + required this.image,
7 + required this.handler});
8
9 final String title;
10 final Image image;
lib/src/screens/dashboard/widgets/action_button.dart
+7 -12
@@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
2
3 class ActionButton extends StatelessWidget {
4 ActionButton(
5 - {@required this.image,
6 - @required this.title,
5 + {required this.image,
6 + required this.title,
7 this.route,
8 this.onClick,
9 this.alignment = Alignment.center,
@@ -11,22 +11,17 @@ class ActionButton extends StatelessWidget {
11
12 final Image image;
13 final String title;
14 - final String route;
14 + final String? route;
15 final Alignment alignment;
16 - final void Function() onClick;
17 - final Color textColor;
16 + final VoidCallback? onClick;
17 + final Color? textColor;
18
19 @override
20 Widget build(BuildContext context) {
21 - var _textColor = textColor ?? Theme.of(context)
22 - .accentTextTheme
23 - .display3
24 - .backgroundColor;
25 -
21 return GestureDetector(
22 onTap: () {
23 if (route?.isNotEmpty ?? false) {
29 - Navigator.of(context, rootNavigator: true).pushNamed(route);
24 + Navigator.of(context, rootNavigator: true).pushNamed(route!);
25 } else {
26 onClick?.call();
27 }
@@ -50,7 +45,7 @@ class ActionButton extends StatelessWidget {
45 title,
46 style: TextStyle(
47 fontSize: 10,
53 - color: _textColor),
48 + color: textColor ?? Theme.of(context).accentTextTheme!.headline2!.backgroundColor!),
49 )
50 ],
51 ),
lib/src/screens/dashboard/widgets/address_page.dart
+22 -20
@@ -17,9 +17,10 @@ import 'package:keyboard_actions/keyboard_actions.dart';
17 import 'package:mobx/mobx.dart';
18
19 class AddressPage extends BasePage {
20 - AddressPage({@required this.addressListViewModel,
21 - this.walletViewModel})
22 - : _cryptoAmountFocus = FocusNode();
20 + AddressPage({
21 + required this.addressListViewModel,
22 + required this.walletViewModel})
23 + : _cryptoAmountFocus = FocusNode();
24
25 final WalletAddressListViewModel addressListViewModel;
26 final DashboardViewModel walletViewModel;
@@ -42,7 +43,7 @@ class AddressPage extends BasePage {
43 @override
44 Widget leading(BuildContext context) {
45 final _backButton = Icon(Icons.arrow_back_ios,
45 - color: Theme.of(context).accentTextTheme.display3.backgroundColor,
46 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
47 size: 16,);
48
49 return SizedBox(
@@ -50,10 +51,11 @@ class AddressPage extends BasePage {
51 width: 37,
52 child: ButtonTheme(
53 minWidth: double.minPositive,
53 - child: FlatButton(
54 - highlightColor: Colors.transparent,
55 - splashColor: Colors.transparent,
56 - padding: EdgeInsets.all(0),
54 + child: TextButton(
55 + // FIX-ME: Style
56 + //highlightColor: Colors.transparent,
57 + //splashColor: Colors.transparent,
58 + //padding: EdgeInsets.all(0),
59 onPressed: () => onClose(context),
60 child: _backButton),
61 ),
@@ -68,7 +70,7 @@ class AddressPage extends BasePage {
70 fontSize: 18.0,
71 fontWeight: FontWeight.bold,
72 fontFamily: 'Lato',
71 - color: Theme.of(context).accentTextTheme.display3.backgroundColor),
73 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!),
74 );
75 }
76
@@ -115,7 +117,7 @@ class AddressPage extends BasePage {
117 config: KeyboardActionsConfig(
118 keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
119 keyboardBarColor:
118 - Theme.of(context).accentTextTheme.body2.backgroundColor,
120 + Theme.of(context).accentTextTheme!.bodyText1!.backgroundColor!,
121 nextFocus: false,
122 actions: [
123 KeyboardActionsItem(
@@ -148,7 +150,7 @@ class AddressPage extends BasePage {
150 BorderRadius.all(Radius.circular(25)),
151 border: Border.all(
152 color:
151 - Theme.of(context).textTheme.subhead.color,
153 + Theme.of(context).textTheme!.subtitle1!.color!,
154 width: 1),
155 color: Theme.of(context).buttonColor),
156 child: Row(
@@ -166,17 +168,17 @@ class AddressPage extends BasePage {
168 fontSize: 14,
169 fontWeight: FontWeight.w500,
170 color: Theme.of(context)
169 - .accentTextTheme
170 - .display3
171 - .backgroundColor),
171 + .accentTextTheme!
172 + .headline2!
173 + .backgroundColor!),
174 )),
175 Icon(
176 Icons.arrow_forward_ios,
177 size: 14,
178 color: Theme.of(context)
177 - .accentTextTheme
178 - .display3
179 - .backgroundColor,
179 + .accentTextTheme!
180 + .headline2!
181 + .backgroundColor!,
182 )
183 ],
184 ),
@@ -188,9 +190,9 @@ class AddressPage extends BasePage {
190 style: TextStyle(
191 fontSize: 15,
192 color: Theme.of(context)
191 - .accentTextTheme
192 - .display2
193 - .backgroundColor));
193 + .accentTextTheme!
194 + .headline3!
195 + .backgroundColor!));
196 })
197 ],
198 ),
lib/src/screens/dashboard/widgets/balance_page.dart
+33 -33
@@ -12,7 +12,7 @@ import 'package:cake_wallet/generated/i18n.dart';
12
13
14 class BalancePage extends StatelessWidget{
15 - BalancePage({@required this.dashboardViewModel, @required this.settingsStore});
15 + BalancePage({required this.dashboardViewModel, required this.settingsStore});
16
17 final DashboardViewModel dashboardViewModel;
18 final SettingsStore settingsStore;
@@ -40,9 +40,9 @@ class BalancePage extends StatelessWidget{
40 fontFamily: 'Lato',
41 fontWeight: FontWeight.w600,
42 color: Theme.of(context)
43 - .accentTextTheme
44 - .display3
45 - .backgroundColor,
43 + .accentTextTheme!
44 + .headline2!
45 + .backgroundColor!,
46 height: 1),
47 maxLines: 1,
48 textAlign: TextAlign.center);
@@ -82,19 +82,19 @@ class BalancePage extends StatelessWidget{
82 }
83
84 Widget buildBalanceRow(BuildContext context,
85 - {String availableBalanceLabel,
86 - String availableBalance,
87 - String availableFiatBalance,
88 - String additionalBalanceLabel,
89 - String additionalBalance,
90 - String additionalFiatBalance,
91 - String currency}) {
85 + {required String availableBalanceLabel,
86 + required String availableBalance,
87 + required String availableFiatBalance,
88 + required String additionalBalanceLabel,
89 + required String additionalBalance,
90 + required String additionalFiatBalance,
91 + required String currency}) {
92 return Container(
93 margin: const EdgeInsets.only(left: 16, right: 16),
94 decoration: BoxDecoration(
95 borderRadius: BorderRadius.circular(30.0),
96 border: Border.all(color: settingsStore.currentTheme.type == ThemeType.bright ? Color.fromRGBO(255, 255, 255, 0.2): Colors.transparent, width: 1, ),
97 - color:Theme.of(context).textTheme.title.backgroundColor
97 + color:Theme.of(context).textTheme!.headline6!.backgroundColor!
98 ),
99 child: Container(
100 margin: const EdgeInsets.only(top: 16, left: 24, right: 24, bottom: 24),
@@ -109,9 +109,9 @@ class BalancePage extends StatelessWidget{
109 fontFamily: 'Lato',
110 fontWeight: FontWeight.w400,
111 color: Theme.of(context)
112 - .accentTextTheme
113 - .display2
114 - .backgroundColor,
112 + .accentTextTheme!
113 + .headline3!
114 + .backgroundColor!,
115 height: 1)),
116 SizedBox(height: 5),
117 Row(
@@ -124,9 +124,9 @@ class BalancePage extends StatelessWidget{
124 fontFamily: 'Lato',
125 fontWeight: FontWeight.w900,
126 color: Theme.of(context)
127 - .accentTextTheme
128 - .display3
129 - .backgroundColor,
127 + .accentTextTheme!
128 + .headline2!
129 + .backgroundColor!,
130 height: 1),
131 maxLines: 1,
132 textAlign: TextAlign.center),
@@ -136,9 +136,9 @@ class BalancePage extends StatelessWidget{
136 fontFamily: 'Lato',
137 fontWeight: FontWeight.w800,
138 color: Theme.of(context)
139 - .accentTextTheme
140 - .display3
141 - .backgroundColor,
139 + .accentTextTheme!
140 + .headline2!
141 + .backgroundColor!,
142 height: 1)),
143 ]),
144 SizedBox(height: 4,),
@@ -149,9 +149,9 @@ class BalancePage extends StatelessWidget{
149 fontFamily: 'Lato',
150 fontWeight: FontWeight.w500,
151 color: Theme.of(context)
152 - .accentTextTheme
153 - .display3
154 - .backgroundColor,
152 + .accentTextTheme!
153 + .headline2!
154 + .backgroundColor!,
155 height: 1)),
156 SizedBox(height: 26),
157 Text('${additionalBalanceLabel}',
@@ -161,9 +161,9 @@ class BalancePage extends StatelessWidget{
161 fontFamily: 'Lato',
162 fontWeight: FontWeight.w400,
163 color: Theme.of(context)
164 - .accentTextTheme
165 - .display2
166 - .backgroundColor,
164 + .accentTextTheme!
165 + .headline3!
166 + .backgroundColor!,
167 height: 1)),
168 SizedBox(height: 8),
169 AutoSizeText(
@@ -173,9 +173,9 @@ class BalancePage extends StatelessWidget{
173 fontFamily: 'Lato',
174 fontWeight: FontWeight.w400,
175 color: Theme.of(context)
176 - .accentTextTheme
177 - .display3
178 - .backgroundColor,
176 + .accentTextTheme!
177 + .headline2!
178 + .backgroundColor!,
179 height: 1),
180 maxLines: 1,
181 textAlign: TextAlign.center),
@@ -187,9 +187,9 @@ class BalancePage extends StatelessWidget{
187 fontFamily: 'Lato',
188 fontWeight: FontWeight.w400,
189 color: Theme.of(context)
190 - .accentTextTheme
191 - .display3
192 - .backgroundColor,
190 + .accentTextTheme!
191 + .headline2!
192 + .backgroundColor!,
193 height: 1),
194 )
195 ])),
lib/src/screens/dashboard/widgets/date_section_raw.dart
+2 -2
@@ -4,7 +4,7 @@ import 'package:cake_wallet/generated/i18n.dart';
4 import 'package:cake_wallet/utils/date_formatter.dart';
5
6 class DateSectionRaw extends StatelessWidget {
7 - DateSectionRaw({this.date});
7 + DateSectionRaw({required this.date});
8
9 final DateTime date;
10
@@ -36,6 +36,6 @@ class DateSectionRaw extends StatelessWidget {
36 child: Text(title,
37 style: TextStyle(
38 fontSize: 12,
39 - color: Theme.of(context).textTheme.overline.backgroundColor)));
39 + color: Theme.of(context).textTheme!.overline!.backgroundColor!)));
40 }
41 }
lib/src/screens/dashboard/widgets/filter_tile.dart
+1 -1
@@ -1,7 +1,7 @@
1 import 'package:flutter/material.dart';
2
3 class FilterTile extends StatelessWidget {
4 - FilterTile({@required this.child});
4 + FilterTile({required this.child});
5
6 final Widget child;
7
lib/src/screens/dashboard/widgets/filter_widget.dart
+23 -23
@@ -8,10 +8,10 @@ import 'package:cake_wallet/src/widgets/alert_background.dart';
8 import 'package:cake_wallet/src/widgets/alert_close_button.dart';
9 import 'package:cake_wallet/src/widgets/checkbox_widget.dart';
10 import 'package:cake_wallet/generated/i18n.dart';
11 -import 'package:date_range_picker/date_range_picker.dart' as date_rage_picker;
11 +//import 'package:date_range_picker/date_range_picker.dart' as date_rage_picker;
12
13 class FilterWidget extends StatelessWidget {
14 - FilterWidget({@required this.dashboardViewModel});
14 + FilterWidget({required this.dashboardViewModel});
15
16 final DashboardViewModel dashboardViewModel;
17 final backVector = Image.asset('assets/images/back_vector.png',
@@ -46,14 +46,14 @@ class FilterWidget extends StatelessWidget {
46 child: ClipRRect(
47 borderRadius: BorderRadius.all(Radius.circular(14)),
48 child: Container(
49 - color: Theme.of(context).textTheme.body2.decorationColor,
49 + color: Theme.of(context).textTheme!.bodyText1!.decorationColor!,
50 child: ListView.separated(
51 shrinkWrap: true,
52 physics: const NeverScrollableScrollPhysics(),
53 itemCount: dashboardViewModel.filterItems.length,
54 separatorBuilder: (context, _) => Container(
55 height: 1,
56 - color: Theme.of(context).accentTextTheme.subhead.backgroundColor,
56 + color: Theme.of(context).accentTextTheme!.subtitle1!.backgroundColor!,
57 ),
58 itemBuilder: (_, index1) {
59 final title = dashboardViewModel.filterItems.keys.elementAt(index1);
@@ -71,7 +71,7 @@ class FilterWidget extends StatelessWidget {
71 child: Text(
72 title,
73 style: TextStyle(
74 - color: Theme.of(context).accentTextTheme.subhead.color,
74 + color: Theme.of(context).accentTextTheme!.subtitle1!.color!,
75 fontSize: 16,
76 fontWeight: FontWeight.w500,
77 fontFamily: 'Lato',
@@ -86,10 +86,10 @@ class FilterWidget extends StatelessWidget {
86 separatorBuilder: (context, _) => Container(
87 height: 1,
88 padding: EdgeInsets.only(left: 24),
89 - color: Theme.of(context).textTheme.body2.decorationColor,
89 + color: Theme.of(context).textTheme!.bodyText1!.decorationColor!,
90 child: Container(
91 height: 1,
92 - color: Theme.of(context).accentTextTheme.subhead.backgroundColor,
92 + color: Theme.of(context).accentTextTheme!.subtitle1!.backgroundColor!,
93 ),
94 ),
95 itemBuilder: (_, index2) {
@@ -103,29 +103,29 @@ class FilterWidget extends StatelessWidget {
103 )
104 : GestureDetector(
105 onTap: () async {
106 - final List<DateTime> picked =
107 - await date_rage_picker.showDatePicker(
108 - context: context,
109 - initialFirstDate: DateTime.now()
110 - .subtract(Duration(days: 1)),
111 - initialLastDate: (DateTime.now()),
112 - firstDate: DateTime(2015),
113 - lastDate: DateTime.now()
114 - .add(Duration(days: 1)));
106 + //final List<DateTime> picked =
107 + //await date_rage_picker.showDatePicker(
108 + // context: context,
109 + // initialFirstDate: DateTime.now()
110 + // .subtract(Duration(days: 1)),
111 + // initialLastDate: (DateTime.now()),
112 + // firstDate: DateTime(2015),
113 + // lastDate: DateTime.now()
114 + // .add(Duration(days: 1)));
115
116 - if (picked != null && picked.length == 2) {
117 - dashboardViewModel.transactionFilterStore
118 - .changeStartDate(picked.first);
119 - dashboardViewModel.transactionFilterStore
120 - .changeEndDate(picked.last);
121 - }
116 + //if (picked != null && picked.length == 2) {
117 + // dashboardViewModel.transactionFilterStore
118 + // .changeStartDate(picked.first);
119 + // dashboardViewModel.transactionFilterStore
120 + // .changeEndDate(picked.last);
121 + //}
122 },
123 child: Padding(
124 padding: EdgeInsets.only(left: 32),
125 child: Text(
126 item.caption,
127 style: TextStyle(
128 - color: Theme.of(context).primaryTextTheme.title.color,
128 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
129 fontSize: 18,
130 fontFamily: 'Lato',
131 fontWeight: FontWeight.w500,
lib/src/screens/dashboard/widgets/header_row.dart
+4 -4
@@ -5,14 +5,14 @@ import 'package:cake_wallet/generated/i18n.dart';
5 import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
6
7 class HeaderRow extends StatelessWidget {
8 - HeaderRow({this.dashboardViewModel});
8 + HeaderRow({required this.dashboardViewModel});
9
10 final DashboardViewModel dashboardViewModel;
11
12 @override
13 Widget build(BuildContext context) {
14 final filterIcon = Image.asset('assets/images/filter_icon.png',
15 - color: Theme.of(context).textTheme.caption.decorationColor);
15 + color: Theme.of(context).textTheme!.caption!.decorationColor!);
16
17 return Container(
18 height: 52,
@@ -27,7 +27,7 @@ class HeaderRow extends StatelessWidget {
27 style: TextStyle(
28 fontSize: 20,
29 fontWeight: FontWeight.w500,
30 - color: Theme.of(context).accentTextTheme.display3.backgroundColor
30 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!
31 ),
32 ),
33 GestureDetector(
@@ -43,7 +43,7 @@ class HeaderRow extends StatelessWidget {
43 width: 36,
44 decoration: BoxDecoration(
45 shape: BoxShape.circle,
46 - color: Theme.of(context).textTheme.overline.color
46 + color: Theme.of(context).textTheme!.overline!.color!
47 ),
48 child: filterIcon,
49 ),
lib/src/screens/dashboard/widgets/market_place_page.dart
+2 -2
@@ -9,7 +9,7 @@ import 'package:cake_wallet/generated/i18n.dart';
9
10 class MarketPlacePage extends StatelessWidget {
11
12 - MarketPlacePage({@required this.dashboardViewModel});
12 + MarketPlacePage({required this.dashboardViewModel});
13
14 final DashboardViewModel dashboardViewModel;
15 final _scrollController = ScrollController();
@@ -35,7 +35,7 @@ class MarketPlacePage extends StatelessWidget {
35 style: TextStyle(
36 fontSize: 24,
37 fontWeight: FontWeight.w500,
38 - color: Theme.of(context).accentTextTheme.display3.backgroundColor,
38 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
39 ),
40 ),
41 Expanded(
lib/src/screens/dashboard/widgets/menu_widget.dart
+41 -27
@@ -19,10 +19,19 @@ class MenuWidget extends StatefulWidget {
19 }
20
21 class MenuWidgetState extends State<MenuWidget> {
22 - Image moneroIcon;
23 - Image bitcoinIcon;
24 - Image litecoinIcon;
25 - Image havenIcon;
22 + MenuWidgetState()
23 + : this.menuWidth = 0,
24 + this.screenWidth = 0,
25 + this.screenHeight = 0,
26 + this.headerHeight = 120,
27 + this.tileHeight = 60,
28 + this.fromTopEdge = 50,
29 + this.fromBottomEdge = 25,
30 + this.moneroIcon = Image.asset('assets/images/monero_menu.png'),
31 + this.bitcoinIcon = Image.asset('assets/images/bitcoin_menu.png'),
32 + this.litecoinIcon = Image.asset('assets/images/litecoin_menu.png'),
33 + this.havenIcon = Image.asset('assets/images/haven_menu.png');
34 +
35 final largeScreen = 731;
36
37 double menuWidth;
@@ -34,6 +43,11 @@ class MenuWidgetState extends State<MenuWidget> {
43 double fromTopEdge;
44 double fromBottomEdge;
45
46 + Image moneroIcon;
47 + Image bitcoinIcon;
48 + Image litecoinIcon;
49 + Image havenIcon;
50 +
51 @override
52 void initState() {
53 menuWidth = 0;
@@ -75,9 +89,9 @@ class MenuWidgetState extends State<MenuWidget> {
89 final itemCount = walletMenu.items.length;
90
91 moneroIcon = Image.asset('assets/images/monero_menu.png',
78 - color: Theme.of(context).accentTextTheme.overline.decorationColor);
92 + color: Theme.of(context).accentTextTheme!.overline!.decorationColor!);
93 bitcoinIcon = Image.asset('assets/images/bitcoin_menu.png',
80 - color: Theme.of(context).accentTextTheme.overline.decorationColor);
94 + color: Theme.of(context).accentTextTheme!.overline!.decorationColor!);
95 litecoinIcon = Image.asset('assets/images/litecoin_menu.png');
96 havenIcon = Image.asset('assets/images/haven_menu.png');
97
@@ -101,7 +115,7 @@ class MenuWidgetState extends State<MenuWidget> {
115 topLeft: Radius.circular(24),
116 bottomLeft: Radius.circular(24)),
117 child: Container(
104 - color: Theme.of(context).textTheme.body2.decorationColor,
118 + color: Theme.of(context).textTheme!.bodyText1!.decorationColor!,
119 child: ListView.separated(
120 padding: EdgeInsets.only(top: 0),
121 itemBuilder: (_, index) {
@@ -112,13 +126,13 @@ class MenuWidgetState extends State<MenuWidget> {
126 gradient: LinearGradient(
127 colors: [
128 Theme.of(context)
115 - .accentTextTheme
116 - .display1
117 - .color,
129 + .accentTextTheme!
130 + .headline4!
131 + .color!,
132 Theme.of(context)
119 - .accentTextTheme
120 - .display1
121 - .decorationColor,
133 + .accentTextTheme!
134 + .headline4!
135 + .decorationColor!,
136 ],
137 begin: Alignment.topLeft,
138 end: Alignment.bottomRight),
@@ -159,9 +173,9 @@ class MenuWidgetState extends State<MenuWidget> {
173 .subname,
174 style: TextStyle(
175 color: Theme.of(context)
162 - .accentTextTheme
163 - .overline
164 - .decorationColor,
176 + .accentTextTheme!
177 + .overline!
178 + .decorationColor!,
179 fontWeight:
180 FontWeight.w500,
181 fontSize: 12),
@@ -188,9 +202,9 @@ class MenuWidgetState extends State<MenuWidget> {
202 },
203 child: Container(
204 color: Theme.of(context)
191 - .textTheme
192 - .body2
193 - .decorationColor,
205 + .textTheme!
206 + .bodyText1!
207 + .decorationColor!,
208 height: isLastTile ? headerHeight : tileHeight,
209 padding: isLastTile
210 ? EdgeInsets.only(
@@ -212,9 +226,9 @@ class MenuWidgetState extends State<MenuWidget> {
226 title,
227 style: TextStyle(
228 color: Theme.of(context)
215 - .textTheme
216 - .display2
217 - .color,
229 + .textTheme!
230 + .headline3!
231 + .color!,
232 fontSize: 16,
233 fontWeight: FontWeight.bold),
234 ))
@@ -225,9 +239,9 @@ class MenuWidgetState extends State<MenuWidget> {
239 separatorBuilder: (_, index) => Container(
240 height: 1,
241 color: Theme.of(context)
228 - .primaryTextTheme
229 - .caption
230 - .decorationColor,
242 + .primaryTextTheme!
243 + .caption!
244 + .decorationColor!,
245 ),
246 itemCount: itemCount + 1),
247 )))
@@ -235,7 +249,7 @@ class MenuWidgetState extends State<MenuWidget> {
249 );
250 }
251
238 - Image _iconFor({@required WalletType type}) {
252 + Image _iconFor({required WalletType type}) {
253 switch (type) {
254 case WalletType.monero:
255 return moneroIcon;
@@ -246,7 +260,7 @@ class MenuWidgetState extends State<MenuWidget> {
260 case WalletType.haven:
261 return havenIcon;
262 default:
249 - return null;
263 + throw Exception('No icon for ${type.toString()}');
264 }
265 }
266 }
lib/src/screens/dashboard/widgets/order_row.dart
+13 -15
@@ -4,23 +4,23 @@ import 'package:flutter/material.dart';
4
5 class OrderRow extends StatelessWidget {
6 OrderRow({
7 - @required this.onTap,
8 - @required this.provider,
9 - this.from,
10 - this.to,
11 - this.createdAtFormattedDate,
7 + required this.provider,
8 + required this.from,
9 + required this.to,
10 + required this.createdAtFormattedDate,
11 + this.onTap,
12 this.formattedAmount});
13 - final VoidCallback onTap;
13 + final VoidCallback? onTap;
14 final BuyProviderDescription provider;
15 final String from;
16 final String to;
17 final String createdAtFormattedDate;
18 - final String formattedAmount;
18 + final String? formattedAmount;
19
20 @override
21 Widget build(BuildContext context) {
22 final iconColor =
23 - Theme.of(context).primaryTextTheme.display4.backgroundColor;
23 + Theme.of(context).primaryTextTheme!.headline1!.backgroundColor!;
24
25 final providerIcon = getBuyProviderIcon(provider, iconColor: iconColor);
26
@@ -48,16 +48,14 @@ class OrderRow extends StatelessWidget {
48 style: TextStyle(
49 fontSize: 16,
50 fontWeight: FontWeight.w500,
51 - color: Theme.of(context).accentTextTheme.
52 - display3.backgroundColor
51 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!
52 )),
53 formattedAmount != null
55 - ? Text(formattedAmount + ' ' + to,
54 + ? Text(formattedAmount! + ' ' + to,
55 style: TextStyle(
56 fontSize: 16,
57 fontWeight: FontWeight.w500,
59 - color: Theme.of(context).accentTextTheme.
60 - display3.backgroundColor
58 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!
59 ))
60 : Container()
61 ]),
@@ -68,8 +66,8 @@ class OrderRow extends StatelessWidget {
66 Text(createdAtFormattedDate,
67 style: TextStyle(
68 fontSize: 14,
71 - color: Theme.of(context).textTheme
72 - .overline.backgroundColor))
69 + color: Theme.of(context).textTheme!
70 + .overline!.backgroundColor!))
71 ])
72 ],
73 )
lib/src/screens/dashboard/widgets/sync_indicator.dart
+4 -4
@@ -6,7 +6,7 @@ import 'package:cw_core/sync_status.dart';
6 import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator_icon.dart';
7
8 class SyncIndicator extends StatelessWidget {
9 - SyncIndicator({@required this.dashboardViewModel,this.onTap});
9 + SyncIndicator({required this.dashboardViewModel, required this.onTap});
10
11 final DashboardViewModel dashboardViewModel;
12 final Function() onTap;
@@ -32,7 +32,7 @@ class SyncIndicator extends StatelessWidget {
32 child: Container(
33 height: 30,
34 width: syncIndicatorWidth,
35 - color: Theme.of(context).textTheme.title.decorationColor,
35 + color: Theme.of(context).textTheme!.headline6!.decorationColor!,
36 child: Stack(
37 alignment: Alignment.center,
38 children: <Widget>[
@@ -44,7 +44,7 @@ class SyncIndicator extends StatelessWidget {
44 child: Container(
45 width: indicatorWidth,
46 height: 30,
47 - color: Theme.of(context).textTheme.title.backgroundColor,
47 + color: Theme.of(context).textTheme!.headline6!.backgroundColor!,
48 )
49 )
50 : Offstage(),
@@ -66,7 +66,7 @@ class SyncIndicator extends StatelessWidget {
66 style: TextStyle(
67 fontSize: 12,
68 fontWeight: FontWeight.w500,
69 - color: Theme.of(context).textTheme.title.color
69 + color: Theme.of(context).textTheme!.headline6!.color!
70 ),
71 ),
72 )
lib/src/screens/dashboard/widgets/sync_indicator_icon.dart
+2 -2
@@ -26,14 +26,14 @@ class SyncIndicatorIcon extends StatelessWidget {
26 if (boolMode) {
27 indicatorColor = isSynced
28 ? PaletteDark.brightGreen
29 - : Theme.of(context).textTheme.caption.color;
29 + : Theme.of(context).textTheme!.caption!.color!;
30 } else {
31 switch (value.toLowerCase()) {
32 case waiting:
33 indicatorColor = Colors.red;
34 break;
35 case actionRequired:
36 - indicatorColor = Theme.of(context).textTheme.display3.decorationColor;
36 + indicatorColor = Theme.of(context).textTheme!.headline2!.decorationColor!;
37 break;
38 case created:
39 indicatorColor = PaletteDark.brightGreen;
lib/src/screens/dashboard/widgets/trade_row.dart
+23 -22
@@ -4,19 +4,19 @@ import 'package:cake_wallet/exchange/exchange_provider_description.dart';
4
5 class TradeRow extends StatelessWidget {
6 TradeRow({
7 - this.provider,
8 - this.from,
9 - this.to,
10 - this.createdAtFormattedDate,
11 - this.formattedAmount,
12 - @required this.onTap});
7 + required this.provider,
8 + required this.from,
9 + required this.to,
10 + required this.createdAtFormattedDate,
11 + this.onTap,
12 + this.formattedAmount,});
13
14 - final VoidCallback onTap;
14 + final VoidCallback? onTap;
15 final ExchangeProviderDescription provider;
16 final CryptoCurrency from;
17 final CryptoCurrency to;
18 - final String createdAtFormattedDate;
19 - final String formattedAmount;
18 + final String? createdAtFormattedDate;
19 + final String? formattedAmount;
20
21 @override
22 Widget build(BuildContext context) {
@@ -31,7 +31,7 @@ class TradeRow extends StatelessWidget {
31 mainAxisSize: MainAxisSize.max,
32 crossAxisAlignment: CrossAxisAlignment.center,
33 children: [
34 - _getPoweredImage(provider),
34 + _getPoweredImage(provider)!,
35 SizedBox(width: 12),
36 Expanded(
37 child: Column(
@@ -44,16 +44,14 @@ class TradeRow extends StatelessWidget {
44 style: TextStyle(
45 fontSize: 16,
46 fontWeight: FontWeight.w500,
47 - color: Theme.of(context).accentTextTheme.
48 - display3.backgroundColor
47 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!
48 )),
49 formattedAmount != null
51 - ? Text(formattedAmount + ' ' + amountCrypto,
50 + ? Text(formattedAmount! + ' ' + amountCrypto,
51 style: TextStyle(
52 fontSize: 16,
53 fontWeight: FontWeight.w500,
55 - color: Theme.of(context).accentTextTheme.
56 - display3.backgroundColor
54 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!
55 ))
56 : Container()
57 ]),
@@ -61,11 +59,12 @@ class TradeRow extends StatelessWidget {
59 Row(
60 mainAxisAlignment: MainAxisAlignment.spaceBetween,
61 children: <Widget>[
64 - Text(createdAtFormattedDate,
65 - style: TextStyle(
66 - fontSize: 14,
67 - color: Theme.of(context).textTheme
68 - .overline.backgroundColor))
62 + if (createdAtFormattedDate != null)
63 + Text(createdAtFormattedDate!,
64 + style: TextStyle(
65 + fontSize: 14,
66 + color: Theme.of(context).textTheme!
67 + .overline!.backgroundColor!))
68 ])
69 ],
70 )
@@ -75,8 +74,9 @@ class TradeRow extends StatelessWidget {
74 ));
75 }
76
78 - Image _getPoweredImage(ExchangeProviderDescription provider) {
79 - Image image;
77 + Image? _getPoweredImage(ExchangeProviderDescription provider) {
78 + Image? image;
79 +
80 switch (provider) {
81 case ExchangeProviderDescription.xmrto:
82 image = Image.asset('assets/images/xmrto.png', height: 36, width: 36);
@@ -96,6 +96,7 @@ class TradeRow extends StatelessWidget {
96 default:
97 image = null;
98 }
99 +
100 return image;
101 }
102 }
\ No newline at end of file
lib/src/screens/dashboard/widgets/transaction_raw.dart
+17 -17
@@ -4,12 +4,12 @@ import 'package:cake_wallet/generated/i18n.dart';
4
5 class TransactionRow extends StatelessWidget {
6 TransactionRow(
7 - {this.direction,
8 - this.formattedDate,
9 - this.formattedAmount,
10 - this.formattedFiatAmount,
11 - this.isPending,
12 - @required this.onTap});
7 + {required this.direction,
8 + required this.formattedDate,
9 + required this.formattedAmount,
10 + required this.formattedFiatAmount,
11 + required this.isPending,
12 + required this.onTap});
13
14 final VoidCallback onTap;
15 final TransactionDirection direction;
@@ -34,7 +34,7 @@ class TransactionRow extends StatelessWidget {
34 width: 36,
35 decoration: BoxDecoration(
36 shape: BoxShape.circle,
37 - color: Theme.of(context).textTheme.overline.decorationColor
37 + color: Theme.of(context).textTheme!.overline!.decorationColor!
38 ),
39 child: Image.asset(
40 direction == TransactionDirection.incoming
@@ -57,14 +57,14 @@ class TransactionRow extends StatelessWidget {
57 style: TextStyle(
58 fontSize: 16,
59 fontWeight: FontWeight.w500,
60 - color: Theme.of(context).accentTextTheme.
61 - display3.backgroundColor)),
60 + color: Theme.of(context).accentTextTheme!
61 + .headline2!.backgroundColor!)),
62 Text(formattedAmount,
63 style: TextStyle(
64 fontSize: 16,
65 fontWeight: FontWeight.w500,
66 - color: Theme.of(context).accentTextTheme.
67 - display3.backgroundColor))
66 + color: Theme.of(context).accentTextTheme!
67 + .headline2!.backgroundColor!))
68 ]),
69 SizedBox(height: 5),
70 Row(
@@ -74,16 +74,16 @@ class TransactionRow extends StatelessWidget {
74 style: TextStyle(
75 fontSize: 14,
76 color: Theme.of(context)
77 - .textTheme
78 - .overline
79 - .backgroundColor)),
77 + .textTheme!
78 + .overline!
79 + .backgroundColor!)),
80 Text(formattedFiatAmount,
81 style: TextStyle(
82 fontSize: 14,
83 color: Theme.of(context)
84 - .textTheme
85 - .overline
86 - .backgroundColor))
84 + .textTheme!
85 + .overline!
86 + .backgroundColor!))
87 ])
88 ],
89 )
lib/src/screens/dashboard/widgets/transactions_page.dart
+8 -6
@@ -15,7 +15,7 @@ import 'package:cake_wallet/routes.dart';
15 import 'package:cake_wallet/generated/i18n.dart';
16
17 class TransactionsPage extends StatelessWidget {
18 - TransactionsPage({@required this.dashboardViewModel});
18 + TransactionsPage({required this.dashboardViewModel});
19
20 final DashboardViewModel dashboardViewModel;
21
@@ -72,7 +72,9 @@ class TransactionsPage extends StatelessWidget {
72 from: trade.from,
73 to: trade.to,
74 createdAtFormattedDate:
75 - DateFormat('HH:mm').format(trade.createdAt),
75 + trade.createdAt != null
76 + ? DateFormat('HH:mm').format(trade.createdAt!)
77 + : null,
78 formattedAmount: item.tradeFormattedAmount
79 ));
80 }
@@ -85,8 +87,8 @@ class TransactionsPage extends StatelessWidget {
87 Routes.orderDetails,
88 arguments: order),
89 provider: order.provider,
88 - from: order.from,
89 - to: order.to,
90 + from: order.from!,
91 + to: order.to!,
92 createdAtFormattedDate:
93 DateFormat('HH:mm').format(order.createdAt),
94 formattedAmount: item.orderFormattedAmount,
@@ -103,8 +105,8 @@ class TransactionsPage extends StatelessWidget {
105 S.of(context).placeholder_transactions,
106 style: TextStyle(
107 fontSize: 14,
106 - color: Theme.of(context).primaryTextTheme
107 - .overline.decorationColor
108 + color: Theme.of(context).primaryTextTheme!
109 + .overline!.decorationColor!
110 ),
111 ),
112 );
lib/src/screens/disclaimer/disclaimer_page.dart
+26 -26
@@ -21,7 +21,7 @@ class DisclaimerPage extends BasePage {
21 String get title => 'Terms of Use';
22
23 @override
24 - Widget leading(BuildContext context) =>
24 + Widget? leading(BuildContext context) =>
25 isReadOnly ? super.leading(context) : null;
26
27 @override
@@ -30,7 +30,7 @@ class DisclaimerPage extends BasePage {
30 }
31
32 class DisclaimerPageBody extends StatefulWidget {
33 - DisclaimerPageBody({this.isReadOnly});
33 + DisclaimerPageBody({required this.isReadOnly});
34
35 final bool isReadOnly;
36
@@ -88,9 +88,9 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
88 fontSize: 20.0,
89 fontWeight: FontWeight.bold,
90 color: Theme.of(context)
91 - .primaryTextTheme
92 - .title
93 - .color),
91 + .primaryTextTheme!
92 + .headline6!
93 + .color!),
94 ),
95 )
96 ],
@@ -108,9 +108,9 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
108 fontSize: 12.0,
109 fontWeight: FontWeight.bold,
110 color: Theme.of(context)
111 - .primaryTextTheme
112 - .title
113 - .color),
111 + .primaryTextTheme!
112 + .headline6!
113 + .color!),
114 ),
115 )
116 ],
@@ -127,9 +127,9 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
127 fontSize: 12.0,
128 fontWeight: FontWeight.normal,
129 color: Theme.of(context)
130 - .primaryTextTheme
131 - .title
132 - .color),
130 + .primaryTextTheme!
131 + .headline6!
132 + .color!),
133 ))
134 ],
135 ),
@@ -147,9 +147,9 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
147 fontSize: 14.0,
148 fontWeight: FontWeight.bold,
149 color: Theme.of(context)
150 - .primaryTextTheme
151 - .title
152 - .color),
150 + .primaryTextTheme!
151 + .headline6!
152 + .color!),
153 ),
154 )
155 ],
@@ -233,9 +233,9 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
233 decoration: BoxDecoration(
234 border: Border.all(
235 color: Theme.of(context)
236 - .primaryTextTheme
237 - .caption
238 - .color,
236 + .primaryTextTheme!
237 + .caption!
238 + .color!,
239 width: 1.0),
240 borderRadius: BorderRadius.all(
241 Radius.circular(8.0)),
@@ -254,9 +254,9 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
254 fontWeight: FontWeight.bold,
255 fontSize: 14.0,
256 color: Theme.of(context)
257 - .primaryTextTheme
258 - .title
259 - .color),
257 + .primaryTextTheme!
258 + .headline6!
259 + .color!),
260 )
261 ],
262 ),
@@ -274,13 +274,13 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
274 : null,
275 text: 'Accept',
276 color: Theme.of(context)
277 - .accentTextTheme
278 - .subtitle
279 - .decorationColor,
277 + .accentTextTheme!
278 + .subtitle2!
279 + .decorationColor!,
280 textColor: Theme.of(context)
281 - .accentTextTheme
282 - .headline
283 - .decorationColor),
281 + .accentTextTheme!
282 + .headline5!
283 + .decorationColor!),
284 ),
285 ],
286 ],
lib/src/screens/exchange/exchange_page.dart
+72 -73
@@ -82,7 +82,7 @@ class ExchangePage extends BasePage {
82 Widget trailing(BuildContext context) => TrailButton(
83 caption: S.of(context).reset,
84 onPressed: () {
85 - _formKey.currentState.reset();
85 + _formKey.currentState?.reset();
86 exchangeViewModel.reset();
87 });
88
@@ -116,7 +116,7 @@ class ExchangePage extends BasePage {
116 config: KeyboardActionsConfig(
117 keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
118 keyboardBarColor:
119 - Theme.of(context).accentTextTheme.body2.backgroundColor,
119 + Theme.of(context).accentTextTheme!.bodyText1!.backgroundColor!,
120 nextFocus: false,
121 actions: [
122 KeyboardActionsItem(
@@ -142,11 +142,11 @@ class ExchangePage extends BasePage {
142 bottomRight: Radius.circular(24)),
143 gradient: LinearGradient(
144 colors: [
145 - Theme.of(context).primaryTextTheme.body1.color,
145 + Theme.of(context).primaryTextTheme!.bodyText2!.color!,
146 Theme.of(context)
147 - .primaryTextTheme
148 - .body1
149 - .decorationColor,
147 + .primaryTextTheme!
148 + .bodyText2!
149 + .decorationColor!,
150 ],
151 stops: [
152 0.35,
@@ -165,13 +165,13 @@ class ExchangePage extends BasePage {
165 gradient: LinearGradient(
166 colors: [
167 Theme.of(context)
168 - .primaryTextTheme
169 - .subtitle
170 - .color,
168 + .primaryTextTheme!
169 + .subtitle2!
170 + .color!,
171 Theme.of(context)
172 - .primaryTextTheme
173 - .subtitle
174 - .decorationColor,
172 + .primaryTextTheme!
173 + .subtitle2!
174 + .decorationColor!,
175 ],
176 begin: Alignment.topLeft,
177 end: Alignment.bottomRight),
@@ -190,7 +190,7 @@ class ExchangePage extends BasePage {
190 title: S.of(context).you_will_send,
191 initialCurrency:
192 exchangeViewModel.depositCurrency,
193 - initialWalletName: depositWalletName,
193 + initialWalletName: depositWalletName ?? '',
194 initialAddress:
195 exchangeViewModel.depositCurrency ==
196 exchangeViewModel.wallet.currency
@@ -230,11 +230,11 @@ class ExchangePage extends BasePage {
230 imageArrow: arrowBottomPurple,
231 currencyButtonColor: Colors.transparent,
232 addressButtonsColor:
233 - Theme.of(context).focusColor,
233 + Theme.of(context).focusColor!,
234 borderColor: Theme.of(context)
235 - .primaryTextTheme
236 - .body2
237 - .color,
235 + .primaryTextTheme!
236 + .bodyText1!
237 + .color!,
238 currencyValueValidator: AmountValidator(
239 type: exchangeViewModel.wallet.type),
240 addressTextFieldValidator: AddressValidator(
@@ -271,7 +271,7 @@ class ExchangePage extends BasePage {
271 title: S.of(context).you_will_get,
272 initialCurrency:
273 exchangeViewModel.receiveCurrency,
274 - initialWalletName: receiveWalletName,
274 + initialWalletName: receiveWalletName ?? '',
275 initialAddress: exchangeViewModel
276 .receiveCurrency ==
277 exchangeViewModel.wallet.currency
@@ -293,11 +293,11 @@ class ExchangePage extends BasePage {
293 imageArrow: arrowBottomCakeGreen,
294 currencyButtonColor: Colors.transparent,
295 addressButtonsColor:
296 - Theme.of(context).focusColor,
296 + Theme.of(context).focusColor!,
297 borderColor: Theme.of(context)
298 - .primaryTextTheme
299 - .body2
300 - .decorationColor,
298 + .primaryTextTheme!
299 + .bodyText1!
300 + .decorationColor!,
301 currencyValueValidator: AmountValidator(
302 type: exchangeViewModel.wallet.type),
303 addressTextFieldValidator:
@@ -366,9 +366,9 @@ class ExchangePage extends BasePage {
366 textAlign: TextAlign.center,
367 style: TextStyle(
368 color: Theme.of(context)
369 - .primaryTextTheme
370 - .display4
371 - .decorationColor,
369 + .primaryTextTheme!
370 + .headline1!
371 + .decorationColor!,
372 fontWeight: FontWeight.w500,
373 fontSize: 12),
374 ),
@@ -379,7 +379,7 @@ class ExchangePage extends BasePage {
379 builder: (_) => LoadingPrimaryButton(
380 text: S.of(context).exchange,
381 onPressed: () {
382 - if (_formKey.currentState.validate()) {
382 + if (_formKey.currentState != null && _formKey.currentState!.validate()) {
383 if ((exchangeViewModel.depositCurrency ==
384 CryptoCurrency.xmr) &&
385 (!(exchangeViewModel.status
@@ -401,7 +401,7 @@ class ExchangePage extends BasePage {
401 }
402 }
403 },
404 - color: Theme.of(context).accentTextTheme.body2.color,
404 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
405 textColor: Colors.white,
406 isDisabled: exchangeViewModel.selectedProviders.isEmpty,
407 isLoading: exchangeViewModel.tradeState is TradeIsCreating)),
@@ -432,9 +432,9 @@ class ExchangePage extends BasePage {
432 borderType: BorderType.RRect,
433 dashPattern: [6, 4],
434 color: Theme.of(context)
435 - .primaryTextTheme
436 - .display2
437 - .decorationColor,
435 + .primaryTextTheme!
436 + .headline3!
437 + .decorationColor!,
438 strokeWidth: 2,
439 radius: Radius.circular(20),
440 child: Container(
@@ -449,9 +449,9 @@ class ExchangePage extends BasePage {
449 ? Icon(
450 Icons.add,
451 color: Theme.of(context)
452 - .primaryTextTheme
453 - .display3
454 - .color,
452 + .primaryTextTheme!
453 + .headline2!
454 + .color!,
455 )
456 : Text(
457 S.of(context).new_template,
@@ -459,9 +459,9 @@ class ExchangePage extends BasePage {
459 fontSize: 14,
460 fontWeight: FontWeight.w600,
461 color: Theme.of(context)
462 - .primaryTextTheme
463 - .display3
464 - .color,
462 + .primaryTextTheme!
463 + .headline2!
464 + .color!,
465 ),
466 ),
467 ),
@@ -545,10 +545,10 @@ class ExchangePage extends BasePage {
545 return;
546 }
547
548 - final depositAddressController = depositKey.currentState.addressController;
549 - final depositAmountController = depositKey.currentState.amountController;
550 - final receiveAddressController = receiveKey.currentState.addressController;
551 - final receiveAmountController = receiveKey.currentState.amountController;
548 + final depositAddressController = depositKey.currentState!.addressController;
549 + final depositAmountController = depositKey.currentState!.amountController;
550 + final receiveAddressController = receiveKey.currentState!.addressController;
551 + final receiveAmountController = receiveKey.currentState!.amountController;
552 final limitsState = exchangeViewModel.limitsState;
553
554 if (limitsState is LimitsLoadedSuccessfully) {
@@ -561,7 +561,7 @@ class ExchangePage extends BasePage {
561 final key = exchangeViewModel.isFixedRateMode
562 ? receiveKey
563 : depositKey;
564 - key.currentState.changeLimits(min: min, max: max);
564 + key.currentState!.changeLimits(min: min, max: max);
565 }
566
567 _onCurrencyChange(
@@ -590,43 +590,42 @@ class ExchangePage extends BasePage {
590 _onCurrencyChange(currency, exchangeViewModel, depositKey));
591
592 reaction((_) => exchangeViewModel.depositAmount, (String amount) {
593 - if (depositKey.currentState.amountController.text != amount) {
594 - depositKey.currentState.amountController.text = amount;
593 + if (depositKey.currentState!.amountController.text != amount) {
594 + depositKey.currentState!.amountController.text = amount;
595 }
596 });
597
598 reaction((_) => exchangeViewModel.depositAddress, (String address) {
599 - if (depositKey.currentState.addressController.text != address) {
600 - depositKey.currentState.addressController.text = address;
599 + if (depositKey.currentState!.addressController.text != address) {
600 + depositKey.currentState!.addressController.text = address;
601 }
602 });
603
604 reaction((_) => exchangeViewModel.isDepositAddressEnabled,
605 (bool isEnabled) {
606 - depositKey.currentState.isAddressEditable(isEditable: isEnabled);
606 + depositKey.currentState!.isAddressEditable(isEditable: isEnabled);
607 });
608
609 reaction((_) => exchangeViewModel.receiveAmount, (String amount) {
610 - if (receiveKey.currentState.amountController.text != amount) {
611 - receiveKey.currentState.amountController.text = amount;
610 + if (receiveKey.currentState!.amountController.text != amount) {
611 + receiveKey.currentState!.amountController.text = amount;
612 }
613 });
614
615 reaction((_) => exchangeViewModel.receiveAddress, (String address) {
616 - if (receiveKey.currentState.addressController.text != address) {
617 - receiveKey.currentState.addressController.text = address;
616 + if (receiveKey.currentState!.addressController.text != address) {
617 + receiveKey.currentState!.addressController.text = address;
618 }
619 });
620
621 reaction((_) => exchangeViewModel.isReceiveAddressEnabled,
622 (bool isEnabled) {
623 - receiveKey.currentState.isAddressEditable(isEditable: isEnabled);
623 + receiveKey.currentState!.isAddressEditable(isEditable: isEnabled);
624 });
625
626 reaction((_) => exchangeViewModel.isReceiveAmountEditable,
627 (bool isReceiveAmountEditable) {
628 - receiveKey.currentState
629 - .isAmountEditable(isEditable: isReceiveAmountEditable);
628 + receiveKey.currentState!.isAmountEditable(isEditable: isReceiveAmountEditable);
629 });
630
631 reaction((_) => exchangeViewModel.tradeState, (ExchangeTradeState state) {
@@ -650,8 +649,8 @@ class ExchangePage extends BasePage {
649 });
650
651 reaction((_) => exchangeViewModel.limitsState, (LimitsState state) {
653 - String min;
654 - String max;
652 + String? min;
653 + String? max;
654
655 if (state is LimitsLoadedSuccessfully) {
656 min = state.limits.min != null ? state.limits.min.toString() : null;
@@ -669,17 +668,17 @@ class ExchangePage extends BasePage {
668 }
669
670 if (exchangeViewModel.isFixedRateMode) {
672 - depositKey.currentState.changeLimits(min: null, max: null);
673 - receiveKey.currentState.changeLimits(min: min, max: max);
671 + depositKey.currentState!.changeLimits(min: null, max: null);
672 + receiveKey.currentState!.changeLimits(min: min, max: max);
673 } else {
675 - depositKey.currentState.changeLimits(min: min, max: max);
676 - receiveKey.currentState.changeLimits(min: null, max: null);
674 + depositKey.currentState!.changeLimits(min: min, max: max);
675 + receiveKey.currentState!.changeLimits(min: null, max: null);
676 }
677 });
678
679 reaction((_) => exchangeViewModel.isFixedRateMode, (bool value) {
681 - if (checkBoxKey.currentState.value != exchangeViewModel.isFixedRateMode) {
682 - checkBoxKey.currentState.value = exchangeViewModel.isFixedRateMode;
680 + if (checkBoxKey.currentState!.value != exchangeViewModel.isFixedRateMode) {
681 + checkBoxKey.currentState!.value = exchangeViewModel.isFixedRateMode;
682 }
683 });
684
@@ -712,11 +711,11 @@ class ExchangePage extends BasePage {
711 reaction((_) => exchangeViewModel.wallet.walletAddresses.address,
712 (String address) {
713 if (exchangeViewModel.depositCurrency == CryptoCurrency.xmr) {
715 - depositKey.currentState.changeAddress(address: address);
714 + depositKey.currentState!.changeAddress(address: address);
715 }
716
717 if (exchangeViewModel.receiveCurrency == CryptoCurrency.xmr) {
719 - receiveKey.currentState.changeAddress(address: address);
718 + receiveKey.currentState!.changeAddress(address: address);
719 }
720 });
721
@@ -760,15 +759,15 @@ class ExchangePage extends BasePage {
759 ExchangeViewModel exchangeViewModel, GlobalKey<ExchangeCardState> key) {
760 final isCurrentTypeWallet = currency == exchangeViewModel.wallet.currency;
761
763 - key.currentState.changeSelectedCurrency(currency);
764 - key.currentState.changeWalletName(
765 - isCurrentTypeWallet ? exchangeViewModel.wallet.name : null);
762 + key.currentState!.changeSelectedCurrency(currency);
763 + key.currentState!.changeWalletName(
764 + isCurrentTypeWallet ? exchangeViewModel.wallet.name : '');
765
767 - key.currentState.changeAddress(
766 + key.currentState!.changeAddress(
767 address: isCurrentTypeWallet
768 ? exchangeViewModel.wallet.walletAddresses.address : '');
769
771 - key.currentState.changeAmount(amount: '');
770 + key.currentState!.changeAmount(amount: '');
771 }
772
773 void _onWalletNameChange(ExchangeViewModel exchangeViewModel,
@@ -776,13 +775,13 @@ class ExchangePage extends BasePage {
775 final isCurrentTypeWallet = currency == exchangeViewModel.wallet.currency;
776
777 if (isCurrentTypeWallet) {
779 - key.currentState.changeWalletName(exchangeViewModel.wallet.name);
780 - key.currentState.addressController.text =
778 + key.currentState!.changeWalletName(exchangeViewModel.wallet.name);
779 + key.currentState!.addressController.text =
780 exchangeViewModel.wallet.walletAddresses.address;
782 - } else if (key.currentState.addressController.text ==
781 + } else if (key.currentState!.addressController.text ==
782 exchangeViewModel.wallet.walletAddresses.address) {
784 - key.currentState.changeWalletName(null);
785 - key.currentState.addressController.text = null;
783 + key.currentState!.changeWalletName('');
784 + key.currentState!.addressController.text = '';
785 }
786 }
787
lib/src/screens/exchange/exchange_template_page.dart
+52 -52
@@ -78,7 +78,7 @@ class ExchangeTemplatePage extends BasePage {
78 config: KeyboardActionsConfig(
79 keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
80 keyboardBarColor:
81 - Theme.of(context).accentTextTheme.body2.backgroundColor,
81 + Theme.of(context).accentTextTheme!.bodyText1!.backgroundColor!,
82 nextFocus: false,
83 actions: [
84 KeyboardActionsItem(
@@ -103,8 +103,8 @@ class ExchangeTemplatePage extends BasePage {
103 ),
104 gradient: LinearGradient(
105 colors: [
106 - Theme.of(context).primaryTextTheme.body1.color,
107 - Theme.of(context).primaryTextTheme.body1.decorationColor,
106 + Theme.of(context).primaryTextTheme!.bodyText2!.color!,
107 + Theme.of(context).primaryTextTheme!.bodyText2!.decorationColor!,
108 ],
109 stops: [0.35, 1.0],
110 begin: Alignment.topLeft,
@@ -121,13 +121,13 @@ class ExchangeTemplatePage extends BasePage {
121 gradient: LinearGradient(
122 colors: [
123 Theme.of(context)
124 - .primaryTextTheme
125 - .subtitle
126 - .color,
124 + .primaryTextTheme!
125 + .subtitle2!
126 + .color!,
127 Theme.of(context)
128 - .primaryTextTheme
129 - .subtitle
130 - .decorationColor,
128 + .primaryTextTheme!
129 + .subtitle2!
130 + .decorationColor!,
131 ],
132 begin: Alignment.topLeft,
133 end: Alignment.bottomRight),
@@ -140,7 +140,7 @@ class ExchangeTemplatePage extends BasePage {
140 title: S.of(context).you_will_send,
141 initialCurrency:
142 exchangeViewModel.depositCurrency,
143 - initialWalletName: depositWalletName,
143 + initialWalletName: depositWalletName ?? '',
144 initialAddress: exchangeViewModel
145 .depositCurrency ==
146 exchangeViewModel.wallet.currency
@@ -159,11 +159,11 @@ class ExchangeTemplatePage extends BasePage {
159 imageArrow: arrowBottomPurple,
160 currencyButtonColor: Colors.transparent,
161 addressButtonsColor:
162 - Theme.of(context).focusColor,
162 + Theme.of(context).focusColor!,
163 borderColor: Theme.of(context)
164 - .primaryTextTheme
165 - .body2
166 - .color,
164 + .primaryTextTheme!
165 + .bodyText1!
166 + .color!,
167 currencyValueValidator: AmountValidator(
168 type: exchangeViewModel.wallet.type),
169 //addressTextFieldValidator: AddressValidator(
@@ -180,7 +180,7 @@ class ExchangeTemplatePage extends BasePage {
180 title: S.of(context).you_will_get,
181 initialCurrency:
182 exchangeViewModel.receiveCurrency,
183 - initialWalletName: receiveWalletName,
183 + initialWalletName: receiveWalletName ?? '',
184 initialAddress:
185 exchangeViewModel.receiveCurrency ==
186 exchangeViewModel.wallet.currency
@@ -200,11 +200,11 @@ class ExchangeTemplatePage extends BasePage {
200 imageArrow: arrowBottomCakeGreen,
201 currencyButtonColor: Colors.transparent,
202 addressButtonsColor:
203 - Theme.of(context).focusColor,
203 + Theme.of(context).focusColor!,
204 borderColor: Theme.of(context)
205 - .primaryTextTheme
206 - .body2
207 - .decorationColor,
205 + .primaryTextTheme!
206 + .bodyText1!
207 + .decorationColor!,
208 currencyValueValidator: AmountValidator(
209 type: exchangeViewModel.wallet.type),
210 //addressTextFieldValidator: AddressValidator(
@@ -230,9 +230,9 @@ class ExchangeTemplatePage extends BasePage {
230 textAlign: TextAlign.center,
231 style: TextStyle(
232 color: Theme.of(context)
233 - .primaryTextTheme
234 - .display4
235 - .decorationColor,
233 + .primaryTextTheme!
234 + .headline1!
235 + .decorationColor!,
236 fontWeight: FontWeight.w500,
237 fontSize: 12),
238 ),
@@ -241,7 +241,7 @@ class ExchangeTemplatePage extends BasePage {
241 ),
242 PrimaryButton(
243 onPressed: () {
244 - if (_formKey.currentState.validate()) {
244 + if (_formKey.currentState != null && _formKey.currentState!.validate()) {
245 exchangeViewModel.addTemplate(
246 amount: exchangeViewModel.depositAmount,
247 depositCurrency:
@@ -270,10 +270,10 @@ class ExchangeTemplatePage extends BasePage {
270 return;
271 }
272
273 - final depositAddressController = depositKey.currentState.addressController;
274 - final depositAmountController = depositKey.currentState.amountController;
275 - final receiveAddressController = receiveKey.currentState.addressController;
276 - final receiveAmountController = receiveKey.currentState.amountController;
273 + final depositAddressController = depositKey.currentState!.addressController;
274 + final depositAmountController = depositKey.currentState!.amountController;
275 + final receiveAddressController = receiveKey.currentState!.addressController;
276 + final receiveAmountController = receiveKey.currentState!.amountController;
277 final limitsState = exchangeViewModel.limitsState;
278
279 // FIXME: FIXME
@@ -317,43 +317,43 @@ class ExchangeTemplatePage extends BasePage {
317 _onCurrencyChange(currency, exchangeViewModel, depositKey));
318
319 reaction((_) => exchangeViewModel.depositAmount, (String amount) {
320 - if (depositKey.currentState.amountController.text != amount) {
321 - depositKey.currentState.amountController.text = amount;
320 + if (depositKey.currentState!.amountController.text != amount) {
321 + depositKey.currentState!.amountController.text = amount;
322 }
323 });
324
325 reaction((_) => exchangeViewModel.depositAddress, (String address) {
326 - if (depositKey.currentState.addressController.text != address) {
327 - depositKey.currentState.addressController.text = address;
326 + if (depositKey.currentState!.addressController.text != address) {
327 + depositKey.currentState!.addressController.text = address;
328 }
329 });
330
331 reaction((_) => exchangeViewModel.isDepositAddressEnabled,
332 (bool isEnabled) {
333 - depositKey.currentState.isAddressEditable(isEditable: isEnabled);
333 + depositKey.currentState!.isAddressEditable(isEditable: isEnabled);
334 });
335
336 reaction((_) => exchangeViewModel.receiveAmount, (String amount) {
337 - if (receiveKey.currentState.amountController.text != amount) {
338 - receiveKey.currentState.amountController.text = amount;
337 + if (receiveKey.currentState!.amountController.text != amount) {
338 + receiveKey.currentState!.amountController.text = amount;
339 }
340 });
341
342 reaction((_) => exchangeViewModel.receiveAddress, (String address) {
343 - if (receiveKey.currentState.addressController.text != address) {
344 - receiveKey.currentState.addressController.text = address;
343 + if (receiveKey.currentState!.addressController.text != address) {
344 + receiveKey.currentState!.addressController.text = address;
345 }
346 });
347
348 reaction((_) => exchangeViewModel.isReceiveAddressEnabled,
349 (bool isEnabled) {
350 - receiveKey.currentState.isAddressEditable(isEditable: isEnabled);
350 + receiveKey.currentState!.isAddressEditable(isEditable: isEnabled);
351 });
352
353 - reaction((_) => exchangeViewModel.provider, (ExchangeProvider provider) {
353 + reaction((_) => exchangeViewModel.provider, (ExchangeProvider? provider) {
354 provider is XMRTOExchangeProvider
355 - ? receiveKey.currentState.isAmountEditable(isEditable: true)
356 - : receiveKey.currentState.isAmountEditable(isEditable: false);
355 + ? receiveKey.currentState!.isAmountEditable(isEditable: true)
356 + : receiveKey.currentState!.isAmountEditable(isEditable: false);
357 });
358
359 /*reaction((_) => exchangeViewModel.limitsState, (LimitsState state) {
@@ -404,11 +404,11 @@ class ExchangeTemplatePage extends BasePage {
404 reaction((_) => exchangeViewModel.wallet.walletAddresses.address,
405 (String address) {
406 if (exchangeViewModel.depositCurrency == CryptoCurrency.xmr) {
407 - depositKey.currentState.changeAddress(address: address);
407 + depositKey.currentState!.changeAddress(address: address);
408 }
409
410 if (exchangeViewModel.receiveCurrency == CryptoCurrency.xmr) {
411 - receiveKey.currentState.changeAddress(address: address);
411 + receiveKey.currentState!.changeAddress(address: address);
412 }
413 });
414
@@ -419,15 +419,15 @@ class ExchangeTemplatePage extends BasePage {
419 ExchangeViewModel exchangeViewModel, GlobalKey<ExchangeCardState> key) {
420 final isCurrentTypeWallet = currency == exchangeViewModel.wallet.currency;
421
422 - key.currentState.changeSelectedCurrency(currency);
423 - key.currentState.changeWalletName(
424 - isCurrentTypeWallet ? exchangeViewModel.wallet.name : null);
422 + key.currentState!.changeSelectedCurrency(currency);
423 + key.currentState!.changeWalletName(
424 + isCurrentTypeWallet ? exchangeViewModel.wallet.name : '');
425
426 - key.currentState.changeAddress(
426 + key.currentState!.changeAddress(
427 address: isCurrentTypeWallet
428 ? exchangeViewModel.wallet.walletAddresses.address : '');
429
430 - key.currentState.changeAmount(amount: '');
430 + key.currentState!.changeAmount(amount: '');
431 }
432
433 void _onWalletNameChange(ExchangeViewModel exchangeViewModel,
@@ -435,13 +435,13 @@ class ExchangeTemplatePage extends BasePage {
435 final isCurrentTypeWallet = currency == exchangeViewModel.wallet.currency;
436
437 if (isCurrentTypeWallet) {
438 - key.currentState.changeWalletName(exchangeViewModel.wallet.name);
439 - key.currentState.addressController.text =
438 + key.currentState!.changeWalletName(exchangeViewModel.wallet.name);
439 + key.currentState!.addressController.text =
440 exchangeViewModel.wallet.walletAddresses.address;
441 - } else if (key.currentState.addressController.text ==
441 + } else if (key.currentState!.addressController.text ==
442 exchangeViewModel.wallet.walletAddresses.address) {
443 - key.currentState.changeWalletName(null);
444 - key.currentState.addressController.text = null;
443 + key.currentState!.changeWalletName('');
444 + key.currentState!.addressController.text = '';
445 }
446 }
447 }
\ No newline at end of file
lib/src/screens/exchange/widgets/currency_picker.dart
+13 -14
@@ -10,9 +10,9 @@ import 'currency_picker_widget.dart';
10
11 class CurrencyPicker extends StatefulWidget {
12 CurrencyPicker(
13 - {@required this.selectedAtIndex,
14 - @required this.items,
15 - @required this.onItemSelected,
13 + {required this.selectedAtIndex,
14 + required this.items,
15 + required this.onItemSelected,
16 this.title,
17 this.hintText,
18 this.isMoneroWallet = false,
@@ -20,11 +20,11 @@ class CurrencyPicker extends StatefulWidget {
20
21 int selectedAtIndex;
22 final List<CryptoCurrency> items;
23 - final String title;
23 + final String? title;
24 final Function(CryptoCurrency) onItemSelected;
25 final bool isMoneroWallet;
26 final bool isConvertFrom;
27 - final String hintText;
27 + final String? hintText;
28
29 @override
30 CurrencyPickerState createState() => CurrencyPickerState(items);
@@ -36,9 +36,8 @@ class CurrencyPickerState extends State<CurrencyPicker> {
36 textFieldValue = '',
37 subPickerItemsList = items,
38 appBarTextStyle =
39 - TextStyle(fontSize: 20, fontFamily: 'Lato', backgroundColor: Colors.transparent, color: Colors.white);
40 -
41 -
39 + TextStyle(fontSize: 20, fontFamily: 'Lato', backgroundColor: Colors.transparent, color: Colors.white),
40 + pickerItemsList = <PickerItem<CryptoCurrency>>[];
41
42 List<PickerItem<CryptoCurrency>> pickerItemsList;
43 List<CryptoCurrency> items;
@@ -55,8 +54,8 @@ class CurrencyPickerState extends State<CurrencyPicker> {
54 subPickerItemsList = items
55 .where((element) =>
56 (element.title != null ? element.title.toLowerCase().contains(subString.toLowerCase()) : false) ||
58 - (element.tag != null ? element.tag.toLowerCase().contains(subString.toLowerCase()) : false) ||
59 - (element.name != null ? element.name.toLowerCase().contains(subString.toLowerCase()) : false))
57 + (element.tag != null ? element.tag!.toLowerCase().contains(subString.toLowerCase()) : false) ||
58 + (element.name != null ? element.name!.toLowerCase().contains(subString.toLowerCase()) : false))
59 .toList();
60 return;
61 }
@@ -77,7 +76,7 @@ class CurrencyPickerState extends State<CurrencyPicker> {
76 Container(
77 padding: EdgeInsets.symmetric(horizontal: 24),
78 child: Text(
80 - widget.title,
79 + widget.title!,
80 textAlign: TextAlign.center,
81 style: TextStyle(
82 fontSize: 18,
@@ -93,7 +92,7 @@ class CurrencyPickerState extends State<CurrencyPicker> {
92 child: ClipRRect(
93 borderRadius: BorderRadius.all(Radius.circular(30)),
94 child: Container(
96 - color: Theme.of(context).accentTextTheme.title.color,
95 + color: Theme.of(context).accentTextTheme!.headline6!.color!,
96 child: ConstrainedBox(
97 constraints: BoxConstraints(
98 maxHeight: MediaQuery.of(context).size.height * 0.65,
@@ -105,7 +104,7 @@ class CurrencyPickerState extends State<CurrencyPicker> {
104 Padding(
105 padding: const EdgeInsets.all(16),
106 child: TextFormField(
108 - style: TextStyle(color: Theme.of(context).primaryTextTheme.title.color),
107 + style: TextStyle(color: Theme.of(context).primaryTextTheme!.headline6!.color!),
108 decoration: InputDecoration(
109 hintText: widget.hintText,
110 prefixIcon: Image.asset("assets/images/search_icon.png"),
@@ -132,7 +131,7 @@ class CurrencyPickerState extends State<CurrencyPicker> {
131 ),
132 ),
133 Divider(
135 - color: Theme.of(context).accentTextTheme.title.backgroundColor,
134 + color: Theme.of(context).accentTextTheme!.headline6!.backgroundColor!,
135 height: 1,
136 ),
137 if (widget.selectedAtIndex != -1)
lib/src/screens/exchange/widgets/currency_picker_item_widget.dart
+15 -10
@@ -2,20 +2,25 @@ import 'package:flutter/material.dart';
2 import 'package:cake_wallet/palette.dart';
3
4 class PickerItemWidget extends StatelessWidget {
5 - const PickerItemWidget({this.iconPath, this.title, this.isSelected = false, this.tag, this.onTap});
5 + const PickerItemWidget({
6 + required this.title,
7 + this.iconPath,
8 + this.isSelected = false,
9 + this.tag,
10 + this.onTap});
11
7 - final String iconPath;
12 + final String? iconPath;
13 final String title;
14 final bool isSelected;
10 - final String tag;
11 - final void Function() onTap;
15 + final String? tag;
16 + final VoidCallback? onTap;
17
18 @override
19 Widget build(BuildContext context) {
20 return GestureDetector(
21 onTap: onTap,
22 child: Container(
18 - color: Theme.of(context).accentTextTheme.headline6.color,
23 + color: Theme.of(context).accentTextTheme!.headline6!.color!,
24 child: Padding(
25 padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 24),
26 child: Row(
@@ -34,7 +39,7 @@ class PickerItemWidget extends StatelessWidget {
39 Text(
40 title,
41 style: TextStyle(
37 - color: isSelected ? Palette.blueCraiola : Theme.of(context).primaryTextTheme.title.color,
42 + color: isSelected ? Palette.blueCraiola : Theme.of(context).primaryTextTheme!.headline6!.color!,
43 fontSize: isSelected ? 16 : 14.0,
44 fontFamily: 'Lato',
45 fontWeight: FontWeight.w600,
@@ -48,22 +53,22 @@ class PickerItemWidget extends StatelessWidget {
53 height: 18.0,
54 child: Center(
55 child: Text(
51 - tag,
56 + tag!,
57 style: TextStyle(
53 - fontSize: 7.0, fontFamily: 'Lato', color: Theme.of(context).textTheme.body1.color),
58 + fontSize: 7.0, fontFamily: 'Lato', color: Theme.of(context).textTheme!.bodyText2!.color!),
59 ),
60 ),
61 decoration: BoxDecoration(
62 borderRadius: BorderRadius.circular(6.0),
63 //border: Border.all(color: ),
59 - color: Theme.of(context).textTheme.body1.decorationColor,
64 + color: Theme.of(context).textTheme!.bodyText2!.decorationColor!,
65 ),
66 ),
67 ),
68 ],
69 ),
70 ),
66 - if (isSelected) Icon(Icons.check_circle, color: Theme.of(context).accentTextTheme.body2.color)
71 + if (isSelected) Icon(Icons.check_circle, color: Theme.of(context).accentTextTheme!.bodyText1!.color!)
72 ],
73 ),
74 ),
lib/src/screens/exchange/widgets/currency_picker_widget.dart
+5 -5
@@ -5,10 +5,10 @@ import 'currency_picker_item_widget.dart';
5
6 class CurrencyPickerWidget extends StatelessWidget {
7 CurrencyPickerWidget({
8 - @required this.crossAxisCount,
9 - @required this.selectedAtIndex,
10 - @required this.pickerItemsList,
11 - @required this.pickListItem,
8 + required this.crossAxisCount,
9 + required this.selectedAtIndex,
10 + required this.pickerItemsList,
11 + required this.pickListItem,
12 });
13
14 final int crossAxisCount;
@@ -21,7 +21,7 @@ class CurrencyPickerWidget extends StatelessWidget {
21 @override
22 Widget build(BuildContext context) {
23 return Container(
24 - color: Theme.of(context).accentTextTheme.headline6.backgroundColor,
24 + color: Theme.of(context).accentTextTheme!.headline6!.backgroundColor!,
25 child: Scrollbar(
26 controller: _scrollController,
27 child: GridView.builder(
lib/src/screens/exchange/widgets/exchange_card.dart
+75 -67
@@ -14,27 +14,27 @@ import 'package:cake_wallet/src/screens/exchange/widgets/currency_picker.dart';
14
15 class ExchangeCard extends StatefulWidget {
16 ExchangeCard(
17 - {Key key,
17 + {Key? key,
18 + required this.initialCurrency,
19 + required this.initialAddress,
20 + required this.initialWalletName,
21 + required this.initialIsAmountEditable,
22 + required this.initialIsAddressEditable,
23 + required this.isAmountEstimated,
24 + required this.currencies,
25 + required this.onCurrencySelected,
26 + required this.imageArrow,
27 + this.currencyValueValidator,
28 + this.addressTextFieldValidator,
29 this.title = '',
19 - this.initialCurrency,
20 - this.initialAddress,
21 - this.initialWalletName,
22 - this.initialIsAmountEditable,
23 - this.initialIsAddressEditable,
24 - this.isAmountEstimated,
30 this.hasRefundAddress = false,
31 this.isMoneroWallet = false,
27 - this.currencies,
28 - this.onCurrencySelected,
29 - this.imageArrow,
32 this.currencyButtonColor = Colors.transparent,
33 this.addressButtonsColor = Colors.transparent,
34 this.borderColor = Colors.transparent,
33 - this.currencyValueValidator,
34 - this.addressTextFieldValidator,
35 + this.hasAllAmount = false,
36 this.amountFocusNode,
37 this.addressFocusNode,
37 - this.hasAllAmount = false,
38 this.allAmount,
39 this.onPushPasteButton,
40 this.onPushAddressBookButton})
@@ -53,28 +53,39 @@ class ExchangeCard extends StatefulWidget {
53 final bool isMoneroWallet;
54 final Image imageArrow;
55 final Color currencyButtonColor;
56 - final Color addressButtonsColor;
56 + final Color? addressButtonsColor;
57 final Color borderColor;
58 - final FormFieldValidator<String> currencyValueValidator;
59 - final FormFieldValidator<String> addressTextFieldValidator;
60 - final FocusNode amountFocusNode;
61 - final FocusNode addressFocusNode;
58 + final FormFieldValidator<String>? currencyValueValidator;
59 + final FormFieldValidator<String>? addressTextFieldValidator;
60 + final FocusNode? amountFocusNode;
61 + final FocusNode? addressFocusNode;
62 final bool hasAllAmount;
63 - final Function allAmount;
64 - final Function(BuildContext context) onPushPasteButton;
65 - final Function(BuildContext context) onPushAddressBookButton;
63 + final VoidCallback? allAmount;
64 + final void Function(BuildContext context)? onPushPasteButton;
65 + final void Function(BuildContext context)? onPushAddressBookButton;
66
67 @override
68 ExchangeCardState createState() => ExchangeCardState();
69 }
70
71 class ExchangeCardState extends State<ExchangeCard> {
72 + ExchangeCardState()
73 + : _title = '',
74 + _min = '',
75 + _max = '',
76 + _isAmountEditable = false,
77 + _isAddressEditable = false,
78 + _walletName = '',
79 + _selectedCurrency = CryptoCurrency.btc,
80 + _isAmountEstimated = false,
81 + _isMoneroWallet = false;
82 +
83 final addressController = TextEditingController();
84 final amountController = TextEditingController();
85
86 String _title;
76 - String _min;
77 - String _max;
87 + String? _min;
88 + String? _max;
89 CryptoCurrency _selectedCurrency;
90 String _walletName;
91 bool _isAmountEditable;
@@ -95,7 +106,7 @@ class ExchangeCardState extends State<ExchangeCard> {
106 super.initState();
107 }
108
98 - void changeLimits({String min, String max}) {
109 + void changeLimits({String? min, String? max}) {
110 setState(() {
111 _min = min;
112 _max = max;
@@ -122,11 +133,11 @@ class ExchangeCardState extends State<ExchangeCard> {
133 setState(() => _isAddressEditable = isEditable);
134 }
135
125 - void changeAddress({String address}) {
136 + void changeAddress({required String address}) {
137 setState(() => addressController.text = address);
138 }
139
129 - void changeAmount({String amount}) {
140 + void changeAmount({required String amount}) {
141 setState(() => amountController.text = amount);
142 }
143
@@ -139,7 +150,7 @@ class ExchangeCardState extends State<ExchangeCard> {
150 final copyImage = Image.asset('assets/images/copy_content.png',
151 height: 16,
152 width: 16,
142 - color: Theme.of(context).primaryTextTheme.display2.color);
153 + color: Theme.of(context).primaryTextTheme!.headline3!.color!);
154
155 return Container(
156 width: double.infinity,
@@ -154,7 +165,7 @@ class ExchangeCardState extends State<ExchangeCard> {
165 style: TextStyle(
166 fontSize: 18,
167 fontWeight: FontWeight.w600,
157 - color: Theme.of(context).textTheme.headline.color),
168 + color: Theme.of(context).textTheme!.headline5!.color!),
169 )
170 ],
171 ),
@@ -189,23 +200,20 @@ class ExchangeCardState extends State<ExchangeCard> {
200 child: Container(
201 height: 32,
202 decoration: BoxDecoration(
192 - color: widget.addressButtonsColor ?? Theme.of(context)
193 - .primaryTextTheme
194 - .display1
195 - .color,
203 + color: widget.addressButtonsColor ?? Theme.of(context).primaryTextTheme!.headline4!.color!,
204 borderRadius:
205 BorderRadius.all(Radius.circular(6))),
206 child: Center(
207 child: Padding(
208 padding: const EdgeInsets.all(6.0),
201 - child: Text(_selectedCurrency.tag,
209 + child: Text(_selectedCurrency.tag!,
210 style: TextStyle(
211 fontSize: 12,
212 fontWeight: FontWeight.bold,
213 color: Theme.of(context)
206 - .primaryTextTheme
207 - .display1
208 - .decorationColor)),
214 + .primaryTextTheme!
215 + .headline4!
216 + .decorationColor!)),
217 ),
218 ),
219 ),
@@ -245,9 +253,9 @@ class ExchangeCardState extends State<ExchangeCard> {
253 fontSize: 16,
254 fontWeight: FontWeight.w600,
255 color: Theme.of(context)
248 - .accentTextTheme
249 - .display4
250 - .decorationColor),
256 + .accentTextTheme!
257 + .headline1!
258 + .decorationColor!),
259 validator: _isAmountEditable
260 ? widget.currencyValueValidator
261 : null),
@@ -258,9 +266,9 @@ class ExchangeCardState extends State<ExchangeCard> {
266 width: 32,
267 decoration: BoxDecoration(
268 color: Theme.of(context)
261 - .primaryTextTheme
262 - .display1
263 - .color,
269 + .primaryTextTheme!
270 + .headline4!
271 + .color!,
272 borderRadius:
273 BorderRadius.all(Radius.circular(6))),
274 child: InkWell(
@@ -272,9 +280,9 @@ class ExchangeCardState extends State<ExchangeCard> {
280 fontSize: 12,
281 fontWeight: FontWeight.bold,
282 color: Theme.of(context)
275 - .primaryTextTheme
276 - .display1
277 - .decorationColor)),
283 + .primaryTextTheme!
284 + .headline4!
285 + .decorationColor!)),
286 ),
287 ),
288 )
@@ -284,9 +292,9 @@ class ExchangeCardState extends State<ExchangeCard> {
292 ],
293 )),
294 Divider(height: 1,color: Theme.of(context)
287 - .primaryTextTheme
288 - .headline
289 - .decorationColor),
295 + .primaryTextTheme!
296 + .headline5!
297 + .decorationColor!),
298 Padding(
299 padding: EdgeInsets.only(top: 5),
300 child: Container(
@@ -298,14 +306,14 @@ class ExchangeCardState extends State<ExchangeCard> {
306 ? Text(
307 S
308 .of(context)
301 - .min_value(_min, _selectedCurrency.toString()),
309 + .min_value(_min ?? '', _selectedCurrency.toString()),
310 style: TextStyle(
311 fontSize: 10,
312 height: 1.2,
313 color: Theme.of(context)
306 - .accentTextTheme
307 - .display4
308 - .decorationColor),
314 + .accentTextTheme!
315 + .headline1!
316 + .decorationColor!),
317 )
318 : Offstage(),
319 _min != null ? SizedBox(width: 10) : Offstage(),
@@ -313,14 +321,14 @@ class ExchangeCardState extends State<ExchangeCard> {
321 ? Text(
322 S
323 .of(context)
316 - .max_value(_max, _selectedCurrency.toString()),
324 + .max_value(_max ?? '', _selectedCurrency.toString()),
325 style: TextStyle(
326 fontSize: 10,
327 height: 1.2,
328 color: Theme.of(context)
321 - .accentTextTheme
322 - .display4
323 - .decorationColor))
329 + .accentTextTheme!
330 + .headline1!
331 + .decorationColor!))
332 : Offstage(),
333 ])),
334 ),
@@ -333,9 +341,9 @@ class ExchangeCardState extends State<ExchangeCard> {
341 fontSize: 14,
342 fontWeight: FontWeight.w500,
343 color: Theme.of(context)
336 - .accentTextTheme
337 - .display4
338 - .decorationColor),
344 + .accentTextTheme!
345 + .headline1!
346 + .decorationColor!),
347 ))
348 : Offstage(),
349 _isAddressEditable
@@ -352,7 +360,7 @@ class ExchangeCardState extends State<ExchangeCard> {
360 _showAmountPopup(context, paymentRequest);
361 return;
362 }
355 - widget.amountFocusNode.requestFocus();
363 + widget.amountFocusNode?.requestFocus();
364 amountController.text = paymentRequest.amount;
365 },
366 placeholder: widget.hasRefundAddress
@@ -372,9 +380,9 @@ class ExchangeCardState extends State<ExchangeCard> {
380 fontSize: 16,
381 fontWeight: FontWeight.w600,
382 color: Theme.of(context)
375 - .accentTextTheme
376 - .display4
377 - .decorationColor),
383 + .accentTextTheme!
384 + .headline1!
385 + .decorationColor!),
386 buttonColor: widget.addressButtonsColor,
387 validator: widget.addressTextFieldValidator,
388 onPushPasteButton: widget.onPushPasteButton,
@@ -439,9 +447,9 @@ class ExchangeCardState extends State<ExchangeCard> {
447 child: Image.asset(
448 'assets/images/open_book.png',
449 color: Theme.of(context)
442 - .primaryTextTheme
443 - .display1
444 - .decorationColor,
450 + .primaryTextTheme!
451 + .headline4!
452 + .decorationColor!,
453 )),
454 )),
455 ),
@@ -500,7 +508,7 @@ class ExchangeCardState extends State<ExchangeCard> {
508 rightButtonText: S.of(context).ok,
509 leftButtonText: S.of(context).cancel,
510 actionRightButton: () {
503 - widget.amountFocusNode.requestFocus();
511 + widget.amountFocusNode?.requestFocus();
512 amountController.text = paymentRequest.amount;
513 Navigator.of(context).pop();
514 },
lib/src/screens/exchange/widgets/picker_item.dart
+4 -1
@@ -1,6 +1,9 @@
1 class PickerItem<T> {
2 PickerItem(this.original,
3 - {this.title, this.iconPath, this.tag, this.description});
3 + {required this.title,
4 + required this.iconPath,
5 + required this.tag,
6 + required this.description});
7
8 final String title;
9 final String iconPath;
lib/src/screens/exchange/widgets/present_provider_picker.dart
+6 -5
@@ -7,7 +7,7 @@ import 'package:cake_wallet/generated/i18n.dart';
7 import 'package:cake_wallet/view_model/exchange/exchange_view_model.dart';
8
9 class PresentProviderPicker extends StatelessWidget {
10 - PresentProviderPicker({@required this.exchangeViewModel});
10 + PresentProviderPicker({required this.exchangeViewModel});
11
12 final ExchangeViewModel exchangeViewModel;
13
@@ -18,10 +18,11 @@ class PresentProviderPicker extends StatelessWidget {
18 color: Colors.white,
19 height: 6);
20
21 - return FlatButton(
21 + return TextButton(
22 onPressed: () => _presentProviderPicker(context),
23 - highlightColor: Colors.transparent,
24 - splashColor: Colors.transparent,
23 + // FIX-ME: Style
24 + //highlightColor: Colors.transparent,
25 + //splashColor: Colors.transparent,
26 child: Row(
27 mainAxisSize: MainAxisSize.min,
28 crossAxisAlignment: CrossAxisAlignment.start,
@@ -45,7 +46,7 @@ class PresentProviderPicker extends StatelessWidget {
46 style: TextStyle(
47 fontSize: 10.0,
48 fontWeight: FontWeight.w500,
48 - color: Theme.of(context).textTheme.headline.color)))
49 + color: Theme.of(context).textTheme!.headline5!.color!)))
50 ],
51 ),
52 SizedBox(width: 5),
lib/src/screens/exchange_trade/exchange_confirm_page.dart
+15 -15
@@ -11,7 +11,7 @@ import 'package:cake_wallet/src/screens/base_page.dart';
11 import 'package:cake_wallet/exchange/trade.dart';
12
13 class ExchangeConfirmPage extends BasePage {
14 - ExchangeConfirmPage({@required this.tradesStore}) : trade = tradesStore.trade;
14 + ExchangeConfirmPage({required this.tradesStore}) : trade = tradesStore.trade!;
15
16 final TradesStore tradesStore;
17 final Trade trade;
@@ -36,7 +36,7 @@ class ExchangeConfirmPage extends BasePage {
36 style: TextStyle(
37 fontSize: 18.0,
38 fontWeight: FontWeight.w500,
39 - color: Theme.of(context).primaryTextTheme.title.color),
39 + color: Theme.of(context).primaryTextTheme!.headline6!.color!),
40 ),
41 )),
42 Container(
@@ -45,8 +45,8 @@ class ExchangeConfirmPage extends BasePage {
45 borderRadius: BorderRadius.all(Radius.circular(30)),
46 border: Border.all(
47 width: 1,
48 - color: Theme.of(context).accentTextTheme.caption.color),
49 - color: Theme.of(context).accentTextTheme.title.color),
48 + color: Theme.of(context).accentTextTheme!.caption!.color!),
49 + color: Theme.of(context).accentTextTheme!.headline6!.color!),
50 child: Column(
51 children: <Widget>[
52 Expanded(
@@ -62,9 +62,9 @@ class ExchangeConfirmPage extends BasePage {
62 fontSize: 12.0,
63 fontWeight: FontWeight.w500,
64 color: Theme.of(context)
65 - .primaryTextTheme
66 - .overline
67 - .color),
65 + .primaryTextTheme!
66 + .overline!
67 + .color!),
68 ),
69 Text(
70 trade.id,
@@ -74,9 +74,9 @@ class ExchangeConfirmPage extends BasePage {
74 fontSize: 20,
75 fontWeight: FontWeight.w600,
76 color: Theme.of(context)
77 - .primaryTextTheme
78 - .title
79 - .color),
77 + .primaryTextTheme!
78 + .headline6!
79 + .color!),
80 ),
81 ],
82 ),
@@ -92,11 +92,11 @@ class ExchangeConfirmPage extends BasePage {
92 },
93 text: S.of(context).copy_id,
94 color: Theme.of(context)
95 - .accentTextTheme
96 - .caption
97 - .backgroundColor,
95 + .accentTextTheme!
96 + .caption!
97 + .backgroundColor!,
98 textColor:
99 - Theme.of(context).primaryTextTheme.title.color),
99 + Theme.of(context).primaryTextTheme!.headline6!.color!),
100 ),
101 )
102 ],
@@ -125,7 +125,7 @@ class ExchangeConfirmPage extends BasePage {
125 onPressed: () => Navigator.of(context)
126 .pushReplacementNamed(Routes.exchangeTrade),
127 text: S.of(context).saved_the_trade_id,
128 - color: Theme.of(context).accentTextTheme.body2.color,
128 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
129 textColor: Colors.white)
130 ],
131 ),
lib/src/screens/exchange_trade/exchange_trade_item.dart
+3 -3
@@ -2,9 +2,9 @@ import 'package:flutter/cupertino.dart';
2
3 class ExchangeTradeItem {
4 ExchangeTradeItem({
5 - @required this.title,
6 - @required this.data,
7 - @required this.isCopied,
5 + required this.title,
6 + required this.data,
7 + required this.isCopied,
8 });
9
10 String title;
lib/src/screens/exchange_trade/exchange_trade_page.dart
+36 -37
@@ -40,7 +40,7 @@ void showInformation(
40 }
41
42 class ExchangeTradePage extends BasePage {
43 - ExchangeTradePage({@required this.exchangeTradeViewModel});
43 + ExchangeTradePage({required this.exchangeTradeViewModel});
44
45 final ExchangeTradeViewModel exchangeTradeViewModel;
46
@@ -50,17 +50,18 @@ class ExchangeTradePage extends BasePage {
50 @override
51 Widget trailing(BuildContext context) {
52 final questionImage = Image.asset('assets/images/question_mark.png',
53 - color: Theme.of(context).primaryTextTheme.title.color);
53 + color: Theme.of(context).primaryTextTheme!.headline6!.color!);
54
55 return SizedBox(
56 height: 20.0,
57 width: 20.0,
58 child: ButtonTheme(
59 minWidth: double.minPositive,
60 - child: FlatButton(
61 - highlightColor: Colors.transparent,
62 - splashColor: Colors.transparent,
63 - padding: EdgeInsets.all(0),
60 + child: TextButton(
61 + // FIX-ME: Style
62 + //highlightColor: Colors.transparent,
63 + //splashColor: Colors.transparent,
64 + //padding: EdgeInsets.all(0),
65 onPressed: () => showInformation(exchangeTradeViewModel, context),
66 child: questionImage),
67 ),
@@ -109,7 +110,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
110 final copyImage = Image.asset('assets/images/copy_content.png',
111 height: 16,
112 width: 16,
112 - color: Theme.of(context).primaryTextTheme.overline.color);
113 + color: Theme.of(context).primaryTextTheme!.overline!.color!);
114
115 _setEffects(context);
116
@@ -132,15 +133,16 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
133 fontSize: 14.0,
134 fontWeight: FontWeight.w500,
135 color: Theme.of(context)
135 - .primaryTextTheme
136 - .overline
137 - .color),
136 + .primaryTextTheme!
137 + .overline!
138 + .color!),
139 ),
139 - TimerWidget(trade.expiredAt,
140 - color: Theme.of(context)
141 - .primaryTextTheme
142 - .title
143 - .color)
140 + if (trade.expiredAt != null)
141 + TimerWidget(trade.expiredAt!,
142 + color: Theme.of(context)
143 + .primaryTextTheme!
144 + .headline6!
145 + .color!)
146 ])
147 : Offstage(),
148 Padding(
@@ -158,18 +160,18 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
160 border: Border.all(
161 width: 3,
162 color: Theme.of(context)
161 - .accentTextTheme
162 - .subtitle
163 - .color
163 + .accentTextTheme!
164 + .subtitle2!
165 + .color!
166 )
167 ),
168 child: QrImage(
169 data: trade.inputAddress ?? fetchingLabel,
170 backgroundColor: Colors.transparent,
171 foregroundColor: Theme.of(context)
170 - .accentTextTheme
171 - .subtitle
172 - .color,
172 + .accentTextTheme!
173 + .subtitle2!
174 + .color!,
175 ),
176 )))),
177 Spacer(flex: 3)
@@ -184,9 +186,9 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
186 separatorBuilder: (context, index) => Container(
187 height: 1,
188 color: Theme.of(context)
187 - .accentTextTheme
188 - .subtitle
189 - .backgroundColor,
189 + .accentTextTheme!
190 + .subtitle2!
191 + .backgroundColor!,
192 ),
193 itemBuilder: (context, index) {
194 final item = widget.exchangeTradeViewModel.items[index];
@@ -227,12 +229,12 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
229 !(sendingState is TransactionCommitted)
230 ? LoadingPrimaryButton(
231 isDisabled: trade.inputAddress == null ||
230 - trade.inputAddress.isEmpty,
232 + trade.inputAddress!.isEmpty,
233 isLoading: sendingState is IsExecutingState,
234 onPressed: () =>
235 widget.exchangeTradeViewModel.confirmSending(),
236 text: S.of(context).confirm,
235 - color: Theme.of(context).accentTextTheme.body2.color,
237 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
238 textColor: Colors.white)
239 : Offstage();
240 })),
@@ -269,10 +271,10 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
271 alertTitle: S.of(context).confirm_sending,
272 amount: S.of(context).send_amount,
273 amountValue: widget.exchangeTradeViewModel.sendViewModel
272 - .pendingTransaction.amountFormatted,
274 + .pendingTransaction!.amountFormatted,
275 fee: S.of(context).send_fee,
276 feeValue: widget.exchangeTradeViewModel.sendViewModel
275 - .pendingTransaction.feeFormatted,
277 + .pendingTransaction!.feeFormatted,
278 rightButtonText: S.of(context).ok,
279 leftButtonText: S.of(context).cancel,
280 actionRightButton: () async {
@@ -311,8 +313,8 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
313 fontSize: 22,
314 fontWeight: FontWeight.bold,
315 color: Theme.of(context)
314 - .primaryTextTheme
315 - .title
316 + .primaryTextTheme!
317 + .headline6!
318 .color,
319 decoration: TextDecoration.none,
320 ),
@@ -328,9 +330,9 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
330 Navigator.of(context).pop(),
331 text: S.of(context).send_got_it,
332 color: Theme.of(context)
331 - .accentTextTheme
332 - .body2
333 - .color,
333 + .accentTextTheme!
334 + .bodyText1!
335 + .color!,
336 textColor: Colors.white))
337 ],
338 );
@@ -362,10 +364,7 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
364 style: TextStyle(
365 fontSize: 22,
366 fontWeight: FontWeight.bold,
365 - color: Theme.of(context)
366 - .primaryTextTheme
367 - .title
368 - .color,
367 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
368 decoration: TextDecoration.none,
369 ),
370 ),
lib/src/screens/exchange_trade/information_page.dart
+5 -5
@@ -6,7 +6,7 @@ import 'package:flutter/material.dart';
6 import 'package:cake_wallet/src/widgets/alert_background.dart';
7
8 class InformationPage extends StatelessWidget {
9 - InformationPage({@required this.information});
9 + InformationPage({required this.information});
10
11 final String information;
12
@@ -21,7 +21,7 @@ class InformationPage extends StatelessWidget {
21 ),
22 decoration: BoxDecoration(
23 borderRadius: BorderRadius.all(Radius.circular(30)),
24 - color: Theme.of(context).textTheme.body2.decorationColor
24 + color: Theme.of(context).textTheme!.bodyText1!.decorationColor!
25 ),
26 child: Column(
27 mainAxisSize: MainAxisSize.min,
@@ -35,7 +35,7 @@ class InformationPage extends StatelessWidget {
35 fontWeight: FontWeight.normal,
36 fontFamily: 'Lato',
37 decoration: TextDecoration.none,
38 - color: Theme.of(context).accentTextTheme.caption.decorationColor
38 + color: Theme.of(context).accentTextTheme!.caption!.decorationColor!
39 ),
40 ),
41 ),
@@ -44,8 +44,8 @@ class InformationPage extends StatelessWidget {
44 child: PrimaryButton(
45 onPressed: () => Navigator.of(context).pop(),
46 text: S.of(context).send_got_it,
47 - color: Theme.of(context).accentTextTheme.caption.backgroundColor,
48 - textColor: Theme.of(context).primaryTextTheme.title.color
47 + color: Theme.of(context).accentTextTheme!.caption!.backgroundColor!,
48 + textColor: Theme.of(context).primaryTextTheme!.headline6!.color!
49 ),
50 )
51 ],
lib/src/screens/exchange_trade/widgets/timer_widget.dart
+7 -3
@@ -13,13 +13,17 @@ class TimerWidget extends StatefulWidget {
13 }
14
15 class TimerWidgetState extends State<TimerWidget> {
16 - TimerWidgetState();
16 + TimerWidgetState()
17 + : _leftSeconds = 0,
18 + _minutes = 0,
19 + _seconds = 0,
20 + _isExpired = false;
21
22 int _leftSeconds;
23 int _minutes;
24 int _seconds;
25 bool _isExpired;
22 - Timer _timer;
26 + Timer? _timer;
27
28 @override
29 void initState() {
@@ -45,7 +49,7 @@ class TimerWidgetState extends State<TimerWidget> {
49
50 @override
51 void dispose() {
48 - if (_timer != null) _timer.cancel();
52 + _timer?.cancel();
53 super.dispose();
54 }
55
lib/src/screens/faq/faq_item.dart
+6 -3
@@ -12,6 +12,9 @@ class FAQItem extends StatefulWidget {
12 }
13
14 class FAQItemState extends State<FAQItem> {
15 + FAQItemState()
16 + : isActive = false;
17 +
18 bool isActive;
19
20 @override
@@ -23,12 +26,12 @@ class FAQItemState extends State<FAQItem> {
26 @override
27 Widget build(BuildContext context) {
28 final addIcon =
26 - Icon(Icons.add, color: Theme.of(context).primaryTextTheme.title.color);
29 + Icon(Icons.add, color: Theme.of(context).primaryTextTheme!.headline6!.color!);
30 final removeIcon = Icon(Icons.remove, color: Palette.blueCraiola);
31 final icon = isActive ? removeIcon : addIcon;
32 final color = isActive
33 ? Palette.blueCraiola
31 - : Theme.of(context).primaryTextTheme.title.color;
34 + : Theme.of(context).primaryTextTheme!.headline6!.color!;
35
36 return ListTileTheme(
37 contentPadding: EdgeInsets.fromLTRB(0, 6, 24, 6),
@@ -50,7 +53,7 @@ class FAQItemState extends State<FAQItem> {
53 style: TextStyle(
54 fontSize: 14,
55 fontWeight: FontWeight.normal,
53 - color: Theme.of(context).primaryTextTheme.title.color),
56 + color: Theme.of(context).primaryTextTheme!.headline6!.color!),
57 ),
58 ))
59 ])
lib/src/screens/ionia/auth/ionia_create_account_page.dart
+5 -5
@@ -40,7 +40,7 @@ class IoniaCreateAccountPage extends BasePage {
40 return Text(
41 S.current.sign_up,
42 style: textMediumSemiBold(
43 - color: Theme.of(context).accentTextTheme.display4.backgroundColor,
43 + color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
44 ),
45 );
46 }
@@ -78,13 +78,13 @@ class IoniaCreateAccountPage extends BasePage {
78 builder: (_) => LoadingPrimaryButton(
79 text: S.of(context).create_account,
80 onPressed: () async {
81 - if (!_formKey.currentState.validate()) {
81 + if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
82 return;
83 }
84 await _authViewModel.createUser(_emailController.text);
85 },
86 isLoading: _authViewModel.createUserState is IoniaCreateStateLoading,
87 - color: Theme.of(context).accentTextTheme.body2.color,
87 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
88 textColor: Colors.white,
89 ),
90 ),
@@ -104,7 +104,7 @@ class IoniaCreateAccountPage extends BasePage {
104 TextSpan(
105 text: S.of(context).settings_terms_and_conditions,
106 style: TextStyle(
107 - color: Theme.of(context).accentTextTheme.body2.color,
107 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
108 fontWeight: FontWeight.w700,
109 ),
110 recognizer: TapGestureRecognizer()
@@ -116,7 +116,7 @@ class IoniaCreateAccountPage extends BasePage {
116 TextSpan(
117 text: S.of(context).privacy_policy,
118 style: TextStyle(
119 - color: Theme.of(context).accentTextTheme.body2.color,
119 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
120 fontWeight: FontWeight.w700,
121 ),
122 recognizer: TapGestureRecognizer()
lib/src/screens/ionia/auth/ionia_login_page.dart
+3 -3
@@ -33,7 +33,7 @@ class IoniaLoginPage extends BasePage {
33 return Text(
34 S.current.login,
35 style: textMediumSemiBold(
36 - color: Theme.of(context).accentTextTheme.display4.backgroundColor,
36 + color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
37 ),
38 );
39 }
@@ -69,13 +69,13 @@ class IoniaLoginPage extends BasePage {
69 builder: (_) => LoadingPrimaryButton(
70 text: S.of(context).login,
71 onPressed: () async {
72 - if (!_formKey.currentState.validate()) {
72 + if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
73 return;
74 }
75 await _authViewModel.signIn(_emailController.text);
76 },
77 isLoading: _authViewModel.signInState is IoniaCreateStateLoading,
78 - color: Theme.of(context).accentTextTheme.body2.color,
78 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
79 textColor: Colors.white,
80 ),
81 ),
lib/src/screens/ionia/auth/ionia_verify_otp_page.dart
+3 -3
@@ -41,7 +41,7 @@ class IoniaVerifyIoniaOtp extends BasePage {
41 return Text(
42 S.current.verification,
43 style: textMediumSemiBold(
44 - color: Theme.of(context).accentTextTheme.display4.backgroundColor,
44 + color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
45 ),
46 );
47 }
@@ -62,7 +62,7 @@ class IoniaVerifyIoniaOtp extends BasePage {
62 return KeyboardActions(
63 config: KeyboardActionsConfig(
64 keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
65 - keyboardBarColor: Theme.of(context).accentTextTheme.body2.backgroundColor,
65 + keyboardBarColor: Theme.of(context).accentTextTheme!.bodyText1!.backgroundColor!,
66 nextFocus: false,
67 actions: [
68 KeyboardActionsItem(
@@ -119,7 +119,7 @@ class IoniaVerifyIoniaOtp extends BasePage {
119 onPressed: () async => await _authViewModel.verifyEmail(_codeController.text),
120 isDisabled: _authViewModel.otpState is IoniaOtpSendDisabled,
121 isLoading: _authViewModel.otpState is IoniaOtpValidating,
122 - color: Theme.of(context).accentTextTheme.body2.color,
122 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
123 textColor: Colors.white,
124 ),
125 ),
lib/src/screens/ionia/auth/ionia_welcome_page.dart
+5 -5
@@ -17,7 +17,7 @@ class IoniaWelcomePage extends BasePage {
17 return Text(
18 S.current.welcome_to_cakepay,
19 style: textMediumSemiBold(
20 - color: Theme.of(context).accentTextTheme.display4.backgroundColor,
20 + color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
21 ),
22 );
23 }
@@ -45,7 +45,7 @@ class IoniaWelcomePage extends BasePage {
45 fontSize: 18,
46 fontWeight: FontWeight.w400,
47 fontFamily: 'Lato',
48 - color: Theme.of(context).primaryTextTheme.title.color,
48 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
49 ),
50 ),
51 SizedBox(height: 20),
@@ -55,7 +55,7 @@ class IoniaWelcomePage extends BasePage {
55 fontSize: 18,
56 fontWeight: FontWeight.w400,
57 fontFamily: 'Lato',
58 - color: Theme.of(context).primaryTextTheme.title.color,
58 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
59 ),
60 ),
61 ],
@@ -66,7 +66,7 @@ class IoniaWelcomePage extends BasePage {
66 PrimaryButton(
67 text: S.of(context).create_account,
68 onPressed: () => Navigator.of(context).pushNamed(Routes.ioniaCreateAccountPage),
69 - color: Theme.of(context).accentTextTheme.body2.color,
69 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
70 textColor: Colors.white,
71 ),
72 SizedBox(
@@ -78,7 +78,7 @@ class IoniaWelcomePage extends BasePage {
78 fontSize: 15,
79 fontWeight: FontWeight.w500,
80 fontFamily: 'Lato',
81 - color: Theme.of(context).primaryTextTheme.title.color,
81 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
82 ),
83 ),
84 SizedBox(height: 8),
lib/src/screens/ionia/cards/ionia_account_cards_page.dart
+19 -17
@@ -20,7 +20,7 @@ class IoniaAccountCardsPage extends BasePage {
20 return Text(
21 S.of(context).cards,
22 style: textLargeSemiBold(
23 - color: Theme.of(context).accentTextTheme.display4.backgroundColor,
23 + color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
24 ),
25 );
26 }
@@ -41,7 +41,9 @@ class _IoniaCardTabs extends StatefulWidget {
41 }
42
43 class _IoniaCardTabsState extends State<_IoniaCardTabs> with SingleTickerProviderStateMixin {
44 - TabController _tabController;
44 + _IoniaCardTabsState();
45 +
46 + TabController? _tabController;
47
48 @override
49 void initState() {
@@ -52,7 +54,7 @@ class _IoniaCardTabsState extends State<_IoniaCardTabs> with SingleTickerProvide
54 @override
55 void dispose() {
56 super.dispose();
55 - _tabController.dispose();
57 + _tabController?.dispose();
58 }
59
60 @override
@@ -67,23 +69,23 @@ class _IoniaCardTabsState extends State<_IoniaCardTabs> with SingleTickerProvide
69 width: 230,
70 padding: EdgeInsets.all(5),
71 decoration: BoxDecoration(
70 - color: Theme.of(context).accentTextTheme.display4.backgroundColor.withOpacity(0.1),
72 + color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!.withOpacity(0.1),
73 borderRadius: BorderRadius.circular(
74 25.0,
75 ),
76 ),
77 child: Theme(
76 - data: ThemeData(primaryTextTheme: TextTheme(body2: TextStyle(backgroundColor: Colors.transparent))),
78 + data: ThemeData(primaryTextTheme: TextTheme(bodyText1: TextStyle(backgroundColor: Colors.transparent))),
79 child: TabBar(
80 controller: _tabController,
81 indicator: BoxDecoration(
82 borderRadius: BorderRadius.circular(
83 25.0,
84 ),
83 - color: Theme.of(context).accentTextTheme.body2.color,
85 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
86 ),
85 - labelColor: Theme.of(context).primaryTextTheme.display4.backgroundColor,
86 - unselectedLabelColor: Theme.of(context).primaryTextTheme.title.color,
87 + labelColor: Theme.of(context).primaryTextTheme!.headline1!.backgroundColor!,
88 + unselectedLabelColor: Theme.of(context).primaryTextTheme!.headline6!.color!,
89 tabs: [
90 Tab(
91 text: S.of(context).active,
@@ -136,10 +138,10 @@ class _IoniaCardTabsState extends State<_IoniaCardTabs> with SingleTickerProvide
138
139 class _IoniaCardListView extends StatelessWidget {
140 _IoniaCardListView({
139 - Key key,
140 - @required this.emptyText,
141 - @required this.merchList,
142 - @required this.onTap,
141 + Key? key,
142 + required this.emptyText,
143 + required this.merchList,
144 + required this.onTap,
145 this.isLoading = false,
146 }) : super(key: key);
147
@@ -153,8 +155,8 @@ class _IoniaCardListView extends StatelessWidget {
155 if(isLoading){
156 return Center(
157 child: CircularProgressIndicator(
156 - backgroundColor: Theme.of(context).accentTextTheme.display3.backgroundColor,
157 - valueColor: AlwaysStoppedAnimation<Color>(Theme.of(context).primaryTextTheme.body1.color),
158 + backgroundColor: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
159 + valueColor: AlwaysStoppedAnimation<Color>(Theme.of(context).primaryTextTheme!.bodyText2!.color!),
160 ),
161 );
162 }
@@ -164,7 +166,7 @@ class _IoniaCardListView extends StatelessWidget {
166 emptyText,
167 textAlign: TextAlign.center,
168 style: textSmall(
167 - color: Theme.of(context).primaryTextTheme.overline.color,
169 + color: Theme.of(context).primaryTextTheme!.overline!.color!,
170 ),
171 ),
172 )
@@ -177,11 +179,11 @@ class _IoniaCardListView extends StatelessWidget {
179 child: CardItem(
180 onTap: () => onTap?.call(merchant),
181 title: merchant.legalName,
180 - backgroundColor: Theme.of(context).accentTextTheme.display4.backgroundColor.withOpacity(0.1),
182 + backgroundColor: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!.withOpacity(0.1),
183 discount: 0,
184 hideBorder: true,
185 discountBackground: AssetImage('assets/images/red_badge_discount.png'),
184 - titleColor: Theme.of(context).accentTextTheme.display4.backgroundColor,
186 + titleColor: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
187 subtitleColor: Theme.of(context).hintColor,
188 subTitle: '',
189 logoUrl: merchant.logoUrl,
lib/src/screens/ionia/cards/ionia_account_page.dart
+9 -14
@@ -19,7 +19,7 @@ class IoniaAccountPage extends BasePage {
19 return Text(
20 S.current.account,
21 style: textMediumSemiBold(
22 - color: Theme.of(context).accentTextTheme.display4.backgroundColor,
22 + color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
23 ),
24 );
25 }
@@ -133,7 +133,7 @@ class IoniaAccountPage extends BasePage {
133 bottomSection: Column(
134 children: [
135 PrimaryButton(
136 - color: Theme.of(context).accentTextTheme.body2.color,
136 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
137 textColor: Colors.white,
138 text: S.of(context).logout,
139 onPressed: () {
@@ -149,31 +149,26 @@ class IoniaAccountPage extends BasePage {
149
150 class _GradiantContainer extends StatelessWidget {
151 const _GradiantContainer({
152 - Key key,
153 - @required this.content,
154 - this.padding,
155 - this.width,
152 + Key? key,
153 + required this.content,
154 }) : super(key: key);
155
156 final Widget content;
159 - final EdgeInsets padding;
160 - final double width;
157
158 @override
159 Widget build(BuildContext context) {
160 return Container(
161 child: content,
166 - width: width,
167 - padding: padding ?? EdgeInsets.all(24),
162 + padding: EdgeInsets.all(24),
163 decoration: BoxDecoration(
164 borderRadius: BorderRadius.circular(15),
165 gradient: LinearGradient(
166 colors: [
167 Theme.of(context)
173 - .primaryTextTheme
174 - .subhead
175 - .decorationColor,
176 - Theme.of(context).primaryTextTheme.subhead.color,
168 + .primaryTextTheme!
169 + .subtitle1!
170 + .decorationColor!,
171 + Theme.of(context).primaryTextTheme!.subtitle1!.color!,
172 ],
173 begin: Alignment.topRight,
174 end: Alignment.bottomLeft,
lib/src/screens/ionia/cards/ionia_activate_debit_card_page.dart
+2 -2
@@ -23,7 +23,7 @@ class IoniaActivateDebitCardPage extends BasePage {
23 return Text(
24 S.current.debit_card,
25 style: textMediumSemiBold(
26 - color: Theme.of(context).accentTextTheme.display4.backgroundColor,
26 + color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
27 ),
28 );
29 }
@@ -76,7 +76,7 @@ class IoniaActivateDebitCardPage extends BasePage {
76 },
77 isLoading: _cardsListViewModel.createCardState is IoniaCreateCardLoading,
78 text: S.of(context).agree_and_continue,
79 - color: Theme.of(context).accentTextTheme.body2.color,
79 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
80 textColor: Colors.white,
81 ),
82 );
lib/src/screens/ionia/cards/ionia_buy_card_detail_page.dart
+42 -39
@@ -1,4 +1,3 @@
1 -import 'dart:ui';
1 import 'package:cake_wallet/core/execution_state.dart';
2 import 'package:cake_wallet/ionia/ionia_merchant.dart';
3 import 'package:cake_wallet/ionia/ionia_tip.dart';
@@ -29,12 +28,12 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
28 Widget middle(BuildContext context) {
29 return Text(
30 ioniaPurchaseViewModel.ioniaMerchant.legalName,
32 - style: textMediumSemiBold(color: Theme.of(context).accentTextTheme.display4.backgroundColor),
31 + style: textMediumSemiBold(color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!),
32 );
33 }
34
35 @override
37 - Widget trailing(BuildContext context)
36 + Widget? trailing(BuildContext context)
37 => ioniaPurchaseViewModel.ioniaMerchant.discount > 0
38 ? DiscountBadge(percentage: ioniaPurchaseViewModel.ioniaMerchant.discount)
39 : null;
@@ -97,8 +96,8 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
96 borderRadius: BorderRadius.circular(20),
97 gradient: LinearGradient(
98 colors: [
100 - Theme.of(context).primaryTextTheme.subhead.color,
101 - Theme.of(context).primaryTextTheme.subhead.decorationColor,
99 + Theme.of(context).primaryTextTheme!.subtitle1!.color!,
100 + Theme.of(context).primaryTextTheme!.subtitle1!.decorationColor!,
101 ],
102 begin: Alignment.topLeft,
103 end: Alignment.bottomRight,
@@ -164,7 +163,7 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
163 Text(
164 S.of(context).tip,
165 style: TextStyle(
167 - color: Theme.of(context).primaryTextTheme.title.color,
166 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
167 fontWeight: FontWeight.w700,
168 fontSize: 14,
169 ),
@@ -172,7 +171,7 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
171 SizedBox(height: 4),
172 Observer(
173 builder: (_) => TipButtonGroup(
175 - selectedTip: ioniaPurchaseViewModel.selectedTip.percentage,
174 + selectedTip: ioniaPurchaseViewModel.selectedTip!.percentage,
175 tipsList: ioniaPurchaseViewModel.tips,
176 onSelect: (value) => ioniaPurchaseViewModel.addTip(value),
177 amount: ioniaPurchaseViewModel.amount,
@@ -203,7 +202,7 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
202 ioniaPurchaseViewModel.invoiceCommittingState is IsExecutingState,
203 onPressed: () => purchaseCard(context),
204 text: S.of(context).purchase_gift_card,
206 - color: Theme.of(context).accentTextTheme.body2.color,
205 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
206 textColor: Colors.white,
207 );
208 }),
@@ -213,7 +212,7 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
212 onTap: () => _showTermsAndCondition(context),
213 child: Text(S.of(context).settings_terms_and_conditions,
214 style: textMediumSemiBold(
216 - color: Theme.of(context).primaryTextTheme.body1.color,
215 + color: Theme.of(context).primaryTextTheme!.bodyText2!.color!,
216 ).copyWith(fontSize: 12)),
217 ),
218 SizedBox(height: 16)
@@ -233,7 +232,7 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
232 child: Text(
233 ioniaPurchaseViewModel.ioniaMerchant.termsAndConditions,
234 style: textMedium(
236 - color: Theme.of(context).textTheme.display2.color,
235 + color: Theme.of(context).textTheme!.headline3!.color!,
236 ),
237 ),
238 ),
@@ -271,13 +270,13 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
270 child: Text(
271 instruction.header,
272 style: textLargeSemiBold(
274 - color: Theme.of(context).textTheme.display2.color,
273 + color: Theme.of(context).textTheme!.headline3!.color!,
274 ),
275 )),
276 Text(
277 instruction.body,
278 style: textMedium(
280 - color: Theme.of(context).textTheme.display2.color,
279 + color: Theme.of(context).textTheme!.headline3!.color!,
280 ),
281 )
282 ];
@@ -290,8 +289,12 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
289 }
290
291 Future<void> _presentSuccessfulInvoiceCreationPopup(BuildContext context) async {
293 - final amount = ioniaPurchaseViewModel.invoice.totalAmount;
294 - final addresses = ioniaPurchaseViewModel.invoice.outAddresses;
292 + if (ioniaPurchaseViewModel.invoice == null) {
293 + return;
294 + }
295 +
296 + final amount = ioniaPurchaseViewModel.invoice!.totalAmount;
297 + final addresses = ioniaPurchaseViewModel.invoice!.outAddresses;
298
299 await showPopUp<void>(
300 context: context,
@@ -310,7 +313,7 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
313 fontWeight: FontWeight.w400,
314 color: PaletteDark.pigeonBlue,
315 decoration: TextDecoration.none)),
313 - Text(ioniaPurchaseViewModel.invoice.paymentId,
316 + Text(ioniaPurchaseViewModel.invoice!.paymentId,
317 style: TextStyle(
318 fontSize: 16,
319 fontWeight: FontWeight.w400,
@@ -326,7 +329,7 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
329 fontWeight: FontWeight.w400,
330 color: PaletteDark.pigeonBlue,
331 decoration: TextDecoration.none)),
329 - Text('$amount ${ioniaPurchaseViewModel.invoice.chain}',
332 + Text('$amount ${ioniaPurchaseViewModel.invoice!.chain}',
333 style: TextStyle(
334 fontSize: 16,
335 fontWeight: FontWeight.w400,
@@ -358,7 +361,7 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
361 rightButtonText: S.of(context).ok,
362 leftButtonText: S.of(context).cancel,
363 leftActionColor: Color(0xffFF6600),
361 - rightActionColor: Theme.of(context).accentTextTheme.body2.color,
364 + rightActionColor: Theme.of(context).accentTextTheme!.bodyText1!.color!,
365 actionRightButton: () async {
366 Navigator.of(context).pop();
367 await ioniaPurchaseViewModel.commitPaymentInvoice();
@@ -371,12 +374,12 @@ class IoniaBuyGiftCardDetailPage extends BasePage {
374
375 class TipButtonGroup extends StatelessWidget {
376 const TipButtonGroup({
374 - Key key,
375 - @required this.selectedTip,
376 - @required this.onSelect,
377 - @required this.tipsList,
378 - @required this.amount,
379 - @required this.merchant,
377 + Key? key,
378 + required this.selectedTip,
379 + required this.onSelect,
380 + required this.tipsList,
381 + required this.amount,
382 + required this.merchant,
383 }) : super(key: key);
384
385 final Function(IoniaTip) onSelect;
@@ -405,7 +408,7 @@ class TipButtonGroup extends StatelessWidget {
408 onTap: () async {
409 IoniaTip ioniaTip = tip;
410 if(tip.isCustom){
408 - final customTip = await Navigator.pushNamed(context, Routes.ioniaCustomTipPage, arguments: [amount, merchant, tip]) as IoniaTip;
411 + final customTip = await Navigator.pushNamed(context, Routes.ioniaCustomTipPage, arguments: [amount, merchant, tip]) as IoniaTip?;
412 ioniaTip = customTip ?? tip;
413 }
414 onSelect(ioniaTip);
@@ -419,14 +422,14 @@ class TipButtonGroup extends StatelessWidget {
422
423 class TipButton extends StatelessWidget {
424 const TipButton({
422 - @required this.caption,
425 + required this.caption,
426 + required this.onTap,
427 this.subTitle,
424 - @required this.onTap,
428 this.isSelected = false,
429 });
430
431 final String caption;
429 - final String subTitle;
432 + final String? subTitle;
433 final bool isSelected;
434 final void Function() onTap;
435
@@ -434,34 +437,34 @@ class TipButton extends StatelessWidget {
437
438 Color captionTextColor(BuildContext context) {
439 if (isDark(context)) {
437 - return Theme.of(context).primaryTextTheme.title.color;
440 + return Theme.of(context).primaryTextTheme!.headline6!.color!;
441 }
442
443 return isSelected
441 - ? Theme.of(context).accentTextTheme.title.color
442 - : Theme.of(context).primaryTextTheme.title.color;
444 + ? Theme.of(context).accentTextTheme!.headline6!.color!
445 + : Theme.of(context).primaryTextTheme!.headline6!.color!;
446 }
447
448 Color subTitleTextColor(BuildContext context) {
449 if (isDark(context)) {
447 - return Theme.of(context).primaryTextTheme.title.color;
450 + return Theme.of(context).primaryTextTheme!.headline6!.color!;
451 }
452
453 return isSelected
451 - ? Theme.of(context).accentTextTheme.title.color
452 - : Theme.of(context).primaryTextTheme.overline.color;
454 + ? Theme.of(context).accentTextTheme!.headline6!.color!
455 + : Theme.of(context).primaryTextTheme!.overline!.color!;
456 }
457
455 - Color backgroundColor(BuildContext context) {
458 + Color? backgroundColor(BuildContext context) {
459 if (isDark(context)) {
460 return isSelected
461 ? null
459 - : Theme.of(context).accentTextTheme.display4.backgroundColor.withOpacity(0.01);
462 + : Theme.of(context).accentTextTheme!.headline1!.backgroundColor!.withOpacity(0.01);
463 }
464
465 return isSelected
466 ? null
464 - : Theme.of(context).accentTextTheme.display4.backgroundColor.withOpacity(0.1);
467 + : Theme.of(context).accentTextTheme!.headline1!.backgroundColor!.withOpacity(0.1);
468 }
469
470 @override
@@ -479,7 +482,7 @@ class TipButton extends StatelessWidget {
482 if (subTitle != null) ...[
483 SizedBox(height: 4),
484 Text(
482 - subTitle,
485 + subTitle!,
486 style: textXxSmallSemiBold(
487 color: subTitleTextColor(context),
488 ),
@@ -494,8 +497,8 @@ class TipButton extends StatelessWidget {
497 gradient: isSelected
498 ? LinearGradient(
499 colors: [
497 - Theme.of(context).primaryTextTheme.subhead.color,
498 - Theme.of(context).primaryTextTheme.subhead.decorationColor,
500 + Theme.of(context).primaryTextTheme!.subtitle1!.color!,
501 + Theme.of(context).primaryTextTheme!.subtitle1!.decorationColor!,
502 ],
503 begin: Alignment.topLeft,
504 end: Alignment.bottomRight,
lib/src/screens/ionia/cards/ionia_buy_gift_card.dart
+11 -11
@@ -50,7 +50,7 @@ class IoniaBuyGiftCardPage extends BasePage {
50 disableScroll: true,
51 config: KeyboardActionsConfig(
52 keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
53 - keyboardBarColor: Theme.of(context).accentTextTheme.body2.backgroundColor,
53 + keyboardBarColor: Theme.of(context).accentTextTheme!.bodyText1!.backgroundColor!,
54 nextFocus: false,
55 actions: [
56 KeyboardActionsItem(
@@ -69,8 +69,8 @@ class IoniaBuyGiftCardPage extends BasePage {
69 decoration: BoxDecoration(
70 borderRadius: BorderRadius.only(bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
71 gradient: LinearGradient(colors: [
72 - Theme.of(context).primaryTextTheme.subhead.color,
73 - Theme.of(context).primaryTextTheme.subhead.decorationColor,
72 + Theme.of(context).primaryTextTheme!.subtitle1!.color!,
73 + Theme.of(context).primaryTextTheme!.subtitle1!.decorationColor!,
74 ], begin: Alignment.topLeft, end: Alignment.bottomRight),
75 ),
76 child: Column(
@@ -85,14 +85,14 @@ class IoniaBuyGiftCardPage extends BasePage {
85 keyboardType: TextInputType.numberWithOptions(signed: false, decimal: true),
86 inputFormatters: [
87 FilteringTextInputFormatter.deny(RegExp('[\-|\ ]')),
88 - WhitelistingTextInputFormatter(RegExp(r'^\d+(\.|\,)?\d{0,2}'))],
88 + FilteringTextInputFormatter.allow(RegExp(r'^\d+(\.|\,)?\d{0,2}'))],
89 hintText: '1000',
90 placeholderTextStyle: TextStyle(
91 - color: Theme.of(context).primaryTextTheme.headline.color,
91 + color: Theme.of(context).primaryTextTheme!.headline5!.color!,
92 fontWeight: FontWeight.w600,
93 fontSize: 36,
94 ),
95 - borderColor: Theme.of(context).primaryTextTheme.headline.color,
95 + borderColor: Theme.of(context).primaryTextTheme!.headline5!.color!,
96 textColor: Colors.white,
97 textStyle: TextStyle(
98 color: Colors.white,
@@ -121,13 +121,13 @@ class IoniaBuyGiftCardPage extends BasePage {
121 Text(
122 S.of(context).min_amount(merchant.minimumCardPurchase.toStringAsFixed(2)),
123 style: TextStyle(
124 - color: Theme.of(context).primaryTextTheme.headline.color,
124 + color: Theme.of(context).primaryTextTheme!.headline5!.color!,
125 ),
126 ),
127 Text(
128 S.of(context).max_amount(merchant.maximumCardPurchase.toStringAsFixed(2)),
129 style: TextStyle(
130 - color: Theme.of(context).primaryTextTheme.headline.color,
130 + color: Theme.of(context).primaryTextTheme!.headline5!.color!,
131 ),
132 ),
133 ],
@@ -140,9 +140,9 @@ class IoniaBuyGiftCardPage extends BasePage {
140 padding: const EdgeInsets.all(24.0),
141 child: CardItem(
142 title: merchant.legalName,
143 - backgroundColor: Theme.of(context).accentTextTheme.display4.backgroundColor.withOpacity(0.1),
143 + backgroundColor: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!.withOpacity(0.1),
144 discount: merchant.discount,
145 - titleColor: Theme.of(context).accentTextTheme.display4.backgroundColor,
145 + titleColor: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
146 subtitleColor: Theme.of(context).hintColor,
147 subTitle: merchant.avaibilityStatus,
148 logoUrl: merchant.logoUrl,
@@ -165,7 +165,7 @@ class IoniaBuyGiftCardPage extends BasePage {
165 ),
166 text: S.of(context).continue_text,
167 isDisabled: !ioniaBuyCardViewModel.isEnablePurchase,
168 - color: Theme.of(context).accentTextTheme.body2.color,
168 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
169 textColor: Colors.white,
170 ),
171 );
lib/src/screens/ionia/cards/ionia_custom_redeem_page.dart
+9 -9
@@ -50,7 +50,7 @@ class IoniaCustomRedeemPage extends BasePage {
50 disableScroll: true,
51 config: KeyboardActionsConfig(
52 keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
53 - keyboardBarColor: Theme.of(context).accentTextTheme.body2.backgroundColor,
53 + keyboardBarColor: Theme.of(context).accentTextTheme!.bodyText1!.backgroundColor!,
54 nextFocus: false,
55 actions: [
56 KeyboardActionsItem(
@@ -69,8 +69,8 @@ class IoniaCustomRedeemPage extends BasePage {
69 decoration: BoxDecoration(
70 borderRadius: BorderRadius.only(bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
71 gradient: LinearGradient(colors: [
72 - Theme.of(context).primaryTextTheme.subhead.color,
73 - Theme.of(context).primaryTextTheme.subhead.decorationColor,
72 + Theme.of(context).primaryTextTheme!.subtitle1!.color!,
73 + Theme.of(context).primaryTextTheme!.subtitle1!.decorationColor!,
74 ], begin: Alignment.topLeft, end: Alignment.bottomRight),
75 ),
76 child: Column(
@@ -85,11 +85,11 @@ class IoniaCustomRedeemPage extends BasePage {
85 inputFormatters: [FilteringTextInputFormatter.deny(RegExp('[\-|\ ]'))],
86 hintText: '1000',
87 placeholderTextStyle: TextStyle(
88 - color: Theme.of(context).primaryTextTheme.headline.color,
88 + color: Theme.of(context).primaryTextTheme!.headline5!.color!,
89 fontWeight: FontWeight.w500,
90 fontSize: 36,
91 ),
92 - borderColor: Theme.of(context).primaryTextTheme.headline.color,
92 + borderColor: Theme.of(context).primaryTextTheme!.headline5!.color!,
93 textColor: Colors.white,
94 textStyle: TextStyle(
95 color: Colors.white,
@@ -119,7 +119,7 @@ class IoniaCustomRedeemPage extends BasePage {
119 Center(
120 child: Text('\$${giftCard.remainingAmount} - \$${ioniaCustomRedeemViewModel.amount} = \$${ioniaCustomRedeemViewModel.formattedRemaining} ${S.of(context).remaining}',
121 style: TextStyle(
122 - color: Theme.of(context).primaryTextTheme.headline.color,
122 + color: Theme.of(context).primaryTextTheme!.headline5!.color!,
123 ),),
124 ) : SizedBox.shrink(),
125 ),
@@ -131,11 +131,11 @@ class IoniaCustomRedeemPage extends BasePage {
131 padding: const EdgeInsets.all(24.0),
132 child: CardItem(
133 title: giftCard.legalName,
134 - backgroundColor: Theme.of(context).accentTextTheme.display4.backgroundColor.withOpacity(0.1),
134 + backgroundColor: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!.withOpacity(0.1),
135 discount: giftCard.remainingAmount,
136 isAmount: true,
137 discountBackground: AssetImage('assets/images/red_badge_discount.png'),
138 - titleColor: Theme.of(context).accentTextTheme.display4.backgroundColor,
138 + titleColor: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
139 subtitleColor: Theme.of(context).hintColor,
140 subTitle: S.of(context).online,
141 logoUrl: giftCard.logoUrl,
@@ -153,7 +153,7 @@ class IoniaCustomRedeemPage extends BasePage {
153 },
154 isDisabled: ioniaCustomRedeemViewModel.disableRedeem,
155 text: S.of(context).add_custom_redemption,
156 - color: Theme.of(context).accentTextTheme.body2.color,
156 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
157 textColor: Colors.white,
158 ),
159 ),
lib/src/screens/ionia/cards/ionia_custom_tip_page.dart
+9 -9
@@ -51,7 +51,7 @@ class IoniaCustomTipPage extends BasePage {
51 disableScroll: true,
52 config: KeyboardActionsConfig(
53 keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
54 - keyboardBarColor: Theme.of(context).accentTextTheme.body2.backgroundColor,
54 + keyboardBarColor: Theme.of(context).accentTextTheme!.bodyText1!.backgroundColor!,
55 nextFocus: false,
56 actions: [
57 KeyboardActionsItem(
@@ -70,8 +70,8 @@ class IoniaCustomTipPage extends BasePage {
70 decoration: BoxDecoration(
71 borderRadius: BorderRadius.only(bottomLeft: Radius.circular(24), bottomRight: Radius.circular(24)),
72 gradient: LinearGradient(colors: [
73 - Theme.of(context).primaryTextTheme.subhead.color,
74 - Theme.of(context).primaryTextTheme.subhead.decorationColor,
73 + Theme.of(context).primaryTextTheme!.subtitle1!.color!,
74 + Theme.of(context).primaryTextTheme!.subtitle1!.decorationColor!,
75 ], begin: Alignment.topLeft, end: Alignment.bottomRight),
76 ),
77 child: Column(
@@ -86,11 +86,11 @@ class IoniaCustomTipPage extends BasePage {
86 inputFormatters: [FilteringTextInputFormatter.deny(RegExp('[\-|\ ]'))],
87 hintText: '1000',
88 placeholderTextStyle: TextStyle(
89 - color: Theme.of(context).primaryTextTheme.headline.color,
89 + color: Theme.of(context).primaryTextTheme!.headline5!.color!,
90 fontWeight: FontWeight.w500,
91 fontSize: 36,
92 ),
93 - borderColor: Theme.of(context).primaryTextTheme.headline.color,
93 + borderColor: Theme.of(context).primaryTextTheme!.headline5!.color!,
94 textColor: Colors.white,
95 textStyle: TextStyle(
96 color: Colors.white,
@@ -125,7 +125,7 @@ class IoniaCustomTipPage extends BasePage {
125 text: TextSpan(
126 text: '\$${_amountController.text}',
127 style: TextStyle(
128 - color: Theme.of(context).primaryTextTheme.headline.color,
128 + color: Theme.of(context).primaryTextTheme!.headline5!.color!,
129 ),
130 children: [
131 TextSpan(text: ' ${S.of(context).is_percentage} '),
@@ -143,9 +143,9 @@ class IoniaCustomTipPage extends BasePage {
143 padding: const EdgeInsets.all(24.0),
144 child: CardItem(
145 title: merchant.legalName,
146 - backgroundColor: Theme.of(context).accentTextTheme.display4.backgroundColor.withOpacity(0.1),
146 + backgroundColor: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!.withOpacity(0.1),
147 discount: 0.0,
148 - titleColor: Theme.of(context).accentTextTheme.display4.backgroundColor,
148 + titleColor: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
149 subtitleColor: Theme.of(context).hintColor,
150 subTitle: merchant.isOnline ? S.of(context).online : S.of(context).offline,
151 logoUrl: merchant.logoUrl,
@@ -162,7 +162,7 @@ class IoniaCustomTipPage extends BasePage {
162 Navigator.of(context).pop(customTipViewModel.customTip);
163 },
164 text: S.of(context).add_tip,
165 - color: Theme.of(context).accentTextTheme.body2.color,
165 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
166 textColor: Colors.white,
167 ),
168 ),
lib/src/screens/ionia/cards/ionia_debit_card_page.dart
+30 -28
@@ -23,7 +23,7 @@ class IoniaDebitCardPage extends BasePage {
23 return Text(
24 S.current.debit_card,
25 style: textMediumSemiBold(
26 - color: Theme.of(context).accentTextTheme.display4.backgroundColor,
26 + color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
27 ),
28 );
29 }
@@ -51,7 +51,7 @@ class IoniaDebitCardPage extends BasePage {
51 padding: const EdgeInsets.symmetric(horizontal: 20.0),
52 child: Text(
53 S.of(context).billing_address_info,
54 - style: textSmall(color: Theme.of(context).textTheme.display1.color),
54 + style: textSmall(color: Theme.of(context).textTheme!.headline4!.color!),
55 textAlign: TextAlign.center,
56 ),
57 ),
@@ -60,13 +60,13 @@ class IoniaDebitCardPage extends BasePage {
60 text: S.of(context).order_physical_card,
61 onPressed: () {},
62 color: Color(0xffE9F2FC),
63 - textColor: Theme.of(context).textTheme.display2.color,
63 + textColor: Theme.of(context).textTheme!.headline3!.color!,
64 ),
65 SizedBox(height: 8),
66 PrimaryButton(
67 text: S.of(context).add_value,
68 onPressed: () {},
69 - color: Theme.of(context).accentTextTheme.body2.color,
69 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
70 textColor: Colors.white,
71 ),
72 SizedBox(height: 16)
@@ -112,11 +112,11 @@ class IoniaDebitCardPage extends BasePage {
112 child: RichText(
113 text: TextSpan(
114 text: S.of(context).get_a,
115 - style: textMedium(color: Theme.of(context).textTheme.display2.color),
115 + style: textMedium(color: Theme.of(context).textTheme!.headline3!.color!),
116 children: [
117 TextSpan(
118 text: S.of(context).digital_and_physical_card,
119 - style: textMediumBold(color: Theme.of(context).textTheme.display2.color),
119 + style: textMediumBold(color: Theme.of(context).textTheme!.headline3!.color!),
120 ),
121 TextSpan(
122 text: S.of(context).get_card_note,
@@ -134,7 +134,7 @@ class IoniaDebitCardPage extends BasePage {
134 bottomSection: PrimaryButton(
135 text: S.of(context).activate,
136 onPressed: () => _showHowToUseCard(context, activate: true),
137 - color: Theme.of(context).accentTextTheme.body2.color,
137 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
138 textColor: Colors.white,
139 ),
140 );
@@ -165,7 +165,7 @@ class IoniaDebitCardPage extends BasePage {
165 Text(
166 S.of(context).how_to_use_card,
167 style: textLargeSemiBold(
168 - color: Theme.of(context).textTheme.body1.color,
168 + color: Theme.of(context).textTheme!.bodyText2!.color!,
169 ),
170 ),
171 SizedBox(height: 24),
@@ -174,7 +174,7 @@ class IoniaDebitCardPage extends BasePage {
174 child: Text(
175 S.of(context).signup_for_card_accept_terms,
176 style: textSmallSemiBold(
177 - color: Theme.of(context).textTheme.display2.color,
177 + color: Theme.of(context).textTheme!.headline3!.color!,
178 ),
179 ),
180 ),
@@ -195,7 +195,7 @@ class IoniaDebitCardPage extends BasePage {
195 : Navigator.pop(context),
196 text: S.of(context).send_got_it,
197 color: Color.fromRGBO(233, 242, 252, 1),
198 - textColor: Theme.of(context).textTheme.display2.color,
198 + textColor: Theme.of(context).textTheme!.headline3!.color!,
199 ),
200 SizedBox(height: 21),
201 ],
@@ -223,14 +223,15 @@ class IoniaDebitCardPage extends BasePage {
223 }
224
225 class _IoniaDebitCard extends StatefulWidget {
226 - final bool isCardSample;
227 - final IoniaVirtualCard cardInfo;
226 const _IoniaDebitCard({
229 - Key key,
230 - this.isCardSample = false,
227 + Key? key,
228 this.cardInfo,
229 + this.isCardSample = false,
230 }) : super(key: key);
231
232 + final bool isCardSample;
233 + final IoniaVirtualCard? cardInfo;
234 +
235 @override
236 _IoniaDebitCardState createState() => _IoniaDebitCardState();
237 }
@@ -246,9 +247,9 @@ class _IoniaDebitCardState extends State<_IoniaDebitCard> {
247 return pan.replaceAllMapped(RegExp(r'.{4}'), (match) => '${match.group(0)} ');
248 }
249
249 - String get _getLast4 => widget.isCardSample ? '0000' : widget.cardInfo.pan.substring(widget.cardInfo.pan.length - 5);
250 + String get _getLast4 => widget.isCardSample ? '0000' : widget.cardInfo!.pan.substring(widget.cardInfo!.pan.length - 5);
251
251 - String get _getSpendLimit => widget.isCardSample ? '10000' : widget.cardInfo.spendLimit.toStringAsFixed(2);
252 + String get _getSpendLimit => widget.isCardSample ? '10000' : widget.cardInfo!.spendLimit.toStringAsFixed(2);
253
254 @override
255 Widget build(BuildContext context) {
@@ -258,8 +259,8 @@ class _IoniaDebitCardState extends State<_IoniaDebitCard> {
259 borderRadius: BorderRadius.circular(24),
260 gradient: LinearGradient(
261 colors: [
261 - Theme.of(context).primaryTextTheme.subhead.color,
262 - Theme.of(context).primaryTextTheme.subhead.decorationColor,
262 + Theme.of(context).primaryTextTheme!.subtitle1!.color!,
263 + Theme.of(context).primaryTextTheme!.subtitle1!.decorationColor!,
264 ],
265 begin: Alignment.topLeft,
266 end: Alignment.bottomRight,
@@ -289,7 +290,7 @@ class _IoniaDebitCardState extends State<_IoniaDebitCard> {
290 ),
291 SizedBox(height: 16),
292 Text(
292 - _showDetails ? _formatPan(widget.cardInfo.pan) : '**** **** **** $_getLast4',
293 + _showDetails ? _formatPan(widget.cardInfo?.pan ?? '') : '**** **** **** $_getLast4',
294 style: textMediumSemiBold(),
295 ),
296 SizedBox(height: 32),
@@ -310,7 +311,7 @@ class _IoniaDebitCardState extends State<_IoniaDebitCard> {
311 ),
312 SizedBox(height: 4),
313 Text(
313 - _showDetails ? widget.cardInfo.cvv : '***',
314 + _showDetails ? widget.cardInfo!.cvv : '***',
315 style: textMediumSemiBold(),
316 )
317 ],
@@ -324,7 +325,7 @@ class _IoniaDebitCardState extends State<_IoniaDebitCard> {
325 ),
326 SizedBox(height: 4),
327 Text(
327 - '${widget.cardInfo.expirationMonth ?? S.of(context).mm}/${widget.cardInfo.expirationYear ?? S.of(context).yy}',
328 + '${widget.cardInfo?.expirationMonth ?? S.of(context).mm}/${widget.cardInfo?.expirationYear ?? S.of(context).yy}',
329 style: textMediumSemiBold(),
330 )
331 ],
@@ -351,14 +352,15 @@ class _IoniaDebitCardState extends State<_IoniaDebitCard> {
352 }
353
354 class _TitleSubtitleTile extends StatelessWidget {
354 - final String title;
355 - final String subtitle;
355 const _TitleSubtitleTile({
357 - Key key,
358 - @required this.title,
359 - @required this.subtitle,
356 + Key? key,
357 + required this.title,
358 + required this.subtitle,
359 }) : super(key: key);
360
361 + final String title;
362 + final String subtitle;
363 +
364 @override
365 Widget build(BuildContext context) {
366 return Column(
@@ -366,12 +368,12 @@ class _TitleSubtitleTile extends StatelessWidget {
368 children: [
369 Text(
370 title,
369 - style: textSmallSemiBold(color: Theme.of(context).textTheme.display2.color),
371 + style: textSmallSemiBold(color: Theme.of(context).textTheme!.headline3!.color!),
372 ),
373 SizedBox(height: 4),
374 Text(
375 subtitle,
374 - style: textSmall(color: Theme.of(context).textTheme.display2.color),
376 + style: textSmall(color: Theme.of(context).textTheme!.headline3!.color!),
377 ),
378 ],
379 );
lib/src/screens/ionia/cards/ionia_gift_card_detail_page.dart
+15 -18
@@ -5,7 +5,6 @@ import 'package:cake_wallet/src/screens/base_page.dart';
5 import 'package:cake_wallet/src/screens/ionia/widgets/ionia_alert_model.dart';
6 import 'package:cake_wallet/src/screens/ionia/widgets/ionia_tile.dart';
7 import 'package:cake_wallet/src/screens/ionia/widgets/text_icon_button.dart';
8 -import 'package:cake_wallet/src/widgets/alert_background.dart';
8 import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
9 import 'package:cake_wallet/src/widgets/primary_button.dart';
10 import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
@@ -16,7 +15,6 @@ import 'package:cake_wallet/view_model/ionia/ionia_gift_card_details_view_model.
15 import 'package:device_display_brightness/device_display_brightness.dart';
16 import 'package:flutter/material.dart';
17 import 'package:flutter/services.dart';
19 -import 'package:flutter/src/widgets/framework.dart';
18 import 'package:cake_wallet/generated/i18n.dart';
19 import 'package:flutter_mobx/flutter_mobx.dart';
20 import 'package:mobx/mobx.dart';
@@ -26,17 +24,15 @@ class IoniaGiftCardDetailPage extends BasePage {
24
25 final IoniaGiftCardDetailsViewModel viewModel;
26
29 -
30 -
27 @override
32 - Widget leading(BuildContext context) {
33 - if (ModalRoute.of(context).isFirst) {
28 + Widget? leading(BuildContext context) {
29 + if (ModalRoute.of(context)!.isFirst) {
30 return null;
31 }
32
33 final _backButton = Icon(
34 Icons.arrow_back_ios,
39 - color: Theme.of(context).primaryTextTheme.title.color,
35 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
36 size: 16,
37 );
38 return Padding(
@@ -46,10 +42,11 @@ class IoniaGiftCardDetailPage extends BasePage {
42 width: 37,
43 child: ButtonTheme(
44 minWidth: double.minPositive,
49 - child: FlatButton(
50 - highlightColor: Colors.transparent,
51 - splashColor: Colors.transparent,
52 - padding: EdgeInsets.all(0),
45 + child: TextButton(
46 + // FIX-ME: Style
47 + //highlightColor: Colors.transparent,
48 + //splashColor: Colors.transparent,
49 + //padding: EdgeInsets.all(0),
50 onPressed: () {
51 onClose(context);
52 DeviceDisplayBrightness.setBrightness(viewModel.brightness);
@@ -64,7 +61,7 @@ class IoniaGiftCardDetailPage extends BasePage {
61 Widget middle(BuildContext context) {
62 return Text(
63 viewModel.giftCard.legalName,
67 - style: textMediumSemiBold(color: Theme.of(context).accentTextTheme.display4.backgroundColor),
64 + style: textMediumSemiBold(color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!),
65 );
66 }
67
@@ -142,8 +139,8 @@ class IoniaGiftCardDetailPage extends BasePage {
139 // }
140 // },
141 // text: S.of(context).more_options,
145 - // color: Theme.of(context).accentTextTheme.caption.color,
146 - // textColor: Theme.of(context).primaryTextTheme.title.color,
142 + // color: Theme.of(context).accentTextTheme!.caption!.color!,
143 + // textColor: Theme.of(context).primaryTextTheme!.headline6!.color!,
144 //),
145 //SizedBox(height: 12),
146 LoadingPrimaryButton(
@@ -155,7 +152,7 @@ class IoniaGiftCardDetailPage extends BasePage {
152 },
153 ),
154 text: S.of(context).mark_as_redeemed,
158 - color: Theme.of(context).accentTextTheme.body2.color,
155 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
156 textColor: Colors.white,
157 ),
158 ],
@@ -169,7 +166,7 @@ class IoniaGiftCardDetailPage extends BasePage {
166 );
167 }
168
172 - Widget buildIoniaTile(BuildContext context, {@required String title, @required String subTitle}) {
169 + Widget buildIoniaTile(BuildContext context, {required String title, required String subTitle}) {
170 return IoniaTile(
171 title: title,
172 subTitle: subTitle,
@@ -199,13 +196,13 @@ class IoniaGiftCardDetailPage extends BasePage {
196 child: Text(
197 instruction.header,
198 style: textLargeSemiBold(
202 - color: Theme.of(context).textTheme.display2.color,
199 + color: Theme.of(context).textTheme!.headline3!.color!,
200 ),
201 )),
202 Text(
203 instruction.body,
204 style: textMedium(
208 - color: Theme.of(context).textTheme.display2.color,
205 + color: Theme.of(context).textTheme!.headline3!.color!,
206 ),
207 )
208 ];
lib/src/screens/ionia/cards/ionia_manage_cards_page.dart
+31 -30
@@ -69,7 +69,7 @@ class IoniaManageCardsPage extends BasePage {
69 Widget leading(BuildContext context) {
70 final _backButton = Icon(
71 Icons.arrow_back_ios,
72 - color: Theme.of(context).accentTextTheme.display3.backgroundColor,
72 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
73 size: 16,
74 );
75
@@ -78,10 +78,11 @@ class IoniaManageCardsPage extends BasePage {
78 width: 37,
79 child: ButtonTheme(
80 minWidth: double.minPositive,
81 - child: FlatButton(
82 - highlightColor: Colors.transparent,
83 - splashColor: Colors.transparent,
84 - padding: EdgeInsets.all(0),
81 + child: TextButton(
82 + // FIX-ME: Style
83 + //highlightColor: Colors.transparent,
84 + //splashColor: Colors.transparent,
85 + //padding: EdgeInsets.all(0),
86 onPressed: () => Navigator.pop(context),
87 child: _backButton),
88 ),
@@ -93,7 +94,7 @@ class IoniaManageCardsPage extends BasePage {
94 return Text(
95 S.of(context).gift_cards,
96 style: textMediumSemiBold(
96 - color: Theme.of(context).accentTextTheme.display3.backgroundColor,
97 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
98 ),
99 );
100 }
@@ -125,7 +126,7 @@ class IoniaManageCardsPage extends BasePage {
126 ),
127 child: Image.asset(
128 'assets/images/filter.png',
128 - color: Theme.of(context).textTheme.caption.decorationColor,
129 + color: Theme.of(context).textTheme!.caption!.decorationColor!,
130 ),
131 )
132 );
@@ -173,8 +174,8 @@ class IoniaManageCardsPage extends BasePage {
174
175 class IoniaManageCardsPageBody extends StatefulWidget {
176 const IoniaManageCardsPageBody({
176 - Key key,
177 - @required this.cardsListViewModel,
177 + Key? key,
178 + required this.cardsListViewModel,
179 }) : super(key: key);
180
181 final IoniaGiftCardsListViewModel cardsListViewModel;
@@ -224,9 +225,9 @@ class _IoniaManageCardsPageBodyState extends State<IoniaManageCardsPageBody> {
225 },
226 title: merchant.legalName,
227 subTitle: merchant.avaibilityStatus,
227 - backgroundColor: Theme.of(context).textTheme.title.backgroundColor,
228 - titleColor: Theme.of(context).accentTextTheme.display3.backgroundColor,
229 - subtitleColor: Theme.of(context).accentTextTheme.display2.backgroundColor,
228 + backgroundColor: Theme.of(context).textTheme!.headline6!.backgroundColor!,
229 + titleColor: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
230 + subtitleColor: Theme.of(context).accentTextTheme!.headline3!.backgroundColor!,
231 discount: merchant.discount,
232 );
233 },
@@ -237,8 +238,8 @@ class _IoniaManageCardsPageBodyState extends State<IoniaManageCardsPageBody> {
238 thumbHeight: thumbHeight,
239 rightOffset: 1,
240 width: 3,
240 - backgroundColor: Theme.of(context).textTheme.caption.decorationColor.withOpacity(0.05),
241 - thumbColor: Theme.of(context).textTheme.caption.decorationColor.withOpacity(0.5),
241 + backgroundColor: Theme.of(context).textTheme!.caption!.decorationColor!.withOpacity(0.05),
242 + thumbColor: Theme.of(context).textTheme!.caption!.decorationColor!.withOpacity(0.5),
243 fromTop: widget.cardsListViewModel.scrollOffsetFromTop,
244 )
245 : Offstage()
@@ -246,8 +247,8 @@ class _IoniaManageCardsPageBodyState extends State<IoniaManageCardsPageBody> {
247 }
248 return Center(
249 child: CircularProgressIndicator(
249 - backgroundColor: Theme.of(context).accentTextTheme.display3.backgroundColor,
250 - valueColor: AlwaysStoppedAnimation<Color>(Theme.of(context).primaryTextTheme.body1.color),
250 + backgroundColor: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
251 + valueColor: AlwaysStoppedAnimation<Color>(Theme.of(context).primaryTextTheme!.bodyText2!.color!),
252 ),
253 );
254 }
@@ -257,8 +258,8 @@ class _IoniaManageCardsPageBodyState extends State<IoniaManageCardsPageBody> {
258
259 class _SearchWidget extends StatelessWidget {
260 const _SearchWidget({
260 - Key key,
261 - @required this.controller,
261 + Key? key,
262 + required this.controller,
263 }) : super(key: key);
264 final TextEditingController controller;
265
@@ -268,12 +269,12 @@ class _SearchWidget extends StatelessWidget {
269 padding: EdgeInsets.all(8),
270 child: Image.asset(
271 'assets/images/mini_search_icon.png',
271 - color: Theme.of(context).textTheme.caption.decorationColor,
272 + color: Theme.of(context).textTheme!.caption!.decorationColor!,
273 ),
274 );
275
276 return TextField(
276 - style: TextStyle(color: Theme.of(context).accentTextTheme.display3.backgroundColor),
277 + style: TextStyle(color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!),
278 controller: controller,
279 decoration: InputDecoration(
280 filled: true,
@@ -281,10 +282,10 @@ class _SearchWidget extends StatelessWidget {
282 top: 10,
283 left: 10,
284 ),
284 - fillColor: Theme.of(context).textTheme.title.backgroundColor,
285 + fillColor: Theme.of(context).textTheme!.headline6!.backgroundColor!,
286 hintText: S.of(context).search,
287 hintStyle: TextStyle(
287 - color: Theme.of(context).accentTextTheme.display2.backgroundColor,
288 + color: Theme.of(context).accentTextTheme!.headline3!.backgroundColor!,
289 ),
290 alignLabelWithHint: true,
291 floatingLabelBehavior: FloatingLabelBehavior.never,
@@ -310,24 +311,24 @@ class _SearchWidget extends StatelessWidget {
311 }
312
313 class _TrailingIcon extends StatelessWidget {
313 - final String asset;
314 - final VoidCallback onPressed;
314 + const _TrailingIcon({required this.asset, this.onPressed});
315
316 - const _TrailingIcon({this.asset, this.onPressed});
316 + final String asset;
317 + final VoidCallback? onPressed;
318
319 @override
320 Widget build(BuildContext context) {
321 return Container(
322 alignment: Alignment.centerRight,
323 width: 25,
323 - child: FlatButton(
324 - highlightColor: Colors.transparent,
325 - splashColor: Colors.transparent,
326 - padding: EdgeInsets.all(0),
324 + child: TextButton(
325 + //highlightColor: Colors.transparent,
326 + //splashColor: Colors.transparent,
327 + //padding: EdgeInsets.all(0),
328 onPressed: onPressed,
329 child: Image.asset(
330 asset,
330 - color: Theme.of(context).accentTextTheme.display3.backgroundColor,
331 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
332 ),
333 ),
334 );
lib/src/screens/ionia/cards/ionia_more_options_page.dart
+5 -10
@@ -16,7 +16,7 @@ class IoniaMoreOptionsPage extends BasePage {
16 return Text(
17 S.current.more_options,
18 style: textMediumSemiBold(
19 - color: Theme.of(context).accentTextTheme.display4.backgroundColor,
19 + color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!,
20 ),
21 );
22 }
@@ -30,7 +30,7 @@ class IoniaMoreOptionsPage extends BasePage {
30 children: [
31 SizedBox(height: 10,),
32 Center(child: Text(S.of(context).choose_from_available_options, style: textMedium(
33 - color: Theme.of(context).primaryTextTheme.title.color,
33 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
34 ),)),
35 SizedBox(height: 40,),
36 InkWell(
@@ -58,22 +58,17 @@ class IoniaMoreOptionsPage extends BasePage {
58
59 class _GradiantContainer extends StatelessWidget {
60 const _GradiantContainer({
61 - Key key,
62 - @required this.content,
63 - this.padding,
64 - this.width,
61 + Key? key,
62 + required this.content
63 }) : super(key: key);
64
65 final Widget content;
68 - final EdgeInsets padding;
69 - final double width;
66
67 @override
68 Widget build(BuildContext context) {
69 return Container(
70 child: content,
75 - width: width,
76 - padding: padding ?? EdgeInsets.all(24),
71 + padding: EdgeInsets.all(24),
72 decoration: BoxDecoration(
73 borderRadius: BorderRadius.circular(15),
74 gradient: LinearGradient(
lib/src/screens/ionia/cards/ionia_payment_status_page.dart
+14 -14
@@ -23,7 +23,7 @@ class IoniaPaymentStatusPage extends BasePage {
23 S.of(context).generating_gift_card,
24 textAlign: TextAlign.center,
25 style: textMediumSemiBold(
26 - color: Theme.of(context).accentTextTheme.display4.backgroundColor));
26 + color: Theme.of(context).accentTextTheme!.headline1!.backgroundColor!));
27 }
28
29 @override
@@ -42,7 +42,7 @@ class _IoniaPaymentStatusPageBody extends StatefulWidget {
42 }
43
44 class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPageBody> {
45 - ReactionDisposer _onGiftCardReaction;
45 + ReactionDisposer? _onGiftCardReaction;
46
47 @override
48 void initState() {
@@ -53,7 +53,7 @@ class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPage
53 });
54 }
55
56 - _onGiftCardReaction = reaction((_) => widget.viewModel.giftCard, (IoniaGiftCard giftCard) {
56 + _onGiftCardReaction = reaction((_) => widget.viewModel.giftCard, (IoniaGiftCard? giftCard) {
57 WidgetsBinding.instance.addPostFrameCallback((_) {
58 Navigator.of(context)
59 .pushReplacementNamed(Routes.ioniaGiftCardDetailPage, arguments: [giftCard]);
@@ -65,8 +65,8 @@ class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPage
65
66 @override
67 void dispose() {
68 - _onGiftCardReaction?.reaction?.dispose();
69 - widget.viewModel.timer.cancel();
68 + _onGiftCardReaction?.reaction.dispose();
69 + widget.viewModel.timer?.cancel();
70 super.dispose();
71 }
72
@@ -90,7 +90,7 @@ class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPage
90 Text(
91 S.of(context).awaiting_payment_confirmation,
92 style: textLargeSemiBold(
93 - color: Theme.of(context).primaryTextTheme.title.color))
93 + color: Theme.of(context).primaryTextTheme!.headline6!.color!))
94 ]),
95 SizedBox(height: 40),
96 Row(children: [
@@ -129,7 +129,7 @@ class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPage
129 Text(
130 S.of(context).gift_card_is_generated,
131 style: textLargeSemiBold(
132 - color: Theme.of(context).primaryTextTheme.title.color))
132 + color: Theme.of(context).primaryTextTheme!.headline6!.color!))
133 ]));
134 }
135
@@ -147,7 +147,7 @@ class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPage
147 Text(
148 S.of(context).generating_gift_card,
149 style: textLargeSemiBold(
150 - color: Theme.of(context).primaryTextTheme.title.color))]);
150 + color: Theme.of(context).primaryTextTheme!.headline6!.color!))]);
151 }),
152 ],
153 ),
@@ -159,7 +159,7 @@ class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPage
159 child: Text(
160 S.of(context).proceed_after_one_minute,
161 style: textMedium(
162 - color: Theme.of(context).primaryTextTheme.title.color,
162 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
163 ).copyWith(fontWeight: FontWeight.w500),
164 textAlign: TextAlign.center,
165 )),
@@ -171,15 +171,15 @@ class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPage
171 Routes.ioniaGiftCardDetailPage,
172 arguments: [widget.viewModel.giftCard]),
173 text: S.of(context).open_gift_card,
174 - color: Theme.of(context).accentTextTheme.body2.color,
174 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
175 textColor: Colors.white);
176 }
177
178 return PrimaryButton(
179 onPressed: () => Navigator.of(context).pushNamed(Routes.support),
180 text: S.of(context).contact_support,
181 - color: Theme.of(context).accentTextTheme.caption.color,
182 - textColor: Theme.of(context).primaryTextTheme.title.color);
181 + color: Theme.of(context).accentTextTheme!.caption!.color!,
182 + textColor: Theme.of(context).primaryTextTheme!.headline6!.color!);
183 })
184 ])
185 ),
@@ -195,14 +195,14 @@ class _IoniaPaymentStatusPageBodyBodyState extends State<_IoniaPaymentStatusPage
195 Text(
196 title,
197 style: textXSmall(
198 - color: Theme.of(context).primaryTextTheme.overline.color,
198 + color: Theme.of(context).primaryTextTheme!.overline!.color!,
199 ),
200 ),
201 SizedBox(height: 8),
202 Text(
203 subtitle,
204 style: textMedium(
205 - color: Theme.of(context).primaryTextTheme.title.color,
205 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
206 ),
207 ),
208 ],
lib/src/screens/ionia/widgets/card_item.dart
+13 -13
@@ -3,30 +3,30 @@ import 'package:flutter/material.dart';
3
4 class CardItem extends StatelessWidget {
5 CardItem({
6 - @required this.title,
7 - @required this.subTitle,
8 - @required this.backgroundColor,
9 - @required this.titleColor,
10 - @required this.subtitleColor,
6 + required this.title,
7 + required this.subTitle,
8 + required this.backgroundColor,
9 + required this.titleColor,
10 + required this.subtitleColor,
11 this.hideBorder = false,
12 + this.discount = 0.0,
13 + this.isAmount = false,
14 this.discountBackground,
15 this.onTap,
16 this.logoUrl,
15 - this.discount,
16 - this.isAmount = false,
17 });
18
19 - final VoidCallback onTap;
19 + final VoidCallback? onTap;
20 final String title;
21 final String subTitle;
22 - final String logoUrl;
22 + final String? logoUrl;
23 final double discount;
24 final bool isAmount;
25 final bool hideBorder;
26 final Color backgroundColor;
27 final Color titleColor;
28 final Color subtitleColor;
29 - final AssetImage discountBackground;
29 + final AssetImage? discountBackground;
30
31 @override
32 Widget build(BuildContext context) {
@@ -49,11 +49,11 @@ class CardItem extends StatelessWidget {
49 if (logoUrl != null) ...[
50 ClipOval(
51 child: Image.network(
52 - logoUrl,
52 + logoUrl!,
53 width: 40.0,
54 height: 40.0,
55 fit: BoxFit.cover,
56 - loadingBuilder: (BuildContext _, Widget child, ImageChunkEvent loadingProgress) {
56 + loadingBuilder: (BuildContext _, Widget child, ImageChunkEvent? loadingProgress) {
57 if (loadingProgress == null) {
58 return child;
59 } else {
@@ -116,7 +116,7 @@ class CardItem extends StatelessWidget {
116 }
117
118 class _PlaceholderContainer extends StatelessWidget {
119 - const _PlaceholderContainer({@required this.text});
119 + const _PlaceholderContainer({required this.text});
120
121 final String text;
122
lib/src/screens/ionia/widgets/confirm_modal.dart
+18 -17
@@ -5,14 +5,14 @@ import 'package:flutter/material.dart';
5
6 class IoniaConfirmModal extends StatelessWidget {
7 IoniaConfirmModal({
8 - @required this.alertTitle,
9 - @required this.alertContent,
10 - @required this.leftButtonText,
11 - @required this.rightButtonText,
12 - @required this.actionLeftButton,
13 - @required this.actionRightButton,
14 - this.leftActionColor,
15 - this.rightActionColor,
8 + required this.alertTitle,
9 + required this.alertContent,
10 + required this.leftButtonText,
11 + required this.rightButtonText,
12 + required this.actionLeftButton,
13 + required this.actionRightButton,
14 + required this.leftActionColor,
15 + required this.rightActionColor,
16 this.hideActions = false,
17 });
18
@@ -57,7 +57,7 @@ class IoniaConfirmModal extends StatelessWidget {
57 fontSize: 20,
58 fontFamily: 'Lato',
59 fontWeight: FontWeight.w600,
60 - color: Theme.of(context).primaryTextTheme.title.color,
60 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
61 decoration: TextDecoration.none,
62 ),
63 );
@@ -78,7 +78,7 @@ class IoniaConfirmModal extends StatelessWidget {
78 borderRadius: BorderRadius.all(Radius.circular(30)),
79 child: Container(
80 width: 327,
81 - color: Theme.of(context).accentTextTheme.title.decorationColor,
81 + color: Theme.of(context).accentTextTheme!.headline6!.decorationColor!,
82 child: Column(
83 mainAxisSize: MainAxisSize.min,
84 children: [
@@ -109,9 +109,9 @@ class IoniaConfirmModal extends StatelessWidget {
109
110 class IoniaActionButton extends StatelessWidget {
111 const IoniaActionButton({
112 - @required this.buttonText,
113 - @required this.action,
114 - this.backgoundColor,
112 + required this.buttonText,
113 + required this.action,
114 + required this.backgoundColor,
115 });
116
117 final String buttonText;
@@ -127,10 +127,11 @@ class IoniaActionButton extends StatelessWidget {
127 color: backgoundColor,
128 child: ButtonTheme(
129 minWidth: double.infinity,
130 - child: FlatButton(
130 + child: TextButton(
131 onPressed: action,
132 - highlightColor: Colors.transparent,
133 - splashColor: Colors.transparent,
132 + // FIX-ME: ignored highlightColor and splashColor
133 + //highlightColor: Colors.transparent,
134 + //splashColor: Colors.transparent,
135 child: Text(
136 buttonText,
137 textAlign: TextAlign.center,
@@ -138,7 +139,7 @@ class IoniaActionButton extends StatelessWidget {
139 fontSize: 15,
140 fontFamily: 'Lato',
141 fontWeight: FontWeight.w600,
141 - color: backgoundColor != null ? Colors.white : Theme.of(context).primaryTextTheme.body1.backgroundColor,
142 + color: backgoundColor != null ? Colors.white : Theme.of(context).primaryTextTheme!.bodyText2!.backgroundColor!,
143 decoration: TextDecoration.none,
144 ),
145 )),
lib/src/screens/ionia/widgets/ionia_alert_model.dart
+7 -7
@@ -5,10 +5,10 @@ import 'package:flutter/material.dart';
5
6 class IoniaAlertModal extends StatelessWidget {
7 const IoniaAlertModal({
8 - Key key,
9 - @required this.title,
10 - @required this.content,
11 - @required this.actionTitle,
8 + Key? key,
9 + required this.title,
10 + required this.content,
11 + required this.actionTitle,
12 this.heightFactor = 0.4,
13 this.showCloseButton = true,
14 }) : super(key: key);
@@ -41,7 +41,7 @@ class IoniaAlertModal extends StatelessWidget {
41 Text(
42 title,
43 style: textLargeSemiBold(
44 - color: Theme.of(context).textTheme.body1.color,
44 + color: Theme.of(context).textTheme!.bodyText2!.color!,
45 ),
46 ),
47 Container(
@@ -56,8 +56,8 @@ class IoniaAlertModal extends StatelessWidget {
56 PrimaryButton(
57 onPressed: () => Navigator.pop(context),
58 text: actionTitle,
59 - color: Theme.of(context).accentTextTheme.caption.color,
60 - textColor: Theme.of(context).primaryTextTheme.title.color,
59 + color: Theme.of(context).accentTextTheme!.caption!.color!,
60 + textColor: Theme.of(context).primaryTextTheme!.headline6!.color!,
61 ),
62 SizedBox(height: 21),
63 ],
lib/src/screens/ionia/widgets/ionia_filter_modal.dart
+5 -5
@@ -8,7 +8,7 @@ import 'package:flutter_mobx/flutter_mobx.dart';
8 import 'package:cake_wallet/palette.dart';
9
10 class IoniaFilterModal extends StatelessWidget {
11 - IoniaFilterModal({@required this.ioniaGiftCardsListViewModel}){
11 + IoniaFilterModal({required this.ioniaGiftCardsListViewModel}){
12 ioniaGiftCardsListViewModel.resetIoniaCategories();
13 }
14
@@ -46,14 +46,14 @@ class IoniaFilterModal extends StatelessWidget {
46 child: TextField(
47 onChanged: ioniaGiftCardsListViewModel.onSearchFilter,
48 style: textMedium(
49 - color: Theme.of(context).primaryTextTheme.title.color,
49 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
50 ),
51 decoration: InputDecoration(
52 filled: true,
53 prefixIcon: searchIcon,
54 hintText: S.of(context).search_category,
55 contentPadding: EdgeInsets.only(bottom: 5),
56 - fillColor: Theme.of(context).textTheme.subhead.backgroundColor,
56 + fillColor: Theme.of(context).textTheme!.subtitle1!.backgroundColor!,
57 border: OutlineInputBorder(
58 borderSide: BorderSide.none,
59 borderRadius: BorderRadius.circular(8),
@@ -84,12 +84,12 @@ class IoniaFilterModal extends StatelessWidget {
84 children: [
85 Image.asset(
86 category.iconPath,
87 - color: Theme.of(context).primaryTextTheme.title.color,
87 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
88 ),
89 SizedBox(width: 10),
90 Text(category.title,
91 style: textSmall(
92 - color: Theme.of(context).primaryTextTheme.title.color,
92 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
93 ).copyWith(fontWeight: FontWeight.w500)),
94 ],
95 ),
lib/src/screens/ionia/widgets/ionia_tile.dart
+7 -7
@@ -3,20 +3,20 @@ import 'package:flutter/material.dart';
3
4 class IoniaTile extends StatelessWidget {
5 const IoniaTile({
6 - Key key,
7 - @required this.title,
8 - @required this.subTitle,
6 + Key? key,
7 + required this.title,
8 + required this.subTitle,
9 this.onTap,
10 }) : super(key: key);
11
12 - final VoidCallback onTap;
12 + final VoidCallback? onTap;
13 final String title;
14 final String subTitle;
15
16 @override
17 Widget build(BuildContext context) {
18 return GestureDetector(
19 - onTap: () => onTap(),
19 + onTap: onTap,
20 child: Row(
21 mainAxisAlignment: MainAxisAlignment.spaceBetween,
22 children: [
@@ -26,14 +26,14 @@ class IoniaTile extends StatelessWidget {
26 Text(
27 title,
28 style: textXSmall(
29 - color: Theme.of(context).primaryTextTheme.overline.color,
29 + color: Theme.of(context).primaryTextTheme!.overline!.color!,
30 ),
31 ),
32 SizedBox(height: 8),
33 Text(
34 subTitle,
35 style: textMediumBold(
36 - color: Theme.of(context).primaryTextTheme.title.color,
36 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
37 ),
38 ),
39 ],
lib/src/screens/ionia/widgets/rounded_checkbox.dart
+2 -2
@@ -3,7 +3,7 @@ import 'package:flutter/cupertino.dart';
3 import 'package:flutter/material.dart';
4
5 class RoundedCheckbox extends StatelessWidget {
6 - RoundedCheckbox({Key key, @required this.value}) : super(key: key);
6 + RoundedCheckbox({Key? key, required this.value}) : super(key: key);
7
8 final bool value;
9
@@ -15,7 +15,7 @@ class RoundedCheckbox extends StatelessWidget {
15 width: 20.0,
16 decoration: BoxDecoration(
17 borderRadius: BorderRadius.all(Radius.circular(50.0)),
18 - color: Theme.of(context).accentTextTheme.body2.color,
18 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
19 ),
20 child: Icon(
21 Icons.check,
lib/src/screens/ionia/widgets/text_icon_button.dart
+7 -6
@@ -2,14 +2,15 @@ import 'package:cake_wallet/typography.dart';
2 import 'package:flutter/material.dart';
3
4 class TextIconButton extends StatelessWidget {
5 - final String label;
6 - final VoidCallback onTap;
5 const TextIconButton({
8 - Key key,
9 - this.label,
6 + Key? key,
7 + required this.label,
8 this.onTap,
9 }) : super(key: key);
10
11 + final String label;
12 + final VoidCallback? onTap;
13 +
14 @override
15 Widget build(BuildContext context) {
16 return
@@ -21,12 +22,12 @@ class TextIconButton extends StatelessWidget {
22 Text(
23 label,
24 style: textMediumSemiBold(
24 - color: Theme.of(context).primaryTextTheme.title.color,
25 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
26 ),
27 ),
28 Icon(
29 Icons.chevron_right_rounded,
29 - color: Theme.of(context).primaryTextTheme.title.color,
30 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
31 ),
32 ],
33 ),
lib/src/screens/monero_accounts/monero_account_edit_or_create_page.dart
+3 -3
@@ -10,7 +10,7 @@ import 'package:cake_wallet/src/screens/base_page.dart';
10 import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
11
12 class MoneroAccountEditOrCreatePage extends BasePage {
13 - MoneroAccountEditOrCreatePage({@required this.moneroAccountCreationViewModel})
13 + MoneroAccountEditOrCreatePage({required this.moneroAccountCreationViewModel})
14 : _formKey = GlobalKey<FormState>(),
15 _textController = TextEditingController() {
16 _textController.addListener(
@@ -45,7 +45,7 @@ class MoneroAccountEditOrCreatePage extends BasePage {
45 builder: (_) =>
46 LoadingPrimaryButton(
47 onPressed: () async {
48 - if (!_formKey.currentState.validate()) {
48 + if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
49 return;
50 }
51
@@ -56,7 +56,7 @@ class MoneroAccountEditOrCreatePage extends BasePage {
56 text: moneroAccountCreationViewModel.isEdit
57 ? S.of(context).rename
58 : S.of(context).add,
59 - color: Theme.of(context).accentTextTheme.body2.color,
59 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
60 textColor: Colors.white,
61 isLoading: moneroAccountCreationViewModel.state
62 is IsExecutingState,
lib/src/screens/monero_accounts/monero_account_list_page.dart
+6 -7
@@ -12,12 +12,11 @@ import 'package:cake_wallet/src/widgets/cake_scrollbar.dart';
12 import 'package:cake_wallet/src/widgets/alert_close_button.dart';
13
14 class MoneroAccountListPage extends StatelessWidget {
15 - MoneroAccountListPage({@required this.accountListViewModel}) {
16 - backgroundHeight = 194;
17 - thumbHeight = 72;
18 - isAlwaysShowScrollThumb = false;
19 - controller = ScrollController();
20 -
15 + MoneroAccountListPage({required this.accountListViewModel})
16 + : backgroundHeight = 194,
17 + thumbHeight = 72,
18 + isAlwaysShowScrollThumb = false,
19 + controller = ScrollController() {
20 controller.addListener(() {
21 final scrollOffsetFromTop = controller.hasClients
22 ? (controller.offset / controller.position.maxScrollExtent * (backgroundHeight - thumbHeight))
@@ -67,7 +66,7 @@ class MoneroAccountListPage extends StatelessWidget {
66 borderRadius: BorderRadius.all(Radius.circular(14)),
67 child: Container(
68 height: 296,
70 - color: Theme.of(context).textTheme.display4.decorationColor,
69 + color: Theme.of(context).textTheme!.headline1!.decorationColor!,
70 child: Column(
71 children: <Widget>[
72 Expanded(
lib/src/screens/monero_accounts/widgets/account_tile.dart
+21 -20
@@ -4,10 +4,10 @@ import 'package:cake_wallet/generated/i18n.dart';
4
5 class AccountTile extends StatelessWidget {
6 AccountTile({
7 - @required this.isCurrent,
8 - @required this.accountName,
9 - @required this.onTap,
10 - @required this.onEdit
7 + required this.isCurrent,
8 + required this.accountName,
9 + required this.onTap,
10 + required this.onEdit
11 });
12
13 final bool isCurrent;
@@ -18,11 +18,11 @@ class AccountTile extends StatelessWidget {
18 @override
19 Widget build(BuildContext context) {
20 final color = isCurrent
21 - ? Theme.of(context).textTheme.subtitle.decorationColor
22 - : Theme.of(context).textTheme.display4.decorationColor;
21 + ? Theme.of(context).textTheme!.subtitle2!.decorationColor!
22 + : Theme.of(context).textTheme!.headline1!.decorationColor!;
23 final textColor = isCurrent
24 - ? Theme.of(context).textTheme.subtitle.color
25 - : Theme.of(context).textTheme.display4.color;
24 + ? Theme.of(context).textTheme!.subtitle2!.color!
25 + : Theme.of(context).textTheme!.headline1!.color!;
26
27 final Widget cell = GestureDetector(
28 onTap: onTap,
@@ -43,17 +43,18 @@ class AccountTile extends StatelessWidget {
43 ),
44 ),
45 );
46 -
47 - return Slidable(
48 - key: Key(accountName),
49 - child: cell,
50 - actionPane: SlidableDrawerActionPane(),
51 - secondaryActions: <Widget>[
52 - IconSlideAction(
53 - caption: S.of(context).edit,
54 - color: Colors.blue,
55 - icon: Icons.edit,
56 - onTap: () => onEdit?.call())
57 - ]);
46 + // FIX-ME: Splidable
47 + return cell;
48 + // return Slidable(
49 + // key: Key(accountName),
50 + // child: cell,
51 + // actionPane: SlidableDrawerActionPane(),
52 + // secondaryActions: <Widget>[
53 + // IconSlideAction(
54 + // caption: S.of(context).edit,
55 + // color: Colors.blue,
56 + // icon: Icons.edit,
57 + // onTap: () => onEdit?.call())
58 + // ]);
59 }
60 }
\ No newline at end of file
lib/src/screens/new_wallet/new_wallet_page.dart
+24 -22
@@ -49,16 +49,18 @@ class WalletNameForm extends StatefulWidget {
49 }
50
51 class _WalletNameFormState extends State<WalletNameForm> {
52 - _WalletNameFormState(this._walletNewVM);
52 + _WalletNameFormState(this._walletNewVM)
53 + : _formKey = GlobalKey<FormState>(),
54 + _languageSelectorKey = GlobalKey<SeedLanguageSelectorState>(),
55 + _controller = TextEditingController();
56
57 static const aspectRatioImage = 1.22;
58
56 - final _formKey = GlobalKey<FormState>();
57 - final _languageSelectorKey = GlobalKey<SeedLanguageSelectorState>();
58 - ReactionDisposer _stateReaction;
59 + final GlobalKey<FormState> _formKey;
60 + final GlobalKey<SeedLanguageSelectorState> _languageSelectorKey;
61 final WalletNewVM _walletNewVM;
60 -
61 - final TextEditingController _controller = TextEditingController();
62 + final TextEditingController _controller;
63 + ReactionDisposer? _stateReaction;
64
65 @override
66 void initState() {
@@ -116,29 +118,29 @@ class _WalletNameFormState extends State<WalletNameForm> {
118 fontSize: 20.0,
119 fontWeight: FontWeight.w600,
120 color:
119 - Theme.of(context).primaryTextTheme.title.color),
121 + Theme.of(context).primaryTextTheme!.headline6!.color!),
122 decoration: InputDecoration(
123 hintStyle: TextStyle(
124 fontSize: 18.0,
125 fontWeight: FontWeight.w500,
126 color: Theme.of(context)
125 - .accentTextTheme
126 - .display3
127 - .color),
127 + .accentTextTheme!
128 + .headline2!
129 + .color!),
130 hintText: S.of(context).wallet_name,
131 focusedBorder: UnderlineInputBorder(
132 borderSide: BorderSide(
133 color: Theme.of(context)
132 - .accentTextTheme
133 - .display3
134 - .decorationColor,
134 + .accentTextTheme!
135 + .headline2!
136 + .decorationColor!,
137 width: 1.0)),
138 enabledBorder: UnderlineInputBorder(
139 borderSide: BorderSide(
140 color: Theme.of(context)
139 - .accentTextTheme
140 - .display3
141 - .decorationColor,
141 + .accentTextTheme!
142 + .headline2!
143 + .decorationColor!,
144 width: 1.0),
145 ),
146 suffixIcon: IconButton(
@@ -164,9 +166,9 @@ class _WalletNameFormState extends State<WalletNameForm> {
166 child: Image.asset(
167 'assets/images/refresh_icon.png',
168 color: Theme.of(context)
167 - .primaryTextTheme
168 - .display1
169 - .decorationColor,
169 + .primaryTextTheme!
170 + .headline4!
171 + .decorationColor!,
172 ),
173 ),
174 ),
@@ -186,7 +188,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
188 style: TextStyle(
189 fontSize: 16.0,
190 fontWeight: FontWeight.w500,
189 - color: Theme.of(context).primaryTextTheme.title.color),
191 + color: Theme.of(context).primaryTextTheme!.headline6!.color!),
192 ),
193 ),
194 Padding(
@@ -215,7 +217,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
217 }
218
219 void _confirmForm() {
218 - if (!_formKey.currentState.validate()) {
220 + if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
221 return;
222 }
223 if (_walletNewVM.nameExists(_walletNewVM.name)) {
@@ -231,7 +233,7 @@ class _WalletNameFormState extends State<WalletNameForm> {
233 } else {
234 _walletNewVM.create(
235 options: _walletNewVM.hasLanguageSelector
234 - ? _languageSelectorKey.currentState.selected
236 + ? _languageSelectorKey.currentState!.selected
237 : null);
238 }
239 }
lib/src/screens/new_wallet/new_wallet_type_page.dart
+22 -47
@@ -5,7 +5,7 @@ import 'package:cake_wallet/routes.dart';
5 import 'package:cake_wallet/store/settings_store.dart';
6 import 'package:cake_wallet/utils/show_bar.dart';
7 import 'package:cake_wallet/view_model/wallet_new_vm.dart';
8 -import 'package:flushbar/flushbar.dart';
8 +// import 'package:flushbar/flushbar.dart';
9 import 'package:cw_core/wallet_type.dart';
10 import 'package:cake_wallet/themes/theme_base.dart';
11 import 'package:flutter/material.dart';
@@ -18,35 +18,29 @@ import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart';
18 import 'package:cake_wallet/wallet_types.g.dart';
19
20 class NewWalletTypePage extends BasePage {
21 - NewWalletTypePage(this.walletNewVM, {this.onTypeSelected, this.isNewWallet});
21 + NewWalletTypePage({required this.onTypeSelected});
22
23 final void Function(BuildContext, WalletType) onTypeSelected;
24 - final bool isNewWallet;
25 - final WalletNewVM walletNewVM;
26 -
24 final walletTypeImage = Image.asset('assets/images/wallet_type.png');
25 final walletTypeLightImage =
26 Image.asset('assets/images/wallet_type_light.png');
27
28 @override
32 - String get title =>
33 - isNewWallet ? S.current.new_wallet : S.current.wallet_list_restore_wallet;
29 + String get title => S.current.wallet_list_restore_wallet;
30
31 @override
36 - Widget body(BuildContext context) => WalletTypeForm(walletNewVM, isNewWallet,
37 - onTypeSelected: onTypeSelected,
38 - walletImage: currentTheme.type == ThemeType.dark
39 - ? walletTypeImage
40 - : walletTypeLightImage);
32 + Widget body(BuildContext context) => WalletTypeForm(
33 + onTypeSelected: onTypeSelected,
34 + walletImage: currentTheme.type == ThemeType.dark
35 + ? walletTypeImage
36 + : walletTypeLightImage);
37 }
38
39 class WalletTypeForm extends StatefulWidget {
44 - WalletTypeForm(this.walletNewVM, this.isNewWallet,
45 - {this.onTypeSelected, this.walletImage});
40 + WalletTypeForm({required this.onTypeSelected,
41 + required this.walletImage});
42
43 final void Function(BuildContext, WalletType) onTypeSelected;
48 - final WalletNewVM walletNewVM;
49 - final bool isNewWallet;
44 final Image walletImage;
45
46 @override
@@ -54,6 +48,9 @@ class WalletTypeForm extends StatefulWidget {
48 }
49
50 class WalletTypeFormState extends State<WalletTypeForm> {
51 + WalletTypeFormState()
52 + : types = availableWalletTypes;
53 +
54 static const aspectRatioImage = 1.22;
55
56 final moneroIcon =
@@ -68,9 +65,10 @@ class WalletTypeFormState extends State<WalletTypeForm> {
65 final havenIcon =
66 Image.asset('assets/images/haven_logo.png', height: 24, width: 24);
67
71 - WalletType selected;
68 + WalletType? selected;
69 List<WalletType> types;
73 - Flushbar<void> _progressBar;
70 + // FIX-ME: Replace Flushbar
71 + // Flushbar<void>? _progressBar;
72
73 @override
74 void initState() {
@@ -99,7 +97,7 @@ class WalletTypeFormState extends State<WalletTypeForm> {
97 style: TextStyle(
98 fontSize: 16,
99 fontWeight: FontWeight.w500,
102 - color: Theme.of(context).primaryTextTheme.title.color),
100 + color: Theme.of(context).primaryTextTheme!.headline6!.color!),
101 ),
102 ),
103 ...types.map((type) => Padding(
@@ -116,7 +114,7 @@ class WalletTypeFormState extends State<WalletTypeForm> {
114 bottomSection: PrimaryButton(
115 onPressed: () => onTypeSelected(),
116 text: S.of(context).seed_language_next,
119 - color: Theme.of(context).accentTextTheme.body2.color,
117 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
118 textColor: Colors.white,
119 isDisabled: selected == null,
120 ),
@@ -134,38 +132,15 @@ class WalletTypeFormState extends State<WalletTypeForm> {
132 case WalletType.haven:
133 return havenIcon;
134 default:
137 - return null;
135 + throw Exception('_iconFor: Incorrect Wallet Type. Cannot find icon for Wallet Type: ${type.toString()}');
136 }
137 }
138
139 Future<void> onTypeSelected() async {
142 - if (!widget.isNewWallet) {
143 - widget.onTypeSelected(context, selected);
144 - return;
140 + if (selected == null) {
141 + throw Exception('Wallet Type is not selected yet.');
142 }
143
147 - try {
148 - _changeProcessText(S.of(context).creating_new_wallet);
149 - widget.walletNewVM.type = selected;
150 - await widget.walletNewVM
151 - .create(options: 'English'); // FIXME: Unnamed constant
152 - await _progressBar?.dismiss();
153 - final state = widget.walletNewVM.state;
154 -
155 - if (state is ExecutedSuccessfullyState) {
156 - widget.onTypeSelected(context, selected);
157 - }
158 -
159 - if (state is FailureState) {
160 - _changeProcessText(
161 - S.of(context).creating_new_wallet_error(state.error));
162 - }
163 - } catch (e) {
164 - _changeProcessText(S.of(context).creating_new_wallet_error(e.toString()));
165 - }
166 - }
167 -
168 - void _changeProcessText(String text) {
169 - _progressBar = createBar<void>(text, duration: null)..show(context);
144 + widget.onTypeSelected(context, selected!);
145 }
146 }
lib/src/screens/new_wallet/widgets/select_button.dart
+9 -9
@@ -2,13 +2,13 @@ import 'package:flutter/material.dart';
2
3 class SelectButton extends StatelessWidget {
4 SelectButton({
5 - @required this.image,
6 - @required this.text,
7 - @required this.onTap,
5 + required this.text,
6 + required this.onTap,
7 + this.image,
8 this.isSelected = false,
9 });
10
11 - final Image image;
11 + final Image? image;
12 final String text;
13 final bool isSelected;
14 final VoidCallback onTap;
@@ -17,13 +17,13 @@ class SelectButton extends StatelessWidget {
17 Widget build(BuildContext context) {
18 final color = isSelected
19 ? Colors.green
20 - : Theme.of(context).accentTextTheme.caption.color;
20 + : Theme.of(context).accentTextTheme!.caption!.color!;
21 final textColor = isSelected
22 - ? Theme.of(context).accentTextTheme.headline.decorationColor
23 - : Theme.of(context).primaryTextTheme.title.color;
22 + ? Theme.of(context).accentTextTheme!.headline5!.decorationColor!
23 + : Theme.of(context).primaryTextTheme!.headline6!.color!;
24 final arrowColor = isSelected
25 - ? Theme.of(context).accentTextTheme.headline.decorationColor
26 - : Theme.of(context).accentTextTheme.subhead.color;
25 + ? Theme.of(context).accentTextTheme!.headline5!.decorationColor!
26 + : Theme.of(context).accentTextTheme!.subtitle1!.color!;
27
28 final selectArrowImage = Image.asset('assets/images/select_arrow.png',
29 color: arrowColor);
lib/src/screens/nodes/node_create_or_edit_page.dart
+3 -3
@@ -187,7 +187,7 @@ class NodeCreateOrEditPage extends BasePage {
187 padding: EdgeInsets.only(right: 8.0),
188 child: LoadingPrimaryButton(
189 onPressed: () async {
190 - if (!_formKey.currentState.validate()) {
190 + if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
191 return;
192 }
193
@@ -205,7 +205,7 @@ class NodeCreateOrEditPage extends BasePage {
205 padding: EdgeInsets.only(left: 8.0),
206 child: PrimaryButton(
207 onPressed: () async {
208 - if (!_formKey.currentState.validate()) {
208 + if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
209 return;
210 }
211
@@ -213,7 +213,7 @@ class NodeCreateOrEditPage extends BasePage {
213 Navigator.of(context).pop();
214 },
215 text: S.of(context).save,
216 - color: Theme.of(context).accentTextTheme.body2.color,
216 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
217 textColor: Colors.white,
218 isDisabled: (!nodeCreateOrEditViewModel.isReady)||
219 (nodeCreateOrEditViewModel
lib/src/screens/nodes/nodes_list_page.dart
+37 -36
@@ -26,10 +26,10 @@ class NodeListPage extends BasePage {
26 height: 32,
27 decoration: BoxDecoration(
28 borderRadius: BorderRadius.all(Radius.circular(16)),
29 - color: Theme.of(context).accentTextTheme.caption.color),
29 + color: Theme.of(context).accentTextTheme!.caption!.color!),
30 child: ButtonTheme(
31 minWidth: double.minPositive,
32 - child: FlatButton(
32 + child: TextButton(
33 onPressed: () async {
34 await showPopUp<void>(
35 context: context,
@@ -114,41 +114,42 @@ class NodeListPage extends BasePage {
114 });
115 });
116 });
117 + // FIX-ME: Slidable
118 + // final dismissibleRow = Slidable(
119 + // key: Key('${node.keyIndex}'),
120 + // actionPane: SlidableDrawerActionPane(),
121 + // child: nodeListRow,
122 + // secondaryActions: <Widget>[
123 + // IconSlideAction(
124 + // caption: S.of(context).delete,
125 + // color: Colors.red,
126 + // icon: CupertinoIcons.delete,
127 + // onTap: () async {
128 + // final confirmed = await showPopUp<bool>(
129 + // context: context,
130 + // builder: (BuildContext context) {
131 + // return AlertWithTwoActions(
132 + // alertTitle: S.of(context).remove_node,
133 + // alertContent:
134 + // S.of(context).remove_node_message,
135 + // rightButtonText: S.of(context).remove,
136 + // leftButtonText: S.of(context).cancel,
137 + // actionRightButton: () =>
138 + // Navigator.pop(context, true),
139 + // actionLeftButton: () =>
140 + // Navigator.pop(context, false));
141 + // }) ??
142 + // false;
143
118 - final dismissibleRow = Slidable(
119 - key: Key('${node.keyIndex}'),
120 - actionPane: SlidableDrawerActionPane(),
121 - child: nodeListRow,
122 - secondaryActions: <Widget>[
123 - IconSlideAction(
124 - caption: S.of(context).delete,
125 - color: Colors.red,
126 - icon: CupertinoIcons.delete,
127 - onTap: () async {
128 - final confirmed = await showPopUp<bool>(
129 - context: context,
130 - builder: (BuildContext context) {
131 - return AlertWithTwoActions(
132 - alertTitle: S.of(context).remove_node,
133 - alertContent:
134 - S.of(context).remove_node_message,
135 - rightButtonText: S.of(context).remove,
136 - leftButtonText: S.of(context).cancel,
137 - actionRightButton: () =>
138 - Navigator.pop(context, true),
139 - actionLeftButton: () =>
140 - Navigator.pop(context, false));
141 - }) ??
142 - false;
143 -
144 - if (confirmed) {
145 - await nodeListViewModel.delete(node);
146 - }
147 - },
148 - ),
149 - ]);
150 -
151 - return isSelected ? nodeListRow : dismissibleRow;
144 + // if (confirmed) {
145 + // await nodeListViewModel.delete(node);
146 + // }
147 + // },
148 + // ),
149 + // ]);
150 +
151 + return nodeListRow;
152 + // return isSelected ? nodeListRow : dismissibleRow;
153 });
154 },
155 ),
lib/src/screens/nodes/widgets/node_list_row.dart
+6 -6
@@ -8,10 +8,10 @@ import 'package:flutter/material.dart';
8
9 class NodeListRow extends StandardListRow {
10 NodeListRow(
11 - {@required String title,
12 - @required void Function(BuildContext context) onTap,
13 - @required bool isSelected,
14 - @required this.isAlive})
11 + {required String title,
12 + required void Function(BuildContext context) onTap,
13 + required bool isSelected,
14 + required this.isAlive})
15 : super(title: title, onTap: onTap, isSelected: isSelected);
16
17 final Future<bool> isAlive;
@@ -32,12 +32,12 @@ class NodeListRow extends StandardListRow {
32 }
33
34 class NodeHeaderListRow extends StandardListRow {
35 - NodeHeaderListRow({@required String title, @required void Function(BuildContext context) onTap})
35 + NodeHeaderListRow({required String title, required void Function(BuildContext context) onTap})
36 : super(title: title, onTap: onTap, isSelected: false);
37
38 @override
39 Widget buildTrailing(BuildContext context) {
40 return Icon(Icons.add,
41 - color: Theme.of(context).accentTextTheme.subhead.color, size: 24.0);
41 + color: Theme.of(context).accentTextTheme!.subtitle1!.color!, size: 24.0);
42 }
43 }
lib/src/screens/order_details/order_details_page.dart
+1
@@ -48,6 +48,7 @@ class OrderDetailsPageBodyState extends State<OrderDetailsPageBody> {
48 Widget build(BuildContext context) {
49 return Observer(builder: (_) {
50 return SectionStandardList(
51 + context: context,
52 sectionCount: 1,
53 itemCounter: (int _) => orderDetailsViewModel.items.length,
54 itemBuilder: (_, __, index) {
lib/src/screens/pin_code/pin_code_widget.dart
+50 -40
@@ -1,22 +1,22 @@
1 import 'package:cake_wallet/utils/show_bar.dart';
2 -import 'package:flushbar/flushbar.dart';
2 +// import 'package:flushbar/flushbar.dart';
3 import 'package:flutter/material.dart';
4 import 'package:flutter/cupertino.dart';
5 import 'package:cake_wallet/generated/i18n.dart';
6
7 class PinCodeWidget extends StatefulWidget {
8 PinCodeWidget(
9 - {Key key,
10 - @required this.onFullPin,
11 - @required this.initialPinLength,
12 - this.onChangedPin,
13 - this.onChangedPinLength,
14 - this.hasLengthSwitcher})
9 + {required Key key,
10 + required this.onFullPin,
11 + required this.initialPinLength,
12 + required this.onChangedPin,
13 + required this.hasLengthSwitcher,
14 + this.onChangedPinLength,})
15 : super(key: key);
16
17 final void Function(String pin, PinCodeState state) onFullPin;
18 final void Function(String pin) onChangedPin;
19 - final void Function(int length) onChangedPinLength;
19 + final void Function(int length)? onChangedPinLength;
20 final bool hasLengthSwitcher;
21 final int initialPinLength;
22
@@ -25,6 +25,11 @@ class PinCodeWidget extends StatefulWidget {
25 }
26
27 class PinCodeState<T extends PinCodeWidget> extends State<T> {
28 + PinCodeState()
29 + : _aspectRatio = 0,
30 + pinLength = 0,
31 + pin = '',
32 + title = '';
33 static const defaultPinLength = fourPinLength;
34 static const sixPinLength = 6;
35 static const fourPinLength = 4;
@@ -35,7 +40,8 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
40 String pin;
41 String title;
42 double _aspectRatio;
38 - Flushbar<void> _progressBar;
43 + // FIX-ME: Replace Flushbar
44 + // Flushbar<void>? _progressBar;
45
46 int currentPinLength() => pin.length;
47
@@ -72,7 +78,7 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
78
79 void calculateAspectRatio() {
80 final renderBox =
75 - _gridViewKey.currentContext.findRenderObject() as RenderBox;
81 + _gridViewKey.currentContext!.findRenderObject() as RenderBox;
82 final cellWidth = renderBox.size.width / 3;
83 final cellHeight = renderBox.size.height / 4;
84
@@ -85,18 +91,19 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
91
92 void changeProcessText(String text) {
93 hideProgressText();
88 - _progressBar = createBar<void>(text, duration: null)
89 - ..show(_key.currentContext);
94 + // FIX-ME: Empty Duration,
95 + // _progressBar = createBar<void>(text, duration: Duration())
96 + // ..show(_key.currentContext);
97 }
98
99 void close() {
93 - _progressBar?.dismiss();
94 - Navigator.of(_key.currentContext).pop();
100 + // _progressBar?.dismiss();
101 + Navigator.of(_key.currentContext!).pop();
102 }
103
104 void hideProgressText() {
98 - _progressBar?.dismiss();
99 - _progressBar = null;
105 + // _progressBar?.dismiss();
106 + // _progressBar = null;
107 }
108
109 @override
@@ -106,11 +113,11 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
113 Widget body(BuildContext context) {
114 final deleteIconImage = Image.asset(
115 'assets/images/delete_icon.png',
109 - color: Theme.of(context).primaryTextTheme.title.color,
116 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
117 );
118 final faceImage = Image.asset(
119 'assets/images/face.png',
113 - color: Theme.of(context).primaryTextTheme.title.color,
120 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
121 );
122
123 return Container(
@@ -122,7 +129,7 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
129 style: TextStyle(
130 fontSize: 20,
131 fontWeight: FontWeight.w500,
125 - color: Theme.of(context).primaryTextTheme.title.color)),
132 + color: Theme.of(context).primaryTextTheme!.headline6!.color!)),
133 Spacer(flex: 3),
134 Container(
135 width: 180,
@@ -138,11 +145,11 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
145 decoration: BoxDecoration(
146 shape: BoxShape.circle,
147 color: isFilled
141 - ? Theme.of(context).primaryTextTheme.title.color
148 + ? Theme.of(context).primaryTextTheme!.headline6!.color!
149 : Theme.of(context)
143 - .accentTextTheme
144 - .body1
145 - .color
150 + .accentTextTheme!
151 + .bodyText2!
152 + .color!
153 .withOpacity(0.25),
154 ));
155 }),
@@ -150,7 +157,7 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
157 ),
158 Spacer(flex: 2),
159 if (widget.hasLengthSwitcher) ...[
153 - FlatButton(
160 + TextButton(
161 onPressed: () {
162 changePinLength(pinLength == PinCodeState.fourPinLength
163 ? PinCodeState.sixPinLength
@@ -162,9 +169,9 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
169 fontSize: 14.0,
170 fontWeight: FontWeight.normal,
171 color: Theme.of(context)
165 - .accentTextTheme
166 - .body1
167 - .decorationColor),
172 + .accentTextTheme!
173 + .bodyText2!
174 + .decorationColor!),
175 ))
176 ],
177 Spacer(flex: 1),
@@ -186,7 +193,7 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
193 return Container(
194 margin: EdgeInsets.only(
195 left: marginLeft, right: marginRight),
189 - child: FlatButton(
196 + child: TextButton(
197 onPressed: () => null,
198 // (widget.hasLengthSwitcher ||
199 // !settingsStore
@@ -213,9 +220,10 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
220 // });
221 // }
222 // },
216 - color: Theme.of(context).backgroundColor,
217 - shape: CircleBorder(),
218 - child: null
223 + // FIX-ME: Style
224 + //color: Theme.of(context).backgroundColor,
225 + //shape: CircleBorder(),
226 + child: Container()
227 // (widget.hasLengthSwitcher ||
228 // !settingsStore
229 // .allowBiometricalAuthentication)
@@ -229,10 +237,11 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
237 return Container(
238 margin: EdgeInsets.only(
239 left: marginLeft, right: marginRight),
232 - child: FlatButton(
240 + child: TextButton(
241 onPressed: () => _pop(),
234 - color: Theme.of(context).backgroundColor,
235 - shape: CircleBorder(),
242 + // FIX-ME: Style
243 + //color: Theme.of(context).backgroundColor,
244 + //shape: CircleBorder(),
245 child: deleteIconImage,
246 ),
247 );
@@ -243,18 +252,19 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
252 return Container(
253 margin: EdgeInsets.only(
254 left: marginLeft, right: marginRight),
246 - child: FlatButton(
255 + child: TextButton(
256 onPressed: () => _push(index),
248 - color: Theme.of(context).backgroundColor,
249 - shape: CircleBorder(),
257 + // FIX-ME: Style
258 + //color: Theme.of(context).backgroundColor,
259 + //shape: CircleBorder(),
260 child: Text('$index',
261 style: TextStyle(
262 fontSize: 30.0,
263 fontWeight: FontWeight.w600,
264 color: Theme.of(context)
255 - .primaryTextTheme
256 - .title
257 - .color)),
265 + .primaryTextTheme!
266 + .headline6!
267 + .color!)),
268 ),
269 );
270 }),
lib/src/screens/receive/fullscreen_qr_page.dart
+9 -8
@@ -5,7 +5,7 @@ import 'package:flutter/cupertino.dart';
5 import 'package:cake_wallet/src/screens/base_page.dart';
6
7 class FullscreenQRPage extends BasePage {
8 - FullscreenQRPage({@required this.qrData, @required this.isLight});
8 + FullscreenQRPage({required this.qrData, required this.isLight});
9
10 final bool isLight;
11 final String qrData;
@@ -23,7 +23,7 @@ class FullscreenQRPage extends BasePage {
23 Widget leading(BuildContext context) {
24 final _backButton = Icon(
25 Icons.arrow_back_ios,
26 - color: Theme.of(context).accentTextTheme.display3.backgroundColor,
26 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
27 size: 16,
28 );
29
@@ -32,10 +32,11 @@ class FullscreenQRPage extends BasePage {
32 width: 37,
33 child: ButtonTheme(
34 minWidth: double.minPositive,
35 - child: FlatButton(
36 - highlightColor: Colors.transparent,
37 - splashColor: Colors.transparent,
38 - padding: EdgeInsets.all(0),
35 + child: TextButton(
36 + // FIX-ME: Style
37 + //highlightColor: Colors.transparent,
38 + //splashColor: Colors.transparent,
39 + //padding: EdgeInsets.all(0),
40 onPressed: () => onClose(context),
41 child: _backButton,
42 ),
@@ -70,11 +71,11 @@ class FullscreenQRPage extends BasePage {
71 child: Container(
72 padding: EdgeInsets.all(5),
73 decoration: BoxDecoration(
73 - border: Border.all(width: 3, color: Theme.of(context).accentTextTheme.display3.backgroundColor)),
74 + border: Border.all(width: 3, color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!)),
75 child: QrImage(
76 data: qrData,
77 backgroundColor: isLight ? Colors.transparent : Colors.black,
77 - foregroundColor: Theme.of(context).accentTextTheme.display3.backgroundColor,
78 + foregroundColor: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
79 ),
80 ),
81 ),
lib/src/screens/receive/receive_page.dart
+35 -30
@@ -6,7 +6,7 @@ import 'package:cw_core/wallet_type.dart';
6 import 'package:flutter/material.dart';
7 import 'package:flutter/cupertino.dart';
8 import 'package:flutter_mobx/flutter_mobx.dart';
9 -import 'package:esys_flutter_share/esys_flutter_share.dart';
9 +// import 'package:esys_flutter_share/esys_flutter_share.dart';
10 import 'package:cake_wallet/routes.dart';
11 import 'package:cake_wallet/generated/i18n.dart';
12 import 'package:cake_wallet/di.dart';
@@ -22,7 +22,7 @@ import 'package:cake_wallet/src/screens/receive/widgets/qr_widget.dart';
22 import 'package:keyboard_actions/keyboard_actions.dart';
23
24 class ReceivePage extends BasePage {
25 - ReceivePage({this.addressListViewModel}) : _cryptoAmountFocus = FocusNode();
25 + ReceivePage({required this.addressListViewModel}) : _cryptoAmountFocus = FocusNode();
26
27 final WalletAddressListViewModel addressListViewModel;
28
@@ -44,7 +44,7 @@ class ReceivePage extends BasePage {
44 @override
45 Widget leading(BuildContext context) {
46 final _backButton = Icon(Icons.arrow_back_ios,
47 - color: Theme.of(context).accentTextTheme.display3.backgroundColor,
47 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
48 size: 16,);
49
50 return SizedBox(
@@ -52,10 +52,11 @@ class ReceivePage extends BasePage {
52 width: 37,
53 child: ButtonTheme(
54 minWidth: double.minPositive,
55 - child: FlatButton(
56 - highlightColor: Colors.transparent,
57 - splashColor: Colors.transparent,
58 - padding: EdgeInsets.all(0),
55 + child: TextButton(
56 + // FIX-ME: Style
57 + //highlightColor: Colors.transparent,
58 + //splashColor: Colors.transparent,
59 + //padding: EdgeInsets.all(0),
60 onPressed: () => onClose(context),
61 child: _backButton),
62 ),
@@ -70,7 +71,7 @@ class ReceivePage extends BasePage {
71 fontSize: 18.0,
72 fontWeight: FontWeight.bold,
73 fontFamily: 'Lato',
73 - color: Theme.of(context).accentTextTheme.display3.backgroundColor),
74 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!),
75 );
76 }
77
@@ -89,19 +90,23 @@ class ReceivePage extends BasePage {
90 Widget trailing(BuildContext context) {
91 final shareImage =
92 Image.asset('assets/images/share.png',
92 - color: Theme.of(context).accentTextTheme.display3.backgroundColor);
93 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!);
94
95 return SizedBox(
96 height: 20.0,
97 width: 20.0,
98 child: ButtonTheme(
99 minWidth: double.minPositive,
99 - child: FlatButton(
100 - highlightColor: Colors.transparent,
101 - splashColor: Colors.transparent,
102 - padding: EdgeInsets.all(0),
103 - onPressed: () => Share.text(S.current.share_address,
104 - addressListViewModel.address.address, 'text/plain'),
100 + child: TextButton(
101 + // FIX-ME: Style
102 + //highlightColor: Colors.transparent,
103 + //splashColor: Colors.transparent,
104 + //padding: EdgeInsets.all(0),
105 + onPressed: () {
106 + // FIX-ME: Share esys_flutter_share.dart
107 + // Share.text(S.current.share_address,
108 + // addressListViewModel.address.address, 'text/plain')
109 + },
110 child: shareImage),
111 ),
112 );
@@ -113,8 +118,8 @@ class ReceivePage extends BasePage {
118 ? KeyboardActions(
119 config: KeyboardActionsConfig(
120 keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
116 - keyboardBarColor: Theme.of(context).accentTextTheme.body2
117 - .backgroundColor,
121 + keyboardBarColor: Theme.of(context).accentTextTheme!.bodyText1!
122 + .backgroundColor!,
123 nextFocus: false,
124 actions: [
125 KeyboardActionsItem(
@@ -156,7 +161,7 @@ class ReceivePage extends BasePage {
161 Icons.arrow_forward_ios,
162 size: 14,
163 color:
159 - Theme.of(context).textTheme.display1.color,
164 + Theme.of(context).textTheme!.headline4!.color!,
165 ));
166 }
167
@@ -169,7 +174,7 @@ class ReceivePage extends BasePage {
174 Icons.add,
175 size: 20,
176 color:
172 - Theme.of(context).textTheme.display1.color,
177 + Theme.of(context).textTheme!.headline4!.color!,
178 ));
179 }
180
@@ -179,16 +184,16 @@ class ReceivePage extends BasePage {
184 addressListViewModel.address.address;
185 final backgroundColor = isCurrent
186 ? Theme.of(context)
182 - .textTheme
183 - .display3
184 - .decorationColor
187 + .textTheme!
188 + .headline2!
189 + .decorationColor!
190 : Theme.of(context)
186 - .textTheme
187 - .display2
188 - .decorationColor;
191 + .textTheme!
192 + .headline3!
193 + .decorationColor!;
194 final textColor = isCurrent
190 - ? Theme.of(context).textTheme.display3.color
191 - : Theme.of(context).textTheme.display2.color;
195 + ? Theme.of(context).textTheme!.headline2!.color!
196 + : Theme.of(context).textTheme!.headline3!.color!;
197
198 return AddressCell.fromItem(item,
199 isCurrent: isCurrent,
@@ -233,9 +238,9 @@ class ReceivePage extends BasePage {
238 style: TextStyle(
239 fontSize: 15,
240 color: Theme.of(context)
236 - .accentTextTheme
237 - .display2
238 - .backgroundColor)),
241 + .accentTextTheme!
242 + .headline3!
243 + .backgroundColor!)),
244 ],
245 ),
246 );
lib/src/screens/receive/widgets/address_cell.dart
+34 -33
@@ -4,15 +4,25 @@ import 'package:cake_wallet/generated/i18n.dart';
4 import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_item.dart';
5
6 class AddressCell extends StatelessWidget {
7 + AddressCell(
8 + {required this.address,
9 + required this.name,
10 + required this.isCurrent,
11 + required this.isPrimary,
12 + required this.backgroundColor,
13 + required this.textColor,
14 + this.onTap,
15 + this.onEdit});
16 +
17 factory AddressCell.fromItem(WalletAddressListItem item,
8 - {@required bool isCurrent,
9 - @required Color backgroundColor,
10 - @required Color textColor,
11 - Function(String) onTap,
12 - Function() onEdit}) =>
18 + {required bool isCurrent,
19 + required Color backgroundColor,
20 + required Color textColor,
21 + Function(String)? onTap,
22 + Function()? onEdit}) =>
23 AddressCell(
24 address: item.address,
15 - name: item.name,
25 + name: item.name ?? '',
26 isCurrent: isCurrent,
27 isPrimary: item.isPrimary,
28 backgroundColor: backgroundColor,
@@ -20,24 +30,14 @@ class AddressCell extends StatelessWidget {
30 onTap: onTap,
31 onEdit: onEdit);
32
23 - AddressCell(
24 - {@required this.address,
25 - @required this.name,
26 - @required this.isCurrent,
27 - @required this.isPrimary,
28 - @required this.backgroundColor,
29 - @required this.textColor,
30 - this.onTap,
31 - this.onEdit});
32 -
33 final String address;
34 final String name;
35 final bool isCurrent;
36 final bool isPrimary;
37 final Color backgroundColor;
38 final Color textColor;
39 - final Function(String) onTap;
40 - final Function() onEdit;
39 + final Function(String)? onTap;
40 + final Function()? onEdit;
41
42 String get label {
43 if (name.isEmpty){
@@ -55,7 +55,7 @@ class AddressCell extends StatelessWidget {
55 @override
56 Widget build(BuildContext context) {
57 final Widget cell = InkWell(
58 - onTap: () => onTap(address),
58 + onTap: () => onTap?.call(address),
59 child: Container(
60 color: backgroundColor,
61 padding: EdgeInsets.only(left: 24, right: 24, top: 28, bottom: 28),
@@ -69,19 +69,20 @@ class AddressCell extends StatelessWidget {
69 ),
70 ),
71 ));
72 -
73 - return Container(
74 - color: backgroundColor,
75 - child: Slidable(
76 - key: Key(address),
77 - actionPane: SlidableDrawerActionPane(),
78 - child: cell,
79 - secondaryActions: <Widget>[
80 - IconSlideAction(
81 - caption: S.of(context).edit,
82 - color: Colors.blue,
83 - icon: Icons.edit,
84 - onTap: () => onEdit?.call())
85 - ]));
72 + // FIX-ME: Slidable
73 + return cell;
74 + // return Container(
75 + // color: backgroundColor,
76 + // child: Slidable(
77 + // key: Key(address),
78 + // actionPane: SlidableDrawerActionPane(),
79 + // child: cell,
80 + // secondaryActions: <Widget>[
81 + // IconSlideAction(
82 + // caption: S.of(context).edit,
83 + // color: Colors.blue,
84 + // icon: Icons.edit,
85 + // onTap: () => onEdit?.call())
86 + // ]));
87 }
88 }
lib/src/screens/receive/widgets/header_tile.dart
+6 -6
@@ -2,9 +2,9 @@ import 'package:flutter/material.dart';
2
3 class HeaderTile extends StatelessWidget {
4 HeaderTile({
5 - @required this.onTap,
6 - @required this.title,
7 - @required this.icon
5 + required this.onTap,
6 + required this.title,
7 + required this.icon
8 });
9
10 final VoidCallback onTap;
@@ -22,7 +22,7 @@ class HeaderTile extends StatelessWidget {
22 top: 24,
23 bottom: 24
24 ),
25 - color: Theme.of(context).textTheme.display2.decorationColor,
25 + color: Theme.of(context).textTheme!.headline3!.decorationColor!,
26 child: Row(
27 mainAxisSize: MainAxisSize.max,
28 mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -32,7 +32,7 @@ class HeaderTile extends StatelessWidget {
32 style: TextStyle(
33 fontSize: 18,
34 fontWeight: FontWeight.w600,
35 - color: Theme.of(context).textTheme.display2.color
35 + color: Theme.of(context).textTheme!.headline3!.color!
36 ),
37 ),
38 Container(
@@ -40,7 +40,7 @@ class HeaderTile extends StatelessWidget {
40 width: 32,
41 decoration: BoxDecoration(
42 shape: BoxShape.circle,
43 - color: Theme.of(context).textTheme.display1.decorationColor
43 + color: Theme.of(context).textTheme!.headline4!.decorationColor!
44 ),
45 child: icon,
46 )
lib/src/screens/receive/widgets/qr_image.dart
+3 -3
@@ -4,16 +4,16 @@ import 'package:cake_wallet/src/screens/receive/widgets/qr_painter.dart';
4
5 class QrImage extends StatelessWidget {
6 QrImage({
7 - @required String data,
7 + required String data,
8 this.size = 100.0,
9 this.backgroundColor,
10 Color foregroundColor = Colors.black,
11 - int version = 7,
11 + int version = 9, // Previous value: 7 something happened after flutter upgrade monero wallets addresses are longer than ver. 7 ???
12 int errorCorrectionLevel = QrErrorCorrectLevel.L,
13 }) : _painter = QrPainter(data, foregroundColor, version, errorCorrectionLevel);
14
15 final QrPainter _painter;
16 - final Color backgroundColor;
16 + final Color? backgroundColor;
17 final double size;
18
19 @override
lib/src/screens/receive/widgets/qr_painter.dart
+4 -4
@@ -7,11 +7,10 @@ class QrPainter extends CustomPainter {
7 this.color,
8 this.version,
9 this.errorCorrectionLevel,
10 - ) : this._qr = QrCode(version, errorCorrectionLevel) {
10 + ) : this._qr = QrCode(version, errorCorrectionLevel)..addData(data) {
11 _p.color = this.color;
12 -
12 _qr.addData(data);
14 - _qr.make();
13 + _qrImage = QrImage(_qr);
14 }
15
16 final int version;
@@ -20,13 +19,14 @@ class QrPainter extends CustomPainter {
19
20 final QrCode _qr;
21 final _p = Paint()..style = PaintingStyle.fill;
22 + late QrImage _qrImage;
23
24 @override
25 void paint(Canvas canvas, Size size) {
26 final squareSize = size.shortestSide / _qr.moduleCount;
27 for (int x = 0; x < _qr.moduleCount; x++) {
28 for (int y = 0; y < _qr.moduleCount; y++) {
29 - if (_qr.isDark(y, x)) {
29 + if (_qrImage.isDark(y, x)) {
30 final squareRect = Rect.fromLTWH(
31 x * squareSize, y * squareSize, squareSize, squareSize);
32 canvas.drawRect(squareRect, _p);
lib/src/screens/receive/widgets/qr_widget.dart
+15 -14
@@ -13,27 +13,27 @@ import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_v
13
14 class QRWidget extends StatelessWidget {
15 QRWidget(
16 - {@required this.addressListViewModel,
16 + {required this.addressListViewModel,
17 + required this.isLight,
18 this.isAmountFieldShow = false,
18 - this.amountTextFieldFocusNode,
19 - this.isLight})
19 + this.amountTextFieldFocusNode})
20 : amountController = TextEditingController(),
21 _formKey = GlobalKey<FormState>() {
22 amountController.addListener(() => addressListViewModel.amount =
23 - _formKey.currentState.validate() ? amountController.text : '');
23 + _formKey.currentState!.validate() ? amountController.text : '');
24 }
25
26 final WalletAddressListViewModel addressListViewModel;
27 final bool isAmountFieldShow;
28 final TextEditingController amountController;
29 - final FocusNode amountTextFieldFocusNode;
29 + final FocusNode? amountTextFieldFocusNode;
30 final GlobalKey<FormState> _formKey;
31 final bool isLight;
32
33 @override
34 Widget build(BuildContext context) {
35 final copyImage = Image.asset('assets/images/copy_address.png',
36 - color: Theme.of(context).textTheme.subhead.decorationColor);
36 + color: Theme.of(context).textTheme!.subtitle1!.decorationColor!);
37
38 return Column(
39 mainAxisSize: MainAxisSize.min,
@@ -49,7 +49,7 @@ class QRWidget extends StatelessWidget {
49 style: TextStyle(
50 fontSize: 14,
51 fontWeight: FontWeight.w500,
52 - color: Theme.of(context).accentTextTheme.display3.backgroundColor),
52 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!),
53 ),
54 ),
55 Row(
@@ -86,13 +86,13 @@ class QRWidget extends StatelessWidget {
86 decoration: BoxDecoration(
87 border: Border.all(
88 width: 3,
89 - color: Theme.of(context).accentTextTheme.display3.backgroundColor,
89 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
90 ),
91 ),
92 child: QrImage(
93 data: addressListViewModel.uri.toString(),
94 backgroundColor: isLight ? Colors.transparent : Colors.black,
95 - foregroundColor: Theme.of(context).accentTextTheme.display3.backgroundColor,
95 + foregroundColor: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
96 ),
97 ),
98 ),
@@ -118,13 +118,14 @@ class QRWidget extends StatelessWidget {
118 focusNode: amountTextFieldFocusNode,
119 controller: amountController,
120 keyboardType: TextInputType.numberWithOptions(decimal: true),
121 - inputFormatters: [BlacklistingTextInputFormatter(RegExp('[\\-|\\ ]'))],
121 + inputFormatters: [FilteringTextInputFormatter.deny(RegExp('[\\-|\\ ]'))],
122 textAlign: TextAlign.center,
123 hintText: S.of(context).receive_amount,
124 - textColor: Theme.of(context).accentTextTheme.display3.backgroundColor,
125 - borderColor: Theme.of(context).textTheme.headline.decorationColor,
124 + textColor: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
125 + borderColor: Theme.of(context).textTheme!.headline5!.decorationColor!,
126 validator: AmountValidator(type: addressListViewModel.type, isAutovalidate: true),
127 - autovalidate: true,
127 + // FIX-ME: Check does it equal to autovalidate: true,
128 + autovalidateMode: AutovalidateMode.always,
129 placeholderTextStyle: TextStyle(
130 color: Theme.of(context).hoverColor,
131 fontSize: 18,
@@ -156,7 +157,7 @@ class QRWidget extends StatelessWidget {
157 style: TextStyle(
158 fontSize: 15,
159 fontWeight: FontWeight.w500,
159 - color: Theme.of(context).accentTextTheme.display3.backgroundColor),
160 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!),
161 ),
162 ),
163 Padding(
lib/src/screens/rescan/rescan_page.dart
+2 -2
@@ -32,10 +32,10 @@ class RescanPage extends BasePage {
32 onPressed: () async {
33 await _rescanViewModel.rescanCurrentWallet(
34 restoreHeight:
35 - _blockchainHeightWidgetKey.currentState.height);
35 + _blockchainHeightWidgetKey.currentState!.height);
36 Navigator.of(context).pop();
37 },
38 - color: Theme.of(context).accentTextTheme.body2.color,
38 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
39 textColor: Colors.white,
40 isDisabled: !_rescanViewModel.isButtonEnabled,
41 ))
lib/src/screens/restore/restore_from_backup_page.dart
+2 -2
@@ -71,7 +71,7 @@ class RestoreFromBackupPage extends BasePage {
71 restoreFromBackupViewModel.state is IsExecutingState,
72 onPressed: () => onImportHandler(context),
73 text: S.of(context).import,
74 - color: Theme.of(context).accentTextTheme.body2.color,
74 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
75 textColor: Colors.white);
76 }))
77 ])),
@@ -85,7 +85,7 @@ class RestoreFromBackupPage extends BasePage {
85 return;
86 }
87
88 - restoreFromBackupViewModel.filePath = result.files.first.path;
88 + restoreFromBackupViewModel.filePath = result!.files.first.path!;
89 }
90
91 Future<void> onImportHandler(BuildContext context) async {
lib/src/screens/restore/restore_wallet_from_keys_page.dart
+3 -3
@@ -15,7 +15,7 @@ import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
15
16 class RestoreWalletFromKeysPage extends BasePage {
17 RestoreWalletFromKeysPage(
18 - {@required this.walletRestorationFromKeysVM});
18 + {required this.walletRestorationFromKeysVM});
19
20 final WalletRestorationFromKeysVM walletRestorationFromKeysVM;
21
@@ -190,7 +190,7 @@ class _RestoreFromKeysFromState extends State<RestoreFromKeysFrom> {
190 bottomSection: Observer(builder: (_) {
191 return LoadingPrimaryButton(
192 onPressed: () {
193 - if (_formKey.currentState.validate()) {
193 + if (_formKey.currentState != null && _formKey.currentState!.validate()) {
194 /*walletRestorationStore.restoreFromKeys(
195 name: _nameController.text,
196 language: seedLanguageStore.selectedSeedLanguage,
@@ -201,7 +201,7 @@ class _RestoreFromKeysFromState extends State<RestoreFromKeysFrom> {
201 }
202 },
203 text: S.of(context).restore_recover,
204 - color: Theme.of(context).accentTextTheme.body2.color,
204 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
205 textColor: Colors.white,
206 //isDisabled: walletRestorationStore.disabledState,
207 );
lib/src/screens/restore/restore_wallet_from_seed_details.dart
+6 -6
@@ -15,7 +15,7 @@ import 'package:cake_wallet/view_model/wallet_restoration_from_seed_vm.dart';
15
16 class RestoreWalletFromSeedDetailsPage extends BasePage {
17 RestoreWalletFromSeedDetailsPage(
18 - {@required this.walletRestorationFromSeedVM});
18 + {required this.walletRestorationFromSeedVM});
19
20 final WalletRestorationFromSeedVM walletRestorationFromSeedVM;
21
@@ -28,7 +28,7 @@ class RestoreWalletFromSeedDetailsPage extends BasePage {
28 }
29
30 class RestoreFromSeedDetailsForm extends StatefulWidget {
31 - RestoreFromSeedDetailsForm({@required this.walletRestorationFromSeedVM});
31 + RestoreFromSeedDetailsForm({required this.walletRestorationFromSeedVM});
32
33 final WalletRestorationFromSeedVM walletRestorationFromSeedVM;
34
@@ -42,7 +42,7 @@ class _RestoreFromSeedDetailsFormState
42 final _formKey = GlobalKey<FormState>();
43 final _blockchainHeightKey = GlobalKey<BlockchainHeightState>();
44 final _nameController = TextEditingController();
45 - ReactionDisposer _stateReaction;
45 + ReactionDisposer? _stateReaction;
46
47 @override
48 void initState() {
@@ -75,7 +75,7 @@ class _RestoreFromSeedDetailsFormState
75 @override
76 void dispose() {
77 _nameController.dispose();
78 - _stateReaction.reaction.dispose();
78 + _stateReaction?.reaction.dispose();
79 super.dispose();
80 }
81
@@ -127,14 +127,14 @@ class _RestoreFromSeedDetailsFormState
127 bottomSection: Observer(builder: (_) {
128 return LoadingPrimaryButton(
129 onPressed: () {
130 - if (_formKey.currentState.validate()) {
130 + if (_formKey.currentState != null && _formKey.currentState!.validate()) {
131 widget.walletRestorationFromSeedVM.create();
132 }
133 },
134 isLoading:
135 widget.walletRestorationFromSeedVM.state is IsExecutingState,
136 text: S.of(context).restore_recover,
137 - color: Theme.of(context).accentTextTheme.body2.color,
137 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
138 textColor: Colors.white,
139 isDisabled: _nameController.text.isNotEmpty,
140 );
lib/src/screens/restore/restore_wallet_from_seed_page.dart
+16 -9
@@ -19,7 +19,8 @@ import 'package:cake_wallet/core/mnemonic_length.dart';
19 import 'package:smooth_page_indicator/smooth_page_indicator.dart';
20
21 class RestoreWalletFromSeedPage extends BasePage {
22 - RestoreWalletFromSeedPage({@required this.type});
22 + RestoreWalletFromSeedPage({required this.type})
23 + : _pages = <Widget>[];
24
25 final WalletType type;
26 final String language = 'en';
@@ -51,9 +52,9 @@ class RestoreWalletFromSeedPage extends BasePage {
52
53 void _setPages(BuildContext context) {
54 _pages = <Widget>[
54 - WalletRestoreFromSeedForm(),
55 + // FIX-ME: Added args (displayBlockHeightSelector: true, displayLanguageSelector: true, type: type)
56 + WalletRestoreFromSeedForm(displayBlockHeightSelector: true, displayLanguageSelector: true, type: type),
57 RestoreFromKeysFrom(),
56 - // Container(color: Colors.yellow)
58 ];
59 }
60
@@ -87,7 +88,7 @@ class RestoreWalletFromSeedPage extends BasePage {
88 text: S.of(context).restore_recover,
89 isDisabled: false,
90 onPressed: () => null,
90 - color: Theme.of(context).accentTextTheme.body2.color,
91 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
92 textColor: Colors.white)),
93 ]);
94
@@ -105,7 +106,7 @@ class RestoreWalletFromSeedPage extends BasePage {
106 // text: S.of(context).restore_next,
107 // isDisabled: false,
108 // onPressed: () => null,
108 - // color: Theme.of(context).accentTextTheme.body2.color,
109 + // color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
110 // textColor: Colors.white)
111 // ]),
112 // contentPadding: EdgeInsets.only(bottom: 24),
@@ -135,12 +136,16 @@ class RestoreWalletFromSeedPage extends BasePage {
136
137 class RestoreFromSeedForm extends StatefulWidget {
138 RestoreFromSeedForm(
138 - {Key key, this.type, this.language, this.leading, this.middle})
139 + {Key? key,
140 + required this.type,
141 + this.language,
142 + this.leading,
143 + this.middle})
144 : super(key: key);
145 final WalletType type;
141 - final String language;
142 - final Widget leading;
143 - final Widget middle;
146 + final String? language;
147 + final Widget? leading;
148 + final Widget? middle;
149
150 @override
151 _RestoreFromSeedFormState createState() => _RestoreFromSeedFormState();
@@ -163,6 +168,8 @@ class _RestoreFromSeedFormState extends State<RestoreFromSeedForm> {
168 // height: 300,
169 child: Column(children: [
170 SeedWidget(
171 + type: widget.type,
172 + language: widget.language ?? '',
173 // key: _seedKey,
174 // maxLength: mnemonicLength(widget.type),
175 // onMnemonicChange: (seed) => null,
lib/src/screens/restore/restore_wallet_options_page.dart
+3 -3
@@ -6,9 +6,9 @@ import 'package:cake_wallet/generated/i18n.dart';
6
7 class RestoreWalletOptionsPage extends BasePage {
8 RestoreWalletOptionsPage(
9 - {@required this.type,
10 - @required this.onRestoreFromSeed,
11 - @required this.onRestoreFromKeys});
9 + {required this.type,
10 + required this.onRestoreFromSeed,
11 + required this.onRestoreFromKeys});
12
13 final WalletType type;
14 final Function(BuildContext context) onRestoreFromSeed;
lib/src/screens/restore/wallet_restore_from_keys_form.dart
+8 -5
@@ -12,10 +12,13 @@ import 'package:cake_wallet/core/wallet_name_validator.dart';
12 import 'package:cake_wallet/entities/generate_name.dart';
13
14 class WalletRestoreFromKeysFrom extends StatefulWidget {
15 - WalletRestoreFromKeysFrom({Key key, this.onHeightOrDateEntered, this.walletRestoreViewModel})
15 + WalletRestoreFromKeysFrom({
16 + required this.walletRestoreViewModel,
17 + Key? key,
18 + this.onHeightOrDateEntered,})
19 : super(key: key);
20
18 - final Function(bool) onHeightOrDateEntered;
21 + final Function(bool)? onHeightOrDateEntered;
22 final WalletRestoreViewModel walletRestoreViewModel;
23
24 @override
@@ -87,9 +90,9 @@ class WalletRestoreFromKeysFromState extends State<WalletRestoreFromKeysFrom> {
90 child: Image.asset(
91 'assets/images/refresh_icon.png',
92 color: Theme.of(context)
90 - .primaryTextTheme
91 - .display1
92 - .decorationColor,
93 + .primaryTextTheme!
94 + .headline4!
95 + .decorationColor!,
96 ),
97 ),
98 ),
lib/src/screens/restore/wallet_restore_from_seed_form.dart
+12 -12
@@ -14,10 +14,10 @@ import 'package:cake_wallet/core/wallet_name_validator.dart';
14
15 class WalletRestoreFromSeedForm extends StatefulWidget {
16 WalletRestoreFromSeedForm(
17 - {Key key,
18 - @required this.displayLanguageSelector,
19 - @required this.displayBlockHeightSelector,
20 - @required this.type,
17 + {Key? key,
18 + required this.displayLanguageSelector,
19 + required this.displayBlockHeightSelector,
20 + required this.type,
21 this.blockHeightFocusNode,
22 this.onHeightOrDateEntered,
23 this.onSeedChange,
@@ -27,10 +27,10 @@ class WalletRestoreFromSeedForm extends StatefulWidget {
27 final WalletType type;
28 final bool displayLanguageSelector;
29 final bool displayBlockHeightSelector;
30 - final FocusNode blockHeightFocusNode;
31 - final Function(bool) onHeightOrDateEntered;
32 - final void Function(String) onSeedChange;
33 - final void Function(String) onLanguageChange;
30 + final FocusNode? blockHeightFocusNode;
31 + final Function(bool)? onHeightOrDateEntered;
32 + final void Function(String)? onSeedChange;
33 + final void Function(String)? onLanguageChange;
34
35 @override
36 WalletRestoreFromSeedFormState createState() =>
@@ -94,9 +94,9 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
94 child: Image.asset(
95 'assets/images/refresh_icon.png',
96 color: Theme.of(context)
97 - .primaryTextTheme
98 - .display1
99 - .decorationColor,
97 + .primaryTextTheme!
98 + .headline4!
99 + .decorationColor!,
100 ),
101 ),
102 ),
@@ -144,7 +144,7 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
144 void _changeLanguage(String language) {
145 setState(() {
146 this.language = language;
147 - seedWidgetStateKey.currentState.changeSeedLanguage(language);
147 + seedWidgetStateKey.currentState!.changeSeedLanguage(language);
148 _setLanguageLabel(language);
149 widget.onLanguageChange?.call(language);
150 });
lib/src/screens/restore/wallet_restore_page.dart
+36 -42
@@ -38,7 +38,7 @@ class WalletRestorePage extends BasePage {
38 walletRestoreViewModel.hasBlockchainHeightLanguageSelector,
39 displayLanguageSelector:
40 walletRestoreViewModel.hasSeedLanguageSelector,
41 - type: walletRestoreViewModel.type,
41 + type: walletRestoreViewModel.type!,
42 key: walletRestoreFromSeedFormKey,
43 blockHeightFocusNode: _blockHeightFocusNode,
44 onHeightOrDateEntered: (value) {
@@ -49,10 +49,7 @@ class WalletRestorePage extends BasePage {
49 onSeedChange: (String seed) {
50 if (walletRestoreViewModel.hasBlockchainHeightLanguageSelector) {
51 final hasHeight = walletRestoreFromSeedFormKey
52 - .currentState
53 - .blockchainHeightKey
54 - .currentState
55 - .restoreHeightController
52 + .currentState!.blockchainHeightKey.currentState!.restoreHeightController
53 .text
54 .isNotEmpty;
55 if (hasHeight) {
@@ -65,10 +62,7 @@ class WalletRestorePage extends BasePage {
62 onLanguageChange: (_) {
63 if (walletRestoreViewModel.hasBlockchainHeightLanguageSelector) {
64 final hasHeight = walletRestoreFromSeedFormKey
68 - .currentState
69 - .blockchainHeightKey
70 - .currentState
71 - .restoreHeightController
65 + .currentState!.blockchainHeightKey.currentState!.restoreHeightController
66 .text
67 .isNotEmpty;
68
@@ -104,7 +98,7 @@ class WalletRestorePage extends BasePage {
98 fontWeight: FontWeight.bold,
99 fontFamily: 'Lato',
100 color: titleColor ??
107 - Theme.of(context).primaryTextTheme.title.color),
101 + Theme.of(context).primaryTextTheme!.headline6!.color!),
102 ));
103
104 final WalletRestoreViewModel walletRestoreViewModel;
@@ -135,24 +129,24 @@ class WalletRestorePage extends BasePage {
129 reaction((_) => walletRestoreViewModel.mode, (WalletRestoreMode mode) {
130 walletRestoreViewModel.isButtonEnabled = false;
131
138 - walletRestoreFromSeedFormKey.currentState.blockchainHeightKey.currentState
139 - .restoreHeightController.text = '';
140 - walletRestoreFromSeedFormKey.currentState.blockchainHeightKey.currentState
141 - .dateController.text = '';
142 - walletRestoreFromSeedFormKey.currentState.nameTextEditingController.text = '';
132 + walletRestoreFromSeedFormKey.currentState!.blockchainHeightKey.currentState
133 + !.restoreHeightController.text = '';
134 + walletRestoreFromSeedFormKey.currentState!.blockchainHeightKey.currentState
135 + !.dateController.text = '';
136 + walletRestoreFromSeedFormKey.currentState!.nameTextEditingController.text = '';
137
144 - walletRestoreFromKeysFormKey.currentState.blockchainHeightKey.currentState
145 - .restoreHeightController.text = '';
146 - walletRestoreFromKeysFormKey.currentState.blockchainHeightKey.currentState
147 - .dateController.text = '';
148 - walletRestoreFromKeysFormKey.currentState.nameTextEditingController.text = '';
138 + walletRestoreFromKeysFormKey.currentState!.blockchainHeightKey.currentState
139 + !.restoreHeightController.text = '';
140 + walletRestoreFromKeysFormKey.currentState!.blockchainHeightKey.currentState
141 + !.dateController.text = '';
142 + walletRestoreFromKeysFormKey.currentState!.nameTextEditingController.text = '';
143 });
144
145 return KeyboardActions(
146 config: KeyboardActionsConfig(
147 keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
154 - keyboardBarColor: Theme.of(context).accentTextTheme.body2
155 - .backgroundColor,
148 + keyboardBarColor: Theme.of(context).accentTextTheme!.bodyText1!
149 + .backgroundColor!,
150 nextFocus: false,
151 actions: [
152 KeyboardActionsItem(
@@ -196,9 +190,9 @@ class WalletRestorePage extends BasePage {
190 onPressed: _confirmForm,
191 text: S.of(context).restore_recover,
192 color:
199 - Theme.of(context).accentTextTheme.subtitle.decorationColor,
193 + Theme.of(context).accentTextTheme!.subtitle2!.decorationColor!,
194 textColor:
201 - Theme.of(context).accentTextTheme.headline.decorationColor,
195 + Theme.of(context).accentTextTheme!.headline5!.decorationColor!,
196 isLoading: walletRestoreViewModel.state is IsExecutingState,
197 isDisabled: !walletRestoreViewModel.isButtonEnabled,
198 );
@@ -210,9 +204,9 @@ class WalletRestorePage extends BasePage {
204 bool _isValidSeed() {
205 final seedWords = walletRestoreFromSeedFormKey
206 .currentState
213 - .seedWidgetStateKey
207 + !.seedWidgetStateKey
208 .currentState
215 - .text
209 + !.text
210 .split(' ');
211
212 if ((walletRestoreViewModel.type == WalletType.monero || walletRestoreViewModel.type == WalletType.haven) &&
@@ -229,9 +223,9 @@ class WalletRestorePage extends BasePage {
223
224 final words = walletRestoreFromSeedFormKey
225 .currentState
232 - .seedWidgetStateKey
226 + !.seedWidgetStateKey
227 .currentState
234 - .words
228 + !.words
229 .toSet();
230 return seedWords
231 .toSet()
@@ -245,24 +239,24 @@ class WalletRestorePage extends BasePage {
239
240 if (walletRestoreViewModel.mode == WalletRestoreMode.seed) {
241 credentials['seed'] = walletRestoreFromSeedFormKey
248 - .currentState.seedWidgetStateKey.currentState.text;
242 + .currentState!.seedWidgetStateKey.currentState!.text;
243
244 if (walletRestoreViewModel.hasBlockchainHeightLanguageSelector) {
245 credentials['height'] = walletRestoreFromSeedFormKey
252 - .currentState.blockchainHeightKey.currentState.height;
246 + .currentState!.blockchainHeightKey.currentState!.height;
247 }
248
255 - credentials['name'] = walletRestoreFromSeedFormKey.currentState.nameTextEditingController.text;
249 + credentials['name'] = walletRestoreFromSeedFormKey.currentState!.nameTextEditingController.text;
250 } else {
251 credentials['address'] =
258 - walletRestoreFromKeysFormKey.currentState.addressController.text;
252 + walletRestoreFromKeysFormKey.currentState!.addressController.text;
253 credentials['viewKey'] =
260 - walletRestoreFromKeysFormKey.currentState.viewKeyController.text;
254 + walletRestoreFromKeysFormKey.currentState!.viewKeyController.text;
255 credentials['spendKey'] =
262 - walletRestoreFromKeysFormKey.currentState.spendKeyController.text;
256 + walletRestoreFromKeysFormKey.currentState!.spendKeyController.text;
257 credentials['height'] = walletRestoreFromKeysFormKey
264 - .currentState.blockchainHeightKey.currentState.height;
265 - credentials['name'] = walletRestoreFromKeysFormKey.currentState.nameTextEditingController.text;
258 + .currentState!.blockchainHeightKey.currentState!.height;
259 + credentials['name'] = walletRestoreFromKeysFormKey.currentState!.nameTextEditingController.text;
260 }
261
262 return credentials;
@@ -274,21 +268,21 @@ class WalletRestorePage extends BasePage {
268 : walletRestoreFromKeysFormKey.currentContext;
269
270 final formKey = walletRestoreViewModel.mode == WalletRestoreMode.seed
277 - ? walletRestoreFromSeedFormKey.currentState.formKey
278 - : walletRestoreFromKeysFormKey.currentState.formKey;
271 + ? walletRestoreFromSeedFormKey.currentState!.formKey
272 + : walletRestoreFromKeysFormKey.currentState!.formKey;
273
274 final name = walletRestoreViewModel.mode == WalletRestoreMode.seed
275 ? walletRestoreFromSeedFormKey
282 - .currentState.nameTextEditingController.value.text
276 + .currentState!.nameTextEditingController.value.text
277 : walletRestoreFromKeysFormKey
284 - .currentState.nameTextEditingController.value.text;
278 + .currentState!.nameTextEditingController.value.text;
279
286 - if (!formKey.currentState.validate()) {
280 + if (!formKey.currentState!.validate()) {
281 return;
282 }
283
284 if (walletRestoreViewModel.nameExists(name)) {
291 - showNameExistsAlert(formContext);
285 + showNameExistsAlert(formContext!);
286 return;
287 }
288
lib/src/screens/restore/widgets/restore_button.dart
+7 -7
@@ -3,10 +3,10 @@ import 'package:flutter/material.dart';
3
4 class RestoreButton extends StatelessWidget {
5 const RestoreButton({
6 - @required this.onPressed,
7 - @required this.image,
8 - @required this.title,
9 - @required this.description});
6 + required this.onPressed,
7 + required this.image,
8 + required this.title,
9 + required this.description});
10
11 final VoidCallback onPressed;
12 final Image image;
@@ -24,7 +24,7 @@ class RestoreButton extends StatelessWidget {
24 alignment: Alignment.topLeft,
25 decoration: BoxDecoration(
26 borderRadius: BorderRadius.all(Radius.circular(12)),
27 - color: Theme.of(context).accentTextTheme.caption.color,
27 + color: Theme.of(context).accentTextTheme!.caption!.color!,
28 ),
29 child: Row(
30 mainAxisSize: MainAxisSize.max,
@@ -45,7 +45,7 @@ class RestoreButton extends StatelessWidget {
45 style: TextStyle(
46 fontSize: 16,
47 fontWeight: FontWeight.w500,
48 - color: Theme.of(context).primaryTextTheme.title.color
48 + color: Theme.of(context).primaryTextTheme!.headline6!.color!
49 ),
50 ),
51 Padding(
@@ -55,7 +55,7 @@ class RestoreButton extends StatelessWidget {
55 style: TextStyle(
56 fontSize: 14,
57 fontWeight: FontWeight.normal,
58 - color: Theme.of(context).primaryTextTheme.overline.color
58 + color: Theme.of(context).primaryTextTheme!.overline!.color!
59 ),
60 ),
61 )
lib/src/screens/root/root.dart
+11 -6
@@ -8,11 +8,11 @@ import 'package:cake_wallet/entities/qr_scanner.dart';
8
9 class Root extends StatefulWidget {
10 Root(
11 - {Key key,
12 - this.authenticationStore,
13 - this.appStore,
14 - this.child,
15 - this.navigatorKey})
11 + {required Key key,
12 + required this.authenticationStore,
13 + required this.appStore,
14 + required this.child,
15 + required this.navigatorKey})
16 : super(key: key);
17
18 final AuthenticationStore authenticationStore;
@@ -25,6 +25,11 @@ class Root extends StatefulWidget {
25 }
26
27 class RootState extends State<Root> with WidgetsBindingObserver {
28 + RootState()
29 + : _isInactiveController = StreamController<bool>.broadcast(),
30 + _isInactive = false,
31 + _postFrameCallback = false;
32 +
33 Stream<bool> get isInactive => _isInactiveController.stream;
34 StreamController<bool> _isInactiveController;
35 bool _isInactive;
@@ -63,7 +68,7 @@ class RootState extends State<Root> with WidgetsBindingObserver {
68 if (_isInactive && !_postFrameCallback) {
69 _postFrameCallback = true;
70 WidgetsBinding.instance.addPostFrameCallback((_) {
66 - widget.navigatorKey.currentState.pushNamed(Routes.unlock,
71 + widget.navigatorKey.currentState?.pushNamed(Routes.unlock,
72 arguments: (bool isAuthenticatedSuccessfully, AuthPageState auth) {
73 if (!isAuthenticatedSuccessfully) {
74 return;
lib/src/screens/seed/pre_seed_page.dart
+6 -6
@@ -21,10 +21,10 @@ class PreSeedPage extends BasePage {
21 final int wordsCount;
22
23 @override
24 - Widget leading(BuildContext context) => null;
24 + Widget? leading(BuildContext context) => null;
25
26 @override
27 - String get title => S.current.pre_seed_title;
27 + String? get title => S.current.pre_seed_title;
28
29 @override
30 Widget body(BuildContext context) {
@@ -57,16 +57,16 @@ class PreSeedPage extends BasePage {
57 fontSize: 14,
58 fontWeight: FontWeight.normal,
59 color: Theme.of(context)
60 - .primaryTextTheme
61 - .caption
62 - .color),
60 + .primaryTextTheme!
61 + .caption!
62 + .color!),
63 ),
64 ),
65 PrimaryButton(
66 onPressed: () => Navigator.of(context)
67 .popAndPushNamed(Routes.seed, arguments: true),
68 text: S.of(context).pre_seed_button_text,
69 - color: Theme.of(context).accentTextTheme.body2.color,
69 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
70 textColor: Colors.white)
71 ],
72 ))
lib/src/screens/seed/wallet_seed_page.dart
+23 -20
@@ -6,7 +6,7 @@ import 'package:cake_wallet/utils/show_pop_up.dart';
6 import 'package:flutter/cupertino.dart';
7 import 'package:flutter/material.dart';
8 import 'package:flutter/services.dart';
9 -import 'package:esys_flutter_share/esys_flutter_share.dart';
9 +// import 'package:esys_flutter_share/esys_flutter_share.dart';
10 import 'package:flutter_mobx/flutter_mobx.dart';
11 import 'package:cake_wallet/generated/i18n.dart';
12 import 'package:cake_wallet/src/widgets/primary_button.dart';
@@ -14,7 +14,7 @@ import 'package:cake_wallet/src/screens/base_page.dart';
14 import 'package:cake_wallet/view_model/wallet_seed_view_model.dart';
15
16 class WalletSeedPage extends BasePage {
17 - WalletSeedPage(this.walletSeedViewModel, {@required this.isNewWalletCreated});
17 + WalletSeedPage(this.walletSeedViewModel, {required this.isNewWalletCreated});
18
19 final imageLight = Image.asset('assets/images/crypto_lock_light.png');
20 final imageDark = Image.asset('assets/images/crypto_lock.png');
@@ -52,7 +52,7 @@ class WalletSeedPage extends BasePage {
52 }
53
54 @override
55 - Widget leading(BuildContext context) =>
55 + Widget? leading(BuildContext context) =>
56 isNewWalletCreated ? Offstage() : super.leading(context);
57
58 @override
@@ -67,7 +67,7 @@ class WalletSeedPage extends BasePage {
67 margin: EdgeInsets.only(left: 10),
68 decoration: BoxDecoration(
69 borderRadius: BorderRadius.all(Radius.circular(16)),
70 - color: Theme.of(context).accentTextTheme.caption.color),
70 + color: Theme.of(context).accentTextTheme!.caption!.color!),
71 child: Text(
72 S.of(context).seed_language_next,
73 style: TextStyle(
@@ -110,9 +110,9 @@ class WalletSeedPage extends BasePage {
110 fontSize: 20,
111 fontWeight: FontWeight.w600,
112 color: Theme.of(context)
113 - .primaryTextTheme
114 - .title
115 - .color),
113 + .primaryTextTheme!
114 + .headline6!
115 + .color!),
116 ),
117 Padding(
118 padding:
@@ -124,9 +124,9 @@ class WalletSeedPage extends BasePage {
124 fontSize: 14,
125 fontWeight: FontWeight.normal,
126 color: Theme.of(context)
127 - .primaryTextTheme
128 - .caption
129 - .color),
127 + .primaryTextTheme!
128 + .caption!
129 + .color!),
130 ),
131 )
132 ],
@@ -146,9 +146,9 @@ class WalletSeedPage extends BasePage {
146 fontSize: 12,
147 fontWeight: FontWeight.normal,
148 color: Theme.of(context)
149 - .primaryTextTheme
150 - .overline
151 - .color),
149 + .primaryTextTheme!
150 + .overline!
151 + .color!),
152 ),
153 )
154 : Offstage(),
@@ -159,10 +159,13 @@ class WalletSeedPage extends BasePage {
159 child: Container(
160 padding: EdgeInsets.only(right: 8.0),
161 child: PrimaryButton(
162 - onPressed: () => Share.text(
163 - S.of(context).seed_share,
164 - walletSeedViewModel.seed,
165 - 'text/plain'),
162 + onPressed: () {
163 + // FIX-ME: Share esys_flutter_share
164 + // Share.text(
165 + // S.of(context).seed_share,
166 + // walletSeedViewModel.seed,
167 + // 'text/plain')
168 + },
169 text: S.of(context).save,
170 color: Colors.green,
171 textColor: Colors.white),
@@ -180,9 +183,9 @@ class WalletSeedPage extends BasePage {
183 },
184 text: S.of(context).copy,
185 color: Theme.of(context)
183 - .accentTextTheme
184 - .body2
185 - .color,
186 + .accentTextTheme!
187 + .bodyText2!
188 + .color!,
189 textColor: Colors.white)),
190 ))
191 ],
lib/src/screens/seed_language/seed_language_page.dart
+4 -4
@@ -10,7 +10,7 @@ import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
10 import 'package:cake_wallet/src/screens/seed_language/widgets/seed_language_picker.dart';
11
12 class SeedLanguage extends BasePage {
13 - SeedLanguage({this.onConfirm});
13 + SeedLanguage({required this.onConfirm});
14
15 final Function(BuildContext, String) onConfirm;
16
@@ -30,7 +30,7 @@ class SeedLanguage extends BasePage {
30 }
31
32 class SeedLanguageForm extends StatefulWidget {
33 - SeedLanguageForm({this.onConfirm, this.walletImage});
33 + SeedLanguageForm({required this.onConfirm, required this.walletImage});
34
35 final Function(BuildContext, String) onConfirm;
36 final Image walletImage;
@@ -66,7 +66,7 @@ class SeedLanguageFormState extends State<SeedLanguageForm> {
66 style: TextStyle(
67 fontSize: 16.0,
68 fontWeight: FontWeight.w500,
69 - color: Theme.of(context).primaryTextTheme.title.color),
69 + color: Theme.of(context).primaryTextTheme!.headline6!.color!),
70 ),
71 ),
72 Padding(
@@ -82,7 +82,7 @@ class SeedLanguageFormState extends State<SeedLanguageForm> {
82 builder: (context) {
83 return PrimaryButton(
84 onPressed: () => widget.onConfirm(
85 - context, _languageSelectorKey.currentState.selected),
85 + context, _languageSelectorKey.currentState!.selected),
86 text: S.of(context).seed_language_next,
87 color: Colors.green,
88 textColor: Colors.white);
lib/src/screens/seed_language/widgets/seed_language_picker.dart
+13 -11
@@ -50,7 +50,9 @@ const List<String> seedLanguages = [
50 enum Places { topLeft, topRight, bottomLeft, bottomRight, inside }
51
52 class SeedLanguagePicker extends StatefulWidget {
53 - SeedLanguagePicker({Key key, this.selected = defaultSeedLanguage})
53 + SeedLanguagePicker({
54 + Key? key,
55 + this.selected = defaultSeedLanguage})
56 : super(key: key);
57
58 final String selected;
@@ -61,7 +63,7 @@ class SeedLanguagePicker extends StatefulWidget {
63 }
64
65 class SeedLanguagePickerState extends State<SeedLanguagePicker> {
64 - SeedLanguagePickerState({this.selected});
66 + SeedLanguagePickerState({required this.selected});
67
68 final closeButton = Image.asset('assets/images/close.png');
69 String selected;
@@ -96,7 +98,7 @@ class SeedLanguagePickerState extends State<SeedLanguagePicker> {
98 height: 300,
99 width: 300,
100 color:
99 - Theme.of(context).accentTextTheme.title.backgroundColor,
101 + Theme.of(context).accentTextTheme!.headline6!.backgroundColor!,
102 child: GridView.count(
103 padding: EdgeInsets.all(0),
104 shrinkWrap: true,
@@ -111,7 +113,7 @@ class SeedLanguagePickerState extends State<SeedLanguagePicker> {
113 isCurrent: false,
114 image: null,
115 text: '',
114 - onTap: null);
116 + onTap: () {});
117 }
118
119 final code = languageCodes[index];
@@ -140,16 +142,16 @@ class SeedLanguagePickerState extends State<SeedLanguagePicker> {
142 }
143
144 Widget gridTile(
143 - {@required bool isCurrent,
144 - @required Image image,
145 - @required String text,
146 - @required VoidCallback onTap}) {
145 + {required bool isCurrent,
146 + required String text,
147 + required VoidCallback onTap,
148 + Image? image}) {
149 final color = isCurrent
148 - ? Theme.of(context).textTheme.body2.color
149 - : Theme.of(context).accentTextTheme.title.color;
150 + ? Theme.of(context).textTheme!.bodyText1!.color!
151 + : Theme.of(context).accentTextTheme!.headline6!.color!;
152 final textColor = isCurrent
153 ? Palette.blueCraiola
152 - : Theme.of(context).primaryTextTheme.title.color;
154 + : Theme.of(context).primaryTextTheme!.headline6!.color!;
155
156 return GestureDetector(
157 onTap: onTap,
lib/src/screens/send/send_page.dart
+42 -34
@@ -28,7 +28,7 @@ import 'package:smooth_page_indicator/smooth_page_indicator.dart';
28 import 'package:cw_core/crypto_currency.dart';
29
30 class SendPage extends BasePage {
31 - SendPage({@required this.sendViewModel,@required this.settingsViewModel }) : _formKey = GlobalKey<FormState>(),fiatFromSettings = settingsViewModel.fiatCurrency;
31 + SendPage({required this.sendViewModel,required this.settingsViewModel }) : _formKey = GlobalKey<FormState>(),fiatFromSettings = settingsViewModel.fiatCurrency;
32
33 final SendViewModel sendViewModel;
34 final SettingsViewModel settingsViewModel;
@@ -60,15 +60,20 @@ class SendPage extends BasePage {
60 }
61
62 @override
63 - Widget middle(BuildContext context) => Row(
63 + Widget? middle(BuildContext context) {
64 + final supMiddle = super.middle(context);
65 + return Row(
66 mainAxisAlignment: MainAxisAlignment.center,
67 children: [
68 Padding(
69 padding: const EdgeInsets.only(right:8.0),
70 child: Observer(builder: (_) => SyncIndicatorIcon(isSynced: sendViewModel.isReadyForSend),),
69 - ),super.middle(context),
71 + ),
72 + if (supMiddle != null)
73 + supMiddle
74 ],
75 );
76 + }
77
78 @override
79 Widget trailing(context) => Observer(builder: (_) {
@@ -76,7 +81,7 @@ class SendPage extends BasePage {
81 ? TrailButton(
82 caption: S.of(context).remove,
83 onPressed: () {
79 - var pageToJump = controller.page.round() - 1;
84 + var pageToJump = (controller.page?.round() ?? 0) - 1;
85 pageToJump = pageToJump > 0 ? pageToJump : 0;
86 final output = _defineCurrentOutput();
87 sendViewModel.removeOutput(output);
@@ -86,7 +91,7 @@ class SendPage extends BasePage {
91 caption: S.of(context).clear,
92 onPressed: () {
93 final output = _defineCurrentOutput();
89 - _formKey.currentState.reset();
94 + _formKey.currentState?.reset();
95 output.reset();
96 });
97 });
@@ -139,13 +144,13 @@ class SendPage extends BasePage {
144 dotWidth: 6.0,
145 dotHeight: 6.0,
146 dotColor: Theme.of(context)
142 - .primaryTextTheme
143 - .display2
144 - .backgroundColor,
147 + .primaryTextTheme!
148 + .headline3!
149 + .backgroundColor!,
150 activeDotColor: Theme.of(context)
146 - .primaryTextTheme
147 - .display3
148 - .backgroundColor),
151 + .primaryTextTheme!
152 + .headline2!
153 + .backgroundColor!),
154 )
155 : Offstage();
156 },
@@ -175,9 +180,9 @@ class SendPage extends BasePage {
180 borderType: BorderType.RRect,
181 dashPattern: [6, 4],
182 color: Theme.of(context)
178 - .primaryTextTheme
179 - .headline2
180 - .decorationColor,
183 + .primaryTextTheme!
184 + .headline2!
185 + .decorationColor!,
186 strokeWidth: 2,
187 radius: Radius.circular(20),
188 child: Container(
@@ -193,9 +198,9 @@ class SendPage extends BasePage {
198 ? Icon(
199 Icons.add,
200 color: Theme.of(context)
196 - .primaryTextTheme
197 - .display3
198 - .color,
201 + .primaryTextTheme!
202 + .headline2!
203 + .color!,
204 )
205 : Text(
206 S.of(context).new_template,
@@ -203,9 +208,9 @@ class SendPage extends BasePage {
208 fontSize: 14,
209 fontWeight: FontWeight.w600,
210 color: Theme.of(context)
206 - .primaryTextTheme
207 - .display3
208 - .color,
211 + .primaryTextTheme!
212 + .headline2!
213 + .color!,
214 ),
215 ),
216 ),
@@ -284,9 +289,9 @@ class SendPage extends BasePage {
289 text: 'Change your asset (${sendViewModel.selectedCryptoCurrency})',
290 color: Colors.transparent,
291 textColor: Theme.of(context)
287 - .accentTextTheme
288 - .display2
289 - .decorationColor,
292 + .accentTextTheme!
293 + .headline3!
294 + .decorationColor!,
295 )
296 )
297 ),
@@ -303,20 +308,20 @@ class SendPage extends BasePage {
308 text: S.of(context).add_receiver,
309 color: Colors.transparent,
310 textColor: Theme.of(context)
306 - .accentTextTheme
307 - .display2
308 - .decorationColor,
311 + .accentTextTheme!
312 + .headline3!
313 + .decorationColor!,
314 isDottedBorder: true,
315 borderColor: Theme.of(context)
311 - .primaryTextTheme
312 - .display2
313 - .decorationColor,
316 + .primaryTextTheme!
317 + .headline3!
318 + .decorationColor!,
319 )),
320 Observer(
321 builder: (_) {
322 return LoadingPrimaryButton(
323 onPressed: () async {
319 - if (!_formKey.currentState.validate()) {
324 + if (_formKey.currentState != null && !_formKey.currentState!.validate()) {
325 if (sendViewModel.outputs.length > 1) {
326 showErrorValidationAlert(context);
327 }
@@ -338,7 +343,7 @@ class SendPage extends BasePage {
343
344 },
345 text: S.of(context).send,
341 - color: Theme.of(context).accentTextTheme.body2.color,
346 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
347 textColor: Colors.white,
348 isLoading: sendViewModel.state is IsExecutingState ||
349 sendViewModel.state is TransactionCommitting,
@@ -380,13 +385,13 @@ class SendPage extends BasePage {
385 alertTitle: S.of(context).confirm_sending,
386 amount: S.of(context).send_amount,
387 amountValue:
383 - sendViewModel.pendingTransaction.amountFormatted,
388 + sendViewModel.pendingTransaction!.amountFormatted,
389 fiatAmountValue:
390 sendViewModel.pendingTransactionFiatAmount +
391 ' ' +
392 sendViewModel.fiat.title,
393 fee: S.of(context).send_fee,
389 - feeValue: sendViewModel.pendingTransaction.feeFormatted,
394 + feeValue: sendViewModel.pendingTransaction!.feeFormatted,
395 feeFiatAmount:
396 sendViewModel.pendingTransactionFeeFiatAmount +
397 ' ' +
@@ -437,7 +442,10 @@ class SendPage extends BasePage {
442 }
443
444 Output _defineCurrentOutput() {
440 - final itemCount = controller.page.round();
445 + if (controller.page == null) {
446 + throw Exception('Controller page is null');
447 + }
448 + final itemCount = controller.page!.round();
449 return sendViewModel.outputs[itemCount];
450 }
451
lib/src/screens/send/send_template_page.dart
+32 -32
@@ -16,7 +16,7 @@ import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
16 import 'package:cake_wallet/src/screens/send/widgets/prefix_currency_icon_widget.dart';
17
18 class SendTemplatePage extends BasePage {
19 - SendTemplatePage({@required this.sendTemplateViewModel}) {
19 + SendTemplatePage({required this.sendTemplateViewModel}) {
20 sendTemplateViewModel.output.reset();
21 }
22
@@ -51,7 +51,7 @@ class SendTemplatePage extends BasePage {
51 config: KeyboardActionsConfig(
52 keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
53 keyboardBarColor:
54 - Theme.of(context).accentTextTheme.body2.backgroundColor,
54 + Theme.of(context).accentTextTheme!.bodyText1!.backgroundColor!,
55 nextFocus: false,
56 actions: [
57 KeyboardActionsItem(
@@ -75,8 +75,8 @@ class SendTemplatePage extends BasePage {
75 bottomRight: Radius.circular(24),
76 ),
77 gradient: LinearGradient(colors: [
78 - Theme.of(context).primaryTextTheme.subhead.color,
79 - Theme.of(context).primaryTextTheme.subhead.decorationColor,
78 + Theme.of(context).primaryTextTheme!.subtitle1!.color!,
79 + Theme.of(context).primaryTextTheme!.subtitle1!.decorationColor!,
80 ], begin: Alignment.topLeft, end: Alignment.bottomRight),
81 ),
82 child: Form(
@@ -91,18 +91,18 @@ class SendTemplatePage extends BasePage {
91 controller: _nameController,
92 hintText: S.of(context).send_name,
93 borderColor: Theme.of(context)
94 - .primaryTextTheme
95 - .headline
96 - .color,
94 + .primaryTextTheme!
95 + .headline5!
96 + .color!,
97 textStyle: TextStyle(
98 fontSize: 14,
99 fontWeight: FontWeight.w500,
100 color: Colors.white),
101 placeholderTextStyle: TextStyle(
102 color: Theme.of(context)
103 - .primaryTextTheme
104 - .headline
105 - .decorationColor,
103 + .primaryTextTheme!
104 + .headline5!
105 + .decorationColor!,
106 fontWeight: FontWeight.w500,
107 fontSize: 14),
108 validator: sendTemplateViewModel.templateValidator,
@@ -122,13 +122,13 @@ class SendTemplatePage extends BasePage {
122 AddressTextFieldOption.addressBook
123 ],
124 buttonColor: Theme.of(context)
125 - .primaryTextTheme
126 - .display1
127 - .color,
125 + .primaryTextTheme!
126 + .headline4!
127 + .color!,
128 borderColor: Theme.of(context)
129 - .primaryTextTheme
130 - .headline
131 - .color,
129 + .primaryTextTheme!
130 + .headline5!
131 + .color!,
132 textStyle: TextStyle(
133 fontSize: 14,
134 fontWeight: FontWeight.w500,
@@ -137,9 +137,9 @@ class SendTemplatePage extends BasePage {
137 fontSize: 14,
138 fontWeight: FontWeight.w500,
139 color: Theme.of(context)
140 - .primaryTextTheme
141 - .headline
142 - .decorationColor),
140 + .primaryTextTheme!
141 + .headline5!
142 + .decorationColor!),
143 ),
144 ),
145 Padding(
@@ -169,18 +169,18 @@ class SendTemplatePage extends BasePage {
169 )),
170 hintText: '0.0000',
171 borderColor: Theme.of(context)
172 - .primaryTextTheme
173 - .headline
174 - .color,
172 + .primaryTextTheme!
173 + .headline5!
174 + .color!,
175 textStyle: TextStyle(
176 fontSize: 14,
177 fontWeight: FontWeight.w500,
178 color: Colors.white),
179 placeholderTextStyle: TextStyle(
180 color: Theme.of(context)
181 - .primaryTextTheme
182 - .headline
183 - .decorationColor,
181 + .primaryTextTheme!
182 + .headline5!
183 + .decorationColor!,
184 fontWeight: FontWeight.w500,
185 fontSize: 14),
186 validator:
@@ -211,18 +211,18 @@ class SendTemplatePage extends BasePage {
211 )),
212 hintText: '0.00',
213 borderColor: Theme.of(context)
214 - .primaryTextTheme
215 - .headline
216 - .color,
214 + .primaryTextTheme!
215 + .headline5!
216 + .color!,
217 textStyle: TextStyle(
218 fontSize: 14,
219 fontWeight: FontWeight.w500,
220 color: Colors.white),
221 placeholderTextStyle: TextStyle(
222 color: Theme.of(context)
223 - .primaryTextTheme
224 - .headline
225 - .decorationColor,
223 + .primaryTextTheme!
224 + .headline5!
225 + .decorationColor!,
226 fontWeight: FontWeight.w500,
227 fontSize: 14),
228 ))),
@@ -237,7 +237,7 @@ class SendTemplatePage extends BasePage {
237 EdgeInsets.only(left: 24, right: 24, bottom: 24),
238 bottomSection: PrimaryButton(
239 onPressed: () {
240 - if (_formKey.currentState.validate()) {
240 + if (_formKey.currentState != null && _formKey.currentState!.validate()) {
241 sendTemplateViewModel.addTemplate(
242 isCurrencySelected: sendTemplateViewModel.isCurrencySelected,
243 name: _nameController.text,
lib/src/screens/send/widgets/choose_yat_address_alert.dart
+5 -5
@@ -4,9 +4,9 @@ import 'package:cake_wallet/src/widgets/base_alert_dialog.dart';
4
5 class ChooseYatAddressAlert extends BaseAlertDialog {
6 ChooseYatAddressAlert({
7 - @required this.alertTitle,
8 - @required this.alertContent,
9 - @required this.addresses,
7 + required this.alertTitle,
8 + required this.alertContent,
9 + required this.addresses,
10 });
11
12 final String alertTitle;
@@ -65,7 +65,7 @@ class ChooseYatAddressButtonsState extends State<ChooseYatAddressButtons> {
65 Container(
66 width: 300,
67 height: 158,
68 - color: Theme.of(context).accentTextTheme.body1.backgroundColor,
68 + color: Theme.of(context).accentTextTheme!.bodyText2!.backgroundColor!,
69 child: ListView.separated(
70 controller: controller,
71 padding: EdgeInsets.all(0),
@@ -97,7 +97,7 @@ class ChooseYatAddressButtonsState extends State<ChooseYatAddressButtons> {
97 fontSize: 15,
98 fontWeight: FontWeight.w600,
99 fontFamily: 'Lato',
100 - color: Theme.of(context).primaryTextTheme.title.color,
100 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
101 decoration: TextDecoration.none,
102 ),
103 )
lib/src/screens/send/widgets/confirm_sending_alert.dart
+38 -43
@@ -7,18 +7,18 @@ import 'package:cake_wallet/src/widgets/cake_scrollbar.dart';
7
8 class ConfirmSendingAlert extends BaseAlertDialog {
9 ConfirmSendingAlert({
10 - @required this.alertTitle,
11 - @required this.amount,
12 - @required this.amountValue,
13 - @required this.fiatAmountValue,
14 - @required this.fee,
15 - @required this.feeValue,
16 - @required this.feeFiatAmount,
17 - @required this.outputs,
18 - @required this.leftButtonText,
19 - @required this.rightButtonText,
20 - @required this.actionLeftButton,
21 - @required this.actionRightButton,
10 + required this.alertTitle,
11 + required this.amount,
12 + required this.amountValue,
13 + required this.fiatAmountValue,
14 + required this.fee,
15 + required this.feeValue,
16 + required this.feeFiatAmount,
17 + required this.outputs,
18 + required this.leftButtonText,
19 + required this.rightButtonText,
20 + required this.actionLeftButton,
21 + required this.actionRightButton,
22 this.alertBarrierDismissible = true});
23
24 final String alertTitle;
@@ -70,13 +70,13 @@ class ConfirmSendingAlert extends BaseAlertDialog {
70
71 class ConfirmSendingAlertContent extends StatefulWidget {
72 ConfirmSendingAlertContent({
73 - @required this.amount,
74 - @required this.amountValue,
75 - @required this.fiatAmountValue,
76 - @required this.fee,
77 - @required this.feeValue,
78 - @required this.feeFiatAmount,
79 - @required this.outputs});
73 + required this.amount,
74 + required this.amountValue,
75 + required this.fiatAmountValue,
76 + required this.fee,
77 + required this.feeValue,
78 + required this.feeFiatAmount,
79 + required this.outputs});
80
81 final String amount;
82 final String amountValue;
@@ -100,14 +100,15 @@ class ConfirmSendingAlertContent extends StatefulWidget {
100
101 class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent> {
102 ConfirmSendingAlertContentState({
103 - @required this.amount,
104 - @required this.amountValue,
105 - @required this.fiatAmountValue,
106 - @required this.fee,
107 - @required this.feeValue,
108 - @required this.feeFiatAmount,
109 - @required this.outputs}) {
110 -
103 + required this.amount,
104 + required this.amountValue,
105 + required this.fiatAmountValue,
106 + required this.fee,
107 + required this.feeValue,
108 + required this.feeFiatAmount,
109 + required this.outputs})
110 + : itemCount = 0,
111 + recipientTitle = '' {
112 itemCount = outputs.length;
113 recipientTitle = itemCount > 1
114 ? S.current.transaction_details_recipient_address
@@ -161,9 +162,9 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
162 fontWeight: FontWeight.normal,
163 fontFamily: 'Lato',
164 color: Theme.of(context)
164 - .primaryTextTheme
165 - .title
166 - .color,
165 + .primaryTextTheme!
166 + .headline6!
167 + .color!,
168 decoration: TextDecoration.none,
169 ),
170 ),
@@ -177,8 +178,8 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
178 fontWeight: FontWeight.w600,
179 fontFamily: 'Lato',
180 color: Theme.of(context)
180 - .primaryTextTheme
181 - .title
181 + .primaryTextTheme!
182 + .headline6!
183 .color,
184 decoration: TextDecoration.none,
185 ),
@@ -210,10 +211,7 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
211 fontSize: 16,
212 fontWeight: FontWeight.normal,
213 fontFamily: 'Lato',
213 - color: Theme.of(context)
214 - .primaryTextTheme
215 - .title
216 - .color,
214 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
215 decoration: TextDecoration.none,
216 ),
217 ),
@@ -226,10 +224,7 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
224 fontSize: 18,
225 fontWeight: FontWeight.w600,
226 fontFamily: 'Lato',
229 - color: Theme.of(context)
230 - .primaryTextTheme
231 - .title
232 - .color,
227 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
228 decoration: TextDecoration.none,
229 ),
230 ),
@@ -259,9 +254,9 @@ class ConfirmSendingAlertContentState extends State<ConfirmSendingAlertContent>
254 fontWeight: FontWeight.normal,
255 fontFamily: 'Lato',
256 color: Theme.of(context)
262 - .primaryTextTheme
263 - .title
264 - .color,
257 + .primaryTextTheme!
258 + .headline6!
259 + .color!,
260 decoration: TextDecoration.none,
261 ),
262 ),
lib/src/screens/send/widgets/extract_address_from_parsed.dart
+3 -3
@@ -46,7 +46,7 @@ Future<String> extractAddressFromParsed(
46
47 content += S.of(context).choose_address;
48
49 - address = await showPopUp<String>(
49 + address = await showPopUp<String?>(
50 context: context,
51 builder: (BuildContext context) {
52
@@ -56,9 +56,9 @@ Future<String> extractAddressFromParsed(
56 alertContent: content,
57 addresses: parsedAddress.addresses),
58 onWillPop: () async => false);
59 - });
59 + }) ?? '';
60
61 - if (address?.isEmpty ?? true) {
61 + if (address.isEmpty) {
62 return parsedAddress.name;
63 }
64
lib/src/screens/send/widgets/prefix_currency_icon_widget.dart
+2 -2
@@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
2
3 class PrefixCurrencyIcon extends StatelessWidget {
4 PrefixCurrencyIcon({
5 - @required this.isSelected,
6 - @required this.title,
5 + required this.isSelected,
6 + required this.title,
7 });
8
9 final bool isSelected;
lib/src/screens/send/widgets/send_card.dart
+64 -64
@@ -6,7 +6,6 @@ import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
6 import 'package:cake_wallet/src/widgets/picker.dart';
7 import 'package:cake_wallet/view_model/send/output.dart';
8 import 'package:cake_wallet/view_model/settings/settings_view_model.dart';
9 -import 'package:flutter/cupertino.dart';
9 import 'package:flutter/material.dart';
10 import 'package:flutter/services.dart';
11 import 'package:flutter_mobx/flutter_mobx.dart';
@@ -19,7 +18,10 @@ import 'package:cake_wallet/generated/i18n.dart';
18 import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
19
20 class SendCard extends StatefulWidget {
22 - SendCard({Key key, @required this.output, @required this.sendViewModel}) : super(key: key);
21 + SendCard({
22 + Key? key,
23 + required this.output,
24 + required this.sendViewModel}) : super(key: key);
25
26 final Output output;
27 final SendViewModel sendViewModel;
@@ -33,7 +35,7 @@ class SendCard extends StatefulWidget {
35
36 class SendCardState extends State<SendCard>
37 with AutomaticKeepAliveClientMixin<SendCard> {
36 - SendCardState({@required this.output, @required this.sendViewModel})
38 + SendCardState({required this.output, required this.sendViewModel})
39 : addressController = TextEditingController(),
40 cryptoAmountController = TextEditingController(),
41 fiatAmountController = TextEditingController(),
@@ -70,8 +72,8 @@ class SendCardState extends State<SendCard>
72 KeyboardActions(
73 config: KeyboardActionsConfig(
74 keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
73 - keyboardBarColor: Theme.of(context).accentTextTheme.body2
74 - .backgroundColor,
75 + keyboardBarColor: Theme.of(context).accentTextTheme!.bodyText1!
76 + .backgroundColor!,
77 nextFocus: false,
78 actions: [
79 KeyboardActionsItem(
@@ -93,11 +95,11 @@ class SendCardState extends State<SendCard>
95 bottomLeft: Radius.circular(24),
96 bottomRight: Radius.circular(24)),
97 gradient: LinearGradient(colors: [
96 - Theme.of(context).primaryTextTheme.subhead.color,
98 + Theme.of(context).primaryTextTheme!.subtitle1!.color!,
99 Theme.of(context)
98 - .primaryTextTheme
99 - .subhead
100 - .decorationColor,
100 + .primaryTextTheme!
101 + .subtitle1!
102 + .decorationColor!,
103 ], begin: Alignment.topLeft, end: Alignment.bottomRight),
104 ),
105 child: Padding(
@@ -126,13 +128,13 @@ class SendCardState extends State<SendCard>
128 AddressTextFieldOption.addressBook
129 ],
130 buttonColor: Theme.of(context)
129 - .primaryTextTheme
130 - .display1
131 - .color,
131 + .primaryTextTheme!
132 + .headline4!
133 + .color!,
134 borderColor: Theme.of(context)
133 - .primaryTextTheme
134 - .headline
135 - .color,
135 + .primaryTextTheme!
136 + .headline5!
137 + .color!,
138 textStyle: TextStyle(
139 fontSize: 14,
140 fontWeight: FontWeight.w500,
@@ -141,9 +143,9 @@ class SendCardState extends State<SendCard>
143 fontSize: 14,
144 fontWeight: FontWeight.w500,
145 color: Theme.of(context)
144 - .primaryTextTheme
145 - .headline
146 - .decorationColor),
146 + .primaryTextTheme!
147 + .headline5!
148 + .decorationColor!),
149 onPushPasteButton: (context) async {
150 output.resetParsedAddress();
151 await output.fetchParsedAddress(context);
@@ -161,9 +163,9 @@ class SendCardState extends State<SendCard>
163 controller: extractedAddressController,
164 readOnly: true,
165 borderColor: Theme.of(context)
164 - .primaryTextTheme
165 - .headline
166 - .color,
166 + .primaryTextTheme!
167 + .headline5!
168 + .color!,
169 textStyle: TextStyle(
170 fontSize: 14,
171 fontWeight: FontWeight.w500,
@@ -193,22 +195,22 @@ class SendCardState extends State<SendCard>
195 height: 32,
196 decoration: BoxDecoration(
197 color: Theme.of(context)
196 - .primaryTextTheme
197 - .display1
198 - .color,
198 + .primaryTextTheme!
199 + .headline4!
200 + .color!,
201 borderRadius:
202 BorderRadius.all(Radius.circular(6))),
203 child: Center(
204 child: Padding(
205 padding: const EdgeInsets.all(6.0),
204 - child: Text( sendViewModel.selectedCryptoCurrency.tag,
206 + child: Text( sendViewModel.selectedCryptoCurrency.tag!,
207 style: TextStyle(
208 fontSize: 12,
209 fontWeight: FontWeight.bold,
210 color: Theme.of(context)
209 - .primaryTextTheme
210 - .display1
211 - .decorationColor)),
211 + .primaryTextTheme!
212 + .headline4!
213 + .decorationColor!)),
214 ),
215 ),
216 ),
@@ -247,9 +249,9 @@ class SendCardState extends State<SendCard>
249 color: Colors.white),
250 placeholderTextStyle: TextStyle(
251 color: Theme.of(context)
250 - .primaryTextTheme
251 - .headline
252 - .decorationColor,
252 + .primaryTextTheme!
253 + .headline5!
254 + .decorationColor!,
255 fontWeight: FontWeight.w500,
256 fontSize: 14),
257 validator: output.sendAll
@@ -268,9 +270,9 @@ class SendCardState extends State<SendCard>
270 child: Container(
271 decoration: BoxDecoration(
272 color: Theme.of(context)
271 - .primaryTextTheme
272 - .display1
273 - .color,
273 + .primaryTextTheme!
274 + .headline4!
275 + .color!,
276 borderRadius:
277 BorderRadius.all(
278 Radius.circular(6))),
@@ -285,18 +287,18 @@ class SendCardState extends State<SendCard>
287 FontWeight.bold,
288 color:
289 Theme.of(context)
288 - .primaryTextTheme
289 - .display1
290 - .decorationColor))),
290 + .primaryTextTheme!
291 + .headline4!
292 + .decorationColor!))),
293 ))))]),
294 ),
295 ],
296 )
297 )),
298 Divider(height: 1,color: Theme.of(context)
297 - .primaryTextTheme
298 - .headline
299 - .decorationColor),
299 + .primaryTextTheme!
300 + .headline5!
301 + .decorationColor!),
302 Observer(
303 builder: (_) => Padding(
304 padding: EdgeInsets.only(top: 10),
@@ -313,9 +315,9 @@ class SendCardState extends State<SendCard>
315 fontSize: 12,
316 fontWeight: FontWeight.w600,
317 color: Theme.of(context)
316 - .primaryTextTheme
317 - .headline
318 - .decorationColor),
318 + .primaryTextTheme!
319 + .headline5!
320 + .decorationColor!),
321 )),
322 Text(
323 sendViewModel.balance,
@@ -323,9 +325,9 @@ class SendCardState extends State<SendCard>
325 fontSize: 12,
326 fontWeight: FontWeight.w600,
327 color: Theme.of(context)
326 - .primaryTextTheme
327 - .headline
328 - .decorationColor),
328 + .primaryTextTheme!
329 + .headline5!
330 + .decorationColor!),
331 )
332 ],
333 ),
@@ -353,18 +355,16 @@ class SendCardState extends State<SendCard>
355 ),
356 hintText: '0.00',
357 borderColor: Theme.of(context)
356 - .primaryTextTheme
357 - .headline
358 - .color,
358 + .primaryTextTheme!
359 + .headline5!
360 + .color!,
361 textStyle: TextStyle(
362 fontSize: 14,
363 fontWeight: FontWeight.w500,
364 color: Colors.white),
365 placeholderTextStyle: TextStyle(
366 color: Theme.of(context)
365 - .primaryTextTheme
366 - .headline
367 - .decorationColor,
367 + .primaryTextTheme!.headline5!.decorationColor!,
368 fontWeight: FontWeight.w500,
369 fontSize: 14),
370 )),
@@ -375,9 +375,9 @@ class SendCardState extends State<SendCard>
375 keyboardType: TextInputType.multiline,
376 maxLines: null,
377 borderColor: Theme.of(context)
378 - .primaryTextTheme
379 - .headline
380 - .color,
378 + .primaryTextTheme!
379 + .headline5!
380 + .color!,
381 textStyle: TextStyle(
382 fontSize: 14,
383 fontWeight: FontWeight.w500,
@@ -387,9 +387,9 @@ class SendCardState extends State<SendCard>
387 fontSize: 14,
388 fontWeight: FontWeight.w500,
389 color: Theme.of(context)
390 - .primaryTextTheme
391 - .headline
392 - .decorationColor),
390 + .primaryTextTheme!
391 + .headline5!
392 + .decorationColor!),
393 ),
394 ),
395 Observer(
@@ -411,7 +411,7 @@ class SendCardState extends State<SendCard>
411 fontSize: 12,
412 fontWeight:
413 FontWeight.w500,
414 - //color: Theme.of(context).primaryTextTheme.display2.color,
414 + //color: Theme.of(context).primaryTextTheme!.headline3!.color!,
415 color: Colors.white)),
416 Container(
417 child: Row(
@@ -432,7 +432,7 @@ class SendCardState extends State<SendCard>
432 fontSize: 12,
433 fontWeight:
434 FontWeight.w600,
435 - //color: Theme.of(context).primaryTextTheme.display2.color,
435 + //color: Theme.of(context).primaryTextTheme!.headline3!.color!,
436 color:
437 Colors.white)),
438 Padding(
@@ -450,9 +450,9 @@ class SendCardState extends State<SendCard>
450 FontWeight.w600,
451 color: Theme
452 .of(context)
453 - .primaryTextTheme
454 - .headline
455 - .decorationColor))
453 + .primaryTextTheme!
454 + .headline5!
455 + .decorationColor!))
456 ),
457 ],
458 ),
@@ -552,7 +552,7 @@ class SendCardState extends State<SendCard>
552 reaction((_) => output.sendAll, (bool all) {
553 if (all) {
554 cryptoAmountController.text = S.current.all;
555 - fiatAmountController.text = null;
555 + fiatAmountController.text = '';
556 }
557 });
558
lib/src/screens/settings/items/settings_item.dart
+7 -7
@@ -3,13 +3,13 @@ import 'package:cake_wallet/src/screens/settings/attributes.dart';
3
4 class SettingsItem {
5 SettingsItem(
6 - {this.onTaped,
7 - this.title,
8 - this.link,
9 - this.image,
10 - this.widget,
11 - this.attribute,
12 - this.widgetBuilder});
6 + {required this.onTaped,
7 + required this.title,
8 + required this.link,
9 + required this.image,
10 + required this.widget,
11 + required this.attribute,
12 + required this.widgetBuilder});
13
14 final VoidCallback onTaped;
15 final String title;
lib/src/screens/settings/settings.dart
+3 -1
@@ -28,7 +28,9 @@ class SettingsPage extends BasePage {
28
29 @override
30 Widget body(BuildContext context) {
31 + // FIX-ME: Added `context` it was not used here before, maby bug ?
32 return SectionStandardList(
33 + context: context,
34 sectionCount: settingsViewModel.sections.length,
35 itemCounter: (int sectionIndex) {
36 if (sectionIndex < settingsViewModel.sections.length) {
@@ -42,7 +44,7 @@ class SettingsPage extends BasePage {
44
45 if (item is PickerListItem) {
46 return Observer(builder: (_) {
45 - return SettingsPickerCell<dynamic>(
47 + return SettingsPickerCell<Object>(
48 displayItem: item.displayItem,
49 title: item.title,
50 selectedItem: item.selectedItem(),
lib/src/screens/settings/widgets/settings_cell_with_arrow.dart
+2 -2
@@ -2,11 +2,11 @@ import 'package:flutter/material.dart';
2 import 'package:cake_wallet/src/widgets/standard_list.dart';
3
4 class SettingsCellWithArrow extends StandardListRow {
5 - SettingsCellWithArrow({@required String title, @required Function(BuildContext context) handler})
5 + SettingsCellWithArrow({required String title, required Function(BuildContext context)? handler})
6 : super(title: title, isSelected: false, onTap: handler);
7
8 @override
9 Widget buildTrailing(BuildContext context) =>
10 Image.asset('assets/images/select_arrow.png',
11 - color: Theme.of(context).primaryTextTheme.overline.color);
11 + color: Theme.of(context).primaryTextTheme!.overline!.color!);
12 }
\ No newline at end of file
lib/src/screens/settings/widgets/settings_choices_cell.dart
+5 -5
@@ -2,7 +2,7 @@ import 'package:cake_wallet/view_model/settings/choices_list_item.dart';
2 import 'package:flutter/material.dart';
3
4 class SettingsChoicesCell extends StatelessWidget {
5 - const SettingsChoicesCell(this.choicesListItem, {Key key}) : super(key: key);
5 + const SettingsChoicesCell(this.choicesListItem, {Key? key}) : super(key: key);
6
7 final ChoicesListItem choicesListItem;
8
@@ -22,7 +22,7 @@ class SettingsChoicesCell extends StatelessWidget {
22 style: TextStyle(
23 fontSize: 14,
24 fontWeight: FontWeight.normal,
25 - color: Theme.of(context).primaryTextTheme.title.color,
25 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
26 ),
27 ),
28 ],
@@ -34,7 +34,7 @@ class SettingsChoicesCell extends StatelessWidget {
34 child: Container(
35 decoration: BoxDecoration(
36 borderRadius: BorderRadius.circular(30),
37 - color: Theme.of(context).accentTextTheme.display2.color,
37 + color: Theme.of(context).accentTextTheme!.headline3!.color!,
38 ),
39 child: Row(
40 mainAxisAlignment: MainAxisAlignment.center,
@@ -48,12 +48,12 @@ class SettingsChoicesCell extends StatelessWidget {
48 padding: EdgeInsets.symmetric(horizontal: 32, vertical: 8),
49 decoration: BoxDecoration(
50 borderRadius: BorderRadius.circular(30),
51 - color: isSelected ? Theme.of(context).accentTextTheme.body2.color : null,
51 + color: isSelected ? Theme.of(context).accentTextTheme!.bodyText1!.color! : null,
52 ),
53 child: Text(
54 choicesListItem.displayItem?.call(e) ?? e.toString(),
55 style: TextStyle(
56 - color: isSelected ? Colors.white : Theme.of(context).primaryTextTheme.caption.color,
56 + color: isSelected ? Colors.white : Theme.of(context).primaryTextTheme!.caption!.color!,
57 fontWeight: isSelected ? FontWeight.w700 : FontWeight.normal,
58 ),
59 ),
lib/src/screens/settings/widgets/settings_link_provider_cell.dart
+10 -9
@@ -5,21 +5,22 @@ import 'package:url_launcher/url_launcher.dart';
5
6 class SettingsLinkProviderCell extends StandardListRow {
7 SettingsLinkProviderCell(
8 - {@required String title,
9 - @required this.icon,
10 - this.iconColor,
11 - @required this.link,
12 - @required this.linkTitle})
8 + {required String title,
9 + required this.link,
10 + required this.linkTitle,
11 + this.icon,
12 + this.iconColor})
13 : super(title: title, isSelected: false, onTap: (BuildContext context) => _launchUrl(link) );
14
15 - final String icon;
15 +
16 final String link;
17 final String linkTitle;
18 - final Color iconColor;
18 + final String? icon;
19 + final Color? iconColor;
20
21 @override
21 - Widget buildLeading(BuildContext context) =>
22 - icon != null ? Image.asset(icon, color: iconColor, height: 30, width: 30) : null;
22 + Widget? buildLeading(BuildContext context) =>
23 + icon != null ? Image.asset(icon!, color: iconColor, height: 30, width: 30) : null;
24
25 @override
26 Widget buildTrailing(BuildContext context) => Text(linkTitle,
lib/src/screens/settings/widgets/settings_picker_cell.dart
+12 -12
@@ -3,12 +3,12 @@ import 'package:flutter/material.dart';
3 import 'package:cake_wallet/src/widgets/picker.dart';
4 import 'package:cake_wallet/src/widgets/standard_list.dart';
5
6 -class SettingsPickerCell<ItemType> extends StandardListRow {
6 +class SettingsPickerCell<ItemType extends Object> extends StandardListRow {
7 SettingsPickerCell(
8 - {@required String title,
9 - @required this.displayItem,
10 - this.selectedItem,
11 - this.items,
8 + {required String title,
9 + required this.selectedItem,
10 + required this.items,
11 + this.displayItem,
12 this.images,
13 this.searchHintText,
14 this.isGridView = false,
@@ -28,7 +28,7 @@ class SettingsPickerCell<ItemType> extends StandardListRow {
28 selectedAtIndex: selectedAtIndex,
29 mainAxisAlignment: MainAxisAlignment.start,
30 onItemSelected: (ItemType item) => onItemSelected?.call(item),
31 - images: images,
31 + images: images ?? const <Image>[],
32 isSeparated: false,
33 hintText: searchHintText,
34 isGridView: isGridView,
@@ -40,12 +40,12 @@ class SettingsPickerCell<ItemType> extends StandardListRow {
40
41 final ItemType selectedItem;
42 final List<ItemType> items;
43 - final void Function(ItemType item) onItemSelected;
44 - final String Function(ItemType item) displayItem;
45 - final List<Image> images;
46 - final String searchHintText;
43 + final void Function(ItemType item)? onItemSelected;
44 + final String Function(ItemType item)? displayItem;
45 + final List<Image>? images;
46 + final String? searchHintText;
47 final bool isGridView;
48 - final bool Function(ItemType, String) matchingCriteria;
48 + final bool Function(ItemType, String)? matchingCriteria;
49
50 @override
51 Widget buildTrailing(BuildContext context) {
@@ -53,7 +53,7 @@ class SettingsPickerCell<ItemType> extends StandardListRow {
53 displayItem?.call(selectedItem) ?? selectedItem.toString(),
54 textAlign: TextAlign.right,
55 style: TextStyle(
56 - fontSize: 14.0, fontWeight: FontWeight.w500, color: Theme.of(context).primaryTextTheme.overline.color),
56 + fontSize: 14.0, fontWeight: FontWeight.w500, color: Theme.of(context).primaryTextTheme!.overline!.color!),
57 );
58 }
59 }
lib/src/screens/settings/widgets/settings_switcher_cell.dart
+3 -3
@@ -4,13 +4,13 @@ import 'package:cake_wallet/src/widgets/standart_switch.dart';
4
5 class SettingsSwitcherCell extends StandardListRow {
6 SettingsSwitcherCell(
7 - {@required String title, @required this.value, this.onValueChange})
7 + {required String title, required this.value, this.onValueChange})
8 : super(title: title, isSelected: false);
9
10 final bool value;
11 - final void Function(BuildContext context, bool value) onValueChange;
11 + final void Function(BuildContext context, bool value)? onValueChange;
12
13 @override
14 Widget buildTrailing(BuildContext context) => StandartSwitch(
15 - value: value, onTaped: () => onValueChange(context, !value));
15 + value: value, onTaped: () => onValueChange?.call(context, !value));
16 }
lib/src/screens/settings/widgets/settings_version_cell.dart
+2 -2
@@ -1,7 +1,7 @@
1 import 'package:flutter/material.dart';
2
3 class SettingsVersionCell extends StatelessWidget {
4 - SettingsVersionCell({@required this.title});
4 + SettingsVersionCell({required this.title});
5
6 final String title;
7
@@ -18,7 +18,7 @@ class SettingsVersionCell extends StatelessWidget {
18 style: TextStyle(
19 fontSize: 12,
20 fontWeight: FontWeight.normal,
21 - color: Theme.of(context).primaryTextTheme.overline.color
21 + color: Theme.of(context).primaryTextTheme!.overline!.color!
22 ),
23 )
24 ],
lib/src/screens/setup_pin_code/setup_pin_code.dart
+5 -2
@@ -12,7 +12,7 @@ class SetupPinCodePage extends BasePage {
12 : pinCodeStateKey = GlobalKey<PinCodeState>();
13
14 final SetupPinCodeViewModel pinCodeViewModel;
15 - final void Function(PinCodeState<PinCodeWidget>, String) onSuccessfulPinSetup;
15 + final void Function(PinCodeState<PinCodeWidget>, String)? onSuccessfulPinSetup;
16 final GlobalKey<PinCodeState> pinCodeStateKey;
17
18 @override
@@ -57,7 +57,10 @@ class SetupPinCodePage extends BasePage {
57 buttonText: S.of(context).ok,
58 buttonAction: () {
59 Navigator.of(context).pop();
60 - onSuccessfulPinSetup(pinCodeStateKey.currentState, pin);
60 + if (pinCodeStateKey.currentState != null) {
61 + onSuccessfulPinSetup?.call(pinCodeStateKey.currentState!, pin);
62 + }
63 +
64 state.reset();
65 },
66 alertBarrierDismissible: false,
lib/src/screens/subaddress/address_edit_or_create_page.dart
+3 -3
@@ -10,7 +10,7 @@ import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
10 import 'package:cake_wallet/src/screens/base_page.dart';
11
12 class AddressEditOrCreatePage extends BasePage {
13 - AddressEditOrCreatePage({@required this.addressEditOrCreateViewModel})
13 + AddressEditOrCreatePage({required this.addressEditOrCreateViewModel})
14 : _formKey = GlobalKey<FormState>(),
15 _labelController = TextEditingController(),
16 super() {
@@ -53,14 +53,14 @@ class AddressEditOrCreatePage extends BasePage {
53 Observer(
54 builder: (_) => LoadingPrimaryButton(
55 onPressed: () async {
56 - if (_formKey.currentState.validate()) {
56 + if (_formKey.currentState?.validate() ?? false) {
57 await addressEditOrCreateViewModel.save();
58 }
59 },
60 text: addressEditOrCreateViewModel.isEdit
61 ? S.of(context).rename
62 : S.of(context).new_subaddress_create,
63 - color: Theme.of(context).accentTextTheme.body2.color,
63 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
64 textColor: Colors.white,
65 isLoading:
66 addressEditOrCreateViewModel.state is AddressIsSaving,
lib/src/screens/support/support_page.dart
+3 -3
@@ -5,7 +5,6 @@ import 'package:cake_wallet/view_model/settings/link_list_item.dart';
5 import 'package:cake_wallet/view_model/settings/regular_list_item.dart';
6 import 'package:cake_wallet/view_model/support_view_model.dart';
7 import 'package:flutter/material.dart';
8 -import 'package:flutter/cupertino.dart';
8 import 'package:cake_wallet/src/screens/base_page.dart';
9 import 'package:cake_wallet/generated/i18n.dart';
10
@@ -20,9 +19,10 @@ class SupportPage extends BasePage {
19 @override
20 Widget body(BuildContext context) {
21 final iconColor =
23 - Theme.of(context).accentTextTheme.display4.backgroundColor;
24 -
22 + Theme.of(context).accentTextTheme!.headline1!.backgroundColor!;
23 + // FIX-ME: Added `context` it was not used here before, maby bug ?
24 return SectionStandardList(
25 + context: context,
26 sectionCount: 1,
27 itemCounter: (int _) => supportViewModel.items.length,
28 itemBuilder: (_, __, index) {
lib/src/screens/trade_details/track_trade_list_item.dart
+4 -1
@@ -1,7 +1,10 @@
1 import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
2
3 class TrackTradeListItem extends StandartListItem {
4 - TrackTradeListItem({String title, String value, this.onTap})
4 + TrackTradeListItem({
5 + required String title,
6 + required String value,
7 + required this.onTap})
8 : super(title: title, value: value);
9 final Function() onTap;
10 }
lib/src/screens/trade_details/trade_details_list_card.dart
+11 -13
@@ -5,20 +5,18 @@ import 'package:cake_wallet/generated/i18n.dart';
5
6 class TradeDetailsListCardItem extends StandartListItem {
7 TradeDetailsListCardItem(
8 - {String title,
9 - String value,
10 - this.id,
11 - this.createdAt,
12 - this.pair,
13 - this.onTap})
14 - : super(title: title, value: value);
8 + {required this.id,
9 + required this.createdAt,
10 + required this.pair,
11 + required this.onTap})
12 + : super(title: '', value: '');
13
14 factory TradeDetailsListCardItem.tradeDetails(
17 - {@required String id,
18 - @required String createdAt,
19 - @required CryptoCurrency from,
20 - @required CryptoCurrency to,
21 - @required Function onTap}) {
15 + {required String id,
16 + required String createdAt,
17 + required CryptoCurrency from,
18 + required CryptoCurrency to,
19 + required void Function(BuildContext) onTap}) {
20 return TradeDetailsListCardItem(
21 id: '${S.current.trade_details_id} ${formatAsText(id)}',
22 createdAt: formatAsText(createdAt),
@@ -29,7 +27,7 @@ class TradeDetailsListCardItem extends StandartListItem {
27 final String id;
28 final String createdAt;
29 final String pair;
32 - final Function onTap;
30 + final void Function(BuildContext) onTap;
31
32 static String formatAsText<T>(T value) => value?.toString() ?? '';
33 }
lib/src/screens/trade_details/trade_details_page.dart
+2
@@ -51,7 +51,9 @@ class TradeDetailsPageBodyState extends State<TradeDetailsPageBody> {
51 @override
52 Widget build(BuildContext context) {
53 return Observer(builder: (_) {
54 + // FIX-ME: Added `context` it was not used here before, maby bug ?
55 return SectionStandardList(
56 + context: context,
57 sectionCount: 1,
58 itemCounter: (int _) => tradeDetailsViewModel.items.length,
59 itemBuilder: (_, __, index) {
lib/src/screens/trade_details/trade_details_status_item.dart
+1 -1
@@ -2,6 +2,6 @@ import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.d
2
3 class DetailsListStatusItem extends StandartListItem {
4 DetailsListStatusItem(
5 - {String title, String value})
5 + {required String title, required String value})
6 : super(title: title, value: value);
7 }
lib/src/screens/transaction_details/blockexplorer_list_item.dart
+1 -2
@@ -1,8 +1,7 @@
1 -import 'package:flutter/material.dart';
1 import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart';
2
3 class BlockExplorerListItem extends TransactionDetailsListItem {
5 - BlockExplorerListItem({String title, String value, this.onTap})
4 + BlockExplorerListItem({required String title, required String value, required this.onTap})
5 : super(title: title, value: value);
6 final Function() onTap;
7 }
lib/src/screens/transaction_details/standart_list_item.dart
+1 -1
@@ -1,6 +1,6 @@
1 import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart';
2
3 class StandartListItem extends TransactionDetailsListItem {
4 - StandartListItem({String title, String value})
4 + StandartListItem({required String title, required String value})
5 : super(title: title, value: value);
6 }
lib/src/screens/transaction_details/textfield_list_item.dart
+4 -1
@@ -1,7 +1,10 @@
1 import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart';
2
3 class TextFieldListItem extends TransactionDetailsListItem {
4 - TextFieldListItem({String title, String value, this.onSubmitted})
4 + TextFieldListItem({
5 + required String title,
6 + required String value,
7 + required this.onSubmitted})
8 : super(title: title, value: value);
9
10 final Function(String value) onSubmitted;
lib/src/screens/transaction_details/transaction_details_list_item.dart
+1 -1
@@ -1,5 +1,5 @@
1 abstract class TransactionDetailsListItem {
2 - TransactionDetailsListItem({this.title, this.value});
2 + TransactionDetailsListItem({required this.title, required this.value});
3
4 final String title;
5 final String value;
lib/src/screens/transaction_details/transaction_details_page.dart
+4 -2
@@ -17,7 +17,7 @@ import 'package:url_launcher/url_launcher.dart';
17 import 'package:hive/hive.dart';
18
19 class TransactionDetailsPage extends BasePage {
20 - TransactionDetailsPage({this.transactionDetailsViewModel});
20 + TransactionDetailsPage({required this.transactionDetailsViewModel});
21
22 @override
23 String get title => S.current.transaction_details_title;
@@ -26,7 +26,9 @@ class TransactionDetailsPage extends BasePage {
26
27 @override
28 Widget body(BuildContext context) {
29 + // FIX-ME: Added `context` it was not used here before, maby bug ?
30 return SectionStandardList(
31 + context: context,
32 sectionCount: 1,
33 itemCounter: (int _) => transactionDetailsViewModel.items.length,
34 itemBuilder: (_, __, index) {
@@ -60,7 +62,7 @@ class TransactionDetailsPage extends BasePage {
62 );
63 }
64
63 - return null;
65 + return Container();
66 });
67 }
68 }
lib/src/screens/transaction_details/widgets/textfield_list_row.dart
+10 -13
@@ -1,16 +1,14 @@
1 -import 'package:flutter/cupertino.dart';
1 import 'package:flutter/material.dart';
2 import 'package:cake_wallet/generated/i18n.dart';
3
4 class TextFieldListRow extends StatelessWidget {
5 TextFieldListRow(
7 - {this.title,
8 - this.value,
6 + {required this.title,
7 + required this.value,
8 this.titleFontSize = 14,
9 this.valueFontSize = 16,
11 - this.onSubmitted}) {
12 -
13 - _textController = TextEditingController();
10 + this.onSubmitted})
11 + : _textController = TextEditingController() {
12 _textController.text = value;
13 }
14
@@ -18,9 +16,8 @@ class TextFieldListRow extends StatelessWidget {
16 final String value;
17 final double titleFontSize;
18 final double valueFontSize;
21 - final Function(String value) onSubmitted;
22 -
23 - TextEditingController _textController;
19 + final Function(String value)? onSubmitted;
20 + final TextEditingController _textController;
21
22 @override
23 Widget build(BuildContext context) {
@@ -38,7 +35,7 @@ class TextFieldListRow extends StatelessWidget {
35 fontSize: titleFontSize,
36 fontWeight: FontWeight.w500,
37 color: Theme.of(context)
41 - .primaryTextTheme.overline.color),
38 + .primaryTextTheme!.overline!.color!),
39 textAlign: TextAlign.left),
40 TextField(
41 controller: _textController,
@@ -50,7 +47,7 @@ class TextFieldListRow extends StatelessWidget {
47 fontSize: valueFontSize,
48 fontWeight: FontWeight.w500,
49 color: Theme.of(context)
53 - .primaryTextTheme.title.color),
50 + .primaryTextTheme!.headline6!.color!),
51 decoration: InputDecoration(
52 isDense: true,
53 contentPadding: EdgeInsets.only(top: 12, bottom: 0),
@@ -59,10 +56,10 @@ class TextFieldListRow extends StatelessWidget {
56 fontSize: valueFontSize,
57 fontWeight: FontWeight.w500,
58 color: Theme.of(context)
62 - .primaryTextTheme.overline.color),
59 + .primaryTextTheme!.overline!.color!),
60 border: InputBorder.none
61 ),
65 - onSubmitted: (value) => onSubmitted.call(value),
62 + onSubmitted: (value) => onSubmitted?.call(value),
63 )
64 ]),
65 ),
lib/src/screens/unspent_coins/unspent_coins_details_page.dart
+4 -2
@@ -12,7 +12,7 @@ import 'package:flutter_mobx/flutter_mobx.dart';
12 import 'package:cake_wallet/generated/i18n.dart';
13
14 class UnspentCoinsDetailsPage extends BasePage {
15 - UnspentCoinsDetailsPage({this.unspentCoinsDetailsViewModel});
15 + UnspentCoinsDetailsPage({required this.unspentCoinsDetailsViewModel});
16
17 @override
18 String get title => S.current.unspent_coins_details_title;
@@ -21,7 +21,9 @@ class UnspentCoinsDetailsPage extends BasePage {
21
22 @override
23 Widget body(BuildContext context) {
24 + // FIX-ME: Added `context` it was not used here before, maby bug ?
25 return SectionStandardList(
26 + context: context,
27 sectionCount: 1,
28 itemCounter: (int _) => unspentCoinsDetailsViewModel.items.length,
29 itemBuilder: (_, __, index) {
@@ -49,7 +51,7 @@ class UnspentCoinsDetailsPage extends BasePage {
51 ));
52 }
53
52 - return null;
54 + return Container();
55 });
56 }
57 }
\ No newline at end of file
lib/src/screens/unspent_coins/unspent_coins_list_page.dart
+2 -2
@@ -10,7 +10,7 @@ import 'package:flutter_mobx/flutter_mobx.dart';
10 import 'package:cake_wallet/generated/i18n.dart';
11
12 class UnspentCoinsListPage extends BasePage {
13 - UnspentCoinsListPage({this.unspentCoinsListViewModel});
13 + UnspentCoinsListPage({required this.unspentCoinsListViewModel});
14
15 @override
16 String get title => S.current.unspent_coins_title;
@@ -18,7 +18,7 @@ class UnspentCoinsListPage extends BasePage {
18 //@override
19 //Widget trailing(BuildContext context) {
20 // final questionImage = Image.asset('assets/images/question_mark.png',
21 - // color: Theme.of(context).primaryTextTheme.title.color);
21 + // color: Theme.of(context).primaryTextTheme!.headline6!.color!);
22
23 // return SizedBox(
24 // height: 20.0,
lib/src/screens/unspent_coins/widgets/unspent_coins_list_item.dart
+10 -10
@@ -6,12 +6,12 @@ import 'package:cake_wallet/generated/i18n.dart';
6
7 class UnspentCoinsListItem extends StatelessWidget {
8 UnspentCoinsListItem({
9 - @required this.note,
10 - @required this.amount,
11 - @required this.address,
12 - @required this.isSending,
13 - @required this.isFrozen,
14 - @required this.onCheckBoxTap,
9 + required this.note,
10 + required this.amount,
11 + required this.address,
12 + required this.isSending,
13 + required this.isFrozen,
14 + this.onCheckBoxTap,
15 });
16
17 static const amountColor = Palette.darkBlueCraiola;
@@ -24,7 +24,7 @@ class UnspentCoinsListItem extends StatelessWidget {
24 final String address;
25 final bool isSending;
26 final bool isFrozen;
27 - final Function() onCheckBoxTap;
27 + final Function()? onCheckBoxTap;
28
29 @override
30 Widget build(BuildContext context) {
@@ -51,9 +51,9 @@ class UnspentCoinsListItem extends StatelessWidget {
51 decoration: BoxDecoration(
52 border: Border.all(
53 color: Theme.of(context)
54 - .primaryTextTheme
55 - .caption
56 - .color,
54 + .primaryTextTheme!
55 + .caption!
56 + .color!,
57 width: 1.0),
58 borderRadius: BorderRadius.all(
59 Radius.circular(8.0)),
lib/src/screens/unspent_coins/widgets/unspent_coins_switch_row.dart
+5 -6
@@ -1,13 +1,12 @@
1 import 'package:cake_wallet/src/widgets/standart_switch.dart';
2 -import 'package:flutter/cupertino.dart';
2 import 'package:flutter/material.dart';
3
4 class UnspentCoinsSwitchRow extends StatelessWidget {
5 UnspentCoinsSwitchRow(
7 - {this.title,
8 - this.titleFontSize = 14,
9 - this.switchValue,
10 - this.onSwitchValueChange});
6 + {required this.title,
7 + required this.switchValue,
8 + required this.onSwitchValueChange,
9 + this.titleFontSize = 14});
10
11 final String title;
12 final double titleFontSize;
@@ -30,7 +29,7 @@ class UnspentCoinsSwitchRow extends StatelessWidget {
29 fontSize: titleFontSize,
30 fontWeight: FontWeight.w500,
31 color: Theme.of(context)
33 - .primaryTextTheme.overline.color),
32 + .primaryTextTheme!.overline!.color!),
33 textAlign: TextAlign.left),
34 Padding(
35 padding: EdgeInsets.only(top: 12),
lib/src/screens/wallet_keys/wallet_keys_page.dart
+1 -1
@@ -26,7 +26,7 @@ class WalletKeysPage extends BasePage {
26 separatorBuilder: (context, index) => Container(
27 height: 1,
28 padding: EdgeInsets.only(left: 24),
29 - color: Theme.of(context).accentTextTheme.title.backgroundColor,
29 + color: Theme.of(context).accentTextTheme!.headline6!.backgroundColor!,
30 child: Container(
31 height: 1,
32 color: Theme.of(context).dividerColor,
lib/src/screens/wallet_list/wallet_list_page.dart
+35 -32
@@ -3,7 +3,7 @@ import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
3 import 'package:cake_wallet/utils/show_bar.dart';
4 import 'package:cake_wallet/utils/show_pop_up.dart';
5 import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
6 -import 'package:flushbar/flushbar.dart';
6 +// import 'package:flushbar/flushbar.dart';
7 import 'package:flutter/material.dart';
8 import 'package:flutter/cupertino.dart';
9 import 'package:flutter_mobx/flutter_mobx.dart';
@@ -18,7 +18,7 @@ import 'package:flutter_slidable/flutter_slidable.dart';
18 import 'package:cake_wallet/wallet_type_utils.dart';
19
20 class WalletListPage extends BasePage {
21 - WalletListPage({this.walletListViewModel});
21 + WalletListPage({required this.walletListViewModel});
22
23 final WalletListViewModel walletListViewModel;
24
@@ -28,7 +28,7 @@ class WalletListPage extends BasePage {
28 }
29
30 class WalletListBody extends StatefulWidget {
31 - WalletListBody({this.walletListViewModel});
31 + WalletListBody({required this.walletListViewModel});
32
33 final WalletListViewModel walletListViewModel;
34
@@ -49,7 +49,7 @@ class WalletListBodyState extends State<WalletListBody> {
49 Image.asset('assets/images/haven_logo.png', height: 24, width: 24);
50 final scrollController = ScrollController();
51 final double tileHeight = 60;
52 - Flushbar<void> _progressBar;
52 + // Flushbar<void>? _progressBar;
53
54 @override
55 Widget build(BuildContext context) {
@@ -58,7 +58,7 @@ class WalletListBodyState extends State<WalletListBody> {
58 final restoreWalletImage = Image.asset('assets/images/restore_wallet.png',
59 height: 12,
60 width: 12,
61 - color: Theme.of(context).primaryTextTheme.title.color);
61 + color: Theme.of(context).primaryTextTheme!.headline6!.color!);
62
63 return Container(
64 padding: EdgeInsets.only(top: 16),
@@ -76,9 +76,9 @@ class WalletListBodyState extends State<WalletListBody> {
76 final wallet = widget.walletListViewModel.wallets[index];
77 final currentColor = wallet.isCurrent
78 ? Theme.of(context)
79 - .accentTextTheme
80 - .subtitle
81 - .decorationColor
79 + .accentTextTheme!
80 + .subtitle2!
81 + .decorationColor!
82 : Theme.of(context).backgroundColor;
83 final row = GestureDetector(
84 onTap: () async {
@@ -144,9 +144,9 @@ class WalletListBodyState extends State<WalletListBody> {
144 fontSize: 22,
145 fontWeight: FontWeight.w500,
146 color: Theme.of(context)
147 - .primaryTextTheme
148 - .title
149 - .color),
147 + .primaryTextTheme!
148 + .headline6!
149 + .color!),
150 )
151 ],
152 ),
@@ -156,20 +156,22 @@ class WalletListBodyState extends State<WalletListBody> {
156 ),
157 ));
158
159 - return wallet.isCurrent
160 - ? row
161 - : Slidable(
162 - key: Key('${wallet.key}'),
163 - actionPane: SlidableDrawerActionPane(),
164 - child: row,
165 - secondaryActions: <Widget>[
166 - IconSlideAction(
167 - caption: S.of(context).delete,
168 - color: Colors.red,
169 - icon: CupertinoIcons.delete,
170 - onTap: () async => _removeWallet(wallet),
171 - )
172 - ]);
159 + // FIX-ME: Slidable for current
160 + return row;
161 + // return wallet.isCurrent
162 + // ? row
163 + // : Slidable(
164 + // key: Key('${wallet.key}'),
165 + // actionPane: SlidableDrawerActionPane(),
166 + // child: row,
167 + // secondaryActions: <Widget>[
168 + // IconSlideAction(
169 + // caption: S.of(context).delete,
170 + // color: Colors.red,
171 + // icon: CupertinoIcons.delete,
172 + // onTap: () async => _removeWallet(wallet),
173 + // )
174 + // ]);
175 }),
176 ),
177 ),
@@ -186,7 +188,7 @@ class WalletListBodyState extends State<WalletListBody> {
188 },
189 image: newWalletImage,
190 text: S.of(context).wallet_list_create_new_wallet,
189 - color: Theme.of(context).accentTextTheme.body2.color,
191 + color: Theme.of(context).accentTextTheme!.bodyText1!.color!,
192 textColor: Colors.white,
193 ),
194 SizedBox(height: 10.0),
@@ -204,13 +206,13 @@ class WalletListBodyState extends State<WalletListBody> {
206 },
207 image: restoreWalletImage,
208 text: S.of(context).wallet_list_restore_wallet,
207 - color: Theme.of(context).accentTextTheme.caption.color,
208 - textColor: Theme.of(context).primaryTextTheme.title.color)
209 + color: Theme.of(context).accentTextTheme!.caption!.color!,
210 + textColor: Theme.of(context).primaryTextTheme!.headline6!.color!)
211 ])),
212 );
213 }
214
213 - Image _imageFor({WalletType type}) {
215 + Image _imageFor({required WalletType type}) {
216 switch (type) {
217 case WalletType.bitcoin:
218 return bitcoinIcon;
@@ -269,11 +271,12 @@ class WalletListBodyState extends State<WalletListBody> {
271 }
272
273 void changeProcessText(String text) {
272 - _progressBar = createBar<void>(text, duration: null)..show(context);
274 + // FIX-ME: Duration
275 + // _progressBar = createBar<void>(text, duration: Duration())..show(context);
276 }
277
278 void hideProgressText() {
276 - _progressBar?.dismiss();
277 - _progressBar = null;
279 + // _progressBar?.dismiss();
280 + // _progressBar = null;
281 }
282 }
lib/src/screens/wallet_list/wallet_menu.dart
+1 -1
@@ -43,7 +43,7 @@ class WalletMenu {
43 ];
44
45 List<WalletMenuItem> generateItemsForWalletMenu(bool isCurrentWallet) {
46 - final items = List<WalletMenuItem>();
46 + final items = <WalletMenuItem>[];
47
48 if (!isCurrentWallet) items.add(menuItems[0]);
49 if (isCurrentWallet) items.add(menuItems[1]);
lib/src/screens/wallet_list/wallet_menu_item.dart
+4 -4
@@ -3,10 +3,10 @@ import 'package:flutter/cupertino.dart';
3
4 class WalletMenuItem {
5 WalletMenuItem({
6 - @required this.title,
7 - @required this.firstGradientColor,
8 - @required this.secondGradientColor,
9 - @required this.image
6 + required this.title,
7 + required this.firstGradientColor,
8 + required this.secondGradientColor,
9 + required this.image
10 });
11
12 final String title;
lib/src/screens/wallet_list/widgets/wallet_menu_alert.dart
+6 -6
@@ -10,9 +10,9 @@ import 'package:cake_wallet/src/widgets/alert_close_button.dart';
10
11 class WalletMenuAlert extends StatelessWidget {
12 WalletMenuAlert({
13 - @required this.wallet,
14 - @required this.walletMenu,
15 - @required this.items
13 + required this.wallet,
14 + required this.walletMenu,
15 + required this.items
16 });
17
18 final WalletListItem wallet;
@@ -36,7 +36,7 @@ class WalletMenuAlert extends StatelessWidget {
36 child: ClipRRect(
37 borderRadius: BorderRadius.all(Radius.circular(14)),
38 child: Container(
39 - color: Theme.of(context).textTheme.body2.decorationColor,
39 + color: Theme.of(context).textTheme!.bodyText1!.decorationColor!,
40 padding: EdgeInsets.only(left: 24),
41 child: ListView.separated(
42 shrinkWrap: true,
@@ -44,7 +44,7 @@ class WalletMenuAlert extends StatelessWidget {
44 itemCount: items.length,
45 separatorBuilder: (context, _) => Container(
46 height: 1,
47 - color: Theme.of(context).accentTextTheme.subhead.backgroundColor,
47 + color: Theme.of(context).accentTextTheme!.subtitle1!.backgroundColor!,
48 ),
49 itemBuilder: (_, index) {
50 final item = items[index];
@@ -87,7 +87,7 @@ class WalletMenuAlert extends StatelessWidget {
87 child: Text(
88 item.title,
89 style: TextStyle(
90 - color: Theme.of(context).primaryTextTheme.title.color,
90 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
91 fontSize: 18,
92 fontFamily: 'Lato',
93 fontWeight: FontWeight.w500,
lib/src/screens/welcome/welcome_page.dart
+37 -45
@@ -55,17 +55,16 @@ class WelcomePage extends BasePage {
55 width: 12,
56 color: Theme
57 .of(context)
58 - .accentTextTheme
59 - .headline
60 - .decorationColor);
58 + .accentTextTheme!
59 + .headline5!
60 + .decorationColor!);
61 final restoreWalletImage = Image.asset('assets/images/restore_wallet.png',
62 height: 12,
63 width: 12,
64 - color: Theme
65 - .of(context)
66 - .primaryTextTheme
67 - .title
68 - .color);
64 + color: Theme.of(context)
65 + .primaryTextTheme!
66 + .headline6!
67 + .color!);
68
69 return WillPopScope(onWillPop: () async => false, child: Container(
70 padding: EdgeInsets.only(top: 64, bottom: 24, left: 24, right: 24),
@@ -97,9 +96,9 @@ class WelcomePage extends BasePage {
96 fontWeight: FontWeight.w500,
97 color: Theme
98 .of(context)
100 - .accentTextTheme
101 - .display3
102 - .color,
99 + .accentTextTheme!
100 + .headline2!
101 + .color!,
102 ),
103 textAlign: TextAlign.center,
104 ),
@@ -111,11 +110,10 @@ class WelcomePage extends BasePage {
110 style: TextStyle(
111 fontSize: 36,
112 fontWeight: FontWeight.bold,
114 - color: Theme
115 - .of(context)
116 - .primaryTextTheme
117 - .title
118 - .color,
113 + color: Theme.of(context)
114 + .primaryTextTheme!
115 + .headline6!
116 + .color!,
117 ),
118 textAlign: TextAlign.center,
119 ),
@@ -129,9 +127,9 @@ class WelcomePage extends BasePage {
127 fontWeight: FontWeight.w500,
128 color: Theme
129 .of(context)
132 - .accentTextTheme
133 - .display3
134 - .color,
130 + .accentTextTheme!
131 + .headline2!
132 + .color!,
133 ),
134 textAlign: TextAlign.center,
135 ),
@@ -147,11 +145,10 @@ class WelcomePage extends BasePage {
145 style: TextStyle(
146 fontSize: 12,
147 fontWeight: FontWeight.normal,
150 - color: Theme
151 - .of(context)
152 - .accentTextTheme
153 - .display3
154 - .color,
148 + color: Theme.of(context)
149 + .accentTextTheme!
150 + .headline2!
151 + .color!,
152 ),
153 textAlign: TextAlign.center,
154 ),
@@ -162,19 +159,16 @@ class WelcomePage extends BasePage {
159 Navigator.pushNamed(context,
160 Routes.newWalletFromWelcome),
161 image: newWalletImage,
165 - text: S
166 - .of(context)
167 - .create_new,
168 - color: Theme
169 - .of(context)
170 - .accentTextTheme
171 - .subtitle
172 - .decorationColor,
162 + text: S.of(context).create_new,
163 + color: Theme.of(context)
164 + .accentTextTheme!
165 + .subtitle2!
166 + .decorationColor!,
167 textColor: Theme
168 .of(context)
175 - .accentTextTheme
176 - .headline
177 - .decorationColor,
169 + .accentTextTheme!
170 + .headline5!
171 + .decorationColor!,
172 ),
173 ),
174 Padding(
@@ -187,16 +181,14 @@ class WelcomePage extends BasePage {
181 text: S
182 .of(context)
183 .restore_wallet,
190 - color: Theme
191 - .of(context)
192 - .accentTextTheme
193 - .caption
194 - .color,
195 - textColor: Theme
196 - .of(context)
197 - .primaryTextTheme
198 - .title
199 - .color),
184 + color: Theme.of(context)
185 + .accentTextTheme!
186 + .caption!
187 + .color!,
188 + textColor: Theme.of(context)
189 + .primaryTextTheme!
190 + .headline6!
191 + .color!),
192 )
193 ],
194 )
lib/src/screens/yat/widgets/first_introduction.dart
+2 -2
@@ -9,10 +9,10 @@ import 'package:lottie/lottie.dart';
9 import 'package:cake_wallet/generated/i18n.dart';
10
11 class FirstIntroduction extends StatelessWidget {
12 - FirstIntroduction({this.onClose, this.onNext});
12 + FirstIntroduction({required this.onNext, this.onClose});
13
14 static const aspectRatioImage = 1.133;
15 - final VoidCallback onClose;
15 + final VoidCallback? onClose;
16 final VoidCallback onNext;
17 final animation = Lottie.asset('assets/animation/anim1.json');
18
lib/src/screens/yat/widgets/second_introduction.dart
+2 -2
@@ -9,9 +9,9 @@ import 'package:lottie/lottie.dart';
9 import 'package:cake_wallet/generated/i18n.dart';
10
11 class SecondIntroduction extends StatelessWidget {
12 - SecondIntroduction({this.onClose, this.onNext});
12 + SecondIntroduction({required this.onNext, this.onClose});
13
14 - final VoidCallback onClose;
14 + final VoidCallback? onClose;
15 final VoidCallback onNext;
16 final animation = Lottie.asset('assets/animation/anim2.json');
17
lib/src/screens/yat/widgets/third_introduction.dart
+5 -2
@@ -9,9 +9,12 @@ import 'package:lottie/lottie.dart';
9 import 'package:cake_wallet/generated/i18n.dart';
10
11 class ThirdIntroduction extends StatelessWidget {
12 - ThirdIntroduction({this.onClose, this.onGet, this.onConnect});
12 + ThirdIntroduction({
13 + required this.onGet,
14 + required this.onConnect,
15 + this.onClose});
16
14 - final VoidCallback onClose;
17 + final VoidCallback? onClose;
18 final VoidCallback onGet;
19 final VoidCallback onConnect;
20 final animation = Lottie.asset('assets/animation/anim3.json');
lib/src/screens/yat/widgets/yat_bar.dart
+1 -1
@@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
4 class YatBar extends StatelessWidget {
5 YatBar({this.onClose});
6
7 - final VoidCallback onClose;
7 + final VoidCallback? onClose;
8 final image = Image.asset('assets/images/yat_logo.png', width: 81, height: 28);
9
10 @override
lib/src/screens/yat/widgets/yat_close_button.dart
+1 -1
@@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
4 class YatCloseButton extends StatelessWidget {
5 YatCloseButton({this.onClose});
6
7 - final VoidCallback onClose;
7 + final VoidCallback? onClose;
8
9 @override
10 Widget build(BuildContext context) {
lib/src/screens/yat/widgets/yat_page_indicator.dart
+1 -1
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
2 import 'package:cake_wallet/palette.dart';
3
4 class YatPageIndicator extends StatelessWidget {
5 - YatPageIndicator({this.filled});
5 + YatPageIndicator({required this.filled});
6
7 final int filled;
8
lib/src/screens/yat/yat_popup.dart
+1 -1
@@ -14,7 +14,7 @@ import 'package:url_launcher/url_launcher.dart';
14 import 'package:cake_wallet/generated/i18n.dart';
15
16 class YatPopup extends StatelessWidget {
17 - YatPopup({this.dashboardViewModel, this.onClose})
17 + YatPopup({required this.dashboardViewModel, required this.onClose})
18 : baseUrl = YatLink.isDevMode
19 ? YatLink.baseDevUrl
20 : YatLink.baseReleaseUrl;
lib/src/screens/yat_emoji_id.dart
+4 -4
@@ -88,7 +88,7 @@ class YatEmojiId extends StatelessWidget {
88 fontSize: 32,
89 fontWeight: FontWeight.bold,
90 fontFamily: 'Lato',
91 - color: Theme.of(context).accentTextTheme.display3.backgroundColor,
91 + color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!,
92 decoration: TextDecoration.none,
93 )
94 ),
@@ -102,9 +102,9 @@ class YatEmojiId extends StatelessWidget {
102 fontWeight: FontWeight.normal,
103 fontFamily: 'Lato',
104 color: Theme.of(context)
105 - .accentTextTheme
106 - .display2
107 - .backgroundColor,
105 + .accentTextTheme!
106 + .headline3!
107 + .backgroundColor!,
108 decoration: TextDecoration.none,
109 )
110 )
lib/src/widgets/address_text_field.dart
+47 -58
@@ -9,7 +9,7 @@ enum AddressTextFieldOption { paste, qrCode, addressBook }
9
10 class AddressTextField extends StatelessWidget {
11 AddressTextField(
12 - {@required this.controller,
12 + {required this.controller,
13 this.isActive = true,
14 this.placeholder,
15 this.options = const [
@@ -32,21 +32,21 @@ class AddressTextField extends StatelessWidget {
32 static const prefixIconHeight = 34.0;
33 static const spaceBetweenPrefixIcons = 10.0;
34
35 - final TextEditingController controller;
35 + final TextEditingController? controller;
36 final bool isActive;
37 - final String placeholder;
38 - final Function(Uri) onURIScanned;
37 + final String? placeholder;
38 + final Function(Uri)? onURIScanned;
39 final List<AddressTextFieldOption> options;
40 - final FormFieldValidator<String> validator;
40 + final FormFieldValidator<String>? validator;
41 final bool isBorderExist;
42 - final Color buttonColor;
43 - final Color borderColor;
44 - final Color iconColor;
45 - final TextStyle textStyle;
46 - final TextStyle hintStyle;
47 - final FocusNode focusNode;
48 - final Function(BuildContext context) onPushPasteButton;
49 - final Function(BuildContext context) onPushAddressBookButton;
42 + final Color? buttonColor;
43 + final Color? borderColor;
44 + final Color? iconColor;
45 + final TextStyle? textStyle;
46 + final TextStyle? hintStyle;
47 + final FocusNode? focusNode;
48 + final Function(BuildContext context)? onPushPasteButton;
49 + final Function(BuildContext context)? onPushAddressBookButton;
50
51 @override
52 Widget build(BuildContext context) {
@@ -60,7 +60,7 @@ class AddressTextField extends StatelessWidget {
60 style: textStyle ??
61 TextStyle(
62 fontSize: 16,
63 - color: Theme.of(context).primaryTextTheme.title.color),
63 + color: Theme.of(context).primaryTextTheme!.headline6!.color!),
64 decoration: InputDecoration(
65 suffixIcon: SizedBox(
66 width: prefixIconWidth * options.length +
@@ -112,18 +112,18 @@ class AddressTextField extends StatelessWidget {
112 decoration: BoxDecoration(
113 color: buttonColor ??
114 Theme.of(context)
115 - .accentTextTheme
116 - .title
117 - .color,
115 + .accentTextTheme!
116 + .headline6!
117 + .color!,
118 borderRadius:
119 BorderRadius.all(Radius.circular(6))),
120 child: Image.asset(
121 'assets/images/paste_ios.png',
122 color: iconColor ??
123 Theme.of(context)
124 - .primaryTextTheme
125 - .display1
126 - .decorationColor,
124 + .primaryTextTheme!
125 + .headline4!
126 + .decorationColor!,
127 )),
128 )),
129 ],
@@ -139,18 +139,18 @@ class AddressTextField extends StatelessWidget {
139 decoration: BoxDecoration(
140 color: buttonColor ??
141 Theme.of(context)
142 - .accentTextTheme
143 - .title
144 - .color,
142 + .accentTextTheme!
143 + .headline6!
144 + .color!,
145 borderRadius:
146 BorderRadius.all(Radius.circular(6))),
147 child: Image.asset(
148 'assets/images/qr_code_icon.png',
149 color: iconColor ??
150 Theme.of(context)
151 - .primaryTextTheme
152 - .display1
153 - .decorationColor,
151 + .primaryTextTheme!
152 + .headline4!
153 + .decorationColor!,
154 )),
155 ))
156 ],
@@ -168,18 +168,18 @@ class AddressTextField extends StatelessWidget {
168 decoration: BoxDecoration(
169 color: buttonColor ??
170 Theme.of(context)
171 - .accentTextTheme
172 - .title
173 - .color,
171 + .accentTextTheme!
172 + .headline6!
173 + .color!,
174 borderRadius:
175 BorderRadius.all(Radius.circular(6))),
176 child: Image.asset(
177 'assets/images/open_book.png',
178 color: iconColor ??
179 Theme.of(context)
180 - .primaryTextTheme
181 - .display1
182 - .decorationColor,
180 + .primaryTextTheme!
181 + .headline4!
182 + .decorationColor!,
183 )),
184 ))
185 ]
@@ -191,27 +191,17 @@ class AddressTextField extends StatelessWidget {
191 }
192
193 Future<void> _presentQRScanner(BuildContext context) async {
194 + final code = await presentQRScanner();
195 + if (code.isEmpty) {
196 + return;
197 + }
198 +
199 try {
195 - final code = await presentQRScanner();
196 - if (code.isEmpty) {
197 - return;
198 - }
200 final uri = Uri.parse(code);
200 - var address = '';
201 -
202 - if (uri == null) {
203 - controller.text = code;
204 - return;
205 - }
206 -
207 - address = uri.path;
208 - controller.text = address;
209 -
210 - if (onURIScanned != null) {
211 - onURIScanned(uri);
212 - }
213 - } catch (e) {
214 - print(e.toString());
201 + controller?.text = uri.path;
202 + onURIScanned?.call(uri);
203 + } catch(_){
204 + controller?.text = code;
205 }
206 }
207
@@ -220,18 +210,17 @@ class AddressTextField extends StatelessWidget {
210 .pushNamed(Routes.pickerAddressBook);
211
212 if (contact is ContactBase && contact.address != null) {
223 - controller.text = contact.address;
213 + controller?.text = contact.address;
214 onPushAddressBookButton?.call(context);
215 }
216 }
217
218 Future<void> _pasteAddress(BuildContext context) async {
229 - String address;
230 -
231 - await Clipboard.getData('text/plain').then((value) => address = value?.text);
232 -
233 - if (address?.isNotEmpty ?? false) {
234 - controller.text = address;
219 + final clipboard = await Clipboard.getData('text/plain');
220 + final address = clipboard?.text ?? '';
221 +
222 + if (address.isNotEmpty) {
223 + controller?.text = address;
224 }
225
226 onPushPasteButton?.call(context);
lib/src/widgets/alert_background.dart
+1 -1
@@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
4 import 'package:cake_wallet/palette.dart';
5
6 class AlertBackground extends StatelessWidget {
7 - AlertBackground({@required this.child});
7 + AlertBackground({required this.child});
8
9 final Widget child;
10
lib/src/widgets/alert_close_button.dart
+1 -1
@@ -4,7 +4,7 @@ import 'package:flutter/material.dart';
4 class AlertCloseButton extends StatelessWidget {
5 AlertCloseButton({this.image});
6
7 - final Image image;
7 + final Image? image;
8
9 final closeButton = Image.asset(
10 'assets/images/close.png',
lib/src/widgets/alert_with_one_action.dart
+11 -10
@@ -3,10 +3,10 @@ import 'package:cake_wallet/src/widgets/base_alert_dialog.dart';
3
4 class AlertWithOneAction extends BaseAlertDialog {
5 AlertWithOneAction({
6 - @required this.alertTitle,
7 - @required this.alertContent,
8 - @required this.buttonText,
9 - @required this.buttonAction,
6 + required this.alertTitle,
7 + required this.alertContent,
8 + required this.buttonText,
9 + required this.buttonAction,
10 this.alertBarrierDismissible = true
11 });
12
@@ -31,21 +31,22 @@ class AlertWithOneAction extends BaseAlertDialog {
31 width: 300,
32 height: 52,
33 padding: EdgeInsets.only(left: 12, right: 12),
34 - color: Theme.of(context).accentTextTheme.body1.backgroundColor,
34 + color: Theme.of(context).accentTextTheme!.bodyText2!.backgroundColor!,
35 child: ButtonTheme(
36 minWidth: double.infinity,
37 - child: FlatButton(
37 + child: TextButton(
38 onPressed: buttonAction,
39 - highlightColor: Colors.transparent,
40 - splashColor: Colors.transparent,
39 + // FIX-ME: Style
40 + //highlightColor: Colors.transparent,
41 + //splashColor: Colors.transparent,
42 child: Text(
43 buttonText,
44 textAlign: TextAlign.center,
45 style: TextStyle(
46 fontSize: 15,
47 fontWeight: FontWeight.w600,
47 - color: Theme.of(context).primaryTextTheme.body1
48 - .backgroundColor,
48 + color: Theme.of(context).primaryTextTheme!.bodyText2!
49 + .backgroundColor!,
50 decoration: TextDecoration.none,
51 ),
52 )),
lib/src/widgets/alert_with_two_actions.dart
+14 -14
@@ -4,16 +4,16 @@ import 'package:flutter/cupertino.dart';
4
5 class AlertWithTwoActions extends BaseAlertDialog {
6 AlertWithTwoActions({
7 - @required this.alertTitle,
8 - @required this.alertContent,
9 - @required this.leftButtonText,
10 - @required this.rightButtonText,
11 - @required this.actionLeftButton,
12 - @required this.actionRightButton,
7 + required this.alertTitle,
8 + required this.alertContent,
9 + required this.leftButtonText,
10 + required this.rightButtonText,
11 + required this.actionLeftButton,
12 + required this.actionRightButton,
13 this.alertBarrierDismissible = true,
14 this.isDividerExist = false,
15 - this.leftActionColor,
16 - this.rightActionColor,
15 + // this.leftActionColor,
16 + // this.rightActionColor,
17 });
18
19 final String alertTitle;
@@ -23,8 +23,8 @@ class AlertWithTwoActions extends BaseAlertDialog {
23 final VoidCallback actionLeftButton;
24 final VoidCallback actionRightButton;
25 final bool alertBarrierDismissible;
26 - final Color leftActionColor;
27 - final Color rightActionColor;
26 + // final Color leftActionColor;
27 + // final Color rightActionColor;
28 final bool isDividerExist;
29
30 @override
@@ -41,10 +41,10 @@ class AlertWithTwoActions extends BaseAlertDialog {
41 VoidCallback get actionRight => actionRightButton;
42 @override
43 bool get barrierDismissible => alertBarrierDismissible;
44 - @override
45 - Color get leftButtonColor => leftActionColor;
46 - @override
47 - Color get rightButtonColor => rightActionColor;
44 + // @override
45 + // Color get leftButtonColor => leftActionColor;
46 + // @override
47 + // Color get rightButtonColor => rightActionColor;
48 @override
49 bool get isDividerExists => isDividerExist;
50 }
lib/src/widgets/base_alert_dialog.dart
+15 -13
@@ -20,7 +20,7 @@ class BaseAlertDialog extends StatelessWidget {
20 fontSize: 20,
21 fontFamily: 'Lato',
22 fontWeight: FontWeight.w600,
23 - color: Theme.of(context).primaryTextTheme.title.color,
23 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
24 decoration: TextDecoration.none,
25 ),
26 );
@@ -34,7 +34,7 @@ class BaseAlertDialog extends StatelessWidget {
34 fontSize: 16,
35 fontWeight: FontWeight.normal,
36 fontFamily: 'Lato',
37 - color: Theme.of(context).primaryTextTheme.title.color,
37 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
38 decoration: TextDecoration.none,
39 ),
40 );
@@ -48,13 +48,14 @@ class BaseAlertDialog extends StatelessWidget {
48 child: Container(
49 height: 52,
50 padding: EdgeInsets.only(left: 6, right: 6),
51 - color: Theme.of(context).accentTextTheme.body2.decorationColor,
51 + color: Theme.of(context).accentTextTheme!.bodyText1!.decorationColor!,
52 child: ButtonTheme(
53 minWidth: double.infinity,
54 - child: FlatButton(
54 + child: TextButton(
55 onPressed: actionLeft,
56 - highlightColor: Colors.transparent,
57 - splashColor: Colors.transparent,
56 + // FIX-ME: Style
57 + //highlightColor: Colors.transparent,
58 + //splashColor: Colors.transparent,
59 child: Text(
60 leftActionButtonText,
61 textAlign: TextAlign.center,
@@ -62,7 +63,7 @@ class BaseAlertDialog extends StatelessWidget {
63 fontSize: 15,
64 fontFamily: 'Lato',
65 fontWeight: FontWeight.w600,
65 - color: Theme.of(context).primaryTextTheme.body2.backgroundColor,
66 + color: Theme.of(context).primaryTextTheme!.bodyText1!.backgroundColor!,
67 decoration: TextDecoration.none,
68 ),
69 )),
@@ -77,13 +78,14 @@ class BaseAlertDialog extends StatelessWidget {
78 child: Container(
79 height: 52,
80 padding: EdgeInsets.only(left: 6, right: 6),
80 - color: Theme.of(context).accentTextTheme.body1.backgroundColor,
81 + color: Theme.of(context).accentTextTheme!.bodyText2!.backgroundColor!,
82 child: ButtonTheme(
83 minWidth: double.infinity,
83 - child: FlatButton(
84 + child: TextButton(
85 onPressed: actionRight,
85 - highlightColor: Colors.transparent,
86 - splashColor: Colors.transparent,
86 + // FIX-ME: Style
87 + //highlightColor: Colors.transparent,
88 + //splashColor: Colors.transparent,
89 child: Text(
90 rightActionButtonText,
91 textAlign: TextAlign.center,
@@ -91,7 +93,7 @@ class BaseAlertDialog extends StatelessWidget {
93 fontSize: 15,
94 fontFamily: 'Lato',
95 fontWeight: FontWeight.w600,
94 - color: Theme.of(context).primaryTextTheme.body1.backgroundColor,
96 + color: Theme.of(context).primaryTextTheme!.bodyText2!.backgroundColor!,
97 decoration: TextDecoration.none,
98 ),
99 )),
@@ -118,7 +120,7 @@ class BaseAlertDialog extends StatelessWidget {
120 borderRadius: BorderRadius.all(Radius.circular(30)),
121 child: Container(
122 width: 300,
121 - color: Theme.of(context).accentTextTheme.title.decorationColor,
123 + color: Theme.of(context).accentTextTheme!.headline6!.decorationColor!,
124 child: Column(
125 mainAxisSize: MainAxisSize.min,
126 children: <Widget>[
lib/src/widgets/base_text_form_field.dart
+28 -28
@@ -7,7 +7,7 @@ class BaseTextFormField extends StatelessWidget {
7 this.keyboardType = TextInputType.text,
8 this.textInputAction = TextInputAction.done,
9 this.textAlign = TextAlign.start,
10 - this.autovalidate = false,
10 + this.autovalidateMode,
11 this.hintText = '',
12 this.maxLines = 1,
13 this.inputFormatters,
@@ -29,30 +29,30 @@ class BaseTextFormField extends StatelessWidget {
29 this.initialValue,
30 this.borderWidth = 1.0});
31
32 - final TextEditingController controller;
33 - final TextInputType keyboardType;
34 - final TextInputAction textInputAction;
32 + final TextEditingController? controller;
33 + final TextInputType? keyboardType;
34 + final TextInputAction? textInputAction;
35 final TextAlign textAlign;
36 - final bool autovalidate;
37 - final String hintText;
38 - final int maxLines;
39 - final List<TextInputFormatter> inputFormatters;
40 - final Color textColor;
41 - final Color hintColor;
42 - final Color borderColor;
43 - final Widget prefix;
44 - final Widget prefixIcon;
45 - final Widget suffix;
46 - final Widget suffixIcon;
47 - final bool enabled;
48 - final FormFieldValidator<String> validator;
49 - final TextStyle placeholderTextStyle;
50 - final TextStyle textStyle;
51 - final int maxLength;
52 - final FocusNode focusNode;
36 + final AutovalidateMode? autovalidateMode;
37 + final String? hintText;
38 + final int? maxLines;
39 + final List<TextInputFormatter>? inputFormatters;
40 + final Color? textColor;
41 + final Color? hintColor;
42 + final Color? borderColor;
43 + final Widget? prefix;
44 + final Widget? prefixIcon;
45 + final Widget? suffix;
46 + final Widget? suffixIcon;
47 + final bool? enabled;
48 + final FormFieldValidator<String>? validator;
49 + final TextStyle? placeholderTextStyle;
50 + final TextStyle? textStyle;
51 + final int? maxLength;
52 + final FocusNode? focusNode;
53 final bool readOnly;
54 - final bool enableInteractiveSelection;
55 - final String initialValue;
54 + final bool? enableInteractiveSelection;
55 + final String? initialValue;
56 final double borderWidth;
57
58 @override
@@ -66,7 +66,7 @@ class BaseTextFormField extends StatelessWidget {
66 keyboardType: keyboardType,
67 textInputAction: textInputAction,
68 textAlign: textAlign,
69 - autovalidate: autovalidate,
69 + autovalidateMode: autovalidateMode,
70 maxLines: maxLines,
71 inputFormatters: inputFormatters,
72 enabled: enabled,
@@ -75,7 +75,7 @@ class BaseTextFormField extends StatelessWidget {
75 TextStyle(
76 fontSize: 16.0,
77 color:
78 - textColor ?? Theme.of(context).primaryTextTheme.title.color),
78 + textColor ?? Theme.of(context).primaryTextTheme!.headline6!.color!),
79 decoration: InputDecoration(
80 prefix: prefix,
81 prefixIcon: prefixIcon,
@@ -89,17 +89,17 @@ class BaseTextFormField extends StatelessWidget {
89 focusedBorder: UnderlineInputBorder(
90 borderSide: BorderSide(
91 color: borderColor ??
92 - Theme.of(context).primaryTextTheme.title.backgroundColor,
92 + Theme.of(context).primaryTextTheme!.headline6!.backgroundColor!,
93 width: borderWidth)),
94 disabledBorder: UnderlineInputBorder(
95 borderSide: BorderSide(
96 color: borderColor ??
97 - Theme.of(context).primaryTextTheme.title.backgroundColor,
97 + Theme.of(context).primaryTextTheme!.headline6!.backgroundColor!,
98 width: borderWidth)),
99 enabledBorder: UnderlineInputBorder(
100 borderSide: BorderSide(
101 color: borderColor ??
102 - Theme.of(context).primaryTextTheme.title.backgroundColor,
102 + Theme.of(context).primaryTextTheme!.headline6!.backgroundColor!,
103 width: borderWidth))),
104 validator: validator,
105 );
lib/src/widgets/blockchain_height_widget.dart
+11 -7
@@ -6,13 +6,17 @@ import 'package:cake_wallet/monero/monero.dart';
6 import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
7
8 class BlockchainHeightWidget extends StatefulWidget {
9 - BlockchainHeightWidget({GlobalKey key, this.onHeightChange, this.focusNode,
10 - this.onHeightOrDateEntered, this.hasDatePicker = true})
9 + BlockchainHeightWidget({
10 + GlobalKey? key,
11 + this.onHeightChange,
12 + this.focusNode,
13 + this.onHeightOrDateEntered,
14 + this.hasDatePicker = true})
15 : super(key: key);
16
13 - final Function(int) onHeightChange;
14 - final Function(bool) onHeightOrDateEntered;
15 - final FocusNode focusNode;
17 + final Function(int)? onHeightChange;
18 + final Function(bool)? onHeightOrDateEntered;
19 + final FocusNode? focusNode;
20 final bool hasDatePicker;
21
22 @override
@@ -76,7 +80,7 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
80 style: TextStyle(
81 fontSize: 16.0,
82 fontWeight: FontWeight.w500,
79 - color: Theme.of(context).primaryTextTheme.title.color),
83 + color: Theme.of(context).primaryTextTheme!.headline6!.color!),
84 ),
85 ),
86 Row(
@@ -120,7 +124,7 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
124 lastDate: now);
125
126 if (date != null) {
123 - final height = monero.getHeigthByDate(date: date);
127 + final height = monero!.getHeigthByDate(date: date);
128 setState(() {
129 dateController.text = DateFormat('yyyy-MM-dd').format(date);
130 restoreHeightController.text = '$height';
lib/src/widgets/cake_scrollbar.dart
+7 -7
@@ -2,9 +2,9 @@ import 'package:flutter/material.dart';
2
3 class CakeScrollbar extends StatelessWidget {
4 CakeScrollbar({
5 - @required this.backgroundHeight,
6 - @required this.thumbHeight,
7 - @required this.fromTop,
5 + required this.backgroundHeight,
6 + required this.thumbHeight,
7 + required this.fromTop,
8 this.rightOffset = 6,
9 this.backgroundColor,
10 this.thumbColor,
@@ -16,8 +16,8 @@ class CakeScrollbar extends StatelessWidget {
16 final double fromTop;
17 final double width;
18 final double rightOffset;
19 - final Color backgroundColor;
20 - final Color thumbColor;
19 + final Color? backgroundColor;
20 + final Color? thumbColor;
21
22 @override
23 Widget build(BuildContext context) {
@@ -27,7 +27,7 @@ class CakeScrollbar extends StatelessWidget {
27 height: backgroundHeight,
28 width: width,
29 decoration: BoxDecoration(
30 - color: backgroundColor ?? Theme.of(context).textTheme.body1.decorationColor,
30 + color: backgroundColor ?? Theme.of(context).textTheme!.bodyText2!.decorationColor!,
31 borderRadius: BorderRadius.all(Radius.circular(3))),
32 child: Stack(
33 children: <Widget>[
@@ -38,7 +38,7 @@ class CakeScrollbar extends StatelessWidget {
38 height: thumbHeight,
39 width: width,
40 decoration: BoxDecoration(
41 - color: thumbColor ?? Theme.of(context).textTheme.body1.color,
41 + color: thumbColor ?? Theme.of(context).textTheme!.bodyText2!.color!,
42 borderRadius: BorderRadius.all(Radius.circular(3))),
43 ),
44 )
lib/src/widgets/check_box_picker.dart
+15 -14
@@ -1,23 +1,20 @@
1 -import 'dart:ui';
1 import 'package:cake_wallet/palette.dart';
3 -import 'package:flutter/cupertino.dart';
2 import 'package:flutter/material.dart';
3 import 'package:cake_wallet/src/widgets/alert_background.dart';
4 import 'package:cake_wallet/src/widgets/alert_close_button.dart';
7 -import 'package:cake_wallet/generated/i18n.dart';
5
6 class CheckBoxPicker extends StatefulWidget {
7 CheckBoxPicker({
11 - @required this.items,
12 - @required this.onChanged,
13 - this.title,
8 + required this.items,
9 + required this.onChanged,
10 + required this.title,
11 this.displayItem,
12 this.isSeparated = true,
13 });
14
15 final List<CheckBoxItem> items;
16 final String title;
20 - final Widget Function(CheckBoxItem) displayItem;
17 + final Widget Function(CheckBoxItem)? displayItem;
18 final bool isSeparated;
19 final Function(int, bool) onChanged;
20
@@ -61,7 +58,7 @@ class CheckBoxPickerState extends State<CheckBoxPicker> {
58 child: ClipRRect(
59 borderRadius: BorderRadius.all(Radius.circular(30)),
60 child: Container(
64 - color: Theme.of(context).accentTextTheme.title.color,
61 + color: Theme.of(context).accentTextTheme!.headline6!.color!,
62 child: ConstrainedBox(
63 constraints: BoxConstraints(
64 maxHeight: MediaQuery.of(context).size.height * 0.65,
@@ -98,14 +95,14 @@ class CheckBoxPickerState extends State<CheckBoxPicker> {
95
96 Widget itemsList() {
97 return Container(
101 - color: Theme.of(context).accentTextTheme.headline6.backgroundColor,
98 + color: Theme.of(context).accentTextTheme!.headline6!.backgroundColor!,
99 child: ListView.separated(
100 padding: EdgeInsets.zero,
101 controller: controller,
102 shrinkWrap: true,
103 separatorBuilder: (context, index) => widget.isSeparated
104 ? Divider(
108 - color: Theme.of(context).accentTextTheme.title.backgroundColor,
105 + color: Theme.of(context).accentTextTheme!.headline6!.backgroundColor!,
106 height: 1,
107 )
108 : const SizedBox(),
@@ -124,13 +121,13 @@ class CheckBoxPickerState extends State<CheckBoxPicker> {
121 },
122 child: Container(
123 height: 55,
127 - color: Theme.of(context).accentTextTheme.headline6.color,
124 + color: Theme.of(context).accentTextTheme!.headline6!.color!,
125 padding: EdgeInsets.only(left: 24, right: 24),
126 child: CheckboxListTile(
127 value: item.value,
128 activeColor: item.value
129 ? Palette.blueCraiola
133 - : Theme.of(context).accentTextTheme.subhead.decorationColor,
130 + : Theme.of(context).accentTextTheme!.subtitle1!.decorationColor!,
131 checkColor: Colors.white,
132 title: widget.displayItem?.call(item) ??
133 Text(
@@ -141,11 +138,15 @@ class CheckBoxPickerState extends State<CheckBoxPicker> {
138 fontWeight: FontWeight.w600,
139 color: item.isDisabled
140 ? Colors.grey.withOpacity(0.5)
144 - : Theme.of(context).primaryTextTheme.title.color,
141 + : Theme.of(context).primaryTextTheme!.headline6!.color!,
142 decoration: TextDecoration.none,
143 ),
144 ),
148 - onChanged: (bool value) {
145 + onChanged: (bool? value) {
146 + if (value == null) {
147 + return;
148 + }
149 +
150 item.value = value;
151 widget.onChanged(index, value);
152 setState(() {});
lib/src/widgets/checkbox_widget.dart
+6 -6
@@ -5,9 +5,9 @@ import 'package:flutter/material.dart';
5
6 class CheckboxWidget extends StatefulWidget {
7 CheckboxWidget({
8 - @required this.value,
9 - @required this.caption,
10 - @required this.onChanged});
8 + required this.value,
9 + required this.caption,
10 + required this.onChanged});
11
12 final bool value;
13 final String caption;
@@ -42,12 +42,12 @@ class CheckboxWidgetState extends State<CheckboxWidget> {
42 decoration: BoxDecoration(
43 color: value
44 ? Palette.blueCraiola
45 - : Theme.of(context).accentTextTheme.subhead.decorationColor,
45 + : Theme.of(context).accentTextTheme!.subtitle1!.decorationColor!,
46 borderRadius: BorderRadius.all(Radius.circular(2)),
47 border: Border.all(
48 color: value
49 ? Palette.blueCraiola
50 - : Theme.of(context).accentTextTheme.overline.color,
50 + : Theme.of(context).accentTextTheme!.overline!.color!,
51 width: 1
52 )
53 ),
@@ -66,7 +66,7 @@ class CheckboxWidgetState extends State<CheckboxWidget> {
66 child: Text(
67 caption,
68 style: TextStyle(
69 - color: Theme.of(context).primaryTextTheme.title.color,
69 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
70 fontSize: 18,
71 fontFamily: 'Lato',
72 fontWeight: FontWeight.w500,
lib/src/widgets/collapsible_standart_list.dart
+24 -25
@@ -3,24 +3,23 @@ import 'package:flutter/material.dart';
3
4 class CollapsibleSectionList extends SectionStandardList {
5 CollapsibleSectionList(
6 - {bool hasTopSeparator,
7 - BuildContext context,
8 - int sectionCount,
9 - int Function(int sectionIndex) itemCounter,
10 - Widget Function(BuildContext context, int sectionIndex, int itemIndex)
11 - itemBuilder,
12 - Widget Function(BuildContext context, int sectionIndex)
13 - sectionTitleBuilder,
14 - Color themeColor,
15 - Color dividerThemeColor})
6 + {required BuildContext context,
7 + required int sectionCount,
8 + required int Function(int sectionIndex) itemCounter,
9 + required Widget Function(BuildContext context, int sectionIndex, int itemIndex) itemBuilder,
10 + Color? themeColor,
11 + Color? dividerThemeColor,
12 + Widget Function(BuildContext context, int sectionIndex)? sectionTitleBuilder,
13 + bool hasTopSeparator = false})
14 : super(
17 - hasTopSeparator: hasTopSeparator,
18 - sectionCount: sectionCount,
19 - itemCounter: itemCounter,
20 - itemBuilder: itemBuilder,
21 - sectionTitleBuilder: sectionTitleBuilder,
22 - themeColor: themeColor,
23 - dividerThemeColor: dividerThemeColor);
15 + context: context,
16 + hasTopSeparator: hasTopSeparator,
17 + sectionCount: sectionCount,
18 + itemCounter: itemCounter,
19 + itemBuilder: itemBuilder,
20 + sectionTitleBuilder: sectionTitleBuilder,
21 + themeColor: themeColor,
22 + dividerThemeColor: dividerThemeColor);
23
24 @override
25 List<Widget> transform(
@@ -28,12 +27,10 @@ class CollapsibleSectionList extends SectionStandardList {
27 BuildContext context,
28 int sectionCount,
29 int Function(int sectionIndex) itemCounter,
31 - Widget Function(BuildContext context, int sectionIndex, int itemIndex)
32 - itemBuilder,
33 - Widget Function(BuildContext context, int sectionIndex)
34 - sectionTitleBuilder,
35 - themeColor,
36 - dividerThemeColor) {
30 + Widget Function(BuildContext context, int sectionIndex, int itemIndex) itemBuilder,
31 + Widget Function(BuildContext context, int sectionIndex)? sectionTitleBuilder,
32 + Color? themeColor,
33 + Color? dividerThemeColor) {
34 final items = <Widget>[];
35
36 for (var sectionIndex = 0; sectionIndex < sectionCount; sectionIndex++) {
@@ -70,8 +67,10 @@ class CollapsibleSectionList extends SectionStandardList {
67 @override
68 Widget buildTitle(
69 List<Widget> items, int sectionIndex, BuildContext context) {
73 - final title = sectionTitleBuilder(context, sectionIndex);
74 - return title;
70 + if (sectionTitleBuilder == null) {
71 + throw Exception('Cannot to build title. sectionTitleBuilder is null');
72 + }
73 + return sectionTitleBuilder!.call(context, sectionIndex);
74 }
75
76 @override
lib/src/widgets/discount_badge.dart
+4 -4
@@ -3,15 +3,15 @@ import 'package:cake_wallet/generated/i18n.dart';
3
4 class DiscountBadge extends StatelessWidget {
5 const DiscountBadge({
6 - Key key,
7 - this.isAmount = false,
8 - @required this.percentage,
6 + Key? key,
7 + required this.percentage,
8 this.discountBackground,
9 + this.isAmount = false,
10 }) : super(key: key);
11
12 final double percentage;
13 final bool isAmount;
14 - final AssetImage discountBackground;
14 + final AssetImage? discountBackground;
15
16 @override
17 Widget build(BuildContext context) {
lib/src/widgets/introducing_card.dart
+11 -8
@@ -4,7 +4,10 @@ import 'package:cake_wallet/palette.dart';
4
5 class IntroducingCard extends StatelessWidget {
6 IntroducingCard(
7 - {this.borderColor, this.closeCard, this.title, this.subTitle});
7 + {required this.borderColor,
8 + required this.closeCard,
9 + required this.title,
10 + required this.subTitle});
11
12 final String title;
13 final String subTitle;
@@ -23,7 +26,7 @@ class IntroducingCard extends StatelessWidget {
26 color: borderColor,
27 width: 1,
28 ),
26 - color: Theme.of(context).textTheme.title.backgroundColor),
29 + color: Theme.of(context).textTheme!.headline6!.backgroundColor!),
30 child: Row(
31 mainAxisAlignment: MainAxisAlignment.spaceBetween,
32 crossAxisAlignment: CrossAxisAlignment.start,
@@ -41,9 +44,9 @@ class IntroducingCard extends StatelessWidget {
44 fontFamily: 'Lato',
45 fontWeight: FontWeight.bold,
46 color: Theme.of(context)
44 - .accentTextTheme
45 - .display3
46 - .backgroundColor,
47 + .accentTextTheme!
48 + .headline2!
49 + .backgroundColor!,
50 height: 1),
51 maxLines: 1,
52 textAlign: TextAlign.center),
@@ -54,9 +57,9 @@ class IntroducingCard extends StatelessWidget {
57 fontSize: 12,
58 fontFamily: 'Lato',
59 color: Theme.of(context)
57 - .accentTextTheme
58 - .display3
59 - .backgroundColor,
60 + .accentTextTheme!
61 + .headline2!
62 + .backgroundColor!,
63 height: 1)),
64 ],
65 ),
lib/src/widgets/market_place_item.dart
+10 -10
@@ -4,9 +4,9 @@ class MarketPlaceItem extends StatelessWidget {
4
5
6 MarketPlaceItem({
7 - @required this.onTap,
8 - @required this.title,
9 - @required this.subTitle,
7 + required this.onTap,
8 + required this.title,
9 + required this.subTitle,
10 });
11
12 final VoidCallback onTap;
@@ -23,7 +23,7 @@ class MarketPlaceItem extends StatelessWidget {
23 padding: EdgeInsets.all(20),
24 width: double.infinity,
25 decoration: BoxDecoration(
26 - color: Theme.of(context).textTheme.title.backgroundColor,
26 + color: Theme.of(context).textTheme!.headline6!.backgroundColor!,
27 borderRadius: BorderRadius.circular(20),
28 border: Border.all(
29 color: Colors.white.withOpacity(0.20),
@@ -37,9 +37,9 @@ class MarketPlaceItem extends StatelessWidget {
37 title,
38 style: TextStyle(
39 color: Theme.of(context)
40 - .accentTextTheme
41 - .display3
42 - .backgroundColor,
40 + .accentTextTheme!
41 + .headline2!
42 + .backgroundColor!,
43 fontSize: 24,
44 fontWeight: FontWeight.w900,
45 ),
@@ -49,9 +49,9 @@ class MarketPlaceItem extends StatelessWidget {
49 subTitle,
50 style: TextStyle(
51 color: Theme.of(context)
52 - .accentTextTheme
53 - .display3
54 - .backgroundColor,
52 + .accentTextTheme!
53 + .headline2!
54 + .backgroundColor!,
55 fontWeight: FontWeight.w500,
56 fontFamily: 'Lato'),
57 )
lib/src/widgets/nav_bar.dart
+13 -15
@@ -3,11 +3,10 @@ import 'package:flutter/material.dart';
3
4 class NavBar extends StatelessWidget implements ObstructingPreferredSizeWidget {
5 factory NavBar(
6 - {BuildContext context,
7 - Widget leading,
8 - Widget middle,
9 - Widget trailing,
10 - Color backgroundColor}) {
6 + {Widget? leading,
7 + Widget? middle,
8 + Widget? trailing,
9 + Color? backgroundColor}) {
10
11 return NavBar._internal(
12 leading: leading,
@@ -18,11 +17,10 @@ class NavBar extends StatelessWidget implements ObstructingPreferredSizeWidget {
17 }
18
19 factory NavBar.withShadow(
21 - {BuildContext context,
22 - Widget leading,
23 - Widget middle,
24 - Widget trailing,
25 - Color backgroundColor}) {
20 + {Widget? leading,
21 + Widget? middle,
22 + Widget? trailing,
23 + Color? backgroundColor}) {
24
25 return NavBar._internal(
26 leading: leading,
@@ -52,11 +50,11 @@ class NavBar extends StatelessWidget implements ObstructingPreferredSizeWidget {
50 static const _originalHeight = 44.0; // iOS nav bar height
51 static const _height = 60.0;
52
55 - final Widget leading;
56 - final Widget middle;
57 - final Widget trailing;
58 - final Color backgroundColor;
59 - final BoxDecoration decoration;
53 + final Widget? leading;
54 + final Widget? middle;
55 + final Widget? trailing;
56 + final Color? backgroundColor;
57 + final BoxDecoration? decoration;
58 final double height;
59
60 @override
lib/src/widgets/picker.dart
+25 -26
@@ -1,17 +1,15 @@
1 -import 'dart:ui';
2 -import 'package:flutter/cupertino.dart';
1 import 'package:flutter/material.dart';
2 import 'package:cake_wallet/src/widgets/alert_background.dart';
3 import 'package:cake_wallet/src/widgets/alert_close_button.dart';
4
5 class Picker<Item extends Object> extends StatefulWidget {
6 Picker({
9 - @required this.selectedAtIndex,
10 - @required this.items,
11 - @required this.onItemSelected,
7 + required this.selectedAtIndex,
8 + required this.items,
9 + required this.onItemSelected,
10 this.title,
11 this.displayItem,
14 - this.images,
12 + this.images = const <Image>[],
13 this.description,
14 this.mainAxisAlignment = MainAxisAlignment.start,
15 this.isGridView = false,
@@ -25,15 +23,15 @@ class Picker<Item extends Object> extends StatefulWidget {
23 final int selectedAtIndex;
24 final List<Item> items;
25 final List<Image> images;
28 - final String title;
29 - final String description;
26 + final String? title;
27 + final String? description;
28 final Function(Item) onItemSelected;
29 final MainAxisAlignment mainAxisAlignment;
32 - final String Function(Item) displayItem;
30 + final String Function(Item)? displayItem;
31 final bool isGridView;
32 final bool isSeparated;
35 - final String hintText;
36 - final bool Function(Item, String) matchingCriteria;
33 + final String? hintText;
34 + final bool Function(Item, String)? matchingCriteria;
35
36 @override
37 PickerState createState() => PickerState<Item>(items, images, onItemSelected);
@@ -80,7 +78,7 @@ class PickerState<Item> extends State<Picker> {
78 Container(
79 padding: EdgeInsets.symmetric(horizontal: 24),
80 child: Text(
83 - widget.title,
81 + widget.title!,
82 textAlign: TextAlign.center,
83 style: TextStyle(
84 fontSize: 18,
@@ -96,7 +94,7 @@ class PickerState<Item> extends State<Picker> {
94 child: ClipRRect(
95 borderRadius: BorderRadius.all(Radius.circular(30)),
96 child: Container(
99 - color: Theme.of(context).accentTextTheme.title.color,
97 + color: Theme.of(context).accentTextTheme!.headline6!.color!,
98 child: ConstrainedBox(
99 constraints: BoxConstraints(
100 maxHeight: MediaQuery.of(context).size.height * 0.65,
@@ -109,12 +107,12 @@ class PickerState<Item> extends State<Picker> {
107 padding: const EdgeInsets.all(16),
108 child: TextFormField(
109 controller: searchController,
112 - style: TextStyle(color: Theme.of(context).primaryTextTheme.title.color),
110 + style: TextStyle(color: Theme.of(context).primaryTextTheme!.headline6!.color!),
111 decoration: InputDecoration(
112 hintText: widget.hintText,
113 prefixIcon: Image.asset("assets/images/search_icon.png"),
114 filled: true,
117 - fillColor: Theme.of(context).accentTextTheme.display2.color,
115 + fillColor: Theme.of(context).accentTextTheme!.headline3!.color!,
116 alignLabelWithHint: false,
117 contentPadding: const EdgeInsets.symmetric(vertical: 4, horizontal: 16),
118 enabledBorder: OutlineInputBorder(
@@ -131,7 +129,7 @@ class PickerState<Item> extends State<Picker> {
129 ),
130 ),
131 Divider(
134 - color: Theme.of(context).accentTextTheme.title.backgroundColor,
132 + color: Theme.of(context).accentTextTheme!.headline6!.backgroundColor!,
133 height: 1,
134 ),
135 if (widget.selectedAtIndex != -1) buildSelectedItem(),
@@ -149,14 +147,14 @@ class PickerState<Item> extends State<Picker> {
147 left: 24,
148 right: 24,
149 child: Text(
152 - widget.description,
150 + widget.description!,
151 textAlign: TextAlign.center,
152 style: TextStyle(
153 fontSize: 12,
154 fontWeight: FontWeight.w500,
155 fontFamily: 'Lato',
156 decoration: TextDecoration.none,
159 - color: Theme.of(context).primaryTextTheme.title.color,
157 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
158 ),
159 ),
160 )
@@ -180,7 +178,7 @@ class PickerState<Item> extends State<Picker> {
178
179 Widget itemsList() {
180 return Container(
183 - color: Theme.of(context).accentTextTheme.headline6.backgroundColor,
181 + color: Theme.of(context).accentTextTheme!.headline6!.backgroundColor!,
182 child: widget.isGridView
183 ? GridView.builder(
184 padding: EdgeInsets.zero,
@@ -200,7 +198,7 @@ class PickerState<Item> extends State<Picker> {
198 shrinkWrap: true,
199 separatorBuilder: (context, index) => widget.isSeparated
200 ? Divider(
203 - color: Theme.of(context).accentTextTheme.title.backgroundColor,
201 + color: Theme.of(context).accentTextTheme!.headline6!.backgroundColor!,
202 height: 1,
203 )
204 : const SizedBox(),
@@ -229,7 +227,7 @@ class PickerState<Item> extends State<Picker> {
227 },
228 child: Container(
229 height: 55,
232 - color: Theme.of(context).accentTextTheme.headline6.color,
230 + color: Theme.of(context).accentTextTheme!.headline6!.color!,
231 padding: EdgeInsets.only(left: 24, right: 24),
232 child: Row(
233 mainAxisSize: MainAxisSize.max,
@@ -241,12 +239,13 @@ class PickerState<Item> extends State<Picker> {
239 child: Padding(
240 padding: EdgeInsets.only(left: image != null ? 12 : 0),
241 child: Text(
244 - widget.displayItem?.call(item) ?? item.toString(),
242 + // What a hack (item as) ?
243 + widget.displayItem?.call(item as Object) ?? item.toString(),
244 style: TextStyle(
245 fontSize: 14,
246 fontFamily: 'Lato',
247 fontWeight: FontWeight.w600,
249 - color: Theme.of(context).primaryTextTheme.title.color,
248 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
249 decoration: TextDecoration.none,
250 ),
251 ),
@@ -264,7 +263,7 @@ class PickerState<Item> extends State<Picker> {
263
264 return Container(
265 height: 55,
267 - color: Theme.of(context).accentTextTheme.headline6.color,
266 + color: Theme.of(context).accentTextTheme!.headline6!.color!,
267 padding: EdgeInsets.only(left: 24, right: 24),
268 child: Row(
269 mainAxisSize: MainAxisSize.max,
@@ -281,13 +280,13 @@ class PickerState<Item> extends State<Picker> {
280 fontSize: 16,
281 fontFamily: 'Lato',
282 fontWeight: FontWeight.w700,
284 - color: Theme.of(context).primaryTextTheme.title.color,
283 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
284 decoration: TextDecoration.none,
285 ),
286 ),
287 ),
288 ),
290 - Icon(Icons.check_circle, color: Theme.of(context).accentTextTheme.body2.color),
289 + Icon(Icons.check_circle, color: Theme.of(context).accentTextTheme!.bodyText1!.color!),
290 ],
291 ),
292 );
lib/src/widgets/primary_button.dart
+59 -52
@@ -4,17 +4,17 @@ import 'package:flutter/material.dart';
4
5 class PrimaryButton extends StatelessWidget {
6 const PrimaryButton(
7 - {@required this.onPressed,
8 - @required this.text,
9 - @required this.color,
10 - @required this.textColor,
7 + {required this.text,
8 + required this.color,
9 + required this.textColor,
10 + this.onPressed,
11 this.isDisabled = false,
12 this.isDottedBorder = false,
13 this.borderColor = Colors.black,
14 this.onDisabledPressed});
15
16 - final VoidCallback onPressed;
17 - final VoidCallback onDisabledPressed;
16 + final VoidCallback? onPressed;
17 + final VoidCallback? onDisabledPressed;
18 final Color color;
19 final Color textColor;
20 final Color borderColor;
@@ -25,19 +25,21 @@ class PrimaryButton extends StatelessWidget {
25 @override
26 Widget build(BuildContext context) {
27 final content = ButtonTheme(
28 - minWidth: double.infinity,
29 - height: 52.0,
30 - child: FlatButton(
28 + //minWidth: double.infinity,
29 + //height: 52.0,
30 + child: TextButton(
31 onPressed: isDisabled
32 ? (onDisabledPressed != null ? onDisabledPressed : null)
33 : onPressed,
34 - color: isDisabled ? color.withOpacity(0.5) : color,
35 - splashColor: Colors.transparent,
36 - highlightColor: Colors.transparent,
37 - disabledColor: color.withOpacity(0.5),
38 - shape: RoundedRectangleBorder(
39 - borderRadius: BorderRadius.circular(26.0),
40 - ),
34 + // FIX-ME: Need to add style
35 + // color: isDisabled ? color.withOpacity(0.5) : color,
36 + //splashColor: Colors.transparent,
37 + //highlightColor: Colors.transparent,
38 + //disabledColor: color.withOpacity(0.5),
39 + //shape: RoundedRectangleBorder(
40 + // borderRadius: BorderRadius.circular(26.0),
41 + //),
42 + style: ButtonStyle(backgroundColor: MaterialStateProperty.all(isDisabled ? color.withOpacity(0.5) : color)),
43 child: Text(text,
44 textAlign: TextAlign.center,
45 style: TextStyle(
@@ -62,10 +64,10 @@ class PrimaryButton extends StatelessWidget {
64
65 class LoadingPrimaryButton extends StatelessWidget {
66 const LoadingPrimaryButton(
65 - {@required this.onPressed,
66 - @required this.text,
67 - @required this.color,
68 - @required this.textColor,
67 + {required this.onPressed,
68 + required this.text,
69 + required this.color,
70 + required this.textColor,
71 this.isDisabled = false,
72 this.isLoading = false});
73
@@ -79,14 +81,16 @@ class LoadingPrimaryButton extends StatelessWidget {
81 @override
82 Widget build(BuildContext context) {
83 return ButtonTheme(
82 - minWidth: double.infinity,
83 - height: 52.0,
84 - child: FlatButton(
84 + // FIX-ME: styles
85 + //minWidth: double.infinity,
86 + //height: 52.0,
87 + child: TextButton(
88 onPressed: (isLoading || isDisabled) ? null : onPressed,
86 - color: color,
87 - disabledColor: color.withOpacity(0.5),
88 - shape: RoundedRectangleBorder(
89 - borderRadius: BorderRadius.circular(26.0)),
89 + //color: color,
90 + //disabledColor: color.withOpacity(0.5),
91 + //shape: RoundedRectangleBorder(
92 + //borderRadius: BorderRadius.circular(26.0)),
93 + style: ButtonStyle(backgroundColor: MaterialStateProperty.all(isDisabled ? color.withOpacity(0.5) : color)),
94 child: isLoading
95 ? CupertinoActivityIndicator(animating: true)
96 : Text(text,
@@ -103,14 +107,14 @@ class LoadingPrimaryButton extends StatelessWidget {
107
108 class PrimaryIconButton extends StatelessWidget {
109 const PrimaryIconButton({
106 - @required this.onPressed,
107 - @required this.iconData,
108 - @required this.text,
109 - @required this.color,
110 - @required this.borderColor,
111 - @required this.iconColor,
112 - @required this.iconBackgroundColor,
113 - @required this.textColor,
110 + required this.onPressed,
111 + required this.iconData,
112 + required this.text,
113 + required this.color,
114 + required this.borderColor,
115 + required this.iconColor,
116 + required this.iconBackgroundColor,
117 + required this.textColor,
118 this.mainAxisAlignment = MainAxisAlignment.start,
119 this.radius = 26
120 });
@@ -129,14 +133,15 @@ class PrimaryIconButton extends StatelessWidget {
133 @override
134 Widget build(BuildContext context) {
135 return ButtonTheme(
132 - minWidth: double.infinity,
133 - height: 52.0,
134 - child: FlatButton(
136 + // FIX-ME: styles
137 + //minWidth: double.infinity,
138 + //height: 52.0,
139 + child: TextButton(
140 onPressed: onPressed,
136 - color: color,
137 - shape: RoundedRectangleBorder(
138 - side: BorderSide(color: borderColor),
139 - borderRadius: BorderRadius.circular(radius)),
141 + //color: color,
142 + //shape: RoundedRectangleBorder(
143 + // side: BorderSide(color: borderColor),
144 + // borderRadius: BorderRadius.circular(radius)),
145 child: Stack(
146 children: <Widget>[
147 Row(
@@ -170,11 +175,11 @@ class PrimaryIconButton extends StatelessWidget {
175
176 class PrimaryImageButton extends StatelessWidget {
177 const PrimaryImageButton(
173 - {@required this.onPressed,
174 - @required this.image,
175 - @required this.text,
176 - @required this.color,
177 - @required this.textColor,
178 + {required this.onPressed,
179 + required this.image,
180 + required this.text,
181 + required this.color,
182 + required this.textColor,
183 this.borderColor = Colors.transparent});
184
185 final VoidCallback onPressed;
@@ -189,12 +194,14 @@ class PrimaryImageButton extends StatelessWidget {
194 return ButtonTheme(
195 minWidth: double.infinity,
196 height: 52.0,
192 - child: FlatButton(
197 + child: TextButton(
198 onPressed: onPressed,
194 - color: color,
195 - shape: RoundedRectangleBorder(
196 - side: BorderSide(color: borderColor),
197 - borderRadius: BorderRadius.circular(26.0)),
199 + // FIX-ME: Style
200 + //color: color,
201 + //shape: RoundedRectangleBorder(
202 + // side: BorderSide(color: borderColor),
203 + // borderRadius: BorderRadius.circular(26.0)),
204 + style: ButtonStyle(backgroundColor: MaterialStateProperty.all(color)),
205 child:Center(
206 child: Row(
207 mainAxisSize: MainAxisSize.min,
lib/src/widgets/scollable_with_bottom_section.dart
+4 -4
@@ -3,15 +3,15 @@ import 'package:flutter/material.dart';
3
4 class ScrollableWithBottomSection extends StatefulWidget {
5 ScrollableWithBottomSection(
6 - {this.content,
7 - this.bottomSection,
6 + {required this.content,
7 + required this.bottomSection,
8 this.contentPadding,
9 this.bottomSectionPadding});
10
11 final Widget content;
12 final Widget bottomSection;
13 - final EdgeInsets contentPadding;
14 - final EdgeInsets bottomSectionPadding;
13 + final EdgeInsets? contentPadding;
14 + final EdgeInsets? bottomSectionPadding;
15
16 @override
17 ScrollableWithBottomSectionState createState() =>
lib/src/widgets/seed_language_selector.dart
+2 -2
@@ -5,7 +5,7 @@ import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart';
5 import 'package:cake_wallet/src/screens/seed_language/widgets/seed_language_picker.dart';
6
7 class SeedLanguageSelector extends StatefulWidget {
8 - SeedLanguageSelector({Key key, this.initialSelected}) : super(key: key);
8 + SeedLanguageSelector({Key? key, required this.initialSelected}) : super(key: key);
9
10 final String initialSelected;
11
@@ -15,7 +15,7 @@ class SeedLanguageSelector extends StatefulWidget {
15 }
16
17 class SeedLanguageSelectorState extends State<SeedLanguageSelector> {
18 - SeedLanguageSelectorState({this.selected});
18 + SeedLanguageSelectorState({required this.selected});
19
20 final seedLocales = [
21 S.current.seed_language_english,
lib/src/widgets/seed_widget.dart
+16 -10
@@ -12,21 +12,27 @@ import 'package:cake_wallet/generated/i18n.dart';
12 import 'package:flutter/widgets.dart';
13
14 class SeedWidget extends StatefulWidget {
15 - SeedWidget({Key key, this.language, this.type, this.onSeedChange}) : super(key: key);
15 + SeedWidget({
16 + Key? key,
17 + required this.language,
18 + required this.type,
19 + this.onSeedChange}) : super(key: key);
20
21 final String language;
22 final WalletType type;
19 - final void Function(String) onSeedChange;
23 + final void Function(String)? onSeedChange;
24
25 @override
26 SeedWidgetState createState() => SeedWidgetState(language, type);
27 }
28
29 class SeedWidgetState extends State<SeedWidget> {
30 +
31 SeedWidgetState(String language, this.type)
32 : controller = TextEditingController(),
33 focusNode = FocusNode(),
29 - words = SeedValidator.getWordList(type: type, language: language) {
34 + words = SeedValidator.getWordList(type: type, language: language),
35 + _showPlaceholder = false {
36 focusNode.addListener(() {
37 setState(() {
38 if (!focusNode.hasFocus && controller.text.isEmpty) {
@@ -83,7 +89,7 @@ class SeedWidgetState extends State<SeedWidget> {
89 cursorColor: Colors.blue,
90 backgroundCursorColor: Colors.blue,
91 validStyle: TextStyle(
86 - color: Theme.of(context).primaryTextTheme.title.color,
92 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
93 backgroundColor: Colors.transparent,
94 fontWeight: FontWeight.normal,
95 fontSize: 16),
@@ -96,7 +102,7 @@ class SeedWidgetState extends State<SeedWidget> {
102 controller: controller,
103 words: words,
104 textStyle: TextStyle(
99 - color: Theme.of(context).primaryTextTheme.title.color,
105 + color: Theme.of(context).primaryTextTheme!.headline6!.color!,
106 backgroundColor: Colors.transparent,
107 fontWeight: FontWeight.normal,
108 fontSize: 16),
@@ -117,15 +123,15 @@ class SeedWidgetState extends State<SeedWidget> {
123 BorderRadius.all(Radius.circular(6))),
124 child: Image.asset('assets/images/paste_ios.png',
125 color: Theme.of(context)
120 - .primaryTextTheme
121 - .display1
122 - .decorationColor)),
126 + .primaryTextTheme!
127 + .headline4!
128 + .decorationColor!)),
129 )))
130 ]),
131 Container(
132 margin: EdgeInsets.only(top: 15),
133 height: 1.0,
128 - color: Theme.of(context).primaryTextTheme.title.backgroundColor),
134 + color: Theme.of(context).primaryTextTheme!.headline6!.backgroundColor!),
135 ]));
136 }
137
@@ -135,7 +141,7 @@ class SeedWidgetState extends State<SeedWidget> {
141 if (value?.text?.isNotEmpty ?? false) {
142 setState(() {
143 _showPlaceholder = false;
138 - controller.text = value.text;
144 + controller.text = value!.text!;
145 });
146 }
147 }
lib/src/widgets/standard_checkbox.dart
+10 -9
@@ -4,10 +4,11 @@ import 'package:flutter/material.dart';
4
5 class StandardCheckbox extends StatefulWidget {
6 StandardCheckbox({
7 - Key key,
8 - @required this.value,
7 + Key? key,
8 + required this.value,
9 this.caption = '',
10 - @required this.onChanged}) : super(key: key);
10 + required this.onChanged})
11 + : super(key: key);
12
13 final bool value;
14 final String caption;
@@ -47,9 +48,9 @@ class StandardCheckboxState extends State<StandardCheckbox> {
48 decoration: BoxDecoration(
49 border: Border.all(
50 color: Theme.of(context)
50 - .primaryTextTheme
51 - .caption
52 - .color,
51 + .primaryTextTheme!
52 + .caption!
53 + .color!,
54 width: 1.0),
55 borderRadius: BorderRadius.all(
56 Radius.circular(8.0)),
@@ -69,9 +70,9 @@ class StandardCheckboxState extends State<StandardCheckbox> {
70 style: TextStyle(
71 fontSize: 16.0,
72 color: Theme.of(context)
72 - .primaryTextTheme
73 - .title
74 - .color),
73 + .primaryTextTheme!
74 + .headline6!
75 + .color!),
76 )
77 )
78 ],
lib/src/widgets/standard_list.dart
+29 -28
@@ -1,16 +1,15 @@
1 import 'package:cake_wallet/palette.dart';
2 import 'package:cake_wallet/src/widgets/standart_list_card.dart';
3 import 'package:cake_wallet/src/widgets/standart_list_status_row.dart';
4 -import 'package:flutter/cupertino.dart';
4 import 'package:flutter/material.dart';
5
6 class StandardListRow extends StatelessWidget {
7 StandardListRow(
9 - {@required this.title, @required this.isSelected, this.onTap});
8 + {required this.title, required this.isSelected, this.onTap});
9
10 final String title;
11 final bool isSelected;
13 - final void Function(BuildContext context) onTap;
12 + final void Function(BuildContext context)? onTap;
13
14 @override
15 Widget build(BuildContext context) {
@@ -32,9 +31,9 @@ class StandardListRow extends StatelessWidget {
31 ])));
32 }
33
35 - Widget buildLeading(BuildContext context) => null;
34 + Widget? buildLeading(BuildContext context) => null;
35
37 - Widget buildCenter(BuildContext context, {@required bool hasLeftOffset}) {
36 + Widget buildCenter(BuildContext context, {required bool hasLeftOffset}) {
37 // FIXME: find better way for keep text on left side.
38 return Expanded(
39 child: Row(mainAxisAlignment: MainAxisAlignment.start, children: [
@@ -51,11 +50,11 @@ class StandardListRow extends StatelessWidget {
50 ]));
51 }
52
54 - Widget buildTrailing(BuildContext context) => null;
53 + Widget? buildTrailing(BuildContext context) => null;
54
55 Color titleColor(BuildContext context) => isSelected
56 ? Palette.blueCraiola
58 - : Theme.of(context).primaryTextTheme.title.color;
57 + : Theme.of(context).primaryTextTheme!.headline6!.color!;
58
59 Color _backgroundColor(BuildContext context) {
60 return Theme.of(context).backgroundColor;
@@ -76,13 +75,11 @@ class SectionHeaderListRow extends StatelessWidget {
75
76 class StandardListSeparator extends StatelessWidget {
77
79 - StandardListSeparator({this.padding,this.height=1});
78 + StandardListSeparator({this.padding, this.height = 1});
79
81 - final EdgeInsets padding;
80 + final EdgeInsets? padding;
81 final double height;
82
84 -
85 -
83 @override
84 Widget build(BuildContext context) {
85 return Container(
@@ -91,12 +88,13 @@ class StandardListSeparator extends StatelessWidget {
88 color: Theme.of(context).backgroundColor,
89 child: Container(
90 height: height,
94 - color: Theme.of(context).primaryTextTheme.title.backgroundColor));
91 + // color: Theme.of(context).primaryTextTheme!.headline6!.backgroundColor!
92 + ));
93 }
94 }
95
96 class StandardList extends StatelessWidget {
99 - StandardList({@required this.itemCount, @required this.itemBuilder});
97 + StandardList({required this.itemCount, required this.itemBuilder});
98
99 final int itemCount;
100 final IndexedWidgetBuilder itemBuilder;
@@ -113,7 +111,7 @@ class StandardList extends StatelessWidget {
111 }
112
113 class SectionStandardListItem {
116 - SectionStandardListItem({this.hasFullSeparator = false, this.child});
114 + SectionStandardListItem({this.hasFullSeparator = false, required this.child});
115
116 final bool hasFullSeparator;
117 final Widget child;
@@ -121,14 +119,14 @@ class SectionStandardListItem {
119
120 class SectionStandardList extends StatelessWidget {
121 SectionStandardList(
124 - {@required this.itemCounter,
125 - @required this.itemBuilder,
126 - @required this.sectionCount,
127 - this.sectionTitleBuilder,
128 - this.hasTopSeparator = false,
122 + {required this.itemCounter,
123 + required this.itemBuilder,
124 + required this.sectionCount,
125 + required BuildContext context,
126 this.themeColor,
127 this.dividerThemeColor,
131 - BuildContext context})
128 + this.sectionTitleBuilder,
129 + this.hasTopSeparator = false,})
130 : totalRows = [] {
131 totalRows.addAll(transform(
132 hasTopSeparator,
@@ -146,11 +144,11 @@ class SectionStandardList extends StatelessWidget {
144 final int Function(int sectionIndex) itemCounter;
145 final Widget Function(BuildContext context, int sectionIndex, int itemIndex)
146 itemBuilder;
149 - final Widget Function(BuildContext context, int sectionIndex)
147 + final Widget Function(BuildContext context, int sectionIndex)?
148 sectionTitleBuilder;
149 final List<Widget> totalRows;
152 - final Color themeColor;
153 - final Color dividerThemeColor;
150 + final Color? themeColor;
151 + final Color? dividerThemeColor;
152
153 List<Widget> transform(
154 bool hasTopSeparator,
@@ -159,10 +157,10 @@ class SectionStandardList extends StatelessWidget {
157 int Function(int sectionIndex) itemCounter,
158 Widget Function(BuildContext context, int sectionIndex, int itemIndex)
159 itemBuilder,
162 - Widget Function(BuildContext context, int sectionIndex)
160 + Widget Function(BuildContext context, int sectionIndex)?
161 sectionTitleBuilder,
164 - Color themeColor,
165 - Color dividerThemeColor) {
162 + Color? themeColor,
163 + Color? dividerThemeColor) {
164 final items = <Widget>[];
165
166 for (var sectionIndex = 0; sectionIndex < sectionCount; sectionIndex++) {
@@ -188,8 +186,11 @@ class SectionStandardList extends StatelessWidget {
186
187 Widget buildTitle(
188 List<Widget> items, int sectionIndex, BuildContext context) {
191 - final title = sectionTitleBuilder(context, sectionIndex);
192 - return title;
189 + if (sectionTitleBuilder == null) {
190 + throw Exception('Cannot to build title. sectionTitleBuilder is null');
191 + }
192 +
193 + return sectionTitleBuilder!.call(context, sectionIndex);
194 }
195
196 List<Widget> buildSection(int itemCount, List<Widget> items, int sectionIndex,
lib/src/widgets/standart_list_card.dart
+7 -4
@@ -1,11 +1,14 @@
1 import 'package:cake_wallet/palette.dart';
2 -import 'package:flutter/cupertino.dart';
2 import 'package:flutter/material.dart';
3 import 'package:cake_wallet/themes/theme_base.dart';
4
5 class TradeDatailsStandartListCard extends StatelessWidget {
6 TradeDatailsStandartListCard(
8 - {this.id, this.create, this.pair, this.onTap, this.currentTheme});
7 + {required this.id,
8 + required this.create,
9 + required this.pair,
10 + required this.onTap,
11 + required this.currentTheme});
12
13 final String id;
14 final String create;
@@ -18,8 +21,8 @@ class TradeDatailsStandartListCard extends StatelessWidget {
21 final darkTheme = currentTheme == ThemeType.dark;
22
23 final baseGradient = LinearGradient(colors: [
21 - Theme.of(context).primaryTextTheme.subtitle.color,
22 - Theme.of(context).primaryTextTheme.subtitle.decorationColor,
24 + Theme.of(context).primaryTextTheme!.subtitle2!.color!,
25 + Theme.of(context).primaryTextTheme!.subtitle2!.decorationColor!,
26 ], begin: Alignment.centerLeft, end: Alignment.centerRight);
27
28 final gradient = LinearGradient(colors: [
lib/src/widgets/standart_list_row.dart
+7 -7
@@ -3,8 +3,8 @@ import 'package:flutter/material.dart';
3
4 class StandartListRow extends StatelessWidget {
5 StandartListRow(
6 - {this.title,
7 - this.value,
6 + {required this.title,
7 + required this.value,
8 this.titleFontSize = 14,
9 this.valueFontSize = 16,
10 this.image});
@@ -13,7 +13,7 @@ class StandartListRow extends StatelessWidget {
13 final String value;
14 final double titleFontSize;
15 final double valueFontSize;
16 - final Image image;
16 + final Image? image;
17
18 @override
19 Widget build(BuildContext context) {
@@ -31,7 +31,7 @@ class StandartListRow extends StatelessWidget {
31 fontSize: titleFontSize,
32 fontWeight: FontWeight.w500,
33 color:
34 - Theme.of(context).primaryTextTheme.overline.color),
34 + Theme.of(context).primaryTextTheme!.overline!.color!),
35 textAlign: TextAlign.left),
36 Padding(
37 padding: const EdgeInsets.only(top: 12),
@@ -46,9 +46,9 @@ class StandartListRow extends StatelessWidget {
46 fontSize: valueFontSize,
47 fontWeight: FontWeight.w500,
48 color: Theme.of(context)
49 - .primaryTextTheme
50 - .title
51 - .color)),
49 + .primaryTextTheme!
50 + .headline6!
51 + .color!)),
52 ),
53 image != null
54 ? Padding(
lib/src/widgets/standart_list_status_row.dart
+6 -6
@@ -4,7 +4,7 @@ import 'package:flutter/cupertino.dart';
4 import 'package:flutter/material.dart';
5
6 class StandartListStatusRow extends StatelessWidget {
7 - StandartListStatusRow({this.title, this.value});
7 + StandartListStatusRow({required this.title, required this.value});
8
9 final String title;
10 final String value;
@@ -24,13 +24,13 @@ class StandartListStatusRow extends StatelessWidget {
24 style: TextStyle(
25 fontSize: 14,
26 fontWeight: FontWeight.w500,
27 - color: Theme.of(context).primaryTextTheme.overline.color),
27 + color: Theme.of(context).primaryTextTheme!.overline!.color!),
28 textAlign: TextAlign.left),
29 Padding(
30 padding: const EdgeInsets.only(top: 12),
31 child: Container(
32 decoration: BoxDecoration(
33 - color: Theme.of(context).accentTextTheme.display2.color,
33 + color: Theme.of(context).accentTextTheme!.headline3!.color!,
34 borderRadius: BorderRadius.circular(30.0),
35 ),
36 child: Padding(
@@ -51,9 +51,9 @@ class StandartListStatusRow extends StatelessWidget {
51 fontSize: 16,
52 fontWeight: FontWeight.w500,
53 color: Theme.of(context)
54 - .primaryTextTheme
55 - .title
56 - .color))
54 + .primaryTextTheme!
55 + .headline6!
56 + .color!))
57 ],
58 ),
59 ),
lib/src/widgets/standart_switch.dart
+3 -3
@@ -2,7 +2,7 @@ import 'package:flutter/cupertino.dart';
2 import 'package:flutter/material.dart';
3
4 class StandartSwitch extends StatefulWidget {
5 - const StandartSwitch({@required this.value, @required this.onTaped});
5 + const StandartSwitch({required this.value, required this.onTaped});
6
7 final bool value;
8 final VoidCallback onTaped;
@@ -24,8 +24,8 @@ class StandartSwitchState extends State<StandartSwitch> {
24 height: 28,
25 decoration: BoxDecoration(
26 color: widget.value
27 - ? Theme.of(context).accentTextTheme.body2.color
28 - : Theme.of(context).accentTextTheme.display4.color,
27 + ? Theme.of(context).accentTextTheme!.bodyText1!.color!
28 + : Theme.of(context).accentTextTheme!.headline1!.color!,
29 borderRadius: BorderRadius.all(Radius.circular(14.0))),
30 child: Container(
31 width: 24.0,
lib/src/widgets/template_tile.dart
+8 -8
@@ -3,12 +3,12 @@ import 'package:cake_wallet/palette.dart';
3
4 class TemplateTile extends StatefulWidget {
5 TemplateTile({
6 - Key key,
7 - @required this.to,
8 - @required this.amount,
9 - @required this.from,
10 - @required this.onTap,
11 - @required this.onRemove
6 + Key? key,
7 + required this.to,
8 + required this.amount,
9 + required this.from,
10 + required this.onTap,
11 + required this.onRemove
12 }) : super(key: key);
13
14 final String to;
@@ -47,7 +47,7 @@ class TemplateTileState extends State<TemplateTile> {
47
48 @override
49 Widget build(BuildContext context) {
50 - final color = isRemovable ? Colors.white : Theme.of(context).primaryTextTheme.title.color;
50 + final color = isRemovable ? Colors.white : Theme.of(context).primaryTextTheme!.headline6!.color!;
51 final toIcon = Image.asset('assets/images/to_icon.png', color: color);
52
53 final content = Row(
@@ -105,7 +105,7 @@ class TemplateTileState extends State<TemplateTile> {
105 child: Container(
106 height: 40,
107 padding: EdgeInsets.only(left: 24, right: 24),
108 - color: Theme.of(context).primaryTextTheme.display3.decorationColor,
108 + color: Theme.of(context).primaryTextTheme!.headline2!.decorationColor!,
109 child: content,
110 ),
111 ),
lib/src/widgets/trail_button.dart
+9 -5
@@ -2,11 +2,14 @@ import 'package:flutter/material.dart';
2 import 'package:cake_wallet/palette.dart';
3
4 class TrailButton extends StatelessWidget {
5 - TrailButton({@required this.caption, this.textColor, @required this.onPressed});
5 + TrailButton({
6 + required this.caption,
7 + required this.onPressed,
8 + this.textColor});
9
10 final String caption;
11 final VoidCallback onPressed;
9 - final Color textColor;
12 + final Color? textColor;
13
14 @override
15 Widget build(BuildContext context) {
@@ -14,13 +17,14 @@ class TrailButton extends StatelessWidget {
17 minWidth: double.minPositive,
18 highlightColor: Colors.transparent,
19 splashColor: Colors.transparent,
17 - child: FlatButton(
18 - padding: EdgeInsets.all(0),
20 + child: TextButton(
21 + // FIX-ME: ignored padding
22 + //padding: EdgeInsets.all(0),
23 child: Text(
24 caption,
25 style: TextStyle(
26 color: textColor ??
23 - Theme.of(context).accentTextTheme.display4.decorationColor,
27 + Theme.of(context).accentTextTheme!.headline1!.decorationColor!,
28 fontWeight: FontWeight.w600,
29 fontSize: 14),
30 ),
lib/src/widgets/validable_annotated_editable_text.dart
+19 -19
@@ -3,7 +3,7 @@ import 'package:cw_core/wallet_type.dart';
3 import 'package:flutter/material.dart';
4
5 class Annotation extends Comparable<Annotation> {
6 - Annotation({@required this.range, this.style});
6 + Annotation({required this.range, required this.style});
7
8 final TextRange range;
9 final TextStyle style;
@@ -13,7 +13,7 @@ class Annotation extends Comparable<Annotation> {
13 }
14
15 class TextAnnotation extends Comparable<TextAnnotation> {
16 - TextAnnotation({@required this.text, this.style});
16 + TextAnnotation({required this.text, required this.style});
17
18 final TextStyle style;
19 final String text;
@@ -24,24 +24,24 @@ class TextAnnotation extends Comparable<TextAnnotation> {
24
25 class ValidatableAnnotatedEditableText extends EditableText {
26 ValidatableAnnotatedEditableText({
27 - Key key,
28 - FocusNode focusNode,
29 - TextEditingController controller,
30 - List<String> wordList,
31 - ValueChanged<String> onChanged,
32 - ValueChanged<String> onSubmitted,
33 - Color cursorColor,
34 - Color selectionColor,
35 - Color backgroundCursorColor,
36 - TextSelectionControls selectionControls,
37 - this.validStyle,
38 - this.invalidStyle,
27 + Key? key,
28 + required FocusNode focusNode,
29 + required TextEditingController controller,
30 + // required List<String> wordList,
31 + required Color cursorColor,
32 + required Color backgroundCursorColor,
33 + required this.validStyle,
34 + required this.invalidStyle,
35 + required this.words,
36 TextStyle textStyle = const TextStyle(
37 color: Colors.black,
38 backgroundColor: Colors.transparent,
39 fontWeight: FontWeight.normal,
40 fontSize: 16),
44 - @required this.words,
41 + TextSelectionControls? selectionControls,
42 + Color? selectionColor,
43 + ValueChanged<String>? onChanged,
44 + ValueChanged<String>? onSubmitted,
45 }) : super(
46 maxLines: null,
47 key: key,
@@ -83,7 +83,7 @@ class ValidatableAnnotatedEditableTextState extends EditableTextState {
83 super.widget as ValidatableAnnotatedEditableText;
84
85 List<Annotation> getRanges() {
86 - final result = List<Annotation>();
86 + final result = <Annotation>[];
87 final text = textEditingValue.text;
88 final source = text
89 .split(' ')
@@ -98,10 +98,10 @@ class ValidatableAnnotatedEditableTextState extends EditableTextState {
98 .expand((e) => e)
99 .toList();
100 source.sort();
101 - Annotation prev;
101 + Annotation? prev;
102
103 for (var item in source) {
104 - Annotation annotation;
104 + Annotation? annotation;
105
106 if (prev == null) {
107 annotation = Annotation(
@@ -134,7 +134,7 @@ class ValidatableAnnotatedEditableTextState extends EditableTextState {
134 bool validate(String source) => widget.words.indexOf(source) >= 0;
135
136 List<TextRange> range(String pattern, String source) {
137 - final result = List<TextRange>();
137 + final result = <TextRange>[];
138
139 if (pattern.isEmpty || source.isEmpty) {
140 return result;
lib/store/app_store.dart
+5 -5
@@ -14,15 +14,15 @@ class AppStore = AppStoreBase with _$AppStore;
14
15 abstract class AppStoreBase with Store {
16 AppStoreBase(
17 - {this.authenticationStore,
18 - this.walletList,
19 - this.settingsStore,
20 - this.nodeListStore});
17 + {required this.authenticationStore,
18 + required this.walletList,
19 + required this.settingsStore,
20 + required this.nodeListStore});
21
22 AuthenticationStore authenticationStore;
23
24 @observable
25 - WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>
25 + WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>?
26 wallet;
27
28 WalletListStore walletList;
lib/store/dashboard/orders_store.dart
+8 -8
@@ -10,26 +10,26 @@ part 'orders_store.g.dart';
10 class OrdersStore = OrdersStoreBase with _$OrdersStore;
11
12 abstract class OrdersStoreBase with Store {
13 - OrdersStoreBase({this.ordersSource, this.settingsStore}) {
14 - orders = <OrderListItem>[];
15 -
16 - orderId = '';
17 -
13 + OrdersStoreBase({required this.ordersSource,
14 + required this.settingsStore})
15 + : orders = <OrderListItem>[],
16 + orderId = '' {
17 _onOrdersChanged =
18 ordersSource.watch().listen((_) async => await updateOrderList());
20 -
19 updateOrderList();
20 }
21
22 Box<Order> ordersSource;
25 - StreamSubscription<BoxEvent> _onOrdersChanged;
23 +
24 SettingsStore settingsStore;
25
26 + StreamSubscription<BoxEvent>? _onOrdersChanged;
27 +
28 @observable
29 List<OrderListItem> orders;
30
31 @observable
32 - Order order;
32 + Order? order;
33
34 @observable
35 String orderId;
lib/store/dashboard/trade_filter_store.dart
+1 -1
@@ -45,7 +45,7 @@ abstract class TradeFilterStoreBase with Store {
45 }
46 }
47
48 - List<TradeListItem> filtered({List<TradeListItem> trades, WalletBase wallet}) {
48 + List<TradeListItem> filtered({required List<TradeListItem> trades, required WalletBase wallet}) {
49 final _trades =
50 trades.where((item) => item.trade.walletId == wallet.id).toList();
51 final needToFilter = !displayChangeNow || !displayXMRTO || !displayMorphToken || !displaySimpleSwap;
lib/store/dashboard/trades_store.dart
+13 -10
@@ -10,31 +10,34 @@ part 'trades_store.g.dart';
10 class TradesStore = TradesStoreBase with _$TradesStore;
11
12 abstract class TradesStoreBase with Store {
13 - TradesStoreBase({this.tradesSource, this.settingsStore}) {
14 - trades = <TradeListItem>[];
15 -
13 + TradesStoreBase({required this.tradesSource, required this.settingsStore})
14 + : trades = <TradeListItem>[] {
15 _onTradesChanged =
16 tradesSource.watch().listen((_) async => await updateTradeList());
18 -
17 updateTradeList();
18 }
19
20 Box<Trade> tradesSource;
23 - StreamSubscription<BoxEvent> _onTradesChanged;
21 + StreamSubscription<BoxEvent>? _onTradesChanged;
22 SettingsStore settingsStore;
23
24 @observable
25 List<TradeListItem> trades;
26
27 @observable
30 - Trade trade;
28 + Trade? trade;
29
30 @action
31 void setTrade(Trade trade) => this.trade = trade;
32
33 @action
36 - Future updateTradeList() async => trades =
37 - tradesSource.values.map((trade) => TradeListItem(
38 - trade: trade,
39 - settingsStore: settingsStore)).toList();
34 + Future<void> updateTradeList() async {
35 + if (trade == null) {
36 + return;
37 + }
38 +
39 + trades = tradesSource.values.map((trade) => TradeListItem(
40 + trade: trade!,
41 + settingsStore: settingsStore)).toList();
42 + }
43 }
\ No newline at end of file
lib/store/dashboard/transaction_filter_store.dart
+5 -5
@@ -18,10 +18,10 @@ abstract class TransactionFilterStoreBase with Store {
18 bool displayOutgoing;
19
20 @observable
21 - DateTime startDate;
21 + DateTime? startDate;
22
23 @observable
24 - DateTime endDate;
24 + DateTime? endDate;
25
26 @action
27 void toggleIncoming() => displayIncoming = !displayIncoming;
@@ -35,7 +35,7 @@ abstract class TransactionFilterStoreBase with Store {
35 @action
36 void changeEndDate(DateTime date) => endDate = date;
37
38 - List<TransactionListItem> filtered({List<TransactionListItem> transactions}) {
38 + List<TransactionListItem> filtered({required List<TransactionListItem> transactions}) {
39 var _transactions = <TransactionListItem>[];
40 final needToFilter = !displayOutgoing ||
41 !displayIncoming ||
@@ -46,8 +46,8 @@ abstract class TransactionFilterStoreBase with Store {
46 var allowed = true;
47
48 if (allowed && startDate != null && endDate != null) {
49 - allowed = startDate.isBefore(item.transaction.date) &&
50 - endDate.isAfter(item.transaction.date);
49 + allowed = (startDate?.isBefore(item.transaction.date) ?? false)
50 + && (endDate?.isAfter(item.transaction.date) ?? false);
51 }
52
53 if (allowed && (!displayOutgoing || !displayIncoming)) {
lib/store/node_list_store.dart
+7 -7
@@ -12,22 +12,22 @@ class NodeListStore = NodeListStoreBase with _$NodeListStore;
12 abstract class NodeListStoreBase with Store {
13 NodeListStoreBase() : nodes = ObservableList<Node>();
14
15 - static StreamSubscription<BoxEvent> _onNodesSourceChange;
16 - static NodeListStore _instance;
15 + static StreamSubscription<BoxEvent>? _onNodesSourceChange;
16 + static NodeListStore? _instance;
17
18 static NodeListStore get instance {
19 if (_instance != null) {
20 - return _instance;
20 + return _instance!;
21 }
22
23 final nodeSource = getIt.get<Box<Node>>();
24 _instance = NodeListStore();
25 - _instance.nodes.clear();
26 - _instance.nodes.addAll(nodeSource.values);
25 + _instance!.nodes.clear();
26 + _instance!.nodes.addAll(nodeSource.values);
27 _onNodesSourceChange?.cancel();
28 - _onNodesSourceChange = nodeSource.bindToList(_instance.nodes);
28 + _onNodesSourceChange = nodeSource.bindToList(_instance!.nodes);
29
30 - return _instance;
30 + return _instance!;
31 }
32
33 final ObservableList<Node> nodes;
lib/store/secret_store.dart
+3 -2
@@ -12,7 +12,8 @@ abstract class SecretStoreBase with Store {
12 final secretStore = SecretStore();
13 final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
14 final backupPassword = await storage.read(key: backupPasswordKey);
15 - secretStore.write(key: backupPasswordKey, value: backupPassword);
15 + // FIX-ME: backupPassword ?? '' ???
16 + secretStore.write(key: backupPasswordKey, value: backupPassword ?? '');
17
18 return secretStore;
19 }
@@ -23,6 +24,6 @@ abstract class SecretStoreBase with Store {
24
25 String read(String key) => values[key] as String;
26
26 - String write({@required String key, @required String value}) =>
27 + String write({required String key, required String value}) =>
28 values[key] = value;
29 }
lib/store/settings_store.dart
+124 -88
@@ -25,35 +25,41 @@ class SettingsStore = SettingsStoreBase with _$SettingsStore;
25
26 abstract class SettingsStoreBase with Store {
27 SettingsStoreBase(
28 - {@required SharedPreferences sharedPreferences,
29 - @required FiatCurrency initialFiatCurrency,
30 - @required BalanceDisplayMode initialBalanceDisplayMode,
31 - @required bool initialSaveRecipientAddress,
32 - @required bool initialAllowBiometricalAuthentication,
33 - @required ThemeBase initialTheme,
34 - @required int initialPinLength,
35 - @required String initialLanguageCode,
36 - // @required String initialCurrentLocale,
37 - @required this.appVersion,
38 - @required Map<WalletType, Node> nodes,
39 - @required TransactionPriority initialBitcoinTransactionPriority,
40 - @required TransactionPriority initialMoneroTransactionPriority,
41 - @required this.shouldShowYatPopup,
42 - @required this.isBitcoinBuyEnabled,
43 - this.actionlistDisplayMode}) {
44 - fiatCurrency = initialFiatCurrency;
45 - balanceDisplayMode = initialBalanceDisplayMode;
46 - shouldSaveRecipientAddress = initialSaveRecipientAddress;
47 - allowBiometricalAuthentication = initialAllowBiometricalAuthentication;
48 - currentTheme = initialTheme;
49 - pinCodeLength = initialPinLength;
50 - languageCode = initialLanguageCode;
51 - priority = ObservableMap<WalletType, TransactionPriority>.of({
52 - WalletType.monero: initialMoneroTransactionPriority,
53 - WalletType.bitcoin: initialBitcoinTransactionPriority
54 - });
55 - this.nodes = ObservableMap<WalletType, Node>.of(nodes);
56 - _sharedPreferences = sharedPreferences;
28 + {required SharedPreferences sharedPreferences,
29 + required FiatCurrency initialFiatCurrency,
30 + required BalanceDisplayMode initialBalanceDisplayMode,
31 + required bool initialSaveRecipientAddress,
32 + required bool initialAllowBiometricalAuthentication,
33 + required ThemeBase initialTheme,
34 + required int initialPinLength,
35 + required String initialLanguageCode,
36 + // required String initialCurrentLocale,
37 + required this.appVersion,
38 + required Map<WalletType, Node> nodes,
39 + required this.shouldShowYatPopup,
40 + required this.isBitcoinBuyEnabled,
41 + required this.actionlistDisplayMode,
42 + TransactionPriority? initialBitcoinTransactionPriority,
43 + TransactionPriority? initialMoneroTransactionPriority})
44 + : nodes = ObservableMap<WalletType, Node>.of(nodes),
45 + _sharedPreferences = sharedPreferences,
46 + fiatCurrency = initialFiatCurrency,
47 + balanceDisplayMode = initialBalanceDisplayMode,
48 + shouldSaveRecipientAddress = initialSaveRecipientAddress,
49 + allowBiometricalAuthentication = initialAllowBiometricalAuthentication,
50 + currentTheme = initialTheme,
51 + pinCodeLength = initialPinLength,
52 + languageCode = initialLanguageCode,
53 + priority = ObservableMap<WalletType, TransactionPriority>() {
54 + //this.nodes = ObservableMap<WalletType, Node>.of(nodes);
55 +
56 + if (initialMoneroTransactionPriority != null) {
57 + priority[WalletType.monero] = initialMoneroTransactionPriority;
58 + }
59 +
60 + if (initialBitcoinTransactionPriority != null) {
61 + priority[WalletType.bitcoin] = initialBitcoinTransactionPriority;
62 + }
63
64 reaction(
65 (_) => fiatCurrency,
@@ -70,7 +76,9 @@ abstract class SettingsStoreBase with Store {
76 ? PreferencesKey.moneroTransactionPriority
77 : PreferencesKey.bitcoinTransactionPriority;
78
73 - sharedPreferences.setInt(key, change.newValue.serialize());
79 + if (change.newValue != null) {
80 + sharedPreferences.setInt(key, change.newValue!.serialize());
81 + }
82 });
83
84 reaction(
@@ -107,7 +115,11 @@ abstract class SettingsStoreBase with Store {
115
116 this
117 .nodes
110 - .observe((change) => _saveCurrentNode(change.newValue, change.key));
118 + .observe((change) {
119 + if (change.newValue != null && change.key != null) {
120 + _saveCurrentNode(change.newValue!, change.key!);
121 + }
122 + });
123 }
124
125 static const defaultPinLength = 4;
@@ -152,7 +164,15 @@ abstract class SettingsStoreBase with Store {
164
165 ObservableMap<WalletType, Node> nodes;
166
155 - Node getCurrentNode(WalletType walletType) => nodes[walletType];
167 + Node getCurrentNode(WalletType walletType) {
168 + final node = nodes[walletType];
169 +
170 + if (node == null) {
171 + throw Exception('No node found for wallet type: ${walletType.toString()}');
172 + }
173 +
174 + return node;
175 + }
176
177 bool isBitcoinBuyEnabled;
178
@@ -163,11 +183,11 @@ abstract class SettingsStoreBase with Store {
183 _sharedPreferences.setBool(PreferencesKey.shouldShowReceiveWarning, value);
184
185 static Future<SettingsStore> load(
166 - {@required Box<Node> nodeSource,
167 - @required bool isBitcoinBuyEnabled,
186 + {required Box<Node> nodeSource,
187 + required bool isBitcoinBuyEnabled,
188 + TransactionPriority? initialMoneroTransactionPriority,
189 + TransactionPriority? initialBitcoinTransactionPriority,
190 FiatCurrency initialFiatCurrency = FiatCurrency.usd,
169 - TransactionPriority initialMoneroTransactionPriority,
170 - TransactionPriority initialBitcoinTransactionPriority,
191 BalanceDisplayMode initialBalanceDisplayMode =
192 BalanceDisplayMode.availableBalance}) async {
193 if (initialBitcoinTransactionPriority == null) {
@@ -179,25 +199,25 @@ abstract class SettingsStoreBase with Store {
199 }
200
201 final sharedPreferences = await getIt.getAsync<SharedPreferences>();
182 - final currentFiatCurrency = FiatCurrency(
183 - symbol:
184 - sharedPreferences.getString(PreferencesKey.currentFiatCurrencyKey));
202 + final currentFiatCurrency = FiatCurrency.deserialize(raw:
203 + sharedPreferences.getString(PreferencesKey.currentFiatCurrencyKey)!);
204 final savedMoneroTransactionPriority =
205 monero?.deserializeMoneroTransactionPriority(
206 raw: sharedPreferences
188 - .getInt(PreferencesKey.moneroTransactionPriority));
207 + .getInt(PreferencesKey.moneroTransactionPriority)!);
208 final savedBitcoinTransactionPriority =
209 bitcoin?.deserializeBitcoinTransactionPriority(sharedPreferences
191 - .getInt(PreferencesKey.bitcoinTransactionPriority));
210 + .getInt(PreferencesKey.bitcoinTransactionPriority)!);
211 final moneroTransactionPriority =
212 savedMoneroTransactionPriority ?? initialMoneroTransactionPriority;
213 final bitcoinTransactionPriority =
214 savedBitcoinTransactionPriority ?? initialBitcoinTransactionPriority;
215 final currentBalanceDisplayMode = BalanceDisplayMode.deserialize(
216 raw: sharedPreferences
198 - .getInt(PreferencesKey.currentBalanceDisplayModeKey));
217 + .getInt(PreferencesKey.currentBalanceDisplayModeKey)!);
218 + // FIX-ME: Check for which default value we should have here
219 final shouldSaveRecipientAddress =
200 - sharedPreferences.getBool(PreferencesKey.shouldSaveRecipientAddressKey);
220 + sharedPreferences.getBool(PreferencesKey.shouldSaveRecipientAddressKey) ?? false;
221 final allowBiometricalAuthentication = sharedPreferences
222 .getBool(PreferencesKey.allowBiometricalAuthenticationKey) ??
223 false;
@@ -237,14 +257,27 @@ abstract class SettingsStoreBase with Store {
257 final shouldShowYatPopup =
258 sharedPreferences.getBool(PreferencesKey.shouldShowYatPopup) ?? true;
259
260 + final nodes = <WalletType, Node>{};
261 +
262 + if (moneroNode != null) {
263 + nodes[WalletType.monero] = moneroNode;
264 + }
265 +
266 + if (bitcoinElectrumServer != null) {
267 + nodes[WalletType.bitcoin] = bitcoinElectrumServer;
268 + }
269 +
270 + if (litecoinElectrumServer != null) {
271 + nodes[WalletType.litecoin] = litecoinElectrumServer;
272 + }
273 +
274 + if (havenNode != null) {
275 + nodes[WalletType.haven] = havenNode;
276 + }
277 +
278 return SettingsStore(
279 sharedPreferences: sharedPreferences,
242 - nodes: {
243 - WalletType.monero: moneroNode,
244 - WalletType.bitcoin: bitcoinElectrumServer,
245 - WalletType.litecoin: litecoinElectrumServer,
246 - WalletType.haven: havenNode
247 - },
280 + nodes: nodes,
281 appVersion: packageInfo.version,
282 isBitcoinBuyEnabled: isBitcoinBuyEnabled,
283 initialFiatCurrency: currentFiatCurrency,
@@ -260,45 +293,48 @@ abstract class SettingsStoreBase with Store {
293 shouldShowYatPopup: shouldShowYatPopup);
294 }
295
263 - Future<void> reload(
264 - {@required Box<Node> nodeSource,
265 - FiatCurrency initialFiatCurrency = FiatCurrency.usd,
266 - TransactionPriority initialMoneroTransactionPriority,
267 - TransactionPriority initialBitcoinTransactionPriority,
268 - BalanceDisplayMode initialBalanceDisplayMode =
269 - BalanceDisplayMode.availableBalance}) async {
270 - if (initialBitcoinTransactionPriority == null) {
271 - initialBitcoinTransactionPriority = bitcoin?.getMediumTransactionPriority();
272 - }
273 -
274 - if (initialMoneroTransactionPriority == null) {
275 - initialMoneroTransactionPriority = monero?.getDefaultTransactionPriority();
276 - }
277 -
278 - final isBitcoinBuyEnabled = (secrets.wyreSecretKey?.isNotEmpty ?? false) &&
279 - (secrets.wyreApiKey?.isNotEmpty ?? false) &&
280 - (secrets.wyreAccountId?.isNotEmpty ?? false);
281 -
282 - final settings = await SettingsStoreBase.load(
283 - nodeSource: nodeSource,
284 - isBitcoinBuyEnabled: isBitcoinBuyEnabled,
285 - initialBalanceDisplayMode: initialBalanceDisplayMode,
286 - initialFiatCurrency: initialFiatCurrency,
287 - initialMoneroTransactionPriority: initialMoneroTransactionPriority,
288 - initialBitcoinTransactionPriority: initialBitcoinTransactionPriority);
289 - fiatCurrency = settings.fiatCurrency;
290 - actionlistDisplayMode = settings.actionlistDisplayMode;
291 - priority[WalletType.monero] = initialMoneroTransactionPriority;
292 - priority[WalletType.bitcoin] = initialBitcoinTransactionPriority;
293 - balanceDisplayMode = settings.balanceDisplayMode;
294 - shouldSaveRecipientAddress = settings.shouldSaveRecipientAddress;
295 - allowBiometricalAuthentication = settings.allowBiometricalAuthentication;
296 - currentTheme = settings.currentTheme;
297 - pinCodeLength = settings.pinCodeLength;
298 - languageCode = settings.languageCode;
299 - appVersion = settings.appVersion;
300 - shouldShowYatPopup = settings.shouldShowYatPopup;
301 - }
296 + // FIX-ME: Dead code
297 +
298 + //Future<void> reload(
299 + // {required Box<Node> nodeSource,
300 + // FiatCurrency initialFiatCurrency = FiatCurrency.usd,
301 + // TransactionPriority? initialMoneroTransactionPriority,
302 + // TransactionPriority? initialBitcoinTransactionPriority,
303 + // BalanceDisplayMode initialBalanceDisplayMode =
304 + // BalanceDisplayMode.availableBalance}) async {
305 +
306 + // if (initialBitcoinTransactionPriority == null) {
307 + // initialBitcoinTransactionPriority = bitcoin?.getMediumTransactionPriority();
308 + // }
309 +
310 + // if (initialMoneroTransactionPriority == null) {
311 + // initialMoneroTransactionPriority = monero?.getDefaultTransactionPriority();
312 + // }
313 +
314 + // final isBitcoinBuyEnabled = (secrets.wyreSecretKey?.isNotEmpty ?? false) &&
315 + // (secrets.wyreApiKey?.isNotEmpty ?? false) &&
316 + // (secrets.wyreAccountId?.isNotEmpty ?? false);
317 +
318 + // final settings = await SettingsStoreBase.load(
319 + // nodeSource: nodeSource,
320 + // isBitcoinBuyEnabled: isBitcoinBuyEnabled,
321 + // initialBalanceDisplayMode: initialBalanceDisplayMode,
322 + // initialFiatCurrency: initialFiatCurrency,
323 + // initialMoneroTransactionPriority: initialMoneroTransactionPriority,
324 + // initialBitcoinTransactionPriority: initialBitcoinTransactionPriority);
325 + // fiatCurrency = settings.fiatCurrency;
326 + // actionlistDisplayMode = settings.actionlistDisplayMode;
327 + // priority[WalletType.monero] = initialMoneroTransactionPriority;
328 + // priority[WalletType.bitcoin] = initialBitcoinTransactionPriority;
329 + // balanceDisplayMode = settings.balanceDisplayMode;
330 + // shouldSaveRecipientAddress = settings.shouldSaveRecipientAddress;
331 + // allowBiometricalAuthentication = settings.allowBiometricalAuthentication;
332 + // currentTheme = settings.currentTheme;
333 + // pinCodeLength = settings.pinCodeLength;
334 + // languageCode = settings.languageCode;
335 + // appVersion = settings.appVersion;
336 + // shouldShowYatPopup = settings.shouldShowYatPopup;
337 + //}
338
339 Future<void> _saveCurrentNode(Node node, WalletType walletType) async {
340 switch (walletType) {
lib/store/templates/exchange_template_store.dart
+10 -4
@@ -8,7 +8,8 @@ part 'exchange_template_store.g.dart';
8 class ExchangeTemplateStore = ExchangeTemplateBase with _$ExchangeTemplateStore;
9
10 abstract class ExchangeTemplateBase with Store {
11 - ExchangeTemplateBase({this.templateSource}) {
11 + ExchangeTemplateBase({required this.templateSource})
12 + : templates = ObservableList<ExchangeTemplate>() {
13 templates = ObservableList<ExchangeTemplate>();
14 update();
15 }
@@ -23,8 +24,13 @@ abstract class ExchangeTemplateBase with Store {
24 templates.replaceRange(0, templates.length, templateSource.values.toList());
25
26 @action
26 - Future addTemplate({String amount, String depositCurrency, String receiveCurrency,
27 - String provider, String depositAddress, String receiveAddress}) async {
27 + Future addTemplate({
28 + required String amount,
29 + required String depositCurrency,
30 + required String receiveCurrency,
31 + required String provider,
32 + required String depositAddress,
33 + required String receiveAddress}) async {
34 final template = ExchangeTemplate(
35 amount: amount,
36 depositCurrency: depositCurrency,
@@ -36,5 +42,5 @@ abstract class ExchangeTemplateBase with Store {
42 }
43
44 @action
39 - Future remove({ExchangeTemplate template}) async => await template.delete();
45 + Future remove({required ExchangeTemplate template}) async => await template.delete();
46 }
\ No newline at end of file
lib/store/templates/send_template_store.dart
+19 -6
@@ -8,8 +8,8 @@ part 'send_template_store.g.dart';
8 class SendTemplateStore = SendTemplateBase with _$SendTemplateStore;
9
10 abstract class SendTemplateBase with Store {
11 - SendTemplateBase({this.templateSource}) {
12 - templates = ObservableList<Template>();
11 + SendTemplateBase({required this.templateSource})
12 + : templates = ObservableList<Template>() {
13 update();
14 }
15
@@ -23,12 +23,25 @@ abstract class SendTemplateBase with Store {
23 templates.replaceRange(0, templates.length, templateSource.values.toList());
24
25 @action
26 - Future addTemplate({String name,bool isCurrencySelected, String address, String cryptoCurrency, String fiatCurrency, String amount,String amountFiat}) async {
27 - final template = Template(name: name,isCurrencySelected: isCurrencySelected, address: address,
28 - cryptoCurrency: cryptoCurrency, fiatCurrency: fiatCurrency, amount: amount, amountFiat: amountFiat);
26 + Future addTemplate({
27 + required String name,
28 + required bool isCurrencySelected,
29 + required String address,
30 + required String cryptoCurrency,
31 + required String fiatCurrency,
32 + required String amount,
33 + required String amountFiat}) async {
34 + final template = Template(
35 + name: name,
36 + isCurrencySelected: isCurrencySelected,
37 + address: address,
38 + cryptoCurrency: cryptoCurrency,
39 + fiatCurrency: fiatCurrency,
40 + amount: amount,
41 + amountFiat: amountFiat);
42 await templateSource.add(template);
43 }
44
45 @action
33 - Future remove({Template template}) async => await template.delete();
46 + Future remove({required Template template}) async => await template.delete();
47 }
\ No newline at end of file
lib/store/yat/yat_exception.dart
+1 -1
@@ -1,7 +1,7 @@
1 import 'package:flutter/foundation.dart';
2
3 class YatException implements Exception {
4 - YatException({@required this.text});
4 + YatException({required this.text});
5
6 final String text;
7
lib/store/yat/yat_store.dart
+18 -13
@@ -169,13 +169,18 @@ Future<String> visualisationForEmojiId(String emojiId) async {
169 class YatStore = YatStoreBase with _$YatStore;
170
171 abstract class YatStoreBase with Store {
172 - YatStoreBase({@required this.appStore, @required this.secureStorage}) {
173 - _wallet ??= appStore.wallet;
174 - emoji = _wallet?.walletInfo?.yatEmojiId ?? '';
172 + YatStoreBase({
173 + required this.appStore,
174 + required this.secureStorage})
175 + : _wallet = appStore.wallet,
176 + emoji = appStore.wallet?.walletInfo?.yatEmojiId ?? '',
177 + refreshToken = '',
178 + accessToken = '',
179 + apiKey = '',
180 + emojiIncommingSC = StreamController<String>.broadcast() {
181 //reaction((_) => appStore.wallet, _onWalletChange);
182 //reaction((_) => emoji, (String _) => _onEmojiChange());
183 //reaction((_) => refreshToken, (String _) => _onRefreshTokenChange());
178 - emojiIncommingSC = StreamController<String>.broadcast();
184 }
185
186 static const yatRefreshTokenKeyBase = 'yat_refresh_token';
@@ -207,17 +212,17 @@ abstract class YatStoreBase with Store {
212 Stream<String> get emojiIncommingStream => emojiIncommingSC.stream;
213
214 @observable
210 - WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>
211 - _wallet;
215 + WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>?
216 + _wallet;
217
218 Future<void> init() async {
219 if (_wallet == null) {
220 return;
221 }
222
218 - refreshToken = await secureStorage.read(key: yatRefreshTokenKey(_wallet.walletInfo.name));
219 - accessToken = await secureStorage.read(key: yatAccessTokenKey(_wallet.walletInfo.name));
220 - apiKey = await secureStorage.read(key: yatApiKey(_wallet.walletInfo.name));
223 + refreshToken = await secureStorage.read(key: yatRefreshTokenKey(_wallet!.walletInfo.name)) ?? '';
224 + accessToken = await secureStorage.read(key: yatAccessTokenKey(_wallet!.walletInfo.name)) ?? '';
225 + apiKey = await secureStorage.read(key: yatApiKey(_wallet!.walletInfo.name)) ?? '';
226 }
227
228 @action
@@ -233,16 +238,16 @@ abstract class YatStoreBase with Store {
238 @action
239 void _onEmojiChange() {
240 try {
236 - final walletInfo = _wallet.walletInfo;
241 + final walletInfo = _wallet?.walletInfo;
242
243 if (walletInfo == null) {
244 return;
245 }
246
242 - walletInfo.yatEid = emoji;
247 + walletInfo!.yatEid = emoji;
248
244 - if (walletInfo.isInBox) {
245 - walletInfo.save();
249 + if (walletInfo!.isInBox) {
250 + walletInfo!.save();
251 }
252 } catch (e) {
253 print(e.toString());
lib/themes/bright_theme.dart
+61 -31
@@ -4,7 +4,7 @@ import 'package:cake_wallet/palette.dart';
4 import 'package:flutter/material.dart';
5
6 class BrightTheme extends ThemeBase {
7 - BrightTheme({@required int raw}) : super(raw: raw);
7 + BrightTheme({required int raw}) : super(raw: raw);
8
9 @override
10 String get title => S.current.bright_theme;
@@ -26,7 +26,8 @@ class BrightTheme extends ThemeBase {
26 dividerColor: Palette.paleBlue,
27 hintColor: Palette.gray,
28 textTheme: TextTheme(
29 - title: TextStyle(
29 + // title -> headline6
30 + headline6: TextStyle(
31 color: Colors.white, // sync_indicator text
32 backgroundColor: Colors.white.withOpacity(0.2), // synced sync_indicator
33 decorationColor: Colors.white.withOpacity(0.15), // not synced sync_indicator
@@ -40,40 +41,49 @@ class BrightTheme extends ThemeBase {
41 backgroundColor: Colors.white.withOpacity(0.5), // date section row
42 decorationColor: Colors.white.withOpacity(0.2) // icons (transaction and trade rows)
43 ),
43 - subhead: TextStyle(
44 + // subhead -> subtitle1
45 + subtitle1: TextStyle(
46 color: Colors.white.withOpacity(0.2), // address button border
47 decorationColor: Colors.white.withOpacity(0.4), // copy button (qr widget)
48 ),
47 - headline: TextStyle(
49 + // headline -> headline5
50 + headline5: TextStyle(
51 color: Colors.white, // qr code
52 decorationColor: Colors.white.withOpacity(0.5), // bottom border of amount (receive page)
53 ),
51 - display1: TextStyle(
54 + // display1 -> headline4
55 + headline4: TextStyle(
56 color: PaletteDark.lightBlueGrey, // icons color (receive page)
57 decorationColor: Palette.lavender, // icons background (receive page)
58 ),
55 - display2: TextStyle(
59 + // display2 -> headline3
60 + headline3: TextStyle(
61 color: Palette.darkBlueCraiola, // text color of tiles (receive page)
62 decorationColor: Colors.white // background of tiles (receive page)
63 ),
59 - display3: TextStyle(
64 + // display3 -> headline2
65 + headline2: TextStyle(
66 color: Colors.white, // text color of current tile (receive page),
67 //decorationColor: Palette.blueCraiola // background of current tile (receive page)
68 decorationColor: Palette.moderateSlateBlue // background of current tile (receive page)
69 ),
64 - display4: TextStyle(
70 + // display4 -> headline1
71 + headline1: TextStyle(
72 color: Palette.violetBlue, // text color of tiles (account list)
73 decorationColor: Colors.white // background of tiles (account list)
74 ),
68 - subtitle: TextStyle(
75 + // subtitle -> subtitle2
76 + subtitle2: TextStyle(
77 color: Palette.moderateSlateBlue, // text color of current tile (account list)
78 decorationColor: Colors.white // background of current tile (account list)
79 ),
72 - body1: TextStyle(
80 + // body -> bodyText2
81 + bodyText2: TextStyle(
82 color: Palette.moderatePurpleBlue, // scrollbar thumb
83 decorationColor: Palette.periwinkleCraiola // scrollbar background
84 ),
76 - body2: TextStyle(
85 + // body2 -> bodyText1
86 + bodyText1: TextStyle(
87 color: Palette.moderateLavender, // menu header
88 decorationColor: Colors.white, // menu background
89 )
@@ -87,7 +97,8 @@ class BrightTheme extends ThemeBase {
97 crossAxisMargin: 6,
98 ),
99 primaryTextTheme: TextTheme(
90 - title: TextStyle(
100 + // title -> headline6
101 + headline6: TextStyle(
102 color: Palette.darkBlueCraiola, // title color
103 backgroundColor: Palette.wildPeriwinkle // textfield underline
104 ),
@@ -99,43 +110,52 @@ class BrightTheme extends ThemeBase {
110 color: Palette.darkGray, // transaction/trade details titles
111 decorationColor: Colors.white.withOpacity(0.5), // placeholder
112 ),
102 - subhead: TextStyle(
113 + // subhead -> subtitle1
114 + subtitle1: TextStyle(
115 color: Palette.blueCraiola, // first gradient color (send page)
116 decorationColor: Palette.pinkFlamingo // second gradient color (send page)
117 ),
106 - headline: TextStyle(
118 + // headline -> headline5
119 + headline5: TextStyle(
120 color: Colors.white.withOpacity(0.5), // text field border color (send page)
121 decorationColor: Colors.white.withOpacity(0.5), // text field hint color (send page)
122 ),
110 - display1: TextStyle(
123 + // display1 -> headline4
124 + headline4: TextStyle(
125 color: Colors.white.withOpacity(0.2), // text field button color (send page)
126 decorationColor: Colors.white // text field button icon color (send page)
127 ),
114 - display2: TextStyle(
128 + // display2 -> headline3
129 + headline3: TextStyle(
130 color: Colors.white.withOpacity(0.5), // estimated fee (send page)
131 backgroundColor: PaletteDark.darkCyanBlue.withOpacity(0.67), // dot color for indicator on send page
132 decorationColor: Palette.shadowWhite // template dotted border (send page)
133 ),
119 - display3: TextStyle(
134 + // display3 -> headline2
135 + headline2: TextStyle(
136 color: Palette.darkBlueCraiola, // template new text (send page)
137 backgroundColor: PaletteDark.darkNightBlue, // active dot color for indicator on send page
138 decorationColor: Palette.shadowWhite // template background color (send page)
139 ),
124 - display4: TextStyle(
140 + // display4 -> headline1
141 + headline1: TextStyle(
142 color: Palette.darkBlueCraiola, // template title (send page)
143 backgroundColor: Colors.white, // icon color on order row (moonpay)
144 decorationColor: Palette.niagara // receive amount text (exchange page)
145 ),
129 - subtitle: TextStyle(
146 + // subtitle -> subtitle2
147 + subtitle2: TextStyle(
148 color: Palette.blueCraiola, // first gradient color top panel (exchange page)
149 decorationColor: Palette.pinkFlamingo // second gradient color top panel (exchange page)
150 ),
133 - body1: TextStyle(
151 + // body -> bodyText2
152 + bodyText2: TextStyle(
153 color: Palette.blueCraiola.withOpacity(0.7), // first gradient color bottom panel (exchange page)
154 decorationColor: Palette.pinkFlamingo.withOpacity(0.7), // second gradient color bottom panel (exchange page)
155 backgroundColor: Palette.moderateSlateBlue // alert right button text
156 ),
138 - body2: TextStyle(
157 + // body2 -> bodyText1
158 + bodyText1: TextStyle(
159 color: Colors.white.withOpacity(0.5), // text field border on top panel (exchange page)
160 decorationColor: Colors.white.withOpacity(0.5), // text field border on bottom panel (exchange page)
161 backgroundColor: Palette.brightOrange // alert left button text
@@ -143,7 +163,8 @@ class BrightTheme extends ThemeBase {
163 ),
164 focusColor: Colors.white.withOpacity(0.2), // text field button (exchange page)
165 accentTextTheme: TextTheme(
146 - title: TextStyle(
166 + // title -> headline6
167 + headline6: TextStyle(
168 color: Colors.white, // picker background
169 backgroundColor: Palette.periwinkleCraiola, // picker divider
170 decorationColor: Colors.white // dialog background
@@ -153,18 +174,21 @@ class BrightTheme extends ThemeBase {
174 backgroundColor: Palette.moderateLavender, // button background (confirm exchange)
175 decorationColor: Palette.darkBlueCraiola, // text color (information page)
176 ),
156 - subtitle: TextStyle(
177 + // subtitle -> subtitle2
178 + subtitle2: TextStyle(
179 color: Palette.darkBlueCraiola, // QR code (exchange trade page)
180 backgroundColor: Palette.wildPeriwinkle, // divider (exchange trade page)
181 //decorationColor: Palette.blueCraiola // crete new wallet button background (wallet list page)
182 decorationColor: Palette.moderateSlateBlue // crete new wallet button background (wallet list page)
183 ),
162 - headline: TextStyle(
184 + // headline -> headline5
185 + headline5: TextStyle(
186 color: Palette.moderateLavender, // first gradient color of wallet action buttons (wallet list page)
187 backgroundColor: Palette.moderateLavender, // second gradient color of wallet action buttons (wallet list page)
188 decorationColor: Colors.white // restore wallet button text color (wallet list page)
189 ),
167 - subhead: TextStyle(
190 + // subhead -> subtitle1
191 + subtitle1: TextStyle(
192 color: Palette.darkGray, // titles color (filter widget)
193 backgroundColor: Palette.periwinkle, // divider color (filter widget)
194 decorationColor: Colors.white // checkbox background (filter widget)
@@ -173,32 +197,38 @@ class BrightTheme extends ThemeBase {
197 color: Palette.wildPeriwinkle, // checkbox bounds (filter widget)
198 decorationColor: Colors.white, // menu subname
199 ),
176 - display1: TextStyle(
200 + // display1 -> headline4
201 + headline4: TextStyle(
202 color: Palette.blueCraiola, // first gradient color (menu header)
203 decorationColor: Palette.pinkFlamingo, // second gradient color(menu header)
204 backgroundColor: Colors.white // active dot color
205 ),
181 - display2: TextStyle(
206 + // display2 -> headline3
207 + headline3: TextStyle(
208 color: Palette.shadowWhite, // action button color (address text field)
209 decorationColor: Palette.darkGray, // hint text (seed widget)
210 backgroundColor: Colors.white.withOpacity(0.5) // text on balance page
211 ),
186 - display3: TextStyle(
212 + // display3 -> headline2
213 + headline2: TextStyle(
214 color: Palette.darkGray, // hint text (new wallet page)
215 decorationColor: Palette.periwinkleCraiola, // underline (new wallet page)
216 backgroundColor: Colors.white // menu, icons, balance (dashboard page)
217 ),
191 - display4: TextStyle(
218 + // display4 -> headline1
219 + headline1: TextStyle(
220 color: Palette.darkGray, // switch background (settings page)
221 backgroundColor: Colors.black, // icon color on support page (moonpay, github)
222 decorationColor: Colors.white.withOpacity(0.4) // hint text (exchange page)
223 ),
196 - body1: TextStyle(
224 + // body -> bodyText2
225 + bodyText2: TextStyle(
226 color: Palette.darkGray, // indicators (PIN code)
227 decorationColor: Palette.darkGray, // switch (PIN code)
228 backgroundColor: Colors.white // alert right button
229 ),
201 - body2: TextStyle(
230 + // body2 -> bodyText1
231 + bodyText1: TextStyle(
232 color: Palette.moderateSlateBlue, // primary buttons
233 decorationColor: Colors.white, // alert left button,
234 backgroundColor: Palette.dullGray // keyboard bar color
lib/themes/dark_theme.dart
+61 -31
@@ -4,7 +4,7 @@ import 'package:cake_wallet/palette.dart';
4 import 'package:flutter/material.dart';
5
6 class DarkTheme extends ThemeBase {
7 - DarkTheme({@required int raw}) : super(raw: raw);
7 + DarkTheme({required int raw}) : super(raw: raw);
8
9 @override
10 String get title => S.current.dark_theme;
@@ -26,7 +26,8 @@ class DarkTheme extends ThemeBase {
26 dividerColor: PaletteDark.dividerColor,
27 hintColor: PaletteDark.pigeonBlue, // menu
28 textTheme: TextTheme(
29 - title: TextStyle(
29 + // title -> headline6
30 + headline6: TextStyle(
31 color: PaletteDark.wildBlue, // sync_indicator text
32 backgroundColor: PaletteDark.lightNightBlue, // synced sync_indicator
33 decorationColor: PaletteDark.oceanBlue // not synced sync_indicator
@@ -40,39 +41,48 @@ class DarkTheme extends ThemeBase {
41 backgroundColor: PaletteDark.darkCyanBlue, // date section row
42 decorationColor: PaletteDark.wildNightBlue // icons (transaction and trade rows)
43 ),
43 - subhead: TextStyle(
44 + // subhead -> subtitle1
45 + subtitle1: TextStyle(
46 color: PaletteDark.nightBlue, // address button border
47 decorationColor: PaletteDark.lightBlueGrey, // copy button (qr widget)
48 ),
47 - headline: TextStyle(
49 + // headline -> headline5
50 + headline5: TextStyle(
51 color: PaletteDark.lightBlueGrey, // qr code
52 decorationColor: PaletteDark.darkGrey, // bottom border of amount (receive page)
53 ),
51 - display1: TextStyle(
54 + // display1 -> headline4
55 + headline4: TextStyle(
56 color: Colors.white, // icons color (receive page)
57 decorationColor: PaletteDark.distantNightBlue, // icons background (receive page)
58 ),
55 - display2: TextStyle(
59 + // display2 -> headline3
60 + headline3: TextStyle(
61 color: Colors.white, // text color of tiles (receive page)
62 decorationColor: PaletteDark.nightBlue // background of tiles (receive page)
63 ),
59 - display3: TextStyle(
64 + // display3 -> headline2
65 + headline2: TextStyle(
66 color: Palette.blueCraiola, // text color of current tile (receive page)
67 decorationColor: PaletteDark.lightOceanBlue // background of current tile (receive page)
68 ),
63 - display4: TextStyle(
69 + // display4 -> headline1
70 + headline1: TextStyle(
71 color: Colors.white, // text color of tiles (account list)
72 decorationColor: PaletteDark.darkOceanBlue // background of tiles (account list)
73 ),
67 - subtitle: TextStyle(
74 + // subtitle -> subtitle2
75 + subtitle2: TextStyle(
76 color: Palette.blueCraiola, // text color of current tile (account list)
77 decorationColor: PaletteDark.darkNightBlue // background of current tile (account list)
78 ),
71 - body1: TextStyle(
79 + // body1 -> bodyText2
80 + bodyText2: TextStyle(
81 color: PaletteDark.wildBlueGrey, // scrollbar thumb
82 decorationColor: PaletteDark.violetBlue // scrollbar background
83 ),
75 - body2: TextStyle(
84 + // body2 -> bodyText1
85 + bodyText1: TextStyle(
86 color: PaletteDark.deepPurpleBlue, // menu header
87 decorationColor: PaletteDark.deepPurpleBlue, // menu background
88 )
@@ -86,7 +96,8 @@ class DarkTheme extends ThemeBase {
96 crossAxisMargin: 6,
97 ),
98 primaryTextTheme: TextTheme(
89 - title: TextStyle(
99 + // title -> headline6
100 + headline6: TextStyle(
101 color: Colors.white, // title color
102 backgroundColor: PaletteDark.darkOceanBlue // textfield underline
103 ),
@@ -98,43 +109,52 @@ class DarkTheme extends ThemeBase {
109 color: PaletteDark.lightBlueGrey, // transaction/trade details titles
110 decorationColor: Colors.grey, // placeholder
111 ),
101 - subhead: TextStyle(
112 + // subhead -> subtitle1
113 + subtitle1: TextStyle(
114 color: PaletteDark.darkNightBlue, // first gradient color (send page)
115 decorationColor: PaletteDark.darkNightBlue // second gradient color (send page)
116 ),
105 - headline: TextStyle(
117 + // headline -> headline5
118 + headline5: TextStyle(
119 color: PaletteDark.lightVioletBlue, // text field border color (send page)
120 decorationColor: PaletteDark.darkCyanBlue, // text field hint color (send page)
121 ),
109 - display1: TextStyle(
122 + // display1 -> headline4
123 + headline4: TextStyle(
124 color: PaletteDark.buttonNightBlue, // text field button color (send page)
125 decorationColor: PaletteDark.gray // text field button icon color (send page)
126 ),
113 - display2: TextStyle(
127 + // display2 -> headline3
128 + headline3: TextStyle(
129 color: Colors.white, // estimated fee (send page)
130 backgroundColor: PaletteDark.cyanBlue, // dot color for indicator on send page
131 decorationColor: PaletteDark.darkCyanBlue // template dotted border (send page)
132 ),
118 - display3: TextStyle(
133 + // display3 -> headline2
134 + headline2: TextStyle(
135 color: PaletteDark.darkCyanBlue, // template new text (send page)
136 backgroundColor: Colors.white, // active dot color for indicator on send page
137 decorationColor: PaletteDark.darkVioletBlue // template background color (send page)
138 ),
123 - display4: TextStyle(
139 + // display4 -> headline1
140 + headline1: TextStyle(
141 color: PaletteDark.cyanBlue, // template title (send page)
142 backgroundColor: Colors.white, // icon color on order row (moonpay)
143 decorationColor: PaletteDark.darkCyanBlue // receive amount text (exchange page)
144 ),
128 - subtitle: TextStyle(
145 + // subtitle -> subtitle2
146 + subtitle2: TextStyle(
147 color: PaletteDark.wildVioletBlue, // first gradient color top panel (exchange page)
148 decorationColor: PaletteDark.wildVioletBlue // second gradient color top panel (exchange page)
149 ),
132 - body1: TextStyle(
150 + // body1 -> bodyText2
151 + bodyText2: TextStyle(
152 color: PaletteDark.darkNightBlue, // first gradient color bottom panel (exchange page)
153 decorationColor: PaletteDark.darkNightBlue, // second gradient color bottom panel (exchange page)
154 backgroundColor: Palette.blueCraiola // alert right button text
155 ),
137 - body2: TextStyle(
156 + // body2 -> bodyText1
157 + bodyText1: TextStyle(
158 color: PaletteDark.blueGrey, // text field border on top panel (exchange page)
159 decorationColor: PaletteDark.moderateVioletBlue, // text field border on bottom panel (exchange page)
160 backgroundColor: Palette.alizarinRed // alert left button text
@@ -142,7 +162,8 @@ class DarkTheme extends ThemeBase {
162 ),
163 focusColor: PaletteDark.moderateBlue, // text field button (exchange page)
164 accentTextTheme: TextTheme(
145 - title: TextStyle(
165 + // title -> headline6
166 + headline6: TextStyle(
167 color: PaletteDark.nightBlue, // picker background
168 backgroundColor: PaletteDark.dividerColor, // picker divider
169 decorationColor: PaletteDark.darkNightBlue // dialog background
@@ -152,18 +173,21 @@ class DarkTheme extends ThemeBase {
173 backgroundColor: PaletteDark.deepVioletBlue, // button background (confirm exchange)
174 decorationColor: Palette.darkLavender, // text color (information page)
175 ),
155 - subtitle: TextStyle(
176 + // subtitle -> subtitle2
177 + subtitle2: TextStyle(
178 //color: PaletteDark.lightBlueGrey, // QR code (exchange trade page)
179 color: Colors.white, // QR code (exchange trade page)
180 backgroundColor: PaletteDark.deepVioletBlue, // divider (exchange trade page)
181 decorationColor: Colors.white // crete new wallet button background (wallet list page)
182 ),
161 - headline: TextStyle(
183 + // headline -> headline5
184 + headline5: TextStyle(
185 color: PaletteDark.distantBlue, // first gradient color of wallet action buttons (wallet list page)
186 backgroundColor: PaletteDark.distantNightBlue, // second gradient color of wallet action buttons (wallet list page)
187 decorationColor: Palette.darkBlueCraiola // restore wallet button text color (wallet list page)
188 ),
166 - subhead: TextStyle(
189 + // subhead -> subtitle1
190 + subtitle1: TextStyle(
191 color: Colors.white, // titles color (filter widget)
192 backgroundColor: PaletteDark.darkOceanBlue, // divider color (filter widget)
193 decorationColor: PaletteDark.wildVioletBlue.withOpacity(0.3) // checkbox background (filter widget)
@@ -172,32 +196,38 @@ class DarkTheme extends ThemeBase {
196 color: PaletteDark.wildVioletBlue, // checkbox bounds (filter widget)
197 decorationColor: PaletteDark.darkCyanBlue, // menu subname
198 ),
175 - display1: TextStyle(
199 + // display1 -> headline4
200 + headline4: TextStyle(
201 color: PaletteDark.deepPurpleBlue, // first gradient color (menu header)
202 decorationColor: PaletteDark.deepPurpleBlue, // second gradient color(menu header)
203 backgroundColor: Colors.white // active dot color
204 ),
180 - display2: TextStyle(
205 + // display2 -> headline3
206 + headline3: TextStyle(
207 color: PaletteDark.nightBlue, // action button color (address text field)
208 decorationColor: PaletteDark.darkCyanBlue, // hint text (seed widget)
209 backgroundColor: PaletteDark.cyanBlue // text on balance page
210 ),
185 - display3: TextStyle(
211 + // display3 -> headline2
212 + headline2: TextStyle(
213 color: PaletteDark.cyanBlue, // hint text (new wallet page)
214 decorationColor: PaletteDark.darkGrey, // underline (new wallet page)
215 backgroundColor: Colors.white // menu, icons, balance (dashboard page)
216 ),
190 - display4: TextStyle(
217 + // display4 -> headline1
218 + headline1: TextStyle(
219 color: PaletteDark.deepVioletBlue, // switch background (settings page)
220 backgroundColor: Colors.white, // icon color on support page (moonpay, github)
221 decorationColor: PaletteDark.lightBlueGrey // hint text (exchange page)
222 ),
195 - body1: TextStyle(
223 + // body1 -> bodyText2
224 + bodyText2: TextStyle(
225 color: PaletteDark.indicatorVioletBlue, // indicators (PIN code)
226 decorationColor: PaletteDark.lightPurpleBlue, // switch (PIN code)
227 backgroundColor: PaletteDark.darkNightBlue // alert right button
228 ),
200 - body2: TextStyle(
229 + // body2 -> bodyText1
230 + bodyText1: TextStyle(
231 color: Palette.blueCraiola, // primary buttons
232 decorationColor: PaletteDark.darkNightBlue, // alert left button
233 backgroundColor: PaletteDark.granite // keyboard bar color
lib/themes/light_theme.dart
+61 -31
@@ -4,7 +4,7 @@ import 'package:cake_wallet/palette.dart';
4 import 'package:flutter/material.dart';
5
6 class LightTheme extends ThemeBase {
7 - LightTheme({@required int raw}) : super(raw: raw);
7 + LightTheme({required int raw}) : super(raw: raw);
8
9 @override
10 String get title => S.current.light_theme;
@@ -26,7 +26,8 @@ class LightTheme extends ThemeBase {
26 dividerColor: Palette.paleBlue,
27 hintColor: Palette.gray,
28 textTheme: TextTheme(
29 - title: TextStyle(
29 + // title -> headline6
30 + headline6: TextStyle(
31 color: Palette.darkBlueCraiola, // sync_indicator text
32 backgroundColor: Palette.blueAlice, // synced sync_indicator
33 decorationColor: Palette.blueAlice.withOpacity(0.75), // not synced sync_indicator
@@ -40,40 +41,49 @@ class LightTheme extends ThemeBase {
41 backgroundColor: PaletteDark.darkCyanBlue, // date section row
42 decorationColor: Palette.blueAlice // icons (transaction and trade rows)
43 ),
43 - subhead: TextStyle(
44 + // subhead -> subtitle1
45 + subtitle1: TextStyle(
46 color: Palette.blueAlice, // address button border
47 decorationColor: PaletteDark.lightBlueGrey, // copy button (qr widget)
48 ),
47 - headline: TextStyle(
49 + // headline -> headline5
50 + headline5: TextStyle(
51 color: Colors.white, // qr code
52 decorationColor: Palette.darkBlueCraiola, // bottom border of amount (receive page)
53 ),
51 - display1: TextStyle(
54 + // display1 -> headline4
55 + headline4: TextStyle(
56 color: PaletteDark.lightBlueGrey, // icons color (receive page)
57 decorationColor: Palette.moderateLavender, // icons background (receive page)
58 ),
55 - display2: TextStyle(
59 + // display2 -> headline3
60 + headline3: TextStyle(
61 color: Palette.darkBlueCraiola, // text color of tiles (receive page)
62 decorationColor: Palette.blueAlice // background of tiles (receive page)
63 ),
59 - display3: TextStyle(
64 + // display3 -> headline2
65 + headline2: TextStyle(
66 color: Colors.white, // text color of current tile (receive page),
67 //decorationColor: Palette.blueCraiola // background of current tile (receive page)
68 decorationColor: Palette.blueCraiola // background of current tile (receive page)
69 ),
64 - display4: TextStyle(
70 + // display4 -> headline1
71 + headline1: TextStyle(
72 color: Palette.violetBlue, // text color of tiles (account list)
73 decorationColor: Colors.white // background of tiles (account list)
74 ),
68 - subtitle: TextStyle(
75 + // subtitle -> subtitle2
76 + subtitle2: TextStyle(
77 color: Palette.protectiveBlue, // text color of current tile (account list)
78 decorationColor: Colors.white // background of current tile (account list)
79 ),
72 - body1: TextStyle(
80 + // body -> bodyText2
81 + bodyText2: TextStyle(
82 color: Palette.moderatePurpleBlue, // scrollbar thumb
83 decorationColor: Palette.periwinkleCraiola // scrollbar background
84 ),
76 - body2: TextStyle(
85 + // body2 -> bodyText1
86 + bodyText1: TextStyle(
87 color: Palette.moderateLavender, // menu header
88 decorationColor: Colors.white, // menu background
89 )
@@ -87,7 +97,8 @@ class LightTheme extends ThemeBase {
97 crossAxisMargin: 6,
98 ),
99 primaryTextTheme: TextTheme(
90 - title: TextStyle(
100 + // title -> headline6
101 + headline6: TextStyle(
102 color: Palette.darkBlueCraiola, // title color
103 backgroundColor: Palette.wildPeriwinkle // textfield underline
104 ),
@@ -99,43 +110,52 @@ class LightTheme extends ThemeBase {
110 color: Palette.darkGray, // transaction/trade details titles
111 decorationColor: PaletteDark.darkCyanBlue, // placeholder
112 ),
102 - subhead: TextStyle(
113 + // subhead -> subtitle1
114 + subtitle1: TextStyle(
115 color: Palette.blueCraiola, // first gradient color (send page)
116 decorationColor: Palette.blueGreyCraiola // second gradient color (send page)
117 ),
106 - headline: TextStyle(
118 + // headline -> headline5
119 + headline5: TextStyle(
120 color: Colors.white.withOpacity(0.5), // text field border color (send page)
121 decorationColor: Colors.white.withOpacity(0.5), // text field hint color (send page)
122 ),
110 - display1: TextStyle(
123 + // display1 -> headline4
124 + headline4: TextStyle(
125 color: Colors.white.withOpacity(0.2), // text field button color (send page)
126 decorationColor: Colors.white // text field button icon color (send page)
127 ),
114 - display2: TextStyle(
128 + // display2 -> headline3
129 + headline3: TextStyle(
130 color: Colors.white.withOpacity(0.5), // estimated fee (send page)
131 backgroundColor: PaletteDark.darkCyanBlue.withOpacity(0.67), // dot color for indicator on send page
132 decorationColor: Palette.moderateLavender // template dotted border (send page)
133 ),
119 - display3: TextStyle(
134 + // display3 -> headline2
135 + headline2: TextStyle(
136 color: Palette.darkBlueCraiola, // template new text (send page)
137 backgroundColor: PaletteDark.darkNightBlue, // active dot color for indicator on send page
138 decorationColor: Palette.blueAlice // template background color (send page)
139 ),
124 - display4: TextStyle(
140 + // display4 -> headline1
141 + headline1: TextStyle(
142 color: Palette.darkBlueCraiola, // template title (send page)
143 backgroundColor: Colors.black, // icon color on order row (moonpay)
144 decorationColor: Palette.niagara // receive amount text (exchange page)
145 ),
129 - subtitle: TextStyle(
146 + // subtitle -> subtitle2
147 + subtitle2: TextStyle(
148 color: Palette.blueCraiola, // first gradient color top panel (exchange page)
149 decorationColor: Palette.blueGreyCraiola // second gradient color top panel (exchange page)
150 ),
133 - body1: TextStyle(
151 + // body -> bodyText2
152 + bodyText2: TextStyle(
153 color: Palette.blueCraiola.withOpacity(0.7), // first gradient color bottom panel (exchange page)
154 decorationColor: Palette.blueGreyCraiola.withOpacity(0.7), // second gradient color bottom panel (exchange page)
155 backgroundColor: Palette.protectiveBlue // alert right button text
156 ),
138 - body2: TextStyle(
157 + // body2 -> bodyText1
158 + bodyText1: TextStyle(
159 color: Colors.white.withOpacity(0.5), // text field border on top panel (exchange page)
160 decorationColor: Colors.white.withOpacity(0.5), // text field border on bottom panel (exchange page)
161 backgroundColor: Palette.brightOrange // alert left button text
@@ -143,7 +163,8 @@ class LightTheme extends ThemeBase {
163 ),
164 focusColor: Colors.white.withOpacity(0.2), // text field button (exchange page)
165 accentTextTheme: TextTheme(
146 - title: TextStyle(
166 + // title -> headline6
167 + headline6: TextStyle(
168 color: Colors.white, // picker background
169 backgroundColor: Palette.periwinkleCraiola, // picker divider
170 decorationColor: Colors.white // dialog background
@@ -153,17 +174,20 @@ class LightTheme extends ThemeBase {
174 backgroundColor: Palette.blueAlice, // button background (confirm exchange)
175 decorationColor: Palette.darkBlueCraiola, // text color (information page)
176 ),
156 - subtitle: TextStyle(
177 + // subtitle -> subtitle2
178 + subtitle2: TextStyle(
179 color: Palette.darkBlueCraiola, // QR code (exchange trade page)
180 backgroundColor: Palette.wildPeriwinkle, // divider (exchange trade page)
181 decorationColor: Palette.protectiveBlue // crete new wallet button background (wallet list page)
182 ),
161 - headline: TextStyle(
183 + // headline -> headline5
184 + headline5: TextStyle(
185 color: Palette.moderateLavender, // first gradient color of wallet action buttons (wallet list page)
186 backgroundColor: Palette.moderateLavender, // second gradient color of wallet action buttons (wallet list page)
187 decorationColor: Colors.white // restore wallet button text color (wallet list page)
188 ),
166 - subhead: TextStyle(
189 + // subhead -> subtitle1
190 + subtitle1: TextStyle(
191 color: Palette.darkGray, // titles color (filter widget)
192 backgroundColor: Palette.periwinkle, // divider color (filter widget)
193 decorationColor: Colors.white // checkbox background (filter widget)
@@ -172,32 +196,38 @@ class LightTheme extends ThemeBase {
196 color: Palette.wildPeriwinkle, // checkbox bounds (filter widget)
197 decorationColor: Colors.white, // menu subname
198 ),
175 - display1: TextStyle(
199 + // display1 -> headline4
200 + headline4: TextStyle(
201 color: Palette.blueCraiola, // first gradient color (menu header)
202 decorationColor: Palette.blueGreyCraiola, // second gradient color(menu header)
203 backgroundColor: PaletteDark.darkNightBlue // active dot color
204 ),
180 - display2: TextStyle(
205 + // display2 -> headline3
206 + headline3: TextStyle(
207 color: Palette.shadowWhite, // action button color (address text field)
208 decorationColor: Palette.darkGray, // hint text (seed widget)
209 backgroundColor: Palette.darkBlueCraiola.withOpacity(0.67) // text on balance page
210 ),
185 - display3: TextStyle(
211 + // display3 -> headline2
212 + headline2: TextStyle(
213 color: Palette.darkGray, // hint text (new wallet page)
214 decorationColor: Palette.periwinkleCraiola, // underline (new wallet page)
215 backgroundColor: Palette.darkBlueCraiola // menu, icons, balance (dashboard page)
216 ),
190 - display4: TextStyle(
217 + // display4 -> headline1
218 + headline1: TextStyle(
219 color: Palette.darkGray, // switch background (settings page)
220 backgroundColor: Colors.black, // icon color on support page (moonpay, github)
221 decorationColor: Colors.white.withOpacity(0.4) // hint text (exchange page)
222 ),
195 - body1: TextStyle(
223 + // body -> bodyText2
224 + bodyText2: TextStyle(
225 color: Palette.darkGray, // indicators (PIN code)
226 decorationColor: Palette.darkGray, // switch (PIN code)
227 backgroundColor: Colors.white // alert right button
228 ),
200 - body2: TextStyle(
229 + // body2 -> bodyText1
230 + bodyText1: TextStyle(
231 color: Palette.protectiveBlue, // primary buttons
232 decorationColor: Colors.white, // alert left button,
233 backgroundColor: Palette.dullGray // keyboard bar color
lib/themes/theme_base.dart
+1 -1
@@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
3 enum ThemeType {light, bright, dark}
4
5 abstract class ThemeBase {
6 - ThemeBase({@required this.raw});
6 + ThemeBase({required this.raw});
7
8 final int raw;
9 String get title;
lib/themes/theme_list.dart
+2 -2
@@ -10,7 +10,7 @@ class ThemeList {
10 static final brightTheme = BrightTheme(raw: 1);
11 static final darkTheme = DarkTheme(raw: 2);
12
13 - static ThemeBase deserialize({int raw}) {
13 + static ThemeBase deserialize({required int raw}) {
14 switch (raw) {
15 case 0:
16 return lightTheme;
@@ -19,7 +19,7 @@ class ThemeList {
19 case 2:
20 return darkTheme;
21 default:
22 - return null;
22 + throw Exception('Unexpected token raw: $raw for deserialization of ThemeBase');
23 }
24 }
25 }
\ No newline at end of file
lib/typography.dart
+19 -19
@@ -2,54 +2,54 @@ import 'package:flutter/material.dart';
2
3 const latoFont = "Lato";
4
5 -TextStyle textXxSmall({Color color}) => _cakeRegular(10, color);
5 +TextStyle textXxSmall({Color? color}) => _cakeRegular(10, color);
6
7 -TextStyle textXxSmallSemiBold({Color color}) => _cakeSemiBold(10, color);
7 +TextStyle textXxSmallSemiBold({Color? color}) => _cakeSemiBold(10, color);
8
9 -TextStyle textXSmall({Color color}) => _cakeRegular(12, color);
9 +TextStyle textXSmall({Color? color}) => _cakeRegular(12, color);
10
11 -TextStyle textXSmallSemiBold({Color color}) => _cakeSemiBold(12, color);
11 +TextStyle textXSmallSemiBold({Color? color}) => _cakeSemiBold(12, color);
12
13 -TextStyle textSmall({Color color}) => _cakeRegular(14, color);
13 +TextStyle textSmall({Color? color}) => _cakeRegular(14, color);
14
15 -TextStyle textSmallSemiBold({Color color}) => _cakeSemiBold(14, color);
15 +TextStyle textSmallSemiBold({Color? color}) => _cakeSemiBold(14, color);
16
17 -TextStyle textMedium({Color color}) => _cakeRegular(16, color);
17 +TextStyle textMedium({Color? color}) => _cakeRegular(16, color);
18
19 -TextStyle textMediumBold({Color color}) => _cakeBold(16, color);
19 +TextStyle textMediumBold({Color? color}) => _cakeBold(16, color);
20
21 -TextStyle textMediumSemiBold({Color color}) => _cakeSemiBold(22, color);
21 +TextStyle textMediumSemiBold({Color? color}) => _cakeSemiBold(22, color);
22
23 -TextStyle textLarge({Color color}) => _cakeRegular(18, color);
23 +TextStyle textLarge({Color? color}) => _cakeRegular(18, color);
24
25 -TextStyle textLargeSemiBold({Color color}) => _cakeSemiBold(24, color);
25 +TextStyle textLargeSemiBold({Color? color}) => _cakeSemiBold(24, color);
26
27 -TextStyle textXLarge({Color color}) => _cakeRegular(32, color);
27 +TextStyle textXLarge({Color? color}) => _cakeRegular(32, color);
28
29 -TextStyle textXLargeSemiBold({Color color}) => _cakeSemiBold(32, color);
29 +TextStyle textXLargeSemiBold({Color? color}) => _cakeSemiBold(32, color);
30
31 -TextStyle _cakeRegular(double size, Color color) => _textStyle(
31 +TextStyle _cakeRegular(double size, Color? color) => _textStyle(
32 size: size,
33 fontWeight: FontWeight.normal,
34 color: color,
35 );
36
37 -TextStyle _cakeBold(double size, Color color) => _textStyle(
37 +TextStyle _cakeBold(double size, Color? color) => _textStyle(
38 size: size,
39 fontWeight: FontWeight.w900,
40 color: color,
41 );
42
43 -TextStyle _cakeSemiBold(double size, Color color) => _textStyle(
43 +TextStyle _cakeSemiBold(double size, Color? color) => _textStyle(
44 size: size,
45 fontWeight: FontWeight.w700,
46 color: color,
47 );
48
49 TextStyle _textStyle({
50 - @required double size,
51 - @required FontWeight fontWeight,
52 - Color color,
50 + required double size,
51 + required FontWeight fontWeight,
52 + Color? color,
53 }) =>
54 TextStyle(
55 fontFamily: latoFont,
lib/utils/date_picker.dart
+8 -8
@@ -2,11 +2,11 @@ import 'dart:io';
2 import 'package:flutter/cupertino.dart';
3 import 'package:flutter/material.dart';
4
5 -Future<DateTime> getDate({
6 - @required BuildContext context,
7 - @required DateTime initialDate,
8 - @required DateTime firstDate,
9 - @required DateTime lastDate}) {
5 +Future<DateTime?> getDate({
6 + required BuildContext context,
7 + required DateTime initialDate,
8 + required DateTime firstDate,
9 + required DateTime lastDate}) {
10
11 if (Platform.isIOS) {
12 return _buildCupertinoDataPicker(context, initialDate, firstDate, lastDate);
@@ -15,7 +15,7 @@ Future<DateTime> getDate({
15 return _buildMaterialDataPicker(context, initialDate, firstDate, lastDate);
16 }
17
18 -Future<DateTime> _buildMaterialDataPicker(
18 +Future<DateTime?> _buildMaterialDataPicker(
19 BuildContext context,
20 DateTime initialDate,
21 DateTime firstDate,
@@ -28,12 +28,12 @@ Future<DateTime> _buildMaterialDataPicker(
28 helpText: '');
29 }
30
31 -Future<DateTime> _buildCupertinoDataPicker(
31 +Future<DateTime?> _buildCupertinoDataPicker(
32 BuildContext context,
33 DateTime initialDate,
34 DateTime firstDate,
35 DateTime lastDate) async {
36 - DateTime date;
36 + DateTime? date;
37 await showModalBottomSheet<void>(
38 context: context,
39 builder: (_) {
lib/utils/debounce.dart
+1 -1
@@ -5,7 +5,7 @@ class Debounce {
5 Debounce(this.duration);
6
7 final Duration duration;
8 - Timer _timer;
8 + Timer? _timer;
9
10 void run(VoidCallback action) {
11 _timer?.cancel();
lib/utils/item_cell.dart
+3 -1
@@ -7,7 +7,9 @@ import 'package:cw_core/keyable.dart';
7 // class NodeListViewModel = NodeListViewModelBase with _$NodeListViewModel;
8
9 class ItemCell<Item> with Keyable {
10 - ItemCell(this.value, {this.isSelectedBuilder, @required dynamic key}) {
10 + ItemCell(this.value, {
11 + required this.isSelectedBuilder,
12 + required dynamic key}) {
13 keyIndex = key;
14 }
15
lib/utils/list_section.dart
+1 -1
@@ -1,5 +1,5 @@
1 class ListSection<Item> {
2 - const ListSection({this.items});
2 + const ListSection({required this.items});
3
4 final List<Item> items;
5 }
\ No newline at end of file
lib/utils/mobx.dart
+13 -7
@@ -6,9 +6,13 @@ import 'package:cw_core/keyable.dart';
6 void connectMapToListWithTransform<T extends Keyable, Y extends Keyable>(
7 ObservableMap<dynamic, T> source,
8 ObservableList<Y> dest,
9 - Y Function(T) transform,
10 - {bool Function(T) filter}) {
9 + Y Function(T?) transform,
10 + {bool Function(T?)? filter}) {
11 source.observe((MapChange<dynamic, T> change) {
12 + if (change.type == null) {
13 + return;
14 + }
15 +
16 switch (change.type) {
17 case OperationType.add:
18 if (filter?.call(change.newValue) ?? true) {
@@ -18,7 +22,7 @@ void connectMapToListWithTransform<T extends Keyable, Y extends Keyable>(
22 case OperationType.remove:
23 // Hive could has equal index and key
24 dest.removeWhere((elem) =>
21 - elem.keyIndex == (change.key ?? change.newValue.keyIndex));
25 + elem.keyIndex == (change.key ?? change.newValue?.keyIndex));
26 break;
27 case OperationType.update:
28 for (var i = 0; i < dest.length; i++) {
@@ -29,6 +33,8 @@ void connectMapToListWithTransform<T extends Keyable, Y extends Keyable>(
33 }
34 }
35 break;
36 + default:
37 + break;
38 }
39 });
40 }
@@ -51,7 +57,7 @@ extension MobxBindable<T extends Keyable> on Box<T> {
57 StreamSubscription<BoxEvent> bindToList(
58 ObservableList<T> dest, {
59 bool initialFire = false,
54 - Filter<T> filter,
60 + Filter<T>? filter,
61 }) {
62 if (initialFire) {
63 final res = filter != null ? values.where(filter) : values;
@@ -71,7 +77,7 @@ extension MobxBindable<T extends Keyable> on Box<T> {
77 ObservableList<Y> dest,
78 Transform<T, Y> transform, {
79 bool initialFire = false,
74 - Filter<T> filter,
80 + Filter<T>? filter,
81 }) {
82 if (initialFire) {
83 dest.addAll(values.map((value) => transform(value)));
@@ -94,7 +100,7 @@ extension HiveBindable<T extends Keyable> on ObservableList<T> {
100 final controller = StreamController<EntityChange<T>>();
101
102 observe((ListChange<T> change) {
97 - change.elementChanges.forEach((change) {
103 + change.elementChanges?.forEach((change) {
104 ChangeType type;
105
106 switch (change.type) {
@@ -121,7 +127,7 @@ extension HiveBindable<T extends Keyable> on ObservableList<T> {
127 StreamSubscription<EntityChange<T>> bindToList(ObservableList<T> dest) =>
128 listen().listen((event) => dest.acceptEntityChange(event));
129
124 - void acceptBoxChange(BoxEvent event, {T transformed}) {
130 + void acceptBoxChange(BoxEvent event, {T? transformed}) {
131 if (event.deleted) {
132 removeWhere((el) {
133 return el.keyIndex == event.key;
lib/utils/show_bar.dart
+49 -46
@@ -1,55 +1,58 @@
1 -import 'package:flushbar/flushbar.dart';
1 +// import 'package:flushbar/flushbar.dart';
2 import 'package:flutter/cupertino.dart';
3 import 'package:flutter/material.dart';
4
5 -Future<T> showBar<T>(BuildContext context, String messageText,
5 +Future<T?> showBar<T>(BuildContext context, String messageText,
6 {bool isDark = false,
7 Duration duration = const Duration(seconds: 1),
8 bool isDismissible = true,
9 - String titleText}) {
10 - final bar = Flushbar<T>(
11 - boxShadows: [
12 - BoxShadow(
13 - color: Colors.black.withOpacity(0.09),
14 - blurRadius: 8,
15 - offset: Offset(0, 2))
16 - ],
17 - backgroundColor: isDark ? Colors.black : Colors.white,
18 - borderRadius: 35,
19 - margin: EdgeInsets.all(50),
20 - titleText: titleText != null
21 - ? Text(titleText,
22 - textAlign: TextAlign.center,
23 - style: TextStyle(color: isDark ? Colors.white : Colors.black, fontWeight: FontWeight.bold, fontSize: 24.0))
24 - : null,
25 - messageText: Text(messageText,
26 - textAlign: TextAlign.center,
27 - style: TextStyle(color: isDark ? Colors.white : Colors.black, fontSize: 16)),
28 - duration: duration,
29 - isDismissible: isDismissible,
30 - flushbarPosition: FlushbarPosition.TOP,
31 - flushbarStyle: FlushbarStyle.FLOATING);
9 + String? titleText}) async {
10 + // FIX-ME: Unimplemented Flushbar
11 + // final bar = Flushbar<T>(
12 + // boxShadows: [
13 + // BoxShadow(
14 + // color: Colors.black.withOpacity(0.09),
15 + // blurRadius: 8,
16 + // offset: Offset(0, 2))
17 + // ],
18 + // backgroundColor: isDark ? Colors.black : Colors.white,
19 + // borderRadius: 35,
20 + // margin: EdgeInsets.all(50),
21 + // titleText: titleText != null
22 + // ? Text(titleText,
23 + // textAlign: TextAlign.center,
24 + // style: TextStyle(color: isDark ? Colors.white : Colors.black, fontWeight: FontWeight.bold, fontSize: 24.0))
25 + // : null,
26 + // messageText: Text(messageText,
27 + // textAlign: TextAlign.center,
28 + // style: TextStyle(color: isDark ? Colors.white : Colors.black, fontSize: 16)),
29 + // duration: duration,
30 + // isDismissible: isDismissible,
31 + // flushbarPosition: FlushbarPosition.TOP,
32 + // flushbarStyle: FlushbarStyle.FLOATING);
33
33 - return bar.show(context);
34 + // return bar.show(context);
35 + return null;
36 }
37
36 -Flushbar<T> createBar<T>(String text,
37 - {bool isDark = false, Duration duration = const Duration(seconds: 1), bool isDismissible = true}) {
38 - return Flushbar<T>(
39 - boxShadows: [
40 - BoxShadow(
41 - color: Colors.black.withOpacity(0.09),
42 - blurRadius: 8,
43 - offset: Offset(0, 2))
44 - ],
45 - backgroundColor: isDark ? Colors.black : Colors.white,
46 - borderRadius: 35,
47 - margin: EdgeInsets.all(50),
48 - messageText: Text(text,
49 - textAlign: TextAlign.center,
50 - style: TextStyle(color: isDark ? Colors.white : Colors.black)),
51 - duration: duration,
52 - isDismissible: isDismissible,
53 - flushbarPosition: FlushbarPosition.TOP,
54 - flushbarStyle: FlushbarStyle.FLOATING);
55 -}
38 +// FIX-ME: Unimplemented Flushbar
39 +// Flushbar<T> createBar<T>(String text,
40 + // {bool isDark = false, Duration duration = const Duration(seconds: 1), bool isDismissible = true}) {
41 + // return Flushbar<T>(
42 + // boxShadows: [
43 + // BoxShadow(
44 + // color: Colors.black.withOpacity(0.09),
45 + // blurRadius: 8,
46 + // offset: Offset(0, 2))
47 + // ],
48 + // backgroundColor: isDark ? Colors.black : Colors.white,
49 + // borderRadius: 35,
50 + // margin: EdgeInsets.all(50),
51 + // messageText: Text(text,
52 + // textAlign: TextAlign.center,
53 + // style: TextStyle(color: isDark ? Colors.white : Colors.black)),
54 + // duration: duration,
55 + // isDismissible: isDismissible,
56 + // flushbarPosition: FlushbarPosition.TOP,
57 + // flushbarStyle: FlushbarStyle.FLOATING);
58 +// }
lib/utils/show_pop_up.dart
+5 -5
@@ -1,13 +1,13 @@
1 import 'package:flutter/material.dart';
2
3 -Future<T> showPopUp<T>({
4 - @required BuildContext context,
5 - WidgetBuilder builder,
3 +Future<T?> showPopUp<T>({
4 + required BuildContext context,
5 + required WidgetBuilder builder,
6 bool barrierDismissible = true,
7 - Color barrierColor,
7 + Color? barrierColor,
8 bool useSafeArea = false,
9 bool useRootNavigator = true,
10 - RouteSettings routeSettings
10 + RouteSettings? routeSettings
11 }) {
12 return showDialog<T>(
13 context: context,
lib/view_model/auth_state.dart
+1 -1
@@ -1,7 +1,7 @@
1 import 'package:cake_wallet/core/execution_state.dart';
2
3 class AuthenticationBanned extends ExecutionState {
4 - AuthenticationBanned({this.error});
4 + AuthenticationBanned({required this.error});
5
6 final String error;
7 }
lib/view_model/auth_view_model.dart
+5 -6
@@ -14,10 +14,9 @@ class AuthViewModel = AuthViewModelBase with _$AuthViewModel;
14
15 abstract class AuthViewModelBase with Store {
16 AuthViewModelBase(this._authService, this._sharedPreferences,
17 - this._settingsStore, this._biometricAuth) {
18 - state = InitialExecutionState();
19 - _failureCounter = 0;
20 - }
17 + this._settingsStore, this._biometricAuth)
18 + : _failureCounter = 0,
19 + state = InitialExecutionState();
20
21 static const maxFailedLogins = 3;
22 static const banTimeout = 180; // 3 minutes
@@ -40,7 +39,7 @@ abstract class AuthViewModelBase with Store {
39 final SettingsStore _settingsStore;
40
41 @action
43 - Future<void> auth({String password}) async {
42 + Future<void> auth({required String password}) async {
43 state = InitialExecutionState();
44 final _banDuration = banDuration();
45
@@ -74,7 +73,7 @@ abstract class AuthViewModelBase with Store {
73 }
74 }
75
77 - Duration banDuration() {
76 + Duration? banDuration() {
77 final unbanTimestamp = _sharedPreferences.getInt(banTimeoutKey);
78
79 if (unbanTimestamp == null) {
lib/view_model/backup_view_model.dart
+6 -5
@@ -12,7 +12,7 @@ import 'package:cake_wallet/wallet_type_utils.dart';
12 part 'backup_view_model.g.dart';
13
14 class BackupExportFile {
15 - BackupExportFile(this.content, {@required this.name});
15 + BackupExportFile(this.content, {required this.name});
16
17 final String name;
18 final List<int> content;
@@ -22,8 +22,9 @@ class BackupViewModel = BackupViewModelBase with _$BackupViewModel;
22
23 abstract class BackupViewModelBase with Store {
24 BackupViewModelBase(this.secureStorage, this.secretStore, this.backupService)
25 - : isBackupPasswordVisible = false {
26 - state = InitialExecutionState();
25 + : isBackupPasswordVisible = false,
26 + backupPassword = '',
27 + state = InitialExecutionState() {
28 final key = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
29 secretStore.values.observe((change) {
30 if (change.key == key) {
@@ -48,11 +49,11 @@ abstract class BackupViewModelBase with Store {
49 @action
50 Future<void> init() async {
51 final key = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
51 - backupPassword = await secureStorage.read(key: key);
52 + backupPassword = (await secureStorage.read(key: key))!;
53 }
54
55 @action
55 - Future<BackupExportFile> exportBackup() async {
56 + Future<BackupExportFile?> exportBackup() async {
57 try {
58 state = IsExecutingState();
59 final backupContent = await backupService.exportBackup(backupPassword);
lib/view_model/buy/buy_amount_view_model.dart
+5 -6
@@ -8,9 +8,8 @@ part 'buy_amount_view_model.g.dart';
8 class BuyAmountViewModel = BuyAmountViewModelBase with _$BuyAmountViewModel;
9
10 abstract class BuyAmountViewModelBase with Store {
11 - BuyAmountViewModelBase() {
12 - amount = '';
13 -
11 + BuyAmountViewModelBase()
12 + : amount = '' {
13 int selectedIndex = FiatCurrency.currenciesAvailableToBuyWith
14 .indexOf(getIt.get<SettingsStore>().fiatCurrency);
15
@@ -25,15 +24,15 @@ abstract class BuyAmountViewModelBase with Store {
24 String amount;
25
26 @observable
28 - FiatCurrency fiatCurrency;
27 + late FiatCurrency fiatCurrency;
28
29 @computed
30 double get doubleAmount {
31 double _amount;
32
33 try {
35 - _amount = double.parse(amount.replaceAll(',', '.')) ?? 0.0;
36 - } catch (e) {
34 + _amount = double.parse(amount.replaceAll(',', '.'));
35 + } catch (_) {
36 _amount = 0.0;
37 }
38
lib/view_model/buy/buy_item.dart
+2 -2
@@ -4,7 +4,7 @@ import 'package:cake_wallet/entities/fiat_currency.dart';
4 import 'package:cake_wallet/view_model/buy/buy_amount_view_model.dart';
5
6 class BuyItem {
7 - BuyItem({this.provider, this.buyAmountViewModel});
7 + BuyItem({required this.provider, required this.buyAmountViewModel});
8
9 final BuyProvider provider;
10 final BuyAmountViewModel buyAmountViewModel;
@@ -18,7 +18,7 @@ class BuyItem {
18
19 try {
20 _buyAmount = await provider
21 - .calculateAmount(amount?.toString(), fiatCurrency.title);
21 + .calculateAmount(amount?.toString() ?? '', fiatCurrency.title);
22 } catch (e) {
23 _buyAmount = BuyAmount(sourceAmount: 0.0, destAmount: 0.0);
24 print(e.toString());
lib/view_model/buy/buy_view_model.dart
+8 -9
@@ -20,13 +20,12 @@ class BuyViewModel = BuyViewModelBase with _$BuyViewModel;
20
21 abstract class BuyViewModelBase with Store {
22 BuyViewModelBase(this.ordersSource, this.ordersStore, this.settingsStore,
23 - this.buyAmountViewModel, {@required this.wallet}) {
24 -
23 + this.buyAmountViewModel, {required this.wallet})
24 + : isRunning = false,
25 + isDisabled = true,
26 + isShowProviderButtons = false,
27 + items = <BuyItem>[] {
28 _fetchBuyItems();
26 -
27 - isRunning = false;
28 - isDisabled = true;
29 - isShowProviderButtons = false;
29 }
30
31 final Box<Order> ordersSource;
@@ -36,7 +35,7 @@ abstract class BuyViewModelBase with Store {
35 final WalletBase wallet;
36
37 @observable
39 - BuyProvider selectedProvider;
38 + BuyProvider? selectedProvider;
39
40 @observable
41 List<BuyItem> items;
@@ -64,7 +63,7 @@ abstract class BuyViewModelBase with Store {
63
64 try {
65 _url = await selectedProvider
67 - ?.requestUrl(doubleAmount?.toString(), fiatCurrency.title);
66 + !.requestUrl(doubleAmount.toString(), fiatCurrency.title);
67 } catch (e) {
68 print(e.toString());
69 }
@@ -74,7 +73,7 @@ abstract class BuyViewModelBase with Store {
73
74 Future<void> saveOrder(String orderId) async {
75 try {
77 - final order = await selectedProvider?.findOrderById(orderId);
76 + final order = await selectedProvider!.findOrderById(orderId);
77 order.from = fiatCurrency.title;
78 order.to = cryptoCurrency.title;
79 await ordersSource.add(order);
lib/view_model/contact_list/contact_list_view_model.dart
+1 -1
@@ -41,7 +41,7 @@ abstract class ContactListViewModelBase with Store {
41 final Box<WalletInfo> walletInfoSource;
42 final ObservableList<ContactRecord> contacts;
43 final List<WalletContact> walletContacts;
44 - StreamSubscription<BoxEvent> _subscription;
44 + StreamSubscription<BoxEvent>? _subscription;
45
46 Future<void> delete(ContactRecord contact) async => contact.original.delete();
47 }
lib/view_model/contact_list/contact_view_model.dart
+15 -16
@@ -11,14 +11,13 @@ part 'contact_view_model.g.dart';
11 class ContactViewModel = ContactViewModelBase with _$ContactViewModel;
12
13 abstract class ContactViewModelBase with Store {
14 - ContactViewModelBase(this._contacts, {ContactRecord contact})
14 + ContactViewModelBase(this._contacts, {ContactRecord? contact})
15 : state = InitialExecutionState(),
16 currencies = CryptoCurrency.all,
17 - _contact = contact {
18 - name = _contact?.name;
19 - address = _contact?.address;
20 - currency = _contact?.type;
21 - }
17 + _contact = contact,
18 + name = contact?.name ?? '',
19 + address = contact?.address ?? '',
20 + currency = contact?.type;
21
22 @observable
23 ExecutionState state;
@@ -30,17 +29,17 @@ abstract class ContactViewModelBase with Store {
29 String address;
30
31 @observable
33 - CryptoCurrency currency;
32 + CryptoCurrency? currency;
33
34 @computed
35 bool get isReady =>
37 - (name?.isNotEmpty ?? false) &&
38 - (currency?.toString()?.isNotEmpty ?? false) &&
39 - (address?.isNotEmpty ?? false);
36 + name.isNotEmpty &&
37 + (currency?.toString().isNotEmpty ?? false) &&
38 + address.isNotEmpty;
39
40 final List<CryptoCurrency> currencies;
41 final Box<Contact> _contacts;
43 - final ContactRecord _contact;
42 + final ContactRecord? _contact;
43
44 @action
45 void reset() {
@@ -54,13 +53,13 @@ abstract class ContactViewModelBase with Store {
53 state = IsExecutingState();
54
55 if (_contact != null) {
57 - _contact.name = name;
58 - _contact.address = address;
59 - _contact.type = currency;
60 - await _contact.save();
56 + _contact?.name = name;
57 + _contact?.address = address;
58 + _contact?.type = currency!;
59 + await _contact?.save();
60 } else {
61 await _contacts
63 - .add(Contact(name: name, address: address, type: currency));
62 + .add(Contact(name: name, address: address, type: currency!));
63 }
64
65 state = ExecutedSuccessfullyState();
lib/view_model/dashboard/action_list_display_mode.dart
+1 -1
@@ -18,7 +18,7 @@ int serializeActionlistDisplayModes(List<ActionListDisplayMode> modes) {
18 }
19
20 List<ActionListDisplayMode> deserializeActionlistDisplayModes(int raw) {
21 - final modes = List<ActionListDisplayMode>();
21 + final modes = <ActionListDisplayMode>[];
22
23 if (raw == 1 || raw - 10 == 1) {
24 modes.add(ActionListDisplayMode.trades);
lib/view_model/dashboard/balance_view_model.dart
+51 -24
@@ -16,12 +16,13 @@ import 'package:mobx/mobx.dart';
16 part 'balance_view_model.g.dart';
17
18 class BalanceRecord {
19 - const BalanceRecord({this.availableBalance,
20 - this.additionalBalance,
21 - this.fiatAvailableBalance,
22 - this.fiatAdditionalBalance,
23 - this.asset,
24 - this.formattedAssetTitle});
19 + const BalanceRecord({
20 + required this.availableBalance,
21 + required this.additionalBalance,
22 + required this.fiatAvailableBalance,
23 + required this.fiatAdditionalBalance,
24 + required this.asset,
25 + required this.formattedAssetTitle});
26 final String fiatAdditionalBalance;
27 final String fiatAvailableBalance;
28 final String additionalBalance;
@@ -34,12 +35,12 @@ class BalanceViewModel = BalanceViewModelBase with _$BalanceViewModel;
35
36 abstract class BalanceViewModelBase with Store {
37 BalanceViewModelBase(
37 - {@required this.appStore,
38 - @required this.settingsStore,
39 - @required this.fiatConvertationStore}) {
40 - isReversing = false;
41 - wallet ??= appStore.wallet;
42 - isShowCard = wallet.walletInfo.isShowIntroCakePayCard;
38 + {required this.appStore,
39 + required this.settingsStore,
40 + required this.fiatConvertationStore})
41 + : isReversing = false,
42 + isShowCard = appStore.wallet!.walletInfo.isShowIntroCakePayCard,
43 + wallet = appStore.wallet! {
44 reaction((_) => appStore.wallet, _onWalletChange);
45 }
46
@@ -57,14 +58,22 @@ abstract class BalanceViewModelBase with Store {
58 wallet;
59
60 @computed
60 - double get price => fiatConvertationStore.prices[appStore.wallet.currency];
61 + double get price {
62 + final price = fiatConvertationStore.prices[appStore.wallet!.currency];
63 +
64 + if (price == null) {
65 + throw Exception('No price for ${appStore.wallet!.currency} (current wallet)');
66 + }
67 +
68 + return price;
69 + }
70
71 @computed
72 BalanceDisplayMode get savedDisplayMode => settingsStore.balanceDisplayMode;
73
74 @computed
75 String get asset {
67 - final typeFormatted = walletTypeToString(appStore.wallet.type);
76 + final typeFormatted = walletTypeToString(appStore.wallet!.type);
77
78 switch(wallet.type) {
79 case WalletType.haven:
@@ -110,7 +119,7 @@ abstract class BalanceViewModelBase with Store {
119 }
120
121 @computed
113 - bool get hasMultiBalance => appStore.wallet.type == WalletType.haven;
122 + bool get hasMultiBalance => appStore.wallet!.type == WalletType.haven;
123
124 @computed
125 String get availableBalance {
@@ -177,16 +186,22 @@ abstract class BalanceViewModelBase with Store {
186 formattedAssetTitle: _formatterAsset(key)));
187 }
188 final fiatCurrency = settingsStore.fiatCurrency;
189 + final price = fiatConvertationStore.prices[key] ?? 0;
190 +
191 + // if (price == null) {
192 + // throw Exception('Price is null for: $key');
193 + // }
194 +
195 final additionalFiatBalance = fiatCurrency.toString()
196 + ' '
197 + _getFiatBalance(
183 - price: fiatConvertationStore.prices[key],
198 + price: price,
199 cryptoAmount: value.formattedAdditionalBalance);
200
201 final availableFiatBalance = fiatCurrency.toString()
202 + ' '
203 + _getFiatBalance(
189 - price: fiatConvertationStore.prices[key],
204 + price: price,
205 cryptoAmount: value.formattedAvailableBalance);
206
207 return MapEntry(key, BalanceRecord(
@@ -231,23 +246,35 @@ abstract class BalanceViewModelBase with Store {
246 }
247
248 @computed
234 - Balance get _walletBalance => wallet.balance[wallet.currency];
249 + Balance get _walletBalance {
250 + final balance = wallet.balance[wallet.currency];
251 +
252 + if (balance == null) {
253 + throw Exception('No balance for ${wallet.currency}');
254 + }
255 +
256 + return balance;
257 + }
258
259 @computed
237 - CryptoCurrency get currency => appStore.wallet.currency;
260 + CryptoCurrency get currency => appStore.wallet!.currency;
261
262 @observable
263 bool isShowCard;
264
242 - ReactionDisposer _onCurrentWalletChangeReaction;
265 + ReactionDisposer? _onCurrentWalletChangeReaction;
266
267 @action
268 void _onWalletChange(
269 WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
247 - TransactionInfo>
270 + TransactionInfo>?
271 wallet) {
249 - this.wallet = wallet;
250 - _onCurrentWalletChangeReaction?.reaction?.dispose();
272 + if (wallet == null) {
273 + return;
274 + }
275 +
276 + this.wallet = wallet;
277 + _onCurrentWalletChangeReaction?.reaction.dispose();
278 isShowCard = wallet.walletInfo.isShowIntroCakePayCard;
279 }
280
@@ -259,7 +286,7 @@ abstract class BalanceViewModelBase with Store {
286 isShowCard = cardDisplayStatus;
287 }
288
262 - String _getFiatBalance({double price, String cryptoAmount}) {
289 + String _getFiatBalance({required double price, String? cryptoAmount}) {
290 if (cryptoAmount == null) {
291 return '0.00';
292 }
lib/view_model/dashboard/dashboard_view_model.dart
+73 -45
@@ -39,14 +39,24 @@ class DashboardViewModel = DashboardViewModelBase with _$DashboardViewModel;
39
40 abstract class DashboardViewModelBase with Store {
41 DashboardViewModelBase(
42 - {this.balanceViewModel,
43 - this.appStore,
44 - this.tradesStore,
45 - this.tradeFilterStore,
46 - this.transactionFilterStore,
47 - this.settingsStore,
48 - this.yatStore,
49 - this.ordersStore}) {
42 + {required this.balanceViewModel,
43 + required this.appStore,
44 + required this.tradesStore,
45 + required this.tradeFilterStore,
46 + required this.transactionFilterStore,
47 + required this.settingsStore,
48 + required this.yatStore,
49 + required this.ordersStore})
50 + : isOutdatedElectrumWallet = false,
51 + hasSellAction = false,
52 + isEnabledSellAction = false,
53 + hasBuyAction = false,
54 + isEnabledBuyAction = false,
55 + hasExchangeAction = false,
56 + isEnabledExchangeAction = false,
57 + isShowFirstYatIntroduction = false,
58 + isShowSecondYatIntroduction = false,
59 + isShowThirdYatIntroduction = false,
60 filterItems = {
61 S.current.transactions: [
62 FilterItem(
@@ -69,10 +79,13 @@ abstract class DashboardViewModelBase with Store {
79 onChanged: (value) => tradeFilterStore
80 .toggleDisplayExchange(ExchangeProviderDescription.changeNow)),
81 ]
72 - };
73 -
74 - name = appStore.wallet?.name;
75 - wallet ??= appStore.wallet;
82 + },
83 + subname = '',
84 + name = appStore.wallet!.name,
85 + type = appStore.wallet!.type,
86 + transactions = ObservableList<TransactionListItem>(),
87 + wallet = appStore.wallet! {
88 + name = wallet.name;
89 type = wallet.type;
90 isOutdatedElectrumWallet =
91 wallet.type == WalletType.bitcoin && wallet.seed.split(' ').length < 24;
@@ -84,17 +97,17 @@ abstract class DashboardViewModelBase with Store {
97 final _wallet = wallet;
98
99 if (_wallet.type == WalletType.monero) {
87 - subname = monero.getCurrentAccount(_wallet)?.label;
100 + subname = monero!.getCurrentAccount(_wallet).label;
101
89 - _onMoneroAccountChangeReaction = reaction((_) => monero.getMoneroWalletDetails(wallet)
102 + _onMoneroAccountChangeReaction = reaction((_) => monero!.getMoneroWalletDetails(wallet)
103 .account, (Account account) => _onMoneroAccountChange(_wallet));
104
92 - _onMoneroBalanceChangeReaction = reaction((_) => monero.getMoneroWalletDetails(wallet).balance,
105 + _onMoneroBalanceChangeReaction = reaction((_) => monero!.getMoneroWalletDetails(wallet).balance,
106 (MoneroBalance balance) => _onMoneroTransactionsUpdate(_wallet));
107
108 final _accountTransactions = _wallet
109 .transactionHistory.transactions.values
97 - .where((tx) => monero.getTransactionInfoAccountId(tx) == monero.getCurrentAccount(wallet).id)
110 + .where((tx) => monero!.getTransactionInfoAccountId(tx) == monero!.getCurrentAccount(wallet).id)
111 .toList();
112
113 transactions = ObservableList.of(_accountTransactions.map((transaction) =>
@@ -114,19 +127,23 @@ abstract class DashboardViewModelBase with Store {
127 reaction((_) => appStore.wallet, _onWalletChange);
128
129 connectMapToListWithTransform(
117 - appStore.wallet.transactionHistory.transactions,
130 + appStore.wallet!.transactionHistory.transactions,
131 transactions,
119 - (TransactionInfo val) => TransactionListItem(
120 - transaction: val,
132 + (TransactionInfo? transaction) => TransactionListItem(
133 + transaction: transaction!,
134 balanceViewModel: balanceViewModel,
135 settingsStore: appStore.settingsStore),
123 - filter: (TransactionInfo tx) {
124 - final wallet = _wallet;
125 - if (wallet.type == WalletType.monero) {
126 - return monero.getTransactionInfoAccountId(tx) == monero.getCurrentAccount(wallet).id;
127 - }
136 + filter: (TransactionInfo? transaction) {
137 + if (transaction == null) {
138 + return false;
139 + }
140 +
141 + final wallet = _wallet;
142 + if (wallet.type == WalletType.monero) {
143 + return monero!.getTransactionInfoAccountId(transaction) == monero!.getCurrentAccount(wallet).id;
144 + }
145
129 - return true;
146 + return true;
147 });
148 }
149
@@ -250,9 +267,9 @@ abstract class DashboardViewModelBase with Store {
267 @observable
268 bool hasSellAction;
269
253 - ReactionDisposer _onMoneroAccountChangeReaction;
270 + ReactionDisposer? _onMoneroAccountChangeReaction;
271
255 - ReactionDisposer _onMoneroBalanceChangeReaction;
272 + ReactionDisposer? _onMoneroBalanceChangeReaction;
273
274 @observable
275 bool isOutdatedElectrumWallet;
@@ -265,8 +282,12 @@ abstract class DashboardViewModelBase with Store {
282 @action
283 void _onWalletChange(
284 WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
268 - TransactionInfo>
285 + TransactionInfo>?
286 wallet) {
287 + if (wallet == null) {
288 + return;
289 + }
290 +
291 this.wallet = wallet;
292 type = wallet.type;
293 name = wallet.name;
@@ -275,20 +296,22 @@ abstract class DashboardViewModelBase with Store {
296 updateActions();
297
298 if (wallet.type == WalletType.monero) {
278 - subname = monero.getCurrentAccount(wallet)?.label;
299 + subname = monero!.getCurrentAccount(wallet).label;
300
280 - _onMoneroAccountChangeReaction?.reaction?.dispose();
281 - _onMoneroBalanceChangeReaction?.reaction?.dispose();
301 + _onMoneroAccountChangeReaction?.reaction.dispose();
302 + _onMoneroBalanceChangeReaction?.reaction.dispose();
303
283 - _onMoneroAccountChangeReaction = reaction((_) => monero.getMoneroWalletDetails(wallet)
304 + _onMoneroAccountChangeReaction = reaction((_) => monero!.getMoneroWalletDetails(wallet)
305 .account, (Account account) => _onMoneroAccountChange(wallet));
306
286 - _onMoneroBalanceChangeReaction = reaction((_) => monero.getMoneroWalletDetails(wallet).balance,
307 + _onMoneroBalanceChangeReaction = reaction((_) => monero!.getMoneroWalletDetails(wallet).balance,
308 (MoneroBalance balance) => _onMoneroTransactionsUpdate(wallet));
309
310 _onMoneroTransactionsUpdate(wallet);
311 } else {
291 - subname = null;
312 + // FIX-ME: Check for side effects
313 + // subname = null;
314 + subname = '';
315
316 transactions.clear();
317
@@ -300,24 +323,29 @@ abstract class DashboardViewModelBase with Store {
323 }
324
325 connectMapToListWithTransform(
303 - appStore.wallet.transactionHistory.transactions,
326 + appStore.wallet!.transactionHistory.transactions,
327 transactions,
305 - (TransactionInfo val) => TransactionListItem(
306 - transaction: val,
328 + (TransactionInfo? transaction)
329 + => TransactionListItem(
330 + transaction: transaction!,
331 balanceViewModel: balanceViewModel,
332 settingsStore: appStore.settingsStore),
309 - filter: (TransactionInfo tx) {
310 - if (wallet.type == WalletType.monero) {
311 - return monero.getTransactionInfoAccountId(tx) == monero.getCurrentAccount(wallet).id;
312 - }
333 + filter: (TransactionInfo? tx) {
334 + if (tx == null) {
335 + return false;
336 + }
337 +
338 + if (wallet.type == WalletType.monero) {
339 + return monero!.getTransactionInfoAccountId(tx) == monero!.getCurrentAccount(wallet).id;
340 + }
341
314 - return true;
342 + return true;
343 });
344 }
345
346 @action
347 void _onMoneroAccountChange(WalletBase wallet) {
320 - subname = monero.getCurrentAccount(wallet)?.label;
348 + subname = monero!.getCurrentAccount(wallet).label;
349 _onMoneroTransactionsUpdate(wallet);
350 }
351
@@ -325,8 +353,8 @@ abstract class DashboardViewModelBase with Store {
353 void _onMoneroTransactionsUpdate(WalletBase wallet) {
354 transactions.clear();
355
328 - final _accountTransactions = monero.getTransactionHistory(wallet).transactions.values
329 - .where((tx) => monero.getTransactionInfoAccountId(tx) == monero.getCurrentAccount(wallet).id)
356 + final _accountTransactions = monero!.getTransactionHistory(wallet).transactions.values
357 + .where((tx) => monero!.getTransactionInfoAccountId(tx) == monero!.getCurrentAccount(wallet).id)
358 .toList();
359
360 transactions.addAll(_accountTransactions.map((transaction) =>
lib/view_model/dashboard/filter_item.dart
+4 -1
@@ -1,5 +1,8 @@
1 class FilterItem {
2 - FilterItem({this.value, this.caption, this.onChanged});
2 + FilterItem({
3 + required this.value,
4 + required this.caption,
5 + required this.onChanged});
6
7 bool Function() value;
8 String caption;
lib/view_model/dashboard/formatted_item_list.dart
+1 -1
@@ -3,7 +3,7 @@ import 'package:cake_wallet/view_model/dashboard/date_section_item.dart';
3
4 List<ActionListItem> formattedItemsList(List<ActionListItem> items) {
5 final formattedList = <ActionListItem>[];
6 - DateTime lastDate;
6 + DateTime? lastDate;
7 items.sort((a, b) => b.date.compareTo(a.date));
8
9 for (var i = 0; i < items.length; i++) {
lib/view_model/dashboard/order_list_item.dart
+3 -1
@@ -4,7 +4,9 @@ import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
4 import 'package:cake_wallet/entities/balance_display_mode.dart';
5
6 class OrderListItem extends ActionListItem {
7 - OrderListItem({this.order, this.settingsStore});
7 + OrderListItem({
8 + required this.order,
9 + required this.settingsStore});
10
11 final Order order;
12 final SettingsStore settingsStore;
lib/view_model/dashboard/trade_list_item.dart
+4 -2
@@ -4,7 +4,9 @@ import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
4 import 'package:cake_wallet/entities/balance_display_mode.dart';
5
6 class TradeListItem extends ActionListItem {
7 - TradeListItem({this.trade, this.settingsStore});
7 + TradeListItem({
8 + required this.trade,
9 + required this.settingsStore});
10
11 final Trade trade;
12 final SettingsStore settingsStore;
@@ -20,5 +22,5 @@ class TradeListItem extends ActionListItem {
22 }
23
24 @override
23 - DateTime get date => trade.createdAt;
25 + DateTime get date => trade.createdAt!;
26 }
lib/view_model/dashboard/transaction_list_item.dart
+8 -6
@@ -13,7 +13,9 @@ import 'package:cw_core/wallet_type.dart';
13
14 class TransactionListItem extends ActionListItem with Keyable {
15 TransactionListItem(
16 - {this.transaction, this.balanceViewModel, this.settingsStore});
16 + {required this.transaction,
17 + required this.balanceViewModel,
18 + required this.settingsStore});
19
20 final TransactionInfo transaction;
21 final BalanceViewModel balanceViewModel;
@@ -40,20 +42,20 @@ class TransactionListItem extends ActionListItem with Keyable {
42 switch(balanceViewModel.wallet.type) {
43 case WalletType.monero:
44 amount = calculateFiatAmountRaw(
43 - cryptoAmount: monero.formatterMoneroAmountToDouble(amount: transaction.amount),
45 + cryptoAmount: monero!.formatterMoneroAmountToDouble(amount: transaction.amount),
46 price: price);
47 break;
48 case WalletType.bitcoin:
49 case WalletType.litecoin:
50 amount = calculateFiatAmountRaw(
49 - cryptoAmount: bitcoin.formatterBitcoinAmountToDouble(amount: transaction.amount),
51 + cryptoAmount: bitcoin!.formatterBitcoinAmountToDouble(amount: transaction.amount),
52 price: price);
53 break;
54 case WalletType.haven:
53 - final asset = haven.assetOfTransaction(transaction);
54 - final price = balanceViewModel.fiatConvertationStore.prices[asset];
55 + final asset = haven!.assetOfTransaction(transaction);
56 + final price = balanceViewModel.fiatConvertationStore.prices[asset]!;
57 amount = calculateFiatAmountRaw(
56 - cryptoAmount: haven.formatterMoneroAmountToDouble(amount: transaction.amount),
58 + cryptoAmount: haven!.formatterMoneroAmountToDouble(amount: transaction.amount),
59 price: price);
60 break;
61 default:
lib/view_model/dashboard/wallet_balance.dart
+1 -1
@@ -1,5 +1,5 @@
1 class WalletBalance {
2 - WalletBalance({this.unlockedBalance, this.totalBalance});
2 + WalletBalance({required this.unlockedBalance, required this.totalBalance});
3
4 String unlockedBalance;
5 String totalBalance;
lib/view_model/edit_backup_password_view_model.dart
+4 -5
@@ -9,10 +9,9 @@ class EditBackupPasswordViewModel = EditBackupPasswordViewModelBase
9 with _$EditBackupPasswordViewModel;
10
11 abstract class EditBackupPasswordViewModelBase with Store {
12 - EditBackupPasswordViewModelBase(this.secureStorage, this.secretStore) {
13 - final key = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
14 - backupPassword = secretStore.read(key);
15 - }
12 + EditBackupPasswordViewModelBase(this.secureStorage, this.secretStore)
13 + : backupPassword = secretStore.read(generateStoreKeyFor(key: SecretStoreKey.backupPassword)),
14 + _originalPassword = '';
15
16 final FlutterSecureStorage secureStorage;
17 final SecretStore secretStore;
@@ -30,7 +29,7 @@ abstract class EditBackupPasswordViewModelBase with Store {
29 @action
30 Future<void> init() async {
31 final key = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
33 - final password = await secureStorage.read(key: key);
32 + final password = (await secureStorage.read(key: key))!;
33 _originalPassword = password;
34 backupPassword = password;
35 }
lib/view_model/exchange/exchange_trade_view_model.dart
+14 -18
@@ -23,12 +23,14 @@ class ExchangeTradeViewModel = ExchangeTradeViewModelBase
23
24 abstract class ExchangeTradeViewModelBase with Store {
25 ExchangeTradeViewModelBase(
26 - {this.wallet, this.trades, this.tradesStore, this.sendViewModel}) {
27 - trade = tradesStore.trade;
28 -
29 - isSendable = trade.from == wallet.currency ||
30 - trade.provider == ExchangeProviderDescription.xmrto;
31 -
26 + {required this.wallet,
27 + required this.trades,
28 + required this.tradesStore,
29 + required this.sendViewModel})
30 + : trade = tradesStore.trade!,
31 + isSendable = tradesStore.trade!.from == wallet.currency ||
32 + tradesStore.trade!.provider == ExchangeProviderDescription.xmrto,
33 + items = ObservableList<ExchangeTradeItem>() {
34 switch (trade.provider) {
35 case ExchangeProviderDescription.xmrto:
36 _provider = XMRTOExchangeProvider();
@@ -47,12 +49,8 @@ abstract class ExchangeTradeViewModelBase with Store {
49 break;
50 }
51
50 - items = ObservableList<ExchangeTradeItem>();
51 -
52 _updateItems();
53 -
53 _updateTrade();
55 -
54 timer = Timer.periodic(Duration(seconds: 20), (_) async => _updateTrade());
55 }
56
@@ -77,9 +75,9 @@ abstract class ExchangeTradeViewModelBase with Store {
75 @observable
76 ObservableList<ExchangeTradeItem> items;
77
80 - ExchangeProvider _provider;
78 + ExchangeProvider? _provider;
79
82 - Timer timer;
80 + Timer? timer;
81
82 @action
83 Future confirmSending() async {
@@ -89,8 +87,7 @@ abstract class ExchangeTradeViewModelBase with Store {
87
88 sendViewModel.clearOutputs();
89 final output = sendViewModel.outputs.first;
92 -
93 - output.address = trade.inputAddress;
90 + output.address = trade.inputAddress ?? '';
91 output.setCryptoAmount(trade.amount);
92 await sendViewModel.createTransaction();
93 }
@@ -98,7 +95,7 @@ abstract class ExchangeTradeViewModelBase with Store {
95 @action
96 Future<void> _updateTrade() async {
97 try {
101 - final updatedTrade = await _provider.findTradeById(id: trade.id);
98 + final updatedTrade = await _provider!.findTradeById(id: trade.id);
99
100 if (updatedTrade.createdAt == null && trade.createdAt != null) {
101 updatedTrade.createdAt = trade.createdAt;
@@ -113,8 +110,7 @@ abstract class ExchangeTradeViewModelBase with Store {
110 }
111
112 void _updateItems() {
116 - items?.clear();
117 -
113 + items.clear();
114 items.add(ExchangeTradeItem(
115 title: "${trade.provider.title} ${S.current.id}", data: '${trade.id}', isCopied: true));
116
@@ -136,7 +132,7 @@ abstract class ExchangeTradeViewModelBase with Store {
132 title: S.current.status, data: '${trade.state}', isCopied: false),
133 ExchangeTradeItem(
134 title: S.current.widgets_address + ':',
139 - data: trade.inputAddress,
135 + data: trade.inputAddress ?? '',
136 isCopied: true),
137 ]);
138 }
lib/view_model/exchange/exchange_view_model.dart
+53 -40
@@ -39,14 +39,32 @@ class ExchangeViewModel = ExchangeViewModelBase with _$ExchangeViewModel;
39
40 abstract class ExchangeViewModelBase with Store {
41 ExchangeViewModelBase(this.wallet, this.trades, this._exchangeTemplateStore,
42 - this.tradesStore, this._settingsStore, this.sharedPreferences) {
42 + this.tradesStore, this._settingsStore, this.sharedPreferences)
43 + : _cryptoNumberFormat = NumberFormat(),
44 + isReverse = false,
45 + isFixedRateMode = false,
46 + isReceiveAmountEntered = false,
47 + depositAmount = '',
48 + receiveAmount = '',
49 + receiveAddress = '',
50 + depositAddress = '',
51 + isDepositAddressEnabled = false,
52 + isReceiveAddressEnabled = false,
53 + isReceiveAmountEditable = false,
54 + receiveCurrencies = <CryptoCurrency>[],
55 + depositCurrencies = <CryptoCurrency>[],
56 + limits = Limits(min: 0, max: 0),
57 + tradeState = ExchangeTradeStateInitial(),
58 + limitsState = LimitsInitialState(),
59 + receiveCurrency = wallet.currency,
60 + depositCurrency = wallet.currency,
61 + providerList = [ChangeNowExchangeProvider(), SideShiftExchangeProvider(), SimpleSwapExchangeProvider()],
62 + selectedProviders = ObservableList<ExchangeProvider>(),
63 + currentTradeAvailableProviders = SplayTreeMap<double, ExchangeProvider>() {
64 const excludeDepositCurrencies = [CryptoCurrency.btt, CryptoCurrency.nano];
65 const excludeReceiveCurrencies = [CryptoCurrency.xlm, CryptoCurrency.xrp,
66 CryptoCurrency.bnb, CryptoCurrency.btt, CryptoCurrency.nano];
46 - providerList = [ChangeNowExchangeProvider(), SideShiftExchangeProvider(), SimpleSwapExchangeProvider()];
67 _initialPairBasedOnWallet();
48 - currentTradeAvailableProviders = SplayTreeMap<double, ExchangeProvider>();
49 -
68 final Map<String, dynamic> exchangeProvidersSelection = json
69 .decode(sharedPreferences.getString(PreferencesKey.exchangeProvidersSelection) ?? "{}") as Map<String, dynamic>;
70
@@ -65,12 +83,10 @@ abstract class ExchangeViewModelBase with Store {
83 receiveAddress = '';
84 depositAddress = depositCurrency == wallet.currency
85 ? wallet.walletAddresses.address : '';
68 - limitsState = LimitsInitialState();
69 - tradeState = ExchangeTradeStateInitial();
86 _cryptoNumberFormat = NumberFormat()..maximumFractionDigits = wallet.type == WalletType.bitcoin ? 8 : 12;
87 provider = providersForCurrentPair().first;
88 final initialProvider = provider;
73 - provider.checkIsAvailable().then((bool isAvailable) {
89 + provider!.checkIsAvailable().then((bool isAvailable) {
90 if (!isAvailable && provider == initialProvider) {
91 provider = providerList.firstWhere(
92 (provider) => provider is ChangeNowExchangeProvider,
@@ -84,9 +100,6 @@ abstract class ExchangeViewModelBase with Store {
100 depositCurrencies = CryptoCurrency.all
101 .where((cryptoCurrency) => !excludeDepositCurrencies.contains(cryptoCurrency))
102 .toList();
87 - isReverse = false;
88 - isFixedRateMode = false;
89 - isReceiveAmountEntered = false;
103 _defineIsReceiveAmountEditable();
104 loadLimits();
105 reaction(
@@ -101,7 +114,7 @@ abstract class ExchangeViewModelBase with Store {
114 final SharedPreferences sharedPreferences;
115
116 @observable
104 - ExchangeProvider provider;
117 + ExchangeProvider? provider;
118
119 /// Maps in dart are not sorted by default
120 /// SplayTreeMap is a map sorted by keys
@@ -179,7 +192,7 @@ abstract class ExchangeViewModelBase with Store {
192 final SettingsStore _settingsStore;
193
194 @action
182 - void changeDepositCurrency({CryptoCurrency currency}) {
195 + void changeDepositCurrency({required CryptoCurrency currency}) {
196 depositCurrency = currency;
197 isFixedRateMode = false;
198 _onPairChange();
@@ -188,7 +201,7 @@ abstract class ExchangeViewModelBase with Store {
201 }
202
203 @action
191 - void changeReceiveCurrency({CryptoCurrency currency}) {
204 + void changeReceiveCurrency({required CryptoCurrency currency}) {
205 receiveCurrency = currency;
206 isFixedRateMode = false;
207 _onPairChange();
@@ -197,7 +210,7 @@ abstract class ExchangeViewModelBase with Store {
210 }
211
212 @action
200 - void changeReceiveAmount({String amount}) {
213 + void changeReceiveAmount({required String amount}) {
214 receiveAmount = amount;
215 isReverse = true;
216
@@ -254,7 +267,7 @@ abstract class ExchangeViewModelBase with Store {
267 }
268
269 @action
257 - void changeDepositAmount({String amount}) {
270 + void changeDepositAmount({required String amount}) {
271 depositAmount = amount;
272 isReverse = false;
273
@@ -344,7 +357,7 @@ abstract class ExchangeViewModelBase with Store {
357
358 /// set the limits with the maximum provider limit
359 /// if there is a provider with null max then it's the maximum limit
347 - if ((tempLimits.max ?? double.maxFinite) > limits.max) {
360 + if ((tempLimits.max ?? double.maxFinite) > limits.max!) {
361 limits = tempLimits;
362 }
363 }
@@ -357,9 +370,9 @@ abstract class ExchangeViewModelBase with Store {
370 }
371
372 @action
360 - Future createTrade() async {
361 - TradeRequest request;
362 - String amount;
373 + Future<void> createTrade() async {
374 + TradeRequest? request;
375 + String amount = '';
376
377 for (var provider in currentTradeAvailableProviders.values) {
378 if (!(await provider.checkIsAvailable())) {
@@ -370,7 +383,7 @@ abstract class ExchangeViewModelBase with Store {
383 request = SideShiftRequest(
384 depositMethod: depositCurrency,
385 settleMethod: receiveCurrency,
373 - depositAmount: depositAmount?.replaceAll(',', '.'),
386 + depositAmount: depositAmount?.replaceAll(',', '.') ?? '',
387 settleAddress: receiveAddress,
388 refundAddress: depositAddress,
389 );
@@ -381,7 +394,7 @@ abstract class ExchangeViewModelBase with Store {
394 request = SimpleSwapRequest(
395 from: depositCurrency,
396 to: receiveCurrency,
384 - amount: depositAmount?.replaceAll(',', '.'),
397 + amount: depositAmount?.replaceAll(',', '.') ?? '',
398 address: receiveAddress,
399 refundAddress: depositAddress,
400 );
@@ -392,8 +405,8 @@ abstract class ExchangeViewModelBase with Store {
405 request = XMRTOTradeRequest(
406 from: depositCurrency,
407 to: receiveCurrency,
395 - amount: depositAmount?.replaceAll(',', '.'),
396 - receiveAmount: receiveAmount?.replaceAll(',', '.'),
408 + amount: depositAmount?.replaceAll(',', '.') ?? '',
409 + receiveAmount: receiveAmount?.replaceAll(',', '.') ?? '',
410 address: receiveAddress,
411 refundAddress: depositAddress,
412 isBTCRequest: isReceiveAmountEntered);
@@ -404,8 +417,8 @@ abstract class ExchangeViewModelBase with Store {
417 request = ChangeNowRequest(
418 from: depositCurrency,
419 to: receiveCurrency,
407 - fromAmount: depositAmount?.replaceAll(',', '.'),
408 - toAmount: receiveAmount?.replaceAll(',', '.'),
420 + fromAmount: depositAmount?.replaceAll(',', '.') ?? '',
421 + toAmount: receiveAmount?.replaceAll(',', '.') ?? '',
422 refundAddress: depositAddress,
423 address: receiveAddress,
424 isReverse: isReverse);
@@ -416,7 +429,7 @@ abstract class ExchangeViewModelBase with Store {
429 request = MorphTokenRequest(
430 from: depositCurrency,
431 to: receiveCurrency,
419 - amount: depositAmount?.replaceAll(',', '.'),
432 + amount: depositAmount?.replaceAll(',', '.') ?? '',
433 refundAddress: depositAddress,
434 address: receiveAddress);
435 amount = depositAmount;
@@ -425,15 +438,15 @@ abstract class ExchangeViewModelBase with Store {
438 amount = amount.replaceAll(',', '.');
439
440 if (limitsState is LimitsLoadedSuccessfully && amount != null) {
428 - if (double.parse(amount) < limits.min) {
441 + if (double.parse(amount) < limits.min!) {
442 continue;
430 - } else if (limits.max != null && double.parse(amount) > limits.max) {
443 + } else if (limits.max != null && double.parse(amount) > limits.max!) {
444 continue;
445 } else {
446 try {
447 tradeState = TradeIsCreating();
448 final trade = await provider.createTrade(
436 - request: request, isFixedRateMode: isFixedRateMode);
449 + request: request!, isFixedRateMode: isFixedRateMode);
450 trade.walletId = wallet.id;
451 tradesStore.setTrade(trade);
452 await trades.add(trade);
@@ -472,8 +485,8 @@ abstract class ExchangeViewModelBase with Store {
485 @action
486 void calculateDepositAllAmount() {
487 if (wallet.type == WalletType.bitcoin) {
475 - final availableBalance = wallet.balance[wallet.currency].available;
476 - final priority = _settingsStore.priority[wallet.type];
488 + final availableBalance = wallet.balance[wallet.currency]!.available;
489 + final priority = _settingsStore.priority[wallet.type]!;
490 final fee = wallet.calculateEstimatedFee(priority, null);
491
492 if (availableBalance < fee || availableBalance == 0) {
@@ -481,19 +494,19 @@ abstract class ExchangeViewModelBase with Store {
494 }
495
496 final amount = availableBalance - fee;
484 - changeDepositAmount(amount: bitcoin.formatterBitcoinAmountToString(amount: amount));
497 + changeDepositAmount(amount: bitcoin!.formatterBitcoinAmountToString(amount: amount));
498 }
499 }
500
501 void updateTemplate() => _exchangeTemplateStore.update();
502
503 void addTemplate(
491 - {String amount,
492 - String depositCurrency,
493 - String receiveCurrency,
494 - String provider,
495 - String depositAddress,
496 - String receiveAddress}) =>
504 + {required String amount,
505 + required String depositCurrency,
506 + required String receiveCurrency,
507 + required String provider,
508 + required String depositAddress,
509 + required String receiveAddress}) =>
510 _exchangeTemplateStore.addTemplate(
511 amount: amount,
512 depositCurrency: depositCurrency,
@@ -502,7 +515,7 @@ abstract class ExchangeViewModelBase with Store {
515 depositAddress: depositAddress,
516 receiveAddress: receiveAddress);
517
505 - void removeTemplate({ExchangeTemplate template}) =>
518 + void removeTemplate({required ExchangeTemplate template}) =>
519 _exchangeTemplateStore.remove(template: template);
520
521 List<ExchangeProvider> providersForCurrentPair() {
@@ -510,7 +523,7 @@ abstract class ExchangeViewModelBase with Store {
523 }
524
525 List<ExchangeProvider> _providersForPair(
513 - {CryptoCurrency from, CryptoCurrency to}) {
526 + {required CryptoCurrency from, required CryptoCurrency to}) {
527 final providers = providerList
528 .where((provider) => provider.pairList
529 .where((pair) =>
lib/view_model/ionia/ionia_account_view_model.dart
+4 -3
@@ -8,9 +8,10 @@ part 'ionia_account_view_model.g.dart';
8 class IoniaAccountViewModel = IoniaAccountViewModelBase with _$IoniaAccountViewModel;
9
10 abstract class IoniaAccountViewModelBase with Store {
11 - IoniaAccountViewModelBase({this.ioniaService}) {
12 - email = '';
13 - giftCards = [];
11 + IoniaAccountViewModelBase({required this.ioniaService})
12 + : email = '',
13 + giftCards = [],
14 + merchantState = InitialIoniaMerchantLoadingState() {
15 ioniaService.getUserEmail().then((email) => this.email = email);
16 updateUserGiftCards();
17 }
lib/view_model/ionia/ionia_auth_view_model.dart
+4 -2
@@ -8,10 +8,12 @@ class IoniaAuthViewModel = IoniaAuthViewModelBase with _$IoniaAuthViewModel;
8
9 abstract class IoniaAuthViewModelBase with Store {
10
11 - IoniaAuthViewModelBase({this.ioniaService}):
11 + IoniaAuthViewModelBase({required this.ioniaService}):
12 createUserState = IoniaInitialCreateState(),
13 signInState = IoniaInitialCreateState(),
14 - otpState = IoniaOtpSendDisabled();
14 + otpState = IoniaOtpSendDisabled(),
15 + email = '',
16 + otp = '';
17
18 final IoniaService ioniaService;
19
lib/view_model/ionia/ionia_buy_card_view_model.dart
+3 -4
@@ -6,10 +6,9 @@ part 'ionia_buy_card_view_model.g.dart';
6 class IoniaBuyCardViewModel = IoniaBuyCardViewModelBase with _$IoniaBuyCardViewModel;
7
8 abstract class IoniaBuyCardViewModelBase with Store {
9 - IoniaBuyCardViewModelBase({this.ioniaMerchant}) {
10 - isEnablePurchase = false;
11 - amount = 0;
12 - }
9 + IoniaBuyCardViewModelBase({required this.ioniaMerchant})
10 + : isEnablePurchase = false,
11 + amount = 0;
12
13 final IoniaMerchant ioniaMerchant;
14
lib/view_model/ionia/ionia_custom_redeem_view_model.dart
+2 -3
@@ -4,9 +4,8 @@ part 'ionia_custom_redeem_view_model.g.dart';
4 class IoniaCustomRedeemViewModel = IoniaCustomRedeemViewModelBase with _$IoniaCustomRedeemViewModel;
5
6 abstract class IoniaCustomRedeemViewModelBase with Store {
7 - IoniaCustomRedeemViewModelBase(this.giftCard){
8 - amount = 0;
9 - }
7 + IoniaCustomRedeemViewModelBase(this.giftCard)
8 + : amount = 0;
9
10 final IoniaGiftCard giftCard;
11
lib/view_model/ionia/ionia_custom_tip_view_model.dart
+7 -4
@@ -7,10 +7,13 @@ part 'ionia_custom_tip_view_model.g.dart';
7 class IoniaCustomTipViewModel = IoniaCustomTipViewModelBase with _$IoniaCustomTipViewModel;
8
9 abstract class IoniaCustomTipViewModelBase with Store {
10 - IoniaCustomTipViewModelBase({this.amount, this.tip, this.ioniaMerchant}){
11 - customTip = tip;
12 - percentage = 0;
13 - }
10 + IoniaCustomTipViewModelBase({
11 + required this.amount,
12 + required this.tip,
13 + required this.ioniaMerchant})
14 + : customTip = tip,
15 + percentage = 0;
16 +
17 final IoniaMerchant ioniaMerchant;
18 final double amount;
19 final IoniaTip tip;
lib/view_model/ionia/ionia_gift_card_details_view_model.dart
+7 -4
@@ -10,12 +10,15 @@ class IoniaGiftCardDetailsViewModel = IoniaGiftCardDetailsViewModelBase with _$
10
11 abstract class IoniaGiftCardDetailsViewModelBase with Store {
12
13 - IoniaGiftCardDetailsViewModelBase({this.ioniaService, this.giftCard}) {
14 - redeemState = InitialExecutionState();
15 - remainingAmount = giftCard.remainingAmount;
16 - }
13 + IoniaGiftCardDetailsViewModelBase({
14 + required this.ioniaService,
15 + required this.giftCard})
16 + : redeemState = InitialExecutionState(),
17 + remainingAmount = giftCard.remainingAmount,
18 + brightness = 0;
19
20 final IoniaService ioniaService;
21 +
22 double brightness;
23
24 @observable
lib/view_model/ionia/ionia_gift_cards_list_view_model.dart
+10 -9
@@ -2,8 +2,6 @@ import 'package:cake_wallet/ionia/ionia_category.dart';
2 import 'package:cake_wallet/ionia/ionia_service.dart';
3 import 'package:cake_wallet/ionia/ionia_create_state.dart';
4 import 'package:cake_wallet/ionia/ionia_merchant.dart';
5 -import 'package:cake_wallet/ionia/ionia_virtual_card.dart';
6 -import 'package:flutter/material.dart';
5 import 'package:mobx/mobx.dart';
6 part 'ionia_gift_cards_list_view_model.g.dart';
7
@@ -11,13 +9,18 @@ class IoniaGiftCardsListViewModel = IoniaGiftCardsListViewModelBase with _$Ionia
9
10 abstract class IoniaGiftCardsListViewModelBase with Store {
11 IoniaGiftCardsListViewModelBase({
14 - @required this.ioniaService,
12 + required this.ioniaService,
13 }) :
14 cardState = IoniaNoCardState(),
15 ioniaMerchants = [],
16 ioniaCategories = IoniaCategory.allCategories,
17 selectedIndices = ObservableList<IoniaCategory>.of([IoniaCategory.all]),
20 - scrollOffsetFromTop = 0.0 {
18 + scrollOffsetFromTop = 0.0,
19 + isLoggedIn = false,
20 + merchantState = InitialIoniaMerchantLoadingState(),
21 + createCardState = IoniaCreateCardState(),
22 + searchString = '',
23 + ioniaMerchantList = <IoniaMerchant>[] {
24 _getAuthStatus().then((value) => isLoggedIn = value);
25 }
26
@@ -56,16 +59,14 @@ abstract class IoniaGiftCardsListViewModelBase with Store {
59 }
60
61 @action
59 - Future<IoniaVirtualCard> createCard() async {
60 - createCardState = IoniaCreateCardLoading();
62 + Future<void> createCard() async {
63 try {
64 + createCardState = IoniaCreateCardLoading();
65 final card = await ioniaService.createCard();
66 createCardState = IoniaCreateCardSuccess();
64 - return card;
65 - } on Exception catch (e) {
67 + } catch (e) {
68 createCardState = IoniaCreateCardFailure(error: e.toString());
69 }
68 - return null;
70 }
71
72 @action
lib/view_model/ionia/ionia_payment_status_view_model.dart
+15 -14
@@ -12,17 +12,18 @@ class IoniaPaymentStatusViewModel = IoniaPaymentStatusViewModelBase with _$Ionia
12
13 abstract class IoniaPaymentStatusViewModelBase with Store {
14 IoniaPaymentStatusViewModelBase(
15 - this.ioniaService,{
16 - @required this.paymentInfo,
17 - @required this.committedInfo}) {
18 - _timer = Timer.periodic(updateTime, (timer) async {
19 - await updatePaymentStatus();
20 -
21 - if (giftCard != null) {
22 - timer?.cancel();
23 - }
24 - });
25 - }
15 + this.ioniaService, {
16 + required this.paymentInfo,
17 + required this.committedInfo})
18 + : error = '' {
19 + _timer = Timer.periodic(updateTime, (timer) async {
20 + await updatePaymentStatus();
21 +
22 + if (giftCard != null) {
23 + timer?.cancel();
24 + }
25 + });
26 + }
27
28 static const updateTime = Duration(seconds: 3);
29
@@ -31,14 +32,14 @@ abstract class IoniaPaymentStatusViewModelBase with Store {
32 final AnyPayPaymentCommittedInfo committedInfo;
33
34 @observable
34 - IoniaGiftCard giftCard;
35 + IoniaGiftCard? giftCard;
36
37 @observable
38 String error;
39
39 - Timer get timer => _timer;
40 + Timer? get timer => _timer;
41
41 - Timer _timer;
42 + Timer? _timer;
43
44 @action
45 Future<void> updatePaymentStatus() async {
lib/view_model/ionia/ionia_purchase_merch_view_model.dart
+24 -19
@@ -14,19 +14,20 @@ class IoniaMerchPurchaseViewModel = IoniaMerchPurchaseViewModelBase with _$Ionia
14
15 abstract class IoniaMerchPurchaseViewModelBase with Store {
16 IoniaMerchPurchaseViewModelBase({
17 - @required this.ioniaAnyPayService,
18 - @required this.amount,
19 - @required this.ioniaMerchant,
20 - }) {
21 - tipAmount = 0.0;
22 - percentage = 0.0;
23 - tips = <IoniaTip>[
24 - IoniaTip(percentage: 0, originalAmount: amount),
25 - IoniaTip(percentage: 15, originalAmount: amount),
26 - IoniaTip(percentage: 18, originalAmount: amount),
27 - IoniaTip(percentage: 20, originalAmount: amount),
28 - IoniaTip(percentage: 0, originalAmount: amount, isCustom: true),
29 - ];
17 + required this.ioniaAnyPayService,
18 + required this.amount,
19 + required this.ioniaMerchant,
20 + }) : tipAmount = 0.0,
21 + percentage = 0.0,
22 + invoiceCreationState = InitialExecutionState(),
23 + invoiceCommittingState = InitialExecutionState(),
24 + tips = <IoniaTip>[
25 + IoniaTip(percentage: 0, originalAmount: amount),
26 + IoniaTip(percentage: 15, originalAmount: amount),
27 + IoniaTip(percentage: 18, originalAmount: amount),
28 + IoniaTip(percentage: 20, originalAmount: amount),
29 + IoniaTip(percentage: 0, originalAmount: amount, isCustom: true),
30 + ] {
31 selectedTip = tips.first;
32 }
33
@@ -35,17 +36,17 @@ abstract class IoniaMerchPurchaseViewModelBase with Store {
36 List<IoniaTip> tips;
37
38 @observable
38 - IoniaTip selectedTip;
39 + IoniaTip? selectedTip;
40
41 final IoniaMerchant ioniaMerchant;
42
43 final IoniaAnyPay ioniaAnyPayService;
44
44 - IoniaAnyPayPaymentInfo paymentInfo;
45 + IoniaAnyPayPaymentInfo? paymentInfo;
46
46 - AnyPayPayment get invoice => paymentInfo?.anyPayPayment;
47 + AnyPayPayment? get invoice => paymentInfo?.anyPayPayment;
48
48 - AnyPayPaymentCommittedInfo committedInfo;
49 + AnyPayPaymentCommittedInfo? committedInfo;
50
51 @observable
52 ExecutionState invoiceCreationState;
@@ -85,9 +86,13 @@ abstract class IoniaMerchPurchaseViewModelBase with Store {
86 @action
87 Future<void> commitPaymentInvoice() async {
88 try {
89 + if (invoice == null) {
90 + throw Exception('Invoice is created. Invoince is null');
91 + }
92 +
93 invoiceCommittingState = IsExecutingState();
89 - committedInfo = await ioniaAnyPayService.commitInvoice(invoice);
90 - invoiceCommittingState = ExecutedSuccessfullyState(payload: committedInfo);
94 + committedInfo = await ioniaAnyPayService.commitInvoice(invoice!);
95 + invoiceCommittingState = ExecutedSuccessfullyState(payload: committedInfo!);
96 } catch (e) {
97 invoiceCommittingState = FailureState(e.toString());
98 }
lib/view_model/monero_account_list/account_list_item.dart
+1 -1
@@ -2,7 +2,7 @@ import 'package:flutter/foundation.dart';
2
3 class AccountListItem {
4 AccountListItem(
5 - {@required this.label, @required this.id, this.isSelected = false});
5 + {required this.label, required this.id, this.isSelected = false});
6
7 final String label;
8 final int id;
lib/view_model/monero_account_list/monero_account_edit_or_create_view_model.dart
+7 -7
@@ -14,7 +14,7 @@ class MoneroAccountEditOrCreateViewModel = MoneroAccountEditOrCreateViewModelBas
14
15 abstract class MoneroAccountEditOrCreateViewModelBase with Store {
16 MoneroAccountEditOrCreateViewModelBase(this._moneroAccountList, this._havenAccountList,
17 - {@required WalletBase wallet, AccountListItem accountListItem})
17 + {required WalletBase wallet, AccountListItem? accountListItem})
18 : state = InitialExecutionState(),
19 isEdit = accountListItem != null,
20 label = accountListItem?.label??'',
@@ -30,8 +30,8 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
30 String label;
31
32 final MoneroAccountList _moneroAccountList;
33 - final HavenAccountList _havenAccountList;
34 - final AccountListItem _accountListItem;
33 + final HavenAccountList? _havenAccountList;
34 + final AccountListItem? _accountListItem;
35 final WalletBase _wallet;
36
37 Future<void> save() async {
@@ -51,7 +51,7 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
51 if (_accountListItem != null) {
52 await _moneroAccountList.setLabelAccount(
53 _wallet,
54 - accountIndex: _accountListItem.id,
54 + accountIndex: _accountListItem!.id,
55 label: label);
56 } else {
57 await _moneroAccountList.addAccount(
@@ -75,12 +75,12 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
75 state = IsExecutingState();
76
77 if (_accountListItem != null) {
78 - await _havenAccountList.setLabelAccount(
78 + await _havenAccountList!.setLabelAccount(
79 _wallet,
80 - accountIndex: _accountListItem.id,
80 + accountIndex: _accountListItem!.id,
81 label: label);
82 } else {
83 - await _havenAccountList.addAccount(
83 + await _havenAccountList!.addAccount(
84 _wallet,
85 label: label);
86 }
lib/view_model/monero_account_list/monero_account_list_view_model.dart
+8 -6
@@ -25,37 +25,39 @@ abstract class MoneroAccountListViewModelBase with Store {
25 List<AccountListItem> get accounts {
26 if (_wallet.type == WalletType.haven) {
27 return haven
28 - .getAccountList(_wallet)
28 + !.getAccountList(_wallet)
29 .accounts.map((acc) => AccountListItem(
30 label: acc.label,
31 id: acc.id,
32 - isSelected: acc.id == haven.getCurrentAccount(_wallet).id))
32 + isSelected: acc.id == haven!.getCurrentAccount(_wallet).id))
33 .toList();
34 }
35
36 if (_wallet.type == WalletType.monero) {
37 return monero
38 - .getAccountList(_wallet)
38 + !.getAccountList(_wallet)
39 .accounts.map((acc) => AccountListItem(
40 label: acc.label,
41 id: acc.id,
42 - isSelected: acc.id == monero.getCurrentAccount(_wallet).id))
42 + isSelected: acc.id == monero!.getCurrentAccount(_wallet).id))
43 .toList();
44 }
45 +
46 + throw Exception('Unexpected wallet type: ${_wallet.type}');
47 }
48
49 final WalletBase _wallet;
50
51 void select(AccountListItem item) {
52 if (_wallet.type == WalletType.monero) {
51 - monero.setCurrentAccount(
53 + monero!.setCurrentAccount(
54 _wallet,
55 item.id,
56 item.label);
57 }
58
59 if (_wallet.type == WalletType.haven) {
58 - haven.setCurrentAccount(
60 + haven!.setCurrentAccount(
61 _wallet,
62 item.id,
63 item.label);
lib/view_model/node_list/node_create_or_edit_view_model.dart
+7 -3
@@ -14,7 +14,11 @@ abstract class NodeCreateOrEditViewModelBase with Store {
14 NodeCreateOrEditViewModelBase(this._nodeSource, this._wallet)
15 : state = InitialExecutionState(),
16 connectionState = InitialExecutionState(),
17 - useSSL = false;
17 + useSSL = false,
18 + address = '',
19 + port = '',
20 + login = '',
21 + password = '';
22
23 @observable
24 ExecutionState state;
@@ -39,7 +43,7 @@ abstract class NodeCreateOrEditViewModelBase with Store {
43
44 @computed
45 bool get isReady =>
42 - (address?.isNotEmpty ?? false) && (port?.isNotEmpty ?? false);
46 + address.isNotEmpty && port.isNotEmpty;
47
48 bool get hasAuthCredentials => _wallet.type == WalletType.monero ||
49 _wallet.type == WalletType.haven;
@@ -47,7 +51,7 @@ abstract class NodeCreateOrEditViewModelBase with Store {
51 String get uri {
52 var uri = address;
53
50 - if (port != null && port.isNotEmpty) {
54 + if (port.isNotEmpty) {
55 uri += ':' + port;
56 }
57
lib/view_model/node_list/node_list_view_model.dart
+12 -4
@@ -20,7 +20,15 @@ abstract class NodeListViewModelBase with Store {
20 }
21
22 @computed
23 - Node get currentNode => settingsStore.nodes[wallet.type];
23 + Node get currentNode {
24 + final node = settingsStore.nodes[wallet.type];
25 +
26 + if (node == null) {
27 + throw Exception('No node for wallet type: ${wallet.type}');
28 + }
29 +
30 + return node;
31 + }
32
33 final ObservableList<Node> nodes;
34 final SettingsStore settingsStore;
@@ -34,16 +42,16 @@ abstract class NodeListViewModelBase with Store {
42
43 switch (wallet.type) {
44 case WalletType.bitcoin:
37 - node = getBitcoinDefaultElectrumServer(nodes: _nodeSource);
45 + node = getBitcoinDefaultElectrumServer(nodes: _nodeSource)!;
46 break;
47 case WalletType.monero:
48 node = getMoneroDefaultNode(nodes: _nodeSource);
49 break;
50 case WalletType.litecoin:
43 - node = getLitecoinDefaultElectrumServer(nodes: _nodeSource);
51 + node = getLitecoinDefaultElectrumServer(nodes: _nodeSource)!;
52 break;
53 default:
46 - break;
54 + throw Exception('Unexpected wallet type: ${wallet.type}');
55 }
56
57 await setAsCurrent(node);
lib/view_model/order_details_view_model.dart
+9 -15
@@ -18,9 +18,9 @@ class OrderDetailsViewModel = OrderDetailsViewModelBase
18 with _$OrderDetailsViewModel;
19
20 abstract class OrderDetailsViewModelBase with Store {
21 - OrderDetailsViewModelBase({WalletBase wallet, Order orderForDetails}) {
22 - order = orderForDetails;
23 -
21 + OrderDetailsViewModelBase({required WalletBase wallet, required Order orderForDetails})
22 + : items = ObservableList<StandartListItem>(),
23 + order = orderForDetails {
24 if (order.provider != null) {
25 switch (order.provider) {
26 case BuyProviderDescription.wyre:
@@ -32,12 +32,8 @@ abstract class OrderDetailsViewModelBase with Store {
32 }
33 }
34
35 - items = ObservableList<StandartListItem>();
36 -
35 _updateItems();
38 -
36 _updateOrder();
40 -
37 timer = Timer.periodic(Duration(seconds: 20), (_) async => _updateOrder());
38 }
39
@@ -47,15 +43,15 @@ abstract class OrderDetailsViewModelBase with Store {
43 @observable
44 ObservableList<StandartListItem> items;
45
50 - BuyProvider _provider;
46 + BuyProvider? _provider;
47
52 - Timer timer;
48 + Timer? timer;
49
50 @action
51 Future<void> _updateOrder() async {
52 try {
53 if (_provider != null) {
58 - final updatedOrder = await _provider.findOrderById(order.id);
54 + final updatedOrder = await _provider!.findOrderById(order.id);
55 updatedOrder.from = order.from;
56 updatedOrder.to = order.to;
57 updatedOrder.receiveAddress = order.receiveAddress;
@@ -73,9 +69,7 @@ abstract class OrderDetailsViewModelBase with Store {
69
70 void _updateItems() {
71 final dateFormat = DateFormatter.withCurrentLocal();
76 -
77 - items?.clear();
78 -
72 + items.clear();
73 items.addAll([
74 StandartListItem(
75 title: 'Transfer ID',
@@ -95,8 +89,8 @@ abstract class OrderDetailsViewModelBase with Store {
89 );
90 }
91
98 - if (_provider?.trackUrl?.isNotEmpty ?? false) {
99 - final buildURL = _provider.trackUrl + '${order.transferId}';
92 + if (_provider!.trackUrl?.isNotEmpty ?? false) {
93 + final buildURL = _provider!.trackUrl + '${order.transferId}';
94 items.add(
95 TrackTradeListItem(
96 title: 'Track',
lib/view_model/rescan_view_model.dart
+6 -6
@@ -8,20 +8,20 @@ class RescanViewModel = RescanViewModelBase with _$RescanViewModel;
8 enum RescanWalletState { rescaning, none }
9
10 abstract class RescanViewModelBase with Store {
11 - RescanViewModelBase(this._wallet) {
12 - state = RescanWalletState.none;
13 - isButtonEnabled = false;
14 - }
11 + RescanViewModelBase(this._wallet)
12 + : state = RescanWalletState.none,
13 + isButtonEnabled = false;
14 +
15 + final WalletBase _wallet;
16
17 @observable
18 RescanWalletState state;
18 - final WalletBase _wallet;
19
20 @observable
21 bool isButtonEnabled;
22
23 @action
24 - Future<void> rescanCurrentWallet({int restoreHeight}) async {
24 + Future<void> rescanCurrentWallet({required int restoreHeight}) async {
25 state = RescanWalletState.rescaning;
26 await _wallet.rescan(height: restoreHeight);
27 state = RescanWalletState.none;
lib/view_model/restore_from_backup_view_model.dart
+9 -6
@@ -15,7 +15,11 @@ class RestoreFromBackupViewModel = RestoreFromBackupViewModelBase
15 with _$RestoreFromBackupViewModel;
16
17 abstract class RestoreFromBackupViewModelBase with Store {
18 - RestoreFromBackupViewModelBase(this.backupService);
18 + RestoreFromBackupViewModelBase(this.backupService)
19 + : state = InitialExecutionState(),
20 + filePath = '';
21 +
22 + final BackupService backupService;
23
24 @observable
25 String filePath;
@@ -23,8 +27,6 @@ abstract class RestoreFromBackupViewModelBase with Store {
27 @observable
28 ExecutionState state;
29
26 - final BackupService backupService;
27 -
30 @action
31 void reset() => filePath = '';
32
@@ -45,15 +47,16 @@ abstract class RestoreFromBackupViewModelBase with Store {
47 await main();
48
49 final store = getIt.get<AppStore>();
48 - ReactionDisposer reaction;
49 - await store.settingsStore.reload(nodeSource: getIt.get<Box<Node>>());
50 + ReactionDisposer? reaction;
51 + // FIX-ME: SettingsStore reload
52 + // await store.settingsStore.reload(nodeSource: getIt.get<Box<Node>>());
53
54 reaction = autorun((_) {
55 final wallet = store.wallet;
56
57 if (wallet != null) {
58 store.authenticationStore.state = AuthenticationState.allowed;
56 - reaction?.reaction?.dispose();
59 + reaction?.reaction.dispose();
60 }
61 });
62
lib/view_model/send/output.dart
+20 -14
@@ -25,10 +25,16 @@ class Output = OutputBase with _$Output;
25
26 abstract class OutputBase with Store {
27 OutputBase(this._wallet, this._settingsStore, this._fiatConversationStore, this.cryptoCurrencyHandler)
28 - : _cryptoNumberFormat = NumberFormat(cryptoNumberPattern) {
29 - reset();
28 + : _cryptoNumberFormat = NumberFormat(cryptoNumberPattern),
29 + key = UniqueKey(),
30 + sendAll = false,
31 + cryptoAmount = '',
32 + fiatAmount = '',
33 + address = '',
34 + note = '',
35 + extractedAddress = '',
36 + parsedAddress = ParsedAddress(addresses: []) {
37 _setCryptoNumMaximumFractionDigits();
31 - key = UniqueKey();
38 }
39
40 Key key;
@@ -69,18 +75,18 @@ abstract class OutputBase with Store {
75 int _amount = 0;
76 switch (walletType) {
77 case WalletType.monero:
72 - _amount = monero.formatterMoneroParseAmount(amount: _cryptoAmount);
78 + _amount = monero!.formatterMoneroParseAmount(amount: _cryptoAmount);
79 break;
80 case WalletType.bitcoin:
81 _amount =
76 - bitcoin.formatterStringDoubleToBitcoinAmount(_cryptoAmount);
82 + bitcoin!.formatterStringDoubleToBitcoinAmount(_cryptoAmount);
83 break;
84 case WalletType.litecoin:
85 _amount =
80 - bitcoin.formatterStringDoubleToBitcoinAmount(_cryptoAmount);
86 + bitcoin!.formatterStringDoubleToBitcoinAmount(_cryptoAmount);
87 break;
88 case WalletType.haven:
83 - _amount = haven.formatterMoneroParseAmount(amount: _cryptoAmount);
89 + _amount = haven!.formatterMoneroParseAmount(amount: _cryptoAmount);
90 break;
91 default:
92 break;
@@ -101,19 +107,19 @@ abstract class OutputBase with Store {
107 double get estimatedFee {
108 try {
109 final fee = _wallet.calculateEstimatedFee(
104 - _settingsStore.priority[_wallet.type], formattedCryptoAmount);
110 + _settingsStore.priority[_wallet.type]!, formattedCryptoAmount);
111
112 if (_wallet.type == WalletType.bitcoin ||
113 _wallet.type == WalletType.litecoin) {
108 - return bitcoin.formatterBitcoinAmountToDouble(amount: fee);
114 + return bitcoin!.formatterBitcoinAmountToDouble(amount: fee);
115 }
116
117 if (_wallet.type == WalletType.monero) {
112 - return monero.formatterMoneroAmountToDouble(amount: fee);
118 + return monero!.formatterMoneroAmountToDouble(amount: fee);
119 }
120
121 if (_wallet.type == WalletType.haven) {
116 - return haven.formatterMoneroAmountToDouble(amount: fee);
122 + return haven!.formatterMoneroAmountToDouble(amount: fee);
123 }
124 } catch (e) {
125 print(e.toString());
@@ -126,7 +132,7 @@ abstract class OutputBase with Store {
132 String get estimatedFeeFiatAmount {
133 try {
134 final fiat = calculateFiatAmountRaw(
129 - price: _fiatConversationStore.prices[cryptoCurrencyHandler()],
135 + price: _fiatConversationStore.prices[cryptoCurrencyHandler()]!,
136 cryptoAmount: estimatedFee);
137 return fiat;
138 } catch (_) {
@@ -179,7 +185,7 @@ abstract class OutputBase with Store {
185 void _updateFiatAmount() {
186 try {
187 final fiat = calculateFiatAmount(
182 - price: _fiatConversationStore.prices[cryptoCurrencyHandler()],
188 + price: _fiatConversationStore.prices[cryptoCurrencyHandler()]!,
189 cryptoAmount: cryptoAmount.replaceAll(',', '.'));
190 if (fiatAmount != fiat) {
191 fiatAmount = fiat;
@@ -193,7 +199,7 @@ abstract class OutputBase with Store {
199 void _updateCryptoAmount() {
200 try {
201 final crypto = double.parse(fiatAmount.replaceAll(',', '.')) /
196 - _fiatConversationStore.prices[cryptoCurrencyHandler()];
202 + _fiatConversationStore.prices[cryptoCurrencyHandler()]!;
203 final cryptoAmountTmp = _cryptoNumberFormat.format(crypto);
204
205 if (cryptoAmount != cryptoAmountTmp) {
lib/view_model/send/send_template_view_model.dart
+10 -10
@@ -19,8 +19,8 @@ class SendTemplateViewModel = SendTemplateViewModelBase
19
20 abstract class SendTemplateViewModelBase with Store {
21 SendTemplateViewModelBase(this._wallet, this._settingsStore,
22 - this._sendTemplateStore, this._fiatConversationStore) {
23 -
22 + this._sendTemplateStore, this._fiatConversationStore)
23 + : output = Output(_wallet, _settingsStore, _fiatConversationStore, () => _wallet.currency) {
24 output = Output(_wallet, _settingsStore, _fiatConversationStore, () => currency);
25 }
26
@@ -65,13 +65,13 @@ abstract class SendTemplateViewModelBase with Store {
65 void updateTemplate() => _sendTemplateStore.update();
66
67 void addTemplate(
68 - {String name,
69 - bool isCurrencySelected,
70 - String address,
71 - String cryptoCurrency,
72 - String fiatCurrency,
73 - String amount,
74 - String amountFiat}) {
68 + {required String name,
69 + required bool isCurrencySelected,
70 + required String address,
71 + required String cryptoCurrency,
72 + required String fiatCurrency,
73 + required String amount,
74 + required String amountFiat}) {
75 _sendTemplateStore.addTemplate(
76 name: name,
77 isCurrencySelected: isCurrencySelected,
@@ -83,7 +83,7 @@ abstract class SendTemplateViewModelBase with Store {
83 updateTemplate();
84 }
85
86 - void removeTemplate({Template template}) {
86 + void removeTemplate({required Template template}) {
87 _sendTemplateStore.remove(template: template);
88 updateTemplate();
89 }
lib/view_model/send/send_view_model.dart
+53 -24
@@ -39,18 +39,18 @@ abstract class SendViewModelBase with Store {
39 this._fiatConversationStore,
40 this.balanceViewModel,
41 this.transactionDescriptionBox)
42 - : state = InitialExecutionState() {
42 + : state = InitialExecutionState(),
43 + currencies = _wallet.balance.keys.toList(),
44 + selectedCryptoCurrency = _wallet.currency,
45 + outputs = ObservableList<Output>() {
46 final priority = _settingsStore.priority[_wallet.type];
47 final priorities = priorityForWalletType(_wallet.type);
45 - selectedCryptoCurrency = _wallet.currency;
46 - currencies = _wallet.balance.keys.toList();
48
49 if (!priorityForWalletType(_wallet.type).contains(priority)) {
50 _settingsStore.priority[_wallet.type] = priorities.first;
51 }
51 -
52 - outputs = ObservableList<Output>()
53 - ..add(Output(_wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency));
52 +
53 + outputs.add(Output(_wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency));
54 }
55
56 @observable
@@ -84,8 +84,8 @@ abstract class SendViewModelBase with Store {
84 try {
85 if (pendingTransaction != null) {
86 final fiat = calculateFiatAmount(
87 - price: _fiatConversationStore.prices[selectedCryptoCurrency],
88 - cryptoAmount: pendingTransaction.amountFormatted);
87 + price: _fiatConversationStore.prices[selectedCryptoCurrency]!,
88 + cryptoAmount: pendingTransaction!.amountFormatted);
89 return fiat;
90 } else {
91 return '0.00';
@@ -100,8 +100,8 @@ abstract class SendViewModelBase with Store {
100 try {
101 if (pendingTransaction != null) {
102 final fiat = calculateFiatAmount(
103 - price: _fiatConversationStore.prices[selectedCryptoCurrency],
104 - cryptoAmount: pendingTransaction.feeFormatted);
103 + price: _fiatConversationStore.prices[selectedCryptoCurrency]!,
104 + cryptoAmount: pendingTransaction!.feeFormatted);
105 return fiat;
106 } else {
107 return '0.00';
@@ -113,8 +113,15 @@ abstract class SendViewModelBase with Store {
113
114 FiatCurrency get fiat => _settingsStore.fiatCurrency;
115
116 - TransactionPriority get transactionPriority =>
117 - _settingsStore.priority[_wallet.type];
116 + TransactionPriority get transactionPriority {
117 + final priority = _settingsStore.priority[_wallet.type];
118 +
119 + if (priority == null) {
120 + throw Exception('Unexpected type ${_wallet.type}');
121 + }
122 +
123 + return priority;
124 + }
125
126 CryptoCurrency get currency => _wallet.currency;
127
@@ -127,7 +134,7 @@ abstract class SendViewModelBase with Store {
134 Validator get textValidator => TextValidator();
135
136 @observable
130 - PendingTransaction pendingTransaction;
137 + PendingTransaction? pendingTransaction;
138
139 @computed
140 String get balance => balanceViewModel.availableBalance ?? '0.0';
@@ -179,6 +186,10 @@ abstract class SendViewModelBase with Store {
186
187 @action
188 Future<void> commitTransaction() async {
189 + if (pendingTransaction == null) {
190 + throw Exception("Pending transaction doesn't exist. It should not be happened.");
191 + }
192 +
193 String address = outputs.fold('', (acc, value) {
194 return value.isParsedAddress
195 ? acc + value.address + '\n' + value.extractedAddress + '\n\n'
@@ -195,16 +206,16 @@ abstract class SendViewModelBase with Store {
206
207 try {
208 state = TransactionCommitting();
198 - await pendingTransaction.commit();
209 + await pendingTransaction!.commit();
210
200 - if (pendingTransaction.id?.isNotEmpty ?? false) {
211 + if (pendingTransaction!.id?.isNotEmpty ?? false) {
212 _settingsStore.shouldSaveRecipientAddress
213 ? await transactionDescriptionBox.add(TransactionDescription(
203 - id: pendingTransaction.id,
214 + id: pendingTransaction!.id,
215 recipientAddress: address,
216 transactionNote: note))
217 : await transactionDescriptionBox.add(TransactionDescription(
207 - id: pendingTransaction.id, transactionNote: note));
218 + id: pendingTransaction!.id, transactionNote: note));
219 }
220
221 state = TransactionCommitted();
@@ -222,23 +233,39 @@ abstract class SendViewModelBase with Store {
233 case WalletType.bitcoin:
234 final priority = _settingsStore.priority[_wallet.type];
235
225 - return bitcoin.createBitcoinTransactionCredentials(outputs, priority: priority);
236 + if (priority == null) {
237 + throw Exception('Priority is null for wallet type: ${_wallet.type}');
238 + }
239 +
240 + return bitcoin!.createBitcoinTransactionCredentials(outputs, priority: priority);
241 case WalletType.litecoin:
242 final priority = _settingsStore.priority[_wallet.type];
243
229 - return bitcoin.createBitcoinTransactionCredentials(outputs, priority: priority);
244 + if (priority == null) {
245 + throw Exception('Priority is null for wallet type: ${_wallet.type}');
246 + }
247 +
248 + return bitcoin!.createBitcoinTransactionCredentials(outputs, priority: priority);
249 case WalletType.monero:
250 final priority = _settingsStore.priority[_wallet.type];
251
233 - return monero.createMoneroTransactionCreationCredentials(
252 + if (priority == null) {
253 + throw Exception('Priority is null for wallet type: ${_wallet.type}');
254 + }
255 +
256 + return monero!.createMoneroTransactionCreationCredentials(
257 outputs: outputs, priority: priority);
258 case WalletType.haven:
259 final priority = _settingsStore.priority[_wallet.type];
260
238 - return haven.createHavenTransactionCreationCredentials(
261 + if (priority == null) {
262 + throw Exception('Priority is null for wallet type: ${_wallet.type}');
263 + }
264 +
265 + return haven!.createHavenTransactionCreationCredentials(
266 outputs: outputs, priority: priority, assetType: selectedCryptoCurrency.title);
267 default:
241 - return null;
268 + throw Exception('Unexpected wallet type: ${_wallet.type}');
269 }
270 }
271
@@ -247,8 +274,10 @@ abstract class SendViewModelBase with Store {
274 final wallet = _wallet;
275
276 if (isElectrumWallet) {
250 - final rate = bitcoin.getFeeRate(wallet, _priority);
251 - return '${priority.labelWithRate(rate)}';
277 + final rate = bitcoin!.getFeeRate(wallet, _priority);
278 + // FIX-ME: labelWithRate
279 + // return '${priority.labelWithRate(rate)}';
280 + return '';
281 }
282
283 return priority.toString();
lib/view_model/settings/choices_list_item.dart
+6 -6
@@ -4,18 +4,18 @@ import 'package:flutter/material.dart';
4
5 class ChoicesListItem<ItemType> extends SettingsListItem {
6 ChoicesListItem(
7 - {@required String title,
8 - @required this.selectedItem,
9 - @required this.items,
7 + {required String title,
8 + required this.selectedItem,
9 + required this.items,
10 this.displayItem,
11 - void Function(ItemType item) onItemSelected})
11 + void Function(ItemType item)? onItemSelected})
12 : _onItemSelected = onItemSelected,
13 super(title);
14
15 final ItemType selectedItem;
16 final List<ItemType> items;
17 - final String Function(ItemType item) displayItem;
18 - final void Function(ItemType item) _onItemSelected;
17 + final String Function(ItemType item)? displayItem;
18 + final void Function(ItemType item)? _onItemSelected;
19
20 void onItemSelected(dynamic item) {
21 if (item is ItemType) {
lib/view_model/settings/link_list_item.dart
+4 -4
@@ -4,14 +4,14 @@ import 'package:flutter/material.dart';
4
5 class LinkListItem extends SettingsListItem {
6 LinkListItem(
7 - {@required String title,
8 - @required this.link,
9 - @required this.linkTitle,
7 + {required String title,
8 + required this.link,
9 + required this.linkTitle,
10 this.icon,
11 this.hasIconColor = false})
12 : super(title);
13
14 - final String icon;
14 + final String? icon;
15 final String link;
16 final String linkTitle;
17 final bool hasIconColor;
lib/view_model/settings/picker_list_item.dart
+12 -12
@@ -2,29 +2,29 @@ import 'package:flutter/foundation.dart';
2 import 'package:cake_wallet/view_model/settings/settings_list_item.dart';
3 import 'package:flutter/material.dart';
4
5 -class PickerListItem<ItemType> extends SettingsListItem {
5 +class PickerListItem<ItemType extends Object> extends SettingsListItem {
6 PickerListItem(
7 - {@required String title,
8 - @required this.selectedItem,
9 - @required this.items,
7 + {required String title,
8 + required this.selectedItem,
9 + required this.items,
10 this.displayItem,
11 this.images,
12 this.searchHintText,
13 this.isGridView = false,
14 - void Function(ItemType item) onItemSelected,
15 - bool Function(ItemType item, String searchText) matchingCriteria})
14 + void Function(ItemType item)? onItemSelected,
15 + bool Function(ItemType item, String searchText)? matchingCriteria})
16 : _onItemSelected = onItemSelected,
17 _matchingCriteria = matchingCriteria,
18 super(title);
19
20 final ItemType Function() selectedItem;
21 final List<ItemType> items;
22 - final String Function(ItemType item) displayItem;
23 - final void Function(ItemType item) _onItemSelected;
24 - final List<Image> images;
25 - final String searchHintText;
22 + final String Function(ItemType item)? displayItem;
23 + final void Function(ItemType item)? _onItemSelected;
24 + final List<Image>? images;
25 + final String? searchHintText;
26 final bool isGridView;
27 - final bool Function(ItemType, String) _matchingCriteria;
27 + final bool Function(ItemType, String)? _matchingCriteria;
28
29 void onItemSelected(dynamic item) {
30 if (item is ItemType) {
@@ -34,7 +34,7 @@ class PickerListItem<ItemType> extends SettingsListItem {
34
35 bool matchingCriteria(dynamic item, String searchText) {
36 if (item is ItemType) {
37 - return _matchingCriteria?.call(item, searchText);
37 + return _matchingCriteria?.call(item, searchText) ?? false;
38 }
39 return true;
40 }
lib/view_model/settings/regular_list_item.dart
+2 -2
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
2 import 'package:cake_wallet/view_model/settings/settings_list_item.dart';
3
4 class RegularListItem extends SettingsListItem {
5 - RegularListItem({@required String title, this.handler}) : super(title);
5 + RegularListItem({required String title, this.handler}) : super(title);
6
7 - final void Function(BuildContext context) handler;
7 + final void Function(BuildContext context)? handler;
8 }
\ No newline at end of file
lib/view_model/settings/settings_view_model.dart
+22 -12
@@ -39,13 +39,13 @@ class SettingsViewModel = SettingsViewModelBase with _$SettingsViewModel;
39 List<TransactionPriority> priorityForWalletType(WalletType type) {
40 switch (type) {
41 case WalletType.monero:
42 - return monero.getTransactionPriorities();
42 + return monero!.getTransactionPriorities();
43 case WalletType.bitcoin:
44 - return bitcoin.getTransactionPriorities();
44 + return bitcoin!.getTransactionPriorities();
45 case WalletType.litecoin:
46 - return bitcoin.getLitecoinTransactionPriorities();
46 + return bitcoin!.getLitecoinTransactionPriorities();
47 case WalletType.haven:
48 - return haven.getTransactionPriorities();
48 + return haven!.getTransactionPriorities();
49 default:
50 return [];
51 }
@@ -60,8 +60,9 @@ abstract class SettingsViewModelBase with Store {
60 wallet)
61 : itemHeaders = {},
62 _walletType = wallet.type,
63 - _biometricAuth = BiometricAuth() {
64 - currentVersion = '';
63 + _biometricAuth = BiometricAuth(),
64 + sections = <List<SettingsListItem>>[],
65 + currentVersion = '' {
66 PackageInfo.fromPlatform().then(
67 (PackageInfo packageInfo) => currentVersion = packageInfo.version);
68
@@ -134,8 +135,10 @@ abstract class SettingsViewModelBase with Store {
135
136 if (wallet.type == WalletType.bitcoin
137 || wallet.type == WalletType.litecoin) {
137 - final rate = bitcoin.getFeeRate(wallet, _priority);
138 - return '${priority.labelWithRate(rate)}';
138 + final rate = bitcoin!.getFeeRate(wallet, _priority);
139 + // FIX-ME: BitcoinTransactionPriority
140 + // return '${priority.labelWithRate(rate)}';
141 + return '';
142 }
143
144 return priority.toString();
@@ -169,7 +172,7 @@ abstract class SettingsViewModelBase with Store {
172 searchHintText: S.current.search_language,
173 items: LanguageService.list.keys.toList(),
174 displayItem: (dynamic code) {
172 - return LanguageService.list[code];
175 + return LanguageService.list[code] ?? '';
176 },
177 selectedItem: () => _settingsStore.languageCode,
178 onItemSelected: (String code) {
@@ -179,7 +182,7 @@ abstract class SettingsViewModelBase with Store {
182 (e) => Image.asset("assets/images/flags/${LanguageService.localeCountryCode[e]}.png"))
183 .toList(),
184 matchingCriteria: (String code, String searchText) {
182 - return LanguageService.list[code].toLowerCase().contains(searchText);
185 + return LanguageService.list[code]?.toLowerCase().contains(searchText) ?? false;
186 },
187 ),
188 SwitcherListItem(
@@ -256,8 +259,15 @@ abstract class SettingsViewModelBase with Store {
259 _settingsStore.actionlistDisplayMode;
260
261 @computed
259 - TransactionPriority get transactionPriority =>
260 - _settingsStore.priority[_walletType];
262 + TransactionPriority get transactionPriority {
263 + final priority = _settingsStore.priority[_walletType];
264 +
265 + if (priority == null) {
266 + throw Exception('Unexpected type ${_walletType.toString()}');
267 + }
268 +
269 + return priority;
270 + }
271
272 @computed
273 BalanceDisplayMode get balanceDisplayMode =>
lib/view_model/settings/switcher_list_item.dart
+3 -3
@@ -4,9 +4,9 @@ import 'package:cake_wallet/view_model/settings/settings_list_item.dart';
4
5 class SwitcherListItem extends SettingsListItem {
6 SwitcherListItem(
7 - {@required String title,
8 - @required this.value,
9 - @required this.onValueChange})
7 + {required String title,
8 + required this.value,
9 + required this.onValueChange})
10 : super(title);
11
12 final bool Function() value;
lib/view_model/settings/version_list_item.dart
+1 -1
@@ -2,5 +2,5 @@ import 'package:flutter/foundation.dart';
2 import 'package:cake_wallet/view_model/settings/settings_list_item.dart';
3
4 class VersionListItem extends SettingsListItem {
5 - VersionListItem({@required String title}) : super(title);
5 + VersionListItem({required String title}) : super(title);
6 }
\ No newline at end of file
lib/view_model/support_view_model.dart
+17 -17
@@ -14,8 +14,8 @@ part 'support_view_model.g.dart';
14 class SupportViewModel = SupportViewModelBase with _$SupportViewModel;
15
16 abstract class SupportViewModelBase with Store {
17 - SupportViewModelBase() {
18 - items = [
17 + SupportViewModelBase()
18 + : items = [
19 RegularListItem(
20 title: S.current.faq,
21 handler: (BuildContext context) async {
@@ -53,27 +53,27 @@ abstract class SupportViewModelBase with Store {
53 icon: 'assets/images/change_now.png',
54 linkTitle: 'support@changenow.io',
55 link: 'mailto:support@changenow.io'),
56 - if (!isMoneroOnly) ... [
57 - LinkListItem(
58 - title: 'Wyre',
59 - icon: 'assets/images/wyre.png',
60 - linkTitle: S.current.submit_request,
61 - link: 'https://wyre-support.zendesk.com/hc/en-us/requests/new'),
62 - LinkListItem(
63 - title: 'MoonPay',
64 - icon: 'assets/images/moonpay.png',
65 - hasIconColor: true,
66 - linkTitle: S.current.submit_request,
67 - link: 'https://support.moonpay.com/hc/en-gb/requests/new')
68 - ]
56 + if (!isMoneroOnly) ... [
57 + LinkListItem(
58 + title: 'Wyre',
59 + icon: 'assets/images/wyre.png',
60 + linkTitle: S.current.submit_request,
61 + link: 'https://wyre-support.zendesk.com/hc/en-us/requests/new'),
62 + LinkListItem(
63 + title: 'MoonPay',
64 + icon: 'assets/images/moonpay.png',
65 + hasIconColor: true,
66 + linkTitle: S.current.submit_request,
67 + link: 'https://support.moonpay.com/hc/en-gb/requests/new')
68 + ]
69 //LinkListItem(
70 // title: 'Yat',
71 // icon: 'assets/images/yat_mini_logo.png',
72 // hasIconColor: true,
73 // linkTitle: 'support@y.at',
74 // link: 'mailto:support@y.at')
75 - ];
76 - }
75 + ];
76 +
77 static const url = 'https://cakewallet.com/guide/';
78
79 List<SettingsListItem> items;
lib/view_model/trade_details_view_model.dart
+12 -9
@@ -26,9 +26,12 @@ class TradeDetailsViewModel = TradeDetailsViewModelBase
26 with _$TradeDetailsViewModel;
27
28 abstract class TradeDetailsViewModelBase with Store {
29 - TradeDetailsViewModelBase({Trade tradeForDetails, this.trades, this.settingsStore}) {
30 - trade = tradeForDetails;
31 -
29 + TradeDetailsViewModelBase({
30 + required Trade tradeForDetails,
31 + required this.trades,
32 + required this.settingsStore})
33 + : items = ObservableList<StandartListItem>(),
34 + trade = tradeForDetails {
35 switch (trade.provider) {
36 case ExchangeProviderDescription.xmrto:
37 _provider = XMRTOExchangeProvider();
@@ -64,16 +67,16 @@ abstract class TradeDetailsViewModelBase with Store {
67 @observable
68 ObservableList<StandartListItem> items;
69
67 - ExchangeProvider _provider;
70 + ExchangeProvider? _provider;
71
69 - Timer timer;
72 + Timer? timer;
73
74 final SettingsStore settingsStore;
75
76 @action
77 Future<void> _updateTrade() async {
78 try {
76 - final updatedTrade = await _provider.findTradeById(id: trade.id);
79 + final updatedTrade = await _provider!.findTradeById(id: trade.id);
80
81 if (updatedTrade.createdAt == null && trade.createdAt != null) {
82 updatedTrade.createdAt = trade.createdAt;
@@ -90,7 +93,7 @@ abstract class TradeDetailsViewModelBase with Store {
93 void _updateItems() {
94 final dateFormat = DateFormatter.withCurrentLocal(reverse: true);
95
93 - items?.clear();
96 + items.clear();
97
98 items.add(
99 DetailsListStatusItem(
@@ -102,7 +105,7 @@ abstract class TradeDetailsViewModelBase with Store {
105
106 items.add(TradeDetailsListCardItem.tradeDetails(
107 id: trade.id,
105 - createdAt: dateFormat.format(trade.createdAt),
108 + createdAt: trade.createdAt != null ? dateFormat.format(trade.createdAt!) : '',
109 from: trade.from,
110 to: trade.to,
111 onTap: (BuildContext context) {
@@ -143,7 +146,7 @@ abstract class TradeDetailsViewModelBase with Store {
146 if (trade.createdAt != null) {
147 items.add(StandartListItem(
148 title: S.current.trade_details_created_at,
146 - value: dateFormat.format(trade.createdAt).toString()));
149 + value: trade.createdAt != null ? dateFormat.format(trade.createdAt!).toString() : ''));
150 }
151
152 if (trade.from != null && trade.to != null) {
lib/view_model/transaction_details_view_model.dart
+33 -27
@@ -23,21 +23,21 @@ class TransactionDetailsViewModel = TransactionDetailsViewModelBase
23
24 abstract class TransactionDetailsViewModelBase with Store {
25 TransactionDetailsViewModelBase(
26 - {this.transactionInfo,
27 - this.transactionDescriptionBox,
28 - this.wallet,
29 - this.settingsStore})
30 - : items = [] {
31 - showRecipientAddress = settingsStore?.shouldSaveRecipientAddress ?? false;
32 - isRecipientAddressShown = false;
33 -
26 + {required this.transactionInfo,
27 + required this.transactionDescriptionBox,
28 + required this.wallet,
29 + required this.settingsStore})
30 + : items = [],
31 + isRecipientAddressShown = false,
32 + showRecipientAddress = settingsStore.shouldSaveRecipientAddress {
33 final dateFormat = DateFormatter.withCurrentLocal();
34 final tx = transactionInfo;
35
36 if (wallet.type == WalletType.monero) {
38 - final key = tx.additionalInfo['key'] as String;
37 + final key = tx.additionalInfo['key'] as String?;
38 final accountIndex = tx.additionalInfo['accountIndex'] as int;
39 final addressIndex = tx.additionalInfo['addressIndex'] as int;
40 + final feeFormatted = tx.feeFormatted();
41 final _items = [
42 StandartListItem(
43 title: S.current.transaction_details_transaction_id, value: tx.id),
@@ -49,18 +49,19 @@ abstract class TransactionDetailsViewModelBase with Store {
49 StandartListItem(
50 title: S.current.transaction_details_amount,
51 value: tx.amountFormatted()),
52 - StandartListItem(
53 - title: S.current.transaction_details_fee, value: tx.feeFormatted()),
52 + if (feeFormatted != null)
53 + StandartListItem(
54 + title: S.current.transaction_details_fee, value: feeFormatted),
55 if (key?.isNotEmpty ?? false)
55 - StandartListItem(title: S.current.transaction_key, value: key)
56 + StandartListItem(title: S.current.transaction_key, value: key!)
57 ];
58
59 if (tx.direction == TransactionDirection.incoming &&
60 accountIndex != null &&
61 addressIndex != null) {
62 try {
62 - final address = monero.getTransactionAddress(wallet, accountIndex, addressIndex);
63 - final label = monero.getSubaddressLabel(wallet, accountIndex, addressIndex);
63 + final address = monero!.getTransactionAddress(wallet, accountIndex, addressIndex);
64 + final label = monero!.getSubaddressLabel(wallet, accountIndex, addressIndex);
65
66 if (address?.isNotEmpty ?? false) {
67 isRecipientAddressShown = true;
@@ -95,16 +96,16 @@ abstract class TransactionDetailsViewModelBase with Store {
96 value: dateFormat.format(tx.date)),
97 StandartListItem(
98 title: S.current.confirmations,
98 - value: tx.confirmations?.toString()),
99 + value: tx.confirmations.toString()),
100 StandartListItem(
101 title: S.current.transaction_details_height, value: '${tx.height}'),
102 StandartListItem(
103 title: S.current.transaction_details_amount,
104 value: tx.amountFormatted()),
104 - if (tx.feeFormatted()?.isNotEmpty)
105 + if (tx.feeFormatted()?.isNotEmpty ?? false)
106 StandartListItem(
107 title: S.current.transaction_details_fee,
107 - value: tx.feeFormatted()),
108 + value: tx.feeFormatted()!),
109 ];
110
111 items.addAll(_items);
@@ -122,20 +123,25 @@ abstract class TransactionDetailsViewModelBase with Store {
123 StandartListItem(
124 title: S.current.transaction_details_amount,
125 value: tx.amountFormatted()),
125 - StandartListItem(
126 - title: S.current.transaction_details_fee, value: tx.feeFormatted()),
126 + if (tx.feeFormatted()?.isNotEmpty ?? false)
127 + StandartListItem(
128 + title: S.current.transaction_details_fee, value: tx.feeFormatted()!),
129 ]);
130 }
131
132 if (showRecipientAddress && !isRecipientAddressShown) {
131 - final recipientAddress = transactionDescriptionBox.values
132 - .firstWhere((val) => val.id == transactionInfo.id, orElse: () => null)
133 - ?.recipientAddress;
134 -
135 - if (recipientAddress?.isNotEmpty ?? false) {
136 - items.add(StandartListItem(
137 - title: S.current.transaction_details_recipient_address,
138 - value: recipientAddress));
133 + try {
134 + final recipientAddress = transactionDescriptionBox.values
135 + .firstWhere((val) => val.id == transactionInfo.id)
136 + .recipientAddress;
137 +
138 + if (recipientAddress?.isNotEmpty ?? false) {
139 + items.add(StandartListItem(
140 + title: S.current.transaction_details_recipient_address,
141 + value: recipientAddress!));
142 + }
143 + } catch(_) {
144 + // FIX-ME: Unhandled exception
145 }
146 }
147
lib/view_model/unspent_coins/unspent_coins_details_view_model.dart
+7 -9
@@ -14,21 +14,19 @@ class UnspentCoinsDetailsViewModel = UnspentCoinsDetailsViewModelBase
14
15 abstract class UnspentCoinsDetailsViewModelBase with Store {
16 UnspentCoinsDetailsViewModelBase({
17 - this.unspentCoinsItem, this.unspentCoinsListViewModel}) {
18 -
19 - final amount = unspentCoinsItem.amount ?? '';
20 - final address = unspentCoinsItem.address ?? '';
21 - isFrozen = unspentCoinsItem.isFrozen ?? false;
22 - note = unspentCoinsItem.note ?? '';
23 -
17 + required this.unspentCoinsItem,
18 + required this.unspentCoinsListViewModel})
19 + : items = <TransactionDetailsListItem>[],
20 + isFrozen = unspentCoinsItem.isFrozen,
21 + note = unspentCoinsItem.note {
22 items = [
23 StandartListItem(
24 title: S.current.transaction_details_amount,
27 - value: amount
25 + value: unspentCoinsItem.amount
26 ),
27 StandartListItem(
28 title: S.current.widgets_address,
31 - value: address
29 + value: unspentCoinsItem.address
30 ),
31 TextFieldListItem(
32 title: S.current.note_tap_to_change,
lib/view_model/unspent_coins/unspent_coins_item.dart
+6 -6
@@ -6,12 +6,12 @@ class UnspentCoinsItem = UnspentCoinsItemBase with _$UnspentCoinsItem;
6
7 abstract class UnspentCoinsItemBase with Store {
8 UnspentCoinsItemBase({
9 - this.address,
10 - this.amount,
11 - this.hash,
12 - this.isFrozen,
13 - this.note,
14 - this.isSending});
9 + required this.address,
10 + required this.amount,
11 + required this.hash,
12 + required this.isFrozen,
13 + required this.note,
14 + required this.isSending});
15
16 @observable
17 String address;
lib/view_model/unspent_coins/unspent_coins_list_view_model.dart
+7 -7
@@ -14,18 +14,18 @@ class UnspentCoinsListViewModel = UnspentCoinsListViewModelBase with _$UnspentCo
14
15 abstract class UnspentCoinsListViewModelBase with Store {
16 UnspentCoinsListViewModelBase({
17 - @required this.wallet,
18 - @required Box<UnspentCoinsInfo> unspentCoinsInfo}) {
19 - _unspentCoinsInfo = unspentCoinsInfo;
20 - bitcoin.updateUnspents(wallet);
17 + required this.wallet,
18 + required Box<UnspentCoinsInfo> unspentCoinsInfo})
19 + : _unspentCoinsInfo = unspentCoinsInfo {
20 + bitcoin!.updateUnspents(wallet);
21 }
22
23 WalletBase wallet;
24 Box<UnspentCoinsInfo> _unspentCoinsInfo;
25
26 @computed
27 - ObservableList<UnspentCoinsItem> get items => ObservableList.of(bitcoin.getUnspents(wallet).map((elem) {
28 - final amount = bitcoin.formatterBitcoinAmountToString(amount: elem.value) +
27 + ObservableList<UnspentCoinsItem> get items => ObservableList.of(bitcoin!.getUnspents(wallet).map((elem) {
28 + final amount = bitcoin!.formatterBitcoinAmountToString(amount: elem.value) +
29 ' ${wallet.currency.title}';
30
31 final info = _unspentCoinsInfo.values
@@ -52,7 +52,7 @@ abstract class UnspentCoinsListViewModelBase with Store {
52 info.note = item.note;
53
54 await info.save();
55 - bitcoin.updateUnspents(wallet);
55 + bitcoin!.updateUnspents(wallet);
56 } catch (e) {
57 print(e.toString());
58 }
lib/view_model/unspent_coins/unspent_coins_switch_item.dart
+4 -4
@@ -2,10 +2,10 @@ import 'package:cake_wallet/src/screens/transaction_details/transaction_details_
2
3 class UnspentCoinsSwitchItem extends TransactionDetailsListItem {
4 UnspentCoinsSwitchItem({
5 - String title,
6 - String value,
7 - this.switchValue,
8 - this.onSwitchValueChange}) : super(title: title, value: value);
5 + required String title,
6 + required String value,
7 + required this.switchValue,
8 + required this.onSwitchValueChange}) : super(title: title, value: value);
9
10 final bool Function() switchValue;
11 final void Function(bool value) onSwitchValueChange;
lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart
+12 -12
@@ -20,17 +20,17 @@ class AddressIsSaving extends AddressEditOrCreateState {}
20 class AddressSavedSuccessfully extends AddressEditOrCreateState {}
21
22 class AddressEditOrCreateStateFailure extends AddressEditOrCreateState {
23 - AddressEditOrCreateStateFailure({this.error});
23 + AddressEditOrCreateStateFailure({required this.error});
24
25 String error;
26 }
27
28 abstract class WalletAddressEditOrCreateViewModelBase with Store {
29 WalletAddressEditOrCreateViewModelBase(
30 - {@required WalletBase wallet, dynamic item})
30 + {required WalletBase wallet, dynamic item})
31 : isEdit = item != null,
32 state = AddressEditOrCreateStateInitial(),
33 - label = item?.name as String,
33 + label = item?.name as String? ?? '',
34 _item = item,
35 _wallet = wallet;
36
@@ -66,26 +66,26 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
66
67 if (wallet.type == WalletType.bitcoin
68 || wallet.type == WalletType.litecoin) {
69 - await bitcoin.generateNewAddress(wallet);
69 + await bitcoin!.generateNewAddress(wallet);
70 await wallet.save();
71 }
72
73 if (wallet.type == WalletType.monero) {
74 await monero
75 - .getSubaddressList(wallet)
75 + !.getSubaddressList(wallet)
76 .addSubaddress(
77 wallet,
78 - accountIndex: monero.getCurrentAccount(wallet).id,
78 + accountIndex: monero!.getCurrentAccount(wallet).id,
79 label: label);
80 await wallet.save();
81 }
82
83 if (wallet.type == WalletType.haven) {
84 await haven
85 - .getSubaddressList(wallet)
85 + !.getSubaddressList(wallet)
86 .addSubaddress(
87 wallet,
88 - accountIndex: haven.getCurrentAccount(wallet).id,
88 + accountIndex: haven!.getCurrentAccount(wallet).id,
89 label: label);
90 await wallet.save();
91 }
@@ -101,10 +101,10 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
101
102 if (wallet.type == WalletType.monero) {
103 await monero
104 - .getSubaddressList(wallet)
104 + !.getSubaddressList(wallet)
105 .setLabelSubaddress(
106 wallet,
107 - accountIndex: monero.getCurrentAccount(wallet).id,
107 + accountIndex: monero!.getCurrentAccount(wallet).id,
108 addressIndex: _item.id as int,
109 label: label);
110 await wallet.save();
@@ -112,10 +112,10 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
112
113 if (wallet.type == WalletType.haven) {
114 await haven
115 - .getSubaddressList(wallet)
115 + !.getSubaddressList(wallet)
116 .setLabelSubaddress(
117 wallet,
118 - accountIndex: haven.getCurrentAccount(wallet).id,
118 + accountIndex: haven!.getCurrentAccount(wallet).id,
119 addressIndex: _item.id as int,
120 label: label);
121 await wallet.save();
lib/view_model/wallet_address_list/wallet_address_list_item.dart
+8 -4
@@ -2,13 +2,17 @@ import 'package:flutter/foundation.dart';
2 import 'package:cake_wallet/utils/list_item.dart';
3
4 class WalletAddressListItem extends ListItem {
5 - const WalletAddressListItem({@required this.address, @required this.isPrimary,
6 - this.name, this.id}) : super();
5 + const WalletAddressListItem({
6 + required this.address,
7 + required this.isPrimary,
8 + this.id,
9 + this.name})
10 + : super();
11
8 - final int id;
12 + final int? id;
13 final bool isPrimary;
14 final String address;
11 - final String name;
15 + final String? name;
16
17 @override
18 String toString() => name ?? address;
lib/view_model/wallet_address_list/wallet_address_list_view_model.dart
+38 -25
@@ -23,14 +23,18 @@ class WalletAddressListViewModel = WalletAddressListViewModelBase
23 with _$WalletAddressListViewModel;
24
25 abstract class PaymentURI {
26 - PaymentURI({this.amount, this.address});
26 + PaymentURI({
27 + required this.amount,
28 + required this.address});
29
30 final String amount;
31 final String address;
32 }
33
34 class MoneroURI extends PaymentURI {
33 - MoneroURI({String amount, String address})
35 + MoneroURI({
36 + required String amount,
37 + required String address})
38 : super(amount: amount, address: address);
39
40 @override
@@ -46,7 +50,9 @@ class MoneroURI extends PaymentURI {
50 }
51
52 class HavenURI extends PaymentURI {
49 - HavenURI({String amount, String address})
53 + HavenURI({
54 + required String amount,
55 + required String address})
56 : super(amount: amount, address: address);
57
58 @override
@@ -62,7 +68,9 @@ class HavenURI extends PaymentURI {
68 }
69
70 class BitcoinURI extends PaymentURI {
65 - BitcoinURI({String amount, String address})
71 + BitcoinURI({
72 + required String amount,
73 + required String address})
74 : super(amount: amount, address: address);
75
76 @override
@@ -78,7 +86,9 @@ class BitcoinURI extends PaymentURI {
86 }
87
88 class LitecoinURI extends PaymentURI {
81 - LitecoinURI({String amount, String address})
89 + LitecoinURI({
90 + required String amount,
91 + required String address})
92 : super(amount: amount, address: address);
93
94 @override
@@ -95,16 +105,19 @@ class LitecoinURI extends PaymentURI {
105
106 abstract class WalletAddressListViewModelBase with Store {
107 WalletAddressListViewModelBase({
98 - @required AppStore appStore,
99 - @required this.yatStore
100 - }) {
101 - _appStore = appStore;
102 - _wallet = _appStore.wallet;
103 - hasAccounts = _wallet?.type == WalletType.monero || _wallet?.type == WalletType.haven;
104 -
108 + required AppStore appStore,
109 + required this.yatStore
110 + }) : _appStore = appStore,
111 + _baseItems = <ListItem>[],
112 + _wallet = appStore.wallet!,
113 + hasAccounts = appStore.wallet!.type == WalletType.monero || appStore.wallet!.type == WalletType.haven,
114 + amount = '' {
115 _onWalletChangeReaction = reaction((_) => _appStore.wallet, (WalletBase<
106 - Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>
116 + Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>?
117 wallet) {
118 + if (wallet == null) {
119 + return;
120 + }
121 _wallet = wallet;
122 hasAccounts = _wallet.type == WalletType.monero;
123 });
@@ -119,7 +132,7 @@ abstract class WalletAddressListViewModelBase with Store {
132
133 @computed
134 WalletAddressListItem get address =>
122 - WalletAddressListItem(address: _wallet.walletAddresses.address);
135 + WalletAddressListItem(address: _wallet.walletAddresses.address, isPrimary: false);
136
137 @computed
138 PaymentURI get uri {
@@ -139,7 +152,7 @@ abstract class WalletAddressListViewModelBase with Store {
152 return LitecoinURI(amount: amount, address: address.address);
153 }
154
142 - return null;
155 + throw Exception('Unexpected type: ${type.toString()}');
156 }
157
158 @computed
@@ -152,9 +165,9 @@ abstract class WalletAddressListViewModelBase with Store {
165 final addressList = ObservableList<ListItem>();
166
167 if (wallet.type == WalletType.monero) {
155 - final primaryAddress = monero.getSubaddressList(wallet).subaddresses.first;
168 + final primaryAddress = monero!.getSubaddressList(wallet).subaddresses.first;
169 final addressItems = monero
157 - .getSubaddressList(wallet)
170 + !.getSubaddressList(wallet)
171 .subaddresses
172 .map((subaddress) {
173 final isPrimary = subaddress == primaryAddress;
@@ -169,9 +182,9 @@ abstract class WalletAddressListViewModelBase with Store {
182 }
183
184 if (wallet.type == WalletType.haven) {
172 - final primaryAddress = haven.getSubaddressList(wallet).subaddresses.first;
185 + final primaryAddress = haven!.getSubaddressList(wallet).subaddresses.first;
186 final addressItems = haven
174 - .getSubaddressList(wallet)
187 + !.getSubaddressList(wallet)
188 .subaddresses
189 .map((subaddress) {
190 final isPrimary = subaddress == primaryAddress;
@@ -186,8 +199,8 @@ abstract class WalletAddressListViewModelBase with Store {
199 }
200
201 if (wallet.type == WalletType.bitcoin) {
189 - final primaryAddress = bitcoin.getAddress(wallet);
190 - final bitcoinAddresses = bitcoin.getAddresses(wallet).map((addr) {
202 + final primaryAddress = bitcoin!.getAddress(wallet);
203 + final bitcoinAddresses = bitcoin!.getAddresses(wallet).map((addr) {
204 final isPrimary = addr == primaryAddress;
205
206 return WalletAddressListItem(
@@ -207,14 +220,14 @@ abstract class WalletAddressListViewModelBase with Store {
220 final wallet = _wallet;
221
222 if (wallet.type == WalletType.monero) {
210 - return monero.getCurrentAccount(wallet).label;
223 + return monero!.getCurrentAccount(wallet).label;
224 }
225
226 if (wallet.type == WalletType.haven) {
214 - return haven.getCurrentAccount(wallet).label;
227 + return haven!.getCurrentAccount(wallet).label;
228 }
229
217 - return null;
230 + return '';
231 }
232
233 @computed
@@ -230,7 +243,7 @@ abstract class WalletAddressListViewModelBase with Store {
243
244 final YatStore yatStore;
245
233 - ReactionDisposer _onWalletChangeReaction;
246 + ReactionDisposer? _onWalletChangeReaction;
247
248 @action
249 void setAddress(WalletAddressListItem address) =>
lib/view_model/wallet_creation_vm.dart
+5 -5
@@ -17,10 +17,9 @@ class WalletCreationVM = WalletCreationVMBase with _$WalletCreationVM;
17
18 abstract class WalletCreationVMBase with Store {
19 WalletCreationVMBase(this._appStore, this._walletInfoSource, this.walletCreationService,
20 - {@required this.type, @required this.isRecovery}) {
21 - state = InitialExecutionState();
22 - name = '';
23 - }
20 + {required this.type, required this.isRecovery})
21 + : state = InitialExecutionState(),
22 + name = '';
23
24 @observable
25 String name;
@@ -43,7 +42,7 @@ abstract class WalletCreationVMBase with Store {
42 Future<void> create({dynamic options}) async {
43 try {
44 state = IsExecutingState();
46 - if (name?.isEmpty ?? true) {
45 + if (name.isEmpty) {
46 name = await generateName();
47 }
48
@@ -60,6 +59,7 @@ abstract class WalletCreationVMBase with Store {
59 date: DateTime.now(),
60 path: path,
61 dirPath: dirPath,
62 + address: '',
63 showIntroCakePayCard: (!walletCreationService.typeExists(type)) && type != WalletType.haven);
64 credentials.walletInfo = walletInfo;
65 final wallet = await process(credentials);
lib/view_model/wallet_keys_view_model.dart
+18 -10
@@ -17,25 +17,33 @@ abstract class WalletKeysViewModelBase with Store {
17 : S.current.wallet_keys,
18 items = ObservableList<StandartListItem>() {
19 if (wallet.type == WalletType.monero) {
20 - final keys = monero.getKeys(wallet);
20 + final keys = monero!.getKeys(wallet);
21
22 items.addAll([
23 - StandartListItem(title: S.current.spend_key_public, value: keys['publicSpendKey']),
24 - StandartListItem(title: S.current.spend_key_private, value: keys['privateSpendKey']),
25 - StandartListItem(title: S.current.view_key_public, value: keys['publicViewKey']),
26 - StandartListItem(title: S.current.view_key_private, value: keys['privateViewKey']),
23 + if (keys['publicSpendKey'] != null)
24 + StandartListItem(title: S.current.spend_key_public, value: keys['publicSpendKey']!),
25 + if (keys['privateSpendKey'] != null)
26 + StandartListItem(title: S.current.spend_key_private, value: keys['privateSpendKey']!),
27 + if (keys['publicViewKey'] != null)
28 + StandartListItem(title: S.current.view_key_public, value: keys['publicViewKey']!),
29 + if (keys['privateViewKey'] != null)
30 + StandartListItem(title: S.current.view_key_private, value: keys['privateViewKey']!),
31 StandartListItem(title: S.current.wallet_seed, value: wallet.seed),
32 ]);
33 }
34
35 if (wallet.type == WalletType.haven) {
32 - final keys = haven.getKeys(wallet);
36 + final keys = haven!.getKeys(wallet);
37
38 items.addAll([
35 - StandartListItem(title: S.current.spend_key_public, value: keys['publicSpendKey']),
36 - StandartListItem(title: S.current.spend_key_private, value: keys['privateSpendKey']),
37 - StandartListItem(title: S.current.view_key_public, value: keys['publicViewKey']),
38 - StandartListItem(title: S.current.view_key_private, value: keys['privateViewKey']),
39 + if (keys['publicSpendKey'] != null)
40 + StandartListItem(title: S.current.spend_key_public, value: keys['publicSpendKey']!),
41 + if (keys['privateSpendKey'] != null)
42 + StandartListItem(title: S.current.spend_key_private, value: keys['privateSpendKey']!),
43 + if (keys['publicViewKey'] != null)
44 + StandartListItem(title: S.current.view_key_public, value: keys['publicViewKey']!),
45 + if (keys['privateViewKey'] != null)
46 + StandartListItem(title: S.current.view_key_private, value: keys['privateViewKey']!),
47 StandartListItem(title: S.current.wallet_seed, value: wallet.seed),
48 ]);
49 }
lib/view_model/wallet_list/wallet_list_item.dart
+3 -3
@@ -3,9 +3,9 @@ import 'package:cw_core/wallet_type.dart';
3
4 class WalletListItem {
5 const WalletListItem(
6 - {@required this.name,
7 - @required this.type,
8 - @required this.key,
6 + {required this.name,
7 + required this.type,
8 + required this.key,
9 this.isCurrent = false,
10 this.isEnabled = true});
11
lib/view_model/wallet_list/wallet_list_view_model.dart
+5 -5
@@ -16,8 +16,8 @@ class WalletListViewModel = WalletListViewModelBase with _$WalletListViewModel;
16
17 abstract class WalletListViewModelBase with Store {
18 WalletListViewModelBase(this._walletInfoSource, this._appStore,
19 - this._walletLoadingService) {
20 - wallets = ObservableList<WalletListItem>();
19 + this._walletLoadingService)
20 + : wallets = ObservableList<WalletListItem>() {
21 _updateList();
22 }
23
@@ -28,7 +28,7 @@ abstract class WalletListViewModelBase with Store {
28 final Box<WalletInfo> _walletInfoSource;
29 final WalletLoadingService _walletLoadingService;
30
31 - WalletType get currentWalletType => _appStore.wallet.type;
31 + WalletType get currentWalletType => _appStore.wallet!.type;
32
33 @action
34 Future<void> loadWallet(WalletListItem walletItem) async {
@@ -51,8 +51,8 @@ abstract class WalletListViewModelBase with Store {
51 name: info.name,
52 type: info.type,
53 key: info.key,
54 - isCurrent: info.name == _appStore.wallet.name &&
55 - info.type == _appStore.wallet.type,
54 + isCurrent: info.name == _appStore.wallet!.name &&
55 + info.type == _appStore.wallet!.type,
56 isEnabled: availableWalletTypes.contains(info.type))));
57 }
58 }
lib/view_model/wallet_new_vm.dart
+6 -6
@@ -19,7 +19,7 @@ class WalletNewVM = WalletNewVMBase with _$WalletNewVM;
19 abstract class WalletNewVMBase extends WalletCreationVM with Store {
20 WalletNewVMBase(AppStore appStore, WalletCreationService walletCreationService,
21 Box<WalletInfo> walletInfoSource,
22 - {@required WalletType type})
22 + {required WalletType type})
23 : selectedMnemonicLanguage = '',
24 super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: false);
25
@@ -32,17 +32,17 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
32 WalletCredentials getCredentials(dynamic options) {
33 switch (type) {
34 case WalletType.monero:
35 - return monero.createMoneroNewWalletCredentials(
35 + return monero!.createMoneroNewWalletCredentials(
36 name: name, language: options as String);
37 case WalletType.bitcoin:
38 - return bitcoin.createBitcoinNewWalletCredentials(name: name);
38 + return bitcoin!.createBitcoinNewWalletCredentials(name: name);
39 case WalletType.litecoin:
40 - return bitcoin.createBitcoinNewWalletCredentials(name: name);
40 + return bitcoin!.createBitcoinNewWalletCredentials(name: name);
41 case WalletType.haven:
42 - return haven.createHavenNewWalletCredentials(
42 + return haven!.createHavenNewWalletCredentials(
43 name: name, language: options as String);
44 default:
45 - return null;
45 + throw Exception('Unexpected type: ${type.toString()}');;
46 }
47 }
48
lib/view_model/wallet_restoration_from_keys_vm.dart
+10 -5
@@ -21,8 +21,13 @@ abstract class WalletRestorationFromKeysVMBase extends WalletCreationVM
21 with Store {
22 WalletRestorationFromKeysVMBase(AppStore appStore,
23 WalletCreationService walletCreationService, Box<WalletInfo> walletInfoSource,
24 - {@required WalletType type, @required this.language})
25 - : super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true);
24 + {required WalletType type, required this.language})
25 + : height = 0,
26 + viewKey = '',
27 + spendKey = '',
28 + wif = '',
29 + address = '',
30 + super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true);
31
32 @observable
33 int height;
@@ -49,7 +54,7 @@ abstract class WalletRestorationFromKeysVMBase extends WalletCreationVM
54
55 switch (type) {
56 case WalletType.monero:
52 - return monero.createMoneroRestoreWalletFromKeysCredentials(
57 + return monero!.createMoneroRestoreWalletFromKeysCredentials(
58 name: name,
59 password: password,
60 language: language,
@@ -58,10 +63,10 @@ abstract class WalletRestorationFromKeysVMBase extends WalletCreationVM
63 spendKey: spendKey,
64 height: height);
65 case WalletType.bitcoin:
61 - return bitcoin.createBitcoinRestoreWalletFromWIFCredentials(
66 + return bitcoin!.createBitcoinRestoreWalletFromWIFCredentials(
67 name: name, password: password, wif: wif);
68 default:
64 - return null;
69 + throw Exception('Unexpected type: ${type.toString()}');;
70 }
71 }
72
lib/view_model/wallet_restoration_from_seed_vm.dart
+6 -5
@@ -21,8 +21,9 @@ abstract class WalletRestorationFromSeedVMBase extends WalletCreationVM
21 with Store {
22 WalletRestorationFromSeedVMBase(AppStore appStore,
23 WalletCreationService walletCreationService, Box<WalletInfo> walletInfoSource,
24 - {@required WalletType type, @required this.language, this.seed})
25 - : super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true);
24 + {required WalletType type, required this.language, this.seed = ''})
25 + : height = 0,
26 + super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true);
27
28 @observable
29 String seed;
@@ -40,13 +41,13 @@ abstract class WalletRestorationFromSeedVMBase extends WalletCreationVM
41
42 switch (type) {
43 case WalletType.monero:
43 - return monero.createMoneroRestoreWalletFromSeedCredentials(
44 + return monero!.createMoneroRestoreWalletFromSeedCredentials(
45 name: name, height: height, mnemonic: seed, password: password);
46 case WalletType.bitcoin:
46 - return bitcoin.createBitcoinRestoreWalletFromSeedCredentials(
47 + return bitcoin!.createBitcoinRestoreWalletFromSeedCredentials(
48 name: name, mnemonic: seed, password: password);
49 default:
49 - return null;
50 + throw Exception('Unexpected type: ${type.toString()}');
51 }
52 }
53
lib/view_model/wallet_restore_view_model.dart
+13 -12
@@ -24,16 +24,17 @@ class WalletRestoreViewModel = WalletRestoreViewModelBase
24 abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
25 WalletRestoreViewModelBase(AppStore appStore, WalletCreationService walletCreationService,
26 Box<WalletInfo> walletInfoSource,
27 - {@required WalletType type})
27 + {required WalletType type})
28 : availableModes = (type == WalletType.monero || type == WalletType.haven)
29 ? WalletRestoreMode.values
30 : [WalletRestoreMode.seed],
31 hasSeedLanguageSelector = type == WalletType.monero || type == WalletType.haven,
32 hasBlockchainHeightLanguageSelector = type == WalletType.monero || type == WalletType.haven,
33 + isButtonEnabled = false,
34 + mode = WalletRestoreMode.seed,
35 super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true) {
36 isButtonEnabled =
37 !hasSeedLanguageSelector && !hasBlockchainHeightLanguageSelector;
36 - mode = WalletRestoreMode.seed;
38 walletCreationService.changeWalletType(type: type);
39 }
40
@@ -54,7 +55,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
55 @override
56 WalletCredentials getCredentials(dynamic options) {
57 final password = generateWalletPassword();
57 - final height = options['height'] as int;
58 + final height = options['height'] as int? ?? 0;
59 name = options['name'] as String;
60
61 if (mode == WalletRestoreMode.seed) {
@@ -62,25 +63,25 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
63
64 switch (type) {
65 case WalletType.monero:
65 - return monero.createMoneroRestoreWalletFromSeedCredentials(
66 + return monero!.createMoneroRestoreWalletFromSeedCredentials(
67 name: name,
67 - height: height ?? 0,
68 + height: height,
69 mnemonic: seed,
70 password: password);
71 case WalletType.bitcoin:
71 - return bitcoin.createBitcoinRestoreWalletFromSeedCredentials(
72 + return bitcoin!.createBitcoinRestoreWalletFromSeedCredentials(
73 name: name,
74 mnemonic: seed,
75 password: password);
76 case WalletType.litecoin:
76 - return bitcoin.createBitcoinRestoreWalletFromSeedCredentials(
77 + return bitcoin!.createBitcoinRestoreWalletFromSeedCredentials(
78 name: name,
79 mnemonic: seed,
80 password: password);
81 case WalletType.haven:
81 - return haven.createHavenRestoreWalletFromSeedCredentials(
82 + return haven!.createHavenRestoreWalletFromSeedCredentials(
83 name: name,
83 - height: height ?? 0,
84 + height: height,
85 mnemonic: seed,
86 password: password);
87 default:
@@ -94,7 +95,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
95 final address = options['address'] as String;
96
97 if (type == WalletType.monero) {
97 - return monero.createMoneroRestoreWalletFromKeysCredentials(
98 + return monero!.createMoneroRestoreWalletFromKeysCredentials(
99 name: name,
100 height: height,
101 spendKey: spendKey,
@@ -105,7 +106,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
106 }
107
108 if (type == WalletType.haven) {
108 - return haven.createHavenRestoreWalletFromKeysCredentials(
109 + return haven!.createHavenRestoreWalletFromKeysCredentials(
110 name: name,
111 height: height,
112 spendKey: spendKey,
@@ -116,7 +117,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
117 }
118 }
119
119 - return null;
120 + throw Exception('Unexpected type: ${type.toString()}');
121 }
122
123 @override
pubspec_base.yaml
+58 -49
@@ -1,71 +1,80 @@
1 -dependencies:
2 - flutter:
1 +flutter:
2 sdk: flutter
3 flutter_localizations:
4 sdk: flutter
5 flutter_cupertino_localizations: ^1.0.1
6 intl: ^0.17.0
8 - url_launcher: ^6.0.3
9 - qr: ^2.0.0
10 - uuid: ^2.2.2
11 - shared_preferences: ^0.5.3+4
7 + url_launcher: ^6.1.4
8 + qr: ^3.0.1
9 + uuid: 3.0.6
10 + shared_preferences: ^2.0.15
11 flutter_secure_storage:
12 git:
13 url: https://github.com/cake-tech/flutter_secure_storage.git
15 - ref: cake
16 - version: 3.3.57
17 - provider: ^5.0.0
18 - rxdart: ^0.26.0
19 - yaml: ^2.1.16
20 - barcode_scan: any
21 - http: ^0.12.0+2
22 - path_provider: ^1.3.0
23 - mobx: ^1.2.1+2
24 - flutter_mobx: ^1.1.0+2
25 - flutter_slidable: ^0.5.3
14 + path: flutter_secure_storage
15 + ref: cake-6.0.0
16 + version: 6.0.0
17 + # provider: ^6.0.3
18 + rxdart: ^0.27.4
19 + yaml: ^3.1.1
20 + #barcode_scan: any
21 + barcode_scan2: ^4.2.1
22 + http: ^0.13.4
23 + path_provider: ^2.0.11
24 + mobx: ^2.0.7+4
25 + flutter_mobx: ^2.0.6+1
26 + flutter_slidable: ^2.0.0
27 share: ^2.0.1
27 - esys_flutter_share: ^1.0.2
28 - date_range_picker: ^1.0.6
29 - dio: ^3.0.10
30 - hive: ^1.4.4+1
31 - hive_flutter: ^0.3.1
32 - local_auth: ^1.1.6
28 + # share_plus: ^4.0.10
29 + # esys_flutter_share: ^1.0.2
30 + # date_range_picker: ^1.0.6
31 + #https://api.flutter.dev/flutter/material/showDateRangePicker.html
32 + dio: ^4.0.6
33 + hive: ^2.2.3
34 + hive_flutter: ^1.1.0
35 + local_auth: ^2.1.0
36 package_info: ^2.0.0
34 - devicelocale: ^0.4.1
35 - auto_size_text: ^2.1.0
36 - dotted_border: ^1.0.5
37 - smooth_page_indicator: ^0.2.0
38 - webview_flutter: ^2.0.2
39 - flutter_spinkit: ^5.0.0
40 - uni_links: ^0.4.0
41 - lottie: ^0.7.0
42 - animate_do: ^2.0.0
43 - cupertino_icons: ^1.0.2
44 - encrypt: ^4.0.0
45 - crypto: ^2.1.5
46 - password: ^1.0.0
47 - basic_utils: ^2.0.3
48 - get_it: ^6.0.0
37 + #package_info_plus: ^1.4.2
38 + devicelocale: ^0.5.4
39 + auto_size_text: ^3.0.0
40 + dotted_border: ^2.0.0+2
41 + smooth_page_indicator: ^1.0.0+2
42 + webview_flutter: ^3.0.4
43 + flutter_spinkit: ^5.1.0
44 + uni_links: ^0.5.1
45 + lottie: ^1.3.0
46 + animate_do: ^2.1.0
47 + cupertino_icons: ^1.0.5
48 + encrypt: ^5.0.1
49 + crypto: ^3.0.2
50 + # password: ^1.0.0
51 + basic_utils: ^4.3.0
52 + get_it: ^7.2.0
53 connectivity: ^3.0.3
50 - keyboard_actions: ^3.3.0
54 + # connectivity_plus: ^2.3.5
55 + keyboard_actions: ^4.0.1
56 flushbar: ^1.10.4
52 - archive: ^2.0.13
53 - cryptography: ^1.4.0
54 - file_picker: ^3.0.0-nullsafety.2
57 + # check flushbar for replace
58 + archive: ^3.3.0
59 + cryptography: ^2.0.5
60 + file_picker: ^4.6.1
61 unorm_dart: ^0.2.0
56 - permission_handler: ^5.0.1+1
62 + # check unorm_dart for usage and for replace
63 + permission_handler: ^10.0.0
64 device_display_brightness: ^0.0.6
58 - platform_device_id: ^0.2.1
65 + platform_device_id: ^1.0.1
66
67 dev_dependencies:
68 flutter_test:
69 sdk: flutter
63 - build_runner: ^1.10.3
64 - build_resolvers: ^1.3.10
65 - mobx_codegen: ^1.1.0+1
66 - hive_generator: ^0.8.1
67 - flutter_launcher_icons: ^0.8.1
70 + build_runner: ^2.1.11
71 + mobx_codegen: ^2.0.7
72 + build_resolvers: ^2.0.9
73 + hive_generator: ^1.1.3
74 + flutter_launcher_icons: ^0.9.3
75 + # check flutter_launcher_icons for usage
76 pedantic: ^1.8.0
77 + # replace https://github.com/dart-lang/lints#migrating-from-packagepedantic
78
79 flutter_icons:
80 image_path: "assets/images/app_logo.png"
pubspec_description.yaml
+2 -1
@@ -1,6 +1,7 @@
1 name: cake_wallet
2 description: Cake Wallet.
3 version: 0.0.0
4 +publish_to: none
5
6 environment:
6 - sdk: ">=2.7.0 <3.0.0"
\ No newline at end of file
7 + sdk: ">=2.17.5 <3.0.0"
\ No newline at end of file
tool/configure.dart
+92 -96
@@ -67,9 +67,9 @@ class Unspent {
67 abstract class Bitcoin {
68 TransactionPriority getMediumTransactionPriority();
69
70 - WalletCredentials createBitcoinRestoreWalletFromSeedCredentials({String name, String mnemonic, String password});
71 - WalletCredentials createBitcoinRestoreWalletFromWIFCredentials({String name, String password, String wif, WalletInfo walletInfo});
72 - WalletCredentials createBitcoinNewWalletCredentials({String name, WalletInfo walletInfo});
70 + WalletCredentials createBitcoinRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password});
71 + WalletCredentials createBitcoinRestoreWalletFromWIFCredentials({required String name, required String password, required String wif, WalletInfo? walletInfo});
72 + WalletCredentials createBitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo});
73 List<String> getWordList();
74 Map<String, String> getWalletKeys(Object wallet);
75 List<TransactionPriority> getTransactionPriorities();
@@ -77,14 +77,14 @@ abstract class Bitcoin {
77 TransactionPriority deserializeBitcoinTransactionPriority(int raw);
78 int getFeeRate(Object wallet, TransactionPriority priority);
79 Future<void> generateNewAddress(Object wallet);
80 - Object createBitcoinTransactionCredentials(List<Output> outputs, {TransactionPriority priority, int feeRate});
81 - Object createBitcoinTransactionCredentialsRaw(List<OutputInfo> outputs, {TransactionPriority priority, int feeRate});
80 + Object createBitcoinTransactionCredentials(List<Output> outputs, {required TransactionPriority priority, int? feeRate});
81 + Object createBitcoinTransactionCredentialsRaw(List<OutputInfo> outputs, {TransactionPriority? priority, required int feeRate});
82
83 List<String> getAddresses(Object wallet);
84 String getAddress(Object wallet);
85
86 - String formatterBitcoinAmountToString({int amount});
87 - double formatterBitcoinAmountToDouble({int amount});
86 + String formatterBitcoinAmountToString({required int amount});
87 + double formatterBitcoinAmountToDouble({required int amount});
88 int formatterStringDoubleToBitcoinAmount(String amount);
89
90 List<Unspent> getUnspents(Object wallet);
@@ -94,8 +94,8 @@ abstract class Bitcoin {
94 }
95 """;
96
97 - const bitcoinEmptyDefinition = 'Bitcoin bitcoin;\n';
98 - const bitcoinCWDefinition = 'Bitcoin bitcoin = CWBitcoin();\n';
97 + const bitcoinEmptyDefinition = 'Bitcoin? bitcoin;\n';
98 + const bitcoinCWDefinition = 'Bitcoin? bitcoin = CWBitcoin();\n';
99
100 final output = '$bitcoinCommonHeaders\n'
101 + (hasImplementation ? '$bitcoinCWHeaders\n' : '\n')
@@ -152,33 +152,35 @@ import 'package:cw_monero/pending_monero_transaction.dart';
152 const moneroCwPart = "part 'cw_monero.dart';";
153 const moneroContent = """
154 class Account {
155 - Account({this.id, this.label});
155 + Account({required this.id, required this.label});
156 final int id;
157 final String label;
158 }
159
160 class Subaddress {
161 - Subaddress({this.id, this.accountId, this.label, this.address});
161 + Subaddress({
162 + required this.id,
163 + required this.label,
164 + required this.address});
165 final int id;
163 - final int accountId;
166 final String label;
167 final String address;
168 }
169
170 class MoneroBalance extends Balance {
169 - MoneroBalance({@required this.fullBalance, @required this.unlockedBalance})
170 - : formattedFullBalance = monero.formatterMoneroAmountToString(amount: fullBalance),
171 + MoneroBalance({required this.fullBalance, required this.unlockedBalance})
172 + : formattedFullBalance = monero!.formatterMoneroAmountToString(amount: fullBalance),
173 formattedUnlockedBalance =
172 - monero.formatterMoneroAmountToString(amount: unlockedBalance),
174 + monero!.formatterMoneroAmountToString(amount: unlockedBalance),
175 super(unlockedBalance, fullBalance);
176
177 MoneroBalance.fromString(
176 - {@required this.formattedFullBalance,
177 - @required this.formattedUnlockedBalance})
178 - : fullBalance = monero.formatterMoneroParseAmount(amount: formattedFullBalance),
179 - unlockedBalance = monero.formatterMoneroParseAmount(amount: formattedUnlockedBalance),
180 - super(monero.formatterMoneroParseAmount(amount: formattedUnlockedBalance),
181 - monero.formatterMoneroParseAmount(amount: formattedFullBalance));
178 + {required this.formattedFullBalance,
179 + required this.formattedUnlockedBalance})
180 + : fullBalance = monero!.formatterMoneroParseAmount(amount: formattedFullBalance),
181 + unlockedBalance = monero!.formatterMoneroParseAmount(amount: formattedUnlockedBalance),
182 + super(monero!.formatterMoneroParseAmount(amount: formattedUnlockedBalance),
183 + monero!.formatterMoneroParseAmount(amount: formattedFullBalance));
184
185 final int fullBalance;
186 final int unlockedBalance;
@@ -194,10 +196,10 @@ class MoneroBalance extends Balance {
196
197 abstract class MoneroWalletDetails {
198 @observable
197 - Account account;
199 + late Account account;
200
201 @observable
200 - MoneroBalance balance;
202 + late MoneroBalance balance;
203 }
204
205 abstract class Monero {
@@ -213,28 +215,28 @@ abstract class Monero {
215
216 String getSubaddressLabel(Object wallet, int accountIndex, int addressIndex);
217
216 - int getHeigthByDate({DateTime date});
218 + int getHeigthByDate({required DateTime date});
219 TransactionPriority getDefaultTransactionPriority();
218 - TransactionPriority deserializeMoneroTransactionPriority({int raw});
220 + TransactionPriority deserializeMoneroTransactionPriority({required int raw});
221 List<TransactionPriority> getTransactionPriorities();
222 List<String> getMoneroWordList(String language);
223
224 WalletCredentials createMoneroRestoreWalletFromKeysCredentials({
223 - String name,
224 - String spendKey,
225 - String viewKey,
226 - String address,
227 - String password,
228 - String language,
229 - int height});
230 - WalletCredentials createMoneroRestoreWalletFromSeedCredentials({String name, String password, int height, String mnemonic});
231 - WalletCredentials createMoneroNewWalletCredentials({String name, String password, String language});
225 + required String name,
226 + required String spendKey,
227 + required String viewKey,
228 + required String address,
229 + required String password,
230 + required String language,
231 + required int height});
232 + WalletCredentials createMoneroRestoreWalletFromSeedCredentials({required String name, required String password, required int height, required String mnemonic});
233 + WalletCredentials createMoneroNewWalletCredentials({required String name, required String language, String password,});
234 Map<String, String> getKeys(Object wallet);
233 - Object createMoneroTransactionCreationCredentials({List<Output> outputs, TransactionPriority priority});
234 - Object createMoneroTransactionCreationCredentialsRaw({List<OutputInfo> outputs, TransactionPriority priority});
235 - String formatterMoneroAmountToString({int amount});
236 - double formatterMoneroAmountToDouble({int amount});
237 - int formatterMoneroParseAmount({String amount});
235 + Object createMoneroTransactionCreationCredentials({required List<Output> outputs, required TransactionPriority priority});
236 + Object createMoneroTransactionCreationCredentialsRaw({required List<OutputInfo> outputs, required TransactionPriority priority});
237 + String formatterMoneroAmountToString({required int amount});
238 + double formatterMoneroAmountToDouble({required int amount});
239 + int formatterMoneroParseAmount({required String amount});
240 Account getCurrentAccount(Object wallet);
241 void setCurrentAccount(Object wallet, int id, String label);
242 void onStartup();
@@ -245,12 +247,12 @@ abstract class Monero {
247
248 abstract class MoneroSubaddressList {
249 ObservableList<Subaddress> get subaddresses;
248 - void update(Object wallet, {int accountIndex});
249 - void refresh(Object wallet, {int accountIndex});
250 + void update(Object wallet, {required int accountIndex});
251 + void refresh(Object wallet, {required int accountIndex});
252 List<Subaddress> getAll(Object wallet);
251 - Future<void> addSubaddress(Object wallet, {int accountIndex, String label});
253 + Future<void> addSubaddress(Object wallet, {required int accountIndex, required String label});
254 Future<void> setLabelSubaddress(Object wallet,
253 - {int accountIndex, int addressIndex, String label});
255 + {required int accountIndex, required int addressIndex, required String label});
256 }
257
258 abstract class MoneroAccountList {
@@ -258,13 +260,13 @@ abstract class MoneroAccountList {
260 void update(Object wallet);
261 void refresh(Object wallet);
262 List<Account> getAll(Object wallet);
261 - Future<void> addAccount(Object wallet, {String label});
262 - Future<void> setLabelAccount(Object wallet, {int accountIndex, String label});
263 + Future<void> addAccount(Object wallet, {required String label});
264 + Future<void> setLabelAccount(Object wallet, {required int accountIndex, required String label});
265 }
266 """;
267
266 - const moneroEmptyDefinition = 'Monero monero;\n';
267 - const moneroCWDefinition = 'Monero monero = CWMonero();\n';
268 + const moneroEmptyDefinition = 'Monero? monero;\n';
269 + const moneroCWDefinition = 'Monero? monero = CWMonero();\n';
270
271 final output = '$moneroCommonHeaders\n'
272 + (hasImplementation ? '$moneroCWHeaders\n' : '\n')
@@ -323,33 +325,35 @@ import 'package:cw_haven/api/balance_list.dart';
325 const havenCwPart = "part 'cw_haven.dart';";
326 const havenContent = """
327 class Account {
326 - Account({this.id, this.label});
328 + Account({required this.id, required this.label});
329 final int id;
330 final String label;
331 }
332
333 class Subaddress {
332 - Subaddress({this.id, this.accountId, this.label, this.address});
334 + Subaddress({
335 + required this.id,
336 + required this.label,
337 + required this.address});
338 final int id;
334 - final int accountId;
339 final String label;
340 final String address;
341 }
342
343 class HavenBalance extends Balance {
340 - HavenBalance({@required this.fullBalance, @required this.unlockedBalance})
341 - : formattedFullBalance = haven.formatterMoneroAmountToString(amount: fullBalance),
344 + HavenBalance({required this.fullBalance, required this.unlockedBalance})
345 + : formattedFullBalance = haven!.formatterMoneroAmountToString(amount: fullBalance),
346 formattedUnlockedBalance =
343 - haven.formatterMoneroAmountToString(amount: unlockedBalance),
347 + haven!.formatterMoneroAmountToString(amount: unlockedBalance),
348 super(unlockedBalance, fullBalance);
349
350 HavenBalance.fromString(
347 - {@required this.formattedFullBalance,
348 - @required this.formattedUnlockedBalance})
349 - : fullBalance = haven.formatterMoneroParseAmount(amount: formattedFullBalance),
350 - unlockedBalance = haven.formatterMoneroParseAmount(amount: formattedUnlockedBalance),
351 - super(haven.formatterMoneroParseAmount(amount: formattedUnlockedBalance),
352 - haven.formatterMoneroParseAmount(amount: formattedFullBalance));
351 + {required this.formattedFullBalance,
352 + required this.formattedUnlockedBalance})
353 + : fullBalance = haven!.formatterMoneroParseAmount(amount: formattedFullBalance),
354 + unlockedBalance = haven!.formatterMoneroParseAmount(amount: formattedUnlockedBalance),
355 + super(haven!.formatterMoneroParseAmount(amount: formattedUnlockedBalance),
356 + haven!.formatterMoneroParseAmount(amount: formattedFullBalance));
357
358 final int fullBalance;
359 final int unlockedBalance;
@@ -364,18 +368,19 @@ class HavenBalance extends Balance {
368 }
369
370 class AssetRate {
371 + AssetRate(this.asset, this.rate);
372 +
373 final String asset;
374 final int rate;
369 -
370 - AssetRate(this.asset, this.rate);
375 }
376
377 abstract class HavenWalletDetails {
378 + // FIX-ME: it's abstruct class
379 @observable
375 - Account account;
376 -
380 + late Account account;
381 + // FIX-ME: it's abstruct class
382 @observable
378 - HavenBalance balance;
383 + late HavenBalance balance;
384 }
385
386 abstract class Haven {
@@ -389,27 +394,27 @@ abstract class Haven {
394
395 String getTransactionAddress(Object wallet, int accountIndex, int addressIndex);
396
392 - int getHeigthByDate({DateTime date});
397 + int getHeigthByDate({required DateTime date});
398 TransactionPriority getDefaultTransactionPriority();
394 - TransactionPriority deserializeMoneroTransactionPriority({int raw});
399 + TransactionPriority deserializeMoneroTransactionPriority({required int raw});
400 List<TransactionPriority> getTransactionPriorities();
401 List<String> getMoneroWordList(String language);
402
403 WalletCredentials createHavenRestoreWalletFromKeysCredentials({
399 - String name,
400 - String spendKey,
401 - String viewKey,
402 - String address,
403 - String password,
404 - String language,
405 - int height});
406 - WalletCredentials createHavenRestoreWalletFromSeedCredentials({String name, String password, int height, String mnemonic});
407 - WalletCredentials createHavenNewWalletCredentials({String name, String password, String language});
404 + required String name,
405 + required String spendKey,
406 + required String viewKey,
407 + required String address,
408 + required String password,
409 + required String language,
410 + required int height});
411 + WalletCredentials createHavenRestoreWalletFromSeedCredentials({required String name, required String password, required int height, required String mnemonic});
412 + WalletCredentials createHavenNewWalletCredentials({required String name, required String language, String password});
413 Map<String, String> getKeys(Object wallet);
409 - Object createHavenTransactionCreationCredentials({List<Output> outputs, TransactionPriority priority, String assetType});
410 - String formatterMoneroAmountToString({int amount});
411 - double formatterMoneroAmountToDouble({int amount});
412 - int formatterMoneroParseAmount({String amount});
414 + Object createHavenTransactionCreationCredentials({required List<Output> outputs, required TransactionPriority priority, required String assetType});
415 + String formatterMoneroAmountToString({required int amount});
416 + double formatterMoneroAmountToDouble({required int amount});
417 + int formatterMoneroParseAmount({required String amount});
418 Account getCurrentAccount(Object wallet);
419 void setCurrentAccount(Object wallet, int id, String label);
420 void onStartup();
@@ -421,26 +426,17 @@ abstract class Haven {
426
427 abstract class MoneroSubaddressList {
428 ObservableList<Subaddress> get subaddresses;
424 - void update(Object wallet, {int accountIndex});
425 - void refresh(Object wallet, {int accountIndex});
429 + void update(Object wallet, {required int accountIndex});
430 + void refresh(Object wallet, {required int accountIndex});
431 List<Subaddress> getAll(Object wallet);
427 - Future<void> addSubaddress(Object wallet, {int accountIndex, String label});
432 + Future<void> addSubaddress(Object wallet, {required int accountIndex, required String label});
433 Future<void> setLabelSubaddress(Object wallet,
429 - {int accountIndex, int addressIndex, String label});
430 -}
431 -
432 -abstract class HavenAccountList {
433 - ObservableList<Account> get accounts;
434 - void update(Object wallet);
435 - void refresh(Object wallet);
436 - List<Account> getAll(Object wallet);
437 - Future<void> addAccount(Object wallet, {String label});
438 - Future<void> setLabelAccount(Object wallet, {int accountIndex, String label});
434 + {required int accountIndex, required int addressIndex, required String label});
435 }
436 """;
437
442 - const havenEmptyDefinition = 'Haven haven;\n';
443 - const havenCWDefinition = 'Haven haven = CWHaven();\n';
438 + const havenEmptyDefinition = 'Haven? haven;\n';
439 + const havenCWDefinition = 'Haven? haven = CWHaven();\n';
440
441 final output = '$havenCommonHeaders\n'
442 + (hasImplementation ? '$havenCWHeaders\n' : '\n')
@@ -456,7 +452,7 @@ abstract class HavenAccountList {
452 await outputFile.writeAsString(output);
453 }
454
459 -Future<void> generatePubspec({bool hasMonero, bool hasBitcoin, bool hasHaven}) async {
455 +Future<void> generatePubspec({required bool hasMonero, required bool hasBitcoin, required bool hasHaven}) async {
456 const cwCore = """
457 cw_core:
458 path: ./cw_core
@@ -509,7 +505,7 @@ Future<void> generatePubspec({bool hasMonero, bool hasBitcoin, bool hasHaven}) a
505 await outputFile.writeAsString(outputContent);
506 }
507
512 -Future<void> generateWalletTypes({bool hasMonero, bool hasBitcoin, bool hasHaven}) async {
508 +Future<void> generateWalletTypes({required bool hasMonero, required bool hasBitcoin, required bool hasHaven}) async {
509 final walletTypesFile = File(walletTypesPath);
510
511 if (walletTypesFile.existsSync()) {
tool/generate_localization.dart
+1 -1
@@ -120,7 +120,7 @@ Future<void> main(List<String> args) async {
120 });
121 }
122
123 -String localizedStrings({Map<String, dynamic> config, bool hasOverride}) {
123 +String localizedStrings({required Map<String, dynamic> config, required bool hasOverride}) {
124 var output = '';
125
126 final pattern = RegExp('[\$]{(.*?)}');
tool/localization/localization_constants.dart
+8 -8
@@ -33,8 +33,8 @@ const part2 = """
33 ];
34 }
35
36 - LocaleListResolutionCallback listResolution({Locale fallback, bool withCountry = true}) {
37 - return (List<Locale> locales, Iterable<Locale> supported) {
36 + LocaleListResolutionCallback listResolution({required Locale fallback, bool withCountry = true}) {
37 + return (List<Locale>? locales, Iterable<Locale> supported) {
38 if (locales == null || locales.isEmpty) {
39 return fallback ?? supported.first;
40 } else {
@@ -43,8 +43,8 @@ const part2 = """
43 };
44 }
45
46 - LocaleResolutionCallback resolution({Locale fallback, bool withCountry = true}) {
47 - return (Locale locale, Iterable<Locale> supported) {
46 + LocaleResolutionCallback resolution({required Locale fallback, bool withCountry = true}) {
47 + return (Locale? locale, Iterable<Locale> supported) {
48 return _resolve(locale, fallback, supported, withCountry);
49 };
50 }
@@ -70,7 +70,7 @@ const part3 = """
70 @override
71 bool shouldReload(GeneratedLocalizationsDelegate old) => false;
72
73 - Locale _resolve(Locale locale, Locale fallback, Iterable<Locale> supported, bool withCountry) {
73 + Locale _resolve(Locale? locale, Locale fallback, Iterable<Locale> supported, bool withCountry) {
74 if (locale == null || !_isSupported(locale, withCountry)) {
75 return fallback ?? supported.first;
76 }
@@ -95,7 +95,7 @@ const part3 = """
95 if (supportedLocale.countryCode == locale.countryCode) {
96 return true;
97 }
98 - if (true != withCountry && (supportedLocale.countryCode == null || supportedLocale.countryCode.isEmpty)) {
98 + if (true != withCountry && (supportedLocale.countryCode == null || supportedLocale.countryCode!.isEmpty)) {
99 return true;
100 }
101 }
@@ -105,8 +105,8 @@ const part3 = """
105 }
106
107 String getLang(Locale l) => l == null
108 - ? null
109 - : l.countryCode != null && l.countryCode.isEmpty
108 + ? throw Exception('Incorrect local')
109 + : l.countryCode != null && l.countryCode!.isEmpty
110 ? l.languageCode
111 : l.toString();
112 """;
\ No newline at end of file
tool/utils/utils.dart
+1 -1
@@ -5,7 +5,7 @@ String normalizeKeyName(String key) {
5 final firstWord = parts.removeAt(0);
6 final capitalized = parts
7 .map((e) => toBeginningOfSentenceCase(e))
8 - .fold('', (String acc, String word) => acc + word);
8 + .fold('', (String acc, String? word) => acc + (word ?? ''));
9 return firstWord + capitalized;
10 }
11