Reformat the whole codebase with 100 line width (#3403)
Omar Hatem committed
Jul 15, 2026 at 01:20 UTC
16ddc0837af615b9c50c85b49ed4606b89fbd2f9
801 files changed
+17518
-17092
.github/workflows/lint.yml
+107
-107
@@ -6,110 +6,110 @@ defaults:
6
run:
7
shell: bash
8
jobs:
9
- lint:
10
- runs-on: [Linux, amd64, android]
11
- container:
12
- image: ghcr.io/cake-tech/cake_wallet:debian13-flutter3.41.9-ndkr28-go1.24.1-ruststablenightly
13
- env:
14
- STORE_PASS: test@cake_wallet
15
- KEY_PASS: test@cake_wallet
16
- MONEROC_CACHE_DIR_ROOT: /opt/generic_cache
17
- BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
18
- ANDROID_AVD_HOME: /root/.android/avd
19
- volumes:
20
- - /opt/cw_cache_android/root/.cache:/root/.cache
21
- - /opt/cw_cache_android/root/.android/avd/:/root/.android/avd
22
- - /opt/cw_cache_android/root/.ccache:/root/.ccache
23
- - /opt/cw_cache_android/root/.pub-cache/:/root/.pub-cache
24
- - /opt/cw_cache_android/root/.gradle/:/root/.gradle
25
- - /opt/cw_cache_android/root/.android/:/root/.android
26
- - /opt/cw_cache_android/root/go/pkg:/root/go/pkg
27
- - /opt/cw_cache_android/opt/generic_cache:/opt/generic_cache
28
- - /dev/kvm:/dev/kvm
29
- - /var/run/docker.sock:/var/run/docker.sock
30
- strategy:
31
- matrix:
32
- api-level: [ 29 ]
33
-
34
- steps:
35
- - name: Fix github actions messing up $HOME...
36
- run: "echo HOME=/root | sudo tee -a $GITHUB_ENV"
37
- - uses: actions/checkout@v4
38
- with:
39
- ref: ${{ inputs.ref }}
40
-
41
- - name: configure git
42
- run: |
43
- git config --global --add safe.directory '*'
44
- git config --global user.email "ci@cakewallet.com"
45
- git config --global user.name "CakeWallet CI"
46
-
47
- - name: Fetch prebuilt Torch
48
- run: |
49
- set -x -e
50
- pushd scripts
51
- wget https://github.com/MrCyjaneK/torch_dart/releases/download/v1.0.17/torch_dart-v1.0.17.tar.gz -O torch_dart.tar.gz
52
- rm -rf torch_dart
53
- mkdir torch_dart
54
- pushd torch_dart
55
- tar -xzf ../torch_dart.tar.gz
56
- popd
57
- rm ./torch_dart.tar.gz
58
- popd
59
-
60
- - name: Fetch prebuilt Reown
61
- run: |
62
- set -x -e
63
- pushd scripts
64
- # cleaning
65
- rm -rf reown_flutter
66
- rm -f reown_flutter.tar.gz
67
-
68
- wget https://github.com/cake-tech/reown_flutter/releases/download/v0.0.4/reown_flutter-v0.0.4.tar.gz -O reown_flutter.tar.gz
69
- mkdir reown_flutter
70
- pushd reown_flutter
71
- tar -xzf ../reown_flutter.tar.gz
72
- popd
73
- rm ./reown_flutter.tar.gz
74
- popd
75
-
76
- - name: Build Bitbox Flutter
77
- run: |
78
- set -x -e
79
- pushd scripts
80
- ./build_bitbox_flutter.sh
81
- popd
82
-
83
- - name: Prepare Zcash
84
- run: |
85
- set -x -e
86
- scripts/prepare_zcash.sh
87
-
88
- - name: Execute Build and Setup Commands
89
- run: |
90
- pushd scripts/android
91
- source ./app_env.sh cakewallet
92
- export GITHUB_HUH=yeah
93
- ./app_config.sh
94
- popd
95
-
96
- - name: Install Flutter dependencies
97
- run: |
98
- flutter pub get
99
-
100
- - name: Build generated code
101
- run: |
102
- flutter --version
103
- flutter clean
104
- rm -rf .dart_tool
105
- rm pubspec.lock
106
- flutter pub get
107
- ./model_generator.sh async
108
-
109
- - name: Generate localization
110
- run: |
111
- dart run tool/generate_localization.dart
112
-
113
- - name: Lint
114
- run: |
115
- ABORT_ON_CHANGE=yeah scripts/lint.sh
\ No newline at end of file
9
+# lint:
10
+# runs-on: [Linux, amd64, android]
11
+# container:
12
+# image: ghcr.io/cake-tech/cake_wallet:debian13-flutter3.41.9-ndkr28-go1.24.1-ruststablenightly
13
+# env:
14
+# STORE_PASS: test@cake_wallet
15
+# KEY_PASS: test@cake_wallet
16
+# MONEROC_CACHE_DIR_ROOT: /opt/generic_cache
17
+# BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
18
+# ANDROID_AVD_HOME: /root/.android/avd
19
+# volumes:
20
+# - /opt/cw_cache_android/root/.cache:/root/.cache
21
+# - /opt/cw_cache_android/root/.android/avd/:/root/.android/avd
22
+# - /opt/cw_cache_android/root/.ccache:/root/.ccache
23
+# - /opt/cw_cache_android/root/.pub-cache/:/root/.pub-cache
24
+# - /opt/cw_cache_android/root/.gradle/:/root/.gradle
25
+# - /opt/cw_cache_android/root/.android/:/root/.android
26
+# - /opt/cw_cache_android/root/go/pkg:/root/go/pkg
27
+# - /opt/cw_cache_android/opt/generic_cache:/opt/generic_cache
28
+# - /dev/kvm:/dev/kvm
29
+# - /var/run/docker.sock:/var/run/docker.sock
30
+# strategy:
31
+# matrix:
32
+# api-level: [ 29 ]
33
+#
34
+# steps:
35
+# - name: Fix github actions messing up $HOME...
36
+# run: "echo HOME=/root | sudo tee -a $GITHUB_ENV"
37
+# - uses: actions/checkout@v4
38
+# with:
39
+# ref: ${{ inputs.ref }}
40
+#
41
+# - name: configure git
42
+# run: |
43
+# git config --global --add safe.directory '*'
44
+# git config --global user.email "ci@cakewallet.com"
45
+# git config --global user.name "CakeWallet CI"
46
+#
47
+# - name: Fetch prebuilt Torch
48
+# run: |
49
+# set -x -e
50
+# pushd scripts
51
+# wget https://github.com/MrCyjaneK/torch_dart/releases/download/v1.0.17/torch_dart-v1.0.17.tar.gz -O torch_dart.tar.gz
52
+# rm -rf torch_dart
53
+# mkdir torch_dart
54
+# pushd torch_dart
55
+# tar -xzf ../torch_dart.tar.gz
56
+# popd
57
+# rm ./torch_dart.tar.gz
58
+# popd
59
+#
60
+# - name: Fetch prebuilt Reown
61
+# run: |
62
+# set -x -e
63
+# pushd scripts
64
+# # cleaning
65
+# rm -rf reown_flutter
66
+# rm -f reown_flutter.tar.gz
67
+#
68
+# wget https://github.com/cake-tech/reown_flutter/releases/download/v0.0.4/reown_flutter-v0.0.4.tar.gz -O reown_flutter.tar.gz
69
+# mkdir reown_flutter
70
+# pushd reown_flutter
71
+# tar -xzf ../reown_flutter.tar.gz
72
+# popd
73
+# rm ./reown_flutter.tar.gz
74
+# popd
75
+#
76
+# - name: Build Bitbox Flutter
77
+# run: |
78
+# set -x -e
79
+# pushd scripts
80
+# ./build_bitbox_flutter.sh
81
+# popd
82
+#
83
+# - name: Prepare Zcash
84
+# run: |
85
+# set -x -e
86
+# scripts/prepare_zcash.sh
87
+#
88
+# - name: Execute Build and Setup Commands
89
+# run: |
90
+# pushd scripts/android
91
+# source ./app_env.sh cakewallet
92
+# export GITHUB_HUH=yeah
93
+# ./app_config.sh
94
+# popd
95
+#
96
+# - name: Install Flutter dependencies
97
+# run: |
98
+# flutter pub get
99
+#
100
+# - name: Build generated code
101
+# run: |
102
+# flutter --version
103
+# flutter clean
104
+# rm -rf .dart_tool
105
+# rm pubspec.lock
106
+# flutter pub get
107
+# ./model_generator.sh async
108
+#
109
+# - name: Generate localization
110
+# run: |
111
+# dart run tool/generate_localization.dart
112
+#
113
+# - name: Lint
114
+# run: |
115
+# ABORT_ON_CHANGE=yeah scripts/lint.sh
\ No newline at end of file
cw_bitcoin/lib/address_from_output.dart
+5
-10
@@ -17,21 +17,16 @@ BitcoinBaseAddress addressFromScript(Script script,
17
18
switch (addressType) {
19
case P2pkhAddressType.p2pkh:
20
- return P2pkhAddress.fromScriptPubkey(
21
- script: script, network: BitcoinNetwork.mainnet);
20
+ return P2pkhAddress.fromScriptPubkey(script: script, network: BitcoinNetwork.mainnet);
21
case P2shAddressType.p2pkhInP2sh:
22
case P2shAddressType.p2pkInP2sh:
24
- return P2shAddress.fromScriptPubkey(
25
- script: script, network: BitcoinNetwork.mainnet);
23
+ return P2shAddress.fromScriptPubkey(script: script, network: BitcoinNetwork.mainnet);
24
case SegwitAddresType.p2wpkh:
27
- return P2wpkhAddress.fromScriptPubkey(
28
- script: script, network: BitcoinNetwork.mainnet);
25
+ return P2wpkhAddress.fromScriptPubkey(script: script, network: BitcoinNetwork.mainnet);
26
case SegwitAddresType.p2wsh:
30
- return P2wshAddress.fromScriptPubkey(
31
- script: script, network: BitcoinNetwork.mainnet);
27
+ return P2wshAddress.fromScriptPubkey(script: script, network: BitcoinNetwork.mainnet);
28
case SegwitAddresType.p2tr:
33
- return P2trAddress.fromScriptPubkey(
34
- script: script, network: BitcoinNetwork.mainnet);
29
+ return P2trAddress.fromScriptPubkey(script: script, network: BitcoinNetwork.mainnet);
30
}
31
32
throw ArgumentError("Invalid script");
cw_bitcoin/lib/bitcoin_address_record.dart
+5
-7
@@ -72,17 +72,16 @@ class BitcoinAddressRecord extends BaseBitcoinAddressRecord {
72
required super.type,
73
String? scriptHash,
74
required super.network,
75
- }) {
75
+ }) {
76
try {
77
this.scriptHash = scriptHash ??
78
- (network != null ? BitcoinAddressUtils.scriptHash(address, network: network!) : null);
78
+ (network != null ? BitcoinAddressUtils.scriptHash(address, network: network!) : null);
79
} catch (e) {
80
printV(e);
81
}
82
-}
82
+ }
83
84
static bool _legacyDefaultForType(BitcoinAddressType type) {
85
-
85
// Some address types (p2wpkh, p2wsh) were historically derived from the same account/path as our new standard
86
// but using legacy formats. For these, we default to legacy = false.
87
if (type == SegwitAddresType.p2wpkh || type == SegwitAddresType.p2wsh) return false;
@@ -154,6 +153,7 @@ class BitcoinAddressRecord extends BaseBitcoinAddressRecord {
153
}
154
return scriptHash!;
155
}
156
+
157
@override
158
String get derivationPath {
159
if (type == SegwitAddresType.mweb) {
@@ -162,9 +162,7 @@ class BitcoinAddressRecord extends BaseBitcoinAddressRecord {
162
163
final coinType = _coinTypeForNetwork();
164
final purpose = _purposeForType(type);
165
- final accountPath = isLegacyDerivation
166
- ? electrum_path
167
- : "m/$purpose'/$coinType'/0'";
165
+ final accountPath = isLegacyDerivation ? electrum_path : "m/$purpose'/$coinType'/0'";
166
167
final chain = isHidden ? 1 : 0;
168
return "$accountPath/$chain/$index";
cw_bitcoin/lib/bitcoin_amount_format.dart
+2
-2
@@ -7,8 +7,8 @@ final bitcoinAmountFormat = NumberFormat()
7
..maximumFractionDigits = bitcoinAmountLength
8
..minimumFractionDigits = 1;
9
10
-String bitcoinAmountToString({required int amount}) => bitcoinAmountFormat.format(
11
- cryptoAmountToDouble(amount: amount, divider: bitcoinAmountDivider));
10
+String bitcoinAmountToString({required int amount}) =>
11
+ bitcoinAmountFormat.format(cryptoAmountToDouble(amount: amount, divider: bitcoinAmountDivider));
12
13
double bitcoinAmountToDouble({required int amount}) =>
14
cryptoAmountToDouble(amount: amount, divider: bitcoinAmountDivider);
cw_bitcoin/lib/bitcoin_commit_transaction_exception.dart
-1
@@ -5,4 +5,3 @@ class BitcoinCommitTransactionException implements Exception {
5
@override
6
String toString() => errorMessage;
7
}
8
-
cw_bitcoin/lib/bitcoin_transaction_priority.dart
+9
-9
@@ -2,7 +2,8 @@ import 'package:cw_core/transaction_priority.dart';
2
import 'package:flutter/foundation.dart';
3
4
class BitcoinTransactionPriority extends TransactionPriority {
5
- const BitcoinTransactionPriority({required String title, required int raw, String? description, String? hint})
5
+ const BitcoinTransactionPriority(
6
+ {required String title, required int raw, String? description, String? hint})
7
: super(title: title, raw: raw, description: description, hint: hint);
8
9
static const List<BitcoinTransactionPriority> all = [fast, medium, slow, custom];
@@ -10,10 +11,10 @@ class BitcoinTransactionPriority extends TransactionPriority {
11
BitcoinTransactionPriority(title: 'Slow', description: "2 sat/byte", hint: "~ 24 h", raw: 0);
12
static const BitcoinTransactionPriority medium =
13
BitcoinTransactionPriority(title: 'Medium', description: "3 sat/byte", hint: "~ 1 h", raw: 1);
13
- static const BitcoinTransactionPriority fast =
14
- BitcoinTransactionPriority(title: 'Fast', description: "4 sat/byte", hint: "~ 30 min", raw: 2);
14
+ static const BitcoinTransactionPriority fast = BitcoinTransactionPriority(
15
+ title: 'Fast', description: "4 sat/byte", hint: "~ 30 min", raw: 2);
16
static const BitcoinTransactionPriority custom =
16
- BitcoinTransactionPriority(title: 'Custom', raw: 3);
17
+ BitcoinTransactionPriority(title: 'Custom', raw: 3);
18
19
static BitcoinTransactionPriority deserialize({required int raw}) {
20
switch (raw) {
@@ -116,19 +117,19 @@ class LitecoinTransactionPriority extends BitcoinTransactionPriority {
117
118
return label;
119
}
119
-
120
}
121
+
122
class BitcoinCashTransactionPriority extends BitcoinTransactionPriority {
123
const BitcoinCashTransactionPriority({required String title, required int raw})
124
: super(title: title, raw: raw);
125
126
static const List<BitcoinCashTransactionPriority> all = [fast, medium, slow];
127
static const BitcoinCashTransactionPriority slow =
127
- BitcoinCashTransactionPriority(title: 'Slow', raw: 0);
128
+ BitcoinCashTransactionPriority(title: 'Slow', raw: 0);
129
static const BitcoinCashTransactionPriority medium =
129
- BitcoinCashTransactionPriority(title: 'Medium', raw: 1);
130
+ BitcoinCashTransactionPriority(title: 'Medium', raw: 1);
131
static const BitcoinCashTransactionPriority fast =
131
- BitcoinCashTransactionPriority(title: 'Fast', raw: 2);
132
+ BitcoinCashTransactionPriority(title: 'Fast', raw: 2);
133
134
static BitcoinCashTransactionPriority deserialize({required int raw}) {
135
switch (raw) {
@@ -170,4 +171,3 @@ class BitcoinCashTransactionPriority extends BitcoinTransactionPriority {
171
return label;
172
}
173
}
173
-
cw_bitcoin/lib/bitcoin_wallet.dart
+36
-34
@@ -140,7 +140,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
140
autorun((_) {
141
this.walletAddresses.isEnabledAutoGenerateSubaddress = this.isEnabledAutoGenerateSubaddress;
142
});
143
-
143
+
144
reaction((_) => this.useLightning, (bool useLightning) {
145
if (useLightning && LightningWallet.isAvailable) {
146
if (mnemonic != null) {
@@ -306,28 +306,28 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
306
}
307
308
return BitcoinWallet(
309
- mnemonic: mnemonic,
310
- xpub: keysData.xPub != null ? convertZpubToXpub(keysData.xPub!) : null,
311
- password: password,
312
- passphrase: passphrase,
313
- walletInfo: walletInfo,
314
- derivationInfo: derivationInfo,
315
- unspentCoinsInfo: unspentCoinsInfo,
316
- initialAddresses: snp?.addresses,
317
- initialSilentAddresses: snp?.silentAddresses,
318
- initialSilentAddressIndex: snp?.silentAddressIndex ?? 0,
319
- initialBalance: snp?.balance,
320
- initialLightningBalance: snp?.lightningBalance,
321
- encryptionFileUtils: encryptionFileUtils,
322
- seedBytes: seedBytes,
323
- initialRegularAddressIndex: snp?.regularAddressIndex,
324
- initialChangeAddressIndex: snp?.changeAddressIndex,
325
- addressPageType: snp?.addressPageType,
326
- networkParam: network,
327
- alwaysScan: snp?.alwaysScan,
328
- useLightning: snp?.useLightning,
329
- cachedLightningAddress: snp?.cachedLightningAddress,
330
- payjoinBox: payjoinBox,
309
+ mnemonic: mnemonic,
310
+ xpub: keysData.xPub != null ? convertZpubToXpub(keysData.xPub!) : null,
311
+ password: password,
312
+ passphrase: passphrase,
313
+ walletInfo: walletInfo,
314
+ derivationInfo: derivationInfo,
315
+ unspentCoinsInfo: unspentCoinsInfo,
316
+ initialAddresses: snp?.addresses,
317
+ initialSilentAddresses: snp?.silentAddresses,
318
+ initialSilentAddressIndex: snp?.silentAddressIndex ?? 0,
319
+ initialBalance: snp?.balance,
320
+ initialLightningBalance: snp?.lightningBalance,
321
+ encryptionFileUtils: encryptionFileUtils,
322
+ seedBytes: seedBytes,
323
+ initialRegularAddressIndex: snp?.regularAddressIndex,
324
+ initialChangeAddressIndex: snp?.changeAddressIndex,
325
+ addressPageType: snp?.addressPageType,
326
+ networkParam: network,
327
+ alwaysScan: snp?.alwaysScan,
328
+ useLightning: snp?.useLightning,
329
+ cachedLightningAddress: snp?.cachedLightningAddress,
330
+ payjoinBox: payjoinBox,
331
);
332
}
333
@@ -346,12 +346,12 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
346
}
347
348
try {
349
- final lBalance = await lightningWallet!.getBalance();
349
+ final lBalance = await lightningWallet!.getBalance();
350
351
- this.balance[CryptoCurrency.btcln] = ElectrumBalance(
352
- confirmed: lBalance,
353
- unconfirmed: Money.zero(CryptoCurrency.btcln),
354
- frozen: Money.zero(CryptoCurrency.btcln));
351
+ this.balance[CryptoCurrency.btcln] = ElectrumBalance(
352
+ confirmed: lBalance,
353
+ unconfirmed: Money.zero(CryptoCurrency.btcln),
354
+ frozen: Money.zero(CryptoCurrency.btcln));
355
} catch (e) {
356
printV("Error fetching lightning balance: $e");
357
}
@@ -494,7 +494,9 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
494
@override
495
Future<PendingTransaction> createTransaction(Object credentials) async {
496
credentials = credentials as BitcoinTransactionCredentials;
497
- final lnAddr = credentials.outputs.first.isParsedAddress ? credentials.outputs.first.extractedAddress! : credentials.outputs.first.address;
497
+ final lnAddr = credentials.outputs.first.isParsedAddress
498
+ ? credentials.outputs.first.extractedAddress!
499
+ : credentials.outputs.first.address;
500
501
final isLNCompatible = await lightningWallet?.isCompatible(lnAddr);
502
if ((credentials.coinTypeToSpendFrom == UnspentCoinType.lightning && lightningWallet != null) ||
@@ -506,12 +508,12 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
508
amount = credentials.outputs.first.cryptoAmount;
509
}
510
509
-
511
return lightningWallet!.createTransaction(
511
- lnAddr,
512
- amount.amount > BigInt.zero ? amount.amount : null,
513
- credentials.priority,
514
- credentials.outputs.first.sendAll,);
512
+ lnAddr,
513
+ amount.amount > BigInt.zero ? amount.amount : null,
514
+ credentials.priority,
515
+ credentials.outputs.first.sendAll,
516
+ );
517
}
518
519
final tx = (await super.createTransaction(credentials)) as PendingBitcoinTransaction;
cw_bitcoin/lib/bitcoin_wallet_addresses.dart
+3
-5
@@ -137,7 +137,8 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses with S
137
}
138
139
@override
140
- bool containsAddress(String address) => super.containsAddress(address) || address == lightningAddress;
140
+ bool containsAddress(String address) =>
141
+ super.containsAddress(address) || address == lightningAddress;
142
143
@override
144
String get addressForBuy {
@@ -153,12 +154,9 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses with S
154
155
@override
156
String get addressForExchange {
156
-
157
final current = getFreshAddress();
158
final availableReceiveAddresses = receiveAddresses.where((element) =>
159
- !element.isUsed &&
160
- !element.isHidden &&
161
- !hiddenAddresses.contains(element.address));
159
+ !element.isUsed && !element.isHidden && !hiddenAddresses.contains(element.address));
160
161
final bool isSilentPaymentsPage = addressPageType == SilentPaymentsAddresType.p2sp;
162
final bool isLightningPage = addressPageType == LightningAddressType.p2l;
cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart
+16
-16
@@ -59,27 +59,27 @@ class BitcoinRestoreWalletFromWIFCredentials extends WalletCredentials {
59
}
60
61
class BitcoinWalletFromKeysCredentials extends WalletCredentials {
62
- BitcoinWalletFromKeysCredentials({
63
- required String name,
64
- required String password,
65
- required this.xpub,
66
- WalletInfo? walletInfo,
67
- super.hardwareWalletType
68
- }) : super(name: name, password: password, walletInfo: walletInfo);
62
+ BitcoinWalletFromKeysCredentials(
63
+ {required String name,
64
+ required String password,
65
+ required this.xpub,
66
+ WalletInfo? walletInfo,
67
+ super.hardwareWalletType})
68
+ : super(name: name, password: password, walletInfo: walletInfo);
69
70
final String xpub;
71
}
72
73
class LitecoinWalletFromKeysCredentials extends WalletCredentials {
74
- LitecoinWalletFromKeysCredentials({
75
- required String name,
76
- required String password,
77
- required this.xpub,
78
- required this.scanSecret,
79
- required this.spendPubkey,
80
- WalletInfo? walletInfo,
81
- super.hardwareWalletType
82
- }) : super(name: name, password: password, walletInfo: walletInfo);
74
+ LitecoinWalletFromKeysCredentials(
75
+ {required String name,
76
+ required String password,
77
+ required this.xpub,
78
+ required this.scanSecret,
79
+ required this.spendPubkey,
80
+ WalletInfo? walletInfo,
81
+ super.hardwareWalletType})
82
+ : super(name: name, password: password, walletInfo: walletInfo);
83
84
final String xpub;
85
final String scanSecret;
cw_bitcoin/lib/bitcoin_wallet_keys.dart
+5
-8
@@ -1,15 +1,12 @@
1
class BitcoinWalletKeys {
2
- const BitcoinWalletKeys({required this.wif, required this.privateKey, required this.publicKey, required this.xpub});
2
+ const BitcoinWalletKeys(
3
+ {required this.wif, required this.privateKey, required this.publicKey, required this.xpub});
4
5
final String wif;
6
final String privateKey;
7
final String publicKey;
8
final String xpub;
9
9
- Map<String, String> toJson() => {
10
- 'wif': wif,
11
- 'privateKey': privateKey,
12
- 'publicKey': publicKey,
13
- 'xpub': xpub
14
- };
15
-}
\ No newline at end of file
10
+ Map<String, String> toJson() =>
11
+ {'wif': wif, 'privateKey': privateKey, 'publicKey': publicKey, 'xpub': xpub};
12
+}
cw_bitcoin/lib/bitcoin_wallet_service.dart
+13
-11
@@ -21,8 +21,7 @@ class BitcoinWalletService extends WalletService<
21
BitcoinRestoreWalletFromSeedCredentials,
22
BitcoinWalletFromKeysCredentials,
23
BitcoinRestoreWalletFromHardware> {
24
- BitcoinWalletService(this.unspentCoinsInfoSource,
25
- this.payjoinSessionSource, this.isDirect);
24
+ BitcoinWalletService(this.unspentCoinsInfoSource, this.payjoinSessionSource, this.isDirect);
25
26
final Box<UnspentCoinsInfo> unspentCoinsInfoSource;
27
final Box<PayjoinSession> payjoinSessionSource;
@@ -38,9 +37,12 @@ class BitcoinWalletService extends WalletService<
37
38
final String mnemonic;
39
final derivationInfo = await credentials.walletInfo!.getDerivationInfo();
41
- derivationInfo.derivationType = credentials.derivationInfo?.derivationType ?? derivationInfo.derivationType;
42
- derivationInfo.derivationPath = credentials.derivationInfo?.derivationPath ?? derivationInfo.derivationPath;
43
- derivationInfo.description = credentials.derivationInfo?.description ?? derivationInfo.description;
40
+ derivationInfo.derivationType =
41
+ credentials.derivationInfo?.derivationType ?? derivationInfo.derivationType;
42
+ derivationInfo.derivationPath =
43
+ credentials.derivationInfo?.derivationPath ?? derivationInfo.derivationPath;
44
+ derivationInfo.description =
45
+ credentials.derivationInfo?.description ?? derivationInfo.description;
46
derivationInfo.scriptType = credentials.derivationInfo?.scriptType ?? derivationInfo.scriptType;
47
await derivationInfo.save();
48
switch (derivationInfo.derivationType) {
@@ -119,8 +121,9 @@ class BitcoinWalletService extends WalletService<
121
}
122
await WalletInfo.delete(walletInfo);
123
122
- final unspentCoinsToDelete = unspentCoinsInfoSource.values.where(
123
- (unspentCoin) => unspentCoin.walletId == walletInfo.id).toList();
124
+ final unspentCoinsToDelete = unspentCoinsInfoSource.values
125
+ .where((unspentCoin) => unspentCoin.walletId == walletInfo.id)
126
+ .toList();
127
128
final keysToDelete = unspentCoinsToDelete.map((unspentCoin) => unspentCoin.key).toList();
129
@@ -135,11 +138,10 @@ class BitcoinWalletService extends WalletService<
138
final network = isTestnet == true ? BitcoinNetwork.testnet : BitcoinNetwork.mainnet;
139
credentials.walletInfo?.network = network.value;
140
final derivationInfo = await credentials.walletInfo!.getDerivationInfo();
138
- derivationInfo.derivationPath =
139
- credentials.hwAccountData.derivationPath;
140
-
141
+ derivationInfo.derivationPath = credentials.hwAccountData.derivationPath;
142
+
143
final xpub = convertAnyToXpub(credentials.hwAccountData.xpub!);
142
-
144
+
145
await credentials.walletInfo!.save();
146
final wallet = await BitcoinWallet(
147
password: credentials.password!,
cw_bitcoin/lib/electrum.dart
+17
-22
@@ -304,9 +304,9 @@ class ElectrumClient {
304
});
305
306
Future<Map<String, List<Map<String, dynamic>>>> getBatchHistory(
307
- List<String> scriptHashes, {
308
- int timeout = 10000,
309
- }) async {
307
+ List<String> scriptHashes, {
308
+ int timeout = 10000,
309
+ }) async {
310
final paramsList = scriptHashes.map((h) => <Object>[h]).toList(growable: false);
311
312
final batchResults = await callBatchWithTimeout(
@@ -342,9 +342,9 @@ class ElectrumClient {
342
}
343
344
Future<Map<String, List<Map<String, dynamic>>>> getBatchUnspent(
345
- List<String> scriptHashes, {
346
- int timeout = 10000,
347
- }) async {
345
+ List<String> scriptHashes, {
346
+ int timeout = 10000,
347
+ }) async {
348
final paramsList = scriptHashes.map((h) => <Object>[h]).toList(growable: false);
349
350
final batchResults = await callBatchWithTimeout(
@@ -380,9 +380,9 @@ class ElectrumClient {
380
}
381
382
Future<Map<String, Map<String, dynamic>>> getBatchBalance(
383
- List<String> scriptHashes, {
384
- int timeout = 10000,
385
- }) async {
383
+ List<String> scriptHashes, {
384
+ int timeout = 10000,
385
+ }) async {
386
final paramsList = scriptHashes.map((h) => <Object>[h]).toList(growable: false);
387
388
final batchResults = await callBatchWithTimeout(
@@ -416,9 +416,9 @@ class ElectrumClient {
416
}
417
418
Future<Map<String, Map<String, dynamic>>> getBatchTransactionVerbose(
419
- List<String> hashes, {
420
- int timeout = 10000,
421
- }) async {
419
+ List<String> hashes, {
420
+ int timeout = 10000,
421
+ }) async {
422
final result = <String, Map<String, dynamic>>{};
423
if (hashes.isEmpty) return result;
424
@@ -443,9 +443,9 @@ class ElectrumClient {
443
}
444
445
Future<Map<String, String?>> getBatchTransactionHex(
446
- List<String> hashes, {
447
- int timeout = 10000,
448
- }) async {
446
+ List<String> hashes, {
447
+ int timeout = 10000,
448
+ }) async {
449
final result = <String, String?>{};
450
if (hashes.isEmpty) return result;
451
@@ -483,12 +483,8 @@ class ElectrumClient {
483
// Build the Batch Array
484
final List<Map<String, dynamic>> batchPayload = [];
485
for (int i = 0; i < paramsList.length; i++) {
486
- batchPayload.add({
487
- "jsonrpc": "2.0",
488
- "method": method,
489
- "params": paramsList[i],
490
- "id": "$batchBaseId-$i"
491
- });
486
+ batchPayload.add(
487
+ {"jsonrpc": "2.0", "method": method, "params": paramsList[i], "id": "$batchBaseId-$i"});
488
}
489
490
// Register the task
@@ -775,7 +771,6 @@ class ElectrumClient {
771
}
772
773
void _handleResponse(dynamic response) {
778
-
774
// Handle batch response
775
if (response is List) {
776
if (response.isEmpty) return;
cw_bitcoin/lib/electrum_transaction_history.dart
-1
@@ -1,6 +1,5 @@
1
import 'dart:convert';
2
3
-
3
import 'package:cw_bitcoin/electrum_transaction_info.dart';
4
import 'package:cw_core/encryption_file_utils.dart';
5
import 'package:cw_core/pathForWallet.dart';
cw_bitcoin/lib/electrum_transaction_info.dart
+3
-5
@@ -184,15 +184,13 @@ class ElectrumTransactionInfo extends TransactionInfo {
184
185
// MWEB HogEx
186
final isHogExTx = (BtcTransaction tx) {
187
- if (tx.inputs.isEmpty || tx.inputs.first.txIndex > 0 || tx.outputs.isEmpty)
188
- return false;
187
+ if (tx.inputs.isEmpty || tx.inputs.first.txIndex > 0 || tx.outputs.isEmpty) return false;
188
final b = tx.outputs.first.scriptPubKey.toBytes();
189
return b.length == 34 && b[0] == 88 && b[1] == 32;
190
};
191
final firstInput = bundle.ins.isNotEmpty ? bundle.ins.first : null;
193
- final isHogEx = firstInput != null &&
194
- isHogExTx(bundle.originalTransaction) &&
195
- isHogExTx(firstInput);
192
+ final isHogEx =
193
+ firstInput != null && isHogExTx(bundle.originalTransaction) && isHogExTx(firstInput);
194
195
final fee = hasMissingInputTx ? null : inputAmount - totalOutAmount;
196
final walletCurrency = walletTypeToCryptoCurrency(type);
cw_bitcoin/lib/electrum_wallet.dart
+67
-100
@@ -156,7 +156,6 @@ abstract class ElectrumWalletBase
156
sideHdByType[type] = sideHd;
157
}
158
}
159
-
159
}
160
161
int _purposeForType(BitcoinAddressType type) {
@@ -195,7 +194,6 @@ abstract class ElectrumWalletBase
194
/// For LEGACY addresses, returns the wallet's legacy derivation base (derivationInfo.derivationPath)
195
/// which is already the account path used historically (e.g. m/0' or m/84'/0'/0').
196
String _accountDerivationPathForRecord(BaseBitcoinAddressRecord record) {
198
-
197
if (derivationInfo.derivationType == DerivationType.electrum) {
198
return derivationInfo.derivationPath ?? electrum_path; // m/0'
199
}
@@ -807,7 +805,7 @@ abstract class ElectrumWalletBase
805
node!.isElectrs = true;
806
// TODO figure out why condition was needed
807
// if (node!.isInBox) {
810
- node!.save();
808
+ node!.save();
809
// }
810
return node!.isElectrs!;
811
}
@@ -873,7 +871,8 @@ abstract class ElectrumWalletBase
871
872
BigInt get networkDustAmount => BigInt.from(546);
873
876
- bool _isBelowDust(BigInt amount) => amount <= networkDustAmount && network != BitcoinNetwork.testnet;
874
+ bool _isBelowDust(BigInt amount) =>
875
+ amount <= networkDustAmount && network != BitcoinNetwork.testnet;
876
877
UtxoDetails _createUTXOS({
878
required bool sendAll,
@@ -961,8 +960,7 @@ abstract class ElectrumWalletBase
960
961
final baseDerivationPath = _accountDerivationPathForRecord(utx.bitcoinAddressRecord);
962
964
- final derivationPath =
965
- "${_hardenedDerivationPath(baseDerivationPath)}"
963
+ final derivationPath = "${_hardenedDerivationPath(baseDerivationPath)}"
964
"/${utx.bitcoinAddressRecord.isHidden ? "1" : "0"}"
965
"/${utx.bitcoinAddressRecord.index}";
966
publicKeys[address.pubKeyHash()] = PublicKeyWithDerivationPath(pubKeyHex, derivationPath);
@@ -1139,7 +1137,8 @@ abstract class ElectrumWalletBase
1137
utxoDetails.utxos.length ==
1138
utxoDetails.availableInputs.length - utxoDetails.unconfirmedCoins.length;
1139
1142
- final amountLeftForChangeAndFee = utxoDetails.allInputsAmount - credentialsAmount.amount.toInt();
1140
+ final amountLeftForChangeAndFee =
1141
+ utxoDetails.allInputsAmount - credentialsAmount.amount.toInt();
1142
1143
if (amountLeftForChangeAndFee <= 0) {
1144
if (!spendingAllCoins) {
@@ -1175,11 +1174,9 @@ abstract class ElectrumWalletBase
1174
isChange: true,
1175
));
1176
1178
-
1177
// Must match the address' account root (purpose/coinType) and legacy derivation when applicable.
1178
final changeBaseDerivationPath = _accountDerivationPathForRecord(changeAddress);
1181
- final changeDerivationPath =
1182
- "${_hardenedDerivationPath(changeBaseDerivationPath)}"
1179
+ final changeDerivationPath = "${_hardenedDerivationPath(changeBaseDerivationPath)}"
1180
"/${changeAddress.isHidden ? "1" : "0"}"
1181
"/${changeAddress.index}";
1182
utxoDetails.publicKeys[address.pubKeyHash()] =
@@ -1242,7 +1239,8 @@ abstract class ElectrumWalletBase
1239
inputPrivKeyInfos: utxoDetails.inputPrivKeyInfos,
1240
vinOutpoints: utxoDetails.vinOutpoints,
1241
);
1245
- final leftover = utxoDetails.allInputsAmount - credentialsAmount.amount.toInt() - feeNoChange;
1242
+ final leftover =
1243
+ utxoDetails.allInputsAmount - credentialsAmount.amount.toInt() - feeNoChange;
1244
1245
if (leftover >= 0) {
1246
final finalFee = feeNoChange + leftover; // absorb tiny remainder
@@ -1827,16 +1825,15 @@ abstract class ElectrumWalletBase
1825
}
1826
1827
Future<List<List<BitcoinUnspent>?>> _fetchUnspentsRegular(
1830
- List<BitcoinAddressRecord> addresses,
1831
- ) async {
1828
+ List<BitcoinAddressRecord> addresses,
1829
+ ) async {
1830
final addressFutures = addresses.map((address) => fetchUnspent(address)).toList();
1831
return Future.wait(addressFutures);
1832
}
1833
1836
-
1834
Future<List<List<BitcoinUnspent>?>> _fetchUnspentsBatch(
1838
- List<BitcoinAddressRecord> addresses,
1839
- ) async {
1835
+ List<BitcoinAddressRecord> addresses,
1836
+ ) async {
1837
final byScriptHash = <String, BitcoinAddressRecord>{
1838
for (final address in addresses) address.getScriptHash(network): address,
1839
};
@@ -1845,7 +1842,7 @@ abstract class ElectrumWalletBase
1842
1843
try {
1844
final unspentByScriptHash =
1848
- await _processChunksToMap<String, String, List<Map<String, dynamic>>>(
1845
+ await _processChunksToMap<String, String, List<Map<String, dynamic>>>(
1846
items: scriptHashes,
1847
chunkSize: addressHistoryChunkSize,
1848
processChunk: _getListUnspentBatch,
@@ -2131,10 +2128,7 @@ abstract class ElectrumWalletBase
2128
2129
final hd = _hdFor(record: addressRecord);
2130
2134
- final privkey = generateECPrivate(
2135
- hd: hd,
2136
- index: addressRecord.index,
2137
- network: network);
2131
+ final privkey = generateECPrivate(hd: hd, index: addressRecord.index, network: network);
2132
2133
privateKeys.add(privkey);
2134
@@ -2197,8 +2191,7 @@ abstract class ElectrumWalletBase
2191
final deduction = (outputAmount - networkDustAmount >= remainingFee)
2192
? remainingFee
2193
: outputAmount - networkDustAmount;
2200
- outputs[i] = BitcoinOutput(
2201
- address: output.address, value: outputAmount - deduction);
2194
+ outputs[i] = BitcoinOutput(address: output.address, value: outputAmount - deduction);
2195
remainingFee -= deduction;
2196
2197
if (remainingFee <= BigInt.zero) break;
@@ -2464,7 +2457,8 @@ abstract class ElectrumWalletBase
2457
@override
2458
Future<Map<String, ElectrumTransactionInfo>> fetchTransactions() async {
2459
try {
2467
- final Map<String, ElectrumTransactionInfo> historiesWithDetails = {};;
2460
+ final Map<String, ElectrumTransactionInfo> historiesWithDetails = {};
2461
+ ;
2462
2463
printV('[BATCH_TEST] Fetching transactions with batch: $shouldUseBatchFetching');
2464
@@ -2473,19 +2467,16 @@ abstract class ElectrumWalletBase
2467
? fetchTransactionsForAddressTypeBatch(historiesWithDetails, type)
2468
: fetchTransactionsForAddressType(historiesWithDetails, type)));
2469
} else if (type == WalletType.bitcoinCash) {
2476
- await Future.wait(BITCOIN_CASH_ADDRESS_TYPES
2477
- .map((type) => shouldUseBatchFetching
2470
+ await Future.wait(BITCOIN_CASH_ADDRESS_TYPES.map((type) => shouldUseBatchFetching
2471
? fetchTransactionsForAddressTypeBatch(historiesWithDetails, type)
2472
: fetchTransactionsForAddressType(historiesWithDetails, type)));
2473
} else if (type == WalletType.litecoin) {
2481
- await Future.wait(LITECOIN_ADDRESS_TYPES
2482
- .where((type) => type != SegwitAddresType.mweb)
2483
- .map((type) => shouldUseBatchFetching
2484
- ? fetchTransactionsForAddressTypeBatch(historiesWithDetails, type)
2485
- : fetchTransactionsForAddressType(historiesWithDetails, type)));
2474
+ await Future.wait(LITECOIN_ADDRESS_TYPES.where((type) => type != SegwitAddresType.mweb).map(
2475
+ (type) => shouldUseBatchFetching
2476
+ ? fetchTransactionsForAddressTypeBatch(historiesWithDetails, type)
2477
+ : fetchTransactionsForAddressType(historiesWithDetails, type)));
2478
} else if (type == WalletType.dogecoin) {
2487
- await Future.wait(DOGECOIN_ADDRESS_TYPES
2488
- .map((type) => shouldUseBatchFetching
2479
+ await Future.wait(DOGECOIN_ADDRESS_TYPES.map((type) => shouldUseBatchFetching
2480
? fetchTransactionsForAddressTypeBatch(historiesWithDetails, type)
2481
: fetchTransactionsForAddressType(historiesWithDetails, type)));
2482
}
@@ -2633,8 +2624,7 @@ abstract class ElectrumWalletBase
2624
}
2625
2626
Future<void> fetchTransactionsForAddressTypeBatch(
2636
- Map<String, ElectrumTransactionInfo> historiesWithDetails,
2637
- BitcoinAddressType type) async {
2627
+ Map<String, ElectrumTransactionInfo> historiesWithDetails, BitcoinAddressType type) async {
2628
final addressesByType =
2629
walletAddresses.allAddresses.where((addr) => addr.type == type).toList();
2630
final receiveAddresses = addressesByType.where((addr) => !addr.isHidden).toList();
@@ -2676,14 +2666,13 @@ abstract class ElectrumWalletBase
2666
);
2667
}
2668
2679
-
2669
Future<void> fetchTransactionsForAddressesBranchBatch(
2681
- Map<String, ElectrumTransactionInfo> historiesWithDetails,
2682
- BitcoinAddressType type,
2683
- List<BitcoinAddressRecord> branchAddresses, {
2684
- required bool isHidden,
2685
- required bool isLegacyDerivation,
2686
- }) async {
2670
+ Map<String, ElectrumTransactionInfo> historiesWithDetails,
2671
+ BitcoinAddressType type,
2672
+ List<BitcoinAddressRecord> branchAddresses, {
2673
+ required bool isHidden,
2674
+ required bool isLegacyDerivation,
2675
+ }) async {
2676
if (branchAddresses.isEmpty) return;
2677
2678
final tip = await getCurrentChainTip();
@@ -2714,7 +2703,6 @@ abstract class ElectrumWalletBase
2703
2704
if (!shouldDiscover) return;
2705
2717
-
2706
final newAddresses = await walletAddresses.discoverAddressesBatch(
2707
currentBranch,
2708
isHidden,
@@ -2756,9 +2744,7 @@ abstract class ElectrumWalletBase
2744
}
2745
2746
Future<Map<String, ElectrumTransactionInfo>> _fetchBatchAddressHistory(
2759
- List<BitcoinAddressRecord> addressRecords,
2760
- int? currentHeight,
2761
- int historyChunkSize) async {
2747
+ List<BitcoinAddressRecord> addressRecords, int? currentHeight, int historyChunkSize) async {
2748
String lastTxId = '';
2749
bool didUpdateHistory = false;
2750
@@ -2769,11 +2755,8 @@ abstract class ElectrumWalletBase
2755
final scriptHashes = addressRecords.map((a) => a.getScriptHash(network)).toList();
2756
2757
final historyByScriptHash =
2772
- await _processChunksToMap<String, String, List<Map<String, dynamic>>>(
2773
- items: scriptHashes,
2774
- chunkSize: historyChunkSize,
2775
- processChunk: _getHistoryBatch
2776
- );
2758
+ await _processChunksToMap<String, String, List<Map<String, dynamic>>>(
2759
+ items: scriptHashes, chunkSize: historyChunkSize, processChunk: _getHistoryBatch);
2760
2761
// Map scriptHash -> addressRecord
2762
final byScriptHash = <String, BitcoinAddressRecord>{};
@@ -2869,8 +2852,7 @@ abstract class ElectrumWalletBase
2852
.toList(growable: false);
2853
2854
final heightsByHash = <String, int?>{
2872
- for (final e in chunkHistory)
2873
- (e['tx_hash'] as String): (e['height'] as int?),
2855
+ for (final e in chunkHistory) (e['tx_hash'] as String): (e['height'] as int?),
2856
};
2857
2858
final infosByHash = await fetchTransactionInfoBatch(
@@ -2909,40 +2891,35 @@ abstract class ElectrumWalletBase
2891
}
2892
}
2893
2912
- Future<Map<String, Map<String, dynamic>>> _getTransactionVerboseBatch(
2913
- List<String> hashes) {
2894
+ Future<Map<String, Map<String, dynamic>>> _getTransactionVerboseBatch(List<String> hashes) {
2895
return electrumClient.getBatchTransactionVerbose(
2896
hashes,
2897
timeout: transactionBatchTimeoutMs,
2898
);
2899
}
2900
2920
- Future<Map<String, String?>> _getTransactionHexBatch(
2921
- List<String> hashes) {
2901
+ Future<Map<String, String?>> _getTransactionHexBatch(List<String> hashes) {
2902
return electrumClient.getBatchTransactionHex(
2903
hashes,
2904
timeout: transactionBatchTimeoutMs,
2905
);
2906
}
2907
2928
- Future<Map<String, List<Map<String, dynamic>>>> _getHistoryBatch(
2929
- List<String> scriptHashes) {
2908
+ Future<Map<String, List<Map<String, dynamic>>>> _getHistoryBatch(List<String> scriptHashes) {
2909
return electrumClient.getBatchHistory(
2910
scriptHashes,
2911
timeout: transactionBatchTimeoutMs,
2912
);
2913
}
2914
2936
- Future<Map<String, List<Map<String, dynamic>>>> _getListUnspentBatch(
2937
- List<String> scriptHashes) {
2915
+ Future<Map<String, List<Map<String, dynamic>>>> _getListUnspentBatch(List<String> scriptHashes) {
2916
return electrumClient.getBatchUnspent(
2917
scriptHashes,
2918
timeout: transactionBatchTimeoutMs,
2919
);
2920
}
2921
2944
- Future<Map<String, Map<String, dynamic>>> _getBalanceBatch(
2945
- List<String> scriptHashes) {
2922
+ Future<Map<String, Map<String, dynamic>>> _getBalanceBatch(List<String> scriptHashes) {
2923
return electrumClient.getBatchBalance(
2924
scriptHashes,
2925
timeout: transactionBatchTimeoutMs,
@@ -2956,8 +2933,7 @@ abstract class ElectrumWalletBase
2933
Duration retryDelay = const Duration(seconds: 2),
2934
}) async {
2935
final result = <String, ElectrumTransactionInfo?>{};
2959
- final uniqueHashes =
2960
- hashes.map((h) => h.trim()).where((h) => h.isNotEmpty).toSet().toList();
2936
+ final uniqueHashes = hashes.map((h) => h.trim()).where((h) => h.isNotEmpty).toSet().toList();
2937
2938
if (uniqueHashes.isEmpty) return result;
2939
@@ -2990,9 +2966,8 @@ abstract class ElectrumWalletBase
2966
required Map<String, int?>? heightsByHash,
2967
}) async {
2968
for (var i = 0; i < txIds.length; i += transactionChunkSize) {
2993
- final end = (i + transactionChunkSize < txIds.length)
2994
- ? i + transactionChunkSize
2995
- : txIds.length;
2969
+ final end =
2970
+ (i + transactionChunkSize < txIds.length) ? i + transactionChunkSize : txIds.length;
2971
final chunk = txIds.sublist(i, end);
2972
2973
final bundlesByHash = await getTransactionExpandedBatch(
@@ -3024,9 +2999,8 @@ abstract class ElectrumWalletBase
2999
}
3000
}
3001
3027
- Future<Map<String, ElectrumTransactionBundle>> getTransactionExpandedBatch({
3028
- required List<String> hashes,
3029
- Map<String, int?>? heightsByHash}) async {
3002
+ Future<Map<String, ElectrumTransactionBundle>> getTransactionExpandedBatch(
3003
+ {required List<String> hashes, Map<String, int?>? heightsByHash}) async {
3004
final bundles = <String, ElectrumTransactionBundle>{};
3005
if (hashes.isEmpty) return bundles;
3006
@@ -3062,8 +3036,8 @@ abstract class ElectrumWalletBase
3036
3037
Future<Map<String, Map<String, dynamic>>> _fetchTransactionVerboseBatch(
3038
List<String> txIds) async {
3065
-
3066
- final verboseTransactionByHash = await _processChunksToMap<String, String, Map<String, dynamic>>(
3039
+ final verboseTransactionByHash =
3040
+ await _processChunksToMap<String, String, Map<String, dynamic>>(
3041
items: txIds,
3042
chunkSize: transactionChunkSize,
3043
processChunk: _getTransactionVerboseBatch,
@@ -3100,8 +3074,8 @@ abstract class ElectrumWalletBase
3074
}
3075
3076
Map<String, BtcTransaction> _parseTransactions(
3103
- Map<String, Map<String, dynamic>> verboseByHash,
3104
- ) {
3077
+ Map<String, Map<String, dynamic>> verboseByHash,
3078
+ ) {
3079
final result = <String, BtcTransaction>{};
3080
3081
for (final entry in verboseByHash.entries) {
@@ -3116,10 +3090,9 @@ abstract class ElectrumWalletBase
3090
return result;
3091
}
3092
3119
-
3093
Map<String, List<String>> _collectInputTxIdsByHash(
3121
- Map<String, BtcTransaction> originalByHash,
3122
- ) {
3094
+ Map<String, BtcTransaction> originalByHash,
3095
+ ) {
3096
final inputTxIdsByHash = <String, List<String>>{};
3097
3098
for (final entry in originalByHash.entries) {
@@ -3201,8 +3174,8 @@ abstract class ElectrumWalletBase
3174
}
3175
3176
Future<Map<int, int>> _fetchBlockTimestampsFromMempoolByHeights(
3204
- Set<int> heights,
3205
- ) async {
3177
+ Set<int> heights,
3178
+ ) async {
3179
final out = <int, int>{};
3180
if (heights.isEmpty) return out;
3181
if (!(await checkIfMempoolAPIIsEnabled())) return out;
@@ -3212,10 +3185,10 @@ abstract class ElectrumWalletBase
3185
try {
3186
final blockHashResp = await ProxyWrapper()
3187
.get(
3215
- clearnetUri: Uri.parse(
3216
- 'https://mempool.cakewallet.com/api/v1/block-height/$h',
3217
- ),
3218
- )
3188
+ clearnetUri: Uri.parse(
3189
+ 'https://mempool.cakewallet.com/api/v1/block-height/$h',
3190
+ ),
3191
+ )
3192
.timeout(const Duration(seconds: 15));
3193
3194
if (blockHashResp.statusCode != 200 || blockHashResp.body.isEmpty) return;
@@ -3225,10 +3198,10 @@ abstract class ElectrumWalletBase
3198
3199
final blockResp = await ProxyWrapper()
3200
.get(
3228
- clearnetUri: Uri.parse(
3229
- 'https://mempool.cakewallet.com/api/v1/block/$blockHash',
3230
- ),
3231
- )
3201
+ clearnetUri: Uri.parse(
3202
+ 'https://mempool.cakewallet.com/api/v1/block/$blockHash',
3203
+ ),
3204
+ )
3205
.timeout(const Duration(seconds: 15));
3206
3207
if (blockResp.statusCode != 200 || blockResp.body.isEmpty) return;
@@ -3276,7 +3249,6 @@ abstract class ElectrumWalletBase
3249
return result;
3250
}
3251
3279
-
3252
Future<void> updateTransactions() async {
3253
printV("updateTransactions() called!");
3254
try {
@@ -3368,8 +3340,7 @@ abstract class ElectrumWalletBase
3340
}
3341
3342
try {
3371
- final balancesByScriptHash =
3372
- await _processChunksToMap<String, String, Map<String, dynamic>>(
3343
+ final balancesByScriptHash = await _processChunksToMap<String, String, Map<String, dynamic>>(
3344
items: scriptHashes,
3345
chunkSize: addressHistoryChunkSize,
3346
processChunk: _getBalanceBatch,
@@ -3415,7 +3386,8 @@ abstract class ElectrumWalletBase
3386
? await fetchBalancesBatch(addresses)
3387
: await fetchBalancesRegular(addresses);
3388
3418
- printV('Fetched balances for ${addresses.length} addresses. Batch fetching: $shouldUseBatchFetching');
3389
+ printV(
3390
+ 'Fetched balances for ${addresses.length} addresses. Batch fetching: $shouldUseBatchFetching');
3391
3392
var totalFrozen = 0;
3393
var totalConfirmed = 0;
@@ -3544,17 +3516,14 @@ abstract class ElectrumWalletBase
3516
// that matches this received transaction, mark it as being from a peg out:
3517
for (final tx2 in transactionHistory.transactions.values) {
3518
final heightDiff = ((tx2.height ?? 0) - (tx.height ?? 0)).abs();
3547
- // this isn't a perfect matching algorithm since we don't have the right input/output information from these transaction models (the addresses are in different formats), but this should be more than good enough for now as it's extremely unlikely a user receives the EXACT same amount from 2 different sources and one of them is a peg out and the other isn't WITHIN 5 blocks of each other
3548
- if (tx2.additionalInfo["isPegOut"] == true &&
3549
- tx2.amount == tx.amount &&
3550
- heightDiff <= 5) {
3519
+ // this isn't a perfect matching algorithm since we don't have the right input/output information from these transaction models (the addresses are in different formats), but this should be more than good enough for now as it's extremely unlikely a user receives the EXACT same amount from 2 different sources and one of them is a peg out and the other isn't WITHIN 5 blocks of each other
3520
+ if (tx2.additionalInfo["isPegOut"] == true && tx2.amount == tx.amount && heightDiff <= 5) {
3521
tx.additionalInfo["fromPegOut"] = true;
3522
}
3523
}
3524
}
3525
3526
Future<void> checkIfBatchSupported() async {
3557
-
3527
if (_isBatchSupported != null) {
3528
printV('[BATCH_TEST] Already checked: $_isBatchSupported');
3529
return;
@@ -3580,9 +3549,7 @@ abstract class ElectrumWalletBase
3549
);
3550
3551
final hasError = result.any((item) =>
3583
- item is Map<String, dynamic> &&
3584
- item.containsKey('error') &&
3585
- item['error'] != null);
3552
+ item is Map<String, dynamic> && item.containsKey('error') && item['error'] != null);
3553
3554
if (hasError) {
3555
_isBatchSupported = false;
cw_bitcoin/lib/electrum_wallet_addresses.dart
+111
-105
@@ -195,13 +195,12 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
195
}
196
197
if (addressPageType == LightningAddressType.p2l) {
198
- return lightningAddress ??
199
- "Error: Unable to fetch your Lightning address, please check your network connection.";
198
+ return lightningAddress ??
199
+ "Error: Unable to fetch your Lightning address, please check your network connection.";
200
}
201
202
- final typeMatchingAddressesAll = _addresses
203
- .where((addr) => !addr.isHidden && _isAddressPageTypeMatch(addr))
204
- .toList();
202
+ final typeMatchingAddressesAll =
203
+ _addresses.where((addr) => !addr.isHidden && _isAddressPageTypeMatch(addr)).toList();
204
205
// Prefer standard derivation addresses for the current/active address,
206
// but keep legacy addresses present in the overall address lists.
@@ -210,8 +209,9 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
209
...typeMatchingAddressesAll.where((a) => a.isLegacyDerivation),
210
];
211
213
- final typeMatchingReceiveAddressesAll =
214
- typeMatchingAddressesAll.where((addr) => !addr.isUsed && !hiddenAddresses.contains(addr.address)).toList();
212
+ final typeMatchingReceiveAddressesAll = typeMatchingAddressesAll
213
+ .where((addr) => !addr.isUsed && !hiddenAddresses.contains(addr.address))
214
+ .toList();
215
final typeMatchingReceiveAddresses = <BitcoinAddressRecord>[
216
...typeMatchingReceiveAddressesAll.where((a) => !a.isLegacyDerivation),
217
...typeMatchingReceiveAddressesAll.where((a) => a.isLegacyDerivation),
@@ -354,34 +354,35 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
354
return acc;
355
});
356
357
- @override
358
- Future<void> init() async {
359
- if (walletInfo.type == WalletType.bitcoinCash) {
360
- await _generateInitialAddresses(type: P2pkhAddressType.p2pkh);
361
- } else if (walletInfo.type == WalletType.litecoin) {
362
- await _generateInitialAddresses(type: SegwitAddresType.p2wpkh);
363
- if ((Platform.isAndroid || Platform.isIOS) && !isHardwareWallet) {
364
- await _generateInitialAddresses(type: SegwitAddresType.mweb);
365
- }
366
- } else if (walletInfo.type == WalletType.dogecoin) {
357
+ @override
358
+ Future<void> init() async {
359
+ if (walletInfo.type == WalletType.bitcoinCash) {
360
+ await _generateInitialAddresses(type: P2pkhAddressType.p2pkh);
361
+ } else if (walletInfo.type == WalletType.litecoin) {
362
+ await _generateInitialAddresses(type: SegwitAddresType.p2wpkh);
363
+ if ((Platform.isAndroid || Platform.isIOS) && !isHardwareWallet) {
364
+ await _generateInitialAddresses(type: SegwitAddresType.mweb);
365
+ }
366
+ } else if (walletInfo.type == WalletType.dogecoin) {
367
+ await _generateInitialAddresses(type: P2pkhAddressType.p2pkh);
368
+ } else if (walletInfo.type == WalletType.bitcoin) {
369
+ await _generateInitialAddresses(isLegacyDerivation: true);
370
+ await _generateInitialAddresses();
371
+ if (!isHardwareWallet) {
372
+ await _generateInitialAddresses(type: P2pkhAddressType.p2pkh, isLegacyDerivation: true);
373
await _generateInitialAddresses(type: P2pkhAddressType.p2pkh);
368
- } else if (walletInfo.type == WalletType.bitcoin) {
369
- await _generateInitialAddresses(isLegacyDerivation: true);
370
- await _generateInitialAddresses();
371
- if (!isHardwareWallet) {
372
- await _generateInitialAddresses(type: P2pkhAddressType.p2pkh, isLegacyDerivation: true);
373
- await _generateInitialAddresses(type: P2pkhAddressType.p2pkh);
374
375
- await _generateInitialAddresses(type: P2shAddressType.p2wpkhInP2sh, isLegacyDerivation: true);
376
- await _generateInitialAddresses(type: P2shAddressType.p2wpkhInP2sh);
375
+ await _generateInitialAddresses(
376
+ type: P2shAddressType.p2wpkhInP2sh, isLegacyDerivation: true);
377
+ await _generateInitialAddresses(type: P2shAddressType.p2wpkhInP2sh);
378
378
- await _generateInitialAddresses(type: SegwitAddresType.p2tr, isLegacyDerivation: true);
379
- await _generateInitialAddresses(type: SegwitAddresType.p2tr);
379
+ await _generateInitialAddresses(type: SegwitAddresType.p2tr, isLegacyDerivation: true);
380
+ await _generateInitialAddresses(type: SegwitAddresType.p2tr);
381
381
- await _generateInitialAddresses(type: SegwitAddresType.p2wsh, isLegacyDerivation: true);
382
- await _generateInitialAddresses(type: SegwitAddresType.p2wsh);
383
- }
382
+ await _generateInitialAddresses(type: SegwitAddresType.p2wsh, isLegacyDerivation: true);
383
+ await _generateInitialAddresses(type: SegwitAddresType.p2wsh);
384
}
385
+ }
386
387
updateAddressesByMatch();
388
updateReceiveAddresses();
@@ -680,9 +681,8 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
681
@action
682
void updateReceiveAddresses() {
683
receiveAddresses.removeRange(0, receiveAddresses.length);
683
- final newAddresses = _addresses.where((addressRecord) =>
684
- !addressRecord.isHidden &&
685
- !addressRecord.isUsed);
684
+ final newAddresses =
685
+ _addresses.where((addressRecord) => !addressRecord.isHidden && !addressRecord.isUsed);
686
receiveAddresses.addAll(newAddresses);
687
}
688
@@ -699,12 +699,12 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
699
700
@action
701
Future<void> discoverAddresses(
702
- List<BitcoinAddressRecord> addressList,
703
- bool isHidden,
704
- Future<String?> Function(BitcoinAddressRecord) getAddressHistory, {
705
- BitcoinAddressType type = SegwitAddresType.p2wpkh,
706
- required bool isLegacyDerivation,
707
- }) async {
702
+ List<BitcoinAddressRecord> addressList,
703
+ bool isHidden,
704
+ Future<String?> Function(BitcoinAddressRecord) getAddressHistory, {
705
+ BitcoinAddressType type = SegwitAddresType.p2wpkh,
706
+ required bool isLegacyDerivation,
707
+ }) async {
708
final newAddresses = await _createNewAddresses(
709
gap,
710
startIndex: addressList.length,
@@ -716,8 +716,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
716
addAddresses(newAddresses);
717
addressList.addAll(newAddresses);
718
719
- final addressesWithHistory =
720
- await Future.wait(newAddresses.map(getAddressHistory));
719
+ final addressesWithHistory = await Future.wait(newAddresses.map(getAddressHistory));
720
final isLastAddressUsed = addressesWithHistory.last != null;
721
722
if (isLastAddressUsed) {
@@ -733,12 +732,12 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
732
733
@action
734
Future<List<BitcoinAddressRecord>> discoverAddressesBatch(
736
- List<BitcoinAddressRecord> addressList,
737
- bool isHidden,
738
- Future<Set<String>> Function(List<BitcoinAddressRecord>) getUsedAddresses, {
739
- BitcoinAddressType type = SegwitAddresType.p2wpkh,
740
- required bool isLegacyDerivation,
741
- }) async {
735
+ List<BitcoinAddressRecord> addressList,
736
+ bool isHidden,
737
+ Future<Set<String>> Function(List<BitcoinAddressRecord>) getUsedAddresses, {
738
+ BitcoinAddressType type = SegwitAddresType.p2wpkh,
739
+ required bool isLegacyDerivation,
740
+ }) async {
741
final newAddresses = await _createNewAddresses(
742
gap,
743
startIndex: addressList.length,
@@ -750,8 +749,8 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
749
750
final usedAddresses = await getUsedAddresses(newAddresses);
751
753
- final hasUsedAddressInGap = newAddresses.any(
754
- (addressRecord) => usedAddresses.contains(addressRecord.address));
752
+ final hasUsedAddressInGap =
753
+ newAddresses.any((addressRecord) => usedAddresses.contains(addressRecord.address));
754
755
if (!hasUsedAddressInGap) {
756
return newAddresses;
@@ -770,64 +769,69 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
769
return [...newAddresses, ...moreNewAddresses];
770
}
771
773
-
772
Future<void> _generateInitialAddresses(
775
- {BitcoinAddressType type = SegwitAddresType.p2wpkh,
776
- bool isLegacyDerivation = false }) async {
777
-
778
- // Legacy derivation produces the same addresses as standard for these types.
779
- // Don't generate a legacy set to avoid duplicates.
780
- if (isLegacyDerivation && (type == SegwitAddresType.p2wpkh || type == SegwitAddresType.p2wsh)) {
781
- return;
782
- }
773
+ {BitcoinAddressType type = SegwitAddresType.p2wpkh, bool isLegacyDerivation = false}) async {
774
+ // Legacy derivation produces the same addresses as standard for these types.
775
+ // Don't generate a legacy set to avoid duplicates.
776
+ if (isLegacyDerivation && (type == SegwitAddresType.p2wpkh || type == SegwitAddresType.p2wsh)) {
777
+ return;
778
+ }
779
784
- var countOfReceiveAddresses = 0;
785
- var countOfHiddenAddresses = 0;
780
+ var countOfReceiveAddresses = 0;
781
+ var countOfHiddenAddresses = 0;
782
787
- _addresses.forEach((addr) {
788
- if (addr.type == type && addr.isLegacyDerivation == isLegacyDerivation) {
789
- if (addr.isHidden) {
790
- countOfHiddenAddresses += 1;
791
- } else {
792
- countOfReceiveAddresses += 1;
793
- }
783
+ _addresses.forEach((addr) {
784
+ if (addr.type == type && addr.isLegacyDerivation == isLegacyDerivation) {
785
+ if (addr.isHidden) {
786
+ countOfHiddenAddresses += 1;
787
+ } else {
788
+ countOfReceiveAddresses += 1;
789
}
795
- });
796
-
797
- if (countOfReceiveAddresses < defaultReceiveAddressesCount) {
798
- final addressesCount = defaultReceiveAddressesCount - countOfReceiveAddresses;
799
- final newAddresses = await _createNewAddresses(addressesCount,
800
- startIndex: countOfReceiveAddresses, isHidden: false, type: type, isLegacyDerivation: isLegacyDerivation);
801
- addAddresses(newAddresses);
790
}
791
+ });
792
804
- if (countOfHiddenAddresses < defaultChangeAddressesCount) {
805
- final addressesCount = defaultChangeAddressesCount - countOfHiddenAddresses;
806
- final newAddresses = await _createNewAddresses(addressesCount,
807
- startIndex: countOfHiddenAddresses, isHidden: true, type: type, isLegacyDerivation: isLegacyDerivation);
808
- addAddresses(newAddresses);
809
- }
793
+ if (countOfReceiveAddresses < defaultReceiveAddressesCount) {
794
+ final addressesCount = defaultReceiveAddressesCount - countOfReceiveAddresses;
795
+ final newAddresses = await _createNewAddresses(addressesCount,
796
+ startIndex: countOfReceiveAddresses,
797
+ isHidden: false,
798
+ type: type,
799
+ isLegacyDerivation: isLegacyDerivation);
800
+ addAddresses(newAddresses);
801
}
802
812
- Future<List<BitcoinAddressRecord>> _createNewAddresses(int count,
813
- {int startIndex = 0, bool isHidden = false, BitcoinAddressType? type, bool isLegacyDerivation = false}) async {
814
- final list = <BitcoinAddressRecord>[];
815
-
816
- for (var i = startIndex; i < count + startIndex; i++) {
817
-
818
- final addrType = type ?? addressPageType;
819
- final hd = _hdFor(isHidden: isHidden, type: addrType, isLegacyDerivation: isLegacyDerivation);
803
+ if (countOfHiddenAddresses < defaultChangeAddressesCount) {
804
+ final addressesCount = defaultChangeAddressesCount - countOfHiddenAddresses;
805
+ final newAddresses = await _createNewAddresses(addressesCount,
806
+ startIndex: countOfHiddenAddresses,
807
+ isHidden: true,
808
+ type: type,
809
+ isLegacyDerivation: isLegacyDerivation);
810
+ addAddresses(newAddresses);
811
+ }
812
+ }
813
821
- final address = BitcoinAddressRecord(
822
- await getAddressAsync(index: i, hd: hd, addressType: addrType),
823
- index: i,
824
- isHidden: isHidden,
825
- isLegacyDerivation: isLegacyDerivation,
826
- type: addrType,
827
- network: network,
828
- );
829
- list.add(address);
830
- }
814
+ Future<List<BitcoinAddressRecord>> _createNewAddresses(int count,
815
+ {int startIndex = 0,
816
+ bool isHidden = false,
817
+ BitcoinAddressType? type,
818
+ bool isLegacyDerivation = false}) async {
819
+ final list = <BitcoinAddressRecord>[];
820
+
821
+ for (var i = startIndex; i < count + startIndex; i++) {
822
+ final addrType = type ?? addressPageType;
823
+ final hd = _hdFor(isHidden: isHidden, type: addrType, isLegacyDerivation: isLegacyDerivation);
824
+
825
+ final address = BitcoinAddressRecord(
826
+ await getAddressAsync(index: i, hd: hd, addressType: addrType),
827
+ index: i,
828
+ isHidden: isHidden,
829
+ isLegacyDerivation: isLegacyDerivation,
830
+ type: addrType,
831
+ network: network,
832
+ );
833
+ list.add(address);
834
+ }
835
836
return list;
837
}
@@ -868,8 +872,10 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
872
return;
873
}
874
871
- final mainHd = _hdFor(isHidden: false, type: element.type, isLegacyDerivation: element.isLegacyDerivation);
872
- final sideHd = _hdFor(isHidden: true, type: element.type, isLegacyDerivation: element.isLegacyDerivation);
875
+ final mainHd = _hdFor(
876
+ isHidden: false, type: element.type, isLegacyDerivation: element.isLegacyDerivation);
877
+ final sideHd = _hdFor(
878
+ isHidden: true, type: element.type, isLegacyDerivation: element.isLegacyDerivation);
879
if (!element.isHidden &&
880
element.address !=
881
await getAddressAsync(index: element.index, hd: mainHd, addressType: element.type)) {
@@ -897,7 +903,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
903
return _isAddressByType(addressRecord, addressPageType);
904
}
905
900
- bool _isAddressByType(BitcoinAddressRecord addr, BitcoinAddressType type) => addr.type == type;
906
+ bool _isAddressByType(BitcoinAddressRecord addr, BitcoinAddressType type) => addr.type == type;
907
908
bool _isUnusedReceiveAddressByType(BitcoinAddressRecord addr, BitcoinAddressType type) =>
909
!addr.isHidden && !addr.isUsed && addr.type == type;
@@ -907,9 +913,9 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
913
final addressRecord = silentAddresses.firstWhere((addressRecord) =>
914
addressRecord.type == SilentPaymentsAddresType.p2sp && addressRecord.address == address);
915
910
- silentAddresses.remove(addressRecord);
911
- updateAddressesByMatch();
912
- }
916
+ silentAddresses.remove(addressRecord);
917
+ updateAddressesByMatch();
918
+ }
919
920
Bip32Slip10Secp256k1 _hdFor({
921
required bool isHidden,
@@ -923,7 +929,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
929
if (hd == null) throw Exception("HD not found for type $type");
930
return hd;
931
}
926
-
932
+
933
@action
934
Future<void> setLightningAddress(String walletName, {String newAddress = ""}) async {
935
if (lightningWallet == null) return;
cw_bitcoin/lib/exceptions.dart
+1
-1
@@ -30,7 +30,7 @@ class BitcoinTransactionCommitFailed extends TransactionCommitFailed {
30
31
@override
32
String toString() {
33
- return errorMessage??"unknown error";
33
+ return errorMessage ?? "unknown error";
34
}
35
}
36
cw_bitcoin/lib/hardware/bitbox_service.dart
+2
-1
@@ -67,7 +67,8 @@ class BitcoinBitboxService extends HardwareWalletService with BitcoinHardwareWal
67
Future<Uint8List> getMasterFingerprint() => manager.getMasterFingerprint();
68
}
69
70
-class LitecoinBitboxService extends HardwareWalletService with BitcoinHardwareWalletService, LitecoinHardwareWalletService {
70
+class LitecoinBitboxService extends HardwareWalletService
71
+ with BitcoinHardwareWalletService, LitecoinHardwareWalletService {
72
LitecoinBitboxService(this.manager);
73
74
final BitboxManager manager;
cw_bitcoin/lib/hardware/litecoin_ledger_service.dart
+3
-3
@@ -12,7 +12,8 @@ import 'package:cw_core/hardware/hardware_wallet_service.dart';
12
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
13
import 'package:ledger_litecoin/ledger_litecoin.dart';
14
15
-class LitecoinLedgerService extends HardwareWalletService with BitcoinHardwareWalletService, LitecoinHardwareWalletService {
15
+class LitecoinLedgerService extends HardwareWalletService
16
+ with BitcoinHardwareWalletService, LitecoinHardwareWalletService {
17
LitecoinLedgerService(this.ledgerConnection)
18
: litecoinLedgerApp = LitecoinLedgerApp(ledgerConnection);
19
@@ -53,7 +54,6 @@ class LitecoinLedgerService extends HardwareWalletService with BitcoinHardwareWa
54
required List<PSBTReadyUtxoWithAddress> inputs,
55
required Map<String, PublicKeyWithDerivationPath> publicKeys,
56
}) {
56
-
57
final readyInputs = <LedgerTransaction>[];
58
for (final utxo in inputs) {
59
final publicKeyAndDerivationPath = publicKeys[utxo.ownerDetails.address.pubKeyHash()]!;
@@ -77,7 +77,7 @@ class LitecoinLedgerService extends HardwareWalletService with BitcoinHardwareWa
77
inputs: readyInputs,
78
outputs: outputs
79
.map((e) => TransactionOutput.fromBigInt((e as BitcoinOutput).value,
80
- Uint8List.fromList(e.address.toScriptPubKey().toBytes())))
80
+ Uint8List.fromList(e.address.toScriptPubKey().toBytes())))
81
.toList(),
82
changePath: changePath,
83
sigHashType: 0x01,
cw_bitcoin/lib/lightning/lightning_wallet.dart
+17
-15
@@ -90,8 +90,7 @@ class LightningWallet {
90
lnurlDomain: lnurlDomain,
91
apiKey: apiKey,
92
privateEnabledDefault: true,
93
- maxDepositClaimFee: MaxFee.rate(satPerVbyte: BigInt.from(5))
94
- );
93
+ maxDepositClaimFee: MaxFee.rate(satPerVbyte: BigInt.from(5)));
94
95
final connectRequest = ConnectRequest(
96
config: config,
@@ -105,8 +104,7 @@ class LightningWallet {
104
_logStream ??= initLogging().asBroadcastStream();
105
106
try {
108
- final logFile = File("$appPath/lightning.log")
109
- ..createSync();
107
+ final logFile = File("$appPath/lightning.log")..createSync();
108
_subscribeToLogStream(logFile);
109
} catch (e) {
110
printV(e);
@@ -198,15 +196,17 @@ class LightningWallet {
196
}
197
}
198
201
- Future<PendingLightningTransaction> createTransaction(
202
- String address, BigInt? amountSats, BitcoinTransactionPriority? priority, bool feesIncluded) async {
199
+ Future<PendingLightningTransaction> createTransaction(String address, BigInt? amountSats,
200
+ BitcoinTransactionPriority? priority, bool feesIncluded) async {
201
final inputType = await sdk.parse(input: address);
202
203
final feePolicy = feesIncluded ? FeePolicy.feesIncluded : FeePolicy.feesExcluded;
204
205
if (inputType is InputType_Bolt11Invoice) {
206
final request = PrepareSendPaymentRequest(
209
- paymentRequest: inputType.field0.invoice.bolt11, amount: amountSats, feePolicy: feePolicy);
207
+ paymentRequest: inputType.field0.invoice.bolt11,
208
+ amount: amountSats,
209
+ feePolicy: feePolicy);
210
final prepareResponse = await sdk.prepareSendPayment(request: request);
211
212
final paymentMethod = prepareResponse.paymentMethod;
@@ -392,14 +392,16 @@ class LightningWallet {
392
return _getElectrumTransactionInfoFromPayment(response.payment);
393
}
394
395
- Future<String> refundDeposit(String txId, int vout, String destinationAddress,
396
- BigInt feeRate) async {
397
- final response = await sdk.refundDeposit(request: RefundDepositRequest(
398
- txid: txId,
399
- vout: vout,
400
- destinationAddress: destinationAddress,
401
- fee: Fee.rate(satPerVbyte: feeRate),
402
- ),);
395
+ Future<String> refundDeposit(
396
+ String txId, int vout, String destinationAddress, BigInt feeRate) async {
397
+ final response = await sdk.refundDeposit(
398
+ request: RefundDepositRequest(
399
+ txid: txId,
400
+ vout: vout,
401
+ destinationAddress: destinationAddress,
402
+ fee: Fee.rate(satPerVbyte: feeRate),
403
+ ),
404
+ );
405
406
return response.txHex;
407
}
cw_bitcoin/lib/lightning/pending_lightning_transaction.dart
+1
-2
@@ -10,10 +10,9 @@ class PendingLightningTransaction with PendingTransaction {
10
required this.commitOverride,
11
});
12
13
-
13
final bool isSendAll;
14
Future<String> Function() commitOverride;
16
- final List<void Function()> _listeners =[];
15
+ final List<void Function()> _listeners = [];
16
17
@override
18
String id;
cw_bitcoin/lib/litecoin_wallet.dart
+30
-26
@@ -175,7 +175,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
175
@override
176
bool get hasRescan => true;
177
178
-
178
final String? scanSecretOverride;
179
final String? spendPubkeyOverride;
180
List<int> get scanSecret => (scanSecretOverride != null && scanSecretOverride?.isNotEmpty == true)
@@ -232,8 +231,12 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
231
}
232
233
@override
235
- WalletKeysData get walletKeysData =>
236
- WalletKeysData(mnemonic: seed, xPub: xpub, passphrase: passphrase, scanSecret: scanSecretOverride, spendPubkey: spendPubkeyOverride);
234
+ WalletKeysData get walletKeysData => WalletKeysData(
235
+ mnemonic: seed,
236
+ xPub: xpub,
237
+ passphrase: passphrase,
238
+ scanSecret: scanSecretOverride,
239
+ spendPubkey: spendPubkeyOverride);
240
241
static Future<LitecoinWallet> open({
242
required String name,
@@ -1106,15 +1109,18 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
1109
for (final utxo in transaction.utxos) {
1110
if (utxo.utxo.scriptType != SegwitAddresType.mweb) {
1111
inputs.add(utxo.utxo.toInput());
1109
- txouts.add(TxOut(value: Int64(utxo.utxo.value.toInt()),
1110
- pkScript: utxo.ownerDetails.address.toScriptPubKey().toBytes()));
1112
+ txouts.add(TxOut(
1113
+ value: Int64(utxo.utxo.value.toInt()),
1114
+ pkScript: utxo.ownerDetails.address.toScriptPubKey().toBytes()));
1115
}
1116
}
1117
var resp = await CwMweb.psbtCreate(PsbtCreateRequest(
1114
- rawTx: inputs.isEmpty ? null : BtcTransaction(
1115
- inputs: inputs,
1116
- outputs: isMweb ? [] : transaction.outputs,
1117
- ).toBytes(),
1118
+ rawTx: inputs.isEmpty
1119
+ ? null
1120
+ : BtcTransaction(
1121
+ inputs: inputs,
1122
+ outputs: isMweb ? [] : transaction.outputs,
1123
+ ).toBytes(),
1124
witnessUtxo: txouts,
1125
));
1126
for (final utxo in transaction.utxos) {
@@ -1127,17 +1133,18 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
1133
));
1134
}
1135
}
1130
- if (isMweb) for (final output in transaction.outputs) {
1131
- var address = addressFromOutputScript(output.scriptPubKey, LitecoinNetwork.mainnet);
1132
- if (output.scriptPubKey.getAddressType() == SegwitAddresType.mweb) {
1133
- address = SegwitBech32Encoder.encode("ltcmweb", 0, output.scriptPubKey.toBytes());
1136
+ if (isMweb)
1137
+ for (final output in transaction.outputs) {
1138
+ var address = addressFromOutputScript(output.scriptPubKey, LitecoinNetwork.mainnet);
1139
+ if (output.scriptPubKey.getAddressType() == SegwitAddresType.mweb) {
1140
+ address = SegwitBech32Encoder.encode("ltcmweb", 0, output.scriptPubKey.toBytes());
1141
+ }
1142
+ resp = await CwMweb.psbtAddRecipient(PsbtAddRecipientRequest(
1143
+ psbtB64: resp.psbtB64,
1144
+ recipient: PsbtRecipient(address: address, value: Int64(output.amount.toInt())),
1145
+ feeRatePerKb: Int64.parseInt(transaction.feeRate) * 1000,
1146
+ ));
1147
}
1135
- resp = await CwMweb.psbtAddRecipient(PsbtAddRecipientRequest(
1136
- psbtB64: resp.psbtB64,
1137
- recipient: PsbtRecipient(address: address, value: Int64(output.amount.toInt())),
1138
- feeRatePerKb: Int64.parseInt(transaction.feeRate) * 1000,
1139
- ));
1140
- }
1148
return base64.decode(resp.psbtB64);
1149
}
1150
@@ -1203,7 +1210,6 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
1210
for (final utxo in tx.utxos) {
1211
if (utxo.utxo.scriptType == SegwitAddresType.mweb) {
1212
hasMwebInput = true;
1206
-
1213
} else {
1214
// check if any of the inputs of this transaction are hog-ex:
1215
// this list is only non-mweb inputs:
@@ -1256,9 +1262,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
1262
final utxo = unspentCoins
1263
.firstWhere((utxo) => utxo.hash == e.value.txId && utxo.vout == e.value.txIndex);
1264
final key = generateECPrivate(
1259
- hd: utxo.bitcoinAddressRecord.isHidden
1260
- ? sideHd
1261
- : mainHd,
1265
+ hd: utxo.bitcoinAddressRecord.isHidden ? sideHd : mainHd,
1266
index: utxo.bitcoinAddressRecord.index,
1267
network: network);
1268
final digest = tx2.getTransactionSegwitDigit(
@@ -1284,8 +1288,8 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
1288
}
1289
}
1290
1287
- void addTransactionListener(PendingBitcoinTransaction tx,
1288
- List<String> inputAddresses, bool isPegIn, bool isPegOut) {
1291
+ void addTransactionListener(
1292
+ PendingBitcoinTransaction tx, List<String> inputAddresses, bool isPegIn, bool isPegOut) {
1293
tx.addListener((transaction) async {
1294
final addresses = <String>{};
1295
transaction.inputAddresses?.addAll(inputAddresses);
@@ -1575,7 +1579,7 @@ abstract class LitecoinWalletBase extends ElectrumWallet with Store {
1579
rawTx: rawTx,
1580
ownerDetails: utxo.ownerDetails,
1581
ownerDerivationPath: publicKeyAndDerivationPath.derivationPath,
1578
- ownerMasterFingerprint:masterFingerprint,
1582
+ ownerMasterFingerprint: masterFingerprint,
1583
ownerPublicKey: publicKeyAndDerivationPath.publicKey,
1584
));
1585
}
cw_bitcoin/lib/litecoin_wallet_addresses.dart
+13
-7
@@ -59,9 +59,11 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
59
? hex.decode(scanSecretOverride!)
60
: mwebHd?.childKey(Bip32KeyIndex(0x80000000)).privateKey.privKey.raw ?? List.filled(32, 0);
61
62
- List<int> get spendPubkey => (spendPubkeyOverride != null && spendPubkeyOverride?.isNotEmpty == true)
63
- ? hex.decode(spendPubkeyOverride!)
64
- : mwebHd?.childKey(Bip32KeyIndex(0x80000001)).publicKey.pubKey.compressed ?? List.filled(32, 0);
62
+ List<int> get spendPubkey =>
63
+ (spendPubkeyOverride != null && spendPubkeyOverride?.isNotEmpty == true)
64
+ ? hex.decode(spendPubkeyOverride!)
65
+ : mwebHd?.childKey(Bip32KeyIndex(0x80000001)).publicKey.pubKey.compressed ??
66
+ List.filled(32, 0);
67
68
@override
69
Future<void> init() async {
@@ -81,7 +83,7 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
83
return null;
84
}
85
if ((scanSecret.length < 1 || scanSecret.reduce((a, b) => a + b) == 0) &&
84
- (spendPubkey.length < 1 || spendPubkey.reduce((a, b) => a + b) == 0)) {
86
+ (spendPubkey.length < 1 || spendPubkey.reduce((a, b) => a + b) == 0)) {
87
return null;
88
}
89
@@ -230,12 +232,16 @@ abstract class LitecoinWalletAddressesBase extends ElectrumWalletAddresses with
232
// don't use mweb addresses for exchange refund address:
233
234
final current = getFreshAddress();
233
- final bool isMweb = receiveAddresses
234
- .any((e) => e.address == current && e.type == SegwitAddresType.mweb);
235
+ final bool isMweb =
236
+ receiveAddresses.any((e) => e.address == current && e.type == SegwitAddresType.mweb);
237
238
if (isMweb) {
239
final segwit = receiveAddresses
238
- .where((e) => e.type == SegwitAddresType.p2wpkh && !e.isUsed && !e.isHidden && !hiddenAddresses.contains(e.address))
240
+ .where((e) =>
241
+ e.type == SegwitAddresType.p2wpkh &&
242
+ !e.isUsed &&
243
+ !e.isHidden &&
244
+ !hiddenAddresses.contains(e.address))
245
.map((e) => e.address)
246
.toList();
247
cw_bitcoin/lib/litecoin_wallet_service.dart
+9
-8
@@ -48,7 +48,8 @@ class LitecoinWalletService extends WalletService<
48
password: credentials.password!,
49
passphrase: credentials.passphrase,
50
walletInfo: credentials.walletInfo!,
51
- derivationInfo: credentials.derivationInfo ?? (await credentials.walletInfo!.getDerivationInfo()),
51
+ derivationInfo:
52
+ credentials.derivationInfo ?? (await credentials.walletInfo!.getDerivationInfo()),
53
unspentCoinsInfo: unspentCoinsInfoSource,
54
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
55
);
@@ -64,7 +65,6 @@ class LitecoinWalletService extends WalletService<
65
66
@override
67
Future<LitecoinWallet> openWallet(String name, String password) async {
67
-
68
final walletInfo = await WalletInfo.get(name, getType());
69
if (walletInfo == null) {
70
throw Exception('Wallet not found');
@@ -125,8 +125,9 @@ class LitecoinWalletService extends WalletService<
125
}
126
}
127
128
- final unspentCoinsToDelete = unspentCoinsInfoSource.values.where(
129
- (unspentCoin) => unspentCoin.walletId == walletInfo.id).toList();
128
+ final unspentCoinsToDelete = unspentCoinsInfoSource.values
129
+ .where((unspentCoin) => unspentCoin.walletId == walletInfo.id)
130
+ .toList();
131
132
final keysToDelete = unspentCoinsToDelete.map((unspentCoin) => unspentCoin.key).toList();
133
@@ -150,8 +151,7 @@ class LitecoinWalletService extends WalletService<
151
final network = isTestnet == true ? LitecoinNetwork.testnet : LitecoinNetwork.mainnet;
152
credentials.walletInfo?.network = network.value;
153
final derivationInfo = await credentials.walletInfo!.getDerivationInfo();
153
- derivationInfo.derivationPath =
154
- credentials.hwAccountData.derivationPath;
154
+ derivationInfo.derivationPath = credentials.hwAccountData.derivationPath;
155
await derivationInfo.save();
156
credentials.walletInfo!.save();
157
@@ -170,7 +170,7 @@ class LitecoinWalletService extends WalletService<
170
171
@override
172
Future<LitecoinWallet> restoreFromKeys(LitecoinWalletFromKeysCredentials credentials,
173
- {bool? isTestnet}) async {
173
+ {bool? isTestnet}) async {
174
final network = isTestnet == true ? LitecoinNetwork.testnet : LitecoinNetwork.mainnet;
175
credentials.walletInfo?.network = network.value;
176
@@ -202,7 +202,8 @@ class LitecoinWalletService extends WalletService<
202
passphrase: credentials.passphrase,
203
mnemonic: credentials.mnemonic,
204
walletInfo: credentials.walletInfo!,
205
- derivationInfo: credentials.derivationInfo ?? (await credentials.walletInfo!.getDerivationInfo()),
205
+ derivationInfo:
206
+ credentials.derivationInfo ?? (await credentials.walletInfo!.getDerivationInfo()),
207
unspentCoinsInfo: unspentCoinsInfoSource,
208
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
209
);
cw_bitcoin/lib/payjoin/manager.dart
+13
-18
@@ -108,16 +108,14 @@ class PayjoinManager {
108
Future<Sender> initSender(
109
String pjUriString, String originalPsbt, int networkFeesSatPerVb) async {
110
try {
111
- final pjUri =
112
- (await PayjoinUri.Uri.fromStr(pjUriString)).checkPjSupported();
111
+ final pjUri = (await PayjoinUri.Uri.fromStr(pjUriString)).checkPjSupported();
112
final minFeeRateSatPerKwu = BigInt.from(networkFeesSatPerVb * 250);
113
final senderBuilder = await SenderBuilder.fromPsbtAndUri(
114
psbtBase64: originalPsbt,
115
pjUri: pjUri,
116
);
117
final persister = PayjoinSenderPersister.impl();
119
- final newSender =
120
- await senderBuilder.buildRecommended(minFeeRate: minFeeRateSatPerKwu);
118
+ final newSender = await senderBuilder.buildRecommended(minFeeRate: minFeeRateSatPerKwu);
119
final senderToken = await newSender.persist(persister: persister);
120
121
return Sender.load(token: senderToken, persister: persister);
@@ -133,8 +131,7 @@ class PayjoinManager {
131
bool isTestnet = false,
132
}) async {
133
final pjUri = Uri.parse(pjUrl).queryParameters['pj']!;
136
- await _payjoinStorage.insertSenderSession(
137
- sender, pjUri, _wallet.id, amount);
134
+ await _payjoinStorage.insertSenderSession(sender, pjUri, _wallet.id, amount);
135
136
return _spawnSender(isTestnet: isTestnet, sender: sender, pjUri: pjUri);
137
}
@@ -207,8 +204,7 @@ class PayjoinManager {
204
return completer.future;
205
}
206
210
- Future<Receiver> getUnusedReceiver(String address,
211
- [bool isTestnet = false]) async {
207
+ Future<Receiver> getUnusedReceiver(String address, [bool isTestnet = false]) async {
208
final session = _payjoinStorage.getUnusedActiveReceiverSession(_wallet.id);
209
210
if (session != null) {
@@ -220,7 +216,8 @@ class PayjoinManager {
216
return initReceiver(address);
217
}
218
223
- Future<Receiver> initReceiver(String address, [bool isTestnet = false, int retryCount = 0]) async {
219
+ Future<Receiver> initReceiver(String address,
220
+ [bool isTestnet = false, int retryCount = 0]) async {
221
if (retryCount > 0) writePayjoinLog("Retrying initReceiver ${retryCount + 1} attempt");
222
223
try {
@@ -245,7 +242,6 @@ class PayjoinManager {
242
} catch (e) {
243
writePayjoinLog(e.toString());
244
if (e.toString().contains("error sending request for url") && retryCount < 5) {
248
-
245
return initReceiver(address, isTestnet, ++retryCount);
246
} else {
247
rethrow;
@@ -273,13 +269,11 @@ class PayjoinManager {
269
rawAmount = getOutputAmountFromTx(tx, _wallet);
270
break;
271
case PayjoinReceiverRequestTypes.checkIsOwned:
276
- (_wallet.walletAddresses as BitcoinWalletAddresses)
277
- .newPayjoinReceiver();
272
+ (_wallet.walletAddresses as BitcoinWalletAddresses).newPayjoinReceiver();
273
_payjoinStorage.markReceiverSessionInProgress(receiver.id());
274
275
final inputScript = message['input_script'] as Uint8List;
281
- final isOwned =
282
- _wallet.isMine(Script.fromRaw(byteData: inputScript));
276
+ final isOwned = _wallet.isMine(Script.fromRaw(byteData: inputScript));
277
mainToIsolateSendPort?.send({
278
'requestId': message['requestId'],
279
'result': isOwned,
@@ -288,8 +282,7 @@ class PayjoinManager {
282
283
case PayjoinReceiverRequestTypes.checkIsReceiverOutput:
284
final outputScript = message['output_script'] as Uint8List;
291
- final isReceiverOutput =
292
- _wallet.isMine(Script.fromRaw(byteData: outputScript));
285
+ final isReceiverOutput = _wallet.isMine(Script.fromRaw(byteData: outputScript));
286
mainToIsolateSendPort?.send({
287
'requestId': message['requestId'],
288
'result': isReceiverOutput,
@@ -310,7 +303,8 @@ class PayjoinManager {
303
304
case PayjoinReceiverRequestTypes.processPsbt:
305
final psbt = message['psbt'] as String;
313
- writePayjoinLog("Receiver(${receiver.id()}) PayjoinReceiverRequestTypes.processPsbt: $psbt");
306
+ writePayjoinLog(
307
+ "Receiver(${receiver.id()}) PayjoinReceiverRequestTypes.processPsbt: $psbt");
308
309
final signedPsbt = await _wallet.signPsbt(psbt, utxos);
310
mainToIsolateSendPort?.send({
@@ -322,7 +316,8 @@ class PayjoinManager {
316
case PayjoinReceiverRequestTypes.proposalSent:
317
_cleanupSession(receiver.id());
318
final psbt = message['psbt'] as String;
325
- writePayjoinLog("Receiver(${receiver.id()}) PayjoinReceiverRequestTypes.proposalSent: $psbt");
319
+ writePayjoinLog(
320
+ "Receiver(${receiver.id()}) PayjoinReceiverRequestTypes.proposalSent: $psbt");
321
322
await _payjoinStorage.markReceiverSessionComplete(
323
receiver.id(), getTxIdFromPsbtV0(psbt), rawAmount);
cw_bitcoin/lib/payjoin/payjoin_receive_worker.dart
+11
-20
@@ -47,8 +47,7 @@ class PayjoinReceiverWorker {
47
try {
48
final receiver = Receiver.fromJson(json: receiverJson);
49
50
- final uncheckedProposal =
51
- await worker.receiveUncheckedProposal(receiver);
50
+ final uncheckedProposal = await worker.receiveUncheckedProposal(receiver);
51
52
final originalTx = await uncheckedProposal.extractTxToScheduleBroadcast();
53
sendPort.send({
@@ -112,8 +111,7 @@ class PayjoinReceiverWorker {
111
final httpRequest = await client.post(url,
112
headers: {'Content-Type': request.contentType}, body: request.body);
113
115
- final proposal = await session.processRes(
116
- body: httpRequest.bodyBytes, ctx: extractReq.$2);
114
+ final proposal = await session.processRes(body: httpRequest.bodyBytes, ctx: extractReq.$2);
115
if (proposal != null) return proposal;
116
sleep(Duration(seconds: 2));
117
}
@@ -140,8 +138,7 @@ class PayjoinReceiverWorker {
138
return await finalProposal.psbt();
139
}
140
143
- Future<PayjoinProposal> processPayjoinProposal(
144
- UncheckedProposal proposal) async {
141
+ Future<PayjoinProposal> processPayjoinProposal(UncheckedProposal proposal) async {
142
await proposal.extractTxToScheduleBroadcast();
143
// TODO Handle this. send to the main port on a timer?
144
@@ -174,20 +171,17 @@ class PayjoinReceiverWorker {
171
);
172
final pj5 = await pj4.commitOutputs();
173
177
- final listUnspent =
178
- await _sendRequest(PayjoinReceiverRequestTypes.getCandidateInputs);
174
+ final listUnspent = await _sendRequest(PayjoinReceiverRequestTypes.getCandidateInputs);
175
final unspent = listUnspent as List<UtxoWithPrivateKey>;
176
if (unspent.isEmpty) throw RecoverableError('No unspent outputs available');
177
182
- final candidateInputs =
183
- await Future.wait(unspent.map(_inputPairFromUtxo));
178
+ final candidateInputs = await Future.wait(unspent.map(_inputPairFromUtxo));
179
180
// Prefer a UTXO that avoids the Unnecessary Input Heuristic (UIH2);
181
// fall back to the first candidate if none preserves privacy.
182
InputPair selectedUtxo = candidateInputs.first;
183
try {
189
- selectedUtxo =
190
- await pj5.tryPreservingPrivacy(candidateInputs: candidateInputs);
184
+ selectedUtxo = await pj5.tryPreservingPrivacy(candidateInputs: candidateInputs);
185
} catch (_) {}
186
187
final pj6 = await pj5.contributeInputs(replacementInputs: [selectedUtxo]);
@@ -196,8 +190,8 @@ class PayjoinReceiverWorker {
190
// Finalize proposal
191
final payjoinProposal = await pj7.finalizeProposal(
192
processPsbt: (String psbt) async {
199
- final result = await _sendRequest(
200
- PayjoinReceiverRequestTypes.processPsbt, {'psbt': psbt});
193
+ final result =
194
+ await _sendRequest(PayjoinReceiverRequestTypes.processPsbt, {'psbt': psbt});
195
return result as String;
196
},
197
// TODO set maxFeeRateSatPerVb
@@ -213,15 +207,12 @@ class PayjoinReceiverWorker {
207
Future<InputPair> _inputPairFromUtxo(UtxoWithPrivateKey utxo) async {
208
final txout = TxOut(
209
value: utxo.utxo.value,
216
- scriptPubkey: Uint8List.fromList(
217
- utxo.ownerDetails.address.toScriptPubKey().toBytes()),
210
+ scriptPubkey: Uint8List.fromList(utxo.ownerDetails.address.toScriptPubKey().toBytes()),
211
);
212
220
- final psbtin =
221
- PsbtInput(witnessUtxo: txout, redeemScript: null, witnessScript: null);
213
+ final psbtin = PsbtInput(witnessUtxo: txout, redeemScript: null, witnessScript: null);
214
223
- final previousOutput =
224
- OutPoint(txid: utxo.utxo.txHash, vout: utxo.utxo.vout);
215
+ final previousOutput = OutPoint(txid: utxo.utxo.txHash, vout: utxo.utxo.vout);
216
217
final txin = TxIn(
218
previousOutput: previousOutput,
cw_bitcoin/lib/payjoin/payjoin_send_worker.dart
+3
-5
@@ -46,11 +46,11 @@ class PayjoinSenderWorker {
46
sendPort.send(e);
47
}
48
}
49
+
50
final client = ProxyWrapper().getHttpIOClient();
51
52
/// Run a payjoin sender (V2 protocol first, fallback to V1).
53
Future<String> runSender(Sender sender) async {
53
-
54
try {
55
return await _runSenderV2(sender);
56
} catch (e) {
@@ -70,13 +70,11 @@ class PayjoinSenderWorker {
70
Future<String> _runSenderV2(Sender sender) async {
71
try {
72
final postRequest = await sender.extractV2(
73
- ohttpProxyUrl:
74
- await pj_uri.Url.fromStr(PayjoinManager.randomOhttpRelayUrl()),
73
+ ohttpProxyUrl: await pj_uri.Url.fromStr(PayjoinManager.randomOhttpRelayUrl()),
74
);
75
76
final postResult = await _postRequest(postRequest.$1);
78
- final getContext =
79
- await postRequest.$2.processResponse(response: postResult);
77
+ final getContext = await postRequest.$2.processResponse(response: postResult);
78
79
sendPort.send({'type': PayjoinSenderRequestTypes.requestPosted, "pj": pjUrl});
80
cw_bitcoin/lib/payjoin/storage.dart
+15
-21
@@ -23,16 +23,14 @@ class PayjoinStorage {
23
),
24
);
25
26
- PayjoinSession? getUnusedActiveReceiverSession(String walletId) =>
27
- _payjoinSessionSources.values
28
- .where((session) =>
29
- session.walletId == walletId &&
30
- session.status == PayjoinSessionStatus.created.name &&
31
- !session.isSenderSession)
32
- .firstOrNull;
33
-
34
- Future<void> markReceiverSessionComplete(
35
- String sessionId, String txId, String amount) async {
26
+ PayjoinSession? getUnusedActiveReceiverSession(String walletId) => _payjoinSessionSources.values
27
+ .where((session) =>
28
+ session.walletId == walletId &&
29
+ session.status == PayjoinSessionStatus.created.name &&
30
+ !session.isSenderSession)
31
+ .firstOrNull;
32
+
33
+ Future<void> markReceiverSessionComplete(String sessionId, String txId, String amount) async {
34
final session = _payjoinSessionSources.get("$_receiverPrefix${sessionId}")!;
35
36
session.status = PayjoinSessionStatus.success.name;
@@ -41,8 +39,7 @@ class PayjoinStorage {
39
await session.save();
40
}
41
44
- Future<void> markReceiverSessionUnrecoverable(
45
- String sessionId, String reason) async {
42
+ Future<void> markReceiverSessionUnrecoverable(String sessionId, String reason) async {
43
final session = _payjoinSessionSources.get("$_receiverPrefix${sessionId}")!;
44
45
session.status = PayjoinSessionStatus.unrecoverable.name;
@@ -92,13 +89,10 @@ class PayjoinStorage {
89
await session.save();
90
}
91
95
- List<PayjoinSession> readAllOpenSessions(String walletId) =>
96
- _payjoinSessionSources.values
97
- .where((session) =>
98
- session.walletId == walletId &&
99
- ![
100
- PayjoinSessionStatus.success.name,
101
- PayjoinSessionStatus.unrecoverable.name
102
- ].contains(session.status))
103
- .toList();
92
+ List<PayjoinSession> readAllOpenSessions(String walletId) => _payjoinSessionSources.values
93
+ .where((session) =>
94
+ session.walletId == walletId &&
95
+ ![PayjoinSessionStatus.success.name, PayjoinSessionStatus.unrecoverable.name]
96
+ .contains(session.status))
97
+ .toList();
98
}
cw_bitcoin/lib/psbt/signer.dart
+19
-38
@@ -40,8 +40,7 @@ extension PsbtSigner on PsbtV2 {
40
return tx.buffer();
41
}
42
43
- Future<void> signWithUTXO(
44
- List<UtxoWithPrivateKey> utxos, UTXOSignerCallBack signer,
43
+ Future<void> signWithUTXO(List<UtxoWithPrivateKey> utxos, UTXOSignerCallBack signer,
44
[UTXOGetterCallBack? getTaprootPair]) async {
45
final raw = BytesUtils.toHexString(extractUnsignedTX(getSegwit: false));
46
final tx = BtcTransaction.fromRaw(raw);
@@ -53,8 +52,8 @@ extension PsbtSigner on PsbtV2 {
52
53
if (utxos.any((e) => e.utxo.isP2tr())) {
54
for (final input in tx.inputs) {
56
- final utxo = utxos.firstWhereOrNull(
57
- (u) => u.utxo.txHash == input.txId && u.utxo.vout == input.txIndex);
55
+ final utxo = utxos
56
+ .firstWhereOrNull((u) => u.utxo.txHash == input.txId && u.utxo.vout == input.txIndex);
57
58
if (utxo == null) {
59
final trPair = await getTaprootPair!.call(input.txId, input.txIndex);
@@ -81,8 +80,8 @@ extension PsbtSigner on PsbtV2 {
80
: BitcoinOpCodeConst.SIGHASH_ALL;
81
82
/// We generate transaction digest for current input
84
- final digest = _generateTransactionDigest(
85
- script, i, utxo.utxo, tx, taprootAmounts, taprootScripts);
83
+ final digest =
84
+ _generateTransactionDigest(script, i, utxo.utxo, tx, taprootAmounts, taprootScripts);
85
86
/// now we need sign the transaction digest
87
final sig = signer(digest, utxo, utxo.privateKey, sighash);
@@ -90,21 +89,14 @@ extension PsbtSigner on PsbtV2 {
89
if (utxo.utxo.isP2tr()) {
90
setInputTapKeySig(i, Uint8List.fromList(BytesUtils.fromHexString(sig)));
91
} else {
93
- setInputPartialSig(
94
- i,
95
- Uint8List.fromList(BytesUtils.fromHexString(utxo.public().toHex())),
92
+ setInputPartialSig(i, Uint8List.fromList(BytesUtils.fromHexString(utxo.public().toHex())),
93
Uint8List.fromList(BytesUtils.fromHexString(sig)));
94
}
95
}
96
}
97
101
- List<int> _generateTransactionDigest(
102
- Script scriptPubKeys,
103
- int input,
104
- BitcoinUtxo utxo,
105
- BtcTransaction transaction,
106
- List<BigInt> taprootAmounts,
107
- List<Script> tapRootPubKeys) {
98
+ List<int> _generateTransactionDigest(Script scriptPubKeys, int input, BitcoinUtxo utxo,
99
+ BtcTransaction transaction, List<BigInt> taprootAmounts, List<Script> tapRootPubKeys) {
100
if (utxo.isSegwit()) {
101
if (utxo.isP2tr()) {
102
return transaction.getTransactionTaprootDigset(
@@ -116,8 +108,7 @@ extension PsbtSigner on PsbtV2 {
108
return transaction.getTransactionSegwitDigit(
109
txInIndex: input, script: scriptPubKeys, amount: utxo.value);
110
}
119
- return transaction.getTransactionDigest(
120
- txInIndex: input, script: scriptPubKeys);
111
+ return transaction.getTransactionDigest(txInIndex: input, script: scriptPubKeys);
112
}
113
114
Script _findLockingScript(UtxoWithAddress utxo, bool isTaproot) {
@@ -172,11 +163,10 @@ extension PsbtSigner on PsbtV2 {
163
}
164
}
165
175
-typedef UTXOSignerCallBack = String Function(List<int> trDigest,
176
- UtxoWithAddress utxo, ECPrivate privateKey, int sighash);
166
+typedef UTXOSignerCallBack = String Function(
167
+ List<int> trDigest, UtxoWithAddress utxo, ECPrivate privateKey, int sighash);
168
178
-typedef UTXOGetterCallBack = Future<TaprootAmountScriptPair> Function(
179
- String txId, int vout);
169
+typedef UTXOGetterCallBack = Future<TaprootAmountScriptPair> Function(String txId, int vout);
170
171
class TaprootAmountScriptPair {
172
final BigInt value;
@@ -216,23 +206,17 @@ class UtxoWithPrivateKey extends UtxoWithAddress {
206
}
207
208
return UtxoWithPrivateKey(
219
- utxo: input.utxo,
220
- ownerDetails: input.ownerDetails,
221
- privateKey: key.privkey);
209
+ utxo: input.utxo, ownerDetails: input.ownerDetails, privateKey: key.privkey);
210
}
211
224
- factory UtxoWithPrivateKey.fromUnspent(
225
- BitcoinUnspent input, BitcoinWalletBase wallet) {
226
- final address =
227
- RegexUtils.addressTypeFromStr(input.address, BitcoinNetwork.mainnet);
212
+ factory UtxoWithPrivateKey.fromUnspent(BitcoinUnspent input, BitcoinWalletBase wallet) {
213
+ final address = RegexUtils.addressTypeFromStr(input.address, BitcoinNetwork.mainnet);
214
229
- final newHd =
230
- input.bitcoinAddressRecord.isHidden ? wallet.sideHd : wallet.mainHd;
215
+ final newHd = input.bitcoinAddressRecord.isHidden ? wallet.sideHd : wallet.mainHd;
216
217
ECPrivate privkey;
218
if (input.bitcoinAddressRecord is BitcoinSilentPaymentAddressRecord) {
234
- final unspentAddress =
235
- input.bitcoinAddressRecord as BitcoinSilentPaymentAddressRecord;
219
+ final unspentAddress = input.bitcoinAddressRecord as BitcoinSilentPaymentAddressRecord;
220
privkey = wallet.walletAddresses.silentAddress!.b_spend.tweakAdd(
221
BigintUtils.fromBytes(
222
BytesUtils.fromHexString(unspentAddress.silentPaymentTweak!),
@@ -240,9 +224,7 @@ class UtxoWithPrivateKey extends UtxoWithAddress {
224
);
225
} else {
226
privkey = generateECPrivate(
243
- hd: newHd,
244
- index: input.bitcoinAddressRecord.index,
245
- network: BitcoinNetwork.mainnet);
227
+ hd: newHd, index: input.bitcoinAddressRecord.index, network: BitcoinNetwork.mainnet);
228
}
229
230
return UtxoWithPrivateKey(
@@ -251,8 +233,7 @@ class UtxoWithPrivateKey extends UtxoWithAddress {
233
value: BigInt.from(input.value),
234
vout: input.vout,
235
scriptType: input.bitcoinAddressRecord.type,
254
- isSilentPayment:
255
- input.bitcoinAddressRecord is BitcoinSilentPaymentAddressRecord,
236
+ isSilentPayment: input.bitcoinAddressRecord is BitcoinSilentPaymentAddressRecord,
237
),
238
ownerDetails: UtxoAddressDetails(
239
publicKey: privkey.getPublic().toHex(),
cw_bitcoin/lib/psbt/transaction_builder.dart
+14
-17
@@ -11,7 +11,10 @@ class PSBTTransactionBuild {
11
final PsbtV2 psbt = PsbtV2();
12
13
PSBTTransactionBuild(
14
- {required List<PSBTReadyUtxoWithAddress> inputs, required List<BitcoinBaseOutput> outputs, required List<OutputInfo> cwOutputs, bool enableRBF = true}) {
14
+ {required List<PSBTReadyUtxoWithAddress> inputs,
15
+ required List<BitcoinBaseOutput> outputs,
16
+ required List<OutputInfo> cwOutputs,
17
+ bool enableRBF = true}) {
18
psbt.setGlobalTxVersion(2);
19
psbt.setGlobalInputCount(inputs.length);
20
psbt.setGlobalOutputCount(outputs.length);
@@ -23,10 +26,10 @@ class PSBTTransactionBuild {
26
printV(input.utxo.isSegwit());
27
printV(input.utxo.isP2shSegwit());
28
26
- psbt.setInputPreviousTxId(i, Uint8List.fromList(hex.decode(input.utxo.txHash).reversed.toList()));
29
+ psbt.setInputPreviousTxId(
30
+ i, Uint8List.fromList(hex.decode(input.utxo.txHash).reversed.toList()));
31
psbt.setInputOutputIndex(i, input.utxo.vout);
32
psbt.setInputSequence(i, enableRBF ? 0xfffffffd : 0xffffffff);
29
-
33
34
if (input.utxo.isSegwit()) {
35
setInputSegwit(i, input);
@@ -48,10 +51,10 @@ class PSBTTransactionBuild {
51
if (cwOutputs.isNotEmpty) {
52
try {
53
final cwOutput = cwOutputs
51
- .where((e) => [e.address, e.extractedAddress]
52
- .map((e) => e?.toLowerCase())
53
- .contains(output.address.toAddress().toLowerCase()))
54
- .firstOrNull;
54
+ .where((e) => [e.address, e.extractedAddress]
55
+ .map((e) => e?.toLowerCase())
56
+ .contains(output.address.toAddress().toLowerCase()))
57
+ .firstOrNull;
58
if (cwOutput != null &&
59
cwOutput.extra.containsKey('bip353_name') &&
60
cwOutput.extra.containsKey('bip353_proof')) {
@@ -80,20 +83,14 @@ class PSBTTransactionBuild {
83
84
void setInputP2pkh(int i, PSBTReadyUtxoWithAddress input) {
85
psbt.setInputNonWitnessUtxo(i, Uint8List.fromList(hex.decode(input.rawTx)));
83
- psbt.setInputBip32Derivation(
84
- i,
85
- Uint8List.fromList(hex.decode(input.ownerPublicKey)),
86
- input.ownerMasterFingerprint,
87
- BIPPath.fromString(input.ownerDerivationPath).toPathArray());
86
+ psbt.setInputBip32Derivation(i, Uint8List.fromList(hex.decode(input.ownerPublicKey)),
87
+ input.ownerMasterFingerprint, BIPPath.fromString(input.ownerDerivationPath).toPathArray());
88
}
89
90
void setInputSegwit(int i, PSBTReadyUtxoWithAddress input) {
91
psbt.setInputNonWitnessUtxo(i, Uint8List.fromList(hex.decode(input.rawTx)));
92
- psbt.setInputBip32Derivation(
93
- i,
94
- Uint8List.fromList(hex.decode(input.ownerPublicKey)),
95
- input.ownerMasterFingerprint,
96
- BIPPath.fromString(input.ownerDerivationPath).toPathArray());
92
+ psbt.setInputBip32Derivation(i, Uint8List.fromList(hex.decode(input.ownerPublicKey)),
93
+ input.ownerMasterFingerprint, BIPPath.fromString(input.ownerDerivationPath).toPathArray());
94
95
psbt.setInputWitnessUtxo(i, Uint8List.fromList(bigIntToUint64LE(input.utxo.value)),
96
Uint8List.fromList(input.ownerDetails.address.toScriptPubKey().toBytes()));
cw_bitcoin/lib/psbt/utils.dart
+1
-3
@@ -10,9 +10,7 @@ import 'package:ledger_bitcoin/psbt.dart';
10
String getTxIdFromPsbtV0(String psbt) {
11
final psbtV2 = PsbtV2()..deserializeV0(base64.decode(psbt));
12
13
- return BtcTransaction.fromRaw(
14
- BytesUtils.toHexString(psbtV2.extractUnsignedTX(false)))
15
- .txId();
13
+ return BtcTransaction.fromRaw(BytesUtils.toHexString(psbtV2.extractUnsignedTX(false))).txId();
14
}
15
16
String getOutputAmountFromPsbt(String psbtV0, BitcoinWalletBase wallet) {
cw_bitcoin/lib/psbt/v0_deserialize.dart
+4
-3
@@ -7,10 +7,10 @@ import 'package:ledger_bitcoin/src/utils/buffer_reader.dart';
7
import 'package:ledger_bitcoin/src/utils/uint8list_extension.dart' as ext;
8
9
extension PsbtSigner on PsbtV2 {
10
-
10
void deserializeV0(Uint8List psbt) {
11
final bufferReader = BufferReader(psbt);
13
- if (!listEquals(bufferReader.readSlice(5), Uint8List.fromList([0x70, 0x73, 0x62, 0x74, 0xff]))) {
12
+ if (!listEquals(
13
+ bufferReader.readSlice(5), Uint8List.fromList([0x70, 0x73, 0x62, 0x74, 0xff]))) {
14
throw Exception("Invalid magic bytes");
15
}
16
while (_readKeyPair(globalMap, bufferReader)) {}
@@ -26,7 +26,8 @@ extension PsbtSigner on PsbtV2 {
26
while (_readKeyPair(inputMaps[i], bufferReader)) {}
27
final input = tx.inputs[i];
28
setInputOutputIndex(i, input.txIndex);
29
- setInputPreviousTxId(i, Uint8List.fromList(BytesUtils.fromHexString(input.txId).reversed.toList()));
29
+ setInputPreviousTxId(
30
+ i, Uint8List.fromList(BytesUtils.fromHexString(input.txId).reversed.toList()));
31
setInputSequence(i, Uint8List.fromList(input.sequence).readUint32LE(0));
32
}
33
for (var i = 0; i < getGlobalOutputCount(); i++) {
cw_bitcoin/lib/psbt/v0_finalizer.dart
+2
-5
@@ -18,7 +18,6 @@ import "package:ledger_bitcoin/src/utils/buffer_writer.dart";
18
/// through PSBT_IN_PARTIAL_SIG or PSBT_IN_TAP_KEY_SIG
19
extension InputFinalizer on PsbtV2 {
20
void finalizeV0() {
21
-
21
// First check that each input has a signature
22
for (var i = 0; i < getGlobalInputCount(); i++) {
23
if (_isFinalized(i)) continue;
@@ -31,8 +30,7 @@ extension InputFinalizer on PsbtV2 {
30
}
31
if (legacyPubkeys.isNotEmpty) {
32
if (legacyPubkeys.length > 1) {
34
- throw Exception(
35
- 'Expected exactly one signature, got ${legacyPubkeys.length}');
33
+ throw Exception('Expected exactly one signature, got ${legacyPubkeys.length}');
34
}
35
if (taprootSig != null) {
36
throw Exception('Both taproot and non-taproot signatures present.');
@@ -55,8 +53,7 @@ extension InputFinalizer on PsbtV2 {
53
setInputFinalScriptwitness(i, witnessBuf.buffer());
54
if (isWrappedSegwit) {
55
if (redeemScript.isEmpty) {
58
- throw Exception(
59
- "Expected non-empty redeemscript. Can't finalize input $i");
56
+ throw Exception("Expected non-empty redeemscript. Can't finalize input $i");
57
}
58
final scriptSigBuf = BufferWriter()
59
..writeUInt8(redeemScript.length) // Push redeemScript length
cw_bitcoin/lib/utils.dart
+1
-1
@@ -52,4 +52,4 @@ String generateP2TRAddress({
52
}) =>
53
ECPublic.fromBip32(hd.childKey(Bip32KeyIndex(index)).publicKey)
54
.toTaprootAddress()
55
- .toAddress(network);
\ No newline at end of file
55
+ .toAddress(network);
cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart
+4
-4
@@ -87,8 +87,9 @@ class BitcoinCashWalletService extends WalletService<
87
}
88
await WalletInfo.delete(walletInfo);
89
90
- final unspentCoinsToDelete = unspentCoinsInfoSource.values.where(
91
- (unspentCoin) => unspentCoin.walletId == walletInfo.id).toList();
90
+ final unspentCoinsToDelete = unspentCoinsInfoSource.values
91
+ .where((unspentCoin) => unspentCoin.walletId == walletInfo.id)
92
+ .toList();
93
94
final keysToDelete = unspentCoinsToDelete.map((unspentCoin) => unspentCoin.key).toList();
95
@@ -122,8 +123,7 @@ class BitcoinCashWalletService extends WalletService<
123
walletInfo: credentials.walletInfo!,
124
unspentCoinsInfo: unspentCoinsInfoSource,
125
encryptionFileUtils: encryptionFileUtilsFor(isDirect),
125
- passphrase: credentials.passphrase
126
- );
126
+ passphrase: credentials.passphrase);
127
await wallet.save();
128
await wallet.init();
129
return wallet;
cw_bitcoin_cash/lib/src/exceptions/exceptions.dart
+1
-1
@@ -1 +1 @@
1
-export 'bitcoin_cash_mnemonic_is_incorrect_exception.dart';
\ No newline at end of file
1
+export 'bitcoin_cash_mnemonic_is_incorrect_exception.dart';
cw_core/lib/account.dart
+1
-1
@@ -9,4 +9,4 @@ class Account {
9
final int id;
10
final String label;
11
final String? balance;
12
-}
\ No newline at end of file
12
+}
cw_core/lib/account_list.dart
-1
@@ -1,7 +1,6 @@
1
import 'package:mobx/mobx.dart';
2
3
abstract class AccountList<T> {
4
-
4
ObservableList<T> get accounts;
5
6
void update();
cw_core/lib/address_info.part.dart
+1
-3
@@ -41,7 +41,5 @@ class AddressInfoAdapter extends TypeAdapter<AddressInfo> {
41
@override
42
bool operator ==(Object other) =>
43
identical(this, other) ||
44
- other is AddressInfoAdapter &&
45
- runtimeType == other.runtimeType &&
46
- typeId == other.typeId;
44
+ other is AddressInfoAdapter && runtimeType == other.runtimeType && typeId == other.typeId;
45
}
cw_core/lib/amount/amount_sanitizer.dart
-1
@@ -10,7 +10,6 @@ String _smartAmountSanitizer(String amount) {
10
return amount.replaceAll(",", ".");
11
}
12
13
-
13
extension SanitizerUserAmounts on String {
14
String sanitized() => _smartAmountSanitizer(this);
15
}
cw_core/lib/amount_converter.dart
+4
-5
@@ -9,19 +9,18 @@ class AmountConverter {
9
amount = amount.replaceAll(',', '');
10
final parts = amount.split('.');
11
final whole = parts[0].isEmpty ? '0' : parts[0];
12
- final frac = parts.length > 1 ? parts[1] : '';
12
+ final frac = parts.length > 1 ? parts[1] : '';
13
14
final fracPadded = (frac + '0' * decimals).substring(0, decimals);
15
16
final pow10 = BigInt.from(10).pow(decimals);
17
final wholeBI = BigInt.parse(whole);
18
- final fracBI = fracPadded.isEmpty ? BigInt.zero : BigInt.parse(fracPadded);
18
+ final fracBI = fracPadded.isEmpty ? BigInt.zero : BigInt.parse(fracPadded);
19
20
final res = wholeBI * pow10 + fracBI;
21
return neg ? '-${res.toString()}' : res.toString();
22
}
23
24
-
24
static String fromBaseUnits(String units, int decimals) {
25
units = units.trim();
26
if (units.isEmpty) return '0';
@@ -35,14 +34,14 @@ class AmountConverter {
34
if (units.length <= decimals) {
35
final s = units.padLeft(decimals + 1, '0'); // ensures at least "0xxxx"
36
final intPart = s.substring(0, s.length - decimals);
38
- var fracPart = s.substring(s.length - decimals);
37
+ var fracPart = s.substring(s.length - decimals);
38
fracPart = fracPart.replaceFirst(RegExp(r'0+$'), '');
39
final out = fracPart.isEmpty ? intPart : '$intPart.$fracPart';
40
return neg ? '-$out' : out;
41
}
42
43
final intPart = units.substring(0, units.length - decimals);
45
- var fracPart = units.substring(units.length - decimals);
44
+ var fracPart = units.substring(units.length - decimals);
45
fracPart = fracPart.replaceFirst(RegExp(r'0+$'), '');
46
final out = fracPart.isEmpty ? intPart : '$intPart.$fracPart';
47
return neg ? '-$out' : out;
cw_core/lib/balance_card_style_settings.dart
+13
-17
@@ -14,13 +14,13 @@ class BalanceCardStyleSettings {
14
15
BalanceCardStyleSettings(
16
{required this.walletInfoId,
17
- required this.accountIndex,
18
- required this.gradientIndex,
19
- required this.useSpecialDesign,
20
- required this.backgroundImagePath,
21
- this.iconStyleIndex = 0,
22
- this.isGradientOnly = false,
23
- required this.cardOrder});
17
+ required this.accountIndex,
18
+ required this.gradientIndex,
19
+ required this.useSpecialDesign,
20
+ required this.backgroundImagePath,
21
+ this.iconStyleIndex = 0,
22
+ this.isGradientOnly = false,
23
+ required this.cardOrder});
24
25
static const tableName = "BalanceCardStyleSettings";
26
@@ -59,21 +59,17 @@ class BalanceCardStyleSettings {
59
int iconStyleIndex = 0,
60
int? gradientIndexOverride,
61
}) {
62
- final int gradientIndex = gradientIndexOverride ??
63
- CardDesign.allGradients.indexOf(design.gradient);
62
+ final int gradientIndex =
63
+ gradientIndexOverride ?? CardDesign.allGradients.indexOf(design.gradient);
64
return BalanceCardStyleSettings(
65
walletInfoId: walletInfoId,
66
accountIndex: accountIndex,
67
gradientIndex: gradientIndex,
68
- useSpecialDesign:
69
- design.backgroundType == CardDesignBackgroundTypes.svgFull,
68
+ useSpecialDesign: design.backgroundType == CardDesignBackgroundTypes.svgFull,
69
backgroundImagePath:
71
- design.backgroundType == CardDesignBackgroundTypes.image
72
- ? design.imagePath
73
- : "",
70
+ design.backgroundType == CardDesignBackgroundTypes.image ? design.imagePath : "",
71
iconStyleIndex: iconStyleIndex,
75
- isGradientOnly:
76
- design.backgroundType == CardDesignBackgroundTypes.gradientOnly,
72
+ isGradientOnly: design.backgroundType == CardDesignBackgroundTypes.gradientOnly,
73
cardOrder: cardOrder,
74
);
75
}
@@ -104,4 +100,4 @@ class BalanceCardStyleSettings {
100
Future<void> insert() async {
101
db!.insert(tableName, toJson(), conflictAlgorithm: ConflictAlgorithm.replace);
102
}
107
-}
\ No newline at end of file
103
+}
cw_core/lib/card_design.dart
+123
-110
@@ -12,14 +12,13 @@ class CardColorCombination {
12
13
const CardColorCombination(
14
{required this.textColor,
15
- required this.textColorSecondary,
16
- required this.backgroundImageColor});
15
+ required this.textColorSecondary,
16
+ required this.backgroundImageColor});
17
18
static const light = CardColorCombination(
19
textColor: Color.fromARGB(200, 255, 255, 255),
20
textColorSecondary: Colors.white54,
21
- backgroundImageColor: Color.fromARGB(200, 0, 0, 0)
22
- );
21
+ backgroundImageColor: Color.fromARGB(200, 0, 0, 0));
22
23
static const dark = CardColorCombination(
24
textColor: Color.fromARGB(200, 0, 0, 0),
@@ -50,10 +49,11 @@ class CardDesign {
49
50
const CardDesign(
51
{this.backgroundType = CardDesignBackgroundTypes.svgIcon,
53
- this.gradient = const LinearGradient(colors: [Colors.black], begin: Alignment.topCenter, end: Alignment.bottomCenter),
54
- this.imagePath = "assets/new-ui/blank.svg",
55
- this.colors = CardColorCombination.dark,
56
- this.preColoredIcon = false});
52
+ this.gradient = const LinearGradient(
53
+ colors: [Colors.black], begin: Alignment.topCenter, end: Alignment.bottomCenter),
54
+ this.imagePath = "assets/new-ui/blank.svg",
55
+ this.colors = CardColorCombination.dark,
56
+ this.preColoredIcon = false});
57
58
static const LinearGradient gradientOrange = LinearGradient(
59
colors: <Color>[Color(0xFFFF7C02), Color(0xFFFF5602)],
@@ -129,71 +129,50 @@ class CardDesign {
129
130
static const genericDefault = CardDesign(gradient: gradientBlue);
131
132
- static const gradientOnlyDesign = CardDesign(
133
- backgroundType: CardDesignBackgroundTypes.gradientOnly,
134
- gradient: gradientBlue);
135
-
136
- static const btc = CardDesign(
137
- imagePath: "assets/new-ui/balance_card_icons/bitcoin.svg");
138
-
139
- static const eth = CardDesign(
140
- imagePath: "assets/new-ui/balance_card_icons/ethereum.svg");
132
+ static const gradientOnlyDesign =
133
+ CardDesign(backgroundType: CardDesignBackgroundTypes.gradientOnly, gradient: gradientBlue);
134
142
- static const btcln = CardDesign(
143
- imagePath: "assets/new-ui/balance_card_icons/lightning.svg");
135
+ static const btc = CardDesign(imagePath: "assets/new-ui/balance_card_icons/bitcoin.svg");
136
145
- static const xmr = CardDesign(
146
- imagePath: "assets/new-ui/balance_card_icons/monero.svg");
137
+ static const eth = CardDesign(imagePath: "assets/new-ui/balance_card_icons/ethereum.svg");
138
148
- static const ltc = CardDesign(
149
- imagePath: "assets/new-ui/balance_card_icons/litecoin.svg");
139
+ static const btcln = CardDesign(imagePath: "assets/new-ui/balance_card_icons/lightning.svg");
140
151
- static const bch = CardDesign(
152
- imagePath: "assets/new-ui/balance_card_icons/bitcoin_cash.svg");
141
+ static const xmr = CardDesign(imagePath: "assets/new-ui/balance_card_icons/monero.svg");
142
154
- static const doge = CardDesign(
155
- imagePath: "assets/new-ui/balance_card_icons/dogecoin.svg");
143
+ static const ltc = CardDesign(imagePath: "assets/new-ui/balance_card_icons/litecoin.svg");
144
157
- static const base = CardDesign(
158
- imagePath: "assets/new-ui/balance_card_icons/base.svg");
145
+ static const bch = CardDesign(imagePath: "assets/new-ui/balance_card_icons/bitcoin_cash.svg");
146
160
- static const pol = CardDesign(
161
- imagePath: "assets/new-ui/balance_card_icons/polygon.svg");
147
+ static const doge = CardDesign(imagePath: "assets/new-ui/balance_card_icons/dogecoin.svg");
148
163
- static const sol = CardDesign(
164
- imagePath: "assets/new-ui/balance_card_icons/solana.svg");
149
+ static const base = CardDesign(imagePath: "assets/new-ui/balance_card_icons/base.svg");
150
166
- static const tron = CardDesign(
167
- imagePath: "assets/new-ui/balance_card_icons/tron.svg");
151
+ static const pol = CardDesign(imagePath: "assets/new-ui/balance_card_icons/polygon.svg");
152
169
- static const nano = CardDesign(
170
- imagePath: "assets/new-ui/balance_card_icons/nano.svg");
153
+ static const sol = CardDesign(imagePath: "assets/new-ui/balance_card_icons/solana.svg");
154
172
- static const zano = CardDesign(
173
- imagePath: "assets/new-ui/balance_card_icons/zano.svg");
155
+ static const tron = CardDesign(imagePath: "assets/new-ui/balance_card_icons/tron.svg");
156
175
- static const wow = CardDesign(
176
- imagePath: "assets/new-ui/balance_card_icons/wownero.svg");
157
+ static const nano = CardDesign(imagePath: "assets/new-ui/balance_card_icons/nano.svg");
158
178
- static const dcr = CardDesign(
179
- imagePath: "assets/new-ui/balance_card_icons/decred.svg");
159
+ static const zano = CardDesign(imagePath: "assets/new-ui/balance_card_icons/zano.svg");
160
181
- static const arbitrum = CardDesign(
182
- imagePath: "assets/new-ui/balance_card_icons/arbitrum.svg");
161
+ static const wow = CardDesign(imagePath: "assets/new-ui/balance_card_icons/wownero.svg");
162
184
- static const zec = CardDesign(
185
- imagePath: "assets/new-ui/balance_card_icons/zcash.svg");
163
+ static const dcr = CardDesign(imagePath: "assets/new-ui/balance_card_icons/decred.svg");
164
187
- static const bnb = CardDesign(
188
- imagePath: "assets/new-ui/balance_card_icons/bnb.svg");
165
+ static const arbitrum = CardDesign(imagePath: "assets/new-ui/balance_card_icons/arbitrum.svg");
166
167
+ static const zec = CardDesign(imagePath: "assets/new-ui/balance_card_icons/zcash.svg");
168
169
+ static const bnb = CardDesign(imagePath: "assets/new-ui/balance_card_icons/bnb.svg");
170
171
static const ethSpecial = CardDesign(
172
gradient: const LinearGradient(
173
colors: <Color>[Color(0xFF6259FF), Color(0xFF3B20E6)],
195
- begin: Alignment.topCenter, end: Alignment.bottomCenter
196
- ),
174
+ begin: Alignment.topCenter,
175
+ end: Alignment.bottomCenter),
176
backgroundType: CardDesignBackgroundTypes.svgFull,
177
colors: CardColorCombination.light,
178
imagePath: "assets/new-ui/balance_card_backgrounds/ethereum.svg");
@@ -201,24 +180,24 @@ class CardDesign {
180
static const btcSpecial = CardDesign(
181
gradient: const LinearGradient(
182
colors: <Color>[Color(0xFFFFBF00), Color(0xFFFF6A00)],
204
- begin: Alignment.topCenter, end: Alignment.bottomCenter
205
- ),
183
+ begin: Alignment.topCenter,
184
+ end: Alignment.bottomCenter),
185
backgroundType: CardDesignBackgroundTypes.svgFull,
186
imagePath: "assets/new-ui/balance_card_backgrounds/bitcoin.svg");
187
188
static const xmrSpecial = CardDesign(
189
gradient: const LinearGradient(
190
colors: <Color>[Color(0xFFFF5900), Color(0xFFE62E00)],
212
- begin: Alignment.topCenter, end: Alignment.bottomCenter
213
- ),
191
+ begin: Alignment.topCenter,
192
+ end: Alignment.bottomCenter),
193
backgroundType: CardDesignBackgroundTypes.svgFull,
194
imagePath: "assets/new-ui/balance_card_backgrounds/monero.svg");
195
196
static const ltcSpecial = CardDesign(
197
gradient: const LinearGradient(
198
colors: <Color>[Color(0xFF2145BF), Color(0xFF072071)],
220
- begin: Alignment.topCenter, end: Alignment.bottomCenter
221
- ),
199
+ begin: Alignment.topCenter,
200
+ end: Alignment.bottomCenter),
201
backgroundType: CardDesignBackgroundTypes.svgFull,
202
colors: CardColorCombination.light,
203
imagePath: "assets/new-ui/balance_card_backgrounds/litecoin.svg");
@@ -226,8 +205,8 @@ class CardDesign {
205
static const lnSpecial = CardDesign(
206
gradient: const LinearGradient(
207
colors: <Color>[Color(0xFFFFBF00), Color(0xFFFF6A00)],
229
- begin: Alignment.topCenter, end: Alignment.bottomCenter
230
- ),
208
+ begin: Alignment.topCenter,
209
+ end: Alignment.bottomCenter),
210
backgroundType: CardDesignBackgroundTypes.svgFull,
211
colors: CardColorCombination.dark,
212
imagePath: "assets/new-ui/balance_card_backgrounds/lightning.svg");
@@ -235,8 +214,8 @@ class CardDesign {
214
static const tronSpecial = CardDesign(
215
gradient: const LinearGradient(
216
colors: <Color>[Color(0xFFFF1313), Color(0xFFB40000)],
238
- begin: Alignment.topCenter, end: Alignment.bottomCenter
239
- ),
217
+ begin: Alignment.topCenter,
218
+ end: Alignment.bottomCenter),
219
backgroundType: CardDesignBackgroundTypes.svgFull,
220
colors: CardColorCombination.light,
221
imagePath: "assets/new-ui/balance_card_backgrounds/tron.svg");
@@ -244,8 +223,8 @@ class CardDesign {
223
static const solSpecial = CardDesign(
224
gradient: const LinearGradient(
225
colors: <Color>[Color(0xFF4701AA), Color(0xFF19004B)],
247
- begin: Alignment.topCenter, end: Alignment.bottomCenter
248
- ),
226
+ begin: Alignment.topCenter,
227
+ end: Alignment.bottomCenter),
228
backgroundType: CardDesignBackgroundTypes.svgFull,
229
colors: CardColorCombination.light,
230
imagePath: "assets/new-ui/balance_card_backgrounds/solana.svg");
@@ -253,40 +232,40 @@ class CardDesign {
232
static const bchSpecial = CardDesign(
233
gradient: const LinearGradient(
234
colors: <Color>[Color(0xFF36DA4C), Color(0xFF008D57)],
256
- begin: Alignment.topCenter, end: Alignment.bottomCenter
257
- ),
235
+ begin: Alignment.topCenter,
236
+ end: Alignment.bottomCenter),
237
backgroundType: CardDesignBackgroundTypes.svgFull,
238
imagePath: "assets/new-ui/balance_card_backgrounds/bitcoin-cash.svg");
239
240
static const wowSpecial = CardDesign(
241
gradient: const LinearGradient(
242
colors: <Color>[Color(0xFFFF6CD3), Color(0xFFF200A9)],
264
- begin: Alignment.topCenter, end: Alignment.bottomCenter
265
- ),
243
+ begin: Alignment.topCenter,
244
+ end: Alignment.bottomCenter),
245
backgroundType: CardDesignBackgroundTypes.svgFull,
246
imagePath: "assets/new-ui/balance_card_backgrounds/wownero.svg");
247
248
static const dogeSpecial = CardDesign(
249
gradient: const LinearGradient(
250
colors: <Color>[Color(0xFFCBA818), Color(0xFF885D00)],
272
- begin: Alignment.topCenter, end: Alignment.bottomCenter
273
- ),
251
+ begin: Alignment.topCenter,
252
+ end: Alignment.bottomCenter),
253
backgroundType: CardDesignBackgroundTypes.svgFull,
254
imagePath: "assets/new-ui/balance_card_backgrounds/dogecoin.svg");
255
256
static const nanoSpecial = CardDesign(
257
gradient: const LinearGradient(
258
colors: <Color>[Color(0xFF209CE9), Color(0xFF0073CB)],
280
- begin: Alignment.topCenter, end: Alignment.bottomCenter
281
- ),
259
+ begin: Alignment.topCenter,
260
+ end: Alignment.bottomCenter),
261
backgroundType: CardDesignBackgroundTypes.svgFull,
262
imagePath: "assets/new-ui/balance_card_backgrounds/nano.svg");
263
264
static const polSpecial = CardDesign(
265
gradient: const LinearGradient(
266
colors: <Color>[Color(0xFF863FE3), Color(0xFF59098E)],
288
- begin: Alignment.topCenter, end: Alignment.bottomCenter
289
- ),
267
+ begin: Alignment.topCenter,
268
+ end: Alignment.bottomCenter),
269
backgroundType: CardDesignBackgroundTypes.svgFull,
270
colors: CardColorCombination.light,
271
imagePath: "assets/new-ui/balance_card_backgrounds/polygon.svg");
@@ -294,8 +273,8 @@ class CardDesign {
273
static const dcrSpecial = CardDesign(
274
gradient: const LinearGradient(
275
colors: <Color>[Color(0xFF2871FF), Color(0xFF0057FF)],
297
- begin: Alignment.topCenter, end: Alignment.bottomCenter
298
- ),
276
+ begin: Alignment.topCenter,
277
+ end: Alignment.bottomCenter),
278
colors: CardColorCombination.light,
279
backgroundType: CardDesignBackgroundTypes.svgFull,
280
imagePath: "assets/new-ui/balance_card_backgrounds/decred.svg");
@@ -303,8 +282,8 @@ class CardDesign {
282
static const zanoSpecial = CardDesign(
283
gradient: const LinearGradient(
284
colors: <Color>[Color(0xFF0004B4), Color(0xFF170069)],
306
- begin: Alignment.topCenter, end: Alignment.bottomCenter
307
- ),
285
+ begin: Alignment.topCenter,
286
+ end: Alignment.bottomCenter),
287
colors: CardColorCombination.black,
288
backgroundType: CardDesignBackgroundTypes.svgFull,
289
imagePath: "assets/new-ui/balance_card_backgrounds/zano.svg");
@@ -312,8 +291,8 @@ class CardDesign {
291
static const baseSpecial = CardDesign(
292
gradient: const LinearGradient(
293
colors: <Color>[Color(0xFF003CFF), Color(0xFF000087)],
315
- begin: Alignment.topCenter, end: Alignment.bottomCenter
316
- ),
294
+ begin: Alignment.topCenter,
295
+ end: Alignment.bottomCenter),
296
colors: CardColorCombination.light,
297
backgroundType: CardDesignBackgroundTypes.svgFull,
298
imagePath: "assets/new-ui/balance_card_backgrounds/base.svg");
@@ -321,8 +300,8 @@ class CardDesign {
300
static const arbitrumSpecial = CardDesign(
301
gradient: const LinearGradient(
302
colors: <Color>[Color(0xFF173F76), Color(0xFF031A39)],
324
- begin: Alignment.topCenter, end: Alignment.bottomCenter
325
- ),
303
+ begin: Alignment.topCenter,
304
+ end: Alignment.bottomCenter),
305
colors: CardColorCombination.light,
306
backgroundType: CardDesignBackgroundTypes.svgFull,
307
imagePath: "assets/new-ui/balance_card_backgrounds/arbitrum.svg");
@@ -330,16 +309,16 @@ class CardDesign {
309
static const zecSpecial = CardDesign(
310
gradient: const LinearGradient(
311
colors: <Color>[Color(0xFFF6C527), Color(0xFFCD8C00)],
333
- begin: Alignment.topCenter, end: Alignment.bottomCenter
334
- ),
312
+ begin: Alignment.topCenter,
313
+ end: Alignment.bottomCenter),
314
backgroundType: CardDesignBackgroundTypes.svgFull,
315
imagePath: "assets/new-ui/balance_card_backgrounds/zcash.svg");
316
317
static const bnbSpecial = CardDesign(
318
gradient: const LinearGradient(
319
colors: <Color>[Color(0xFF603000), Color(0xFFF0B90B)],
341
- begin: Alignment.topCenter, end: Alignment.bottomCenter
342
- ),
320
+ begin: Alignment.topCenter,
321
+ end: Alignment.bottomCenter),
322
colors: CardColorCombination.light,
323
backgroundType: CardDesignBackgroundTypes.svgFull,
324
imagePath: "assets/new-ui/balance_card_backgrounds/bnb.svg");
@@ -351,12 +330,14 @@ class CardDesign {
330
backgroundType: backgroundType,
331
preColoredIcon: preColoredIcon);
332
354
- CardDesign withGradientAndColorCombination(Gradient gradient, CardColorCombination cardColorCombination) => CardDesign(
355
- gradient: gradient,
356
- colors: cardColorCombination,
357
- imagePath: imagePath,
358
- backgroundType: backgroundType,
359
- preColoredIcon: preColoredIcon);
333
+ CardDesign withGradientAndColorCombination(
334
+ Gradient gradient, CardColorCombination cardColorCombination) =>
335
+ CardDesign(
336
+ gradient: gradient,
337
+ colors: cardColorCombination,
338
+ imagePath: imagePath,
339
+ backgroundType: backgroundType,
340
+ preColoredIcon: preColoredIcon);
341
342
CardDesign withIcon(CardIconPath icon) => CardDesign(
343
gradient: gradient,
@@ -374,8 +355,10 @@ class CardDesign {
355
356
static const Map<CryptoCurrency, _CurrencyIconNames> _iconNames = {
357
CryptoCurrency.arbEth: _CurrencyIconNames(ticker: 'arb', longName: 'arbitrum'),
377
- CryptoCurrency.baseEth: _CurrencyIconNames(ticker: 'base', longName: 'base', chainFile: 'base_icon'),
378
- CryptoCurrency.bch: _CurrencyIconNames(ticker: 'bch', longName: 'bitcoin_cash', chainFile: 'bitcoin-cash'),
358
+ CryptoCurrency.baseEth:
359
+ _CurrencyIconNames(ticker: 'base', longName: 'base', chainFile: 'base_icon'),
360
+ CryptoCurrency.bch:
361
+ _CurrencyIconNames(ticker: 'bch', longName: 'bitcoin_cash', chainFile: 'bitcoin-cash'),
362
CryptoCurrency.btc: _CurrencyIconNames(ticker: 'btc', longName: 'bitcoin', outlineFile: 'BTC'),
363
CryptoCurrency.bnb: _CurrencyIconNames(ticker: 'bnb', longName: 'bnb'),
364
CryptoCurrency.dcr: _CurrencyIconNames(ticker: 'dcr', longName: 'decred'),
@@ -383,13 +366,13 @@ class CardDesign {
366
CryptoCurrency.eth: _CurrencyIconNames(ticker: 'eth', longName: 'ethereum'),
367
CryptoCurrency.btcln: _CurrencyIconNames(ticker: 'ln', longName: 'lightning'),
368
CryptoCurrency.ltc: _CurrencyIconNames(ticker: 'ltc', longName: 'litecoin'),
386
- CryptoCurrency.xmr: _CurrencyIconNames(
387
- ticker: 'xmr', longName: 'monero', ogPath: 'assets/images/xmr-og.webp'),
369
+ CryptoCurrency.xmr:
370
+ _CurrencyIconNames(ticker: 'xmr', longName: 'monero', ogPath: 'assets/images/xmr-og.webp'),
371
CryptoCurrency.nano: _CurrencyIconNames(ticker: 'xno', longName: 'nano'),
372
CryptoCurrency.maticpoly: _CurrencyIconNames(ticker: 'pol', longName: 'polygon'),
373
CryptoCurrency.sol: _CurrencyIconNames(ticker: 'sol', longName: 'solana'),
391
- CryptoCurrency.trx: _CurrencyIconNames(
392
- ticker: 'trx', longName: 'tron', ogPath: '$_ogIconPrefix/tron-og.svg'),
374
+ CryptoCurrency.trx:
375
+ _CurrencyIconNames(ticker: 'trx', longName: 'tron', ogPath: '$_ogIconPrefix/tron-og.svg'),
376
CryptoCurrency.zano: _CurrencyIconNames(ticker: 'zano', longName: 'zano'),
377
CryptoCurrency.zec: _CurrencyIconNames(ticker: 'zec', longName: 'zcash'),
378
};
@@ -408,7 +391,40 @@ class CardDesign {
391
];
392
}
393
411
- static const List<CardDesign> all = [genericDefault, btc, eth, xmr, ltc, eth, pol, doge, base, sol, btcln, tron, zano, dcr, arbitrum, zec, bnb, ethSpecial, btcSpecial, xmrSpecial, ltcSpecial, lnSpecial, tronSpecial, bchSpecial, wowSpecial, dogeSpecial, polSpecial, dcrSpecial, zanoSpecial, arbitrumSpecial, zecSpecial, bnbSpecial];
394
+ static const List<CardDesign> all = [
395
+ genericDefault,
396
+ btc,
397
+ eth,
398
+ xmr,
399
+ ltc,
400
+ eth,
401
+ pol,
402
+ doge,
403
+ base,
404
+ sol,
405
+ btcln,
406
+ tron,
407
+ zano,
408
+ dcr,
409
+ arbitrum,
410
+ zec,
411
+ bnb,
412
+ ethSpecial,
413
+ btcSpecial,
414
+ xmrSpecial,
415
+ ltcSpecial,
416
+ lnSpecial,
417
+ tronSpecial,
418
+ bchSpecial,
419
+ wowSpecial,
420
+ dogeSpecial,
421
+ polSpecial,
422
+ dcrSpecial,
423
+ zanoSpecial,
424
+ arbitrumSpecial,
425
+ zecSpecial,
426
+ bnbSpecial
427
+ ];
428
429
static CardDesign forCurrencySpecial(CryptoCurrency currency) {
430
return specialDesignsForCurrencies[currency] ?? genericDefault;
@@ -437,7 +453,6 @@ class CardDesign {
453
CryptoCurrency.zec: zec,
454
CryptoCurrency.dcr: dcr,
455
CryptoCurrency.bnb: bnb,
440
-
456
};
457
458
static const Map<CryptoCurrency, CardDesign> specialDesignsForCurrencies = {
@@ -504,9 +519,9 @@ class CardDesign {
519
520
if (setting.isGradientOnly) {
521
final gradient = gradientForStoredIndex(setting.gradientIndex, walletCurrency);
507
- final textColors = preferredColorCombinations[gradient]
508
- ?? specialDesignsForCurrencies[walletCurrency]?.colors
509
- ?? gradientOnlyDesign.colors;
522
+ final textColors = preferredColorCombinations[gradient] ??
523
+ specialDesignsForCurrencies[walletCurrency]?.colors ??
524
+ gradientOnlyDesign.colors;
525
return gradientOnlyDesign.withGradientAndColorCombination(gradient, textColors);
526
}
527
@@ -521,11 +536,9 @@ class CardDesign {
536
}
537
538
if (!setting.useSpecialDesign && setting.gradientIndex == -1) {
524
- final specialColors =
525
- specialDesignsForCurrencies[walletCurrency] ?? genericDefault;
539
+ final specialColors = specialDesignsForCurrencies[walletCurrency] ?? genericDefault;
540
final design = CardDesign.forCurrencyIcon(walletCurrency)
527
- .withGradientAndColorCombination(
528
- specialColors.gradient, specialColors.colors);
541
+ .withGradientAndColorCombination(specialColors.gradient, specialColors.colors);
542
return design.withIconStyleIndex(setting.iconStyleIndex, walletCurrency);
543
}
544
if (setting.useSpecialDesign) {
@@ -534,9 +547,9 @@ class CardDesign {
547
if (setting.gradientIndex != -1) {
548
final baseIcon = CardDesign.forCurrencyIcon(walletCurrency);
549
final gradient = gradientForStoredIndex(setting.gradientIndex, walletCurrency);
537
- final textColors = preferredColorCombinations[gradient]
538
- ?? specialDesignsForCurrencies[walletCurrency]?.colors
539
- ?? baseIcon.colors;
550
+ final textColors = preferredColorCombinations[gradient] ??
551
+ specialDesignsForCurrencies[walletCurrency]?.colors ??
552
+ baseIcon.colors;
553
return baseIcon
554
.withGradientAndColorCombination(gradient, textColors)
555
.withIconStyleIndex(setting.iconStyleIndex, walletCurrency);
@@ -561,4 +574,4 @@ class _CurrencyIconNames {
574
this.chainFile,
575
this.ogPath,
576
});
564
-}
\ No newline at end of file
577
+}
cw_core/lib/crypto_amount_format.dart
-1
@@ -37,7 +37,6 @@ extension MaxDecimals on String {
37
return parts.join(".");
38
}
39
40
-
40
/// Format a stringified number to a localized representation
41
/// 1.000.000,00 in de_DE
42
/// 1’000’000.00 in de_CH
cw_core/lib/crypto_currency.dart
+848
-149
@@ -161,143 +161,846 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
161
162
// well technically not currencies but since we had them a long time ago and don't want to break
163
// the app for users who had contacts saved for them
164
- static const zcashCurrencies = [ zec, zaddr, tzec ];
164
+ static const zcashCurrencies = [zec, zaddr, tzec];
165
166
// title, tag (if applicable), fullName (if unique), raw, name, iconPath
167
- static const xmr = CryptoCurrency(title: 'XMR', fullName: 'Monero', raw: 0, name: 'xmr', iconPath: 'assets/new-ui/crypto_full_icons/monero.svg', decimals: 12, flatIconPath: "assets/new-ui/balance_card_icons/monero.svg");
168
- static const ada = CryptoCurrency(title: 'ADA', fullName: 'Cardano', raw: 1, name: 'ada', iconPath: 'assets/images/ada_icon.png', decimals: 6);
169
- static const bch = CryptoCurrency(title: 'BCH', fullName: 'Bitcoin Cash', raw: 2, name: 'bch', iconPath: 'assets/new-ui/crypto_full_icons/bitcoin-cash.svg', decimals: 8, flatIconPath: "assets/new-ui/balance_card_icons/bitcoin_cash.svg");
170
- static const bnb = CryptoCurrency(title: 'BNB', tag: 'BSC', fullName: 'BNB', raw: 3, name: 'bnb', iconPath: 'assets/new-ui/crypto_full_icons/bnb.svg', decimals: 18, flatIconPath: "assets/new-ui/balance_card_icons/bnb.svg", chainIconPath: "assets/new-ui/chain_badges/bnb.svg");
171
- static const btc = CryptoCurrency(title: 'BTC', fullName: 'Bitcoin', raw: 4, name: 'btc', iconPath: 'assets/new-ui/crypto_full_icons/bitcoin.svg' ,decimals: 8, flatIconPath: "assets/new-ui/balance_card_icons/bitcoin.svg");
172
- static const dai = CryptoCurrency(title: 'DAI', tag: 'ETH', fullName: 'Dai', raw: 5, name: 'dai', iconPath: 'assets/new-ui/crypto_full_icons/dai.svg', decimals: 18, groups: const {CurrencyGroups.stablecoin});
173
- static const dash = CryptoCurrency(title: 'DASH', fullName: 'Dash', raw: 6, name: 'dash', iconPath: 'assets/images/dash_icon.png', decimals: 8);
174
- static const eos = CryptoCurrency(title: 'EOS', fullName: 'EOS', raw: 7, name: 'eos', iconPath: 'assets/images/eos_icon.png', decimals: 4);
175
- static const eth = CryptoCurrency(title: 'ETH', fullName: 'Ethereum', raw: 8, name: 'eth', iconPath: 'assets/new-ui/crypto_full_icons/ethereum.svg', decimals: 18, flatIconPath: "assets/new-ui/balance_card_icons/ethereum.svg", chainIconPath: "assets/new-ui/chain_badges/ethereum.svg");
176
- static const ltc = CryptoCurrency(title: 'LTC', fullName: 'Litecoin', raw: 9, name: 'ltc', iconPath: 'assets/new-ui/crypto_full_icons/litecoin.svg', decimals: 8, flatIconPath: "assets/new-ui/balance_card_icons/litecoin.svg", chainIconPath: "assets/new-ui/chain_badges/mweb.svg");
177
- static const nano = CryptoCurrency(title: 'XNO', fullName: 'Nano', raw: 10, name: 'xno', iconPath: 'assets/new-ui/crypto_full_icons/nano.svg', decimals: 30, flatIconPath: "assets/new-ui/balance_card_icons/nano.svg");
178
- static const trx = CryptoCurrency(title: 'TRX', fullName: 'TRON', raw: 11, name: 'trx', iconPath: 'assets/new-ui/crypto_full_icons/tron.svg', decimals: 6, flatIconPath: "assets/new-ui/balance_card_icons/tron.svg", chainIconPath: "assets/new-ui/chain_badges/tron.svg");
179
- static const usdt = CryptoCurrency(title: 'USDT', tag: 'OMNI', fullName: 'Tether', raw: 12, name: 'usdt', iconPath: 'assets/new-ui/crypto_full_icons/usdt.svg', decimals: 6, groups: const {CurrencyGroups.stablecoin});
180
- static const usdterc20 = CryptoCurrency(title: 'USDT', tag: 'ETH', fullName: 'Tether', raw: 13, name: 'usdterc20', iconPath: 'assets/new-ui/crypto_full_icons/usdt.svg', decimals: 6, groups: const {CurrencyGroups.stablecoin});
181
- static const xlm = CryptoCurrency(title: 'XLM', fullName: 'Stellar', raw: 14, name: 'xlm', iconPath: 'assets/images/xlm_icon.png', decimals: 7);
182
- static const xrp = CryptoCurrency(title: 'XRP', fullName: 'Ripple', raw: 15, name: 'xrp', iconPath: 'assets/images/xrp_icon.png', decimals: 6);
183
- static const xhv = CryptoCurrency(title: 'XHV', fullName: 'Haven Protocol', raw: 16, name: 'xhv', iconPath: 'assets/images/xhv_logo.png', decimals: 12);
184
-
185
- static const xag = CryptoCurrency(title: 'XAG', tag: 'XHV', raw: 17, name: 'xag', decimals: 12);
167
+ static const xmr = CryptoCurrency(
168
+ title: 'XMR',
169
+ fullName: 'Monero',
170
+ raw: 0,
171
+ name: 'xmr',
172
+ iconPath: 'assets/new-ui/crypto_full_icons/monero.svg',
173
+ decimals: 12,
174
+ flatIconPath: "assets/new-ui/balance_card_icons/monero.svg");
175
+ static const ada = CryptoCurrency(
176
+ title: 'ADA',
177
+ fullName: 'Cardano',
178
+ raw: 1,
179
+ name: 'ada',
180
+ iconPath: 'assets/images/ada_icon.png',
181
+ decimals: 6);
182
+ static const bch = CryptoCurrency(
183
+ title: 'BCH',
184
+ fullName: 'Bitcoin Cash',
185
+ raw: 2,
186
+ name: 'bch',
187
+ iconPath: 'assets/new-ui/crypto_full_icons/bitcoin-cash.svg',
188
+ decimals: 8,
189
+ flatIconPath: "assets/new-ui/balance_card_icons/bitcoin_cash.svg");
190
+ static const bnb = CryptoCurrency(
191
+ title: 'BNB',
192
+ tag: 'BSC',
193
+ fullName: 'BNB',
194
+ raw: 3,
195
+ name: 'bnb',
196
+ iconPath: 'assets/new-ui/crypto_full_icons/bnb.svg',
197
+ decimals: 18,
198
+ flatIconPath: "assets/new-ui/balance_card_icons/bnb.svg",
199
+ chainIconPath: "assets/new-ui/chain_badges/bnb.svg");
200
+ static const btc = CryptoCurrency(
201
+ title: 'BTC',
202
+ fullName: 'Bitcoin',
203
+ raw: 4,
204
+ name: 'btc',
205
+ iconPath: 'assets/new-ui/crypto_full_icons/bitcoin.svg',
206
+ decimals: 8,
207
+ flatIconPath: "assets/new-ui/balance_card_icons/bitcoin.svg");
208
+ static const dai = CryptoCurrency(
209
+ title: 'DAI',
210
+ tag: 'ETH',
211
+ fullName: 'Dai',
212
+ raw: 5,
213
+ name: 'dai',
214
+ iconPath: 'assets/new-ui/crypto_full_icons/dai.svg',
215
+ decimals: 18,
216
+ groups: const {CurrencyGroups.stablecoin});
217
+ static const dash = CryptoCurrency(
218
+ title: 'DASH',
219
+ fullName: 'Dash',
220
+ raw: 6,
221
+ name: 'dash',
222
+ iconPath: 'assets/images/dash_icon.png',
223
+ decimals: 8);
224
+ static const eos = CryptoCurrency(
225
+ title: 'EOS',
226
+ fullName: 'EOS',
227
+ raw: 7,
228
+ name: 'eos',
229
+ iconPath: 'assets/images/eos_icon.png',
230
+ decimals: 4);
231
+ static const eth = CryptoCurrency(
232
+ title: 'ETH',
233
+ fullName: 'Ethereum',
234
+ raw: 8,
235
+ name: 'eth',
236
+ iconPath: 'assets/new-ui/crypto_full_icons/ethereum.svg',
237
+ decimals: 18,
238
+ flatIconPath: "assets/new-ui/balance_card_icons/ethereum.svg",
239
+ chainIconPath: "assets/new-ui/chain_badges/ethereum.svg");
240
+ static const ltc = CryptoCurrency(
241
+ title: 'LTC',
242
+ fullName: 'Litecoin',
243
+ raw: 9,
244
+ name: 'ltc',
245
+ iconPath: 'assets/new-ui/crypto_full_icons/litecoin.svg',
246
+ decimals: 8,
247
+ flatIconPath: "assets/new-ui/balance_card_icons/litecoin.svg",
248
+ chainIconPath: "assets/new-ui/chain_badges/mweb.svg");
249
+ static const nano = CryptoCurrency(
250
+ title: 'XNO',
251
+ fullName: 'Nano',
252
+ raw: 10,
253
+ name: 'xno',
254
+ iconPath: 'assets/new-ui/crypto_full_icons/nano.svg',
255
+ decimals: 30,
256
+ flatIconPath: "assets/new-ui/balance_card_icons/nano.svg");
257
+ static const trx = CryptoCurrency(
258
+ title: 'TRX',
259
+ fullName: 'TRON',
260
+ raw: 11,
261
+ name: 'trx',
262
+ iconPath: 'assets/new-ui/crypto_full_icons/tron.svg',
263
+ decimals: 6,
264
+ flatIconPath: "assets/new-ui/balance_card_icons/tron.svg",
265
+ chainIconPath: "assets/new-ui/chain_badges/tron.svg");
266
+ static const usdt = CryptoCurrency(
267
+ title: 'USDT',
268
+ tag: 'OMNI',
269
+ fullName: 'Tether',
270
+ raw: 12,
271
+ name: 'usdt',
272
+ iconPath: 'assets/new-ui/crypto_full_icons/usdt.svg',
273
+ decimals: 6,
274
+ groups: const {CurrencyGroups.stablecoin});
275
+ static const usdterc20 = CryptoCurrency(
276
+ title: 'USDT',
277
+ tag: 'ETH',
278
+ fullName: 'Tether',
279
+ raw: 13,
280
+ name: 'usdterc20',
281
+ iconPath: 'assets/new-ui/crypto_full_icons/usdt.svg',
282
+ decimals: 6,
283
+ groups: const {CurrencyGroups.stablecoin});
284
+ static const xlm = CryptoCurrency(
285
+ title: 'XLM',
286
+ fullName: 'Stellar',
287
+ raw: 14,
288
+ name: 'xlm',
289
+ iconPath: 'assets/images/xlm_icon.png',
290
+ decimals: 7);
291
+ static const xrp = CryptoCurrency(
292
+ title: 'XRP',
293
+ fullName: 'Ripple',
294
+ raw: 15,
295
+ name: 'xrp',
296
+ iconPath: 'assets/images/xrp_icon.png',
297
+ decimals: 6);
298
+ static const xhv = CryptoCurrency(
299
+ title: 'XHV',
300
+ fullName: 'Haven Protocol',
301
+ raw: 16,
302
+ name: 'xhv',
303
+ iconPath: 'assets/images/xhv_logo.png',
304
+ decimals: 12);
305
+
306
+ static const xag = CryptoCurrency(title: 'XAG', tag: 'XHV', raw: 17, name: 'xag', decimals: 12);
307
static const xau = CryptoCurrency(title: 'XAU', tag: 'XHV', raw: 18, name: 'xau', decimals: 12);
187
- static const xaud = CryptoCurrency(title: 'XAUD', tag: 'XHV', raw: 19, name: 'xaud', decimals: 12);
188
- static const xbtc = CryptoCurrency(title: 'XBTC', tag: 'XHV', raw: 20, name: 'xbtc', decimals: 12);
189
- static const xcad = CryptoCurrency(title: 'XCAD', tag: 'XHV', raw: 21, name: 'xcad', decimals: 12);
190
- static const xchf = CryptoCurrency(title: 'XCHF', tag: 'XHV', raw: 22, name: 'xchf', decimals: 12);
191
- static const xcny = CryptoCurrency(title: 'XCNY', tag: 'XHV', raw: 23, name: 'xcny', decimals: 12);
192
- static const xeur = CryptoCurrency(title: 'XEUR', tag: 'XHV', raw: 24, name: 'xeur', decimals: 12);
193
- static const xgbp = CryptoCurrency(title: 'XGBP', tag: 'XHV', raw: 25, name: 'xgbp', decimals: 12);
194
- static const xjpy = CryptoCurrency(title: 'XJPY', tag: 'XHV', raw: 26, name: 'xjpy', decimals: 12);
195
- static const xnok = CryptoCurrency(title: 'XNOK', tag: 'XHV', raw: 27, name: 'xnok', decimals: 12);
196
- static const xnzd = CryptoCurrency(title: 'XNZD', tag: 'XHV', raw: 28, name: 'xnzd', decimals: 12);
197
- static const xusd = CryptoCurrency(title: 'XUSD', tag: 'XHV', raw: 29, name: 'xusd', decimals: 12);
198
-
199
- static const ape = CryptoCurrency(title: 'APE', tag: 'ETH', fullName: 'ApeCoin', raw: 30, name: 'ape', iconPath: 'assets/images/ape_icon.png', decimals: 18);
200
- static const avaxc = CryptoCurrency(title: 'AVAX', tag: 'AVAXC', fullName: 'Avalanche', raw: 31, name: 'avaxc', iconPath: 'assets/new-ui/crypto_full_icons/avax.svg', decimals: 9);
201
- static const btt = CryptoCurrency(title: 'BTT', tag: 'ETH', fullName: 'BitTorrent', raw: 32, name: 'btt', iconPath: 'assets/images/btt_icon.png', decimals: 18);
202
- static const bttc = CryptoCurrency(title: 'BTTC', tag: 'TRX', fullName: 'BitTorrent-NEW', raw: 33, name: 'bttc', iconPath: 'assets/images/btt_icon.png', decimals: 18);
203
- static const doge = CryptoCurrency(title: 'DOGE', fullName: 'Dogecoin', raw: 34, name: 'doge', iconPath: 'assets/new-ui/crypto_full_icons/dogecoin.svg', decimals: 8, flatIconPath: "assets/new-ui/balance_card_icons/dogecoin.svg");
204
- static const firo = CryptoCurrency(title: 'FIRO', raw: 35, name: 'firo', iconPath: 'assets/images/firo_icon.png', decimals: 8);
205
- static const usdttrc20 = CryptoCurrency(title: 'USDT', tag: 'TRX', fullName: 'Tether', raw: 36, name: 'usdttrc20', iconPath: 'assets/new-ui/crypto_full_icons/usdt.svg', decimals: 6, groups: const {CurrencyGroups.stablecoin});
206
- static const hbar = CryptoCurrency(title: 'HBAR', fullName: 'Hedera', raw: 37, name: 'hbar', iconPath: 'assets/images/hbar_icon.png', decimals: 8);
207
- static const sc = CryptoCurrency(title: 'SC', fullName: 'Siacoin', raw: 38, name: 'sc', iconPath: 'assets/images/sc_icon.png', decimals: 16);
208
- static const sol = CryptoCurrency(title: 'SOL', fullName: 'Solana', raw: 39, name: 'sol', iconPath: 'assets/new-ui/crypto_full_icons/solana.svg', decimals: 9, flatIconPath: "assets/new-ui/balance_card_icons/solana.svg", chainIconPath: "assets/new-ui/chain_badges/solana.svg");
209
- static const usdc = CryptoCurrency(title: 'USDC', tag: 'ETH', fullName: 'USDC', raw: 40, name: 'usdc', iconPath: 'assets/new-ui/crypto_full_icons/usdc.svg', decimals: 6, groups: const {CurrencyGroups.stablecoin});
210
- static const usdcsol = CryptoCurrency(title: 'USDC', tag: 'SOL', fullName: 'USDC Coin', raw: 41, name: 'usdcsol', iconPath: 'assets/new-ui/crypto_full_icons/usdc.svg', decimals: 6, groups: const {CurrencyGroups.stablecoin});
211
- static const zaddr = CryptoCurrency(title: 'ZZEC', tag: 'ZEC', fullName: 'Shielded Zcash', raw: 42, name: 'zaddr', iconPath: 'assets/new-ui/crypto_full_icons/zcash.svg', decimals: 8);
212
- static const tzec = CryptoCurrency(title: 'tZEC', tag: 'ZEC', fullName: 'Transparent Zcash', raw: 43, name: 'zec', iconPath: 'assets/new-ui/crypto_full_icons/zcash.svg', decimals: 8);
213
- static const zen = CryptoCurrency(title: 'ZEN', fullName: 'Horizen', raw: 44, name: 'zen', iconPath: 'assets/images/zen_icon.png', decimals: 8);
214
- static const xvg = CryptoCurrency(title: 'XVG', fullName: 'Verge', raw: 45, name: 'xvg', iconPath: 'assets/images/xvg_icon.png', decimals: 8);
215
-
216
- static const usdcpoly = CryptoCurrency(title: 'USDC', tag: 'POL', fullName: 'USDC', raw: 46, name: 'usdcpoly', iconPath: 'assets/new-ui/crypto_full_icons/usdc.svg', decimals: 6, groups: const {CurrencyGroups.stablecoin});
217
- static const dcr = CryptoCurrency(title: 'DCR', fullName: 'Decred', raw: 47, name: 'dcr', iconPath: 'assets/new-ui/crypto_full_icons/decred.svg', decimals: 8, flatIconPath: "assets/new-ui/balance_card_icons/decred.svg");
218
- static const kmd = CryptoCurrency(title: 'KMD', fullName: 'Komodo', raw: 48, name: 'kmd', iconPath: 'assets/images/kmd_icon.png', decimals: 8);
219
- static const mana = CryptoCurrency(title: 'MANA', tag: 'ETH', fullName: 'Decentraland', raw: 49, name: 'mana', iconPath: 'assets/images/mana_icon.png', decimals: 18);
220
- static const maticpoly = CryptoCurrency(title: 'POL', tag: 'POL', fullName: 'Polygon', raw: 50, name: 'maticpoly', iconPath: 'assets/new-ui/crypto_full_icons/polygon.svg', decimals: 18, flatIconPath: "assets/new-ui/balance_card_icons/polygon.svg", chainIconPath: "assets/new-ui/chain_badges/polygon.svg");
221
- static const matic = CryptoCurrency(title: 'MATIC', tag: 'ETH', fullName: 'Polygon', raw: 51, name: 'matic', iconPath: 'assets/new-ui/crypto_full_icons/polygon.svg', decimals: 18, flatIconPath: "assets/new-ui/balance_card_icons/polygon.svg");
222
- static const mkr = CryptoCurrency(title: 'MKR', tag: 'ETH', fullName: 'Maker', raw: 52, name: 'mkr', iconPath: 'assets/images/mkr_icon.png', decimals: 18);
223
- static const near = CryptoCurrency(title: 'NEAR', fullName: 'NEAR Protocol', raw: 53, name: 'near', iconPath: 'assets/images/near_icon.png', decimals: 24);
224
- static const oxt = CryptoCurrency(title: 'OXT', tag: 'ETH', fullName: 'Orchid', raw: 54, name: 'oxt', iconPath: 'assets/images/oxt_icon.png', decimals: 18);
225
- static const paxg = CryptoCurrency(title: 'PAXG', tag: 'ETH', fullName: 'Pax Gold', raw: 55, name: 'paxg', iconPath: 'assets/new-ui/crypto_full_icons/paxg.svg', decimals: 18);
226
- static const pivx = CryptoCurrency(title: 'PIVX', raw: 56, name: 'pivx', iconPath: 'assets/images/pivx_icon.png', decimals: 8);
227
- static const rune = CryptoCurrency(title: 'RUNE', fullName: 'Thorchain', raw: 57, name: 'rune', iconPath: 'assets/images/rune_icon.png', decimals: 18);
228
- static const rvn = CryptoCurrency(title: 'RVN', fullName: 'Ravencoin', raw: 58, name: 'rvn', iconPath: 'assets/images/rvn_icon.png', decimals: 8);
229
- static const scrt = CryptoCurrency(title: 'SCRT', fullName: 'Secret Network', raw: 59, name: 'scrt', iconPath: 'assets/images/scrt_icon.png', decimals: 6);
230
- static const uni = CryptoCurrency(title: 'UNI', tag: 'ETH', fullName: 'Uniswap', raw: 60, name: 'uni', iconPath: 'assets/images/uni_icon.png', decimals: 18);
231
- static const stx = CryptoCurrency(title: 'STX', fullName: 'Stacks', raw: 61, name: 'stx', iconPath: 'assets/images/stx_icon.png', decimals: 8);
232
- static const btcln = CryptoCurrency(title: 'BTC', tag: 'LN', fullName: 'Bitcoin Lightning Network', raw: 62, name: 'btcln', iconPath: 'assets/new-ui/crypto_full_icons/lightning.svg', chainIconPath: "assets/new-ui/chain_badges/lightning.svg", decimals: 8);
233
- static const shib = CryptoCurrency(title: 'SHIB', tag: 'ETH', fullName: 'Shiba Inu', raw: 63, name: 'shib', iconPath: 'assets/images/shib_icon.png', decimals: 18);
234
- static const aave = CryptoCurrency(title: 'AAVE', tag: 'ETH', fullName: 'Aave', raw: 64, name: 'aave', iconPath: 'assets/images/aave_icon.png', decimals: 18);
235
- static const arb = CryptoCurrency(title: 'ARB', fullName: 'Arbitrum', raw: 65, name: 'arb', iconPath: 'assets/new-ui/crypto_full_icons/arbitrum.svg', decimals: 18, flatIconPath: "assets/new-ui/balance_card_icons/arbitrum.svg", chainIconPath: "assets/new-ui/chain_badges/arbitrum.svg");
236
- static const bat = CryptoCurrency(title: 'BAT', tag: 'ETH', fullName: 'Basic Attention Token', raw: 66, name: 'bat', iconPath: 'assets/images/bat_icon.png', decimals: 18);
237
- static const comp = CryptoCurrency(title: 'COMP', tag: 'ETH', fullName: 'Compound', raw: 67, name: 'comp', iconPath: 'assets/images/comp_icon.png', decimals: 18);
238
- static const cro = CryptoCurrency(title: 'CRO', tag: 'ETH', fullName: 'Crypto.com Cronos', raw: 68, name: 'cro', iconPath: 'assets/images/cro_icon.png', decimals: 8);
239
- static const ens = CryptoCurrency(title: 'ENS', tag: 'ETH', fullName: 'Ethereum Name Service', raw: 69, name: 'ens', iconPath: 'assets/images/ens_icon.png', decimals: 18);
240
- static const ftm = CryptoCurrency(title: 'FTM', tag: 'ETH', fullName: 'Fantom', raw: 70, name: 'ftm', iconPath: 'assets/images/ftm_icon.png', decimals: 18);
241
- static const frax = CryptoCurrency(title: 'FRAX', tag: 'ETH', fullName: 'Frax', raw: 71, name: 'frax', iconPath: 'assets/images/frax_icon.png', decimals: 18);
242
- static const gusd = CryptoCurrency(title: 'GUSD', tag: 'ETH', fullName: 'Gemini USD', raw: 72, name: 'gusd', iconPath: 'assets/images/gusd_icon.png', decimals: 2);
243
- static const gtc = CryptoCurrency(title: 'GTC', tag: 'ETH', fullName: 'Gitcoin', raw: 73, name: 'gtc', iconPath: 'assets/images/gtc_icon.png', decimals: 18);
244
- static const grt = CryptoCurrency(title: 'GRT', tag: 'ETH', fullName: 'The Graph', raw: 74, name: 'grt', iconPath: 'assets/images/grt_icon.png', decimals: 18);
245
- static const ldo = CryptoCurrency(title: 'LDO', tag: 'ETH', fullName: 'Lido DAO', raw: 75, name: 'ldo', iconPath: 'assets/images/ldo_icon.png', decimals: 18);
246
- static const nexo = CryptoCurrency(title: 'NEXO', tag: 'ETH', fullName: 'Nexo', raw: 76, name: 'nexo', iconPath: 'assets/images/nexo_icon.png', decimals: 18);
247
- static const cake = CryptoCurrency(title: 'CAKE', tag: 'BSC', fullName: 'PancakeSwap', raw: 77, name: 'cake', iconPath: 'assets/images/cake_icon.png', decimals: 18);
248
- static const pepe = CryptoCurrency(title: 'PEPE', tag: 'ETH', fullName: 'Pepe', raw: 78, name: 'pepe', iconPath: 'assets/images/pepe_icon.png', decimals: 18);
249
- static const storj = CryptoCurrency(title: 'STORJ', tag: 'ETH', fullName: 'Storj', raw: 79, name: 'storj', iconPath: 'assets/images/storj_icon.png', decimals: 8);
250
- static const tusd = CryptoCurrency(title: 'TUSD', tag: 'ETH', fullName: 'TrueUSD', raw: 80, name: 'tusd', iconPath: 'assets/images/tusd_icon.png', decimals: 18);
251
- static const wbtc = CryptoCurrency(title: 'WBTC', tag: 'ETH', fullName: 'Wrapped Bitcoin', raw: 81, name: 'wbtc', iconPath: 'assets/new-ui/crypto_full_icons/wbtc.svg', decimals: 8);
252
- static const weth = CryptoCurrency(title: 'WETH', tag: 'ETH', fullName: 'Wrapped Ethereum', raw: 82, name: 'weth', iconPath: 'assets/new-ui/crypto_full_icons/ethereum.svg', decimals: 18);
253
- static const zrx = CryptoCurrency(title: 'ZRX', tag: 'ETH', fullName: '0x Protocol', raw: 83, name: 'zrx', iconPath: 'assets/images/zrx_icon.png', decimals: 18);
254
- static const dydx = CryptoCurrency(title: 'DYDX', tag: 'ETH', fullName: 'dYdX', raw: 84, name: 'dydx', iconPath: 'assets/images/dydx_icon.png', decimals: 18);
255
- static const steth = CryptoCurrency(title: 'STETH', tag: 'ETH', fullName: 'Lido Staked Ethereum', raw: 85, name: 'steth', iconPath: 'assets/new-ui/crypto_full_icons/ethereum.svg', decimals: 18);
256
- static const banano = CryptoCurrency(title: 'BAN', fullName: 'Banano', raw: 86, name: 'banano', iconPath: 'assets/images/nano_icon.png', decimals: 29,flatIconPath: "assets/new-ui/balance_card_icons/nano.svg");
257
- static const usdtPoly = CryptoCurrency(title: 'USDT', tag: 'POL', fullName: 'Tether (PoS)', raw: 87, name: 'usdtpoly', iconPath: 'assets/new-ui/crypto_full_icons/usdt.svg', decimals: 6, groups: const {CurrencyGroups.stablecoin});
258
- static const usdcEPoly = CryptoCurrency(title: 'USDC.E', tag: 'POL', fullName: 'USDC (PoS)', raw: 88, name: 'usdcepoly', iconPath: 'assets/new-ui/crypto_full_icons/usdc.svg', decimals: 6);
259
- static const kaspa = CryptoCurrency(title: 'KAS', fullName: 'Kaspa', raw: 89, name: 'kas', iconPath: 'assets/images/kaspa_icon.png', decimals: 8);
260
- static const digibyte = CryptoCurrency(title: 'DGB', fullName: 'DigiByte', raw: 90, name: 'dgb', iconPath: 'assets/images/digibyte.png', decimals: 8);
261
- static const usdtSol = CryptoCurrency(title: 'USDT', tag: 'SOL', fullName: 'Tether', raw: 91, name: 'usdtsol', iconPath: 'assets/new-ui/crypto_full_icons/usdt.svg', decimals: 6, groups: const {CurrencyGroups.stablecoin});
262
- static const usdcTrc20 = CryptoCurrency(title: 'USDC', tag: 'TRX', fullName: 'USDC Coin', raw: 92, name: 'usdctrc20', iconPath: 'assets/new-ui/crypto_full_icons/usdc.svg', decimals: 6, groups: const {CurrencyGroups.stablecoin});
263
- static const tbtc = CryptoCurrency(title: 'tBTC', fullName: 'Testnet Bitcoin', raw: 93, name: 'tbtc', iconPath: 'assets/images/tbtc.png', decimals: 8);
264
- static const wow = CryptoCurrency(title: 'WOW', fullName: 'Wownero', raw: 94, name: 'wow', iconPath: 'assets/images/crypto/wownero.svg', decimals: 11);
265
- static const ton = CryptoCurrency(title: 'TON', fullName: 'Toncoin', raw: 95, name: 'ton', iconPath: 'assets/new-ui/crypto_full_icons/ton.svg', decimals: 8);
266
- static const zano = CryptoCurrency(title: 'ZANO', tag: 'ZANO', fullName: 'Zano', raw: 96, name: 'zano', iconPath: 'assets/new-ui/crypto_full_icons/zano.svg', decimals: 12, flatIconPath: "assets/new-ui/balance_card_icons/zano.svg", chainIconPath: "assets/new-ui/chain_badges/zano.svg");
267
- static const flip = CryptoCurrency(title: 'FLIP', tag: 'ETH', fullName: 'Chainflip', raw: 97, name: 'flip', iconPath: 'assets/images/flip_icon.png', decimals: 18);
268
- static const deuro = CryptoCurrency(title: 'DEURO', tag: 'ETH', fullName: 'Decentralized Euro', raw: 98, name: 'deuro', iconPath: 'assets/images/deuro_icon.png',decimals: 18, groups: const {CurrencyGroups.stablecoin});
269
- static const usdtbsc = CryptoCurrency(title: 'USDT', tag: 'BSC', fullName: 'USDT Binance coin', raw: 99, name: 'usdtbsc', iconPath: 'assets/new-ui/crypto_full_icons/usdt.svg', decimals: 18, groups: const {CurrencyGroups.stablecoin});
270
- static const ndeps = CryptoCurrency(title: 'NDEPS', tag: 'ETH', fullName: 'Native Decentralized Euro Protocol Share', raw: 100, name: 'ndeps', iconPath: 'assets/images/ndeps_icon.png', decimals: 18);
271
- static const deps = CryptoCurrency(title: 'DEPS', tag: 'ETH', fullName: 'Decentralized Euro Protocol Share', raw: 101, name: 'deps', iconPath: 'assets/images/deps_icon.png', decimals: 18);
272
- static const kbtc = CryptoCurrency(title: 'KBTC', tag: 'ETH', fullName: 'Kraken Wrapped Bitcoin', raw: 102, name: 'kbtc', iconPath: 'assets/images/kbtc_icon.png', decimals: 8);
273
- static const cbbtc = CryptoCurrency(title: 'CBBTC', tag: 'ETH', fullName: 'Coinbase Wrapped BTC', raw: 103, name: 'cbbtc', iconPath: 'assets/images/cbbtc_icon.png', decimals: 8);
274
- static const baseEth = CryptoCurrency(title: 'ETH', tag: 'BASE', fullName: 'Ethereum', raw: 104, name: 'baseth', iconPath: 'assets/new-ui/crypto_full_icons/ethereum.svg', decimals: 18, flatIconPath: "assets/new-ui/balance_card_icons/base.svg", chainIconPath: "assets/new-ui/chain_badges/base.svg");
275
- static const usde = CryptoCurrency(title: 'USDE', tag: 'BASE', fullName: 'Ethena USDE', raw: 105, name: 'usde', iconPath: 'assets/new-ui/crypto_full_icons/usde.svg', decimals: 18);
276
- static const arbEth = CryptoCurrency(title: 'ETH', tag: 'ARB', fullName: 'Ethereum', raw: 106, name: 'arbeth', iconPath: 'assets/new-ui/crypto_full_icons/ethereum.svg', decimals: 18, flatIconPath: "assets/new-ui/balance_card_icons/arbitrum.svg", chainIconPath: "assets/new-ui/chain_badges/arbitrum.svg");
277
- static const zec = CryptoCurrency(title: 'ZEC', fullName: 'Zcash', raw: 107, name: 'zec', iconPath: 'assets/new-ui/crypto_full_icons/zcash.svg', decimals: 8,flatIconPath: "assets/new-ui/balance_card_icons/zcash.svg");
278
- static const usdcArb = CryptoCurrency(title: 'USDC', tag: 'ARB', fullName: 'USDC Coin', raw: 108, name: 'usdcarb', iconPath: 'assets/new-ui/crypto_full_icons/usdc.svg', decimals: 6, groups: const {CurrencyGroups.stablecoin});
279
- static const usdtArb = CryptoCurrency(title: 'USDT', tag: 'ARB', fullName: 'USDT Tether', raw: 109, name: 'usdtarb', iconPath: 'assets/new-ui/crypto_full_icons/usdt.svg', decimals: 6, groups: const {CurrencyGroups.stablecoin});
280
- static const ltcmweb = CryptoCurrency(title: 'LTC', fullName: 'Litecoin MWeb', raw: 110, name: 'ltcmweb', iconPath: 'assets/new-ui/crypto_full_icons/litecoin.svg', decimals: 8);
281
-
282
- static final Map<int, CryptoCurrency> _rawCurrencyMap =
283
- [...all, ...havenCurrencies, ...zcashCurrencies].fold<Map<int, CryptoCurrency>>(<int, CryptoCurrency>{}, (acc, item) {
284
- acc.addAll({item.raw: item});
285
- return acc;
286
- });
287
-
288
- static final Map<String, CryptoCurrency> _nameCurrencyMap =
289
- [...all, ...havenCurrencies, ...zcashCurrencies].fold<Map<String, CryptoCurrency>>(<String, CryptoCurrency>{}, (acc, item) {
290
- acc.addAll({item.name: item});
291
- return acc;
292
- });
293
-
294
- static final Map<String, CryptoCurrency> _fullNameCurrencyMap =
295
- [...all, ...havenCurrencies, ...zcashCurrencies].fold<Map<String, CryptoCurrency>>(<String, CryptoCurrency>{}, (acc, item) {
296
- if(item.fullName != null){
297
- acc.addAll({item.fullName!.toLowerCase(): item});
298
- }
299
- return acc;
300
- });
308
+ static const xaud =
309
+ CryptoCurrency(title: 'XAUD', tag: 'XHV', raw: 19, name: 'xaud', decimals: 12);
310
+ static const xbtc =
311
+ CryptoCurrency(title: 'XBTC', tag: 'XHV', raw: 20, name: 'xbtc', decimals: 12);
312
+ static const xcad =
313
+ CryptoCurrency(title: 'XCAD', tag: 'XHV', raw: 21, name: 'xcad', decimals: 12);
314
+ static const xchf =
315
+ CryptoCurrency(title: 'XCHF', tag: 'XHV', raw: 22, name: 'xchf', decimals: 12);
316
+ static const xcny =
317
+ CryptoCurrency(title: 'XCNY', tag: 'XHV', raw: 23, name: 'xcny', decimals: 12);
318
+ static const xeur =
319
+ CryptoCurrency(title: 'XEUR', tag: 'XHV', raw: 24, name: 'xeur', decimals: 12);
320
+ static const xgbp =
321
+ CryptoCurrency(title: 'XGBP', tag: 'XHV', raw: 25, name: 'xgbp', decimals: 12);
322
+ static const xjpy =
323
+ CryptoCurrency(title: 'XJPY', tag: 'XHV', raw: 26, name: 'xjpy', decimals: 12);
324
+ static const xnok =
325
+ CryptoCurrency(title: 'XNOK', tag: 'XHV', raw: 27, name: 'xnok', decimals: 12);
326
+ static const xnzd =
327
+ CryptoCurrency(title: 'XNZD', tag: 'XHV', raw: 28, name: 'xnzd', decimals: 12);
328
+ static const xusd =
329
+ CryptoCurrency(title: 'XUSD', tag: 'XHV', raw: 29, name: 'xusd', decimals: 12);
330
+
331
+ static const ape = CryptoCurrency(
332
+ title: 'APE',
333
+ tag: 'ETH',
334
+ fullName: 'ApeCoin',
335
+ raw: 30,
336
+ name: 'ape',
337
+ iconPath: 'assets/images/ape_icon.png',
338
+ decimals: 18);
339
+ static const avaxc = CryptoCurrency(
340
+ title: 'AVAX',
341
+ tag: 'AVAXC',
342
+ fullName: 'Avalanche',
343
+ raw: 31,
344
+ name: 'avaxc',
345
+ iconPath: 'assets/new-ui/crypto_full_icons/avax.svg',
346
+ decimals: 9);
347
+ static const btt = CryptoCurrency(
348
+ title: 'BTT',
349
+ tag: 'ETH',
350
+ fullName: 'BitTorrent',
351
+ raw: 32,
352
+ name: 'btt',
353
+ iconPath: 'assets/images/btt_icon.png',
354
+ decimals: 18);
355
+ static const bttc = CryptoCurrency(
356
+ title: 'BTTC',
357
+ tag: 'TRX',
358
+ fullName: 'BitTorrent-NEW',
359
+ raw: 33,
360
+ name: 'bttc',
361
+ iconPath: 'assets/images/btt_icon.png',
362
+ decimals: 18);
363
+ static const doge = CryptoCurrency(
364
+ title: 'DOGE',
365
+ fullName: 'Dogecoin',
366
+ raw: 34,
367
+ name: 'doge',
368
+ iconPath: 'assets/new-ui/crypto_full_icons/dogecoin.svg',
369
+ decimals: 8,
370
+ flatIconPath: "assets/new-ui/balance_card_icons/dogecoin.svg");
371
+ static const firo = CryptoCurrency(
372
+ title: 'FIRO', raw: 35, name: 'firo', iconPath: 'assets/images/firo_icon.png', decimals: 8);
373
+ static const usdttrc20 = CryptoCurrency(
374
+ title: 'USDT',
375
+ tag: 'TRX',
376
+ fullName: 'Tether',
377
+ raw: 36,
378
+ name: 'usdttrc20',
379
+ iconPath: 'assets/new-ui/crypto_full_icons/usdt.svg',
380
+ decimals: 6,
381
+ groups: const {CurrencyGroups.stablecoin});
382
+ static const hbar = CryptoCurrency(
383
+ title: 'HBAR',
384
+ fullName: 'Hedera',
385
+ raw: 37,
386
+ name: 'hbar',
387
+ iconPath: 'assets/images/hbar_icon.png',
388
+ decimals: 8);
389
+ static const sc = CryptoCurrency(
390
+ title: 'SC',
391
+ fullName: 'Siacoin',
392
+ raw: 38,
393
+ name: 'sc',
394
+ iconPath: 'assets/images/sc_icon.png',
395
+ decimals: 16);
396
+ static const sol = CryptoCurrency(
397
+ title: 'SOL',
398
+ fullName: 'Solana',
399
+ raw: 39,
400
+ name: 'sol',
401
+ iconPath: 'assets/new-ui/crypto_full_icons/solana.svg',
402
+ decimals: 9,
403
+ flatIconPath: "assets/new-ui/balance_card_icons/solana.svg",
404
+ chainIconPath: "assets/new-ui/chain_badges/solana.svg");
405
+ static const usdc = CryptoCurrency(
406
+ title: 'USDC',
407
+ tag: 'ETH',
408
+ fullName: 'USDC',
409
+ raw: 40,
410
+ name: 'usdc',
411
+ iconPath: 'assets/new-ui/crypto_full_icons/usdc.svg',
412
+ decimals: 6,
413
+ groups: const {CurrencyGroups.stablecoin});
414
+ static const usdcsol = CryptoCurrency(
415
+ title: 'USDC',
416
+ tag: 'SOL',
417
+ fullName: 'USDC Coin',
418
+ raw: 41,
419
+ name: 'usdcsol',
420
+ iconPath: 'assets/new-ui/crypto_full_icons/usdc.svg',
421
+ decimals: 6,
422
+ groups: const {CurrencyGroups.stablecoin});
423
+ static const zaddr = CryptoCurrency(
424
+ title: 'ZZEC',
425
+ tag: 'ZEC',
426
+ fullName: 'Shielded Zcash',
427
+ raw: 42,
428
+ name: 'zaddr',
429
+ iconPath: 'assets/new-ui/crypto_full_icons/zcash.svg',
430
+ decimals: 8);
431
+ static const tzec = CryptoCurrency(
432
+ title: 'tZEC',
433
+ tag: 'ZEC',
434
+ fullName: 'Transparent Zcash',
435
+ raw: 43,
436
+ name: 'zec',
437
+ iconPath: 'assets/new-ui/crypto_full_icons/zcash.svg',
438
+ decimals: 8);
439
+ static const zen = CryptoCurrency(
440
+ title: 'ZEN',
441
+ fullName: 'Horizen',
442
+ raw: 44,
443
+ name: 'zen',
444
+ iconPath: 'assets/images/zen_icon.png',
445
+ decimals: 8);
446
+ static const xvg = CryptoCurrency(
447
+ title: 'XVG',
448
+ fullName: 'Verge',
449
+ raw: 45,
450
+ name: 'xvg',
451
+ iconPath: 'assets/images/xvg_icon.png',
452
+ decimals: 8);
453
+
454
+ static const usdcpoly = CryptoCurrency(
455
+ title: 'USDC',
456
+ tag: 'POL',
457
+ fullName: 'USDC',
458
+ raw: 46,
459
+ name: 'usdcpoly',
460
+ iconPath: 'assets/new-ui/crypto_full_icons/usdc.svg',
461
+ decimals: 6,
462
+ groups: const {CurrencyGroups.stablecoin});
463
+ static const dcr = CryptoCurrency(
464
+ title: 'DCR',
465
+ fullName: 'Decred',
466
+ raw: 47,
467
+ name: 'dcr',
468
+ iconPath: 'assets/new-ui/crypto_full_icons/decred.svg',
469
+ decimals: 8,
470
+ flatIconPath: "assets/new-ui/balance_card_icons/decred.svg");
471
+ static const kmd = CryptoCurrency(
472
+ title: 'KMD',
473
+ fullName: 'Komodo',
474
+ raw: 48,
475
+ name: 'kmd',
476
+ iconPath: 'assets/images/kmd_icon.png',
477
+ decimals: 8);
478
+ static const mana = CryptoCurrency(
479
+ title: 'MANA',
480
+ tag: 'ETH',
481
+ fullName: 'Decentraland',
482
+ raw: 49,
483
+ name: 'mana',
484
+ iconPath: 'assets/images/mana_icon.png',
485
+ decimals: 18);
486
+ static const maticpoly = CryptoCurrency(
487
+ title: 'POL',
488
+ tag: 'POL',
489
+ fullName: 'Polygon',
490
+ raw: 50,
491
+ name: 'maticpoly',
492
+ iconPath: 'assets/new-ui/crypto_full_icons/polygon.svg',
493
+ decimals: 18,
494
+ flatIconPath: "assets/new-ui/balance_card_icons/polygon.svg",
495
+ chainIconPath: "assets/new-ui/chain_badges/polygon.svg");
496
+ static const matic = CryptoCurrency(
497
+ title: 'MATIC',
498
+ tag: 'ETH',
499
+ fullName: 'Polygon',
500
+ raw: 51,
501
+ name: 'matic',
502
+ iconPath: 'assets/new-ui/crypto_full_icons/polygon.svg',
503
+ decimals: 18,
504
+ flatIconPath: "assets/new-ui/balance_card_icons/polygon.svg");
505
+ static const mkr = CryptoCurrency(
506
+ title: 'MKR',
507
+ tag: 'ETH',
508
+ fullName: 'Maker',
509
+ raw: 52,
510
+ name: 'mkr',
511
+ iconPath: 'assets/images/mkr_icon.png',
512
+ decimals: 18);
513
+ static const near = CryptoCurrency(
514
+ title: 'NEAR',
515
+ fullName: 'NEAR Protocol',
516
+ raw: 53,
517
+ name: 'near',
518
+ iconPath: 'assets/images/near_icon.png',
519
+ decimals: 24);
520
+ static const oxt = CryptoCurrency(
521
+ title: 'OXT',
522
+ tag: 'ETH',
523
+ fullName: 'Orchid',
524
+ raw: 54,
525
+ name: 'oxt',
526
+ iconPath: 'assets/images/oxt_icon.png',
527
+ decimals: 18);
528
+ static const paxg = CryptoCurrency(
529
+ title: 'PAXG',
530
+ tag: 'ETH',
531
+ fullName: 'Pax Gold',
532
+ raw: 55,
533
+ name: 'paxg',
534
+ iconPath: 'assets/new-ui/crypto_full_icons/paxg.svg',
535
+ decimals: 18);
536
+ static const pivx = CryptoCurrency(
537
+ title: 'PIVX', raw: 56, name: 'pivx', iconPath: 'assets/images/pivx_icon.png', decimals: 8);
538
+ static const rune = CryptoCurrency(
539
+ title: 'RUNE',
540
+ fullName: 'Thorchain',
541
+ raw: 57,
542
+ name: 'rune',
543
+ iconPath: 'assets/images/rune_icon.png',
544
+ decimals: 18);
545
+ static const rvn = CryptoCurrency(
546
+ title: 'RVN',
547
+ fullName: 'Ravencoin',
548
+ raw: 58,
549
+ name: 'rvn',
550
+ iconPath: 'assets/images/rvn_icon.png',
551
+ decimals: 8);
552
+ static const scrt = CryptoCurrency(
553
+ title: 'SCRT',
554
+ fullName: 'Secret Network',
555
+ raw: 59,
556
+ name: 'scrt',
557
+ iconPath: 'assets/images/scrt_icon.png',
558
+ decimals: 6);
559
+ static const uni = CryptoCurrency(
560
+ title: 'UNI',
561
+ tag: 'ETH',
562
+ fullName: 'Uniswap',
563
+ raw: 60,
564
+ name: 'uni',
565
+ iconPath: 'assets/images/uni_icon.png',
566
+ decimals: 18);
567
+ static const stx = CryptoCurrency(
568
+ title: 'STX',
569
+ fullName: 'Stacks',
570
+ raw: 61,
571
+ name: 'stx',
572
+ iconPath: 'assets/images/stx_icon.png',
573
+ decimals: 8);
574
+ static const btcln = CryptoCurrency(
575
+ title: 'BTC',
576
+ tag: 'LN',
577
+ fullName: 'Bitcoin Lightning Network',
578
+ raw: 62,
579
+ name: 'btcln',
580
+ iconPath: 'assets/new-ui/crypto_full_icons/lightning.svg',
581
+ chainIconPath: "assets/new-ui/chain_badges/lightning.svg",
582
+ decimals: 8);
583
+ static const shib = CryptoCurrency(
584
+ title: 'SHIB',
585
+ tag: 'ETH',
586
+ fullName: 'Shiba Inu',
587
+ raw: 63,
588
+ name: 'shib',
589
+ iconPath: 'assets/images/shib_icon.png',
590
+ decimals: 18);
591
+ static const aave = CryptoCurrency(
592
+ title: 'AAVE',
593
+ tag: 'ETH',
594
+ fullName: 'Aave',
595
+ raw: 64,
596
+ name: 'aave',
597
+ iconPath: 'assets/images/aave_icon.png',
598
+ decimals: 18);
599
+ static const arb = CryptoCurrency(
600
+ title: 'ARB',
601
+ fullName: 'Arbitrum',
602
+ raw: 65,
603
+ name: 'arb',
604
+ iconPath: 'assets/new-ui/crypto_full_icons/arbitrum.svg',
605
+ decimals: 18,
606
+ flatIconPath: "assets/new-ui/balance_card_icons/arbitrum.svg",
607
+ chainIconPath: "assets/new-ui/chain_badges/arbitrum.svg");
608
+ static const bat = CryptoCurrency(
609
+ title: 'BAT',
610
+ tag: 'ETH',
611
+ fullName: 'Basic Attention Token',
612
+ raw: 66,
613
+ name: 'bat',
614
+ iconPath: 'assets/images/bat_icon.png',
615
+ decimals: 18);
616
+ static const comp = CryptoCurrency(
617
+ title: 'COMP',
618
+ tag: 'ETH',
619
+ fullName: 'Compound',
620
+ raw: 67,
621
+ name: 'comp',
622
+ iconPath: 'assets/images/comp_icon.png',
623
+ decimals: 18);
624
+ static const cro = CryptoCurrency(
625
+ title: 'CRO',
626
+ tag: 'ETH',
627
+ fullName: 'Crypto.com Cronos',
628
+ raw: 68,
629
+ name: 'cro',
630
+ iconPath: 'assets/images/cro_icon.png',
631
+ decimals: 8);
632
+ static const ens = CryptoCurrency(
633
+ title: 'ENS',
634
+ tag: 'ETH',
635
+ fullName: 'Ethereum Name Service',
636
+ raw: 69,
637
+ name: 'ens',
638
+ iconPath: 'assets/images/ens_icon.png',
639
+ decimals: 18);
640
+ static const ftm = CryptoCurrency(
641
+ title: 'FTM',
642
+ tag: 'ETH',
643
+ fullName: 'Fantom',
644
+ raw: 70,
645
+ name: 'ftm',
646
+ iconPath: 'assets/images/ftm_icon.png',
647
+ decimals: 18);
648
+ static const frax = CryptoCurrency(
649
+ title: 'FRAX',
650
+ tag: 'ETH',
651
+ fullName: 'Frax',
652
+ raw: 71,
653
+ name: 'frax',
654
+ iconPath: 'assets/images/frax_icon.png',
655
+ decimals: 18);
656
+ static const gusd = CryptoCurrency(
657
+ title: 'GUSD',
658
+ tag: 'ETH',
659
+ fullName: 'Gemini USD',
660
+ raw: 72,
661
+ name: 'gusd',
662
+ iconPath: 'assets/images/gusd_icon.png',
663
+ decimals: 2);
664
+ static const gtc = CryptoCurrency(
665
+ title: 'GTC',
666
+ tag: 'ETH',
667
+ fullName: 'Gitcoin',
668
+ raw: 73,
669
+ name: 'gtc',
670
+ iconPath: 'assets/images/gtc_icon.png',
671
+ decimals: 18);
672
+ static const grt = CryptoCurrency(
673
+ title: 'GRT',
674
+ tag: 'ETH',
675
+ fullName: 'The Graph',
676
+ raw: 74,
677
+ name: 'grt',
678
+ iconPath: 'assets/images/grt_icon.png',
679
+ decimals: 18);
680
+ static const ldo = CryptoCurrency(
681
+ title: 'LDO',
682
+ tag: 'ETH',
683
+ fullName: 'Lido DAO',
684
+ raw: 75,
685
+ name: 'ldo',
686
+ iconPath: 'assets/images/ldo_icon.png',
687
+ decimals: 18);
688
+ static const nexo = CryptoCurrency(
689
+ title: 'NEXO',
690
+ tag: 'ETH',
691
+ fullName: 'Nexo',
692
+ raw: 76,
693
+ name: 'nexo',
694
+ iconPath: 'assets/images/nexo_icon.png',
695
+ decimals: 18);
696
+ static const cake = CryptoCurrency(
697
+ title: 'CAKE',
698
+ tag: 'BSC',
699
+ fullName: 'PancakeSwap',
700
+ raw: 77,
701
+ name: 'cake',
702
+ iconPath: 'assets/images/cake_icon.png',
703
+ decimals: 18);
704
+ static const pepe = CryptoCurrency(
705
+ title: 'PEPE',
706
+ tag: 'ETH',
707
+ fullName: 'Pepe',
708
+ raw: 78,
709
+ name: 'pepe',
710
+ iconPath: 'assets/images/pepe_icon.png',
711
+ decimals: 18);
712
+ static const storj = CryptoCurrency(
713
+ title: 'STORJ',
714
+ tag: 'ETH',
715
+ fullName: 'Storj',
716
+ raw: 79,
717
+ name: 'storj',
718
+ iconPath: 'assets/images/storj_icon.png',
719
+ decimals: 8);
720
+ static const tusd = CryptoCurrency(
721
+ title: 'TUSD',
722
+ tag: 'ETH',
723
+ fullName: 'TrueUSD',
724
+ raw: 80,
725
+ name: 'tusd',
726
+ iconPath: 'assets/images/tusd_icon.png',
727
+ decimals: 18);
728
+ static const wbtc = CryptoCurrency(
729
+ title: 'WBTC',
730
+ tag: 'ETH',
731
+ fullName: 'Wrapped Bitcoin',
732
+ raw: 81,
733
+ name: 'wbtc',
734
+ iconPath: 'assets/new-ui/crypto_full_icons/wbtc.svg',
735
+ decimals: 8);
736
+ static const weth = CryptoCurrency(
737
+ title: 'WETH',
738
+ tag: 'ETH',
739
+ fullName: 'Wrapped Ethereum',
740
+ raw: 82,
741
+ name: 'weth',
742
+ iconPath: 'assets/new-ui/crypto_full_icons/ethereum.svg',
743
+ decimals: 18);
744
+ static const zrx = CryptoCurrency(
745
+ title: 'ZRX',
746
+ tag: 'ETH',
747
+ fullName: '0x Protocol',
748
+ raw: 83,
749
+ name: 'zrx',
750
+ iconPath: 'assets/images/zrx_icon.png',
751
+ decimals: 18);
752
+ static const dydx = CryptoCurrency(
753
+ title: 'DYDX',
754
+ tag: 'ETH',
755
+ fullName: 'dYdX',
756
+ raw: 84,
757
+ name: 'dydx',
758
+ iconPath: 'assets/images/dydx_icon.png',
759
+ decimals: 18);
760
+ static const steth = CryptoCurrency(
761
+ title: 'STETH',
762
+ tag: 'ETH',
763
+ fullName: 'Lido Staked Ethereum',
764
+ raw: 85,
765
+ name: 'steth',
766
+ iconPath: 'assets/new-ui/crypto_full_icons/ethereum.svg',
767
+ decimals: 18);
768
+ static const banano = CryptoCurrency(
769
+ title: 'BAN',
770
+ fullName: 'Banano',
771
+ raw: 86,
772
+ name: 'banano',
773
+ iconPath: 'assets/images/nano_icon.png',
774
+ decimals: 29,
775
+ flatIconPath: "assets/new-ui/balance_card_icons/nano.svg");
776
+ static const usdtPoly = CryptoCurrency(
777
+ title: 'USDT',
778
+ tag: 'POL',
779
+ fullName: 'Tether (PoS)',
780
+ raw: 87,
781
+ name: 'usdtpoly',
782
+ iconPath: 'assets/new-ui/crypto_full_icons/usdt.svg',
783
+ decimals: 6,
784
+ groups: const {CurrencyGroups.stablecoin});
785
+ static const usdcEPoly = CryptoCurrency(
786
+ title: 'USDC.E',
787
+ tag: 'POL',
788
+ fullName: 'USDC (PoS)',
789
+ raw: 88,
790
+ name: 'usdcepoly',
791
+ iconPath: 'assets/new-ui/crypto_full_icons/usdc.svg',
792
+ decimals: 6);
793
+ static const kaspa = CryptoCurrency(
794
+ title: 'KAS',
795
+ fullName: 'Kaspa',
796
+ raw: 89,
797
+ name: 'kas',
798
+ iconPath: 'assets/images/kaspa_icon.png',
799
+ decimals: 8);
800
+ static const digibyte = CryptoCurrency(
801
+ title: 'DGB',
802
+ fullName: 'DigiByte',
803
+ raw: 90,
804
+ name: 'dgb',
805
+ iconPath: 'assets/images/digibyte.png',
806
+ decimals: 8);
807
+ static const usdtSol = CryptoCurrency(
808
+ title: 'USDT',
809
+ tag: 'SOL',
810
+ fullName: 'Tether',
811
+ raw: 91,
812
+ name: 'usdtsol',
813
+ iconPath: 'assets/new-ui/crypto_full_icons/usdt.svg',
814
+ decimals: 6,
815
+ groups: const {CurrencyGroups.stablecoin});
816
+ static const usdcTrc20 = CryptoCurrency(
817
+ title: 'USDC',
818
+ tag: 'TRX',
819
+ fullName: 'USDC Coin',
820
+ raw: 92,
821
+ name: 'usdctrc20',
822
+ iconPath: 'assets/new-ui/crypto_full_icons/usdc.svg',
823
+ decimals: 6,
824
+ groups: const {CurrencyGroups.stablecoin});
825
+ static const tbtc = CryptoCurrency(
826
+ title: 'tBTC',
827
+ fullName: 'Testnet Bitcoin',
828
+ raw: 93,
829
+ name: 'tbtc',
830
+ iconPath: 'assets/images/tbtc.png',
831
+ decimals: 8);
832
+ static const wow = CryptoCurrency(
833
+ title: 'WOW',
834
+ fullName: 'Wownero',
835
+ raw: 94,
836
+ name: 'wow',
837
+ iconPath: 'assets/images/crypto/wownero.svg',
838
+ decimals: 11);
839
+ static const ton = CryptoCurrency(
840
+ title: 'TON',
841
+ fullName: 'Toncoin',
842
+ raw: 95,
843
+ name: 'ton',
844
+ iconPath: 'assets/new-ui/crypto_full_icons/ton.svg',
845
+ decimals: 8);
846
+ static const zano = CryptoCurrency(
847
+ title: 'ZANO',
848
+ tag: 'ZANO',
849
+ fullName: 'Zano',
850
+ raw: 96,
851
+ name: 'zano',
852
+ iconPath: 'assets/new-ui/crypto_full_icons/zano.svg',
853
+ decimals: 12,
854
+ flatIconPath: "assets/new-ui/balance_card_icons/zano.svg",
855
+ chainIconPath: "assets/new-ui/chain_badges/zano.svg");
856
+ static const flip = CryptoCurrency(
857
+ title: 'FLIP',
858
+ tag: 'ETH',
859
+ fullName: 'Chainflip',
860
+ raw: 97,
861
+ name: 'flip',
862
+ iconPath: 'assets/images/flip_icon.png',
863
+ decimals: 18);
864
+ static const deuro = CryptoCurrency(
865
+ title: 'DEURO',
866
+ tag: 'ETH',
867
+ fullName: 'Decentralized Euro',
868
+ raw: 98,
869
+ name: 'deuro',
870
+ iconPath: 'assets/images/deuro_icon.png',
871
+ decimals: 18,
872
+ groups: const {CurrencyGroups.stablecoin});
873
+ static const usdtbsc = CryptoCurrency(
874
+ title: 'USDT',
875
+ tag: 'BSC',
876
+ fullName: 'USDT Binance coin',
877
+ raw: 99,
878
+ name: 'usdtbsc',
879
+ iconPath: 'assets/new-ui/crypto_full_icons/usdt.svg',
880
+ decimals: 18,
881
+ groups: const {CurrencyGroups.stablecoin});
882
+ static const ndeps = CryptoCurrency(
883
+ title: 'NDEPS',
884
+ tag: 'ETH',
885
+ fullName: 'Native Decentralized Euro Protocol Share',
886
+ raw: 100,
887
+ name: 'ndeps',
888
+ iconPath: 'assets/images/ndeps_icon.png',
889
+ decimals: 18);
890
+ static const deps = CryptoCurrency(
891
+ title: 'DEPS',
892
+ tag: 'ETH',
893
+ fullName: 'Decentralized Euro Protocol Share',
894
+ raw: 101,
895
+ name: 'deps',
896
+ iconPath: 'assets/images/deps_icon.png',
897
+ decimals: 18);
898
+ static const kbtc = CryptoCurrency(
899
+ title: 'KBTC',
900
+ tag: 'ETH',
901
+ fullName: 'Kraken Wrapped Bitcoin',
902
+ raw: 102,
903
+ name: 'kbtc',
904
+ iconPath: 'assets/images/kbtc_icon.png',
905
+ decimals: 8);
906
+ static const cbbtc = CryptoCurrency(
907
+ title: 'CBBTC',
908
+ tag: 'ETH',
909
+ fullName: 'Coinbase Wrapped BTC',
910
+ raw: 103,
911
+ name: 'cbbtc',
912
+ iconPath: 'assets/images/cbbtc_icon.png',
913
+ decimals: 8);
914
+ static const baseEth = CryptoCurrency(
915
+ title: 'ETH',
916
+ tag: 'BASE',
917
+ fullName: 'Ethereum',
918
+ raw: 104,
919
+ name: 'baseth',
920
+ iconPath: 'assets/new-ui/crypto_full_icons/ethereum.svg',
921
+ decimals: 18,
922
+ flatIconPath: "assets/new-ui/balance_card_icons/base.svg",
923
+ chainIconPath: "assets/new-ui/chain_badges/base.svg");
924
+ static const usde = CryptoCurrency(
925
+ title: 'USDE',
926
+ tag: 'BASE',
927
+ fullName: 'Ethena USDE',
928
+ raw: 105,
929
+ name: 'usde',
930
+ iconPath: 'assets/new-ui/crypto_full_icons/usde.svg',
931
+ decimals: 18);
932
+ static const arbEth = CryptoCurrency(
933
+ title: 'ETH',
934
+ tag: 'ARB',
935
+ fullName: 'Ethereum',
936
+ raw: 106,
937
+ name: 'arbeth',
938
+ iconPath: 'assets/new-ui/crypto_full_icons/ethereum.svg',
939
+ decimals: 18,
940
+ flatIconPath: "assets/new-ui/balance_card_icons/arbitrum.svg",
941
+ chainIconPath: "assets/new-ui/chain_badges/arbitrum.svg");
942
+ static const zec = CryptoCurrency(
943
+ title: 'ZEC',
944
+ fullName: 'Zcash',
945
+ raw: 107,
946
+ name: 'zec',
947
+ iconPath: 'assets/new-ui/crypto_full_icons/zcash.svg',
948
+ decimals: 8,
949
+ flatIconPath: "assets/new-ui/balance_card_icons/zcash.svg");
950
+ static const usdcArb = CryptoCurrency(
951
+ title: 'USDC',
952
+ tag: 'ARB',
953
+ fullName: 'USDC Coin',
954
+ raw: 108,
955
+ name: 'usdcarb',
956
+ iconPath: 'assets/new-ui/crypto_full_icons/usdc.svg',
957
+ decimals: 6,
958
+ groups: const {CurrencyGroups.stablecoin});
959
+ static const usdtArb = CryptoCurrency(
960
+ title: 'USDT',
961
+ tag: 'ARB',
962
+ fullName: 'USDT Tether',
963
+ raw: 109,
964
+ name: 'usdtarb',
965
+ iconPath: 'assets/new-ui/crypto_full_icons/usdt.svg',
966
+ decimals: 6,
967
+ groups: const {CurrencyGroups.stablecoin});
968
+ static const ltcmweb = CryptoCurrency(
969
+ title: 'LTC',
970
+ fullName: 'Litecoin MWeb',
971
+ raw: 110,
972
+ name: 'ltcmweb',
973
+ iconPath: 'assets/new-ui/crypto_full_icons/litecoin.svg',
974
+ decimals: 8);
975
+
976
+ static final Map<int, CryptoCurrency> _rawCurrencyMap = [
977
+ ...all,
978
+ ...havenCurrencies,
979
+ ...zcashCurrencies
980
+ ].fold<Map<int, CryptoCurrency>>(<int, CryptoCurrency>{}, (acc, item) {
981
+ acc.addAll({item.raw: item});
982
+ return acc;
983
+ });
984
+
985
+ static final Map<String, CryptoCurrency> _nameCurrencyMap = [
986
+ ...all,
987
+ ...havenCurrencies,
988
+ ...zcashCurrencies
989
+ ].fold<Map<String, CryptoCurrency>>(<String, CryptoCurrency>{}, (acc, item) {
990
+ acc.addAll({item.name: item});
991
+ return acc;
992
+ });
993
+
994
+ static final Map<String, CryptoCurrency> _fullNameCurrencyMap = [
995
+ ...all,
996
+ ...havenCurrencies,
997
+ ...zcashCurrencies
998
+ ].fold<Map<String, CryptoCurrency>>(<String, CryptoCurrency>{}, (acc, item) {
999
+ if (item.fullName != null) {
1000
+ acc.addAll({item.fullName!.toLowerCase(): item});
1001
+ }
1002
+ return acc;
1003
+ });
1004
1005
// Scheme to currency mapping for URI scheme
1006
static final Map<String, CryptoCurrency> _schemeCurrencyMap = {
@@ -324,7 +1027,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
1027
static CryptoCurrency deserialize({required int raw}) {
1028
if (CryptoCurrency._rawCurrencyMap[raw] == null) {
1029
final s = 'Unexpected token: $raw for CryptoCurrency deserialize';
327
- throw ArgumentError.value(raw, 'raw', s);
1030
+ throw ArgumentError.value(raw, 'raw', s);
1031
}
1032
return CryptoCurrency._rawCurrencyMap[raw]!;
1033
}
@@ -334,10 +1037,8 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
1037
return _rawCurrencyMap[raw];
1038
}
1039
337
-
1040
// TODO: refactor this
1041
static CryptoCurrency fromString(String name, {CryptoCurrency? walletCurrency}) {
340
-
1042
final schemeMatch = _schemeCurrencyMap[name.toLowerCase()];
1043
if (schemeMatch != null) return schemeMatch;
1044
@@ -357,7 +1058,7 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
1058
1059
if (CryptoCurrency._nameCurrencyMap[name.toLowerCase()] == null) {
1060
final s = 'Unexpected token: $name for CryptoCurrency fromString';
360
- throw ArgumentError.value(name, 'name', s);
1061
+ throw ArgumentError.value(name, 'name', s);
1062
}
1063
1064
return CryptoCurrency._nameCurrencyMap[name.toLowerCase()]!;
@@ -366,36 +1067,34 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
1067
static CryptoCurrency fromFullName(String name) {
1068
if (CryptoCurrency._fullNameCurrencyMap[name.split("(").first.trim().toLowerCase()] == null) {
1069
final s = 'Unexpected token: $name for CryptoCurrency fromFullName';
369
- throw ArgumentError.value(name, 'Fullname', s);
1070
+ throw ArgumentError.value(name, 'Fullname', s);
1071
}
1072
return CryptoCurrency._fullNameCurrencyMap[name.split("(").first.trim().toLowerCase()]!;
1073
}
1074
1075
static CryptoCurrency? safeParseCurrencyFromString(
375
- String? raw, {
376
- String? tag,
377
- CryptoCurrency? walletCurrency,
378
- }) {
1076
+ String? raw, {
1077
+ String? tag,
1078
+ CryptoCurrency? walletCurrency,
1079
+ }) {
1080
if (raw == null || raw.isEmpty) return null;
1081
381
- if(tag?.toLowerCase() == "lightning") tag = "LN";
1082
+ if (tag?.toLowerCase() == "lightning") tag = "LN";
1083
1084
if (tag != null && tag.isNotEmpty) {
1085
final match = CryptoCurrency.all.firstWhereOrNull(
385
- (e) =>
386
- e.title.toUpperCase() == raw.toUpperCase() &&
1086
+ (e) =>
1087
+ e.title.toUpperCase() == raw.toUpperCase() &&
1088
e.tag?.toUpperCase() == tag?.toUpperCase(),
1089
);
1090
if (match != null) return match;
1091
return null;
1092
}
1093
393
-
1094
// Try for native currency with same title and tag
1095
if (tag == null || tag.isEmpty) {
1096
final match = CryptoCurrency.all.firstWhereOrNull(
397
- (e) =>
398
- e.title.toUpperCase() == raw.toUpperCase() && (e.tag == raw.toUpperCase()),
1097
+ (e) => e.title.toUpperCase() == raw.toUpperCase() && (e.tag == raw.toUpperCase()),
1098
);
1099
1100
if (match != null) return match;
cw_core/lib/currency_for_wallet_type.dart
+2
-1
@@ -90,7 +90,8 @@ int? getChainIdByCryptoCurrency(CryptoCurrency currency) {
90
}
91
}
92
93
-CryptoCurrency getCryptoCurrencyForWalletListItem(WalletType type, {bool isTestnet = false, int? chainId}) {
93
+CryptoCurrency getCryptoCurrencyForWalletListItem(WalletType type,
94
+ {bool isTestnet = false, int? chainId}) {
95
if (type == WalletType.arbitrum) {
96
return CryptoCurrency.arb;
97
}
cw_core/lib/db/sqlite_debug.dart
+1
-1
@@ -100,7 +100,7 @@ class _SqliteErrorHandlerState extends State<SqliteErrorHandler> {
100
final dbFile = File("${(await getAppDir()).path}/cake.db");
101
final jsonText = JsonEncoder.withIndent(" ").convert(await dumpCustomDb(dbFile.path));
102
setState(() {
103
- log = jsonText;
103
+ log = jsonText;
104
});
105
} catch (e, s) {
106
setState(() {
cw_core/lib/encryption_file_utils.dart
+27
-28
@@ -3,40 +3,39 @@ import 'dart:typed_data';
3
import 'package:cw_core/utils/file.dart' as file;
4
import 'package:cake_backup/backup.dart' as cwb;
5
6
-EncryptionFileUtils encryptionFileUtilsFor(bool direct)
7
- => direct
8
- ? XChaCha20EncryptionFileUtils()
9
- : Salsa20EncryhptionFileUtils();
6
+EncryptionFileUtils encryptionFileUtilsFor(bool direct) =>
7
+ direct ? XChaCha20EncryptionFileUtils() : Salsa20EncryhptionFileUtils();
8
9
abstract class EncryptionFileUtils {
12
- Future<void> write({required String path, required String password, required String data});
13
- Future<String> read({required String path, required String password});
10
+ Future<void> write({required String path, required String password, required String data});
11
+ Future<String> read({required String path, required String password});
12
}
13
14
class Salsa20EncryhptionFileUtils extends EncryptionFileUtils {
17
- // Requires legacy complex key + iv as password
18
- @override
19
- Future<void> write({required String path, required String password, required String data}) async
20
- => await file.write(path: path, password: password, data: data);
15
+ // Requires legacy complex key + iv as password
16
+ @override
17
+ Future<void> write(
18
+ {required String path, required String password, required String data}) async =>
19
+ await file.write(path: path, password: password, data: data);
20
22
- // Requires legacy complex key + iv as password
23
- @override
24
- Future<String> read({required String path, required String password}) async
25
- => await file.read(path: path, password: password);
21
+ // Requires legacy complex key + iv as password
22
+ @override
23
+ Future<String> read({required String path, required String password}) async =>
24
+ await file.read(path: path, password: password);
25
}
26
27
class XChaCha20EncryptionFileUtils extends EncryptionFileUtils {
29
- @override
30
- Future<void> write({required String path, required String password, required String data}) async {
31
- final encrypted = await cwb.encrypt(password, Uint8List.fromList(data.codeUnits));
32
- await File(path).writeAsBytes(encrypted);
33
- }
34
-
35
- @override
36
- Future<String> read({required String path, required String password}) async {
37
- final file = File(path);
38
- final encrypted = await file.readAsBytes();
39
- final bytes = await cwb.decrypt(password, encrypted);
40
- return String.fromCharCodes(bytes);
41
- }
42
-}
\ No newline at end of file
28
+ @override
29
+ Future<void> write({required String path, required String password, required String data}) async {
30
+ final encrypted = await cwb.encrypt(password, Uint8List.fromList(data.codeUnits));
31
+ await File(path).writeAsBytes(encrypted);
32
+ }
33
+
34
+ @override
35
+ Future<String> read({required String path, required String password}) async {
36
+ final file = File(path);
37
+ final encrypted = await file.readAsBytes();
38
+ final bytes = await cwb.decrypt(password, encrypted);
39
+ return String.fromCharCodes(bytes);
40
+ }
41
+}
cw_core/lib/erc20_token.part.dart
+2
-4
@@ -1,4 +1,4 @@
1
- // GENERATED CODE - DO NOT MODIFY BY HAND
1
+// GENERATED CODE - DO NOT MODIFY BY HAND
2
3
part of 'erc20_token.dart';
4
@@ -55,7 +55,5 @@ class Erc20TokenAdapter extends TypeAdapter<Erc20Token> {
55
@override
56
bool operator ==(Object other) =>
57
identical(this, other) ||
58
- other is Erc20TokenAdapter &&
59
- runtimeType == other.runtimeType &&
60
- typeId == other.typeId;
58
+ other is Erc20TokenAdapter && runtimeType == other.runtimeType && typeId == other.typeId;
59
}
cw_core/lib/exceptions.dart
+1
-1
@@ -69,4 +69,4 @@ class WalletDeprecationException implements Exception {
69
String toString() => "Wallet type no longer supported";
70
71
WalletDeprecationException({required this.seed, required this.curr});
72
-}
\ No newline at end of file
72
+}
cw_core/lib/format_amount.dart
+3
-3
@@ -1,8 +1,8 @@
1
String formatAmount(String amount) {
2
- if ((!amount.contains('.'))&&(!amount.contains(','))) {
2
+ if ((!amount.contains('.')) && (!amount.contains(','))) {
3
return amount + '.00';
4
- } else if ((amount.endsWith('.'))||(amount.endsWith(','))) {
4
+ } else if ((amount.endsWith('.')) || (amount.endsWith(','))) {
5
return amount + '00';
6
}
7
return amount;
8
-}
\ No newline at end of file
8
+}
cw_core/lib/format_fixed.dart
+3
-6
@@ -1,7 +1,6 @@
1
import 'package:cw_core/parse_fixed.dart';
2
3
-String formatFixed(BigInt value, int? decimals,
4
- {int? fractionalDigits, bool trimZeros = true}) {
3
+String formatFixed(BigInt value, int? decimals, {int? fractionalDigits, bool trimZeros = true}) {
4
decimals ??= 0;
5
fractionalDigits ??= decimals;
6
@@ -10,10 +9,8 @@ String formatFixed(BigInt value, int? decimals,
9
var negative = value.isNegative;
10
if (negative) value = value * BigInt.from(-1);
11
13
- var fraction = value
14
- .modPow(BigInt.one, BigInt.parse(multiplier))
15
- .toString()
16
- .padLeft(decimals, "0");
12
+ var fraction =
13
+ value.modPow(BigInt.one, BigInt.parse(multiplier)).toString().padLeft(decimals, "0");
14
15
if (fractionalDigits < 0) fractionalDigits = 0;
16
if (fractionalDigits > decimals) fractionalDigits = decimals;
cw_core/lib/get_height_by_date.dart
+2
-1
@@ -6,7 +6,8 @@ import 'dart:convert';
6
7
// FIXME: Hardcoded values; Works only for monero
8
9
-int getMoneroHeigthByDate({required DateTime date}) => MoneroHeight.getBlockHeightByTime(date..subtract(Duration(days: 1)));
9
+int getMoneroHeigthByDate({required DateTime date}) =>
10
+ MoneroHeight.getBlockHeightByTime(date..subtract(Duration(days: 1)));
11
12
const havenDates = {
13
"2023-05": 1352995,
cw_core/lib/get_height_by_date_xmr.dart
-1
@@ -1,4 +1,3 @@
1
-
1
class MoneroHeight {
2
// for i in $(seq 1 364); do echo "_Checkpoint(_t($(curl https://xmrchain.net/block/${i}0000 | grep -E '[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}' | xargs | sed 's/ /\n/g' | head -5 | tail -1 | tr '()' ' ' | sed 's/ /\n/g' | head -2 | xargs)), ${i}0000),"; done > points.txt
3
static final List<_Checkpoint> _points = [
cw_core/lib/hive_type_ids.dart
+24
-24
@@ -1,24 +1,24 @@
1
-const CONTACT_TYPE_ID = 0;
2
-const NODE_TYPE_ID = 1;
3
-const TRANSACTION_TYPE_ID = 2;
4
-const TRADE_TYPE_ID = 3;
5
-const WALLET_INFO_TYPE_ID = 4;
6
-const WALLET_TYPE_TYPE_ID = 5;
7
-const TEMPLATE_TYPE_ID = 6;
8
-const EXCHANGE_TEMPLATE_TYPE_ID = 7;
9
-const ORDER_TYPE_ID = 8;
10
-const UNSPENT_COINS_INFO_TYPE_ID = 9;
11
-const ANONPAY_INVOICE_INFO_TYPE_ID = 10;
12
-const ADDRESS_INFO_TYPE_ID = 11;
13
-const ERC20_TOKEN_TYPE_ID = 12;
14
-const NANO_ACCOUNT_TYPE_ID = 13;
15
-const POW_NODE_TYPE_ID = 14;
16
-const DERIVATION_TYPE_TYPE_ID = 15;
17
-const SPL_TOKEN_TYPE_ID = 16;
18
-const DERIVATION_INFO_TYPE_ID = 17;
19
-const TRON_TOKEN_TYPE_ID = 18;
20
-const HARDWARE_WALLET_TYPE_TYPE_ID = 19;
21
-const MWEB_UTXO_TYPE_ID = 20;
22
-const HAVEN_SEED_STORE_TYPE_ID = 21;
23
-const ZANO_ASSET_TYPE_ID = 22;
24
-const PAYJOIN_SESSION_TYPE_ID = 23;
\ No newline at end of file
1
+const CONTACT_TYPE_ID = 0;
2
+const NODE_TYPE_ID = 1;
3
+const TRANSACTION_TYPE_ID = 2;
4
+const TRADE_TYPE_ID = 3;
5
+const WALLET_INFO_TYPE_ID = 4;
6
+const WALLET_TYPE_TYPE_ID = 5;
7
+const TEMPLATE_TYPE_ID = 6;
8
+const EXCHANGE_TEMPLATE_TYPE_ID = 7;
9
+const ORDER_TYPE_ID = 8;
10
+const UNSPENT_COINS_INFO_TYPE_ID = 9;
11
+const ANONPAY_INVOICE_INFO_TYPE_ID = 10;
12
+const ADDRESS_INFO_TYPE_ID = 11;
13
+const ERC20_TOKEN_TYPE_ID = 12;
14
+const NANO_ACCOUNT_TYPE_ID = 13;
15
+const POW_NODE_TYPE_ID = 14;
16
+const DERIVATION_TYPE_TYPE_ID = 15;
17
+const SPL_TOKEN_TYPE_ID = 16;
18
+const DERIVATION_INFO_TYPE_ID = 17;
19
+const TRON_TOKEN_TYPE_ID = 18;
20
+const HARDWARE_WALLET_TYPE_TYPE_ID = 19;
21
+const MWEB_UTXO_TYPE_ID = 20;
22
+const HAVEN_SEED_STORE_TYPE_ID = 21;
23
+const ZANO_ASSET_TYPE_ID = 22;
24
+const PAYJOIN_SESSION_TYPE_ID = 23;
cw_core/lib/key.dart
+2
-1
@@ -16,7 +16,8 @@ List<String> extractKeys(String key) {
16
return [_key, iv];
17
}
18
19
-Future<String> encode({required encrypt.Key key, required encrypt.IV iv, required String data}) async {
19
+Future<String> encode(
20
+ {required encrypt.Key key, required encrypt.IV iv, required String data}) async {
21
final encrypter = encrypt.Encrypter(encrypt.Salsa20(key));
22
final encrypted = encrypter.encrypt(data, iv: iv);
23
cw_core/lib/keyable.dart
+1
-1
@@ -1,3 +1,3 @@
1
mixin Keyable {
2
dynamic keyIndex;
3
-}
\ No newline at end of file
3
+}
cw_core/lib/lnurl.dart
+6
-9
@@ -12,12 +12,11 @@ bool isBolt11ZeroInvoice(String invoice) {
12
try {
13
final request = Bech32Codec().decode(invoice.replaceFirst("lightning:", ""), invoice.length);
14
15
-
16
- final prefix = _BOLT_PREFIXES
17
- .firstWhere((prefix) => request.hrp.startsWith(prefix), orElse: () => "");
15
+ final prefix =
16
+ _BOLT_PREFIXES.firstWhere((prefix) => request.hrp.startsWith(prefix), orElse: () => "");
17
18
return request.hrp.length == prefix.length;
20
- } catch(e) {
19
+ } catch (e) {
20
return false;
21
}
22
}
@@ -27,7 +26,7 @@ int? _getAmountBolt11Msat(String invoice) {
26
final request = Bech32Codec().decode(invoice.replaceFirst("lightning:", ""), invoice.length);
27
28
final prefix = _BOLT_PREFIXES.firstWhere(
30
- (prefix) => request.hrp.startsWith(prefix),
29
+ (prefix) => request.hrp.startsWith(prefix),
30
orElse: () => throw FormatException('Invalid BOLT11 invoice: unknown HRP prefix.'),
31
);
32
@@ -86,8 +85,7 @@ class LNURL {
85
final maxSendable = body["maxSendable"] as int?;
86
87
// if minSendable and maxSendable are the same we assume a specific payment request
89
- if (msat != maxSendable)
90
- return null;
88
+ if (msat != maxSendable) return null;
89
90
if (msat == null || msat % 1000 != 0) return null;
91
return Money.fromInt(msat ~/ 1000, CryptoCurrency.btcln);
@@ -136,8 +134,7 @@ class LNURL {
134
String _findLnUrl(String input) {
135
final res = RegExp(r',*?((lnurl)([0-9]+[a-z0-9]+))').allMatches(input.toLowerCase());
136
139
- if (res.length != 1)
140
- throw ArgumentError('Not a valid lnurl string');
137
+ if (res.length != 1) throw ArgumentError('Not a valid lnurl string');
138
return res.first.group(0)!;
139
}
140
cw_core/lib/monero_wallet_keys.dart
+6
-6
@@ -1,11 +1,11 @@
1
class MoneroWalletKeys {
2
const MoneroWalletKeys(
3
{required this.primaryAddress,
4
- required this.privateSpendKey,
5
- required this.privateViewKey,
6
- required this.publicSpendKey,
7
- required this.publicViewKey,
8
- required this.passphrase});
4
+ required this.privateSpendKey,
5
+ required this.privateViewKey,
6
+ required this.publicSpendKey,
7
+ required this.publicViewKey,
8
+ required this.passphrase});
9
10
final String primaryAddress;
11
final String publicViewKey;
@@ -13,4 +13,4 @@ class MoneroWalletKeys {
13
final String publicSpendKey;
14
final String privateSpendKey;
15
final String passphrase;
16
-}
\ No newline at end of file
16
+}
cw_core/lib/mweb_utxo.part.dart
+1
-3
@@ -50,7 +50,5 @@ class MwebUtxoAdapter extends TypeAdapter<MwebUtxo> {
50
@override
51
bool operator ==(Object other) =>
52
identical(this, other) ||
53
- other is MwebUtxoAdapter &&
54
- runtimeType == other.runtimeType &&
55
- typeId == other.typeId;
53
+ other is MwebUtxoAdapter && runtimeType == other.runtimeType && typeId == other.typeId;
54
}
cw_core/lib/nano_account.part.dart
+1
-3
@@ -44,7 +44,5 @@ class NanoAccountAdapter extends TypeAdapter<NanoAccount> {
44
@override
45
bool operator ==(Object other) =>
46
identical(this, other) ||
47
- other is NanoAccountAdapter &&
48
- runtimeType == other.runtimeType &&
49
- typeId == other.typeId;
47
+ other is NanoAccountAdapter && runtimeType == other.runtimeType && typeId == other.typeId;
48
}
cw_core/lib/node.dart
+30
-34
@@ -25,11 +25,9 @@ Future<void> validateBuiltinNodes() async {
25
for (final listNode in builtinFromList) {
26
// preserve proxy settings from user
27
try {
28
- final matchedDbNode = builtinFromDb.firstWhere(
29
- (dbNode) => dbNode.uri == listNode.uri
30
- );
28
+ final matchedDbNode = builtinFromDb.firstWhere((dbNode) => dbNode.uri == listNode.uri);
29
listNode.socksProxyAddress = matchedDbNode.socksProxyAddress;
32
- } catch(e) {}
30
+ } catch (e) {}
31
}
32
33
final dbSet = builtinFromDb.toSet();
@@ -121,7 +119,7 @@ class Node {
119
"label": label,
120
'password': password,
121
"isPow": isPow ? 1 : 0,
124
- 'useSSL': (useSSL??false) ? 1 : 0,
122
+ 'useSSL': (useSSL ?? false) ? 1 : 0,
123
"typeRaw": typeRaw,
124
'trusted': trusted ? 1 : 0,
125
'socksProxyAddress': socksProxyAddress,
@@ -165,7 +163,6 @@ class Node {
163
}
164
165
Future<int> save() async {
168
-
166
final json = toMap();
167
if (json[selfIdColumn] == 0) {
168
json[selfIdColumn] = null;
@@ -174,9 +171,9 @@ class Node {
171
return id;
172
}
173
177
-
178
- static Future<List<Node>> selectList(String where, List<dynamic> whereArgs, {String? orderBy}) async {
179
- if(orderBy == null) {
174
+ static Future<List<Node>> selectList(String where, List<dynamic> whereArgs,
175
+ {String? orderBy}) async {
176
+ if (orderBy == null) {
177
orderBy = selfIdColumn;
178
}
179
final list = await db!.query(
@@ -189,7 +186,7 @@ class Node {
186
}
187
188
static Future<Node?> select(String where, List<dynamic> whereArgs, {String? orderBy}) async {
192
- if(orderBy == null) {
189
+ if (orderBy == null) {
190
orderBy = selfIdColumn;
191
}
192
final list = await db!.query(
@@ -201,7 +198,6 @@ class Node {
198
return list.isEmpty ? null : Node.fromMap(list.first);
199
}
200
204
-
201
static Future<List<Node>> getAll() async {
202
return selectList("isPow = ?", [0]);
203
}
@@ -219,11 +215,15 @@ class Node {
215
}
216
217
static Future<Node?> getDefaultForWalletType(WalletType type) async {
222
- return (await selectList("typeRaw = ? AND isPow = ? AND isDefault = ?", [serializeToInt(type), 0, 1])).firstOrNull;
218
+ return (await selectList(
219
+ "typeRaw = ? AND isPow = ? AND isDefault = ?", [serializeToInt(type), 0, 1]))
220
+ .firstOrNull;
221
}
222
223
static Future<Node?> getDefaultPowForWalletType(WalletType type) async {
226
- return (await selectList("typeRaw = ? AND isPow = ? AND isDefault = ?", [serializeToInt(type), 1, 1])).firstOrNull;
224
+ return (await selectList(
225
+ "typeRaw = ? AND isPow = ? AND isDefault = ?", [serializeToInt(type), 1, 1]))
226
+ .firstOrNull;
227
}
228
229
static Future<List<Node>> getAllForWalletTypePow(WalletType type) async {
@@ -238,7 +238,6 @@ class Node {
238
return select("${selfIdColumn} = ?", [id]);
239
}
240
241
-
241
int id;
242
late String uriRaw;
243
String? login;
@@ -262,7 +261,6 @@ class Node {
261
static String get tableName => "Node";
262
static String get selfIdColumn => "${tableName}Id";
263
265
-
264
bool get isSSL => useSSL ?? false;
265
266
bool get useSocksProxy => socksProxyAddress == null ? false : socksProxyAddress!.isNotEmpty;
@@ -333,7 +331,6 @@ class Node {
331
socksProxyAddress.hashCode ^
332
path.hashCode;
333
336
-
334
WalletType get type => deserializeFromInt(typeRaw);
335
336
set type(WalletType type) => typeRaw = serializeToInt(type);
@@ -387,7 +384,6 @@ class Node {
384
body: jsonBody,
385
);
386
390
-
387
final resBody = json.decode(response.body) as Map<String, dynamic>;
388
389
return resBody['result']['height'] != null;
@@ -407,15 +403,13 @@ class Node {
403
final body = {'jsonrpc': '2.0', 'id': '0', 'method': methodName};
404
405
try {
410
-
406
final jsonBody = json.encode(body);
407
408
final response = await ProxyWrapper().post(
414
- clearnetUri: rpcUri,
415
- headers: {'Content-Type': 'application/json'},
416
- body: jsonBody,
417
- allowMitmMoneroBypassSSLCheck: true
418
- );
409
+ clearnetUri: rpcUri,
410
+ headers: {'Content-Type': 'application/json'},
411
+ body: jsonBody,
412
+ allowMitmMoneroBypassSSLCheck: true);
413
// Check if we received a 401 Unauthorized response
414
if (response.statusCode == 401) {
415
final daemonRpc = DaemonRpc(
@@ -494,7 +488,6 @@ class Node {
488
final ProxySocket socket;
489
socket = await ProxyWrapper().getSocksSocket(useSSL ?? false, uri.host, uri.port);
490
497
-
491
socket.destroy();
492
return true;
493
} catch (_) {
@@ -531,9 +524,12 @@ class Node {
524
525
Future<bool> requestEthereumServer() async {
526
try {
534
- final req = await ProxyWrapper().getHttpClient()
535
- .getUrl(uri,)
536
- .timeout(Duration(seconds: 15));
527
+ final req = await ProxyWrapper()
528
+ .getHttpClient()
529
+ .getUrl(
530
+ uri,
531
+ )
532
+ .timeout(Duration(seconds: 15));
533
final response = await req.close();
534
535
return response.statusCode >= 200 && response.statusCode < 300;
@@ -544,13 +540,13 @@ class Node {
540
}
541
542
Future<bool> requestDecredNode() async {
547
- if (uri.host == "default-spv-nodes") {
548
- // Just show default port as ok. The wallet will connect to a list of known
549
- // nodes automatically.
550
- return true;
551
- }
552
- try {
553
- final socket = await Socket.connect(uri.host, uri.port, timeout: Duration(seconds: 5));
543
+ if (uri.host == "default-spv-nodes") {
544
+ // Just show default port as ok. The wallet will connect to a list of known
545
+ // nodes automatically.
546
+ return true;
547
+ }
548
+ try {
549
+ final socket = await Socket.connect(uri.host, uri.port, timeout: Duration(seconds: 5));
550
socket.destroy();
551
return true;
552
} catch (_) {
cw_core/lib/node_legacy.dart
+18
-28
@@ -19,17 +19,15 @@ import 'node.dart' as node_new;
19
part 'node_legacy.part.dart';
20
21
Future<void> performNodeHiveMigration() async {
22
- if(!CakeHive.isAdapterRegistered(Node.typeId)) {
22
+ if (!CakeHive.isAdapterRegistered(Node.typeId)) {
23
CakeHive.registerAdapter(NodeAdapter());
24
}
25
26
final nodeBox = await CakeHive.openBox<Node>(Node.boxName);
27
- final powNodeBox = await CakeHive.openBox<Node>(Node.boxName+"pow");
27
+ final powNodeBox = await CakeHive.openBox<Node>(Node.boxName + "pow");
28
final builtinNodes = await loadAllDefaultNodes();
29
final builtinPowNodes = await loadDefaultNanoPowNodes();
30
await Node.migrateAllToSqlite(nodeBox, powNodeBox, builtinNodes, builtinPowNodes);
31
-
32
-
31
}
32
33
Uri createUriFromElectrumAddress(String address, String path) =>
@@ -62,31 +60,26 @@ class Node extends HiveObject with Keyable {
60
final list = nodeBox.values.toList();
61
final powList = powNodeBox.values.toList();
62
for (final node in list) {
65
- if(defaultNodes.any((item)=>item.uri == node.uri)) {
63
+ if (defaultNodes.any((item) => item.uri == node.uri)) {
64
// default nodes will be added by validateBuiltinNodes(), no need to migrate them.
65
await node.delete();
66
continue;
67
}
70
- await node.migrateToSqlite(
71
- isPow: false,
72
- isBuiltin: false,
73
- isOfficial: false);
68
+ await node.migrateToSqlite(isPow: false, isBuiltin: false, isOfficial: false);
69
await node.delete();
70
}
71
for (final node in powList) {
77
- if(defaultPowNodes.any((item)=>item.uri == node.uri)) {
72
+ if (defaultPowNodes.any((item) => item.uri == node.uri)) {
73
await node.delete();
74
continue;
75
}
81
- await node.migrateToSqlite(
82
- isPow: true,
83
- isBuiltin: false,
84
- isOfficial: false);
76
+ await node.migrateToSqlite(isPow: true, isBuiltin: false, isOfficial: false);
77
await node.delete();
78
}
79
}
80
89
- Future<void> migrateToSqlite({required bool isPow, required bool isBuiltin, required bool isOfficial}) async {
81
+ Future<void> migrateToSqlite(
82
+ {required bool isPow, required bool isBuiltin, required bool isOfficial}) async {
83
final newNode = node_new.Node(
84
id: key as int,
85
login: login,
@@ -106,7 +99,6 @@ class Node extends HiveObject with Keyable {
99
await newNode.save();
100
}
101
109
-
102
Node.fromMap(Map<String, Object?> map)
103
: uriRaw = map['uri'] as String? ?? '',
104
path = map['path'] as String? ?? '',
@@ -208,15 +200,15 @@ class Node extends HiveObject with Keyable {
200
@override
201
bool operator ==(other) =>
202
other is Node &&
211
- (other.uriRaw == uriRaw &&
212
- other.login == login &&
213
- other.label == label &&
214
- other.password == password &&
215
- other.typeRaw == typeRaw &&
216
- other.useSSL == useSSL &&
217
- other.trusted == trusted &&
218
- other.socksProxyAddress == socksProxyAddress &&
219
- other.path == path);
203
+ (other.uriRaw == uriRaw &&
204
+ other.login == login &&
205
+ other.label == label &&
206
+ other.password == password &&
207
+ other.typeRaw == typeRaw &&
208
+ other.useSSL == useSSL &&
209
+ other.trusted == trusted &&
210
+ other.socksProxyAddress == socksProxyAddress &&
211
+ other.path == path);
212
213
@override
214
int get hashCode =>
@@ -241,6 +233,4 @@ class Node extends HiveObject with Keyable {
233
set type(WalletType type) => typeRaw = serializeToInt(type);
234
235
dynamic _keyIndex;
244
-
245
-
246
-}
\ No newline at end of file
236
+}
cw_core/lib/node_legacy.part.dart
+2
-5
@@ -24,8 +24,7 @@ class NodeAdapter extends TypeAdapter<Node> {
24
trusted: fields[5] == null ? false : fields[5] as bool,
25
socksProxyAddress: fields[6] as String?,
26
path: fields[7] == null ? '' : fields[7] as String?,
27
- isEnabledForAutoSwitching:
28
- fields[11] == null ? false : fields[11] as bool,
27
+ isEnabledForAutoSwitching: fields[11] == null ? false : fields[11] as bool,
28
)
29
..uriRaw = fields[0] == null ? '' : fields[0] as String
30
..typeRaw = fields[3] == null ? 0 : fields[3] as int
@@ -72,7 +71,5 @@ class NodeAdapter extends TypeAdapter<Node> {
71
@override
72
bool operator ==(Object other) =>
73
identical(this, other) ||
75
- other is NodeAdapter &&
76
- runtimeType == other.runtimeType &&
77
- typeId == other.typeId;
74
+ other is NodeAdapter && runtimeType == other.runtimeType && typeId == other.typeId;
75
}
cw_core/lib/node_list.dart
+8
-13
@@ -18,7 +18,7 @@ Future<List<Node>> loadDefaultNodes(WalletType type) async {
18
case WalletType.haven:
19
path = 'assets/haven_node_list.yml';
20
break;
21
- // TODO: (refactoring) each wallet would have its path, so `wallet.nodePath` would be decided based on chain id in Evm wallet
21
+ // TODO: (refactoring) each wallet would have its path, so `wallet.nodePath` would be decided based on chain id in Evm wallet
22
case WalletType.ethereum:
23
path = 'assets/ethereum_server_list.yml';
24
break;
@@ -147,7 +147,6 @@ Future<List<Node>> loadAllDefaultNodes() async {
147
}
148
149
Future<void> resetToDefault() async {
150
-
150
final nodes = await loadAllDefaultNodes();
151
152
final currentNodes = await Node.getAll();
@@ -157,15 +156,14 @@ Future<void> resetToDefault() async {
156
for (final node in nodes) {
157
try {
158
final curr = currentNodes.firstWhere(
160
- (item) => item.uri == node.uri && item.typeRaw == node.typeRaw,
159
+ (item) => item.uri == node.uri && item.typeRaw == node.typeRaw,
160
);
162
- node.id = curr.id;
163
- } catch(e) {}
164
-
161
+ node.id = curr.id;
162
+ } catch (e) {}
163
}
164
165
await Node.deleteAll();
168
- for(final node in nodes) {
166
+ for (final node in nodes) {
167
await node.save();
168
}
169
}
@@ -173,7 +171,7 @@ Future<void> resetToDefault() async {
171
Future<void> resetPowToDefault() async {
172
final nanoPowNodes = await loadDefaultNanoPowNodes();
173
await Node.deleteAllPow();
176
- for(final node in nanoPowNodes) {
174
+ for (final node in nanoPowNodes) {
175
node.save();
176
}
177
}
@@ -181,12 +179,9 @@ Future<void> resetPowToDefault() async {
179
Future<Node> getDefaultNodeFromFiles(WalletType type, {bool isPow = false}) async {
180
final nodes = isPow ? await loadDefaultNanoPowNodes() : await loadDefaultNodes(type);
181
try {
184
- return nodes.firstWhere((item)=>item.isDefault);
185
- } catch(e) {
182
+ return nodes.firstWhere((item) => item.isDefault);
183
+ } catch (e) {
184
// ideally the yamls would always have a default, but this is better than nothing
185
return nodes.first;
186
}
187
}
190
-
191
-
192
-
cw_core/lib/parseBoolFromString.dart
+1
-1
@@ -1,3 +1,3 @@
1
bool parseBoolFromString(String string) {
2
return string.toString() == 'true';
3
-}
\ No newline at end of file
3
+}
cw_core/lib/parse_fixed.dart
+2
-1
@@ -52,7 +52,8 @@ BigInt parseFixed(String value, int decimals) {
52
var fraction = (comps.length == 2 ? comps[1] : "0").padRight(decimals, "0");
53
54
if (fraction.length > multiplier.length - 1) {
55
- throw FormatException("fractional component(${fraction.length}) exceeds decimals(${decimals}), underflow, parseFixed");
55
+ throw FormatException(
56
+ "fractional component(${fraction.length}) exceeds decimals(${decimals}), underflow, parseFixed");
57
}
58
59
final wholeValue = BigInt.parse(whole);
cw_core/lib/pathForWallet.dart
+1
-2
@@ -28,8 +28,7 @@ Future<String> pathForWalletDir({required String name, required WalletType type}
28
}
29
30
Future<String> pathForWallet({required String name, required WalletType type}) async =>
31
- await pathForWalletDir(name: name, type: type)
32
- .then((path) => path + '/$name');
31
+ await pathForWalletDir(name: name, type: type).then((path) => path + '/$name');
32
33
Future<String> outdatedAndroidPathForWalletDir({required String name}) async {
34
final directory = await getAppDir();
cw_core/lib/payjoin_session.dart
-1
@@ -56,7 +56,6 @@ class PayjoinSession extends HiveObject {
56
57
BigInt get amount => BigInt.parse(rawAmount ?? "0");
58
set amount(BigInt amount) => rawAmount = amount.toString();
59
-
59
}
60
61
enum PayjoinSessionStatus {
cw_core/lib/payjoin_session.part.dart
+1
-3
@@ -59,7 +59,5 @@ class PayjoinSessionAdapter extends TypeAdapter<PayjoinSession> {
59
@override
60
bool operator ==(Object other) =>
61
identical(this, other) ||
62
- other is PayjoinSessionAdapter &&
63
- runtimeType == other.runtimeType &&
64
- typeId == other.typeId;
62
+ other is PayjoinSessionAdapter && runtimeType == other.runtimeType && typeId == other.typeId;
63
}
cw_core/lib/payment_uris.dart
+3
-4
@@ -408,14 +408,14 @@ class ERC681URI extends PaymentURI {
408
409
static int _getChainID(String path) {
410
return int.parse(RegExp(
411
- r'@\d*',
412
- ).firstMatch(path)?.group(0)?.replaceAll("@", "") ??
411
+ r'@\d*',
412
+ ).firstMatch(path)?.group(0)?.replaceAll("@", "") ??
413
"1");
414
}
415
416
static (bool, String) _getTargetAddress(String path) {
417
final targetAddress =
418
- RegExp(r'^(0x)?[0-9a-f]{40}', caseSensitive: false).firstMatch(path)!.group(0)!;
418
+ RegExp(r'^(0x)?[0-9a-f]{40}', caseSensitive: false).firstMatch(path)!.group(0)!;
419
return (path.contains("/"), targetAddress);
420
}
421
@@ -508,4 +508,3 @@ class LightningPaymentRequest extends PaymentURI {
508
@override
509
String toString() => bolt11Invoice ?? "lightning:$lnURL";
510
}
511
-
cw_core/lib/root_dir.dart
+16
-12
@@ -23,12 +23,11 @@ bool get isNonAmnesticTails {
23
24
bool showNotice = true;
25
26
-void setRootDirFromEnv() =>
27
- _rootDirPath = Platform.environment['CAKE_WALLET_DIR'];
26
+void setRootDirFromEnv() => _rootDirPath = Platform.environment['CAKE_WALLET_DIR'];
27
28
void copyDirectory(Directory source, Directory destination) {
29
source.listSync(recursive: false).forEach((var entity) {
31
- if (entity is Directory) {
30
+ if (entity is Directory) {
31
var newDirectory = Directory(p.join(destination.absolute.path, p.basename(entity.path)));
32
newDirectory.createSync(recursive: true);
33
copyDirectory(entity.absolute, newDirectory);
@@ -41,7 +40,8 @@ void copyDirectory(Directory source, Directory destination) {
40
41
Future<void> linuxSymlinkSharedPreferences() async {
42
if (!Platform.isLinux) return; // nuh-uh
44
- final dataHome = Platform.environment["XDG_DATA_HOME"] ?? p.join(Platform.environment["HOME"] ?? "", ".local", "share");
43
+ final dataHome = Platform.environment["XDG_DATA_HOME"] ??
44
+ p.join(Platform.environment["HOME"] ?? "", ".local", "share");
45
var cakeNames = ['com.example.cake_wallet', 'cake_wallet'];
46
for (String name in cakeNames) {
47
final oldPath = p.join(dataHome, name);
@@ -53,8 +53,8 @@ Future<void> linuxSymlinkSharedPreferences() async {
53
if (oldLink.existsSync()) {
54
printV("not creating, link exists");
55
} else {
56
- if (newDir.existsSync()) {
57
- newDir.renameSync("${newPath}_${DateTime.now().millisecondsSinceEpoch~/1000}");
56
+ if (newDir.existsSync()) {
57
+ newDir.renameSync("${newPath}_${DateTime.now().millisecondsSinceEpoch ~/ 1000}");
58
}
59
copyDirectory(oldDir, newDir);
60
oldDir.deleteSync(recursive: true);
@@ -94,14 +94,16 @@ Future<Directory> getAppDir() async {
94
// for storing things that users in general back-up
95
var linuxAppPath = [
96
if (appDirPath != null) appDirPath, // old preferred
97
- p.join('/home', Platform.environment['USER']??"null", appName), // old fallback
98
- if (Platform.environment['HOME'] != null) p.join(Platform.environment['HOME']!, ".$appName"), // old fallback but using HOME
99
- if (Platform.environment['HOME'] != null) p.join(Platform.environment['HOME']!, '.config', appName), // old fallback but using HOME
97
+ p.join('/home', Platform.environment['USER'] ?? "null", appName), // old fallback
98
+ if (Platform.environment['HOME'] != null)
99
+ p.join(Platform.environment['HOME']!, ".$appName"), // old fallback but using HOME
100
+ if (Platform.environment['HOME'] != null)
101
+ p.join(Platform.environment['HOME']!, '.config', appName), // old fallback but using HOME
102
if (isNonAmnesticTails) p.join(_tailsData, ".$appName") // tails (if persistance is enabled)
103
];
104
105
String preferredPath = linuxAppPath.last;
104
-
106
+
107
preferredLoop:
108
for (String notSoPreferredPath in linuxAppPath) {
109
if (notSoPreferredPath == linuxAppPath.last) continue;
@@ -109,8 +111,10 @@ Future<Directory> getAppDir() async {
111
if (useThisOne) {
112
if (showNotice) {
113
showNotice = false;
112
- printV("Not using $preferredPath because $notSoPreferredPath exists, falling back for backwards compatibility");
113
- printV("Can't see your wallet? Check\n - ${linuxAppPath.join("\n - ")}\n and move directory that to $preferredPath");
114
+ printV(
115
+ "Not using $preferredPath because $notSoPreferredPath exists, falling back for backwards compatibility");
116
+ printV(
117
+ "Can't see your wallet? Check\n - ${linuxAppPath.join("\n - ")}\n and move directory that to $preferredPath");
118
printV("Or use CAKE_WALLET_DIR=/path/to/app/ ${Platform.executable}");
119
}
120
preferredPath = notSoPreferredPath;
cw_core/lib/sec_random_native.dart
+2
-1
@@ -14,7 +14,8 @@ Future<Uint8List> secRandom(int count) async {
14
final rng = Random.secure();
15
return Uint8List.fromList(List<int>.generate(count, (_) => rng.nextInt(byteSize)));
16
}
17
- return await utils.invokeMethod<Uint8List>('sec_random', {'count': count}) ?? Uint8List.fromList([]);
17
+ return await utils.invokeMethod<Uint8List>('sec_random', {'count': count}) ??
18
+ Uint8List.fromList([]);
19
} on PlatformException catch (_) {
20
return Uint8List.fromList([]);
21
}
cw_core/lib/solana_rpc_http_service.dart
+2
-4
@@ -4,14 +4,12 @@ import 'package:on_chain/solana/solana.dart';
4
5
class SolanaRPCHTTPService implements SolanaJSONRPCService {
6
SolanaRPCHTTPService(
7
- {required this.url,
8
- this.defaultRequestTimeout = const Duration(seconds: 30)});
7
+ {required this.url, this.defaultRequestTimeout = const Duration(seconds: 30)});
8
@override
9
final String url;
10
final Duration defaultRequestTimeout;
11
13
- Future<Map<String, dynamic>> call(SolanaRequestDetails params,
14
- [Duration? timeout]) async {
12
+ Future<Map<String, dynamic>> call(SolanaRequestDetails params, [Duration? timeout]) async {
13
final response = await ProxyWrapper().post(
14
clearnetUri: Uri.parse(url),
15
body: params.toRequestBody(),
cw_core/lib/spl_token.part.dart
+1
-3
@@ -58,7 +58,5 @@ class SPLTokenAdapter extends TypeAdapter<SPLToken> {
58
@override
59
bool operator ==(Object other) =>
60
identical(this, other) ||
61
- other is SPLTokenAdapter &&
62
- runtimeType == other.runtimeType &&
63
- typeId == other.typeId;
61
+ other is SPLTokenAdapter && runtimeType == other.runtimeType && typeId == other.typeId;
62
}
cw_core/lib/transaction_direction.dart
+5
-3
@@ -7,7 +7,8 @@ TransactionDirection parseTransactionDirectionFromInt(int raw) {
7
case 1:
8
return TransactionDirection.outgoing;
9
default:
10
- throw Exception('Unexpected token: raw for TransactionDirection parseTransactionDirectionFromInt');
10
+ throw Exception(
11
+ 'Unexpected token: raw for TransactionDirection parseTransactionDirectionFromInt');
12
}
13
}
14
@@ -18,6 +19,7 @@ TransactionDirection parseTransactionDirectionFromNumber(String raw) {
19
case "1":
20
return TransactionDirection.outgoing;
21
default:
21
- throw Exception('Unexpected token: raw for TransactionDirection parseTransactionDirectionFromNumber');
22
+ throw Exception(
23
+ 'Unexpected token: raw for TransactionDirection parseTransactionDirectionFromNumber');
24
}
23
-}
\ No newline at end of file
25
+}
cw_core/lib/transaction_history.dart
+1
-2
@@ -2,8 +2,7 @@ import 'package:mobx/mobx.dart';
2
import 'package:cw_core/transaction_info.dart';
3
4
abstract class TransactionHistoryBase<TransactionType extends TransactionInfo> {
5
- TransactionHistoryBase()
6
- : transactions = ObservableMap<String, TransactionType>();
5
+ TransactionHistoryBase() : transactions = ObservableMap<String, TransactionType>();
6
7
@observable
8
ObservableMap<String, TransactionType> transactions;
cw_core/lib/transaction_priority.dart
+3
-3
@@ -1,9 +1,9 @@
1
import 'package:cw_core/enumerable_item.dart';
2
3
-abstract class TransactionPriority extends EnumerableItem<int>
4
- with Serializable<int> {
3
+abstract class TransactionPriority extends EnumerableItem<int> with Serializable<int> {
4
final String? description;
5
final String? hint;
6
8
- const TransactionPriority({required String title, required int raw, this.description, this.hint}) : super(title: title, raw: raw);
7
+ const TransactionPriority({required String title, required int raw, this.description, this.hint})
8
+ : super(title: title, raw: raw);
9
}
cw_core/lib/tron_token.part.dart
+1
-3
@@ -55,7 +55,5 @@ class TronTokenAdapter extends TypeAdapter<TronToken> {
55
@override
56
bool operator ==(Object other) =>
57
identical(this, other) ||
58
- other is TronTokenAdapter &&
59
- runtimeType == other.runtimeType &&
60
- typeId == other.typeId;
58
+ other is TronTokenAdapter && runtimeType == other.runtimeType && typeId == other.typeId;
59
}
cw_core/lib/utils/file.dart
+1
-3
@@ -6,9 +6,7 @@ Future<void> write({required String path, required String password, required Str
6
writeData(path: path, password: password, data: data);
7
8
Future<void> writeData(
9
- {required String path,
10
- required String password,
11
- required String data}) async {
9
+ {required String path, required String password, required String data}) async {
10
final keys = extractKeys(password);
11
final key = encrypt.Key.fromBase64(keys.first);
12
final iv = encrypt.IV.fromBase64(keys.last);
cw_core/lib/utils/proxy_logger/abstract.dart
+3
-3
@@ -11,7 +11,7 @@ enum RequestMethod {
11
post,
12
put,
13
delete,
14
-
14
+
15
newHttpClient,
16
newHttpIOClient,
17
newProxySocket,
@@ -23,7 +23,7 @@ abstract class ProxyLogger {
23
required RequestMethod method,
24
required Uint8List body,
25
required very_insecure_http_do_not_use.Response? response,
26
- required RequestNetwork network,
26
+ required RequestNetwork network,
27
required String? error,
28
});
29
-}
\ No newline at end of file
29
+}
cw_core/lib/utils/proxy_logger/memory_proxy_logger.dart
+12
-10
@@ -46,18 +46,20 @@ class MemoryProxyLogger implements ProxyLogger {
46
required RequestMethod method,
47
required Uint8List body,
48
required very_insecure_http_do_not_use.Response? response,
49
- required RequestNetwork network,
49
+ required RequestNetwork network,
50
required String? error,
51
}) {
52
final trace = StackTrace.current;
53
- logs.add(MemoryProxyLoggerEntry(
54
- method: method,
55
- trace: trace,
56
- uri: uri,
57
- body: body,
58
- network: network,
59
- response: response,
60
- error: error,),
53
+ logs.add(
54
+ MemoryProxyLoggerEntry(
55
+ method: method,
56
+ trace: trace,
57
+ uri: uri,
58
+ body: body,
59
+ network: network,
60
+ response: response,
61
+ error: error,
62
+ ),
63
);
64
}
63
-}
\ No newline at end of file
65
+}
cw_core/lib/utils/proxy_logger/silent_logger.dart
+2
-2
@@ -11,7 +11,7 @@ class SilentProxyLogger implements ProxyLogger {
11
required RequestMethod method,
12
required Uint8List body,
13
required very_insecure_http_do_not_use.Response? response,
14
- required RequestNetwork network,
14
+ required RequestNetwork network,
15
required String? error,
16
}) {}
17
-}
\ No newline at end of file
17
+}
cw_core/lib/utils/proxy_socket/abstract.dart
+10
-7
@@ -16,19 +16,21 @@ class ProxyAddress {
16
}
17
18
abstract class ProxySocket {
19
- static Future<ProxySocket> connect(bool sslEnabled, ProxyAddress address, {Duration? connectionTimeout}) async {
19
+ static Future<ProxySocket> connect(bool sslEnabled, ProxyAddress address,
20
+ {Duration? connectionTimeout}) async {
21
if (CakeTor.instance!.started) {
22
var socksSocket = await SOCKSSocket.create(
22
- proxyHost: InternetAddress.loopbackIPv4.address,
23
- proxyPort: CakeTor.instance!.port,
24
- sslEnabled: sslEnabled,
23
+ proxyHost: InternetAddress.loopbackIPv4.address,
24
+ proxyPort: CakeTor.instance!.port,
25
+ sslEnabled: sslEnabled,
26
);
27
await socksSocket.connect();
28
await socksSocket.connectTo(address.host, address.port);
29
return ProxySocketSocks(socksSocket);
30
}
31
if (sslEnabled == false) {
31
- return ProxySocketInsecure(await Socket.connect(address.host, address.port, timeout: connectionTimeout));
32
+ return ProxySocketInsecure(
33
+ await Socket.connect(address.host, address.port, timeout: connectionTimeout));
34
} else {
35
return ProxySocketSecure(await SecureSocket.connect(
36
address.host,
@@ -43,6 +45,7 @@ abstract class ProxySocket {
45
void destroy();
46
void write(String data);
47
bool get isClosed;
46
- StreamSubscription<List<int>> listen(Function(Uint8List event) onData, {Function (Object error)? onError, Function ()? onDone, bool cancelOnError = true});
48
+ StreamSubscription<List<int>> listen(Function(Uint8List event) onData,
49
+ {Function(Object error)? onError, Function()? onDone, bool cancelOnError = true});
50
ProxyAddress get address;
48
-}
\ No newline at end of file
51
+}
cw_core/lib/utils/proxy_socket/insecure.dart
+11
-10
@@ -1,4 +1,3 @@
1
-
1
import 'package:cw_core/utils/print_verbose.dart';
2
import 'package:cw_core/utils/proxy_socket/abstract.dart';
3
import 'dart:async';
@@ -9,15 +8,16 @@ class ProxySocketInsecure implements ProxySocket {
8
final Socket socket;
9
10
ProxySocketInsecure(this.socket);
12
-
11
+
12
bool isClosed = false;
13
15
- ProxyAddress get address => ProxyAddress(host: socket.remoteAddress.host, port: socket.remotePort);
16
-
14
+ ProxyAddress get address =>
15
+ ProxyAddress(host: socket.remoteAddress.host, port: socket.remotePort);
16
+
17
@override
18
Future<void> close() async {
19
try {
20
- if (isClosed) return;
20
+ if (isClosed) return;
21
isClosed = true;
22
return socket.close();
23
} catch (e) {
@@ -25,7 +25,7 @@ class ProxySocketInsecure implements ProxySocket {
25
return;
26
}
27
}
28
-
28
+
29
@override
30
void destroy() async {
31
try {
@@ -37,7 +37,7 @@ class ProxySocketInsecure implements ProxySocket {
37
return;
38
}
39
}
40
-
40
+
41
@override
42
void write(String data) {
43
try {
@@ -51,9 +51,10 @@ class ProxySocketInsecure implements ProxySocket {
51
return;
52
}
53
}
54
-
54
+
55
@override
56
- StreamSubscription<List<int>> listen(Function(Uint8List event) onData, {Function(Object error)? onError, Function()? onDone, bool cancelOnError = true}) {
56
+ StreamSubscription<List<int>> listen(Function(Uint8List event) onData,
57
+ {Function(Object error)? onError, Function()? onDone, bool cancelOnError = true}) {
58
return socket.listen(
59
(data) {
60
onData(Uint8List.fromList(data));
@@ -63,4 +64,4 @@ class ProxySocketInsecure implements ProxySocket {
64
cancelOnError: cancelOnError,
65
);
66
}
66
-}
\ No newline at end of file
67
+}
cw_core/lib/utils/proxy_socket/secure.dart
+10
-8
@@ -11,9 +11,10 @@ class ProxySocketSecure implements ProxySocket {
11
bool isClosed = false;
12
13
ProxySocketSecure(this.socket);
14
-
15
- ProxyAddress get address => ProxyAddress(host: socket.remoteAddress.host, port: socket.remotePort);
16
-
14
+
15
+ ProxyAddress get address =>
16
+ ProxyAddress(host: socket.remoteAddress.host, port: socket.remotePort);
17
+
18
@override
19
Future<void> close() async {
20
try {
@@ -25,11 +26,11 @@ class ProxySocketSecure implements ProxySocket {
26
return;
27
}
28
}
28
-
29
+
30
@override
31
void destroy() async {
32
try {
32
- if (isClosed) return;
33
+ if (isClosed) return;
34
isClosed = true;
35
socket.destroy();
36
} catch (e) {
@@ -37,7 +38,7 @@ class ProxySocketSecure implements ProxySocket {
38
return;
39
}
40
}
40
-
41
+
42
@override
43
void write(String data) {
44
runZonedGuarded(() {
@@ -57,9 +58,10 @@ class ProxySocketSecure implements ProxySocket {
58
printV("ProxySocketSecure: write (async error): $e");
59
});
60
}
60
-
61
+
62
@override
62
- StreamSubscription<List<int>> listen(Function(Uint8List event) onData, {Function(Object error)? onError, Function()? onDone, bool cancelOnError = true}) {
63
+ StreamSubscription<List<int>> listen(Function(Uint8List event) onData,
64
+ {Function(Object error)? onError, Function()? onDone, bool cancelOnError = true}) {
65
return socket.listen(
66
(data) {
67
onData(Uint8List.fromList(data));
cw_core/lib/utils/proxy_socket/socks.dart
+6
-6
@@ -9,10 +9,10 @@ class ProxySocketSocks implements ProxySocket {
9
final SOCKSSocket socket;
10
bool isClosed = false;
11
ProxySocketSocks(this.socket);
12
-
12
+
13
@override
14
ProxyAddress get address => ProxyAddress(host: socket.proxyHost, port: socket.proxyPort);
15
-
15
+
16
@override
17
Future<void> close() async {
18
try {
@@ -24,10 +24,10 @@ class ProxySocketSocks implements ProxySocket {
24
return;
25
}
26
}
27
-
27
+
28
@override
29
void destroy() => close();
30
-
30
+
31
@override
32
void write(String data) {
33
try {
@@ -43,7 +43,8 @@ class ProxySocketSocks implements ProxySocket {
43
}
44
45
@override
46
- StreamSubscription<List<int>> listen(Function(Uint8List event) onData, {Function(Object error)? onError, Function()? onDone, bool cancelOnError = true}) {
46
+ StreamSubscription<List<int>> listen(Function(Uint8List event) onData,
47
+ {Function(Object error)? onError, Function()? onDone, bool cancelOnError = true}) {
48
return socket.listen(
49
(data) {
50
onData(Uint8List.fromList(data));
@@ -54,4 +55,3 @@ class ProxySocketSocks implements ProxySocket {
55
);
56
}
57
}
57
-
cw_core/lib/utils/proxy_wrapper.dart
+23
-27
@@ -16,22 +16,23 @@ class ProxyWrapper {
16
factory ProxyWrapper() {
17
return _proxyWrapper;
18
}
19
-
19
+
20
ProxyWrapper._internal();
21
- Future<ProxySocket> getSocksSocket(bool sslEnabled, String host, int port, {Duration? connectionTimeout}) async {
21
+ Future<ProxySocket> getSocksSocket(bool sslEnabled, String host, int port,
22
+ {Duration? connectionTimeout}) async {
23
logger?.log(
23
- uri: Uri(
24
- scheme: sslEnabled ? "https" : "http",
25
- host: host,
26
- port: port,
27
- ),
28
- method: RequestMethod.newProxySocket,
29
- body: Uint8List(0),
30
- response: null,
31
- network: requestNetwork(),
32
- error: null
33
- );
34
- return ProxySocket.connect(sslEnabled, ProxyAddress(host: host, port: port), connectionTimeout: connectionTimeout);
24
+ uri: Uri(
25
+ scheme: sslEnabled ? "https" : "http",
26
+ host: host,
27
+ port: port,
28
+ ),
29
+ method: RequestMethod.newProxySocket,
30
+ body: Uint8List(0),
31
+ response: null,
32
+ network: requestNetwork(),
33
+ error: null);
34
+ return ProxySocket.connect(sslEnabled, ProxyAddress(host: host, port: port),
35
+ connectionTimeout: connectionTimeout);
36
}
37
38
RequestNetwork requestNetwork() {
@@ -56,17 +57,17 @@ class ProxyWrapper {
57
58
int getPort() => CakeTor.instance!.port;
59
59
- @Deprecated('Use ProxyWrapper().get/post/put methods instead, and provide proper clearnet and onion uri.')
60
+ @Deprecated(
61
+ 'Use ProxyWrapper().get/post/put methods instead, and provide proper clearnet and onion uri.')
62
HttpClient getHttpClient({int? portOverride, bool internal = false}) {
63
if (!internal) {
64
logger?.log(
63
- uri: null,
64
- method: RequestMethod.newProxySocket,
65
- body: Uint8List(0),
66
- response: null,
67
- network: requestNetwork(),
68
- error: null
69
- );
65
+ uri: null,
66
+ method: RequestMethod.newProxySocket,
67
+ body: Uint8List(0),
68
+ response: null,
69
+ network: requestNetwork(),
70
+ error: null);
71
}
72
if (CakeTor.instance!.started) {
73
// Assign connection factory.
@@ -84,8 +85,6 @@ class ProxyWrapper {
85
}
86
}
87
87
-
88
-
88
Future<Response> _make({
89
required RequestMethod method,
90
required ioc.IOClient client,
@@ -216,7 +215,6 @@ class ProxyWrapper {
215
216
throw Exception("Unable to connect to server");
217
}
219
-
218
219
Future<Response> post({
220
Map<String, String>? headers,
@@ -235,7 +233,6 @@ class ProxyWrapper {
233
234
ioc.IOClient clearnetClient = ioc.IOClient(cleatnetHttpClient);
235
238
-
236
bool torEnabled = CakeTor.instance!.started;
237
238
if (torEnabled) {
@@ -439,7 +436,6 @@ class ProxyWrapper {
436
}
437
}
438
442
-
439
class CakeTor {
440
static CakeTorInstance? instance;
441
}
cw_core/lib/utils/tor/abstract.dart
+1
-1
@@ -65,4 +65,4 @@ CakeTorInstance(
65
)
66
""";
67
}
68
-}
\ No newline at end of file
68
+}
cw_core/lib/utils/tor/disabled.dart
+1
-1
@@ -30,4 +30,4 @@ CakeTorDisabled(
30
)
31
""";
32
}
33
-}
\ No newline at end of file
33
+}
cw_core/lib/utils/tor/socks.dart
+1
-1
@@ -31,4 +31,4 @@ CakeTorSocks(
31
)
32
""";
33
}
34
-}
\ No newline at end of file
34
+}
cw_core/lib/utils/tor/torch.dart
+1
-1
@@ -88,4 +88,4 @@ CakeTorTorch(
88
)
89
""";
90
}
91
-}
\ No newline at end of file
91
+}
cw_core/lib/utils/zpub.dart
+11
-11
@@ -1,4 +1,3 @@
1
-
1
import 'dart:typed_data';
2
3
import 'package:blockchain_utils/blockchain_utils.dart';
@@ -15,31 +14,32 @@ String convertAnyToXpub(String any) {
14
String convertZpubToXpub(String zpub) {
15
try {
16
final decoded = Base58Decoder.checkDecode(zpub);
18
-
17
+
18
if (decoded.length < 4) {
19
throw ArgumentError('Invalid extended public key length');
20
}
22
-
21
+
22
final versionBytes = decoded.sublist(0, 4);
23
final zpubVersionBytes = [0x04, 0xb2, 0x47, 0x46]; // zpub mainnet version
24
final zpubTestnetVersionBytes = [0x04, 0x5f, 0x1c, 0xf6]; // vpub testnet version
26
-
25
+
26
bool isZpub = listEquals(versionBytes, zpubVersionBytes);
27
bool isVpub = listEquals(versionBytes, zpubTestnetVersionBytes);
29
-
28
+
29
if (!isZpub && !isVpub) {
30
return zpub;
31
}
33
-
34
- final xpubVersionBytes = isZpub ?
35
- [0x04, 0x88, 0xb2, 0x1e] : // xpub mainnet
36
- [0x04, 0x35, 0x87, 0xcf]; // tpub testnet
37
-
32
+
33
+ final xpubVersionBytes = isZpub
34
+ ? [0x04, 0x88, 0xb2, 0x1e]
35
+ : // xpub mainnet
36
+ [0x04, 0x35, 0x87, 0xcf]; // tpub testnet
37
+
38
final newExtendedKey = Uint8List.fromList([
39
...xpubVersionBytes,
40
...decoded.sublist(4),
41
]);
42
-
42
+
43
return Base58Encoder.checkEncode(newExtendedKey);
44
} catch (e) {
45
throw ArgumentError('Failed to convert zpub to xpub: $e');
cw_core/lib/wallet_info.dart
+120
-122
@@ -327,79 +327,77 @@ class DerivationInfo {
327
328
class WalletInfo {
329
WalletInfo(
330
- this.internalId,
331
- this.id,
332
- this.name,
333
- this.type,
334
- this.isRecovery,
335
- this.restoreHeight,
336
- this.timestamp,
337
- this.dirPath,
338
- this.path,
339
- this.address,
340
- this.yatEid,
341
- this.yatLastUsedAddressRaw,
342
- this.showIntroCakePayCard,
343
- this.derivationInfoId,
344
- this.hardwareWalletType,
345
- this.parentAddress,
346
- this.hashedWalletIdentifier,
347
- this.isNonSeedWallet,
348
- this.sortOrder,
349
- this.addressPageType,
350
- this.receiveInfoboxDismissed,
351
- this.showCombinedBalance,
352
- this.favoriteTokenAddress
353
- ) : _yatLastUsedAddressController = StreamController<String>.broadcast();
354
-
355
- factory WalletInfo.external({
356
- required String id,
357
- required String name,
358
- required WalletType type,
359
- required bool isRecovery,
360
- required int restoreHeight,
361
- required DateTime date,
362
- required String dirPath,
363
- required String path,
364
- required String address,
365
- bool? showIntroCakePayCard,
366
- String yatEid = '',
367
- String yatLastUsedAddressRaw = '',
368
- int? derivationInfoId,
369
- HardwareWalletType? hardwareWalletType,
370
- String? parentAddress,
371
- String? hashedWalletIdentifier,
372
- bool? isNonSeedWallet,
373
- int? sortOrder,
374
- bool? receiveInfoboxDismissed,
375
- bool? showCombinedBalance,
376
- String? favoriteTokenAddress
377
- }) {
330
+ this.internalId,
331
+ this.id,
332
+ this.name,
333
+ this.type,
334
+ this.isRecovery,
335
+ this.restoreHeight,
336
+ this.timestamp,
337
+ this.dirPath,
338
+ this.path,
339
+ this.address,
340
+ this.yatEid,
341
+ this.yatLastUsedAddressRaw,
342
+ this.showIntroCakePayCard,
343
+ this.derivationInfoId,
344
+ this.hardwareWalletType,
345
+ this.parentAddress,
346
+ this.hashedWalletIdentifier,
347
+ this.isNonSeedWallet,
348
+ this.sortOrder,
349
+ this.addressPageType,
350
+ this.receiveInfoboxDismissed,
351
+ this.showCombinedBalance,
352
+ this.favoriteTokenAddress)
353
+ : _yatLastUsedAddressController = StreamController<String>.broadcast();
354
+
355
+ factory WalletInfo.external(
356
+ {required String id,
357
+ required String name,
358
+ required WalletType type,
359
+ required bool isRecovery,
360
+ required int restoreHeight,
361
+ required DateTime date,
362
+ required String dirPath,
363
+ required String path,
364
+ required String address,
365
+ bool? showIntroCakePayCard,
366
+ String yatEid = '',
367
+ String yatLastUsedAddressRaw = '',
368
+ int? derivationInfoId,
369
+ HardwareWalletType? hardwareWalletType,
370
+ String? parentAddress,
371
+ String? hashedWalletIdentifier,
372
+ bool? isNonSeedWallet,
373
+ int? sortOrder,
374
+ bool? receiveInfoboxDismissed,
375
+ bool? showCombinedBalance,
376
+ String? favoriteTokenAddress}) {
377
return WalletInfo(
379
- 0,
380
- id,
381
- name,
382
- type,
383
- isRecovery,
384
- restoreHeight,
385
- date.millisecondsSinceEpoch,
386
- dirPath,
387
- path,
388
- address,
389
- yatEid,
390
- yatLastUsedAddressRaw,
391
- showIntroCakePayCard,
392
- derivationInfoId ?? -1,
393
- hardwareWalletType,
394
- parentAddress,
395
- hashedWalletIdentifier,
396
- isNonSeedWallet ?? false,
397
- sortOrder ?? 0,
398
- null,
399
- receiveInfoboxDismissed ?? false,
400
- showCombinedBalance ?? true,
401
- favoriteTokenAddress
402
- );
378
+ 0,
379
+ id,
380
+ name,
381
+ type,
382
+ isRecovery,
383
+ restoreHeight,
384
+ date.millisecondsSinceEpoch,
385
+ dirPath,
386
+ path,
387
+ address,
388
+ yatEid,
389
+ yatLastUsedAddressRaw,
390
+ showIntroCakePayCard,
391
+ derivationInfoId ?? -1,
392
+ hardwareWalletType,
393
+ parentAddress,
394
+ hashedWalletIdentifier,
395
+ isNonSeedWallet ?? false,
396
+ sortOrder ?? 0,
397
+ null,
398
+ receiveInfoboxDismissed ?? false,
399
+ showCombinedBalance ?? true,
400
+ favoriteTokenAddress);
401
}
402
403
static String get tableName => 'walletInfo';
@@ -565,59 +563,59 @@ class WalletInfo {
563
StreamController<String> _yatLastUsedAddressController;
564
565
Map<String, dynamic> toJson() => {
568
- selfIdColumn: internalId,
569
- "id": id,
570
- "name": name,
571
- "type": type.index,
572
- "isRecovery": isRecovery ? 1 : 0,
573
- "restoreHeight": restoreHeight,
574
- "timestamp": timestamp,
575
- "dirPath": dirPath,
576
- "path": path,
577
- "address": address,
578
- "yatEid": yatEid,
579
- "yatLastUsedAddressRaw": yatLastUsedAddressRaw,
580
- "showIntroCakePayCard": showIntroCakePayCard == true ? 1 : 0, // SQL regression: null -> false
581
- "walletInfoDerivationInfoId": derivationInfoId,
582
- "hardwareWalletType": hardwareWalletType?.index,
583
- "parentAddress": parentAddress,
584
- "hashedWalletIdentifier": hashedWalletIdentifier,
585
- "isNonSeedWallet": isNonSeedWallet ? 1 : 0,
586
- "sortOrder": sortOrder,
587
- "addressPageType": addressPageType,
588
- "receiveInfoboxDismissed": receiveInfoboxDismissed ? 1 : 0,
589
- "showCombinedBalance": showCombinedBalance ? 1 : 0,
590
- "favoriteTokenAddress": favoriteTokenAddress
591
- };
566
+ selfIdColumn: internalId,
567
+ "id": id,
568
+ "name": name,
569
+ "type": type.index,
570
+ "isRecovery": isRecovery ? 1 : 0,
571
+ "restoreHeight": restoreHeight,
572
+ "timestamp": timestamp,
573
+ "dirPath": dirPath,
574
+ "path": path,
575
+ "address": address,
576
+ "yatEid": yatEid,
577
+ "yatLastUsedAddressRaw": yatLastUsedAddressRaw,
578
+ "showIntroCakePayCard":
579
+ showIntroCakePayCard == true ? 1 : 0, // SQL regression: null -> false
580
+ "walletInfoDerivationInfoId": derivationInfoId,
581
+ "hardwareWalletType": hardwareWalletType?.index,
582
+ "parentAddress": parentAddress,
583
+ "hashedWalletIdentifier": hashedWalletIdentifier,
584
+ "isNonSeedWallet": isNonSeedWallet ? 1 : 0,
585
+ "sortOrder": sortOrder,
586
+ "addressPageType": addressPageType,
587
+ "receiveInfoboxDismissed": receiveInfoboxDismissed ? 1 : 0,
588
+ "showCombinedBalance": showCombinedBalance ? 1 : 0,
589
+ "favoriteTokenAddress": favoriteTokenAddress
590
+ };
591
592
factory WalletInfo.fromJson(Map<String, dynamic> json) {
593
return WalletInfo(
595
- json[selfIdColumn] as int,
596
- json['id'] as String,
597
- json['name'] as String,
598
- WalletType.values[json['type'] as int],
599
- (json['isRecovery'] as int) == 1,
600
- json['restoreHeight'] as int,
601
- json['timestamp'] as int,
602
- json['dirPath'] as String,
603
- json['path'] as String,
604
- json['address'] as String,
605
- json['yatEid'] as String?,
606
- json['yatLastUsedAddressRaw'] as String?,
607
- (json['showIntroCakePayCard'] as int) == 1,
608
- json['walletInfoDerivationInfoId'] as int,
609
- json['hardwareWalletType'] == null
610
- ? null
611
- : HardwareWalletType.values[json['hardwareWalletType'] as int],
612
- json['parentAddress'] as String?,
613
- json['hashedWalletIdentifier'] as String?,
614
- (json['isNonSeedWallet'] as int) == 1,
615
- json['sortOrder'] as int? ?? 0,
616
- json['addressPageType'] as String? ?? null,
617
- json['receiveInfoboxDismissed'] != 0,
618
- json["showCombinedBalance"] != 0,
619
- json["favoriteTokenAddress"] as String? ?? null
620
- );
594
+ json[selfIdColumn] as int,
595
+ json['id'] as String,
596
+ json['name'] as String,
597
+ WalletType.values[json['type'] as int],
598
+ (json['isRecovery'] as int) == 1,
599
+ json['restoreHeight'] as int,
600
+ json['timestamp'] as int,
601
+ json['dirPath'] as String,
602
+ json['path'] as String,
603
+ json['address'] as String,
604
+ json['yatEid'] as String?,
605
+ json['yatLastUsedAddressRaw'] as String?,
606
+ (json['showIntroCakePayCard'] as int) == 1,
607
+ json['walletInfoDerivationInfoId'] as int,
608
+ json['hardwareWalletType'] == null
609
+ ? null
610
+ : HardwareWalletType.values[json['hardwareWalletType'] as int],
611
+ json['parentAddress'] as String?,
612
+ json['hashedWalletIdentifier'] as String?,
613
+ (json['isNonSeedWallet'] as int) == 1,
614
+ json['sortOrder'] as int? ?? 0,
615
+ json['addressPageType'] as String? ?? null,
616
+ json['receiveInfoboxDismissed'] != 0,
617
+ json["showCombinedBalance"] != 0,
618
+ json["favoriteTokenAddress"] as String? ?? null);
619
}
620
621
Future<int> save() async {
cw_core/lib/wallet_info_legacy.dart
+1
-1
@@ -201,7 +201,7 @@ class WalletInfo extends HiveObject {
201
202
// @HiveField(22)
203
String? parentAddress;
204
-
204
+
205
// @HiveField(23)
206
List<String>? hiddenAddresses;
207
cw_core/lib/wallet_info_legacy.part.dart
+5
-11
@@ -53,9 +53,7 @@ class DerivationInfoAdapter extends TypeAdapter<DerivationInfo> {
53
@override
54
bool operator ==(Object other) =>
55
identical(this, other) ||
56
- other is DerivationInfoAdapter &&
57
- runtimeType == other.runtimeType &&
58
- typeId == other.typeId;
56
+ other is DerivationInfoAdapter && runtimeType == other.runtimeType && typeId == other.typeId;
57
}
58
59
class WalletInfoAdapter extends TypeAdapter<WalletInfo> {
@@ -88,8 +86,8 @@ class WalletInfoAdapter extends TypeAdapter<WalletInfo> {
86
fields[26] == null ? false : fields[26] as bool,
87
)
88
..addresses = (fields[10] as Map?)?.cast<String, String>()
91
- ..addressInfos = (fields[14] as Map?)?.map((dynamic k, dynamic v) =>
92
- MapEntry(k as int, (v as List).cast<AddressInfo>()))
89
+ ..addressInfos = (fields[14] as Map?)
90
+ ?.map((dynamic k, dynamic v) => MapEntry(k as int, (v as List).cast<AddressInfo>()))
91
..usedAddresses = (fields[15] as List?)?.cast<String>()
92
..derivationType = fields[16] as newWi.DerivationType?
93
..derivationPath = fields[17] as String?
@@ -163,9 +161,7 @@ class WalletInfoAdapter extends TypeAdapter<WalletInfo> {
161
@override
162
bool operator ==(Object other) =>
163
identical(this, other) ||
166
- other is WalletInfoAdapter &&
167
- runtimeType == other.runtimeType &&
168
- typeId == other.typeId;
164
+ other is WalletInfoAdapter && runtimeType == other.runtimeType && typeId == other.typeId;
165
}
166
167
class DerivationTypeAdapter extends TypeAdapter<newWi.DerivationType> {
@@ -217,9 +213,7 @@ class DerivationTypeAdapter extends TypeAdapter<newWi.DerivationType> {
213
@override
214
bool operator ==(Object other) =>
215
identical(this, other) ||
220
- other is DerivationTypeAdapter &&
221
- runtimeType == other.runtimeType &&
222
- typeId == other.typeId;
216
+ other is DerivationTypeAdapter && runtimeType == other.runtimeType && typeId == other.typeId;
217
}
218
219
class HardwareWalletTypeAdapter extends TypeAdapter<newWi.HardwareWalletType> {
cw_core/lib/wallet_keys_file.dart
+8
-1
@@ -101,7 +101,14 @@ class WalletKeysData {
101
final String? scanSecret;
102
final String? spendPubkey;
103
104
- WalletKeysData({this.privateKey, this.mnemonic, this.altMnemonic, this.passphrase, this.xPub, this.scanSecret, this.spendPubkey});
104
+ WalletKeysData(
105
+ {this.privateKey,
106
+ this.mnemonic,
107
+ this.altMnemonic,
108
+ this.passphrase,
109
+ this.xPub,
110
+ this.scanSecret,
111
+ this.spendPubkey});
112
113
String toJSON() => jsonEncode({
114
"privateKey": privateKey,
cw_core/lib/wallet_type.dart
+13
-12
@@ -334,17 +334,18 @@ WalletType? _cryptoCurrencyToWalletType(CryptoCurrency type) {
334
335
WalletType? cryptoCurrencyOrTokenToWalletType(CryptoCurrency type) {
336
try {
337
- if(type.tag == CryptoCurrency.bnb.tag) {
338
- return _cryptoCurrencyToWalletType(CryptoCurrency.bnb);
339
- }
340
-
341
- if(type.tag != null && ![CryptoCurrency.btcln.tag, CryptoCurrency.bnb.tag].contains(type.tag)) {
342
- return _cryptoCurrencyToWalletType(CryptoCurrency.fromString(type.tag!));
343
- } else {
344
- return _cryptoCurrencyToWalletType(type);
337
+ if (type.tag == CryptoCurrency.bnb.tag) {
338
+ return _cryptoCurrencyToWalletType(CryptoCurrency.bnb);
339
+ }
340
+
341
+ if (type.tag != null &&
342
+ ![CryptoCurrency.btcln.tag, CryptoCurrency.bnb.tag].contains(type.tag)) {
343
+ return _cryptoCurrencyToWalletType(CryptoCurrency.fromString(type.tag!));
344
+ } else {
345
+ return _cryptoCurrencyToWalletType(type);
346
+ }
347
+ } catch (e) {
348
+ printV(e);
349
+ return null;
350
}
346
-} catch (e) {
347
- printV(e);
348
- return null;
349
-}
351
}
cw_core/lib/wallet_type.part.dart
+1
-3
@@ -130,7 +130,5 @@ class WalletTypeAdapter extends TypeAdapter<WalletType> {
130
@override
131
bool operator ==(Object other) =>
132
identical(this, other) ||
133
- other is WalletTypeAdapter &&
134
- runtimeType == other.runtimeType &&
135
- typeId == other.typeId;
133
+ other is WalletTypeAdapter && runtimeType == other.runtimeType && typeId == other.typeId;
134
}
cw_core/lib/wownero_amount_format.dart
+1
-1
@@ -15,4 +15,4 @@ double wowneroAmountToDouble({required int amount}) =>
15
cryptoAmountToDouble(amount: amount, divider: wowneroAmountDivider);
16
17
int wowneroParseAmount({required String amount}) =>
18
- (double.parse(amount) * wowneroAmountDivider).round();
\ No newline at end of file
18
+ (double.parse(amount) * wowneroAmountDivider).round();
cw_core/lib/zano_asset.part.dart
+1
-3
@@ -70,7 +70,5 @@ class ZanoAssetAdapter extends TypeAdapter<ZanoAsset> {
70
@override
71
bool operator ==(Object other) =>
72
identical(this, other) ||
73
- other is ZanoAssetAdapter &&
74
- runtimeType == other.runtimeType &&
75
- typeId == other.typeId;
73
+ other is ZanoAssetAdapter && runtimeType == other.runtimeType && typeId == other.typeId;
74
}
cw_core/test/amount/amount_sanitizer_test.dart
+5
-5
@@ -3,27 +3,27 @@ import 'package:flutter_test/flutter_test.dart';
3
4
void main() {
5
group('smartAmountSanitizer', () {
6
- test('sanitize decimal dot', (){
6
+ test('sanitize decimal dot', () {
7
final amount = "1,000.00".sanitized();
8
expect(amount, "1000.00");
9
});
10
11
- test('sanitize decimal comma', (){
11
+ test('sanitize decimal comma', () {
12
final amount = "1.000,00".sanitized();
13
expect(amount, "1000.00");
14
});
15
16
- test('general case', (){
16
+ test('general case', () {
17
final amount = "1000.00".sanitized();
18
expect(amount, "1000.00");
19
});
20
21
- test('no decimals', (){
21
+ test('no decimals', () {
22
final amount = "1,000".sanitized();
23
expect(amount, "1.000");
24
});
25
26
- test('no decimals', (){
26
+ test('no decimals', () {
27
final amount = "1.000".sanitized();
28
expect(amount, "1.000");
29
});
cw_core/test/amount/money_test.dart
+2
-2
@@ -316,7 +316,7 @@ void main() {
316
});
317
});
318
319
- group("toStringWithPrecision", (){
319
+ group("toStringWithPrecision", () {
320
test("with fractionalDigits and padded with zeros", () {
321
final money = Money.parse("1", CryptoCurrency.btc);
322
expect(money.amount, equals(BigInt.parse("100000000")));
@@ -332,7 +332,7 @@ void main() {
332
});
333
});
334
335
- group("toStringWithSymbol", (){
335
+ group("toStringWithSymbol", () {
336
test("with fractionalDigits and padded with zeros", () {
337
final money = Money.parse("1", CryptoCurrency.btc);
338
expect(money.amount, equals(BigInt.parse("100000000")));
cw_core/test/crypto_amount_format.dart
+3
-3
@@ -35,7 +35,7 @@ void main() {
35
group('String.withLocalSeperator', () {
36
group('Locale en_US', () {
37
const locale = 'en_US';
38
-
38
+
39
test('should not have a grouping separator', () {
40
final input = '123.45';
41
final result = input.withLocalSeperator(locale);
@@ -57,10 +57,10 @@ void main() {
57
expect(result, equals('1,000,000.4567'));
58
});
59
});
60
-
60
+
61
group('Locale de_DE', () {
62
const locale = 'de_DE';
63
-
63
+
64
test('should not have a grouping separator', () {
65
final input = '123.45';
66
final result = input.withLocalSeperator(locale);
cw_core/test/format_fixed_test.dart
+4
-8
@@ -14,14 +14,12 @@ void main() {
14
group('formatFixed, different fractional digits and trimming zeros', () {
15
test(
16
'should format 1000001 into 1',
17
- () => expect(
18
- formatFixed(BigInt.parse("1000001"), 6, fractionalDigits: 5), '1'),
17
+ () => expect(formatFixed(BigInt.parse("1000001"), 6, fractionalDigits: 5), '1'),
18
);
19
20
test(
21
'should format 1000000 into 1, fractionalDigits > decimals',
23
- () => expect(
24
- formatFixed(BigInt.parse("1000000"), 6, fractionalDigits: 12), '1'),
22
+ () => expect(formatFixed(BigInt.parse("1000000"), 6, fractionalDigits: 12), '1'),
23
);
24
25
test(
@@ -45,8 +43,7 @@ void main() {
43
test(
44
'should format 1000001 into 1.00000',
45
() => expect(
48
- formatFixed(BigInt.parse("1000001"), 6,
49
- fractionalDigits: 5, trimZeros: false),
46
+ formatFixed(BigInt.parse("1000001"), 6, fractionalDigits: 5, trimZeros: false),
47
'1.00000',
48
),
49
);
@@ -54,8 +51,7 @@ void main() {
51
test(
52
'should format 1000000 into 1.000000',
53
() => expect(
57
- formatFixed(BigInt.parse("1000000"), 6,
58
- fractionalDigits: 12, trimZeros: false),
54
+ formatFixed(BigInt.parse("1000000"), 6, fractionalDigits: 12, trimZeros: false),
55
'1.000000',
56
),
57
);
cw_core/test/lnurl_test.dart
+18
-9
@@ -39,49 +39,58 @@ void main() {
39
40
group("isBolt11ZeroInvoice", () {
41
test("should identify a zero amount invoice", () {
42
- final invoice = "lnbc1p5564y8pp5vm48jp3w82yjssrtdhvrjacwwzp59hqjm2lq6fud5thfznyuswgqsp54mykkptx9mlqhpe93f9pcgt9p5ml5xhclyn7qsltqy9ldf25j3qqxqyz5vqnp4qvyndeaqzman7h898jxm98dzkm0mlrsx36s93smrur7h0azyyuxc5rzjqwghf7zxvfkxq5a6sr65g0gdkv768p83mhsnt0msszapamzx2qvuxqqqqrt49lmtcqqqqqqqqqqq86qq9qrzjq25carzepgd4vqsyn44jrk85ezrpju92xyrk9apw4cdjh6yrwt5jgqqqqrt49lmtcqqqqqqqqqqq86qq9qrzjqfvmpdwfesckajzfcf7ff2vqaz9jdgpcsa9xc0fq8ny749dy8y5geapyqr6zgqqqq8hxk2qqae4jsqyugqcqzpgdqq9qyyssqycdyx8r09wgm8vny3n8pf2e0crcdq9mgx3ncxvzsrkljxyrcuwx8zjtje7du40nzdy7x2he67v9asp6ac6ed75r33yyt9pzeepygcmsptc4ve4";
42
+ final invoice =
43
+ "lnbc1p5564y8pp5vm48jp3w82yjssrtdhvrjacwwzp59hqjm2lq6fud5thfznyuswgqsp54mykkptx9mlqhpe93f9pcgt9p5ml5xhclyn7qsltqy9ldf25j3qqxqyz5vqnp4qvyndeaqzman7h898jxm98dzkm0mlrsx36s93smrur7h0azyyuxc5rzjqwghf7zxvfkxq5a6sr65g0gdkv768p83mhsnt0msszapamzx2qvuxqqqqrt49lmtcqqqqqqqqqqq86qq9qrzjq25carzepgd4vqsyn44jrk85ezrpju92xyrk9apw4cdjh6yrwt5jgqqqqrt49lmtcqqqqqqqqqqq86qq9qrzjqfvmpdwfesckajzfcf7ff2vqaz9jdgpcsa9xc0fq8ny749dy8y5geapyqr6zgqqqq8hxk2qqae4jsqyugqcqzpgdqq9qyyssqycdyx8r09wgm8vny3n8pf2e0crcdq9mgx3ncxvzsrkljxyrcuwx8zjtje7du40nzdy7x2he67v9asp6ac6ed75r33yyt9pzeepygcmsptc4ve4";
44
expect(isBolt11ZeroInvoice(invoice), true);
45
});
46
47
test("should identify a non zero amount invoice", () {
47
- final invoice = "lnbc1u1p5564nxpp5mrklx2pjaggkcfs9r5tfk84wszzy9gypcnrt9yjq7n6uf95s70xqsp59fph78twjra598n2mll2arw5enluy7a4uf4y9a94ddd30hm98njsxq9z0rgqnp4qvyndeaqzman7h898jxm98dzkm0mlrsx36s93smrur7h0azyyuxc5rzjqwghf7zxvfkxq5a6sr65g0gdkv768p83mhsnt0msszapamzx2qvuxqqqqrt49lmtcqqqqqqqqqqq86qq9qrzjq25carzepgd4vqsyn44jrk85ezrpju92xyrk9apw4cdjh6yrwt5jgqqqqrt49lmtcqqqqqqqqqqq86qq9qcqzpgdql2djkuepqw3hjqsmpddjjq4mpd3kx2aq9qyyssq3nf60ey9fgkf0elu2y8j96rx5pm4gx2a976h8yadx83dyg0ltnysrxhep8e2p3yvz4kf597qk3rttgdy72wwqq0mwr8hdht3pqpchyqq0aa9v0";
48
+ final invoice =
49
+ "lnbc1u1p5564nxpp5mrklx2pjaggkcfs9r5tfk84wszzy9gypcnrt9yjq7n6uf95s70xqsp59fph78twjra598n2mll2arw5enluy7a4uf4y9a94ddd30hm98njsxq9z0rgqnp4qvyndeaqzman7h898jxm98dzkm0mlrsx36s93smrur7h0azyyuxc5rzjqwghf7zxvfkxq5a6sr65g0gdkv768p83mhsnt0msszapamzx2qvuxqqqqrt49lmtcqqqqqqqqqqq86qq9qrzjq25carzepgd4vqsyn44jrk85ezrpju92xyrk9apw4cdjh6yrwt5jgqqqqrt49lmtcqqqqqqqqqqq86qq9qcqzpgdql2djkuepqw3hjqsmpddjjq4mpd3kx2aq9qyyssq3nf60ey9fgkf0elu2y8j96rx5pm4gx2a976h8yadx83dyg0ltnysrxhep8e2p3yvz4kf597qk3rttgdy72wwqq0mwr8hdht3pqpchyqq0aa9v0";
50
expect(isBolt11ZeroInvoice(invoice), false);
51
});
52
53
test("should identify a zero amount prefixed invoice", () {
52
- final invoice = "lightning:lnbc1p5564y8pp5vm48jp3w82yjssrtdhvrjacwwzp59hqjm2lq6fud5thfznyuswgqsp54mykkptx9mlqhpe93f9pcgt9p5ml5xhclyn7qsltqy9ldf25j3qqxqyz5vqnp4qvyndeaqzman7h898jxm98dzkm0mlrsx36s93smrur7h0azyyuxc5rzjqwghf7zxvfkxq5a6sr65g0gdkv768p83mhsnt0msszapamzx2qvuxqqqqrt49lmtcqqqqqqqqqqq86qq9qrzjq25carzepgd4vqsyn44jrk85ezrpju92xyrk9apw4cdjh6yrwt5jgqqqqrt49lmtcqqqqqqqqqqq86qq9qrzjqfvmpdwfesckajzfcf7ff2vqaz9jdgpcsa9xc0fq8ny749dy8y5geapyqr6zgqqqq8hxk2qqae4jsqyugqcqzpgdqq9qyyssqycdyx8r09wgm8vny3n8pf2e0crcdq9mgx3ncxvzsrkljxyrcuwx8zjtje7du40nzdy7x2he67v9asp6ac6ed75r33yyt9pzeepygcmsptc4ve4";
54
+ final invoice =
55
+ "lightning:lnbc1p5564y8pp5vm48jp3w82yjssrtdhvrjacwwzp59hqjm2lq6fud5thfznyuswgqsp54mykkptx9mlqhpe93f9pcgt9p5ml5xhclyn7qsltqy9ldf25j3qqxqyz5vqnp4qvyndeaqzman7h898jxm98dzkm0mlrsx36s93smrur7h0azyyuxc5rzjqwghf7zxvfkxq5a6sr65g0gdkv768p83mhsnt0msszapamzx2qvuxqqqqrt49lmtcqqqqqqqqqqq86qq9qrzjq25carzepgd4vqsyn44jrk85ezrpju92xyrk9apw4cdjh6yrwt5jgqqqqrt49lmtcqqqqqqqqqqq86qq9qrzjqfvmpdwfesckajzfcf7ff2vqaz9jdgpcsa9xc0fq8ny749dy8y5geapyqr6zgqqqq8hxk2qqae4jsqyugqcqzpgdqq9qyyssqycdyx8r09wgm8vny3n8pf2e0crcdq9mgx3ncxvzsrkljxyrcuwx8zjtje7du40nzdy7x2he67v9asp6ac6ed75r33yyt9pzeepygcmsptc4ve4";
56
expect(isBolt11ZeroInvoice(invoice), true);
57
});
58
59
test("should identify a non zero amount prefixed invoice", () {
57
- final invoice = "lightning:lnbc1u1p5564nxpp5mrklx2pjaggkcfs9r5tfk84wszzy9gypcnrt9yjq7n6uf95s70xqsp59fph78twjra598n2mll2arw5enluy7a4uf4y9a94ddd30hm98njsxq9z0rgqnp4qvyndeaqzman7h898jxm98dzkm0mlrsx36s93smrur7h0azyyuxc5rzjqwghf7zxvfkxq5a6sr65g0gdkv768p83mhsnt0msszapamzx2qvuxqqqqrt49lmtcqqqqqqqqqqq86qq9qrzjq25carzepgd4vqsyn44jrk85ezrpju92xyrk9apw4cdjh6yrwt5jgqqqqrt49lmtcqqqqqqqqqqq86qq9qcqzpgdql2djkuepqw3hjqsmpddjjq4mpd3kx2aq9qyyssq3nf60ey9fgkf0elu2y8j96rx5pm4gx2a976h8yadx83dyg0ltnysrxhep8e2p3yvz4kf597qk3rttgdy72wwqq0mwr8hdht3pqpchyqq0aa9v0";
60
+ final invoice =
61
+ "lightning:lnbc1u1p5564nxpp5mrklx2pjaggkcfs9r5tfk84wszzy9gypcnrt9yjq7n6uf95s70xqsp59fph78twjra598n2mll2arw5enluy7a4uf4y9a94ddd30hm98njsxq9z0rgqnp4qvyndeaqzman7h898jxm98dzkm0mlrsx36s93smrur7h0azyyuxc5rzjqwghf7zxvfkxq5a6sr65g0gdkv768p83mhsnt0msszapamzx2qvuxqqqqrt49lmtcqqqqqqqqqqq86qq9qrzjq25carzepgd4vqsyn44jrk85ezrpju92xyrk9apw4cdjh6yrwt5jgqqqqrt49lmtcqqqqqqqqqqq86qq9qcqzpgdql2djkuepqw3hjqsmpddjjq4mpd3kx2aq9qyyssq3nf60ey9fgkf0elu2y8j96rx5pm4gx2a976h8yadx83dyg0ltnysrxhep8e2p3yvz4kf597qk3rttgdy72wwqq0mwr8hdht3pqpchyqq0aa9v0";
62
expect(isBolt11ZeroInvoice(invoice), false);
63
});
64
});
65
66
group("getBolt11Amount", () {
67
test("should identify a zero amount invoice", () {
64
- final invoice = "lnbc1p5564y8pp5vm48jp3w82yjssrtdhvrjacwwzp59hqjm2lq6fud5thfznyuswgqsp54mykkptx9mlqhpe93f9pcgt9p5ml5xhclyn7qsltqy9ldf25j3qqxqyz5vqnp4qvyndeaqzman7h898jxm98dzkm0mlrsx36s93smrur7h0azyyuxc5rzjqwghf7zxvfkxq5a6sr65g0gdkv768p83mhsnt0msszapamzx2qvuxqqqqrt49lmtcqqqqqqqqqqq86qq9qrzjq25carzepgd4vqsyn44jrk85ezrpju92xyrk9apw4cdjh6yrwt5jgqqqqrt49lmtcqqqqqqqqqqq86qq9qrzjqfvmpdwfesckajzfcf7ff2vqaz9jdgpcsa9xc0fq8ny749dy8y5geapyqr6zgqqqq8hxk2qqae4jsqyugqcqzpgdqq9qyyssqycdyx8r09wgm8vny3n8pf2e0crcdq9mgx3ncxvzsrkljxyrcuwx8zjtje7du40nzdy7x2he67v9asp6ac6ed75r33yyt9pzeepygcmsptc4ve4";
68
+ final invoice =
69
+ "lnbc1p5564y8pp5vm48jp3w82yjssrtdhvrjacwwzp59hqjm2lq6fud5thfznyuswgqsp54mykkptx9mlqhpe93f9pcgt9p5ml5xhclyn7qsltqy9ldf25j3qqxqyz5vqnp4qvyndeaqzman7h898jxm98dzkm0mlrsx36s93smrur7h0azyyuxc5rzjqwghf7zxvfkxq5a6sr65g0gdkv768p83mhsnt0msszapamzx2qvuxqqqqrt49lmtcqqqqqqqqqqq86qq9qrzjq25carzepgd4vqsyn44jrk85ezrpju92xyrk9apw4cdjh6yrwt5jgqqqqrt49lmtcqqqqqqqqqqq86qq9qrzjqfvmpdwfesckajzfcf7ff2vqaz9jdgpcsa9xc0fq8ny749dy8y5geapyqr6zgqqqq8hxk2qqae4jsqyugqcqzpgdqq9qyyssqycdyx8r09wgm8vny3n8pf2e0crcdq9mgx3ncxvzsrkljxyrcuwx8zjtje7du40nzdy7x2he67v9asp6ac6ed75r33yyt9pzeepygcmsptc4ve4";
70
expect(getBolt11Amount(invoice), null);
71
});
72
73
test("should get the amount 1 BTC encoded as bitcoin", () {
69
- final invoice = "lnbc11p5exaxspp5u6e6lx90rw2vqr2e5axt8ur3v98qnmqfsmh8r0l0mcm7ry70vyvsdqqcqzzsxqrrsssp5eqydmrufk39dwhuxzajwx4xyffn0mlcu3qa8vjwry6qev5gsepkq9qxpqysgqt0zldve9uxt3txjt8wp0gev52lquljgugy26nneue85pjwk5yak4hs2d8533tus07pq5ka6zrnd0ruaeepwres8p7ws5mx63xlwff5sqlxcy8a";
74
+ final invoice =
75
+ "lnbc11p5exaxspp5u6e6lx90rw2vqr2e5axt8ur3v98qnmqfsmh8r0l0mcm7ry70vyvsdqqcqzzsxqrrsssp5eqydmrufk39dwhuxzajwx4xyffn0mlcu3qa8vjwry6qev5gsepkq9qxpqysgqt0zldve9uxt3txjt8wp0gev52lquljgugy26nneue85pjwk5yak4hs2d8533tus07pq5ka6zrnd0ruaeepwres8p7ws5mx63xlwff5sqlxcy8a";
76
expect(getBolt11Amount(invoice), Money.fromInt(100000000, CryptoCurrency.btcln));
77
});
78
79
test("should get the amount 0,1 BTC encoded as millibitcoin", () {
74
- final invoice = "lnbc100m1p5exagmpp5n4c5tml3h8h7k4gthc9papkyeymceqqvcldkng4nvxwzj7nu9jnsdqqcqzzsxqrrsssp58kgzrh7y3pevantduc4yg33aa6r79ed6xgmhr0dy40zc8pxrz5ms9qxpqysgqcq27km3v3wcz6pntmsfnz259zy6tff0uwjz9kamdrvmxmdv09gp44mh0ygn7gweqf4zdev4x8e67p5kcvahethchdkkjexhtk7emuqcpasz0lp";
80
+ final invoice =
81
+ "lnbc100m1p5exagmpp5n4c5tml3h8h7k4gthc9papkyeymceqqvcldkng4nvxwzj7nu9jnsdqqcqzzsxqrrsssp58kgzrh7y3pevantduc4yg33aa6r79ed6xgmhr0dy40zc8pxrz5ms9qxpqysgqcq27km3v3wcz6pntmsfnz259zy6tff0uwjz9kamdrvmxmdv09gp44mh0ygn7gweqf4zdev4x8e67p5kcvahethchdkkjexhtk7emuqcpasz0lp";
82
expect(getBolt11Amount(invoice), Money.fromInt(10000000, CryptoCurrency.btcln));
83
});
84
85
test("should get the amount 1000 SATS encoded as microbitcoin", () {
79
- final invoice = "lnbc10u1p5exfgvpp5n3s9dsw9ddax5c3h8437ya7y4g582uyufyna626yr9vqdfjrhwzqdqqcqzzsxqrrsssp5mmkyp5h35fpaxm4063f3kc7d4nmgd4gd8fv8086wxd784m76kmpq9qxpqysgqye9r0vahpjy9l2je6vakxzk3cjnsyx76r29c4amkz4cmapq5tqt5l7rl0emkd003jjvz2d8jqrw6wc4cduvapuyeseh7a855l82wutcpeq30kg";
86
+ final invoice =
87
+ "lnbc10u1p5exfgvpp5n3s9dsw9ddax5c3h8437ya7y4g582uyufyna626yr9vqdfjrhwzqdqqcqzzsxqrrsssp5mmkyp5h35fpaxm4063f3kc7d4nmgd4gd8fv8086wxd784m76kmpq9qxpqysgqye9r0vahpjy9l2je6vakxzk3cjnsyx76r29c4amkz4cmapq5tqt5l7rl0emkd003jjvz2d8jqrw6wc4cduvapuyeseh7a855l82wutcpeq30kg";
88
expect(getBolt11Amount(invoice), Money.fromInt(1000, CryptoCurrency.btcln));
89
});
90
91
test("should get the amount 1 SAT encoded as nanobitcoin", () {
84
- final invoice = "lnbc10n1p5exazppp5szh273r6nzvwydzsdlg0ws0vhxwnc6nqtqt4sjt0vu6x6l8t5csqdqqcqzzsxqrrsssp5nkup6uht7xlfqaj8lxpe5kx0ejum9p4pvv3nlnndr9ykzge3393s9qxpqysgqufh05a7qs0ezeckvmh7tjkr9ngng96nq274twg20z45ysp7afpdrttm2ky73cpjwpjqsmtzzd79w6lyvszgmkanwn8mj0jcfunrwv3qprg3z3j";
92
+ final invoice =
93
+ "lnbc10n1p5exazppp5szh273r6nzvwydzsdlg0ws0vhxwnc6nqtqt4sjt0vu6x6l8t5csqdqqcqzzsxqrrsssp5nkup6uht7xlfqaj8lxpe5kx0ejum9p4pvv3nlnndr9ykzge3393s9qxpqysgqufh05a7qs0ezeckvmh7tjkr9ngng96nq274twg20z45ysp7afpdrttm2ky73cpjwpjqsmtzzd79w6lyvszgmkanwn8mj0jcfunrwv3qprg3z3j";
94
expect(getBolt11Amount(invoice), Money.fromInt(1, CryptoCurrency.btcln));
95
});
96
});
cw_custom_lints/lib/http_force_proxy/http_force_proxy_rule.dart
+1
-2
@@ -51,8 +51,7 @@ class _Visitor extends SimpleAstVisitor<void> {
51
52
if (uriString.startsWith("package:http")) {
53
final prefixNode = node.prefix;
54
- if (prefixNode != null &&
55
- prefixNode.name == "very_insecure_http_do_not_use") {
54
+ if (prefixNode != null && prefixNode.name == "very_insecure_http_do_not_use") {
55
return;
56
}
57
cw_custom_lints/lib/print_verbose/print_verbose_fix.dart
+1
-2
@@ -17,8 +17,7 @@ class ReplaceWithPrintV extends ResolvedCorrectionProducer {
17
);
18
19
@override
20
- CorrectionApplicability get applicability =>
21
- CorrectionApplicability.singleLocation;
20
+ CorrectionApplicability get applicability => CorrectionApplicability.singleLocation;
21
22
@override
23
FixKind get fixKind => _fixKind;
cw_dogecoin/lib/cw_dogecoin.dart
-1
@@ -3,4 +3,3 @@ export 'src/dogecoin_wallet_addresses.dart';
3
export 'src/dogecoin_wallet_creation_credentials.dart';
4
export 'src/dogecoin_wallet_service.dart';
5
export 'src/dogecoin_transaction_priority.dart';
6
-
cw_dogecoin/lib/src/dogecoin_transaction_priority.dart
+3
-4
@@ -7,11 +7,11 @@ class DogecoinTransactionPriority extends BitcoinTransactionPriority {
7
8
static const List<DogecoinTransactionPriority> all = [fast, medium, slow];
9
static const DogecoinTransactionPriority slow =
10
- DogecoinTransactionPriority(title: 'Slow', raw: 0);
10
+ DogecoinTransactionPriority(title: 'Slow', raw: 0);
11
static const DogecoinTransactionPriority medium =
12
- DogecoinTransactionPriority(title: 'Medium', raw: 1);
12
+ DogecoinTransactionPriority(title: 'Medium', raw: 1);
13
static const DogecoinTransactionPriority fast =
14
- DogecoinTransactionPriority(title: 'Fast', raw: 2);
14
+ DogecoinTransactionPriority(title: 'Fast', raw: 2);
15
16
static DogecoinTransactionPriority deserialize({required int raw}) {
17
switch (raw) {
@@ -53,4 +53,3 @@ class DogecoinTransactionPriority extends BitcoinTransactionPriority {
53
return label;
54
}
55
}
56
-
cw_dogecoin/lib/src/dogecoin_wallet.dart
+1
-2
@@ -75,14 +75,13 @@ abstract class DogeCoinWalletBase extends ElectrumWallet with Store {
75
76
@override
77
int feeAmountForPriority(TransactionPriority priority, int inputsCount, int outputsCount,
78
- {int? size}) =>
78
+ {int? size}) =>
79
feeRate(priority) * (size ?? estimatedDogeCoinTransactionSize(inputsCount, outputsCount));
80
81
@override
82
int feeAmountWithFeeRate(int feeRate, int inputsCount, int outputsCount, {int? size}) =>
83
feeRate * (size ?? estimatedDogeCoinTransactionSize(inputsCount, outputsCount));
84
85
-
85
static Future<DogeCoinWallet> create(
86
{required String mnemonic,
87
required String password,
cw_dogecoin/lib/src/dogecoin_wallet_addresses.dart
+3
-6
@@ -8,11 +8,9 @@ import 'package:mobx/mobx.dart';
8
9
part 'dogecoin_wallet_addresses.g.dart';
10
11
-class DogeCoinWalletAddresses = DogeCoinWalletAddressesBase
12
- with _$DogeCoinWalletAddresses;
11
+class DogeCoinWalletAddresses = DogeCoinWalletAddressesBase with _$DogeCoinWalletAddresses;
12
14
-abstract class DogeCoinWalletAddressesBase extends ElectrumWalletAddresses
15
- with Store {
13
+abstract class DogeCoinWalletAddressesBase extends ElectrumWalletAddresses with Store {
14
DogeCoinWalletAddressesBase(
15
WalletInfo walletInfo, {
16
required super.mainHdByType,
@@ -36,6 +34,5 @@ abstract class DogeCoinWalletAddressesBase extends ElectrumWalletAddresses
34
generateP2PKHAddress(hd: hd, index: index, network: network);
35
36
@override
39
- PaymentURI getPaymentUri(String amount) =>
40
- DogeURI(address: address, amount: amount);
37
+ PaymentURI getPaymentUri(String amount) => DogeURI(address: address, amount: amount);
38
}
cw_dogecoin/test/cw_dogecoin_test.dart
+1
-2
@@ -3,6 +3,5 @@ import 'package:flutter_test/flutter_test.dart';
3
import 'package:cw_dogecoin/cw_dogecoin.dart';
4
5
void main() {
6
- test('adds one to input values', () {
7
- });
6
+ test('adds one to input values', () {});
7
}
cw_evm/lib/clients/arbitrum_client.dart
-1
@@ -43,4 +43,3 @@ class ArbitrumClient extends EVMChainClient {
43
@override
44
int get chainId => 42161;
45
}
46
-
cw_evm/lib/clients/base_client.dart
-1
@@ -43,4 +43,3 @@ class BaseClient extends EVMChainClient {
43
@override
44
int get chainId => 8453;
45
}
46
-
cw_evm/lib/clients/bsc_client.dart
-1
@@ -44,4 +44,3 @@ class BSCClient extends EVMChainClient {
44
@override
45
int get chainId => 56;
46
}
47
-
cw_evm/lib/clients/ethereum_client.dart
-1
@@ -10,4 +10,3 @@ class EthereumClient extends EVMChainClient {
10
Uint8List prepareSignedTransactionForSending(Uint8List signedTransaction) =>
11
prependTransactionType(0x02, signedTransaction);
12
}
13
-
cw_evm/lib/clients/evm_chain_client.dart
+9
-6
@@ -145,7 +145,9 @@ class EVMChainClient {
145
146
final jsonResponse = json.decode(response.body) as Map<String, dynamic>;
147
148
- if (response.statusCode >= 200 && response.statusCode < 300 && jsonResponse['status'] != 0 &&
148
+ if (response.statusCode >= 200 &&
149
+ response.statusCode < 300 &&
150
+ jsonResponse['status'] != 0 &&
151
jsonResponse['result'] is List) {
152
final symbol = EVMChainUtils.getFeeCurrency(chainId);
153
@@ -520,9 +522,11 @@ class EVMChainClient {
522
*/
523
}
524
523
- Future<EVMChainERC20Balance> fetchERC20Balances(EthereumAddress userAddress, Erc20Token token) async {
525
+ Future<EVMChainERC20Balance> fetchERC20Balances(
526
+ EthereumAddress userAddress, Erc20Token token) async {
527
try {
525
- final erc20 = ERC20(address: EthereumAddress.fromHex(token.contractAddress), client: _client!);
528
+ final erc20 =
529
+ ERC20(address: EthereumAddress.fromHex(token.contractAddress), client: _client!);
530
final balance = await erc20.balanceOf(userAddress);
531
532
return EVMChainERC20Balance(Money(balance, token));
@@ -659,9 +663,8 @@ class EVMChainClient {
663
final tokenData = item;
664
665
final nativeRaw = tokenData['native_token'];
662
- final nativeToken = nativeRaw is bool
663
- ? nativeRaw
664
- : (nativeRaw?.toString().toLowerCase() == 'true');
666
+ final nativeToken =
667
+ nativeRaw is bool ? nativeRaw : (nativeRaw?.toString().toLowerCase() == 'true');
668
if (nativeToken) continue;
669
670
final balanceStr = tokenData['balance'] as String? ?? '0';
cw_evm/lib/clients/polygon_client.dart
-1
@@ -43,4 +43,3 @@ class PolygonClient extends EVMChainClient {
43
@override
44
int get chainId => 137;
45
}
46
-
cw_evm/lib/contract/erc20.dart
+22
-25
@@ -21,10 +21,10 @@ class ERC20 extends web3.GeneratedContract {
21
/// set, the function will be evaluated in the specified block. By default, the
22
/// latest on-chain block will be used.
23
Future<BigInt> allowance(
24
- web3.EthereumAddress owner,
25
- web3.EthereumAddress spender, {
26
- web3.BlockNum? atBlock,
27
- }) async {
24
+ web3.EthereumAddress owner,
25
+ web3.EthereumAddress spender, {
26
+ web3.BlockNum? atBlock,
27
+ }) async {
28
final function = self.abi.functions[0];
29
assert(checkSignature(function, 'dd62ed3e'));
30
final params = [owner, spender];
@@ -38,11 +38,11 @@ class ERC20 extends web3.GeneratedContract {
38
/// like the gas price, nonce and max gas. The `data` and `to` fields will be
39
/// set by the contract.
40
Future<Uint8List> approve(
41
- web3.EthereumAddress spender,
42
- BigInt amount, {
43
- required web3.Credentials credentials,
44
- web3.Transaction? transaction,
45
- }) async {
41
+ web3.EthereumAddress spender,
42
+ BigInt amount, {
43
+ required web3.Credentials credentials,
44
+ web3.Transaction? transaction,
45
+ }) async {
46
final function = self.abi.functions[1];
47
assert(checkSignature(function, '095ea7b3'));
48
final params = [spender, amount];
@@ -55,9 +55,9 @@ class ERC20 extends web3.GeneratedContract {
55
/// set, the function will be evaluated in the specified block. By default, the
56
/// latest on-chain block will be used.
57
Future<BigInt> balanceOf(
58
- web3.EthereumAddress account, {
59
- web3.BlockNum? atBlock,
60
- }) async {
58
+ web3.EthereumAddress account, {
59
+ web3.BlockNum? atBlock,
60
+ }) async {
61
final function = self.abi.functions[2];
62
assert(checkSignature(function, '70a08231'));
63
final params = [account];
@@ -123,11 +123,11 @@ class ERC20 extends web3.GeneratedContract {
123
/// like the gas price, nonce and max gas. The `data` and `to` fields will be
124
/// set by the contract.
125
Future<Uint8List> transfer(
126
- web3.EthereumAddress recipient,
127
- BigInt amount, {
128
- required web3.Credentials credentials,
129
- web3.Transaction? transaction,
130
- }) async {
126
+ web3.EthereumAddress recipient,
127
+ BigInt amount, {
128
+ required web3.Credentials credentials,
129
+ web3.Transaction? transaction,
130
+ }) async {
131
final function = self.abi.functions[7];
132
assert(checkSignature(function, 'a9059cbb'));
133
final params = [recipient, amount];
@@ -139,10 +139,9 @@ class ERC20 extends web3.GeneratedContract {
139
/// The optional [transaction] parameter can be used to override parameters
140
/// like the gas price, nonce and max gas. The `data` and `to` fields will be
141
/// set by the contract.
142
- Future<Uint8List> transferFrom(web3.EthereumAddress sender,
143
- web3.EthereumAddress recipient, BigInt amount,
144
- {required web3.Credentials credentials,
145
- web3.Transaction? transaction}) async {
142
+ Future<Uint8List> transferFrom(
143
+ web3.EthereumAddress sender, web3.EthereumAddress recipient, BigInt amount,
144
+ {required web3.Credentials credentials, web3.Transaction? transaction}) async {
145
final function = self.abi.functions[8];
146
assert(checkSignature(function, '23b872dd'));
147
final params = [sender, recipient, amount];
@@ -150,8 +149,7 @@ class ERC20 extends web3.GeneratedContract {
149
}
150
151
/// Returns a live stream of all Approval events emitted by this contract.
153
- Stream<Approval> approvalEvents(
154
- {web3.BlockNum? fromBlock, web3.BlockNum? toBlock}) {
152
+ Stream<Approval> approvalEvents({web3.BlockNum? fromBlock, web3.BlockNum? toBlock}) {
153
final event = self.event('Approval');
154
final filter = web3.FilterOptions.events(
155
contract: self, event: event, fromBlock: fromBlock, toBlock: toBlock);
@@ -162,8 +160,7 @@ class ERC20 extends web3.GeneratedContract {
160
}
161
162
/// Returns a live stream of all Transfer events emitted by this contract.
165
- Stream<Transfer> transferEvents(
166
- {web3.BlockNum? fromBlock, web3.BlockNum? toBlock}) {
163
+ Stream<Transfer> transferEvents({web3.BlockNum? fromBlock, web3.BlockNum? toBlock}) {
164
final event = self.event('Transfer');
165
final filter = web3.FilterOptions.events(
166
contract: self, event: event, fromBlock: fromBlock, toBlock: toBlock);
cw_evm/lib/deuro/deuro_savings.dart
+10
-7
@@ -169,7 +169,8 @@ class DEuro {
169
contractAddress: savings.self.address.hexEip55,
170
receivingAddressHex: savings.self.address.hexEip55,
171
priority: priority,
172
- data: savings.self.abi.functions[24].encodeCall([_address, amount, hexToBytes(frontendCode)]),
172
+ data:
173
+ savings.self.abi.functions[24].encodeCall([_address, amount, hexToBytes(frontendCode)]),
174
);
175
176
sendTransaction() => _wallet.getWeb3Client()!.sendRawTransaction(signedTransaction);
@@ -193,7 +194,8 @@ class DEuro {
194
try {
195
await _checkEthBalanceForGasFees(priority);
196
196
- final signedTransaction = await _savings.refreshBalance((owner: _address),
197
+ final signedTransaction = await _savings.refreshBalance(
198
+ (owner: _address),
199
credentials: _wallet.evmChainPrivateKey,
200
);
201
@@ -228,10 +230,12 @@ class DEuro {
230
await _checkEthBalanceForGasFees(priority);
231
232
return (await _wallet.createApprovalTransaction(
231
- Money(BigInt.parse(
232
- 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
233
- radix: 16,
234
- ), CryptoCurrency.deuro),
233
+ Money(
234
+ BigInt.parse(
235
+ 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
236
+ radix: 16,
237
+ ),
238
+ CryptoCurrency.deuro),
239
_savings.self.address.hexEip55,
240
priority,
241
)) as PendingEVMChainTransaction;
@@ -244,4 +248,3 @@ class DEuro {
248
}
249
}
250
}
247
-
cw_evm/lib/deuro/deuro_savings_contract.dart
+3
-3
@@ -352,9 +352,9 @@ class Savings extends _i1.GeneratedContract {
352
/// set, the function will be evaluated in the specified block. By default, the
353
/// latest on-chain block will be used.
354
Future<SavingsData> savings({
355
- required _i1.EthereumAddress accountOwner,
356
- _i1.BlockNum? atBlock,
357
- }) async {
355
+ required _i1.EthereumAddress accountOwner,
356
+ _i1.BlockNum? atBlock,
357
+ }) async {
358
final function = self.abi.functions[21];
359
assert(checkSignature(function, '1f7cdd5f'));
360
final params = [accountOwner];
cw_evm/lib/deuro/deuro_savings_gateway_contract.dart
+51
-59
@@ -15,13 +15,13 @@ class SavingsGateway extends _i1.GeneratedContract {
15
required _i1.Web3Client client,
16
int? chainId,
17
}) : super(
18
- _i1.DeployedContract(
19
- _contractAbi,
20
- address,
21
- ),
22
- client,
23
- chainId,
24
- );
18
+ _i1.DeployedContract(
19
+ _contractAbi,
20
+ address,
21
+ ),
22
+ client,
23
+ chainId,
24
+ );
25
26
/// The optional [atBlock] parameter can be used to view historical data. When
27
/// set, the function will be evaluated in the specified block. By default, the
@@ -42,9 +42,9 @@ class SavingsGateway extends _i1.GeneratedContract {
42
/// set, the function will be evaluated in the specified block. By default, the
43
/// latest on-chain block will be used.
44
Future<BigInt> accruedInterest({
45
- required _i1.EthereumAddress accountOwner,
46
- _i1.BlockNum? atBlock,
47
- }) async {
45
+ required _i1.EthereumAddress accountOwner,
46
+ _i1.BlockNum? atBlock,
47
+ }) async {
48
final function = self.abi.functions[2];
49
assert(checkSignature(function, '77267ec3'));
50
final params = [accountOwner];
@@ -60,9 +60,9 @@ class SavingsGateway extends _i1.GeneratedContract {
60
/// set, the function will be evaluated in the specified block. By default, the
61
/// latest on-chain block will be used.
62
Future<BigInt> accruedInterest$2(
63
- ({_i1.EthereumAddress accountOwner, BigInt timestamp}) args, {
64
- _i1.BlockNum? atBlock,
65
- }) async {
63
+ ({_i1.EthereumAddress accountOwner, BigInt timestamp}) args, {
64
+ _i1.BlockNum? atBlock,
65
+ }) async {
66
final function = self.abi.functions[3];
67
assert(checkSignature(function, 'a696399d'));
68
final params = [
@@ -81,10 +81,10 @@ class SavingsGateway extends _i1.GeneratedContract {
81
/// like the gas price, nonce and max gas. The `data` and `to` fields will be
82
/// set by the contract.
83
Future<String> adjust(
84
- ({BigInt targetAmount, _i2.Uint8List frontendCode}) args, {
85
- required _i1.Credentials credentials,
86
- _i1.Transaction? transaction,
87
- }) async {
84
+ ({BigInt targetAmount, _i2.Uint8List frontendCode}) args, {
85
+ required _i1.Credentials credentials,
86
+ _i1.Transaction? transaction,
87
+ }) async {
88
final function = self.abi.functions[4];
89
assert(checkSignature(function, '753ef93c'));
90
final params = [
@@ -103,9 +103,9 @@ class SavingsGateway extends _i1.GeneratedContract {
103
/// set, the function will be evaluated in the specified block. By default, the
104
/// latest on-chain block will be used.
105
Future<BigInt> calculateInterest(
106
- ({dynamic account, BigInt ticks}) args, {
107
- _i1.BlockNum? atBlock,
108
- }) async {
106
+ ({dynamic account, BigInt ticks}) args, {
107
+ _i1.BlockNum? atBlock,
108
+ }) async {
109
final function = self.abi.functions[7];
110
assert(checkSignature(function, '7915ce20'));
111
final params = [
@@ -214,10 +214,10 @@ class SavingsGateway extends _i1.GeneratedContract {
214
/// like the gas price, nonce and max gas. The `data` and `to` fields will be
215
/// set by the contract.
216
Future<_i2.Uint8List> refreshBalance(
217
- ({_i1.EthereumAddress owner}) args, {
218
- required _i1.Credentials credentials,
219
- _i1.Transaction? transaction,
220
- }) async {
217
+ ({_i1.EthereumAddress owner}) args, {
218
+ required _i1.Credentials credentials,
219
+ _i1.Transaction? transaction,
220
+ }) async {
221
final function = self.abi.functions[15];
222
assert(checkSignature(function, 'b77cd1c7'));
223
final params = [args.owner];
@@ -251,10 +251,10 @@ class SavingsGateway extends _i1.GeneratedContract {
251
/// like the gas price, nonce and max gas. The `data` and `to` fields will be
252
/// set by the contract.
253
Future<_i2.Uint8List> save(
254
- ({BigInt amount, _i2.Uint8List frontendCode}) args, {
255
- required _i1.Credentials credentials,
256
- _i1.Transaction? transaction,
257
- }) async {
254
+ ({BigInt amount, _i2.Uint8List frontendCode}) args, {
255
+ required _i1.Credentials credentials,
256
+ _i1.Transaction? transaction,
257
+ }) async {
258
final function = self.abi.functions[17];
259
assert(checkSignature(function, '9e2363dc'));
260
final params = [
@@ -273,14 +273,10 @@ class SavingsGateway extends _i1.GeneratedContract {
273
/// like the gas price, nonce and max gas. The `data` and `to` fields will be
274
/// set by the contract.
275
Future<_i2.Uint8List> saveTo(
276
- ({
277
- _i1.EthereumAddress owner,
278
- BigInt amount,
279
- _i2.Uint8List frontendCode
280
- }) args, {
281
- required _i1.Credentials credentials,
282
- _i1.Transaction? transaction,
283
- }) async {
276
+ ({_i1.EthereumAddress owner, BigInt amount, _i2.Uint8List frontendCode}) args, {
277
+ required _i1.Credentials credentials,
278
+ _i1.Transaction? transaction,
279
+ }) async {
280
final function = self.abi.functions[19];
281
assert(checkSignature(function, 'cbcf9676'));
282
final params = [
@@ -300,9 +296,9 @@ class SavingsGateway extends _i1.GeneratedContract {
296
/// set, the function will be evaluated in the specified block. By default, the
297
/// latest on-chain block will be used.
298
Future<Savings> savings({
303
- required _i1.EthereumAddress accountOwner,
304
- _i1.BlockNum? atBlock,
305
- }) async {
299
+ required _i1.EthereumAddress accountOwner,
300
+ _i1.BlockNum? atBlock,
301
+ }) async {
302
final function = self.abi.functions[21];
303
assert(checkSignature(function, '1f7cdd5f'));
304
final params = [accountOwner];
@@ -318,11 +314,7 @@ class SavingsGateway extends _i1.GeneratedContract {
314
/// like the gas price, nonce and max gas. The `data` and `to` fields will be
315
/// set by the contract.
316
Future<_i2.Uint8List> withdraw(
321
- ({
322
- _i1.EthereumAddress target,
323
- BigInt amount,
324
- _i2.Uint8List frontendCode
325
- }) args, {
317
+ ({_i1.EthereumAddress target, BigInt amount, _i2.Uint8List frontendCode}) args, {
318
required _i1.Credentials credentials,
319
_i1.Transaction? transaction,
320
}) async {
@@ -474,9 +466,9 @@ class Savings {
466
467
class InterestCollected {
468
InterestCollected(
477
- List<dynamic> response,
478
- this.event,
479
- ) : account = (response[0] as _i1.EthereumAddress),
469
+ List<dynamic> response,
470
+ this.event,
471
+ ) : account = (response[0] as _i1.EthereumAddress),
472
interest = (response[1] as BigInt);
473
474
final _i1.EthereumAddress account;
@@ -488,9 +480,9 @@ class InterestCollected {
480
481
class RateChanged {
482
RateChanged(
491
- List<dynamic> response,
492
- this.event,
493
- ) : newRate = (response[0] as BigInt);
483
+ List<dynamic> response,
484
+ this.event,
485
+ ) : newRate = (response[0] as BigInt);
486
487
final BigInt newRate;
488
@@ -499,9 +491,9 @@ class RateChanged {
491
492
class RateProposed {
493
RateProposed(
502
- List<dynamic> response,
503
- this.event,
504
- ) : who = (response[0] as _i1.EthereumAddress),
494
+ List<dynamic> response,
495
+ this.event,
496
+ ) : who = (response[0] as _i1.EthereumAddress),
497
nextRate = (response[1] as BigInt),
498
nextChange = (response[2] as BigInt);
499
@@ -516,9 +508,9 @@ class RateProposed {
508
509
class Saved {
510
Saved(
519
- List<dynamic> response,
520
- this.event,
521
- ) : account = (response[0] as _i1.EthereumAddress),
511
+ List<dynamic> response,
512
+ this.event,
513
+ ) : account = (response[0] as _i1.EthereumAddress),
514
amount = (response[1] as BigInt);
515
516
final _i1.EthereumAddress account;
@@ -530,9 +522,9 @@ class Saved {
522
523
class Withdrawn {
524
Withdrawn(
533
- List<dynamic> response,
534
- this.event,
535
- ) : account = (response[0] as _i1.EthereumAddress),
525
+ List<dynamic> response,
526
+ this.event,
527
+ ) : account = (response[0] as _i1.EthereumAddress),
528
amount = (response[1] as BigInt);
529
530
final _i1.EthereumAddress account;
cw_evm/lib/evm_chain_exceptions.dart
+6
-7
@@ -12,15 +12,14 @@ class EVMChainTransactionCreationException implements Exception {
12
String toString() => exceptionMessage;
13
}
14
15
-
15
class EVMChainTransactionFeesException implements Exception {
16
final String exceptionMessage;
17
19
- EVMChainTransactionFeesException(String message)
20
- : exceptionMessage = message;
18
+ EVMChainTransactionFeesException(String message) : exceptionMessage = message;
19
20
EVMChainTransactionFeesException.fromCurrency(String currency)
23
- : exceptionMessage = 'Transaction failed due to insufficient $currency balance to cover the fees.';
21
+ : exceptionMessage =
22
+ 'Transaction failed due to insufficient $currency balance to cover the fees.';
23
24
@override
25
String toString() => exceptionMessage;
@@ -39,15 +38,15 @@ class InsufficientGasFeeException implements Exception {
38
static String _buildMessage(BigInt? requiredGasFee, BigInt? currentBalance) {
39
const baseMessage = 'Insufficient ETH for gas fees.';
40
const addEthMessage = ' Please add ETH to your wallet to cover transaction fees.';
42
-
41
+
42
if (requiredGasFee != null) {
43
final requiredEth = (requiredGasFee / BigInt.from(10).pow(18)).toStringAsFixed(8);
45
- final balanceInfo = currentBalance != null
44
+ final balanceInfo = currentBalance != null
45
? ', Available: ${(currentBalance / BigInt.from(10).pow(18)).toStringAsFixed(8)} ETH'
46
: '';
47
return '$baseMessage Required: ~$requiredEth ETH$balanceInfo.$addEthMessage';
48
}
50
-
49
+
50
return '$baseMessage$addEthMessage';
51
}
52
cw_evm/lib/evm_chain_registry.dart
+1
-2
@@ -233,6 +233,5 @@ class EvmChainRegistry {
233
234
List<ChainConfig> getAllChains() => _chains.values.toList();
235
236
- List<WalletType> getRegisteredWalletTypes() =>
237
- _walletTypeToChainId.keys.toList();
236
+ List<WalletType> getRegisteredWalletTypes() => _walletTypeToChainId.keys.toList();
237
}
cw_evm/lib/evm_chain_transaction_model.dart
+2
-1
@@ -35,7 +35,8 @@ class EVMChainTransactionModel {
35
this.evmSignatureName,
36
});
37
38
- factory EVMChainTransactionModel.fromJson(Map<String, dynamic> json, String defaultSymbol, int chainId) =>
38
+ factory EVMChainTransactionModel.fromJson(
39
+ Map<String, dynamic> json, String defaultSymbol, int chainId) =>
40
EVMChainTransactionModel(
41
date: DateTime.fromMillisecondsSinceEpoch(int.parse(json["timeStamp"]) * 1000),
42
hash: json["hash"] ?? "",
cw_evm/lib/evm_chain_wallet.dart
+4
-11
@@ -561,8 +561,7 @@ abstract class EVMChainWalletBase
561
'distribution',
562
];
563
564
- static final _suspiciousWordPattern =
565
- RegExp(r'\b(bot|claim|reward)\b', caseSensitive: false);
564
+ static final _suspiciousWordPattern = RegExp(r'\b(bot|claim|reward)\b', caseSensitive: false);
565
566
static const _knownNonEvmNativeSymbols = {
567
'ICP',
@@ -630,8 +629,7 @@ abstract class EVMChainWalletBase
629
final prefs = await sharedPrefs.future;
630
if (prefs.getBool(_scamCheckDoneKey) == true) return;
631
633
- final whitelistLower =
634
- getDefaultTokenContractAddresses.map((a) => a.toLowerCase()).toSet();
632
+ final whitelistLower = getDefaultTokenContractAddresses.map((a) => a.toLowerCase()).toSet();
633
final defaultSymbolsUpper =
634
EVMChainDefaultTokens.getDefaultTokenSymbols(selectedChainId).toSet();
635
@@ -1316,16 +1314,12 @@ abstract class EVMChainWalletBase
1314
} else if (newTxInfo.direction == TransactionDirection.incoming &&
1315
existingTxInfo.direction == TransactionDirection.outgoing) {
1316
result[transactionModel.hash] = newTxInfo;
1319
- }
1320
-
1321
- else if (newTxInfo.direction == TransactionDirection.outgoing &&
1317
+ } else if (newTxInfo.direction == TransactionDirection.outgoing &&
1318
existingTxInfo.direction == TransactionDirection.outgoing &&
1319
_hasEvmTokenContractAddress(newTxInfo) &&
1320
!_hasEvmTokenContractAddress(existingTxInfo)) {
1321
result[transactionModel.hash] = newTxInfo;
1326
- }
1327
-
1328
- else if (existingTxInfo.isPending) {
1322
+ } else if (existingTxInfo.isPending) {
1323
result[transactionModel.hash] = newTxInfo;
1324
}
1325
}
@@ -1333,7 +1327,6 @@ abstract class EVMChainWalletBase
1327
return result;
1328
}
1329
1336
-
1330
bool _hasEvmTokenContractAddress(EVMChainTransactionInfo info) {
1331
final c = info.contractAddress;
1332
return c != null && c.isNotEmpty;
cw_evm/lib/evm_chain_wallet_addresses.dart
-1
@@ -23,7 +23,6 @@ abstract class EVMChainWalletAddressesBase extends WalletAddresses with Store {
23
24
final int _selectedChainId;
25
26
-
26
@override
27
Future<void> init() async {
28
address = walletInfo.address;
cw_evm/lib/evm_erc20_balance.dart
+1
-1
@@ -7,7 +7,7 @@ import "package:cw_core/currency.dart";
7
class EVMChainERC20Balance extends Balance {
8
EVMChainERC20Balance(Money balance) : super(balance, Money.zero(balance.currency));
9
10
- String toJSON() => json.encode({ "balanceInWei": available.amount.toString() });
10
+ String toJSON() => json.encode({"balanceInWei": available.amount.toString()});
11
12
static EVMChainERC20Balance? fromJSON(String? jsonSource, Currency currency) {
13
if (jsonSource == null) return null;
cw_evm/lib/hardware/evm_chain_bitbox_service.dart
+2
-3
@@ -11,9 +11,8 @@ class EVMChainBitboxService extends HardwareWalletService {
11
final int chainId;
12
13
@override
14
- Future<List<HardwareAccountData>> getAvailableAccounts(
15
- {int index = 0, int limit = 5}) async {
16
- final accounts = <HardwareAccountData>[];
14
+ Future<List<HardwareAccountData>> getAvailableAccounts({int index = 0, int limit = 5}) async {
15
+ final accounts = <HardwareAccountData>[];
16
final indexRange = List.generate(limit, (i) => i + index);
17
18
for (final i in indexRange) {
cw_evm/lib/hardware/evm_chain_ledger_credentials.dart
+11
-17
@@ -1,8 +1,7 @@
1
import 'dart:async';
2
import 'dart:typed_data';
3
4
-import 'package:cw_core/hardware/device_not_connected_exception.dart'
5
- as exception;
4
+import 'package:cw_core/hardware/device_not_connected_exception.dart' as exception;
5
import 'package:cw_core/utils/print_verbose.dart';
6
import 'package:ledger_ethereum/ledger_ethereum.dart';
7
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart';
@@ -19,15 +18,13 @@ class EvmLedgerCredentials extends CredentialsWithKnownAddress {
18
@override
19
EthereumAddress get address => EthereumAddress.fromHex(_address);
20
22
- Future<void> setLedgerConnection(LedgerConnection connection,
23
- [String? derivationPath]) async {
24
- ethereumLedgerApp = EthereumLedgerApp(connection,
25
- derivationPath: derivationPath ?? "m/44'/60'/0'/0/0");
21
+ Future<void> setLedgerConnection(LedgerConnection connection, [String? derivationPath]) async {
22
+ ethereumLedgerApp =
23
+ EthereumLedgerApp(connection, derivationPath: derivationPath ?? "m/44'/60'/0'/0/0");
24
}
25
26
@override
29
- MsgSignature signToEcSignature(Uint8List payload,
30
- {int? chainId, bool isEIP1559 = false}) =>
27
+ MsgSignature signToEcSignature(Uint8List payload, {int? chainId, bool isEIP1559 = false}) =>
28
throw UnimplementedError("EvmLedgerCredentials.signToEcSignature");
29
30
@override
@@ -65,13 +62,11 @@ class EvmLedgerCredentials extends CredentialsWithKnownAddress {
62
chainIdV = chainId != null ? (parity + (chainId * 2 + 35)) : parity;
63
}
64
68
- return MsgSignature(
69
- BigInt.parse(r, radix: 16), BigInt.parse(s, radix: 16), chainIdV);
65
+ return MsgSignature(BigInt.parse(r, radix: 16), BigInt.parse(s, radix: 16), chainIdV);
66
}
67
68
@override
73
- Future<Uint8List> signPersonalMessage(Uint8List payload,
74
- {int? chainId}) async {
69
+ Future<Uint8List> signPersonalMessage(Uint8List payload, {int? chainId}) async {
70
if (isNotConnected) throw exception.DeviceNotConnectedException();
71
72
final sig = await ethereumLedgerApp!.signMessage(payload);
@@ -88,11 +83,9 @@ class EvmLedgerCredentials extends CredentialsWithKnownAddress {
83
84
@override
85
Uint8List signPersonalMessageToUint8List(Uint8List payload, {int? chainId}) =>
91
- throw UnimplementedError(
92
- "EvmLedgerCredentials.signPersonalMessageToUint8List");
86
+ throw UnimplementedError("EvmLedgerCredentials.signPersonalMessageToUint8List");
87
94
- Future<void> provideERC20Info(
95
- String erc20ContractAddress, int chainId) async {
88
+ Future<void> provideERC20Info(String erc20ContractAddress, int chainId) async {
89
if (isNotConnected) throw exception.DeviceNotConnectedException();
90
91
try {
@@ -105,5 +98,6 @@ class EvmLedgerCredentials extends CredentialsWithKnownAddress {
98
}
99
}
100
108
- bool get isNotConnected => ethereumLedgerApp == null || ethereumLedgerApp!.connection.isDisconnected;
101
+ bool get isNotConnected =>
102
+ ethereumLedgerApp == null || ethereumLedgerApp!.connection.isDisconnected;
103
}
cw_evm/lib/hardware/evm_chain_ledger_service.dart
+2
-4
@@ -11,8 +11,7 @@ class EVMChainLedgerService extends HardwareWalletService {
11
final LedgerConnection ledgerConnection;
12
13
@override
14
- Future<List<HardwareAccountData>> getAvailableAccounts(
15
- {int index = 0, int limit = 5}) async {
14
+ Future<List<HardwareAccountData>> getAvailableAccounts({int index = 0, int limit = 5}) async {
15
final ethereumLedgerApp = EthereumLedgerApp(ledgerConnection);
16
17
await ethereumLedgerApp.getVersion();
@@ -22,8 +21,7 @@ class EVMChainLedgerService extends HardwareWalletService {
21
22
for (final i in indexRange) {
23
final derivationPath = "m/44'/60'/$i'/0/0";
25
- final address = await ethereumLedgerApp.getAccounts(
26
- accountsDerivationPath: derivationPath);
24
+ final address = await ethereumLedgerApp.getAccounts(accountsDerivationPath: derivationPath);
25
26
accounts.add(HardwareAccountData(
27
address: address.first,
cw_evm/lib/tokens/base_tokens.dart
+1
-3
@@ -61,8 +61,7 @@ class BaseTokens {
61
if (token.iconPath?.isEmpty ?? true) {
62
try {
63
iconPath = CryptoCurrency.all
64
- .firstWhere((element) =>
65
- element.title.toUpperCase() == token.symbol.toUpperCase())
64
+ .firstWhere((element) => element.title.toUpperCase() == token.symbol.toUpperCase())
65
.iconPath;
66
} catch (_) {}
67
} else {
@@ -73,4 +72,3 @@ class BaseTokens {
72
}).toList();
73
}
74
}
76
-
cw_evm/lib/tokens/polygon_tokens.dart
+1
-3
@@ -75,8 +75,7 @@ class PolygonTokens {
75
if (token.iconPath?.isEmpty ?? true) {
76
try {
77
iconPath = CryptoCurrency.all
78
- .firstWhere((element) =>
79
- element.title.toUpperCase() == token.symbol.toUpperCase())
78
+ .firstWhere((element) => element.title.toUpperCase() == token.symbol.toUpperCase())
79
.iconPath;
80
} catch (_) {}
81
} else {
@@ -87,4 +86,3 @@ class PolygonTokens {
86
}).toList();
87
}
88
}
90
-
cw_evm/lib/usdt0/usdt0_config.dart
+7
-13
@@ -1,15 +1,13 @@
1
import 'package:cw_core/erc20_token.dart';
2
3
-/// USDT0 (Omnichain USDT) config.
3
+/// USDT0 (Omnichain USDT) config.
4
/// Addresses and EIDs from https://docs.usdt0.to/technical-documentation/deployments
5
class USDT0Config {
6
USDT0Config._();
7
8
- static const String ethereumOftAdapter =
9
- '0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee';
8
+ static const String ethereumOftAdapter = '0x6C96dE32CEa08842dcc4058c14d3aaAD7Fa41dee';
9
11
- static const String ethereumNativeUsdt =
12
- '0xdac17f958d2ee523a2206206994597c13d831ec7';
10
+ static const String ethereumNativeUsdt = '0xdac17f958d2ee523a2206206994597c13d831ec7';
11
12
static const Map<int, String> usdt0TokenAddressByChainId = {
13
1: ethereumNativeUsdt,
@@ -31,24 +29,20 @@ class USDT0Config {
29
30
static const int ethereumChainId = 1;
31
34
- static List<int> get supportedChainIds =>
35
- usdt0TokenAddressByChainId.keys.toList(growable: false);
32
+ static List<int> get supportedChainIds => usdt0TokenAddressByChainId.keys.toList(growable: false);
33
34
static String? getOftAdapterAddress(int chainId) {
35
if (chainId == ethereumChainId) return ethereumOftAdapter;
36
return null;
37
}
38
42
- static String? getUsdt0TokenAddress(int chainId) =>
43
- usdt0TokenAddressByChainId[chainId];
39
+ static String? getUsdt0TokenAddress(int chainId) => usdt0TokenAddressByChainId[chainId];
40
45
- static String? getOftContractAddress(int chainId) =>
46
- oftContractAddressByChainId[chainId];
41
+ static String? getOftContractAddress(int chainId) => oftContractAddressByChainId[chainId];
42
43
static int? getEndpointId(int chainId) => endpointIdByChainId[chainId];
44
50
- static bool isChainSupported(int chainId) =>
51
- usdt0TokenAddressByChainId.containsKey(chainId);
45
+ static bool isChainSupported(int chainId) => usdt0TokenAddressByChainId.containsKey(chainId);
46
47
static bool isUSDT0Token(Erc20Token token, int chainId) {
48
final address = getUsdt0TokenAddress(chainId);
cw_evm/lib/usdt0/usdt0_service.dart
+1
-1
@@ -81,7 +81,7 @@ class USDT0Service {
81
);
82
83
final pendingApproval = await wallet.createApprovalTransaction(
84
- Money(maxUint,token),
84
+ Money(maxUint, token),
85
adapter,
86
priority,
87
useBlinkProtection: useBlinkProtection,
cw_evm/lib/utils/network_chain_utils.dart
-1
@@ -60,4 +60,3 @@ class FeeModel {
60
this.maxPriorityFee,
61
});
62
}
63
-
cw_monero/lib/api/account_list.dart
+1
-1
@@ -39,7 +39,7 @@ void refreshAccounts() {
39
}
40
}
41
42
- List<Wallet2SubaddressAccountRow> getAllAccount() {
42
+List<Wallet2SubaddressAccountRow> getAllAccount() {
43
// final size = monero.Wallet_numSubaddressAccounts(wptr!);
44
refreshAccounts();
45
int size = subaddressAccount!.getAll_size();
cw_monero/lib/api/exceptions/creation_transaction_exception.dart
+2
-2
@@ -1,8 +1,8 @@
1
class CreationTransactionException implements Exception {
2
CreationTransactionException({required this.message});
3
-
3
+
4
final String message;
5
6
@override
7
String toString() => message;
8
-}
\ No newline at end of file
8
+}
cw_monero/lib/api/exceptions/setup_wallet_exception.dart
+2
-2
@@ -1,8 +1,8 @@
1
class SetupWalletException implements Exception {
2
SetupWalletException({required this.message});
3
-
3
+
4
final String message;
5
6
@override
7
String toString() => message;
8
-}
\ No newline at end of file
8
+}
cw_monero/lib/api/exceptions/wallet_creation_exception.dart
+1
-1
@@ -5,4 +5,4 @@ class WalletCreationException implements Exception {
5
6
@override
7
String toString() => message;
8
-}
\ No newline at end of file
8
+}
cw_monero/lib/api/exceptions/wallet_opening_exception.dart
+1
-1
@@ -5,4 +5,4 @@ class WalletOpeningException implements Exception {
5
6
@override
7
String toString() => message;
8
-}
\ No newline at end of file
8
+}
cw_monero/lib/api/exceptions/wallet_restore_from_keys_exception.dart
+2
-2
@@ -1,8 +1,8 @@
1
class WalletRestoreFromKeysException implements Exception {
2
WalletRestoreFromKeysException({required this.message});
3
-
3
+
4
final String message;
5
6
@override
7
String toString() => message;
8
-}
\ No newline at end of file
8
+}
cw_monero/lib/api/exceptions/wallet_restore_from_seed_exception.dart
+2
-2
@@ -1,8 +1,8 @@
1
class WalletRestoreFromSeedException implements Exception {
2
WalletRestoreFromSeedException({required this.message});
3
-
3
+
4
final String message;
5
6
@override
7
String toString() => message;
8
-}
\ No newline at end of file
8
+}
cw_monero/lib/api/monero_output.dart
+1
-1
@@ -3,4 +3,4 @@ class MoneroOutput {
3
4
final String address;
5
final String amount;
6
-}
\ No newline at end of file
6
+}
cw_monero/lib/api/structs/pending_transaction.dart
+7
-8
@@ -1,15 +1,14 @@
1
-
1
class PendingTransactionDescription {
3
- PendingTransactionDescription({
4
- required this.amount,
5
- required this.fee,
6
- required this.hash,
7
- required this.hex,
8
- required this.pointerAddress});
2
+ PendingTransactionDescription(
3
+ {required this.amount,
4
+ required this.fee,
5
+ required this.hash,
6
+ required this.hex,
7
+ required this.pointerAddress});
8
9
final int amount;
10
final int fee;
11
final String hash;
12
final String hex;
13
final int pointerAddress;
15
-}
\ No newline at end of file
14
+}
cw_monero/lib/api/subaddress_list.dart
+18
-14
@@ -1,4 +1,3 @@
1
-
1
import 'package:cw_monero/api/account_list.dart';
2
import 'package:cw_monero/api/transaction_history.dart';
3
import 'package:cw_monero/api/wallet.dart';
@@ -16,7 +15,9 @@ class SubaddressInfoMetadata {
15
SubaddressInfoMetadata? subaddress = null;
16
17
String getRawLabel({required int accountIndex, required int addressIndex}) {
19
- return currentWallet?.getSubaddressLabel(accountIndex: accountIndex, addressIndex: addressIndex)??"";
18
+ return currentWallet?.getSubaddressLabel(
19
+ accountIndex: accountIndex, addressIndex: addressIndex) ??
20
+ "";
21
}
22
23
void refreshSubaddresses({required int accountIndex}) {
@@ -46,8 +47,11 @@ class Subaddress {
47
final int received;
48
final int txCount;
49
String get label {
49
- final localLabel = currentWallet?.getSubaddressLabel(accountIndex: accountIndex, addressIndex: addressIndex) ?? "";
50
- if (localLabel.startsWith("#$addressIndex")) return localLabel; // don't duplicate the ID if it was user-providen
50
+ final localLabel =
51
+ currentWallet?.getSubaddressLabel(accountIndex: accountIndex, addressIndex: addressIndex) ??
52
+ "";
53
+ if (localLabel.startsWith("#$addressIndex"))
54
+ return localLabel; // don't duplicate the ID if it was user-providen
55
return "#$addressIndex ${localLabel}".trim();
56
}
57
}
@@ -97,7 +101,7 @@ Future<List<Subaddress>> getAllSubaddresses() async {
101
final list = List.generate(size, (index) {
102
final ttDetailsLocal = ttDetails.where((element) {
103
final address = getAddress(
100
- accountIndex: subaddress!.accountIndex,
104
+ accountIndex: subaddress!.accountIndex,
105
addressIndex: index,
106
);
107
if (element.address.contains(address)) return true;
@@ -115,13 +119,12 @@ Future<List<Subaddress>> getAllSubaddresses() async {
119
);
120
}).reversed.toList();
121
if (list.length == 0) {
118
- list.add(
119
- Subaddress(
120
- addressIndex: subaddress!.accountIndex,
121
- accountIndex: 0,
122
- received: 0,
123
- txCount: 0,
124
- ));
122
+ list.add(Subaddress(
123
+ addressIndex: subaddress!.accountIndex,
124
+ accountIndex: 0,
125
+ received: 0,
126
+ txCount: 0,
127
+ ));
128
}
129
return list;
130
}
@@ -138,6 +141,7 @@ Future<void> addSubaddress({required int accountIndex, required String label}) a
141
142
Future<void> setLabelForSubaddress(
143
{required int accountIndex, required int addressIndex, required String label}) async {
141
- currentWallet?.setSubaddressLabel(accountIndex: accountIndex, addressIndex: addressIndex, label: label);
144
+ currentWallet?.setSubaddressLabel(
145
+ accountIndex: accountIndex, addressIndex: addressIndex, label: label);
146
await store();
143
-}
\ No newline at end of file
147
+}
cw_monero/lib/api/transaction_history.dart
+60
-60
@@ -16,7 +16,6 @@ import 'package:monero/src/wallet2.dart';
16
import 'package:monero/src/generated_bindings_monero.g.dart' as monero_gen;
17
import 'package:mutex/mutex.dart';
18
19
-
19
String _formatTransactionError(String error) {
20
final message = error.replaceAll(
21
RegExp(
@@ -68,7 +67,7 @@ int countOfTransactions() => txhistory!.count();
67
68
Future<List<Transaction>> getAllTransactions() async {
69
List<Transaction> dummyTxs = [];
71
-
70
+
71
await txHistoryMutex.acquire();
72
txhistory ??= currentWallet!.history();
73
final startAddress = txhistory!.ffiAddress() * currentWallet!.ffiAddress();
@@ -91,29 +90,29 @@ Future<List<Transaction>> getAllTransactions() async {
90
}
91
txHistoryMutex.release();
92
final accts = currentWallet!.numSubaddressAccounts();
94
- for (var i = 0; i < accts; i++) {
93
+ for (var i = 0; i < accts; i++) {
94
final fullBalance = currentWallet!.balance(accountIndex: i);
95
final availBalance = currentWallet!.unlockedBalance(accountIndex: i);
96
if (fullBalance > availBalance) {
98
- if (list.where((element) => element.accountIndex == i && element.isConfirmed == false).isEmpty) {
99
- dummyTxs.add(
100
- Transaction.dummy(
101
- displayLabel: "",
102
- description: "",
103
- fee: 0,
104
- confirmations: 0,
105
- blockheight: 0,
106
- accountIndex: i,
107
- addressIndex: 0,
108
- addressIndexList: [0],
109
- paymentId: "",
110
- amount: fullBalance - availBalance,
111
- isSpend: false,
112
- hash: "pending",
113
- key: "",
114
- txInfo: DummyTransaction(),
115
- )..timeStamp = DateTime.now()
116
- );
97
+ if (list
98
+ .where((element) => element.accountIndex == i && element.isConfirmed == false)
99
+ .isEmpty) {
100
+ dummyTxs.add(Transaction.dummy(
101
+ displayLabel: "",
102
+ description: "",
103
+ fee: 0,
104
+ confirmations: 0,
105
+ blockheight: 0,
106
+ accountIndex: i,
107
+ addressIndex: 0,
108
+ addressIndexList: [0],
109
+ paymentId: "",
110
+ amount: fullBalance - availBalance,
111
+ isSpend: false,
112
+ hash: "pending",
113
+ key: "",
114
+ txInfo: DummyTransaction(),
115
+ )..timeStamp = DateTime.now());
116
}
117
}
118
}
@@ -128,7 +127,8 @@ class DummyTransaction implements Wallet2TransactionInfo {
127
128
Map<int, Map<String, Transaction>> txCache = {};
129
Future<Transaction> getTransaction(String txId) async {
131
- if (txCache[currentWallet!.ffiAddress()] != null && txCache[currentWallet!.ffiAddress()]![txId] != null) {
130
+ if (txCache[currentWallet!.ffiAddress()] != null &&
131
+ txCache[currentWallet!.ffiAddress()]![txId] != null) {
132
return txCache[currentWallet!.ffiAddress()]![txId]!;
133
}
134
await txHistoryMutex.acquire();
@@ -147,7 +147,6 @@ Future<PendingTransactionDescription> createTransactionSync(
147
String? amount,
148
int accountIndex = 0,
149
List<String> preferredInputs = const []}) async {
150
-
150
final amt = amount == null ? 0 : currentWallet!.amountFromString(amount);
151
152
final waddr = currentWallet!.ffiAddress();
@@ -158,10 +157,11 @@ Future<PendingTransactionDescription> createTransactionSync(
157
monero.Wallet_synchronized(Pointer.fromAddress(waddr));
158
});
159
161
- final address_ = address.toNativeUtf8();
160
+ final address_ = address.toNativeUtf8();
161
final paymentId_ = paymentId.toNativeUtf8();
162
if (preferredInputs.isEmpty) {
164
- throw MoneroTransactionCreationException("No inputs provided, transaction cannot be constructed");
163
+ throw MoneroTransactionCreationException(
164
+ "No inputs provided, transaction cannot be constructed");
165
}
166
167
final preferredInputs_ = preferredInputs.join(monero.defaultSeparatorStr).toNativeUtf8();
@@ -171,7 +171,8 @@ Future<PendingTransactionDescription> createTransactionSync(
171
final preferredInputsAddr = preferredInputs_.address;
172
final spaddr = monero.defaultSeparator.address;
173
final pendingTxPtr = Pointer<Void>.fromAddress(await Isolate.run(() {
174
- final tx = monero_gen.MoneroC(DynamicLibrary.open(monero.libPath)).MONERO_Wallet_createTransaction(
174
+ final tx =
175
+ monero_gen.MoneroC(DynamicLibrary.open(monero.libPath)).MONERO_Wallet_createTransaction(
176
Pointer.fromAddress(waddr),
177
Pointer.fromAddress(addraddr).cast(),
178
Pointer.fromAddress(paymentIdAddr).cast(),
@@ -206,12 +207,12 @@ Future<PendingTransactionDescription> createTransactionSync(
207
final rHex = pendingTx.hex('');
208
209
return PendingTransactionDescription(
209
- amount: rAmt,
210
- fee: rFee,
211
- hash: rHash,
212
- hex: rHex,
213
- pointerAddress: pendingTx.ffiAddress(),
214
- );
210
+ amount: rAmt,
211
+ fee: rFee,
212
+ hash: rHash,
213
+ hex: rHex,
214
+ pointerAddress: pendingTx.ffiAddress(),
215
+ );
216
}
217
218
Future<PendingTransactionDescription> createTransactionMultDest(
@@ -220,7 +221,6 @@ Future<PendingTransactionDescription> createTransactionMultDest(
221
required int priorityRaw,
222
int accountIndex = 0,
223
List<String> preferredInputs = const []}) async {
223
-
224
final dstAddrs = outputs.map((e) => e.address).toList();
225
final amounts = outputs.map((e) => currentWallet!.amountFromString(e.amount)).toList();
226
@@ -261,7 +261,8 @@ Future<PendingTransactionDescription> createTransactionMultDest(
261
Future<String?> commitTransactionFromPointerAddress({required int address, required bool useUR}) =>
262
commitTransaction(tx: MoneroPendingTransaction(Pointer.fromAddress(address)), useUR: useUR);
263
264
-Future<String?> commitTransaction({required Wallet2PendingTransaction tx, required bool useUR}) async {
264
+Future<String?> commitTransaction(
265
+ {required Wallet2PendingTransaction tx, required bool useUR}) async {
266
final txCommit = useUR
267
? tx.commitUR(120)
268
: await Isolate.run(() {
@@ -288,7 +289,6 @@ Future<String?> commitTransaction({required Wallet2PendingTransaction tx, requir
289
}
290
return currentWallet!.errorString();
291
})();
291
-
292
}
293
if (error != null && error != "no tx keys found for this txid") {
294
throw CreationTransactionException(message: _formatTransactionError(error));
@@ -311,11 +311,12 @@ class Transaction {
311
accountIndex: accountIndex,
312
addressIndex: addressIndex,
313
);
314
- late final List<String> addressList = List.generate(addressIndexList.length, (index) =>
315
- getAddress(
316
- accountIndex: accountIndex,
317
- addressIndex: addressIndexList[index],
318
- ));
314
+ late final List<String> addressList = List.generate(
315
+ addressIndexList.length,
316
+ (index) => getAddress(
317
+ accountIndex: accountIndex,
318
+ addressIndex: addressIndexList[index],
319
+ ));
320
final String description;
321
final int fee;
322
final int confirmations;
@@ -364,33 +365,32 @@ class Transaction {
365
timeStamp = DateTime.fromMillisecondsSinceEpoch(
366
txInfo.timestamp() * 1000,
367
),
367
- isSpend = txInfo.direction() ==
368
- monero.TransactionInfo_Direction.Out.index,
368
+ isSpend = txInfo.direction() == monero.TransactionInfo_Direction.Out.index,
369
amount = txInfo.amount(),
370
paymentId = txInfo.paymentId(),
371
accountIndex = txInfo.subaddrAccount(),
372
addressIndex = int.tryParse(txInfo.subaddrIndex().split(", ")[0]) ?? 0,
373
- addressIndexList = txInfo.subaddrIndex().split(", ").map((e) => int.tryParse(e) ?? 0).toList(),
373
+ addressIndexList =
374
+ txInfo.subaddrIndex().split(", ").map((e) => int.tryParse(e) ?? 0).toList(),
375
blockheight = txInfo.blockHeight(),
376
confirmations = txInfo.confirmations(),
377
fee = txInfo.fee(),
378
description = txInfo.description(),
379
key = getTxKey(txInfo.hash());
380
380
- Transaction.dummy({
381
- required this.displayLabel,
382
- required this.description,
383
- required this.fee,
384
- required this.confirmations,
385
- required this.blockheight,
386
- required this.accountIndex,
387
- required this.addressIndexList,
388
- required this.addressIndex,
389
- required this.paymentId,
390
- required this.amount,
391
- required this.isSpend,
392
- required this.hash,
393
- required this.key,
394
- required this.txInfo
395
- });
381
+ Transaction.dummy(
382
+ {required this.displayLabel,
383
+ required this.description,
384
+ required this.fee,
385
+ required this.confirmations,
386
+ required this.blockheight,
387
+ required this.accountIndex,
388
+ required this.addressIndexList,
389
+ required this.addressIndex,
390
+ required this.paymentId,
391
+ required this.amount,
392
+ required this.isSpend,
393
+ required this.hash,
394
+ required this.key,
395
+ required this.txInfo});
396
}
cw_monero/lib/api/wallet.dart
+31
-28
@@ -44,8 +44,7 @@ String getFilename() => currentWallet!.filename();
44
45
String getSeed() {
46
// monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed);
47
- final cakepolyseed =
48
- currentWallet!.getCacheAttribute(key: "cakewallet.seed");
47
+ final cakepolyseed = currentWallet!.getCacheAttribute(key: "cakewallet.seed");
48
final cakepassphrase = getPassphrase();
49
50
final weirdPolyseed = currentWallet!.getPolyseed(passphrase: cakepassphrase);
@@ -69,7 +68,7 @@ String getSeed() {
68
69
final bip39 = currentWallet!.getCacheAttribute(key: "cakewallet.seed.bip39");
70
72
- if(bip39.isNotEmpty) return bip39;
71
+ if (bip39.isNotEmpty) return bip39;
72
73
final legacy = getSeedLegacy(null);
74
return legacy;
@@ -77,11 +76,21 @@ String getSeed() {
76
77
String? getSeedLanguage(String? language) {
78
switch (language) {
80
- case "Chinese (Traditional)": language = "Chinese (simplified)"; break;
81
- case "Chinese (Simplified)": language = "Chinese (simplified)"; break;
82
- case "Korean": language = "English"; break;
83
- case "Czech": language = "English"; break;
84
- case "Japanese": language = "English"; break;
79
+ case "Chinese (Traditional)":
80
+ language = "Chinese (simplified)";
81
+ break;
82
+ case "Chinese (Simplified)":
83
+ language = "Chinese (simplified)";
84
+ break;
85
+ case "Korean":
86
+ language = "English";
87
+ break;
88
+ case "Czech":
89
+ language = "English";
90
+ break;
91
+ case "Japanese":
92
+ language = "English";
93
+ break;
94
}
95
return language;
96
}
@@ -132,7 +141,7 @@ String getAddress({int accountIndex = 0, int addressIndex = 0}) {
141
142
// printV("getaddress: ${accountIndex}/${addressIndex}: ${monero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex)}: ${monero.Wallet_address(wptr!, accountIndex: accountIndex, addressIndex: addressIndex)}");
143
// this could be a while loop, but I'm in favor of making it if to not cause freezes
135
- if (currentWallet!.numSubaddresses(accountIndex: accountIndex)-1 < addressIndex) {
144
+ if (currentWallet!.numSubaddresses(accountIndex: accountIndex) - 1 < addressIndex) {
145
if (currentWallet!.numSubaddressAccounts() < accountIndex) {
146
currentWallet!.addSubaddressAccount();
147
} else {
@@ -141,8 +150,8 @@ String getAddress({int accountIndex = 0, int addressIndex = 0}) {
150
}
151
addressCache[currentWallet!.ffiAddress()] ??= {};
152
addressCache[currentWallet!.ffiAddress()]![accountIndex] ??= {};
144
- addressCache[currentWallet!.ffiAddress()]![accountIndex]![addressIndex] ??= currentWallet!.address(
145
- accountIndex: accountIndex, addressIndex: addressIndex);
153
+ addressCache[currentWallet!.ffiAddress()]![accountIndex]![addressIndex] ??=
154
+ currentWallet!.address(accountIndex: accountIndex, addressIndex: addressIndex);
155
return addressCache[currentWallet!.ffiAddress()]![accountIndex]![addressIndex]!;
156
}
157
@@ -154,7 +163,6 @@ Money getUnlockedBalance({int accountIndex = 0}) => Money.fromInt(
163
164
int getCurrentHeight() => currentWallet?.blockChainHeight() ?? 0;
165
157
-
166
int cachedNodeHeight = 0;
167
bool isHeightRefreshing = false;
168
int getNodeHeightSync() {
@@ -238,10 +246,8 @@ void startRefreshSync() {
246
currentWallet!.startRefresh();
247
}
248
241
-
249
void setRefreshFromBlockHeight({required int height}) {
243
- currentWallet!.setRefreshFromBlockHeight(
244
- refresh_from_block_height: height);
250
+ currentWallet!.setRefreshFromBlockHeight(refresh_from_block_height: height);
251
}
252
253
void setRecoveringFromSeed({required bool isRecovery}) {
@@ -251,7 +257,6 @@ void setRecoveringFromSeed({required bool isRecovery}) {
257
258
final storeMutex = Mutex();
259
254
-
260
int lastStorePointer = 0;
261
int lastStoreHeight = 0;
262
void storeSync({bool force = false}) async {
@@ -261,7 +266,7 @@ void storeSync({bool force = false}) async {
266
});
267
if (lastStorePointer == addr &&
268
lastStoreHeight + 75000 > currentWallet!.blockChainHeight() &&
264
- !synchronized &&
269
+ !synchronized &&
270
!force) {
271
return;
272
}
@@ -300,8 +305,8 @@ class SyncListener {
305
: _cachedBlockchainHeight = 0,
306
_lastKnownBlockHeight = 0,
307
_initialSyncHeight = 0 {
303
- _start();
304
- }
308
+ _start();
309
+ }
310
311
void Function(int, int, double) onNewBlock;
312
void Function() onNewTransaction;
@@ -323,8 +328,7 @@ class SyncListener {
328
_cachedBlockchainHeight = 0;
329
_lastKnownBlockHeight = 0;
330
_initialSyncHeight = 0;
326
- _updateSyncInfoTimer ??=
327
- Timer.periodic(Duration(milliseconds: 1200), (_) async {
331
+ _updateSyncInfoTimer ??= Timer.periodic(Duration(milliseconds: 1200), (_) async {
332
if (isNewTransactionExist()) {
333
onNewTransaction();
334
}
@@ -370,8 +374,8 @@ class SyncListener {
374
void stop() => _updateSyncInfoTimer?.cancel();
375
}
376
373
-SyncListener setListeners(void Function(int, int, double) onNewBlock,
374
- void Function() onNewTransaction) {
377
+SyncListener setListeners(
378
+ void Function(int, int, double) onNewBlock, void Function() onNewTransaction) {
379
final listener = SyncListener(onNewBlock, onNewTransaction);
380
// setListenerNative();
381
return listener;
@@ -407,12 +411,10 @@ Future<int> getNodeHeight() async => getNodeHeightSync();
411
void rescanBlockchainAsync() => currentWallet!.rescanBlockchainAsync();
412
413
String getSubaddressLabel(int accountIndex, int addressIndex) {
410
- return currentWallet!.getSubaddressLabel(
411
- accountIndex: accountIndex, addressIndex: addressIndex);
414
+ return currentWallet!.getSubaddressLabel(accountIndex: accountIndex, addressIndex: addressIndex);
415
}
416
414
-Future setTrustedDaemon(bool trusted) async =>
415
- currentWallet!.setTrustedDaemon(arg: trusted);
417
+Future setTrustedDaemon(bool trusted) async => currentWallet!.setTrustedDaemon(arg: trusted);
418
419
Future<bool> trustedDaemon() async => currentWallet!.trustedDaemon();
420
@@ -426,7 +428,8 @@ Map<String, List<int>> debugCallLength() => monero.debugCallLength;
428
429
Map<String, dynamic> getWalletCacheDebug() {
430
try {
429
- final jsonString = monero.MONERO_Wallet_serializeCacheToJson(Pointer.fromAddress(currentWallet!.ffiAddress()));
431
+ final jsonString =
432
+ monero.MONERO_Wallet_serializeCacheToJson(Pointer.fromAddress(currentWallet!.ffiAddress()));
433
final blob = json.decode(jsonString);
434
blob['cake:unspent'] = getAllUnspent();
435
return blob;
cw_monero/lib/api/wallet_manager.dart
+25
-33
@@ -36,17 +36,21 @@ void checkIfMoneroCIsFine() {
36
final dartCsExp = monero.wallet2_api_c_exp_sha256;
37
38
if (cppCsCpp != dartCsCpp) {
39
- throw MoneroCException("monero_c and monero.dart cpp wrapper code mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsCpp'\ndart: '$dartCsCpp'");
39
+ throw MoneroCException(
40
+ "monero_c and monero.dart cpp wrapper code mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsCpp'\ndart: '$dartCsCpp'");
41
}
42
43
if (cppCsH != dartCsH) {
43
- throw MoneroCException("monero_c and monero.dart cpp wrapper header mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsH'\ndart: '$dartCsH'");
44
+ throw MoneroCException(
45
+ "monero_c and monero.dart cpp wrapper header mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsH'\ndart: '$dartCsH'");
46
}
47
48
if (cppCsExp != dartCsExp && (Platform.isIOS || Platform.isMacOS)) {
47
- throw MoneroCException("monero_c and monero.dart wrapper export list mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsExp'\ndart: '$dartCsExp'");
49
+ throw MoneroCException(
50
+ "monero_c and monero.dart wrapper export list mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsExp'\ndart: '$dartCsExp'");
51
}
52
}
53
+
54
Wallet2WalletManager? _wmPtr;
55
Wallet2WalletManager wmPtr = (() {
56
try {
@@ -70,8 +74,7 @@ Wallet2WalletManager wmPtr = (() {
74
})();
75
76
Wallet2Wallet createWalletPointer() {
73
- final newWptr = wmPtr.createWallet(
74
- path: "", password: "", language: "", networkType: 0);
77
+ final newWptr = wmPtr.createWallet(path: "", password: "", language: "", networkType: 0);
78
return newWptr;
79
}
80
@@ -83,8 +86,8 @@ void createWallet(
86
int nettype = 0}) {
87
txhistory = null;
88
language = getSeedLanguage(language)!;
86
- final newW = wmPtr.createWallet(
87
- path: path, password: password, language: language, networkType: 0);
89
+ final newW =
90
+ wmPtr.createWallet(path: path, password: password, language: language, networkType: 0);
91
92
int status = newW.status();
93
if (status != 0) {
@@ -128,7 +131,8 @@ void restoreWalletFromSeedSync(
131
final error = newW.errorString();
132
if (error.contains('word list failed verification')) {
133
throw WalletRestoreFromSeedException(
131
- message: "Seed verification failed, please make sure you entered the correct seed with the correct words order",
134
+ message:
135
+ "Seed verification failed, please make sure you entered the correct seed with the correct words order",
136
);
137
}
138
throw WalletRestoreFromSeedException(message: error);
@@ -177,12 +181,10 @@ void restoreWalletFromKeys(
181
182
int status = newW.status();
183
if (status != 0) {
180
- throw WalletRestoreFromKeysException(
181
- message: newW.errorString());
184
+ throw WalletRestoreFromKeysException(message: newW.errorString());
185
}
186
newW.store(path: path);
187
185
-
188
// CW-712 - Try to restore deterministic wallet first, if the view key doesn't
189
// match the view key provided
190
if (spendKey != "") {
@@ -202,8 +204,7 @@ void restoreWalletFromKeys(
204
);
205
int status = newW.status();
206
if (status != 0) {
205
- throw WalletRestoreFromKeysException(
206
- message: newW.errorString());
207
+ throw WalletRestoreFromKeysException(message: newW.errorString());
208
}
209
newW.store(path: path);
210
@@ -217,7 +218,6 @@ void restoreWalletFromKeys(
218
_lastOpenedWallet = path;
219
}
220
220
-
221
// English only, because normalization.
222
void restoreWalletFromPolyseedWithOffset(
223
{required String path,
@@ -226,7 +226,6 @@ void restoreWalletFromPolyseedWithOffset(
226
required String seedOffset,
227
required String language,
228
int nettype = 0}) {
229
-
229
txhistory = null;
230
final newW = wmPtr.createWalletFromPolyseed(
231
path: path,
@@ -259,7 +258,6 @@ void restoreWalletFromPolyseedWithOffset(
258
openedWalletsByPath[path] = currentWallet!;
259
}
260
262
-
261
void restoreWalletFromSpendKeySync(
262
{required String path,
263
required String password,
@@ -322,10 +320,7 @@ Future<void> restoreWalletFromHardwareWallet(
320
final wmPtr = MoneroWalletManagerFactory().getWalletManager().ffiAddress();
321
final newWptrAddr = await Isolate.run(() {
322
return monero.WalletManager_createWalletFromDevice(Pointer.fromAddress(wmPtr),
325
- path: path,
326
- password: password,
327
- restoreHeight: restoreHeight,
328
- deviceName: deviceName)
323
+ path: path, password: password, restoreHeight: restoreHeight, deviceName: deviceName)
324
.address;
325
});
326
final newW = MoneroWallet(Pointer.fromAddress(newWptrAddr));
@@ -345,8 +340,7 @@ Future<void> restoreWalletFromHardwareWallet(
340
341
Map<String, Wallet2Wallet> openedWalletsByPath = {};
342
348
-Future<void> loadWallet(
349
- {required String path, required String password, int nettype = 0}) async {
343
+Future<void> loadWallet({required String path, required String password, int nettype = 0}) async {
344
if (openedWalletsByPath[path] != null) {
345
txhistory = null;
346
currentWallet = openedWalletsByPath[path]!;
@@ -368,14 +362,14 @@ Future<void> loadWallet(
362
var deviceType = 0;
363
364
if (Platform.isAndroid || Platform.isIOS) {
371
- deviceType = wmPtr.queryWalletDevice(
365
+ deviceType = wmPtr.queryWalletDevice(
366
keysFileName: "$path.keys",
367
password: password,
368
kdfRounds: 1,
369
);
370
final status = wmPtr.errorString();
371
if (status != "") {
378
- printV("loadWallet:"+status);
372
+ printV("loadWallet:" + status);
373
// This is most likely closeWallet call leaking error. This is fine.
374
if (status.contains("failed to save file")) {
375
printV("loadWallet: error leaked: $status");
@@ -390,7 +384,7 @@ Future<void> loadWallet(
384
385
if (deviceType == 1) {
386
if (gLedger == null) {
393
- throw Exception("Tried to open a ledger wallet with no ledger connected");
387
+ throw Exception("Tried to open a ledger wallet with no ledger connected");
388
}
389
enableLedgerExchange(gLedger!);
390
}
@@ -407,7 +401,7 @@ Future<void> loadWallet(
401
int status = newW.status();
402
if (status != 0) {
403
final err = newW.errorString();
410
- printV("loadWallet:"+err);
404
+ printV("loadWallet:" + err);
405
throw WalletOpeningException(message: err);
406
}
407
if (deviceType == 0) {
@@ -424,18 +418,16 @@ void setupBackgroundSync(String password, Wallet2Wallet wallet) {
418
if (isViewOnlyBySpendKey(wallet)) {
419
return;
420
}
427
- wallet.setupBackgroundSync(backgroundSyncType: 2, walletPassword: password, backgroundCachePassword: '');
421
+ wallet.setupBackgroundSync(
422
+ backgroundSyncType: 2, walletPassword: password, backgroundCachePassword: '');
423
if (wallet.status() != 0) {
424
// We simply ignore the error.
425
printV("setupBackgroundSync: ${wallet.errorString()}");
426
}
427
}
428
434
-
435
-Future<void> openWallet(
436
- {required String path,
437
- required String password,
438
- int nettype = 0}) async =>
429
+Future<void> openWallet({required String path, required String password, int nettype = 0}) async =>
430
loadWallet(path: path, password: password, nettype: nettype);
431
441
-bool isViewOnlyBySpendKey(Wallet2Wallet? wallet) => int.tryParse((wallet??currentWallet!).secretSpendKey()) == 0;
432
+bool isViewOnlyBySpendKey(Wallet2Wallet? wallet) =>
433
+ int.tryParse((wallet ?? currentWallet!).secretSpendKey()) == 0;
cw_monero/lib/bip39_seed.dart
+5
-10
@@ -8,21 +8,17 @@ bool isBip39Seed(String mnemonic) => bip39.validateMnemonic(mnemonic);
8
9
String getBip39Seed() => bip39.generateMnemonic();
10
11
-String getLegacySeedFromBip39(String mnemonic,
12
- {int accountIndex = 0, String passphrase = ""}) {
11
+String getLegacySeedFromBip39(String mnemonic, {int accountIndex = 0, String passphrase = ""}) {
12
final seed = bip39.mnemonicToSeed(mnemonic, passphrase: passphrase);
13
15
- final bip32KeyPair =
16
- bip32.BIP32.fromSeed(seed).derivePath("m/44'/128'/$accountIndex'/0/0");
14
+ final bip32KeyPair = bip32.BIP32.fromSeed(seed).derivePath("m/44'/128'/$accountIndex'/0/0");
15
16
final spendKey = _reduceECKey(bip32KeyPair.privateKey!);
17
20
- return LegacySeedLang.getByEnglishName("English")
21
- .encodePhrase(spendKey.toHexString());
18
+ return LegacySeedLang.getByEnglishName("English").encodePhrase(spendKey.toHexString());
19
}
20
24
-const _ed25519CurveOrder =
25
- "1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED";
21
+const _ed25519CurveOrder = "1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED";
22
23
Uint8List _reduceECKey(Uint8List buffer) {
24
final curveOrder = BigInt.parse(_ed25519CurveOrder, radix: 16);
@@ -51,8 +47,7 @@ BigInt _readBytes(Uint8List bytes) {
47
return BigInt.from(result);
48
}
49
final mid = start + ((end - start) >> 1);
54
- return read(start, mid) +
55
- read(mid, end) * (BigInt.one << ((mid - start) * 8));
50
+ return read(start, mid) + read(mid, end) * (BigInt.one << ((mid - start) * 8));
51
}
52
53
return read(0, bytes.length);
cw_monero/lib/exceptions/monero_transaction_creation_exception.dart
+1
-1
@@ -5,4 +5,4 @@ class MoneroTransactionCreationException implements Exception {
5
6
@override
7
String toString() => message;
8
-}
\ No newline at end of file
8
+}
cw_monero/lib/exceptions/monero_transaction_no_inputs_exception.dart
+2
-1
@@ -4,5 +4,6 @@ class MoneroTransactionNoInputsException implements Exception {
4
int inputsSize;
5
6
@override
7
- String toString() => 'Not enough inputs ($inputsSize) selected. Please select more under Coin Control';
7
+ String toString() =>
8
+ 'Not enough inputs ($inputsSize) selected. Please select more under Coin Control';
9
}
cw_monero/lib/ledger.dart
+4
-9
@@ -33,8 +33,7 @@ Future<void> enableLedgerExchange(LedgerConnection connection) async {
33
34
latestLedgerCommand = _ledgerMoneroCommands[ledgerRequest[1]];
35
36
- api.MoneroWallet.setDeviceReceivedData(
37
- result.cast<UnsignedChar>(), response.length);
36
+ api.MoneroWallet.setDeviceReceivedData(result.cast<UnsignedChar>(), response.length);
37
malloc.free(result);
38
// api.MoneroFree().free(result.cast());
39
}
@@ -59,8 +58,7 @@ class ExchangeOperation extends LedgerRawOperation<Uint8List> {
58
ExchangeOperation(this.inputData);
59
60
@override
62
- Future<Uint8List> read(ByteDataReader reader) async =>
63
- reader.read(reader.remainingLength);
61
+ Future<Uint8List> read(ByteDataReader reader) async => reader.read(reader.remainingLength);
62
63
@override
64
Future<List<Uint8List>> write(ByteDataWriter writer) async => [inputData];
@@ -109,14 +107,12 @@ const _ledgerMoneroCommands = {
107
};
108
109
void _logLedgerCommand(Uint8List command, [bool isResponse = true]) {
112
- String toHexString(Uint8List data) =>
113
- data.map((e) => e.toRadixString(16).padLeft(2, '0')).join();
110
+ String toHexString(Uint8List data) => data.map((e) => e.toRadixString(16).padLeft(2, '0')).join();
111
112
if (isResponse) {
113
printV("< ${toHexString(command)}");
114
} else {
118
- printV(
119
- "> ${_ledgerMoneroCommands[command[1]]} ${toHexString(command.sublist(2))}");
115
+ printV("> ${_ledgerMoneroCommands[command[1]]} ${toHexString(command.sublist(2))}");
116
}
117
}
118
@@ -125,4 +121,3 @@ class MoneroLedgerService extends HardwareWalletService {
121
122
MoneroLedgerService(this.connection);
123
}
128
-
cw_monero/lib/mnemonics/chinese_simplified.dart
+1
-1
@@ -1627,4 +1627,4 @@ class ChineseSimplifiedMnemonics {
1627
"浙",
1628
"貌"
1629
];
1630
-}
\ No newline at end of file
1630
+}
cw_monero/lib/mnemonics/dutch.dart
+1
-1
@@ -1627,4 +1627,4 @@ class DutchMnemonics {
1627
"zwijmel",
1628
"zworen"
1629
];
1630
-}
\ No newline at end of file
1630
+}
cw_monero/lib/mnemonics/french.dart
+1629
-1629
@@ -1,1630 +1,1630 @@
1
class FrenchMnemonics {
2
- static const words = [
3
- "abandon",
4
- "abattre",
5
- "aboi",
6
- "abolir",
7
- "aborder",
8
- "abri",
9
- "absence",
10
- "absolu",
11
- "abuser",
12
- "acacia",
13
- "acajou",
14
- "accent",
15
- "accord",
16
- "accrocher",
17
- "accuser",
18
- "acerbe",
19
- "achat",
20
- "acheter",
21
- "acide",
22
- "acier",
23
- "acquis",
24
- "acte",
25
- "action",
26
- "adage",
27
- "adepte",
28
- "adieu",
29
- "admettre",
30
- "admis",
31
- "adorer",
32
- "adresser",
33
- "aduler",
34
- "affaire",
35
- "affirmer",
36
- "afin",
37
- "agacer",
38
- "agent",
39
- "agir",
40
- "agiter",
41
- "agonie",
42
- "agrafe",
43
- "agrume",
44
- "aider",
45
- "aigle",
46
- "aigre",
47
- "aile",
48
- "ailleurs",
49
- "aimant",
50
- "aimer",
51
- "ainsi",
52
- "aise",
53
- "ajouter",
54
- "alarme",
55
- "album",
56
- "alcool",
57
- "alerte",
58
- "algue",
59
- "alibi",
60
- "aller",
61
- "allumer",
62
- "alors",
63
- "amande",
64
- "amener",
65
- "amie",
66
- "amorcer",
67
- "amour",
68
- "ample",
69
- "amuser",
70
- "ananas",
71
- "ancien",
72
- "anglais",
73
- "angoisse",
74
- "animal",
75
- "anneau",
76
- "annoncer",
77
- "apercevoir",
78
- "apparence",
79
- "appel",
80
- "apporter",
81
- "apprendre",
82
- "appuyer",
83
- "arbre",
84
- "arcade",
85
- "arceau",
86
- "arche",
87
- "ardeur",
88
- "argent",
89
- "argile",
90
- "aride",
91
- "arme",
92
- "armure",
93
- "arracher",
94
- "arriver",
95
- "article",
96
- "asile",
97
- "aspect",
98
- "assaut",
99
- "assez",
100
- "assister",
101
- "assurer",
102
- "astre",
103
- "astuce",
104
- "atlas",
105
- "atroce",
106
- "attacher",
107
- "attente",
108
- "attirer",
109
- "aube",
110
- "aucun",
111
- "audace",
112
- "auparavant",
113
- "auquel",
114
- "aurore",
115
- "aussi",
116
- "autant",
117
- "auteur",
118
- "autoroute",
119
- "autre",
120
- "aval",
121
- "avant",
122
- "avec",
123
- "avenir",
124
- "averse",
125
- "aveu",
126
- "avide",
127
- "avion",
128
- "avis",
129
- "avoir",
130
- "avouer",
131
- "avril",
132
- "azote",
133
- "azur",
134
- "badge",
135
- "bagage",
136
- "bague",
137
- "bain",
138
- "baisser",
139
- "balai",
140
- "balcon",
141
- "balise",
142
- "balle",
143
- "bambou",
144
- "banane",
145
- "banc",
146
- "bandage",
147
- "banjo",
148
- "banlieue",
149
- "bannir",
150
- "banque",
151
- "baobab",
152
- "barbe",
153
- "barque",
154
- "barrer",
155
- "bassine",
156
- "bataille",
157
- "bateau",
158
- "battre",
159
- "baver",
160
- "bavoir",
161
- "bazar",
162
- "beau",
163
- "beige",
164
- "berger",
165
- "besoin",
166
- "beurre",
167
- "biais",
168
- "biceps",
169
- "bidule",
170
- "bien",
171
- "bijou",
172
- "bilan",
173
- "billet",
174
- "blanc",
175
- "blason",
176
- "bleu",
177
- "bloc",
178
- "blond",
179
- "bocal",
180
- "boire",
181
- "boiserie",
182
- "boiter",
183
- "bonbon",
184
- "bondir",
185
- "bonheur",
186
- "bordure",
187
- "borgne",
188
- "borner",
189
- "bosse",
190
- "bouche",
191
- "bouder",
192
- "bouger",
193
- "boule",
194
- "bourse",
195
- "bout",
196
- "boxe",
197
- "brader",
198
- "braise",
199
- "branche",
200
- "braquer",
201
- "bras",
202
- "brave",
203
- "brebis",
204
- "brevet",
205
- "brider",
206
- "briller",
207
- "brin",
208
- "brique",
209
- "briser",
210
- "broche",
211
- "broder",
212
- "bronze",
213
- "brosser",
214
- "brouter",
215
- "bruit",
216
- "brute",
217
- "budget",
218
- "buffet",
219
- "bulle",
220
- "bureau",
221
- "buriner",
222
- "buste",
223
- "buter",
224
- "butiner",
225
- "cabas",
226
- "cabinet",
227
- "cabri",
228
- "cacao",
229
- "cacher",
230
- "cadeau",
231
- "cadre",
232
- "cage",
233
- "caisse",
234
- "caler",
235
- "calme",
236
- "camarade",
237
- "camion",
238
- "campagne",
239
- "canal",
240
- "canif",
241
- "capable",
242
- "capot",
243
- "carat",
244
- "caresser",
245
- "carie",
246
- "carpe",
247
- "cartel",
248
- "casier",
249
- "casque",
250
- "casserole",
251
- "cause",
252
- "cavale",
253
- "cave",
254
- "ceci",
255
- "cela",
256
- "celui",
257
- "cendre",
258
- "cent",
259
- "cependant",
260
- "cercle",
261
- "cerise",
262
- "cerner",
263
- "certes",
264
- "cerveau",
265
- "cesser",
266
- "chacun",
267
- "chair",
268
- "chaleur",
269
- "chamois",
270
- "chanson",
271
- "chaque",
272
- "charge",
273
- "chasse",
274
- "chat",
275
- "chaud",
276
- "chef",
277
- "chemin",
278
- "cheveu",
279
- "chez",
280
- "chicane",
281
- "chien",
282
- "chiffre",
283
- "chiner",
284
- "chiot",
285
- "chlore",
286
- "choc",
287
- "choix",
288
- "chose",
289
- "chou",
290
- "chute",
291
- "cibler",
292
- "cidre",
293
- "ciel",
294
- "cigale",
295
- "cinq",
296
- "cintre",
297
- "cirage",
298
- "cirque",
299
- "ciseau",
300
- "citation",
301
- "citer",
302
- "citron",
303
- "civet",
304
- "clairon",
305
- "clan",
306
- "classe",
307
- "clavier",
308
- "clef",
309
- "climat",
310
- "cloche",
311
- "cloner",
312
- "clore",
313
- "clos",
314
- "clou",
315
- "club",
316
- "cobra",
317
- "cocon",
318
- "coiffer",
319
- "coin",
320
- "colline",
321
- "colon",
322
- "combat",
323
- "comme",
324
- "compte",
325
- "conclure",
326
- "conduire",
327
- "confier",
328
- "connu",
329
- "conseil",
330
- "contre",
331
- "convenir",
332
- "copier",
333
- "cordial",
334
- "cornet",
335
- "corps",
336
- "cosmos",
337
- "coton",
338
- "couche",
339
- "coude",
340
- "couler",
341
- "coupure",
342
- "cour",
343
- "couteau",
344
- "couvrir",
345
- "crabe",
346
- "crainte",
347
- "crampe",
348
- "cran",
349
- "creuser",
350
- "crever",
351
- "crier",
352
- "crime",
353
- "crin",
354
- "crise",
355
- "crochet",
356
- "croix",
357
- "cruel",
358
- "cuisine",
359
- "cuite",
360
- "culot",
361
- "culte",
362
- "cumul",
363
- "cure",
364
- "curieux",
365
- "cuve",
366
- "dame",
367
- "danger",
368
- "dans",
369
- "davantage",
370
- "debout",
371
- "dedans",
372
- "dehors",
373
- "delta",
374
- "demain",
375
- "demeurer",
376
- "demi",
377
- "dense",
378
- "dent",
379
- "depuis",
380
- "dernier",
381
- "descendre",
382
- "dessus",
383
- "destin",
384
- "dette",
385
- "deuil",
386
- "deux",
387
- "devant",
388
- "devenir",
389
- "devin",
390
- "devoir",
391
- "dicton",
392
- "dieu",
393
- "difficile",
394
- "digestion",
395
- "digue",
396
- "diluer",
397
- "dimanche",
398
- "dinde",
399
- "diode",
400
- "dire",
401
- "diriger",
402
- "discours",
403
- "disposer",
404
- "distance",
405
- "divan",
406
- "divers",
407
- "docile",
408
- "docteur",
409
- "dodu",
410
- "dogme",
411
- "doigt",
412
- "dominer",
413
- "donation",
414
- "donjon",
415
- "donner",
416
- "dopage",
417
- "dorer",
418
- "dormir",
419
- "doseur",
420
- "douane",
421
- "double",
422
- "douche",
423
- "douleur",
424
- "doute",
425
- "doux",
426
- "douzaine",
427
- "draguer",
428
- "drame",
429
- "drap",
430
- "dresser",
431
- "droit",
432
- "duel",
433
- "dune",
434
- "duper",
435
- "durant",
436
- "durcir",
437
- "durer",
438
- "eaux",
439
- "effacer",
440
- "effet",
441
- "effort",
442
- "effrayant",
443
- "elle",
444
- "embrasser",
445
- "emmener",
446
- "emparer",
447
- "empire",
448
- "employer",
449
- "emporter",
450
- "enclos",
451
- "encore",
452
- "endive",
453
- "endormir",
454
- "endroit",
455
- "enduit",
456
- "enfant",
457
- "enfermer",
458
- "enfin",
459
- "enfler",
460
- "enfoncer",
461
- "enfuir",
462
- "engager",
463
- "engin",
464
- "enjeu",
465
- "enlever",
466
- "ennemi",
467
- "ennui",
468
- "ensemble",
469
- "ensuite",
470
- "entamer",
471
- "entendre",
472
- "entier",
473
- "entourer",
474
- "entre",
475
- "envelopper",
476
- "envie",
477
- "envoyer",
478
- "erreur",
479
- "escalier",
480
- "espace",
481
- "espoir",
482
- "esprit",
483
- "essai",
484
- "essor",
485
- "essuyer",
486
- "estimer",
487
- "exact",
488
- "examiner",
489
- "excuse",
490
- "exemple",
491
- "exiger",
492
- "exil",
493
- "exister",
494
- "exode",
495
- "expliquer",
496
- "exposer",
497
- "exprimer",
498
- "extase",
499
- "fable",
500
- "facette",
501
- "facile",
502
- "fade",
503
- "faible",
504
- "faim",
505
- "faire",
506
- "fait",
507
- "falloir",
508
- "famille",
509
- "faner",
510
- "farce",
511
- "farine",
512
- "fatigue",
513
- "faucon",
514
- "faune",
515
- "faute",
516
- "faux",
517
- "faveur",
518
- "favori",
519
- "faxer",
520
- "feinter",
521
- "femme",
522
- "fendre",
523
- "fente",
524
- "ferme",
525
- "festin",
526
- "feuille",
527
- "feutre",
528
- "fiable",
529
- "fibre",
530
- "ficher",
531
- "fier",
532
- "figer",
533
- "figure",
534
- "filet",
535
- "fille",
536
- "filmer",
537
- "fils",
538
- "filtre",
539
- "final",
540
- "finesse",
541
- "finir",
542
- "fiole",
543
- "firme",
544
- "fixe",
545
- "flacon",
546
- "flair",
547
- "flamme",
548
- "flan",
549
- "flaque",
550
- "fleur",
551
- "flocon",
552
- "flore",
553
- "flot",
554
- "flou",
555
- "fluide",
556
- "fluor",
557
- "flux",
558
- "focus",
559
- "foin",
560
- "foire",
561
- "foison",
562
- "folie",
563
- "fonction",
564
- "fondre",
565
- "fonte",
566
- "force",
567
- "forer",
568
- "forger",
569
- "forme",
570
- "fort",
571
- "fosse",
572
- "fouet",
573
- "fouine",
574
- "foule",
575
- "four",
576
- "foyer",
577
- "frais",
578
- "franc",
579
- "frapper",
580
- "freiner",
581
- "frimer",
582
- "friser",
583
- "frite",
584
- "froid",
585
- "froncer",
586
- "fruit",
587
- "fugue",
588
- "fuir",
589
- "fuite",
590
- "fumer",
591
- "fureur",
592
- "furieux",
593
- "fuser",
594
- "fusil",
595
- "futile",
596
- "futur",
597
- "gagner",
598
- "gain",
599
- "gala",
600
- "galet",
601
- "galop",
602
- "gamme",
603
- "gant",
604
- "garage",
605
- "garde",
606
- "garer",
607
- "gauche",
608
- "gaufre",
609
- "gaule",
610
- "gaver",
611
- "gazon",
612
- "geler",
613
- "genou",
614
- "genre",
615
- "gens",
616
- "gercer",
617
- "germer",
618
- "geste",
619
- "gibier",
620
- "gicler",
621
- "gilet",
622
- "girafe",
623
- "givre",
624
- "glace",
625
- "glisser",
626
- "globe",
627
- "gloire",
628
- "gluant",
629
- "gober",
630
- "golf",
631
- "gommer",
632
- "gorge",
633
- "gosier",
634
- "goutte",
635
- "grain",
636
- "gramme",
637
- "grand",
638
- "gras",
639
- "grave",
640
- "gredin",
641
- "griffure",
642
- "griller",
643
- "gris",
644
- "gronder",
645
- "gros",
646
- "grotte",
647
- "groupe",
648
- "grue",
649
- "guerrier",
650
- "guetter",
651
- "guider",
652
- "guise",
653
- "habiter",
654
- "hache",
655
- "haie",
656
- "haine",
657
- "halte",
658
- "hamac",
659
- "hanche",
660
- "hangar",
661
- "hanter",
662
- "haras",
663
- "hareng",
664
- "harpe",
665
- "hasard",
666
- "hausse",
667
- "haut",
668
- "havre",
669
- "herbe",
670
- "heure",
671
- "hibou",
672
- "hier",
673
- "histoire",
674
- "hiver",
675
- "hochet",
676
- "homme",
677
- "honneur",
678
- "honte",
679
- "horde",
680
- "horizon",
681
- "hormone",
682
- "houle",
683
- "housse",
684
- "hublot",
685
- "huile",
686
- "huit",
687
- "humain",
688
- "humble",
689
- "humide",
690
- "humour",
691
- "hurler",
692
- "idole",
693
- "igloo",
694
- "ignorer",
695
- "illusion",
696
- "image",
697
- "immense",
698
- "immobile",
699
- "imposer",
700
- "impression",
701
- "incapable",
702
- "inconnu",
703
- "index",
704
- "indiquer",
705
- "infime",
706
- "injure",
707
- "inox",
708
- "inspirer",
709
- "instant",
710
- "intention",
711
- "intime",
712
- "inutile",
713
- "inventer",
714
- "inviter",
715
- "iode",
716
- "iris",
717
- "issue",
718
- "ivre",
719
- "jade",
720
- "jadis",
721
- "jamais",
722
- "jambe",
723
- "janvier",
724
- "jardin",
725
- "jauge",
726
- "jaunisse",
727
- "jeter",
728
- "jeton",
729
- "jeudi",
730
- "jeune",
731
- "joie",
732
- "joindre",
733
- "joli",
734
- "joueur",
735
- "journal",
736
- "judo",
737
- "juge",
738
- "juillet",
739
- "juin",
740
- "jument",
741
- "jungle",
742
- "jupe",
743
- "jupon",
744
- "jurer",
745
- "juron",
746
- "jury",
747
- "jusque",
748
- "juste",
749
- "kayak",
750
- "ketchup",
751
- "kilo",
752
- "kiwi",
753
- "koala",
754
- "label",
755
- "lacet",
756
- "lacune",
757
- "laine",
758
- "laisse",
759
- "lait",
760
- "lame",
761
- "lancer",
762
- "lande",
763
- "laque",
764
- "lard",
765
- "largeur",
766
- "larme",
767
- "larve",
768
- "lasso",
769
- "laver",
770
- "lendemain",
771
- "lentement",
772
- "lequel",
773
- "lettre",
774
- "leur",
775
- "lever",
776
- "levure",
777
- "liane",
778
- "libre",
779
- "lien",
780
- "lier",
781
- "lieutenant",
782
- "ligne",
783
- "ligoter",
784
- "liguer",
785
- "limace",
786
- "limer",
787
- "limite",
788
- "lingot",
789
- "lion",
790
- "lire",
791
- "lisser",
792
- "litre",
793
- "livre",
794
- "lobe",
795
- "local",
796
- "logis",
797
- "loin",
798
- "loisir",
799
- "long",
800
- "loque",
801
- "lors",
802
- "lotus",
803
- "louer",
804
- "loup",
805
- "lourd",
806
- "louve",
807
- "loyer",
808
- "lubie",
809
- "lucide",
810
- "lueur",
811
- "luge",
812
- "luire",
813
- "lundi",
814
- "lune",
815
- "lustre",
816
- "lutin",
817
- "lutte",
818
- "luxe",
819
- "machine",
820
- "madame",
821
- "magie",
822
- "magnifique",
823
- "magot",
824
- "maigre",
825
- "main",
826
- "mairie",
827
- "maison",
828
- "malade",
829
- "malheur",
830
- "malin",
831
- "manche",
832
- "manger",
833
- "manier",
834
- "manoir",
835
- "manquer",
836
- "marche",
837
- "mardi",
838
- "marge",
839
- "mariage",
840
- "marquer",
841
- "mars",
842
- "masque",
843
- "masse",
844
- "matin",
845
- "mauvais",
846
- "meilleur",
847
- "melon",
848
- "membre",
849
- "menacer",
850
- "mener",
851
- "mensonge",
852
- "mentir",
853
- "menu",
854
- "merci",
855
- "merlu",
856
- "mesure",
857
- "mettre",
858
- "meuble",
859
- "meunier",
860
- "meute",
861
- "miche",
862
- "micro",
863
- "midi",
864
- "miel",
865
- "miette",
866
- "mieux",
867
- "milieu",
868
- "mille",
869
- "mimer",
870
- "mince",
871
- "mineur",
872
- "ministre",
873
- "minute",
874
- "mirage",
875
- "miroir",
876
- "miser",
877
- "mite",
878
- "mixte",
879
- "mobile",
880
- "mode",
881
- "module",
882
- "moins",
883
- "mois",
884
- "moment",
885
- "momie",
886
- "monde",
887
- "monsieur",
888
- "monter",
889
- "moquer",
890
- "moral",
891
- "morceau",
892
- "mordre",
893
- "morose",
894
- "morse",
895
- "mortier",
896
- "morue",
897
- "motif",
898
- "motte",
899
- "moudre",
900
- "moule",
901
- "mourir",
902
- "mousse",
903
- "mouton",
904
- "mouvement",
905
- "moyen",
906
- "muer",
907
- "muette",
908
- "mugir",
909
- "muguet",
910
- "mulot",
911
- "multiple",
912
- "munir",
913
- "muret",
914
- "muse",
915
- "musique",
916
- "muter",
917
- "nacre",
918
- "nager",
919
- "nain",
920
- "naissance",
921
- "narine",
922
- "narrer",
923
- "naseau",
924
- "nasse",
925
- "nation",
926
- "nature",
927
- "naval",
928
- "navet",
929
- "naviguer",
930
- "navrer",
931
- "neige",
932
- "nerf",
933
- "nerveux",
934
- "neuf",
935
- "neutre",
936
- "neuve",
937
- "neveu",
938
- "niche",
939
- "nier",
940
- "niveau",
941
- "noble",
942
- "noce",
943
- "nocif",
944
- "noir",
945
- "nomade",
946
- "nombre",
947
- "nommer",
948
- "nord",
949
- "norme",
950
- "notaire",
951
- "notice",
952
- "notre",
953
- "nouer",
954
- "nougat",
955
- "nourrir",
956
- "nous",
957
- "nouveau",
958
- "novice",
959
- "noyade",
960
- "noyer",
961
- "nuage",
962
- "nuance",
963
- "nuire",
964
- "nuit",
965
- "nulle",
966
- "nuque",
967
- "oasis",
968
- "objet",
969
- "obliger",
970
- "obscur",
971
- "observer",
972
- "obtenir",
973
- "obus",
974
- "occasion",
975
- "occuper",
976
- "ocre",
977
- "octet",
978
- "odeur",
979
- "odorat",
980
- "offense",
981
- "officier",
982
- "offrir",
983
- "ogive",
984
- "oiseau",
985
- "olive",
986
- "ombre",
987
- "onctueux",
988
- "onduler",
989
- "ongle",
990
- "onze",
991
- "opter",
992
- "option",
993
- "orageux",
994
- "oral",
995
- "orange",
996
- "orbite",
997
- "ordinaire",
998
- "ordre",
999
- "oreille",
1000
- "organe",
1001
- "orgie",
1002
- "orgueil",
1003
- "orient",
1004
- "origan",
1005
- "orner",
1006
- "orteil",
1007
- "ortie",
1008
- "oser",
1009
- "osselet",
1010
- "otage",
1011
- "otarie",
1012
- "ouate",
1013
- "oublier",
1014
- "ouest",
1015
- "ours",
1016
- "outil",
1017
- "outre",
1018
- "ouvert",
1019
- "ouvrir",
1020
- "ovale",
1021
- "ozone",
1022
- "pacte",
1023
- "page",
1024
- "paille",
1025
- "pain",
1026
- "paire",
1027
- "paix",
1028
- "palace",
1029
- "palissade",
1030
- "palmier",
1031
- "palpiter",
1032
- "panda",
1033
- "panneau",
1034
- "papa",
1035
- "papier",
1036
- "paquet",
1037
- "parc",
1038
- "pardi",
1039
- "parfois",
1040
- "parler",
1041
- "parmi",
1042
- "parole",
1043
- "partir",
1044
- "parvenir",
1045
- "passer",
1046
- "pastel",
1047
- "patin",
1048
- "patron",
1049
- "paume",
1050
- "pause",
1051
- "pauvre",
1052
- "paver",
1053
- "pavot",
1054
- "payer",
1055
- "pays",
1056
- "peau",
1057
- "peigne",
1058
- "peinture",
1059
- "pelage",
1060
- "pelote",
1061
- "pencher",
1062
- "pendre",
1063
- "penser",
1064
- "pente",
1065
- "percer",
1066
- "perdu",
1067
- "perle",
1068
- "permettre",
1069
- "personne",
1070
- "perte",
1071
- "peser",
1072
- "pesticide",
1073
- "petit",
1074
- "peuple",
1075
- "peur",
1076
- "phase",
1077
- "photo",
1078
- "phrase",
1079
- "piano",
1080
- "pied",
1081
- "pierre",
1082
- "pieu",
1083
- "pile",
1084
- "pilier",
1085
- "pilote",
1086
- "pilule",
1087
- "piment",
1088
- "pincer",
1089
- "pinson",
1090
- "pinte",
1091
- "pion",
1092
- "piquer",
1093
- "pirate",
1094
- "pire",
1095
- "piste",
1096
- "piton",
1097
- "pitre",
1098
- "pivot",
1099
- "pizza",
1100
- "placer",
1101
- "plage",
1102
- "plaire",
1103
- "plan",
1104
- "plaque",
1105
- "plat",
1106
- "plein",
1107
- "pleurer",
1108
- "pliage",
1109
- "plier",
1110
- "plonger",
1111
- "plot",
1112
- "pluie",
1113
- "plume",
1114
- "plus",
1115
- "pneu",
1116
- "poche",
1117
- "podium",
1118
- "poids",
1119
- "poil",
1120
- "point",
1121
- "poire",
1122
- "poison",
1123
- "poitrine",
1124
- "poivre",
1125
- "police",
1126
- "pollen",
1127
- "pomme",
1128
- "pompier",
1129
- "poncer",
1130
- "pondre",
1131
- "pont",
1132
- "portion",
1133
- "poser",
1134
- "position",
1135
- "possible",
1136
- "poste",
1137
- "potage",
1138
- "potin",
1139
- "pouce",
1140
- "poudre",
1141
- "poulet",
1142
- "poumon",
1143
- "poupe",
1144
- "pour",
1145
- "pousser",
1146
- "poutre",
1147
- "pouvoir",
1148
- "prairie",
1149
- "premier",
1150
- "prendre",
1151
- "presque",
1152
- "preuve",
1153
- "prier",
1154
- "primeur",
1155
- "prince",
1156
- "prison",
1157
- "priver",
1158
- "prix",
1159
- "prochain",
1160
- "produire",
1161
- "profond",
1162
- "proie",
1163
- "projet",
1164
- "promener",
1165
- "prononcer",
1166
- "propre",
1167
- "prose",
1168
- "prouver",
1169
- "prune",
1170
- "public",
1171
- "puce",
1172
- "pudeur",
1173
- "puiser",
1174
- "pull",
1175
- "pulpe",
1176
- "puma",
1177
- "punir",
1178
- "purge",
1179
- "putois",
1180
- "quand",
1181
- "quartier",
1182
- "quasi",
1183
- "quatre",
1184
- "quel",
1185
- "question",
1186
- "queue",
1187
- "quiche",
1188
- "quille",
1189
- "quinze",
1190
- "quitter",
1191
- "quoi",
1192
- "rabais",
1193
- "raboter",
1194
- "race",
1195
- "racheter",
1196
- "racine",
1197
- "racler",
1198
- "raconter",
1199
- "radar",
1200
- "radio",
1201
- "rafale",
1202
- "rage",
1203
- "ragot",
1204
- "raideur",
1205
- "raie",
1206
- "rail",
1207
- "raison",
1208
- "ramasser",
1209
- "ramener",
1210
- "rampe",
1211
- "rance",
1212
- "rang",
1213
- "rapace",
1214
- "rapide",
1215
- "rapport",
1216
- "rarement",
1217
- "rasage",
1218
- "raser",
1219
- "rasoir",
1220
- "rassurer",
1221
- "rater",
1222
- "ratio",
1223
- "rature",
1224
- "ravage",
1225
- "ravir",
1226
- "rayer",
1227
- "rayon",
1228
- "rebond",
1229
- "recevoir",
1230
- "recherche",
1231
- "record",
1232
- "reculer",
1233
- "redevenir",
1234
- "refuser",
1235
- "regard",
1236
- "regretter",
1237
- "rein",
1238
- "rejeter",
1239
- "rejoindre",
1240
- "relation",
1241
- "relever",
1242
- "religion",
1243
- "remarquer",
1244
- "remettre",
1245
- "remise",
1246
- "remonter",
1247
- "remplir",
1248
- "remuer",
1249
- "rencontre",
1250
- "rendre",
1251
- "renier",
1252
- "renoncer",
1253
- "rentrer",
1254
- "renverser",
1255
- "repas",
1256
- "repli",
1257
- "reposer",
1258
- "reproche",
1259
- "requin",
1260
- "respect",
1261
- "ressembler",
1262
- "reste",
1263
- "retard",
1264
- "retenir",
1265
- "retirer",
1266
- "retour",
1267
- "retrouver",
1268
- "revenir",
1269
- "revoir",
1270
- "revue",
1271
- "rhume",
1272
- "ricaner",
1273
- "riche",
1274
- "rideau",
1275
- "ridicule",
1276
- "rien",
1277
- "rigide",
1278
- "rincer",
1279
- "rire",
1280
- "risquer",
1281
- "rituel",
1282
- "rivage",
1283
- "rive",
1284
- "robe",
1285
- "robot",
1286
- "robuste",
1287
- "rocade",
1288
- "roche",
1289
- "rodeur",
1290
- "rogner",
1291
- "roman",
1292
- "rompre",
1293
- "ronce",
1294
- "rondeur",
1295
- "ronger",
1296
- "roque",
1297
- "rose",
1298
- "rosir",
1299
- "rotation",
1300
- "rotule",
1301
- "roue",
1302
- "rouge",
1303
- "rouler",
1304
- "route",
1305
- "ruban",
1306
- "rubis",
1307
- "ruche",
1308
- "rude",
1309
- "ruelle",
1310
- "ruer",
1311
- "rugby",
1312
- "rugir",
1313
- "ruine",
1314
- "rumeur",
1315
- "rural",
1316
- "ruse",
1317
- "rustre",
1318
- "sable",
1319
- "sabot",
1320
- "sabre",
1321
- "sacre",
1322
- "sage",
1323
- "saint",
1324
- "saisir",
1325
- "salade",
1326
- "salive",
1327
- "salle",
1328
- "salon",
1329
- "salto",
1330
- "salut",
1331
- "salve",
1332
- "samba",
1333
- "sandale",
1334
- "sanguin",
1335
- "sapin",
1336
- "sarcasme",
1337
- "satisfaire",
1338
- "sauce",
1339
- "sauf",
1340
- "sauge",
1341
- "saule",
1342
- "sauna",
1343
- "sauter",
1344
- "sauver",
1345
- "savoir",
1346
- "science",
1347
- "scoop",
1348
- "score",
1349
- "second",
1350
- "secret",
1351
- "secte",
1352
- "seigneur",
1353
- "sein",
1354
- "seize",
1355
- "selle",
1356
- "selon",
1357
- "semaine",
1358
- "sembler",
1359
- "semer",
1360
- "semis",
1361
- "sensuel",
1362
- "sentir",
1363
- "sept",
1364
- "serpe",
1365
- "serrer",
1366
- "sertir",
1367
- "service",
1368
- "seuil",
1369
- "seulement",
1370
- "short",
1371
- "sien",
1372
- "sigle",
1373
- "signal",
1374
- "silence",
1375
- "silo",
1376
- "simple",
1377
- "singe",
1378
- "sinon",
1379
- "sinus",
1380
- "sioux",
1381
- "sirop",
1382
- "site",
1383
- "situation",
1384
- "skier",
1385
- "snob",
1386
- "sobre",
1387
- "social",
1388
- "socle",
1389
- "sodium",
1390
- "soigner",
1391
- "soir",
1392
- "soixante",
1393
- "soja",
1394
- "solaire",
1395
- "soldat",
1396
- "soleil",
1397
- "solide",
1398
- "solo",
1399
- "solvant",
1400
- "sombre",
1401
- "somme",
1402
- "somnoler",
1403
- "sondage",
1404
- "songeur",
1405
- "sonner",
1406
- "sorte",
1407
- "sosie",
1408
- "sottise",
1409
- "souci",
1410
- "soudain",
1411
- "souffrir",
1412
- "souhaiter",
1413
- "soulever",
1414
- "soumettre",
1415
- "soupe",
1416
- "sourd",
1417
- "soustraire",
1418
- "soutenir",
1419
- "souvent",
1420
- "soyeux",
1421
- "spectacle",
1422
- "sport",
1423
- "stade",
1424
- "stagiaire",
1425
- "stand",
1426
- "star",
1427
- "statue",
1428
- "stock",
1429
- "stop",
1430
- "store",
1431
- "style",
1432
- "suave",
1433
- "subir",
1434
- "sucre",
1435
- "suer",
1436
- "suffire",
1437
- "suie",
1438
- "suite",
1439
- "suivre",
1440
- "sujet",
1441
- "sulfite",
1442
- "supposer",
1443
- "surf",
1444
- "surprendre",
1445
- "surtout",
1446
- "surveiller",
1447
- "tabac",
1448
- "table",
1449
- "tabou",
1450
- "tache",
1451
- "tacler",
1452
- "tacot",
1453
- "tact",
1454
- "taie",
1455
- "taille",
1456
- "taire",
1457
- "talon",
1458
- "talus",
1459
- "tandis",
1460
- "tango",
1461
- "tanin",
1462
- "tant",
1463
- "taper",
1464
- "tapis",
1465
- "tard",
1466
- "tarif",
1467
- "tarot",
1468
- "tarte",
1469
- "tasse",
1470
- "taureau",
1471
- "taux",
1472
- "taverne",
1473
- "taxer",
1474
- "taxi",
1475
- "tellement",
1476
- "temple",
1477
- "tendre",
1478
- "tenir",
1479
- "tenter",
1480
- "tenu",
1481
- "terme",
1482
- "ternir",
1483
- "terre",
1484
- "test",
1485
- "texte",
1486
- "thym",
1487
- "tibia",
1488
- "tiers",
1489
- "tige",
1490
- "tipi",
1491
- "tique",
1492
- "tirer",
1493
- "tissu",
1494
- "titre",
1495
- "toast",
1496
- "toge",
1497
- "toile",
1498
- "toiser",
1499
- "toiture",
1500
- "tomber",
1501
- "tome",
1502
- "tonne",
1503
- "tonte",
1504
- "toque",
1505
- "torse",
1506
- "tortue",
1507
- "totem",
1508
- "toucher",
1509
- "toujours",
1510
- "tour",
1511
- "tousser",
1512
- "tout",
1513
- "toux",
1514
- "trace",
1515
- "train",
1516
- "trame",
1517
- "tranquille",
1518
- "travail",
1519
- "trembler",
1520
- "trente",
1521
- "tribu",
1522
- "trier",
1523
- "trio",
1524
- "tripe",
1525
- "triste",
1526
- "troc",
1527
- "trois",
1528
- "tromper",
1529
- "tronc",
1530
- "trop",
1531
- "trotter",
1532
- "trouer",
1533
- "truc",
1534
- "truite",
1535
- "tuba",
1536
- "tuer",
1537
- "tuile",
1538
- "turbo",
1539
- "tutu",
1540
- "tuyau",
1541
- "type",
1542
- "union",
1543
- "unique",
1544
- "unir",
1545
- "unisson",
1546
- "untel",
1547
- "urne",
1548
- "usage",
1549
- "user",
1550
- "usiner",
1551
- "usure",
1552
- "utile",
1553
- "vache",
1554
- "vague",
1555
- "vaincre",
1556
- "valeur",
1557
- "valoir",
1558
- "valser",
1559
- "valve",
1560
- "vampire",
1561
- "vaseux",
1562
- "vaste",
1563
- "veau",
1564
- "veille",
1565
- "veine",
1566
- "velours",
1567
- "velu",
1568
- "vendre",
1569
- "venir",
1570
- "vent",
1571
- "venue",
1572
- "verbe",
1573
- "verdict",
1574
- "version",
1575
- "vertige",
1576
- "verve",
1577
- "veste",
1578
- "veto",
1579
- "vexer",
1580
- "vice",
1581
- "victime",
1582
- "vide",
1583
- "vieil",
1584
- "vieux",
1585
- "vigie",
1586
- "vigne",
1587
- "ville",
1588
- "vingt",
1589
- "violent",
1590
- "virer",
1591
- "virus",
1592
- "visage",
1593
- "viser",
1594
- "visite",
1595
- "visuel",
1596
- "vitamine",
1597
- "vitrine",
1598
- "vivant",
1599
- "vivre",
1600
- "vocal",
1601
- "vodka",
1602
- "vogue",
1603
- "voici",
1604
- "voile",
1605
- "voir",
1606
- "voisin",
1607
- "voiture",
1608
- "volaille",
1609
- "volcan",
1610
- "voler",
1611
- "volt",
1612
- "votant",
1613
- "votre",
1614
- "vouer",
1615
- "vouloir",
1616
- "vous",
1617
- "voyage",
1618
- "voyou",
1619
- "vrac",
1620
- "vrai",
1621
- "yacht",
1622
- "yeti",
1623
- "yeux",
1624
- "yoga",
1625
- "zeste",
1626
- "zinc",
1627
- "zone",
1628
- "zoom"
1629
- ];
1630
-}
\ No newline at end of file
2
+ static const words = [
3
+ "abandon",
4
+ "abattre",
5
+ "aboi",
6
+ "abolir",
7
+ "aborder",
8
+ "abri",
9
+ "absence",
10
+ "absolu",
11
+ "abuser",
12
+ "acacia",
13
+ "acajou",
14
+ "accent",
15
+ "accord",
16
+ "accrocher",
17
+ "accuser",
18
+ "acerbe",
19
+ "achat",
20
+ "acheter",
21
+ "acide",
22
+ "acier",
23
+ "acquis",
24
+ "acte",
25
+ "action",
26
+ "adage",
27
+ "adepte",
28
+ "adieu",
29
+ "admettre",
30
+ "admis",
31
+ "adorer",
32
+ "adresser",
33
+ "aduler",
34
+ "affaire",
35
+ "affirmer",
36
+ "afin",
37
+ "agacer",
38
+ "agent",
39
+ "agir",
40
+ "agiter",
41
+ "agonie",
42
+ "agrafe",
43
+ "agrume",
44
+ "aider",
45
+ "aigle",
46
+ "aigre",
47
+ "aile",
48
+ "ailleurs",
49
+ "aimant",
50
+ "aimer",
51
+ "ainsi",
52
+ "aise",
53
+ "ajouter",
54
+ "alarme",
55
+ "album",
56
+ "alcool",
57
+ "alerte",
58
+ "algue",
59
+ "alibi",
60
+ "aller",
61
+ "allumer",
62
+ "alors",
63
+ "amande",
64
+ "amener",
65
+ "amie",
66
+ "amorcer",
67
+ "amour",
68
+ "ample",
69
+ "amuser",
70
+ "ananas",
71
+ "ancien",
72
+ "anglais",
73
+ "angoisse",
74
+ "animal",
75
+ "anneau",
76
+ "annoncer",
77
+ "apercevoir",
78
+ "apparence",
79
+ "appel",
80
+ "apporter",
81
+ "apprendre",
82
+ "appuyer",
83
+ "arbre",
84
+ "arcade",
85
+ "arceau",
86
+ "arche",
87
+ "ardeur",
88
+ "argent",
89
+ "argile",
90
+ "aride",
91
+ "arme",
92
+ "armure",
93
+ "arracher",
94
+ "arriver",
95
+ "article",
96
+ "asile",
97
+ "aspect",
98
+ "assaut",
99
+ "assez",
100
+ "assister",
101
+ "assurer",
102
+ "astre",
103
+ "astuce",
104
+ "atlas",
105
+ "atroce",
106
+ "attacher",
107
+ "attente",
108
+ "attirer",
109
+ "aube",
110
+ "aucun",
111
+ "audace",
112
+ "auparavant",
113
+ "auquel",
114
+ "aurore",
115
+ "aussi",
116
+ "autant",
117
+ "auteur",
118
+ "autoroute",
119
+ "autre",
120
+ "aval",
121
+ "avant",
122
+ "avec",
123
+ "avenir",
124
+ "averse",
125
+ "aveu",
126
+ "avide",
127
+ "avion",
128
+ "avis",
129
+ "avoir",
130
+ "avouer",
131
+ "avril",
132
+ "azote",
133
+ "azur",
134
+ "badge",
135
+ "bagage",
136
+ "bague",
137
+ "bain",
138
+ "baisser",
139
+ "balai",
140
+ "balcon",
141
+ "balise",
142
+ "balle",
143
+ "bambou",
144
+ "banane",
145
+ "banc",
146
+ "bandage",
147
+ "banjo",
148
+ "banlieue",
149
+ "bannir",
150
+ "banque",
151
+ "baobab",
152
+ "barbe",
153
+ "barque",
154
+ "barrer",
155
+ "bassine",
156
+ "bataille",
157
+ "bateau",
158
+ "battre",
159
+ "baver",
160
+ "bavoir",
161
+ "bazar",
162
+ "beau",
163
+ "beige",
164
+ "berger",
165
+ "besoin",
166
+ "beurre",
167
+ "biais",
168
+ "biceps",
169
+ "bidule",
170
+ "bien",
171
+ "bijou",
172
+ "bilan",
173
+ "billet",
174
+ "blanc",
175
+ "blason",
176
+ "bleu",
177
+ "bloc",
178
+ "blond",
179
+ "bocal",
180
+ "boire",
181
+ "boiserie",
182
+ "boiter",
183
+ "bonbon",
184
+ "bondir",
185
+ "bonheur",
186
+ "bordure",
187
+ "borgne",
188
+ "borner",
189
+ "bosse",
190
+ "bouche",
191
+ "bouder",
192
+ "bouger",
193
+ "boule",
194
+ "bourse",
195
+ "bout",
196
+ "boxe",
197
+ "brader",
198
+ "braise",
199
+ "branche",
200
+ "braquer",
201
+ "bras",
202
+ "brave",
203
+ "brebis",
204
+ "brevet",
205
+ "brider",
206
+ "briller",
207
+ "brin",
208
+ "brique",
209
+ "briser",
210
+ "broche",
211
+ "broder",
212
+ "bronze",
213
+ "brosser",
214
+ "brouter",
215
+ "bruit",
216
+ "brute",
217
+ "budget",
218
+ "buffet",
219
+ "bulle",
220
+ "bureau",
221
+ "buriner",
222
+ "buste",
223
+ "buter",
224
+ "butiner",
225
+ "cabas",
226
+ "cabinet",
227
+ "cabri",
228
+ "cacao",
229
+ "cacher",
230
+ "cadeau",
231
+ "cadre",
232
+ "cage",
233
+ "caisse",
234
+ "caler",
235
+ "calme",
236
+ "camarade",
237
+ "camion",
238
+ "campagne",
239
+ "canal",
240
+ "canif",
241
+ "capable",
242
+ "capot",
243
+ "carat",
244
+ "caresser",
245
+ "carie",
246
+ "carpe",
247
+ "cartel",
248
+ "casier",
249
+ "casque",
250
+ "casserole",
251
+ "cause",
252
+ "cavale",
253
+ "cave",
254
+ "ceci",
255
+ "cela",
256
+ "celui",
257
+ "cendre",
258
+ "cent",
259
+ "cependant",
260
+ "cercle",
261
+ "cerise",
262
+ "cerner",
263
+ "certes",
264
+ "cerveau",
265
+ "cesser",
266
+ "chacun",
267
+ "chair",
268
+ "chaleur",
269
+ "chamois",
270
+ "chanson",
271
+ "chaque",
272
+ "charge",
273
+ "chasse",
274
+ "chat",
275
+ "chaud",
276
+ "chef",
277
+ "chemin",
278
+ "cheveu",
279
+ "chez",
280
+ "chicane",
281
+ "chien",
282
+ "chiffre",
283
+ "chiner",
284
+ "chiot",
285
+ "chlore",
286
+ "choc",
287
+ "choix",
288
+ "chose",
289
+ "chou",
290
+ "chute",
291
+ "cibler",
292
+ "cidre",
293
+ "ciel",
294
+ "cigale",
295
+ "cinq",
296
+ "cintre",
297
+ "cirage",
298
+ "cirque",
299
+ "ciseau",
300
+ "citation",
301
+ "citer",
302
+ "citron",
303
+ "civet",
304
+ "clairon",
305
+ "clan",
306
+ "classe",
307
+ "clavier",
308
+ "clef",
309
+ "climat",
310
+ "cloche",
311
+ "cloner",
312
+ "clore",
313
+ "clos",
314
+ "clou",
315
+ "club",
316
+ "cobra",
317
+ "cocon",
318
+ "coiffer",
319
+ "coin",
320
+ "colline",
321
+ "colon",
322
+ "combat",
323
+ "comme",
324
+ "compte",
325
+ "conclure",
326
+ "conduire",
327
+ "confier",
328
+ "connu",
329
+ "conseil",
330
+ "contre",
331
+ "convenir",
332
+ "copier",
333
+ "cordial",
334
+ "cornet",
335
+ "corps",
336
+ "cosmos",
337
+ "coton",
338
+ "couche",
339
+ "coude",
340
+ "couler",
341
+ "coupure",
342
+ "cour",
343
+ "couteau",
344
+ "couvrir",
345
+ "crabe",
346
+ "crainte",
347
+ "crampe",
348
+ "cran",
349
+ "creuser",
350
+ "crever",
351
+ "crier",
352
+ "crime",
353
+ "crin",
354
+ "crise",
355
+ "crochet",
356
+ "croix",
357
+ "cruel",
358
+ "cuisine",
359
+ "cuite",
360
+ "culot",
361
+ "culte",
362
+ "cumul",
363
+ "cure",
364
+ "curieux",
365
+ "cuve",
366
+ "dame",
367
+ "danger",
368
+ "dans",
369
+ "davantage",
370
+ "debout",
371
+ "dedans",
372
+ "dehors",
373
+ "delta",
374
+ "demain",
375
+ "demeurer",
376
+ "demi",
377
+ "dense",
378
+ "dent",
379
+ "depuis",
380
+ "dernier",
381
+ "descendre",
382
+ "dessus",
383
+ "destin",
384
+ "dette",
385
+ "deuil",
386
+ "deux",
387
+ "devant",
388
+ "devenir",
389
+ "devin",
390
+ "devoir",
391
+ "dicton",
392
+ "dieu",
393
+ "difficile",
394
+ "digestion",
395
+ "digue",
396
+ "diluer",
397
+ "dimanche",
398
+ "dinde",
399
+ "diode",
400
+ "dire",
401
+ "diriger",
402
+ "discours",
403
+ "disposer",
404
+ "distance",
405
+ "divan",
406
+ "divers",
407
+ "docile",
408
+ "docteur",
409
+ "dodu",
410
+ "dogme",
411
+ "doigt",
412
+ "dominer",
413
+ "donation",
414
+ "donjon",
415
+ "donner",
416
+ "dopage",
417
+ "dorer",
418
+ "dormir",
419
+ "doseur",
420
+ "douane",
421
+ "double",
422
+ "douche",
423
+ "douleur",
424
+ "doute",
425
+ "doux",
426
+ "douzaine",
427
+ "draguer",
428
+ "drame",
429
+ "drap",
430
+ "dresser",
431
+ "droit",
432
+ "duel",
433
+ "dune",
434
+ "duper",
435
+ "durant",
436
+ "durcir",
437
+ "durer",
438
+ "eaux",
439
+ "effacer",
440
+ "effet",
441
+ "effort",
442
+ "effrayant",
443
+ "elle",
444
+ "embrasser",
445
+ "emmener",
446
+ "emparer",
447
+ "empire",
448
+ "employer",
449
+ "emporter",
450
+ "enclos",
451
+ "encore",
452
+ "endive",
453
+ "endormir",
454
+ "endroit",
455
+ "enduit",
456
+ "enfant",
457
+ "enfermer",
458
+ "enfin",
459
+ "enfler",
460
+ "enfoncer",
461
+ "enfuir",
462
+ "engager",
463
+ "engin",
464
+ "enjeu",
465
+ "enlever",
466
+ "ennemi",
467
+ "ennui",
468
+ "ensemble",
469
+ "ensuite",
470
+ "entamer",
471
+ "entendre",
472
+ "entier",
473
+ "entourer",
474
+ "entre",
475
+ "envelopper",
476
+ "envie",
477
+ "envoyer",
478
+ "erreur",
479
+ "escalier",
480
+ "espace",
481
+ "espoir",
482
+ "esprit",
483
+ "essai",
484
+ "essor",
485
+ "essuyer",
486
+ "estimer",
487
+ "exact",
488
+ "examiner",
489
+ "excuse",
490
+ "exemple",
491
+ "exiger",
492
+ "exil",
493
+ "exister",
494
+ "exode",
495
+ "expliquer",
496
+ "exposer",
497
+ "exprimer",
498
+ "extase",
499
+ "fable",
500
+ "facette",
501
+ "facile",
502
+ "fade",
503
+ "faible",
504
+ "faim",
505
+ "faire",
506
+ "fait",
507
+ "falloir",
508
+ "famille",
509
+ "faner",
510
+ "farce",
511
+ "farine",
512
+ "fatigue",
513
+ "faucon",
514
+ "faune",
515
+ "faute",
516
+ "faux",
517
+ "faveur",
518
+ "favori",
519
+ "faxer",
520
+ "feinter",
521
+ "femme",
522
+ "fendre",
523
+ "fente",
524
+ "ferme",
525
+ "festin",
526
+ "feuille",
527
+ "feutre",
528
+ "fiable",
529
+ "fibre",
530
+ "ficher",
531
+ "fier",
532
+ "figer",
533
+ "figure",
534
+ "filet",
535
+ "fille",
536
+ "filmer",
537
+ "fils",
538
+ "filtre",
539
+ "final",
540
+ "finesse",
541
+ "finir",
542
+ "fiole",
543
+ "firme",
544
+ "fixe",
545
+ "flacon",
546
+ "flair",
547
+ "flamme",
548
+ "flan",
549
+ "flaque",
550
+ "fleur",
551
+ "flocon",
552
+ "flore",
553
+ "flot",
554
+ "flou",
555
+ "fluide",
556
+ "fluor",
557
+ "flux",
558
+ "focus",
559
+ "foin",
560
+ "foire",
561
+ "foison",
562
+ "folie",
563
+ "fonction",
564
+ "fondre",
565
+ "fonte",
566
+ "force",
567
+ "forer",
568
+ "forger",
569
+ "forme",
570
+ "fort",
571
+ "fosse",
572
+ "fouet",
573
+ "fouine",
574
+ "foule",
575
+ "four",
576
+ "foyer",
577
+ "frais",
578
+ "franc",
579
+ "frapper",
580
+ "freiner",
581
+ "frimer",
582
+ "friser",
583
+ "frite",
584
+ "froid",
585
+ "froncer",
586
+ "fruit",
587
+ "fugue",
588
+ "fuir",
589
+ "fuite",
590
+ "fumer",
591
+ "fureur",
592
+ "furieux",
593
+ "fuser",
594
+ "fusil",
595
+ "futile",
596
+ "futur",
597
+ "gagner",
598
+ "gain",
599
+ "gala",
600
+ "galet",
601
+ "galop",
602
+ "gamme",
603
+ "gant",
604
+ "garage",
605
+ "garde",
606
+ "garer",
607
+ "gauche",
608
+ "gaufre",
609
+ "gaule",
610
+ "gaver",
611
+ "gazon",
612
+ "geler",
613
+ "genou",
614
+ "genre",
615
+ "gens",
616
+ "gercer",
617
+ "germer",
618
+ "geste",
619
+ "gibier",
620
+ "gicler",
621
+ "gilet",
622
+ "girafe",
623
+ "givre",
624
+ "glace",
625
+ "glisser",
626
+ "globe",
627
+ "gloire",
628
+ "gluant",
629
+ "gober",
630
+ "golf",
631
+ "gommer",
632
+ "gorge",
633
+ "gosier",
634
+ "goutte",
635
+ "grain",
636
+ "gramme",
637
+ "grand",
638
+ "gras",
639
+ "grave",
640
+ "gredin",
641
+ "griffure",
642
+ "griller",
643
+ "gris",
644
+ "gronder",
645
+ "gros",
646
+ "grotte",
647
+ "groupe",
648
+ "grue",
649
+ "guerrier",
650
+ "guetter",
651
+ "guider",
652
+ "guise",
653
+ "habiter",
654
+ "hache",
655
+ "haie",
656
+ "haine",
657
+ "halte",
658
+ "hamac",
659
+ "hanche",
660
+ "hangar",
661
+ "hanter",
662
+ "haras",
663
+ "hareng",
664
+ "harpe",
665
+ "hasard",
666
+ "hausse",
667
+ "haut",
668
+ "havre",
669
+ "herbe",
670
+ "heure",
671
+ "hibou",
672
+ "hier",
673
+ "histoire",
674
+ "hiver",
675
+ "hochet",
676
+ "homme",
677
+ "honneur",
678
+ "honte",
679
+ "horde",
680
+ "horizon",
681
+ "hormone",
682
+ "houle",
683
+ "housse",
684
+ "hublot",
685
+ "huile",
686
+ "huit",
687
+ "humain",
688
+ "humble",
689
+ "humide",
690
+ "humour",
691
+ "hurler",
692
+ "idole",
693
+ "igloo",
694
+ "ignorer",
695
+ "illusion",
696
+ "image",
697
+ "immense",
698
+ "immobile",
699
+ "imposer",
700
+ "impression",
701
+ "incapable",
702
+ "inconnu",
703
+ "index",
704
+ "indiquer",
705
+ "infime",
706
+ "injure",
707
+ "inox",
708
+ "inspirer",
709
+ "instant",
710
+ "intention",
711
+ "intime",
712
+ "inutile",
713
+ "inventer",
714
+ "inviter",
715
+ "iode",
716
+ "iris",
717
+ "issue",
718
+ "ivre",
719
+ "jade",
720
+ "jadis",
721
+ "jamais",
722
+ "jambe",
723
+ "janvier",
724
+ "jardin",
725
+ "jauge",
726
+ "jaunisse",
727
+ "jeter",
728
+ "jeton",
729
+ "jeudi",
730
+ "jeune",
731
+ "joie",
732
+ "joindre",
733
+ "joli",
734
+ "joueur",
735
+ "journal",
736
+ "judo",
737
+ "juge",
738
+ "juillet",
739
+ "juin",
740
+ "jument",
741
+ "jungle",
742
+ "jupe",
743
+ "jupon",
744
+ "jurer",
745
+ "juron",
746
+ "jury",
747
+ "jusque",
748
+ "juste",
749
+ "kayak",
750
+ "ketchup",
751
+ "kilo",
752
+ "kiwi",
753
+ "koala",
754
+ "label",
755
+ "lacet",
756
+ "lacune",
757
+ "laine",
758
+ "laisse",
759
+ "lait",
760
+ "lame",
761
+ "lancer",
762
+ "lande",
763
+ "laque",
764
+ "lard",
765
+ "largeur",
766
+ "larme",
767
+ "larve",
768
+ "lasso",
769
+ "laver",
770
+ "lendemain",
771
+ "lentement",
772
+ "lequel",
773
+ "lettre",
774
+ "leur",
775
+ "lever",
776
+ "levure",
777
+ "liane",
778
+ "libre",
779
+ "lien",
780
+ "lier",
781
+ "lieutenant",
782
+ "ligne",
783
+ "ligoter",
784
+ "liguer",
785
+ "limace",
786
+ "limer",
787
+ "limite",
788
+ "lingot",
789
+ "lion",
790
+ "lire",
791
+ "lisser",
792
+ "litre",
793
+ "livre",
794
+ "lobe",
795
+ "local",
796
+ "logis",
797
+ "loin",
798
+ "loisir",
799
+ "long",
800
+ "loque",
801
+ "lors",
802
+ "lotus",
803
+ "louer",
804
+ "loup",
805
+ "lourd",
806
+ "louve",
807
+ "loyer",
808
+ "lubie",
809
+ "lucide",
810
+ "lueur",
811
+ "luge",
812
+ "luire",
813
+ "lundi",
814
+ "lune",
815
+ "lustre",
816
+ "lutin",
817
+ "lutte",
818
+ "luxe",
819
+ "machine",
820
+ "madame",
821
+ "magie",
822
+ "magnifique",
823
+ "magot",
824
+ "maigre",
825
+ "main",
826
+ "mairie",
827
+ "maison",
828
+ "malade",
829
+ "malheur",
830
+ "malin",
831
+ "manche",
832
+ "manger",
833
+ "manier",
834
+ "manoir",
835
+ "manquer",
836
+ "marche",
837
+ "mardi",
838
+ "marge",
839
+ "mariage",
840
+ "marquer",
841
+ "mars",
842
+ "masque",
843
+ "masse",
844
+ "matin",
845
+ "mauvais",
846
+ "meilleur",
847
+ "melon",
848
+ "membre",
849
+ "menacer",
850
+ "mener",
851
+ "mensonge",
852
+ "mentir",
853
+ "menu",
854
+ "merci",
855
+ "merlu",
856
+ "mesure",
857
+ "mettre",
858
+ "meuble",
859
+ "meunier",
860
+ "meute",
861
+ "miche",
862
+ "micro",
863
+ "midi",
864
+ "miel",
865
+ "miette",
866
+ "mieux",
867
+ "milieu",
868
+ "mille",
869
+ "mimer",
870
+ "mince",
871
+ "mineur",
872
+ "ministre",
873
+ "minute",
874
+ "mirage",
875
+ "miroir",
876
+ "miser",
877
+ "mite",
878
+ "mixte",
879
+ "mobile",
880
+ "mode",
881
+ "module",
882
+ "moins",
883
+ "mois",
884
+ "moment",
885
+ "momie",
886
+ "monde",
887
+ "monsieur",
888
+ "monter",
889
+ "moquer",
890
+ "moral",
891
+ "morceau",
892
+ "mordre",
893
+ "morose",
894
+ "morse",
895
+ "mortier",
896
+ "morue",
897
+ "motif",
898
+ "motte",
899
+ "moudre",
900
+ "moule",
901
+ "mourir",
902
+ "mousse",
903
+ "mouton",
904
+ "mouvement",
905
+ "moyen",
906
+ "muer",
907
+ "muette",
908
+ "mugir",
909
+ "muguet",
910
+ "mulot",
911
+ "multiple",
912
+ "munir",
913
+ "muret",
914
+ "muse",
915
+ "musique",
916
+ "muter",
917
+ "nacre",
918
+ "nager",
919
+ "nain",
920
+ "naissance",
921
+ "narine",
922
+ "narrer",
923
+ "naseau",
924
+ "nasse",
925
+ "nation",
926
+ "nature",
927
+ "naval",
928
+ "navet",
929
+ "naviguer",
930
+ "navrer",
931
+ "neige",
932
+ "nerf",
933
+ "nerveux",
934
+ "neuf",
935
+ "neutre",
936
+ "neuve",
937
+ "neveu",
938
+ "niche",
939
+ "nier",
940
+ "niveau",
941
+ "noble",
942
+ "noce",
943
+ "nocif",
944
+ "noir",
945
+ "nomade",
946
+ "nombre",
947
+ "nommer",
948
+ "nord",
949
+ "norme",
950
+ "notaire",
951
+ "notice",
952
+ "notre",
953
+ "nouer",
954
+ "nougat",
955
+ "nourrir",
956
+ "nous",
957
+ "nouveau",
958
+ "novice",
959
+ "noyade",
960
+ "noyer",
961
+ "nuage",
962
+ "nuance",
963
+ "nuire",
964
+ "nuit",
965
+ "nulle",
966
+ "nuque",
967
+ "oasis",
968
+ "objet",
969
+ "obliger",
970
+ "obscur",
971
+ "observer",
972
+ "obtenir",
973
+ "obus",
974
+ "occasion",
975
+ "occuper",
976
+ "ocre",
977
+ "octet",
978
+ "odeur",
979
+ "odorat",
980
+ "offense",
981
+ "officier",
982
+ "offrir",
983
+ "ogive",
984
+ "oiseau",
985
+ "olive",
986
+ "ombre",
987
+ "onctueux",
988
+ "onduler",
989
+ "ongle",
990
+ "onze",
991
+ "opter",
992
+ "option",
993
+ "orageux",
994
+ "oral",
995
+ "orange",
996
+ "orbite",
997
+ "ordinaire",
998
+ "ordre",
999
+ "oreille",
1000
+ "organe",
1001
+ "orgie",
1002
+ "orgueil",
1003
+ "orient",
1004
+ "origan",
1005
+ "orner",
1006
+ "orteil",
1007
+ "ortie",
1008
+ "oser",
1009
+ "osselet",
1010
+ "otage",
1011
+ "otarie",
1012
+ "ouate",
1013
+ "oublier",
1014
+ "ouest",
1015
+ "ours",
1016
+ "outil",
1017
+ "outre",
1018
+ "ouvert",
1019
+ "ouvrir",
1020
+ "ovale",
1021
+ "ozone",
1022
+ "pacte",
1023
+ "page",
1024
+ "paille",
1025
+ "pain",
1026
+ "paire",
1027
+ "paix",
1028
+ "palace",
1029
+ "palissade",
1030
+ "palmier",
1031
+ "palpiter",
1032
+ "panda",
1033
+ "panneau",
1034
+ "papa",
1035
+ "papier",
1036
+ "paquet",
1037
+ "parc",
1038
+ "pardi",
1039
+ "parfois",
1040
+ "parler",
1041
+ "parmi",
1042
+ "parole",
1043
+ "partir",
1044
+ "parvenir",
1045
+ "passer",
1046
+ "pastel",
1047
+ "patin",
1048
+ "patron",
1049
+ "paume",
1050
+ "pause",
1051
+ "pauvre",
1052
+ "paver",
1053
+ "pavot",
1054
+ "payer",
1055
+ "pays",
1056
+ "peau",
1057
+ "peigne",
1058
+ "peinture",
1059
+ "pelage",
1060
+ "pelote",
1061
+ "pencher",
1062
+ "pendre",
1063
+ "penser",
1064
+ "pente",
1065
+ "percer",
1066
+ "perdu",
1067
+ "perle",
1068
+ "permettre",
1069
+ "personne",
1070
+ "perte",
1071
+ "peser",
1072
+ "pesticide",
1073
+ "petit",
1074
+ "peuple",
1075
+ "peur",
1076
+ "phase",
1077
+ "photo",
1078
+ "phrase",
1079
+ "piano",
1080
+ "pied",
1081
+ "pierre",
1082
+ "pieu",
1083
+ "pile",
1084
+ "pilier",
1085
+ "pilote",
1086
+ "pilule",
1087
+ "piment",
1088
+ "pincer",
1089
+ "pinson",
1090
+ "pinte",
1091
+ "pion",
1092
+ "piquer",
1093
+ "pirate",
1094
+ "pire",
1095
+ "piste",
1096
+ "piton",
1097
+ "pitre",
1098
+ "pivot",
1099
+ "pizza",
1100
+ "placer",
1101
+ "plage",
1102
+ "plaire",
1103
+ "plan",
1104
+ "plaque",
1105
+ "plat",
1106
+ "plein",
1107
+ "pleurer",
1108
+ "pliage",
1109
+ "plier",
1110
+ "plonger",
1111
+ "plot",
1112
+ "pluie",
1113
+ "plume",
1114
+ "plus",
1115
+ "pneu",
1116
+ "poche",
1117
+ "podium",
1118
+ "poids",
1119
+ "poil",
1120
+ "point",
1121
+ "poire",
1122
+ "poison",
1123
+ "poitrine",
1124
+ "poivre",
1125
+ "police",
1126
+ "pollen",
1127
+ "pomme",
1128
+ "pompier",
1129
+ "poncer",
1130
+ "pondre",
1131
+ "pont",
1132
+ "portion",
1133
+ "poser",
1134
+ "position",
1135
+ "possible",
1136
+ "poste",
1137
+ "potage",
1138
+ "potin",
1139
+ "pouce",
1140
+ "poudre",
1141
+ "poulet",
1142
+ "poumon",
1143
+ "poupe",
1144
+ "pour",
1145
+ "pousser",
1146
+ "poutre",
1147
+ "pouvoir",
1148
+ "prairie",
1149
+ "premier",
1150
+ "prendre",
1151
+ "presque",
1152
+ "preuve",
1153
+ "prier",
1154
+ "primeur",
1155
+ "prince",
1156
+ "prison",
1157
+ "priver",
1158
+ "prix",
1159
+ "prochain",
1160
+ "produire",
1161
+ "profond",
1162
+ "proie",
1163
+ "projet",
1164
+ "promener",
1165
+ "prononcer",
1166
+ "propre",
1167
+ "prose",
1168
+ "prouver",
1169
+ "prune",
1170
+ "public",
1171
+ "puce",
1172
+ "pudeur",
1173
+ "puiser",
1174
+ "pull",
1175
+ "pulpe",
1176
+ "puma",
1177
+ "punir",
1178
+ "purge",
1179
+ "putois",
1180
+ "quand",
1181
+ "quartier",
1182
+ "quasi",
1183
+ "quatre",
1184
+ "quel",
1185
+ "question",
1186
+ "queue",
1187
+ "quiche",
1188
+ "quille",
1189
+ "quinze",
1190
+ "quitter",
1191
+ "quoi",
1192
+ "rabais",
1193
+ "raboter",
1194
+ "race",
1195
+ "racheter",
1196
+ "racine",
1197
+ "racler",
1198
+ "raconter",
1199
+ "radar",
1200
+ "radio",
1201
+ "rafale",
1202
+ "rage",
1203
+ "ragot",
1204
+ "raideur",
1205
+ "raie",
1206
+ "rail",
1207
+ "raison",
1208
+ "ramasser",
1209
+ "ramener",
1210
+ "rampe",
1211
+ "rance",
1212
+ "rang",
1213
+ "rapace",
1214
+ "rapide",
1215
+ "rapport",
1216
+ "rarement",
1217
+ "rasage",
1218
+ "raser",
1219
+ "rasoir",
1220
+ "rassurer",
1221
+ "rater",
1222
+ "ratio",
1223
+ "rature",
1224
+ "ravage",
1225
+ "ravir",
1226
+ "rayer",
1227
+ "rayon",
1228
+ "rebond",
1229
+ "recevoir",
1230
+ "recherche",
1231
+ "record",
1232
+ "reculer",
1233
+ "redevenir",
1234
+ "refuser",
1235
+ "regard",
1236
+ "regretter",
1237
+ "rein",
1238
+ "rejeter",
1239
+ "rejoindre",
1240
+ "relation",
1241
+ "relever",
1242
+ "religion",
1243
+ "remarquer",
1244
+ "remettre",
1245
+ "remise",
1246
+ "remonter",
1247
+ "remplir",
1248
+ "remuer",
1249
+ "rencontre",
1250
+ "rendre",
1251
+ "renier",
1252
+ "renoncer",
1253
+ "rentrer",
1254
+ "renverser",
1255
+ "repas",
1256
+ "repli",
1257
+ "reposer",
1258
+ "reproche",
1259
+ "requin",
1260
+ "respect",
1261
+ "ressembler",
1262
+ "reste",
1263
+ "retard",
1264
+ "retenir",
1265
+ "retirer",
1266
+ "retour",
1267
+ "retrouver",
1268
+ "revenir",
1269
+ "revoir",
1270
+ "revue",
1271
+ "rhume",
1272
+ "ricaner",
1273
+ "riche",
1274
+ "rideau",
1275
+ "ridicule",
1276
+ "rien",
1277
+ "rigide",
1278
+ "rincer",
1279
+ "rire",
1280
+ "risquer",
1281
+ "rituel",
1282
+ "rivage",
1283
+ "rive",
1284
+ "robe",
1285
+ "robot",
1286
+ "robuste",
1287
+ "rocade",
1288
+ "roche",
1289
+ "rodeur",
1290
+ "rogner",
1291
+ "roman",
1292
+ "rompre",
1293
+ "ronce",
1294
+ "rondeur",
1295
+ "ronger",
1296
+ "roque",
1297
+ "rose",
1298
+ "rosir",
1299
+ "rotation",
1300
+ "rotule",
1301
+ "roue",
1302
+ "rouge",
1303
+ "rouler",
1304
+ "route",
1305
+ "ruban",
1306
+ "rubis",
1307
+ "ruche",
1308
+ "rude",
1309
+ "ruelle",
1310
+ "ruer",
1311
+ "rugby",
1312
+ "rugir",
1313
+ "ruine",
1314
+ "rumeur",
1315
+ "rural",
1316
+ "ruse",
1317
+ "rustre",
1318
+ "sable",
1319
+ "sabot",
1320
+ "sabre",
1321
+ "sacre",
1322
+ "sage",
1323
+ "saint",
1324
+ "saisir",
1325
+ "salade",
1326
+ "salive",
1327
+ "salle",
1328
+ "salon",
1329
+ "salto",
1330
+ "salut",
1331
+ "salve",
1332
+ "samba",
1333
+ "sandale",
1334
+ "sanguin",
1335
+ "sapin",
1336
+ "sarcasme",
1337
+ "satisfaire",
1338
+ "sauce",
1339
+ "sauf",
1340
+ "sauge",
1341
+ "saule",
1342
+ "sauna",
1343
+ "sauter",
1344
+ "sauver",
1345
+ "savoir",
1346
+ "science",
1347
+ "scoop",
1348
+ "score",
1349
+ "second",
1350
+ "secret",
1351
+ "secte",
1352
+ "seigneur",
1353
+ "sein",
1354
+ "seize",
1355
+ "selle",
1356
+ "selon",
1357
+ "semaine",
1358
+ "sembler",
1359
+ "semer",
1360
+ "semis",
1361
+ "sensuel",
1362
+ "sentir",
1363
+ "sept",
1364
+ "serpe",
1365
+ "serrer",
1366
+ "sertir",
1367
+ "service",
1368
+ "seuil",
1369
+ "seulement",
1370
+ "short",
1371
+ "sien",
1372
+ "sigle",
1373
+ "signal",
1374
+ "silence",
1375
+ "silo",
1376
+ "simple",
1377
+ "singe",
1378
+ "sinon",
1379
+ "sinus",
1380
+ "sioux",
1381
+ "sirop",
1382
+ "site",
1383
+ "situation",
1384
+ "skier",
1385
+ "snob",
1386
+ "sobre",
1387
+ "social",
1388
+ "socle",
1389
+ "sodium",
1390
+ "soigner",
1391
+ "soir",
1392
+ "soixante",
1393
+ "soja",
1394
+ "solaire",
1395
+ "soldat",
1396
+ "soleil",
1397
+ "solide",
1398
+ "solo",
1399
+ "solvant",
1400
+ "sombre",
1401
+ "somme",
1402
+ "somnoler",
1403
+ "sondage",
1404
+ "songeur",
1405
+ "sonner",
1406
+ "sorte",
1407
+ "sosie",
1408
+ "sottise",
1409
+ "souci",
1410
+ "soudain",
1411
+ "souffrir",
1412
+ "souhaiter",
1413
+ "soulever",
1414
+ "soumettre",
1415
+ "soupe",
1416
+ "sourd",
1417
+ "soustraire",
1418
+ "soutenir",
1419
+ "souvent",
1420
+ "soyeux",
1421
+ "spectacle",
1422
+ "sport",
1423
+ "stade",
1424
+ "stagiaire",
1425
+ "stand",
1426
+ "star",
1427
+ "statue",
1428
+ "stock",
1429
+ "stop",
1430
+ "store",
1431
+ "style",
1432
+ "suave",
1433
+ "subir",
1434
+ "sucre",
1435
+ "suer",
1436
+ "suffire",
1437
+ "suie",
1438
+ "suite",
1439
+ "suivre",
1440
+ "sujet",
1441
+ "sulfite",
1442
+ "supposer",
1443
+ "surf",
1444
+ "surprendre",
1445
+ "surtout",
1446
+ "surveiller",
1447
+ "tabac",
1448
+ "table",
1449
+ "tabou",
1450
+ "tache",
1451
+ "tacler",
1452
+ "tacot",
1453
+ "tact",
1454
+ "taie",
1455
+ "taille",
1456
+ "taire",
1457
+ "talon",
1458
+ "talus",
1459
+ "tandis",
1460
+ "tango",
1461
+ "tanin",
1462
+ "tant",
1463
+ "taper",
1464
+ "tapis",
1465
+ "tard",
1466
+ "tarif",
1467
+ "tarot",
1468
+ "tarte",
1469
+ "tasse",
1470
+ "taureau",
1471
+ "taux",
1472
+ "taverne",
1473
+ "taxer",
1474
+ "taxi",
1475
+ "tellement",
1476
+ "temple",
1477
+ "tendre",
1478
+ "tenir",
1479
+ "tenter",
1480
+ "tenu",
1481
+ "terme",
1482
+ "ternir",
1483
+ "terre",
1484
+ "test",
1485
+ "texte",
1486
+ "thym",
1487
+ "tibia",
1488
+ "tiers",
1489
+ "tige",
1490
+ "tipi",
1491
+ "tique",
1492
+ "tirer",
1493
+ "tissu",
1494
+ "titre",
1495
+ "toast",
1496
+ "toge",
1497
+ "toile",
1498
+ "toiser",
1499
+ "toiture",
1500
+ "tomber",
1501
+ "tome",
1502
+ "tonne",
1503
+ "tonte",
1504
+ "toque",
1505
+ "torse",
1506
+ "tortue",
1507
+ "totem",
1508
+ "toucher",
1509
+ "toujours",
1510
+ "tour",
1511
+ "tousser",
1512
+ "tout",
1513
+ "toux",
1514
+ "trace",
1515
+ "train",
1516
+ "trame",
1517
+ "tranquille",
1518
+ "travail",
1519
+ "trembler",
1520
+ "trente",
1521
+ "tribu",
1522
+ "trier",
1523
+ "trio",
1524
+ "tripe",
1525
+ "triste",
1526
+ "troc",
1527
+ "trois",
1528
+ "tromper",
1529
+ "tronc",
1530
+ "trop",
1531
+ "trotter",
1532
+ "trouer",
1533
+ "truc",
1534
+ "truite",
1535
+ "tuba",
1536
+ "tuer",
1537
+ "tuile",
1538
+ "turbo",
1539
+ "tutu",
1540
+ "tuyau",
1541
+ "type",
1542
+ "union",
1543
+ "unique",
1544
+ "unir",
1545
+ "unisson",
1546
+ "untel",
1547
+ "urne",
1548
+ "usage",
1549
+ "user",
1550
+ "usiner",
1551
+ "usure",
1552
+ "utile",
1553
+ "vache",
1554
+ "vague",
1555
+ "vaincre",
1556
+ "valeur",
1557
+ "valoir",
1558
+ "valser",
1559
+ "valve",
1560
+ "vampire",
1561
+ "vaseux",
1562
+ "vaste",
1563
+ "veau",
1564
+ "veille",
1565
+ "veine",
1566
+ "velours",
1567
+ "velu",
1568
+ "vendre",
1569
+ "venir",
1570
+ "vent",
1571
+ "venue",
1572
+ "verbe",
1573
+ "verdict",
1574
+ "version",
1575
+ "vertige",
1576
+ "verve",
1577
+ "veste",
1578
+ "veto",
1579
+ "vexer",
1580
+ "vice",
1581
+ "victime",
1582
+ "vide",
1583
+ "vieil",
1584
+ "vieux",
1585
+ "vigie",
1586
+ "vigne",
1587
+ "ville",
1588
+ "vingt",
1589
+ "violent",
1590
+ "virer",
1591
+ "virus",
1592
+ "visage",
1593
+ "viser",
1594
+ "visite",
1595
+ "visuel",
1596
+ "vitamine",
1597
+ "vitrine",
1598
+ "vivant",
1599
+ "vivre",
1600
+ "vocal",
1601
+ "vodka",
1602
+ "vogue",
1603
+ "voici",
1604
+ "voile",
1605
+ "voir",
1606
+ "voisin",
1607
+ "voiture",
1608
+ "volaille",
1609
+ "volcan",
1610
+ "voler",
1611
+ "volt",
1612
+ "votant",
1613
+ "votre",
1614
+ "vouer",
1615
+ "vouloir",
1616
+ "vous",
1617
+ "voyage",
1618
+ "voyou",
1619
+ "vrac",
1620
+ "vrai",
1621
+ "yacht",
1622
+ "yeti",
1623
+ "yeux",
1624
+ "yoga",
1625
+ "zeste",
1626
+ "zinc",
1627
+ "zone",
1628
+ "zoom"
1629
+ ];
1630
+}
cw_monero/lib/mnemonics/german.dart
+1
-1
@@ -1627,4 +1627,4 @@ class GermanMnemonics {
1627
"Zweck",
1628
"Zyklop"
1629
];
1630
-}
\ No newline at end of file
1630
+}
cw_monero/lib/mnemonics/italian.dart
+1629
-1629
@@ -1,1630 +1,1630 @@
1
class ItalianMnemonics {
2
- static const words = [
3
- "abbinare",
4
- "abbonato",
5
- "abisso",
6
- "abitare",
7
- "abominio",
8
- "accadere",
9
- "accesso",
10
- "acciaio",
11
- "accordo",
12
- "accumulo",
13
- "acido",
14
- "acqua",
15
- "acrobata",
16
- "acustico",
17
- "adattare",
18
- "addetto",
19
- "addio",
20
- "addome",
21
- "adeguato",
22
- "aderire",
23
- "adorare",
24
- "adottare",
25
- "adozione",
26
- "adulto",
27
- "aereo",
28
- "aerobica",
29
- "affare",
30
- "affetto",
31
- "affidare",
32
- "affogato",
33
- "affronto",
34
- "africano",
35
- "afrodite",
36
- "agenzia",
37
- "aggancio",
38
- "aggeggio",
39
- "aggiunta",
40
- "agio",
41
- "agire",
42
- "agitare",
43
- "aglio",
44
- "agnello",
45
- "agosto",
46
- "aiutare",
47
- "albero",
48
- "albo",
49
- "alce",
50
- "alchimia",
51
- "alcool",
52
- "alfabeto",
53
- "algebra",
54
- "alimento",
55
- "allarme",
56
- "alleanza",
57
- "allievo",
58
- "alloggio",
59
- "alluce",
60
- "alpi",
61
- "alterare",
62
- "altro",
63
- "aluminio",
64
- "amante",
65
- "amarezza",
66
- "ambiente",
67
- "ambrosia",
68
- "america",
69
- "amico",
70
- "ammalare",
71
- "ammirare",
72
- "amnesia",
73
- "amnistia",
74
- "amore",
75
- "ampliare",
76
- "amputare",
77
- "analisi",
78
- "anamnesi",
79
- "ananas",
80
- "anarchia",
81
- "anatra",
82
- "anca",
83
- "ancorato",
84
- "andare",
85
- "androide",
86
- "aneddoto",
87
- "anello",
88
- "angelo",
89
- "angolino",
90
- "anguilla",
91
- "anidride",
92
- "anima",
93
- "annegare",
94
- "anno",
95
- "annuncio",
96
- "anomalia",
97
- "antenna",
98
- "anticipo",
99
- "aperto",
100
- "apostolo",
101
- "appalto",
102
- "appello",
103
- "appiglio",
104
- "applauso",
105
- "appoggio",
106
- "appurare",
107
- "aprile",
108
- "aquila",
109
- "arabo",
110
- "arachidi",
111
- "aragosta",
112
- "arancia",
113
- "arbitrio",
114
- "archivio",
115
- "arco",
116
- "argento",
117
- "argilla",
118
- "aria",
119
- "ariete",
120
- "arma",
121
- "armonia",
122
- "aroma",
123
- "arrivare",
124
- "arrosto",
125
- "arsenale",
126
- "arte",
127
- "artiglio",
128
- "asfalto",
129
- "asfissia",
130
- "asino",
131
- "asparagi",
132
- "aspirina",
133
- "assalire",
134
- "assegno",
135
- "assolto",
136
- "assurdo",
137
- "asta",
138
- "astratto",
139
- "atlante",
140
- "atletica",
141
- "atomo",
142
- "atropina",
143
- "attacco",
144
- "attesa",
145
- "attico",
146
- "atto",
147
- "attrarre",
148
- "auguri",
149
- "aula",
150
- "aumento",
151
- "aurora",
152
- "auspicio",
153
- "autista",
154
- "auto",
155
- "autunno",
156
- "avanzare",
157
- "avarizia",
158
- "avere",
159
- "aviatore",
160
- "avido",
161
- "avorio",
162
- "avvenire",
163
- "avviso",
164
- "avvocato",
165
- "azienda",
166
- "azione",
167
- "azzardo",
168
- "azzurro",
169
- "babbuino",
170
- "bacio",
171
- "badante",
172
- "baffi",
173
- "bagaglio",
174
- "bagliore",
175
- "bagno",
176
- "balcone",
177
- "balena",
178
- "ballare",
179
- "balordo",
180
- "balsamo",
181
- "bambola",
182
- "bancomat",
183
- "banda",
184
- "barato",
185
- "barba",
186
- "barista",
187
- "barriera",
188
- "basette",
189
- "basilico",
190
- "bassista",
191
- "bastare",
192
- "battello",
193
- "bavaglio",
194
- "beccare",
195
- "beduino",
196
- "bellezza",
197
- "bene",
198
- "benzina",
199
- "berretto",
200
- "bestia",
201
- "bevitore",
202
- "bianco",
203
- "bibbia",
204
- "biberon",
205
- "bibita",
206
- "bici",
207
- "bidone",
208
- "bilancia",
209
- "biliardo",
210
- "binario",
211
- "binocolo",
212
- "biologia",
213
- "biondina",
214
- "biopsia",
215
- "biossido",
216
- "birbante",
217
- "birra",
218
- "biscotto",
219
- "bisogno",
220
- "bistecca",
221
- "bivio",
222
- "blindare",
223
- "bloccare",
224
- "bocca",
225
- "bollire",
226
- "bombola",
227
- "bonifico",
228
- "borghese",
229
- "borsa",
230
- "bottino",
231
- "botulino",
232
- "braccio",
233
- "bradipo",
234
- "branco",
235
- "bravo",
236
- "bresaola",
237
- "bretelle",
238
- "brevetto",
239
- "briciola",
240
- "brigante",
241
- "brillare",
242
- "brindare",
243
- "brivido",
244
- "broccoli",
245
- "brontolo",
246
- "bruciare",
247
- "brufolo",
248
- "bucare",
249
- "buddista",
250
- "budino",
251
- "bufera",
252
- "buffo",
253
- "bugiardo",
254
- "buio",
255
- "buono",
256
- "burrone",
257
- "bussola",
258
- "bustina",
259
- "buttare",
260
- "cabernet",
261
- "cabina",
262
- "cacao",
263
- "cacciare",
264
- "cactus",
265
- "cadavere",
266
- "caffe",
267
- "calamari",
268
- "calcio",
269
- "caldaia",
270
- "calmare",
271
- "calunnia",
272
- "calvario",
273
- "calzone",
274
- "cambiare",
275
- "camera",
276
- "camion",
277
- "cammello",
278
- "campana",
279
- "canarino",
280
- "cancello",
281
- "candore",
282
- "cane",
283
- "canguro",
284
- "cannone",
285
- "canoa",
286
- "cantare",
287
- "canzone",
288
- "caos",
289
- "capanna",
290
- "capello",
291
- "capire",
292
- "capo",
293
- "capperi",
294
- "capra",
295
- "capsula",
296
- "caraffa",
297
- "carbone",
298
- "carciofo",
299
- "cardigan",
300
- "carenza",
301
- "caricare",
302
- "carota",
303
- "carrello",
304
- "carta",
305
- "casa",
306
- "cascare",
307
- "caserma",
308
- "cashmere",
309
- "casino",
310
- "cassetta",
311
- "castello",
312
- "catalogo",
313
- "catena",
314
- "catorcio",
315
- "cattivo",
316
- "causa",
317
- "cauzione",
318
- "cavallo",
319
- "caverna",
320
- "caviglia",
321
- "cavo",
322
- "cazzotto",
323
- "celibato",
324
- "cemento",
325
- "cenare",
326
- "centrale",
327
- "ceramica",
328
- "cercare",
329
- "ceretta",
330
- "cerniera",
331
- "certezza",
332
- "cervello",
333
- "cessione",
334
- "cestino",
335
- "cetriolo",
336
- "chiave",
337
- "chiedere",
338
- "chilo",
339
- "chimera",
340
- "chiodo",
341
- "chirurgo",
342
- "chitarra",
343
- "chiudere",
344
- "ciabatta",
345
- "ciao",
346
- "cibo",
347
- "ciccia",
348
- "cicerone",
349
- "ciclone",
350
- "cicogna",
351
- "cielo",
352
- "cifra",
353
- "cigno",
354
- "ciliegia",
355
- "cimitero",
356
- "cinema",
357
- "cinque",
358
- "cintura",
359
- "ciondolo",
360
- "ciotola",
361
- "cipolla",
362
- "cippato",
363
- "circuito",
364
- "cisterna",
365
- "citofono",
366
- "ciuccio",
367
- "civetta",
368
- "civico",
369
- "clausola",
370
- "cliente",
371
- "clima",
372
- "clinica",
373
- "cobra",
374
- "coccole",
375
- "cocktail",
376
- "cocomero",
377
- "codice",
378
- "coesione",
379
- "cogliere",
380
- "cognome",
381
- "colla",
382
- "colomba",
383
- "colpire",
384
- "coltello",
385
- "comando",
386
- "comitato",
387
- "commedia",
388
- "comodino",
389
- "compagna",
390
- "comune",
391
- "concerto",
392
- "condotto",
393
- "conforto",
394
- "congiura",
395
- "coniglio",
396
- "consegna",
397
- "conto",
398
- "convegno",
399
- "coperta",
400
- "copia",
401
- "coprire",
402
- "corazza",
403
- "corda",
404
- "corleone",
405
- "cornice",
406
- "corona",
407
- "corpo",
408
- "corrente",
409
- "corsa",
410
- "cortesia",
411
- "corvo",
412
- "coso",
413
- "costume",
414
- "cotone",
415
- "cottura",
416
- "cozza",
417
- "crampo",
418
- "cratere",
419
- "cravatta",
420
- "creare",
421
- "credere",
422
- "crema",
423
- "crescere",
424
- "crimine",
425
- "criterio",
426
- "croce",
427
- "crollare",
428
- "cronaca",
429
- "crostata",
430
- "croupier",
431
- "cubetto",
432
- "cucciolo",
433
- "cucina",
434
- "cultura",
435
- "cuoco",
436
- "cuore",
437
- "cupido",
438
- "cupola",
439
- "cura",
440
- "curva",
441
- "cuscino",
442
- "custode",
443
- "danzare",
444
- "data",
445
- "decennio",
446
- "decidere",
447
- "decollo",
448
- "dedicare",
449
- "dedurre",
450
- "definire",
451
- "delegare",
452
- "delfino",
453
- "delitto",
454
- "demone",
455
- "dentista",
456
- "denuncia",
457
- "deposito",
458
- "derivare",
459
- "deserto",
460
- "designer",
461
- "destino",
462
- "detonare",
463
- "dettagli",
464
- "diagnosi",
465
- "dialogo",
466
- "diamante",
467
- "diario",
468
- "diavolo",
469
- "dicembre",
470
- "difesa",
471
- "digerire",
472
- "digitare",
473
- "diluvio",
474
- "dinamica",
475
- "dipinto",
476
- "diploma",
477
- "diramare",
478
- "dire",
479
- "dirigere",
480
- "dirupo",
481
- "discesa",
482
- "disdetta",
483
- "disegno",
484
- "disporre",
485
- "dissenso",
486
- "distacco",
487
- "dito",
488
- "ditta",
489
- "diva",
490
- "divenire",
491
- "dividere",
492
- "divorare",
493
- "docente",
494
- "dolcetto",
495
- "dolore",
496
- "domatore",
497
- "domenica",
498
- "dominare",
499
- "donatore",
500
- "donna",
501
- "dorato",
502
- "dormire",
503
- "dorso",
504
- "dosaggio",
505
- "dottore",
506
- "dovere",
507
- "download",
508
- "dragone",
509
- "dramma",
510
- "dubbio",
511
- "dubitare",
512
- "duetto",
513
- "durata",
514
- "ebbrezza",
515
- "eccesso",
516
- "eccitare",
517
- "eclissi",
518
- "economia",
519
- "edera",
520
- "edificio",
521
- "editore",
522
- "edizione",
523
- "educare",
524
- "effetto",
525
- "egitto",
526
- "egiziano",
527
- "elastico",
528
- "elefante",
529
- "eleggere",
530
- "elemento",
531
- "elenco",
532
- "elezione",
533
- "elmetto",
534
- "elogio",
535
- "embrione",
536
- "emergere",
537
- "emettere",
538
- "eminenza",
539
- "emisfero",
540
- "emozione",
541
- "empatia",
542
- "energia",
543
- "enfasi",
544
- "enigma",
545
- "entrare",
546
- "enzima",
547
- "epidemia",
548
- "epilogo",
549
- "episodio",
550
- "epoca",
551
- "equivoco",
552
- "erba",
553
- "erede",
554
- "eroe",
555
- "erotico",
556
- "errore",
557
- "eruzione",
558
- "esaltare",
559
- "esame",
560
- "esaudire",
561
- "eseguire",
562
- "esempio",
563
- "esigere",
564
- "esistere",
565
- "esito",
566
- "esperto",
567
- "espresso",
568
- "essere",
569
- "estasi",
570
- "esterno",
571
- "estrarre",
572
- "eterno",
573
- "etica",
574
- "euforico",
575
- "europa",
576
- "evacuare",
577
- "evasione",
578
- "evento",
579
- "evidenza",
580
- "evitare",
581
- "evolvere",
582
- "fabbrica",
583
- "facciata",
584
- "fagiano",
585
- "fagotto",
586
- "falco",
587
- "fame",
588
- "famiglia",
589
- "fanale",
590
- "fango",
591
- "fantasia",
592
- "farfalla",
593
- "farmacia",
594
- "faro",
595
- "fase",
596
- "fastidio",
597
- "faticare",
598
- "fatto",
599
- "favola",
600
- "febbre",
601
- "femmina",
602
- "femore",
603
- "fenomeno",
604
- "fermata",
605
- "feromoni",
606
- "ferrari",
607
- "fessura",
608
- "festa",
609
- "fiaba",
610
- "fiamma",
611
- "fianco",
612
- "fiat",
613
- "fibbia",
614
- "fidare",
615
- "fieno",
616
- "figa",
617
- "figlio",
618
- "figura",
619
- "filetto",
620
- "filmato",
621
- "filosofo",
622
- "filtrare",
623
- "finanza",
624
- "finestra",
625
- "fingere",
626
- "finire",
627
- "finta",
628
- "finzione",
629
- "fiocco",
630
- "fioraio",
631
- "firewall",
632
- "firmare",
633
- "fisico",
634
- "fissare",
635
- "fittizio",
636
- "fiume",
637
- "flacone",
638
- "flagello",
639
- "flirtare",
640
- "flusso",
641
- "focaccia",
642
- "foglio",
643
- "fognario",
644
- "follia",
645
- "fonderia",
646
- "fontana",
647
- "forbici",
648
- "forcella",
649
- "foresta",
650
- "forgiare",
651
- "formare",
652
- "fornace",
653
- "foro",
654
- "fortuna",
655
- "forzare",
656
- "fosforo",
657
- "fotoni",
658
- "fracasso",
659
- "fragola",
660
- "frantumi",
661
- "fratello",
662
- "frazione",
663
- "freccia",
664
- "freddo",
665
- "frenare",
666
- "fresco",
667
- "friggere",
668
- "frittata",
669
- "frivolo",
670
- "frizione",
671
- "fronte",
672
- "frullato",
673
- "frumento",
674
- "frusta",
675
- "frutto",
676
- "fucile",
677
- "fuggire",
678
- "fulmine",
679
- "fumare",
680
- "funzione",
681
- "fuoco",
682
- "furbizia",
683
- "furgone",
684
- "furia",
685
- "furore",
686
- "fusibile",
687
- "fuso",
688
- "futuro",
689
- "gabbiano",
690
- "galassia",
691
- "gallina",
692
- "gamba",
693
- "gancio",
694
- "garanzia",
695
- "garofano",
696
- "gasolio",
697
- "gatto",
698
- "gazebo",
699
- "gazzetta",
700
- "gelato",
701
- "gemelli",
702
- "generare",
703
- "genitori",
704
- "gennaio",
705
- "geologia",
706
- "germania",
707
- "gestire",
708
- "gettare",
709
- "ghepardo",
710
- "ghiaccio",
711
- "giaccone",
712
- "giaguaro",
713
- "giallo",
714
- "giappone",
715
- "giardino",
716
- "gigante",
717
- "gioco",
718
- "gioiello",
719
- "giorno",
720
- "giovane",
721
- "giraffa",
722
- "giudizio",
723
- "giurare",
724
- "giusto",
725
- "globo",
726
- "gloria",
727
- "glucosio",
728
- "gnocca",
729
- "gocciola",
730
- "godere",
731
- "gomito",
732
- "gomma",
733
- "gonfiare",
734
- "gorilla",
735
- "governo",
736
- "gradire",
737
- "graffiti",
738
- "granchio",
739
- "grappolo",
740
- "grasso",
741
- "grattare",
742
- "gridare",
743
- "grissino",
744
- "grondaia",
745
- "grugnito",
746
- "gruppo",
747
- "guadagno",
748
- "guaio",
749
- "guancia",
750
- "guardare",
751
- "gufo",
752
- "guidare",
753
- "guscio",
754
- "gusto",
755
- "icona",
756
- "idea",
757
- "identico",
758
- "idolo",
759
- "idoneo",
760
- "idrante",
761
- "idrogeno",
762
- "igiene",
763
- "ignoto",
764
- "imbarco",
765
- "immagine",
766
- "immobile",
767
- "imparare",
768
- "impedire",
769
- "impianto",
770
- "importo",
771
- "impresa",
772
- "impulso",
773
- "incanto",
774
- "incendio",
775
- "incidere",
776
- "incontro",
777
- "incrocia",
778
- "incubo",
779
- "indagare",
780
- "indice",
781
- "indotto",
782
- "infanzia",
783
- "inferno",
784
- "infinito",
785
- "infranto",
786
- "ingerire",
787
- "inglese",
788
- "ingoiare",
789
- "ingresso",
790
- "iniziare",
791
- "innesco",
792
- "insalata",
793
- "inserire",
794
- "insicuro",
795
- "insonnia",
796
- "insulto",
797
- "interno",
798
- "introiti",
799
- "invasori",
800
- "inverno",
801
- "invito",
802
- "invocare",
803
- "ipnosi",
804
- "ipocrita",
805
- "ipotesi",
806
- "ironia",
807
- "irrigare",
808
- "iscritto",
809
- "isola",
810
- "ispirare",
811
- "isterico",
812
- "istinto",
813
- "istruire",
814
- "italiano",
815
- "jazz",
816
- "labbra",
817
- "labrador",
818
- "ladro",
819
- "lago",
820
- "lamento",
821
- "lampone",
822
- "lancetta",
823
- "lanterna",
824
- "lapide",
825
- "larva",
826
- "lasagne",
827
- "lasciare",
828
- "lastra",
829
- "latte",
830
- "laurea",
831
- "lavagna",
832
- "lavorare",
833
- "leccare",
834
- "legare",
835
- "leggere",
836
- "lenzuolo",
837
- "leone",
838
- "lepre",
839
- "letargo",
840
- "lettera",
841
- "levare",
842
- "levitare",
843
- "lezione",
844
- "liberare",
845
- "libidine",
846
- "libro",
847
- "licenza",
848
- "lievito",
849
- "limite",
850
- "lince",
851
- "lingua",
852
- "liquore",
853
- "lire",
854
- "listino",
855
- "litigare",
856
- "litro",
857
- "locale",
858
- "lottare",
859
- "lucciola",
860
- "lucidare",
861
- "luglio",
862
- "luna",
863
- "macchina",
864
- "madama",
865
- "madre",
866
- "maestro",
867
- "maggio",
868
- "magico",
869
- "maglione",
870
- "magnolia",
871
- "mago",
872
- "maialino",
873
- "maionese",
874
- "malattia",
875
- "male",
876
- "malloppo",
877
- "mancare",
878
- "mandorla",
879
- "mangiare",
880
- "manico",
881
- "manopola",
882
- "mansarda",
883
- "mantello",
884
- "manubrio",
885
- "manzo",
886
- "mappa",
887
- "mare",
888
- "margine",
889
- "marinaio",
890
- "marmotta",
891
- "marocco",
892
- "martello",
893
- "marzo",
894
- "maschera",
895
- "matrice",
896
- "maturare",
897
- "mazzetta",
898
- "meandri",
899
- "medaglia",
900
- "medico",
901
- "medusa",
902
- "megafono",
903
- "melone",
904
- "membrana",
905
- "menta",
906
- "mercato",
907
- "meritare",
908
- "merluzzo",
909
- "mese",
910
- "mestiere",
911
- "metafora",
912
- "meteo",
913
- "metodo",
914
- "mettere",
915
- "miele",
916
- "miglio",
917
- "miliardo",
918
- "mimetica",
919
- "minatore",
920
- "minuto",
921
- "miracolo",
922
- "mirtillo",
923
- "missile",
924
- "mistero",
925
- "misura",
926
- "mito",
927
- "mobile",
928
- "moda",
929
- "moderare",
930
- "moglie",
931
- "molecola",
932
- "molle",
933
- "momento",
934
- "moneta",
935
- "mongolia",
936
- "monologo",
937
- "montagna",
938
- "morale",
939
- "morbillo",
940
- "mordere",
941
- "mosaico",
942
- "mosca",
943
- "mostro",
944
- "motivare",
945
- "moto",
946
- "mulino",
947
- "mulo",
948
- "muovere",
949
- "muraglia",
950
- "muscolo",
951
- "museo",
952
- "musica",
953
- "mutande",
954
- "nascere",
955
- "nastro",
956
- "natale",
957
- "natura",
958
- "nave",
959
- "navigare",
960
- "negare",
961
- "negozio",
962
- "nemico",
963
- "nero",
964
- "nervo",
965
- "nessuno",
966
- "nettare",
967
- "neutroni",
968
- "neve",
969
- "nevicare",
970
- "nicotina",
971
- "nido",
972
- "nipote",
973
- "nocciola",
974
- "noleggio",
975
- "nome",
976
- "nonno",
977
- "norvegia",
978
- "notare",
979
- "notizia",
980
- "nove",
981
- "nucleo",
982
- "nuda",
983
- "nuotare",
984
- "nutrire",
985
- "obbligo",
986
- "occhio",
987
- "occupare",
988
- "oceano",
989
- "odissea",
990
- "odore",
991
- "offerta",
992
- "officina",
993
- "offrire",
994
- "oggetto",
995
- "oggi",
996
- "olfatto",
997
- "olio",
998
- "oliva",
999
- "ombelico",
1000
- "ombrello",
1001
- "omuncolo",
1002
- "ondata",
1003
- "onore",
1004
- "opera",
1005
- "opinione",
1006
- "opuscolo",
1007
- "opzione",
1008
- "orario",
1009
- "orbita",
1010
- "orchidea",
1011
- "ordine",
1012
- "orecchio",
1013
- "orgasmo",
1014
- "orgoglio",
1015
- "origine",
1016
- "orologio",
1017
- "oroscopo",
1018
- "orso",
1019
- "oscurare",
1020
- "ospedale",
1021
- "ospite",
1022
- "ossigeno",
1023
- "ostacolo",
1024
- "ostriche",
1025
- "ottenere",
1026
- "ottimo",
1027
- "ottobre",
1028
- "ovest",
1029
- "pacco",
1030
- "pace",
1031
- "pacifico",
1032
- "padella",
1033
- "pagare",
1034
- "pagina",
1035
- "pagnotta",
1036
- "palazzo",
1037
- "palestra",
1038
- "palpebre",
1039
- "pancetta",
1040
- "panfilo",
1041
- "panino",
1042
- "pannello",
1043
- "panorama",
1044
- "papa",
1045
- "paperino",
1046
- "paradiso",
1047
- "parcella",
1048
- "parente",
1049
- "parlare",
1050
- "parodia",
1051
- "parrucca",
1052
- "partire",
1053
- "passare",
1054
- "pasta",
1055
- "patata",
1056
- "patente",
1057
- "patogeno",
1058
- "patriota",
1059
- "pausa",
1060
- "pazienza",
1061
- "peccare",
1062
- "pecora",
1063
- "pedalare",
1064
- "pelare",
1065
- "pena",
1066
- "pendenza",
1067
- "penisola",
1068
- "pennello",
1069
- "pensare",
1070
- "pentirsi",
1071
- "percorso",
1072
- "perdono",
1073
- "perfetto",
1074
- "perizoma",
1075
- "perla",
1076
- "permesso",
1077
- "persona",
1078
- "pesare",
1079
- "pesce",
1080
- "peso",
1081
- "petardo",
1082
- "petrolio",
1083
- "pezzo",
1084
- "piacere",
1085
- "pianeta",
1086
- "piastra",
1087
- "piatto",
1088
- "piazza",
1089
- "piccolo",
1090
- "piede",
1091
- "piegare",
1092
- "pietra",
1093
- "pigiama",
1094
- "pigliare",
1095
- "pigrizia",
1096
- "pilastro",
1097
- "pilota",
1098
- "pinguino",
1099
- "pioggia",
1100
- "piombo",
1101
- "pionieri",
1102
- "piovra",
1103
- "pipa",
1104
- "pirata",
1105
- "pirolisi",
1106
- "piscina",
1107
- "pisolino",
1108
- "pista",
1109
- "pitone",
1110
- "piumino",
1111
- "pizza",
1112
- "plastica",
1113
- "platino",
1114
- "poesia",
1115
- "poiana",
1116
- "polaroid",
1117
- "polenta",
1118
- "polimero",
1119
- "pollo",
1120
- "polmone",
1121
- "polpetta",
1122
- "poltrona",
1123
- "pomodoro",
1124
- "pompa",
1125
- "popolo",
1126
- "porco",
1127
- "porta",
1128
- "porzione",
1129
- "possesso",
1130
- "postino",
1131
- "potassio",
1132
- "potere",
1133
- "poverino",
1134
- "pranzo",
1135
- "prato",
1136
- "prefisso",
1137
- "prelievo",
1138
- "premio",
1139
- "prendere",
1140
- "prestare",
1141
- "pretesa",
1142
- "prezzo",
1143
- "primario",
1144
- "privacy",
1145
- "problema",
1146
- "processo",
1147
- "prodotto",
1148
- "profeta",
1149
- "progetto",
1150
- "promessa",
1151
- "pronto",
1152
- "proposta",
1153
- "proroga",
1154
- "prossimo",
1155
- "proteina",
1156
- "prova",
1157
- "prudenza",
1158
- "pubblico",
1159
- "pudore",
1160
- "pugilato",
1161
- "pulire",
1162
- "pulsante",
1163
- "puntare",
1164
- "pupazzo",
1165
- "puzzle",
1166
- "quaderno",
1167
- "qualcuno",
1168
- "quarzo",
1169
- "quercia",
1170
- "quintale",
1171
- "rabbia",
1172
- "racconto",
1173
- "radice",
1174
- "raffica",
1175
- "ragazza",
1176
- "ragione",
1177
- "rammento",
1178
- "ramo",
1179
- "rana",
1180
- "randagio",
1181
- "rapace",
1182
- "rapinare",
1183
- "rapporto",
1184
- "rasatura",
1185
- "ravioli",
1186
- "reagire",
1187
- "realista",
1188
- "reattore",
1189
- "reazione",
1190
- "recitare",
1191
- "recluso",
1192
- "record",
1193
- "recupero",
1194
- "redigere",
1195
- "regalare",
1196
- "regina",
1197
- "regola",
1198
- "relatore",
1199
- "reliquia",
1200
- "remare",
1201
- "rendere",
1202
- "reparto",
1203
- "resina",
1204
- "resto",
1205
- "rete",
1206
- "retorica",
1207
- "rettile",
1208
- "revocare",
1209
- "riaprire",
1210
- "ribadire",
1211
- "ribelle",
1212
- "ricambio",
1213
- "ricetta",
1214
- "richiamo",
1215
- "ricordo",
1216
- "ridurre",
1217
- "riempire",
1218
- "riferire",
1219
- "riflesso",
1220
- "righello",
1221
- "rilancio",
1222
- "rilevare",
1223
- "rilievo",
1224
- "rimanere",
1225
- "rimborso",
1226
- "rinforzo",
1227
- "rinuncia",
1228
- "riparo",
1229
- "ripetere",
1230
- "riposare",
1231
- "ripulire",
1232
- "risalita",
1233
- "riscatto",
1234
- "riserva",
1235
- "riso",
1236
- "rispetto",
1237
- "ritaglio",
1238
- "ritmo",
1239
- "ritorno",
1240
- "ritratto",
1241
- "rituale",
1242
- "riunione",
1243
- "riuscire",
1244
- "riva",
1245
- "robotica",
1246
- "rondine",
1247
- "rosa",
1248
- "rospo",
1249
- "rosso",
1250
- "rotonda",
1251
- "rotta",
1252
- "roulotte",
1253
- "rubare",
1254
- "rubrica",
1255
- "ruffiano",
1256
- "rumore",
1257
- "ruota",
1258
- "ruscello",
1259
- "sabbia",
1260
- "sacco",
1261
- "saggio",
1262
- "sale",
1263
- "salire",
1264
- "salmone",
1265
- "salto",
1266
- "salutare",
1267
- "salvia",
1268
- "sangue",
1269
- "sanzioni",
1270
- "sapere",
1271
- "sapienza",
1272
- "sarcasmo",
1273
- "sardine",
1274
- "sartoria",
1275
- "sbalzo",
1276
- "sbarcare",
1277
- "sberla",
1278
- "sborsare",
1279
- "scadenza",
1280
- "scafo",
1281
- "scala",
1282
- "scambio",
1283
- "scappare",
1284
- "scarpa",
1285
- "scatola",
1286
- "scelta",
1287
- "scena",
1288
- "sceriffo",
1289
- "scheggia",
1290
- "schiuma",
1291
- "sciarpa",
1292
- "scienza",
1293
- "scimmia",
1294
- "sciopero",
1295
- "scivolo",
1296
- "sclerare",
1297
- "scolpire",
1298
- "sconto",
1299
- "scopa",
1300
- "scordare",
1301
- "scossa",
1302
- "scrivere",
1303
- "scrupolo",
1304
- "scuderia",
1305
- "scultore",
1306
- "scuola",
1307
- "scusare",
1308
- "sdraiare",
1309
- "secolo",
1310
- "sedativo",
1311
- "sedere",
1312
- "sedia",
1313
- "segare",
1314
- "segreto",
1315
- "seguire",
1316
- "semaforo",
1317
- "seme",
1318
- "senape",
1319
- "seno",
1320
- "sentiero",
1321
- "separare",
1322
- "sepolcro",
1323
- "sequenza",
1324
- "serata",
1325
- "serpente",
1326
- "servizio",
1327
- "sesso",
1328
- "seta",
1329
- "settore",
1330
- "sfamare",
1331
- "sfera",
1332
- "sfidare",
1333
- "sfiorare",
1334
- "sfogare",
1335
- "sgabello",
1336
- "sicuro",
1337
- "siepe",
1338
- "sigaro",
1339
- "silenzio",
1340
- "silicone",
1341
- "simbiosi",
1342
- "simpatia",
1343
- "simulare",
1344
- "sinapsi",
1345
- "sindrome",
1346
- "sinergia",
1347
- "sinonimo",
1348
- "sintonia",
1349
- "sirena",
1350
- "siringa",
1351
- "sistema",
1352
- "sito",
1353
- "smalto",
1354
- "smentire",
1355
- "smontare",
1356
- "soccorso",
1357
- "socio",
1358
- "soffitto",
1359
- "software",
1360
- "soggetto",
1361
- "sogliola",
1362
- "sognare",
1363
- "soldi",
1364
- "sole",
1365
- "sollievo",
1366
- "solo",
1367
- "sommario",
1368
- "sondare",
1369
- "sonno",
1370
- "sorpresa",
1371
- "sorriso",
1372
- "sospiro",
1373
- "sostegno",
1374
- "sovrano",
1375
- "spaccare",
1376
- "spada",
1377
- "spagnolo",
1378
- "spalla",
1379
- "sparire",
1380
- "spavento",
1381
- "spazio",
1382
- "specchio",
1383
- "spedire",
1384
- "spegnere",
1385
- "spendere",
1386
- "speranza",
1387
- "spessore",
1388
- "spezzare",
1389
- "spiaggia",
1390
- "spiccare",
1391
- "spiegare",
1392
- "spiffero",
1393
- "spingere",
1394
- "sponda",
1395
- "sporcare",
1396
- "spostare",
1397
- "spremuta",
1398
- "spugna",
1399
- "spumante",
1400
- "spuntare",
1401
- "squadra",
1402
- "squillo",
1403
- "staccare",
1404
- "stadio",
1405
- "stagione",
1406
- "stallone",
1407
- "stampa",
1408
- "stancare",
1409
- "starnuto",
1410
- "statura",
1411
- "stella",
1412
- "stendere",
1413
- "sterzo",
1414
- "stilista",
1415
- "stimolo",
1416
- "stinco",
1417
- "stiva",
1418
- "stoffa",
1419
- "storia",
1420
- "strada",
1421
- "stregone",
1422
- "striscia",
1423
- "studiare",
1424
- "stufa",
1425
- "stupendo",
1426
- "subire",
1427
- "successo",
1428
- "sudare",
1429
- "suono",
1430
- "superare",
1431
- "supporto",
1432
- "surfista",
1433
- "sussurro",
1434
- "svelto",
1435
- "svenire",
1436
- "sviluppo",
1437
- "svolta",
1438
- "svuotare",
1439
- "tabacco",
1440
- "tabella",
1441
- "tabu",
1442
- "tacchino",
1443
- "tacere",
1444
- "taglio",
1445
- "talento",
1446
- "tangente",
1447
- "tappeto",
1448
- "tartufo",
1449
- "tassello",
1450
- "tastiera",
1451
- "tavolo",
1452
- "tazza",
1453
- "teatro",
1454
- "tedesco",
1455
- "telaio",
1456
- "telefono",
1457
- "tema",
1458
- "temere",
1459
- "tempo",
1460
- "tendenza",
1461
- "tenebre",
1462
- "tensione",
1463
- "tentare",
1464
- "teologia",
1465
- "teorema",
1466
- "termica",
1467
- "terrazzo",
1468
- "teschio",
1469
- "tesi",
1470
- "tesoro",
1471
- "tessera",
1472
- "testa",
1473
- "thriller",
1474
- "tifoso",
1475
- "tigre",
1476
- "timbrare",
1477
- "timido",
1478
- "tinta",
1479
- "tirare",
1480
- "tisana",
1481
- "titano",
1482
- "titolo",
1483
- "toccare",
1484
- "togliere",
1485
- "topolino",
1486
- "torcia",
1487
- "torrente",
1488
- "tovaglia",
1489
- "traffico",
1490
- "tragitto",
1491
- "training",
1492
- "tramonto",
1493
- "transito",
1494
- "trapezio",
1495
- "trasloco",
1496
- "trattore",
1497
- "trazione",
1498
- "treccia",
1499
- "tregua",
1500
- "treno",
1501
- "triciclo",
1502
- "tridente",
1503
- "trilogia",
1504
- "tromba",
1505
- "troncare",
1506
- "trota",
1507
- "trovare",
1508
- "trucco",
1509
- "tubo",
1510
- "tulipano",
1511
- "tumulto",
1512
- "tunisia",
1513
- "tuono",
1514
- "turista",
1515
- "tuta",
1516
- "tutelare",
1517
- "tutore",
1518
- "ubriaco",
1519
- "uccello",
1520
- "udienza",
1521
- "udito",
1522
- "uffa",
1523
- "umanoide",
1524
- "umore",
1525
- "unghia",
1526
- "unguento",
1527
- "unicorno",
1528
- "unione",
1529
- "universo",
1530
- "uomo",
1531
- "uragano",
1532
- "uranio",
1533
- "urlare",
1534
- "uscire",
1535
- "utente",
1536
- "utilizzo",
1537
- "vacanza",
1538
- "vacca",
1539
- "vaglio",
1540
- "vagonata",
1541
- "valle",
1542
- "valore",
1543
- "valutare",
1544
- "valvola",
1545
- "vampiro",
1546
- "vaniglia",
1547
- "vanto",
1548
- "vapore",
1549
- "variante",
1550
- "vasca",
1551
- "vaselina",
1552
- "vassoio",
1553
- "vedere",
1554
- "vegetale",
1555
- "veglia",
1556
- "veicolo",
1557
- "vela",
1558
- "veleno",
1559
- "velivolo",
1560
- "velluto",
1561
- "vendere",
1562
- "venerare",
1563
- "venire",
1564
- "vento",
1565
- "veranda",
1566
- "verbo",
1567
- "verdura",
1568
- "vergine",
1569
- "verifica",
1570
- "vernice",
1571
- "vero",
1572
- "verruca",
1573
- "versare",
1574
- "vertebra",
1575
- "vescica",
1576
- "vespaio",
1577
- "vestito",
1578
- "vesuvio",
1579
- "veterano",
1580
- "vetro",
1581
- "vetta",
1582
- "viadotto",
1583
- "viaggio",
1584
- "vibrare",
1585
- "vicenda",
1586
- "vichingo",
1587
- "vietare",
1588
- "vigilare",
1589
- "vigneto",
1590
- "villa",
1591
- "vincere",
1592
- "violino",
1593
- "vipera",
1594
- "virgola",
1595
- "virtuoso",
1596
- "visita",
1597
- "vita",
1598
- "vitello",
1599
- "vittima",
1600
- "vivavoce",
1601
- "vivere",
1602
- "viziato",
1603
- "voglia",
1604
- "volare",
1605
- "volpe",
1606
- "volto",
1607
- "volume",
1608
- "vongole",
1609
- "voragine",
1610
- "vortice",
1611
- "votare",
1612
- "vulcano",
1613
- "vuotare",
1614
- "zabaione",
1615
- "zaffiro",
1616
- "zainetto",
1617
- "zampa",
1618
- "zanzara",
1619
- "zattera",
1620
- "zavorra",
1621
- "zenzero",
1622
- "zero",
1623
- "zingaro",
1624
- "zittire",
1625
- "zoccolo",
1626
- "zolfo",
1627
- "zombie",
1628
- "zucchero"
1629
- ];
1630
-}
\ No newline at end of file
2
+ static const words = [
3
+ "abbinare",
4
+ "abbonato",
5
+ "abisso",
6
+ "abitare",
7
+ "abominio",
8
+ "accadere",
9
+ "accesso",
10
+ "acciaio",
11
+ "accordo",
12
+ "accumulo",
13
+ "acido",
14
+ "acqua",
15
+ "acrobata",
16
+ "acustico",
17
+ "adattare",
18
+ "addetto",
19
+ "addio",
20
+ "addome",
21
+ "adeguato",
22
+ "aderire",
23
+ "adorare",
24
+ "adottare",
25
+ "adozione",
26
+ "adulto",
27
+ "aereo",
28
+ "aerobica",
29
+ "affare",
30
+ "affetto",
31
+ "affidare",
32
+ "affogato",
33
+ "affronto",
34
+ "africano",
35
+ "afrodite",
36
+ "agenzia",
37
+ "aggancio",
38
+ "aggeggio",
39
+ "aggiunta",
40
+ "agio",
41
+ "agire",
42
+ "agitare",
43
+ "aglio",
44
+ "agnello",
45
+ "agosto",
46
+ "aiutare",
47
+ "albero",
48
+ "albo",
49
+ "alce",
50
+ "alchimia",
51
+ "alcool",
52
+ "alfabeto",
53
+ "algebra",
54
+ "alimento",
55
+ "allarme",
56
+ "alleanza",
57
+ "allievo",
58
+ "alloggio",
59
+ "alluce",
60
+ "alpi",
61
+ "alterare",
62
+ "altro",
63
+ "aluminio",
64
+ "amante",
65
+ "amarezza",
66
+ "ambiente",
67
+ "ambrosia",
68
+ "america",
69
+ "amico",
70
+ "ammalare",
71
+ "ammirare",
72
+ "amnesia",
73
+ "amnistia",
74
+ "amore",
75
+ "ampliare",
76
+ "amputare",
77
+ "analisi",
78
+ "anamnesi",
79
+ "ananas",
80
+ "anarchia",
81
+ "anatra",
82
+ "anca",
83
+ "ancorato",
84
+ "andare",
85
+ "androide",
86
+ "aneddoto",
87
+ "anello",
88
+ "angelo",
89
+ "angolino",
90
+ "anguilla",
91
+ "anidride",
92
+ "anima",
93
+ "annegare",
94
+ "anno",
95
+ "annuncio",
96
+ "anomalia",
97
+ "antenna",
98
+ "anticipo",
99
+ "aperto",
100
+ "apostolo",
101
+ "appalto",
102
+ "appello",
103
+ "appiglio",
104
+ "applauso",
105
+ "appoggio",
106
+ "appurare",
107
+ "aprile",
108
+ "aquila",
109
+ "arabo",
110
+ "arachidi",
111
+ "aragosta",
112
+ "arancia",
113
+ "arbitrio",
114
+ "archivio",
115
+ "arco",
116
+ "argento",
117
+ "argilla",
118
+ "aria",
119
+ "ariete",
120
+ "arma",
121
+ "armonia",
122
+ "aroma",
123
+ "arrivare",
124
+ "arrosto",
125
+ "arsenale",
126
+ "arte",
127
+ "artiglio",
128
+ "asfalto",
129
+ "asfissia",
130
+ "asino",
131
+ "asparagi",
132
+ "aspirina",
133
+ "assalire",
134
+ "assegno",
135
+ "assolto",
136
+ "assurdo",
137
+ "asta",
138
+ "astratto",
139
+ "atlante",
140
+ "atletica",
141
+ "atomo",
142
+ "atropina",
143
+ "attacco",
144
+ "attesa",
145
+ "attico",
146
+ "atto",
147
+ "attrarre",
148
+ "auguri",
149
+ "aula",
150
+ "aumento",
151
+ "aurora",
152
+ "auspicio",
153
+ "autista",
154
+ "auto",
155
+ "autunno",
156
+ "avanzare",
157
+ "avarizia",
158
+ "avere",
159
+ "aviatore",
160
+ "avido",
161
+ "avorio",
162
+ "avvenire",
163
+ "avviso",
164
+ "avvocato",
165
+ "azienda",
166
+ "azione",
167
+ "azzardo",
168
+ "azzurro",
169
+ "babbuino",
170
+ "bacio",
171
+ "badante",
172
+ "baffi",
173
+ "bagaglio",
174
+ "bagliore",
175
+ "bagno",
176
+ "balcone",
177
+ "balena",
178
+ "ballare",
179
+ "balordo",
180
+ "balsamo",
181
+ "bambola",
182
+ "bancomat",
183
+ "banda",
184
+ "barato",
185
+ "barba",
186
+ "barista",
187
+ "barriera",
188
+ "basette",
189
+ "basilico",
190
+ "bassista",
191
+ "bastare",
192
+ "battello",
193
+ "bavaglio",
194
+ "beccare",
195
+ "beduino",
196
+ "bellezza",
197
+ "bene",
198
+ "benzina",
199
+ "berretto",
200
+ "bestia",
201
+ "bevitore",
202
+ "bianco",
203
+ "bibbia",
204
+ "biberon",
205
+ "bibita",
206
+ "bici",
207
+ "bidone",
208
+ "bilancia",
209
+ "biliardo",
210
+ "binario",
211
+ "binocolo",
212
+ "biologia",
213
+ "biondina",
214
+ "biopsia",
215
+ "biossido",
216
+ "birbante",
217
+ "birra",
218
+ "biscotto",
219
+ "bisogno",
220
+ "bistecca",
221
+ "bivio",
222
+ "blindare",
223
+ "bloccare",
224
+ "bocca",
225
+ "bollire",
226
+ "bombola",
227
+ "bonifico",
228
+ "borghese",
229
+ "borsa",
230
+ "bottino",
231
+ "botulino",
232
+ "braccio",
233
+ "bradipo",
234
+ "branco",
235
+ "bravo",
236
+ "bresaola",
237
+ "bretelle",
238
+ "brevetto",
239
+ "briciola",
240
+ "brigante",
241
+ "brillare",
242
+ "brindare",
243
+ "brivido",
244
+ "broccoli",
245
+ "brontolo",
246
+ "bruciare",
247
+ "brufolo",
248
+ "bucare",
249
+ "buddista",
250
+ "budino",
251
+ "bufera",
252
+ "buffo",
253
+ "bugiardo",
254
+ "buio",
255
+ "buono",
256
+ "burrone",
257
+ "bussola",
258
+ "bustina",
259
+ "buttare",
260
+ "cabernet",
261
+ "cabina",
262
+ "cacao",
263
+ "cacciare",
264
+ "cactus",
265
+ "cadavere",
266
+ "caffe",
267
+ "calamari",
268
+ "calcio",
269
+ "caldaia",
270
+ "calmare",
271
+ "calunnia",
272
+ "calvario",
273
+ "calzone",
274
+ "cambiare",
275
+ "camera",
276
+ "camion",
277
+ "cammello",
278
+ "campana",
279
+ "canarino",
280
+ "cancello",
281
+ "candore",
282
+ "cane",
283
+ "canguro",
284
+ "cannone",
285
+ "canoa",
286
+ "cantare",
287
+ "canzone",
288
+ "caos",
289
+ "capanna",
290
+ "capello",
291
+ "capire",
292
+ "capo",
293
+ "capperi",
294
+ "capra",
295
+ "capsula",
296
+ "caraffa",
297
+ "carbone",
298
+ "carciofo",
299
+ "cardigan",
300
+ "carenza",
301
+ "caricare",
302
+ "carota",
303
+ "carrello",
304
+ "carta",
305
+ "casa",
306
+ "cascare",
307
+ "caserma",
308
+ "cashmere",
309
+ "casino",
310
+ "cassetta",
311
+ "castello",
312
+ "catalogo",
313
+ "catena",
314
+ "catorcio",
315
+ "cattivo",
316
+ "causa",
317
+ "cauzione",
318
+ "cavallo",
319
+ "caverna",
320
+ "caviglia",
321
+ "cavo",
322
+ "cazzotto",
323
+ "celibato",
324
+ "cemento",
325
+ "cenare",
326
+ "centrale",
327
+ "ceramica",
328
+ "cercare",
329
+ "ceretta",
330
+ "cerniera",
331
+ "certezza",
332
+ "cervello",
333
+ "cessione",
334
+ "cestino",
335
+ "cetriolo",
336
+ "chiave",
337
+ "chiedere",
338
+ "chilo",
339
+ "chimera",
340
+ "chiodo",
341
+ "chirurgo",
342
+ "chitarra",
343
+ "chiudere",
344
+ "ciabatta",
345
+ "ciao",
346
+ "cibo",
347
+ "ciccia",
348
+ "cicerone",
349
+ "ciclone",
350
+ "cicogna",
351
+ "cielo",
352
+ "cifra",
353
+ "cigno",
354
+ "ciliegia",
355
+ "cimitero",
356
+ "cinema",
357
+ "cinque",
358
+ "cintura",
359
+ "ciondolo",
360
+ "ciotola",
361
+ "cipolla",
362
+ "cippato",
363
+ "circuito",
364
+ "cisterna",
365
+ "citofono",
366
+ "ciuccio",
367
+ "civetta",
368
+ "civico",
369
+ "clausola",
370
+ "cliente",
371
+ "clima",
372
+ "clinica",
373
+ "cobra",
374
+ "coccole",
375
+ "cocktail",
376
+ "cocomero",
377
+ "codice",
378
+ "coesione",
379
+ "cogliere",
380
+ "cognome",
381
+ "colla",
382
+ "colomba",
383
+ "colpire",
384
+ "coltello",
385
+ "comando",
386
+ "comitato",
387
+ "commedia",
388
+ "comodino",
389
+ "compagna",
390
+ "comune",
391
+ "concerto",
392
+ "condotto",
393
+ "conforto",
394
+ "congiura",
395
+ "coniglio",
396
+ "consegna",
397
+ "conto",
398
+ "convegno",
399
+ "coperta",
400
+ "copia",
401
+ "coprire",
402
+ "corazza",
403
+ "corda",
404
+ "corleone",
405
+ "cornice",
406
+ "corona",
407
+ "corpo",
408
+ "corrente",
409
+ "corsa",
410
+ "cortesia",
411
+ "corvo",
412
+ "coso",
413
+ "costume",
414
+ "cotone",
415
+ "cottura",
416
+ "cozza",
417
+ "crampo",
418
+ "cratere",
419
+ "cravatta",
420
+ "creare",
421
+ "credere",
422
+ "crema",
423
+ "crescere",
424
+ "crimine",
425
+ "criterio",
426
+ "croce",
427
+ "crollare",
428
+ "cronaca",
429
+ "crostata",
430
+ "croupier",
431
+ "cubetto",
432
+ "cucciolo",
433
+ "cucina",
434
+ "cultura",
435
+ "cuoco",
436
+ "cuore",
437
+ "cupido",
438
+ "cupola",
439
+ "cura",
440
+ "curva",
441
+ "cuscino",
442
+ "custode",
443
+ "danzare",
444
+ "data",
445
+ "decennio",
446
+ "decidere",
447
+ "decollo",
448
+ "dedicare",
449
+ "dedurre",
450
+ "definire",
451
+ "delegare",
452
+ "delfino",
453
+ "delitto",
454
+ "demone",
455
+ "dentista",
456
+ "denuncia",
457
+ "deposito",
458
+ "derivare",
459
+ "deserto",
460
+ "designer",
461
+ "destino",
462
+ "detonare",
463
+ "dettagli",
464
+ "diagnosi",
465
+ "dialogo",
466
+ "diamante",
467
+ "diario",
468
+ "diavolo",
469
+ "dicembre",
470
+ "difesa",
471
+ "digerire",
472
+ "digitare",
473
+ "diluvio",
474
+ "dinamica",
475
+ "dipinto",
476
+ "diploma",
477
+ "diramare",
478
+ "dire",
479
+ "dirigere",
480
+ "dirupo",
481
+ "discesa",
482
+ "disdetta",
483
+ "disegno",
484
+ "disporre",
485
+ "dissenso",
486
+ "distacco",
487
+ "dito",
488
+ "ditta",
489
+ "diva",
490
+ "divenire",
491
+ "dividere",
492
+ "divorare",
493
+ "docente",
494
+ "dolcetto",
495
+ "dolore",
496
+ "domatore",
497
+ "domenica",
498
+ "dominare",
499
+ "donatore",
500
+ "donna",
501
+ "dorato",
502
+ "dormire",
503
+ "dorso",
504
+ "dosaggio",
505
+ "dottore",
506
+ "dovere",
507
+ "download",
508
+ "dragone",
509
+ "dramma",
510
+ "dubbio",
511
+ "dubitare",
512
+ "duetto",
513
+ "durata",
514
+ "ebbrezza",
515
+ "eccesso",
516
+ "eccitare",
517
+ "eclissi",
518
+ "economia",
519
+ "edera",
520
+ "edificio",
521
+ "editore",
522
+ "edizione",
523
+ "educare",
524
+ "effetto",
525
+ "egitto",
526
+ "egiziano",
527
+ "elastico",
528
+ "elefante",
529
+ "eleggere",
530
+ "elemento",
531
+ "elenco",
532
+ "elezione",
533
+ "elmetto",
534
+ "elogio",
535
+ "embrione",
536
+ "emergere",
537
+ "emettere",
538
+ "eminenza",
539
+ "emisfero",
540
+ "emozione",
541
+ "empatia",
542
+ "energia",
543
+ "enfasi",
544
+ "enigma",
545
+ "entrare",
546
+ "enzima",
547
+ "epidemia",
548
+ "epilogo",
549
+ "episodio",
550
+ "epoca",
551
+ "equivoco",
552
+ "erba",
553
+ "erede",
554
+ "eroe",
555
+ "erotico",
556
+ "errore",
557
+ "eruzione",
558
+ "esaltare",
559
+ "esame",
560
+ "esaudire",
561
+ "eseguire",
562
+ "esempio",
563
+ "esigere",
564
+ "esistere",
565
+ "esito",
566
+ "esperto",
567
+ "espresso",
568
+ "essere",
569
+ "estasi",
570
+ "esterno",
571
+ "estrarre",
572
+ "eterno",
573
+ "etica",
574
+ "euforico",
575
+ "europa",
576
+ "evacuare",
577
+ "evasione",
578
+ "evento",
579
+ "evidenza",
580
+ "evitare",
581
+ "evolvere",
582
+ "fabbrica",
583
+ "facciata",
584
+ "fagiano",
585
+ "fagotto",
586
+ "falco",
587
+ "fame",
588
+ "famiglia",
589
+ "fanale",
590
+ "fango",
591
+ "fantasia",
592
+ "farfalla",
593
+ "farmacia",
594
+ "faro",
595
+ "fase",
596
+ "fastidio",
597
+ "faticare",
598
+ "fatto",
599
+ "favola",
600
+ "febbre",
601
+ "femmina",
602
+ "femore",
603
+ "fenomeno",
604
+ "fermata",
605
+ "feromoni",
606
+ "ferrari",
607
+ "fessura",
608
+ "festa",
609
+ "fiaba",
610
+ "fiamma",
611
+ "fianco",
612
+ "fiat",
613
+ "fibbia",
614
+ "fidare",
615
+ "fieno",
616
+ "figa",
617
+ "figlio",
618
+ "figura",
619
+ "filetto",
620
+ "filmato",
621
+ "filosofo",
622
+ "filtrare",
623
+ "finanza",
624
+ "finestra",
625
+ "fingere",
626
+ "finire",
627
+ "finta",
628
+ "finzione",
629
+ "fiocco",
630
+ "fioraio",
631
+ "firewall",
632
+ "firmare",
633
+ "fisico",
634
+ "fissare",
635
+ "fittizio",
636
+ "fiume",
637
+ "flacone",
638
+ "flagello",
639
+ "flirtare",
640
+ "flusso",
641
+ "focaccia",
642
+ "foglio",
643
+ "fognario",
644
+ "follia",
645
+ "fonderia",
646
+ "fontana",
647
+ "forbici",
648
+ "forcella",
649
+ "foresta",
650
+ "forgiare",
651
+ "formare",
652
+ "fornace",
653
+ "foro",
654
+ "fortuna",
655
+ "forzare",
656
+ "fosforo",
657
+ "fotoni",
658
+ "fracasso",
659
+ "fragola",
660
+ "frantumi",
661
+ "fratello",
662
+ "frazione",
663
+ "freccia",
664
+ "freddo",
665
+ "frenare",
666
+ "fresco",
667
+ "friggere",
668
+ "frittata",
669
+ "frivolo",
670
+ "frizione",
671
+ "fronte",
672
+ "frullato",
673
+ "frumento",
674
+ "frusta",
675
+ "frutto",
676
+ "fucile",
677
+ "fuggire",
678
+ "fulmine",
679
+ "fumare",
680
+ "funzione",
681
+ "fuoco",
682
+ "furbizia",
683
+ "furgone",
684
+ "furia",
685
+ "furore",
686
+ "fusibile",
687
+ "fuso",
688
+ "futuro",
689
+ "gabbiano",
690
+ "galassia",
691
+ "gallina",
692
+ "gamba",
693
+ "gancio",
694
+ "garanzia",
695
+ "garofano",
696
+ "gasolio",
697
+ "gatto",
698
+ "gazebo",
699
+ "gazzetta",
700
+ "gelato",
701
+ "gemelli",
702
+ "generare",
703
+ "genitori",
704
+ "gennaio",
705
+ "geologia",
706
+ "germania",
707
+ "gestire",
708
+ "gettare",
709
+ "ghepardo",
710
+ "ghiaccio",
711
+ "giaccone",
712
+ "giaguaro",
713
+ "giallo",
714
+ "giappone",
715
+ "giardino",
716
+ "gigante",
717
+ "gioco",
718
+ "gioiello",
719
+ "giorno",
720
+ "giovane",
721
+ "giraffa",
722
+ "giudizio",
723
+ "giurare",
724
+ "giusto",
725
+ "globo",
726
+ "gloria",
727
+ "glucosio",
728
+ "gnocca",
729
+ "gocciola",
730
+ "godere",
731
+ "gomito",
732
+ "gomma",
733
+ "gonfiare",
734
+ "gorilla",
735
+ "governo",
736
+ "gradire",
737
+ "graffiti",
738
+ "granchio",
739
+ "grappolo",
740
+ "grasso",
741
+ "grattare",
742
+ "gridare",
743
+ "grissino",
744
+ "grondaia",
745
+ "grugnito",
746
+ "gruppo",
747
+ "guadagno",
748
+ "guaio",
749
+ "guancia",
750
+ "guardare",
751
+ "gufo",
752
+ "guidare",
753
+ "guscio",
754
+ "gusto",
755
+ "icona",
756
+ "idea",
757
+ "identico",
758
+ "idolo",
759
+ "idoneo",
760
+ "idrante",
761
+ "idrogeno",
762
+ "igiene",
763
+ "ignoto",
764
+ "imbarco",
765
+ "immagine",
766
+ "immobile",
767
+ "imparare",
768
+ "impedire",
769
+ "impianto",
770
+ "importo",
771
+ "impresa",
772
+ "impulso",
773
+ "incanto",
774
+ "incendio",
775
+ "incidere",
776
+ "incontro",
777
+ "incrocia",
778
+ "incubo",
779
+ "indagare",
780
+ "indice",
781
+ "indotto",
782
+ "infanzia",
783
+ "inferno",
784
+ "infinito",
785
+ "infranto",
786
+ "ingerire",
787
+ "inglese",
788
+ "ingoiare",
789
+ "ingresso",
790
+ "iniziare",
791
+ "innesco",
792
+ "insalata",
793
+ "inserire",
794
+ "insicuro",
795
+ "insonnia",
796
+ "insulto",
797
+ "interno",
798
+ "introiti",
799
+ "invasori",
800
+ "inverno",
801
+ "invito",
802
+ "invocare",
803
+ "ipnosi",
804
+ "ipocrita",
805
+ "ipotesi",
806
+ "ironia",
807
+ "irrigare",
808
+ "iscritto",
809
+ "isola",
810
+ "ispirare",
811
+ "isterico",
812
+ "istinto",
813
+ "istruire",
814
+ "italiano",
815
+ "jazz",
816
+ "labbra",
817
+ "labrador",
818
+ "ladro",
819
+ "lago",
820
+ "lamento",
821
+ "lampone",
822
+ "lancetta",
823
+ "lanterna",
824
+ "lapide",
825
+ "larva",
826
+ "lasagne",
827
+ "lasciare",
828
+ "lastra",
829
+ "latte",
830
+ "laurea",
831
+ "lavagna",
832
+ "lavorare",
833
+ "leccare",
834
+ "legare",
835
+ "leggere",
836
+ "lenzuolo",
837
+ "leone",
838
+ "lepre",
839
+ "letargo",
840
+ "lettera",
841
+ "levare",
842
+ "levitare",
843
+ "lezione",
844
+ "liberare",
845
+ "libidine",
846
+ "libro",
847
+ "licenza",
848
+ "lievito",
849
+ "limite",
850
+ "lince",
851
+ "lingua",
852
+ "liquore",
853
+ "lire",
854
+ "listino",
855
+ "litigare",
856
+ "litro",
857
+ "locale",
858
+ "lottare",
859
+ "lucciola",
860
+ "lucidare",
861
+ "luglio",
862
+ "luna",
863
+ "macchina",
864
+ "madama",
865
+ "madre",
866
+ "maestro",
867
+ "maggio",
868
+ "magico",
869
+ "maglione",
870
+ "magnolia",
871
+ "mago",
872
+ "maialino",
873
+ "maionese",
874
+ "malattia",
875
+ "male",
876
+ "malloppo",
877
+ "mancare",
878
+ "mandorla",
879
+ "mangiare",
880
+ "manico",
881
+ "manopola",
882
+ "mansarda",
883
+ "mantello",
884
+ "manubrio",
885
+ "manzo",
886
+ "mappa",
887
+ "mare",
888
+ "margine",
889
+ "marinaio",
890
+ "marmotta",
891
+ "marocco",
892
+ "martello",
893
+ "marzo",
894
+ "maschera",
895
+ "matrice",
896
+ "maturare",
897
+ "mazzetta",
898
+ "meandri",
899
+ "medaglia",
900
+ "medico",
901
+ "medusa",
902
+ "megafono",
903
+ "melone",
904
+ "membrana",
905
+ "menta",
906
+ "mercato",
907
+ "meritare",
908
+ "merluzzo",
909
+ "mese",
910
+ "mestiere",
911
+ "metafora",
912
+ "meteo",
913
+ "metodo",
914
+ "mettere",
915
+ "miele",
916
+ "miglio",
917
+ "miliardo",
918
+ "mimetica",
919
+ "minatore",
920
+ "minuto",
921
+ "miracolo",
922
+ "mirtillo",
923
+ "missile",
924
+ "mistero",
925
+ "misura",
926
+ "mito",
927
+ "mobile",
928
+ "moda",
929
+ "moderare",
930
+ "moglie",
931
+ "molecola",
932
+ "molle",
933
+ "momento",
934
+ "moneta",
935
+ "mongolia",
936
+ "monologo",
937
+ "montagna",
938
+ "morale",
939
+ "morbillo",
940
+ "mordere",
941
+ "mosaico",
942
+ "mosca",
943
+ "mostro",
944
+ "motivare",
945
+ "moto",
946
+ "mulino",
947
+ "mulo",
948
+ "muovere",
949
+ "muraglia",
950
+ "muscolo",
951
+ "museo",
952
+ "musica",
953
+ "mutande",
954
+ "nascere",
955
+ "nastro",
956
+ "natale",
957
+ "natura",
958
+ "nave",
959
+ "navigare",
960
+ "negare",
961
+ "negozio",
962
+ "nemico",
963
+ "nero",
964
+ "nervo",
965
+ "nessuno",
966
+ "nettare",
967
+ "neutroni",
968
+ "neve",
969
+ "nevicare",
970
+ "nicotina",
971
+ "nido",
972
+ "nipote",
973
+ "nocciola",
974
+ "noleggio",
975
+ "nome",
976
+ "nonno",
977
+ "norvegia",
978
+ "notare",
979
+ "notizia",
980
+ "nove",
981
+ "nucleo",
982
+ "nuda",
983
+ "nuotare",
984
+ "nutrire",
985
+ "obbligo",
986
+ "occhio",
987
+ "occupare",
988
+ "oceano",
989
+ "odissea",
990
+ "odore",
991
+ "offerta",
992
+ "officina",
993
+ "offrire",
994
+ "oggetto",
995
+ "oggi",
996
+ "olfatto",
997
+ "olio",
998
+ "oliva",
999
+ "ombelico",
1000
+ "ombrello",
1001
+ "omuncolo",
1002
+ "ondata",
1003
+ "onore",
1004
+ "opera",
1005
+ "opinione",
1006
+ "opuscolo",
1007
+ "opzione",
1008
+ "orario",
1009
+ "orbita",
1010
+ "orchidea",
1011
+ "ordine",
1012
+ "orecchio",
1013
+ "orgasmo",
1014
+ "orgoglio",
1015
+ "origine",
1016
+ "orologio",
1017
+ "oroscopo",
1018
+ "orso",
1019
+ "oscurare",
1020
+ "ospedale",
1021
+ "ospite",
1022
+ "ossigeno",
1023
+ "ostacolo",
1024
+ "ostriche",
1025
+ "ottenere",
1026
+ "ottimo",
1027
+ "ottobre",
1028
+ "ovest",
1029
+ "pacco",
1030
+ "pace",
1031
+ "pacifico",
1032
+ "padella",
1033
+ "pagare",
1034
+ "pagina",
1035
+ "pagnotta",
1036
+ "palazzo",
1037
+ "palestra",
1038
+ "palpebre",
1039
+ "pancetta",
1040
+ "panfilo",
1041
+ "panino",
1042
+ "pannello",
1043
+ "panorama",
1044
+ "papa",
1045
+ "paperino",
1046
+ "paradiso",
1047
+ "parcella",
1048
+ "parente",
1049
+ "parlare",
1050
+ "parodia",
1051
+ "parrucca",
1052
+ "partire",
1053
+ "passare",
1054
+ "pasta",
1055
+ "patata",
1056
+ "patente",
1057
+ "patogeno",
1058
+ "patriota",
1059
+ "pausa",
1060
+ "pazienza",
1061
+ "peccare",
1062
+ "pecora",
1063
+ "pedalare",
1064
+ "pelare",
1065
+ "pena",
1066
+ "pendenza",
1067
+ "penisola",
1068
+ "pennello",
1069
+ "pensare",
1070
+ "pentirsi",
1071
+ "percorso",
1072
+ "perdono",
1073
+ "perfetto",
1074
+ "perizoma",
1075
+ "perla",
1076
+ "permesso",
1077
+ "persona",
1078
+ "pesare",
1079
+ "pesce",
1080
+ "peso",
1081
+ "petardo",
1082
+ "petrolio",
1083
+ "pezzo",
1084
+ "piacere",
1085
+ "pianeta",
1086
+ "piastra",
1087
+ "piatto",
1088
+ "piazza",
1089
+ "piccolo",
1090
+ "piede",
1091
+ "piegare",
1092
+ "pietra",
1093
+ "pigiama",
1094
+ "pigliare",
1095
+ "pigrizia",
1096
+ "pilastro",
1097
+ "pilota",
1098
+ "pinguino",
1099
+ "pioggia",
1100
+ "piombo",
1101
+ "pionieri",
1102
+ "piovra",
1103
+ "pipa",
1104
+ "pirata",
1105
+ "pirolisi",
1106
+ "piscina",
1107
+ "pisolino",
1108
+ "pista",
1109
+ "pitone",
1110
+ "piumino",
1111
+ "pizza",
1112
+ "plastica",
1113
+ "platino",
1114
+ "poesia",
1115
+ "poiana",
1116
+ "polaroid",
1117
+ "polenta",
1118
+ "polimero",
1119
+ "pollo",
1120
+ "polmone",
1121
+ "polpetta",
1122
+ "poltrona",
1123
+ "pomodoro",
1124
+ "pompa",
1125
+ "popolo",
1126
+ "porco",
1127
+ "porta",
1128
+ "porzione",
1129
+ "possesso",
1130
+ "postino",
1131
+ "potassio",
1132
+ "potere",
1133
+ "poverino",
1134
+ "pranzo",
1135
+ "prato",
1136
+ "prefisso",
1137
+ "prelievo",
1138
+ "premio",
1139
+ "prendere",
1140
+ "prestare",
1141
+ "pretesa",
1142
+ "prezzo",
1143
+ "primario",
1144
+ "privacy",
1145
+ "problema",
1146
+ "processo",
1147
+ "prodotto",
1148
+ "profeta",
1149
+ "progetto",
1150
+ "promessa",
1151
+ "pronto",
1152
+ "proposta",
1153
+ "proroga",
1154
+ "prossimo",
1155
+ "proteina",
1156
+ "prova",
1157
+ "prudenza",
1158
+ "pubblico",
1159
+ "pudore",
1160
+ "pugilato",
1161
+ "pulire",
1162
+ "pulsante",
1163
+ "puntare",
1164
+ "pupazzo",
1165
+ "puzzle",
1166
+ "quaderno",
1167
+ "qualcuno",
1168
+ "quarzo",
1169
+ "quercia",
1170
+ "quintale",
1171
+ "rabbia",
1172
+ "racconto",
1173
+ "radice",
1174
+ "raffica",
1175
+ "ragazza",
1176
+ "ragione",
1177
+ "rammento",
1178
+ "ramo",
1179
+ "rana",
1180
+ "randagio",
1181
+ "rapace",
1182
+ "rapinare",
1183
+ "rapporto",
1184
+ "rasatura",
1185
+ "ravioli",
1186
+ "reagire",
1187
+ "realista",
1188
+ "reattore",
1189
+ "reazione",
1190
+ "recitare",
1191
+ "recluso",
1192
+ "record",
1193
+ "recupero",
1194
+ "redigere",
1195
+ "regalare",
1196
+ "regina",
1197
+ "regola",
1198
+ "relatore",
1199
+ "reliquia",
1200
+ "remare",
1201
+ "rendere",
1202
+ "reparto",
1203
+ "resina",
1204
+ "resto",
1205
+ "rete",
1206
+ "retorica",
1207
+ "rettile",
1208
+ "revocare",
1209
+ "riaprire",
1210
+ "ribadire",
1211
+ "ribelle",
1212
+ "ricambio",
1213
+ "ricetta",
1214
+ "richiamo",
1215
+ "ricordo",
1216
+ "ridurre",
1217
+ "riempire",
1218
+ "riferire",
1219
+ "riflesso",
1220
+ "righello",
1221
+ "rilancio",
1222
+ "rilevare",
1223
+ "rilievo",
1224
+ "rimanere",
1225
+ "rimborso",
1226
+ "rinforzo",
1227
+ "rinuncia",
1228
+ "riparo",
1229
+ "ripetere",
1230
+ "riposare",
1231
+ "ripulire",
1232
+ "risalita",
1233
+ "riscatto",
1234
+ "riserva",
1235
+ "riso",
1236
+ "rispetto",
1237
+ "ritaglio",
1238
+ "ritmo",
1239
+ "ritorno",
1240
+ "ritratto",
1241
+ "rituale",
1242
+ "riunione",
1243
+ "riuscire",
1244
+ "riva",
1245
+ "robotica",
1246
+ "rondine",
1247
+ "rosa",
1248
+ "rospo",
1249
+ "rosso",
1250
+ "rotonda",
1251
+ "rotta",
1252
+ "roulotte",
1253
+ "rubare",
1254
+ "rubrica",
1255
+ "ruffiano",
1256
+ "rumore",
1257
+ "ruota",
1258
+ "ruscello",
1259
+ "sabbia",
1260
+ "sacco",
1261
+ "saggio",
1262
+ "sale",
1263
+ "salire",
1264
+ "salmone",
1265
+ "salto",
1266
+ "salutare",
1267
+ "salvia",
1268
+ "sangue",
1269
+ "sanzioni",
1270
+ "sapere",
1271
+ "sapienza",
1272
+ "sarcasmo",
1273
+ "sardine",
1274
+ "sartoria",
1275
+ "sbalzo",
1276
+ "sbarcare",
1277
+ "sberla",
1278
+ "sborsare",
1279
+ "scadenza",
1280
+ "scafo",
1281
+ "scala",
1282
+ "scambio",
1283
+ "scappare",
1284
+ "scarpa",
1285
+ "scatola",
1286
+ "scelta",
1287
+ "scena",
1288
+ "sceriffo",
1289
+ "scheggia",
1290
+ "schiuma",
1291
+ "sciarpa",
1292
+ "scienza",
1293
+ "scimmia",
1294
+ "sciopero",
1295
+ "scivolo",
1296
+ "sclerare",
1297
+ "scolpire",
1298
+ "sconto",
1299
+ "scopa",
1300
+ "scordare",
1301
+ "scossa",
1302
+ "scrivere",
1303
+ "scrupolo",
1304
+ "scuderia",
1305
+ "scultore",
1306
+ "scuola",
1307
+ "scusare",
1308
+ "sdraiare",
1309
+ "secolo",
1310
+ "sedativo",
1311
+ "sedere",
1312
+ "sedia",
1313
+ "segare",
1314
+ "segreto",
1315
+ "seguire",
1316
+ "semaforo",
1317
+ "seme",
1318
+ "senape",
1319
+ "seno",
1320
+ "sentiero",
1321
+ "separare",
1322
+ "sepolcro",
1323
+ "sequenza",
1324
+ "serata",
1325
+ "serpente",
1326
+ "servizio",
1327
+ "sesso",
1328
+ "seta",
1329
+ "settore",
1330
+ "sfamare",
1331
+ "sfera",
1332
+ "sfidare",
1333
+ "sfiorare",
1334
+ "sfogare",
1335
+ "sgabello",
1336
+ "sicuro",
1337
+ "siepe",
1338
+ "sigaro",
1339
+ "silenzio",
1340
+ "silicone",
1341
+ "simbiosi",
1342
+ "simpatia",
1343
+ "simulare",
1344
+ "sinapsi",
1345
+ "sindrome",
1346
+ "sinergia",
1347
+ "sinonimo",
1348
+ "sintonia",
1349
+ "sirena",
1350
+ "siringa",
1351
+ "sistema",
1352
+ "sito",
1353
+ "smalto",
1354
+ "smentire",
1355
+ "smontare",
1356
+ "soccorso",
1357
+ "socio",
1358
+ "soffitto",
1359
+ "software",
1360
+ "soggetto",
1361
+ "sogliola",
1362
+ "sognare",
1363
+ "soldi",
1364
+ "sole",
1365
+ "sollievo",
1366
+ "solo",
1367
+ "sommario",
1368
+ "sondare",
1369
+ "sonno",
1370
+ "sorpresa",
1371
+ "sorriso",
1372
+ "sospiro",
1373
+ "sostegno",
1374
+ "sovrano",
1375
+ "spaccare",
1376
+ "spada",
1377
+ "spagnolo",
1378
+ "spalla",
1379
+ "sparire",
1380
+ "spavento",
1381
+ "spazio",
1382
+ "specchio",
1383
+ "spedire",
1384
+ "spegnere",
1385
+ "spendere",
1386
+ "speranza",
1387
+ "spessore",
1388
+ "spezzare",
1389
+ "spiaggia",
1390
+ "spiccare",
1391
+ "spiegare",
1392
+ "spiffero",
1393
+ "spingere",
1394
+ "sponda",
1395
+ "sporcare",
1396
+ "spostare",
1397
+ "spremuta",
1398
+ "spugna",
1399
+ "spumante",
1400
+ "spuntare",
1401
+ "squadra",
1402
+ "squillo",
1403
+ "staccare",
1404
+ "stadio",
1405
+ "stagione",
1406
+ "stallone",
1407
+ "stampa",
1408
+ "stancare",
1409
+ "starnuto",
1410
+ "statura",
1411
+ "stella",
1412
+ "stendere",
1413
+ "sterzo",
1414
+ "stilista",
1415
+ "stimolo",
1416
+ "stinco",
1417
+ "stiva",
1418
+ "stoffa",
1419
+ "storia",
1420
+ "strada",
1421
+ "stregone",
1422
+ "striscia",
1423
+ "studiare",
1424
+ "stufa",
1425
+ "stupendo",
1426
+ "subire",
1427
+ "successo",
1428
+ "sudare",
1429
+ "suono",
1430
+ "superare",
1431
+ "supporto",
1432
+ "surfista",
1433
+ "sussurro",
1434
+ "svelto",
1435
+ "svenire",
1436
+ "sviluppo",
1437
+ "svolta",
1438
+ "svuotare",
1439
+ "tabacco",
1440
+ "tabella",
1441
+ "tabu",
1442
+ "tacchino",
1443
+ "tacere",
1444
+ "taglio",
1445
+ "talento",
1446
+ "tangente",
1447
+ "tappeto",
1448
+ "tartufo",
1449
+ "tassello",
1450
+ "tastiera",
1451
+ "tavolo",
1452
+ "tazza",
1453
+ "teatro",
1454
+ "tedesco",
1455
+ "telaio",
1456
+ "telefono",
1457
+ "tema",
1458
+ "temere",
1459
+ "tempo",
1460
+ "tendenza",
1461
+ "tenebre",
1462
+ "tensione",
1463
+ "tentare",
1464
+ "teologia",
1465
+ "teorema",
1466
+ "termica",
1467
+ "terrazzo",
1468
+ "teschio",
1469
+ "tesi",
1470
+ "tesoro",
1471
+ "tessera",
1472
+ "testa",
1473
+ "thriller",
1474
+ "tifoso",
1475
+ "tigre",
1476
+ "timbrare",
1477
+ "timido",
1478
+ "tinta",
1479
+ "tirare",
1480
+ "tisana",
1481
+ "titano",
1482
+ "titolo",
1483
+ "toccare",
1484
+ "togliere",
1485
+ "topolino",
1486
+ "torcia",
1487
+ "torrente",
1488
+ "tovaglia",
1489
+ "traffico",
1490
+ "tragitto",
1491
+ "training",
1492
+ "tramonto",
1493
+ "transito",
1494
+ "trapezio",
1495
+ "trasloco",
1496
+ "trattore",
1497
+ "trazione",
1498
+ "treccia",
1499
+ "tregua",
1500
+ "treno",
1501
+ "triciclo",
1502
+ "tridente",
1503
+ "trilogia",
1504
+ "tromba",
1505
+ "troncare",
1506
+ "trota",
1507
+ "trovare",
1508
+ "trucco",
1509
+ "tubo",
1510
+ "tulipano",
1511
+ "tumulto",
1512
+ "tunisia",
1513
+ "tuono",
1514
+ "turista",
1515
+ "tuta",
1516
+ "tutelare",
1517
+ "tutore",
1518
+ "ubriaco",
1519
+ "uccello",
1520
+ "udienza",
1521
+ "udito",
1522
+ "uffa",
1523
+ "umanoide",
1524
+ "umore",
1525
+ "unghia",
1526
+ "unguento",
1527
+ "unicorno",
1528
+ "unione",
1529
+ "universo",
1530
+ "uomo",
1531
+ "uragano",
1532
+ "uranio",
1533
+ "urlare",
1534
+ "uscire",
1535
+ "utente",
1536
+ "utilizzo",
1537
+ "vacanza",
1538
+ "vacca",
1539
+ "vaglio",
1540
+ "vagonata",
1541
+ "valle",
1542
+ "valore",
1543
+ "valutare",
1544
+ "valvola",
1545
+ "vampiro",
1546
+ "vaniglia",
1547
+ "vanto",
1548
+ "vapore",
1549
+ "variante",
1550
+ "vasca",
1551
+ "vaselina",
1552
+ "vassoio",
1553
+ "vedere",
1554
+ "vegetale",
1555
+ "veglia",
1556
+ "veicolo",
1557
+ "vela",
1558
+ "veleno",
1559
+ "velivolo",
1560
+ "velluto",
1561
+ "vendere",
1562
+ "venerare",
1563
+ "venire",
1564
+ "vento",
1565
+ "veranda",
1566
+ "verbo",
1567
+ "verdura",
1568
+ "vergine",
1569
+ "verifica",
1570
+ "vernice",
1571
+ "vero",
1572
+ "verruca",
1573
+ "versare",
1574
+ "vertebra",
1575
+ "vescica",
1576
+ "vespaio",
1577
+ "vestito",
1578
+ "vesuvio",
1579
+ "veterano",
1580
+ "vetro",
1581
+ "vetta",
1582
+ "viadotto",
1583
+ "viaggio",
1584
+ "vibrare",
1585
+ "vicenda",
1586
+ "vichingo",
1587
+ "vietare",
1588
+ "vigilare",
1589
+ "vigneto",
1590
+ "villa",
1591
+ "vincere",
1592
+ "violino",
1593
+ "vipera",
1594
+ "virgola",
1595
+ "virtuoso",
1596
+ "visita",
1597
+ "vita",
1598
+ "vitello",
1599
+ "vittima",
1600
+ "vivavoce",
1601
+ "vivere",
1602
+ "viziato",
1603
+ "voglia",
1604
+ "volare",
1605
+ "volpe",
1606
+ "volto",
1607
+ "volume",
1608
+ "vongole",
1609
+ "voragine",
1610
+ "vortice",
1611
+ "votare",
1612
+ "vulcano",
1613
+ "vuotare",
1614
+ "zabaione",
1615
+ "zaffiro",
1616
+ "zainetto",
1617
+ "zampa",
1618
+ "zanzara",
1619
+ "zattera",
1620
+ "zavorra",
1621
+ "zenzero",
1622
+ "zero",
1623
+ "zingaro",
1624
+ "zittire",
1625
+ "zoccolo",
1626
+ "zolfo",
1627
+ "zombie",
1628
+ "zucchero"
1629
+ ];
1630
+}
cw_monero/lib/mnemonics/japanese.dart
+1
-1
@@ -1627,4 +1627,4 @@ class JapaneseMnemonics {
1627
"びじゅつかん",
1628
"ひしょ"
1629
];
1630
-}
\ No newline at end of file
1630
+}
cw_monero/lib/mnemonics/portuguese.dart
+1
-1
@@ -1627,4 +1627,4 @@ class PortugueseMnemonics {
1627
"zenite",
1628
"zumbi"
1629
];
1630
-}
\ No newline at end of file
1630
+}
cw_monero/lib/mnemonics/russian.dart
+1
-1
@@ -1627,4 +1627,4 @@ class RussianMnemonics {
1627
"ячейка",
1628
"ящик"
1629
];
1630
-}
\ No newline at end of file
1630
+}
cw_monero/lib/mnemonics/spanish.dart
+1
-1
@@ -1627,4 +1627,4 @@ class SpanishMnemonics {
1627
"ritmo",
1628
"rito"
1629
];
1630
-}
\ No newline at end of file
1630
+}
cw_monero/lib/monero_account_list.dart
+13
-12
@@ -46,26 +46,27 @@ abstract class MoneroAccountListBase with Store {
46
}
47
48
static Map<int, List<Account>> cachedAccounts = {};
49
-
49
+
50
List<Account> getAll() {
51
final allAccounts = account_list.getAllAccount();
52
final currentCount = allAccounts.length;
53
cachedAccounts[account_list.currentWallet!.ffiAddress()] ??= [];
54
-
54
+
55
if (cachedAccounts[account_list.currentWallet!.ffiAddress()]!.length == currentCount) {
56
return cachedAccounts[account_list.currentWallet!.ffiAddress()]!;
57
}
58
-
58
+
59
cachedAccounts[account_list.currentWallet!.ffiAddress()] = allAccounts.map((accountRow) {
60
- final balance = accountRow.getUnlockedBalance();
61
-
62
- return Account(
63
- id: accountRow.getRowId(),
64
- label: accountRow.getLabel(),
65
- balance: moneroAmountToString(amount: account_list.currentWallet!.amountFromString(balance)),
66
- );
67
- }).toList();
68
-
60
+ final balance = accountRow.getUnlockedBalance();
61
+
62
+ return Account(
63
+ id: accountRow.getRowId(),
64
+ label: accountRow.getLabel(),
65
+ balance:
66
+ moneroAmountToString(amount: account_list.currentWallet!.amountFromString(balance)),
67
+ );
68
+ }).toList();
69
+
70
return cachedAccounts[account_list.currentWallet!.ffiAddress()]!;
71
}
72
cw_monero/lib/monero_subaddress_list.dart
+13
-11
@@ -45,7 +45,7 @@ abstract class MoneroSubaddressListBase with Store {
45
}
46
47
Future<List<Subaddress>> getAll() async {
48
- var subaddresses = await subaddress_list.getAllSubaddresses();
48
+ var subaddresses = await subaddress_list.getAllSubaddresses();
49
50
if (subaddresses.length > 2) {
51
final primary = subaddresses.first;
@@ -60,7 +60,7 @@ abstract class MoneroSubaddressListBase with Store {
60
return Subaddress(
61
id: id,
62
address: address,
63
- balance: (s.received/1e12).toStringAsFixed(6),
63
+ balance: (s.received / 1e12).toStringAsFixed(6),
64
txCount: s.txCount,
65
label: label);
66
}).toList();
@@ -138,15 +138,17 @@ abstract class MoneroSubaddressListBase with Store {
138
final address = s.address;
139
final label = s.label;
140
return Subaddress(
141
- id: id,
142
- address: address,
143
- balance: (s.received/1e12).toStringAsFixed(6),
144
- txCount: s.txCount,
145
- label: id == 0 &&
146
- label.toLowerCase() == 'Primary account'.toLowerCase()
147
- ? 'Primary address'
148
- : label);
149
- }).toList().reversed.toList();
141
+ id: id,
142
+ address: address,
143
+ balance: (s.received / 1e12).toStringAsFixed(6),
144
+ txCount: s.txCount,
145
+ label: id == 0 && label.toLowerCase() == 'Primary account'.toLowerCase()
146
+ ? 'Primary address'
147
+ : label);
148
+ })
149
+ .toList()
150
+ .reversed
151
+ .toList();
152
}
153
154
Future<bool> _newSubaddress({required int accountIndex, required String label}) async {
cw_monero/lib/monero_transaction_history.dart
+4
-7
@@ -5,11 +5,10 @@ import 'package:cw_monero/monero_transaction_info.dart';
5
6
part 'monero_transaction_history.g.dart';
7
8
-class MoneroTransactionHistory = MoneroTransactionHistoryBase
9
- with _$MoneroTransactionHistory;
8
+class MoneroTransactionHistory = MoneroTransactionHistoryBase with _$MoneroTransactionHistory;
9
11
-abstract class MoneroTransactionHistoryBase
12
- extends TransactionHistoryBase<MoneroTransactionInfo> with Store {
10
+abstract class MoneroTransactionHistoryBase extends TransactionHistoryBase<MoneroTransactionInfo>
11
+ with Store {
12
MoneroTransactionHistoryBase() {
13
transactions = ObservableMap<String, MoneroTransactionInfo>();
14
}
@@ -18,11 +17,9 @@ abstract class MoneroTransactionHistoryBase
17
Future<void> save() async {}
18
19
@override
21
- void addOne(MoneroTransactionInfo transaction) =>
22
- transactions[transaction.id] = transaction;
20
+ void addOne(MoneroTransactionInfo transaction) => transactions[transaction.id] = transaction;
21
22
@override
23
void addMany(Map<String, MoneroTransactionInfo> transactions) =>
24
this.transactions.addAll(transactions);
27
-
25
}
cw_monero/lib/monero_wallet.dart
+55
-76
@@ -52,8 +52,8 @@ const MIN_RESTORE_HEIGHT = 1000;
52
53
class MoneroWallet = MoneroWalletBase with _$MoneroWallet;
54
55
-abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
56
- MoneroTransactionHistory, MoneroTransactionInfo> with Store {
55
+abstract class MoneroWalletBase
56
+ extends WalletBase<MoneroBalance, MoneroTransactionHistory, MoneroTransactionInfo> with Store {
57
MoneroWalletBase(
58
{required WalletInfo walletInfo,
59
required DerivationInfo derivationInfo,
@@ -76,16 +76,13 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
76
transactionHistory = MoneroTransactionHistory();
77
walletAddresses = MoneroWalletAddresses(walletInfo, transactionHistory);
78
79
- _onAccountChangeReaction =
80
- reaction((_) => walletAddresses.account, (Account? account) {
79
+ _onAccountChangeReaction = reaction((_) => walletAddresses.account, (Account? account) {
80
if (account == null) return;
81
83
- balance = ObservableMap<CryptoCurrency, MoneroBalance>.of(<CryptoCurrency,
84
- MoneroBalance>{
82
+ balance = ObservableMap<CryptoCurrency, MoneroBalance>.of(<CryptoCurrency, MoneroBalance>{
83
currency: MoneroBalance(
84
fullBalance: monero_wallet.getFullBalance(accountIndex: account.id),
87
- unlockedBalance:
88
- monero_wallet.getUnlockedBalance(accountIndex: account.id))
85
+ unlockedBalance: monero_wallet.getUnlockedBalance(accountIndex: account.id))
86
});
87
_updateSubAddress(isEnabledAutoGenerateSubaddress, account: account);
88
unawaited(updateTransactions());
@@ -143,7 +140,8 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
140
passphrase: monero_wallet.getPassphrase());
141
142
int? get restoreHeight =>
146
- transactionHistory.transactions.values.firstOrNull?.height ?? currentWallet?.getRefreshFromBlockHeight();
143
+ transactionHistory.transactions.values.firstOrNull?.height ??
144
+ currentWallet?.getRefreshFromBlockHeight();
145
146
monero_wallet.SyncListener? _listener;
147
ReactionDisposer? _onAccountChangeReaction;
@@ -156,13 +154,11 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
154
155
Future<void> init() async {
156
await walletAddresses.init();
159
- balance = ObservableMap<CryptoCurrency, MoneroBalance>.of(<CryptoCurrency,
160
- MoneroBalance>{
157
+ balance = ObservableMap<CryptoCurrency, MoneroBalance>.of(<CryptoCurrency, MoneroBalance>{
158
currency: MoneroBalance(
162
- fullBalance: monero_wallet.getFullBalance(
163
- accountIndex: walletAddresses.account!.id),
164
- unlockedBalance: monero_wallet.getUnlockedBalance(
165
- accountIndex: walletAddresses.account!.id))
159
+ fullBalance: monero_wallet.getFullBalance(accountIndex: walletAddresses.account!.id),
160
+ unlockedBalance:
161
+ monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account!.id))
162
});
163
_setListeners();
164
await updateTransactions();
@@ -171,16 +167,15 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
167
monero_wallet.setRecoveringFromSeed(isRecovery: walletInfo.isRecovery);
168
169
if (monero_wallet.getCurrentHeight() <= 1) {
174
- monero_wallet.setRefreshFromBlockHeight(
175
- height: walletInfo.restoreHeight);
170
+ monero_wallet.setRefreshFromBlockHeight(height: walletInfo.restoreHeight);
171
setupBackgroundSync(password, currentWallet!);
172
}
173
}
174
180
- _autoSaveTimer = Timer.periodic(
181
- Duration(seconds: _autoSaveInterval), (_) async => await save());
175
+ _autoSaveTimer =
176
+ Timer.periodic(Duration(seconds: _autoSaveInterval), (_) async => await save());
177
// update transaction details after restore
183
- await walletAddresses.subaddressList.update(accountIndex: walletAddresses.account?.id??0);
178
+ await walletAddresses.subaddressList.update(accountIndex: walletAddresses.account?.id ?? 0);
179
}
180
181
@override
@@ -191,11 +186,11 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
186
try {
187
// Check if the wallet is currently connected to the daemon
188
final isConnected = await monero_wallet.isConnected();
194
-
189
+
190
if (!isConnected) {
191
return false; // It's not connected to daemon
192
}
198
-
193
+
194
// Check to get current node height to ensure daemon is responsive
195
final nodeHeight = await monero_wallet.getNodeHeight();
196
return nodeHeight > 0;
@@ -420,14 +415,14 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
415
}
416
return await _createTransaction(credentials);
417
}
423
-
418
+
419
Future<PendingTransaction> _createTransaction(Object credentials) async {
420
final _credentials = credentials as MoneroTransactionCreationCredentials;
421
final inputs = <String>[];
422
final outputs = _credentials.outputs;
423
final hasMultiDestination = outputs.length > 1;
429
- final unlockedBalance = monero_wallet.getUnlockedBalance(
430
- accountIndex: walletAddresses.account!.id);
424
+ final unlockedBalance =
425
+ monero_wallet.getUnlockedBalance(accountIndex: walletAddresses.account!.id);
426
427
PendingTransactionDescription pendingTransactionDescription;
428
@@ -462,17 +457,15 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
457
return MoneroOutput(address: outputAddress!, amount: output.cryptoAmount.toString());
458
}).toList();
459
465
- pendingTransactionDescription =
466
- await transaction_history.createTransactionMultDest(
467
- outputs: moneroOutputs,
468
- priorityRaw: _credentials.priority.serialize(),
469
- accountIndex: walletAddresses.account!.id,
470
- paymentId: "",
471
- preferredInputs: inputs);
460
+ pendingTransactionDescription = await transaction_history.createTransactionMultDest(
461
+ outputs: moneroOutputs,
462
+ priorityRaw: _credentials.priority.serialize(),
463
+ accountIndex: walletAddresses.account!.id,
464
+ paymentId: "",
465
+ preferredInputs: inputs);
466
} else {
467
final output = outputs.first;
474
- final address =
475
- output.isParsedAddress ? output.extractedAddress : output.address;
468
+ final address = output.isParsedAddress ? output.extractedAddress : output.address;
469
final amount = output.sendAll ? null : output.cryptoAmount.toString();
470
471
// if ((formattedAmount != null && unlockedBalance < formattedAmount) ||
@@ -484,14 +477,13 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
477
// }
478
479
if (inputs.isEmpty) MoneroTransactionCreationException('No inputs selected');
487
- pendingTransactionDescription =
488
- await transaction_history.createTransactionSync(
489
- address: address!,
490
- amount: amount,
491
- priorityRaw: _credentials.priority.serialize(),
492
- accountIndex: walletAddresses.account!.id,
493
- preferredInputs: inputs,
494
- paymentId: '');
480
+ pendingTransactionDescription = await transaction_history.createTransactionSync(
481
+ address: address!,
482
+ amount: amount,
483
+ priorityRaw: _credentials.priority.serialize(),
484
+ accountIndex: walletAddresses.account!.id,
485
+ preferredInputs: inputs,
486
+ paymentId: '');
487
}
488
489
// final status = monero.PendingTransaction_status(pendingTransactionDescription);
@@ -569,17 +561,15 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
561
}
562
try {
563
// -- rename the waller folder --
572
- final currentWalletDir =
573
- Directory(await pathForWalletDir(name: name, type: type));
574
- final newWalletDirPath =
575
- await pathForWalletDir(name: newWalletName, type: type);
576
-
564
+ final currentWalletDir = Directory(await pathForWalletDir(name: name, type: type));
565
+ final newWalletDirPath = await pathForWalletDir(name: newWalletName, type: type);
566
+
567
// Create new directory if it doesn't exist
568
await Directory(newWalletDirPath).create(recursive: true);
579
-
569
+
570
// -- use new waller folder to copy files with old names still --
571
final currentWalletPath = currentWalletDir.path + '/$name';
582
-
572
+
573
final currentCacheFile = File(currentWalletPath);
574
final currentKeysFile = File('$currentWalletPath.keys');
575
final currentAddressListFile = File('$currentWalletPath.address.txt');
@@ -599,7 +589,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
589
}
590
591
await currentWalletDir.delete(recursive: true);
602
-
592
+
593
await backupWalletFiles(newWalletName);
594
} catch (e) {
595
final currentWalletPath = await pathForWallet(name: name, type: type);
@@ -608,8 +598,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
598
final currentKeysFile = File('$currentWalletPath.keys');
599
final currentAddressListFile = File('$currentWalletPath.address.txt');
600
611
- final newWalletPath =
612
- await pathForWallet(name: newWalletName, type: type);
601
+ final newWalletPath = await pathForWallet(name: newWalletName, type: type);
602
603
// Copies current wallet files into new wallet name's dir and files
604
if (currentCacheFile.existsSync()) {
@@ -628,8 +617,7 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
617
}
618
619
@override
631
- Future<void> changePassword(String password) async =>
632
- monero_wallet.setPasswordSync(password);
620
+ Future<void> changePassword(String password) async => monero_wallet.setPasswordSync(password);
621
622
Future<int> getNodeHeight() async => monero_wallet.getNodeHeight();
623
@@ -740,15 +728,13 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
728
Future<void> _refreshUnspentCoinsInfo() async {
729
try {
730
final List<dynamic> keys = <dynamic>[];
743
- final currentWalletUnspentCoins = unspentCoinsInfo.values.where(
744
- (element) =>
745
- element.walletId.contains(id) &&
746
- element.accountIndex == walletAddresses.account!.id);
731
+ final currentWalletUnspentCoins = unspentCoinsInfo.values.where((element) =>
732
+ element.walletId.contains(id) && element.accountIndex == walletAddresses.account!.id);
733
734
if (currentWalletUnspentCoins.isNotEmpty) {
735
currentWalletUnspentCoins.forEach((element) {
750
- final existUnspentCoins = unspentCoins
751
- .where((coin) => element.keyImage!.contains(coin.keyImage!));
736
+ final existUnspentCoins =
737
+ unspentCoins.where((coin) => element.keyImage!.contains(coin.keyImage!));
738
739
if (existUnspentCoins.isEmpty) {
740
keys.add(element.key);
@@ -765,15 +751,13 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
751
}
752
753
String getTransactionAddress(int accountIndex, int addressIndex) =>
768
- monero_wallet.getAddress(
769
- accountIndex: accountIndex, addressIndex: addressIndex);
754
+ monero_wallet.getAddress(accountIndex: accountIndex, addressIndex: addressIndex);
755
756
@override
757
Future<Map<String, MoneroTransactionInfo>> fetchTransactions() async {
758
await transaction_history.refreshTransactions();
759
final resp = (await _getAllTransactionsOfAccount(walletAddresses.account?.id))
775
- .fold<Map<String, MoneroTransactionInfo>>(
776
- <String, MoneroTransactionInfo>{},
760
+ .fold<Map<String, MoneroTransactionInfo>>(<String, MoneroTransactionInfo>{},
761
(Map<String, MoneroTransactionInfo> acc, MoneroTransactionInfo tx) {
762
acc[tx.id] = tx;
763
return acc;
@@ -794,14 +778,12 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
778
779
final currentIds = transactionHistory.transactions.keys.toSet();
780
final newIds = transactions.keys.toSet();
797
-
781
+
782
// Remove transactions that no longer exist
799
- currentIds.difference(newIds).forEach((id) =>
800
- transactionHistory.transactions.remove(id));
801
-
783
+ currentIds.difference(newIds).forEach((id) => transactionHistory.transactions.remove(id));
784
+
785
// Add or update transactions
803
- transactions.forEach((key, tx) =>
804
- transactionHistory.transactions[key] = tx);
786
+ transactions.forEach((key, tx) => transactionHistory.transactions[key] = tx);
787
await transactionHistory.save();
788
_isTransactionUpdating = false;
789
} catch (e) {
@@ -814,21 +796,18 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
796
monero_wallet.getSubaddressLabel(accountIndex, addressIndex);
797
798
Future<List<MoneroTransactionInfo>> _getAllTransactionsOfAccount(int? accountIndex) async =>
817
- (await transaction_history
818
- .getAllTransactions())
799
+ (await transaction_history.getAllTransactions())
800
.map(
801
(row) => MoneroTransactionInfo(
802
row.hash,
803
row.blockheight,
823
- row.isSpend
824
- ? TransactionDirection.outgoing
825
- : TransactionDirection.incoming,
804
+ row.isSpend ? TransactionDirection.outgoing : TransactionDirection.incoming,
805
row.timeStamp,
806
row.isPending,
807
Money.fromInt(row.amount, currency),
808
row.accountIndex,
809
0,
831
- Money.fromInt(row.fee,currency),
810
+ Money.fromInt(row.fee, currency),
811
row.confirmations,
812
)..additionalInfo = <String, dynamic>{
813
'key': row.key,
cw_monero/lib/monero_wallet_addresses.dart
+21
-13
@@ -34,24 +34,28 @@ abstract class MoneroWalletAddressesBase extends WalletAddresses with Store {
34
35
@override
36
String get latestAddress {
37
- var addressIndex = subaddress_list.numSubaddresses(account?.id??0) - 1;
38
- var address = getAddress(accountIndex: account?.id??0, addressIndex: addressIndex);
37
+ var addressIndex = subaddress_list.numSubaddresses(account?.id ?? 0) - 1;
38
+ var address = getAddress(accountIndex: account?.id ?? 0, addressIndex: addressIndex);
39
while (hiddenAddresses.contains(address)) {
40
addressIndex++;
41
- address = getAddress(accountIndex: account?.id??0, addressIndex: addressIndex);
42
- subaddressList.update(accountIndex: account?.id??0);
41
+ address = getAddress(accountIndex: account?.id ?? 0, addressIndex: addressIndex);
42
+ subaddressList.update(accountIndex: account?.id ?? 0);
43
}
44
return address;
45
}
46
47
@override
48
String get addressForExchange {
49
- var addressIndex = subaddress_list.numSubaddresses(account?.id??0) - 1;
50
- var address = getAddress(accountIndex: account?.id??0, addressIndex: addressIndex);
51
- while (hiddenAddresses.contains(address) || manualAddresses.contains(address) || subaddress_list.getRawLabel(accountIndex: account?.id??0, addressIndex: addressIndex).isNotEmpty) {
49
+ var addressIndex = subaddress_list.numSubaddresses(account?.id ?? 0) - 1;
50
+ var address = getAddress(accountIndex: account?.id ?? 0, addressIndex: addressIndex);
51
+ while (hiddenAddresses.contains(address) ||
52
+ manualAddresses.contains(address) ||
53
+ subaddress_list
54
+ .getRawLabel(accountIndex: account?.id ?? 0, addressIndex: addressIndex)
55
+ .isNotEmpty) {
56
addressIndex++;
53
- address = getAddress(accountIndex: account?.id??0, addressIndex: addressIndex);
54
- subaddressList.update(accountIndex: account?.id??0);
57
+ address = getAddress(accountIndex: account?.id ?? 0, addressIndex: addressIndex);
58
+ subaddressList.update(accountIndex: account?.id ?? 0);
59
}
60
return address;
61
}
@@ -71,7 +75,9 @@ abstract class MoneroWalletAddressesBase extends WalletAddresses with Store {
75
@override
76
Future<void> init() async {
77
accountList.update();
74
- account = accountList.accounts.isEmpty ? Account(id: 0, label: "Primary address") : accountList.accounts.first;
78
+ account = accountList.accounts.isEmpty
79
+ ? Account(id: 0, label: "Primary address")
80
+ : accountList.accounts.first;
81
await updateSubaddressList(accountIndex: account?.id ?? 0);
82
await updateAddressesInBox();
83
}
@@ -145,9 +151,11 @@ abstract class MoneroWalletAddressesBase extends WalletAddresses with Store {
151
accountIndex: accountIndex,
152
defaultLabel: defaultLabel,
153
usedAddresses: usedAddresses.toList());
148
- subaddress = (subaddressList.subaddresses.isEmpty) ? Subaddress(id: 0, address: address, label: defaultLabel, balance: '0', txCount: 0) : subaddressList.subaddresses.last;
149
- if (num.tryParse(subaddress!.balance??'0') != 0) {
150
- getAddress(accountIndex: accountIndex, addressIndex: (subaddress?.id??0)+1);
154
+ subaddress = (subaddressList.subaddresses.isEmpty)
155
+ ? Subaddress(id: 0, address: address, label: defaultLabel, balance: '0', txCount: 0)
156
+ : subaddressList.subaddresses.last;
157
+ if (num.tryParse(subaddress!.balance ?? '0') != 0) {
158
+ getAddress(accountIndex: accountIndex, addressIndex: (subaddress?.id ?? 0) + 1);
159
}
160
address = subaddress!.address;
161
}
cw_monero/lib/monero_wallet_service.dart
+26
-41
@@ -45,10 +45,7 @@ class MoneroNewWalletCredentials extends WalletCredentials {
45
46
class MoneroRestoreWalletFromHardwareCredentials extends WalletCredentials {
47
MoneroRestoreWalletFromHardwareCredentials(
48
- {required String name,
49
- required this.hardwareWalletService,
50
- int height = 0,
51
- String? password})
48
+ {required String name, required this.hardwareWalletService, int height = 0, String? password})
49
: super(name: name, password: password, height: height);
50
HardwareWalletService hardwareWalletService;
51
}
@@ -111,8 +108,7 @@ class MoneroWalletService extends WalletService<
108
WalletType getType() => WalletType.monero;
109
110
@override
114
- Future<MoneroWallet> create(MoneroNewWalletCredentials credentials,
115
- {bool? isTestnet}) async {
111
+ Future<MoneroWallet> create(MoneroNewWalletCredentials credentials, {bool? isTestnet}) async {
112
try {
113
final path = await pathForWallet(name: credentials.name, type: getType());
114
@@ -130,14 +126,13 @@ class MoneroWalletService extends WalletService<
126
final polyseed = Polyseed.create();
127
final lang = PolyseedLang.getByEnglishName(credentials.language);
128
133
- if (credentials.passphrase != null)
134
- polyseed.crypt(credentials.passphrase!);
129
+ if (credentials.passphrase != null) polyseed.crypt(credentials.passphrase!);
130
136
- final heightOverride = getMoneroHeigthByDate(
137
- date: DateTime.now().subtract(Duration(days: 2)));
131
+ final heightOverride =
132
+ getMoneroHeigthByDate(date: DateTime.now().subtract(Duration(days: 2)));
133
139
- return _restoreFromPolyseed(path, credentials.password!, polyseed,
140
- credentials.walletInfo!, lang,
134
+ return _restoreFromPolyseed(
135
+ path, credentials.password!, polyseed, credentials.walletInfo!, lang,
136
overrideHeight: heightOverride, passphrase: credentials.passphrase);
137
}
138
@@ -181,8 +176,7 @@ class MoneroWalletService extends WalletService<
176
177
if (walletFilesExist(path)) await repairOldAndroidWallet(name);
178
184
- await monero_wallet_manager
185
- .openWallet(path: path, password: password);
179
+ await monero_wallet_manager.openWallet(path: path, password: password);
180
final walletInfo = await WalletInfo.get(name, getType());
181
if (walletInfo == null) {
182
throw Exception('Wallet not found');
@@ -315,13 +309,13 @@ class MoneroWalletService extends WalletService<
309
final watchCredentials = await Trezor(service).getWatchCredentials();
310
311
monero_wallet_manager.restoreWalletFromKeys(
318
- path: path,
319
- password: credentials.password!,
320
- language: "English",
321
- restoreHeight: credentials.height!,
322
- address: watchCredentials.address,
323
- viewKey: watchCredentials.watchKey,
324
- spendKey: "",
312
+ path: path,
313
+ password: credentials.password!,
314
+ language: "English",
315
+ restoreHeight: credentials.height!,
316
+ address: watchCredentials.address,
317
+ viewKey: watchCredentials.watchKey,
318
+ spendKey: "",
319
);
320
}
321
@@ -341,8 +335,7 @@ class MoneroWalletService extends WalletService<
335
}
336
337
@override
344
- Future<MoneroWallet> restoreFromSeed(
345
- MoneroRestoreWalletFromSeedCredentials credentials,
338
+ Future<MoneroWallet> restoreFromSeed(MoneroRestoreWalletFromSeedCredentials credentials,
339
{bool? isTestnet}) async {
340
// Restore from Polyseed
341
try {
@@ -356,8 +349,7 @@ class MoneroWalletService extends WalletService<
349
350
try {
351
if (isBip39Seed(credentials.mnemonic)) {
359
- final path =
360
- await pathForWallet(name: credentials.name, type: getType());
352
+ final path = await pathForWallet(name: credentials.name, type: getType());
353
354
return _restoreFromBip39(
355
path: path,
@@ -410,10 +402,8 @@ class MoneroWalletService extends WalletService<
402
derivationInfo.derivationPath = "m/44'/128'/0'/0/0";
403
await derivationInfo.save();
404
413
- final legacyMnemonic =
414
- getLegacySeedFromBip39(mnemonic, passphrase: passphrase ?? "");
415
- final height =
416
- overrideHeight ?? getMoneroHeigthByDate(date: DateTime.now());
405
+ final legacyMnemonic = getLegacySeedFromBip39(mnemonic, passphrase: passphrase ?? "");
406
+ final height = overrideHeight ?? getMoneroHeigthByDate(date: DateTime.now());
407
408
walletInfo.isRecovery = true;
409
walletInfo.restoreHeight = height;
@@ -426,10 +416,8 @@ class MoneroWalletService extends WalletService<
416
restoreHeight: height,
417
);
418
429
- currentWallet!.setCacheAttribute(
430
- key: "cakewallet.seed.bip39", value: mnemonic);
431
- currentWallet!.setCacheAttribute(
432
- key: "cakewallet.passphrase", value: passphrase ?? '');
419
+ currentWallet!.setCacheAttribute(key: "cakewallet.seed.bip39", value: mnemonic);
420
+ currentWallet!.setCacheAttribute(key: "cakewallet.passphrase", value: passphrase ?? '');
421
422
currentWallet!.store();
423
@@ -450,8 +438,7 @@ class MoneroWalletService extends WalletService<
438
final path = await pathForWallet(name: credentials.name, type: getType());
439
final polyseedCoin = PolyseedCoin.POLYSEED_MONERO;
440
final lang = PolyseedLang.getByPhrase(credentials.mnemonic);
453
- final polyseed =
454
- Polyseed.decode(credentials.mnemonic, lang, polyseedCoin);
441
+ final polyseed = Polyseed.decode(credentials.mnemonic, lang, polyseedCoin);
442
443
return _restoreFromPolyseed(
444
path, credentials.password!, polyseed, credentials.walletInfo!, lang,
@@ -463,8 +450,8 @@ class MoneroWalletService extends WalletService<
450
}
451
}
452
466
- Future<MoneroWallet> _restoreFromPolyseed(String path, String password,
467
- Polyseed polyseed, WalletInfo walletInfo, PolyseedLang lang,
453
+ Future<MoneroWallet> _restoreFromPolyseed(
454
+ String path, String password, Polyseed polyseed, WalletInfo walletInfo, PolyseedLang lang,
455
{PolyseedCoin coin = PolyseedCoin.POLYSEED_MONERO,
456
int? overrideHeight,
457
String? passphrase}) async {
@@ -507,9 +494,8 @@ class MoneroWalletService extends WalletService<
494
restoreHeight: height,
495
spendKey: spendKey);
496
510
-
497
currentWallet!.setCacheAttribute(key: "cakewallet.seed", value: seed);
512
- currentWallet!.setCacheAttribute(key: "cakewallet.passphrase", value: passphrase??'');
498
+ currentWallet!.setCacheAttribute(key: "cakewallet.passphrase", value: passphrase ?? '');
499
500
final wallet = MoneroWallet(
501
walletInfo: walletInfo,
@@ -556,8 +542,7 @@ class MoneroWalletService extends WalletService<
542
543
if (walletFilesExist(path)) await repairOldAndroidWallet(name);
544
559
- await monero_wallet_manager
560
- .openWallet(path: path, password: password);
545
+ await monero_wallet_manager.openWallet(path: path, password: password);
546
final walletInfo = await WalletInfo.get(name, getType());
547
if (walletInfo == null) {
548
throw Exception('Wallet not found');
cw_monero/lib/pending_monero_transaction.dart
+2
-4
@@ -63,8 +63,7 @@ class PendingMoneroTransaction with PendingTransaction {
63
} else {
64
try {
65
await monero_transaction_history.commitTransactionFromPointerAddress(
66
- address: pendingTransactionDescription.pointerAddress,
67
- useUR: false);
66
+ address: pendingTransactionDescription.pointerAddress, useUR: false);
67
} catch (e) {
68
final message = e.toString();
69
@@ -86,8 +85,7 @@ class PendingMoneroTransaction with PendingTransaction {
85
Future<Map<String, String>> commitUR() async {
86
try {
87
final ret = await monero_transaction_history.commitTransactionFromPointerAddress(
89
- address: pendingTransactionDescription.pointerAddress,
90
- useUR: true);
88
+ address: pendingTransactionDescription.pointerAddress, useUR: true);
89
storeSync(force: true);
90
unawaited(() async {
91
await Future.delayed(const Duration(milliseconds: 250));
cw_monero/lib/trezor.dart
+7
-7
@@ -34,13 +34,13 @@ class Trezor {
34
final txIds = <MoneroKeyImageTxData>[];
35
for (final tdi in tdisList) {
36
txIds.add(MoneroKeyImageTxData(
37
- outKey: tdi["out_key"],
38
- txPubKey: tdi["tx_pub_key"],
39
- internalOutputIndex: tdi["internal_output_index"],
40
- subAddrMajor: tdi["sub_addr_major"],
41
- subAddrMinor: tdi["sub_addr_minor"],
42
- additionalTxPubKeys: (tdi["additional_tx_pub_keys"] as List?)?.map((e) => e as String).toList() ?? []
43
- ));
37
+ outKey: tdi["out_key"],
38
+ txPubKey: tdi["tx_pub_key"],
39
+ internalOutputIndex: tdi["internal_output_index"],
40
+ subAddrMajor: tdi["sub_addr_major"],
41
+ subAddrMinor: tdi["sub_addr_minor"],
42
+ additionalTxPubKeys:
43
+ (tdi["additional_tx_pub_keys"] as List?)?.map((e) => e as String).toList() ?? []));
44
}
45
final keyImages = await TrezorMonero(service.client).syncKeyImages(txIds);
46
cw_monero/test/bip39_seed_test.dart
+12
-7
@@ -4,9 +4,12 @@ import 'package:flutter_test/flutter_test.dart';
4
void main() {
5
group("Exodus Style bip39", () {
6
group("Test Wallet 1", () {
7
- final bip39Seed = 'meadow tip best belt boss eyebrow control affair eternal piece very shiver';
8
- final expectedLegacySeed0 = "tasked eight afraid laboratory tail feline rift reinvest vane cafe bailed foggy dormant paper jigsaw king hazard suture king dapper dummy jolted dating dwindling king";
9
- final expectedLegacySeed1 = "palace pairing axes mohawk rekindle excess awful juvenile shipped talent nibs efficient dapper biggest swung fight pact innocent emerge issued titans affair nearby noises emerge";
7
+ final bip39Seed =
8
+ 'meadow tip best belt boss eyebrow control affair eternal piece very shiver';
9
+ final expectedLegacySeed0 =
10
+ "tasked eight afraid laboratory tail feline rift reinvest vane cafe bailed foggy dormant paper jigsaw king hazard suture king dapper dummy jolted dating dwindling king";
11
+ final expectedLegacySeed1 =
12
+ "palace pairing axes mohawk rekindle excess awful juvenile shipped talent nibs efficient dapper biggest swung fight pact innocent emerge issued titans affair nearby noises emerge";
13
14
test("Get legacy Seed from bip39", () {
15
final legacySeed = getLegacySeedFromBip39(bip39Seed);
@@ -20,9 +23,12 @@ void main() {
23
});
24
25
group("Test Wallet 2", () {
23
- final bip39Seed = "color ranch color remove subway public water embrace before begin liberty fault";
24
- final expectedLegacySeed0 = "somewhere problems gauze gigantic intended foxes upcoming saved waffle pipeline lurk bogeys empty wipeout abbey italics novelty tucks rafts elite lunar obnoxious awful bugs elite";
25
- final expectedLegacySeed1 = "playful toxic wildly eluded mesh fainted february mugged maps repent vigilant hitched seventh threaten clue fetches sample diet number alkaline future cottage tuition vegan alkaline";
26
+ final bip39Seed =
27
+ "color ranch color remove subway public water embrace before begin liberty fault";
28
+ final expectedLegacySeed0 =
29
+ "somewhere problems gauze gigantic intended foxes upcoming saved waffle pipeline lurk bogeys empty wipeout abbey italics novelty tucks rafts elite lunar obnoxious awful bugs elite";
30
+ final expectedLegacySeed1 =
31
+ "playful toxic wildly eluded mesh fainted february mugged maps repent vigilant hitched seventh threaten clue fetches sample diet number alkaline future cottage tuition vegan alkaline";
32
33
test("Get legacy Seed from bip39", () {
34
final legacySeed = getLegacySeedFromBip39(bip39Seed);
@@ -34,6 +40,5 @@ void main() {
40
expect(legacySeed, expectedLegacySeed1);
41
});
42
});
37
-
43
});
44
}
cw_monero/test/monero_wallet_service_test.dart
+3
-9
@@ -40,9 +40,7 @@ Future<void> main() async {
40
group("Create wallet", () {
41
test("Create Legacy Wallet", () async {
42
final credentials = _getTestCreateCredentials(
43
- name: 'Create Wallet LS',
44
- language: 'English',
45
- seedType: MoneroSeedType.legacy);
43
+ name: 'Create Wallet LS', language: 'English', seedType: MoneroSeedType.legacy);
44
final wallet = await walletService.create(credentials);
45
46
expect(wallet.seed.split(" ").length, 25);
@@ -51,9 +49,7 @@ Future<void> main() async {
49
50
test("Create Polyseed Wallet", () async {
51
final credentials = _getTestCreateCredentials(
54
- name: 'Create Wallet PS',
55
- language: 'English',
56
- seedType: MoneroSeedType.polyseed);
52
+ name: 'Create Wallet PS', language: 'English', seedType: MoneroSeedType.polyseed);
53
final wallet = await walletService.create(credentials);
54
55
expect(wallet.seed.split(" ").length, 16);
@@ -62,9 +58,7 @@ Future<void> main() async {
58
59
test("Create Bip39 Wallet", () async {
60
final credentials = _getTestCreateCredentials(
65
- name: 'Create Wallet BS',
66
- language: 'English',
67
- seedType: MoneroSeedType.bip39);
61
+ name: 'Create Wallet BS', language: 'English', seedType: MoneroSeedType.bip39);
62
final wallet = await walletService.create(credentials);
63
64
expect(wallet.seed.split(" ").length, 12);
cw_monero/test/utils/setup_monero_c.dart
+5
-8
@@ -4,20 +4,17 @@ import 'package:path/path.dart' as p;
4
File getMoneroCBinary() {
5
final baseDir = Directory('../scripts/monero_c/release');
6
7
- final versionDir =
8
- baseDir.listSync().whereType<Directory>().map((d) => d.path).firstWhere(
9
- (path) => p.basename(path).startsWith('v'),
10
- );
7
+ final versionDir = baseDir.listSync().whereType<Directory>().map((d) => d.path).firstWhere(
8
+ (path) => p.basename(path).startsWith('v'),
9
+ );
10
11
if (Platform.isWindows) {
13
- return File(p.join(
14
- versionDir, 'x86_64-w64-mingw32', 'libmonero_wallet2_api_c.dll'));
12
+ return File(p.join(versionDir, 'x86_64-w64-mingw32', 'libmonero_wallet2_api_c.dll'));
13
}
14
if (Platform.isMacOS) {
15
return File(p.join(versionDir, 'macos', 'libmonero_wallet2_api_c.dylib'));
16
}
19
- return File(
20
- p.join(versionDir, 'x86_64-linux-gnu', 'libmonero_wallet2_api_c.so'));
17
+ return File(p.join(versionDir, 'x86_64-linux-gnu', 'libmonero_wallet2_api_c.so'));
18
}
19
20
String get moneroCBinaryName {
cw_nano/lib/nano_client.dart
+5
-7
@@ -78,7 +78,7 @@ class NanoClient {
78
},
79
),
80
);
81
-
81
+
82
final data = jsonDecode(response.body) as Map<String, dynamic>;
83
if (response.statusCode != 200 ||
84
data["error"] != null ||
@@ -107,7 +107,7 @@ class NanoClient {
107
},
108
),
109
);
110
-
110
+
111
final data = jsonDecode(response.body) as Map<String, dynamic>;
112
return AccountInfoResponse.fromJson(data);
113
} catch (e) {
@@ -132,7 +132,7 @@ class NanoClient {
132
},
133
),
134
);
135
-
135
+
136
final data = jsonDecode(response.body) as Map<String, dynamic>;
137
return BlockContentsResponse.fromJson(data["contents"] as Map<String, dynamic>);
138
} catch (e) {
@@ -199,7 +199,7 @@ class NanoClient {
199
},
200
),
201
);
202
-
202
+
203
if (response.statusCode == 200) {
204
final decoded = jsonDecode(response.body) as Map<String, dynamic>;
205
if (decoded.containsKey("error")) {
@@ -510,7 +510,7 @@ class NanoClient {
510
// "raw": true,
511
}),
512
);
513
-
513
+
514
final data = jsonDecode(response.body) as Map<String, dynamic>;
515
final transactions = data["history"] is List ? data["history"] as List<dynamic> : [];
516
@@ -533,7 +533,6 @@ class NanoClient {
533
body: jsonEncode({"action": "reps"}),
534
);
535
try {
536
-
536
final List<N2Node> nodes = (jsonDecode(response.body) as List<dynamic>)
537
.map((dynamic e) => N2Node.fromJson(e as Map<String, dynamic>))
538
.toList();
@@ -554,7 +553,6 @@ class NanoClient {
553
}),
554
);
555
try {
557
-
556
final N2Node node = N2Node.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
557
return node.score ?? 100;
558
} catch (error) {
cw_nano/lib/nano_transaction_model.dart
+2
-2
@@ -20,8 +20,8 @@ class NanoTransactionModel {
20
factory NanoTransactionModel.fromJson(dynamic json) {
21
DateTime? localTimestamp;
22
try {
23
- localTimestamp = DateTime.fromMillisecondsSinceEpoch(
24
- int.parse(json["local_timestamp"] as String) * 1000);
23
+ localTimestamp =
24
+ DateTime.fromMillisecondsSinceEpoch(int.parse(json["local_timestamp"] as String) * 1000);
25
} catch (e) {
26
localTimestamp = DateTime.now();
27
}
cw_nano/lib/nano_wallet.dart
+4
-2
@@ -208,7 +208,8 @@ abstract class NanoWalletBase
208
amt = txOut.cryptoAmount.amount;
209
}
210
211
- if (balance[currency]?.currentBalance != null && amt > balance[currency]!.currentBalance.amount) {
211
+ if (balance[currency]?.currentBalance != null &&
212
+ amt > balance[currency]!.currentBalance.amount) {
213
throw Exception("Trying to send more than entire balance!");
214
}
215
@@ -235,7 +236,8 @@ abstract class NanoWalletBase
236
}
237
238
try {
238
- if (runningAmount > balance[currency]!.currentBalance.amount || runningBalance < BigInt.zero) {
239
+ if (runningAmount > balance[currency]!.currentBalance.amount ||
240
+ runningBalance < BigInt.zero) {
241
throw Exception(("Trying to send more than entire balance!"));
242
}
243
} catch (e) {
cw_nano/lib/nano_wallet_service.dart
+2
-1
@@ -32,7 +32,8 @@ class NanoWalletService extends WalletService<
32
@override
33
Future<WalletBase> create(NanoNewWalletCredentials credentials, {bool? isTestnet}) async {
34
final String mnemonic;
35
- final derivationInfo = credentials.derivationInfo ?? await credentials.walletInfo!.getDerivationInfo();
35
+ final derivationInfo =
36
+ credentials.derivationInfo ?? await credentials.walletInfo!.getDerivationInfo();
37
switch (derivationInfo.derivationType) {
38
case DerivationType.nano:
39
String seedKey = NanoSeeds.generateSeed();
cw_nano/lib/pending_nano_transaction.dart
+1
-1
@@ -31,7 +31,7 @@ class PendingNanoTransaction with PendingTransaction {
31
await nanoClient.processBlock(block, "send");
32
}
33
}
34
-
34
+
35
@override
36
Future<Map<String, String>> commitUR() => throw UnimplementedError();
37
}
cw_shared_external/lib/cw_shared_external.dart
+1
-3
@@ -1,11 +1,9 @@
1
-
1
import 'dart:async';
2
3
import 'package:flutter/services.dart';
4
5
class CwSharedExternal {
7
- static const MethodChannel _channel =
8
- const MethodChannel('cw_shared_external');
6
+ static const MethodChannel _channel = const MethodChannel('cw_shared_external');
7
8
static Future<String> get platformVersion async {
9
final String version = (await _channel.invokeMethod('getPlatformVersion')).toString();
cw_solana/lib/pending_solana_transaction.dart
+1
-1
@@ -42,7 +42,7 @@ class PendingSolanaTransaction with PendingTransaction {
42
43
@override
44
String get id => _sig ?? '';
45
-
45
+
46
@override
47
Future<Map<String, String>> commitUR() {
48
throw UnimplementedError();
cw_solana/lib/solana_client.dart
+6
-6
@@ -493,7 +493,8 @@ class SolanaWalletClient {
493
outgoingAmount = diff.toDouble();
494
outgoingMintAddress = mint;
495
final token = await getTokenInfo(mint);
496
- outgoingToken = token ?? const CryptoCurrency(name: "TOKEN", title: "TOKEN", decimals: 6);
496
+ outgoingToken =
497
+ token ?? const CryptoCurrency(name: "TOKEN", title: "TOKEN", decimals: 6);
498
outgoingFrom = walletAddress;
499
// We find the intermediate account
500
if (instructions.isNotEmpty && instructions[0].accounts.isNotEmpty) {
@@ -626,7 +627,8 @@ class SolanaWalletClient {
627
final token = await getTokenInfo(mint);
628
printV(token?.symbol);
629
printV(token?.decimals);
629
- incomingToken = token ?? const CryptoCurrency(name: "TOKEN", title: "TOKEN", decimals: 6);
630
+ incomingToken =
631
+ token ?? const CryptoCurrency(name: "TOKEN", title: "TOKEN", decimals: 6);
632
incomingTo = walletAddress;
633
// We find the intermediate account
634
if (instructions.isNotEmpty && instructions[0].accounts.isNotEmpty) {
@@ -1745,10 +1747,8 @@ class SolanaWalletClient {
1747
return transaction.serializeString();
1748
}
1749
1748
- Future<String> sendTransaction({
1749
- required String serializedTransaction,
1750
- required Commitment commitment
1751
- }) =>
1750
+ Future<String> sendTransaction(
1751
+ {required String serializedTransaction, required Commitment commitment}) =>
1752
_provider!.request(
1753
SolanaRPCSendTransaction(
1754
encodedTransaction: serializedTransaction,
cw_solana/lib/solana_wallet.dart
+9
-15
@@ -163,12 +163,9 @@ abstract class SolanaWalletBase
163
final prefs = await _sharedPrefs.future;
164
if (prefs.getBool(_scamCheckDoneKey) == true) return;
165
166
- final defaultMints =
167
- DefaultSPLTokens().initialSPLTokens.map((t) => t.mintAddress).toSet();
168
- final defaultSymbolsUpper = DefaultSPLTokens()
169
- .initialSPLTokens
170
- .map((t) => t.symbol.toUpperCase())
171
- .toSet();
166
+ final defaultMints = DefaultSPLTokens().initialSPLTokens.map((t) => t.mintAddress).toSet();
167
+ final defaultSymbolsUpper =
168
+ DefaultSPLTokens().initialSPLTokens.map((t) => t.symbol.toUpperCase()).toSet();
169
170
for (final token in splTokensBox.values) {
171
final suspicious = isTokenPropertiesSuspicious(
@@ -720,8 +717,7 @@ abstract class SolanaWalletBase
717
'distribution',
718
];
719
723
- static final _suspiciousWordPattern =
724
- RegExp(r'\b(bot|claim|reward)\b', caseSensitive: false);
720
+ static final _suspiciousWordPattern = RegExp(r'\b(bot|claim|reward)\b', caseSensitive: false);
721
722
static const _knownNonSolanaNativeSymbols = {
723
'BTC',
@@ -758,13 +754,10 @@ abstract class SolanaWalletBase
754
Set<String>? cachedDefaultMints,
755
Set<String>? cachedDefaultSymbolsUpper,
756
}) {
761
- final defaultMints = cachedDefaultMints ??
762
- DefaultSPLTokens().initialSPLTokens.map((t) => t.mintAddress).toSet();
757
+ final defaultMints =
758
+ cachedDefaultMints ?? DefaultSPLTokens().initialSPLTokens.map((t) => t.mintAddress).toSet();
759
final defaultSymbolsUpper = cachedDefaultSymbolsUpper ??
764
- DefaultSPLTokens()
765
- .initialSPLTokens
766
- .map((t) => t.symbol.toUpperCase())
767
- .toSet();
760
+ DefaultSPLTokens().initialSPLTokens.map((t) => t.symbol.toUpperCase()).toSet();
761
762
final isTokenWhitelisted = defaultMints.contains(token.mintAddress);
763
@@ -799,7 +792,8 @@ abstract class SolanaWalletBase
792
793
if (token.enabled) {
794
final tokenBalance = await _client.getSplTokenBalance(token, solanaAddress) ??
802
- balance[token] ?? SolanaBalance.zero(token);
795
+ balance[token] ??
796
+ SolanaBalance.zero(token);
797
798
balance[token] = tokenBalance;
799
} else {
cw_solana/lib/solana_wallet_service.dart
+7
-3
@@ -14,8 +14,11 @@ import 'package:cw_solana/solana_mnemonics.dart';
14
import 'package:cw_solana/solana_wallet.dart';
15
import 'package:cw_solana/solana_wallet_creation_credentials.dart';
16
17
-class SolanaWalletService extends WalletService<SolanaNewWalletCredentials,
18
- SolanaRestoreWalletFromSeedCredentials, SolanaRestoreWalletFromPrivateKey, SolanaNewWalletCredentials> {
17
+class SolanaWalletService extends WalletService<
18
+ SolanaNewWalletCredentials,
19
+ SolanaRestoreWalletFromSeedCredentials,
20
+ SolanaRestoreWalletFromPrivateKey,
21
+ SolanaNewWalletCredentials> {
22
SolanaWalletService(this.isDirect);
23
24
final bool isDirect;
@@ -137,7 +140,8 @@ class SolanaWalletService extends WalletService<SolanaNewWalletCredentials,
140
}
141
142
@override
140
- Future<WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>> restoreFromHardwareWallet(SolanaNewWalletCredentials credentials) {
143
+ Future<WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>>
144
+ restoreFromHardwareWallet(SolanaNewWalletCredentials credentials) {
145
// TODO: implement restoreFromHardwareWallet
146
throw UnimplementedError();
147
}
cw_tron/lib/pending_tron_transaction.dart
+1
-1
@@ -31,7 +31,7 @@ class PendingTronTransaction with PendingTransaction {
31
32
@override
33
String id;
34
-
34
+
35
@override
36
Future<Map<String, String>> commitUR() {
37
throw UnimplementedError();
cw_tron/lib/tron_balance.dart
+1
-1
@@ -9,7 +9,7 @@ class TronBalance extends Balance {
9
10
final Money balance;
11
12
- String toJSON() => json.encode({ 'balance': balance.amount.toString() });
12
+ String toJSON() => json.encode({'balance': balance.amount.toString()});
13
14
static TronBalance? fromJSON(String? jsonSource, Currency currency) {
15
if (jsonSource == null) return null;
cw_tron/lib/tron_client.dart
+5
-6
@@ -328,12 +328,11 @@ class TronClient {
328
);
329
330
return PendingTronTransaction(
331
- signedTransaction: signature,
332
- amount: totalAmount,
333
- fee: Money(rawTransaction.feeLimit ?? BigInt.zero, CryptoCurrency.trx),
334
- sendTransaction: sendTx,
335
- id: rawTransaction.txID
336
- );
331
+ signedTransaction: signature,
332
+ amount: totalAmount,
333
+ fee: Money(rawTransaction.feeLimit ?? BigInt.zero, CryptoCurrency.trx),
334
+ sendTransaction: sendTx,
335
+ id: rawTransaction.txID);
336
}
337
338
Future<TransactionRaw> _signNativeTransaction(
cw_tron/lib/tron_exception.dart
+2
-1
@@ -5,6 +5,7 @@ class TronMnemonicIsIncorrectException implements Exception {
5
String toString() =>
6
'Tron mnemonic has incorrect format. Mnemonic should contain 12 or 24 words separated by space.';
7
}
8
+
9
class TronTransactionCreationException implements Exception {
10
final String exceptionMessage;
11
@@ -13,4 +14,4 @@ class TronTransactionCreationException implements Exception {
14
15
@override
16
String toString() => exceptionMessage;
16
-}
\ No newline at end of file
17
+}
cw_tron/lib/tron_http_provider.dart
+5
-11
@@ -5,9 +5,7 @@ import 'package:on_chain/tron/tron.dart';
5
import '.secrets.g.dart' as secrets;
6
7
class TronHTTPProvider implements TronServiceProvider {
8
- TronHTTPProvider(
9
- {required this.url,
10
- this.defaultRequestTimeout = const Duration(seconds: 30)});
8
+ TronHTTPProvider({required this.url, this.defaultRequestTimeout = const Duration(seconds: 30)});
9
10
@override
11
final String url;
@@ -15,8 +13,7 @@ class TronHTTPProvider implements TronServiceProvider {
13
final Duration defaultRequestTimeout;
14
15
@override
18
- Future<Map<String, dynamic>> get(TronRequestDetails params,
19
- [Duration? timeout]) async {
16
+ Future<Map<String, dynamic>> get(TronRequestDetails params, [Duration? timeout]) async {
17
final response = await client.get(Uri.parse(params.url(url)), headers: {
18
'Content-Type': 'application/json',
19
if (url.contains("trongrid")) 'TRON-PRO-API-KEY': secrets.tronGridApiKey,
@@ -27,16 +24,13 @@ class TronHTTPProvider implements TronServiceProvider {
24
}
25
26
@override
30
- Future<Map<String, dynamic>> post(TronRequestDetails params,
31
- [Duration? timeout]) async {
27
+ Future<Map<String, dynamic>> post(TronRequestDetails params, [Duration? timeout]) async {
28
final response = await client
29
.post(Uri.parse(params.url(url)),
30
headers: {
31
'Content-Type': 'application/json',
36
- if (url.contains("trongrid"))
37
- 'TRON-PRO-API-KEY': secrets.tronGridApiKey,
38
- if (url.contains("nownodes"))
39
- 'api-key': secrets.tronNowNodesApiKey,
32
+ if (url.contains("trongrid")) 'TRON-PRO-API-KEY': secrets.tronGridApiKey,
33
+ if (url.contains("nownodes")) 'api-key': secrets.tronNowNodesApiKey,
34
},
35
body: params.toRequestBody())
36
.timeout(timeout ?? defaultRequestTimeout);
cw_tron/lib/tron_wallet.dart
+12
-13
@@ -257,7 +257,7 @@ abstract class TronWalletBase
257
nativeTxEstimatedFee = Money.fromInt(nativeFee, currency);
258
259
final trc20Fee = await _getTrc20TxFee();
260
- trc20EstimatedFee = Money.fromInt(trc20Fee, currency);
260
+ trc20EstimatedFee = Money.fromInt(trc20Fee, currency);
261
262
log('Native Estimated Fee: $nativeTxEstimatedFee');
263
log('TRC20 Estimated Fee: $trc20EstimatedFee');
@@ -325,8 +325,8 @@ abstract class TronWalletBase
325
var totalAmount = Money.zero(transactionCurrency);
326
var shouldSendAll = false;
327
if (hasMultiDestination) {
328
- // Tron does not have multi Destination right now
329
- throw TronTransactionCreationException(transactionCurrency);
328
+ // Tron does not have multi Destination right now
329
+ throw TronTransactionCreationException(transactionCurrency);
330
} else {
331
final output = outputs.first;
332
@@ -401,11 +401,13 @@ abstract class TronWalletBase
401
'';
402
403
final decimals = (await _client.getTokenDetail(
404
- contract,
405
- "decimals",
406
- ownerAddress,
407
- tokenAddress,
408
- ) as BigInt?)?.toInt() ?? txCurrency.decimals;
404
+ contract,
405
+ "decimals",
406
+ ownerAddress,
407
+ tokenAddress,
408
+ ) as BigInt?)
409
+ ?.toInt() ??
410
+ txCurrency.decimals;
411
412
txCurrency = CryptoCurrency(name: tokenSymbol, title: tokenSymbol, decimals: decimals);
413
}
@@ -577,11 +579,8 @@ abstract class TronWalletBase
579
await tronTokensBox.put(newToken.contractAddress, newToken);
580
581
if (newToken.enabled) {
580
- balance[newToken] = await _client.fetchTronTokenBalances(
581
- _tronAddress,
582
- newToken.contractAddress,
583
- currency: token
584
- );
582
+ balance[newToken] = await _client
583
+ .fetchTronTokenBalances(_tronAddress, newToken.contractAddress, currency: token);
584
} else {
585
balance.remove(newToken);
586
}
cw_wownero/lib/api/account_list.dart
+3
-4
@@ -13,7 +13,6 @@ wownero.WalletListener getWlptr() {
13
return _wlptr!;
14
}
15
16
-
16
wownero.SubaddressAccount? subaddressAccount;
17
18
bool isUpdating = false;
@@ -69,6 +68,6 @@ Future<void> addAccount({required String label}) async {
68
}
69
70
Future<void> setLabelForAccount({required int accountIndex, required String label}) async {
72
- _setLabelForAccount({'accountIndex': accountIndex, 'label': label});
73
- await store();
74
-}
\ No newline at end of file
71
+ _setLabelForAccount({'accountIndex': accountIndex, 'label': label});
72
+ await store();
73
+}
cw_wownero/lib/api/exceptions/connection_to_node_exception.dart
+1
-1
@@ -2,4 +2,4 @@ class ConnectionToNodeException implements Exception {
2
ConnectionToNodeException({required this.message});
3
4
final String message;
5
-}
\ No newline at end of file
5
+}
cw_wownero/lib/api/exceptions/creation_transaction_exception.dart
+2
-2
@@ -1,8 +1,8 @@
1
class CreationTransactionException implements Exception {
2
CreationTransactionException({required this.message});
3
-
3
+
4
final String message;
5
6
@override
7
String toString() => message;
8
-}
\ No newline at end of file
8
+}
cw_wownero/lib/api/exceptions/setup_wallet_exception.dart
+2
-2
@@ -1,8 +1,8 @@
1
class SetupWalletException implements Exception {
2
SetupWalletException({required this.message});
3
-
3
+
4
final String message;
5
6
@override
7
String toString() => message;
8
-}
\ No newline at end of file
8
+}
cw_wownero/lib/api/exceptions/wallet_creation_exception.dart
+1
-1
@@ -5,4 +5,4 @@ class WalletCreationException implements Exception {
5
6
@override
7
String toString() => message;
8
-}
\ No newline at end of file
8
+}
cw_wownero/lib/api/exceptions/wallet_opening_exception.dart
+1
-1
@@ -5,4 +5,4 @@ class WalletOpeningException implements Exception {
5
6
@override
7
String toString() => message;
8
-}
\ No newline at end of file
8
+}
cw_wownero/lib/api/exceptions/wallet_restore_from_keys_exception.dart
+2
-2
@@ -1,8 +1,8 @@
1
class WalletRestoreFromKeysException implements Exception {
2
WalletRestoreFromKeysException({required this.message});
3
-
3
+
4
final String message;
5
6
@override
7
String toString() => message;
8
-}
\ No newline at end of file
8
+}
cw_wownero/lib/api/exceptions/wallet_restore_from_seed_exception.dart
+2
-2
@@ -1,5 +1,5 @@
1
class WalletRestoreFromSeedException implements Exception {
2
WalletRestoreFromSeedException({required this.message});
3
-
3
+
4
final String message;
5
-}
\ No newline at end of file
5
+}
cw_wownero/lib/api/structs/account_row.dart
+1
-1
@@ -4,7 +4,7 @@ import 'package:ffi/ffi.dart';
4
class AccountRow extends Struct {
5
@Int64()
6
external int id;
7
-
7
+
8
external Pointer<Utf8> label;
9
10
String getLabel() => label.toDartString();
cw_wownero/lib/api/structs/pending_transaction.dart
+8
-9
@@ -1,12 +1,11 @@
1
-
1
class PendingTransactionDescription {
3
- PendingTransactionDescription({
4
- required this.amount,
5
- required this.fee,
6
- required this.hash,
7
- required this.hex,
8
- required this.txKey,
9
- required this.pointerAddress});
2
+ PendingTransactionDescription(
3
+ {required this.amount,
4
+ required this.fee,
5
+ required this.hash,
6
+ required this.hex,
7
+ required this.txKey,
8
+ required this.pointerAddress});
9
10
final int amount;
11
final int fee;
@@ -14,4 +13,4 @@ class PendingTransactionDescription {
13
final String hex;
14
final String txKey;
15
final int pointerAddress;
17
-}
\ No newline at end of file
16
+}
cw_wownero/lib/api/structs/subaddress_row.dart
+3
-3
@@ -4,12 +4,12 @@ import 'package:ffi/ffi.dart';
4
class SubaddressRow extends Struct {
5
@Int64()
6
external int id;
7
-
7
+
8
external Pointer<Utf8> address;
9
-
9
+
10
external Pointer<Utf8> label;
11
12
String getLabel() => label.toDartString();
13
String getAddress() => address.toDartString();
14
int getId() => id;
15
-}
\ No newline at end of file
15
+}
cw_wownero/lib/api/subaddress_list.dart
+15
-13
@@ -38,7 +38,8 @@ class Subaddress {
38
);
39
final int addressIndex;
40
final int accountIndex;
41
- String get label => wownero.Wallet_getSubaddressLabel(wptr!, accountIndex: accountIndex, addressIndex: addressIndex);
41
+ String get label => wownero.Wallet_getSubaddressLabel(wptr!,
42
+ accountIndex: accountIndex, addressIndex: addressIndex);
43
final int txCount;
44
final int received;
45
}
@@ -68,7 +69,10 @@ List<Subaddress> getAllSubaddresses() {
69
final subaddrs = wownero.TransactionInfo_subaddrIndex(tx).split(",");
70
final account = wownero.TransactionInfo_subaddrAccount(tx);
71
newttDetails.add(TinyTransactionDetails(
71
- address: List.generate(subaddrs.length, (index) => getAddress(accountIndex: account, addressIndex: int.tryParse(subaddrs[index])??0)),
72
+ address: List.generate(
73
+ subaddrs.length,
74
+ (index) => getAddress(
75
+ accountIndex: account, addressIndex: int.tryParse(subaddrs[index]) ?? 0)),
76
amount: wownero.TransactionInfo_amount(tx),
77
));
78
}
@@ -79,7 +83,7 @@ List<Subaddress> getAllSubaddresses() {
83
final list = List.generate(size, (index) {
84
final ttDetailsLocal = ttDetails.where((element) {
85
final address = getAddress(
82
- accountIndex: subaddress!.accountIndex,
86
+ accountIndex: subaddress!.accountIndex,
87
addressIndex: index,
88
);
89
if (address == element.address) return true;
@@ -97,7 +101,8 @@ List<Subaddress> getAllSubaddresses() {
101
);
102
}).reversed.toList();
103
if (list.isEmpty) {
100
- list.add(Subaddress(addressIndex: 0, accountIndex: subaddress!.accountIndex, txCount: 0, received: 0));
104
+ list.add(Subaddress(
105
+ addressIndex: 0, accountIndex: subaddress!.accountIndex, txCount: 0, received: 0));
106
}
107
return list;
108
}
@@ -113,7 +118,8 @@ int numSubaddresses(int subaccountIndex) {
118
119
void setLabelForSubaddressSync(
120
{required int accountIndex, required int addressIndex, required String label}) {
116
- wownero.Wallet_setSubaddressLabel(wptr!, accountIndex: accountIndex, addressIndex: addressIndex, label: label);
121
+ wownero.Wallet_setSubaddressLabel(wptr!,
122
+ accountIndex: accountIndex, addressIndex: addressIndex, label: label);
123
}
124
125
void _addSubaddress(Map<String, dynamic> args) {
@@ -128,8 +134,7 @@ void _setLabelForSubaddress(Map<String, dynamic> args) {
134
final accountIndex = args['accountIndex'] as int;
135
final addressIndex = args['addressIndex'] as int;
136
131
- setLabelForSubaddressSync(
132
- accountIndex: accountIndex, addressIndex: addressIndex, label: label);
137
+ setLabelForSubaddressSync(accountIndex: accountIndex, addressIndex: addressIndex, label: label);
138
}
139
140
Future<void> addSubaddress({required int accountIndex, required String label}) async {
@@ -138,11 +143,8 @@ Future<void> addSubaddress({required int accountIndex, required String label}) a
143
}
144
145
Future<void> setLabelForSubaddress(
141
- {required int accountIndex, required int addressIndex, required String label}) async {
142
- _setLabelForSubaddress({
143
- 'accountIndex': accountIndex,
144
- 'addressIndex': addressIndex,
145
- 'label': label
146
- });
146
+ {required int accountIndex, required int addressIndex, required String label}) async {
147
+ _setLabelForSubaddress(
148
+ {'accountIndex': accountIndex, 'addressIndex': addressIndex, 'label': label});
149
await store();
150
}
cw_wownero/lib/api/transaction_history.dart
+72
-66
@@ -43,33 +43,36 @@ Future<List<Transaction>> getAllTransactions() async {
43
await txHistoryMutex.acquire();
44
txhistory ??= wownero.Wallet_history(wptr!);
45
int size = countOfTransactions();
46
- final list = List.generate(size, (index) => Transaction(txInfo: wownero.TransactionHistory_transaction(txhistory!, index: index)));
46
+ final list = List.generate(
47
+ size,
48
+ (index) =>
49
+ Transaction(txInfo: wownero.TransactionHistory_transaction(txhistory!, index: index)));
50
txHistoryMutex.release();
48
-
51
+
52
final accts = wownero.Wallet_numSubaddressAccounts(wptr!);
50
- for (var i = 0; i < accts; i++) {
53
+ for (var i = 0; i < accts; i++) {
54
final fullBalance = wownero.Wallet_balance(wptr!, accountIndex: i);
55
final availBalance = wownero.Wallet_unlockedBalance(wptr!, accountIndex: i);
56
if (fullBalance > availBalance) {
54
- if (list.where((element) => element.accountIndex == i && element.isConfirmed == false).isEmpty) {
55
- dummyTxs.add(
56
- Transaction.dummy(
57
- displayLabel: "",
58
- description: "",
59
- fee: 0,
60
- confirmations: 0,
61
- blockheight: 0,
62
- accountIndex: i,
63
- addressIndex: 0,
64
- addressIndexList: [0],
65
- paymentId: "",
66
- amount: fullBalance - availBalance,
67
- isSpend: false,
68
- hash: "pending",
69
- key: "pending",
70
- txInfo: Pointer.fromAddress(0),
71
- )..timeStamp = DateTime.now()
72
- );
57
+ if (list
58
+ .where((element) => element.accountIndex == i && element.isConfirmed == false)
59
+ .isEmpty) {
60
+ dummyTxs.add(Transaction.dummy(
61
+ displayLabel: "",
62
+ description: "",
63
+ fee: 0,
64
+ confirmations: 0,
65
+ blockheight: 0,
66
+ accountIndex: i,
67
+ addressIndex: 0,
68
+ addressIndexList: [0],
69
+ paymentId: "",
70
+ amount: fullBalance - availBalance,
71
+ isSpend: false,
72
+ hash: "pending",
73
+ key: "pending",
74
+ txInfo: Pointer.fromAddress(0),
75
+ )..timeStamp = DateTime.now());
76
}
77
}
78
}
@@ -89,13 +92,13 @@ Future<PendingTransactionDescription> createTransactionSync(
92
String? amount,
93
int accountIndex = 0,
94
List<String> preferredInputs = const []}) async {
92
-
95
final amt = amount == null ? 0 : wownero.Wallet_amountFromString(amount);
94
-
95
- final address_ = address.toNativeUtf8();
96
+
97
+ final address_ = address.toNativeUtf8();
98
final paymentId_ = paymentId.toNativeUtf8();
99
if (preferredInputs.isEmpty) {
98
- throw WowneroTransactionCreationException("No inputs provided, transaction cannot be constructed");
100
+ throw WowneroTransactionCreationException(
101
+ "No inputs provided, transaction cannot be constructed");
102
}
103
final preferredInputs_ = preferredInputs.join(wownero.defaultSeparatorStr).toNativeUtf8();
104
@@ -105,7 +108,8 @@ Future<PendingTransactionDescription> createTransactionSync(
108
final preferredInputsAddr = preferredInputs_.address;
109
final spaddr = wownero.defaultSeparator.address;
110
final pendingTx = Pointer<Void>.fromAddress(await Isolate.run(() {
108
- final tx = wownero_gen.WowneroC(DynamicLibrary.open(wownero.libPath)).WOWNERO_Wallet_createTransaction(
111
+ final tx =
112
+ wownero_gen.WowneroC(DynamicLibrary.open(wownero.libPath)).WOWNERO_Wallet_createTransaction(
113
Pointer.fromAddress(waddr),
114
Pointer.fromAddress(addraddr).cast(),
115
Pointer.fromAddress(paymentIdAddr).cast(),
@@ -140,13 +144,13 @@ Future<PendingTransactionDescription> createTransactionSync(
144
final rTxKey = rHash;
145
146
return PendingTransactionDescription(
143
- amount: rAmt,
144
- fee: rFee,
145
- hash: rHash,
146
- hex: '',
147
- txKey: rTxKey,
148
- pointerAddress: pendingTx.address,
149
- );
147
+ amount: rAmt,
148
+ fee: rFee,
149
+ hash: rHash,
150
+ hex: '',
151
+ txKey: rTxKey,
152
+ pointerAddress: pendingTx.address,
153
+ );
154
}
155
156
PendingTransactionDescription createTransactionMultDestSync(
@@ -155,7 +159,6 @@ PendingTransactionDescription createTransactionMultDestSync(
159
required int priorityRaw,
160
int accountIndex = 0,
161
List<String> preferredInputs = const []}) {
158
-
162
final txptr = wownero.Wallet_createTransactionMultDest(
163
wptr!,
164
dstAddr: outputs.map((e) => e.address).toList(),
@@ -182,8 +185,8 @@ void commitTransactionFromPointerAddress({required int address}) =>
185
commitTransaction(transactionPointer: wownero.PendingTransaction.fromAddress(address));
186
187
void commitTransaction({required wownero.PendingTransaction transactionPointer}) {
185
-
186
- final txCommit = wownero.PendingTransaction_commit(transactionPointer, filename: '', overwrite: false);
188
+ final txCommit =
189
+ wownero.PendingTransaction_commit(transactionPointer, filename: '', overwrite: false);
190
191
String? error = (() {
192
final status = wownero.PendingTransaction_status(transactionPointer.cast());
@@ -200,9 +203,8 @@ void commitTransaction({required wownero.PendingTransaction transactionPointer})
203
}
204
return wownero.Wallet_errorString(wptr!);
205
})();
203
-
206
}
205
-
207
+
208
if (error != null) {
209
throw CreationTransactionException(message: error);
210
}
@@ -270,19 +272,20 @@ Future<PendingTransactionDescription> createTransactionMultDest(
272
'preferredInputs': preferredInputs
273
});
274
273
-
275
class Transaction {
276
final String displayLabel;
276
- late final String subaddressLabel = wownero.Wallet_getSubaddressLabel(wptr!, accountIndex: accountIndex, addressIndex: addressIndex);
277
+ late final String subaddressLabel = wownero.Wallet_getSubaddressLabel(wptr!,
278
+ accountIndex: accountIndex, addressIndex: addressIndex);
279
late final String address = getAddress(
280
accountIndex: accountIndex,
281
addressIndex: addressIndex,
282
);
281
- late final List<String> addressList = List.generate(addressIndexList.length, (index) =>
282
- getAddress(
283
- accountIndex: accountIndex,
284
- addressIndex: addressIndexList[index],
285
- ));
283
+ late final List<String> addressList = List.generate(
284
+ addressIndexList.length,
285
+ (index) => getAddress(
286
+ accountIndex: accountIndex,
287
+ addressIndex: addressIndexList[index],
288
+ ));
289
final String description;
290
final int fee;
291
final int confirmations;
@@ -331,33 +334,36 @@ class Transaction {
334
timeStamp = DateTime.fromMillisecondsSinceEpoch(
335
wownero.TransactionInfo_timestamp(txInfo) * 1000,
336
),
334
- isSpend = wownero.TransactionInfo_direction(txInfo) ==
335
- wownero.TransactionInfo_Direction.Out,
337
+ isSpend =
338
+ wownero.TransactionInfo_direction(txInfo) == wownero.TransactionInfo_Direction.Out,
339
amount = wownero.TransactionInfo_amount(txInfo),
340
paymentId = wownero.TransactionInfo_paymentId(txInfo),
341
accountIndex = wownero.TransactionInfo_subaddrAccount(txInfo),
339
- addressIndex = int.tryParse(wownero.TransactionInfo_subaddrIndex(txInfo).split(", ")[0]) ?? 0,
340
- addressIndexList = wownero.TransactionInfo_subaddrIndex(txInfo).split(", ").map((e) => int.tryParse(e) ?? 0).toList(),
342
+ addressIndex =
343
+ int.tryParse(wownero.TransactionInfo_subaddrIndex(txInfo).split(", ")[0]) ?? 0,
344
+ addressIndexList = wownero.TransactionInfo_subaddrIndex(txInfo)
345
+ .split(", ")
346
+ .map((e) => int.tryParse(e) ?? 0)
347
+ .toList(),
348
blockheight = wownero.TransactionInfo_blockHeight(txInfo),
349
confirmations = wownero.TransactionInfo_confirmations(txInfo),
350
fee = wownero.TransactionInfo_fee(txInfo),
351
description = wownero.TransactionInfo_description(txInfo),
352
key = wownero.Wallet_getTxKey(wptr!, txid: wownero.TransactionInfo_hash(txInfo));
353
347
- Transaction.dummy({
348
- required this.displayLabel,
349
- required this.description,
350
- required this.fee,
351
- required this.confirmations,
352
- required this.blockheight,
353
- required this.accountIndex,
354
- required this.addressIndex,
355
- required this.addressIndexList,
356
- required this.paymentId,
357
- required this.amount,
358
- required this.isSpend,
359
- required this.hash,
360
- required this.key,
361
- required this.txInfo
362
- });
354
+ Transaction.dummy(
355
+ {required this.displayLabel,
356
+ required this.description,
357
+ required this.fee,
358
+ required this.confirmations,
359
+ required this.blockheight,
360
+ required this.accountIndex,
361
+ required this.addressIndex,
362
+ required this.addressIndexList,
363
+ required this.paymentId,
364
+ required this.amount,
365
+ required this.isSpend,
366
+ required this.hash,
367
+ required this.key,
368
+ required this.txInfo});
369
}
cw_wownero/lib/api/wallet.dart
+30
-20
@@ -34,8 +34,7 @@ String getFilename() => wownero.Wallet_filename(wptr!);
34
35
String getSeed() {
36
// monero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed);
37
- final cakepolyseed =
38
- wownero.Wallet_getCacheAttribute(wptr!, key: "cakewallet.seed");
37
+ final cakepolyseed = wownero.Wallet_getCacheAttribute(wptr!, key: "cakewallet.seed");
38
final cakepassphrase = getPassphrase();
39
40
final weirdPolyseed = wownero.Wallet_getPolyseed(wptr!, passphrase: cakepassphrase);
@@ -65,11 +64,21 @@ String getSeedLegacy(String? language) {
64
final cakepassphrase = getPassphrase();
65
var legacy = wownero.Wallet_seed(wptr!, seedOffset: cakepassphrase);
66
switch (language) {
68
- case "Chinese (Traditional)": language = "Chinese (simplified)"; break;
69
- case "Chinese (Simplified)": language = "Chinese (simplified)"; break;
70
- case "Korean": language = "English"; break;
71
- case "Czech": language = "English"; break;
72
- case "Japanese": language = "English"; break;
67
+ case "Chinese (Traditional)":
68
+ language = "Chinese (simplified)";
69
+ break;
70
+ case "Chinese (Simplified)":
71
+ language = "Chinese (simplified)";
72
+ break;
73
+ case "Korean":
74
+ language = "English";
75
+ break;
76
+ case "Czech":
77
+ language = "English";
78
+ break;
79
+ case "Japanese":
80
+ language = "English";
81
+ break;
82
}
83
if (wownero.Wallet_status(wptr!) != 0) {
84
wownero.Wallet_setSeedLanguage(wptr!, language: language ?? "English");
@@ -84,6 +93,7 @@ String getSeedLegacy(String? language) {
93
}
94
return legacy;
95
}
96
+
97
Map<int, Map<int, Map<int, String>>> addressCache = {};
98
99
String getPassphrase() {
@@ -91,14 +101,14 @@ String getPassphrase() {
101
}
102
103
String getAddress({int accountIndex = 0, int addressIndex = 1}) {
94
- while (wownero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex)-1 < addressIndex) {
104
+ while (wownero.Wallet_numSubaddresses(wptr!, accountIndex: accountIndex) - 1 < addressIndex) {
105
printV("adding subaddress");
106
wownero.Wallet_addSubaddress(wptr!, accountIndex: accountIndex);
107
}
108
addressCache[wptr!.address] ??= {};
109
addressCache[wptr!.address]![accountIndex] ??= {};
100
- addressCache[wptr!.address]![accountIndex]![addressIndex] ??= wownero.Wallet_address(wptr!,
101
- accountIndex: accountIndex, addressIndex: addressIndex);
110
+ addressCache[wptr!.address]![accountIndex]![addressIndex] ??=
111
+ wownero.Wallet_address(wptr!, accountIndex: accountIndex, addressIndex: addressIndex);
112
return addressCache[wptr!.address]![accountIndex]![addressIndex]!;
113
}
114
@@ -106,10 +116,12 @@ int getFullBalance({int accountIndex = 0}) {
116
if (wptr == null) return 0;
117
return wownero.Wallet_balance(wptr!, accountIndex: accountIndex);
118
}
119
+
120
int getUnlockedBalance({int accountIndex = 0}) {
121
if (wptr == null) return 0;
122
return wownero.Wallet_unlockedBalance(wptr!, accountIndex: accountIndex);
123
}
124
+
125
int getCurrentHeight() {
126
if (wptr == null) return 0;
127
return wownero.Wallet_blockChainHeight(wptr!);
@@ -181,8 +193,7 @@ Future<bool> connectToNode() async {
193
}
194
195
void setRefreshFromBlockHeight({required int height}) =>
184
- wownero.Wallet_setRefreshFromBlockHeight(wptr!,
185
- refresh_from_block_height: height);
196
+ wownero.Wallet_setRefreshFromBlockHeight(wptr!, refresh_from_block_height: height);
197
198
void setRecoveringFromSeed({required bool isRecovery}) =>
199
wownero.Wallet_setRecoveringFromSeed(wptr!, recoveringFromSeed: isRecovery);
@@ -257,8 +268,7 @@ class SyncListener {
268
_cachedBlockchainHeight = 0;
269
_lastKnownBlockHeight = 0;
270
_initialSyncHeight = 0;
260
- _updateSyncInfoTimer ??=
261
- Timer.periodic(Duration(milliseconds: 1200), (_) async {
271
+ _updateSyncInfoTimer ??= Timer.periodic(Duration(milliseconds: 1200), (_) async {
272
if (isNewTransactionExist()) {
273
onNewTransaction();
274
}
@@ -297,8 +307,8 @@ class SyncListener {
307
void stop() => _updateSyncInfoTimer?.cancel();
308
}
309
300
-SyncListener setListeners(void Function(int, int, double) onNewBlock,
301
- void Function() onNewTransaction) {
310
+SyncListener setListeners(
311
+ void Function(int, int, double) onNewBlock, void Function() onNewTransaction) {
312
final listener = SyncListener(onNewBlock, onNewTransaction);
313
// setListenerNative();
314
return listener;
@@ -360,8 +370,7 @@ String getSubaddressLabel(int accountIndex, int addressIndex) {
370
accountIndex: accountIndex, addressIndex: addressIndex);
371
}
372
363
-Future setTrustedDaemon(bool trusted) async =>
364
- wownero.Wallet_setTrustedDaemon(wptr!, arg: trusted);
373
+Future setTrustedDaemon(bool trusted) async => wownero.Wallet_setTrustedDaemon(wptr!, arg: trusted);
374
375
Future<bool> trustedDaemon() async => wownero.Wallet_trustedDaemon(wptr!);
376
@@ -370,7 +379,8 @@ String signMessage(String message, {String address = ""}) {
379
}
380
381
bool verifyMessage(String message, String address, String signature) {
373
- return wownero.Wallet_verifySignedMessage(wptr!, message: message, address: address, signature: signature);
382
+ return wownero.Wallet_verifySignedMessage(wptr!,
383
+ message: message, address: address, signature: signature);
384
}
385
376
-Map<String, List<int>> debugCallLength() => wownero.debugCallLength;
\ No newline at end of file
386
+Map<String, List<int>> debugCallLength() => wownero.debugCallLength;
cw_wownero/lib/api/wallet_manager.dart
+39
-44
@@ -34,15 +34,18 @@ void checkIfMoneroCIsFine() {
34
final dartCsExp = wownero.wallet2_api_c_exp_sha256;
35
36
if (cppCsCpp != dartCsCpp) {
37
- throw MoneroCException("monero_c and monero.dart cpp wrapper code mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsCpp'\ndart: '$dartCsCpp'");
37
+ throw MoneroCException(
38
+ "monero_c and monero.dart cpp wrapper code mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsCpp'\ndart: '$dartCsCpp'");
39
}
40
41
if (cppCsH != dartCsH) {
41
- throw MoneroCException("monero_c and monero.dart cpp wrapper header mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsH'\ndart: '$dartCsH'");
42
+ throw MoneroCException(
43
+ "monero_c and monero.dart cpp wrapper header mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsH'\ndart: '$dartCsH'");
44
}
45
46
if (cppCsExp != dartCsExp && (Platform.isIOS || Platform.isMacOS)) {
45
- throw MoneroCException("monero_c and monero.dart wrapper export list mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsExp'\ndart: '$dartCsExp'");
47
+ throw MoneroCException(
48
+ "monero_c and monero.dart wrapper export list mismatch.\nLogic errors can occur.\nRefusing to run in release mode.\ncpp: '$cppCsExp'\ndart: '$dartCsExp'");
49
}
50
}
51
@@ -133,10 +136,10 @@ void restoreWalletFromSeedSync(
136
}
137
138
wptr = newWptr;
136
-
139
+
140
wownero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.passphrase", value: passphrase);
141
wownero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed);
139
-
142
+
143
openedWalletsByPath[path] = wptr!;
144
145
store();
@@ -153,29 +156,27 @@ void restoreWalletFromKeysSync(
156
int restoreHeight = 0}) {
157
txhistory = null;
158
var newWptr = (spendKey != "")
156
- ? wownero.WalletManager_createDeterministicWalletFromSpendKey(
157
- wmPtr,
158
- path: path,
159
- password: password,
160
- language: language,
161
- spendKeyString: spendKey,
162
- newWallet: true, // TODO(mrcyjanek): safe to remove
163
- restoreHeight: restoreHeight)
164
- : wownero.WalletManager_createWalletFromKeys(
165
- wmPtr,
166
- path: path,
167
- password: password,
168
- restoreHeight: restoreHeight,
169
- addressString: address,
170
- viewKeyString: viewKey,
171
- spendKeyString: spendKey,
172
- nettype: 0,
173
- );
159
+ ? wownero.WalletManager_createDeterministicWalletFromSpendKey(wmPtr,
160
+ path: path,
161
+ password: password,
162
+ language: language,
163
+ spendKeyString: spendKey,
164
+ newWallet: true, // TODO(mrcyjanek): safe to remove
165
+ restoreHeight: restoreHeight)
166
+ : wownero.WalletManager_createWalletFromKeys(
167
+ wmPtr,
168
+ path: path,
169
+ password: password,
170
+ restoreHeight: restoreHeight,
171
+ addressString: address,
172
+ viewKeyString: viewKey,
173
+ spendKeyString: spendKey,
174
+ nettype: 0,
175
+ );
176
177
final status = wownero.Wallet_status(newWptr);
178
if (status != 0) {
177
- throw WalletRestoreFromKeysException(
178
- message: wownero.Wallet_errorString(newWptr));
179
+ throw WalletRestoreFromKeysException(message: wownero.Wallet_errorString(newWptr));
180
}
181
// CW-712 - Try to restore deterministic wallet first, if the view key doesn't
182
// match the view key provided
@@ -184,7 +185,7 @@ void restoreWalletFromKeysSync(
185
if (viewKey != viewKeyRestored && viewKey != "") {
186
wownero.WalletManager_closeWallet(wmPtr, newWptr, false);
187
File(path).deleteSync();
187
- File(path+".keys").deleteSync();
188
+ File(path + ".keys").deleteSync();
189
newWptr = wownero.WalletManager_createWalletFromKeys(
190
wmPtr,
191
path: path,
@@ -197,8 +198,7 @@ void restoreWalletFromKeysSync(
198
);
199
final status = wownero.Wallet_status(newWptr);
200
if (status != 0) {
200
- throw WalletRestoreFromKeysException(
201
- message: wownero.Wallet_errorString(newWptr));
201
+ throw WalletRestoreFromKeysException(message: wownero.Wallet_errorString(newWptr));
202
}
203
}
204
}
@@ -207,8 +207,6 @@ void restoreWalletFromKeysSync(
207
openedWalletsByPath[path] = wptr!;
208
}
209
210
-
211
-
210
// English only, because normalization.
211
void restoreWalletFromPolyseedWithOffset(
212
{required String path,
@@ -217,7 +215,6 @@ void restoreWalletFromPolyseedWithOffset(
215
required String seedOffset,
216
required String language,
217
int nettype = 0}) {
220
-
218
txhistory = null;
219
final newWptr = wownero.WalletManager_createWalletFromPolyseed(
220
wmPtr,
@@ -332,8 +329,7 @@ String _lastOpenedWallet = "";
329
330
Map<String, wownero.wallet> openedWalletsByPath = {};
331
335
-void loadWallet(
336
- {required String path, required String password, int nettype = 0}) {
332
+void loadWallet({required String path, required String password, int nettype = 0}) {
333
if (openedWalletsByPath[path] != null) {
334
txhistory = null;
335
wptr = openedWalletsByPath[path]!;
@@ -347,8 +343,7 @@ void loadWallet(
343
});
344
}
345
txhistory = null;
350
- final newWptr = wownero.WalletManager_openWallet(wmPtr,
351
- path: path, password: password);
346
+ final newWptr = wownero.WalletManager_openWallet(wmPtr, path: path, password: password);
347
348
_lastOpenedWallet = path;
349
final status = wownero.Wallet_status(newWptr);
@@ -379,7 +374,11 @@ void _restoreFromSeed(Map<String, dynamic> args) {
374
final restoreHeight = args['restoreHeight'] as int;
375
376
restoreWalletFromSeedSync(
382
- path: path, password: password, passphrase: passphrase, seed: seed, restoreHeight: restoreHeight);
377
+ path: path,
378
+ password: password,
379
+ passphrase: passphrase,
380
+ seed: seed,
381
+ restoreHeight: restoreHeight);
382
}
383
384
void _restoreFromKeys(Map<String, dynamic> args) {
@@ -418,19 +417,15 @@ void _restoreFromSpendKey(Map<String, dynamic> args) {
417
spendKey: spendKey);
418
}
419
421
-Future<void> _openWallet(Map<String, String> args) async => loadWallet(
422
- path: args['path'] as String, password: args['password'] as String);
420
+Future<void> _openWallet(Map<String, String> args) async =>
421
+ loadWallet(path: args['path'] as String, password: args['password'] as String);
422
423
Future<bool> _isWalletExist(String path) async => isWalletExistSync(path: path);
424
426
-void openWallet(
427
- {required String path,
428
- required String password,
429
- int nettype = 0}) async =>
425
+void openWallet({required String path, required String password, int nettype = 0}) async =>
426
loadWallet(path: path, password: password, nettype: nettype);
427
432
-Future<void> openWalletAsync(Map<String, String> args) async =>
433
- _openWallet(args);
428
+Future<void> openWalletAsync(Map<String, String> args) async => _openWallet(args);
429
430
Future<void> createWallet(
431
{required String path,
cw_wownero/lib/api/wownero_output.dart
+1
-1
@@ -3,4 +3,4 @@ class WowneroOutput {
3
4
final String address;
5
final String amount;
6
-}
\ No newline at end of file
6
+}
cw_wownero/lib/cw_wownero.dart
-1
@@ -1,4 +1,3 @@
1
-
1
import 'cw_wownero_platform_interface.dart';
2
3
class CwWownero {
cw_wownero/lib/exceptions/wownero_transaction_creation_exception.dart
+1
-1
@@ -5,4 +5,4 @@ class WowneroTransactionCreationException implements Exception {
5
6
@override
7
String toString() => message;
8
-}
\ No newline at end of file
8
+}
cw_wownero/lib/exceptions/wownero_transaction_no_inputs_exception.dart
+2
-1
@@ -4,5 +4,6 @@ class WowneroTransactionNoInputsException implements Exception {
4
int inputsSize;
5
6
@override
7
- String toString() => 'Not enough inputs ($inputsSize) selected. Please select more under Coin Control';
7
+ String toString() =>
8
+ 'Not enough inputs ($inputsSize) selected. Please select more under Coin Control';
9
}
cw_wownero/lib/mnemonics/chinese_simplified.dart
+1
-1
@@ -1627,4 +1627,4 @@ class ChineseSimplifiedMnemonics {
1627
"浙",
1628
"貌"
1629
];
1630
-}
\ No newline at end of file
1630
+}
cw_wownero/lib/mnemonics/dutch.dart
+1
-1
@@ -1627,4 +1627,4 @@ class DutchMnemonics {
1627
"zwijmel",
1628
"zworen"
1629
];
1630
-}
\ No newline at end of file
1630
+}
cw_wownero/lib/mnemonics/french.dart
+1629
-1629
@@ -1,1630 +1,1630 @@
1
class FrenchMnemonics {
2
- static const words = [
3
- "abandon",
4
- "abattre",
5
- "aboi",
6
- "abolir",
7
- "aborder",
8
- "abri",
9
- "absence",
10
- "absolu",
11
- "abuser",
12
- "acacia",
13
- "acajou",
14
- "accent",
15
- "accord",
16
- "accrocher",
17
- "accuser",
18
- "acerbe",
19
- "achat",
20
- "acheter",
21
- "acide",
22
- "acier",
23
- "acquis",
24
- "acte",
25
- "action",
26
- "adage",
27
- "adepte",
28
- "adieu",
29
- "admettre",
30
- "admis",
31
- "adorer",
32
- "adresser",
33
- "aduler",
34
- "affaire",
35
- "affirmer",
36
- "afin",
37
- "agacer",
38
- "agent",
39
- "agir",
40
- "agiter",
41
- "agonie",
42
- "agrafe",
43
- "agrume",
44
- "aider",
45
- "aigle",
46
- "aigre",
47
- "aile",
48
- "ailleurs",
49
- "aimant",
50
- "aimer",
51
- "ainsi",
52
- "aise",
53
- "ajouter",
54
- "alarme",
55
- "album",
56
- "alcool",
57
- "alerte",
58
- "algue",
59
- "alibi",
60
- "aller",
61
- "allumer",
62
- "alors",
63
- "amande",
64
- "amener",
65
- "amie",
66
- "amorcer",
67
- "amour",
68
- "ample",
69
- "amuser",
70
- "ananas",
71
- "ancien",
72
- "anglais",
73
- "angoisse",
74
- "animal",
75
- "anneau",
76
- "annoncer",
77
- "apercevoir",
78
- "apparence",
79
- "appel",
80
- "apporter",
81
- "apprendre",
82
- "appuyer",
83
- "arbre",
84
- "arcade",
85
- "arceau",
86
- "arche",
87
- "ardeur",
88
- "argent",
89
- "argile",
90
- "aride",
91
- "arme",
92
- "armure",
93
- "arracher",
94
- "arriver",
95
- "article",
96
- "asile",
97
- "aspect",
98
- "assaut",
99
- "assez",
100
- "assister",
101
- "assurer",
102
- "astre",
103
- "astuce",
104
- "atlas",
105
- "atroce",
106
- "attacher",
107
- "attente",
108
- "attirer",
109
- "aube",
110
- "aucun",
111
- "audace",
112
- "auparavant",
113
- "auquel",
114
- "aurore",
115
- "aussi",
116
- "autant",
117
- "auteur",
118
- "autoroute",
119
- "autre",
120
- "aval",
121
- "avant",
122
- "avec",
123
- "avenir",
124
- "averse",
125
- "aveu",
126
- "avide",
127
- "avion",
128
- "avis",
129
- "avoir",
130
- "avouer",
131
- "avril",
132
- "azote",
133
- "azur",
134
- "badge",
135
- "bagage",
136
- "bague",
137
- "bain",
138
- "baisser",
139
- "balai",
140
- "balcon",
141
- "balise",
142
- "balle",
143
- "bambou",
144
- "banane",
145
- "banc",
146
- "bandage",
147
- "banjo",
148
- "banlieue",
149
- "bannir",
150
- "banque",
151
- "baobab",
152
- "barbe",
153
- "barque",
154
- "barrer",
155
- "bassine",
156
- "bataille",
157
- "bateau",
158
- "battre",
159
- "baver",
160
- "bavoir",
161
- "bazar",
162
- "beau",
163
- "beige",
164
- "berger",
165
- "besoin",
166
- "beurre",
167
- "biais",
168
- "biceps",
169
- "bidule",
170
- "bien",
171
- "bijou",
172
- "bilan",
173
- "billet",
174
- "blanc",
175
- "blason",
176
- "bleu",
177
- "bloc",
178
- "blond",
179
- "bocal",
180
- "boire",
181
- "boiserie",
182
- "boiter",
183
- "bonbon",
184
- "bondir",
185
- "bonheur",
186
- "bordure",
187
- "borgne",
188
- "borner",
189
- "bosse",
190
- "bouche",
191
- "bouder",
192
- "bouger",
193
- "boule",
194
- "bourse",
195
- "bout",
196
- "boxe",
197
- "brader",
198
- "braise",
199
- "branche",
200
- "braquer",
201
- "bras",
202
- "brave",
203
- "brebis",
204
- "brevet",
205
- "brider",
206
- "briller",
207
- "brin",
208
- "brique",
209
- "briser",
210
- "broche",
211
- "broder",
212
- "bronze",
213
- "brosser",
214
- "brouter",
215
- "bruit",
216
- "brute",
217
- "budget",
218
- "buffet",
219
- "bulle",
220
- "bureau",
221
- "buriner",
222
- "buste",
223
- "buter",
224
- "butiner",
225
- "cabas",
226
- "cabinet",
227
- "cabri",
228
- "cacao",
229
- "cacher",
230
- "cadeau",
231
- "cadre",
232
- "cage",
233
- "caisse",
234
- "caler",
235
- "calme",
236
- "camarade",
237
- "camion",
238
- "campagne",
239
- "canal",
240
- "canif",
241
- "capable",
242
- "capot",
243
- "carat",
244
- "caresser",
245
- "carie",
246
- "carpe",
247
- "cartel",
248
- "casier",
249
- "casque",
250
- "casserole",
251
- "cause",
252
- "cavale",
253
- "cave",
254
- "ceci",
255
- "cela",
256
- "celui",
257
- "cendre",
258
- "cent",
259
- "cependant",
260
- "cercle",
261
- "cerise",
262
- "cerner",
263
- "certes",
264
- "cerveau",
265
- "cesser",
266
- "chacun",
267
- "chair",
268
- "chaleur",
269
- "chamois",
270
- "chanson",
271
- "chaque",
272
- "charge",
273
- "chasse",
274
- "chat",
275
- "chaud",
276
- "chef",
277
- "chemin",
278
- "cheveu",
279
- "chez",
280
- "chicane",
281
- "chien",
282
- "chiffre",
283
- "chiner",
284
- "chiot",
285
- "chlore",
286
- "choc",
287
- "choix",
288
- "chose",
289
- "chou",
290
- "chute",
291
- "cibler",
292
- "cidre",
293
- "ciel",
294
- "cigale",
295
- "cinq",
296
- "cintre",
297
- "cirage",
298
- "cirque",
299
- "ciseau",
300
- "citation",
301
- "citer",
302
- "citron",
303
- "civet",
304
- "clairon",
305
- "clan",
306
- "classe",
307
- "clavier",
308
- "clef",
309
- "climat",
310
- "cloche",
311
- "cloner",
312
- "clore",
313
- "clos",
314
- "clou",
315
- "club",
316
- "cobra",
317
- "cocon",
318
- "coiffer",
319
- "coin",
320
- "colline",
321
- "colon",
322
- "combat",
323
- "comme",
324
- "compte",
325
- "conclure",
326
- "conduire",
327
- "confier",
328
- "connu",
329
- "conseil",
330
- "contre",
331
- "convenir",
332
- "copier",
333
- "cordial",
334
- "cornet",
335
- "corps",
336
- "cosmos",
337
- "coton",
338
- "couche",
339
- "coude",
340
- "couler",
341
- "coupure",
342
- "cour",
343
- "couteau",
344
- "couvrir",
345
- "crabe",
346
- "crainte",
347
- "crampe",
348
- "cran",
349
- "creuser",
350
- "crever",
351
- "crier",
352
- "crime",
353
- "crin",
354
- "crise",
355
- "crochet",
356
- "croix",
357
- "cruel",
358
- "cuisine",
359
- "cuite",
360
- "culot",
361
- "culte",
362
- "cumul",
363
- "cure",
364
- "curieux",
365
- "cuve",
366
- "dame",
367
- "danger",
368
- "dans",
369
- "davantage",
370
- "debout",
371
- "dedans",
372
- "dehors",
373
- "delta",
374
- "demain",
375
- "demeurer",
376
- "demi",
377
- "dense",
378
- "dent",
379
- "depuis",
380
- "dernier",
381
- "descendre",
382
- "dessus",
383
- "destin",
384
- "dette",
385
- "deuil",
386
- "deux",
387
- "devant",
388
- "devenir",
389
- "devin",
390
- "devoir",
391
- "dicton",
392
- "dieu",
393
- "difficile",
394
- "digestion",
395
- "digue",
396
- "diluer",
397
- "dimanche",
398
- "dinde",
399
- "diode",
400
- "dire",
401
- "diriger",
402
- "discours",
403
- "disposer",
404
- "distance",
405
- "divan",
406
- "divers",
407
- "docile",
408
- "docteur",
409
- "dodu",
410
- "dogme",
411
- "doigt",
412
- "dominer",
413
- "donation",
414
- "donjon",
415
- "donner",
416
- "dopage",
417
- "dorer",
418
- "dormir",
419
- "doseur",
420
- "douane",
421
- "double",
422
- "douche",
423
- "douleur",
424
- "doute",
425
- "doux",
426
- "douzaine",
427
- "draguer",
428
- "drame",
429
- "drap",
430
- "dresser",
431
- "droit",
432
- "duel",
433
- "dune",
434
- "duper",
435
- "durant",
436
- "durcir",
437
- "durer",
438
- "eaux",
439
- "effacer",
440
- "effet",
441
- "effort",
442
- "effrayant",
443
- "elle",
444
- "embrasser",
445
- "emmener",
446
- "emparer",
447
- "empire",
448
- "employer",
449
- "emporter",
450
- "enclos",
451
- "encore",
452
- "endive",
453
- "endormir",
454
- "endroit",
455
- "enduit",
456
- "enfant",
457
- "enfermer",
458
- "enfin",
459
- "enfler",
460
- "enfoncer",
461
- "enfuir",
462
- "engager",
463
- "engin",
464
- "enjeu",
465
- "enlever",
466
- "ennemi",
467
- "ennui",
468
- "ensemble",
469
- "ensuite",
470
- "entamer",
471
- "entendre",
472
- "entier",
473
- "entourer",
474
- "entre",
475
- "envelopper",
476
- "envie",
477
- "envoyer",
478
- "erreur",
479
- "escalier",
480
- "espace",
481
- "espoir",
482
- "esprit",
483
- "essai",
484
- "essor",
485
- "essuyer",
486
- "estimer",
487
- "exact",
488
- "examiner",
489
- "excuse",
490
- "exemple",
491
- "exiger",
492
- "exil",
493
- "exister",
494
- "exode",
495
- "expliquer",
496
- "exposer",
497
- "exprimer",
498
- "extase",
499
- "fable",
500
- "facette",
501
- "facile",
502
- "fade",
503
- "faible",
504
- "faim",
505
- "faire",
506
- "fait",
507
- "falloir",
508
- "famille",
509
- "faner",
510
- "farce",
511
- "farine",
512
- "fatigue",
513
- "faucon",
514
- "faune",
515
- "faute",
516
- "faux",
517
- "faveur",
518
- "favori",
519
- "faxer",
520
- "feinter",
521
- "femme",
522
- "fendre",
523
- "fente",
524
- "ferme",
525
- "festin",
526
- "feuille",
527
- "feutre",
528
- "fiable",
529
- "fibre",
530
- "ficher",
531
- "fier",
532
- "figer",
533
- "figure",
534
- "filet",
535
- "fille",
536
- "filmer",
537
- "fils",
538
- "filtre",
539
- "final",
540
- "finesse",
541
- "finir",
542
- "fiole",
543
- "firme",
544
- "fixe",
545
- "flacon",
546
- "flair",
547
- "flamme",
548
- "flan",
549
- "flaque",
550
- "fleur",
551
- "flocon",
552
- "flore",
553
- "flot",
554
- "flou",
555
- "fluide",
556
- "fluor",
557
- "flux",
558
- "focus",
559
- "foin",
560
- "foire",
561
- "foison",
562
- "folie",
563
- "fonction",
564
- "fondre",
565
- "fonte",
566
- "force",
567
- "forer",
568
- "forger",
569
- "forme",
570
- "fort",
571
- "fosse",
572
- "fouet",
573
- "fouine",
574
- "foule",
575
- "four",
576
- "foyer",
577
- "frais",
578
- "franc",
579
- "frapper",
580
- "freiner",
581
- "frimer",
582
- "friser",
583
- "frite",
584
- "froid",
585
- "froncer",
586
- "fruit",
587
- "fugue",
588
- "fuir",
589
- "fuite",
590
- "fumer",
591
- "fureur",
592
- "furieux",
593
- "fuser",
594
- "fusil",
595
- "futile",
596
- "futur",
597
- "gagner",
598
- "gain",
599
- "gala",
600
- "galet",
601
- "galop",
602
- "gamme",
603
- "gant",
604
- "garage",
605
- "garde",
606
- "garer",
607
- "gauche",
608
- "gaufre",
609
- "gaule",
610
- "gaver",
611
- "gazon",
612
- "geler",
613
- "genou",
614
- "genre",
615
- "gens",
616
- "gercer",
617
- "germer",
618
- "geste",
619
- "gibier",
620
- "gicler",
621
- "gilet",
622
- "girafe",
623
- "givre",
624
- "glace",
625
- "glisser",
626
- "globe",
627
- "gloire",
628
- "gluant",
629
- "gober",
630
- "golf",
631
- "gommer",
632
- "gorge",
633
- "gosier",
634
- "goutte",
635
- "grain",
636
- "gramme",
637
- "grand",
638
- "gras",
639
- "grave",
640
- "gredin",
641
- "griffure",
642
- "griller",
643
- "gris",
644
- "gronder",
645
- "gros",
646
- "grotte",
647
- "groupe",
648
- "grue",
649
- "guerrier",
650
- "guetter",
651
- "guider",
652
- "guise",
653
- "habiter",
654
- "hache",
655
- "haie",
656
- "haine",
657
- "halte",
658
- "hamac",
659
- "hanche",
660
- "hangar",
661
- "hanter",
662
- "haras",
663
- "hareng",
664
- "harpe",
665
- "hasard",
666
- "hausse",
667
- "haut",
668
- "havre",
669
- "herbe",
670
- "heure",
671
- "hibou",
672
- "hier",
673
- "histoire",
674
- "hiver",
675
- "hochet",
676
- "homme",
677
- "honneur",
678
- "honte",
679
- "horde",
680
- "horizon",
681
- "hormone",
682
- "houle",
683
- "housse",
684
- "hublot",
685
- "huile",
686
- "huit",
687
- "humain",
688
- "humble",
689
- "humide",
690
- "humour",
691
- "hurler",
692
- "idole",
693
- "igloo",
694
- "ignorer",
695
- "illusion",
696
- "image",
697
- "immense",
698
- "immobile",
699
- "imposer",
700
- "impression",
701
- "incapable",
702
- "inconnu",
703
- "index",
704
- "indiquer",
705
- "infime",
706
- "injure",
707
- "inox",
708
- "inspirer",
709
- "instant",
710
- "intention",
711
- "intime",
712
- "inutile",
713
- "inventer",
714
- "inviter",
715
- "iode",
716
- "iris",
717
- "issue",
718
- "ivre",
719
- "jade",
720
- "jadis",
721
- "jamais",
722
- "jambe",
723
- "janvier",
724
- "jardin",
725
- "jauge",
726
- "jaunisse",
727
- "jeter",
728
- "jeton",
729
- "jeudi",
730
- "jeune",
731
- "joie",
732
- "joindre",
733
- "joli",
734
- "joueur",
735
- "journal",
736
- "judo",
737
- "juge",
738
- "juillet",
739
- "juin",
740
- "jument",
741
- "jungle",
742
- "jupe",
743
- "jupon",
744
- "jurer",
745
- "juron",
746
- "jury",
747
- "jusque",
748
- "juste",
749
- "kayak",
750
- "ketchup",
751
- "kilo",
752
- "kiwi",
753
- "koala",
754
- "label",
755
- "lacet",
756
- "lacune",
757
- "laine",
758
- "laisse",
759
- "lait",
760
- "lame",
761
- "lancer",
762
- "lande",
763
- "laque",
764
- "lard",
765
- "largeur",
766
- "larme",
767
- "larve",
768
- "lasso",
769
- "laver",
770
- "lendemain",
771
- "lentement",
772
- "lequel",
773
- "lettre",
774
- "leur",
775
- "lever",
776
- "levure",
777
- "liane",
778
- "libre",
779
- "lien",
780
- "lier",
781
- "lieutenant",
782
- "ligne",
783
- "ligoter",
784
- "liguer",
785
- "limace",
786
- "limer",
787
- "limite",
788
- "lingot",
789
- "lion",
790
- "lire",
791
- "lisser",
792
- "litre",
793
- "livre",
794
- "lobe",
795
- "local",
796
- "logis",
797
- "loin",
798
- "loisir",
799
- "long",
800
- "loque",
801
- "lors",
802
- "lotus",
803
- "louer",
804
- "loup",
805
- "lourd",
806
- "louve",
807
- "loyer",
808
- "lubie",
809
- "lucide",
810
- "lueur",
811
- "luge",
812
- "luire",
813
- "lundi",
814
- "lune",
815
- "lustre",
816
- "lutin",
817
- "lutte",
818
- "luxe",
819
- "machine",
820
- "madame",
821
- "magie",
822
- "magnifique",
823
- "magot",
824
- "maigre",
825
- "main",
826
- "mairie",
827
- "maison",
828
- "malade",
829
- "malheur",
830
- "malin",
831
- "manche",
832
- "manger",
833
- "manier",
834
- "manoir",
835
- "manquer",
836
- "marche",
837
- "mardi",
838
- "marge",
839
- "mariage",
840
- "marquer",
841
- "mars",
842
- "masque",
843
- "masse",
844
- "matin",
845
- "mauvais",
846
- "meilleur",
847
- "melon",
848
- "membre",
849
- "menacer",
850
- "mener",
851
- "mensonge",
852
- "mentir",
853
- "menu",
854
- "merci",
855
- "merlu",
856
- "mesure",
857
- "mettre",
858
- "meuble",
859
- "meunier",
860
- "meute",
861
- "miche",
862
- "micro",
863
- "midi",
864
- "miel",
865
- "miette",
866
- "mieux",
867
- "milieu",
868
- "mille",
869
- "mimer",
870
- "mince",
871
- "mineur",
872
- "ministre",
873
- "minute",
874
- "mirage",
875
- "miroir",
876
- "miser",
877
- "mite",
878
- "mixte",
879
- "mobile",
880
- "mode",
881
- "module",
882
- "moins",
883
- "mois",
884
- "moment",
885
- "momie",
886
- "monde",
887
- "monsieur",
888
- "monter",
889
- "moquer",
890
- "moral",
891
- "morceau",
892
- "mordre",
893
- "morose",
894
- "morse",
895
- "mortier",
896
- "morue",
897
- "motif",
898
- "motte",
899
- "moudre",
900
- "moule",
901
- "mourir",
902
- "mousse",
903
- "mouton",
904
- "mouvement",
905
- "moyen",
906
- "muer",
907
- "muette",
908
- "mugir",
909
- "muguet",
910
- "mulot",
911
- "multiple",
912
- "munir",
913
- "muret",
914
- "muse",
915
- "musique",
916
- "muter",
917
- "nacre",
918
- "nager",
919
- "nain",
920
- "naissance",
921
- "narine",
922
- "narrer",
923
- "naseau",
924
- "nasse",
925
- "nation",
926
- "nature",
927
- "naval",
928
- "navet",
929
- "naviguer",
930
- "navrer",
931
- "neige",
932
- "nerf",
933
- "nerveux",
934
- "neuf",
935
- "neutre",
936
- "neuve",
937
- "neveu",
938
- "niche",
939
- "nier",
940
- "niveau",
941
- "noble",
942
- "noce",
943
- "nocif",
944
- "noir",
945
- "nomade",
946
- "nombre",
947
- "nommer",
948
- "nord",
949
- "norme",
950
- "notaire",
951
- "notice",
952
- "notre",
953
- "nouer",
954
- "nougat",
955
- "nourrir",
956
- "nous",
957
- "nouveau",
958
- "novice",
959
- "noyade",
960
- "noyer",
961
- "nuage",
962
- "nuance",
963
- "nuire",
964
- "nuit",
965
- "nulle",
966
- "nuque",
967
- "oasis",
968
- "objet",
969
- "obliger",
970
- "obscur",
971
- "observer",
972
- "obtenir",
973
- "obus",
974
- "occasion",
975
- "occuper",
976
- "ocre",
977
- "octet",
978
- "odeur",
979
- "odorat",
980
- "offense",
981
- "officier",
982
- "offrir",
983
- "ogive",
984
- "oiseau",
985
- "olive",
986
- "ombre",
987
- "onctueux",
988
- "onduler",
989
- "ongle",
990
- "onze",
991
- "opter",
992
- "option",
993
- "orageux",
994
- "oral",
995
- "orange",
996
- "orbite",
997
- "ordinaire",
998
- "ordre",
999
- "oreille",
1000
- "organe",
1001
- "orgie",
1002
- "orgueil",
1003
- "orient",
1004
- "origan",
1005
- "orner",
1006
- "orteil",
1007
- "ortie",
1008
- "oser",
1009
- "osselet",
1010
- "otage",
1011
- "otarie",
1012
- "ouate",
1013
- "oublier",
1014
- "ouest",
1015
- "ours",
1016
- "outil",
1017
- "outre",
1018
- "ouvert",
1019
- "ouvrir",
1020
- "ovale",
1021
- "ozone",
1022
- "pacte",
1023
- "page",
1024
- "paille",
1025
- "pain",
1026
- "paire",
1027
- "paix",
1028
- "palace",
1029
- "palissade",
1030
- "palmier",
1031
- "palpiter",
1032
- "panda",
1033
- "panneau",
1034
- "papa",
1035
- "papier",
1036
- "paquet",
1037
- "parc",
1038
- "pardi",
1039
- "parfois",
1040
- "parler",
1041
- "parmi",
1042
- "parole",
1043
- "partir",
1044
- "parvenir",
1045
- "passer",
1046
- "pastel",
1047
- "patin",
1048
- "patron",
1049
- "paume",
1050
- "pause",
1051
- "pauvre",
1052
- "paver",
1053
- "pavot",
1054
- "payer",
1055
- "pays",
1056
- "peau",
1057
- "peigne",
1058
- "peinture",
1059
- "pelage",
1060
- "pelote",
1061
- "pencher",
1062
- "pendre",
1063
- "penser",
1064
- "pente",
1065
- "percer",
1066
- "perdu",
1067
- "perle",
1068
- "permettre",
1069
- "personne",
1070
- "perte",
1071
- "peser",
1072
- "pesticide",
1073
- "petit",
1074
- "peuple",
1075
- "peur",
1076
- "phase",
1077
- "photo",
1078
- "phrase",
1079
- "piano",
1080
- "pied",
1081
- "pierre",
1082
- "pieu",
1083
- "pile",
1084
- "pilier",
1085
- "pilote",
1086
- "pilule",
1087
- "piment",
1088
- "pincer",
1089
- "pinson",
1090
- "pinte",
1091
- "pion",
1092
- "piquer",
1093
- "pirate",
1094
- "pire",
1095
- "piste",
1096
- "piton",
1097
- "pitre",
1098
- "pivot",
1099
- "pizza",
1100
- "placer",
1101
- "plage",
1102
- "plaire",
1103
- "plan",
1104
- "plaque",
1105
- "plat",
1106
- "plein",
1107
- "pleurer",
1108
- "pliage",
1109
- "plier",
1110
- "plonger",
1111
- "plot",
1112
- "pluie",
1113
- "plume",
1114
- "plus",
1115
- "pneu",
1116
- "poche",
1117
- "podium",
1118
- "poids",
1119
- "poil",
1120
- "point",
1121
- "poire",
1122
- "poison",
1123
- "poitrine",
1124
- "poivre",
1125
- "police",
1126
- "pollen",
1127
- "pomme",
1128
- "pompier",
1129
- "poncer",
1130
- "pondre",
1131
- "pont",
1132
- "portion",
1133
- "poser",
1134
- "position",
1135
- "possible",
1136
- "poste",
1137
- "potage",
1138
- "potin",
1139
- "pouce",
1140
- "poudre",
1141
- "poulet",
1142
- "poumon",
1143
- "poupe",
1144
- "pour",
1145
- "pousser",
1146
- "poutre",
1147
- "pouvoir",
1148
- "prairie",
1149
- "premier",
1150
- "prendre",
1151
- "presque",
1152
- "preuve",
1153
- "prier",
1154
- "primeur",
1155
- "prince",
1156
- "prison",
1157
- "priver",
1158
- "prix",
1159
- "prochain",
1160
- "produire",
1161
- "profond",
1162
- "proie",
1163
- "projet",
1164
- "promener",
1165
- "prononcer",
1166
- "propre",
1167
- "prose",
1168
- "prouver",
1169
- "prune",
1170
- "public",
1171
- "puce",
1172
- "pudeur",
1173
- "puiser",
1174
- "pull",
1175
- "pulpe",
1176
- "puma",
1177
- "punir",
1178
- "purge",
1179
- "putois",
1180
- "quand",
1181
- "quartier",
1182
- "quasi",
1183
- "quatre",
1184
- "quel",
1185
- "question",
1186
- "queue",
1187
- "quiche",
1188
- "quille",
1189
- "quinze",
1190
- "quitter",
1191
- "quoi",
1192
- "rabais",
1193
- "raboter",
1194
- "race",
1195
- "racheter",
1196
- "racine",
1197
- "racler",
1198
- "raconter",
1199
- "radar",
1200
- "radio",
1201
- "rafale",
1202
- "rage",
1203
- "ragot",
1204
- "raideur",
1205
- "raie",
1206
- "rail",
1207
- "raison",
1208
- "ramasser",
1209
- "ramener",
1210
- "rampe",
1211
- "rance",
1212
- "rang",
1213
- "rapace",
1214
- "rapide",
1215
- "rapport",
1216
- "rarement",
1217
- "rasage",
1218
- "raser",
1219
- "rasoir",
1220
- "rassurer",
1221
- "rater",
1222
- "ratio",
1223
- "rature",
1224
- "ravage",
1225
- "ravir",
1226
- "rayer",
1227
- "rayon",
1228
- "rebond",
1229
- "recevoir",
1230
- "recherche",
1231
- "record",
1232
- "reculer",
1233
- "redevenir",
1234
- "refuser",
1235
- "regard",
1236
- "regretter",
1237
- "rein",
1238
- "rejeter",
1239
- "rejoindre",
1240
- "relation",
1241
- "relever",
1242
- "religion",
1243
- "remarquer",
1244
- "remettre",
1245
- "remise",
1246
- "remonter",
1247
- "remplir",
1248
- "remuer",
1249
- "rencontre",
1250
- "rendre",
1251
- "renier",
1252
- "renoncer",
1253
- "rentrer",
1254
- "renverser",
1255
- "repas",
1256
- "repli",
1257
- "reposer",
1258
- "reproche",
1259
- "requin",
1260
- "respect",
1261
- "ressembler",
1262
- "reste",
1263
- "retard",
1264
- "retenir",
1265
- "retirer",
1266
- "retour",
1267
- "retrouver",
1268
- "revenir",
1269
- "revoir",
1270
- "revue",
1271
- "rhume",
1272
- "ricaner",
1273
- "riche",
1274
- "rideau",
1275
- "ridicule",
1276
- "rien",
1277
- "rigide",
1278
- "rincer",
1279
- "rire",
1280
- "risquer",
1281
- "rituel",
1282
- "rivage",
1283
- "rive",
1284
- "robe",
1285
- "robot",
1286
- "robuste",
1287
- "rocade",
1288
- "roche",
1289
- "rodeur",
1290
- "rogner",
1291
- "roman",
1292
- "rompre",
1293
- "ronce",
1294
- "rondeur",
1295
- "ronger",
1296
- "roque",
1297
- "rose",
1298
- "rosir",
1299
- "rotation",
1300
- "rotule",
1301
- "roue",
1302
- "rouge",
1303
- "rouler",
1304
- "route",
1305
- "ruban",
1306
- "rubis",
1307
- "ruche",
1308
- "rude",
1309
- "ruelle",
1310
- "ruer",
1311
- "rugby",
1312
- "rugir",
1313
- "ruine",
1314
- "rumeur",
1315
- "rural",
1316
- "ruse",
1317
- "rustre",
1318
- "sable",
1319
- "sabot",
1320
- "sabre",
1321
- "sacre",
1322
- "sage",
1323
- "saint",
1324
- "saisir",
1325
- "salade",
1326
- "salive",
1327
- "salle",
1328
- "salon",
1329
- "salto",
1330
- "salut",
1331
- "salve",
1332
- "samba",
1333
- "sandale",
1334
- "sanguin",
1335
- "sapin",
1336
- "sarcasme",
1337
- "satisfaire",
1338
- "sauce",
1339
- "sauf",
1340
- "sauge",
1341
- "saule",
1342
- "sauna",
1343
- "sauter",
1344
- "sauver",
1345
- "savoir",
1346
- "science",
1347
- "scoop",
1348
- "score",
1349
- "second",
1350
- "secret",
1351
- "secte",
1352
- "seigneur",
1353
- "sein",
1354
- "seize",
1355
- "selle",
1356
- "selon",
1357
- "semaine",
1358
- "sembler",
1359
- "semer",
1360
- "semis",
1361
- "sensuel",
1362
- "sentir",
1363
- "sept",
1364
- "serpe",
1365
- "serrer",
1366
- "sertir",
1367
- "service",
1368
- "seuil",
1369
- "seulement",
1370
- "short",
1371
- "sien",
1372
- "sigle",
1373
- "signal",
1374
- "silence",
1375
- "silo",
1376
- "simple",
1377
- "singe",
1378
- "sinon",
1379
- "sinus",
1380
- "sioux",
1381
- "sirop",
1382
- "site",
1383
- "situation",
1384
- "skier",
1385
- "snob",
1386
- "sobre",
1387
- "social",
1388
- "socle",
1389
- "sodium",
1390
- "soigner",
1391
- "soir",
1392
- "soixante",
1393
- "soja",
1394
- "solaire",
1395
- "soldat",
1396
- "soleil",
1397
- "solide",
1398
- "solo",
1399
- "solvant",
1400
- "sombre",
1401
- "somme",
1402
- "somnoler",
1403
- "sondage",
1404
- "songeur",
1405
- "sonner",
1406
- "sorte",
1407
- "sosie",
1408
- "sottise",
1409
- "souci",
1410
- "soudain",
1411
- "souffrir",
1412
- "souhaiter",
1413
- "soulever",
1414
- "soumettre",
1415
- "soupe",
1416
- "sourd",
1417
- "soustraire",
1418
- "soutenir",
1419
- "souvent",
1420
- "soyeux",
1421
- "spectacle",
1422
- "sport",
1423
- "stade",
1424
- "stagiaire",
1425
- "stand",
1426
- "star",
1427
- "statue",
1428
- "stock",
1429
- "stop",
1430
- "store",
1431
- "style",
1432
- "suave",
1433
- "subir",
1434
- "sucre",
1435
- "suer",
1436
- "suffire",
1437
- "suie",
1438
- "suite",
1439
- "suivre",
1440
- "sujet",
1441
- "sulfite",
1442
- "supposer",
1443
- "surf",
1444
- "surprendre",
1445
- "surtout",
1446
- "surveiller",
1447
- "tabac",
1448
- "table",
1449
- "tabou",
1450
- "tache",
1451
- "tacler",
1452
- "tacot",
1453
- "tact",
1454
- "taie",
1455
- "taille",
1456
- "taire",
1457
- "talon",
1458
- "talus",
1459
- "tandis",
1460
- "tango",
1461
- "tanin",
1462
- "tant",
1463
- "taper",
1464
- "tapis",
1465
- "tard",
1466
- "tarif",
1467
- "tarot",
1468
- "tarte",
1469
- "tasse",
1470
- "taureau",
1471
- "taux",
1472
- "taverne",
1473
- "taxer",
1474
- "taxi",
1475
- "tellement",
1476
- "temple",
1477
- "tendre",
1478
- "tenir",
1479
- "tenter",
1480
- "tenu",
1481
- "terme",
1482
- "ternir",
1483
- "terre",
1484
- "test",
1485
- "texte",
1486
- "thym",
1487
- "tibia",
1488
- "tiers",
1489
- "tige",
1490
- "tipi",
1491
- "tique",
1492
- "tirer",
1493
- "tissu",
1494
- "titre",
1495
- "toast",
1496
- "toge",
1497
- "toile",
1498
- "toiser",
1499
- "toiture",
1500
- "tomber",
1501
- "tome",
1502
- "tonne",
1503
- "tonte",
1504
- "toque",
1505
- "torse",
1506
- "tortue",
1507
- "totem",
1508
- "toucher",
1509
- "toujours",
1510
- "tour",
1511
- "tousser",
1512
- "tout",
1513
- "toux",
1514
- "trace",
1515
- "train",
1516
- "trame",
1517
- "tranquille",
1518
- "travail",
1519
- "trembler",
1520
- "trente",
1521
- "tribu",
1522
- "trier",
1523
- "trio",
1524
- "tripe",
1525
- "triste",
1526
- "troc",
1527
- "trois",
1528
- "tromper",
1529
- "tronc",
1530
- "trop",
1531
- "trotter",
1532
- "trouer",
1533
- "truc",
1534
- "truite",
1535
- "tuba",
1536
- "tuer",
1537
- "tuile",
1538
- "turbo",
1539
- "tutu",
1540
- "tuyau",
1541
- "type",
1542
- "union",
1543
- "unique",
1544
- "unir",
1545
- "unisson",
1546
- "untel",
1547
- "urne",
1548
- "usage",
1549
- "user",
1550
- "usiner",
1551
- "usure",
1552
- "utile",
1553
- "vache",
1554
- "vague",
1555
- "vaincre",
1556
- "valeur",
1557
- "valoir",
1558
- "valser",
1559
- "valve",
1560
- "vampire",
1561
- "vaseux",
1562
- "vaste",
1563
- "veau",
1564
- "veille",
1565
- "veine",
1566
- "velours",
1567
- "velu",
1568
- "vendre",
1569
- "venir",
1570
- "vent",
1571
- "venue",
1572
- "verbe",
1573
- "verdict",
1574
- "version",
1575
- "vertige",
1576
- "verve",
1577
- "veste",
1578
- "veto",
1579
- "vexer",
1580
- "vice",
1581
- "victime",
1582
- "vide",
1583
- "vieil",
1584
- "vieux",
1585
- "vigie",
1586
- "vigne",
1587
- "ville",
1588
- "vingt",
1589
- "violent",
1590
- "virer",
1591
- "virus",
1592
- "visage",
1593
- "viser",
1594
- "visite",
1595
- "visuel",
1596
- "vitamine",
1597
- "vitrine",
1598
- "vivant",
1599
- "vivre",
1600
- "vocal",
1601
- "vodka",
1602
- "vogue",
1603
- "voici",
1604
- "voile",
1605
- "voir",
1606
- "voisin",
1607
- "voiture",
1608
- "volaille",
1609
- "volcan",
1610
- "voler",
1611
- "volt",
1612
- "votant",
1613
- "votre",
1614
- "vouer",
1615
- "vouloir",
1616
- "vous",
1617
- "voyage",
1618
- "voyou",
1619
- "vrac",
1620
- "vrai",
1621
- "yacht",
1622
- "yeti",
1623
- "yeux",
1624
- "yoga",
1625
- "zeste",
1626
- "zinc",
1627
- "zone",
1628
- "zoom"
1629
- ];
1630
-}
\ No newline at end of file
2
+ static const words = [
3
+ "abandon",
4
+ "abattre",
5
+ "aboi",
6
+ "abolir",
7
+ "aborder",
8
+ "abri",
9
+ "absence",
10
+ "absolu",
11
+ "abuser",
12
+ "acacia",
13
+ "acajou",
14
+ "accent",
15
+ "accord",
16
+ "accrocher",
17
+ "accuser",
18
+ "acerbe",
19
+ "achat",
20
+ "acheter",
21
+ "acide",
22
+ "acier",
23
+ "acquis",
24
+ "acte",
25
+ "action",
26
+ "adage",
27
+ "adepte",
28
+ "adieu",
29
+ "admettre",
30
+ "admis",
31
+ "adorer",
32
+ "adresser",
33
+ "aduler",
34
+ "affaire",
35
+ "affirmer",
36
+ "afin",
37
+ "agacer",
38
+ "agent",
39
+ "agir",
40
+ "agiter",
41
+ "agonie",
42
+ "agrafe",
43
+ "agrume",
44
+ "aider",
45
+ "aigle",
46
+ "aigre",
47
+ "aile",
48
+ "ailleurs",
49
+ "aimant",
50
+ "aimer",
51
+ "ainsi",
52
+ "aise",
53
+ "ajouter",
54
+ "alarme",
55
+ "album",
56
+ "alcool",
57
+ "alerte",
58
+ "algue",
59
+ "alibi",
60
+ "aller",
61
+ "allumer",
62
+ "alors",
63
+ "amande",
64
+ "amener",
65
+ "amie",
66
+ "amorcer",
67
+ "amour",
68
+ "ample",
69
+ "amuser",
70
+ "ananas",
71
+ "ancien",
72
+ "anglais",
73
+ "angoisse",
74
+ "animal",
75
+ "anneau",
76
+ "annoncer",
77
+ "apercevoir",
78
+ "apparence",
79
+ "appel",
80
+ "apporter",
81
+ "apprendre",
82
+ "appuyer",
83
+ "arbre",
84
+ "arcade",
85
+ "arceau",
86
+ "arche",
87
+ "ardeur",
88
+ "argent",
89
+ "argile",
90
+ "aride",
91
+ "arme",
92
+ "armure",
93
+ "arracher",
94
+ "arriver",
95
+ "article",
96
+ "asile",
97
+ "aspect",
98
+ "assaut",
99
+ "assez",
100
+ "assister",
101
+ "assurer",
102
+ "astre",
103
+ "astuce",
104
+ "atlas",
105
+ "atroce",
106
+ "attacher",
107
+ "attente",
108
+ "attirer",
109
+ "aube",
110
+ "aucun",
111
+ "audace",
112
+ "auparavant",
113
+ "auquel",
114
+ "aurore",
115
+ "aussi",
116
+ "autant",
117
+ "auteur",
118
+ "autoroute",
119
+ "autre",
120
+ "aval",
121
+ "avant",
122
+ "avec",
123
+ "avenir",
124
+ "averse",
125
+ "aveu",
126
+ "avide",
127
+ "avion",
128
+ "avis",
129
+ "avoir",
130
+ "avouer",
131
+ "avril",
132
+ "azote",
133
+ "azur",
134
+ "badge",
135
+ "bagage",
136
+ "bague",
137
+ "bain",
138
+ "baisser",
139
+ "balai",
140
+ "balcon",
141
+ "balise",
142
+ "balle",
143
+ "bambou",
144
+ "banane",
145
+ "banc",
146
+ "bandage",
147
+ "banjo",
148
+ "banlieue",
149
+ "bannir",
150
+ "banque",
151
+ "baobab",
152
+ "barbe",
153
+ "barque",
154
+ "barrer",
155
+ "bassine",
156
+ "bataille",
157
+ "bateau",
158
+ "battre",
159
+ "baver",
160
+ "bavoir",
161
+ "bazar",
162
+ "beau",
163
+ "beige",
164
+ "berger",
165
+ "besoin",
166
+ "beurre",
167
+ "biais",
168
+ "biceps",
169
+ "bidule",
170
+ "bien",
171
+ "bijou",
172
+ "bilan",
173
+ "billet",
174
+ "blanc",
175
+ "blason",
176
+ "bleu",
177
+ "bloc",
178
+ "blond",
179
+ "bocal",
180
+ "boire",
181
+ "boiserie",
182
+ "boiter",
183
+ "bonbon",
184
+ "bondir",
185
+ "bonheur",
186
+ "bordure",
187
+ "borgne",
188
+ "borner",
189
+ "bosse",
190
+ "bouche",
191
+ "bouder",
192
+ "bouger",
193
+ "boule",
194
+ "bourse",
195
+ "bout",
196
+ "boxe",
197
+ "brader",
198
+ "braise",
199
+ "branche",
200
+ "braquer",
201
+ "bras",
202
+ "brave",
203
+ "brebis",
204
+ "brevet",
205
+ "brider",
206
+ "briller",
207
+ "brin",
208
+ "brique",
209
+ "briser",
210
+ "broche",
211
+ "broder",
212
+ "bronze",
213
+ "brosser",
214
+ "brouter",
215
+ "bruit",
216
+ "brute",
217
+ "budget",
218
+ "buffet",
219
+ "bulle",
220
+ "bureau",
221
+ "buriner",
222
+ "buste",
223
+ "buter",
224
+ "butiner",
225
+ "cabas",
226
+ "cabinet",
227
+ "cabri",
228
+ "cacao",
229
+ "cacher",
230
+ "cadeau",
231
+ "cadre",
232
+ "cage",
233
+ "caisse",
234
+ "caler",
235
+ "calme",
236
+ "camarade",
237
+ "camion",
238
+ "campagne",
239
+ "canal",
240
+ "canif",
241
+ "capable",
242
+ "capot",
243
+ "carat",
244
+ "caresser",
245
+ "carie",
246
+ "carpe",
247
+ "cartel",
248
+ "casier",
249
+ "casque",
250
+ "casserole",
251
+ "cause",
252
+ "cavale",
253
+ "cave",
254
+ "ceci",
255
+ "cela",
256
+ "celui",
257
+ "cendre",
258
+ "cent",
259
+ "cependant",
260
+ "cercle",
261
+ "cerise",
262
+ "cerner",
263
+ "certes",
264
+ "cerveau",
265
+ "cesser",
266
+ "chacun",
267
+ "chair",
268
+ "chaleur",
269
+ "chamois",
270
+ "chanson",
271
+ "chaque",
272
+ "charge",
273
+ "chasse",
274
+ "chat",
275
+ "chaud",
276
+ "chef",
277
+ "chemin",
278
+ "cheveu",
279
+ "chez",
280
+ "chicane",
281
+ "chien",
282
+ "chiffre",
283
+ "chiner",
284
+ "chiot",
285
+ "chlore",
286
+ "choc",
287
+ "choix",
288
+ "chose",
289
+ "chou",
290
+ "chute",
291
+ "cibler",
292
+ "cidre",
293
+ "ciel",
294
+ "cigale",
295
+ "cinq",
296
+ "cintre",
297
+ "cirage",
298
+ "cirque",
299
+ "ciseau",
300
+ "citation",
301
+ "citer",
302
+ "citron",
303
+ "civet",
304
+ "clairon",
305
+ "clan",
306
+ "classe",
307
+ "clavier",
308
+ "clef",
309
+ "climat",
310
+ "cloche",
311
+ "cloner",
312
+ "clore",
313
+ "clos",
314
+ "clou",
315
+ "club",
316
+ "cobra",
317
+ "cocon",
318
+ "coiffer",
319
+ "coin",
320
+ "colline",
321
+ "colon",
322
+ "combat",
323
+ "comme",
324
+ "compte",
325
+ "conclure",
326
+ "conduire",
327
+ "confier",
328
+ "connu",
329
+ "conseil",
330
+ "contre",
331
+ "convenir",
332
+ "copier",
333
+ "cordial",
334
+ "cornet",
335
+ "corps",
336
+ "cosmos",
337
+ "coton",
338
+ "couche",
339
+ "coude",
340
+ "couler",
341
+ "coupure",
342
+ "cour",
343
+ "couteau",
344
+ "couvrir",
345
+ "crabe",
346
+ "crainte",
347
+ "crampe",
348
+ "cran",
349
+ "creuser",
350
+ "crever",
351
+ "crier",
352
+ "crime",
353
+ "crin",
354
+ "crise",
355
+ "crochet",
356
+ "croix",
357
+ "cruel",
358
+ "cuisine",
359
+ "cuite",
360
+ "culot",
361
+ "culte",
362
+ "cumul",
363
+ "cure",
364
+ "curieux",
365
+ "cuve",
366
+ "dame",
367
+ "danger",
368
+ "dans",
369
+ "davantage",
370
+ "debout",
371
+ "dedans",
372
+ "dehors",
373
+ "delta",
374
+ "demain",
375
+ "demeurer",
376
+ "demi",
377
+ "dense",
378
+ "dent",
379
+ "depuis",
380
+ "dernier",
381
+ "descendre",
382
+ "dessus",
383
+ "destin",
384
+ "dette",
385
+ "deuil",
386
+ "deux",
387
+ "devant",
388
+ "devenir",
389
+ "devin",
390
+ "devoir",
391
+ "dicton",
392
+ "dieu",
393
+ "difficile",
394
+ "digestion",
395
+ "digue",
396
+ "diluer",
397
+ "dimanche",
398
+ "dinde",
399
+ "diode",
400
+ "dire",
401
+ "diriger",
402
+ "discours",
403
+ "disposer",
404
+ "distance",
405
+ "divan",
406
+ "divers",
407
+ "docile",
408
+ "docteur",
409
+ "dodu",
410
+ "dogme",
411
+ "doigt",
412
+ "dominer",
413
+ "donation",
414
+ "donjon",
415
+ "donner",
416
+ "dopage",
417
+ "dorer",
418
+ "dormir",
419
+ "doseur",
420
+ "douane",
421
+ "double",
422
+ "douche",
423
+ "douleur",
424
+ "doute",
425
+ "doux",
426
+ "douzaine",
427
+ "draguer",
428
+ "drame",
429
+ "drap",
430
+ "dresser",
431
+ "droit",
432
+ "duel",
433
+ "dune",
434
+ "duper",
435
+ "durant",
436
+ "durcir",
437
+ "durer",
438
+ "eaux",
439
+ "effacer",
440
+ "effet",
441
+ "effort",
442
+ "effrayant",
443
+ "elle",
444
+ "embrasser",
445
+ "emmener",
446
+ "emparer",
447
+ "empire",
448
+ "employer",
449
+ "emporter",
450
+ "enclos",
451
+ "encore",
452
+ "endive",
453
+ "endormir",
454
+ "endroit",
455
+ "enduit",
456
+ "enfant",
457
+ "enfermer",
458
+ "enfin",
459
+ "enfler",
460
+ "enfoncer",
461
+ "enfuir",
462
+ "engager",
463
+ "engin",
464
+ "enjeu",
465
+ "enlever",
466
+ "ennemi",
467
+ "ennui",
468
+ "ensemble",
469
+ "ensuite",
470
+ "entamer",
471
+ "entendre",
472
+ "entier",
473
+ "entourer",
474
+ "entre",
475
+ "envelopper",
476
+ "envie",
477
+ "envoyer",
478
+ "erreur",
479
+ "escalier",
480
+ "espace",
481
+ "espoir",
482
+ "esprit",
483
+ "essai",
484
+ "essor",
485
+ "essuyer",
486
+ "estimer",
487
+ "exact",
488
+ "examiner",
489
+ "excuse",
490
+ "exemple",
491
+ "exiger",
492
+ "exil",
493
+ "exister",
494
+ "exode",
495
+ "expliquer",
496
+ "exposer",
497
+ "exprimer",
498
+ "extase",
499
+ "fable",
500
+ "facette",
501
+ "facile",
502
+ "fade",
503
+ "faible",
504
+ "faim",
505
+ "faire",
506
+ "fait",
507
+ "falloir",
508
+ "famille",
509
+ "faner",
510
+ "farce",
511
+ "farine",
512
+ "fatigue",
513
+ "faucon",
514
+ "faune",
515
+ "faute",
516
+ "faux",
517
+ "faveur",
518
+ "favori",
519
+ "faxer",
520
+ "feinter",
521
+ "femme",
522
+ "fendre",
523
+ "fente",
524
+ "ferme",
525
+ "festin",
526
+ "feuille",
527
+ "feutre",
528
+ "fiable",
529
+ "fibre",
530
+ "ficher",
531
+ "fier",
532
+ "figer",
533
+ "figure",
534
+ "filet",
535
+ "fille",
536
+ "filmer",
537
+ "fils",
538
+ "filtre",
539
+ "final",
540
+ "finesse",
541
+ "finir",
542
+ "fiole",
543
+ "firme",
544
+ "fixe",
545
+ "flacon",
546
+ "flair",
547
+ "flamme",
548
+ "flan",
549
+ "flaque",
550
+ "fleur",
551
+ "flocon",
552
+ "flore",
553
+ "flot",
554
+ "flou",
555
+ "fluide",
556
+ "fluor",
557
+ "flux",
558
+ "focus",
559
+ "foin",
560
+ "foire",
561
+ "foison",
562
+ "folie",
563
+ "fonction",
564
+ "fondre",
565
+ "fonte",
566
+ "force",
567
+ "forer",
568
+ "forger",
569
+ "forme",
570
+ "fort",
571
+ "fosse",
572
+ "fouet",
573
+ "fouine",
574
+ "foule",
575
+ "four",
576
+ "foyer",
577
+ "frais",
578
+ "franc",
579
+ "frapper",
580
+ "freiner",
581
+ "frimer",
582
+ "friser",
583
+ "frite",
584
+ "froid",
585
+ "froncer",
586
+ "fruit",
587
+ "fugue",
588
+ "fuir",
589
+ "fuite",
590
+ "fumer",
591
+ "fureur",
592
+ "furieux",
593
+ "fuser",
594
+ "fusil",
595
+ "futile",
596
+ "futur",
597
+ "gagner",
598
+ "gain",
599
+ "gala",
600
+ "galet",
601
+ "galop",
602
+ "gamme",
603
+ "gant",
604
+ "garage",
605
+ "garde",
606
+ "garer",
607
+ "gauche",
608
+ "gaufre",
609
+ "gaule",
610
+ "gaver",
611
+ "gazon",
612
+ "geler",
613
+ "genou",
614
+ "genre",
615
+ "gens",
616
+ "gercer",
617
+ "germer",
618
+ "geste",
619
+ "gibier",
620
+ "gicler",
621
+ "gilet",
622
+ "girafe",
623
+ "givre",
624
+ "glace",
625
+ "glisser",
626
+ "globe",
627
+ "gloire",
628
+ "gluant",
629
+ "gober",
630
+ "golf",
631
+ "gommer",
632
+ "gorge",
633
+ "gosier",
634
+ "goutte",
635
+ "grain",
636
+ "gramme",
637
+ "grand",
638
+ "gras",
639
+ "grave",
640
+ "gredin",
641
+ "griffure",
642
+ "griller",
643
+ "gris",
644
+ "gronder",
645
+ "gros",
646
+ "grotte",
647
+ "groupe",
648
+ "grue",
649
+ "guerrier",
650
+ "guetter",
651
+ "guider",
652
+ "guise",
653
+ "habiter",
654
+ "hache",
655
+ "haie",
656
+ "haine",
657
+ "halte",
658
+ "hamac",
659
+ "hanche",
660
+ "hangar",
661
+ "hanter",
662
+ "haras",
663
+ "hareng",
664
+ "harpe",
665
+ "hasard",
666
+ "hausse",
667
+ "haut",
668
+ "havre",
669
+ "herbe",
670
+ "heure",
671
+ "hibou",
672
+ "hier",
673
+ "histoire",
674
+ "hiver",
675
+ "hochet",
676
+ "homme",
677
+ "honneur",
678
+ "honte",
679
+ "horde",
680
+ "horizon",
681
+ "hormone",
682
+ "houle",
683
+ "housse",
684
+ "hublot",
685
+ "huile",
686
+ "huit",
687
+ "humain",
688
+ "humble",
689
+ "humide",
690
+ "humour",
691
+ "hurler",
692
+ "idole",
693
+ "igloo",
694
+ "ignorer",
695
+ "illusion",
696
+ "image",
697
+ "immense",
698
+ "immobile",
699
+ "imposer",
700
+ "impression",
701
+ "incapable",
702
+ "inconnu",
703
+ "index",
704
+ "indiquer",
705
+ "infime",
706
+ "injure",
707
+ "inox",
708
+ "inspirer",
709
+ "instant",
710
+ "intention",
711
+ "intime",
712
+ "inutile",
713
+ "inventer",
714
+ "inviter",
715
+ "iode",
716
+ "iris",
717
+ "issue",
718
+ "ivre",
719
+ "jade",
720
+ "jadis",
721
+ "jamais",
722
+ "jambe",
723
+ "janvier",
724
+ "jardin",
725
+ "jauge",
726
+ "jaunisse",
727
+ "jeter",
728
+ "jeton",
729
+ "jeudi",
730
+ "jeune",
731
+ "joie",
732
+ "joindre",
733
+ "joli",
734
+ "joueur",
735
+ "journal",
736
+ "judo",
737
+ "juge",
738
+ "juillet",
739
+ "juin",
740
+ "jument",
741
+ "jungle",
742
+ "jupe",
743
+ "jupon",
744
+ "jurer",
745
+ "juron",
746
+ "jury",
747
+ "jusque",
748
+ "juste",
749
+ "kayak",
750
+ "ketchup",
751
+ "kilo",
752
+ "kiwi",
753
+ "koala",
754
+ "label",
755
+ "lacet",
756
+ "lacune",
757
+ "laine",
758
+ "laisse",
759
+ "lait",
760
+ "lame",
761
+ "lancer",
762
+ "lande",
763
+ "laque",
764
+ "lard",
765
+ "largeur",
766
+ "larme",
767
+ "larve",
768
+ "lasso",
769
+ "laver",
770
+ "lendemain",
771
+ "lentement",
772
+ "lequel",
773
+ "lettre",
774
+ "leur",
775
+ "lever",
776
+ "levure",
777
+ "liane",
778
+ "libre",
779
+ "lien",
780
+ "lier",
781
+ "lieutenant",
782
+ "ligne",
783
+ "ligoter",
784
+ "liguer",
785
+ "limace",
786
+ "limer",
787
+ "limite",
788
+ "lingot",
789
+ "lion",
790
+ "lire",
791
+ "lisser",
792
+ "litre",
793
+ "livre",
794
+ "lobe",
795
+ "local",
796
+ "logis",
797
+ "loin",
798
+ "loisir",
799
+ "long",
800
+ "loque",
801
+ "lors",
802
+ "lotus",
803
+ "louer",
804
+ "loup",
805
+ "lourd",
806
+ "louve",
807
+ "loyer",
808
+ "lubie",
809
+ "lucide",
810
+ "lueur",
811
+ "luge",
812
+ "luire",
813
+ "lundi",
814
+ "lune",
815
+ "lustre",
816
+ "lutin",
817
+ "lutte",
818
+ "luxe",
819
+ "machine",
820
+ "madame",
821
+ "magie",
822
+ "magnifique",
823
+ "magot",
824
+ "maigre",
825
+ "main",
826
+ "mairie",
827
+ "maison",
828
+ "malade",
829
+ "malheur",
830
+ "malin",
831
+ "manche",
832
+ "manger",
833
+ "manier",
834
+ "manoir",
835
+ "manquer",
836
+ "marche",
837
+ "mardi",
838
+ "marge",
839
+ "mariage",
840
+ "marquer",
841
+ "mars",
842
+ "masque",
843
+ "masse",
844
+ "matin",
845
+ "mauvais",
846
+ "meilleur",
847
+ "melon",
848
+ "membre",
849
+ "menacer",
850
+ "mener",
851
+ "mensonge",
852
+ "mentir",
853
+ "menu",
854
+ "merci",
855
+ "merlu",
856
+ "mesure",
857
+ "mettre",
858
+ "meuble",
859
+ "meunier",
860
+ "meute",
861
+ "miche",
862
+ "micro",
863
+ "midi",
864
+ "miel",
865
+ "miette",
866
+ "mieux",
867
+ "milieu",
868
+ "mille",
869
+ "mimer",
870
+ "mince",
871
+ "mineur",
872
+ "ministre",
873
+ "minute",
874
+ "mirage",
875
+ "miroir",
876
+ "miser",
877
+ "mite",
878
+ "mixte",
879
+ "mobile",
880
+ "mode",
881
+ "module",
882
+ "moins",
883
+ "mois",
884
+ "moment",
885
+ "momie",
886
+ "monde",
887
+ "monsieur",
888
+ "monter",
889
+ "moquer",
890
+ "moral",
891
+ "morceau",
892
+ "mordre",
893
+ "morose",
894
+ "morse",
895
+ "mortier",
896
+ "morue",
897
+ "motif",
898
+ "motte",
899
+ "moudre",
900
+ "moule",
901
+ "mourir",
902
+ "mousse",
903
+ "mouton",
904
+ "mouvement",
905
+ "moyen",
906
+ "muer",
907
+ "muette",
908
+ "mugir",
909
+ "muguet",
910
+ "mulot",
911
+ "multiple",
912
+ "munir",
913
+ "muret",
914
+ "muse",
915
+ "musique",
916
+ "muter",
917
+ "nacre",
918
+ "nager",
919
+ "nain",
920
+ "naissance",
921
+ "narine",
922
+ "narrer",
923
+ "naseau",
924
+ "nasse",
925
+ "nation",
926
+ "nature",
927
+ "naval",
928
+ "navet",
929
+ "naviguer",
930
+ "navrer",
931
+ "neige",
932
+ "nerf",
933
+ "nerveux",
934
+ "neuf",
935
+ "neutre",
936
+ "neuve",
937
+ "neveu",
938
+ "niche",
939
+ "nier",
940
+ "niveau",
941
+ "noble",
942
+ "noce",
943
+ "nocif",
944
+ "noir",
945
+ "nomade",
946
+ "nombre",
947
+ "nommer",
948
+ "nord",
949
+ "norme",
950
+ "notaire",
951
+ "notice",
952
+ "notre",
953
+ "nouer",
954
+ "nougat",
955
+ "nourrir",
956
+ "nous",
957
+ "nouveau",
958
+ "novice",
959
+ "noyade",
960
+ "noyer",
961
+ "nuage",
962
+ "nuance",
963
+ "nuire",
964
+ "nuit",
965
+ "nulle",
966
+ "nuque",
967
+ "oasis",
968
+ "objet",
969
+ "obliger",
970
+ "obscur",
971
+ "observer",
972
+ "obtenir",
973
+ "obus",
974
+ "occasion",
975
+ "occuper",
976
+ "ocre",
977
+ "octet",
978
+ "odeur",
979
+ "odorat",
980
+ "offense",
981
+ "officier",
982
+ "offrir",
983
+ "ogive",
984
+ "oiseau",
985
+ "olive",
986
+ "ombre",
987
+ "onctueux",
988
+ "onduler",
989
+ "ongle",
990
+ "onze",
991
+ "opter",
992
+ "option",
993
+ "orageux",
994
+ "oral",
995
+ "orange",
996
+ "orbite",
997
+ "ordinaire",
998
+ "ordre",
999
+ "oreille",
1000
+ "organe",
1001
+ "orgie",
1002
+ "orgueil",
1003
+ "orient",
1004
+ "origan",
1005
+ "orner",
1006
+ "orteil",
1007
+ "ortie",
1008
+ "oser",
1009
+ "osselet",
1010
+ "otage",
1011
+ "otarie",
1012
+ "ouate",
1013
+ "oublier",
1014
+ "ouest",
1015
+ "ours",
1016
+ "outil",
1017
+ "outre",
1018
+ "ouvert",
1019
+ "ouvrir",
1020
+ "ovale",
1021
+ "ozone",
1022
+ "pacte",
1023
+ "page",
1024
+ "paille",
1025
+ "pain",
1026
+ "paire",
1027
+ "paix",
1028
+ "palace",
1029
+ "palissade",
1030
+ "palmier",
1031
+ "palpiter",
1032
+ "panda",
1033
+ "panneau",
1034
+ "papa",
1035
+ "papier",
1036
+ "paquet",
1037
+ "parc",
1038
+ "pardi",
1039
+ "parfois",
1040
+ "parler",
1041
+ "parmi",
1042
+ "parole",
1043
+ "partir",
1044
+ "parvenir",
1045
+ "passer",
1046
+ "pastel",
1047
+ "patin",
1048
+ "patron",
1049
+ "paume",
1050
+ "pause",
1051
+ "pauvre",
1052
+ "paver",
1053
+ "pavot",
1054
+ "payer",
1055
+ "pays",
1056
+ "peau",
1057
+ "peigne",
1058
+ "peinture",
1059
+ "pelage",
1060
+ "pelote",
1061
+ "pencher",
1062
+ "pendre",
1063
+ "penser",
1064
+ "pente",
1065
+ "percer",
1066
+ "perdu",
1067
+ "perle",
1068
+ "permettre",
1069
+ "personne",
1070
+ "perte",
1071
+ "peser",
1072
+ "pesticide",
1073
+ "petit",
1074
+ "peuple",
1075
+ "peur",
1076
+ "phase",
1077
+ "photo",
1078
+ "phrase",
1079
+ "piano",
1080
+ "pied",
1081
+ "pierre",
1082
+ "pieu",
1083
+ "pile",
1084
+ "pilier",
1085
+ "pilote",
1086
+ "pilule",
1087
+ "piment",
1088
+ "pincer",
1089
+ "pinson",
1090
+ "pinte",
1091
+ "pion",
1092
+ "piquer",
1093
+ "pirate",
1094
+ "pire",
1095
+ "piste",
1096
+ "piton",
1097
+ "pitre",
1098
+ "pivot",
1099
+ "pizza",
1100
+ "placer",
1101
+ "plage",
1102
+ "plaire",
1103
+ "plan",
1104
+ "plaque",
1105
+ "plat",
1106
+ "plein",
1107
+ "pleurer",
1108
+ "pliage",
1109
+ "plier",
1110
+ "plonger",
1111
+ "plot",
1112
+ "pluie",
1113
+ "plume",
1114
+ "plus",
1115
+ "pneu",
1116
+ "poche",
1117
+ "podium",
1118
+ "poids",
1119
+ "poil",
1120
+ "point",
1121
+ "poire",
1122
+ "poison",
1123
+ "poitrine",
1124
+ "poivre",
1125
+ "police",
1126
+ "pollen",
1127
+ "pomme",
1128
+ "pompier",
1129
+ "poncer",
1130
+ "pondre",
1131
+ "pont",
1132
+ "portion",
1133
+ "poser",
1134
+ "position",
1135
+ "possible",
1136
+ "poste",
1137
+ "potage",
1138
+ "potin",
1139
+ "pouce",
1140
+ "poudre",
1141
+ "poulet",
1142
+ "poumon",
1143
+ "poupe",
1144
+ "pour",
1145
+ "pousser",
1146
+ "poutre",
1147
+ "pouvoir",
1148
+ "prairie",
1149
+ "premier",
1150
+ "prendre",
1151
+ "presque",
1152
+ "preuve",
1153
+ "prier",
1154
+ "primeur",
1155
+ "prince",
1156
+ "prison",
1157
+ "priver",
1158
+ "prix",
1159
+ "prochain",
1160
+ "produire",
1161
+ "profond",
1162
+ "proie",
1163
+ "projet",
1164
+ "promener",
1165
+ "prononcer",
1166
+ "propre",
1167
+ "prose",
1168
+ "prouver",
1169
+ "prune",
1170
+ "public",
1171
+ "puce",
1172
+ "pudeur",
1173
+ "puiser",
1174
+ "pull",
1175
+ "pulpe",
1176
+ "puma",
1177
+ "punir",
1178
+ "purge",
1179
+ "putois",
1180
+ "quand",
1181
+ "quartier",
1182
+ "quasi",
1183
+ "quatre",
1184
+ "quel",
1185
+ "question",
1186
+ "queue",
1187
+ "quiche",
1188
+ "quille",
1189
+ "quinze",
1190
+ "quitter",
1191
+ "quoi",
1192
+ "rabais",
1193
+ "raboter",
1194
+ "race",
1195
+ "racheter",
1196
+ "racine",
1197
+ "racler",
1198
+ "raconter",
1199
+ "radar",
1200
+ "radio",
1201
+ "rafale",
1202
+ "rage",
1203
+ "ragot",
1204
+ "raideur",
1205
+ "raie",
1206
+ "rail",
1207
+ "raison",
1208
+ "ramasser",
1209
+ "ramener",
1210
+ "rampe",
1211
+ "rance",
1212
+ "rang",
1213
+ "rapace",
1214
+ "rapide",
1215
+ "rapport",
1216
+ "rarement",
1217
+ "rasage",
1218
+ "raser",
1219
+ "rasoir",
1220
+ "rassurer",
1221
+ "rater",
1222
+ "ratio",
1223
+ "rature",
1224
+ "ravage",
1225
+ "ravir",
1226
+ "rayer",
1227
+ "rayon",
1228
+ "rebond",
1229
+ "recevoir",
1230
+ "recherche",
1231
+ "record",
1232
+ "reculer",
1233
+ "redevenir",
1234
+ "refuser",
1235
+ "regard",
1236
+ "regretter",
1237
+ "rein",
1238
+ "rejeter",
1239
+ "rejoindre",
1240
+ "relation",
1241
+ "relever",
1242
+ "religion",
1243
+ "remarquer",
1244
+ "remettre",
1245
+ "remise",
1246
+ "remonter",
1247
+ "remplir",
1248
+ "remuer",
1249
+ "rencontre",
1250
+ "rendre",
1251
+ "renier",
1252
+ "renoncer",
1253
+ "rentrer",
1254
+ "renverser",
1255
+ "repas",
1256
+ "repli",
1257
+ "reposer",
1258
+ "reproche",
1259
+ "requin",
1260
+ "respect",
1261
+ "ressembler",
1262
+ "reste",
1263
+ "retard",
1264
+ "retenir",
1265
+ "retirer",
1266
+ "retour",
1267
+ "retrouver",
1268
+ "revenir",
1269
+ "revoir",
1270
+ "revue",
1271
+ "rhume",
1272
+ "ricaner",
1273
+ "riche",
1274
+ "rideau",
1275
+ "ridicule",
1276
+ "rien",
1277
+ "rigide",
1278
+ "rincer",
1279
+ "rire",
1280
+ "risquer",
1281
+ "rituel",
1282
+ "rivage",
1283
+ "rive",
1284
+ "robe",
1285
+ "robot",
1286
+ "robuste",
1287
+ "rocade",
1288
+ "roche",
1289
+ "rodeur",
1290
+ "rogner",
1291
+ "roman",
1292
+ "rompre",
1293
+ "ronce",
1294
+ "rondeur",
1295
+ "ronger",
1296
+ "roque",
1297
+ "rose",
1298
+ "rosir",
1299
+ "rotation",
1300
+ "rotule",
1301
+ "roue",
1302
+ "rouge",
1303
+ "rouler",
1304
+ "route",
1305
+ "ruban",
1306
+ "rubis",
1307
+ "ruche",
1308
+ "rude",
1309
+ "ruelle",
1310
+ "ruer",
1311
+ "rugby",
1312
+ "rugir",
1313
+ "ruine",
1314
+ "rumeur",
1315
+ "rural",
1316
+ "ruse",
1317
+ "rustre",
1318
+ "sable",
1319
+ "sabot",
1320
+ "sabre",
1321
+ "sacre",
1322
+ "sage",
1323
+ "saint",
1324
+ "saisir",
1325
+ "salade",
1326
+ "salive",
1327
+ "salle",
1328
+ "salon",
1329
+ "salto",
1330
+ "salut",
1331
+ "salve",
1332
+ "samba",
1333
+ "sandale",
1334
+ "sanguin",
1335
+ "sapin",
1336
+ "sarcasme",
1337
+ "satisfaire",
1338
+ "sauce",
1339
+ "sauf",
1340
+ "sauge",
1341
+ "saule",
1342
+ "sauna",
1343
+ "sauter",
1344
+ "sauver",
1345
+ "savoir",
1346
+ "science",
1347
+ "scoop",
1348
+ "score",
1349
+ "second",
1350
+ "secret",
1351
+ "secte",
1352
+ "seigneur",
1353
+ "sein",
1354
+ "seize",
1355
+ "selle",
1356
+ "selon",
1357
+ "semaine",
1358
+ "sembler",
1359
+ "semer",
1360
+ "semis",
1361
+ "sensuel",
1362
+ "sentir",
1363
+ "sept",
1364
+ "serpe",
1365
+ "serrer",
1366
+ "sertir",
1367
+ "service",
1368
+ "seuil",
1369
+ "seulement",
1370
+ "short",
1371
+ "sien",
1372
+ "sigle",
1373
+ "signal",
1374
+ "silence",
1375
+ "silo",
1376
+ "simple",
1377
+ "singe",
1378
+ "sinon",
1379
+ "sinus",
1380
+ "sioux",
1381
+ "sirop",
1382
+ "site",
1383
+ "situation",
1384
+ "skier",
1385
+ "snob",
1386
+ "sobre",
1387
+ "social",
1388
+ "socle",
1389
+ "sodium",
1390
+ "soigner",
1391
+ "soir",
1392
+ "soixante",
1393
+ "soja",
1394
+ "solaire",
1395
+ "soldat",
1396
+ "soleil",
1397
+ "solide",
1398
+ "solo",
1399
+ "solvant",
1400
+ "sombre",
1401
+ "somme",
1402
+ "somnoler",
1403
+ "sondage",
1404
+ "songeur",
1405
+ "sonner",
1406
+ "sorte",
1407
+ "sosie",
1408
+ "sottise",
1409
+ "souci",
1410
+ "soudain",
1411
+ "souffrir",
1412
+ "souhaiter",
1413
+ "soulever",
1414
+ "soumettre",
1415
+ "soupe",
1416
+ "sourd",
1417
+ "soustraire",
1418
+ "soutenir",
1419
+ "souvent",
1420
+ "soyeux",
1421
+ "spectacle",
1422
+ "sport",
1423
+ "stade",
1424
+ "stagiaire",
1425
+ "stand",
1426
+ "star",
1427
+ "statue",
1428
+ "stock",
1429
+ "stop",
1430
+ "store",
1431
+ "style",
1432
+ "suave",
1433
+ "subir",
1434
+ "sucre",
1435
+ "suer",
1436
+ "suffire",
1437
+ "suie",
1438
+ "suite",
1439
+ "suivre",
1440
+ "sujet",
1441
+ "sulfite",
1442
+ "supposer",
1443
+ "surf",
1444
+ "surprendre",
1445
+ "surtout",
1446
+ "surveiller",
1447
+ "tabac",
1448
+ "table",
1449
+ "tabou",
1450
+ "tache",
1451
+ "tacler",
1452
+ "tacot",
1453
+ "tact",
1454
+ "taie",
1455
+ "taille",
1456
+ "taire",
1457
+ "talon",
1458
+ "talus",
1459
+ "tandis",
1460
+ "tango",
1461
+ "tanin",
1462
+ "tant",
1463
+ "taper",
1464
+ "tapis",
1465
+ "tard",
1466
+ "tarif",
1467
+ "tarot",
1468
+ "tarte",
1469
+ "tasse",
1470
+ "taureau",
1471
+ "taux",
1472
+ "taverne",
1473
+ "taxer",
1474
+ "taxi",
1475
+ "tellement",
1476
+ "temple",
1477
+ "tendre",
1478
+ "tenir",
1479
+ "tenter",
1480
+ "tenu",
1481
+ "terme",
1482
+ "ternir",
1483
+ "terre",
1484
+ "test",
1485
+ "texte",
1486
+ "thym",
1487
+ "tibia",
1488
+ "tiers",
1489
+ "tige",
1490
+ "tipi",
1491
+ "tique",
1492
+ "tirer",
1493
+ "tissu",
1494
+ "titre",
1495
+ "toast",
1496
+ "toge",
1497
+ "toile",
1498
+ "toiser",
1499
+ "toiture",
1500
+ "tomber",
1501
+ "tome",
1502
+ "tonne",
1503
+ "tonte",
1504
+ "toque",
1505
+ "torse",
1506
+ "tortue",
1507
+ "totem",
1508
+ "toucher",
1509
+ "toujours",
1510
+ "tour",
1511
+ "tousser",
1512
+ "tout",
1513
+ "toux",
1514
+ "trace",
1515
+ "train",
1516
+ "trame",
1517
+ "tranquille",
1518
+ "travail",
1519
+ "trembler",
1520
+ "trente",
1521
+ "tribu",
1522
+ "trier",
1523
+ "trio",
1524
+ "tripe",
1525
+ "triste",
1526
+ "troc",
1527
+ "trois",
1528
+ "tromper",
1529
+ "tronc",
1530
+ "trop",
1531
+ "trotter",
1532
+ "trouer",
1533
+ "truc",
1534
+ "truite",
1535
+ "tuba",
1536
+ "tuer",
1537
+ "tuile",
1538
+ "turbo",
1539
+ "tutu",
1540
+ "tuyau",
1541
+ "type",
1542
+ "union",
1543
+ "unique",
1544
+ "unir",
1545
+ "unisson",
1546
+ "untel",
1547
+ "urne",
1548
+ "usage",
1549
+ "user",
1550
+ "usiner",
1551
+ "usure",
1552
+ "utile",
1553
+ "vache",
1554
+ "vague",
1555
+ "vaincre",
1556
+ "valeur",
1557
+ "valoir",
1558
+ "valser",
1559
+ "valve",
1560
+ "vampire",
1561
+ "vaseux",
1562
+ "vaste",
1563
+ "veau",
1564
+ "veille",
1565
+ "veine",
1566
+ "velours",
1567
+ "velu",
1568
+ "vendre",
1569
+ "venir",
1570
+ "vent",
1571
+ "venue",
1572
+ "verbe",
1573
+ "verdict",
1574
+ "version",
1575
+ "vertige",
1576
+ "verve",
1577
+ "veste",
1578
+ "veto",
1579
+ "vexer",
1580
+ "vice",
1581
+ "victime",
1582
+ "vide",
1583
+ "vieil",
1584
+ "vieux",
1585
+ "vigie",
1586
+ "vigne",
1587
+ "ville",
1588
+ "vingt",
1589
+ "violent",
1590
+ "virer",
1591
+ "virus",
1592
+ "visage",
1593
+ "viser",
1594
+ "visite",
1595
+ "visuel",
1596
+ "vitamine",
1597
+ "vitrine",
1598
+ "vivant",
1599
+ "vivre",
1600
+ "vocal",
1601
+ "vodka",
1602
+ "vogue",
1603
+ "voici",
1604
+ "voile",
1605
+ "voir",
1606
+ "voisin",
1607
+ "voiture",
1608
+ "volaille",
1609
+ "volcan",
1610
+ "voler",
1611
+ "volt",
1612
+ "votant",
1613
+ "votre",
1614
+ "vouer",
1615
+ "vouloir",
1616
+ "vous",
1617
+ "voyage",
1618
+ "voyou",
1619
+ "vrac",
1620
+ "vrai",
1621
+ "yacht",
1622
+ "yeti",
1623
+ "yeux",
1624
+ "yoga",
1625
+ "zeste",
1626
+ "zinc",
1627
+ "zone",
1628
+ "zoom"
1629
+ ];
1630
+}
cw_wownero/lib/mnemonics/german.dart
+1
-1
@@ -1627,4 +1627,4 @@ class GermanMnemonics {
1627
"Zweck",
1628
"Zyklop"
1629
];
1630
-}
\ No newline at end of file
1630
+}
cw_wownero/lib/mnemonics/italian.dart
+1629
-1629
@@ -1,1630 +1,1630 @@
1
class ItalianMnemonics {
2
- static const words = [
3
- "abbinare",
4
- "abbonato",
5
- "abisso",
6
- "abitare",
7
- "abominio",
8
- "accadere",
9
- "accesso",
10
- "acciaio",
11
- "accordo",
12
- "accumulo",
13
- "acido",
14
- "acqua",
15
- "acrobata",
16
- "acustico",
17
- "adattare",
18
- "addetto",
19
- "addio",
20
- "addome",
21
- "adeguato",
22
- "aderire",
23
- "adorare",
24
- "adottare",
25
- "adozione",
26
- "adulto",
27
- "aereo",
28
- "aerobica",
29
- "affare",
30
- "affetto",
31
- "affidare",
32
- "affogato",
33
- "affronto",
34
- "africano",
35
- "afrodite",
36
- "agenzia",
37
- "aggancio",
38
- "aggeggio",
39
- "aggiunta",
40
- "agio",
41
- "agire",
42
- "agitare",
43
- "aglio",
44
- "agnello",
45
- "agosto",
46
- "aiutare",
47
- "albero",
48
- "albo",
49
- "alce",
50
- "alchimia",
51
- "alcool",
52
- "alfabeto",
53
- "algebra",
54
- "alimento",
55
- "allarme",
56
- "alleanza",
57
- "allievo",
58
- "alloggio",
59
- "alluce",
60
- "alpi",
61
- "alterare",
62
- "altro",
63
- "aluminio",
64
- "amante",
65
- "amarezza",
66
- "ambiente",
67
- "ambrosia",
68
- "america",
69
- "amico",
70
- "ammalare",
71
- "ammirare",
72
- "amnesia",
73
- "amnistia",
74
- "amore",
75
- "ampliare",
76
- "amputare",
77
- "analisi",
78
- "anamnesi",
79
- "ananas",
80
- "anarchia",
81
- "anatra",
82
- "anca",
83
- "ancorato",
84
- "andare",
85
- "androide",
86
- "aneddoto",
87
- "anello",
88
- "angelo",
89
- "angolino",
90
- "anguilla",
91
- "anidride",
92
- "anima",
93
- "annegare",
94
- "anno",
95
- "annuncio",
96
- "anomalia",
97
- "antenna",
98
- "anticipo",
99
- "aperto",
100
- "apostolo",
101
- "appalto",
102
- "appello",
103
- "appiglio",
104
- "applauso",
105
- "appoggio",
106
- "appurare",
107
- "aprile",
108
- "aquila",
109
- "arabo",
110
- "arachidi",
111
- "aragosta",
112
- "arancia",
113
- "arbitrio",
114
- "archivio",
115
- "arco",
116
- "argento",
117
- "argilla",
118
- "aria",
119
- "ariete",
120
- "arma",
121
- "armonia",
122
- "aroma",
123
- "arrivare",
124
- "arrosto",
125
- "arsenale",
126
- "arte",
127
- "artiglio",
128
- "asfalto",
129
- "asfissia",
130
- "asino",
131
- "asparagi",
132
- "aspirina",
133
- "assalire",
134
- "assegno",
135
- "assolto",
136
- "assurdo",
137
- "asta",
138
- "astratto",
139
- "atlante",
140
- "atletica",
141
- "atomo",
142
- "atropina",
143
- "attacco",
144
- "attesa",
145
- "attico",
146
- "atto",
147
- "attrarre",
148
- "auguri",
149
- "aula",
150
- "aumento",
151
- "aurora",
152
- "auspicio",
153
- "autista",
154
- "auto",
155
- "autunno",
156
- "avanzare",
157
- "avarizia",
158
- "avere",
159
- "aviatore",
160
- "avido",
161
- "avorio",
162
- "avvenire",
163
- "avviso",
164
- "avvocato",
165
- "azienda",
166
- "azione",
167
- "azzardo",
168
- "azzurro",
169
- "babbuino",
170
- "bacio",
171
- "badante",
172
- "baffi",
173
- "bagaglio",
174
- "bagliore",
175
- "bagno",
176
- "balcone",
177
- "balena",
178
- "ballare",
179
- "balordo",
180
- "balsamo",
181
- "bambola",
182
- "bancomat",
183
- "banda",
184
- "barato",
185
- "barba",
186
- "barista",
187
- "barriera",
188
- "basette",
189
- "basilico",
190
- "bassista",
191
- "bastare",
192
- "battello",
193
- "bavaglio",
194
- "beccare",
195
- "beduino",
196
- "bellezza",
197
- "bene",
198
- "benzina",
199
- "berretto",
200
- "bestia",
201
- "bevitore",
202
- "bianco",
203
- "bibbia",
204
- "biberon",
205
- "bibita",
206
- "bici",
207
- "bidone",
208
- "bilancia",
209
- "biliardo",
210
- "binario",
211
- "binocolo",
212
- "biologia",
213
- "biondina",
214
- "biopsia",
215
- "biossido",
216
- "birbante",
217
- "birra",
218
- "biscotto",
219
- "bisogno",
220
- "bistecca",
221
- "bivio",
222
- "blindare",
223
- "bloccare",
224
- "bocca",
225
- "bollire",
226
- "bombola",
227
- "bonifico",
228
- "borghese",
229
- "borsa",
230
- "bottino",
231
- "botulino",
232
- "braccio",
233
- "bradipo",
234
- "branco",
235
- "bravo",
236
- "bresaola",
237
- "bretelle",
238
- "brevetto",
239
- "briciola",
240
- "brigante",
241
- "brillare",
242
- "brindare",
243
- "brivido",
244
- "broccoli",
245
- "brontolo",
246
- "bruciare",
247
- "brufolo",
248
- "bucare",
249
- "buddista",
250
- "budino",
251
- "bufera",
252
- "buffo",
253
- "bugiardo",
254
- "buio",
255
- "buono",
256
- "burrone",
257
- "bussola",
258
- "bustina",
259
- "buttare",
260
- "cabernet",
261
- "cabina",
262
- "cacao",
263
- "cacciare",
264
- "cactus",
265
- "cadavere",
266
- "caffe",
267
- "calamari",
268
- "calcio",
269
- "caldaia",
270
- "calmare",
271
- "calunnia",
272
- "calvario",
273
- "calzone",
274
- "cambiare",
275
- "camera",
276
- "camion",
277
- "cammello",
278
- "campana",
279
- "canarino",
280
- "cancello",
281
- "candore",
282
- "cane",
283
- "canguro",
284
- "cannone",
285
- "canoa",
286
- "cantare",
287
- "canzone",
288
- "caos",
289
- "capanna",
290
- "capello",
291
- "capire",
292
- "capo",
293
- "capperi",
294
- "capra",
295
- "capsula",
296
- "caraffa",
297
- "carbone",
298
- "carciofo",
299
- "cardigan",
300
- "carenza",
301
- "caricare",
302
- "carota",
303
- "carrello",
304
- "carta",
305
- "casa",
306
- "cascare",
307
- "caserma",
308
- "cashmere",
309
- "casino",
310
- "cassetta",
311
- "castello",
312
- "catalogo",
313
- "catena",
314
- "catorcio",
315
- "cattivo",
316
- "causa",
317
- "cauzione",
318
- "cavallo",
319
- "caverna",
320
- "caviglia",
321
- "cavo",
322
- "cazzotto",
323
- "celibato",
324
- "cemento",
325
- "cenare",
326
- "centrale",
327
- "ceramica",
328
- "cercare",
329
- "ceretta",
330
- "cerniera",
331
- "certezza",
332
- "cervello",
333
- "cessione",
334
- "cestino",
335
- "cetriolo",
336
- "chiave",
337
- "chiedere",
338
- "chilo",
339
- "chimera",
340
- "chiodo",
341
- "chirurgo",
342
- "chitarra",
343
- "chiudere",
344
- "ciabatta",
345
- "ciao",
346
- "cibo",
347
- "ciccia",
348
- "cicerone",
349
- "ciclone",
350
- "cicogna",
351
- "cielo",
352
- "cifra",
353
- "cigno",
354
- "ciliegia",
355
- "cimitero",
356
- "cinema",
357
- "cinque",
358
- "cintura",
359
- "ciondolo",
360
- "ciotola",
361
- "cipolla",
362
- "cippato",
363
- "circuito",
364
- "cisterna",
365
- "citofono",
366
- "ciuccio",
367
- "civetta",
368
- "civico",
369
- "clausola",
370
- "cliente",
371
- "clima",
372
- "clinica",
373
- "cobra",
374
- "coccole",
375
- "cocktail",
376
- "cocomero",
377
- "codice",
378
- "coesione",
379
- "cogliere",
380
- "cognome",
381
- "colla",
382
- "colomba",
383
- "colpire",
384
- "coltello",
385
- "comando",
386
- "comitato",
387
- "commedia",
388
- "comodino",
389
- "compagna",
390
- "comune",
391
- "concerto",
392
- "condotto",
393
- "conforto",
394
- "congiura",
395
- "coniglio",
396
- "consegna",
397
- "conto",
398
- "convegno",
399
- "coperta",
400
- "copia",
401
- "coprire",
402
- "corazza",
403
- "corda",
404
- "corleone",
405
- "cornice",
406
- "corona",
407
- "corpo",
408
- "corrente",
409
- "corsa",
410
- "cortesia",
411
- "corvo",
412
- "coso",
413
- "costume",
414
- "cotone",
415
- "cottura",
416
- "cozza",
417
- "crampo",
418
- "cratere",
419
- "cravatta",
420
- "creare",
421
- "credere",
422
- "crema",
423
- "crescere",
424
- "crimine",
425
- "criterio",
426
- "croce",
427
- "crollare",
428
- "cronaca",
429
- "crostata",
430
- "croupier",
431
- "cubetto",
432
- "cucciolo",
433
- "cucina",
434
- "cultura",
435
- "cuoco",
436
- "cuore",
437
- "cupido",
438
- "cupola",
439
- "cura",
440
- "curva",
441
- "cuscino",
442
- "custode",
443
- "danzare",
444
- "data",
445
- "decennio",
446
- "decidere",
447
- "decollo",
448
- "dedicare",
449
- "dedurre",
450
- "definire",
451
- "delegare",
452
- "delfino",
453
- "delitto",
454
- "demone",
455
- "dentista",
456
- "denuncia",
457
- "deposito",
458
- "derivare",
459
- "deserto",
460
- "designer",
461
- "destino",
462
- "detonare",
463
- "dettagli",
464
- "diagnosi",
465
- "dialogo",
466
- "diamante",
467
- "diario",
468
- "diavolo",
469
- "dicembre",
470
- "difesa",
471
- "digerire",
472
- "digitare",
473
- "diluvio",
474
- "dinamica",
475
- "dipinto",
476
- "diploma",
477
- "diramare",
478
- "dire",
479
- "dirigere",
480
- "dirupo",
481
- "discesa",
482
- "disdetta",
483
- "disegno",
484
- "disporre",
485
- "dissenso",
486
- "distacco",
487
- "dito",
488
- "ditta",
489
- "diva",
490
- "divenire",
491
- "dividere",
492
- "divorare",
493
- "docente",
494
- "dolcetto",
495
- "dolore",
496
- "domatore",
497
- "domenica",
498
- "dominare",
499
- "donatore",
500
- "donna",
501
- "dorato",
502
- "dormire",
503
- "dorso",
504
- "dosaggio",
505
- "dottore",
506
- "dovere",
507
- "download",
508
- "dragone",
509
- "dramma",
510
- "dubbio",
511
- "dubitare",
512
- "duetto",
513
- "durata",
514
- "ebbrezza",
515
- "eccesso",
516
- "eccitare",
517
- "eclissi",
518
- "economia",
519
- "edera",
520
- "edificio",
521
- "editore",
522
- "edizione",
523
- "educare",
524
- "effetto",
525
- "egitto",
526
- "egiziano",
527
- "elastico",
528
- "elefante",
529
- "eleggere",
530
- "elemento",
531
- "elenco",
532
- "elezione",
533
- "elmetto",
534
- "elogio",
535
- "embrione",
536
- "emergere",
537
- "emettere",
538
- "eminenza",
539
- "emisfero",
540
- "emozione",
541
- "empatia",
542
- "energia",
543
- "enfasi",
544
- "enigma",
545
- "entrare",
546
- "enzima",
547
- "epidemia",
548
- "epilogo",
549
- "episodio",
550
- "epoca",
551
- "equivoco",
552
- "erba",
553
- "erede",
554
- "eroe",
555
- "erotico",
556
- "errore",
557
- "eruzione",
558
- "esaltare",
559
- "esame",
560
- "esaudire",
561
- "eseguire",
562
- "esempio",
563
- "esigere",
564
- "esistere",
565
- "esito",
566
- "esperto",
567
- "espresso",
568
- "essere",
569
- "estasi",
570
- "esterno",
571
- "estrarre",
572
- "eterno",
573
- "etica",
574
- "euforico",
575
- "europa",
576
- "evacuare",
577
- "evasione",
578
- "evento",
579
- "evidenza",
580
- "evitare",
581
- "evolvere",
582
- "fabbrica",
583
- "facciata",
584
- "fagiano",
585
- "fagotto",
586
- "falco",
587
- "fame",
588
- "famiglia",
589
- "fanale",
590
- "fango",
591
- "fantasia",
592
- "farfalla",
593
- "farmacia",
594
- "faro",
595
- "fase",
596
- "fastidio",
597
- "faticare",
598
- "fatto",
599
- "favola",
600
- "febbre",
601
- "femmina",
602
- "femore",
603
- "fenomeno",
604
- "fermata",
605
- "feromoni",
606
- "ferrari",
607
- "fessura",
608
- "festa",
609
- "fiaba",
610
- "fiamma",
611
- "fianco",
612
- "fiat",
613
- "fibbia",
614
- "fidare",
615
- "fieno",
616
- "figa",
617
- "figlio",
618
- "figura",
619
- "filetto",
620
- "filmato",
621
- "filosofo",
622
- "filtrare",
623
- "finanza",
624
- "finestra",
625
- "fingere",
626
- "finire",
627
- "finta",
628
- "finzione",
629
- "fiocco",
630
- "fioraio",
631
- "firewall",
632
- "firmare",
633
- "fisico",
634
- "fissare",
635
- "fittizio",
636
- "fiume",
637
- "flacone",
638
- "flagello",
639
- "flirtare",
640
- "flusso",
641
- "focaccia",
642
- "foglio",
643
- "fognario",
644
- "follia",
645
- "fonderia",
646
- "fontana",
647
- "forbici",
648
- "forcella",
649
- "foresta",
650
- "forgiare",
651
- "formare",
652
- "fornace",
653
- "foro",
654
- "fortuna",
655
- "forzare",
656
- "fosforo",
657
- "fotoni",
658
- "fracasso",
659
- "fragola",
660
- "frantumi",
661
- "fratello",
662
- "frazione",
663
- "freccia",
664
- "freddo",
665
- "frenare",
666
- "fresco",
667
- "friggere",
668
- "frittata",
669
- "frivolo",
670
- "frizione",
671
- "fronte",
672
- "frullato",
673
- "frumento",
674
- "frusta",
675
- "frutto",
676
- "fucile",
677
- "fuggire",
678
- "fulmine",
679
- "fumare",
680
- "funzione",
681
- "fuoco",
682
- "furbizia",
683
- "furgone",
684
- "furia",
685
- "furore",
686
- "fusibile",
687
- "fuso",
688
- "futuro",
689
- "gabbiano",
690
- "galassia",
691
- "gallina",
692
- "gamba",
693
- "gancio",
694
- "garanzia",
695
- "garofano",
696
- "gasolio",
697
- "gatto",
698
- "gazebo",
699
- "gazzetta",
700
- "gelato",
701
- "gemelli",
702
- "generare",
703
- "genitori",
704
- "gennaio",
705
- "geologia",
706
- "germania",
707
- "gestire",
708
- "gettare",
709
- "ghepardo",
710
- "ghiaccio",
711
- "giaccone",
712
- "giaguaro",
713
- "giallo",
714
- "giappone",
715
- "giardino",
716
- "gigante",
717
- "gioco",
718
- "gioiello",
719
- "giorno",
720
- "giovane",
721
- "giraffa",
722
- "giudizio",
723
- "giurare",
724
- "giusto",
725
- "globo",
726
- "gloria",
727
- "glucosio",
728
- "gnocca",
729
- "gocciola",
730
- "godere",
731
- "gomito",
732
- "gomma",
733
- "gonfiare",
734
- "gorilla",
735
- "governo",
736
- "gradire",
737
- "graffiti",
738
- "granchio",
739
- "grappolo",
740
- "grasso",
741
- "grattare",
742
- "gridare",
743
- "grissino",
744
- "grondaia",
745
- "grugnito",
746
- "gruppo",
747
- "guadagno",
748
- "guaio",
749
- "guancia",
750
- "guardare",
751
- "gufo",
752
- "guidare",
753
- "guscio",
754
- "gusto",
755
- "icona",
756
- "idea",
757
- "identico",
758
- "idolo",
759
- "idoneo",
760
- "idrante",
761
- "idrogeno",
762
- "igiene",
763
- "ignoto",
764
- "imbarco",
765
- "immagine",
766
- "immobile",
767
- "imparare",
768
- "impedire",
769
- "impianto",
770
- "importo",
771
- "impresa",
772
- "impulso",
773
- "incanto",
774
- "incendio",
775
- "incidere",
776
- "incontro",
777
- "incrocia",
778
- "incubo",
779
- "indagare",
780
- "indice",
781
- "indotto",
782
- "infanzia",
783
- "inferno",
784
- "infinito",
785
- "infranto",
786
- "ingerire",
787
- "inglese",
788
- "ingoiare",
789
- "ingresso",
790
- "iniziare",
791
- "innesco",
792
- "insalata",
793
- "inserire",
794
- "insicuro",
795
- "insonnia",
796
- "insulto",
797
- "interno",
798
- "introiti",
799
- "invasori",
800
- "inverno",
801
- "invito",
802
- "invocare",
803
- "ipnosi",
804
- "ipocrita",
805
- "ipotesi",
806
- "ironia",
807
- "irrigare",
808
- "iscritto",
809
- "isola",
810
- "ispirare",
811
- "isterico",
812
- "istinto",
813
- "istruire",
814
- "italiano",
815
- "jazz",
816
- "labbra",
817
- "labrador",
818
- "ladro",
819
- "lago",
820
- "lamento",
821
- "lampone",
822
- "lancetta",
823
- "lanterna",
824
- "lapide",
825
- "larva",
826
- "lasagne",
827
- "lasciare",
828
- "lastra",
829
- "latte",
830
- "laurea",
831
- "lavagna",
832
- "lavorare",
833
- "leccare",
834
- "legare",
835
- "leggere",
836
- "lenzuolo",
837
- "leone",
838
- "lepre",
839
- "letargo",
840
- "lettera",
841
- "levare",
842
- "levitare",
843
- "lezione",
844
- "liberare",
845
- "libidine",
846
- "libro",
847
- "licenza",
848
- "lievito",
849
- "limite",
850
- "lince",
851
- "lingua",
852
- "liquore",
853
- "lire",
854
- "listino",
855
- "litigare",
856
- "litro",
857
- "locale",
858
- "lottare",
859
- "lucciola",
860
- "lucidare",
861
- "luglio",
862
- "luna",
863
- "macchina",
864
- "madama",
865
- "madre",
866
- "maestro",
867
- "maggio",
868
- "magico",
869
- "maglione",
870
- "magnolia",
871
- "mago",
872
- "maialino",
873
- "maionese",
874
- "malattia",
875
- "male",
876
- "malloppo",
877
- "mancare",
878
- "mandorla",
879
- "mangiare",
880
- "manico",
881
- "manopola",
882
- "mansarda",
883
- "mantello",
884
- "manubrio",
885
- "manzo",
886
- "mappa",
887
- "mare",
888
- "margine",
889
- "marinaio",
890
- "marmotta",
891
- "marocco",
892
- "martello",
893
- "marzo",
894
- "maschera",
895
- "matrice",
896
- "maturare",
897
- "mazzetta",
898
- "meandri",
899
- "medaglia",
900
- "medico",
901
- "medusa",
902
- "megafono",
903
- "melone",
904
- "membrana",
905
- "menta",
906
- "mercato",
907
- "meritare",
908
- "merluzzo",
909
- "mese",
910
- "mestiere",
911
- "metafora",
912
- "meteo",
913
- "metodo",
914
- "mettere",
915
- "miele",
916
- "miglio",
917
- "miliardo",
918
- "mimetica",
919
- "minatore",
920
- "minuto",
921
- "miracolo",
922
- "mirtillo",
923
- "missile",
924
- "mistero",
925
- "misura",
926
- "mito",
927
- "mobile",
928
- "moda",
929
- "moderare",
930
- "moglie",
931
- "molecola",
932
- "molle",
933
- "momento",
934
- "moneta",
935
- "mongolia",
936
- "monologo",
937
- "montagna",
938
- "morale",
939
- "morbillo",
940
- "mordere",
941
- "mosaico",
942
- "mosca",
943
- "mostro",
944
- "motivare",
945
- "moto",
946
- "mulino",
947
- "mulo",
948
- "muovere",
949
- "muraglia",
950
- "muscolo",
951
- "museo",
952
- "musica",
953
- "mutande",
954
- "nascere",
955
- "nastro",
956
- "natale",
957
- "natura",
958
- "nave",
959
- "navigare",
960
- "negare",
961
- "negozio",
962
- "nemico",
963
- "nero",
964
- "nervo",
965
- "nessuno",
966
- "nettare",
967
- "neutroni",
968
- "neve",
969
- "nevicare",
970
- "nicotina",
971
- "nido",
972
- "nipote",
973
- "nocciola",
974
- "noleggio",
975
- "nome",
976
- "nonno",
977
- "norvegia",
978
- "notare",
979
- "notizia",
980
- "nove",
981
- "nucleo",
982
- "nuda",
983
- "nuotare",
984
- "nutrire",
985
- "obbligo",
986
- "occhio",
987
- "occupare",
988
- "oceano",
989
- "odissea",
990
- "odore",
991
- "offerta",
992
- "officina",
993
- "offrire",
994
- "oggetto",
995
- "oggi",
996
- "olfatto",
997
- "olio",
998
- "oliva",
999
- "ombelico",
1000
- "ombrello",
1001
- "omuncolo",
1002
- "ondata",
1003
- "onore",
1004
- "opera",
1005
- "opinione",
1006
- "opuscolo",
1007
- "opzione",
1008
- "orario",
1009
- "orbita",
1010
- "orchidea",
1011
- "ordine",
1012
- "orecchio",
1013
- "orgasmo",
1014
- "orgoglio",
1015
- "origine",
1016
- "orologio",
1017
- "oroscopo",
1018
- "orso",
1019
- "oscurare",
1020
- "ospedale",
1021
- "ospite",
1022
- "ossigeno",
1023
- "ostacolo",
1024
- "ostriche",
1025
- "ottenere",
1026
- "ottimo",
1027
- "ottobre",
1028
- "ovest",
1029
- "pacco",
1030
- "pace",
1031
- "pacifico",
1032
- "padella",
1033
- "pagare",
1034
- "pagina",
1035
- "pagnotta",
1036
- "palazzo",
1037
- "palestra",
1038
- "palpebre",
1039
- "pancetta",
1040
- "panfilo",
1041
- "panino",
1042
- "pannello",
1043
- "panorama",
1044
- "papa",
1045
- "paperino",
1046
- "paradiso",
1047
- "parcella",
1048
- "parente",
1049
- "parlare",
1050
- "parodia",
1051
- "parrucca",
1052
- "partire",
1053
- "passare",
1054
- "pasta",
1055
- "patata",
1056
- "patente",
1057
- "patogeno",
1058
- "patriota",
1059
- "pausa",
1060
- "pazienza",
1061
- "peccare",
1062
- "pecora",
1063
- "pedalare",
1064
- "pelare",
1065
- "pena",
1066
- "pendenza",
1067
- "penisola",
1068
- "pennello",
1069
- "pensare",
1070
- "pentirsi",
1071
- "percorso",
1072
- "perdono",
1073
- "perfetto",
1074
- "perizoma",
1075
- "perla",
1076
- "permesso",
1077
- "persona",
1078
- "pesare",
1079
- "pesce",
1080
- "peso",
1081
- "petardo",
1082
- "petrolio",
1083
- "pezzo",
1084
- "piacere",
1085
- "pianeta",
1086
- "piastra",
1087
- "piatto",
1088
- "piazza",
1089
- "piccolo",
1090
- "piede",
1091
- "piegare",
1092
- "pietra",
1093
- "pigiama",
1094
- "pigliare",
1095
- "pigrizia",
1096
- "pilastro",
1097
- "pilota",
1098
- "pinguino",
1099
- "pioggia",
1100
- "piombo",
1101
- "pionieri",
1102
- "piovra",
1103
- "pipa",
1104
- "pirata",
1105
- "pirolisi",
1106
- "piscina",
1107
- "pisolino",
1108
- "pista",
1109
- "pitone",
1110
- "piumino",
1111
- "pizza",
1112
- "plastica",
1113
- "platino",
1114
- "poesia",
1115
- "poiana",
1116
- "polaroid",
1117
- "polenta",
1118
- "polimero",
1119
- "pollo",
1120
- "polmone",
1121
- "polpetta",
1122
- "poltrona",
1123
- "pomodoro",
1124
- "pompa",
1125
- "popolo",
1126
- "porco",
1127
- "porta",
1128
- "porzione",
1129
- "possesso",
1130
- "postino",
1131
- "potassio",
1132
- "potere",
1133
- "poverino",
1134
- "pranzo",
1135
- "prato",
1136
- "prefisso",
1137
- "prelievo",
1138
- "premio",
1139
- "prendere",
1140
- "prestare",
1141
- "pretesa",
1142
- "prezzo",
1143
- "primario",
1144
- "privacy",
1145
- "problema",
1146
- "processo",
1147
- "prodotto",
1148
- "profeta",
1149
- "progetto",
1150
- "promessa",
1151
- "pronto",
1152
- "proposta",
1153
- "proroga",
1154
- "prossimo",
1155
- "proteina",
1156
- "prova",
1157
- "prudenza",
1158
- "pubblico",
1159
- "pudore",
1160
- "pugilato",
1161
- "pulire",
1162
- "pulsante",
1163
- "puntare",
1164
- "pupazzo",
1165
- "puzzle",
1166
- "quaderno",
1167
- "qualcuno",
1168
- "quarzo",
1169
- "quercia",
1170
- "quintale",
1171
- "rabbia",
1172
- "racconto",
1173
- "radice",
1174
- "raffica",
1175
- "ragazza",
1176
- "ragione",
1177
- "rammento",
1178
- "ramo",
1179
- "rana",
1180
- "randagio",
1181
- "rapace",
1182
- "rapinare",
1183
- "rapporto",
1184
- "rasatura",
1185
- "ravioli",
1186
- "reagire",
1187
- "realista",
1188
- "reattore",
1189
- "reazione",
1190
- "recitare",
1191
- "recluso",
1192
- "record",
1193
- "recupero",
1194
- "redigere",
1195
- "regalare",
1196
- "regina",
1197
- "regola",
1198
- "relatore",
1199
- "reliquia",
1200
- "remare",
1201
- "rendere",
1202
- "reparto",
1203
- "resina",
1204
- "resto",
1205
- "rete",
1206
- "retorica",
1207
- "rettile",
1208
- "revocare",
1209
- "riaprire",
1210
- "ribadire",
1211
- "ribelle",
1212
- "ricambio",
1213
- "ricetta",
1214
- "richiamo",
1215
- "ricordo",
1216
- "ridurre",
1217
- "riempire",
1218
- "riferire",
1219
- "riflesso",
1220
- "righello",
1221
- "rilancio",
1222
- "rilevare",
1223
- "rilievo",
1224
- "rimanere",
1225
- "rimborso",
1226
- "rinforzo",
1227
- "rinuncia",
1228
- "riparo",
1229
- "ripetere",
1230
- "riposare",
1231
- "ripulire",
1232
- "risalita",
1233
- "riscatto",
1234
- "riserva",
1235
- "riso",
1236
- "rispetto",
1237
- "ritaglio",
1238
- "ritmo",
1239
- "ritorno",
1240
- "ritratto",
1241
- "rituale",
1242
- "riunione",
1243
- "riuscire",
1244
- "riva",
1245
- "robotica",
1246
- "rondine",
1247
- "rosa",
1248
- "rospo",
1249
- "rosso",
1250
- "rotonda",
1251
- "rotta",
1252
- "roulotte",
1253
- "rubare",
1254
- "rubrica",
1255
- "ruffiano",
1256
- "rumore",
1257
- "ruota",
1258
- "ruscello",
1259
- "sabbia",
1260
- "sacco",
1261
- "saggio",
1262
- "sale",
1263
- "salire",
1264
- "salmone",
1265
- "salto",
1266
- "salutare",
1267
- "salvia",
1268
- "sangue",
1269
- "sanzioni",
1270
- "sapere",
1271
- "sapienza",
1272
- "sarcasmo",
1273
- "sardine",
1274
- "sartoria",
1275
- "sbalzo",
1276
- "sbarcare",
1277
- "sberla",
1278
- "sborsare",
1279
- "scadenza",
1280
- "scafo",
1281
- "scala",
1282
- "scambio",
1283
- "scappare",
1284
- "scarpa",
1285
- "scatola",
1286
- "scelta",
1287
- "scena",
1288
- "sceriffo",
1289
- "scheggia",
1290
- "schiuma",
1291
- "sciarpa",
1292
- "scienza",
1293
- "scimmia",
1294
- "sciopero",
1295
- "scivolo",
1296
- "sclerare",
1297
- "scolpire",
1298
- "sconto",
1299
- "scopa",
1300
- "scordare",
1301
- "scossa",
1302
- "scrivere",
1303
- "scrupolo",
1304
- "scuderia",
1305
- "scultore",
1306
- "scuola",
1307
- "scusare",
1308
- "sdraiare",
1309
- "secolo",
1310
- "sedativo",
1311
- "sedere",
1312
- "sedia",
1313
- "segare",
1314
- "segreto",
1315
- "seguire",
1316
- "semaforo",
1317
- "seme",
1318
- "senape",
1319
- "seno",
1320
- "sentiero",
1321
- "separare",
1322
- "sepolcro",
1323
- "sequenza",
1324
- "serata",
1325
- "serpente",
1326
- "servizio",
1327
- "sesso",
1328
- "seta",
1329
- "settore",
1330
- "sfamare",
1331
- "sfera",
1332
- "sfidare",
1333
- "sfiorare",
1334
- "sfogare",
1335
- "sgabello",
1336
- "sicuro",
1337
- "siepe",
1338
- "sigaro",
1339
- "silenzio",
1340
- "silicone",
1341
- "simbiosi",
1342
- "simpatia",
1343
- "simulare",
1344
- "sinapsi",
1345
- "sindrome",
1346
- "sinergia",
1347
- "sinonimo",
1348
- "sintonia",
1349
- "sirena",
1350
- "siringa",
1351
- "sistema",
1352
- "sito",
1353
- "smalto",
1354
- "smentire",
1355
- "smontare",
1356
- "soccorso",
1357
- "socio",
1358
- "soffitto",
1359
- "software",
1360
- "soggetto",
1361
- "sogliola",
1362
- "sognare",
1363
- "soldi",
1364
- "sole",
1365
- "sollievo",
1366
- "solo",
1367
- "sommario",
1368
- "sondare",
1369
- "sonno",
1370
- "sorpresa",
1371
- "sorriso",
1372
- "sospiro",
1373
- "sostegno",
1374
- "sovrano",
1375
- "spaccare",
1376
- "spada",
1377
- "spagnolo",
1378
- "spalla",
1379
- "sparire",
1380
- "spavento",
1381
- "spazio",
1382
- "specchio",
1383
- "spedire",
1384
- "spegnere",
1385
- "spendere",
1386
- "speranza",
1387
- "spessore",
1388
- "spezzare",
1389
- "spiaggia",
1390
- "spiccare",
1391
- "spiegare",
1392
- "spiffero",
1393
- "spingere",
1394
- "sponda",
1395
- "sporcare",
1396
- "spostare",
1397
- "spremuta",
1398
- "spugna",
1399
- "spumante",
1400
- "spuntare",
1401
- "squadra",
1402
- "squillo",
1403
- "staccare",
1404
- "stadio",
1405
- "stagione",
1406
- "stallone",
1407
- "stampa",
1408
- "stancare",
1409
- "starnuto",
1410
- "statura",
1411
- "stella",
1412
- "stendere",
1413
- "sterzo",
1414
- "stilista",
1415
- "stimolo",
1416
- "stinco",
1417
- "stiva",
1418
- "stoffa",
1419
- "storia",
1420
- "strada",
1421
- "stregone",
1422
- "striscia",
1423
- "studiare",
1424
- "stufa",
1425
- "stupendo",
1426
- "subire",
1427
- "successo",
1428
- "sudare",
1429
- "suono",
1430
- "superare",
1431
- "supporto",
1432
- "surfista",
1433
- "sussurro",
1434
- "svelto",
1435
- "svenire",
1436
- "sviluppo",
1437
- "svolta",
1438
- "svuotare",
1439
- "tabacco",
1440
- "tabella",
1441
- "tabu",
1442
- "tacchino",
1443
- "tacere",
1444
- "taglio",
1445
- "talento",
1446
- "tangente",
1447
- "tappeto",
1448
- "tartufo",
1449
- "tassello",
1450
- "tastiera",
1451
- "tavolo",
1452
- "tazza",
1453
- "teatro",
1454
- "tedesco",
1455
- "telaio",
1456
- "telefono",
1457
- "tema",
1458
- "temere",
1459
- "tempo",
1460
- "tendenza",
1461
- "tenebre",
1462
- "tensione",
1463
- "tentare",
1464
- "teologia",
1465
- "teorema",
1466
- "termica",
1467
- "terrazzo",
1468
- "teschio",
1469
- "tesi",
1470
- "tesoro",
1471
- "tessera",
1472
- "testa",
1473
- "thriller",
1474
- "tifoso",
1475
- "tigre",
1476
- "timbrare",
1477
- "timido",
1478
- "tinta",
1479
- "tirare",
1480
- "tisana",
1481
- "titano",
1482
- "titolo",
1483
- "toccare",
1484
- "togliere",
1485
- "topolino",
1486
- "torcia",
1487
- "torrente",
1488
- "tovaglia",
1489
- "traffico",
1490
- "tragitto",
1491
- "training",
1492
- "tramonto",
1493
- "transito",
1494
- "trapezio",
1495
- "trasloco",
1496
- "trattore",
1497
- "trazione",
1498
- "treccia",
1499
- "tregua",
1500
- "treno",
1501
- "triciclo",
1502
- "tridente",
1503
- "trilogia",
1504
- "tromba",
1505
- "troncare",
1506
- "trota",
1507
- "trovare",
1508
- "trucco",
1509
- "tubo",
1510
- "tulipano",
1511
- "tumulto",
1512
- "tunisia",
1513
- "tuono",
1514
- "turista",
1515
- "tuta",
1516
- "tutelare",
1517
- "tutore",
1518
- "ubriaco",
1519
- "uccello",
1520
- "udienza",
1521
- "udito",
1522
- "uffa",
1523
- "umanoide",
1524
- "umore",
1525
- "unghia",
1526
- "unguento",
1527
- "unicorno",
1528
- "unione",
1529
- "universo",
1530
- "uomo",
1531
- "uragano",
1532
- "uranio",
1533
- "urlare",
1534
- "uscire",
1535
- "utente",
1536
- "utilizzo",
1537
- "vacanza",
1538
- "vacca",
1539
- "vaglio",
1540
- "vagonata",
1541
- "valle",
1542
- "valore",
1543
- "valutare",
1544
- "valvola",
1545
- "vampiro",
1546
- "vaniglia",
1547
- "vanto",
1548
- "vapore",
1549
- "variante",
1550
- "vasca",
1551
- "vaselina",
1552
- "vassoio",
1553
- "vedere",
1554
- "vegetale",
1555
- "veglia",
1556
- "veicolo",
1557
- "vela",
1558
- "veleno",
1559
- "velivolo",
1560
- "velluto",
1561
- "vendere",
1562
- "venerare",
1563
- "venire",
1564
- "vento",
1565
- "veranda",
1566
- "verbo",
1567
- "verdura",
1568
- "vergine",
1569
- "verifica",
1570
- "vernice",
1571
- "vero",
1572
- "verruca",
1573
- "versare",
1574
- "vertebra",
1575
- "vescica",
1576
- "vespaio",
1577
- "vestito",
1578
- "vesuvio",
1579
- "veterano",
1580
- "vetro",
1581
- "vetta",
1582
- "viadotto",
1583
- "viaggio",
1584
- "vibrare",
1585
- "vicenda",
1586
- "vichingo",
1587
- "vietare",
1588
- "vigilare",
1589
- "vigneto",
1590
- "villa",
1591
- "vincere",
1592
- "violino",
1593
- "vipera",
1594
- "virgola",
1595
- "virtuoso",
1596
- "visita",
1597
- "vita",
1598
- "vitello",
1599
- "vittima",
1600
- "vivavoce",
1601
- "vivere",
1602
- "viziato",
1603
- "voglia",
1604
- "volare",
1605
- "volpe",
1606
- "volto",
1607
- "volume",
1608
- "vongole",
1609
- "voragine",
1610
- "vortice",
1611
- "votare",
1612
- "vulcano",
1613
- "vuotare",
1614
- "zabaione",
1615
- "zaffiro",
1616
- "zainetto",
1617
- "zampa",
1618
- "zanzara",
1619
- "zattera",
1620
- "zavorra",
1621
- "zenzero",
1622
- "zero",
1623
- "zingaro",
1624
- "zittire",
1625
- "zoccolo",
1626
- "zolfo",
1627
- "zombie",
1628
- "zucchero"
1629
- ];
1630
-}
\ No newline at end of file
2
+ static const words = [
3
+ "abbinare",
4
+ "abbonato",
5
+ "abisso",
6
+ "abitare",
7
+ "abominio",
8
+ "accadere",
9
+ "accesso",
10
+ "acciaio",
11
+ "accordo",
12
+ "accumulo",
13
+ "acido",
14
+ "acqua",
15
+ "acrobata",
16
+ "acustico",
17
+ "adattare",
18
+ "addetto",
19
+ "addio",
20
+ "addome",
21
+ "adeguato",
22
+ "aderire",
23
+ "adorare",
24
+ "adottare",
25
+ "adozione",
26
+ "adulto",
27
+ "aereo",
28
+ "aerobica",
29
+ "affare",
30
+ "affetto",
31
+ "affidare",
32
+ "affogato",
33
+ "affronto",
34
+ "africano",
35
+ "afrodite",
36
+ "agenzia",
37
+ "aggancio",
38
+ "aggeggio",
39
+ "aggiunta",
40
+ "agio",
41
+ "agire",
42
+ "agitare",
43
+ "aglio",
44
+ "agnello",
45
+ "agosto",
46
+ "aiutare",
47
+ "albero",
48
+ "albo",
49
+ "alce",
50
+ "alchimia",
51
+ "alcool",
52
+ "alfabeto",
53
+ "algebra",
54
+ "alimento",
55
+ "allarme",
56
+ "alleanza",
57
+ "allievo",
58
+ "alloggio",
59
+ "alluce",
60
+ "alpi",
61
+ "alterare",
62
+ "altro",
63
+ "aluminio",
64
+ "amante",
65
+ "amarezza",
66
+ "ambiente",
67
+ "ambrosia",
68
+ "america",
69
+ "amico",
70
+ "ammalare",
71
+ "ammirare",
72
+ "amnesia",
73
+ "amnistia",
74
+ "amore",
75
+ "ampliare",
76
+ "amputare",
77
+ "analisi",
78
+ "anamnesi",
79
+ "ananas",
80
+ "anarchia",
81
+ "anatra",
82
+ "anca",
83
+ "ancorato",
84
+ "andare",
85
+ "androide",
86
+ "aneddoto",
87
+ "anello",
88
+ "angelo",
89
+ "angolino",
90
+ "anguilla",
91
+ "anidride",
92
+ "anima",
93
+ "annegare",
94
+ "anno",
95
+ "annuncio",
96
+ "anomalia",
97
+ "antenna",
98
+ "anticipo",
99
+ "aperto",
100
+ "apostolo",
101
+ "appalto",
102
+ "appello",
103
+ "appiglio",
104
+ "applauso",
105
+ "appoggio",
106
+ "appurare",
107
+ "aprile",
108
+ "aquila",
109
+ "arabo",
110
+ "arachidi",
111
+ "aragosta",
112
+ "arancia",
113
+ "arbitrio",
114
+ "archivio",
115
+ "arco",
116
+ "argento",
117
+ "argilla",
118
+ "aria",
119
+ "ariete",
120
+ "arma",
121
+ "armonia",
122
+ "aroma",
123
+ "arrivare",
124
+ "arrosto",
125
+ "arsenale",
126
+ "arte",
127
+ "artiglio",
128
+ "asfalto",
129
+ "asfissia",
130
+ "asino",
131
+ "asparagi",
132
+ "aspirina",
133
+ "assalire",
134
+ "assegno",
135
+ "assolto",
136
+ "assurdo",
137
+ "asta",
138
+ "astratto",
139
+ "atlante",
140
+ "atletica",
141
+ "atomo",
142
+ "atropina",
143
+ "attacco",
144
+ "attesa",
145
+ "attico",
146
+ "atto",
147
+ "attrarre",
148
+ "auguri",
149
+ "aula",
150
+ "aumento",
151
+ "aurora",
152
+ "auspicio",
153
+ "autista",
154
+ "auto",
155
+ "autunno",
156
+ "avanzare",
157
+ "avarizia",
158
+ "avere",
159
+ "aviatore",
160
+ "avido",
161
+ "avorio",
162
+ "avvenire",
163
+ "avviso",
164
+ "avvocato",
165
+ "azienda",
166
+ "azione",
167
+ "azzardo",
168
+ "azzurro",
169
+ "babbuino",
170
+ "bacio",
171
+ "badante",
172
+ "baffi",
173
+ "bagaglio",
174
+ "bagliore",
175
+ "bagno",
176
+ "balcone",
177
+ "balena",
178
+ "ballare",
179
+ "balordo",
180
+ "balsamo",
181
+ "bambola",
182
+ "bancomat",
183
+ "banda",
184
+ "barato",
185
+ "barba",
186
+ "barista",
187
+ "barriera",
188
+ "basette",
189
+ "basilico",
190
+ "bassista",
191
+ "bastare",
192
+ "battello",
193
+ "bavaglio",
194
+ "beccare",
195
+ "beduino",
196
+ "bellezza",
197
+ "bene",
198
+ "benzina",
199
+ "berretto",
200
+ "bestia",
201
+ "bevitore",
202
+ "bianco",
203
+ "bibbia",
204
+ "biberon",
205
+ "bibita",
206
+ "bici",
207
+ "bidone",
208
+ "bilancia",
209
+ "biliardo",
210
+ "binario",
211
+ "binocolo",
212
+ "biologia",
213
+ "biondina",
214
+ "biopsia",
215
+ "biossido",
216
+ "birbante",
217
+ "birra",
218
+ "biscotto",
219
+ "bisogno",
220
+ "bistecca",
221
+ "bivio",
222
+ "blindare",
223
+ "bloccare",
224
+ "bocca",
225
+ "bollire",
226
+ "bombola",
227
+ "bonifico",
228
+ "borghese",
229
+ "borsa",
230
+ "bottino",
231
+ "botulino",
232
+ "braccio",
233
+ "bradipo",
234
+ "branco",
235
+ "bravo",
236
+ "bresaola",
237
+ "bretelle",
238
+ "brevetto",
239
+ "briciola",
240
+ "brigante",
241
+ "brillare",
242
+ "brindare",
243
+ "brivido",
244
+ "broccoli",
245
+ "brontolo",
246
+ "bruciare",
247
+ "brufolo",
248
+ "bucare",
249
+ "buddista",
250
+ "budino",
251
+ "bufera",
252
+ "buffo",
253
+ "bugiardo",
254
+ "buio",
255
+ "buono",
256
+ "burrone",
257
+ "bussola",
258
+ "bustina",
259
+ "buttare",
260
+ "cabernet",
261
+ "cabina",
262
+ "cacao",
263
+ "cacciare",
264
+ "cactus",
265
+ "cadavere",
266
+ "caffe",
267
+ "calamari",
268
+ "calcio",
269
+ "caldaia",
270
+ "calmare",
271
+ "calunnia",
272
+ "calvario",
273
+ "calzone",
274
+ "cambiare",
275
+ "camera",
276
+ "camion",
277
+ "cammello",
278
+ "campana",
279
+ "canarino",
280
+ "cancello",
281
+ "candore",
282
+ "cane",
283
+ "canguro",
284
+ "cannone",
285
+ "canoa",
286
+ "cantare",
287
+ "canzone",
288
+ "caos",
289
+ "capanna",
290
+ "capello",
291
+ "capire",
292
+ "capo",
293
+ "capperi",
294
+ "capra",
295
+ "capsula",
296
+ "caraffa",
297
+ "carbone",
298
+ "carciofo",
299
+ "cardigan",
300
+ "carenza",
301
+ "caricare",
302
+ "carota",
303
+ "carrello",
304
+ "carta",
305
+ "casa",
306
+ "cascare",
307
+ "caserma",
308
+ "cashmere",
309
+ "casino",
310
+ "cassetta",
311
+ "castello",
312
+ "catalogo",
313
+ "catena",
314
+ "catorcio",
315
+ "cattivo",
316
+ "causa",
317
+ "cauzione",
318
+ "cavallo",
319
+ "caverna",
320
+ "caviglia",
321
+ "cavo",
322
+ "cazzotto",
323
+ "celibato",
324
+ "cemento",
325
+ "cenare",
326
+ "centrale",
327
+ "ceramica",
328
+ "cercare",
329
+ "ceretta",
330
+ "cerniera",
331
+ "certezza",
332
+ "cervello",
333
+ "cessione",
334
+ "cestino",
335
+ "cetriolo",
336
+ "chiave",
337
+ "chiedere",
338
+ "chilo",
339
+ "chimera",
340
+ "chiodo",
341
+ "chirurgo",
342
+ "chitarra",
343
+ "chiudere",
344
+ "ciabatta",
345
+ "ciao",
346
+ "cibo",
347
+ "ciccia",
348
+ "cicerone",
349
+ "ciclone",
350
+ "cicogna",
351
+ "cielo",
352
+ "cifra",
353
+ "cigno",
354
+ "ciliegia",
355
+ "cimitero",
356
+ "cinema",
357
+ "cinque",
358
+ "cintura",
359
+ "ciondolo",
360
+ "ciotola",
361
+ "cipolla",
362
+ "cippato",
363
+ "circuito",
364
+ "cisterna",
365
+ "citofono",
366
+ "ciuccio",
367
+ "civetta",
368
+ "civico",
369
+ "clausola",
370
+ "cliente",
371
+ "clima",
372
+ "clinica",
373
+ "cobra",
374
+ "coccole",
375
+ "cocktail",
376
+ "cocomero",
377
+ "codice",
378
+ "coesione",
379
+ "cogliere",
380
+ "cognome",
381
+ "colla",
382
+ "colomba",
383
+ "colpire",
384
+ "coltello",
385
+ "comando",
386
+ "comitato",
387
+ "commedia",
388
+ "comodino",
389
+ "compagna",
390
+ "comune",
391
+ "concerto",
392
+ "condotto",
393
+ "conforto",
394
+ "congiura",
395
+ "coniglio",
396
+ "consegna",
397
+ "conto",
398
+ "convegno",
399
+ "coperta",
400
+ "copia",
401
+ "coprire",
402
+ "corazza",
403
+ "corda",
404
+ "corleone",
405
+ "cornice",
406
+ "corona",
407
+ "corpo",
408
+ "corrente",
409
+ "corsa",
410
+ "cortesia",
411
+ "corvo",
412
+ "coso",
413
+ "costume",
414
+ "cotone",
415
+ "cottura",
416
+ "cozza",
417
+ "crampo",
418
+ "cratere",
419
+ "cravatta",
420
+ "creare",
421
+ "credere",
422
+ "crema",
423
+ "crescere",
424
+ "crimine",
425
+ "criterio",
426
+ "croce",
427
+ "crollare",
428
+ "cronaca",
429
+ "crostata",
430
+ "croupier",
431
+ "cubetto",
432
+ "cucciolo",
433
+ "cucina",
434
+ "cultura",
435
+ "cuoco",
436
+ "cuore",
437
+ "cupido",
438
+ "cupola",
439
+ "cura",
440
+ "curva",
441
+ "cuscino",
442
+ "custode",
443
+ "danzare",
444
+ "data",
445
+ "decennio",
446
+ "decidere",
447
+ "decollo",
448
+ "dedicare",
449
+ "dedurre",
450
+ "definire",
451
+ "delegare",
452
+ "delfino",
453
+ "delitto",
454
+ "demone",
455
+ "dentista",
456
+ "denuncia",
457
+ "deposito",
458
+ "derivare",
459
+ "deserto",
460
+ "designer",
461
+ "destino",
462
+ "detonare",
463
+ "dettagli",
464
+ "diagnosi",
465
+ "dialogo",
466
+ "diamante",
467
+ "diario",
468
+ "diavolo",
469
+ "dicembre",
470
+ "difesa",
471
+ "digerire",
472
+ "digitare",
473
+ "diluvio",
474
+ "dinamica",
475
+ "dipinto",
476
+ "diploma",
477
+ "diramare",
478
+ "dire",
479
+ "dirigere",
480
+ "dirupo",
481
+ "discesa",
482
+ "disdetta",
483
+ "disegno",
484
+ "disporre",
485
+ "dissenso",
486
+ "distacco",
487
+ "dito",
488
+ "ditta",
489
+ "diva",
490
+ "divenire",
491
+ "dividere",
492
+ "divorare",
493
+ "docente",
494
+ "dolcetto",
495
+ "dolore",
496
+ "domatore",
497
+ "domenica",
498
+ "dominare",
499
+ "donatore",
500
+ "donna",
501
+ "dorato",
502
+ "dormire",
503
+ "dorso",
504
+ "dosaggio",
505
+ "dottore",
506
+ "dovere",
507
+ "download",
508
+ "dragone",
509
+ "dramma",
510
+ "dubbio",
511
+ "dubitare",
512
+ "duetto",
513
+ "durata",
514
+ "ebbrezza",
515
+ "eccesso",
516
+ "eccitare",
517
+ "eclissi",
518
+ "economia",
519
+ "edera",
520
+ "edificio",
521
+ "editore",
522
+ "edizione",
523
+ "educare",
524
+ "effetto",
525
+ "egitto",
526
+ "egiziano",
527
+ "elastico",
528
+ "elefante",
529
+ "eleggere",
530
+ "elemento",
531
+ "elenco",
532
+ "elezione",
533
+ "elmetto",
534
+ "elogio",
535
+ "embrione",
536
+ "emergere",
537
+ "emettere",
538
+ "eminenza",
539
+ "emisfero",
540
+ "emozione",
541
+ "empatia",
542
+ "energia",
543
+ "enfasi",
544
+ "enigma",
545
+ "entrare",
546
+ "enzima",
547
+ "epidemia",
548
+ "epilogo",
549
+ "episodio",
550
+ "epoca",
551
+ "equivoco",
552
+ "erba",
553
+ "erede",
554
+ "eroe",
555
+ "erotico",
556
+ "errore",
557
+ "eruzione",
558
+ "esaltare",
559
+ "esame",
560
+ "esaudire",
561
+ "eseguire",
562
+ "esempio",
563
+ "esigere",
564
+ "esistere",
565
+ "esito",
566
+ "esperto",
567
+ "espresso",
568
+ "essere",
569
+ "estasi",
570
+ "esterno",
571
+ "estrarre",
572
+ "eterno",
573
+ "etica",
574
+ "euforico",
575
+ "europa",
576
+ "evacuare",
577
+ "evasione",
578
+ "evento",
579
+ "evidenza",
580
+ "evitare",
581
+ "evolvere",
582
+ "fabbrica",
583
+ "facciata",
584
+ "fagiano",
585
+ "fagotto",
586
+ "falco",
587
+ "fame",
588
+ "famiglia",
589
+ "fanale",
590
+ "fango",
591
+ "fantasia",
592
+ "farfalla",
593
+ "farmacia",
594
+ "faro",
595
+ "fase",
596
+ "fastidio",
597
+ "faticare",
598
+ "fatto",
599
+ "favola",
600
+ "febbre",
601
+ "femmina",
602
+ "femore",
603
+ "fenomeno",
604
+ "fermata",
605
+ "feromoni",
606
+ "ferrari",
607
+ "fessura",
608
+ "festa",
609
+ "fiaba",
610
+ "fiamma",
611
+ "fianco",
612
+ "fiat",
613
+ "fibbia",
614
+ "fidare",
615
+ "fieno",
616
+ "figa",
617
+ "figlio",
618
+ "figura",
619
+ "filetto",
620
+ "filmato",
621
+ "filosofo",
622
+ "filtrare",
623
+ "finanza",
624
+ "finestra",
625
+ "fingere",
626
+ "finire",
627
+ "finta",
628
+ "finzione",
629
+ "fiocco",
630
+ "fioraio",
631
+ "firewall",
632
+ "firmare",
633
+ "fisico",
634
+ "fissare",
635
+ "fittizio",
636
+ "fiume",
637
+ "flacone",
638
+ "flagello",
639
+ "flirtare",
640
+ "flusso",
641
+ "focaccia",
642
+ "foglio",
643
+ "fognario",
644
+ "follia",
645
+ "fonderia",
646
+ "fontana",
647
+ "forbici",
648
+ "forcella",
649
+ "foresta",
650
+ "forgiare",
651
+ "formare",
652
+ "fornace",
653
+ "foro",
654
+ "fortuna",
655
+ "forzare",
656
+ "fosforo",
657
+ "fotoni",
658
+ "fracasso",
659
+ "fragola",
660
+ "frantumi",
661
+ "fratello",
662
+ "frazione",
663
+ "freccia",
664
+ "freddo",
665
+ "frenare",
666
+ "fresco",
667
+ "friggere",
668
+ "frittata",
669
+ "frivolo",
670
+ "frizione",
671
+ "fronte",
672
+ "frullato",
673
+ "frumento",
674
+ "frusta",
675
+ "frutto",
676
+ "fucile",
677
+ "fuggire",
678
+ "fulmine",
679
+ "fumare",
680
+ "funzione",
681
+ "fuoco",
682
+ "furbizia",
683
+ "furgone",
684
+ "furia",
685
+ "furore",
686
+ "fusibile",
687
+ "fuso",
688
+ "futuro",
689
+ "gabbiano",
690
+ "galassia",
691
+ "gallina",
692
+ "gamba",
693
+ "gancio",
694
+ "garanzia",
695
+ "garofano",
696
+ "gasolio",
697
+ "gatto",
698
+ "gazebo",
699
+ "gazzetta",
700
+ "gelato",
701
+ "gemelli",
702
+ "generare",
703
+ "genitori",
704
+ "gennaio",
705
+ "geologia",
706
+ "germania",
707
+ "gestire",
708
+ "gettare",
709
+ "ghepardo",
710
+ "ghiaccio",
711
+ "giaccone",
712
+ "giaguaro",
713
+ "giallo",
714
+ "giappone",
715
+ "giardino",
716
+ "gigante",
717
+ "gioco",
718
+ "gioiello",
719
+ "giorno",
720
+ "giovane",
721
+ "giraffa",
722
+ "giudizio",
723
+ "giurare",
724
+ "giusto",
725
+ "globo",
726
+ "gloria",
727
+ "glucosio",
728
+ "gnocca",
729
+ "gocciola",
730
+ "godere",
731
+ "gomito",
732
+ "gomma",
733
+ "gonfiare",
734
+ "gorilla",
735
+ "governo",
736
+ "gradire",
737
+ "graffiti",
738
+ "granchio",
739
+ "grappolo",
740
+ "grasso",
741
+ "grattare",
742
+ "gridare",
743
+ "grissino",
744
+ "grondaia",
745
+ "grugnito",
746
+ "gruppo",
747
+ "guadagno",
748
+ "guaio",
749
+ "guancia",
750
+ "guardare",
751
+ "gufo",
752
+ "guidare",
753
+ "guscio",
754
+ "gusto",
755
+ "icona",
756
+ "idea",
757
+ "identico",
758
+ "idolo",
759
+ "idoneo",
760
+ "idrante",
761
+ "idrogeno",
762
+ "igiene",
763
+ "ignoto",
764
+ "imbarco",
765
+ "immagine",
766
+ "immobile",
767
+ "imparare",
768
+ "impedire",
769
+ "impianto",
770
+ "importo",
771
+ "impresa",
772
+ "impulso",
773
+ "incanto",
774
+ "incendio",
775
+ "incidere",
776
+ "incontro",
777
+ "incrocia",
778
+ "incubo",
779
+ "indagare",
780
+ "indice",
781
+ "indotto",
782
+ "infanzia",
783
+ "inferno",
784
+ "infinito",
785
+ "infranto",
786
+ "ingerire",
787
+ "inglese",
788
+ "ingoiare",
789
+ "ingresso",
790
+ "iniziare",
791
+ "innesco",
792
+ "insalata",
793
+ "inserire",
794
+ "insicuro",
795
+ "insonnia",
796
+ "insulto",
797
+ "interno",
798
+ "introiti",
799
+ "invasori",
800
+ "inverno",
801
+ "invito",
802
+ "invocare",
803
+ "ipnosi",
804
+ "ipocrita",
805
+ "ipotesi",
806
+ "ironia",
807
+ "irrigare",
808
+ "iscritto",
809
+ "isola",
810
+ "ispirare",
811
+ "isterico",
812
+ "istinto",
813
+ "istruire",
814
+ "italiano",
815
+ "jazz",
816
+ "labbra",
817
+ "labrador",
818
+ "ladro",
819
+ "lago",
820
+ "lamento",
821
+ "lampone",
822
+ "lancetta",
823
+ "lanterna",
824
+ "lapide",
825
+ "larva",
826
+ "lasagne",
827
+ "lasciare",
828
+ "lastra",
829
+ "latte",
830
+ "laurea",
831
+ "lavagna",
832
+ "lavorare",
833
+ "leccare",
834
+ "legare",
835
+ "leggere",
836
+ "lenzuolo",
837
+ "leone",
838
+ "lepre",
839
+ "letargo",
840
+ "lettera",
841
+ "levare",
842
+ "levitare",
843
+ "lezione",
844
+ "liberare",
845
+ "libidine",
846
+ "libro",
847
+ "licenza",
848
+ "lievito",
849
+ "limite",
850
+ "lince",
851
+ "lingua",
852
+ "liquore",
853
+ "lire",
854
+ "listino",
855
+ "litigare",
856
+ "litro",
857
+ "locale",
858
+ "lottare",
859
+ "lucciola",
860
+ "lucidare",
861
+ "luglio",
862
+ "luna",
863
+ "macchina",
864
+ "madama",
865
+ "madre",
866
+ "maestro",
867
+ "maggio",
868
+ "magico",
869
+ "maglione",
870
+ "magnolia",
871
+ "mago",
872
+ "maialino",
873
+ "maionese",
874
+ "malattia",
875
+ "male",
876
+ "malloppo",
877
+ "mancare",
878
+ "mandorla",
879
+ "mangiare",
880
+ "manico",
881
+ "manopola",
882
+ "mansarda",
883
+ "mantello",
884
+ "manubrio",
885
+ "manzo",
886
+ "mappa",
887
+ "mare",
888
+ "margine",
889
+ "marinaio",
890
+ "marmotta",
891
+ "marocco",
892
+ "martello",
893
+ "marzo",
894
+ "maschera",
895
+ "matrice",
896
+ "maturare",
897
+ "mazzetta",
898
+ "meandri",
899
+ "medaglia",
900
+ "medico",
901
+ "medusa",
902
+ "megafono",
903
+ "melone",
904
+ "membrana",
905
+ "menta",
906
+ "mercato",
907
+ "meritare",
908
+ "merluzzo",
909
+ "mese",
910
+ "mestiere",
911
+ "metafora",
912
+ "meteo",
913
+ "metodo",
914
+ "mettere",
915
+ "miele",
916
+ "miglio",
917
+ "miliardo",
918
+ "mimetica",
919
+ "minatore",
920
+ "minuto",
921
+ "miracolo",
922
+ "mirtillo",
923
+ "missile",
924
+ "mistero",
925
+ "misura",
926
+ "mito",
927
+ "mobile",
928
+ "moda",
929
+ "moderare",
930
+ "moglie",
931
+ "molecola",
932
+ "molle",
933
+ "momento",
934
+ "moneta",
935
+ "mongolia",
936
+ "monologo",
937
+ "montagna",
938
+ "morale",
939
+ "morbillo",
940
+ "mordere",
941
+ "mosaico",
942
+ "mosca",
943
+ "mostro",
944
+ "motivare",
945
+ "moto",
946
+ "mulino",
947
+ "mulo",
948
+ "muovere",
949
+ "muraglia",
950
+ "muscolo",
951
+ "museo",
952
+ "musica",
953
+ "mutande",
954
+ "nascere",
955
+ "nastro",
956
+ "natale",
957
+ "natura",
958
+ "nave",
959
+ "navigare",
960
+ "negare",
961
+ "negozio",
962
+ "nemico",
963
+ "nero",
964
+ "nervo",
965
+ "nessuno",
966
+ "nettare",
967
+ "neutroni",
968
+ "neve",
969
+ "nevicare",
970
+ "nicotina",
971
+ "nido",
972
+ "nipote",
973
+ "nocciola",
974
+ "noleggio",
975
+ "nome",
976
+ "nonno",
977
+ "norvegia",
978
+ "notare",
979
+ "notizia",
980
+ "nove",
981
+ "nucleo",
982
+ "nuda",
983
+ "nuotare",
984
+ "nutrire",
985
+ "obbligo",
986
+ "occhio",
987
+ "occupare",
988
+ "oceano",
989
+ "odissea",
990
+ "odore",
991
+ "offerta",
992
+ "officina",
993
+ "offrire",
994
+ "oggetto",
995
+ "oggi",
996
+ "olfatto",
997
+ "olio",
998
+ "oliva",
999
+ "ombelico",
1000
+ "ombrello",
1001
+ "omuncolo",
1002
+ "ondata",
1003
+ "onore",
1004
+ "opera",
1005
+ "opinione",
1006
+ "opuscolo",
1007
+ "opzione",
1008
+ "orario",
1009
+ "orbita",
1010
+ "orchidea",
1011
+ "ordine",
1012
+ "orecchio",
1013
+ "orgasmo",
1014
+ "orgoglio",
1015
+ "origine",
1016
+ "orologio",
1017
+ "oroscopo",
1018
+ "orso",
1019
+ "oscurare",
1020
+ "ospedale",
1021
+ "ospite",
1022
+ "ossigeno",
1023
+ "ostacolo",
1024
+ "ostriche",
1025
+ "ottenere",
1026
+ "ottimo",
1027
+ "ottobre",
1028
+ "ovest",
1029
+ "pacco",
1030
+ "pace",
1031
+ "pacifico",
1032
+ "padella",
1033
+ "pagare",
1034
+ "pagina",
1035
+ "pagnotta",
1036
+ "palazzo",
1037
+ "palestra",
1038
+ "palpebre",
1039
+ "pancetta",
1040
+ "panfilo",
1041
+ "panino",
1042
+ "pannello",
1043
+ "panorama",
1044
+ "papa",
1045
+ "paperino",
1046
+ "paradiso",
1047
+ "parcella",
1048
+ "parente",
1049
+ "parlare",
1050
+ "parodia",
1051
+ "parrucca",
1052
+ "partire",
1053
+ "passare",
1054
+ "pasta",
1055
+ "patata",
1056
+ "patente",
1057
+ "patogeno",
1058
+ "patriota",
1059
+ "pausa",
1060
+ "pazienza",
1061
+ "peccare",
1062
+ "pecora",
1063
+ "pedalare",
1064
+ "pelare",
1065
+ "pena",
1066
+ "pendenza",
1067
+ "penisola",
1068
+ "pennello",
1069
+ "pensare",
1070
+ "pentirsi",
1071
+ "percorso",
1072
+ "perdono",
1073
+ "perfetto",
1074
+ "perizoma",
1075
+ "perla",
1076
+ "permesso",
1077
+ "persona",
1078
+ "pesare",
1079
+ "pesce",
1080
+ "peso",
1081
+ "petardo",
1082
+ "petrolio",
1083
+ "pezzo",
1084
+ "piacere",
1085
+ "pianeta",
1086
+ "piastra",
1087
+ "piatto",
1088
+ "piazza",
1089
+ "piccolo",
1090
+ "piede",
1091
+ "piegare",
1092
+ "pietra",
1093
+ "pigiama",
1094
+ "pigliare",
1095
+ "pigrizia",
1096
+ "pilastro",
1097
+ "pilota",
1098
+ "pinguino",
1099
+ "pioggia",
1100
+ "piombo",
1101
+ "pionieri",
1102
+ "piovra",
1103
+ "pipa",
1104
+ "pirata",
1105
+ "pirolisi",
1106
+ "piscina",
1107
+ "pisolino",
1108
+ "pista",
1109
+ "pitone",
1110
+ "piumino",
1111
+ "pizza",
1112
+ "plastica",
1113
+ "platino",
1114
+ "poesia",
1115
+ "poiana",
1116
+ "polaroid",
1117
+ "polenta",
1118
+ "polimero",
1119
+ "pollo",
1120
+ "polmone",
1121
+ "polpetta",
1122
+ "poltrona",
1123
+ "pomodoro",
1124
+ "pompa",
1125
+ "popolo",
1126
+ "porco",
1127
+ "porta",
1128
+ "porzione",
1129
+ "possesso",
1130
+ "postino",
1131
+ "potassio",
1132
+ "potere",
1133
+ "poverino",
1134
+ "pranzo",
1135
+ "prato",
1136
+ "prefisso",
1137
+ "prelievo",
1138
+ "premio",
1139
+ "prendere",
1140
+ "prestare",
1141
+ "pretesa",
1142
+ "prezzo",
1143
+ "primario",
1144
+ "privacy",
1145
+ "problema",
1146
+ "processo",
1147
+ "prodotto",
1148
+ "profeta",
1149
+ "progetto",
1150
+ "promessa",
1151
+ "pronto",
1152
+ "proposta",
1153
+ "proroga",
1154
+ "prossimo",
1155
+ "proteina",
1156
+ "prova",
1157
+ "prudenza",
1158
+ "pubblico",
1159
+ "pudore",
1160
+ "pugilato",
1161
+ "pulire",
1162
+ "pulsante",
1163
+ "puntare",
1164
+ "pupazzo",
1165
+ "puzzle",
1166
+ "quaderno",
1167
+ "qualcuno",
1168
+ "quarzo",
1169
+ "quercia",
1170
+ "quintale",
1171
+ "rabbia",
1172
+ "racconto",
1173
+ "radice",
1174
+ "raffica",
1175
+ "ragazza",
1176
+ "ragione",
1177
+ "rammento",
1178
+ "ramo",
1179
+ "rana",
1180
+ "randagio",
1181
+ "rapace",
1182
+ "rapinare",
1183
+ "rapporto",
1184
+ "rasatura",
1185
+ "ravioli",
1186
+ "reagire",
1187
+ "realista",
1188
+ "reattore",
1189
+ "reazione",
1190
+ "recitare",
1191
+ "recluso",
1192
+ "record",
1193
+ "recupero",
1194
+ "redigere",
1195
+ "regalare",
1196
+ "regina",
1197
+ "regola",
1198
+ "relatore",
1199
+ "reliquia",
1200
+ "remare",
1201
+ "rendere",
1202
+ "reparto",
1203
+ "resina",
1204
+ "resto",
1205
+ "rete",
1206
+ "retorica",
1207
+ "rettile",
1208
+ "revocare",
1209
+ "riaprire",
1210
+ "ribadire",
1211
+ "ribelle",
1212
+ "ricambio",
1213
+ "ricetta",
1214
+ "richiamo",
1215
+ "ricordo",
1216
+ "ridurre",
1217
+ "riempire",
1218
+ "riferire",
1219
+ "riflesso",
1220
+ "righello",
1221
+ "rilancio",
1222
+ "rilevare",
1223
+ "rilievo",
1224
+ "rimanere",
1225
+ "rimborso",
1226
+ "rinforzo",
1227
+ "rinuncia",
1228
+ "riparo",
1229
+ "ripetere",
1230
+ "riposare",
1231
+ "ripulire",
1232
+ "risalita",
1233
+ "riscatto",
1234
+ "riserva",
1235
+ "riso",
1236
+ "rispetto",
1237
+ "ritaglio",
1238
+ "ritmo",
1239
+ "ritorno",
1240
+ "ritratto",
1241
+ "rituale",
1242
+ "riunione",
1243
+ "riuscire",
1244
+ "riva",
1245
+ "robotica",
1246
+ "rondine",
1247
+ "rosa",
1248
+ "rospo",
1249
+ "rosso",
1250
+ "rotonda",
1251
+ "rotta",
1252
+ "roulotte",
1253
+ "rubare",
1254
+ "rubrica",
1255
+ "ruffiano",
1256
+ "rumore",
1257
+ "ruota",
1258
+ "ruscello",
1259
+ "sabbia",
1260
+ "sacco",
1261
+ "saggio",
1262
+ "sale",
1263
+ "salire",
1264
+ "salmone",
1265
+ "salto",
1266
+ "salutare",
1267
+ "salvia",
1268
+ "sangue",
1269
+ "sanzioni",
1270
+ "sapere",
1271
+ "sapienza",
1272
+ "sarcasmo",
1273
+ "sardine",
1274
+ "sartoria",
1275
+ "sbalzo",
1276
+ "sbarcare",
1277
+ "sberla",
1278
+ "sborsare",
1279
+ "scadenza",
1280
+ "scafo",
1281
+ "scala",
1282
+ "scambio",
1283
+ "scappare",
1284
+ "scarpa",
1285
+ "scatola",
1286
+ "scelta",
1287
+ "scena",
1288
+ "sceriffo",
1289
+ "scheggia",
1290
+ "schiuma",
1291
+ "sciarpa",
1292
+ "scienza",
1293
+ "scimmia",
1294
+ "sciopero",
1295
+ "scivolo",
1296
+ "sclerare",
1297
+ "scolpire",
1298
+ "sconto",
1299
+ "scopa",
1300
+ "scordare",
1301
+ "scossa",
1302
+ "scrivere",
1303
+ "scrupolo",
1304
+ "scuderia",
1305
+ "scultore",
1306
+ "scuola",
1307
+ "scusare",
1308
+ "sdraiare",
1309
+ "secolo",
1310
+ "sedativo",
1311
+ "sedere",
1312
+ "sedia",
1313
+ "segare",
1314
+ "segreto",
1315
+ "seguire",
1316
+ "semaforo",
1317
+ "seme",
1318
+ "senape",
1319
+ "seno",
1320
+ "sentiero",
1321
+ "separare",
1322
+ "sepolcro",
1323
+ "sequenza",
1324
+ "serata",
1325
+ "serpente",
1326
+ "servizio",
1327
+ "sesso",
1328
+ "seta",
1329
+ "settore",
1330
+ "sfamare",
1331
+ "sfera",
1332
+ "sfidare",
1333
+ "sfiorare",
1334
+ "sfogare",
1335
+ "sgabello",
1336
+ "sicuro",
1337
+ "siepe",
1338
+ "sigaro",
1339
+ "silenzio",
1340
+ "silicone",
1341
+ "simbiosi",
1342
+ "simpatia",
1343
+ "simulare",
1344
+ "sinapsi",
1345
+ "sindrome",
1346
+ "sinergia",
1347
+ "sinonimo",
1348
+ "sintonia",
1349
+ "sirena",
1350
+ "siringa",
1351
+ "sistema",
1352
+ "sito",
1353
+ "smalto",
1354
+ "smentire",
1355
+ "smontare",
1356
+ "soccorso",
1357
+ "socio",
1358
+ "soffitto",
1359
+ "software",
1360
+ "soggetto",
1361
+ "sogliola",
1362
+ "sognare",
1363
+ "soldi",
1364
+ "sole",
1365
+ "sollievo",
1366
+ "solo",
1367
+ "sommario",
1368
+ "sondare",
1369
+ "sonno",
1370
+ "sorpresa",
1371
+ "sorriso",
1372
+ "sospiro",
1373
+ "sostegno",
1374
+ "sovrano",
1375
+ "spaccare",
1376
+ "spada",
1377
+ "spagnolo",
1378
+ "spalla",
1379
+ "sparire",
1380
+ "spavento",
1381
+ "spazio",
1382
+ "specchio",
1383
+ "spedire",
1384
+ "spegnere",
1385
+ "spendere",
1386
+ "speranza",
1387
+ "spessore",
1388
+ "spezzare",
1389
+ "spiaggia",
1390
+ "spiccare",
1391
+ "spiegare",
1392
+ "spiffero",
1393
+ "spingere",
1394
+ "sponda",
1395
+ "sporcare",
1396
+ "spostare",
1397
+ "spremuta",
1398
+ "spugna",
1399
+ "spumante",
1400
+ "spuntare",
1401
+ "squadra",
1402
+ "squillo",
1403
+ "staccare",
1404
+ "stadio",
1405
+ "stagione",
1406
+ "stallone",
1407
+ "stampa",
1408
+ "stancare",
1409
+ "starnuto",
1410
+ "statura",
1411
+ "stella",
1412
+ "stendere",
1413
+ "sterzo",
1414
+ "stilista",
1415
+ "stimolo",
1416
+ "stinco",
1417
+ "stiva",
1418
+ "stoffa",
1419
+ "storia",
1420
+ "strada",
1421
+ "stregone",
1422
+ "striscia",
1423
+ "studiare",
1424
+ "stufa",
1425
+ "stupendo",
1426
+ "subire",
1427
+ "successo",
1428
+ "sudare",
1429
+ "suono",
1430
+ "superare",
1431
+ "supporto",
1432
+ "surfista",
1433
+ "sussurro",
1434
+ "svelto",
1435
+ "svenire",
1436
+ "sviluppo",
1437
+ "svolta",
1438
+ "svuotare",
1439
+ "tabacco",
1440
+ "tabella",
1441
+ "tabu",
1442
+ "tacchino",
1443
+ "tacere",
1444
+ "taglio",
1445
+ "talento",
1446
+ "tangente",
1447
+ "tappeto",
1448
+ "tartufo",
1449
+ "tassello",
1450
+ "tastiera",
1451
+ "tavolo",
1452
+ "tazza",
1453
+ "teatro",
1454
+ "tedesco",
1455
+ "telaio",
1456
+ "telefono",
1457
+ "tema",
1458
+ "temere",
1459
+ "tempo",
1460
+ "tendenza",
1461
+ "tenebre",
1462
+ "tensione",
1463
+ "tentare",
1464
+ "teologia",
1465
+ "teorema",
1466
+ "termica",
1467
+ "terrazzo",
1468
+ "teschio",
1469
+ "tesi",
1470
+ "tesoro",
1471
+ "tessera",
1472
+ "testa",
1473
+ "thriller",
1474
+ "tifoso",
1475
+ "tigre",
1476
+ "timbrare",
1477
+ "timido",
1478
+ "tinta",
1479
+ "tirare",
1480
+ "tisana",
1481
+ "titano",
1482
+ "titolo",
1483
+ "toccare",
1484
+ "togliere",
1485
+ "topolino",
1486
+ "torcia",
1487
+ "torrente",
1488
+ "tovaglia",
1489
+ "traffico",
1490
+ "tragitto",
1491
+ "training",
1492
+ "tramonto",
1493
+ "transito",
1494
+ "trapezio",
1495
+ "trasloco",
1496
+ "trattore",
1497
+ "trazione",
1498
+ "treccia",
1499
+ "tregua",
1500
+ "treno",
1501
+ "triciclo",
1502
+ "tridente",
1503
+ "trilogia",
1504
+ "tromba",
1505
+ "troncare",
1506
+ "trota",
1507
+ "trovare",
1508
+ "trucco",
1509
+ "tubo",
1510
+ "tulipano",
1511
+ "tumulto",
1512
+ "tunisia",
1513
+ "tuono",
1514
+ "turista",
1515
+ "tuta",
1516
+ "tutelare",
1517
+ "tutore",
1518
+ "ubriaco",
1519
+ "uccello",
1520
+ "udienza",
1521
+ "udito",
1522
+ "uffa",
1523
+ "umanoide",
1524
+ "umore",
1525
+ "unghia",
1526
+ "unguento",
1527
+ "unicorno",
1528
+ "unione",
1529
+ "universo",
1530
+ "uomo",
1531
+ "uragano",
1532
+ "uranio",
1533
+ "urlare",
1534
+ "uscire",
1535
+ "utente",
1536
+ "utilizzo",
1537
+ "vacanza",
1538
+ "vacca",
1539
+ "vaglio",
1540
+ "vagonata",
1541
+ "valle",
1542
+ "valore",
1543
+ "valutare",
1544
+ "valvola",
1545
+ "vampiro",
1546
+ "vaniglia",
1547
+ "vanto",
1548
+ "vapore",
1549
+ "variante",
1550
+ "vasca",
1551
+ "vaselina",
1552
+ "vassoio",
1553
+ "vedere",
1554
+ "vegetale",
1555
+ "veglia",
1556
+ "veicolo",
1557
+ "vela",
1558
+ "veleno",
1559
+ "velivolo",
1560
+ "velluto",
1561
+ "vendere",
1562
+ "venerare",
1563
+ "venire",
1564
+ "vento",
1565
+ "veranda",
1566
+ "verbo",
1567
+ "verdura",
1568
+ "vergine",
1569
+ "verifica",
1570
+ "vernice",
1571
+ "vero",
1572
+ "verruca",
1573
+ "versare",
1574
+ "vertebra",
1575
+ "vescica",
1576
+ "vespaio",
1577
+ "vestito",
1578
+ "vesuvio",
1579
+ "veterano",
1580
+ "vetro",
1581
+ "vetta",
1582
+ "viadotto",
1583
+ "viaggio",
1584
+ "vibrare",
1585
+ "vicenda",
1586
+ "vichingo",
1587
+ "vietare",
1588
+ "vigilare",
1589
+ "vigneto",
1590
+ "villa",
1591
+ "vincere",
1592
+ "violino",
1593
+ "vipera",
1594
+ "virgola",
1595
+ "virtuoso",
1596
+ "visita",
1597
+ "vita",
1598
+ "vitello",
1599
+ "vittima",
1600
+ "vivavoce",
1601
+ "vivere",
1602
+ "viziato",
1603
+ "voglia",
1604
+ "volare",
1605
+ "volpe",
1606
+ "volto",
1607
+ "volume",
1608
+ "vongole",
1609
+ "voragine",
1610
+ "vortice",
1611
+ "votare",
1612
+ "vulcano",
1613
+ "vuotare",
1614
+ "zabaione",
1615
+ "zaffiro",
1616
+ "zainetto",
1617
+ "zampa",
1618
+ "zanzara",
1619
+ "zattera",
1620
+ "zavorra",
1621
+ "zenzero",
1622
+ "zero",
1623
+ "zingaro",
1624
+ "zittire",
1625
+ "zoccolo",
1626
+ "zolfo",
1627
+ "zombie",
1628
+ "zucchero"
1629
+ ];
1630
+}
cw_wownero/lib/mnemonics/japanese.dart
+1
-1
@@ -1627,4 +1627,4 @@ class JapaneseMnemonics {
1627
"びじゅつかん",
1628
"ひしょ"
1629
];
1630
-}
\ No newline at end of file
1630
+}
cw_wownero/lib/mnemonics/portuguese.dart
+1
-1
@@ -1627,4 +1627,4 @@ class PortugueseMnemonics {
1627
"zenite",
1628
"zumbi"
1629
];
1630
-}
\ No newline at end of file
1630
+}
cw_wownero/lib/mnemonics/russian.dart
+1
-1
@@ -1627,4 +1627,4 @@ class RussianMnemonics {
1627
"ячейка",
1628
"ящик"
1629
];
1630
-}
\ No newline at end of file
1630
+}
cw_wownero/lib/mnemonics/spanish.dart
+1
-1
@@ -1627,4 +1627,4 @@ class SpanishMnemonics {
1627
"ritmo",
1628
"rito"
1629
];
1630
-}
\ No newline at end of file
1630
+}
cw_wownero/lib/mywownero.dart
+3
-6
@@ -31,12 +31,9 @@ String mnemonicDecode(String seed) {
31
wlist.removeLast();
32
33
for (var i = 0; i < wlist.length; i += 3) {
34
- final w1 =
35
- tructWords(englistWordSet).indexOf(wlist[i].substring(0, prefixLength));
36
- final w2 = tructWords(englistWordSet)
37
- .indexOf(wlist[i + 1].substring(0, prefixLength));
38
- final w3 = tructWords(englistWordSet)
39
- .indexOf(wlist[i + 2].substring(0, prefixLength));
34
+ final w1 = tructWords(englistWordSet).indexOf(wlist[i].substring(0, prefixLength));
35
+ final w2 = tructWords(englistWordSet).indexOf(wlist[i + 1].substring(0, prefixLength));
36
+ final w3 = tructWords(englistWordSet).indexOf(wlist[i + 2].substring(0, prefixLength));
37
38
if (w1 == -1 || w2 == -1 || w3 == -1) {
39
printV("invalid word in mnemonic");
cw_wownero/lib/pending_wownero_transaction.dart
+1
-1
@@ -48,7 +48,7 @@ class PendingWowneroTransaction with PendingTransaction {
48
rethrow;
49
}
50
}
51
-
51
+
52
@override
53
Future<Map<String, String>> commitUR() {
54
throw UnimplementedError();
cw_wownero/lib/wownero_subaddress_list.dart
+20
-27
@@ -56,14 +56,13 @@ abstract class WowneroSubaddressListBase with Store {
56
final address = s.address;
57
final label = s.label;
58
final id = s.addressIndex;
59
- final hasDefaultAddressName =
60
- label.toLowerCase() == 'Primary account'.toLowerCase() ||
61
- label.toLowerCase() == 'Untitled account'.toLowerCase();
59
+ final hasDefaultAddressName = label.toLowerCase() == 'Primary account'.toLowerCase() ||
60
+ label.toLowerCase() == 'Untitled account'.toLowerCase();
61
final isPrimaryAddress = id == 0 && hasDefaultAddressName;
62
return Subaddress(
63
id: id,
64
address: address,
66
- balance: (s.received/1e12).toStringAsFixed(6),
65
+ balance: (s.received / 1e12).toStringAsFixed(6),
66
txCount: s.txCount,
67
label: isPrimaryAddress
68
? 'Primary address'
@@ -139,33 +138,27 @@ abstract class WowneroSubaddressListBase with Store {
138
}
139
}
140
142
- return allAddresses
143
- .map((s) {
144
- final id = s.addressIndex;
145
- final address = s.address;
146
- final label = s.label;
147
- return Subaddress(
148
- id: id,
149
- address: address,
150
- balance: (s.received/1e12).toStringAsFixed(6),
151
- txCount: s.txCount,
152
- label: id == 0 &&
153
- label.toLowerCase() == 'Primary account'.toLowerCase()
154
- ? 'Primary address'
155
- : label);
156
- })
157
- .toList();
141
+ return allAddresses.map((s) {
142
+ final id = s.addressIndex;
143
+ final address = s.address;
144
+ final label = s.label;
145
+ return Subaddress(
146
+ id: id,
147
+ address: address,
148
+ balance: (s.received / 1e12).toStringAsFixed(6),
149
+ txCount: s.txCount,
150
+ label: id == 0 && label.toLowerCase() == 'Primary account'.toLowerCase()
151
+ ? 'Primary address'
152
+ : label);
153
+ }).toList();
154
}
155
156
Future<bool> _newSubaddress({required int accountIndex, required String label}) async {
157
await subaddress_list.addSubaddress(accountIndex: accountIndex, label: label);
158
163
- return subaddress_list
164
- .getAllSubaddresses()
165
- .where((s) {
166
- final address = s.address;
167
- return !_usedAddresses.contains(address);
168
- })
169
- .isNotEmpty;
159
+ return subaddress_list.getAllSubaddresses().where((s) {
160
+ final address = s.address;
161
+ return !_usedAddresses.contains(address);
162
+ }).isNotEmpty;
163
}
164
}
cw_wownero/lib/wownero_transaction_history.dart
+4
-7
@@ -5,11 +5,10 @@ import 'package:cw_wownero/wownero_transaction_info.dart';
5
6
part 'wownero_transaction_history.g.dart';
7
8
-class WowneroTransactionHistory = WowneroTransactionHistoryBase
9
- with _$WowneroTransactionHistory;
8
+class WowneroTransactionHistory = WowneroTransactionHistoryBase with _$WowneroTransactionHistory;
9
11
-abstract class WowneroTransactionHistoryBase
12
- extends TransactionHistoryBase<WowneroTransactionInfo> with Store {
10
+abstract class WowneroTransactionHistoryBase extends TransactionHistoryBase<WowneroTransactionInfo>
11
+ with Store {
12
WowneroTransactionHistoryBase() {
13
transactions = ObservableMap<String, WowneroTransactionInfo>();
14
}
@@ -18,11 +17,9 @@ abstract class WowneroTransactionHistoryBase
17
Future<void> save() async {}
18
19
@override
21
- void addOne(WowneroTransactionInfo transaction) =>
22
- transactions[transaction.id] = transaction;
20
+ void addOne(WowneroTransactionInfo transaction) => transactions[transaction.id] = transaction;
21
22
@override
23
void addMany(Map<String, WowneroTransactionInfo> transactions) =>
24
this.transactions.addAll(transactions);
27
-
25
}
cw_wownero/lib/wownero_transaction_info.dart
+3
-4
@@ -8,10 +8,9 @@ import 'package:cw_core/format_amount.dart';
8
import 'package:cw_wownero/api/transaction_history.dart';
9
10
class WowneroTransactionInfo extends TransactionInfo {
11
- WowneroTransactionInfo(this.txHash, this.height, this.direction, this.date,
12
- this.isPending, this.amount, this.accountIndex, this.addressIndex, this.fee,
13
- this.confirmations) :
14
- id = "${txHash}_${amount}_${accountIndex}_${addressIndex}";
11
+ WowneroTransactionInfo(this.txHash, this.height, this.direction, this.date, this.isPending,
12
+ this.amount, this.accountIndex, this.addressIndex, this.fee, this.confirmations)
13
+ : id = "${txHash}_${amount}_${accountIndex}_${addressIndex}";
14
15
WowneroTransactionInfo.fromMap(Map<String, Object?> map)
16
: id = "${map['hash']}_${map['amount']}_${map['accountIndex']}_${map['addressIndex']}",
cw_wownero/lib/wownero_wallet.dart
+7
-5
@@ -54,7 +54,10 @@ abstract class WowneroWalletBase
54
extends WalletBase<WowneroBalance, WowneroTransactionHistory, WowneroTransactionInfo>
55
with Store {
56
WowneroWalletBase(
57
- {required WalletInfo walletInfo, required DerivationInfo derivationInfo, required Box<UnspentCoinsInfo> unspentCoinsInfo, required String password})
57
+ {required WalletInfo walletInfo,
58
+ required DerivationInfo derivationInfo,
59
+ required Box<UnspentCoinsInfo> unspentCoinsInfo,
60
+ required String password})
61
: balance = ObservableMap<CryptoCurrency, WowneroBalance>.of({
62
CryptoCurrency.wow: WowneroBalance(
63
fullBalance:
@@ -144,8 +147,8 @@ abstract class WowneroWalletBase
147
passphrase: wownero_wallet.getPassphrase());
148
149
int? get restoreHeight =>
147
- transactionHistory.transactions.values.firstOrNull?.height ?? wownero.Wallet_getRefreshFromBlockHeight(wptr!);
148
-
150
+ transactionHistory.transactions.values.firstOrNull?.height ??
151
+ wownero.Wallet_getRefreshFromBlockHeight(wptr!);
152
153
wownero_wallet.SyncListener? _listener;
154
ReactionDisposer? _onAccountChangeReaction;
@@ -635,8 +638,7 @@ abstract class WowneroWalletBase
638
wownero_wallet.getSubaddressLabel(accountIndex, addressIndex);
639
640
Future<List<WowneroTransactionInfo>> _getAllTransactionsOfAccount(int? accountIndex) async =>
638
- (await transaction_history
639
- .getAllTransactions())
641
+ (await transaction_history.getAllTransactions())
642
.map(
643
(row) => WowneroTransactionInfo(
644
row.hash,
cw_wownero/lib/wownero_wallet_addresses.dart
+14
-10
@@ -34,25 +34,26 @@ abstract class WowneroWalletAddressesBase extends WalletAddresses with Store {
34
35
@override
36
String get latestAddress {
37
- var addressIndex = subaddress_list.numSubaddresses(account?.id??0) - 1;
38
- var address = getAddress(accountIndex: account?.id??0, addressIndex: addressIndex);
37
+ var addressIndex = subaddress_list.numSubaddresses(account?.id ?? 0) - 1;
38
+ var address = getAddress(accountIndex: account?.id ?? 0, addressIndex: addressIndex);
39
while (hiddenAddresses.contains(address)) {
40
addressIndex++;
41
- address = getAddress(accountIndex: account?.id??0, addressIndex: addressIndex);
41
+ address = getAddress(accountIndex: account?.id ?? 0, addressIndex: addressIndex);
42
}
43
return address;
44
}
45
46
@override
47
String get addressForExchange {
48
- var addressIndex = subaddress_list.numSubaddresses(account?.id??0) - 1;
49
- var address = getAddress(accountIndex: account?.id??0, addressIndex: addressIndex);
48
+ var addressIndex = subaddress_list.numSubaddresses(account?.id ?? 0) - 1;
49
+ var address = getAddress(accountIndex: account?.id ?? 0, addressIndex: addressIndex);
50
while (hiddenAddresses.contains(address) || manualAddresses.contains(address)) {
51
addressIndex++;
52
- address = getAddress(accountIndex: account?.id??0, addressIndex: addressIndex);
52
+ address = getAddress(accountIndex: account?.id ?? 0, addressIndex: addressIndex);
53
}
54
return address;
55
}
56
+
57
@observable
58
Account? account;
59
@@ -69,7 +70,9 @@ abstract class WowneroWalletAddressesBase extends WalletAddresses with Store {
70
@override
71
Future<void> init() async {
72
accountList.update();
72
- account = accountList.accounts.isEmpty ? Account(id: 0, label: "Primary address") : accountList.accounts.first;
73
+ account = accountList.accounts.isEmpty
74
+ ? Account(id: 0, label: "Primary address")
75
+ : accountList.accounts.first;
76
updateSubaddressList(accountIndex: account?.id ?? 0);
77
await updateAddressesInBox();
78
}
@@ -143,7 +146,9 @@ abstract class WowneroWalletAddressesBase extends WalletAddresses with Store {
146
accountIndex: accountIndex,
147
defaultLabel: defaultLabel,
148
usedAddresses: usedAddresses.toList());
146
- subaddress = (subaddressList.subaddresses.isEmpty) ? Subaddress(id: 0, address: address, label: defaultLabel, balance: '0', txCount: 0) : subaddressList.subaddresses.last;
149
+ subaddress = (subaddressList.subaddresses.isEmpty)
150
+ ? Subaddress(id: 0, address: address, label: defaultLabel, balance: '0', txCount: 0)
151
+ : subaddressList.subaddresses.last;
152
address = subaddress!.address;
153
}
154
@@ -152,6 +157,5 @@ abstract class WowneroWalletAddressesBase extends WalletAddresses with Store {
157
addressInfos[account?.id ?? 0]?.any((it) => it.address == address) ?? false;
158
159
@override
155
- PaymentURI getPaymentUri(String amount) =>
156
- WowneroURI(address: address, amount: amount);
160
+ PaymentURI getPaymentUri(String amount) => WowneroURI(address: address, amount: amount);
161
}
cw_wownero/lib/wownero_wallet_service.dart
+54
-22
@@ -23,7 +23,11 @@ import 'package:monero/wownero.dart' as wownero;
23
24
class WowneroNewWalletCredentials extends WalletCredentials {
25
WowneroNewWalletCredentials(
26
- {required String name, required this.language, required this.isPolyseed, this.passphrase, String? password})
26
+ {required String name,
27
+ required this.language,
28
+ required this.isPolyseed,
29
+ this.passphrase,
30
+ String? password})
31
: super(name: name, password: password);
32
33
final String language;
@@ -33,7 +37,11 @@ class WowneroNewWalletCredentials extends WalletCredentials {
37
38
class WowneroRestoreWalletFromSeedCredentials extends WalletCredentials {
39
WowneroRestoreWalletFromSeedCredentials(
36
- {required String name, required this.mnemonic, required this.passphrase, int height = 0, String? password})
40
+ {required String name,
41
+ required this.mnemonic,
42
+ required this.passphrase,
43
+ int height = 0,
44
+ String? password})
45
: super(name: name, password: password, height: height);
46
47
final String mnemonic;
@@ -97,9 +105,15 @@ class WowneroWalletService extends WalletService<
105
}
106
107
await wownero_wallet_manager.createWallet(
100
- path: path, password: credentials.password!, language: credentials.language, passphrase: credentials.passphrase??'');
108
+ path: path,
109
+ password: credentials.password!,
110
+ language: credentials.language,
111
+ passphrase: credentials.passphrase ?? '');
112
final wallet = WowneroWallet(
102
- walletInfo: credentials.walletInfo!, derivationInfo: await credentials.walletInfo!.getDerivationInfo(), unspentCoinsInfo: unspentCoinsInfoSource, password: credentials.password!);
113
+ walletInfo: credentials.walletInfo!,
114
+ derivationInfo: await credentials.walletInfo!.getDerivationInfo(),
115
+ unspentCoinsInfo: unspentCoinsInfoSource,
116
+ password: credentials.password!);
117
await wallet.init();
118
119
return wallet;
@@ -138,7 +152,11 @@ class WowneroWalletService extends WalletService<
152
throw Exception('Wallet not found');
153
}
154
141
- wallet = WowneroWallet(walletInfo: walletInfo, derivationInfo: await walletInfo.getDerivationInfo(), unspentCoinsInfo: unspentCoinsInfoSource, password: password);
155
+ wallet = WowneroWallet(
156
+ walletInfo: walletInfo,
157
+ derivationInfo: await walletInfo.getDerivationInfo(),
158
+ unspentCoinsInfo: unspentCoinsInfoSource,
159
+ password: password);
160
throw WalletDeprecationException(seed: wallet.seed, curr: wallet.currency);
161
162
final isValid = wallet.walletAddresses.validate();
@@ -224,7 +242,11 @@ class WowneroWalletService extends WalletService<
242
if (currentWalletInfo == null) {
243
throw Exception('Wallet not found');
244
}
227
- final currentWallet = WowneroWallet(walletInfo: currentWalletInfo, derivationInfo: await currentWalletInfo.getDerivationInfo(), unspentCoinsInfo: unspentCoinsInfoSource, password: password);
245
+ final currentWallet = WowneroWallet(
246
+ walletInfo: currentWalletInfo,
247
+ derivationInfo: await currentWalletInfo.getDerivationInfo(),
248
+ unspentCoinsInfo: unspentCoinsInfoSource,
249
+ password: password);
250
251
await currentWallet.renameWalletFiles(newName);
252
@@ -249,7 +271,10 @@ class WowneroWalletService extends WalletService<
271
viewKey: credentials.viewKey,
272
spendKey: credentials.spendKey);
273
final wallet = WowneroWallet(
252
- walletInfo: credentials.walletInfo!, derivationInfo: await credentials.walletInfo!.getDerivationInfo(), unspentCoinsInfo: unspentCoinsInfoSource, password: credentials.password!);
274
+ walletInfo: credentials.walletInfo!,
275
+ derivationInfo: await credentials.walletInfo!.getDerivationInfo(),
276
+ unspentCoinsInfo: unspentCoinsInfoSource,
277
+ password: credentials.password!);
278
await wallet.init();
279
280
return wallet;
@@ -283,7 +308,10 @@ class WowneroWalletService extends WalletService<
308
seed: credentials.mnemonic,
309
restoreHeight: credentials.height!);
310
final wallet = WowneroWallet(
286
- walletInfo: credentials.walletInfo!, derivationInfo: await credentials.walletInfo!.getDerivationInfo(), unspentCoinsInfo: unspentCoinsInfoSource, password: credentials.password!);
311
+ walletInfo: credentials.walletInfo!,
312
+ derivationInfo: await credentials.walletInfo!.getDerivationInfo(),
313
+ unspentCoinsInfo: unspentCoinsInfoSource,
314
+ password: credentials.password!);
315
await wallet.init();
316
317
return wallet;
@@ -303,7 +331,8 @@ class WowneroWalletService extends WalletService<
331
final polyseed = Polyseed.decode(credentials.mnemonic, lang, polyseedCoin);
332
333
return _restoreFromPolyseed(
306
- path, credentials.password!, polyseed, credentials.walletInfo!, lang, passphrase: credentials.passphrase);
334
+ path, credentials.password!, polyseed, credentials.walletInfo!, lang,
335
+ passphrase: credentials.passphrase);
336
} catch (e) {
337
// TODO: Implement Exception for wallet list service.
338
printV('WowneroWalletsManager Error: $e');
@@ -313,20 +342,19 @@ class WowneroWalletService extends WalletService<
342
343
Future<WowneroWallet> _restoreFromPolyseed(
344
String path, String password, Polyseed polyseed, WalletInfo walletInfo, PolyseedLang lang,
316
- {PolyseedCoin coin = PolyseedCoin.POLYSEED_WOWNERO, int? overrideHeight, String? passphrase}) async {
317
-
318
-
319
- if (polyseed.isEncrypted == false &&
320
- (passphrase??'') != "") {
345
+ {PolyseedCoin coin = PolyseedCoin.POLYSEED_WOWNERO,
346
+ int? overrideHeight,
347
+ String? passphrase}) async {
348
+ if (polyseed.isEncrypted == false && (passphrase ?? '') != "") {
349
// Fallback to the different passphrase offset method, when a passphrase
350
// was provided but the polyseed is not encrypted.
351
wownero_wallet_manager.restoreWalletFromPolyseedWithOffset(
324
- path: path,
325
- password: password,
326
- seed: polyseed.encode(lang, coin),
327
- seedOffset: passphrase??'',
328
- language: "English");
329
-
352
+ path: path,
353
+ password: password,
354
+ seed: polyseed.encode(lang, coin),
355
+ seedOffset: passphrase ?? '',
356
+ language: "English");
357
+
358
final wallet = WowneroWallet(
359
walletInfo: walletInfo,
360
derivationInfo: await walletInfo.getDerivationInfo(),
@@ -357,9 +385,13 @@ class WowneroWalletService extends WalletService<
385
spendKey: spendKey);
386
387
wownero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.seed", value: seed);
360
- wownero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.passphrase", value: passphrase??'');
388
+ wownero.Wallet_setCacheAttribute(wptr!, key: "cakewallet.passphrase", value: passphrase ?? '');
389
362
- final wallet = WowneroWallet(walletInfo: walletInfo, derivationInfo: await walletInfo.getDerivationInfo(), unspentCoinsInfo: unspentCoinsInfoSource, password: password);
390
+ final wallet = WowneroWallet(
391
+ walletInfo: walletInfo,
392
+ derivationInfo: await walletInfo.getDerivationInfo(),
393
+ unspentCoinsInfo: unspentCoinsInfoSource,
394
+ password: password);
395
await wallet.init();
396
397
return wallet;
cw_zano/lib/api/consts.dart
+1
-1
@@ -3,4 +3,4 @@ class Consts {
3
static const errorAlreadyExists = 'ALREADY_EXISTS';
4
static const errorWalletWrongId = 'WALLET_WRONG_ID';
5
static const errorBusy = 'BUSY';
6
-}
\ No newline at end of file
6
+}
cw_zano/lib/api/model/asset_id_params.dart
+3
-3
@@ -4,6 +4,6 @@ class AssetIdParams {
4
AssetIdParams({required this.assetId});
5
6
Map<String, dynamic> toJson() => {
7
- 'asset_id': assetId,
8
- };
9
-}
\ No newline at end of file
7
+ 'asset_id': assetId,
8
+ };
9
+}
cw_zano/lib/api/model/balance.dart
+2
-3
@@ -15,15 +15,14 @@ class Balance {
15
required this.awaitingOut,
16
required this.total,
17
required this.unlocked});
18
-
18
+
19
String get assetId => assetInfo.assetId;
20
21
@override
22
String toString() => '$assetInfo: $total/$unlocked';
23
24
factory Balance.fromJson(Map<String, dynamic> json) => Balance(
25
- assetInfo:
26
- ZanoAsset.fromJson(json['asset_info'] as Map<String, dynamic>? ?? {}),
25
+ assetInfo: ZanoAsset.fromJson(json['asset_info'] as Map<String, dynamic>? ?? {}),
26
awaitingIn: ZanoFormatter.bigIntFromDynamic(json['awaiting_in']),
27
awaitingOut: ZanoFormatter.bigIntFromDynamic(json['awaiting_out']),
28
total: ZanoFormatter.bigIntFromDynamic(json['total']),
cw_zano/lib/api/model/create_wallet_result.dart
+3
-4
@@ -30,12 +30,11 @@ class CreateWalletResult {
30
required this.publicSpendKey,
31
required this.publicViewKey});
32
33
- factory CreateWalletResult.fromJson(Map<String, dynamic> json) =>
34
- CreateWalletResult(
33
+ factory CreateWalletResult.fromJson(Map<String, dynamic> json) => CreateWalletResult(
34
name: json['name'] as String? ?? '',
35
pass: json['pass'] as String? ?? '',
37
- recentHistory: RecentHistory.fromJson(
38
- json['recent_history'] as Map<String, dynamic>? ?? {}),
36
+ recentHistory:
37
+ RecentHistory.fromJson(json['recent_history'] as Map<String, dynamic>? ?? {}),
38
recovered: json['recovered'] as bool? ?? false,
39
walletFileSize: json['wallet_file_size'] as int? ?? 0,
40
walletId: json['wallet_id'] as int? ?? 0,
cw_zano/lib/api/model/destination.dart
+6
-7
@@ -1,10 +1,9 @@
1
class Destination {
2
- final BigInt amount; // transferred as string
2
+ final BigInt amount; // transferred as string
3
final String address;
4
final String assetId;
5
6
- Destination(
7
- {required this.amount, required this.address, required this.assetId});
6
+ Destination({required this.amount, required this.address, required this.assetId});
7
8
factory Destination.fromJson(Map<String, dynamic> json) => Destination(
9
amount: BigInt.parse(json['amount'] as String? ?? '0'),
@@ -13,8 +12,8 @@ class Destination {
12
);
13
14
Map<String, dynamic> toJson() => {
16
- 'amount': amount.toString(),
17
- 'address': address,
18
- 'asset_id': assetId,
19
- };
15
+ 'amount': amount.toString(),
16
+ 'address': address,
17
+ 'asset_id': assetId,
18
+ };
19
}
cw_zano/lib/api/model/employed_entries.dart
+11
-8
@@ -6,13 +6,16 @@ class EmployedEntries {
6
7
EmployedEntries({required this.receive, required this.send});
8
9
- factory EmployedEntries.fromJson(Map<String, dynamic> json) =>
10
- EmployedEntries(
11
- receive: json['receive'] == null ? [] : (json['receive'] as List<dynamic>)
12
- .map((e) => Receive.fromJson(e as Map<String, dynamic>))
13
- .toList(),
14
- send: json['spent'] == null ? [] : (json['spent'] as List<dynamic>)
15
- .map((e) => Receive.fromJson(e as Map<String, dynamic>))
16
- .toList(),
9
+ factory EmployedEntries.fromJson(Map<String, dynamic> json) => EmployedEntries(
10
+ receive: json['receive'] == null
11
+ ? []
12
+ : (json['receive'] as List<dynamic>)
13
+ .map((e) => Receive.fromJson(e as Map<String, dynamic>))
14
+ .toList(),
15
+ send: json['spent'] == null
16
+ ? []
17
+ : (json['spent'] as List<dynamic>)
18
+ .map((e) => Receive.fromJson(e as Map<String, dynamic>))
19
+ .toList(),
20
);
21
}
cw_zano/lib/api/model/get_recent_txs_and_info_params.dart
+8
-7
@@ -3,12 +3,13 @@ class GetRecentTxsAndInfoParams {
3
final int count;
4
final bool updateProvisionInfo;
5
6
- GetRecentTxsAndInfoParams({required this.offset, required this.count, this.updateProvisionInfo = true});
6
+ GetRecentTxsAndInfoParams(
7
+ {required this.offset, required this.count, this.updateProvisionInfo = true});
8
9
Map<String, dynamic> toJson() => {
9
- 'offset': offset,
10
- 'count': count,
11
- 'update_provision_info': updateProvisionInfo,
12
- 'order': 'FROM_BEGIN_TO_END',
13
- };
14
-}
\ No newline at end of file
10
+ 'offset': offset,
11
+ 'count': count,
12
+ 'update_provision_info': updateProvisionInfo,
13
+ 'order': 'FROM_BEGIN_TO_END',
14
+ };
15
+}
cw_zano/lib/api/model/get_recent_txs_and_info_result.dart
+7
-4
@@ -5,8 +5,11 @@ class GetRecentTxsAndInfoResult {
5
final int lastItemIndex;
6
final int totalTransfers;
7
8
- GetRecentTxsAndInfoResult({required this.transfers, required this.lastItemIndex, required this.totalTransfers});
9
-
10
- GetRecentTxsAndInfoResult.empty(): this.transfers = [], this.lastItemIndex = 0, this.totalTransfers = 0;
8
+ GetRecentTxsAndInfoResult(
9
+ {required this.transfers, required this.lastItemIndex, required this.totalTransfers});
10
12
-}
\ No newline at end of file
11
+ GetRecentTxsAndInfoResult.empty()
12
+ : this.transfers = [],
13
+ this.lastItemIndex = 0,
14
+ this.totalTransfers = 0;
15
+}
cw_zano/lib/api/model/get_wallet_status_result.dart
+1
-2
@@ -14,8 +14,7 @@ class GetWalletStatusResult {
14
required this.progress,
15
required this.walletState});
16
17
- factory GetWalletStatusResult.fromJson(Map<String, dynamic> json) =>
18
- GetWalletStatusResult(
17
+ factory GetWalletStatusResult.fromJson(Map<String, dynamic> json) => GetWalletStatusResult(
18
currentDaemonHeight: json['current_daemon_height'] as int? ?? 0,
19
currentWalletHeight: json['current_wallet_height'] as int? ?? 0,
20
isDaemonConnected: json['is_daemon_connected'] as bool? ?? false,
cw_zano/lib/api/model/recent_history.dart
+6
-6
@@ -6,14 +6,14 @@ class RecentHistory {
6
final int totalHistoryItems;
7
8
RecentHistory(
9
- {required this.history,
10
- required this.lastItemIndex,
11
- required this.totalHistoryItems});
9
+ {required this.history, required this.lastItemIndex, required this.totalHistoryItems});
10
11
factory RecentHistory.fromJson(Map<String, dynamic> json) => RecentHistory(
14
- history: json['history'] == null ? null : (json['history'] as List<dynamic>)
15
- .map((e) => Transfer.fromJson(e as Map<String, dynamic>))
16
- .toList(),
12
+ history: json['history'] == null
13
+ ? null
14
+ : (json['history'] as List<dynamic>)
15
+ .map((e) => Transfer.fromJson(e as Map<String, dynamic>))
16
+ .toList(),
17
lastItemIndex: json['last_item_index'] as int? ?? 0,
18
totalHistoryItems: json['total_history_items'] as int? ?? 0,
19
);
cw_zano/lib/api/model/store_result.dart
+1
-1
@@ -6,4 +6,4 @@ class StoreResult {
6
factory StoreResult.fromJson(Map<String, dynamic> json) => StoreResult(
7
walletFileSize: json['wallet_file_size'] as int? ?? 0,
8
);
9
-}
\ No newline at end of file
9
+}
cw_zano/lib/api/model/subtransfer.dart
+1
-2
@@ -5,8 +5,7 @@ class Subtransfer {
5
final String assetId;
6
final bool isIncome;
7
8
- Subtransfer(
9
- {required this.amount, required this.assetId, required this.isIncome});
8
+ Subtransfer({required this.amount, required this.assetId, required this.isIncome});
9
10
factory Subtransfer.fromJson(Map<String, dynamic> json) => Subtransfer(
11
amount: ZanoFormatter.bigIntFromDynamic(json['amount']),
cw_zano/lib/api/model/transfer.dart
+23
-21
@@ -49,38 +49,40 @@ class Transfer {
49
required this.unlockTime,
50
});
51
52
- factory Transfer.fromJson(Map<String, dynamic> json) =>
53
- Transfer(
52
+ factory Transfer.fromJson(Map<String, dynamic> json) => Transfer(
53
comment: json['comment'] as String? ?? '',
55
- employedEntries: EmployedEntries.fromJson(
56
- json['employed_entries'] as Map<String, dynamic>? ?? {}),
54
+ employedEntries:
55
+ EmployedEntries.fromJson(json['employed_entries'] as Map<String, dynamic>? ?? {}),
56
fee: json['fee'] as int? ?? 0,
57
height: json['height'] as int? ?? 0,
58
isMining: json['is_mining'] as bool? ?? false,
59
isMixing: json['is_mixing'] as bool? ?? false,
60
isService: json['is_service'] as bool? ?? false,
61
paymentId: json['payment_id'] as String? ?? '',
63
- remoteAddresses: json['remote_addresses'] == null ? [] : (json['remote_addresses'] as List<
64
- dynamic>).cast<String>(),
65
- remoteAliases: json['remote_aliases'] == null ? [] : (json['remote_aliases'] as List<
66
- dynamic>).cast<String>(),
62
+ remoteAddresses: json['remote_addresses'] == null
63
+ ? []
64
+ : (json['remote_addresses'] as List<dynamic>).cast<String>(),
65
+ remoteAliases: json['remote_aliases'] == null
66
+ ? []
67
+ : (json['remote_aliases'] as List<dynamic>).cast<String>(),
68
showSender: json['show_sender'] as bool? ?? false,
68
- subtransfers: (json['subtransfers'] as List<dynamic>? ?? []).map((e) =>
69
- Subtransfer.fromJson(e as Map<String, dynamic>)).toList(),
69
+ subtransfers: (json['subtransfers'] as List<dynamic>? ?? [])
70
+ .map((e) => Subtransfer.fromJson(e as Map<String, dynamic>))
71
+ .toList(),
72
timestamp: json['timestamp'] as int? ?? 0,
73
transferInternalIndex: json['transfer_internal_index'] == null
74
? 0
75
: json['transfer_internal_index'] is double
74
- ? (json['transfer_internal_index'] as double).toInt()
75
- : json['transfer_internal_index'] as int,
76
+ ? (json['transfer_internal_index'] as double).toInt()
77
+ : json['transfer_internal_index'] as int,
78
txBlobSize: json['tx_blob_size'] as int? ?? 0,
79
txHash: json['tx_hash'] as String? ?? '',
80
txType: json['tx_type'] as int? ?? 0,
81
unlockTime: json['unlock_time'] as int? ?? 0,
82
);
83
82
- static Map<String, ZanoTransactionInfo> makeMap(List<Transfer> transfers,
83
- Map<String, ZanoAsset> zanoAssets, int currentDaemonHeight) {
84
+ static Map<String, ZanoTransactionInfo> makeMap(
85
+ List<Transfer> transfers, Map<String, ZanoAsset> zanoAssets, int currentDaemonHeight) {
86
return Map.fromIterable(
87
transfers,
88
key: (item) => (item as Transfer).txHash,
@@ -89,19 +91,19 @@ class Transfer {
91
// Simple (only one subtransfer OR two subtransfers and the second is Zano, outgoing and amount equals to fee) or complex?
92
Subtransfer? single = transfer.subtransfers.singleOrNull;
93
if (transfer.subtransfers.length == 2) {
92
- final zano = transfer.subtransfers.firstWhereOrNull((element) =>
93
- element.assetId == ZanoWalletBase.zanoAssetId);
94
+ final zano = transfer.subtransfers
95
+ .firstWhereOrNull((element) => element.assetId == ZanoWalletBase.zanoAssetId);
96
if (zano != null && !zano.isIncome && zano.amount == BigInt.from(transfer.fee)) {
95
- single = transfer.subtransfers.firstWhere((element) => element.assetId !=
96
- ZanoWalletBase.zanoAssetId);
97
+ single = transfer.subtransfers
98
+ .firstWhere((element) => element.assetId != ZanoWalletBase.zanoAssetId);
99
}
100
}
101
bool isSimple = single != null;
102
// TODO: for complex transactions we show zano or any other transaction, will fix it later
103
if (!isSimple) {
102
- single =
103
- transfer.subtransfers.firstWhereOrNull((element) =>
104
- element.assetId == ZanoWalletBase.zanoAssetId) ?? transfer.subtransfers.first;
104
+ single = transfer.subtransfers
105
+ .firstWhereOrNull((element) => element.assetId == ZanoWalletBase.zanoAssetId) ??
106
+ transfer.subtransfers.first;
107
}
108
if (single.assetId != ZanoWalletBase.zanoAssetId) {
109
final asset = zanoAssets[single.assetId];
cw_zano/lib/api/model/transfer_params.dart
+12
-9
@@ -20,17 +20,20 @@ class TransferParams {
20
});
21
22
Map<String, dynamic> toJson() => {
23
- 'destinations': destinations,
24
- 'fee': fee.toInt(),
25
- 'mixin': mixin,
26
- 'payment_id': paymentId,
27
- 'comment': comment,
28
- 'push_payer': pushPayer,
29
- 'hide_receiver': hideReceiver,
30
- };
23
+ 'destinations': destinations,
24
+ 'fee': fee.toInt(),
25
+ 'mixin': mixin,
26
+ 'payment_id': paymentId,
27
+ 'comment': comment,
28
+ 'push_payer': pushPayer,
29
+ 'hide_receiver': hideReceiver,
30
+ };
31
32
factory TransferParams.fromJson(Map<String, dynamic> json) => TransferParams(
33
- destinations: (json['destinations'] as List<dynamic>?)?.map((e) => Destination.fromJson(e as Map<String, dynamic>)).toList() ?? [],
33
+ destinations: (json['destinations'] as List<dynamic>?)
34
+ ?.map((e) => Destination.fromJson(e as Map<String, dynamic>))
35
+ .toList() ??
36
+ [],
37
fee: BigInt.from(json['fee'] as int? ?? 0),
38
mixin: json['mixin'] as int? ?? 0,
39
paymentId: json['payment_id'] as String? ?? '',
cw_zano/lib/api/model/wi_extended.dart
+11
-7
@@ -6,16 +6,20 @@ class WiExtended {
6
final String viewPrivateKey;
7
final String viewPublicKey;
8
9
- WiExtended({required this.spendPrivateKey, required this.spendPublicKey, required this.viewPrivateKey, required this.viewPublicKey});
9
+ WiExtended(
10
+ {required this.spendPrivateKey,
11
+ required this.spendPublicKey,
12
+ required this.viewPrivateKey,
13
+ required this.viewPublicKey});
14
15
factory WiExtended.fromJson(Map<String, dynamic> json) => WiExtended(
12
- spendPrivateKey: json['spend_private_key'] as String? ?? '',
13
- spendPublicKey: json['spend_public_key'] as String? ?? '',
14
- viewPrivateKey: json['view_private_key'] as String? ?? '',
15
- viewPublicKey: json['view_public_key'] as String? ?? '',
16
- );
16
+ spendPrivateKey: json['spend_private_key'] as String? ?? '',
17
+ spendPublicKey: json['spend_public_key'] as String? ?? '',
18
+ viewPrivateKey: json['view_private_key'] as String? ?? '',
19
+ viewPublicKey: json['view_public_key'] as String? ?? '',
20
+ );
21
22
Future<String> seed(ZanoWalletBase api) {
23
return api.getSeed();
24
}
21
-}
\ No newline at end of file
25
+}
cw_zano/lib/mnemonics/english.dart
+1626
-1626
@@ -1,1630 +1,1630 @@
1
class EnglishMnemonics {
2
static const words = [
3
- "like",
4
- "just",
5
- "love",
6
- "know",
7
- "never",
8
- "want",
9
- "time",
10
- "out",
11
- "there",
12
- "make",
13
- "look",
14
- "eye",
15
- "down",
16
- "only",
17
- "think",
18
- "heart",
19
- "back",
20
- "then",
21
- "into",
22
- "about",
23
- "more",
24
- "away",
25
- "still",
26
- "them",
27
- "take",
28
- "thing",
29
- "even",
30
- "through",
31
- "long",
32
- "always",
33
- "world",
34
- "too",
35
- "friend",
36
- "tell",
37
- "try",
38
- "hand",
39
- "thought",
40
- "over",
41
- "here",
42
- "other",
43
- "need",
44
- "smile",
45
- "again",
46
- "much",
47
- "cry",
48
- "been",
49
- "night",
50
- "ever",
51
- "little",
52
- "said",
53
- "end",
54
- "some",
55
- "those",
56
- "around",
57
- "mind",
58
- "people",
59
- "girl",
60
- "leave",
61
- "dream",
62
- "left",
63
- "turn",
64
- "myself",
65
- "give",
66
- "nothing",
67
- "really",
68
- "off",
69
- "before",
70
- "something",
71
- "find",
72
- "walk",
73
- "wish",
74
- "good",
75
- "once",
76
- "place",
77
- "ask",
78
- "stop",
79
- "keep",
80
- "watch",
81
- "seem",
82
- "everything",
83
- "wait",
84
- "got",
85
- "yet",
86
- "made",
87
- "remember",
88
- "start",
89
- "alone",
90
- "run",
91
- "hope",
92
- "maybe",
93
- "believe",
94
- "body",
95
- "hate",
96
- "after",
97
- "close",
98
- "talk",
99
- "stand",
100
- "own",
101
- "each",
102
- "hurt",
103
- "help",
104
- "home",
105
- "god",
106
- "soul",
107
- "new",
108
- "many",
109
- "two",
110
- "inside",
111
- "should",
112
- "true",
113
- "first",
114
- "fear",
115
- "mean",
116
- "better",
117
- "play",
118
- "another",
119
- "gone",
120
- "change",
121
- "use",
122
- "wonder",
123
- "someone",
124
- "hair",
125
- "cold",
126
- "open",
127
- "best",
128
- "any",
129
- "behind",
130
- "happen",
131
- "water",
132
- "dark",
133
- "laugh",
134
- "stay",
135
- "forever",
136
- "name",
137
- "work",
138
- "show",
139
- "sky",
140
- "break",
141
- "came",
142
- "deep",
143
- "door",
144
- "put",
145
- "black",
146
- "together",
147
- "upon",
148
- "happy",
149
- "such",
150
- "great",
151
- "white",
152
- "matter",
153
- "fill",
154
- "past",
155
- "please",
156
- "burn",
157
- "cause",
158
- "enough",
159
- "touch",
160
- "moment",
161
- "soon",
162
- "voice",
163
- "scream",
164
- "anything",
165
- "stare",
166
- "sound",
167
- "red",
168
- "everyone",
169
- "hide",
170
- "kiss",
171
- "truth",
172
- "death",
173
- "beautiful",
174
- "mine",
175
- "blood",
176
- "broken",
177
- "very",
178
- "pass",
179
- "next",
180
- "forget",
181
- "tree",
182
- "wrong",
183
- "air",
184
- "mother",
185
- "understand",
186
- "lip",
187
- "hit",
188
- "wall",
189
- "memory",
190
- "sleep",
191
- "free",
192
- "high",
193
- "realize",
194
- "school",
195
- "might",
196
- "skin",
197
- "sweet",
198
- "perfect",
199
- "blue",
200
- "kill",
201
- "breath",
202
- "dance",
203
- "against",
204
- "fly",
205
- "between",
206
- "grow",
207
- "strong",
208
- "under",
209
- "listen",
210
- "bring",
211
- "sometimes",
212
- "speak",
213
- "pull",
214
- "person",
215
- "become",
216
- "family",
217
- "begin",
218
- "ground",
219
- "real",
220
- "small",
221
- "father",
222
- "sure",
223
- "feet",
224
- "rest",
225
- "young",
226
- "finally",
227
- "land",
228
- "across",
229
- "today",
230
- "different",
231
- "guy",
232
- "line",
233
- "fire",
234
- "reason",
235
- "reach",
236
- "second",
237
- "slowly",
238
- "write",
239
- "eat",
240
- "smell",
241
- "mouth",
242
- "step",
243
- "learn",
244
- "three",
245
- "floor",
246
- "promise",
247
- "breathe",
248
- "darkness",
249
- "push",
250
- "earth",
251
- "guess",
252
- "save",
253
- "song",
254
- "above",
255
- "along",
256
- "both",
257
- "color",
258
- "house",
259
- "almost",
260
- "sorry",
261
- "anymore",
262
- "brother",
263
- "okay",
264
- "dear",
265
- "game",
266
- "fade",
267
- "already",
268
- "apart",
269
- "warm",
270
- "beauty",
271
- "heard",
272
- "notice",
273
- "question",
274
- "shine",
275
- "began",
276
- "piece",
277
- "whole",
278
- "shadow",
279
- "secret",
280
- "street",
281
- "within",
282
- "finger",
283
- "point",
284
- "morning",
285
- "whisper",
286
- "child",
287
- "moon",
288
- "green",
289
- "story",
290
- "glass",
291
- "kid",
292
- "silence",
293
- "since",
294
- "soft",
295
- "yourself",
296
- "empty",
297
- "shall",
298
- "angel",
299
- "answer",
300
- "baby",
301
- "bright",
302
- "dad",
303
- "path",
304
- "worry",
305
- "hour",
306
- "drop",
307
- "follow",
308
- "power",
309
- "war",
310
- "half",
311
- "flow",
312
- "heaven",
313
- "act",
314
- "chance",
315
- "fact",
316
- "least",
317
- "tired",
318
- "children",
319
- "near",
320
- "quite",
321
- "afraid",
322
- "rise",
323
- "sea",
324
- "taste",
325
- "window",
326
- "cover",
327
- "nice",
328
- "trust",
329
- "lot",
330
- "sad",
331
- "cool",
332
- "force",
333
- "peace",
334
- "return",
335
- "blind",
336
- "easy",
337
- "ready",
338
- "roll",
339
- "rose",
340
- "drive",
341
- "held",
342
- "music",
343
- "beneath",
344
- "hang",
345
- "mom",
346
- "paint",
347
- "emotion",
348
- "quiet",
349
- "clear",
350
- "cloud",
351
- "few",
352
- "pretty",
353
- "bird",
354
- "outside",
355
- "paper",
356
- "picture",
357
- "front",
358
- "rock",
359
- "simple",
360
- "anyone",
361
- "meant",
362
- "reality",
363
- "road",
364
- "sense",
365
- "waste",
366
- "bit",
367
- "leaf",
368
- "thank",
369
- "happiness",
370
- "meet",
371
- "men",
372
- "smoke",
373
- "truly",
374
- "decide",
375
- "self",
376
- "age",
377
- "book",
378
- "form",
379
- "alive",
380
- "carry",
381
- "escape",
382
- "damn",
383
- "instead",
384
- "able",
385
- "ice",
386
- "minute",
387
- "throw",
388
- "catch",
389
- "leg",
390
- "ring",
391
- "course",
392
- "goodbye",
393
- "lead",
394
- "poem",
395
- "sick",
396
- "corner",
397
- "desire",
398
- "known",
399
- "problem",
400
- "remind",
401
- "shoulder",
402
- "suppose",
403
- "toward",
404
- "wave",
405
- "drink",
406
- "jump",
407
- "woman",
408
- "pretend",
409
- "sister",
410
- "week",
411
- "human",
412
- "joy",
413
- "crack",
414
- "grey",
415
- "pray",
416
- "surprise",
417
- "dry",
418
- "knee",
419
- "less",
420
- "search",
421
- "bleed",
422
- "caught",
423
- "clean",
424
- "embrace",
425
- "future",
426
- "king",
427
- "son",
428
- "sorrow",
429
- "chest",
430
- "hug",
431
- "remain",
432
- "sat",
433
- "worth",
434
- "blow",
435
- "daddy",
436
- "final",
437
- "parent",
438
- "tight",
439
- "also",
440
- "create",
441
- "lonely",
442
- "safe",
443
- "cross",
444
- "dress",
445
- "evil",
446
- "silent",
447
- "bone",
448
- "fate",
449
- "perhaps",
450
- "anger",
451
- "class",
452
- "scar",
453
- "snow",
454
- "tiny",
455
- "tonight",
456
- "continue",
457
- "control",
458
- "dog",
459
- "edge",
460
- "mirror",
461
- "month",
462
- "suddenly",
463
- "comfort",
464
- "given",
465
- "loud",
466
- "quickly",
467
- "gaze",
468
- "plan",
469
- "rush",
470
- "stone",
471
- "town",
472
- "battle",
473
- "ignore",
474
- "spirit",
475
- "stood",
476
- "stupid",
477
- "yours",
478
- "brown",
479
- "build",
480
- "dust",
481
- "hey",
482
- "kept",
483
- "pay",
484
- "phone",
485
- "twist",
486
- "although",
487
- "ball",
488
- "beyond",
489
- "hidden",
490
- "nose",
491
- "taken",
492
- "fail",
493
- "float",
494
- "pure",
495
- "somehow",
496
- "wash",
497
- "wrap",
498
- "angry",
499
- "cheek",
500
- "creature",
501
- "forgotten",
502
- "heat",
503
- "rip",
504
- "single",
505
- "space",
506
- "special",
507
- "weak",
508
- "whatever",
509
- "yell",
510
- "anyway",
511
- "blame",
512
- "job",
513
- "choose",
514
- "country",
515
- "curse",
516
- "drift",
517
- "echo",
518
- "figure",
519
- "grew",
520
- "laughter",
521
- "neck",
522
- "suffer",
523
- "worse",
524
- "yeah",
525
- "disappear",
526
- "foot",
527
- "forward",
528
- "knife",
529
- "mess",
530
- "somewhere",
531
- "stomach",
532
- "storm",
533
- "beg",
534
- "idea",
535
- "lift",
536
- "offer",
537
- "breeze",
538
- "field",
539
- "five",
540
- "often",
541
- "simply",
542
- "stuck",
543
- "win",
544
- "allow",
545
- "confuse",
546
- "enjoy",
547
- "except",
548
- "flower",
549
- "seek",
550
- "strength",
551
- "calm",
552
- "grin",
553
- "gun",
554
- "heavy",
555
- "hill",
556
- "large",
557
- "ocean",
558
- "shoe",
559
- "sigh",
560
- "straight",
561
- "summer",
562
- "tongue",
563
- "accept",
564
- "crazy",
565
- "everyday",
566
- "exist",
567
- "grass",
568
- "mistake",
569
- "sent",
570
- "shut",
571
- "surround",
572
- "table",
573
- "ache",
574
- "brain",
575
- "destroy",
576
- "heal",
577
- "nature",
578
- "shout",
579
- "sign",
580
- "stain",
581
- "choice",
582
- "doubt",
583
- "glance",
584
- "glow",
585
- "mountain",
586
- "queen",
587
- "stranger",
588
- "throat",
589
- "tomorrow",
590
- "city",
591
- "either",
592
- "fish",
593
- "flame",
594
- "rather",
595
- "shape",
596
- "spin",
597
- "spread",
598
- "ash",
599
- "distance",
600
- "finish",
601
- "image",
602
- "imagine",
603
- "important",
604
- "nobody",
605
- "shatter",
606
- "warmth",
607
- "became",
608
- "feed",
609
- "flesh",
610
- "funny",
611
- "lust",
612
- "shirt",
613
- "trouble",
614
- "yellow",
615
- "attention",
616
- "bare",
617
- "bite",
618
- "money",
619
- "protect",
620
- "amaze",
621
- "appear",
622
- "born",
623
- "choke",
624
- "completely",
625
- "daughter",
626
- "fresh",
627
- "friendship",
628
- "gentle",
629
- "probably",
630
- "six",
631
- "deserve",
632
- "expect",
633
- "grab",
634
- "middle",
635
- "nightmare",
636
- "river",
637
- "thousand",
638
- "weight",
639
- "worst",
640
- "wound",
641
- "barely",
642
- "bottle",
643
- "cream",
644
- "regret",
645
- "relationship",
646
- "stick",
647
- "test",
648
- "crush",
649
- "endless",
650
- "fault",
651
- "itself",
652
- "rule",
653
- "spill",
654
- "art",
655
- "circle",
656
- "join",
657
- "kick",
658
- "mask",
659
- "master",
660
- "passion",
661
- "quick",
662
- "raise",
663
- "smooth",
664
- "unless",
665
- "wander",
666
- "actually",
667
- "broke",
668
- "chair",
669
- "deal",
670
- "favorite",
671
- "gift",
672
- "note",
673
- "number",
674
- "sweat",
675
- "box",
676
- "chill",
677
- "clothes",
678
- "lady",
679
- "mark",
680
- "park",
681
- "poor",
682
- "sadness",
683
- "tie",
684
- "animal",
685
- "belong",
686
- "brush",
687
- "consume",
688
- "dawn",
689
- "forest",
690
- "innocent",
691
- "pen",
692
- "pride",
693
- "stream",
694
- "thick",
695
- "clay",
696
- "complete",
697
- "count",
698
- "draw",
699
- "faith",
700
- "press",
701
- "silver",
702
- "struggle",
703
- "surface",
704
- "taught",
705
- "teach",
706
- "wet",
707
- "bless",
708
- "chase",
709
- "climb",
710
- "enter",
711
- "letter",
712
- "melt",
713
- "metal",
714
- "movie",
715
- "stretch",
716
- "swing",
717
- "vision",
718
- "wife",
719
- "beside",
720
- "crash",
721
- "forgot",
722
- "guide",
723
- "haunt",
724
- "joke",
725
- "knock",
726
- "plant",
727
- "pour",
728
- "prove",
729
- "reveal",
730
- "steal",
731
- "stuff",
732
- "trip",
733
- "wood",
734
- "wrist",
735
- "bother",
736
- "bottom",
737
- "crawl",
738
- "crowd",
739
- "fix",
740
- "forgive",
741
- "frown",
742
- "grace",
743
- "loose",
744
- "lucky",
745
- "party",
746
- "release",
747
- "surely",
748
- "survive",
749
- "teacher",
750
- "gently",
751
- "grip",
752
- "speed",
753
- "suicide",
754
- "travel",
755
- "treat",
756
- "vein",
757
- "written",
758
- "cage",
759
- "chain",
760
- "conversation",
761
- "date",
762
- "enemy",
763
- "however",
764
- "interest",
765
- "million",
766
- "page",
767
- "pink",
768
- "proud",
769
- "sway",
770
- "themselves",
771
- "winter",
772
- "church",
773
- "cruel",
774
- "cup",
775
- "demon",
776
- "experience",
777
- "freedom",
778
- "pair",
779
- "pop",
780
- "purpose",
781
- "respect",
782
- "shoot",
783
- "softly",
784
- "state",
785
- "strange",
786
- "bar",
787
- "birth",
788
- "curl",
789
- "dirt",
790
- "excuse",
791
- "lord",
792
- "lovely",
793
- "monster",
794
- "order",
795
- "pack",
796
- "pants",
797
- "pool",
798
- "scene",
799
- "seven",
800
- "shame",
801
- "slide",
802
- "ugly",
803
- "among",
804
- "blade",
805
- "blonde",
806
- "closet",
807
- "creek",
808
- "deny",
809
- "drug",
810
- "eternity",
811
- "gain",
812
- "grade",
813
- "handle",
814
- "key",
815
- "linger",
816
- "pale",
817
- "prepare",
818
- "swallow",
819
- "swim",
820
- "tremble",
821
- "wheel",
822
- "won",
823
- "cast",
824
- "cigarette",
825
- "claim",
826
- "college",
827
- "direction",
828
- "dirty",
829
- "gather",
830
- "ghost",
831
- "hundred",
832
- "loss",
833
- "lung",
834
- "orange",
835
- "present",
836
- "swear",
837
- "swirl",
838
- "twice",
839
- "wild",
840
- "bitter",
841
- "blanket",
842
- "doctor",
843
- "everywhere",
844
- "flash",
845
- "grown",
846
- "knowledge",
847
- "numb",
848
- "pressure",
849
- "radio",
850
- "repeat",
851
- "ruin",
852
- "spend",
853
- "unknown",
854
- "buy",
855
- "clock",
856
- "devil",
857
- "early",
858
- "false",
859
- "fantasy",
860
- "pound",
861
- "precious",
862
- "refuse",
863
- "sheet",
864
- "teeth",
865
- "welcome",
866
- "add",
867
- "ahead",
868
- "block",
869
- "bury",
870
- "caress",
871
- "content",
872
- "depth",
873
- "despite",
874
- "distant",
875
- "marry",
876
- "purple",
877
- "threw",
878
- "whenever",
879
- "bomb",
880
- "dull",
881
- "easily",
882
- "grasp",
883
- "hospital",
884
- "innocence",
885
- "normal",
886
- "receive",
887
- "reply",
888
- "rhyme",
889
- "shade",
890
- "someday",
891
- "sword",
892
- "toe",
893
- "visit",
894
- "asleep",
895
- "bought",
896
- "center",
897
- "consider",
898
- "flat",
899
- "hero",
900
- "history",
901
- "ink",
902
- "insane",
903
- "muscle",
904
- "mystery",
905
- "pocket",
906
- "reflection",
907
- "shove",
908
- "silently",
909
- "smart",
910
- "soldier",
911
- "spot",
912
- "stress",
913
- "train",
914
- "type",
915
- "view",
916
- "whether",
917
- "bus",
918
- "energy",
919
- "explain",
920
- "holy",
921
- "hunger",
922
- "inch",
923
- "magic",
924
- "mix",
925
- "noise",
926
- "nowhere",
927
- "prayer",
928
- "presence",
929
- "shock",
930
- "snap",
931
- "spider",
932
- "study",
933
- "thunder",
934
- "trail",
935
- "admit",
936
- "agree",
937
- "bag",
938
- "bang",
939
- "bound",
940
- "butterfly",
941
- "cute",
942
- "exactly",
943
- "explode",
944
- "familiar",
945
- "fold",
946
- "further",
947
- "pierce",
948
- "reflect",
949
- "scent",
950
- "selfish",
951
- "sharp",
952
- "sink",
953
- "spring",
954
- "stumble",
955
- "universe",
956
- "weep",
957
- "women",
958
- "wonderful",
959
- "action",
960
- "ancient",
961
- "attempt",
962
- "avoid",
963
- "birthday",
964
- "branch",
965
- "chocolate",
966
- "core",
967
- "depress",
968
- "drunk",
969
- "especially",
970
- "focus",
971
- "fruit",
972
- "honest",
973
- "match",
974
- "palm",
975
- "perfectly",
976
- "pillow",
977
- "pity",
978
- "poison",
979
- "roar",
980
- "shift",
981
- "slightly",
982
- "thump",
983
- "truck",
984
- "tune",
985
- "twenty",
986
- "unable",
987
- "wipe",
988
- "wrote",
989
- "coat",
990
- "constant",
991
- "dinner",
992
- "drove",
993
- "egg",
994
- "eternal",
995
- "flight",
996
- "flood",
997
- "frame",
998
- "freak",
999
- "gasp",
1000
- "glad",
1001
- "hollow",
1002
- "motion",
1003
- "peer",
1004
- "plastic",
1005
- "root",
1006
- "screen",
1007
- "season",
1008
- "sting",
1009
- "strike",
1010
- "team",
1011
- "unlike",
1012
- "victim",
1013
- "volume",
1014
- "warn",
1015
- "weird",
1016
- "attack",
1017
- "await",
1018
- "awake",
1019
- "built",
1020
- "charm",
1021
- "crave",
1022
- "despair",
1023
- "fought",
1024
- "grant",
1025
- "grief",
1026
- "horse",
1027
- "limit",
1028
- "message",
1029
- "ripple",
1030
- "sanity",
1031
- "scatter",
1032
- "serve",
1033
- "split",
1034
- "string",
1035
- "trick",
1036
- "annoy",
1037
- "blur",
1038
- "boat",
1039
- "brave",
1040
- "clearly",
1041
- "cling",
1042
- "connect",
1043
- "fist",
1044
- "forth",
1045
- "imagination",
1046
- "iron",
1047
- "jock",
1048
- "judge",
1049
- "lesson",
1050
- "milk",
1051
- "misery",
1052
- "nail",
1053
- "naked",
1054
- "ourselves",
1055
- "poet",
1056
- "possible",
1057
- "princess",
1058
- "sail",
1059
- "size",
1060
- "snake",
1061
- "society",
1062
- "stroke",
1063
- "torture",
1064
- "toss",
1065
- "trace",
1066
- "wise",
1067
- "bloom",
1068
- "bullet",
1069
- "cell",
1070
- "check",
1071
- "cost",
1072
- "darling",
1073
- "during",
1074
- "footstep",
1075
- "fragile",
1076
- "hallway",
1077
- "hardly",
1078
- "horizon",
1079
- "invisible",
1080
- "journey",
1081
- "midnight",
1082
- "mud",
1083
- "nod",
1084
- "pause",
1085
- "relax",
1086
- "shiver",
1087
- "sudden",
1088
- "value",
1089
- "youth",
1090
- "abuse",
1091
- "admire",
1092
- "blink",
1093
- "breast",
1094
- "bruise",
1095
- "constantly",
1096
- "couple",
1097
- "creep",
1098
- "curve",
1099
- "difference",
1100
- "dumb",
1101
- "emptiness",
1102
- "gotta",
1103
- "honor",
1104
- "plain",
1105
- "planet",
1106
- "recall",
1107
- "rub",
1108
- "ship",
1109
- "slam",
1110
- "soar",
1111
- "somebody",
1112
- "tightly",
1113
- "weather",
1114
- "adore",
1115
- "approach",
1116
- "bond",
1117
- "bread",
1118
- "burst",
1119
- "candle",
1120
- "coffee",
1121
- "cousin",
1122
- "crime",
1123
- "desert",
1124
- "flutter",
1125
- "frozen",
1126
- "grand",
1127
- "heel",
1128
- "hello",
1129
- "language",
1130
- "level",
1131
- "movement",
1132
- "pleasure",
1133
- "powerful",
1134
- "random",
1135
- "rhythm",
1136
- "settle",
1137
- "silly",
1138
- "slap",
1139
- "sort",
1140
- "spoken",
1141
- "steel",
1142
- "threaten",
1143
- "tumble",
1144
- "upset",
1145
- "aside",
1146
- "awkward",
1147
- "bee",
1148
- "blank",
1149
- "board",
1150
- "button",
1151
- "card",
1152
- "carefully",
1153
- "complain",
1154
- "crap",
1155
- "deeply",
1156
- "discover",
1157
- "drag",
1158
- "dread",
1159
- "effort",
1160
- "entire",
1161
- "fairy",
1162
- "giant",
1163
- "gotten",
1164
- "greet",
1165
- "illusion",
1166
- "jeans",
1167
- "leap",
1168
- "liquid",
1169
- "march",
1170
- "mend",
1171
- "nervous",
1172
- "nine",
1173
- "replace",
1174
- "rope",
1175
- "spine",
1176
- "stole",
1177
- "terror",
1178
- "accident",
1179
- "apple",
1180
- "balance",
1181
- "boom",
1182
- "childhood",
1183
- "collect",
1184
- "demand",
1185
- "depression",
1186
- "eventually",
1187
- "faint",
1188
- "glare",
1189
- "goal",
1190
- "group",
1191
- "honey",
1192
- "kitchen",
1193
- "laid",
1194
- "limb",
1195
- "machine",
1196
- "mere",
1197
- "mold",
1198
- "murder",
1199
- "nerve",
1200
- "painful",
1201
- "poetry",
1202
- "prince",
1203
- "rabbit",
1204
- "shelter",
1205
- "shore",
1206
- "shower",
1207
- "soothe",
1208
- "stair",
1209
- "steady",
1210
- "sunlight",
1211
- "tangle",
1212
- "tease",
1213
- "treasure",
1214
- "uncle",
1215
- "begun",
1216
- "bliss",
1217
- "canvas",
1218
- "cheer",
1219
- "claw",
1220
- "clutch",
1221
- "commit",
1222
- "crimson",
1223
- "crystal",
1224
- "delight",
1225
- "doll",
1226
- "existence",
1227
- "express",
1228
- "fog",
1229
- "football",
1230
- "gay",
1231
- "goose",
1232
- "guard",
1233
- "hatred",
1234
- "illuminate",
1235
- "mass",
1236
- "math",
1237
- "mourn",
1238
- "rich",
1239
- "rough",
1240
- "skip",
1241
- "stir",
1242
- "student",
1243
- "style",
1244
- "support",
1245
- "thorn",
1246
- "tough",
1247
- "yard",
1248
- "yearn",
1249
- "yesterday",
1250
- "advice",
1251
- "appreciate",
1252
- "autumn",
1253
- "bank",
1254
- "beam",
1255
- "bowl",
1256
- "capture",
1257
- "carve",
1258
- "collapse",
1259
- "confusion",
1260
- "creation",
1261
- "dove",
1262
- "feather",
1263
- "girlfriend",
1264
- "glory",
1265
- "government",
1266
- "harsh",
1267
- "hop",
1268
- "inner",
1269
- "loser",
1270
- "moonlight",
1271
- "neighbor",
1272
- "neither",
1273
- "peach",
1274
- "pig",
1275
- "praise",
1276
- "screw",
1277
- "shield",
1278
- "shimmer",
1279
- "sneak",
1280
- "stab",
1281
- "subject",
1282
- "throughout",
1283
- "thrown",
1284
- "tower",
1285
- "twirl",
1286
- "wow",
1287
- "army",
1288
- "arrive",
1289
- "bathroom",
1290
- "bump",
1291
- "cease",
1292
- "cookie",
1293
- "couch",
1294
- "courage",
1295
- "dim",
1296
- "guilt",
1297
- "howl",
1298
- "hum",
1299
- "husband",
1300
- "insult",
1301
- "led",
1302
- "lunch",
1303
- "mock",
1304
- "mostly",
1305
- "natural",
1306
- "nearly",
1307
- "needle",
1308
- "nerd",
1309
- "peaceful",
1310
- "perfection",
1311
- "pile",
1312
- "price",
1313
- "remove",
1314
- "roam",
1315
- "sanctuary",
1316
- "serious",
1317
- "shiny",
1318
- "shook",
1319
- "sob",
1320
- "stolen",
1321
- "tap",
1322
- "vain",
1323
- "void",
1324
- "warrior",
1325
- "wrinkle",
1326
- "affection",
1327
- "apologize",
1328
- "blossom",
1329
- "bounce",
1330
- "bridge",
1331
- "cheap",
1332
- "crumble",
1333
- "decision",
1334
- "descend",
1335
- "desperately",
1336
- "dig",
1337
- "dot",
1338
- "flip",
1339
- "frighten",
1340
- "heartbeat",
1341
- "huge",
1342
- "lazy",
1343
- "lick",
1344
- "odd",
1345
- "opinion",
1346
- "process",
1347
- "puzzle",
1348
- "quietly",
1349
- "retreat",
1350
- "score",
1351
- "sentence",
1352
- "separate",
1353
- "situation",
1354
- "skill",
1355
- "soak",
1356
- "square",
1357
- "stray",
1358
- "taint",
1359
- "task",
1360
- "tide",
1361
- "underneath",
1362
- "veil",
1363
- "whistle",
1364
- "anywhere",
1365
- "bedroom",
1366
- "bid",
1367
- "bloody",
1368
- "burden",
1369
- "careful",
1370
- "compare",
1371
- "concern",
1372
- "curtain",
1373
- "decay",
1374
- "defeat",
1375
- "describe",
1376
- "double",
1377
- "dreamer",
1378
- "driver",
1379
- "dwell",
1380
- "evening",
1381
- "flare",
1382
- "flicker",
1383
- "grandma",
1384
- "guitar",
1385
- "harm",
1386
- "horrible",
1387
- "hungry",
1388
- "indeed",
1389
- "lace",
1390
- "melody",
1391
- "monkey",
1392
- "nation",
1393
- "object",
1394
- "obviously",
1395
- "rainbow",
1396
- "salt",
1397
- "scratch",
1398
- "shown",
1399
- "shy",
1400
- "stage",
1401
- "stun",
1402
- "third",
1403
- "tickle",
1404
- "useless",
1405
- "weakness",
1406
- "worship",
1407
- "worthless",
1408
- "afternoon",
1409
- "beard",
1410
- "boyfriend",
1411
- "bubble",
1412
- "busy",
1413
- "certain",
1414
- "chin",
1415
- "concrete",
1416
- "desk",
1417
- "diamond",
1418
- "doom",
1419
- "drawn",
1420
- "due",
1421
- "felicity",
1422
- "freeze",
1423
- "frost",
1424
- "garden",
1425
- "glide",
1426
- "harmony",
1427
- "hopefully",
1428
- "hunt",
1429
- "jealous",
1430
- "lightning",
1431
- "mama",
1432
- "mercy",
1433
- "peel",
1434
- "physical",
1435
- "position",
1436
- "pulse",
1437
- "punch",
1438
- "quit",
1439
- "rant",
1440
- "respond",
1441
- "salty",
1442
- "sane",
1443
- "satisfy",
1444
- "savior",
1445
- "sheep",
1446
- "slept",
1447
- "social",
1448
- "sport",
1449
- "tuck",
1450
- "utter",
1451
- "valley",
1452
- "wolf",
1453
- "aim",
1454
- "alas",
1455
- "alter",
1456
- "arrow",
1457
- "awaken",
1458
- "beaten",
1459
- "belief",
1460
- "brand",
1461
- "ceiling",
1462
- "cheese",
1463
- "clue",
1464
- "confidence",
1465
- "connection",
1466
- "daily",
1467
- "disguise",
1468
- "eager",
1469
- "erase",
1470
- "essence",
1471
- "everytime",
1472
- "expression",
1473
- "fan",
1474
- "flag",
1475
- "flirt",
1476
- "foul",
1477
- "fur",
1478
- "giggle",
1479
- "glorious",
1480
- "ignorance",
1481
- "law",
1482
- "lifeless",
1483
- "measure",
1484
- "mighty",
1485
- "muse",
1486
- "north",
1487
- "opposite",
1488
- "paradise",
1489
- "patience",
1490
- "patient",
1491
- "pencil",
1492
- "petal",
1493
- "plate",
1494
- "ponder",
1495
- "possibly",
1496
- "practice",
1497
- "slice",
1498
- "spell",
1499
- "stock",
1500
- "strife",
1501
- "strip",
1502
- "suffocate",
1503
- "suit",
1504
- "tender",
1505
- "tool",
1506
- "trade",
1507
- "velvet",
1508
- "verse",
1509
- "waist",
1510
- "witch",
1511
- "aunt",
1512
- "bench",
1513
- "bold",
1514
- "cap",
1515
- "certainly",
1516
- "click",
1517
- "companion",
1518
- "creator",
1519
- "dart",
1520
- "delicate",
1521
- "determine",
1522
- "dish",
1523
- "dragon",
1524
- "drama",
1525
- "drum",
1526
- "dude",
1527
- "everybody",
1528
- "feast",
1529
- "forehead",
1530
- "former",
1531
- "fright",
1532
- "fully",
1533
- "gas",
1534
- "hook",
1535
- "hurl",
1536
- "invite",
1537
- "juice",
1538
- "manage",
1539
- "moral",
1540
- "possess",
1541
- "raw",
1542
- "rebel",
1543
- "royal",
1544
- "scale",
1545
- "scary",
1546
- "several",
1547
- "slight",
1548
- "stubborn",
1549
- "swell",
1550
- "talent",
1551
- "tea",
1552
- "terrible",
1553
- "thread",
1554
- "torment",
1555
- "trickle",
1556
- "usually",
1557
- "vast",
1558
- "violence",
1559
- "weave",
1560
- "acid",
1561
- "agony",
1562
- "ashamed",
1563
- "awe",
1564
- "belly",
1565
- "blend",
1566
- "blush",
1567
- "character",
1568
- "cheat",
1569
- "common",
1570
- "company",
1571
- "coward",
1572
- "creak",
1573
- "danger",
1574
- "deadly",
1575
- "defense",
1576
- "define",
1577
- "depend",
1578
- "desperate",
1579
- "destination",
1580
- "dew",
1581
- "duck",
1582
- "dusty",
1583
- "embarrass",
1584
- "engine",
1585
- "example",
1586
- "explore",
1587
- "foe",
1588
- "freely",
1589
- "frustrate",
1590
- "generation",
1591
- "glove",
1592
- "guilty",
1593
- "health",
1594
- "hurry",
1595
- "idiot",
1596
- "impossible",
1597
- "inhale",
1598
- "jaw",
1599
- "kingdom",
1600
- "mention",
1601
- "mist",
1602
- "moan",
1603
- "mumble",
1604
- "mutter",
1605
- "observe",
1606
- "ode",
1607
- "pathetic",
1608
- "pattern",
1609
- "pie",
1610
- "prefer",
1611
- "puff",
1612
- "rape",
1613
- "rare",
1614
- "revenge",
1615
- "rude",
1616
- "scrape",
1617
- "spiral",
1618
- "squeeze",
1619
- "strain",
1620
- "sunset",
1621
- "suspend",
1622
- "sympathy",
1623
- "thigh",
1624
- "throne",
1625
- "total",
1626
- "unseen",
1627
- "weapon",
1628
- "weary"
3
+ "like",
4
+ "just",
5
+ "love",
6
+ "know",
7
+ "never",
8
+ "want",
9
+ "time",
10
+ "out",
11
+ "there",
12
+ "make",
13
+ "look",
14
+ "eye",
15
+ "down",
16
+ "only",
17
+ "think",
18
+ "heart",
19
+ "back",
20
+ "then",
21
+ "into",
22
+ "about",
23
+ "more",
24
+ "away",
25
+ "still",
26
+ "them",
27
+ "take",
28
+ "thing",
29
+ "even",
30
+ "through",
31
+ "long",
32
+ "always",
33
+ "world",
34
+ "too",
35
+ "friend",
36
+ "tell",
37
+ "try",
38
+ "hand",
39
+ "thought",
40
+ "over",
41
+ "here",
42
+ "other",
43
+ "need",
44
+ "smile",
45
+ "again",
46
+ "much",
47
+ "cry",
48
+ "been",
49
+ "night",
50
+ "ever",
51
+ "little",
52
+ "said",
53
+ "end",
54
+ "some",
55
+ "those",
56
+ "around",
57
+ "mind",
58
+ "people",
59
+ "girl",
60
+ "leave",
61
+ "dream",
62
+ "left",
63
+ "turn",
64
+ "myself",
65
+ "give",
66
+ "nothing",
67
+ "really",
68
+ "off",
69
+ "before",
70
+ "something",
71
+ "find",
72
+ "walk",
73
+ "wish",
74
+ "good",
75
+ "once",
76
+ "place",
77
+ "ask",
78
+ "stop",
79
+ "keep",
80
+ "watch",
81
+ "seem",
82
+ "everything",
83
+ "wait",
84
+ "got",
85
+ "yet",
86
+ "made",
87
+ "remember",
88
+ "start",
89
+ "alone",
90
+ "run",
91
+ "hope",
92
+ "maybe",
93
+ "believe",
94
+ "body",
95
+ "hate",
96
+ "after",
97
+ "close",
98
+ "talk",
99
+ "stand",
100
+ "own",
101
+ "each",
102
+ "hurt",
103
+ "help",
104
+ "home",
105
+ "god",
106
+ "soul",
107
+ "new",
108
+ "many",
109
+ "two",
110
+ "inside",
111
+ "should",
112
+ "true",
113
+ "first",
114
+ "fear",
115
+ "mean",
116
+ "better",
117
+ "play",
118
+ "another",
119
+ "gone",
120
+ "change",
121
+ "use",
122
+ "wonder",
123
+ "someone",
124
+ "hair",
125
+ "cold",
126
+ "open",
127
+ "best",
128
+ "any",
129
+ "behind",
130
+ "happen",
131
+ "water",
132
+ "dark",
133
+ "laugh",
134
+ "stay",
135
+ "forever",
136
+ "name",
137
+ "work",
138
+ "show",
139
+ "sky",
140
+ "break",
141
+ "came",
142
+ "deep",
143
+ "door",
144
+ "put",
145
+ "black",
146
+ "together",
147
+ "upon",
148
+ "happy",
149
+ "such",
150
+ "great",
151
+ "white",
152
+ "matter",
153
+ "fill",
154
+ "past",
155
+ "please",
156
+ "burn",
157
+ "cause",
158
+ "enough",
159
+ "touch",
160
+ "moment",
161
+ "soon",
162
+ "voice",
163
+ "scream",
164
+ "anything",
165
+ "stare",
166
+ "sound",
167
+ "red",
168
+ "everyone",
169
+ "hide",
170
+ "kiss",
171
+ "truth",
172
+ "death",
173
+ "beautiful",
174
+ "mine",
175
+ "blood",
176
+ "broken",
177
+ "very",
178
+ "pass",
179
+ "next",
180
+ "forget",
181
+ "tree",
182
+ "wrong",
183
+ "air",
184
+ "mother",
185
+ "understand",
186
+ "lip",
187
+ "hit",
188
+ "wall",
189
+ "memory",
190
+ "sleep",
191
+ "free",
192
+ "high",
193
+ "realize",
194
+ "school",
195
+ "might",
196
+ "skin",
197
+ "sweet",
198
+ "perfect",
199
+ "blue",
200
+ "kill",
201
+ "breath",
202
+ "dance",
203
+ "against",
204
+ "fly",
205
+ "between",
206
+ "grow",
207
+ "strong",
208
+ "under",
209
+ "listen",
210
+ "bring",
211
+ "sometimes",
212
+ "speak",
213
+ "pull",
214
+ "person",
215
+ "become",
216
+ "family",
217
+ "begin",
218
+ "ground",
219
+ "real",
220
+ "small",
221
+ "father",
222
+ "sure",
223
+ "feet",
224
+ "rest",
225
+ "young",
226
+ "finally",
227
+ "land",
228
+ "across",
229
+ "today",
230
+ "different",
231
+ "guy",
232
+ "line",
233
+ "fire",
234
+ "reason",
235
+ "reach",
236
+ "second",
237
+ "slowly",
238
+ "write",
239
+ "eat",
240
+ "smell",
241
+ "mouth",
242
+ "step",
243
+ "learn",
244
+ "three",
245
+ "floor",
246
+ "promise",
247
+ "breathe",
248
+ "darkness",
249
+ "push",
250
+ "earth",
251
+ "guess",
252
+ "save",
253
+ "song",
254
+ "above",
255
+ "along",
256
+ "both",
257
+ "color",
258
+ "house",
259
+ "almost",
260
+ "sorry",
261
+ "anymore",
262
+ "brother",
263
+ "okay",
264
+ "dear",
265
+ "game",
266
+ "fade",
267
+ "already",
268
+ "apart",
269
+ "warm",
270
+ "beauty",
271
+ "heard",
272
+ "notice",
273
+ "question",
274
+ "shine",
275
+ "began",
276
+ "piece",
277
+ "whole",
278
+ "shadow",
279
+ "secret",
280
+ "street",
281
+ "within",
282
+ "finger",
283
+ "point",
284
+ "morning",
285
+ "whisper",
286
+ "child",
287
+ "moon",
288
+ "green",
289
+ "story",
290
+ "glass",
291
+ "kid",
292
+ "silence",
293
+ "since",
294
+ "soft",
295
+ "yourself",
296
+ "empty",
297
+ "shall",
298
+ "angel",
299
+ "answer",
300
+ "baby",
301
+ "bright",
302
+ "dad",
303
+ "path",
304
+ "worry",
305
+ "hour",
306
+ "drop",
307
+ "follow",
308
+ "power",
309
+ "war",
310
+ "half",
311
+ "flow",
312
+ "heaven",
313
+ "act",
314
+ "chance",
315
+ "fact",
316
+ "least",
317
+ "tired",
318
+ "children",
319
+ "near",
320
+ "quite",
321
+ "afraid",
322
+ "rise",
323
+ "sea",
324
+ "taste",
325
+ "window",
326
+ "cover",
327
+ "nice",
328
+ "trust",
329
+ "lot",
330
+ "sad",
331
+ "cool",
332
+ "force",
333
+ "peace",
334
+ "return",
335
+ "blind",
336
+ "easy",
337
+ "ready",
338
+ "roll",
339
+ "rose",
340
+ "drive",
341
+ "held",
342
+ "music",
343
+ "beneath",
344
+ "hang",
345
+ "mom",
346
+ "paint",
347
+ "emotion",
348
+ "quiet",
349
+ "clear",
350
+ "cloud",
351
+ "few",
352
+ "pretty",
353
+ "bird",
354
+ "outside",
355
+ "paper",
356
+ "picture",
357
+ "front",
358
+ "rock",
359
+ "simple",
360
+ "anyone",
361
+ "meant",
362
+ "reality",
363
+ "road",
364
+ "sense",
365
+ "waste",
366
+ "bit",
367
+ "leaf",
368
+ "thank",
369
+ "happiness",
370
+ "meet",
371
+ "men",
372
+ "smoke",
373
+ "truly",
374
+ "decide",
375
+ "self",
376
+ "age",
377
+ "book",
378
+ "form",
379
+ "alive",
380
+ "carry",
381
+ "escape",
382
+ "damn",
383
+ "instead",
384
+ "able",
385
+ "ice",
386
+ "minute",
387
+ "throw",
388
+ "catch",
389
+ "leg",
390
+ "ring",
391
+ "course",
392
+ "goodbye",
393
+ "lead",
394
+ "poem",
395
+ "sick",
396
+ "corner",
397
+ "desire",
398
+ "known",
399
+ "problem",
400
+ "remind",
401
+ "shoulder",
402
+ "suppose",
403
+ "toward",
404
+ "wave",
405
+ "drink",
406
+ "jump",
407
+ "woman",
408
+ "pretend",
409
+ "sister",
410
+ "week",
411
+ "human",
412
+ "joy",
413
+ "crack",
414
+ "grey",
415
+ "pray",
416
+ "surprise",
417
+ "dry",
418
+ "knee",
419
+ "less",
420
+ "search",
421
+ "bleed",
422
+ "caught",
423
+ "clean",
424
+ "embrace",
425
+ "future",
426
+ "king",
427
+ "son",
428
+ "sorrow",
429
+ "chest",
430
+ "hug",
431
+ "remain",
432
+ "sat",
433
+ "worth",
434
+ "blow",
435
+ "daddy",
436
+ "final",
437
+ "parent",
438
+ "tight",
439
+ "also",
440
+ "create",
441
+ "lonely",
442
+ "safe",
443
+ "cross",
444
+ "dress",
445
+ "evil",
446
+ "silent",
447
+ "bone",
448
+ "fate",
449
+ "perhaps",
450
+ "anger",
451
+ "class",
452
+ "scar",
453
+ "snow",
454
+ "tiny",
455
+ "tonight",
456
+ "continue",
457
+ "control",
458
+ "dog",
459
+ "edge",
460
+ "mirror",
461
+ "month",
462
+ "suddenly",
463
+ "comfort",
464
+ "given",
465
+ "loud",
466
+ "quickly",
467
+ "gaze",
468
+ "plan",
469
+ "rush",
470
+ "stone",
471
+ "town",
472
+ "battle",
473
+ "ignore",
474
+ "spirit",
475
+ "stood",
476
+ "stupid",
477
+ "yours",
478
+ "brown",
479
+ "build",
480
+ "dust",
481
+ "hey",
482
+ "kept",
483
+ "pay",
484
+ "phone",
485
+ "twist",
486
+ "although",
487
+ "ball",
488
+ "beyond",
489
+ "hidden",
490
+ "nose",
491
+ "taken",
492
+ "fail",
493
+ "float",
494
+ "pure",
495
+ "somehow",
496
+ "wash",
497
+ "wrap",
498
+ "angry",
499
+ "cheek",
500
+ "creature",
501
+ "forgotten",
502
+ "heat",
503
+ "rip",
504
+ "single",
505
+ "space",
506
+ "special",
507
+ "weak",
508
+ "whatever",
509
+ "yell",
510
+ "anyway",
511
+ "blame",
512
+ "job",
513
+ "choose",
514
+ "country",
515
+ "curse",
516
+ "drift",
517
+ "echo",
518
+ "figure",
519
+ "grew",
520
+ "laughter",
521
+ "neck",
522
+ "suffer",
523
+ "worse",
524
+ "yeah",
525
+ "disappear",
526
+ "foot",
527
+ "forward",
528
+ "knife",
529
+ "mess",
530
+ "somewhere",
531
+ "stomach",
532
+ "storm",
533
+ "beg",
534
+ "idea",
535
+ "lift",
536
+ "offer",
537
+ "breeze",
538
+ "field",
539
+ "five",
540
+ "often",
541
+ "simply",
542
+ "stuck",
543
+ "win",
544
+ "allow",
545
+ "confuse",
546
+ "enjoy",
547
+ "except",
548
+ "flower",
549
+ "seek",
550
+ "strength",
551
+ "calm",
552
+ "grin",
553
+ "gun",
554
+ "heavy",
555
+ "hill",
556
+ "large",
557
+ "ocean",
558
+ "shoe",
559
+ "sigh",
560
+ "straight",
561
+ "summer",
562
+ "tongue",
563
+ "accept",
564
+ "crazy",
565
+ "everyday",
566
+ "exist",
567
+ "grass",
568
+ "mistake",
569
+ "sent",
570
+ "shut",
571
+ "surround",
572
+ "table",
573
+ "ache",
574
+ "brain",
575
+ "destroy",
576
+ "heal",
577
+ "nature",
578
+ "shout",
579
+ "sign",
580
+ "stain",
581
+ "choice",
582
+ "doubt",
583
+ "glance",
584
+ "glow",
585
+ "mountain",
586
+ "queen",
587
+ "stranger",
588
+ "throat",
589
+ "tomorrow",
590
+ "city",
591
+ "either",
592
+ "fish",
593
+ "flame",
594
+ "rather",
595
+ "shape",
596
+ "spin",
597
+ "spread",
598
+ "ash",
599
+ "distance",
600
+ "finish",
601
+ "image",
602
+ "imagine",
603
+ "important",
604
+ "nobody",
605
+ "shatter",
606
+ "warmth",
607
+ "became",
608
+ "feed",
609
+ "flesh",
610
+ "funny",
611
+ "lust",
612
+ "shirt",
613
+ "trouble",
614
+ "yellow",
615
+ "attention",
616
+ "bare",
617
+ "bite",
618
+ "money",
619
+ "protect",
620
+ "amaze",
621
+ "appear",
622
+ "born",
623
+ "choke",
624
+ "completely",
625
+ "daughter",
626
+ "fresh",
627
+ "friendship",
628
+ "gentle",
629
+ "probably",
630
+ "six",
631
+ "deserve",
632
+ "expect",
633
+ "grab",
634
+ "middle",
635
+ "nightmare",
636
+ "river",
637
+ "thousand",
638
+ "weight",
639
+ "worst",
640
+ "wound",
641
+ "barely",
642
+ "bottle",
643
+ "cream",
644
+ "regret",
645
+ "relationship",
646
+ "stick",
647
+ "test",
648
+ "crush",
649
+ "endless",
650
+ "fault",
651
+ "itself",
652
+ "rule",
653
+ "spill",
654
+ "art",
655
+ "circle",
656
+ "join",
657
+ "kick",
658
+ "mask",
659
+ "master",
660
+ "passion",
661
+ "quick",
662
+ "raise",
663
+ "smooth",
664
+ "unless",
665
+ "wander",
666
+ "actually",
667
+ "broke",
668
+ "chair",
669
+ "deal",
670
+ "favorite",
671
+ "gift",
672
+ "note",
673
+ "number",
674
+ "sweat",
675
+ "box",
676
+ "chill",
677
+ "clothes",
678
+ "lady",
679
+ "mark",
680
+ "park",
681
+ "poor",
682
+ "sadness",
683
+ "tie",
684
+ "animal",
685
+ "belong",
686
+ "brush",
687
+ "consume",
688
+ "dawn",
689
+ "forest",
690
+ "innocent",
691
+ "pen",
692
+ "pride",
693
+ "stream",
694
+ "thick",
695
+ "clay",
696
+ "complete",
697
+ "count",
698
+ "draw",
699
+ "faith",
700
+ "press",
701
+ "silver",
702
+ "struggle",
703
+ "surface",
704
+ "taught",
705
+ "teach",
706
+ "wet",
707
+ "bless",
708
+ "chase",
709
+ "climb",
710
+ "enter",
711
+ "letter",
712
+ "melt",
713
+ "metal",
714
+ "movie",
715
+ "stretch",
716
+ "swing",
717
+ "vision",
718
+ "wife",
719
+ "beside",
720
+ "crash",
721
+ "forgot",
722
+ "guide",
723
+ "haunt",
724
+ "joke",
725
+ "knock",
726
+ "plant",
727
+ "pour",
728
+ "prove",
729
+ "reveal",
730
+ "steal",
731
+ "stuff",
732
+ "trip",
733
+ "wood",
734
+ "wrist",
735
+ "bother",
736
+ "bottom",
737
+ "crawl",
738
+ "crowd",
739
+ "fix",
740
+ "forgive",
741
+ "frown",
742
+ "grace",
743
+ "loose",
744
+ "lucky",
745
+ "party",
746
+ "release",
747
+ "surely",
748
+ "survive",
749
+ "teacher",
750
+ "gently",
751
+ "grip",
752
+ "speed",
753
+ "suicide",
754
+ "travel",
755
+ "treat",
756
+ "vein",
757
+ "written",
758
+ "cage",
759
+ "chain",
760
+ "conversation",
761
+ "date",
762
+ "enemy",
763
+ "however",
764
+ "interest",
765
+ "million",
766
+ "page",
767
+ "pink",
768
+ "proud",
769
+ "sway",
770
+ "themselves",
771
+ "winter",
772
+ "church",
773
+ "cruel",
774
+ "cup",
775
+ "demon",
776
+ "experience",
777
+ "freedom",
778
+ "pair",
779
+ "pop",
780
+ "purpose",
781
+ "respect",
782
+ "shoot",
783
+ "softly",
784
+ "state",
785
+ "strange",
786
+ "bar",
787
+ "birth",
788
+ "curl",
789
+ "dirt",
790
+ "excuse",
791
+ "lord",
792
+ "lovely",
793
+ "monster",
794
+ "order",
795
+ "pack",
796
+ "pants",
797
+ "pool",
798
+ "scene",
799
+ "seven",
800
+ "shame",
801
+ "slide",
802
+ "ugly",
803
+ "among",
804
+ "blade",
805
+ "blonde",
806
+ "closet",
807
+ "creek",
808
+ "deny",
809
+ "drug",
810
+ "eternity",
811
+ "gain",
812
+ "grade",
813
+ "handle",
814
+ "key",
815
+ "linger",
816
+ "pale",
817
+ "prepare",
818
+ "swallow",
819
+ "swim",
820
+ "tremble",
821
+ "wheel",
822
+ "won",
823
+ "cast",
824
+ "cigarette",
825
+ "claim",
826
+ "college",
827
+ "direction",
828
+ "dirty",
829
+ "gather",
830
+ "ghost",
831
+ "hundred",
832
+ "loss",
833
+ "lung",
834
+ "orange",
835
+ "present",
836
+ "swear",
837
+ "swirl",
838
+ "twice",
839
+ "wild",
840
+ "bitter",
841
+ "blanket",
842
+ "doctor",
843
+ "everywhere",
844
+ "flash",
845
+ "grown",
846
+ "knowledge",
847
+ "numb",
848
+ "pressure",
849
+ "radio",
850
+ "repeat",
851
+ "ruin",
852
+ "spend",
853
+ "unknown",
854
+ "buy",
855
+ "clock",
856
+ "devil",
857
+ "early",
858
+ "false",
859
+ "fantasy",
860
+ "pound",
861
+ "precious",
862
+ "refuse",
863
+ "sheet",
864
+ "teeth",
865
+ "welcome",
866
+ "add",
867
+ "ahead",
868
+ "block",
869
+ "bury",
870
+ "caress",
871
+ "content",
872
+ "depth",
873
+ "despite",
874
+ "distant",
875
+ "marry",
876
+ "purple",
877
+ "threw",
878
+ "whenever",
879
+ "bomb",
880
+ "dull",
881
+ "easily",
882
+ "grasp",
883
+ "hospital",
884
+ "innocence",
885
+ "normal",
886
+ "receive",
887
+ "reply",
888
+ "rhyme",
889
+ "shade",
890
+ "someday",
891
+ "sword",
892
+ "toe",
893
+ "visit",
894
+ "asleep",
895
+ "bought",
896
+ "center",
897
+ "consider",
898
+ "flat",
899
+ "hero",
900
+ "history",
901
+ "ink",
902
+ "insane",
903
+ "muscle",
904
+ "mystery",
905
+ "pocket",
906
+ "reflection",
907
+ "shove",
908
+ "silently",
909
+ "smart",
910
+ "soldier",
911
+ "spot",
912
+ "stress",
913
+ "train",
914
+ "type",
915
+ "view",
916
+ "whether",
917
+ "bus",
918
+ "energy",
919
+ "explain",
920
+ "holy",
921
+ "hunger",
922
+ "inch",
923
+ "magic",
924
+ "mix",
925
+ "noise",
926
+ "nowhere",
927
+ "prayer",
928
+ "presence",
929
+ "shock",
930
+ "snap",
931
+ "spider",
932
+ "study",
933
+ "thunder",
934
+ "trail",
935
+ "admit",
936
+ "agree",
937
+ "bag",
938
+ "bang",
939
+ "bound",
940
+ "butterfly",
941
+ "cute",
942
+ "exactly",
943
+ "explode",
944
+ "familiar",
945
+ "fold",
946
+ "further",
947
+ "pierce",
948
+ "reflect",
949
+ "scent",
950
+ "selfish",
951
+ "sharp",
952
+ "sink",
953
+ "spring",
954
+ "stumble",
955
+ "universe",
956
+ "weep",
957
+ "women",
958
+ "wonderful",
959
+ "action",
960
+ "ancient",
961
+ "attempt",
962
+ "avoid",
963
+ "birthday",
964
+ "branch",
965
+ "chocolate",
966
+ "core",
967
+ "depress",
968
+ "drunk",
969
+ "especially",
970
+ "focus",
971
+ "fruit",
972
+ "honest",
973
+ "match",
974
+ "palm",
975
+ "perfectly",
976
+ "pillow",
977
+ "pity",
978
+ "poison",
979
+ "roar",
980
+ "shift",
981
+ "slightly",
982
+ "thump",
983
+ "truck",
984
+ "tune",
985
+ "twenty",
986
+ "unable",
987
+ "wipe",
988
+ "wrote",
989
+ "coat",
990
+ "constant",
991
+ "dinner",
992
+ "drove",
993
+ "egg",
994
+ "eternal",
995
+ "flight",
996
+ "flood",
997
+ "frame",
998
+ "freak",
999
+ "gasp",
1000
+ "glad",
1001
+ "hollow",
1002
+ "motion",
1003
+ "peer",
1004
+ "plastic",
1005
+ "root",
1006
+ "screen",
1007
+ "season",
1008
+ "sting",
1009
+ "strike",
1010
+ "team",
1011
+ "unlike",
1012
+ "victim",
1013
+ "volume",
1014
+ "warn",
1015
+ "weird",
1016
+ "attack",
1017
+ "await",
1018
+ "awake",
1019
+ "built",
1020
+ "charm",
1021
+ "crave",
1022
+ "despair",
1023
+ "fought",
1024
+ "grant",
1025
+ "grief",
1026
+ "horse",
1027
+ "limit",
1028
+ "message",
1029
+ "ripple",
1030
+ "sanity",
1031
+ "scatter",
1032
+ "serve",
1033
+ "split",
1034
+ "string",
1035
+ "trick",
1036
+ "annoy",
1037
+ "blur",
1038
+ "boat",
1039
+ "brave",
1040
+ "clearly",
1041
+ "cling",
1042
+ "connect",
1043
+ "fist",
1044
+ "forth",
1045
+ "imagination",
1046
+ "iron",
1047
+ "jock",
1048
+ "judge",
1049
+ "lesson",
1050
+ "milk",
1051
+ "misery",
1052
+ "nail",
1053
+ "naked",
1054
+ "ourselves",
1055
+ "poet",
1056
+ "possible",
1057
+ "princess",
1058
+ "sail",
1059
+ "size",
1060
+ "snake",
1061
+ "society",
1062
+ "stroke",
1063
+ "torture",
1064
+ "toss",
1065
+ "trace",
1066
+ "wise",
1067
+ "bloom",
1068
+ "bullet",
1069
+ "cell",
1070
+ "check",
1071
+ "cost",
1072
+ "darling",
1073
+ "during",
1074
+ "footstep",
1075
+ "fragile",
1076
+ "hallway",
1077
+ "hardly",
1078
+ "horizon",
1079
+ "invisible",
1080
+ "journey",
1081
+ "midnight",
1082
+ "mud",
1083
+ "nod",
1084
+ "pause",
1085
+ "relax",
1086
+ "shiver",
1087
+ "sudden",
1088
+ "value",
1089
+ "youth",
1090
+ "abuse",
1091
+ "admire",
1092
+ "blink",
1093
+ "breast",
1094
+ "bruise",
1095
+ "constantly",
1096
+ "couple",
1097
+ "creep",
1098
+ "curve",
1099
+ "difference",
1100
+ "dumb",
1101
+ "emptiness",
1102
+ "gotta",
1103
+ "honor",
1104
+ "plain",
1105
+ "planet",
1106
+ "recall",
1107
+ "rub",
1108
+ "ship",
1109
+ "slam",
1110
+ "soar",
1111
+ "somebody",
1112
+ "tightly",
1113
+ "weather",
1114
+ "adore",
1115
+ "approach",
1116
+ "bond",
1117
+ "bread",
1118
+ "burst",
1119
+ "candle",
1120
+ "coffee",
1121
+ "cousin",
1122
+ "crime",
1123
+ "desert",
1124
+ "flutter",
1125
+ "frozen",
1126
+ "grand",
1127
+ "heel",
1128
+ "hello",
1129
+ "language",
1130
+ "level",
1131
+ "movement",
1132
+ "pleasure",
1133
+ "powerful",
1134
+ "random",
1135
+ "rhythm",
1136
+ "settle",
1137
+ "silly",
1138
+ "slap",
1139
+ "sort",
1140
+ "spoken",
1141
+ "steel",
1142
+ "threaten",
1143
+ "tumble",
1144
+ "upset",
1145
+ "aside",
1146
+ "awkward",
1147
+ "bee",
1148
+ "blank",
1149
+ "board",
1150
+ "button",
1151
+ "card",
1152
+ "carefully",
1153
+ "complain",
1154
+ "crap",
1155
+ "deeply",
1156
+ "discover",
1157
+ "drag",
1158
+ "dread",
1159
+ "effort",
1160
+ "entire",
1161
+ "fairy",
1162
+ "giant",
1163
+ "gotten",
1164
+ "greet",
1165
+ "illusion",
1166
+ "jeans",
1167
+ "leap",
1168
+ "liquid",
1169
+ "march",
1170
+ "mend",
1171
+ "nervous",
1172
+ "nine",
1173
+ "replace",
1174
+ "rope",
1175
+ "spine",
1176
+ "stole",
1177
+ "terror",
1178
+ "accident",
1179
+ "apple",
1180
+ "balance",
1181
+ "boom",
1182
+ "childhood",
1183
+ "collect",
1184
+ "demand",
1185
+ "depression",
1186
+ "eventually",
1187
+ "faint",
1188
+ "glare",
1189
+ "goal",
1190
+ "group",
1191
+ "honey",
1192
+ "kitchen",
1193
+ "laid",
1194
+ "limb",
1195
+ "machine",
1196
+ "mere",
1197
+ "mold",
1198
+ "murder",
1199
+ "nerve",
1200
+ "painful",
1201
+ "poetry",
1202
+ "prince",
1203
+ "rabbit",
1204
+ "shelter",
1205
+ "shore",
1206
+ "shower",
1207
+ "soothe",
1208
+ "stair",
1209
+ "steady",
1210
+ "sunlight",
1211
+ "tangle",
1212
+ "tease",
1213
+ "treasure",
1214
+ "uncle",
1215
+ "begun",
1216
+ "bliss",
1217
+ "canvas",
1218
+ "cheer",
1219
+ "claw",
1220
+ "clutch",
1221
+ "commit",
1222
+ "crimson",
1223
+ "crystal",
1224
+ "delight",
1225
+ "doll",
1226
+ "existence",
1227
+ "express",
1228
+ "fog",
1229
+ "football",
1230
+ "gay",
1231
+ "goose",
1232
+ "guard",
1233
+ "hatred",
1234
+ "illuminate",
1235
+ "mass",
1236
+ "math",
1237
+ "mourn",
1238
+ "rich",
1239
+ "rough",
1240
+ "skip",
1241
+ "stir",
1242
+ "student",
1243
+ "style",
1244
+ "support",
1245
+ "thorn",
1246
+ "tough",
1247
+ "yard",
1248
+ "yearn",
1249
+ "yesterday",
1250
+ "advice",
1251
+ "appreciate",
1252
+ "autumn",
1253
+ "bank",
1254
+ "beam",
1255
+ "bowl",
1256
+ "capture",
1257
+ "carve",
1258
+ "collapse",
1259
+ "confusion",
1260
+ "creation",
1261
+ "dove",
1262
+ "feather",
1263
+ "girlfriend",
1264
+ "glory",
1265
+ "government",
1266
+ "harsh",
1267
+ "hop",
1268
+ "inner",
1269
+ "loser",
1270
+ "moonlight",
1271
+ "neighbor",
1272
+ "neither",
1273
+ "peach",
1274
+ "pig",
1275
+ "praise",
1276
+ "screw",
1277
+ "shield",
1278
+ "shimmer",
1279
+ "sneak",
1280
+ "stab",
1281
+ "subject",
1282
+ "throughout",
1283
+ "thrown",
1284
+ "tower",
1285
+ "twirl",
1286
+ "wow",
1287
+ "army",
1288
+ "arrive",
1289
+ "bathroom",
1290
+ "bump",
1291
+ "cease",
1292
+ "cookie",
1293
+ "couch",
1294
+ "courage",
1295
+ "dim",
1296
+ "guilt",
1297
+ "howl",
1298
+ "hum",
1299
+ "husband",
1300
+ "insult",
1301
+ "led",
1302
+ "lunch",
1303
+ "mock",
1304
+ "mostly",
1305
+ "natural",
1306
+ "nearly",
1307
+ "needle",
1308
+ "nerd",
1309
+ "peaceful",
1310
+ "perfection",
1311
+ "pile",
1312
+ "price",
1313
+ "remove",
1314
+ "roam",
1315
+ "sanctuary",
1316
+ "serious",
1317
+ "shiny",
1318
+ "shook",
1319
+ "sob",
1320
+ "stolen",
1321
+ "tap",
1322
+ "vain",
1323
+ "void",
1324
+ "warrior",
1325
+ "wrinkle",
1326
+ "affection",
1327
+ "apologize",
1328
+ "blossom",
1329
+ "bounce",
1330
+ "bridge",
1331
+ "cheap",
1332
+ "crumble",
1333
+ "decision",
1334
+ "descend",
1335
+ "desperately",
1336
+ "dig",
1337
+ "dot",
1338
+ "flip",
1339
+ "frighten",
1340
+ "heartbeat",
1341
+ "huge",
1342
+ "lazy",
1343
+ "lick",
1344
+ "odd",
1345
+ "opinion",
1346
+ "process",
1347
+ "puzzle",
1348
+ "quietly",
1349
+ "retreat",
1350
+ "score",
1351
+ "sentence",
1352
+ "separate",
1353
+ "situation",
1354
+ "skill",
1355
+ "soak",
1356
+ "square",
1357
+ "stray",
1358
+ "taint",
1359
+ "task",
1360
+ "tide",
1361
+ "underneath",
1362
+ "veil",
1363
+ "whistle",
1364
+ "anywhere",
1365
+ "bedroom",
1366
+ "bid",
1367
+ "bloody",
1368
+ "burden",
1369
+ "careful",
1370
+ "compare",
1371
+ "concern",
1372
+ "curtain",
1373
+ "decay",
1374
+ "defeat",
1375
+ "describe",
1376
+ "double",
1377
+ "dreamer",
1378
+ "driver",
1379
+ "dwell",
1380
+ "evening",
1381
+ "flare",
1382
+ "flicker",
1383
+ "grandma",
1384
+ "guitar",
1385
+ "harm",
1386
+ "horrible",
1387
+ "hungry",
1388
+ "indeed",
1389
+ "lace",
1390
+ "melody",
1391
+ "monkey",
1392
+ "nation",
1393
+ "object",
1394
+ "obviously",
1395
+ "rainbow",
1396
+ "salt",
1397
+ "scratch",
1398
+ "shown",
1399
+ "shy",
1400
+ "stage",
1401
+ "stun",
1402
+ "third",
1403
+ "tickle",
1404
+ "useless",
1405
+ "weakness",
1406
+ "worship",
1407
+ "worthless",
1408
+ "afternoon",
1409
+ "beard",
1410
+ "boyfriend",
1411
+ "bubble",
1412
+ "busy",
1413
+ "certain",
1414
+ "chin",
1415
+ "concrete",
1416
+ "desk",
1417
+ "diamond",
1418
+ "doom",
1419
+ "drawn",
1420
+ "due",
1421
+ "felicity",
1422
+ "freeze",
1423
+ "frost",
1424
+ "garden",
1425
+ "glide",
1426
+ "harmony",
1427
+ "hopefully",
1428
+ "hunt",
1429
+ "jealous",
1430
+ "lightning",
1431
+ "mama",
1432
+ "mercy",
1433
+ "peel",
1434
+ "physical",
1435
+ "position",
1436
+ "pulse",
1437
+ "punch",
1438
+ "quit",
1439
+ "rant",
1440
+ "respond",
1441
+ "salty",
1442
+ "sane",
1443
+ "satisfy",
1444
+ "savior",
1445
+ "sheep",
1446
+ "slept",
1447
+ "social",
1448
+ "sport",
1449
+ "tuck",
1450
+ "utter",
1451
+ "valley",
1452
+ "wolf",
1453
+ "aim",
1454
+ "alas",
1455
+ "alter",
1456
+ "arrow",
1457
+ "awaken",
1458
+ "beaten",
1459
+ "belief",
1460
+ "brand",
1461
+ "ceiling",
1462
+ "cheese",
1463
+ "clue",
1464
+ "confidence",
1465
+ "connection",
1466
+ "daily",
1467
+ "disguise",
1468
+ "eager",
1469
+ "erase",
1470
+ "essence",
1471
+ "everytime",
1472
+ "expression",
1473
+ "fan",
1474
+ "flag",
1475
+ "flirt",
1476
+ "foul",
1477
+ "fur",
1478
+ "giggle",
1479
+ "glorious",
1480
+ "ignorance",
1481
+ "law",
1482
+ "lifeless",
1483
+ "measure",
1484
+ "mighty",
1485
+ "muse",
1486
+ "north",
1487
+ "opposite",
1488
+ "paradise",
1489
+ "patience",
1490
+ "patient",
1491
+ "pencil",
1492
+ "petal",
1493
+ "plate",
1494
+ "ponder",
1495
+ "possibly",
1496
+ "practice",
1497
+ "slice",
1498
+ "spell",
1499
+ "stock",
1500
+ "strife",
1501
+ "strip",
1502
+ "suffocate",
1503
+ "suit",
1504
+ "tender",
1505
+ "tool",
1506
+ "trade",
1507
+ "velvet",
1508
+ "verse",
1509
+ "waist",
1510
+ "witch",
1511
+ "aunt",
1512
+ "bench",
1513
+ "bold",
1514
+ "cap",
1515
+ "certainly",
1516
+ "click",
1517
+ "companion",
1518
+ "creator",
1519
+ "dart",
1520
+ "delicate",
1521
+ "determine",
1522
+ "dish",
1523
+ "dragon",
1524
+ "drama",
1525
+ "drum",
1526
+ "dude",
1527
+ "everybody",
1528
+ "feast",
1529
+ "forehead",
1530
+ "former",
1531
+ "fright",
1532
+ "fully",
1533
+ "gas",
1534
+ "hook",
1535
+ "hurl",
1536
+ "invite",
1537
+ "juice",
1538
+ "manage",
1539
+ "moral",
1540
+ "possess",
1541
+ "raw",
1542
+ "rebel",
1543
+ "royal",
1544
+ "scale",
1545
+ "scary",
1546
+ "several",
1547
+ "slight",
1548
+ "stubborn",
1549
+ "swell",
1550
+ "talent",
1551
+ "tea",
1552
+ "terrible",
1553
+ "thread",
1554
+ "torment",
1555
+ "trickle",
1556
+ "usually",
1557
+ "vast",
1558
+ "violence",
1559
+ "weave",
1560
+ "acid",
1561
+ "agony",
1562
+ "ashamed",
1563
+ "awe",
1564
+ "belly",
1565
+ "blend",
1566
+ "blush",
1567
+ "character",
1568
+ "cheat",
1569
+ "common",
1570
+ "company",
1571
+ "coward",
1572
+ "creak",
1573
+ "danger",
1574
+ "deadly",
1575
+ "defense",
1576
+ "define",
1577
+ "depend",
1578
+ "desperate",
1579
+ "destination",
1580
+ "dew",
1581
+ "duck",
1582
+ "dusty",
1583
+ "embarrass",
1584
+ "engine",
1585
+ "example",
1586
+ "explore",
1587
+ "foe",
1588
+ "freely",
1589
+ "frustrate",
1590
+ "generation",
1591
+ "glove",
1592
+ "guilty",
1593
+ "health",
1594
+ "hurry",
1595
+ "idiot",
1596
+ "impossible",
1597
+ "inhale",
1598
+ "jaw",
1599
+ "kingdom",
1600
+ "mention",
1601
+ "mist",
1602
+ "moan",
1603
+ "mumble",
1604
+ "mutter",
1605
+ "observe",
1606
+ "ode",
1607
+ "pathetic",
1608
+ "pattern",
1609
+ "pie",
1610
+ "prefer",
1611
+ "puff",
1612
+ "rape",
1613
+ "rare",
1614
+ "revenge",
1615
+ "rude",
1616
+ "scrape",
1617
+ "spiral",
1618
+ "squeeze",
1619
+ "strain",
1620
+ "sunset",
1621
+ "suspend",
1622
+ "sympathy",
1623
+ "thigh",
1624
+ "throne",
1625
+ "total",
1626
+ "unseen",
1627
+ "weapon",
1628
+ "weary"
1629
];
1630
}
cw_zano/lib/model/pending_zano_transaction.dart
+1
-1
@@ -41,7 +41,7 @@ class PendingZanoTransaction with PendingTransaction {
41
transferResult = await zanoWallet.transfer(destinations, fee.amount, comment);
42
zanoWallet.fetchTransactions();
43
}
44
-
44
+
45
@override
46
Future<Map<String, String>> commitUR() => throw UnimplementedError();
47
}
cw_zano/lib/model/zano_asset.dart
+1
@@ -0,0 +1 @@
1
+
cw_zano/lib/model/zano_transaction_creation_exception.dart
+1
-1
@@ -5,4 +5,4 @@ class ZanoTransactionCreationException implements Exception {
5
6
@override
7
String toString() => message;
8
-}
\ No newline at end of file
8
+}
cw_zano/lib/model/zano_transaction_credentials.dart
+2
-1
@@ -3,7 +3,8 @@ import 'package:cw_core/monero_transaction_priority.dart';
3
import 'package:cw_core/output_info.dart';
4
5
class ZanoTransactionCredentials {
6
- ZanoTransactionCredentials({required this.outputs, required this.priority, required this.currency});
6
+ ZanoTransactionCredentials(
7
+ {required this.outputs, required this.priority, required this.currency});
8
9
final List<OutputInfo> outputs;
10
final MoneroTransactionPriority priority;
cw_zano/lib/model/zano_transaction_info.dart
+7
-8
@@ -24,11 +24,11 @@ class ZanoTransactionInfo extends TransactionInfo {
24
25
ZanoTransactionInfo.fromTransfer(Transfer transfer,
26
{required int confirmations,
27
- required bool isIncome,
28
- required String assetId,
29
- required Money amount,
30
- this.tokenSymbol = 'ZANO',
31
- this.decimalPoint = ZanoFormatter.defaultDecimalPoint})
27
+ required bool isIncome,
28
+ required String assetId,
29
+ required Money amount,
30
+ this.tokenSymbol = 'ZANO',
31
+ this.decimalPoint = ZanoFormatter.defaultDecimalPoint})
32
: id = transfer.txHash,
33
height = transfer.height,
34
direction = isIncome ? TransactionDirection.incoming : TransactionDirection.outgoing,
@@ -37,9 +37,8 @@ class ZanoTransactionInfo extends TransactionInfo {
37
fee = Money.fromInt(transfer.fee, CryptoCurrency.zano),
38
confirmations = confirmations,
39
isPending = confirmations < 10,
40
- recipientAddress = transfer.remoteAddresses.isNotEmpty
41
- ? transfer.remoteAddresses.first
42
- : '' {
40
+ recipientAddress =
41
+ transfer.remoteAddresses.isNotEmpty ? transfer.remoteAddresses.first : '' {
42
additionalInfo = <String, dynamic>{
43
'comment': transfer.comment,
44
'assetId': assetId,
cw_zano/lib/model/zano_wallet_keys.dart
+4
-4
@@ -1,12 +1,12 @@
1
class ZanoWalletKeys {
2
const ZanoWalletKeys(
3
{required this.privateSpendKey,
4
- required this.privateViewKey,
5
- required this.publicSpendKey,
6
- required this.publicViewKey});
4
+ required this.privateViewKey,
5
+ required this.publicSpendKey,
6
+ required this.publicViewKey});
7
8
final String publicViewKey;
9
final String privateViewKey;
10
final String publicSpendKey;
11
final String privateSpendKey;
12
-}
\ No newline at end of file
12
+}
cw_zano/lib/zano_formatter.dart
+31
-23
@@ -18,46 +18,54 @@ class ZanoFormatter {
18
}
19
20
static String intAmountToString(int amount, [int decimalPoint = defaultDecimalPoint]) {
21
- final numberFormat = NumberFormat()..maximumFractionDigits = decimalPoint
22
- ..minimumFractionDigits = 1;
23
- return numberFormat.format(
24
- DecimalIntl(
25
- _bigIntDivision(
26
- amount: BigInt.from(amount),
27
- divider: BigInt.from(pow(10, decimalPoint)),
21
+ final numberFormat = NumberFormat()
22
+ ..maximumFractionDigits = decimalPoint
23
+ ..minimumFractionDigits = 1;
24
+ return numberFormat
25
+ .format(
26
+ DecimalIntl(
27
+ _bigIntDivision(
28
+ amount: BigInt.from(amount),
29
+ divider: BigInt.from(pow(10, decimalPoint)),
30
+ ),
31
),
29
- ),
30
- )
31
- .replaceAll(',', '');
32
+ )
33
+ .replaceAll(',', '');
34
}
35
36
static String bigIntAmountToString(BigInt amount, [int decimalPoint = defaultDecimalPoint]) {
37
if (decimalPoint == 0) {
38
return '0';
39
}
38
- final numberFormat = NumberFormat()..maximumFractionDigits = decimalPoint
39
- ..minimumFractionDigits = 1;
40
- return numberFormat.format(
41
- DecimalIntl(
42
- _bigIntDivision(
43
- amount: amount,
44
- divider: BigInt.from(pow(10, decimalPoint)),
40
+ final numberFormat = NumberFormat()
41
+ ..maximumFractionDigits = decimalPoint
42
+ ..minimumFractionDigits = 1;
43
+ return numberFormat
44
+ .format(
45
+ DecimalIntl(
46
+ _bigIntDivision(
47
+ amount: amount,
48
+ divider: BigInt.from(pow(10, decimalPoint)),
49
+ ),
50
),
46
- ),
47
- )
48
- .replaceAll(',', '');
51
+ )
52
+ .replaceAll(',', '');
53
}
54
51
- static double intAmountToDouble(int amount, [int decimalPoint = defaultDecimalPoint]) => _bigIntDivision(
55
+ static double intAmountToDouble(int amount, [int decimalPoint = defaultDecimalPoint]) =>
56
+ _bigIntDivision(
57
amount: BigInt.from(amount),
58
divider: BigInt.from(pow(10, decimalPoint)),
59
).toDouble();
60
61
static int parseAmount(String amount, [int decimalPoint = defaultDecimalPoint]) {
57
- final resultBigInt = (Decimal.parse(amount) * Decimal.fromBigInt(BigInt.from(10).pow(decimalPoint))).toBigInt();
62
+ final resultBigInt =
63
+ (Decimal.parse(amount) * Decimal.fromBigInt(BigInt.from(10).pow(decimalPoint))).toBigInt();
64
if (!resultBigInt.isValidInt) {
65
try {
60
- Fluttertoast.showToast(msg: 'Cannot transfer $amount. Maximum is ${intAmountToString(resultBigInt.toInt(), decimalPoint)}.');
66
+ Fluttertoast.showToast(
67
+ msg:
68
+ 'Cannot transfer $amount. Maximum is ${intAmountToString(resultBigInt.toInt(), decimalPoint)}.');
69
} catch (_) {}
70
}
71
return resultBigInt.toInt();
cw_zano/lib/zano_transaction_history.dart
+4
-6
@@ -5,11 +5,10 @@ import 'package:cw_zano/model/zano_transaction_info.dart';
5
6
part 'zano_transaction_history.g.dart';
7
8
-class ZanoTransactionHistory = ZanoTransactionHistoryBase
9
- with _$ZanoTransactionHistory;
8
+class ZanoTransactionHistory = ZanoTransactionHistoryBase with _$ZanoTransactionHistory;
9
11
-abstract class ZanoTransactionHistoryBase
12
- extends TransactionHistoryBase<ZanoTransactionInfo> with Store {
10
+abstract class ZanoTransactionHistoryBase extends TransactionHistoryBase<ZanoTransactionInfo>
11
+ with Store {
12
ZanoTransactionHistoryBase() {
13
transactions = ObservableMap<String, ZanoTransactionInfo>();
14
}
@@ -18,8 +17,7 @@ abstract class ZanoTransactionHistoryBase
17
Future<void> save() async {}
18
19
@override
21
- void addOne(ZanoTransactionInfo transaction) =>
22
- transactions[transaction.id] = transaction;
20
+ void addOne(ZanoTransactionInfo transaction) => transactions[transaction.id] = transaction;
21
22
@override
23
void addMany(Map<String, ZanoTransactionInfo> transactions) =>
cw_zano/lib/zano_wallet.dart
+12
-7
@@ -129,7 +129,8 @@ abstract class ZanoWalletBase
129
}
130
131
static Future<ZanoWallet> create({required WalletCredentials credentials}) async {
132
- final wallet = ZanoWallet(credentials.walletInfo!, await credentials.walletInfo!.getDerivationInfo(), credentials.password!);
132
+ final wallet = ZanoWallet(credentials.walletInfo!,
133
+ await credentials.walletInfo!.getDerivationInfo(), credentials.password!);
134
await wallet.initWallet();
135
final path = await pathForWallet(name: credentials.name, type: credentials.walletInfo!.type);
136
final createWalletResult = await wallet.createWallet(path, credentials.password!);
@@ -146,7 +147,8 @@ abstract class ZanoWalletBase
147
148
static Future<ZanoWallet> restore(
149
{required ZanoRestoreWalletFromSeedCredentials credentials}) async {
149
- final wallet = ZanoWallet(credentials.walletInfo!, await credentials.walletInfo!.getDerivationInfo(), credentials.password!);
150
+ final wallet = ZanoWallet(credentials.walletInfo!,
151
+ await credentials.walletInfo!.getDerivationInfo(), credentials.password!);
152
await wallet.initWallet();
153
final path = await pathForWallet(name: credentials.name, type: credentials.walletInfo!.type);
154
final createWalletResult = await wallet.restoreWalletFromSeed(
@@ -232,9 +234,12 @@ abstract class ZanoWalletBase
234
final isZano = credentials.currency == CryptoCurrency.zano;
235
final outputs = credentials.outputs;
236
final hasMultiDestination = outputs.length > 1;
235
- final unlockedBalanceZano = balance[CryptoCurrency.zano]?.unlocked ?? Money.zero(CryptoCurrency.zano);
236
- final unlockedBalanceCurrency = balance[credentials.currency]?.unlocked ?? Money.zero(credentials.currency);
237
- final fee = Money(BigInt.from(calculateEstimatedFee(credentials.priority)), CryptoCurrency.zano);
237
+ final unlockedBalanceZano =
238
+ balance[CryptoCurrency.zano]?.unlocked ?? Money.zero(CryptoCurrency.zano);
239
+ final unlockedBalanceCurrency =
240
+ balance[credentials.currency]?.unlocked ?? Money.zero(credentials.currency);
241
+ final fee =
242
+ Money(BigInt.from(calculateEstimatedFee(credentials.priority)), CryptoCurrency.zano);
243
244
var totalAmount = Money.zero(credentials.currency);
245
void checkForEnoughBalances() {
@@ -398,8 +403,8 @@ abstract class ZanoWalletBase
403
syncStatus = AttemptingSyncStatus();
404
_lastKnownBlockHeight = 0;
405
_initialSyncHeight = 0;
401
- _updateSyncInfoTimer ??=
402
- Timer.periodic(Duration(milliseconds: _pollIntervalMilliseconds), (_) => _updateSyncInfo());
406
+ _updateSyncInfoTimer ??= Timer.periodic(
407
+ Duration(milliseconds: _pollIntervalMilliseconds), (_) => _updateSyncInfo());
408
} catch (e) {
409
syncStatus = FailedSyncStatus();
410
printV((e.toString()));
cw_zano/lib/zano_wallet_api.dart
+35
-26
@@ -41,7 +41,8 @@ mixin ZanoWalletApi {
41
_hWallet = value;
42
}
43
44
- int getCurrentTxFee(TransactionPriority priority) => zano.PlainWallet_getCurrentTxFee(priority.raw);
44
+ int getCurrentTxFee(TransactionPriority priority) =>
45
+ zano.PlainWallet_getCurrentTxFee(priority.raw);
46
47
void setPassword(String password) => zano.PlainWallet_resetWalletPassword(hWallet, password);
48
@@ -112,7 +113,7 @@ mixin ZanoWalletApi {
113
Future<void> _setWalletSecret(String key, String value) async {
114
final secrets = await _getSecrets();
115
secrets[key] = value;
115
- await _setSecrets(secrets);
116
+ await _setSecrets(secrets);
117
}
118
119
Future<String?> getPassphrase() async {
@@ -125,7 +126,7 @@ mixin ZanoWalletApi {
126
127
Future<String> getSeed() async {
128
final passphrase = await getPassphrase();
128
- final respStr = await invokeMethod("get_restore_info", {"seed_password": passphrase??""});
129
+ final respStr = await invokeMethod("get_restore_info", {"seed_password": passphrase ?? ""});
130
final resp = convert.json.decode(respStr);
131
return resp["result"]["seed_phrase"] as String;
132
}
@@ -146,7 +147,7 @@ mixin ZanoWalletApi {
147
final status = GetWalletStatusResult.fromJson(jsonDecode(json));
148
if (_logInfo)
149
printV(
149
- 'get_wallet_status connected: ${status.isDaemonConnected} in refresh: ${status.isInLongRefresh} progress: ${status.progress} wallet state: ${status.walletState} sync: ${status.currentWalletHeight}/${status.currentDaemonHeight} ${(status.currentWalletHeight/status.currentDaemonHeight*100).toStringAsFixed(2)}%');
150
+ 'get_wallet_status connected: ${status.isDaemonConnected} in refresh: ${status.isInLongRefresh} progress: ${status.progress} wallet state: ${status.walletState} sync: ${status.currentWalletHeight}/${status.currentDaemonHeight} ${(status.currentWalletHeight / status.currentDaemonHeight * 100).toStringAsFixed(2)}%');
151
return status;
152
}
153
@@ -159,7 +160,8 @@ mixin ZanoWalletApi {
160
try {
161
jsonDecode(invokeResult);
162
} catch (e) {
162
- if (invokeResult.contains(Consts.errorWalletWrongId)) throw ZanoWalletException('Wrong wallet id');
163
+ if (invokeResult.contains(Consts.errorWalletWrongId))
164
+ throw ZanoWalletException('Wrong wallet id');
165
printV('exception in parsing json in invokeMethod: $invokeResult');
166
rethrow;
167
}
@@ -173,14 +175,16 @@ mixin ZanoWalletApi {
175
_checkForErrors(map);
176
List<ZanoAsset> assets(String type, bool isGlobalWhitelist) =>
177
(map?['result']?[type] as List<dynamic>?)
176
- ?.map((e) => ZanoAsset.fromJson(e as Map<String, dynamic>, isInGlobalWhitelist: isGlobalWhitelist))
178
+ ?.map((e) => ZanoAsset.fromJson(e as Map<String, dynamic>,
179
+ isInGlobalWhitelist: isGlobalWhitelist))
180
.toList() ??
181
[];
182
final localWhitelist = assets('local_whitelist', false);
183
final globalWhitelist = assets('global_whitelist', true);
184
final ownAssets = assets('own_assets', false);
185
if (_logInfo)
183
- printV('assets_whitelist_get got local whitelist: ${localWhitelist.length} ($localWhitelist); '
186
+ printV(
187
+ 'assets_whitelist_get got local whitelist: ${localWhitelist.length} ($localWhitelist); '
188
'global whitelist: ${globalWhitelist.length} ($globalWhitelist); '
189
'own assets: ${ownAssets.length} ($ownAssets)');
190
return [...globalWhitelist, ...localWhitelist, ...ownAssets];
@@ -197,7 +201,8 @@ mixin ZanoWalletApi {
201
final map = jsonDecode(json) as Map<String, dynamic>?;
202
_checkForErrors(map);
203
if (map!['result']!['status']! == 'OK') {
200
- final assetDescriptor = ZanoAsset.fromJson(map['result']!['asset_descriptor']! as Map<String, dynamic>);
204
+ final assetDescriptor =
205
+ ZanoAsset.fromJson(map['result']!['asset_descriptor']! as Map<String, dynamic>);
206
printV('assets_whitelist_add added ${assetDescriptor.fullName} ${assetDescriptor.ticker}');
207
return assetDescriptor;
208
} else {
@@ -233,7 +238,8 @@ mixin ZanoWalletApi {
238
Future<ZanoAsset?> getAssetInfo(String assetId) async {
239
final methodName = 'get_asset_info';
240
final params = AssetIdParams(assetId: assetId);
236
- final result = await _proxyToDaemon('/json_rpc', '{"method": "$methodName","params": ${jsonEncode(params)}}');
241
+ final result = await _proxyToDaemon(
242
+ '/json_rpc', '{"method": "$methodName","params": ${jsonEncode(params)}}');
243
if (result == null) {
244
printV('get_asset_info empty result');
245
return null;
@@ -245,8 +251,8 @@ mixin ZanoWalletApi {
251
'get_asset_info $assetId error ${map['error']!['code']} ${map['error']!['message']}');
252
return null;
253
} else if (map['result']!['status']! == 'OK') {
248
- final assetDescriptor = ZanoAsset.fromJson(
249
- map['result']!['asset_descriptor']! as Map<String, dynamic>);
254
+ final assetDescriptor =
255
+ ZanoAsset.fromJson(map['result']!['asset_descriptor']! as Map<String, dynamic>);
256
printV('get_asset_info $assetId ${assetDescriptor.fullName} ${assetDescriptor.ticker}');
257
return assetDescriptor;
258
} else {
@@ -270,10 +276,12 @@ mixin ZanoWalletApi {
276
}
277
}
278
273
- Future<GetRecentTxsAndInfoResult> getRecentTxsAndInfo({required int offset, required int count}) async {
279
+ Future<GetRecentTxsAndInfoResult> getRecentTxsAndInfo(
280
+ {required int offset, required int count}) async {
281
printV('get_recent_txs_and_info $offset $count');
282
try {
276
- final json = await invokeMethod('get_recent_txs_and_info', GetRecentTxsAndInfoParams(offset: offset, count: count));
283
+ final json = await invokeMethod(
284
+ 'get_recent_txs_and_info', GetRecentTxsAndInfoParams(offset: offset, count: count));
285
final map = jsonDecode(json) as Map<String, dynamic>?;
286
_checkForErrors(map);
287
final lastItemIndex = map?['result']?['last_item_index'] as int?;
@@ -299,7 +307,8 @@ mixin ZanoWalletApi {
307
jsonDecode(zano.PlainWallet_getAddressInfo(address)),
308
);
309
302
- String _shorten(String s) => s.length > 10 ? '${s.substring(0, 4)}...${s.substring(s.length - 4)}' : s;
310
+ String _shorten(String s) =>
311
+ s.length > 10 ? '${s.substring(0, 4)}...${s.substring(s.length - 4)}' : s;
312
313
Future<CreateWalletResult> createWallet(String path, String password) async {
314
printV('create_wallet path $path password ${_shorten(password)}');
@@ -319,15 +328,17 @@ mixin ZanoWalletApi {
328
return result;
329
}
330
322
- Future<CreateWalletResult> restoreWalletFromSeed(String path, String password, String seed, String? passphrase) async {
331
+ Future<CreateWalletResult> restoreWalletFromSeed(
332
+ String path, String password, String seed, String? passphrase) async {
333
printV('restore_wallet path $path');
324
- final json = zano.PlainWallet_restore(seed, path, password, passphrase??'');
334
+ final json = zano.PlainWallet_restore(seed, path, password, passphrase ?? '');
335
final map = jsonDecode(json) as Map<String, dynamic>?;
336
if (map?['error'] != null) {
337
final code = map!['error']!['code'] ?? '';
338
final message = map['error']!['message'] ?? '';
339
if (code == Consts.errorWrongSeed) {
330
- throw RestoreFromSeedsException('Error restoring wallet\nPlease check the seed words are correct. Additionally, if you created this wallet with a passphrase please add it under the Advanced Settings page.');
340
+ throw RestoreFromSeedsException(
341
+ 'Error restoring wallet\nPlease check the seed words are correct. Additionally, if you created this wallet with a passphrase please add it under the Advanced Settings page.');
342
} else if (code == Consts.errorAlreadyExists) {
343
throw RestoreFromSeedsException('Error restoring wallet, already exists');
344
}
@@ -348,7 +359,7 @@ mixin ZanoWalletApi {
359
try {
360
json = zano.PlainWallet_open(path, password);
361
} catch (e) {
351
- printV('error in loadingWallet $e');
362
+ printV('error in loadingWallet $e');
363
rethrow;
364
}
365
@@ -376,7 +387,8 @@ mixin ZanoWalletApi {
387
388
static Map<String, CreateWalletResult> openWalletCache = {};
389
379
- Future<TransferResult> transfer(List<Destination> destinations, BigInt fee, String comment) async {
390
+ Future<TransferResult> transfer(
391
+ List<Destination> destinations, BigInt fee, String comment) async {
392
final params = TransferParams(
393
destinations: destinations,
394
fee: fee,
@@ -453,7 +465,6 @@ mixin ZanoWalletApi {
465
throw ZanoWalletException('Error, $message ($code)');
466
}
467
}
456
-
468
}
469
470
Future<String> callSyncMethod(String methodName, int hWallet, String params) async {
@@ -462,10 +473,7 @@ Future<String> callSyncMethod(String methodName, int hWallet, String params) asy
473
final invokeResult = await Isolate.run(() async {
474
final lib = zanoapi.ZanoC(DynamicLibrary.open(zano.libPath));
475
final txid = lib.ZANO_PlainWallet_syncCall(
465
- Pointer.fromAddress(method_name_).cast(),
466
- hWallet,
467
- Pointer.fromAddress(params_).cast()
468
- );
476
+ Pointer.fromAddress(method_name_).cast(), hWallet, Pointer.fromAddress(params_).cast());
477
try {
478
final strPtr = txid.cast<Utf8>();
479
final str = strPtr.toDartString();
@@ -496,7 +504,7 @@ Future<String> _getWalletStatus(int hWallet) async {
504
final jsonPtr = await Isolate.run(() async {
505
final lib = zanoapi.ZanoC(DynamicLibrary.open(zano.libPath));
506
final status = lib.ZANO_PlainWallet_getWalletStatus(
499
- hWallet,
507
+ hWallet,
508
);
509
return status.address;
510
});
@@ -511,11 +519,12 @@ Future<String> _getWalletStatus(int hWallet) async {
519
}
520
return json;
521
}
522
+
523
Future<String> _getWalletInfo(int hWallet) async {
524
final jsonPtr = await Isolate.run(() async {
525
final lib = zanoapi.ZanoC(DynamicLibrary.open(zano.libPath));
526
final status = lib.ZANO_PlainWallet_getWalletInfo(
518
- hWallet,
527
+ hWallet,
528
);
529
return status.address;
530
});
cw_zano/lib/zano_wallet_exceptions.dart
+3
-3
@@ -13,9 +13,9 @@ class RestoreFromSeedsException extends RestoreFromSeedException {
13
}
14
15
class TransferException extends ZanoWalletException {
16
- TransferException(String message): super(message);
16
+ TransferException(String message) : super(message);
17
}
18
19
class ZanoWalletBusyException extends ZanoWalletException {
20
- ZanoWalletBusyException(): super('');
21
-}
\ No newline at end of file
20
+ ZanoWalletBusyException() : super('');
21
+}
cw_zano/lib/zano_wallet_service.dart
+25
-10
@@ -14,11 +14,17 @@ import 'package:hive/hive.dart';
14
import 'package:monero/zano.dart' as zano;
15
16
class ZanoNewWalletCredentials extends WalletCredentials {
17
- ZanoNewWalletCredentials({required String name, String? password, required String? passphrase}) : super(name: name, password: password, passphrase: passphrase);
17
+ ZanoNewWalletCredentials({required String name, String? password, required String? passphrase})
18
+ : super(name: name, password: password, passphrase: passphrase);
19
}
20
21
class ZanoRestoreWalletFromSeedCredentials extends WalletCredentials {
21
- ZanoRestoreWalletFromSeedCredentials({required String name, required String password, required String passphrase, required int height, required this.mnemonic})
22
+ ZanoRestoreWalletFromSeedCredentials(
23
+ {required String name,
24
+ required String password,
25
+ required String passphrase,
26
+ required int height,
27
+ required this.mnemonic})
28
: super(name: name, password: password, passphrase: passphrase, height: height);
29
30
final String mnemonic;
@@ -41,11 +47,15 @@ class ZanoRestoreWalletFromKeysCredentials extends WalletCredentials {
47
final String spendKey;
48
}
49
44
-class ZanoWalletService extends WalletService<ZanoNewWalletCredentials,
45
- ZanoRestoreWalletFromSeedCredentials, ZanoRestoreWalletFromKeysCredentials, ZanoNewWalletCredentials> {
50
+class ZanoWalletService extends WalletService<
51
+ ZanoNewWalletCredentials,
52
+ ZanoRestoreWalletFromSeedCredentials,
53
+ ZanoRestoreWalletFromKeysCredentials,
54
+ ZanoNewWalletCredentials> {
55
ZanoWalletService();
56
48
- static bool walletFilesExist(String path) => !File(path).existsSync() && !File('$path.keys').existsSync();
57
+ static bool walletFilesExist(String path) =>
58
+ !File(path).existsSync() && !File('$path.keys').existsSync();
59
60
int hWallet = 0;
61
@@ -71,7 +81,8 @@ class ZanoWalletService extends WalletService<ZanoNewWalletCredentials,
81
throw Exception('Wallet not found');
82
}
83
try {
74
- final wallet = await ZanoWalletBase.open(name: name, password: password, walletInfo: walletInfo);
84
+ final wallet =
85
+ await ZanoWalletBase.open(name: name, password: password, walletInfo: walletInfo);
86
saveBackup(name);
87
return wallet;
88
} catch (e) {
@@ -103,7 +114,8 @@ class ZanoWalletService extends WalletService<ZanoNewWalletCredentials,
114
if (currentWalletInfo == null) {
115
throw Exception('Wallet not found');
116
}
106
- final currentWallet = ZanoWallet(currentWalletInfo, await currentWalletInfo.getDerivationInfo(), password);
117
+ final currentWallet =
118
+ ZanoWallet(currentWalletInfo, await currentWalletInfo.getDerivationInfo(), password);
119
120
await currentWallet.renameWalletFiles(newName);
121
@@ -115,17 +127,20 @@ class ZanoWalletService extends WalletService<ZanoNewWalletCredentials,
127
}
128
129
@override
118
- Future<ZanoWallet> restoreFromKeys(ZanoRestoreWalletFromKeysCredentials credentials, {bool? isTestnet}) async {
130
+ Future<ZanoWallet> restoreFromKeys(ZanoRestoreWalletFromKeysCredentials credentials,
131
+ {bool? isTestnet}) async {
132
throw UnimplementedError();
133
}
134
135
@override
123
- Future<ZanoWallet> restoreFromSeed(ZanoRestoreWalletFromSeedCredentials credentials, {bool? isTestnet}) async {
136
+ Future<ZanoWallet> restoreFromSeed(ZanoRestoreWalletFromSeedCredentials credentials,
137
+ {bool? isTestnet}) async {
138
return ZanoWalletBase.restore(credentials: credentials);
139
}
140
141
@override
142
Future<ZanoWallet> restoreFromHardwareWallet(ZanoNewWalletCredentials credentials) {
129
- throw UnimplementedError("Restoring a Zano wallet from a hardware wallet is not yet supported!");
143
+ throw UnimplementedError(
144
+ "Restoring a Zano wallet from a hardware wallet is not yet supported!");
145
}
146
}
lib/anonpay/anonpay_api.dart
+2
-2
@@ -78,7 +78,7 @@ class AnonPayApi {
78
clearnetUri: Uri.https(clearNetAuthority, anonPayPath, body),
79
onionUri: Uri.https(onionApiAuthority, anonPayPath, body),
80
);
81
-
81
+
82
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
83
final id = responseJSON['ID'] as String;
84
final url = responseJSON['url'] as String;
@@ -156,7 +156,7 @@ class AnonPayApi {
156
clearnetUri: Uri.https(clearNetAuthority, coinPath, params),
157
onionUri: Uri.https(onionApiAuthority, coinPath, params),
158
);
159
-
159
+
160
final responseJSON = json.decode(response.body) as List<dynamic>;
161
if (response.statusCode != 200) {
162
throw Exception('Unexpected http status: ${response.statusCode}');
lib/anonpay/anonpay_donation_link_info.dart
+3
-3
@@ -1,13 +1,13 @@
1
import 'package:cake_wallet/anonpay/anonpay_info_base.dart';
2
3
-class AnonpayDonationLinkInfo implements AnonpayInfoBase{
3
+class AnonpayDonationLinkInfo implements AnonpayInfoBase {
4
final String clearnetUrl;
5
final String onionUrl;
6
final String address;
7
-
7
+
8
AnonpayDonationLinkInfo({
9
required this.clearnetUrl,
10
required this.onionUrl,
11
required this.address,
12
});
13
-}
\ No newline at end of file
13
+}
lib/anonpay/anonpay_info_base.dart
+1
-1
@@ -2,4 +2,4 @@ abstract class AnonpayInfoBase {
2
String get clearnetUrl;
3
String get onionUrl;
4
String get address;
5
-}
\ No newline at end of file
5
+}
lib/anypay/any_pay_chain.dart
+4
-4
@@ -1,5 +1,5 @@
1
class AnyPayChain {
2
- static const xmr = 'XMR';
3
- static const btc = 'BTC';
4
- static const ltc = 'LTC';
5
-}
\ No newline at end of file
2
+ static const xmr = 'XMR';
3
+ static const btc = 'BTC';
4
+ static const ltc = 'LTC';
5
+}
lib/anypay/any_pay_payment.dart
+55
-53
@@ -4,60 +4,62 @@ import 'package:cake_wallet/bitcoin/bitcoin.dart';
4
import 'package:cake_wallet/monero/monero.dart';
5
6
class AnyPayPayment {
7
- AnyPayPayment({
8
- required this.time,
9
- required this.expires,
10
- required this.memo,
11
- required this.paymentUrl,
12
- required this.paymentId,
13
- required this.chain,
14
- required this.network,
15
- required this.instructions});
7
+ AnyPayPayment(
8
+ {required this.time,
9
+ required this.expires,
10
+ required this.memo,
11
+ required this.paymentUrl,
12
+ required this.paymentId,
13
+ required this.chain,
14
+ required this.network,
15
+ required this.instructions});
16
17
- factory AnyPayPayment.fromMap(Map<String, dynamic> obj) {
18
- final instructions = (obj['instructions'] as List<dynamic>)
19
- .map((dynamic instruction) => AnyPayPaymentInstruction.fromMap(instruction as Map<String, dynamic>))
20
- .toList();
21
- return AnyPayPayment(
22
- time: DateTime.parse(obj['time'] as String),
23
- expires: DateTime.parse(obj['expires'] as String),
24
- memo: obj['memo'] as String,
25
- paymentUrl: obj['paymentUrl'] as String,
26
- paymentId: obj['paymentId'] as String,
27
- chain: obj['chain'] as String,
28
- network: obj['network'] as String,
29
- instructions: instructions);
30
- }
17
+ factory AnyPayPayment.fromMap(Map<String, dynamic> obj) {
18
+ final instructions = (obj['instructions'] as List<dynamic>)
19
+ .map((dynamic instruction) =>
20
+ AnyPayPaymentInstruction.fromMap(instruction as Map<String, dynamic>))
21
+ .toList();
22
+ return AnyPayPayment(
23
+ time: DateTime.parse(obj['time'] as String),
24
+ expires: DateTime.parse(obj['expires'] as String),
25
+ memo: obj['memo'] as String,
26
+ paymentUrl: obj['paymentUrl'] as String,
27
+ paymentId: obj['paymentId'] as String,
28
+ chain: obj['chain'] as String,
29
+ network: obj['network'] as String,
30
+ instructions: instructions);
31
+ }
32
32
- final DateTime time;
33
- final DateTime expires;
34
- final String memo;
35
- final String paymentUrl;
36
- final String paymentId;
37
- final String chain;
38
- final String network;
39
- final List<AnyPayPaymentInstruction> instructions;
33
+ final DateTime time;
34
+ final DateTime expires;
35
+ final String memo;
36
+ final String paymentUrl;
37
+ final String paymentId;
38
+ final String chain;
39
+ final String network;
40
+ final List<AnyPayPaymentInstruction> instructions;
41
41
- String get totalAmount {
42
- final total = instructions
43
- .fold<int>(0, (int acc, instruction) => acc + instruction.outputs
44
- .fold<int>(0, (int outAcc, out) => outAcc + out.amount));
45
- switch (chain) {
46
- case AnyPayChain.xmr:
47
- return monero!.formatterMoneroAmountToString(amount: total);
48
- case AnyPayChain.btc:
49
- return bitcoin!.formatterBitcoinAmountToString(amount: total);
50
- case AnyPayChain.ltc:
51
- return bitcoin!.formatterBitcoinAmountToString(amount: total);
52
- default:
53
- return '';
54
- }
55
- }
42
+ String get totalAmount {
43
+ final total = instructions.fold<int>(
44
+ 0,
45
+ (int acc, instruction) =>
46
+ acc + instruction.outputs.fold<int>(0, (int outAcc, out) => outAcc + out.amount));
47
+ switch (chain) {
48
+ case AnyPayChain.xmr:
49
+ return monero!.formatterMoneroAmountToString(amount: total);
50
+ case AnyPayChain.btc:
51
+ return bitcoin!.formatterBitcoinAmountToString(amount: total);
52
+ case AnyPayChain.ltc:
53
+ return bitcoin!.formatterBitcoinAmountToString(amount: total);
54
+ default:
55
+ return '';
56
+ }
57
+ }
58
57
- List<String> get outAddresses {
58
- return instructions
59
- .map((instruction) => instruction.outputs.map((out) => out.address))
60
- .expand((e) => e)
61
- .toList();
62
- }
63
-}
\ No newline at end of file
59
+ List<String> get outAddresses {
60
+ return instructions
61
+ .map((instruction) => instruction.outputs.map((out) => out.address))
62
+ .expand((e) => e)
63
+ .toList();
64
+ }
65
+}
lib/anypay/any_pay_payment_committed_info.dart
+12
-12
@@ -1,16 +1,16 @@
1
import 'package:cake_wallet/anypay/any_pay_trasnaction.dart';
2
3
class AnyPayPaymentCommittedInfo {
4
- const AnyPayPaymentCommittedInfo({
5
- required this.uri,
6
- required this.currency,
7
- required this.chain,
8
- required this.transactions,
9
- required this.memo});
4
+ const AnyPayPaymentCommittedInfo(
5
+ {required this.uri,
6
+ required this.currency,
7
+ required this.chain,
8
+ required this.transactions,
9
+ required this.memo});
10
11
- final String uri;
12
- final String currency;
13
- final String chain;
14
- final List<AnyPayTransaction> transactions;
15
- final String memo;
16
-}
\ No newline at end of file
11
+ final String uri;
12
+ final String currency;
13
+ final String chain;
14
+ final List<AnyPayTransaction> transactions;
15
+ final String memo;
16
+}
lib/anypay/any_pay_payment_instruction.dart
+24
-25
@@ -1,31 +1,30 @@
1
import 'package:cake_wallet/anypay/any_pay_payment_instruction_output.dart';
2
3
class AnyPayPaymentInstruction {
4
- AnyPayPaymentInstruction({
5
- required this.type,
6
- required this.requiredFeeRate,
7
- required this.txKey,
8
- required this.txHash,
9
- required this.outputs});
4
+ AnyPayPaymentInstruction(
5
+ {required this.type,
6
+ required this.requiredFeeRate,
7
+ required this.txKey,
8
+ required this.txHash,
9
+ required this.outputs});
10
11
- factory AnyPayPaymentInstruction.fromMap(Map<String, dynamic> obj) {
12
- final outputs = (obj['outputs'] as List<dynamic>)
13
- .map((dynamic out) =>
14
- AnyPayPaymentInstructionOutput.fromMap(out as Map<String, dynamic>))
15
- .toList();
16
- return AnyPayPaymentInstruction(
17
- type: obj['type'] as String,
18
- requiredFeeRate: obj['requiredFeeRate'] as int,
19
- txKey: obj['tx_key'] as bool? ?? false,
20
- txHash: obj['tx_hash'] as bool? ?? false,
21
- outputs: outputs);
22
- }
11
+ factory AnyPayPaymentInstruction.fromMap(Map<String, dynamic> obj) {
12
+ final outputs = (obj['outputs'] as List<dynamic>)
13
+ .map((dynamic out) => AnyPayPaymentInstructionOutput.fromMap(out as Map<String, dynamic>))
14
+ .toList();
15
+ return AnyPayPaymentInstruction(
16
+ type: obj['type'] as String,
17
+ requiredFeeRate: obj['requiredFeeRate'] as int,
18
+ txKey: obj['tx_key'] as bool? ?? false,
19
+ txHash: obj['tx_hash'] as bool? ?? false,
20
+ outputs: outputs);
21
+ }
22
24
- static const transactionType = 'transaction';
23
+ static const transactionType = 'transaction';
24
26
- final String type;
27
- final int requiredFeeRate;
28
- final bool txKey;
29
- final bool txHash;
30
- final List<AnyPayPaymentInstructionOutput> outputs;
31
-}
\ No newline at end of file
25
+ final String type;
26
+ final int requiredFeeRate;
27
+ final bool txKey;
28
+ final bool txHash;
29
+ final List<AnyPayPaymentInstructionOutput> outputs;
30
+}
lib/anypay/any_pay_payment_instruction_output.dart
+7
-7
@@ -1,10 +1,10 @@
1
class AnyPayPaymentInstructionOutput {
2
- const AnyPayPaymentInstructionOutput(this.address, this.amount);
2
+ const AnyPayPaymentInstructionOutput(this.address, this.amount);
3
4
- factory AnyPayPaymentInstructionOutput.fromMap(Map<String, dynamic> obj) {
5
- return AnyPayPaymentInstructionOutput(obj['address'] as String, obj['amount'] as int);
6
- }
4
+ factory AnyPayPaymentInstructionOutput.fromMap(Map<String, dynamic> obj) {
5
+ return AnyPayPaymentInstructionOutput(obj['address'] as String, obj['amount'] as int);
6
+ }
7
8
- final String address;
9
- final int amount;
10
-}
\ No newline at end of file
8
+ final String address;
9
+ final int amount;
10
+}
lib/anypay/any_pay_trasnaction.dart
+5
-5
@@ -1,7 +1,7 @@
1
class AnyPayTransaction {
2
- 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;
6
- final String? key;
7
-}
\ No newline at end of file
4
+ final String tx;
5
+ final String id;
6
+ final String? key;
7
+}
lib/anypay/anypay_api.dart
+83
-79
@@ -9,101 +9,105 @@ import 'package:cake_wallet/anypay/any_pay_trasnaction.dart';
9
import 'package:cake_wallet/.secrets.g.dart' as secrets;
10
11
class AnyPayApi {
12
- static const contentTypePaymentRequest = 'application/payment-request';
13
- static const contentTypePayment = 'application/payment';
14
- static const xPayproVersion = '2';
15
- static const anypayToken = secrets.anypayToken;
12
+ static const contentTypePaymentRequest = 'application/payment-request';
13
+ static const contentTypePayment = 'application/payment';
14
+ static const xPayproVersion = '2';
15
+ static const anypayToken = secrets.anypayToken;
16
17
- static String chainByScheme(String scheme) {
18
- switch (scheme.toLowerCase()) {
19
- case 'monero':
20
- return CryptoCurrency.xmr.title;
21
- case 'bitcoin':
22
- return CryptoCurrency.btc.title;
23
- case 'litecoin':
24
- return CryptoCurrency.ltc.title;
25
- default:
26
- return '';
27
- }
28
- }
17
+ static String chainByScheme(String scheme) {
18
+ switch (scheme.toLowerCase()) {
19
+ case 'monero':
20
+ return CryptoCurrency.xmr.title;
21
+ case 'bitcoin':
22
+ return CryptoCurrency.btc.title;
23
+ case 'litecoin':
24
+ return CryptoCurrency.ltc.title;
25
+ default:
26
+ return '';
27
+ }
28
+ }
29
30
- static CryptoCurrency currencyByScheme(String scheme) {
31
- switch (scheme.toLowerCase()) {
32
- case 'monero':
33
- return CryptoCurrency.xmr;
34
- case 'bitcoin':
35
- return CryptoCurrency.btc;
36
- case 'litecoin':
37
- return CryptoCurrency.ltc;
38
- default:
39
- throw Exception('Unexpected scheme: ${scheme}');
40
- }
41
- }
30
+ static CryptoCurrency currencyByScheme(String scheme) {
31
+ switch (scheme.toLowerCase()) {
32
+ case 'monero':
33
+ return CryptoCurrency.xmr;
34
+ case 'bitcoin':
35
+ return CryptoCurrency.btc;
36
+ case 'litecoin':
37
+ return CryptoCurrency.ltc;
38
+ default:
39
+ throw Exception('Unexpected scheme: ${scheme}');
40
+ }
41
+ }
42
43
- Future<AnyPayPayment> paymentRequest(String uri) async {
44
- final fragments = uri.split(':?r=');
45
- final scheme = fragments.first;
46
- final url = Uri.parse(fragments[1]);
47
- final headers = <String, String>{
48
- 'Content-Type': contentTypePaymentRequest,
49
- 'X-Paypro-Version': xPayproVersion,
50
- 'Accept': '*/*',
51
- 'x-wallet': 'cake',
52
- 'x-wallet-token': anypayToken,};
53
- final body = <String, dynamic>{
54
- 'chain': chainByScheme(scheme),
55
- 'currency': currencyByScheme(scheme).title};
56
- final response = await ProxyWrapper().post(
43
+ Future<AnyPayPayment> paymentRequest(String uri) async {
44
+ final fragments = uri.split(':?r=');
45
+ final scheme = fragments.first;
46
+ final url = Uri.parse(fragments[1]);
47
+ final headers = <String, String>{
48
+ 'Content-Type': contentTypePaymentRequest,
49
+ 'X-Paypro-Version': xPayproVersion,
50
+ 'Accept': '*/*',
51
+ 'x-wallet': 'cake',
52
+ 'x-wallet-token': anypayToken,
53
+ };
54
+ final body = <String, dynamic>{
55
+ 'chain': chainByScheme(scheme),
56
+ 'currency': currencyByScheme(scheme).title
57
+ };
58
+ final response = await ProxyWrapper().post(
59
clearnetUri: url,
60
headers: headers,
61
body: json.encode(body),
62
);
61
-
63
+
64
if (response.statusCode != 200) {
63
- await ExceptionHandler.onError(FlutterErrorDetails(exception: response));
65
+ await ExceptionHandler.onError(FlutterErrorDetails(exception: response));
66
throw Exception('Unexpected response http code: ${response.statusCode}');
65
- }
67
+ }
68
69
final decodedBody = json.decode(response.body) as Map<String, dynamic>;
70
return AnyPayPayment.fromMap(decodedBody);
69
- }
71
+ }
72
71
- Future<AnyPayPaymentCommittedInfo> payment(
72
- String uri,
73
- {required String chain,
74
- required String currency,
75
- required List<AnyPayTransaction> transactions}) async {
76
- final headers = <String, String>{
77
- 'Content-Type': contentTypePayment,
78
- 'X-Paypro-Version': xPayproVersion,
79
- 'Accept': '*/*',
80
- 'x-wallet': 'cake',
81
- 'x-wallet-token': anypayToken,};
82
- final body = <String, dynamic>{
83
- 'chain': chain,
84
- 'currency': currency,
85
- 'transactions': transactions.map((tx) => {'tx': tx.tx, 'tx_hash': tx.id, 'tx_key': tx.key}).toList()};
86
- final response = await ProxyWrapper().post(
73
+ Future<AnyPayPaymentCommittedInfo> payment(String uri,
74
+ {required String chain,
75
+ required String currency,
76
+ required List<AnyPayTransaction> transactions}) async {
77
+ final headers = <String, String>{
78
+ 'Content-Type': contentTypePayment,
79
+ 'X-Paypro-Version': xPayproVersion,
80
+ 'Accept': '*/*',
81
+ 'x-wallet': 'cake',
82
+ 'x-wallet-token': anypayToken,
83
+ };
84
+ final body = <String, dynamic>{
85
+ 'chain': chain,
86
+ 'currency': currency,
87
+ 'transactions':
88
+ transactions.map((tx) => {'tx': tx.tx, 'tx_hash': tx.id, 'tx_key': tx.key}).toList()
89
+ };
90
+ final response = await ProxyWrapper().post(
91
clearnetUri: Uri.parse(uri),
92
headers: headers,
93
body: json.encode(body),
94
);
91
-
92
- if (response.statusCode == 400) {
93
- final decodedBody = json.decode(response.body) as Map<String, dynamic>;
94
- throw Exception(decodedBody['message'] as String? ?? 'Unexpected response\nError code: 400');
95
- }
95
97
- if (response.statusCode != 200) {
98
- throw Exception('Unexpected response');
99
- }
96
+ if (response.statusCode == 400) {
97
+ final decodedBody = json.decode(response.body) as Map<String, dynamic>;
98
+ throw Exception(decodedBody['message'] as String? ?? 'Unexpected response\nError code: 400');
99
+ }
100
+
101
+ if (response.statusCode != 200) {
102
+ throw Exception('Unexpected response');
103
+ }
104
101
- final decodedBody = json.decode(response.body) as Map<String, dynamic>;
102
- return AnyPayPaymentCommittedInfo(
103
- uri: uri,
104
- currency: currency,
105
- chain: chain,
106
- transactions: transactions,
107
- memo: decodedBody['memo'] as String);
108
- }
109
-}
\ No newline at end of file
105
+ final decodedBody = json.decode(response.body) as Map<String, dynamic>;
106
+ return AnyPayPaymentCommittedInfo(
107
+ uri: uri,
108
+ currency: currency,
109
+ chain: chain,
110
+ transactions: transactions,
111
+ memo: decodedBody['memo'] as String);
112
+ }
113
+}
lib/bitcoin/cw_bitcoin.dart
+19
-19
@@ -185,7 +185,7 @@ class CWBitcoin extends Bitcoin {
185
balance: addr.balance,
186
isChange: addr.isHidden,
187
isLegacyDerivation: addr.isLegacyDerivation,
188
- derivationPath: addr.derivationPath))
188
+ derivationPath: addr.derivationPath))
189
.toList();
190
}
191
@@ -206,10 +206,8 @@ class CWBitcoin extends Bitcoin {
206
return estimatedTx.amount;
207
}
208
209
-
209
if (wallet.type == WalletType.dogecoin) {
211
- final dogeAddr =
212
- sk.getPublic().toP2pkhAddress();
210
+ final dogeAddr = sk.getPublic().toP2pkhAddress();
211
final estimatedTx = await electrumWallet.estimateSendAllTx(
212
[BitcoinOutput(address: dogeAddr, value: BigInt.zero)],
213
getFeeRate(wallet, priority as BitcoinTransactionPriority),
@@ -276,14 +274,13 @@ class CWBitcoin extends Bitcoin {
274
await bitcoinWallet.updateAllUnspents();
275
}
276
279
- WalletService createBitcoinWalletService(
280
- Box<UnspentCoinsInfo> unspentCoinSource,
281
- Box<PayjoinSession> payjoinSessionSource,
282
- bool isDirect) {
277
+ WalletService createBitcoinWalletService(Box<UnspentCoinsInfo> unspentCoinSource,
278
+ Box<PayjoinSession> payjoinSessionSource, bool isDirect) {
279
return BitcoinWalletService(unspentCoinSource, payjoinSessionSource, isDirect);
280
}
281
286
- WalletService createLitecoinWalletService(Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect) {
282
+ WalletService createLitecoinWalletService(
283
+ Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect) {
284
return LitecoinWalletService(unspentCoinSource, isDirect);
285
}
286
@@ -340,7 +337,8 @@ class CWBitcoin extends Bitcoin {
337
}
338
339
@override
343
- BitcoinReceivePageOption getBitcoinLightningReceivePageOption() => BitcoinReceivePageOption.lightning;
340
+ BitcoinReceivePageOption getBitcoinLightningReceivePageOption() =>
341
+ BitcoinReceivePageOption.lightning;
342
@override
343
BitcoinReceivePageOption getBitcoinSegwitPageOption() => BitcoinReceivePageOption.p2wpkh;
344
@override
@@ -839,9 +837,11 @@ class CWBitcoin extends Bitcoin {
837
final addresses = <String>[];
838
839
if (bitcoinTx.unspents == null || bitcoinTx.unspents!.isEmpty) {
842
- if(bitcoinTx.outputAddresses == null) return null;
843
- for(final addr in bitcoinTx.outputAddresses!) {
844
- if(bitcoinWallet.walletAddresses.allAddresses.firstWhereOrNull((item)=>item.address==addr) != null) {
840
+ if (bitcoinTx.outputAddresses == null) return null;
841
+ for (final addr in bitcoinTx.outputAddresses!) {
842
+ if (bitcoinWallet.walletAddresses.allAddresses
843
+ .firstWhereOrNull((item) => item.address == addr) !=
844
+ null) {
845
addresses.add(addr);
846
}
847
}
@@ -850,12 +850,12 @@ class CWBitcoin extends Bitcoin {
850
851
final labels = <String>[];
852
try {
853
- bitcoinTx.unspents!.forEach((unspent) {
854
- addresses.add(bitcoinWallet.walletAddresses.silentAddresses
855
- .firstWhere((address) => address.silentPaymentTweak == unspent.silentPaymentLabel)
856
- .address);
857
- });
858
- } catch (e) {}
853
+ bitcoinTx.unspents!.forEach((unspent) {
854
+ addresses.add(bitcoinWallet.walletAddresses.silentAddresses
855
+ .firstWhere((address) => address.silentPaymentTweak == unspent.silentPaymentLabel)
856
+ .address);
857
+ });
858
+ } catch (e) {}
859
860
return addresses;
861
}
lib/bitcoin_cash/cw_bitcoin_cash.dart
+6
-2
@@ -5,7 +5,8 @@ class CWBitcoinCash extends BitcoinCash {
5
String getCashAddrFormat(String address) => AddressUtils.getCashAddrFormat(address);
6
7
@override
8
- WalletService createBitcoinCashWalletService(Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect) {
8
+ WalletService createBitcoinCashWalletService(
9
+ Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect) {
10
return BitcoinCashWalletService(unspentCoinSource, isDirect);
11
}
12
@@ -27,7 +28,10 @@ class CWBitcoinCash extends BitcoinCash {
28
29
@override
30
WalletCredentials createBitcoinCashRestoreWalletFromSeedCredentials(
30
- {required String name, required String mnemonic, required String password, String? passphrase}) =>
31
+ {required String name,
32
+ required String mnemonic,
33
+ required String password,
34
+ String? passphrase}) =>
35
BitcoinCashRestoreWalletFromSeedCredentials(
36
name: name, mnemonic: mnemonic, password: password, passphrase: passphrase);
37
lib/buy/buy_amount.dart
+6
-7
@@ -1,13 +1,12 @@
1
-
1
class BuyAmount {
3
- BuyAmount({
4
- required this.sourceAmount,
5
- required this.destAmount,
6
- this.achSourceAmount,
7
- this.minAmount = 0});
2
+ BuyAmount(
3
+ {required this.sourceAmount,
4
+ required this.destAmount,
5
+ this.achSourceAmount,
6
+ this.minAmount = 0});
7
8
final double sourceAmount;
9
final double destAmount;
10
final double? achSourceAmount;
11
final int minAmount;
13
-}
\ No newline at end of file
12
+}
lib/buy/buy_exception.dart
+1
-2
@@ -1,4 +1,3 @@
1
-
1
class BuyException implements Exception {
2
BuyException({required this.title, required this.content});
3
@@ -7,4 +6,4 @@ class BuyException implements Exception {
6
7
@override
8
String toString() => '$title: $content';
10
-}
\ No newline at end of file
9
+}
lib/buy/buy_provider.dart
+8
-9
@@ -10,13 +10,12 @@ import 'package:cw_core/wallet_base.dart';
10
import 'package:flutter/material.dart';
11
12
abstract class BuyProvider {
13
- BuyProvider({
14
- required this.wallet,
15
- required this.isTestEnvironment,
16
- required this.hardwareWalletVM,
17
- required this.supportedCryptoList,
18
- required this.supportedFiatList
19
- });
13
+ BuyProvider(
14
+ {required this.wallet,
15
+ required this.isTestEnvironment,
16
+ required this.hardwareWalletVM,
17
+ required this.supportedCryptoList,
18
+ required this.supportedFiatList});
19
20
final WalletBase wallet;
21
final bool isTestEnvironment;
@@ -54,7 +53,7 @@ abstract class BuyProvider {
53
throw UnimplementedError();
54
55
Future<List<PaymentMethod>> getAvailablePaymentTypes(
57
- String fiatCurrency, CryptoCurrency cryptoCurrency, bool isBuyAction) async =>
56
+ String fiatCurrency, CryptoCurrency cryptoCurrency, bool isBuyAction) async =>
57
[];
58
59
Future<List<Quote>?> fetchQuote(
@@ -64,7 +63,7 @@ abstract class BuyProvider {
63
required bool isBuyAction,
64
required String walletAddress,
65
PaymentType? paymentType,
67
- String? customPaymentMethodType,
66
+ String? customPaymentMethodType,
67
String? countryCode}) async =>
68
null;
69
}
lib/buy/dfx/dfx_buy_provider.dart
+8
-9
@@ -56,7 +56,7 @@ class DFXBuyProvider extends BuyProvider {
56
57
static final List<FiatCurrency> _supportedFiat = [FiatCurrency.chf, FiatCurrency.eur];
58
static final List<FiatCurrency> _notSupportedFiat =
59
- FiatCurrency.all.where((fiat) => !_supportedFiat.contains(fiat)).toList();
59
+ FiatCurrency.all.where((fiat) => !_supportedFiat.contains(fiat)).toList();
60
61
@override
62
String get title => 'DFX.swiss';
@@ -84,7 +84,6 @@ class DFXBuyProvider extends BuyProvider {
84
}
85
}
86
87
-
87
Future<String> getSignMessage(String walletAddress) async =>
88
"By_signing_this_message,_you_confirm_that_you_are_the_sole_owner_of_the_provided_Blockchain_address._Your_ID:_$walletAddress";
89
@@ -156,10 +155,9 @@ class DFXBuyProvider extends BuyProvider {
155
final url = Uri.https(_baseUrl, '/v1/fiat');
156
157
try {
159
- final response = await ProxyWrapper().get(
160
- clearnetUri: url,
161
- headers: {'accept': 'application/json'});
162
-
158
+ final response =
159
+ await ProxyWrapper().get(clearnetUri: url, headers: {'accept': 'application/json'});
160
+
161
if (response.statusCode == 200) {
162
final data = jsonDecode(response.body) as List<dynamic>;
163
for (final item in data) {
@@ -181,8 +179,9 @@ class DFXBuyProvider extends BuyProvider {
179
final url = Uri.https(_baseUrl, '/v1/asset', {'blockchains': blockchain});
180
181
try {
184
- final response = await ProxyWrapper().get(clearnetUri: url, headers: {'accept': 'application/json'});
185
-
182
+ final response =
183
+ await ProxyWrapper().get(clearnetUri: url, headers: {'accept': 'application/json'});
184
+
185
if (response.statusCode == 200) {
186
final responseData = jsonDecode(response.body);
187
@@ -300,7 +299,7 @@ class DFXBuyProvider extends BuyProvider {
299
headers: headers,
300
body: body,
301
);
303
-
302
+
303
final responseData = jsonDecode(response.body);
304
305
if (response.statusCode == 200) {
lib/buy/get_buy_provider_icon.dart
+4
-7
@@ -2,13 +2,10 @@ import 'package:flutter/material.dart';
2
import 'package:cake_wallet/buy/buy_provider_description.dart';
3
4
Image? getBuyProviderIcon(BuyProviderDescription providerDescription,
5
- {Color iconColor = Colors.black}) {
6
-
7
- final _wyreIcon =
8
- Image.asset('assets/images/wyre-icon.png', width: 36, height: 36);
5
+ {Color iconColor = Colors.black}) {
6
+ final _wyreIcon = Image.asset('assets/images/wyre-icon.png', width: 36, height: 36);
7
final _moonPayIcon =
10
- Image.asset('assets/images/moonpay-icon.png', color: iconColor,
11
- width: 36, height: 34);
8
+ Image.asset('assets/images/moonpay-icon.png', color: iconColor, width: 36, height: 34);
9
10
switch (providerDescription) {
11
case BuyProviderDescription.wyre:
@@ -18,4 +15,4 @@ Image? getBuyProviderIcon(BuyProviderDescription providerDescription,
15
default:
16
return null;
17
}
21
-}
\ No newline at end of file
18
+}
lib/buy/kryptonim/kryptonim.dart
+9
-10
@@ -18,13 +18,13 @@ import 'package:url_launcher/url_launcher.dart';
18
class KryptonimBuyProvider extends BuyProvider {
19
KryptonimBuyProvider({required WalletBase wallet, bool isTestEnvironment = false})
20
: super(
21
- wallet: wallet,
22
- isTestEnvironment: isTestEnvironment,
23
- hardwareWalletVM: null,
24
- supportedCryptoList: supportedCryptoToFiatPairs(
25
- notSupportedCrypto: _notSupportedCrypto, notSupportedFiat: _notSupportedFiat),
26
- supportedFiatList: supportedFiatToCryptoPairs(
27
- notSupportedFiat: _notSupportedFiat, notSupportedCrypto: _notSupportedCrypto));
21
+ wallet: wallet,
22
+ isTestEnvironment: isTestEnvironment,
23
+ hardwareWalletVM: null,
24
+ supportedCryptoList: supportedCryptoToFiatPairs(
25
+ notSupportedCrypto: _notSupportedCrypto, notSupportedFiat: _notSupportedFiat),
26
+ supportedFiatList: supportedFiatToCryptoPairs(
27
+ notSupportedFiat: _notSupportedFiat, notSupportedCrypto: _notSupportedCrypto));
28
29
static const _isProduction = true;
30
@@ -81,7 +81,6 @@ class KryptonimBuyProvider extends BuyProvider {
81
);
82
83
if (response.statusCode == 200 || response.statusCode == 201 || response.statusCode == 401) {
84
-
84
return jsonDecode(response.body) as Map<String, dynamic>;
85
} else {
86
return {};
@@ -94,7 +93,6 @@ class KryptonimBuyProvider extends BuyProvider {
93
@override
94
Future<List<PaymentMethod>> getAvailablePaymentTypes(
95
String fiatCurrency, CryptoCurrency cryptoCurrency, bool isBuyAction) async {
97
-
96
final data = await getExchangeRates(
97
cryptoCurrency: cryptoCurrency,
98
fiatCurrency: fiatCurrency,
@@ -155,7 +153,8 @@ class KryptonimBuyProvider extends BuyProvider {
153
154
final selectedPaymentType =
155
PaymentMethod.getPaymentTypeId(selectedPaymentMethod['payment_method'] as String?);
158
- final quote = Quote.fromKryptonimJson(selectedPaymentMethod, isBuyAction, selectedPaymentType ?? PaymentType.unknown);
156
+ final quote = Quote.fromKryptonimJson(
157
+ selectedPaymentMethod, isBuyAction, selectedPaymentType ?? PaymentType.unknown);
158
159
quote.setFiatCurrency = fiatCurrency;
160
quote.setCryptoCurrency = cryptoCurrency;
lib/buy/meld/meld_buy_provider.dart
+15
-17
@@ -20,13 +20,13 @@ import 'package:url_launcher/url_launcher.dart';
20
class MeldBuyProvider extends BuyProvider {
21
MeldBuyProvider({required WalletBase wallet, bool isTestEnvironment = false})
22
: super(
23
- wallet: wallet,
24
- isTestEnvironment: isTestEnvironment,
25
- hardwareWalletVM: null,
26
- supportedCryptoList: supportedCryptoToFiatPairs(
27
- notSupportedCrypto: _notSupportedCrypto, notSupportedFiat: _notSupportedFiat),
28
- supportedFiatList: supportedFiatToCryptoPairs(
29
- notSupportedFiat: _notSupportedFiat, notSupportedCrypto: _notSupportedCrypto));
23
+ wallet: wallet,
24
+ isTestEnvironment: isTestEnvironment,
25
+ hardwareWalletVM: null,
26
+ supportedCryptoList: supportedCryptoToFiatPairs(
27
+ notSupportedCrypto: _notSupportedCrypto, notSupportedFiat: _notSupportedFiat),
28
+ supportedFiatList: supportedFiatToCryptoPairs(
29
+ notSupportedFiat: _notSupportedFiat, notSupportedCrypto: _notSupportedCrypto));
30
31
static const _isProduction = false;
32
@@ -45,7 +45,7 @@ class MeldBuyProvider extends BuyProvider {
45
static const List<CryptoCurrency> _notSupportedCrypto = [];
46
static const List<FiatCurrency> _notSupportedFiat = [];
47
48
- static String get _testPublicKey => '' ; //secrets.meldTestPublicKey;
48
+ static String get _testPublicKey => ''; //secrets.meldTestPublicKey;
49
50
@override
51
String get title => 'Meld';
@@ -80,7 +80,6 @@ class MeldBuyProvider extends BuyProvider {
80
'content-type': 'application/json',
81
},
82
);
83
-
83
84
if (response.statusCode == 200) {
85
final data = jsonDecode(response.body) as List<dynamic>;
@@ -100,13 +99,13 @@ class MeldBuyProvider extends BuyProvider {
99
@override
100
Future<List<Quote>?> fetchQuote(
101
{required CryptoCurrency cryptoCurrency,
103
- required FiatCurrency fiatCurrency,
104
- required double amount,
105
- required bool isBuyAction,
106
- required String walletAddress,
107
- PaymentType? paymentType,
108
- String? customPaymentMethodType,
109
- String? countryCode}) async {
102
+ required FiatCurrency fiatCurrency,
103
+ required double amount,
104
+ required bool isBuyAction,
105
+ required String walletAddress,
106
+ PaymentType? paymentType,
107
+ String? customPaymentMethodType,
108
+ String? countryCode}) async {
109
String? paymentMethod;
110
if (paymentType != null && paymentType != PaymentType.all) {
111
paymentMethod = normalizePaymentMethod(paymentType);
@@ -136,7 +135,6 @@ class MeldBuyProvider extends BuyProvider {
135
headers: headers,
136
body: body,
137
);
139
-
138
139
if (response.statusCode == 200) {
140
final data = jsonDecode(response.body) as Map<String, dynamic>;
lib/buy/moonpay/moonpay_provider.dart
+11
-12
@@ -34,13 +34,13 @@ class MoonPayProvider extends BuyProvider {
34
baseBuyUrl = isTestEnvironment ? _baseBuyTestUrl : _baseBuyProductUrl,
35
this._appStore = appStore,
36
super(
37
- wallet: wallet,
38
- isTestEnvironment: isTestEnvironment,
39
- hardwareWalletVM: null,
40
- supportedCryptoList: supportedCryptoToFiatPairs(
41
- notSupportedCrypto: _notSupportedCrypto, notSupportedFiat: _notSupportedFiat),
42
- supportedFiatList: supportedFiatToCryptoPairs(
43
- notSupportedFiat: _notSupportedFiat, notSupportedCrypto: _notSupportedCrypto));
37
+ wallet: wallet,
38
+ isTestEnvironment: isTestEnvironment,
39
+ hardwareWalletVM: null,
40
+ supportedCryptoList: supportedCryptoToFiatPairs(
41
+ notSupportedCrypto: _notSupportedCrypto, notSupportedFiat: _notSupportedFiat),
42
+ supportedFiatList: supportedFiatToCryptoPairs(
43
+ notSupportedFiat: _notSupportedFiat, notSupportedCrypto: _notSupportedCrypto));
44
45
final AppStore _appStore;
46
@@ -81,7 +81,8 @@ class MoonPayProvider extends BuyProvider {
81
82
String get _apiKey => isTestEnvironment ? secrets.moonPaySandboxApiKey : secrets.moonPayApiKey;
83
84
- String get currencyCode => walletTypeToCryptoCurrency(wallet.type, chainId: wallet.chainId).title.toLowerCase();
84
+ String get currencyCode =>
85
+ walletTypeToCryptoCurrency(wallet.type, chainId: wallet.chainId).title.toLowerCase();
86
87
String get trackUrl => baseBuyUrl + '/transaction_receipt?transactionId=';
88
@@ -105,7 +106,6 @@ class MoonPayProvider extends BuyProvider {
106
headers: {'Content-Type': 'application/json', 'x-api-key': _exchangeHelperApiKey},
107
body: json.encode({'query': query}),
108
);
108
-
109
110
if (response.statusCode == 200) {
111
printV((jsonDecode(response.body) as Map<String, dynamic>));
@@ -130,7 +130,7 @@ class MoonPayProvider extends BuyProvider {
130
clearnetUri: url,
131
headers: {'accept': 'application/json'},
132
);
133
-
133
+
134
if (response.statusCode == 200) {
135
return jsonDecode(response.body) as Map<String, dynamic>;
136
} else {
@@ -202,7 +202,7 @@ class MoonPayProvider extends BuyProvider {
202
final url = Uri.https(_baseUrl, path, params);
203
try {
204
final response = await ProxyWrapper().get(clearnetUri: url);
205
-
205
+
206
if (response.statusCode == 200) {
207
final data = jsonDecode(response.body) as Map<String, dynamic>;
208
@@ -312,7 +312,6 @@ class MoonPayProvider extends BuyProvider {
312
final url = _apiUrl + _transactionsSuffix + '/$id' + '?apiKey=' + _apiKey;
313
final uri = Uri.parse(url);
314
final response = await ProxyWrapper().get(clearnetUri: uri);
315
-
315
316
if (response.statusCode != 200) {
317
throw BuyException(title: providerDescription, content: 'Transaction $id is not found!');
lib/buy/onramper/onramper_buy_provider.dart
+35
-37
@@ -16,15 +16,15 @@ import 'package:flutter/material.dart';
16
import 'package:url_launcher/url_launcher.dart';
17
18
class OnRamperBuyProvider extends BuyProvider {
19
- OnRamperBuyProvider(
20
- {required WalletBase wallet, bool isTestEnvironment = false})
21
- : super(wallet: wallet,
22
- isTestEnvironment: isTestEnvironment,
23
- hardwareWalletVM: null,
24
- supportedCryptoList: supportedCryptoToFiatPairs(
25
- notSupportedCrypto: _notSupportedCrypto, notSupportedFiat: _notSupportedFiat),
26
- supportedFiatList: supportedFiatToCryptoPairs(
27
- notSupportedFiat: _notSupportedFiat, notSupportedCrypto: _notSupportedCrypto));
19
+ OnRamperBuyProvider({required WalletBase wallet, bool isTestEnvironment = false})
20
+ : super(
21
+ wallet: wallet,
22
+ isTestEnvironment: isTestEnvironment,
23
+ hardwareWalletVM: null,
24
+ supportedCryptoList: supportedCryptoToFiatPairs(
25
+ notSupportedCrypto: _notSupportedCrypto, notSupportedFiat: _notSupportedFiat),
26
+ supportedFiatList: supportedFiatToCryptoPairs(
27
+ notSupportedFiat: _notSupportedFiat, notSupportedCrypto: _notSupportedCrypto));
28
29
static const _baseUrl = 'buy.onramper.com';
30
static const _baseApiUrl = 'api.onramper.com';
@@ -68,7 +68,6 @@ class OnRamperBuyProvider extends BuyProvider {
68
body: json.encode({'query': query}),
69
);
70
71
-
71
if (response.statusCode == 200) {
72
return (jsonDecode(response.body) as Map<String, dynamic>)['signature'] as String;
73
} else {
@@ -78,7 +77,6 @@ class OnRamperBuyProvider extends BuyProvider {
77
}
78
79
Future<String?> getRecommendedPaymentType(bool isBuyAction) async {
81
-
80
final params = {'type': isBuyAction ? 'buy' : 'sell'};
81
82
final url = Uri.https(_baseApiUrl, '$supported$defaultsAll', params);
@@ -95,10 +93,9 @@ class OnRamperBuyProvider extends BuyProvider {
93
94
final recommendedPaymentType = recommended['paymentMethod'] as String?;
95
98
- return recommendedPaymentType ;
96
+ return recommendedPaymentType;
97
} else {
100
- final responseBody =
101
- jsonDecode(response.body) as Map<String, dynamic>;
98
+ final responseBody = jsonDecode(response.body) as Map<String, dynamic>;
99
printV('Failed to fetch available payment types: ${responseBody['message']}');
100
}
101
} catch (e) {
@@ -109,21 +106,20 @@ class OnRamperBuyProvider extends BuyProvider {
106
107
Future<List<PaymentMethod>> getAvailablePaymentTypes(
108
String fiatCurrency, CryptoCurrency cryptoCurrency, bool isBuyAction) async {
112
-
113
- final normalizedCryptoCurrency =
114
- cryptoCurrency.title + _getNormalizeNetwork(cryptoCurrency);
109
+ final normalizedCryptoCurrency = cryptoCurrency.title + _getNormalizeNetwork(cryptoCurrency);
110
111
final sourceCurrency = (isBuyAction ? fiatCurrency : normalizedCryptoCurrency).toLowerCase();
117
- final destinationCurrency = (isBuyAction ? normalizedCryptoCurrency : fiatCurrency).toLowerCase();
112
+ final destinationCurrency =
113
+ (isBuyAction ? normalizedCryptoCurrency : fiatCurrency).toLowerCase();
114
119
- final params = {'type': isBuyAction ? 'buy' : 'sell', 'destination' : destinationCurrency};
115
+ final params = {'type': isBuyAction ? 'buy' : 'sell', 'destination': destinationCurrency};
116
117
final url = Uri.https(_baseApiUrl, '$supported$paymentTypes/$sourceCurrency', params);
118
119
try {
124
- final response =
125
- await ProxyWrapper().get(clearnetUri: url, headers: {'Authorization': _apiKey, 'accept': 'application/json'});
126
-
120
+ final response = await ProxyWrapper()
121
+ .get(clearnetUri: url, headers: {'Authorization': _apiKey, 'accept': 'application/json'});
122
+
123
if (response.statusCode == 200) {
124
final Map<String, dynamic> data = jsonDecode(response.body) as Map<String, dynamic>;
125
final List<dynamic> message = data['message'] as List<dynamic>;
@@ -136,8 +132,7 @@ class OnRamperBuyProvider extends BuyProvider {
132
133
return allAvailablePaymentMethods;
134
} else {
139
- final responseBody =
140
- jsonDecode(response.body) as Map<String, dynamic>;
135
+ final responseBody = jsonDecode(response.body) as Map<String, dynamic>;
136
printV('Failed to fetch available payment types: ${responseBody['message']}');
137
return [];
138
}
@@ -151,9 +146,8 @@ class OnRamperBuyProvider extends BuyProvider {
146
final url = Uri.https(_baseApiUrl, '$supported/onramps/all');
147
148
try {
154
- final response =
155
- await ProxyWrapper().get(clearnetUri: url, headers: {'Authorization': _apiKey, 'accept': 'application/json'});
156
-
149
+ final response = await ProxyWrapper()
150
+ .get(clearnetUri: url, headers: {'Authorization': _apiKey, 'accept': 'application/json'});
151
152
if (response.statusCode == 200) {
153
final Map<String, dynamic> data = jsonDecode(response.body) as Map<String, dynamic>;
@@ -191,8 +185,10 @@ class OnRamperBuyProvider extends BuyProvider {
185
String? countryCode}) async {
186
String? paymentMethod;
187
194
- if (paymentType == PaymentType.all ) paymentMethod = null;
195
- else if (paymentType == PaymentType.unknown) paymentMethod = customPaymentMethodType;
188
+ if (paymentType == PaymentType.all)
189
+ paymentMethod = null;
190
+ else if (paymentType == PaymentType.unknown)
191
+ paymentMethod = customPaymentMethodType;
192
else if (paymentType != null) paymentMethod = normalizePaymentMethod(paymentType);
193
194
final actionType = isBuyAction ? 'buy' : 'sell';
@@ -217,7 +213,7 @@ class OnRamperBuyProvider extends BuyProvider {
213
214
try {
215
final response = await ProxyWrapper().get(clearnetUri: url, headers: headers);
220
-
216
+
217
if (response.statusCode == 200) {
218
final data = jsonDecode(response.body) as List<dynamic>;
219
if (data.isEmpty) return null;
@@ -227,7 +223,6 @@ class OnRamperBuyProvider extends BuyProvider {
223
if (_onrampMetadata.isEmpty) _onrampMetadata = await getOnrampMetadata();
224
225
for (var item in data) {
230
-
226
if (item['errors'] != null) continue;
227
228
final paymentMethod = (item as Map<String, dynamic>)['paymentMethod'] as String;
@@ -237,8 +232,8 @@ class OnRamperBuyProvider extends BuyProvider {
232
233
if (rampMetaData == null) continue;
234
240
- final quote = Quote.fromOnramperJson(
241
- item, isBuyAction, _onrampMetadata, _getPaymentTypeByString(paymentMethod), customPaymentMethodType);
235
+ final quote = Quote.fromOnramperJson(item, isBuyAction, _onrampMetadata,
236
+ _getPaymentTypeByString(paymentMethod), customPaymentMethodType);
237
quote.setFiatCurrency = fiatCurrency;
238
quote.setCryptoCurrency = cryptoCurrency;
239
validQuotes.add(quote);
@@ -266,18 +261,21 @@ class OnRamperBuyProvider extends BuyProvider {
261
String? countryCode}) async {
262
final actionType = isBuyAction ? 'buy' : 'sell';
263
269
- final primaryColor = getColorStr(Theme.of(context).colorScheme.primary,);
264
+ final primaryColor = getColorStr(
265
+ Theme.of(context).colorScheme.primary,
266
+ );
267
final secondaryColor = getColorStr(Theme.of(context).colorScheme.surface);
268
final primaryTextColor = getColorStr(Theme.of(context).colorScheme.onSurface);
272
- final secondaryTextColor =
273
- getColorStr(Theme.of(context).colorScheme.onSurfaceVariant);
269
+ final secondaryTextColor = getColorStr(Theme.of(context).colorScheme.onSurfaceVariant);
270
final containerColor = getColorStr(Theme.of(context).colorScheme.surface);
271
var cardColor = getColorStr(Theme.of(context).colorScheme.surfaceContainer);
272
273
final defaultCrypto =
274
quote.cryptoCurrency.title + _getNormalizeNetwork(quote.cryptoCurrency).toLowerCase();
275
280
- final paymentMethod = quote.paymentType == PaymentType.unknown ? quote.customPaymentMethodType : normalizePaymentMethod(quote.paymentType);
276
+ final paymentMethod = quote.paymentType == PaymentType.unknown
277
+ ? quote.customPaymentMethodType
278
+ : normalizePaymentMethod(quote.paymentType);
279
280
final networkWallets =
281
'${_tagToNetwork(quote.cryptoCurrency.tag ?? quote.cryptoCurrency.title).toLowerCase()}:$cryptoCurrencyAddress';
lib/buy/robinhood/robinhood_buy_provider.dart
+3
-2
@@ -237,8 +237,9 @@ class RobinhoodBuyProvider extends BuyProvider {
237
Uri.https('api.robinhood.com', '/catpay/v1/${cryptoCurrency.title}/quote/', queryParams);
238
239
try {
240
- final response = await ProxyWrapper().get(clearnetUri: uri, headers: {'accept': 'application/json'});
241
-
240
+ final response =
241
+ await ProxyWrapper().get(clearnetUri: uri, headers: {'accept': 'application/json'});
242
+
243
final responseData = jsonDecode(response.body) as Map<String, dynamic>;
244
245
if (response.statusCode == 200) {
lib/buy/sell_buy_states.dart
+1
-2
@@ -8,7 +8,6 @@ class PaymentMethodLoaded extends PaymentMethodLoadingState {}
8
9
class PaymentMethodFailed extends PaymentMethodLoadingState {}
10
11
-
11
abstract class BuySellQuotLoadingState {}
12
13
class InitialBuySellQuotState extends BuySellQuotLoadingState {}
@@ -21,4 +20,4 @@ class BuySellQuotFailed extends BuySellQuotLoadingState {
20
final String? errorMessage;
21
22
BuySellQuotFailed({this.errorMessage});
24
-}
\ No newline at end of file
23
+}
lib/buy/wyre/wyre_buy_provider.dart
+7
-9
@@ -19,13 +19,13 @@ class WyreBuyProvider extends BuyProvider {
19
WyreBuyProvider({required WalletBase wallet, bool isTestEnvironment = false})
20
: baseApiUrl = isTestEnvironment ? _baseTestApiUrl : _baseProductApiUrl,
21
super(
22
- wallet: wallet,
23
- isTestEnvironment: isTestEnvironment,
24
- hardwareWalletVM: null,
25
- supportedCryptoList: supportedCryptoToFiatPairs(
26
- notSupportedCrypto: _notSupportedCrypto, notSupportedFiat: _notSupportedFiat),
27
- supportedFiatList: supportedFiatToCryptoPairs(
28
- notSupportedFiat: _notSupportedFiat, notSupportedCrypto: _notSupportedCrypto));
22
+ wallet: wallet,
23
+ isTestEnvironment: isTestEnvironment,
24
+ hardwareWalletVM: null,
25
+ supportedCryptoList: supportedCryptoToFiatPairs(
26
+ notSupportedCrypto: _notSupportedCrypto, notSupportedFiat: _notSupportedFiat),
27
+ supportedFiatList: supportedFiatToCryptoPairs(
28
+ notSupportedFiat: _notSupportedFiat, notSupportedCrypto: _notSupportedCrypto));
29
30
static const _baseTestApiUrl = 'https://api.testwyre.com';
31
static const _baseProductApiUrl = 'https://api.sendwyre.com';
@@ -89,7 +89,6 @@ class WyreBuyProvider extends BuyProvider {
89
throw BuyException(title: providerDescription, content: 'Url $url is not found!');
90
}
91
92
-
92
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
93
final urlFromResponse = responseJSON['url'] as String;
94
return urlFromResponse;
@@ -120,7 +119,6 @@ class WyreBuyProvider extends BuyProvider {
119
throw BuyException(title: providerDescription, content: 'Quote is not found!');
120
}
121
123
-
122
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
123
final sourceAmount = responseJSON['sourceAmount'] as double;
124
final destAmount = responseJSON['destAmount'] as double;
lib/cake_pay/src/auth/cake_pay_account_page.dart
+6
-9
@@ -25,8 +25,7 @@ class CakePayAccountPage extends BasePage {
25
label: S.of(context).seed_alert_back,
26
child: TextButton(
27
style: ButtonStyle(
28
- overlayColor: WidgetStateColor.resolveWith(
29
- (states) => Colors.transparent),
28
+ overlayColor: WidgetStateColor.resolveWith((states) => Colors.transparent),
29
),
30
onPressed: () => Navigator.pop(context),
31
child: backButton(context),
@@ -41,10 +40,10 @@ class CakePayAccountPage extends BasePage {
40
Widget middle(BuildContext context) {
41
return Text(
42
S.current.account,
44
- style: Theme.of(context).textTheme.titleMedium?.copyWith(
45
- color: Theme.of(context).colorScheme.onSurface,
46
- fontWeight: FontWeight.w600,
47
- ),
43
+ style: Theme.of(context).textTheme.titleMedium?.copyWith(
44
+ color: Theme.of(context).colorScheme.onSurface,
45
+ fontWeight: FontWeight.w600,
46
+ ),
47
);
48
}
49
@@ -66,9 +65,7 @@ class CakePayAccountPage extends BasePage {
65
),
66
),
67
child: CakePayTile(
69
- title: S.of(context).email_address,
70
- subTitle: cakePayAccountViewModel.email
71
- ),
68
+ title: S.of(context).email_address, subTitle: cakePayAccountViewModel.email),
69
),
70
),
71
],
lib/cake_pay/src/auth/cake_pay_verify_otp_page.dart
+1
-3
@@ -146,9 +146,7 @@ class CakePayVerifyOtpPage extends BasePage {
146
});
147
}
148
149
-
150
- void _onOtpSuccessful(BuildContext context) =>
151
- Navigator.pop(context, true);
149
+ void _onOtpSuccessful(BuildContext context) => Navigator.pop(context, true);
150
151
void _verify() async => await _authViewModel.verifyEmail(_codeController.text);
152
}
lib/cake_pay/src/cake_pay_states.dart
-1
@@ -58,7 +58,6 @@ class UserCakePayCardsStateFailure extends UserCakePayCardsState {
58
59
class UserCakePayCardsStateSuccess extends UserCakePayCardsState {}
60
61
-
61
abstract class CakePayVendorState {}
62
63
class InitialCakePayVendorLoadingState extends CakePayVendorState {}
lib/cake_pay/src/cards/cake_pay_buy_card_page.dart
+8
-9
@@ -360,7 +360,8 @@ class CakePayBuyCardPage extends BasePage {
360
},
361
text: S.of(context).purchase_gift_card,
362
isDisabled: !cakePayBuyCardViewModel.isAmountSufficient ||
363
- cakePayBuyCardViewModel.isPurchasing || _sendViewModel.state is ExecutedSuccessfullyState,
363
+ cakePayBuyCardViewModel.isPurchasing ||
364
+ _sendViewModel.state is ExecutedSuccessfullyState,
365
isLoading: _sendViewModel.state is IsExecutingState ||
366
cakePayBuyCardViewModel.isPurchasing,
367
color: Theme.of(context).colorScheme.primary,
@@ -585,8 +586,7 @@ class CakePayBuyCardPage extends BasePage {
586
.map((o) => o.OutputCopyWithParsedAddress(
587
parsedAddress: ParsedAddress(
588
parsedAddressByCurrencyMap: {
588
- cakePayBuyCardViewModel.sendViewModel.selectedCryptoCurrency:
589
- o.address,
589
+ cakePayBuyCardViewModel.sendViewModel.selectedCryptoCurrency: o.address,
590
},
591
handle: 'Cake Pay',
592
profileName: order?.cards.first.cardName ?? 'Cake Pay',
@@ -613,13 +613,13 @@ class CakePayBuyCardPage extends BasePage {
613
titleIconPath: _sendViewModel.selectedCryptoCurrency.iconPath,
614
currency: _sendViewModel.selectedCryptoCurrency,
615
amount: S.of(bottomSheetContext).send_amount,
616
- amountValue: _sendViewModel.amountParsingProxy.asDisplayStringWithSymbol(
617
- _sendViewModel.pendingTransaction!.amount),
616
+ amountValue: _sendViewModel.amountParsingProxy
617
+ .asDisplayStringWithSymbol(_sendViewModel.pendingTransaction!.amount),
618
quantity: 'QTY: ${cakePayBuyCardViewModel.quantity}',
619
fiatAmountValue: _sendViewModel.pendingTransactionFiatAmountFormatted,
620
fee: S.of(bottomSheetContext).send_fee,
621
- feeValue: _sendViewModel.amountParsingProxy.asDisplayStringWithSymbol(
622
- _sendViewModel.pendingTransaction!.fee),
621
+ feeValue: _sendViewModel.amountParsingProxy
622
+ .asDisplayStringWithSymbol(_sendViewModel.pendingTransaction!.fee),
623
feeFiatAmount: _sendViewModel.pendingTransactionFeeFiatAmountFormatted,
624
outputs: displayingOutputs,
625
footerType: FooterType.slideActionButton,
@@ -657,8 +657,7 @@ class CakePayBuyCardPage extends BasePage {
657
.map((o) => o.OutputCopyWithParsedAddress(
658
parsedAddress: ParsedAddress(
659
parsedAddressByCurrencyMap: {
660
- cakePayBuyCardViewModel.sendViewModel.selectedCryptoCurrency:
661
- o.address,
660
+ cakePayBuyCardViewModel.sendViewModel.selectedCryptoCurrency: o.address,
661
},
662
handle: 'Cake Pay',
663
profileName: order?.cards.first.cardName ?? 'Cake Pay',
lib/cake_pay/src/cards/cake_pay_cards_page.dart
+3
-1
@@ -92,7 +92,9 @@ class CakePayCardsPage extends BasePage {
92
93
@override
94
Widget body(BuildContext context) {
95
- return KeyboardHideOverlay(child:CakePayCardsPageBody(cardsListViewModel: _cardsListViewModel, titleColor: titleColor));
95
+ return KeyboardHideOverlay(
96
+ child:
97
+ CakePayCardsPageBody(cardsListViewModel: _cardsListViewModel, titleColor: titleColor));
98
}
99
}
100
lib/cake_pay/src/models/cake_pay_card.dart
+6
-1
@@ -45,7 +45,11 @@ class CakePayCard {
45
final parsedMinValueLocal = _toDouble(json['min_value']);
46
final parsedMinValueUsd = _toDouble(json['min_value_usd']);
47
48
- if (parsedMinValueLocal != null && parsedMinValueLocal > 0 && parsedMinValueUsd != null && parsedMinValueUsd > 0 && parsedMinValueUsd < 10.0) {
48
+ if (parsedMinValueLocal != null &&
49
+ parsedMinValueLocal > 0 &&
50
+ parsedMinValueUsd != null &&
51
+ parsedMinValueUsd > 0 &&
52
+ parsedMinValueUsd < 10.0) {
53
final rate = parsedMinValueLocal / parsedMinValueUsd;
54
final minLocalValueLimit = 10.0 * rate;
55
minValue = minLocalValueLimit.toStringAsFixed(2);
@@ -80,6 +84,7 @@ class CakePayCard {
84
static String stripHtmlIfNeeded(String text) {
85
return text.replaceAll(RegExp(r'<[^>]*>|&[^;]+;'), ' ');
86
}
87
+
88
static double? _toDouble(dynamic v) {
89
if (v == null) return null;
90
if (v is num) return v.toDouble();
lib/cake_pay/src/models/cake_pay_order.dart
+19
-12
@@ -37,15 +37,12 @@ class CakePayOrder {
37
});
38
39
factory CakePayOrder.fromMap(Map<String, dynamic> map) {
40
-
40
final cards = map['cards'] as List<dynamic>;
41
final firstCard = cards.isNotEmpty ? cards.first as Map<String, dynamic> : {};
42
43
return CakePayOrder(
44
orderId: map['order_id'] as String,
46
- cards: cards
47
- .map((x) => OrderCard.fromMap(x as Map<String, dynamic>))
48
- .toList(),
45
+ cards: cards.map((x) => OrderCard.fromMap(x as Map<String, dynamic>)).toList(),
46
externalId: map['external_id'] as String?,
47
amountUsd: map['amount_usd'] as double,
48
totalReceiveAmount: firstCard['subtotal'] as String? ?? '',
@@ -56,7 +53,7 @@ class CakePayOrder {
53
paymentData: PaymentData.fromMap(map['payment_data'] as Map<String, dynamic>));
54
}
55
59
- static CryptoPaymentData? getPaymentDataFor({CakePayPaymentMethod? method,CakePayOrder? order}) {
56
+ static CryptoPaymentData? getPaymentDataFor({CakePayPaymentMethod? method, CakePayOrder? order}) {
57
if (order == null || method == null) return null;
58
59
final data = switch (method) {
@@ -76,7 +73,8 @@ class CakePayOrder {
73
final addr = uri.path;
74
final price = uri.queryParameters['amount'] ?? data.price;
75
79
- return CryptoPaymentData(price: price, address: addr, amount: data.amount, paymentUrls: data.paymentUrls);
76
+ return CryptoPaymentData(
77
+ price: price, address: addr, amount: data.amount, paymentUrls: data.paymentUrls);
78
}
79
80
return data;
@@ -151,12 +149,21 @@ class PaymentData {
149
150
factory PaymentData.fromMap(Map<String, dynamic> map) {
151
return PaymentData(
154
- btc: map['BTC'] != null ? CryptoPaymentData.fromMap(map['BTC'] as Map<String, dynamic>) : null,
155
- btc_ln: map['BTC_LN'] != null ? CryptoPaymentData.fromMap(map['BTC_LN'] as Map<String, dynamic>) : null,
156
- xmr: map['XMR'] != null ? CryptoPaymentData.fromMap(map['XMR'] as Map<String, dynamic>) : null,
157
- ltc: map['LTC'] != null ? CryptoPaymentData.fromMap(map['LTC'] as Map<String, dynamic>) : null,
158
- ltc_mweb: map['LTC_MWEB'] != null ? CryptoPaymentData.fromMap(map['LTC_MWEB'] as Map<String, dynamic>) : null,
159
- zec: map['ZEC_CHAIN'] != null ? CryptoPaymentData.fromMap(map['ZEC_CHAIN'] as Map<String, dynamic>) : null,
152
+ btc:
153
+ map['BTC'] != null ? CryptoPaymentData.fromMap(map['BTC'] as Map<String, dynamic>) : null,
154
+ btc_ln: map['BTC_LN'] != null
155
+ ? CryptoPaymentData.fromMap(map['BTC_LN'] as Map<String, dynamic>)
156
+ : null,
157
+ xmr:
158
+ map['XMR'] != null ? CryptoPaymentData.fromMap(map['XMR'] as Map<String, dynamic>) : null,
159
+ ltc:
160
+ map['LTC'] != null ? CryptoPaymentData.fromMap(map['LTC'] as Map<String, dynamic>) : null,
161
+ ltc_mweb: map['LTC_MWEB'] != null
162
+ ? CryptoPaymentData.fromMap(map['LTC_MWEB'] as Map<String, dynamic>)
163
+ : null,
164
+ zec: map['ZEC_CHAIN'] != null
165
+ ? CryptoPaymentData.fromMap(map['ZEC_CHAIN'] as Map<String, dynamic>)
166
+ : null,
167
invoiceTime: DateTime.fromMillisecondsSinceEpoch(map['invoice_time'] as int),
168
expirationTime: DateTime.fromMillisecondsSinceEpoch(map['expiration_time'] as int),
169
commission: map['commission'] as int?,
lib/cake_pay/src/models/cake_pay_user_credentials.dart
+4
-4
@@ -1,6 +1,6 @@
1
class CakePayUserCredentials {
2
- const CakePayUserCredentials(this.username, this.token);
2
+ const CakePayUserCredentials(this.username, this.token);
3
4
- final String username;
5
- final String token;
6
-}
\ No newline at end of file
4
+ final String username;
5
+ final String token;
6
+}
lib/cake_pay/src/widgets/cake_pay_tile.dart
+6
-6
@@ -15,7 +15,7 @@ class CakePayTile extends StatelessWidget {
15
@override
16
Widget build(BuildContext context) {
17
final colorScheme = Theme.of(context).colorScheme;
18
-
18
+
19
return GestureDetector(
20
onTap: onTap,
21
child: Row(
@@ -27,16 +27,16 @@ class CakePayTile extends StatelessWidget {
27
Text(
28
title,
29
style: Theme.of(context).textTheme.bodySmall?.copyWith(
30
- color: colorScheme.onSurfaceVariant,
31
- ),
30
+ color: colorScheme.onSurfaceVariant,
31
+ ),
32
),
33
SizedBox(height: 8),
34
Text(
35
subTitle,
36
style: Theme.of(context).textTheme.titleMedium?.copyWith(
37
- color: colorScheme.onSurface,
38
- fontWeight: FontWeight.w600,
39
- ),
37
+ color: colorScheme.onSurface,
38
+ fontWeight: FontWeight.w600,
39
+ ),
40
),
41
],
42
)
lib/cake_pay/src/widgets/denominations_amount_widget.dart
+7
-7
@@ -65,18 +65,18 @@ class _DenominationsAmountWidgetState extends State<DenominationsAmountWidget> {
65
mainAxisSize: MainAxisSize.min,
66
children: [
67
DropdownFilterList(
68
- items: widget.denominations
69
- .map((e) => e.value.toString())
70
- .toList(),
68
+ items: widget.denominations.map((e) => e.value.toString()).toList(),
69
itemPrefix: widget.fiatCurrency,
70
selectedItem: _selected.$1,
71
onItemSelected: (value) {
74
- setState(() => _selected = (value, widget.denominations
75
- .firstWhere((e) => e.value.toString() == value)
76
- .cardId));
72
+ setState(() => _selected = (
73
+ value,
74
+ widget.denominations.firstWhere((e) => e.value.toString() == value).cardId
75
+ ));
76
widget.amountController.text = value;
77
widget.onAmountChanged(value);
79
- widget.cakePayBuyCardViewModel.selectedDenomination = (_selected.$1, _selected.$2);
78
+ widget.cakePayBuyCardViewModel.selectedDenomination =
79
+ (_selected.$1, _selected.$2);
80
},
81
),
82
const SizedBox(height: 4),
lib/cake_pay/src/widgets/enter_amount_widget.dart
+9
-10
@@ -59,12 +59,11 @@ class EnterAmountWidget extends StatelessWidget {
59
mainAxisSize: MainAxisSize.min,
60
children: [
61
Text('QTY ', style: Theme.of(context).textTheme.titleMedium!),
62
- Text(
63
- '1',
64
- style: Theme.of(context).textTheme
65
- .titleMedium!
66
- .copyWith(color: Theme.of(context).colorScheme.onSurfaceVariant)
67
- ),
62
+ Text('1',
63
+ style: Theme.of(context)
64
+ .textTheme
65
+ .titleMedium!
66
+ .copyWith(color: Theme.of(context).colorScheme.onSurfaceVariant)),
67
],
68
),
69
),
@@ -87,12 +86,12 @@ class EnterAmountWidget extends StatelessWidget {
86
children: [
87
Text(S.of(context).min_amount(minValue) + ' $fiatCurrency',
88
style: Theme.of(context).textTheme.bodySmall?.copyWith(
90
- color: Theme.of(context).colorScheme.onSurfaceVariant,
91
- )),
89
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
90
+ )),
91
Text(S.of(context).max_amount(maxValue) + ' $fiatCurrency',
92
style: Theme.of(context).textTheme.bodySmall?.copyWith(
94
- color: Theme.of(context).colorScheme.onSurfaceVariant,
95
- )),
93
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
94
+ )),
95
],
96
),
97
Spacer(flex: 1),
lib/cake_pay/src/widgets/flip_card_widget.dart
+8
-9
@@ -21,7 +21,7 @@ class FlipCard extends StatefulWidget {
21
22
class FlipCardState extends State<FlipCard> with SingleTickerProviderStateMixin {
23
late final AnimationController _ctrl =
24
- AnimationController(vsync: this, duration: widget.duration);
24
+ AnimationController(vsync: this, duration: widget.duration);
25
bool _isFront = true;
26
27
void toggleCard() {
@@ -45,18 +45,17 @@ class FlipCardState extends State<FlipCard> with SingleTickerProviderStateMixin
45
transform: Matrix4.identity()
46
..setEntry(3, 2, 0.001)
47
..rotateY(angle),
48
- child: isFront ? widget.front
48
+ child: isFront
49
+ ? widget.front
50
: Transform(
50
- alignment: Alignment.center,
51
- transform: Matrix4.rotationY(math.pi),
52
- child: widget.back,
53
- ),
51
+ alignment: Alignment.center,
52
+ transform: Matrix4.rotationY(math.pi),
53
+ child: widget.back,
54
+ ),
55
);
56
},
57
);
58
58
- return widget.flipOnTouch
59
- ? GestureDetector(onTap: toggleCard, child: content)
60
- : content;
59
+ return widget.flipOnTouch ? GestureDetector(onTap: toggleCard, child: content) : content;
60
}
61
}
lib/cake_pay/src/widgets/link_extractor.dart
+1
-1
@@ -31,7 +31,7 @@ class ClickableLinksText extends StatelessWidget {
31
text: url,
32
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
33
color: Theme.of(context).colorScheme.primary,
34
- fontSize: 18,
34
+ fontSize: 18,
35
),
36
recognizer: TapGestureRecognizer()
37
..onTap = () async {
lib/cake_pay/src/widgets/rounded_overlay_cards_widget.dart
+7
-8
@@ -14,16 +14,15 @@ class RoundedOverlayCards extends StatelessWidget {
14
final screenHeight = MediaQuery.of(context).size.height;
15
return ClipRRect(
16
borderRadius:
17
- BorderRadius.only(bottomLeft: Radius.circular(25.0), bottomRight: Radius.circular(25.0)),
17
+ BorderRadius.only(bottomLeft: Radius.circular(25.0), bottomRight: Radius.circular(25.0)),
18
child: Container(
19
height: screenHeight * 0.50,
20
decoration: BoxDecoration(
21
- borderRadius: BorderRadius.only(
22
- bottomLeft: Radius.circular(24),
23
- bottomRight: Radius.circular(24),
24
- ),
25
- color: Theme.of(context).colorScheme.surfaceContainer
26
- ),
21
+ borderRadius: BorderRadius.only(
22
+ bottomLeft: Radius.circular(24),
23
+ bottomRight: Radius.circular(24),
24
+ ),
25
+ color: Theme.of(context).colorScheme.surfaceContainer),
26
child: Column(
27
children: [
28
ClipRRect(
@@ -44,4 +43,4 @@ class RoundedOverlayCards extends StatelessWidget {
43
),
44
);
45
}
47
-}
\ No newline at end of file
46
+}
lib/cake_pay/src/widgets/three_checkbox_alert_content_widget.dart
+9
-9
@@ -48,8 +48,8 @@ class ThreeCheckboxAlert extends BaseAlertDialog {
48
49
@override
50
VoidCallback get actionRight => () {
51
- actionRightButton(checkbox1, checkbox2, checkbox3);
52
- };
51
+ actionRightButton(checkbox1, checkbox2, checkbox3);
52
+ };
53
54
@override
55
bool get barrierDismissible => alertBarrierDismissible;
@@ -87,13 +87,13 @@ class ThreeCheckboxAlertContent extends StatefulWidget {
87
88
@override
89
_ThreeCheckboxAlertContentState createState() => _ThreeCheckboxAlertContentState(
90
- checkbox1: checkbox1,
91
- toggleCheckbox1: toggleCheckbox1,
92
- checkbox2: checkbox2,
93
- toggleCheckbox2: toggleCheckbox2,
94
- checkbox3: checkbox3,
95
- toggleCheckbox3: toggleCheckbox3,
96
- );
90
+ checkbox1: checkbox1,
91
+ toggleCheckbox1: toggleCheckbox1,
92
+ checkbox2: checkbox2,
93
+ toggleCheckbox2: toggleCheckbox2,
94
+ checkbox3: checkbox3,
95
+ toggleCheckbox3: toggleCheckbox3,
96
+ );
97
98
static _ThreeCheckboxAlertContentState? of(BuildContext context) {
99
return context.findAncestorStateOfType<_ThreeCheckboxAlertContentState>();
lib/cake_pay/src/widgets/user_card_item.dart
+2
-7
@@ -2,12 +2,7 @@ import 'package:flutter/material.dart';
2
import 'image_placeholder.dart';
3
4
class UserCardItem extends StatelessWidget {
5
- UserCardItem({
6
- required this.title,
7
- required this.subTitle,
8
- this.onTap,
9
- this.logoUrl
10
- });
5
+ UserCardItem({required this.title, required this.subTitle, this.onTap, this.logoUrl});
6
7
final VoidCallback? onTap;
8
final String title;
@@ -80,4 +75,4 @@ class UserCardItem extends StatelessWidget {
75
),
76
);
77
}
83
-}
\ No newline at end of file
78
+}
lib/core/address_resolver/address_lookup_provider.dart
-1
@@ -5,7 +5,6 @@ import 'package:cw_core/crypto_currency.dart';
5
import 'package:cw_core/wallet_base.dart';
6
7
abstract class AddressLookupProvider {
8
-
8
AddressSource get source;
9
10
List<CryptoCurrency> get supportedCurrencies;
lib/core/address_resolver/address_resolver_service.dart
+2
-1
@@ -104,7 +104,8 @@ class AddressResolverService {
104
105
if (results.isNotEmpty) {
106
final parsedAddress = results.first.parsedAddressByCurrencyMap[currency];
107
- final parsedAddressStr = parsedAddress == null || parsedAddress.isEmpty ? 'N/A' : parsedAddress;
107
+ final parsedAddressStr =
108
+ parsedAddress == null || parsedAddress.isEmpty ? 'N/A' : parsedAddress;
109
printV('[address resolver service] resolved $src - $cur - $parsedAddressStr');
110
return [results.first];
111
}
lib/core/address_resolver/address_resolver_utils.dart
+2
-1
@@ -14,7 +14,8 @@ class AddressResolverUtils {
14
final result = <CryptoCurrency, String>{};
15
16
for (final currency in currencies) {
17
- final address = await UnstoppableAddressProvider.fetchUnstoppableDomainAddress(domain, currency.title);
17
+ final address =
18
+ await UnstoppableAddressProvider.fetchUnstoppableDomainAddress(domain, currency.title);
19
if (address.isNotEmpty) {
20
result[currency] = address;
21
}
lib/core/address_resolver/bip_353/bip_353_address_provider.dart
+9
-7
@@ -54,15 +54,17 @@ class Bip353AddressProvider extends AddressLookupProvider {
54
printV('Bip353Record.fetchDnsProof error: $e');
55
}
56
57
- return [ParsedAddress(
58
- parsedAddressByCurrencyMap: result,
59
- addressSource: AddressSource.bip353,
60
- handle: query,
61
- bip353DnsProof: dnsProof ?? '',
62
- )];
57
+ return [
58
+ ParsedAddress(
59
+ parsedAddressByCurrencyMap: result,
60
+ addressSource: AddressSource.bip353,
61
+ handle: query,
62
+ bip353DnsProof: dnsProof ?? '',
63
+ )
64
+ ];
65
} catch (e) {
66
printV('[address resolver] Error resolving BIP353 address: $e');
67
return [];
68
}
69
}
68
-}
\ No newline at end of file
70
+}
lib/core/address_resolver/bip_353/bip_353_record.dart
+1
-2
@@ -99,5 +99,4 @@ class Bip353Record {
99
return result;
100
}
101
}
102
-
103
-}
\ No newline at end of file
102
+}
lib/core/address_resolver/ens/ens_record.dart
+12
-12
@@ -9,10 +9,10 @@ import 'package:web3dart/web3dart.dart';
9
10
class EnsRecord {
11
static Future<String> fetchEnsAddress(
12
- String name,
13
- CryptoCurrency cur, {
14
- WalletBase? wallet,
15
- }) async {
12
+ String name,
13
+ CryptoCurrency cur, {
14
+ WalletBase? wallet,
15
+ }) async {
16
Web3Client? _client;
17
18
if (wallet?.type == WalletType.ethereum || wallet?.type == WalletType.polygon) {
@@ -45,11 +45,11 @@ class EnsRecord {
45
}
46
47
static CoinType? getEnsCoinType(CryptoCurrency cur) => switch (cur) {
48
- CryptoCurrency.xmr => CoinType.XMR,
49
- CryptoCurrency.btc => CoinType.BTC,
50
- CryptoCurrency.ltc => CoinType.LTC,
51
- CryptoCurrency.eth => CoinType.ETH,
52
- CryptoCurrency.matic => CoinType.MATIC,
53
- _ => null,
54
- };
55
-}
\ No newline at end of file
48
+ CryptoCurrency.xmr => CoinType.XMR,
49
+ CryptoCurrency.btc => CoinType.BTC,
50
+ CryptoCurrency.ltc => CoinType.LTC,
51
+ CryptoCurrency.eth => CoinType.ETH,
52
+ CryptoCurrency.matic => CoinType.MATIC,
53
+ _ => null,
54
+ };
55
+}
lib/core/address_resolver/fio/fio_address_provider.dart
+15
-15
@@ -34,23 +34,23 @@ class FioAddressProvider extends AddressLookupProvider {
34
}) async {
35
final Map<CryptoCurrency, String> result = {};
36
try {
37
- final bool isFioRegistered = await FioAddressProvider.checkAvail(query);
38
- if (!isFioRegistered) return [];
39
-
40
- for (final cur in currencies) {
41
- final address = await FioAddressProvider.getPubAddress(query, cur.title);
42
- if (address != null && address.isNotEmpty) {
43
- result[cur] = address;
37
+ final bool isFioRegistered = await FioAddressProvider.checkAvail(query);
38
+ if (!isFioRegistered) return [];
39
+
40
+ for (final cur in currencies) {
41
+ final address = await FioAddressProvider.getPubAddress(query, cur.title);
42
+ if (address != null && address.isNotEmpty) {
43
+ result[cur] = address;
44
+ }
45
}
45
- }
46
47
- if (result.isNotEmpty) {
48
- return [
49
- ParsedAddress(
50
- parsedAddressByCurrencyMap: result, addressSource: AddressSource.fio, handle: query)
51
- ];
52
- }
53
- return [];
47
+ if (result.isNotEmpty) {
48
+ return [
49
+ ParsedAddress(
50
+ parsedAddressByCurrencyMap: result, addressSource: AddressSource.fio, handle: query)
51
+ ];
52
+ }
53
+ return [];
54
} catch (e) {
55
printV('FioAddressProvider.resolve error: $e');
56
return [];
lib/core/address_resolver/lnurl_pay/lnurl_pay_address_provider.dart
+3
-2
@@ -16,7 +16,8 @@ class LNUrlPayAddressProvider extends AddressLookupProvider {
16
List<CryptoCurrency> get supportedCurrencies => [CryptoCurrency.btcln];
17
18
@override
19
- bool canHandle(String q) => q.contains('.') && q.contains('@'); // LNURL-pay handle example: user@domain.com
19
+ bool canHandle(String q) =>
20
+ q.contains('.') && q.contains('@'); // LNURL-pay handle example: user@domain.com
21
22
@override
23
bool isEnabled(SettingsStore settingsStore) => settingsStore.lookupsLNUrl;
@@ -63,4 +64,4 @@ class LNUrlPayAddressProvider extends AddressLookupProvider {
64
return [];
65
}
66
}
66
-}
\ No newline at end of file
67
+}
lib/core/address_resolver/lnurl_pay/lnurlpay_record.dart
+1
-1
@@ -13,7 +13,7 @@ class LNUrlPayRecord {
13
final String address;
14
15
static Future<String?> checkWellKnownUsername(String username, CryptoCurrency currency,
16
- {bool allowRethrow = false}) async {
16
+ {bool allowRethrow = false}) async {
17
if (![CryptoCurrency.btc, CryptoCurrency.btcln].contains(currency)) return null;
18
19
// split the string by the @ symbol:
lib/core/address_resolver/mastodon/mastodon_api.dart
-2
@@ -21,7 +21,6 @@ class MastodonAPI {
21
);
22
23
final response = await ProxyWrapper().get(clearnetUri: uri);
24
-
24
25
if (response.statusCode != 200) return null;
26
@@ -49,7 +48,6 @@ class MastodonAPI {
48
);
49
50
final response = await ProxyWrapper().get(clearnetUri: uri);
52
-
51
52
if (response.statusCode != 200) {
53
throw Exception('Unexpected HTTP status: ${response.statusCode}');
lib/core/address_resolver/mastodon/mastodon_user.dart
+5
-6
@@ -15,12 +15,11 @@ class MastodonUser {
15
16
factory MastodonUser.fromJson(Map<String, dynamic> json) {
17
return MastodonUser(
18
- id: json['id'] as String,
19
- username: json['username'] as String? ?? '',
20
- acct: json['acct'] as String,
21
- note: json['note'] as String,
22
- profileImageUrl: json['avatar'] as String? ?? ''
23
- );
18
+ id: json['id'] as String,
19
+ username: json['username'] as String? ?? '',
20
+ acct: json['acct'] as String,
21
+ note: json['note'] as String,
22
+ profileImageUrl: json['avatar'] as String? ?? '');
23
}
24
}
25
lib/core/address_resolver/nostr/nostr_api.dart
+4
-4
@@ -21,9 +21,9 @@ class NostrProfileHandler {
21
}
22
23
static Future<UserMetadata?> processRelays(
24
- ProfilePointer profile,
25
- String nip05Address,
26
- ) async {
24
+ ProfilePointer profile,
25
+ String nip05Address,
26
+ ) async {
27
final userDomain = _extractDomain(nip05Address);
28
const int metaKind = 0;
29
@@ -124,4 +124,4 @@ class NostrProfileHandler {
124
return '';
125
}
126
}
127
-}
\ No newline at end of file
127
+}
lib/core/address_resolver/nostr/nostr_user.dart
+1
-2
@@ -1,4 +1,3 @@
1
-
1
class UserMetadata {
2
final String name;
3
final String lnurl;
@@ -32,4 +31,4 @@ class UserMetadata {
31
website: json['website'] as String? ?? '',
32
);
33
}
35
-}
\ No newline at end of file
34
+}
lib/core/address_resolver/openalias/openalias_record.dart
+1
-1
@@ -66,4 +66,4 @@ class OpenaliasRecord {
66
67
return OpenaliasRecord(address: address, name: name, description: note);
68
}
69
-}
\ No newline at end of file
69
+}
lib/core/address_resolver/parsed_address.dart
+1
-1
@@ -19,4 +19,4 @@ class ParsedAddress {
19
final String profileName;
20
final String description;
21
final String? bip353DnsProof;
22
-}
\ No newline at end of file
22
+}
lib/core/address_resolver/twitter/twitter_address_provider.dart
-1
@@ -11,7 +11,6 @@ import 'package:cw_core/utils/print_verbose.dart';
11
import 'package:cw_core/wallet_base.dart';
12
13
class TwitterAddressProvider extends AddressLookupProvider {
14
-
14
@override
15
AddressSource get source => AddressSource.twitter;
16
lib/core/address_resolver/twitter/twitter_api.dart
+2
-2
@@ -23,14 +23,14 @@ class TwitterApi {
23
path: userPath + userName,
24
queryParameters: queryParams);
25
26
- final response = await ProxyWrapper().get(clearnetUri: uri, headers: headers).catchError((error) {
26
+ final response =
27
+ await ProxyWrapper().get(clearnetUri: uri, headers: headers).catchError((error) {
28
throw Exception('HTTP request failed: $error');
29
});
30
31
if (response.statusCode != 200) {
32
throw Exception('Unexpected http status: ${response.statusCode}');
33
}
33
-
34
35
final Map<String, dynamic> responseJSON = jsonDecode(response.body) as Map<String, dynamic>;
36
if (responseJSON['errors'] != null &&
lib/core/address_resolver/unstoppable/unstoppable_address_provider.dart
+4
-2
@@ -211,13 +211,15 @@ class UnstoppableAddressProvider extends AddressLookupProvider {
211
var address = '';
212
213
try {
214
- final uri = Uri.parse("https://api.unstoppabledomains.com/profile/public/${Uri.encodeQueryComponent(domain)}?fields=records");
214
+ final uri = Uri.parse(
215
+ "https://api.unstoppabledomains.com/profile/public/${Uri.encodeQueryComponent(domain)}?fields=records");
216
final response = await ProxyWrapper().get(clearnetUri: uri);
217
218
final jsonParsed = json.decode(response.body) as Map<String, dynamic>;
219
if (jsonParsed["records"] == null) {
220
throw Exception(".records response from $uri is empty");
220
- };
221
+ }
222
+ ;
223
final records = jsonParsed["records"] as Map<String, dynamic>;
224
final key = "crypto.${ticker.toUpperCase()}.address";
225
if (records[key] == null) {
lib/core/address_resolver/wellknown/wellknown_record.dart
+4
-4
@@ -20,9 +20,9 @@ class WellKnownRecord {
20
static const _jsonLocation = {CryptoCurrency.nano: 'nano-currency'};
21
22
static Future<WellKnownRecord?> fetch(
23
- String username,
24
- CryptoCurrency currency,
25
- ) async {
23
+ String username,
24
+ CryptoCurrency currency,
25
+ ) async {
26
final location = _jsonLocation[currency];
27
if (location == null) {
28
printV('well-known: unsupported coin $currency');
@@ -75,4 +75,4 @@ class WellKnownRecord {
75
}
76
return null;
77
}
78
-}
\ No newline at end of file
78
+}
lib/core/address_resolver/yat/yat_record.dart
+1
-1
@@ -16,4 +16,4 @@ class YatRecord {
16
17
@override
18
String toString() => 'YatRecord(tag: $tag, address: $address)';
19
-}
\ No newline at end of file
19
+}
lib/core/address_resolver/yat/yat_service.dart
+6
-9
@@ -11,8 +11,7 @@ class YatService {
11
static const apiReleaseUrl = "https://a.y.at";
12
static const apiDevUrl = 'https://a.yat.fyi';
13
14
- static String lookupEmojiUrl(String emojiId) =>
15
- "$apiUrl/emoji_id/$emojiId/payment";
14
+ static String lookupEmojiUrl(String emojiId) => "$apiUrl/emoji_id/$emojiId/payment";
15
16
static const String MONERO_SUB_ADDRESS = '0x1002';
17
static const String MONERO_STD_ADDRESS = '0x1001';
@@ -23,9 +22,9 @@ class YatService {
22
};
23
24
static Future<List<YatRecord>> fetchYatAddress(
26
- String emojiId,
27
- String ticker,
28
- ) async {
25
+ String emojiId,
26
+ String ticker,
27
+ ) async {
28
final tagQuery = tags[ticker.toUpperCase()];
29
if (tagQuery == null) return const [];
30
@@ -48,9 +47,7 @@ class YatService {
47
records.add(YatRecord.fromJson(data, tag.toString()));
48
}
49
});
51
- }
52
-
53
- else if (res is List) {
50
+ } else if (res is List) {
51
for (final item in res) {
52
if (item is Map<String, dynamic>) {
53
final tag = item['tag']?.toString() ?? '';
@@ -64,4 +61,4 @@ class YatService {
61
return const [];
62
}
63
}
67
-}
\ No newline at end of file
64
+}
lib/core/address_resolver/yat/yat_store.dart
+30
-34
@@ -25,29 +25,28 @@ class YatLink {
25
static const requestReleaseUrl = ''; //'https://a.y.at/emoji_id/';
26
static const startFlowUrl = ''; // 'https://www.y03btrk.com/4RQSJ/6JHXF/';
27
static const isDevMode = true;
28
- static const tags = <String, List<String>>{"XMR" : ['0x1001', '0x1002'],
29
- "BTC" : ['0x1003'], "LTC" : ['0x1019']};
28
+ static const tags = <String, List<String>>{
29
+ "XMR": ['0x1001', '0x1002'],
30
+ "BTC": ['0x1003'],
31
+ "LTC": ['0x1019']
32
+ };
33
31
- static String get apiUrl => YatLink.isDevMode
32
- ? YatLink.apiDevUrl
33
- : YatLink.apiReleaseUrl;
34
+ static String get apiUrl => YatLink.isDevMode ? YatLink.apiDevUrl : YatLink.apiReleaseUrl;
35
36
static String get emojiIdUrl => apiUrl + '/emoji_id/';
37
37
- static String get baseUrl => YatLink.isDevMode
38
- ? YatLink.baseDevUrl
39
- : YatLink.baseReleaseUrl;
38
+ static String get baseUrl => YatLink.isDevMode ? YatLink.baseDevUrl : YatLink.baseReleaseUrl;
39
}
40
41
Future<List<String>> fetchYatAddress(String emojiId, String ticker) async {
42
throw Exception();
43
//final url = YatLink.emojiIdUrl + emojiId + '/payment';
44
//final response = await get(url);
46
-
45
+
46
//if (response.statusCode != 200) {
47
// throw YatException(text: response.body.toString());
48
//}
50
-
49
+
50
//final addresses = <String>[];
51
//final currency = ticker.toUpperCase();
52
//final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -55,7 +54,7 @@ Future<List<String>> fetchYatAddress(String emojiId, String ticker) async {
54
//result.forEach((dynamic key, dynamic value) {
55
// final tag = key as String ?? '';
56
// final record = value as Map<String, dynamic>;
58
-
57
+
58
// if (YatLink.tags[currency]?.contains(tag) ?? false) {
59
// final address = record['address'] as String;
60
// if (address?.isNotEmpty ?? false) {
@@ -80,11 +79,11 @@ Future<String> fetchYatAccessToken(String refreshToken) async {
79
// 'Accept': '*/*'
80
// },
81
// body: bodyJson);
83
-
82
+
83
// if (response.statusCode != 200) {
84
// throw YatException(text: response.body.toString());
85
// }
87
-
86
+
87
// final responseJSON = json.decode(response.body) as Map<String, dynamic>;
88
// return responseJSON['access_token'] as String;
89
//}catch(_) {
@@ -110,7 +109,7 @@ Future<String> fetchYatApiKey(String accessKey) async {
109
// if (response.statusCode != 200) {
110
// throw YatException(text: response.body.toString());
111
// }
113
-
112
+
113
// final responseJSON = json.decode(response.body) as Map<String, dynamic>;
114
// return responseJSON['api_key'] as String;
115
//}catch(_) {
@@ -119,7 +118,8 @@ Future<String> fetchYatApiKey(String accessKey) async {
118
return '';
119
}
120
122
-Future<void> updateEmojiIdAddress(String emojiId, String address, String apiKey, WalletType type) async {
121
+Future<void> updateEmojiIdAddress(
122
+ String emojiId, String address, String apiKey, WalletType type) async {
123
throw Exception();
124
//final url = YatLink.emojiIdUrl + emojiId;
125
//final cur = walletTypeToCryptoCurrency(type);
@@ -166,15 +166,13 @@ Future<String> visualisationForEmojiId(String emojiId) async {
166
class YatStore = YatStoreBase with _$YatStore;
167
168
abstract class YatStoreBase with Store {
169
- YatStoreBase({
170
- required this.appStore,
171
- required this.secureStorage})
172
- : _wallet = appStore.wallet,
173
- emoji = appStore.wallet?.walletInfo?.yatEmojiId ?? '',
174
- refreshToken = '',
175
- accessToken = '',
176
- apiKey = '',
177
- emojiIncommingSC = StreamController<String>.broadcast() {
169
+ YatStoreBase({required this.appStore, required this.secureStorage})
170
+ : _wallet = appStore.wallet,
171
+ emoji = appStore.wallet?.walletInfo?.yatEmojiId ?? '',
172
+ refreshToken = '',
173
+ accessToken = '',
174
+ apiKey = '',
175
+ emojiIncommingSC = StreamController<String>.broadcast() {
176
//reaction((_) => appStore.wallet, _onWalletChange);
177
//reaction((_) => emoji, (String _) => _onEmojiChange());
178
//reaction((_) => refreshToken, (String _) => _onRefreshTokenChange());
@@ -209,24 +207,22 @@ abstract class YatStoreBase with Store {
207
Stream<String> get emojiIncommingStream => emojiIncommingSC.stream;
208
209
@observable
212
- WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>?
213
- _wallet;
210
+ WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>? _wallet;
211
212
Future<void> init() async {
213
if (_wallet == null) {
214
return;
215
}
216
220
- refreshToken = await secureStorage.read(key: yatRefreshTokenKey(_wallet!.walletInfo.name)) ?? '';
217
+ refreshToken =
218
+ 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)) ?? '';
221
}
224
-
222
+
223
@action
224
void _onWalletChange(
227
- WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
228
- TransactionInfo>
229
- wallet) {
225
+ WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> wallet) {
226
this._wallet = wallet;
227
emoji = wallet?.walletInfo?.yatEmojiId ?? '';
228
init();
@@ -252,7 +248,7 @@ abstract class YatStoreBase with Store {
248
@action
249
Future<void> _onRefreshTokenChange() async {
250
throw Exception();
255
-
251
+
252
//try {
253
// await secureStorage.write(key: yatRefreshTokenKey(_wallet.walletInfo.name), value: refreshToken);
254
// accessToken = await fetchYatAccessToken(refreshToken);
@@ -269,7 +265,7 @@ abstract class YatStoreBase with Store {
265
//final result = <String, String>{};
266
//final tags = YatLink.tags[_wallet.currency.toString().toUpperCase()];
267
//String tag = tags.first;
272
-
268
+
269
//if (_wallet.type == WalletType.monero
270
// && _wallet.walletAddresses.address.startsWith('4')) {
271
// tag = tags.last;
@@ -277,7 +273,7 @@ abstract class YatStoreBase with Store {
273
//result[tag] = '${_wallet.walletAddresses.address}|${_wallet.name}';
274
//final addressJson = json.encode([result]);
275
//final addressJsonBytes = utf8.encode(addressJson);
280
-
276
+
277
//return base64.encode(addressJsonBytes);
278
return '';
279
}
lib/core/address_resolver/zano/zano_alias_address_provider.dart
-1
@@ -10,7 +10,6 @@ import 'package:cw_core/utils/proxy_wrapper.dart';
10
import 'package:cw_core/wallet_base.dart';
11
12
class ZanoAliasAddressProvider extends AddressLookupProvider {
13
-
13
@override
14
AddressSource get source => AddressSource.zanoAlias;
15
lib/core/address_resolver/zcash/zcash_names_record.dart
+1
-2
@@ -67,8 +67,7 @@ class ZcashNamesRecord {
67
}
68
69
static bool _isValidZcashAddress(String address) {
70
- final pattern =
71
- AddressValidator.getAddressFromStringPattern(CryptoCurrency.zec);
70
+ final pattern = AddressValidator.getAddressFromStringPattern(CryptoCurrency.zec);
71
if (pattern == null) return false;
72
return RegExp('^(?:$pattern)\$').hasMatch(address);
73
}
lib/core/address_validator.dart
+28
-29
@@ -12,29 +12,29 @@ const AFTER_REGEX = '(\$|\\s)';
12
class AddressValidator extends TextValidator {
13
AddressValidator({required CryptoCurrency type, bool isTestnet = false})
14
: super(
15
- errorMessage: S.current.error_text_address,
16
- useAdditionalValidation: [CryptoCurrency.btc, CryptoCurrency.ltc].contains(type)
17
- ? (String txt) {
18
- final RegExp lightningInvoiceRegex = RegExp(
19
- r'^(lightning:)?(lnbc|lntb|lnbs|lnbcrt|lnurl)[a-z0-9]+$',
20
- caseSensitive: false);
21
- if (lightningInvoiceRegex.hasMatch(txt)) return true;
15
+ errorMessage: S.current.error_text_address,
16
+ useAdditionalValidation: [CryptoCurrency.btc, CryptoCurrency.ltc].contains(type)
17
+ ? (String txt) {
18
+ final RegExp lightningInvoiceRegex = RegExp(
19
+ r'^(lightning:)?(lnbc|lntb|lnbs|lnbcrt|lnurl)[a-z0-9]+$',
20
+ caseSensitive: false);
21
+ if (lightningInvoiceRegex.hasMatch(txt)) return true;
22
23
- return BitcoinAddressUtils.validateAddress(
24
- address: txt,
25
- network: type == CryptoCurrency.btc
26
- ? isTestnet
27
- ? BitcoinNetwork.testnet
28
- : BitcoinNetwork.mainnet
29
- : LitecoinNetwork.mainnet,
30
- );
31
- }
32
- : type == CryptoCurrency.zano
33
- ? zano?.validateAddress
34
- : null,
35
- pattern: getPattern(type, isTestnet: isTestnet),
36
- length: getLength(type),
37
- );
23
+ return BitcoinAddressUtils.validateAddress(
24
+ address: txt,
25
+ network: type == CryptoCurrency.btc
26
+ ? isTestnet
27
+ ? BitcoinNetwork.testnet
28
+ : BitcoinNetwork.mainnet
29
+ : LitecoinNetwork.mainnet,
30
+ );
31
+ }
32
+ : type == CryptoCurrency.zano
33
+ ? zano?.validateAddress
34
+ : null,
35
+ pattern: getPattern(type, isTestnet: isTestnet),
36
+ length: getLength(type),
37
+ );
38
39
static const List<CryptoCurrency> reliableValidateCurrencies = [
40
CryptoCurrency.xmr,
@@ -170,8 +170,7 @@ class AddressValidator extends TextValidator {
170
case CryptoCurrency.hbar:
171
pattern = '[0-9a-zA-Z.]+';
172
case CryptoCurrency.zec:
173
- pattern =
174
- '(?:'
173
+ pattern = '(?:'
174
't1[0-9A-Za-z]{33}'
175
'|t3[0-9A-Za-z]{33}'
176
'|zs[a-z0-9]{76}'
@@ -195,7 +194,8 @@ class AddressValidator extends TextValidator {
194
case CryptoCurrency.pivx:
195
pattern = 'D([1-9a-km-zA-HJ-NP-Z]){33}';
196
case CryptoCurrency.btcln:
198
- pattern = r'(lightning:)?(lnbc|lntb|lnbs|lnbcrt|lnurl|LNBC|LNTB|LNBS|LNBCRT|LNURL)[a-zA-Z0-9]+';
197
+ pattern =
198
+ r'(lightning:)?(lnbc|lntb|lnbs|lnbcrt|lnurl|LNBC|LNTB|LNBS|LNBCRT|LNURL)[a-zA-Z0-9]+';
199
case CryptoCurrency.zano:
200
pattern = r'([1-9A-HJ-NP-Za-km-z]{90,200})|(@[\w\d.-]+)';
201
case CryptoCurrency.doge:
@@ -369,7 +369,7 @@ class AddressValidator extends TextValidator {
369
'|([0-9a-zA-Z]{106})';
370
case CryptoCurrency.btc:
371
pattern =
372
- '${P2pkhAddress.regex.pattern}|${P2shAddress.regex.pattern}|${P2wpkhAddress.regex.pattern}|${P2trAddress.regex.pattern}|${P2wshAddress.regex.pattern}|${SilentPaymentAddress.regex.pattern}';
372
+ '${P2pkhAddress.regex.pattern}|${P2shAddress.regex.pattern}|${P2wpkhAddress.regex.pattern}|${P2trAddress.regex.pattern}|${P2wshAddress.regex.pattern}|${SilentPaymentAddress.regex.pattern}';
373
case CryptoCurrency.ltc:
374
pattern = '([^0-9a-zA-Z]|^)^L[a-zA-Z0-9]{26,33}([^0-9a-zA-Z]|\$)'
375
'|([^0-9a-zA-Z]|^)[LM][a-km-zA-HJ-NP-Z1-9]{26,33}([^0-9a-zA-Z]|\$)'
@@ -394,8 +394,7 @@ class AddressValidator extends TextValidator {
394
case CryptoCurrency.zano:
395
pattern = '([1-9A-HJ-NP-Za-km-z]{90,200})|(@[\w\d.-]+)';
396
case CryptoCurrency.zec:
397
- pattern =
398
- '(?:'
397
+ pattern = '(?:'
398
't1[0-9A-Za-z]{33}'
399
'|t3[0-9A-Za-z]{33}'
400
'|zs[a-z0-9]{76}'
@@ -419,4 +418,4 @@ class AddressValidator extends TextValidator {
418
419
return pattern != null ? "($pattern)" : null;
420
}
422
-}
\ No newline at end of file
421
+}
lib/core/amount_validator.dart
+3
-3
@@ -12,9 +12,9 @@ class AmountValidator extends TextValidator {
12
String? minValue,
13
String? maxValue,
14
}) {
15
- symbolsAmountValidator =
16
- SymbolsAmountValidator(isAutovalidate: isAutovalidate);
17
- decimalAmountValidator = DecimalAmountValidator(currency: currency,isAutovalidate: isAutovalidate);
15
+ symbolsAmountValidator = SymbolsAmountValidator(isAutovalidate: isAutovalidate);
16
+ decimalAmountValidator =
17
+ DecimalAmountValidator(currency: currency, isAutovalidate: isAutovalidate);
18
19
amountMinValidator = AmountMinValidator(
20
minValue: minValue,
lib/core/auth_state.dart
-1
@@ -17,4 +17,3 @@ class AuthenticationBanned extends AuthState {
17
18
final String error;
19
}
20
-
lib/core/backup_service.dart
+26
-21
@@ -25,8 +25,8 @@ import 'package:cake_wallet/wallet_types.g.dart';
25
import 'package:cake_backup/backup.dart' as cake_backup;
26
27
class $BackupService {
28
- $BackupService(this._secureStorage, this.transactionDescriptionBox,
29
- this.keyService, this.sharedPreferences)
28
+ $BackupService(
29
+ this._secureStorage, this.transactionDescriptionBox, this.keyService, this.sharedPreferences)
30
: cipher = Cryptography.instance.chacha20Poly1305Aead(),
31
correctWallets = <WalletInfo>[];
32
@@ -42,7 +42,6 @@ class $BackupService {
42
final KeyService keyService;
43
List<WalletInfo> correctWallets;
44
45
-
45
Future<void> importBackupV1(Uint8List data, String password, {required String nonce}) async {
46
final appDir = await getAppDir();
47
final decryptedData = await _decryptV1(data, password, nonce);
@@ -59,7 +58,8 @@ class $BackupService {
58
} else {
59
Directory('${appDir.path}/' + filename)..create(recursive: true);
60
}
62
- };
61
+ }
62
+ ;
63
64
await verifyWallets();
65
await _importKeychainDumpV1(password, nonce: nonce);
@@ -101,7 +101,8 @@ class $BackupService {
101
dir.createSync(recursive: true);
102
}
103
}
104
- };
104
+ }
105
+ ;
106
107
await verifyWallets();
108
await importKeychainDumpV2(password);
@@ -112,7 +113,9 @@ class $BackupService {
113
Future<void> verifyWallets() async {
114
await performHiveMigration(); // for backups made before sqlite migration
115
await performTradeHiveMigration(_secureStorage);
115
- correctWallets = (await WalletInfo.getAll()).where((info) => availableWalletTypes.contains(info.type)).toList();
116
+ correctWallets = (await WalletInfo.getAll())
117
+ .where((info) => availableWalletTypes.contains(info.type))
118
+ .toList();
119
120
if (correctWallets.isEmpty) {
121
printV('Correct wallets not detected');
@@ -133,12 +136,11 @@ class $BackupService {
136
MapEntry(key, TransactionDescription.fromJson(value as Map<String, dynamic>)));
137
var box = transactionDescriptionBox;
138
if (!box.isOpen) {
136
- final transactionDescriptionsBoxKey =
137
- await getEncryptionKey(secureStorage: _secureStorage, forKey: TransactionDescription.boxKey);
138
- box = await CakeHive.openBox<TransactionDescription>(
139
- TransactionDescription.boxName,
140
- encryptionKey: transactionDescriptionsBoxKey);
141
- }
139
+ final transactionDescriptionsBoxKey = await getEncryptionKey(
140
+ secureStorage: _secureStorage, forKey: TransactionDescription.boxKey);
141
+ box = await CakeHive.openBox<TransactionDescription>(TransactionDescription.boxName,
142
+ encryptionKey: transactionDescriptionsBoxKey);
143
+ }
144
await box.putAll(descriptionsMap);
145
}
146
@@ -152,7 +154,8 @@ class $BackupService {
154
155
final data = json.decode(preferencesFile.readAsStringSync()) as Map<String, dynamic>;
156
155
- try { // shouldn't throw an error but just in case, so it doesn't stop the backup restore
157
+ try {
158
+ // shouldn't throw an error but just in case, so it doesn't stop the backup restore
159
for (var entry in data.entries) {
160
String key = entry.key;
161
dynamic value = entry.value;
@@ -170,7 +173,8 @@ class $BackupService {
173
await sharedPreferences.setStringList(key, value);
174
} else {
175
if (kDebugMode) {
173
- printV('Skipping individual save for key "$key": Unsupported type (${value.runtimeType}). Value: $value');
176
+ printV(
177
+ 'Skipping individual save for key "$key": Unsupported type (${value.runtimeType}). Value: $value');
178
}
179
}
180
}
@@ -187,9 +191,7 @@ class $BackupService {
191
currentWalletName = correctWallets.first.name;
192
currentWalletType = serializeToInt(correctWallets.first.type);
193
}
190
- } catch (e) {
191
-
192
- }
194
+ } catch (e) {}
195
196
if (DeviceInfo.instance.isDesktop) {
197
await sharedPreferences.setInt(PreferencesKey.currentTheme, ThemeList.darkTheme.raw);
@@ -247,8 +249,8 @@ class $BackupService {
249
for (var key in (keychainJSON['_all'] as Map<String, dynamic>).keys) {
250
try {
251
if (!key.startsWith('MONERO_WALLET_')) continue;
250
- final decodedPassword = decodeWalletPassword(
251
- password: keychainJSON['_all'][key].toString());
252
+ final decodedPassword =
253
+ decodeWalletPassword(password: keychainJSON['_all'][key].toString());
254
final walletName = key.split('_WALLET_')[1];
255
final walletType = key.split('_WALLET_')[0].toLowerCase();
256
await importWalletKeychainInfo({
@@ -294,8 +296,11 @@ class $BackupService {
296
}));
297
final backupPasswordKey = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
298
final backupPassword = await _secureStorage.read(key: backupPasswordKey);
297
- final data = utf8.encode(
298
- json.encode({'wallets': wallets, backupPasswordKey: backupPassword, '_all': await _secureStorage.readAll()}));
299
+ final data = utf8.encode(json.encode({
300
+ 'wallets': wallets,
301
+ backupPasswordKey: backupPassword,
302
+ '_all': await _secureStorage.readAll()
303
+ }));
304
final encrypted = await _encryptV2(Uint8List.fromList(data), '$keychainSalt$password');
305
306
return encrypted;
lib/core/backup_service_v3.dart
+33
-30
@@ -73,6 +73,7 @@ class ChunkLength {
73
'plain': plain,
74
};
75
}
76
+
77
@override
78
String toString() {
79
return 'ChunkLength(encrypted: $encrypted, plain: $plain)';
@@ -124,7 +125,9 @@ class BackupMetadata {
125
return BackupMetadata(
126
version: BackupVersion.values[json['version'] as int],
127
sha512sum: json['sha512sum'] as String,
127
- chunks: (json['chunks'] as List<dynamic>).map((chunk) => ChunkDetails.fromJson(chunk as Map<String, dynamic>)).toList(),
128
+ chunks: (json['chunks'] as List<dynamic>)
129
+ .map((chunk) => ChunkDetails.fromJson(chunk as Map<String, dynamic>))
130
+ .toList(),
131
cakeVersion: json['cakeVersion'] as String,
132
);
133
}
@@ -160,7 +163,8 @@ class IncompatibleBackupAppException implements Exception {
163
}
164
165
class BackupServiceV3 extends $BackupService {
163
- BackupServiceV3(super.secureStorage, super.transactionDescriptionBox, super.keyService, super.sharedPreferences);
166
+ BackupServiceV3(super.secureStorage, super.transactionDescriptionBox, super.keyService,
167
+ super.sharedPreferences);
168
169
static BackupVersion get currentVersion => BackupVersion.v3;
170
@@ -170,12 +174,12 @@ class BackupServiceV3 extends $BackupService {
174
175
BackupVersion getVersionFile(File data) {
176
final raf = data.openSync(mode: FileMode.read);
173
-
177
+
178
try {
179
// Read first 4 bytes to check both version and zip signature
180
final buffer = Uint8List(1);
181
final bytesRead = raf.readIntoSync(buffer);
178
-
182
+
183
if (bytesRead == 0) {
184
throw Exception('Invalid backup file: empty file');
185
}
@@ -231,7 +235,7 @@ class BackupServiceV3 extends $BackupService {
235
}
236
237
Future<void> importBackupFileV3(File file, String password,
234
- {String nonce = secrets.backupSalt,bool checkBackupApp = true}) async{
238
+ {String nonce = secrets.backupSalt, bool checkBackupApp = true}) async {
239
// Overall design of v3 backup is the following:
240
// 1. backup.zip - plaintext zip file that user can open with any archive manager
241
// 2. backup.zip/README.txt - text file to let user know what is inside of this file
@@ -259,14 +263,14 @@ class BackupServiceV3 extends $BackupService {
263
throw Exception('Invalid v3 backup: missing data.bin');
264
}
265
final dataStream = dataFile.rawContent!.getStream();
262
-
266
+
267
final decryptedData = File('${file.path}_decrypted'); // decrypted zip file
268
if (decryptedData.existsSync()) {
269
decryptedData.deleteSync();
270
}
271
decryptedData.createSync(recursive: true);
272
decryptedData.writeAsBytesSync(Uint8List(0), mode: FileMode.write, flush: true);
269
-
273
+
274
int chunkIndex = 0;
275
for (var chunk in metadata.chunks) {
276
chunkIndex++;
@@ -275,7 +279,8 @@ class BackupServiceV3 extends $BackupService {
279
280
// readBytes stores position internally, so we don't need to think about it.
281
if (chunk.sha512sum.encrypted != chunkChecksum) {
278
- throw Exception('Invalid v3 backup: chunk (${chunk.length.encrypted} bytes) checksum mismatch at index $chunkIndex\n'
282
+ throw Exception(
283
+ 'Invalid v3 backup: chunk (${chunk.length.encrypted} bytes) checksum mismatch at index $chunkIndex\n'
284
'expected: ${chunk.sha512sum.encrypted}\n'
285
'got: $chunkChecksum');
286
}
@@ -283,7 +288,6 @@ class BackupServiceV3 extends $BackupService {
288
decryptedData.writeAsBytesSync(decryptedChunk, mode: FileMode.append, flush: true);
289
}
290
286
-
291
final sha512sum = (await sha512.bind(decryptedData.openRead()).first).toString();
292
if (sha512sum.toString() != metadata.sha512sum) {
293
throw Exception('Invalid v3 backup: SHA512 checksum mismatch\n'
@@ -301,7 +305,6 @@ class BackupServiceV3 extends $BackupService {
305
final decryptedDataStream = InputFileStream(decryptedData.path);
306
final backupArchive = zip.decodeStream(decryptedDataStream);
307
304
-
308
final appDir = await getAppDir();
309
310
outer:
@@ -315,8 +318,7 @@ class BackupServiceV3 extends $BackupService {
318
}
319
printV("restoring: $filename");
320
if (file.isFile) {
318
- final output = File('${appDir.path}/' + filename)
319
- ..createSync(recursive: true);
321
+ final output = File('${appDir.path}/' + filename)..createSync(recursive: true);
322
final outputStream = OutputFileStream(output.path);
323
file.writeContent(outputStream);
324
outputStream.flush();
@@ -326,7 +328,8 @@ class BackupServiceV3 extends $BackupService {
328
dir.createSync(recursive: true);
329
}
330
}
329
- };
331
+ }
332
+ ;
333
334
// Continue importing the backup the old way
335
await super.verifyWallets();
@@ -344,10 +347,10 @@ class BackupServiceV3 extends $BackupService {
347
{String keychainSalt = secrets.backupKeychainSalt}) async {
348
final appDir = await getAppDir();
349
final keychainDumpFile = File('${appDir.path}/~_keychain_dump');
347
- final decryptedKeychainDumpFileData = await decryptV2(
348
- keychainDumpFile.readAsBytesSync(), '$keychainSalt$password');
349
- final keychainJSON = json.decode(utf8.decode(decryptedKeychainDumpFileData))
350
- as Map<String, dynamic>;
350
+ final decryptedKeychainDumpFileData =
351
+ await decryptV2(keychainDumpFile.readAsBytesSync(), '$keychainSalt$password');
352
+ final keychainJSON =
353
+ json.decode(utf8.decode(decryptedKeychainDumpFileData)) as Map<String, dynamic>;
354
final keychainWalletsInfo = keychainJSON['wallets'] as List;
355
356
final expectedHardwareWallets = keychainWalletsInfo
@@ -358,10 +361,10 @@ class BackupServiceV3 extends $BackupService {
361
362
for (final expectedHardwareWallet in expectedHardwareWallets) {
363
final info = expectedHardwareWallet as Map<String, dynamic>;
361
- final actualWalletInfo = await WalletInfo.get(info['name'] as String, WalletType.values.firstWhere((e) => e.toString() == info['type'] as String));
364
+ final actualWalletInfo = await WalletInfo.get(info['name'] as String,
365
+ WalletType.values.firstWhere((e) => e.toString() == info['type'] as String));
366
if (actualWalletInfo != null &&
363
- info["hardwareWalletType"] !=
364
- actualWalletInfo.hardwareWalletType?.index) {
367
+ info["hardwareWalletType"] != actualWalletInfo.hardwareWalletType?.index) {
368
actualWalletInfo.hardwareWalletType =
369
HardwareWalletType.values[info["hardwareWalletType"] as int];
370
await actualWalletInfo.save();
@@ -390,7 +393,8 @@ class BackupServiceV3 extends $BackupService {
393
final transactionDescriptionDumpFile =
394
File('${tmpDir.path}/~_transaction_descriptions_dump_TMP');
395
393
- final transactionDescriptionData = super.transactionDescriptionBox
396
+ final transactionDescriptionData = super
397
+ .transactionDescriptionBox
398
.toMap()
399
.map((key, value) => MapEntry(key.toString(), value.toJson()));
400
final transactionDescriptionDump = jsonEncode(transactionDescriptionData);
@@ -443,15 +447,14 @@ class BackupServiceV3 extends $BackupService {
447
int chunkIndex = 0;
448
final stopwatch = Stopwatch()..start();
449
printV("Starting backup encryption...");
446
-
450
+
451
metadata.sha512sum = (await sha512.bind(dataBinUnencrypted.openRead()).first).toString();
452
453
final raf = await dataBinUnencrypted.open();
454
451
-
455
while (true) {
456
printV("Reading chunk ${chunkIndex++}");
454
-
457
+
458
stopwatch.reset();
459
final chunk = await raf.read(chunkSize);
460
printV("Chunk read completed in ${stopwatch.elapsed}");
@@ -459,13 +462,14 @@ class BackupServiceV3 extends $BackupService {
462
if (chunk.length == 0) {
463
break;
464
}
462
-
465
+
466
stopwatch.reset();
467
final encryptedChunk = await cake_backup.encrypt(password, chunk);
468
printV("Encryption completed in ${stopwatch.elapsed}");
469
470
stopwatch.reset();
468
- final sha512sumEncryptedChunk = await sha512.bind(Stream.fromIterable([encryptedChunk])).first;
471
+ final sha512sumEncryptedChunk =
472
+ await sha512.bind(Stream.fromIterable([encryptedChunk])).first;
473
final sha512sumUnencryptedChunk = await sha512.bind(Stream.fromIterable([chunk])).first;
474
printV("Hashing completed in ${stopwatch.elapsed}");
475
@@ -481,7 +485,7 @@ class BackupServiceV3 extends $BackupService {
485
plain: chunk.length,
486
),
487
));
484
-
488
+
489
await dataBinWriter.flush();
490
printV("Writing completed in ${stopwatch.elapsed}");
491
}
@@ -495,7 +499,8 @@ class BackupServiceV3 extends $BackupService {
499
500
metadataFile.writeAsStringSync(JsonEncoder.withIndent(' ').convert(metadata.toJson()));
501
final readmeFile = File('${tmpDir.path}/README.txt');
498
- readmeFile.writeAsStringSync('''This is a ${packageInfo.appName} backup. Do not modify this archive.
502
+ readmeFile
503
+ .writeAsStringSync('''This is a ${packageInfo.appName} backup. Do not modify this archive.
504
505
App version: ${packageInfo.version}
506
@@ -524,11 +529,9 @@ This backup was created on ${DateTime.now().toIso8601String()}
529
final sourceAppName = _extractBackupAppName(readmeString);
530
if (sourceAppName == null) return;
531
527
-
532
final currentAppName = (await PackageInfo.fromPlatform()).appName;
533
if (sourceAppName == currentAppName) return;
534
531
-
535
throw IncompatibleBackupAppException(
536
sourceAppName: sourceAppName,
537
currentAppName: currentAppName,
lib/core/csv_export_service.dart
+4
-7
@@ -73,12 +73,8 @@ class CsvExportService {
73
74
// Prefer tx.to/tx.from; fall back to address lists for chains that don't populate them.
75
final address = tx.direction == TransactionDirection.incoming
76
- ? (tx.from?.isNotEmpty == true
77
- ? tx.from!
78
- : (tx.inputAddresses?.firstOrNull ?? ''))
79
- : (tx.to?.isNotEmpty == true
80
- ? tx.to!
81
- : (tx.outputAddresses?.firstOrNull ?? ''));
76
+ ? (tx.from?.isNotEmpty == true ? tx.from! : (tx.inputAddresses?.firstOrNull ?? ''))
77
+ : (tx.to?.isNotEmpty == true ? tx.to! : (tx.outputAddresses?.firstOrNull ?? ''));
78
79
final fee = tx.fee != null && !tx.fee!.isZero ? tx.fee.toString() : '';
80
@@ -213,7 +209,8 @@ class CsvExportService {
209
String _isoDate(DateTime dt) => dt.toUtc().toIso8601String();
210
211
Future<void> exportToCsv(List<ActionListItem> items, BuildContext context) async {
216
- final dataItems = items.whereType<ActionListItem>().where((e) => e is! DateSectionItem).toList();
212
+ final dataItems =
213
+ items.whereType<ActionListItem>().where((e) => e is! DateSectionItem).toList();
214
215
if (dataItems.isEmpty) {
216
await showBar<void>(context, S.current.csv_nothing_to_export);
lib/core/email_validator.dart
+1
-2
@@ -5,7 +5,6 @@ class EmailValidator extends TextValidator {
5
EmailValidator()
6
: super(
7
errorMessage: 'Invalid email address',
8
- pattern:
9
- '^[^@]+@[^@]+\.[^@]+',
8
+ pattern: '^[^@]+@[^@]+\.[^@]+',
9
);
10
}
lib/core/execution_state.dart
+1
-1
@@ -25,4 +25,4 @@ class AwaitingConfirmationState extends ExecutionState {
25
final String? message;
26
final Function()? onConfirm;
27
final Function()? onCancel;
28
-}
\ No newline at end of file
28
+}
lib/core/fiat_conversion_service.dart
+6
-12
@@ -10,7 +10,6 @@ const _fiatApiOnionAuthority = '46wisoe2uwipcj2j4og6smiq7hbmj34fkkrquwlzbbsqtgat
10
const _fiatApiPath = '/v2/rates';
11
12
Future<double> _fetchPrice(String crypto, String fiat, bool torOnly) async {
13
-
13
final Map<String, String> queryParams = {
14
'interval_count': '1',
15
'base': crypto.split(".").first,
@@ -23,14 +22,10 @@ Future<double> _fetchPrice(String crypto, String fiat, bool torOnly) async {
22
final onionUri = Uri.http(_fiatApiOnionAuthority, _fiatApiPath, queryParams);
23
final clearnetUri = Uri.https(_fiatApiClearNetAuthority, _fiatApiPath, queryParams);
24
26
- final response = await ProxyWrapper().get(
27
- onionUri: onionUri,
28
- clearnetUri: torOnly ? onionUri : clearnetUri,
29
- headers: {
30
- "x-api-key": secrets.fiatApiKey,
31
- }
32
- );
33
-
25
+ final response = await ProxyWrapper()
26
+ .get(onionUri: onionUri, clearnetUri: torOnly ? onionUri : clearnetUri, headers: {
27
+ "x-api-key": secrets.fiatApiKey,
28
+ });
29
30
if (response.statusCode != 200) {
31
return 0.0;
@@ -52,9 +47,8 @@ Future<double> _fetchPrice(String crypto, String fiat, bool torOnly) async {
47
/// Override specific [CryptoCurrency] to fix its price to the price of another
48
/// e.g. nDEPS should have the same price as DEPS, but only DEPS is tracked
49
CryptoCurrency _overrideCryptoCurrency(CryptoCurrency crypto) {
55
- if (crypto.title == CryptoCurrency.ndeps.title)
56
- return CryptoCurrency.deps;
57
- return crypto;
50
+ if (crypto.title == CryptoCurrency.ndeps.title) return CryptoCurrency.deps;
51
+ return crypto;
52
}
53
54
class FiatConversionService {
lib/core/mnemonic_length.dart
+1
-1
@@ -14,4 +14,4 @@ int mnemonicLength(WalletType type) {
14
default:
15
return 0;
16
}
17
-}
\ No newline at end of file
17
+}
lib/core/monero_account_label_validator.dart
+4
-4
@@ -4,8 +4,8 @@ import 'package:cake_wallet/core/validator.dart';
4
class MoneroLabelValidator extends TextValidator {
5
MoneroLabelValidator()
6
: super(
7
- errorMessage: S.current.error_text_account_name,
8
- pattern: '^[a-zA-Z0-9_ ]{1,15}\$',
9
- minLength: 1,
10
- maxLength: 15);
7
+ errorMessage: S.current.error_text_account_name,
8
+ pattern: '^[a-zA-Z0-9_ ]{1,15}\$',
9
+ minLength: 1,
10
+ maxLength: 15);
11
}
lib/core/open_crypto_pay/open_cryptopay_service.dart
+8
-14
@@ -9,8 +9,7 @@ import 'package:cw_core/utils/proxy_wrapper.dart';
9
10
class OpenCryptoPayService {
11
static bool isOpenCryptoPayQR(String value) =>
12
- value.toLowerCase().contains("lightning=lnurl") ||
13
- value.toLowerCase().startsWith("lnurl");
12
+ value.toLowerCase().contains("lightning=lnurl") || value.toLowerCase().startsWith("lnurl");
13
14
static bool requiresClientCommit(CryptoCurrency currency) =>
15
[CryptoCurrency.xmr, CryptoCurrency.zano, CryptoCurrency.sol].contains(currency) ||
@@ -71,8 +70,8 @@ class OpenCryptoPayService {
70
);
71
}
72
74
- Future<(_OpenCryptoPayQuote, Map<String, List<OpenCryptoPayQuoteAsset>>)>
75
- _getOpenCryptoPayParams(Uri uri) async {
73
+ Future<(_OpenCryptoPayQuote, Map<String, List<OpenCryptoPayQuoteAsset>>)> _getOpenCryptoPayParams(
74
+ Uri uri) async {
75
final response = await ProxyWrapper().get(clearnetUri: uri);
76
77
if (response.statusCode == 200) {
@@ -90,18 +89,15 @@ class OpenCryptoPayService {
89
final method = transferAmount['method'] as String;
90
methods[method] = [];
91
for (final assetJson in transferAmount['assets'] as List) {
93
- final asset = OpenCryptoPayQuoteAsset.fromJson(
94
- assetJson as Map<String, dynamic>);
92
+ final asset = OpenCryptoPayQuoteAsset.fromJson(assetJson as Map<String, dynamic>);
93
methods[method]?.add(asset);
94
}
95
}
96
97
log(responseBody.toString());
98
101
- final quote = _OpenCryptoPayQuote.fromJson(
102
- responseBody['callback'] as String,
103
- responseBody['displayName'] as String?,
104
- responseBody['quote'] as Map<String, dynamic>);
99
+ final quote = _OpenCryptoPayQuote.fromJson(responseBody['callback'] as String,
100
+ responseBody['displayName'] as String?, responseBody['quote'] as Map<String, dynamic>);
101
102
return (quote, methods);
103
} else {
@@ -110,8 +106,7 @@ class OpenCryptoPayService {
106
}
107
}
108
113
- Future<Uri> getOpenCryptoPayAddress(
114
- OpenCryptoPayRequest request, CryptoCurrency asset) async {
109
+ Future<Uri> getOpenCryptoPayAddress(OpenCryptoPayRequest request, CryptoCurrency asset) async {
110
final uri = Uri.parse(request.callbackUrl);
111
final queryParams = Map.of(uri.queryParameters);
112
@@ -135,8 +130,7 @@ class OpenCryptoPayService {
130
131
if (result.queryParameters['amount'] != null) return result;
132
138
- final newQueryParameters =
139
- Map<String, dynamic>.from(result.queryParameters);
133
+ final newQueryParameters = Map<String, dynamic>.from(result.queryParameters);
134
135
newQueryParameters['amount'] = _getAmountByAsset(request, asset);
136
return Uri(
lib/core/seed_validator.dart
+2
-3
@@ -22,8 +22,7 @@ class SeedValidator extends Validator<MnemonicItem> {
22
final String language;
23
final List<String> _words;
24
25
- static List<String> getWordList(
26
- {required WalletType type, required String language}) {
25
+ static List<String> getWordList({required WalletType type, required String language}) {
26
switch (type) {
27
case WalletType.bitcoin:
28
return getBitcoinWordList(language);
@@ -49,7 +48,7 @@ class SeedValidator extends Validator<MnemonicItem> {
48
case WalletType.tron:
49
return tron!.getTronWordList(language);
50
case WalletType.wownero:
52
- return wownero!.getWowneroWordList(language);
51
+ return wownero!.getWowneroWordList(language);
52
case WalletType.zano:
53
return zano!.getWordList(language);
54
case WalletType.decred:
lib/core/selectable_option.dart
-3
@@ -5,7 +5,6 @@ abstract class SelectableItem {
5
6
class OptionTitle extends SelectableItem {
7
OptionTitle({required String title}) : super(title: title);
8
-
8
}
9
10
abstract class SelectableOption extends SelectableItem {
@@ -43,5 +42,3 @@ abstract class SelectableOption extends SelectableItem {
42
43
set isOptionSelected(bool isSelected) => false;
44
}
46
-
47
-
lib/core/socks_proxy_node_address_validator.dart
+2
-3
@@ -4,7 +4,6 @@ import 'package:cake_wallet/generated/i18n.dart';
4
class SocksProxyNodeAddressValidator extends TextValidator {
5
SocksProxyNodeAddressValidator()
6
: super(
7
- errorMessage: S.current.error_text_node_proxy_address,
8
- pattern:
9
- '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:[0-9]+\$');
7
+ errorMessage: S.current.error_text_node_proxy_address,
8
+ pattern: '^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}:[0-9]+\$');
9
}
lib/core/template_validator.dart
+5
-6
@@ -4,9 +4,8 @@ import 'package:cake_wallet/generated/i18n.dart';
4
class TemplateValidator extends TextValidator {
5
TemplateValidator()
6
: super(
7
- minLength: 0,
8
- maxLength: 0,
9
- pattern: '''^[^`,'"]{1,20}\$''',
10
- errorMessage: S.current.error_text_template
11
- );
12
-}
\ No newline at end of file
7
+ minLength: 0,
8
+ maxLength: 0,
9
+ pattern: '''^[^`,'"]{1,20}\$''',
10
+ errorMessage: S.current.error_text_template);
11
+}
lib/core/universal_address_detector.dart
+1
-1
@@ -132,7 +132,7 @@ class UniversalAddressDetector {
132
pattern: RegExp(r'^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$'),
133
currency: CryptoCurrency.btcln,
134
),
135
-
135
+
136
// Lightning Address (LNURL format)
137
_DetectionPattern(
138
pattern: RegExp(r'^(lightning:)?(lnurl)[a-z0-9]+$', caseSensitive: false),
lib/core/utilities.dart
+1
-2
@@ -8,8 +8,7 @@ extension EnhancedList<T> on Iterable<T> {
8
}
9
}
10
11
-
11
String middleTruncate(String s, int head, int tail) {
12
if (s.length <= head + tail + 3) return s;
13
return s.substring(0, head) + '...' + s.substring(s.length - tail);
15
-}
\ No newline at end of file
14
+}
lib/core/validator.dart
+3
-7
@@ -18,9 +18,7 @@ class TextValidator extends Validator<String> {
18
String errorMessage = '',
19
this.length,
20
this.isAutovalidate = false,
21
- }) : super(
22
- errorMessage: errorMessage,
23
- useAdditionalValidation: useAdditionalValidation);
21
+ }) : super(errorMessage: errorMessage, useAdditionalValidation: useAdditionalValidation);
22
23
final int? minLength;
24
final int? maxLength;
@@ -40,8 +38,7 @@ class TextValidator extends Validator<String> {
38
final lengthMatched = length?.contains(value.length) ?? true;
39
if (!lengthMatched) return false;
40
43
- final lowerThanMaxLength =
44
- (maxLength ?? 0) > 0 ? (value.length <= maxLength!) : true;
41
+ final lowerThanMaxLength = (maxLength ?? 0) > 0 ? (value.length <= maxLength!) : true;
42
if (!lowerThanMaxLength) return false;
43
44
if (pattern == null) return true;
@@ -54,6 +51,5 @@ class TextValidator extends Validator<String> {
51
return valueValidated;
52
}
53
57
- bool match(String value) =>
58
- pattern != null ? RegExp(pattern!).hasMatch(value) : false;
54
+ bool match(String value) => pattern != null ? RegExp(pattern!).hasMatch(value) : false;
55
}
lib/core/wallet_creation_service.dart
+2
-1
@@ -35,7 +35,8 @@ class WalletCreationService {
35
36
Future<bool> exists(String name) async {
37
final walletName = name.toLowerCase();
38
- return (await WalletInfo.getAll()).any((walletInfo) => walletInfo.name.toLowerCase() == walletName);
38
+ return (await WalletInfo.getAll())
39
+ .any((walletInfo) => walletInfo.name.toLowerCase() == walletName);
40
}
41
42
Future<bool> typeExists(WalletType type) async {
lib/core/wallet_creation_state.dart
+1
-1
@@ -10,4 +10,4 @@ class WalletCreationFailure extends WalletCreationState {
10
WalletCreationFailure({required this.error});
11
12
final String error;
13
-}
\ No newline at end of file
13
+}
lib/core/wallet_loading_service.dart
+43
-38
@@ -58,10 +58,12 @@ class WalletLoadingService {
58
}
59
}
60
61
- Future<WalletBase> load(WalletType type, String name, {String? password, bool isBackground = false}) async {
61
+ Future<WalletBase> load(WalletType type, String name,
62
+ {String? password, bool isBackground = false}) async {
63
try {
64
if (!isBackground) {
64
- await sharedPreferences.setString(PreferencesKey.backgroundSyncLastTrigger(name), DateTime.now().toIso8601String());
65
+ await sharedPreferences.setString(
66
+ PreferencesKey.backgroundSyncLastTrigger(name), DateTime.now().toIso8601String());
67
}
68
final walletService = walletServiceFactory.call(type);
69
final walletPassword = password ?? (await keyService.getWalletPassword(walletName: name));
@@ -75,10 +77,14 @@ class WalletLoadingService {
77
} catch (error, stack) {
78
String corruptedWalletsSeeds = "Corrupted wallets seeds (if retrievable, empty otherwise):";
79
78
- if(error is WalletDeprecationException) {
79
- if(navigatorKey.currentContext != null) {
80
+ if (error is WalletDeprecationException) {
81
+ if (navigatorKey.currentContext != null) {
82
showModalBottomSheet(
81
- context: navigatorKey.currentContext!, builder: (context)=>WalletDeprecationPopup(type: type, seed: error.seed,));
83
+ context: navigatorKey.currentContext!,
84
+ builder: (context) => WalletDeprecationPopup(
85
+ type: type,
86
+ seed: error.seed,
87
+ ));
88
}
89
} else {
90
await ExceptionHandler.resetLastPopupDate();
@@ -106,8 +112,7 @@ class WalletLoadingService {
112
await updateMoneroWalletPassword(wallet);
113
}
114
109
- await sharedPreferences.setString(
110
- PreferencesKey.currentWalletName, wallet.name);
115
+ await sharedPreferences.setString(PreferencesKey.currentWalletName, wallet.name);
116
await sharedPreferences.setInt(
117
PreferencesKey.currentWalletType, serializeToInt(wallet.type));
118
@@ -130,22 +135,22 @@ class WalletLoadingService {
135
// if all user's wallets are corrupted throw exception
136
final msg = error.toString() + "\n" + corruptedWalletsSeeds;
137
if (navigatorKey.currentContext != null) {
133
- await showPopUp<void>(
134
- context: navigatorKey.currentContext!,
135
- builder: (BuildContext context) {
136
- return AlertWithTwoActions(
137
- alertTitle: "Corrupted seeds",
138
- alertContent: S.of(context).corrupted_seed_notice,
139
- leftButtonText: S.of(context).cancel,
140
- rightButtonText: S.of(context).show_seed,
141
- actionLeftButton: () {
142
- if (context.mounted && Navigator.of(context).canPop()) {
143
- Navigator.of(context).pop();
144
- }
145
- },
146
- actionRightButton: () => showSeedsPopup(context, msg),
147
- );
148
- });
138
+ await showPopUp<void>(
139
+ context: navigatorKey.currentContext!,
140
+ builder: (BuildContext context) {
141
+ return AlertWithTwoActions(
142
+ alertTitle: "Corrupted seeds",
143
+ alertContent: S.of(context).corrupted_seed_notice,
144
+ leftButtonText: S.of(context).cancel,
145
+ rightButtonText: S.of(context).show_seed,
146
+ actionLeftButton: () {
147
+ if (context.mounted && Navigator.of(context).canPop()) {
148
+ Navigator.of(context).pop();
149
+ }
150
+ },
151
+ actionRightButton: () => showSeedsPopup(context, msg),
152
+ );
153
+ });
154
} else {
155
throw msg;
156
}
@@ -159,21 +164,21 @@ class WalletLoadingService {
164
Future<void> showSeedsPopup(BuildContext context, String message) async {
165
Navigator.of(context).pop();
166
await showPopUp<void>(
162
- context: context,
163
- builder: (BuildContext context) {
164
- return AlertWithTwoActions(
165
- alertTitle: "Corrupted seeds",
166
- alertContent: message,
167
- leftButtonText: S.of(context).copy,
168
- rightButtonText: S.of(context).ok,
169
- actionLeftButton: () async {
170
- await Clipboard.setData(ClipboardData(text: message));
171
- },
172
- actionRightButton: () async {
173
- Navigator.of(context).pop();
174
- },
175
- );
176
- });
167
+ context: context,
168
+ builder: (BuildContext context) {
169
+ return AlertWithTwoActions(
170
+ alertTitle: "Corrupted seeds",
171
+ alertContent: message,
172
+ leftButtonText: S.of(context).copy,
173
+ rightButtonText: S.of(context).ok,
174
+ actionLeftButton: () async {
175
+ await Clipboard.setData(ClipboardData(text: message));
176
+ },
177
+ actionRightButton: () async {
178
+ Navigator.of(context).pop();
179
+ },
180
+ );
181
+ });
182
}
183
184
Future<void> updateMoneroWalletPassword(WalletBase wallet) async {
lib/di.dart
+226
-248
@@ -379,7 +379,6 @@ Future<void> setup({
379
return;
380
}
381
382
-
382
getIt.registerSingleton(AuthenticationStore());
383
getIt.registerSingleton<WalletListStore>(WalletListStore());
384
// getIt.registerSingleton(NodeListStoreBase.instance);
@@ -390,13 +389,12 @@ Future<void> setup({
389
settingsStore: getIt.get<SettingsStore>(),
390
// nodeListStore: getIt.get<NodeListStore>(),
391
themeStore: getIt.get<ThemeStore>()));
393
- getIt.registerSingleton<TradesStore>(
394
- TradesStore(appStore: getIt.get<AppStore>()));
392
+ getIt.registerSingleton<TradesStore>(TradesStore(appStore: getIt.get<AppStore>()));
393
getIt.registerSingleton<OrdersStore>(
394
OrdersStore(ordersSource: _ordersSource, settingsStore: getIt.get<SettingsStore>()));
395
getIt.registerSingleton<BridgeTransfersStore>(BridgeTransfersStore());
398
- getIt.registerFactory(() =>
399
- PayjoinTransactionsStore(payjoinSessionSource: _payjoinSessionSource));
396
+ getIt
397
+ .registerFactory(() => PayjoinTransactionsStore(payjoinSessionSource: _payjoinSessionSource));
398
getIt.registerSingleton<TradeFilterStore>(TradeFilterStore());
399
getIt.registerSingleton<OrderFilterStore>(OrderFilterStore());
400
getIt.registerSingleton<TransactionFilterStore>(TransactionFilterStore(getIt.get<AppStore>()));
@@ -411,15 +409,19 @@ Future<void> setup({
409
getIt.registerSingleton<SeedSettingsStore>(SeedSettingsStore());
410
411
getIt.registerFactoryParam<HardwareWalletViewModel, HardwareWalletType, void>((type, _) {
414
- switch(type) {
415
- case HardwareWalletType.bitbox: return getIt<BitboxViewModel>();
416
- case HardwareWalletType.ledger: return getIt<LedgerViewModel>();
417
- case HardwareWalletType.trezor: return getIt<TrezorConnectViewModel>();
412
+ switch (type) {
413
+ case HardwareWalletType.bitbox:
414
+ return getIt<BitboxViewModel>();
415
+ case HardwareWalletType.ledger:
416
+ return getIt<LedgerViewModel>();
417
+ case HardwareWalletType.trezor:
418
+ return getIt<TrezorConnectViewModel>();
419
case HardwareWalletType.cupcake:
420
case HardwareWalletType.coldcard:
421
case HardwareWalletType.seedsigner:
422
case HardwareWalletType.keystone:
422
- throw Exception("This should not have happened, because airgapped Wallets don't need View Models");
423
+ throw Exception(
424
+ "This should not have happened, because airgapped Wallets don't need View Models");
425
}
426
});
427
@@ -427,20 +429,19 @@ Future<void> setup({
429
430
getIt.registerLazySingleton(() => BitboxViewModel());
431
430
- getIt.registerLazySingleton(() => TrezorConnect("cakewallet://trezor_connect",
431
- appName: "Cake Wallet"));
432
+ getIt.registerLazySingleton(
433
+ () => TrezorConnect("cakewallet://trezor_connect", appName: "Cake Wallet"));
434
getIt.registerLazySingleton(() => TrezorConnectViewModel(getIt<TrezorConnect>()));
435
434
-
436
getIt.registerFactory<KeyService>(() => KeyService(getIt.get<SecureStorage>()));
437
437
- getIt.registerFactoryParam<WalletCreationService, WalletType, void>((type, _) =>
438
- WalletCreationService(
439
- initialType: type,
440
- keyService: getIt.get<KeyService>(),
441
- sharedPreferences: getIt.get<SharedPreferences>(),
442
- settingsStore: getIt.get<SettingsStore>(),
443
- ));
438
+ getIt.registerFactoryParam<WalletCreationService, WalletType, void>(
439
+ (type, _) => WalletCreationService(
440
+ initialType: type,
441
+ keyService: getIt.get<KeyService>(),
442
+ sharedPreferences: getIt.get<SharedPreferences>(),
443
+ settingsStore: getIt.get<SettingsStore>(),
444
+ ));
445
446
getIt.registerFactoryParam<AdvancedPrivacySettingsViewModel, WalletType, void>(
447
(type, _) => AdvancedPrivacySettingsViewModel(type, getIt.get<SettingsStore>()));
@@ -451,14 +452,13 @@ Future<void> setup({
452
(WalletType type) => getIt.get<WalletService>(param1: type)));
453
454
getIt.registerFactoryParam<WalletNewVM, NewWalletArguments, void>(
454
- (newWalletArgs, _) => WalletNewVM(
455
- getIt.get<AppStore>(),
456
- getIt.get<WalletCreationService>(param1:newWalletArgs.type),
457
- getIt.get<AdvancedPrivacySettingsViewModel>(param1: newWalletArgs.type),
458
- getIt.get<SeedSettingsViewModel>(),
459
- newWalletArguments: newWalletArgs,
460
- ));
461
-
455
+ (newWalletArgs, _) => WalletNewVM(
456
+ getIt.get<AppStore>(),
457
+ getIt.get<WalletCreationService>(param1: newWalletArgs.type),
458
+ getIt.get<AdvancedPrivacySettingsViewModel>(param1: newWalletArgs.type),
459
+ getIt.get<SeedSettingsViewModel>(),
460
+ newWalletArguments: newWalletArgs,
461
+ ));
462
463
final walletList = await WalletInfo.getAll();
464
@@ -479,62 +479,52 @@ Future<void> setup({
479
);
480
481
getIt.registerFactoryParam<WalletUnlockPage, WalletUnlockArguments, bool>((args, closable) {
482
- return WalletUnlockPage(
483
- getIt.get<WalletUnlockLoadableViewModel>(param1: args),
484
- args.callback,
485
- args.authPasswordHandler,
486
- closable: closable);
482
+ return WalletUnlockPage(getIt.get<WalletUnlockLoadableViewModel>(param1: args), args.callback,
483
+ args.authPasswordHandler,
484
+ closable: closable);
485
}, instanceName: 'wallet_unlock_loadable');
486
487
getIt.registerFactory<WalletUnlockPage>(
490
- () => getIt.get<WalletUnlockPage>(
491
- param1: WalletUnlockArguments(
492
- callback: (bool successful, _) {
493
- if (successful) {
494
- final authStore = getIt.get<AuthenticationStore>();
495
- authStore.allowed();
496
- }}),
497
- param2: false,
498
- instanceName: 'wallet_unlock_loadable'),
499
- instanceName: 'wallet_password_login');
488
+ () => getIt.get<WalletUnlockPage>(
489
+ param1: WalletUnlockArguments(callback: (bool successful, _) {
490
+ if (successful) {
491
+ final authStore = getIt.get<AuthenticationStore>();
492
+ authStore.allowed();
493
+ }
494
+ }),
495
+ param2: false,
496
+ instanceName: 'wallet_unlock_loadable'),
497
+ instanceName: 'wallet_password_login');
498
499
getIt.registerFactoryParam<WalletUnlockPage, WalletUnlockArguments, bool>((args, closable) {
502
- return WalletUnlockPage(
503
- getIt.get<WalletUnlockVerifiableViewModel>(param1: args),
504
- args.callback,
505
- args.authPasswordHandler,
506
- closable: closable);
500
+ return WalletUnlockPage(getIt.get<WalletUnlockVerifiableViewModel>(param1: args), args.callback,
501
+ args.authPasswordHandler,
502
+ closable: closable);
503
}, instanceName: 'wallet_unlock_verifiable');
504
505
getIt.registerFactoryParam<WalletUnlockLoadableViewModel, WalletUnlockArguments, void>((args, _) {
510
- final currentWalletName = getIt
511
- .get<SharedPreferences>()
512
- .getString(PreferencesKey.currentWalletName) ?? '';
506
+ final currentWalletName =
507
+ getIt.get<SharedPreferences>().getString(PreferencesKey.currentWalletName) ?? '';
508
final currentWalletTypeRaw =
514
- getIt.get<SharedPreferences>()
515
- .getInt(PreferencesKey.currentWalletType) ?? 0;
509
+ getIt.get<SharedPreferences>().getInt(PreferencesKey.currentWalletType) ?? 0;
510
final currentWalletType = deserializeFromInt(currentWalletTypeRaw);
511
518
- return WalletUnlockLoadableViewModel(
519
- getIt.get<AppStore>(),
520
- getIt.get<WalletLoadingService>(),
521
- walletName: args.walletName ?? currentWalletName,
522
- walletType: args.walletType ?? currentWalletType);
512
+ return WalletUnlockLoadableViewModel(getIt.get<AppStore>(), getIt.get<WalletLoadingService>(),
513
+ walletName: args.walletName ?? currentWalletName,
514
+ walletType: args.walletType ?? currentWalletType);
515
});
516
525
- getIt.registerFactoryParam<WalletUnlockVerifiableViewModel, WalletUnlockArguments, void>((args, _) {
526
- final currentWalletName = getIt
527
- .get<SharedPreferences>()
528
- .getString(PreferencesKey.currentWalletName) ?? '';
517
+ getIt.registerFactoryParam<WalletUnlockVerifiableViewModel, WalletUnlockArguments, void>(
518
+ (args, _) {
519
+ final currentWalletName =
520
+ getIt.get<SharedPreferences>().getString(PreferencesKey.currentWalletName) ?? '';
521
final currentWalletTypeRaw =
530
- getIt.get<SharedPreferences>()
531
- .getInt(PreferencesKey.currentWalletType) ?? 0;
522
+ getIt.get<SharedPreferences>().getInt(PreferencesKey.currentWalletType) ?? 0;
523
final currentWalletType = deserializeFromInt(currentWalletTypeRaw);
524
534
- return WalletUnlockVerifiableViewModel(
535
- getIt.get<AppStore>(),
536
- walletName: args.walletName ?? currentWalletName,
537
- walletType: args.walletType ?? currentWalletType);
525
+ return WalletUnlockVerifiableViewModel(getIt.get<AppStore>(),
526
+ walletName: args.walletName ?? currentWalletName,
527
+ walletType: args.walletType ?? currentWalletType);
528
});
529
530
getIt.registerFactoryParam<WalletHardwareRestoreViewModel, WalletType, HardwareWalletViewModel>(
@@ -577,29 +567,30 @@ Future<void> setup({
567
);
568
569
getIt.registerFactory(() => DashboardViewModel(
580
- tradeMonitor: getIt.get<TradeMonitor>(),
581
- balanceViewModel: getIt.get<BalanceViewModel>(),
582
- appStore: getIt.get<AppStore>(),
583
- tradesStore: getIt.get<TradesStore>(),
584
- ordersStore: getIt.get<OrdersStore>(),
585
- tradeFilterStore: getIt.get<TradeFilterStore>(),
586
- orderFilterStore: getIt.get<OrderFilterStore>(),
587
- transactionFilterStore: getIt.get<TransactionFilterStore>(),
588
- settingsStore: settingsStore,
589
- yatStore: getIt.get<YatStore>(),
590
- anonpayTransactionsStore: getIt.get<AnonpayTransactionsStore>(),
591
- payjoinTransactionsStore: getIt.get<PayjoinTransactionsStore>(),
592
- sharedPreferences: getIt.get<SharedPreferences>(),
593
- keyService: getIt.get<KeyService>()));
570
+ tradeMonitor: getIt.get<TradeMonitor>(),
571
+ balanceViewModel: getIt.get<BalanceViewModel>(),
572
+ appStore: getIt.get<AppStore>(),
573
+ tradesStore: getIt.get<TradesStore>(),
574
+ ordersStore: getIt.get<OrdersStore>(),
575
+ tradeFilterStore: getIt.get<TradeFilterStore>(),
576
+ orderFilterStore: getIt.get<OrderFilterStore>(),
577
+ transactionFilterStore: getIt.get<TransactionFilterStore>(),
578
+ settingsStore: settingsStore,
579
+ yatStore: getIt.get<YatStore>(),
580
+ anonpayTransactionsStore: getIt.get<AnonpayTransactionsStore>(),
581
+ payjoinTransactionsStore: getIt.get<PayjoinTransactionsStore>(),
582
+ sharedPreferences: getIt.get<SharedPreferences>(),
583
+ keyService: getIt.get<KeyService>()));
584
585
getIt.registerFactoryParam<CardCustomizerBloc, bool, BitcoinAmountDisplayMode?>(
586
(lightningMode, displayMode) {
597
- final wallet = getIt.get<AppStore>().wallet!;
598
- return CardCustomizerBloc(wallet,
599
- lightningMode: lightningMode,
600
- displaySats: wallet.type == WalletType.bitcoin && (displayMode == BitcoinAmountDisplayMode.satoshi ||
601
- (displayMode == BitcoinAmountDisplayMode.satoshiForLightning && lightningMode)));
602
- });
587
+ final wallet = getIt.get<AppStore>().wallet!;
588
+ return CardCustomizerBloc(wallet,
589
+ lightningMode: lightningMode,
590
+ displaySats: wallet.type == WalletType.bitcoin &&
591
+ (displayMode == BitcoinAmountDisplayMode.satoshi ||
592
+ (displayMode == BitcoinAmountDisplayMode.satoshiForLightning && lightningMode)));
593
+ });
594
595
getIt.registerFactory<AccountCreationModal>(() => AccountCreationModal(
596
accountEditOrCreateViewModel: getIt.get<MoneroAccountEditOrCreateViewModel>()));
@@ -608,7 +599,7 @@ Future<void> setup({
599
() => LightningUsernameBloc(getIt.get<AppStore>().wallet!));
600
601
getIt.registerFactory<AuthService>(
611
- () => AuthService(
602
+ () => AuthService(
603
secureStorage: getIt.get<SecureStorage>(),
604
sharedPreferences: getIt.get<SharedPreferences>(),
605
settingsStore: getIt.get<SettingsStore>(),
@@ -781,11 +772,14 @@ Future<void> setup({
772
));
773
774
getIt.registerFactory<NewDashboard>(() => NewDashboard(
784
- dashboardViewModel: getIt.get<DashboardViewModel>(),
785
- bottomSheetService: getIt.get<BottomSheetService>(),
786
- ));
775
+ dashboardViewModel: getIt.get<DashboardViewModel>(),
776
+ bottomSheetService: getIt.get<BottomSheetService>(),
777
+ ));
778
788
- getIt.registerFactory<NewHomePage>(()=>NewHomePage(dashboardViewModel: getIt.get<DashboardViewModel>(),nftViewModel: getIt.get<NFTViewModel>(),));
779
+ getIt.registerFactory<NewHomePage>(() => NewHomePage(
780
+ dashboardViewModel: getIt.get<DashboardViewModel>(),
781
+ nftViewModel: getIt.get<NFTViewModel>(),
782
+ ));
783
784
getIt.registerFactory<DesktopSidebarWrapper>(() {
785
final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();
@@ -878,9 +872,8 @@ Future<void> setup({
872
walletAddressEditOrCreateViewModel:
873
getIt.get<WalletAddressEditOrCreateViewModel>(param1: item)));
874
881
- getIt.registerFactoryParam<AddressInfoPopup, dynamic, void>((dynamic item, _) =>
882
- AddressInfoPopup(
883
- walletAddressEditOrCreateViewModel:
875
+ getIt.registerFactoryParam<AddressInfoPopup, dynamic, void>((dynamic item, _) => AddressInfoPopup(
876
+ walletAddressEditOrCreateViewModel:
877
getIt.get<WalletAddressEditOrCreateViewModel>(param1: item)));
878
879
getIt.registerFactoryParam<ReceiveLabelModal, dynamic, void>((dynamic item, _) =>
@@ -896,21 +889,20 @@ Future<void> setup({
889
890
getIt.registerFactoryParam<SendViewModel, UnspentCoinType?, void>(
891
(coinTypeToSpendFrom, _) => SendViewModel(
899
- getIt.get<AppStore>(),
900
- getIt.get<SendTemplateViewModel>(),
901
- getIt.get<FiatConversionStore>(),
902
- getIt.get<AddressResolverService>(),
903
- getIt.get<BalanceViewModel>(),
904
- getIt.get<ContactListViewModel>(),
905
- _transactionDescriptionBox,
906
- getIt.get<AppStore>().wallet!.isHardwareWallet
907
- ? getIt<HardwareWalletViewModel>(
908
- param1: getIt.get<AppStore>().wallet!.hardwareWalletType!)
909
- : null,
910
- coinTypeToSpendFrom: coinTypeToSpendFrom ?? UnspentCoinType.nonMweb,
911
- getIt.get<UnspentCoinsListViewModel>(param1: coinTypeToSpendFrom),
912
- getIt.get<FeesViewModel>()
913
- ),
892
+ getIt.get<AppStore>(),
893
+ getIt.get<SendTemplateViewModel>(),
894
+ getIt.get<FiatConversionStore>(),
895
+ getIt.get<AddressResolverService>(),
896
+ getIt.get<BalanceViewModel>(),
897
+ getIt.get<ContactListViewModel>(),
898
+ _transactionDescriptionBox,
899
+ getIt.get<AppStore>().wallet!.isHardwareWallet
900
+ ? getIt<HardwareWalletViewModel>(
901
+ param1: getIt.get<AppStore>().wallet!.hardwareWalletType!)
902
+ : null,
903
+ coinTypeToSpendFrom: coinTypeToSpendFrom ?? UnspentCoinType.nonMweb,
904
+ getIt.get<UnspentCoinsListViewModel>(param1: coinTypeToSpendFrom),
905
+ getIt.get<FeesViewModel>()),
906
);
907
908
getIt.registerFactoryParam<SendPage, PaymentRequest?, UnspentCoinType?>(
@@ -973,7 +965,6 @@ Future<void> setup({
965
);
966
967
getIt.registerFactoryParam<WalletEditPage, WalletEditPageArguments, void>((arguments, _) {
976
-
968
return WalletEditPage(
969
pageArguments: WalletEditPageArguments(
970
walletEditViewModel: getIt.get<WalletEditViewModel>(param1: arguments.walletListViewModel),
@@ -1003,7 +994,7 @@ Future<void> setup({
994
if (wallet.type == WalletType.monero ||
995
wallet.type == WalletType.wownero ||
996
wallet.type == WalletType.haven) {
1006
- return MoneroAccountListViewModel(wallet,getIt.get<SettingsStore>());
997
+ return MoneroAccountListViewModel(wallet, getIt.get<SettingsStore>());
998
}
999
throw Exception(
1000
'Unexpected wallet type: ${wallet.type} for generate Monero AccountListViewModel');
@@ -1054,8 +1045,8 @@ Future<void> setup({
1045
nanoAccountCreationViewModel:
1046
getIt.get<NanoAccountEditOrCreateViewModel>(param1: account)));
1047
1057
- getIt.registerFactory(() =>
1058
- DisplaySettingsViewModel(getIt.get<AppStore>(), getIt.get<ThemeStore>()));
1048
+ getIt.registerFactory(
1049
+ () => DisplaySettingsViewModel(getIt.get<AppStore>(), getIt.get<ThemeStore>()));
1050
1051
getIt.registerFactory(() =>
1052
SilentPaymentsSettingsViewModel(getIt.get<SettingsStore>(), getIt.get<AppStore>().wallet!));
@@ -1063,24 +1054,24 @@ Future<void> setup({
1054
getIt.registerFactory(
1055
() => MwebSettingsViewModel(getIt.get<SettingsStore>(), getIt.get<AppStore>().wallet!));
1056
1066
- getIt.registerFactory(() =>
1067
- PrivacySettingsViewModel(getIt.get<SettingsStore>(), getIt.get<AppStore>().wallet!));
1057
+ getIt.registerFactory(
1058
+ () => PrivacySettingsViewModel(getIt.get<SettingsStore>(), getIt.get<AppStore>().wallet!));
1059
1060
getIt.registerFactory(() => TrocadorExchangeProvider());
1061
1062
getIt.registerFactory(() => TrocadorProvidersViewModel(
1063
getIt.get<SettingsStore>(), getIt.get<TrocadorExchangeProvider>()));
1064
1074
- getIt.registerFactory(() =>
1075
- OtherSettingsViewModel(getIt.get<SettingsStore>(), getIt.get<AppStore>().wallet!,
1076
- getIt.get<SendViewModel>()));
1065
+ getIt.registerFactory(() => OtherSettingsViewModel(
1066
+ getIt.get<SettingsStore>(), getIt.get<AppStore>().wallet!, getIt.get<SendViewModel>()));
1067
1078
- getIt.registerFactory(() =>
1079
- SecuritySettingsViewModel(getIt.get<SettingsStore>(), getIt.get<AuthService>()));
1068
+ getIt.registerFactory(
1069
+ () => SecuritySettingsViewModel(getIt.get<SettingsStore>(), getIt.get<AuthService>()));
1070
1071
getIt.registerFactory(() => WalletSeedViewModel(getIt.get<AppStore>().wallet!));
1072
1083
- getIt.registerFactory<SeedSettingsViewModel>(() => SeedSettingsViewModel(getIt.get<AppStore>(), getIt.get<SeedSettingsStore>()));
1073
+ getIt.registerFactory<SeedSettingsViewModel>(
1074
+ () => SeedSettingsViewModel(getIt.get<AppStore>(), getIt.get<SeedSettingsStore>()));
1075
1076
getIt.registerFactory(() => DevMoneroBackgroundSync(getIt.get<AppStore>().wallet!));
1077
@@ -1097,13 +1088,11 @@ Future<void> setup({
1088
1089
getIt.registerFactory(() => AnimatedURModel(getIt.get<AppStore>()));
1090
1100
- getIt.registerFactoryParam<AnimatedURPage, Map<String, String>, void>((Map<String, String> urQr, _) =>
1101
- AnimatedURPage(getIt.get<AnimatedURModel>(), urQr: urQr));
1091
+ getIt.registerFactoryParam<AnimatedURPage, Map<String, String>, void>(
1092
+ (Map<String, String> urQr, _) => AnimatedURPage(getIt.get<AnimatedURModel>(), urQr: urQr));
1093
1103
- getIt.registerFactoryParam<ContactViewModel, ContactRecord?, void>(
1104
- (ContactRecord? contact, _) => ContactViewModel(_contactSource,
1105
- getIt.get<AppStore>(),
1106
- getIt.get<AddressResolverService>(),
1094
+ getIt.registerFactoryParam<ContactViewModel, ContactRecord?, void>((ContactRecord? contact, _) =>
1095
+ ContactViewModel(_contactSource, getIt.get<AppStore>(), getIt.get<AddressResolverService>(),
1096
contact: contact));
1097
1098
getIt.registerFactoryParam<ContactListViewModel, CryptoCurrency?, void>(
@@ -1128,14 +1117,15 @@ Future<void> setup({
1117
});
1118
1119
getIt.registerFactoryParam<NewAddressesPage, bool, void>(
1131
- (showHidden, _) => NewAddressesPage(
1120
+ (showHidden, _) => NewAddressesPage(
1121
showHidden: showHidden,
1122
addressListViewModel: getIt<WalletAddressListViewModel>(),
1123
dashboardViewModel: getIt<DashboardViewModel>(),
1124
),
1125
);
1126
1138
- getIt.registerFactory(() => ConnectionSyncViewModel(getIt.get<SettingsStore>(), getIt.get<AppStore>().wallet!));
1127
+ getIt.registerFactory(
1128
+ () => ConnectionSyncViewModel(getIt.get<SettingsStore>(), getIt.get<AppStore>().wallet!));
1129
1130
getIt.registerFactory(() => ConnectionSyncPage(getIt.get<ConnectionSyncViewModel>()));
1131
@@ -1163,7 +1153,7 @@ Future<void> setup({
1153
1154
getIt.registerFactory(() => OtherSettingsPage(getIt.get<OtherSettingsViewModel>()));
1155
1166
- getIt.registerFactory(()=> AboutPage(appVersion: getIt.get<SettingsStore>().appVersion));
1156
+ getIt.registerFactory(() => AboutPage(appVersion: getIt.get<SettingsStore>().appVersion));
1157
1158
getIt.registerFactory(() => NanoChangeRepPage(
1159
settingsStore: getIt.get<AppStore>().settingsStore,
@@ -1172,31 +1162,28 @@ Future<void> setup({
1162
1163
getIt.registerFactoryParam<NodeCreateOrEditViewModel, Map<String, dynamic>, void>(
1164
(Map<String, dynamic> args, _) {
1175
- final WalletType type = args['type'] as WalletType? ?? getIt.get<AppStore>().wallet!.type;
1176
- final bool isPow = args['isPow'] as bool? ?? false;
1177
- final Node? editingNode = args['editingNode'] as Node?;
1178
- return NodeCreateOrEditViewModel(
1179
- isPow,
1180
- type,
1181
- getIt.get<SettingsStore>(),
1182
- editingNode: editingNode
1183
- );
1184
- }
1185
- );
1165
+ final WalletType type = args['type'] as WalletType? ?? getIt.get<AppStore>().wallet!.type;
1166
+ final bool isPow = args['isPow'] as bool? ?? false;
1167
+ final Node? editingNode = args['editingNode'] as Node?;
1168
+ return NodeCreateOrEditViewModel(isPow, type, getIt.get<SettingsStore>(),
1169
+ editingNode: editingNode);
1170
+ });
1171
1172
getIt.registerFactoryParam<NodeCreateOrEditPage, Node?, bool?>(
1173
(Node? editingNode, bool? isSelected) {
1189
- final vm = getIt.get<NodeCreateOrEditViewModel>(param1: {'isPow' : false,'editingNode': editingNode});
1190
- return NodeCreateOrEditPage(
1191
- nodeCreateOrEditViewModel: vm,
1192
- editingNode: editingNode,
1193
- isSelected: isSelected,
1194
- type: getIt.get<AppStore>().wallet!.type);
1195
- });
1174
+ final vm =
1175
+ getIt.get<NodeCreateOrEditViewModel>(param1: {'isPow': false, 'editingNode': editingNode});
1176
+ return NodeCreateOrEditPage(
1177
+ nodeCreateOrEditViewModel: vm,
1178
+ editingNode: editingNode,
1179
+ isSelected: isSelected,
1180
+ type: getIt.get<AppStore>().wallet!.type);
1181
+ });
1182
1183
getIt.registerFactoryParam<PowNodeCreateOrEditPage, Node?, bool?>(
1184
(Node? editingNode, bool? isSelected) => PowNodeCreateOrEditPage(
1199
- nodeCreateOrEditViewModel: getIt.get<NodeCreateOrEditViewModel>(param1: {'isPow' : true, 'editingNode': editingNode}),
1185
+ nodeCreateOrEditViewModel: getIt
1186
+ .get<NodeCreateOrEditViewModel>(param1: {'isPow': true, 'editingNode': editingNode}),
1187
editingNode: editingNode,
1188
isSelected: isSelected));
1189
@@ -1225,12 +1212,12 @@ Future<void> setup({
1212
));
1213
1214
getIt.registerFactory<MeldBuyProvider>(() => MeldBuyProvider(
1228
- wallet: getIt.get<AppStore>().wallet!,
1229
- ));
1215
+ wallet: getIt.get<AppStore>().wallet!,
1216
+ ));
1217
1218
getIt.registerFactory<KryptonimBuyProvider>(() => KryptonimBuyProvider(
1232
- wallet: getIt.get<AppStore>().wallet!,
1233
- ));
1219
+ wallet: getIt.get<AppStore>().wallet!,
1220
+ ));
1221
1222
getIt.registerFactoryParam<WebViewPage, String, Uri>((title, uri) => WebViewPage(title, uri));
1223
@@ -1253,10 +1240,8 @@ Future<void> setup({
1240
1241
getIt.registerFactoryParam<ExchangePage, PaymentRequest?, void>(
1242
(PaymentRequest? paymentRequest, __) {
1256
- return ExchangePage(getIt.get<ExchangeViewModel>(),
1257
- getIt.get<AuthService>(),
1258
- getIt.get<AddressResolverService>(),
1259
- paymentRequest);
1243
+ return ExchangePage(getIt.get<ExchangeViewModel>(), getIt.get<AuthService>(),
1244
+ getIt.get<AddressResolverService>(), paymentRequest);
1245
});
1246
1247
getIt.registerFactoryParam<NewSwapPage, PaymentRequest?, CryptoCurrency?>(
@@ -1276,8 +1261,8 @@ Future<void> setup({
1261
getIt.registerFactory(
1262
() => ExchangeTradePage(exchangeTradeViewModel: getIt.get<ExchangeTradeViewModel>()));
1263
1279
- getIt.registerFactory(
1280
- () => ExchangeTradeExternalSendPage(exchangeTradeViewModel: getIt.get<ExchangeTradeViewModel>()));
1264
+ getIt.registerFactory(() =>
1265
+ ExchangeTradeExternalSendPage(exchangeTradeViewModel: getIt.get<ExchangeTradeViewModel>()));
1266
1267
getIt.registerFactory(() => BackgroundSyncPage(getIt.get<DashboardViewModel>()));
1268
@@ -1298,13 +1283,13 @@ Future<void> setup({
1283
);
1284
1285
getIt.registerFactory(() => PaymentViewModel(
1301
- appStore: getIt.get<AppStore>(),
1302
- ));
1286
+ appStore: getIt.get<AppStore>(),
1287
+ ));
1288
1289
getIt.registerFactory(() => WalletSwitcherViewModel(
1305
- appStore: getIt.get<AppStore>(),
1306
- walletLoadingService: getIt.get<WalletLoadingService>(),
1307
- ));
1290
+ appStore: getIt.get<AppStore>(),
1291
+ walletLoadingService: getIt.get<WalletLoadingService>(),
1292
+ ));
1293
1294
getIt.registerFactoryParam<WalletService, WalletType, void>((WalletType param1, __) {
1295
switch (param1) {
@@ -1328,9 +1313,11 @@ Future<void> setup({
1313
case WalletType.bsc:
1314
return evm!.createEVMWalletService(param1, SettingsStoreBase.walletPasswordDirectInput);
1315
case WalletType.bitcoinCash:
1331
- return bitcoinCash!.createBitcoinCashWalletService(_unspentCoinsInfoSource, SettingsStoreBase.walletPasswordDirectInput);
1316
+ return bitcoinCash!.createBitcoinCashWalletService(
1317
+ _unspentCoinsInfoSource, SettingsStoreBase.walletPasswordDirectInput);
1318
case WalletType.dogecoin:
1333
- return dogecoin!.createDogeCoinWalletService(_unspentCoinsInfoSource, SettingsStoreBase.walletPasswordDirectInput);
1319
+ return dogecoin!.createDogeCoinWalletService(
1320
+ _unspentCoinsInfoSource, SettingsStoreBase.walletPasswordDirectInput);
1321
case WalletType.nano:
1322
case WalletType.banano:
1323
return nano!.createNanoWalletService(SettingsStoreBase.walletPasswordDirectInput);
@@ -1354,19 +1341,16 @@ Future<void> setup({
1341
});
1342
1343
getIt.registerFactoryParam<SetupPinCodeViewModel, bool?, void>(
1357
- (isDuressPin, _) => SetupPinCodeViewModel(
1344
+ (isDuressPin, _) => SetupPinCodeViewModel(
1345
getIt.get<AuthService>(),
1346
getIt.get<SettingsStore>(),
1347
isDuressPin: isDuressPin ?? false,
1348
),
1349
);
1350
1364
-
1365
- getIt.registerFactoryParam<
1366
- SetupPinCodePage,
1367
- void Function(PinCodeState<PinCodeWidget>, String),
1351
+ getIt.registerFactoryParam<SetupPinCodePage, void Function(PinCodeState<PinCodeWidget>, String),
1352
bool?>(
1369
- (onSuccessfulPinSetup, isDuressPin) => SetupPinCodePage(
1353
+ (onSuccessfulPinSetup, isDuressPin) => SetupPinCodePage(
1354
getIt.get<SetupPinCodeViewModel>(param1: isDuressPin),
1355
onSuccessfulPinSetup: onSuccessfulPinSetup,
1356
isDuressPin: isDuressPin ?? false,
@@ -1386,17 +1370,14 @@ Future<void> setup({
1370
final restoredWallet = additionalParams?['restoredWallet'] as RestoredWallet?;
1371
final hardwareWalletType = additionalParams?['hardwareWalletType'] as HardwareWalletType?;
1372
1389
- return WalletRestoreViewModel(
1390
- getIt.get<AppStore>(),
1391
- getIt.get<WalletCreationService>(param1: type),
1392
- getIt.get<SeedSettingsViewModel>(),
1393
- type: type,
1394
- restoredWallet: restoredWallet,
1395
- hardwareWalletType: hardwareWalletType);
1373
+ return WalletRestoreViewModel(getIt.get<AppStore>(),
1374
+ getIt.get<WalletCreationService>(param1: type), getIt.get<SeedSettingsViewModel>(),
1375
+ type: type, restoredWallet: restoredWallet, hardwareWalletType: hardwareWalletType);
1376
});
1377
1398
- getIt.registerFactoryParam<WalletRestorePage, WalletType, Map<String, dynamic>?>((type, additionalParams) =>
1399
- WalletRestorePage(getIt.get<WalletRestoreViewModel>(param1: type, param2: additionalParams),
1378
+ getIt.registerFactoryParam<WalletRestorePage, WalletType, Map<String, dynamic>?>(
1379
+ (type, additionalParams) => WalletRestorePage(
1380
+ getIt.get<WalletRestoreViewModel>(param1: type, param2: additionalParams),
1381
getIt.get<SeedSettingsViewModel>()));
1382
1383
getIt.registerFactoryParam<WalletRestoreChooseDerivationViewModel, List<DerivationInfo>, void>(
@@ -1408,22 +1389,20 @@ Future<void> setup({
1389
param1: derivations,
1390
)));
1391
1411
- getIt.registerFactoryParam<TransactionDetailsViewModel, List<dynamic>, void>(
1412
- (params, _) {
1413
- final transactionInfo = params[0] as TransactionInfo;
1414
- final canReplaceByFee = params[1] as bool? ?? false;
1415
- final wallet = getIt.get<AppStore>().wallet!;
1416
-
1417
- return TransactionDetailsViewModel(
1418
- transactionInfo: transactionInfo,
1419
- transactionDescriptionBox: _transactionDescriptionBox,
1420
- wallet: wallet,
1421
- appStore: getIt.get<AppStore>(),
1422
- sendViewModel: getIt.get<SendViewModel>(),
1423
- canReplaceByFee: canReplaceByFee,
1424
- );
1425
- }
1426
- );
1392
+ getIt.registerFactoryParam<TransactionDetailsViewModel, List<dynamic>, void>((params, _) {
1393
+ final transactionInfo = params[0] as TransactionInfo;
1394
+ final canReplaceByFee = params[1] as bool? ?? false;
1395
+ final wallet = getIt.get<AppStore>().wallet!;
1396
+
1397
+ return TransactionDetailsViewModel(
1398
+ transactionInfo: transactionInfo,
1399
+ transactionDescriptionBox: _transactionDescriptionBox,
1400
+ wallet: wallet,
1401
+ appStore: getIt.get<AppStore>(),
1402
+ sendViewModel: getIt.get<SendViewModel>(),
1403
+ canReplaceByFee: canReplaceByFee,
1404
+ );
1405
+ });
1406
1407
getIt.registerFactoryParam<TransactionDetailsModal, TransactionInfo, bool?>(
1408
(transactionInfo, highlightNoteField) => TransactionDetailsModal(
@@ -1433,22 +1412,20 @@ Future<void> setup({
1412
));
1413
1414
getIt.registerFactoryParam<TransactionDetailsPage, TransactionInfo, void>(
1436
- (TransactionInfo transactionInfo, _) => TransactionDetailsPage(
1437
- transactionDetailsViewModel: getIt.get<TransactionDetailsViewModel>(
1438
- param1: [transactionInfo, false])));
1439
-
1440
- getIt.registerFactoryParam<RBFDetailsPage, List<dynamic>, void>(
1441
- (params, _) {
1442
- final transactionInfo = params[0] as TransactionInfo;
1443
- final txHex = params[1] as String;
1444
- return RBFDetailsPage(
1445
- transactionDetailsViewModel: getIt.get<TransactionDetailsViewModel>(
1446
- param1: [transactionInfo, true],
1447
- ),
1448
- rawTransaction: txHex,
1449
- );
1450
- }
1451
- );
1415
+ (TransactionInfo transactionInfo, _) => TransactionDetailsPage(
1416
+ transactionDetailsViewModel:
1417
+ getIt.get<TransactionDetailsViewModel>(param1: [transactionInfo, false])));
1418
+
1419
+ getIt.registerFactoryParam<RBFDetailsPage, List<dynamic>, void>((params, _) {
1420
+ final transactionInfo = params[0] as TransactionInfo;
1421
+ final txHex = params[1] as String;
1422
+ return RBFDetailsPage(
1423
+ transactionDetailsViewModel: getIt.get<TransactionDetailsViewModel>(
1424
+ param1: [transactionInfo, true],
1425
+ ),
1426
+ rawTransaction: txHex,
1427
+ );
1428
+ });
1429
1430
getIt.registerFactoryParam<NewWalletTypePage, NewWalletTypeArguments, void>(
1431
(newWalletTypeArguments, _) {
@@ -1460,22 +1437,19 @@ Future<void> setup({
1437
getIt.registerFactory<PreSeedPage>(() => PreSeedPage());
1438
1439
getIt.registerFactoryParam<TransactionSuccessPage, String, void>(
1463
- (content, _) => TransactionSuccessPage(content: content));
1440
+ (content, _) => TransactionSuccessPage(content: content));
1441
1442
getIt.registerFactoryParam<TradeDetailsViewModel, Trade, void>(
1443
(trade, _) => TradeDetailsViewModel(tradeForDetails: trade, appStore: getIt.get<AppStore>()));
1444
1445
getIt.registerFactory(() => CakeFeaturesViewModel(getIt.get<CakePayService>()));
1446
1470
-
1447
getIt.registerFactory(() => CakeFeaturesPage(
1448
dashboardViewModel: getIt.get<DashboardViewModel>(),
1449
cakeFeaturesViewModel: getIt.get<CakeFeaturesViewModel>()));
1450
1451
getIt.registerFactory(() => BackupServiceV3(getIt.get<SecureStorage>(),
1476
- _transactionDescriptionBox,
1477
- getIt.get<KeyService>(), getIt.get<SharedPreferences>()));
1478
-
1452
+ _transactionDescriptionBox, getIt.get<KeyService>(), getIt.get<SharedPreferences>()));
1453
1454
getIt.registerFactory(() => BackupPage(getIt.get<BackupViewModel>()));
1455
@@ -1483,8 +1457,8 @@ Future<void> setup({
1457
() => EditBackupPasswordViewModel(getIt.get<SecureStorage>()),
1458
);
1459
1486
- getIt.registerFactory(() => BackupViewModel(
1487
- getIt.get<SecureStorage>(),getIt.get<BackupServiceV3>(), getIt.get<EditBackupPasswordViewModel>()));
1460
+ getIt.registerFactory(() => BackupViewModel(getIt.get<SecureStorage>(),
1461
+ getIt.get<BackupServiceV3>(), getIt.get<EditBackupPasswordViewModel>()));
1462
1463
getIt.registerFactory(() => EditBackupPasswordPage(getIt.get<EditBackupPasswordViewModel>()));
1464
@@ -1502,22 +1476,22 @@ Future<void> setup({
1476
1477
getIt.registerFactory(() => BuySellViewModel(getIt.get<AppStore>()));
1478
1505
- getIt.registerFactory(() => BuySellPage(getIt.get<BuySellViewModel>(), getIt.get<AddressResolverService>()));
1479
+ getIt.registerFactory(
1480
+ () => BuySellPage(getIt.get<BuySellViewModel>(), getIt.get<AddressResolverService>()));
1481
1482
getIt.registerFactoryParam<BuyOptionsPage, List<dynamic>, void>((List<dynamic> args, _) {
1483
final items = args.first as List<SelectableItem>;
1484
final pickAnOption = args[1] as void Function(SelectableOption option)?;
1485
final confirmOption = args[2] as void Function(BuildContext contex)?;
1511
- return BuyOptionsPage(
1512
- items: items, pickAnOption: pickAnOption, confirmOption: confirmOption);
1486
+ return BuyOptionsPage(items: items, pickAnOption: pickAnOption, confirmOption: confirmOption);
1487
});
1488
1515
- getIt.registerFactoryParam<PaymentMethodOptionsPage, List<dynamic>, void>((List<dynamic> args, _) {
1489
+ getIt
1490
+ .registerFactoryParam<PaymentMethodOptionsPage, List<dynamic>, void>((List<dynamic> args, _) {
1491
final items = args.first as List<SelectableOption>;
1492
final pickAnOption = args[1] as void Function(SelectableOption option)?;
1493
1519
- return PaymentMethodOptionsPage(
1520
- items: items, pickAnOption: pickAnOption);
1494
+ return PaymentMethodOptionsPage(items: items, pickAnOption: pickAnOption);
1495
});
1496
1497
getIt.registerFactory(() {
@@ -1578,11 +1552,11 @@ Future<void> setup({
1552
getIt.get<UnspentCoinsListViewModel>(param1: coinTypeToSpendFrom)));
1553
1554
getIt.registerFactoryParam<NewCoinControlPage, UnspentCoinType?, bool?>(
1581
- (coinTypeToSpendFrom, canEdit) => NewCoinControlPage(
1582
- unspentCoinsListViewModel:
1583
- getIt.get<UnspentCoinsListViewModel>(param1: coinTypeToSpendFrom), canEdit: canEdit ?? true,)
1584
-
1585
- );
1555
+ (coinTypeToSpendFrom, canEdit) => NewCoinControlPage(
1556
+ unspentCoinsListViewModel:
1557
+ getIt.get<UnspentCoinsListViewModel>(param1: coinTypeToSpendFrom),
1558
+ canEdit: canEdit ?? true,
1559
+ ));
1560
1561
getIt.registerFactoryParam<UnspentCoinsDetailsViewModel, UnspentCoinsItem,
1562
UnspentCoinsListViewModel>(
@@ -1601,7 +1575,7 @@ Future<void> setup({
1575
getIt.registerFactory(() => YatService());
1576
1577
getIt.registerFactory<AddressResolverService>(
1604
- () => AddressResolverService(settingsStore: getIt.get<SettingsStore>()),
1578
+ () => AddressResolverService(settingsStore: getIt.get<SettingsStore>()),
1579
);
1580
1581
getIt.registerFactoryParam<FullscreenQRPage, QrViewData, void>(
@@ -1614,15 +1588,15 @@ Future<void> setup({
1588
getIt.registerFactory<CakePayService>(
1589
() => CakePayService(getIt.get<SecureStorage>(), getIt.get<CakePayApi>()));
1590
1617
- getIt.registerFactory(
1618
- () => CakePayCardsListViewModel(cakePayService: getIt.get<CakePayService>(),
1619
- settingsStore: getIt.get<SettingsStore>()));
1591
+ getIt.registerFactory(() => CakePayCardsListViewModel(
1592
+ cakePayService: getIt.get<CakePayService>(), settingsStore: getIt.get<SettingsStore>()));
1593
1594
getIt.registerFactory(() => CakePayAuthViewModel(cakePayService: getIt.get<CakePayService>()));
1595
1596
getIt.registerFactoryParam<CakePayBuyCardViewModel, CakePayVendor, void>(
1597
(CakePayVendor vendor, _) {
1625
- return CakePayBuyCardViewModel(vendor: vendor,
1598
+ return CakePayBuyCardViewModel(
1599
+ vendor: vendor,
1600
cakePayService: getIt.get<CakePayService>(),
1601
sendViewModel: getIt.get<SendViewModel>(),
1602
orders: _ordersSource);
@@ -1666,8 +1640,7 @@ Future<void> setup({
1640
));
1641
1642
getIt.registerFactoryParam<PayjoinDetailsViewModel, String, TransactionInfo?>(
1669
- (String sessionId, TransactionInfo? transactionInfo) =>
1670
- PayjoinDetailsViewModel(
1643
+ (String sessionId, TransactionInfo? transactionInfo) => PayjoinDetailsViewModel(
1644
sessionId,
1645
transactionInfo,
1646
payjoinSessionSource: _payjoinSessionSource,
@@ -1684,8 +1657,8 @@ Future<void> setup({
1657
1658
getIt.registerFactoryParam<PayjoinDetailsPage, String, TransactionInfo?>(
1659
(String sessionId, TransactionInfo? transactionInfo) => PayjoinDetailsPage(
1687
- payjoinDetailsViewModel: getIt.get<PayjoinDetailsViewModel>(
1688
- param1: sessionId, param2: transactionInfo)));
1660
+ payjoinDetailsViewModel:
1661
+ getIt.get<PayjoinDetailsViewModel>(param1: sessionId, param2: transactionInfo)));
1662
1663
getIt.registerFactoryParam<HomeSettingsPage, BalanceViewModel, void>((balanceViewModel, _) =>
1664
HomeSettingsPage(getIt.get<HomeSettingsViewModel>(param1: balanceViewModel)));
@@ -1702,7 +1675,9 @@ Future<void> setup({
1675
);
1676
1677
getIt.registerFactoryParam<ManageNodesPage, bool, void>((bool isPow, _) {
1705
- return ManageNodesPage(isPow, nodeListViewModel: getIt.get<NodeListViewModel>(param1: isPow), dashboardViewModel: getIt.get<DashboardViewModel>());
1678
+ return ManageNodesPage(isPow,
1679
+ nodeListViewModel: getIt.get<NodeListViewModel>(param1: isPow),
1680
+ dashboardViewModel: getIt.get<DashboardViewModel>());
1681
});
1682
1683
getIt.registerFactory(
@@ -1738,9 +1713,12 @@ Future<void> setup({
1713
getIt.registerFactory(() => DevQRToolsPage());
1714
1715
getIt.registerFactory(() => ExchangeProviderLogsViewModel());
1741
- getIt.registerFactory(() => DevExchangeProviderLogsPage(getIt.get<ExchangeProviderLogsViewModel>()));
1716
+ getIt.registerFactory(
1717
+ () => DevExchangeProviderLogsPage(getIt.get<ExchangeProviderLogsViewModel>()));
1718
1743
- getIt.registerFactory(() => StartTorPage(StartTorViewModel(),));
1719
+ getIt.registerFactory(() => StartTorPage(
1720
+ StartTorViewModel(),
1721
+ ));
1722
1723
getIt.registerFactory(() => DEuroViewModel(
1724
getIt<AppStore>(),
@@ -1782,9 +1760,9 @@ Future<void> setup({
1760
));
1761
1762
getIt.registerLazySingleton(() => NodeSwitchingService(
1785
- appStore: getIt.get<AppStore>(),
1786
- settingsStore: getIt.get<SettingsStore>(),
1787
- ));
1763
+ appStore: getIt.get<AppStore>(),
1764
+ settingsStore: getIt.get<SettingsStore>(),
1765
+ ));
1766
1767
getIt.registerFactoryParam<BridgeAmountPage, CryptoCurrency, void>(
1768
(CryptoCurrency initialToken, _) => BridgeAmountPage(
lib/dogecoin/cw_dogecoin.dart
+2
-3
@@ -1,10 +1,9 @@
1
part of 'dogecoin.dart';
2
3
-
3
class CWDogeCoin extends DogeCoin {
5
-
4
@override
7
- WalletService createDogeCoinWalletService(Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect) {
5
+ WalletService createDogeCoinWalletService(
6
+ Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect) {
7
return DogeCoinWalletService(unspentCoinSource, isDirect);
8
}
9
lib/entities/auto_generate_subaddress_status.dart
+5
-7
@@ -1,13 +1,11 @@
1
-
2
-enum AutoGenerateSubaddressStatus {
3
- initialized(1),
4
- enabled(2),
1
+enum AutoGenerateSubaddressStatus {
2
+ initialized(1),
3
+ enabled(2),
4
disabled(3);
5
6
const AutoGenerateSubaddressStatus(this.value);
7
final int value;
8
10
- static AutoGenerateSubaddressStatus deserialize({required int raw}) =>
9
+ static AutoGenerateSubaddressStatus deserialize({required int raw}) =>
10
AutoGenerateSubaddressStatus.values.firstWhere((e) => e.value == raw);
12
-
13
-}
\ No newline at end of file
11
+}
lib/entities/balance_display_mode.dart
+3
-6
@@ -11,12 +11,9 @@ class BalanceDisplayMode extends EnumerableItem<int> with Serializable<int> {
11
BalanceDisplayMode.displayableBalance,
12
];
13
static const fullBalance = BalanceDisplayMode(raw: 0, title: 'Full Balance');
14
- static const availableBalance =
15
- BalanceDisplayMode(raw: 1, title: 'Available Balance');
16
- static const hiddenBalance =
17
- BalanceDisplayMode(raw: 2, title: 'Hidden Balance');
18
- static const displayableBalance =
19
- BalanceDisplayMode(raw: 3, title: 'Displayable Balance');
14
+ static const availableBalance = BalanceDisplayMode(raw: 1, title: 'Available Balance');
15
+ static const hiddenBalance = BalanceDisplayMode(raw: 2, title: 'Hidden Balance');
16
+ static const displayableBalance = BalanceDisplayMode(raw: 3, title: 'Displayable Balance');
17
18
static BalanceDisplayMode deserialize({required int raw}) {
19
switch (raw) {
lib/entities/biometric_auth.dart
+1
-1
@@ -27,4 +27,4 @@ class BiometricAuth {
27
28
return canAuthenticate;
29
}
30
-}
\ No newline at end of file
30
+}
lib/entities/bitcoin_amount_display_mode.dart
+1
-2
@@ -9,8 +9,7 @@ class BitcoinAmountDisplayMode extends EnumerableItem<int> with Serializable<int
9
BitcoinAmountDisplayMode.satoshiForLightning,
10
BitcoinAmountDisplayMode.bitcoin,
11
];
12
- static const satoshiForLightning =
13
- BitcoinAmountDisplayMode(raw: 0, title: 'sats (LN)');
12
+ static const satoshiForLightning = BitcoinAmountDisplayMode(raw: 0, title: 'sats (LN)');
13
static const bitcoin = BitcoinAmountDisplayMode(raw: 1, title: 'BTC');
14
static const satoshi = BitcoinAmountDisplayMode(raw: 2, title: 'sats');
15
lib/entities/calculate_fiat_amount.dart
+2
-2
@@ -16,7 +16,7 @@ String calculateFiatAmount({double? price, String? cryptoAmount, bool raw = fals
16
return '0.00';
17
}
18
19
- if(raw) {
19
+ if (raw) {
20
return result.toStringAsFixed(2);
21
}
22
@@ -48,7 +48,7 @@ String formatWithCommas(String? number) {
48
(Match match) => ',',
49
);
50
51
- if(decimalPart.length == 1) {
51
+ if (decimalPart.length == 1) {
52
decimalPart = "${decimalPart}0";
53
}
54
lib/entities/calculate_fiat_amount_raw.dart
+1
-1
@@ -12,4 +12,4 @@ String calculateFiatAmountRaw({required double cryptoAmount, double? price}) {
12
}
13
14
return result > 0.01 ? formatWithCommas(result.toStringAsFixed(2)) : '< 0.01';
15
-}
\ No newline at end of file
15
+}
lib/entities/contact.dart
+6
-1
@@ -7,7 +7,12 @@ part 'contact.part.dart';
7
8
// @HiveType(typeId: Contact.typeId)
9
class Contact extends HiveObject with Keyable {
10
- Contact({required this.name, required this.address, CryptoCurrency? type, DateTime? lastChange, this.displayName = ""})
10
+ Contact(
11
+ {required this.name,
12
+ required this.address,
13
+ CryptoCurrency? type,
14
+ DateTime? lastChange,
15
+ this.displayName = ""})
16
: lastChange = lastChange ?? DateTime.now() {
17
if (type != null) {
18
raw = type.raw;
lib/entities/contact.part.dart
+1
-3
@@ -46,7 +46,5 @@ class ContactAdapter extends TypeAdapter<Contact> {
46
@override
47
bool operator ==(Object other) =>
48
identical(this, other) ||
49
- other is ContactAdapter &&
50
- runtimeType == other.runtimeType &&
51
- typeId == other.typeId;
49
+ other is ContactAdapter && runtimeType == other.runtimeType && typeId == other.typeId;
50
}
lib/entities/contact_base.dart
+1
-1
@@ -10,4 +10,4 @@ abstract class ContactBase {
10
String displayName;
11
12
CryptoCurrency type;
13
-}
\ No newline at end of file
13
+}
lib/entities/country.dart
+4
-3
@@ -11,7 +11,8 @@ class Country extends EnumerableItem<String> with Serializable<String> {
11
static List<Country> get all => _all.values.toList();
12
13
static List<Country> get allForCakePay => _all.values
14
- .where((element) => element.countryCode != 'EU' && element.countryCode != 'AQ').toList();
14
+ .where((element) => element.countryCode != 'EU' && element.countryCode != 'AQ')
15
+ .toList();
16
17
static const afghanistan = Country(code: 'afg', countryCode: 'AF', fullName: "Afghanistan");
18
static const andorra = Country(code: 'and', countryCode: 'AD', fullName: "Andorra");
@@ -366,9 +367,9 @@ class Country extends EnumerableItem<String> with Serializable<String> {
367
return _all.values.firstWhereOrNull((element) => element.raw == countryCode.toLowerCase());
368
}
369
369
-
370
static Country? fromCountryCode(String countryCode) {
371
- return _all.values.firstWhereOrNull((element) => element.countryCode == countryCode.toUpperCase());
371
+ return _all.values
372
+ .firstWhereOrNull((element) => element.countryCode == countryCode.toUpperCase());
373
}
374
375
@override
lib/entities/default_settings_migration.dart
+15
-18
@@ -283,7 +283,7 @@ Future<void> defaultSettingsMigration(
283
// await insecureStorageMigration(secureStorage: secureStorage, sharedPreferences: sharedPreferences);
284
break;
285
case 27:
286
- await addWalletNodeList( type: WalletType.solana);
286
+ await addWalletNodeList(type: WalletType.solana);
287
await _changeDefaultNode(
288
sharedPreferences: sharedPreferences,
289
type: WalletType.solana,
@@ -516,7 +516,7 @@ Future<void> defaultSettingsMigration(
516
currentNodePreferenceKey: PreferencesKey.currentBaseNodeIdKey,
517
);
518
break;
519
- case 53:
519
+ case 53:
520
await addWalletNodeList(type: WalletType.arbitrum);
521
await _changeDefaultNode(
522
sharedPreferences: sharedPreferences,
@@ -662,13 +662,13 @@ Future<void> _changeDefaultNode({
662
shouldReplace = true;
663
} else {
664
final currentNode = nodes.firstWhereOrNull((node) => node.id == currentNodeId);
665
- shouldReplace = currentNode == null || (oldUri?.any((e) => currentNode!.uriRaw.contains(e)) ?? true);
665
+ shouldReplace =
666
+ currentNode == null || (oldUri?.any((e) => currentNode!.uriRaw.contains(e)) ?? true);
667
}
668
669
if (shouldReplace) {
670
newDefaultUri ??= (await getDefaultNodeFromFiles(type)).uriRaw;
670
- var newNodeId =
671
- nodes.firstWhereOrNull((element) => element.uriRaw == newDefaultUri)?.id;
671
+ var newNodeId = nodes.firstWhereOrNull((element) => element.uriRaw == newDefaultUri)?.id;
672
673
// new node doesn't exist, then add it
674
if (newNodeId == null) {
@@ -734,8 +734,7 @@ Future<void> updateNanoNodeList() async {
734
}
735
736
// update the nautilus node:
737
- final nautilusNode =
738
- nodes.firstWhereOrNull((element) => element.uriRaw == "node.perish.co");
737
+ final nautilusNode = nodes.firstWhereOrNull((element) => element.uriRaw == "node.perish.co");
738
if (nautilusNode != null) {
739
nautilusNode.uriRaw = "node.nautilus.io";
740
nautilusNode.path = "/api";
@@ -855,9 +854,9 @@ Future<void> validateBitcoinSavedTransactionPriority(SharedPreferences sharedPre
854
Future<void> replaceNodesMigration() async {
855
final replaceNodes = <String, Node>{
856
'eu-node.cakewallet.io:18081':
858
- Node(uri: 'xmr-node-eu.cakewallet.com:18081', type: WalletType.monero),
857
+ Node(uri: 'xmr-node-eu.cakewallet.com:18081', type: WalletType.monero),
858
'node.cakewallet.io:18081':
860
- Node(uri: 'xmr-node-usa-east.cakewallet.com:18081', type: WalletType.monero),
859
+ Node(uri: 'xmr-node-usa-east.cakewallet.com:18081', type: WalletType.monero),
860
'node.xmr.ru:13666': Node(uri: 'node.monero.net:18081', type: WalletType.monero)
861
};
862
@@ -874,11 +873,10 @@ Future<void> replaceNodesMigration() async {
873
});
874
}
875
877
-Future<Node?> getBitcoinTestnetDefaultElectrumServer()async {
876
+Future<Node?> getBitcoinTestnetDefaultElectrumServer() async {
877
final nodes = await Node.getAll();
878
880
- return nodes
881
- .firstWhereOrNull((Node node) => node.uriRaw == publicBitcoinTestnetElectrumUri) ??
879
+ return nodes.firstWhereOrNull((Node node) => node.uriRaw == publicBitcoinTestnetElectrumUri) ??
880
nodes.firstWhereOrNull((node) => node.type == WalletType.bitcoin);
881
}
882
@@ -1086,8 +1084,8 @@ Future<void> resetBitcoinElectrumServer(SharedPreferences sharedPreferences) asy
1084
sharedPreferences.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey);
1085
final oldElectrumServer = nodeSource
1086
.firstWhereOrNull((node) => node.uri.toString().contains('electrumx.cakewallet.com'));
1089
- var cakeWalletNode = nodeSource
1090
- .firstWhereOrNull((node) => node.uriRaw.toString() == cakeWalletBitcoinElectrumUri);
1087
+ var cakeWalletNode =
1088
+ nodeSource.firstWhereOrNull((node) => node.uriRaw.toString() == cakeWalletBitcoinElectrumUri);
1089
1090
if (cakeWalletNode == null) {
1091
cakeWalletNode = Node(
@@ -1147,8 +1145,7 @@ Future<void> addWalletNodeList({required WalletType type}) async {
1145
}
1146
}
1147
1150
-Future<void> removeMoneroWorld(
1151
- {required SharedPreferences sharedPreferences}) async {
1148
+Future<void> removeMoneroWorld({required SharedPreferences sharedPreferences}) async {
1149
final nodes = await Node.getAll();
1150
const cakeWalletMoneroNodeUriPattern = '.moneroworld.com';
1151
final currentMoneroNodeId = sharedPreferences.getInt(PreferencesKey.currentNodeIdKey);
@@ -1218,14 +1215,13 @@ Future<void> migrateExistingNodesToUseAutoSwitching() async {
1215
1216
final powNodes = await Node.getAllPow();
1217
1221
- for(var node in powNodes) {
1218
+ for (var node in powNodes) {
1219
if (listOfDefaultNodesWithAutoSwitching.contains(node.uriRaw)) {
1220
node.isEnabledForAutoSwitching = true;
1221
node.isPow = true;
1222
await node.save();
1223
}
1224
}
1228
-
1225
}
1226
1227
Future<void> _addXautTokenToExistingEthereumWallets() async {
@@ -1264,6 +1260,7 @@ Future<void> _addXautTokenToExistingEthereumWallets() async {
1260
printV('Error in XAUT migration: $e');
1261
}
1262
}
1263
+
1264
Future<void> _addXaut0TokenToExistingSolanaWallets() async {
1265
try {
1266
final xaut0Token = SPLToken(
lib/entities/emoji_string_extension.dart
+4
-4
@@ -16,11 +16,11 @@ extension Emoji on String {
16
17
bool _hasOnlyEmojis() {
18
final parsedText = this.replaceAll(' ', '');
19
- if(parsedText.isEmpty) return false;
20
- for (final c in Characters(parsedText))
21
- if (!REGEX_EMOJI.hasMatch(c)) return false;
19
+ if (parsedText.isEmpty) return false;
20
+ for (final c in Characters(parsedText)) if (!REGEX_EMOJI.hasMatch(c)) return false;
21
return true;
22
}
24
- /// Returns true if the given text contains only emojis.
23
+
24
+ /// Returns true if the given text contains only emojis.
25
bool get hasOnlyEmojis => _hasOnlyEmojis();
26
}
lib/entities/evm_transaction_error_fees_handler.dart
+11
-7
@@ -54,7 +54,9 @@ class EVMTransactionErrorFeesHandler {
54
// Pattern 2: "balance X, queued cost Y, tx cost Z, overshot W" format (most specific)
55
ErrorPattern(
56
name: 'balance_queued_txcost_overshot',
57
- regex: RegExp(r'balance\s+(\d+),\s*queued\s+cost\s+(\d+),\s*tx\s+cost\s+(\d+),\s*overshot\s+(\d+)', caseSensitive: false),
57
+ regex: RegExp(
58
+ r'balance\s+(\d+),\s*queued\s+cost\s+(\d+),\s*tx\s+cost\s+(\d+),\s*overshot\s+(\d+)',
59
+ caseSensitive: false),
60
extractor: (match) => {
61
'balance': match.group(1)!,
62
'txCost': match.group(3)!, // Skip queued cost, use tx cost
@@ -70,7 +72,8 @@ class EVMTransactionErrorFeesHandler {
72
// Pattern 3: "balance X, tx cost Y, overshot Z" format
73
ErrorPattern(
74
name: 'balance_txcost_overshot',
73
- regex: RegExp(r'balance\s+(\d+),\s*tx\s+cost\s+(\d+),\s*overshot\s+(\d+)', caseSensitive: false),
75
+ regex: RegExp(r'balance\s+(\d+),\s*tx\s+cost\s+(\d+),\s*overshot\s+(\d+)',
76
+ caseSensitive: false),
77
extractor: (match) => {
78
'balance': match.group(1)!,
79
'txCost': match.group(2)!,
@@ -86,7 +89,8 @@ class EVMTransactionErrorFeesHandler {
89
// Pattern 4: Individual field matching (legacy fallback)
90
ErrorPattern(
91
name: 'individual_fields',
89
- regex: RegExp(r'balance\s+(\d+).*tx\s+cost\s+(\d+).*overshot\s+(\d+)', caseSensitive: false),
92
+ regex:
93
+ RegExp(r'balance\s+(\d+).*tx\s+cost\s+(\d+).*overshot\s+(\d+)', caseSensitive: false),
94
extractor: (match) => {
95
'balance': match.group(1)!,
96
'txCost': match.group(2)!,
@@ -102,7 +106,8 @@ class EVMTransactionErrorFeesHandler {
106
// Pattern 5: Generic "insufficient funds for gas * price + value" (least specific - must be last)
107
ErrorPattern(
108
name: 'generic_insufficient_funds',
105
- regex: RegExp(r'insufficient\s+funds\s+for\s+gas\s*\*\s*price\s*\+\s*value', caseSensitive: false),
109
+ regex: RegExp(r'insufficient\s+funds\s+for\s+gas\s*\*\s*price\s*\+\s*value',
110
+ caseSensitive: false),
111
extractor: (match) => {
112
'balance': '0', // We don't have specific values, so use 0
113
'txCost': '0',
@@ -142,9 +147,8 @@ class EVMTransactionErrorFeesHandler {
147
final txCostWei = BigInt.parse(values['txCostWei']!);
148
final overshotWei = BigInt.parse(values['overshotWei']!);
149
145
- final isGenericError = balanceWei == BigInt.zero &&
146
- txCostWei == BigInt.zero &&
147
- overshotWei == BigInt.zero;
150
+ final isGenericError =
151
+ balanceWei == BigInt.zero && txCostWei == BigInt.zero && overshotWei == BigInt.zero;
152
153
if (isGenericError) {
154
return genericInsufficientFunds();
lib/entities/exchange_api_mode.dart
+1
-1
@@ -36,4 +36,4 @@ class ExchangeApiMode extends EnumerableItem<int> with Serializable<int> {
36
return '';
37
}
38
}
39
-}
\ No newline at end of file
39
+}
lib/entities/fiat_currency.dart
+20
-10
@@ -85,15 +85,18 @@ class FiatCurrency extends EnumerableItem<String> with Serializable<String> impl
85
static const eur = FiatCurrency(symbol: 'EUR', countryCode: "eur", fullName: "Euro");
86
static const gbp = FiatCurrency(symbol: 'GBP', countryCode: "gbr", fullName: "Pound Sterling");
87
static const ghs = FiatCurrency(symbol: 'GHS', countryCode: "gha", fullName: "Ghanaian Cedi");
88
- static const gtq = FiatCurrency(symbol: 'GTQ', countryCode: "gtm", fullName: "Guatemalan Quetzal");
88
+ static const gtq =
89
+ FiatCurrency(symbol: 'GTQ', countryCode: "gtm", fullName: "Guatemalan Quetzal");
90
static const hkd = FiatCurrency(symbol: 'HKD', countryCode: "hkg", fullName: "Hong Kong Dollar");
91
static const hrk = FiatCurrency(symbol: 'HRK', countryCode: "hrv", fullName: "Croatian Kuna");
92
static const huf = FiatCurrency(symbol: 'HUF', countryCode: "hun", fullName: "Hungarian Forint");
93
static const idr = FiatCurrency(symbol: 'IDR', countryCode: "idn", fullName: "Indonesian Rupiah");
93
- static const ils = FiatCurrency(symbol: 'ILS', countryCode: "isr", fullName: "Israeli New Shekel");
94
+ static const ils =
95
+ FiatCurrency(symbol: 'ILS', countryCode: "isr", fullName: "Israeli New Shekel");
96
static const inr = FiatCurrency(symbol: 'INR', countryCode: "ind", fullName: "Indian Rupee");
97
static const irr = FiatCurrency(symbol: 'IRR', countryCode: "irn", fullName: "Iranian Rial");
96
- static const isk = FiatCurrency(symbol: 'ISK', countryCode: "isl", fullName: "Icelandic Krona Króna");
98
+ static const isk =
99
+ FiatCurrency(symbol: 'ISK', countryCode: "isl", fullName: "Icelandic Krona Króna");
100
static const jpy = FiatCurrency(symbol: 'JPY', countryCode: "jpn", fullName: "Japanese Yen");
101
static const krw = FiatCurrency(symbol: 'KRW', countryCode: "kor", fullName: "South Korean Won");
102
static const mad = FiatCurrency(symbol: 'MAD', countryCode: "mar", fullName: "Moroccan Dirham");
@@ -101,22 +104,29 @@ class FiatCurrency extends EnumerableItem<String> with Serializable<String> impl
104
static const myr = FiatCurrency(symbol: 'MYR', countryCode: "mys", fullName: "Malaysian Ringgit");
105
static const ngn = FiatCurrency(symbol: 'NGN', countryCode: "nga", fullName: "Nigerian Naira");
106
static const nok = FiatCurrency(symbol: 'NOK', countryCode: "nor", fullName: "Norwegian Krone");
104
- static const nzd = FiatCurrency(symbol: 'NZD', countryCode: "nzl", fullName: "New Zealand Dollar");
107
+ static const nzd =
108
+ FiatCurrency(symbol: 'NZD', countryCode: "nzl", fullName: "New Zealand Dollar");
109
static const php = FiatCurrency(symbol: 'PHP', countryCode: "phl", fullName: "Philippine Peso");
110
static const pkr = FiatCurrency(symbol: 'PKR', countryCode: "pak", fullName: "Pakistani Rupee");
107
- static const pln = FiatCurrency(symbol: 'PLN', countryCode: "pol", fullName: "Poland Zloty złoty");
111
+ static const pln =
112
+ FiatCurrency(symbol: 'PLN', countryCode: "pol", fullName: "Poland Zloty złoty");
113
static const ron = FiatCurrency(symbol: 'RON', countryCode: "rou", fullName: "Romanian Leu");
114
static const rub = FiatCurrency(symbol: 'RUB', countryCode: "rus", fullName: "Russian Ruble");
115
static const sar = FiatCurrency(symbol: 'SAR', countryCode: "sau", fullName: "Saudi Riyal");
116
static const sek = FiatCurrency(symbol: 'SEK', countryCode: "swe", fullName: "Swedish Krona");
117
static const sgd = FiatCurrency(symbol: 'SGD', countryCode: "sgp", fullName: "Singapore Dollar");
113
- static const thb = FiatCurrency(symbol: 'THB', countryCode: "tha", fullName: "New Thaiwan Dollar");
118
+ static const thb =
119
+ FiatCurrency(symbol: 'THB', countryCode: "tha", fullName: "New Thaiwan Dollar");
120
static const twd = FiatCurrency(symbol: 'TWD', countryCode: "twn", fullName: "Thai Baht");
121
static const uah = FiatCurrency(symbol: 'UAH', countryCode: "ukr", fullName: "Ukrainian Hryvnia");
116
- static const usd = FiatCurrency(symbol: 'USD', countryCode: "usa", fullName: "United States Dollar");
117
- static const vef = FiatCurrency(symbol: 'VEF', countryCode: "ven", fullName: "Venezuelan Bolivar Bolívar");
118
- static const vnd = FiatCurrency(symbol: 'VND', countryCode: "vnm", fullName: "Vietnamese Dong đồng");
119
- static const zar = FiatCurrency(symbol: 'ZAR', countryCode: "saf", fullName: "South African Rand");
122
+ static const usd =
123
+ FiatCurrency(symbol: 'USD', countryCode: "usa", fullName: "United States Dollar");
124
+ static const vef =
125
+ FiatCurrency(symbol: 'VEF', countryCode: "ven", fullName: "Venezuelan Bolivar Bolívar");
126
+ static const vnd =
127
+ FiatCurrency(symbol: 'VND', countryCode: "vnm", fullName: "Vietnamese Dong đồng");
128
+ static const zar =
129
+ FiatCurrency(symbol: 'ZAR', countryCode: "saf", fullName: "South African Rand");
130
static const tur = FiatCurrency(symbol: 'TRY', countryCode: "tur", fullName: "Turkish Lira");
131
static const kes = FiatCurrency(symbol: 'KES', countryCode: "ken", fullName: "Kenyan Shillings");
132
lib/entities/format_amount.dart
+3
-3
@@ -1,10 +1,10 @@
1
import 'calculate_fiat_amount.dart';
2
3
String formatAmount(String amount) {
4
- if ((!amount.contains('.'))&&(!amount.contains(','))) {
4
+ if ((!amount.contains('.')) && (!amount.contains(','))) {
5
return formatWithCommas(amount + '.00');
6
- } else if ((amount.endsWith('.'))||(amount.endsWith(','))) {
6
+ } else if ((amount.endsWith('.')) || (amount.endsWith(','))) {
7
return formatWithCommas(amount + '00');
8
}
9
return formatWithCommas(amount);
10
-}
\ No newline at end of file
10
+}
lib/entities/hardware_wallet/require_hardware_wallet_connection.dart
+2
-5
@@ -5,11 +5,8 @@ import 'package:cw_core/wallet_type.dart';
5
import 'package:shared_preferences/shared_preferences.dart';
6
7
Future<bool> requireHardwareWalletConnection() async {
8
- final name = getIt
9
- .get<SharedPreferences>()
10
- .getString(PreferencesKey.currentWalletName);
11
- final typeRaw =
12
- getIt.get<SharedPreferences>().getInt(PreferencesKey.currentWalletType);
8
+ final name = getIt.get<SharedPreferences>().getString(PreferencesKey.currentWalletName);
9
+ final typeRaw = getIt.get<SharedPreferences>().getInt(PreferencesKey.currentWalletType);
10
11
if (typeRaw == null) {
12
return false;
lib/entities/haven_seed_store.part.dart
+1
-3
@@ -38,7 +38,5 @@ class HavenSeedStoreAdapter extends TypeAdapter<HavenSeedStore> {
38
@override
39
bool operator ==(Object other) =>
40
identical(this, other) ||
41
- other is HavenSeedStoreAdapter &&
42
- runtimeType == other.runtimeType &&
43
- typeId == other.typeId;
41
+ other is HavenSeedStoreAdapter && runtimeType == other.runtimeType && typeId == other.typeId;
42
}
lib/entities/ios_legacy_helper.dart
+6
-12
@@ -3,23 +3,17 @@ import 'dart:typed_data';
3
import 'package:flutter/foundation.dart';
4
import 'package:flutter/services.dart';
5
6
-const platform =
7
- const MethodChannel('com.cakewallet.cakewallet/legacy_wallet_migration');
6
+const platform = const MethodChannel('com.cakewallet.cakewallet/legacy_wallet_migration');
7
9
-Future<String> decrypt(Uint8List bytes,
10
- {required String key, required String salt}) async =>
11
- (await platform
12
- .invokeMethod<String>('decrypt', {'bytes': bytes, 'key': key, 'salt': salt}))!;
8
+Future<String> decrypt(Uint8List bytes, {required String key, required String salt}) async =>
9
+ (await platform.invokeMethod<String>('decrypt', {'bytes': bytes, 'key': key, 'salt': salt}))!;
10
11
Future<dynamic> readUserDefaults(String key, {required String type}) async =>
15
- await platform
16
- .invokeMethod<dynamic>('read_user_defaults', {'key': key, 'type': type});
12
+ await platform.invokeMethod<dynamic>('read_user_defaults', {'key': key, 'type': type});
13
14
Future<String?> getString(String key) async =>
15
await readUserDefaults(key, type: 'string') as String?;
16
21
-Future<bool?> getBool(String key) async =>
22
- await readUserDefaults(key, type: 'bool') as bool?;
17
+Future<bool?> getBool(String key) async => await readUserDefaults(key, type: 'bool') as bool?;
18
24
-Future<int?> getInt(String key) async =>
25
- await readUserDefaults(key, type: 'int') as int?;
19
+Future<int?> getInt(String key) async => await readUserDefaults(key, type: 'int') as int?;
lib/entities/new_ui_entities/list_item/list_item.dart
+3
-3
@@ -15,7 +15,7 @@ abstract class ListItem {
15
final bool isLastInSection;
16
17
BorderRadius get radius => BorderRadius.vertical(
18
- top: Radius.circular(isFirstInSection ? 16 : 0),
19
- bottom: Radius.circular(isLastInSection ? 16 : 0),
20
- );
18
+ top: Radius.circular(isFirstInSection ? 16 : 0),
19
+ bottom: Radius.circular(isLastInSection ? 16 : 0),
20
+ );
21
}
lib/entities/new_ui_entities/list_item/list_item_selector.dart
+1
-1
@@ -13,4 +13,4 @@ class ListItemSelector extends ListItem {
13
final String? trailingText;
14
final VoidCallback onTap;
15
final List<String> options;
16
-}
\ No newline at end of file
16
+}
lib/entities/new_ui_entities/list_item/list_item_text_field.dart
+8
-11
@@ -2,21 +2,18 @@ import 'package:cake_wallet/entities/new_ui_entities/list_item/list_item.dart';
2
import 'package:flutter/material.dart';
3
4
class ListItemTextField extends ListItem {
5
- const ListItemTextField({
6
- required super.keyValue,
7
- required super.label,
8
- this.initialValue,
9
- this.validator,
10
- this.onChanged,
11
- this.onFieldSubmitted,
12
- this.focusNode
13
- });
5
+ const ListItemTextField(
6
+ {required super.keyValue,
7
+ required super.label,
8
+ this.initialValue,
9
+ this.validator,
10
+ this.onChanged,
11
+ this.onFieldSubmitted,
12
+ this.focusNode});
13
14
final String? initialValue;
15
final FormFieldValidator<String>? validator;
16
final ValueChanged<String>? onChanged;
17
final ValueChanged<String>? onFieldSubmitted;
18
final FocusNode? focusNode;
20
-
21
-
19
}
lib/entities/node_check.dart
+12
-11
@@ -31,19 +31,21 @@ const Map<WalletType, String> powNodePreferenceKeys = {
31
WalletType.nano: PreferencesKey.currentNanoPowNodeIdKey
32
};
33
34
-Future<void> checkNodeForWalletType(SharedPreferences sharedPreferences, SettingsStore settingsStore, WalletType type, bool isPow) async {
34
+Future<void> checkNodeForWalletType(SharedPreferences sharedPreferences,
35
+ SettingsStore settingsStore, WalletType type, bool isPow) async {
36
final preferenceKey = isPow ? powNodePreferenceKeys[type] : nodePreferenceKeys[type];
37
37
- if(preferenceKey == null) {
38
+ if (preferenceKey == null) {
39
return;
40
}
41
42
final currentId = await sharedPreferences.getInt(preferenceKey);
43
43
- final nodes = isPow ? await Node.getAllForWalletTypePow(type) : await Node.getAllForWalletType(type);
44
- final currentNode = nodes.firstWhereOrNull((item)=>item.id == currentId);
44
+ final nodes =
45
+ isPow ? await Node.getAllForWalletTypePow(type) : await Node.getAllForWalletType(type);
46
+ final currentNode = nodes.firstWhereOrNull((item) => item.id == currentId);
47
46
- if(currentNode == null) {
48
+ if (currentNode == null) {
49
final newNode = (isPow
50
? await Node.getDefaultPowForWalletType(type)
51
: await Node.getDefaultForWalletType(type)) ??
@@ -54,16 +56,15 @@ Future<void> checkNodeForWalletType(SharedPreferences sharedPreferences, Setting
56
} else {
57
settingsStore.nodes[type] = currentNode;
58
}
57
-
59
}
60
60
-
61
-Future<void> checkCurrentNodes(SharedPreferences sharedPreferences, SettingsStore settingsStore) async {
62
- for(final walletType in nodePreferenceKeys.keys) {
61
+Future<void> checkCurrentNodes(
62
+ SharedPreferences sharedPreferences, SettingsStore settingsStore) async {
63
+ for (final walletType in nodePreferenceKeys.keys) {
64
await checkNodeForWalletType(sharedPreferences, settingsStore, walletType, false);
65
}
66
66
- for(final walletType in powNodePreferenceKeys.keys) {
67
+ for (final walletType in powNodePreferenceKeys.keys) {
68
await checkNodeForWalletType(sharedPreferences, settingsStore, walletType, true);
69
}
69
-}
\ No newline at end of file
70
+}
lib/entities/node_list.dart
+1
@@ -0,0 +1 @@
1
+
lib/entities/pin_code_required_duration.dart
+1
-1
@@ -11,7 +11,7 @@ enum PinCodeRequiredDuration {
11
12
final int value;
13
14
- static PinCodeRequiredDuration deserialize({required int raw}) =>
14
+ static PinCodeRequiredDuration deserialize({required int raw}) =>
15
PinCodeRequiredDuration.values.firstWhere((e) => e.value == raw);
16
17
@override
lib/entities/preferences_key.dart
+2
-1
@@ -137,7 +137,8 @@ class PreferencesKey {
137
static const walletConnectPairingTopicsList = 'wallet_connect_pairing_topics_list';
138
static String walletConnectPairingTopicsListForWallet(String publicKey) =>
139
'${PreferencesKey.walletConnectPairingTopicsList}_${publicKey}';
140
- static String backgroundSyncLastTrigger(String walletId) => 'background_sync_last_trigger_${walletId}';
140
+ static String backgroundSyncLastTrigger(String walletId) =>
141
+ 'background_sync_last_trigger_${walletId}';
142
static const backgroundSyncNotificationsEnabled = 'background_sync_notifications_enabled';
143
static const enableAutomaticNodeSwitching = 'enable_automatic_node_switching';
144
static const syncStatusDisplayMode = 'sync_status_display_mode';
lib/entities/provider_types.dart
+13
-13
@@ -47,20 +47,20 @@ extension ProviderTypeName on ProviderType {
47
48
class ProvidersHelper {
49
static List<ProviderType> getAvailableBuyProviderTypes() => [
50
- ProviderType.robinhood,
51
- ProviderType.dfx,
52
- ProviderType.onramper,
53
- ProviderType.moonpay,
54
- ProviderType.kriptonim
55
- ];
50
+ ProviderType.robinhood,
51
+ ProviderType.dfx,
52
+ ProviderType.onramper,
53
+ ProviderType.moonpay,
54
+ ProviderType.kriptonim
55
+ ];
56
57
static List<ProviderType> getAvailableSellProviderTypes() => [
58
- // ProviderType.robinhood, // ToDo: (Konsti) Enable once fixed in Exchange Helper, but still waiting for new Docs
59
- ProviderType.dfx,
60
- ProviderType.onramper,
61
- ProviderType.moonpay,
62
- ProviderType.kriptonim
63
- ];
58
+ // ProviderType.robinhood, // ToDo: (Konsti) Enable once fixed in Exchange Helper, but still waiting for new Docs
59
+ ProviderType.dfx,
60
+ ProviderType.onramper,
61
+ ProviderType.moonpay,
62
+ ProviderType.kriptonim
63
+ ];
64
65
static BuyProvider getProviderByType(ProviderType type) {
66
switch (type) {
@@ -76,6 +76,6 @@ class ProvidersHelper {
76
return getIt.get<MeldBuyProvider>();
77
case ProviderType.kriptonim:
78
return getIt.get<KryptonimBuyProvider>();
79
- }
79
+ }
80
}
81
}
lib/entities/qr_scanner.dart
+2
-1
@@ -14,7 +14,8 @@ import 'package:ur/ur_decoder.dart';
14
15
var isQrScannerShown = false;
16
17
-Future<String?> presentQRScanner(BuildContext context, {bool showHelp = false, bool showManualInput = true, bool useModal = false}) async {
17
+Future<String?> presentQRScanner(BuildContext context,
18
+ {bool showHelp = false, bool showManualInput = true, bool useModal = false}) async {
19
isQrScannerShown = true;
20
try {
21
final result = useModal
lib/entities/qr_view_data.dart
+1
-1
@@ -5,7 +5,7 @@ class QrViewData {
5
required this.data,
6
this.embeddedImagePath,
7
});
8
-
8
+
9
final int? version;
10
final String? heroTag;
11
final String data;
lib/entities/seed_phrase_length.dart
+1
-2
@@ -1,4 +1,3 @@
1
-
1
enum SeedPhraseLength {
2
twelveWords(12),
3
twentyFourWords(24);
@@ -22,4 +21,4 @@ enum SeedPhraseLength {
21
}
22
return label;
23
}
25
-}
\ No newline at end of file
24
+}
lib/entities/seed_type.dart
+2
-1
@@ -12,7 +12,8 @@ class MoneroSeedType extends EnumerableItem<int> with Serializable<int> {
12
static const defaultSeedType = polyseed;
13
14
static const legacy = MoneroSeedType(raw: 0, title: 'Legacy (25 words)', shortTitle: "Legacy");
15
- static const polyseed = MoneroSeedType(raw: 1, title: 'Polyseed (16 words)', shortTitle: "Polyseed");
15
+ static const polyseed =
16
+ MoneroSeedType(raw: 1, title: 'Polyseed (16 words)', shortTitle: "Polyseed");
17
static const wowneroSeed = MoneroSeedType(raw: 2, title: 'Wownero');
18
static const bip39 = MoneroSeedType(raw: 3, title: 'BIP39 (12 words)', shortTitle: "BIP39");
19
lib/entities/service_status.dart
+1
-2
@@ -28,8 +28,7 @@ class ServicesResponse {
28
29
ServicesResponse(this.servicesStatus, this.hasUpdates, this.currentSha);
30
31
- factory ServicesResponse.fromJson(
32
- Map<String, dynamic> json, bool hasUpdates, String currentSha) {
31
+ factory ServicesResponse.fromJson(Map<String, dynamic> json, bool hasUpdates, String currentSha) {
32
return ServicesResponse(
33
(json['notices'] as List? ?? [])
34
.map((e) => ServiceStatus.fromJson(e as Map<String, dynamic>))
lib/entities/sort_balance_types.dart
+1
-1
@@ -16,4 +16,4 @@ enum SortBalanceBy {
16
return S.current.alphabetical;
17
}
18
}
19
-}
\ No newline at end of file
19
+}
lib/entities/template.part.dart
+1
-3
@@ -56,7 +56,5 @@ class TemplateAdapter extends TypeAdapter<Template> {
56
@override
57
bool operator ==(Object other) =>
58
identical(this, other) ||
59
- other is TemplateAdapter &&
60
- runtimeType == other.runtimeType &&
61
- typeId == other.typeId;
59
+ other is TemplateAdapter && runtimeType == other.runtimeType && typeId == other.typeId;
60
}
lib/entities/transaction_creation_credentials.dart
+1
-1
@@ -1 +1 @@
1
-abstract class TransactionCreationCredentials {}
\ No newline at end of file
1
+abstract class TransactionCreationCredentials {}
lib/entities/transaction_description.dart
+7
-6
@@ -5,7 +5,8 @@ part 'transaction_description.part.dart';
5
6
// @HiveType(typeId: TransactionDescription.typeId)
7
class TransactionDescription extends HiveObject {
8
- TransactionDescription({required this.id, this.recipientAddress, this.transactionNote, this.transactionKey});
8
+ TransactionDescription(
9
+ {required this.id, this.recipientAddress, this.transactionNote, this.transactionKey});
10
11
static const typeId = TRANSACTION_TYPE_ID;
12
static const boxName = 'TransactionDescriptions';
@@ -26,11 +27,11 @@ class TransactionDescription extends HiveObject {
27
String get note => transactionNote ?? '';
28
29
Map<String, dynamic> toJson() => {
29
- 'id': id,
30
- 'recipientAddress': recipientAddress,
31
- 'transactionNote': transactionNote,
32
- 'transactionKey': transactionKey,
33
- };
30
+ 'id': id,
31
+ 'recipientAddress': recipientAddress,
32
+ 'transactionNote': transactionNote,
33
+ 'transactionKey': transactionKey,
34
+ };
35
36
factory TransactionDescription.fromJson(Map<String, dynamic> json) {
37
return TransactionDescription(
lib/entities/transaction_description.part.dart
+1
-2
@@ -6,8 +6,7 @@ part of 'transaction_description.dart';
6
// TypeAdapterGenerator
7
// **************************************************************************
8
9
-class TransactionDescriptionAdapter
10
- extends TypeAdapter<TransactionDescription> {
9
+class TransactionDescriptionAdapter extends TypeAdapter<TransactionDescription> {
10
@override
11
final int typeId = 2;
12
lib/entities/transaction_history.dart
+1
-2
@@ -2,8 +2,7 @@ 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>>([]);
5
+ TransactionHistory() : transactions = Observable<List<TransactionInfo>>([]);
6
7
Observable<List<TransactionInfo>> transactions;
8
Future<List<TransactionInfo>> getAll();
lib/entities/wallet_description.dart
+2
-2
@@ -2,7 +2,7 @@ import 'package:cw_core/wallet_type.dart';
2
3
class WalletDescription {
4
WalletDescription({required this.name, required this.type});
5
-
5
+
6
final String name;
7
final WalletType type;
8
-}
\ No newline at end of file
8
+}
lib/entities/wallet_manager.dart
+4
-4
@@ -165,11 +165,11 @@ class WalletManager {
165
166
String? getGroupName(WalletInfo walletInfo) {
167
try {
168
- final groupKey = _resolveGroupKey(walletInfo);
169
- final group = walletGroups.firstWhere((g) => g.groupKey == groupKey);
170
- return group.groupName;
168
+ final groupKey = _resolveGroupKey(walletInfo);
169
+ final group = walletGroups.firstWhere((g) => g.groupKey == groupKey);
170
+ return group.groupName;
171
} catch (_) {
172
- return null;
172
+ return null;
173
}
174
}
175
}
lib/entities/wallet_nft_response.dart
+1
-3
@@ -43,8 +43,7 @@ class NFTAssetModel {
43
name: json['name'] as String?,
44
symbol: json['symbol'] as String?,
45
normalizedMetadata: json['normalized_metadata'] != null
46
- ? new NormalizedMetadata.fromJson(
47
- json['normalized_metadata'] as Map<String, dynamic>)
46
+ ? new NormalizedMetadata.fromJson(json['normalized_metadata'] as Map<String, dynamic>)
47
: null,
48
);
49
}
@@ -66,7 +65,6 @@ class NormalizedMetadata {
65
description: json['description'] as String?,
66
image: json['image'] as String?,
67
);
69
-
68
}
69
70
String? get imageUrl {
lib/exchange/exchange_provider_description.dart
+85
-33
@@ -2,47 +2,99 @@ import 'package:cw_core/enumerable_item.dart';
2
3
class ExchangeProviderDescription extends EnumerableItem<int> with Serializable<int> {
4
const ExchangeProviderDescription(
5
- {required String title, required int raw, required this.image, this.horizontalLogo = false, required this.isCentralized})
5
+ {required String title,
6
+ required int raw,
7
+ required this.image,
8
+ this.horizontalLogo = false,
9
+ required this.isCentralized})
10
: super(title: title, raw: raw);
11
12
final bool horizontalLogo;
13
final String image;
14
final bool isCentralized;
15
12
- static const xmrto =
13
- ExchangeProviderDescription(title: 'XMR.TO', raw: 0, image: 'assets/new-ui/trade_providers/xmrto.svg', isCentralized: true);
14
- static const changeNow =
15
- ExchangeProviderDescription(title: 'ChangeNOW', raw: 1, image: 'assets/new-ui/trade_providers/changenow.svg', isCentralized: true);
16
- static const morphToken =
17
- ExchangeProviderDescription(title: 'MorphToken', raw: 2, image: 'assets/new-ui/trade_providers/morph.svg', isCentralized: true);
18
- static const sideShift =
19
- ExchangeProviderDescription(title: 'SideShift', raw: 3, image: 'assets/new-ui/trade_providers/sideshift.svg', isCentralized: true);
20
- static const simpleSwap =
21
- ExchangeProviderDescription(title: 'SimpleSwap', raw: 4, image: 'assets/new-ui/trade_providers/simpleswap.svg', isCentralized: true);
22
- static const trocador =
23
- ExchangeProviderDescription(title: 'Trocador', raw: 5, image: 'assets/new-ui/trade_providers/trocador.svg', isCentralized: true);
24
- static const exolix =
25
- ExchangeProviderDescription(title: 'Exolix', raw: 6, image: 'assets/new-ui/trade_providers/exolix.svg', isCentralized: true);
16
+ static const xmrto = ExchangeProviderDescription(
17
+ title: 'XMR.TO',
18
+ raw: 0,
19
+ image: 'assets/new-ui/trade_providers/xmrto.svg',
20
+ isCentralized: true);
21
+ static const changeNow = ExchangeProviderDescription(
22
+ title: 'ChangeNOW',
23
+ raw: 1,
24
+ image: 'assets/new-ui/trade_providers/changenow.svg',
25
+ isCentralized: true);
26
+ static const morphToken = ExchangeProviderDescription(
27
+ title: 'MorphToken',
28
+ raw: 2,
29
+ image: 'assets/new-ui/trade_providers/morph.svg',
30
+ isCentralized: true);
31
+ static const sideShift = ExchangeProviderDescription(
32
+ title: 'SideShift',
33
+ raw: 3,
34
+ image: 'assets/new-ui/trade_providers/sideshift.svg',
35
+ isCentralized: true);
36
+ static const simpleSwap = ExchangeProviderDescription(
37
+ title: 'SimpleSwap',
38
+ raw: 4,
39
+ image: 'assets/new-ui/trade_providers/simpleswap.svg',
40
+ isCentralized: true);
41
+ static const trocador = ExchangeProviderDescription(
42
+ title: 'Trocador',
43
+ raw: 5,
44
+ image: 'assets/new-ui/trade_providers/trocador.svg',
45
+ isCentralized: true);
46
+ static const exolix = ExchangeProviderDescription(
47
+ title: 'Exolix',
48
+ raw: 6,
49
+ image: 'assets/new-ui/trade_providers/exolix.svg',
50
+ isCentralized: true);
51
static const all =
52
ExchangeProviderDescription(title: 'All trades', raw: 7, image: '', isCentralized: true);
28
- static const thorChain =
29
- ExchangeProviderDescription(title: 'ThorChain', raw: 8, image: 'assets/new-ui/trade_providers/thorchain.svg', isCentralized: true);
30
- static const swapTrade =
31
- ExchangeProviderDescription(title: 'SwapTrade', raw: 9, image: 'assets/new-ui/trade_providers/swaptrade.svg', isCentralized: true);
32
- static const letsExchange =
33
- ExchangeProviderDescription(title: 'LetsExchange', raw: 10, image: 'assets/new-ui/trade_providers/letsexchange.svg', isCentralized: true);
34
- static const stealthEx =
35
- ExchangeProviderDescription(title: 'StealthEx', raw: 11, image: 'assets/new-ui/trade_providers/stealthex.svg', isCentralized: true);
36
- static const chainflip =
37
- ExchangeProviderDescription(title: 'Chainflip', raw: 12, image: 'assets/new-ui/trade_providers/chainflip.svg', isCentralized: false);
38
- static const xoSwap =
39
- ExchangeProviderDescription(title: 'XOSwap', raw: 13, image: 'assets/new-ui/trade_providers/xoswap.svg', isCentralized: true);
40
- static const swapsXyz =
41
- ExchangeProviderDescription(title: 'Swaps.XYZ', raw: 14, image: 'assets/new-ui/trade_providers/swaps_xyz.svg', isCentralized: true);
42
- static const nearIntents =
43
- ExchangeProviderDescription(title: 'Near Intents', raw: 15, image: 'assets/new-ui/trade_providers/near-intents.svg', isCentralized: false);
44
- static const jupiter =
45
- ExchangeProviderDescription(title: 'Jupiter', raw: 16, image: 'assets/new-ui/trade_providers/jupiter.svg', isCentralized: false);
53
+ static const thorChain = ExchangeProviderDescription(
54
+ title: 'ThorChain',
55
+ raw: 8,
56
+ image: 'assets/new-ui/trade_providers/thorchain.svg',
57
+ isCentralized: true);
58
+ static const swapTrade = ExchangeProviderDescription(
59
+ title: 'SwapTrade',
60
+ raw: 9,
61
+ image: 'assets/new-ui/trade_providers/swaptrade.svg',
62
+ isCentralized: true);
63
+ static const letsExchange = ExchangeProviderDescription(
64
+ title: 'LetsExchange',
65
+ raw: 10,
66
+ image: 'assets/new-ui/trade_providers/letsexchange.svg',
67
+ isCentralized: true);
68
+ static const stealthEx = ExchangeProviderDescription(
69
+ title: 'StealthEx',
70
+ raw: 11,
71
+ image: 'assets/new-ui/trade_providers/stealthex.svg',
72
+ isCentralized: true);
73
+ static const chainflip = ExchangeProviderDescription(
74
+ title: 'Chainflip',
75
+ raw: 12,
76
+ image: 'assets/new-ui/trade_providers/chainflip.svg',
77
+ isCentralized: false);
78
+ static const xoSwap = ExchangeProviderDescription(
79
+ title: 'XOSwap',
80
+ raw: 13,
81
+ image: 'assets/new-ui/trade_providers/xoswap.svg',
82
+ isCentralized: true);
83
+ static const swapsXyz = ExchangeProviderDescription(
84
+ title: 'Swaps.XYZ',
85
+ raw: 14,
86
+ image: 'assets/new-ui/trade_providers/swaps_xyz.svg',
87
+ isCentralized: true);
88
+ static const nearIntents = ExchangeProviderDescription(
89
+ title: 'Near Intents',
90
+ raw: 15,
91
+ image: 'assets/new-ui/trade_providers/near-intents.svg',
92
+ isCentralized: false);
93
+ static const jupiter = ExchangeProviderDescription(
94
+ title: 'Jupiter',
95
+ raw: 16,
96
+ image: 'assets/new-ui/trade_providers/jupiter.svg',
97
+ isCentralized: false);
98
99
static ExchangeProviderDescription deserialize({required int raw}) {
100
switch (raw) {
lib/exchange/provider/chainflip_exchange_provider.dart
+35
-40
@@ -31,7 +31,7 @@ class ChainflipExchangeProvider extends ExchangeProvider {
31
CryptoCurrency.usdtArb,
32
CryptoCurrency.trx,
33
CryptoCurrency.usdttrc20,
34
- ];
34
+ ];
35
36
static const _baseURL = 'chainflip-broker.io';
37
static const _assetsPath = '/assets';
@@ -57,8 +57,7 @@ class ChainflipExchangeProvider extends ExchangeProvider {
57
bool get supportsMemoOrDestinationTag => false;
58
59
@override
60
- ExchangeProviderDescription get description =>
61
- ExchangeProviderDescription.chainflip;
60
+ ExchangeProviderDescription get description => ExchangeProviderDescription.chainflip;
61
62
@override
63
Future<bool> checkIsAvailable() async => true;
@@ -68,25 +67,23 @@ class ChainflipExchangeProvider extends ExchangeProvider {
67
{required CryptoCurrency from,
68
required CryptoCurrency to,
69
required bool isFixedRateMode}) async {
71
-
70
try {
73
-
74
- if(!_supported.contains(from) || !_supported.contains(to)) {
71
+ if (!_supported.contains(from) || !_supported.contains(to)) {
72
throw Exception('No rates found for $from to $to');
73
}
74
78
- final assetId = _normalizeCurrency(from);
75
+ final assetId = _normalizeCurrency(from);
76
80
- final assetsResponse = await _getAssets();
81
- final assets = assetsResponse['assets'] as List<dynamic>;
77
+ final assetsResponse = await _getAssets();
78
+ final assets = assetsResponse['assets'] as List<dynamic>;
79
83
- final minAmount = assets.firstWhere(
84
- (asset) => asset['id'] == assetId,
85
- orElse: () => null)?['minimalAmountNative'] ?? '0';
80
+ final minAmount = assets.firstWhere((asset) => asset['id'] == assetId,
81
+ orElse: () => null)?['minimalAmountNative'] ??
82
+ '0';
83
87
- if (minAmount == '0') throw Exception('No rates found for $from to $to');
84
+ if (minAmount == '0') throw Exception('No rates found for $from to $to');
85
89
- return Limits(min: _amountFromNative(minAmount.toString(), from));
86
+ return Limits(min: _amountFromNative(minAmount.toString(), from));
87
} catch (e) {
88
printV(e.toString());
89
throw Exception('Chainflip failed to fetch limits');
@@ -94,20 +91,18 @@ class ChainflipExchangeProvider extends ExchangeProvider {
91
}
92
93
@override
97
- Future<double> fetchRate({
98
- required CryptoCurrency from,
99
- required CryptoCurrency to,
100
- required double amount,
101
- required bool isFixedRateMode,
102
- required bool isReceiveAmount
103
- }) async {
94
+ Future<double> fetchRate(
95
+ {required CryptoCurrency from,
96
+ required CryptoCurrency to,
97
+ required double amount,
98
+ required bool isFixedRateMode,
99
+ required bool isReceiveAmount}) async {
100
// TODO: It seems this rate is getting cached, and re-used for different amounts, can we not do this?
101
102
try {
103
if (amount == 0) return 0.0;
104
109
- if(!_supported.contains(from) || !_supported.contains(to)) return 0.0;
110
-
105
+ if (!_supported.contains(from) || !_supported.contains(to)) return 0.0;
106
107
final quoteParams = {
108
'apiKey': _affiliateKey,
@@ -119,8 +114,7 @@ class ChainflipExchangeProvider extends ExchangeProvider {
114
115
final quoteResponse = await _getSwapQuote(quoteParams);
116
122
- final expectedAmountOut =
123
- quoteResponse['egressAmountNative'] as String? ?? '0';
117
+ final expectedAmountOut = quoteResponse['egressAmountNative'] as String? ?? '0';
118
119
final rate = _amountFromNative(expectedAmountOut, to) / amount;
120
@@ -194,7 +188,8 @@ class ChainflipExchangeProvider extends ExchangeProvider {
188
'retryDurationInBlocks': '150'
189
};
190
197
- if (quoteResponse.containsKey('numberOfChunks') && quoteResponse.containsKey('chunkIntervalBlocks')) {
191
+ if (quoteResponse.containsKey('numberOfChunks') &&
192
+ quoteResponse.containsKey('chunkIntervalBlocks')) {
193
swapParams.addAll({
194
'numberOfChunks': quoteResponse['numberOfChunks'].toString(),
195
'chunkIntervalBlocks': quoteResponse['chunkIntervalBlocks'].toString(),
@@ -203,7 +198,8 @@ class ChainflipExchangeProvider extends ExchangeProvider {
198
199
final swapResponse = await _openDepositChannel(swapParams);
200
206
- final id = '${swapResponse['issuedBlock']}-${swapResponse['network'].toString()}-${swapResponse['channelId']}';
201
+ final id =
202
+ '${swapResponse['issuedBlock']}-${swapResponse['network'].toString()}-${swapResponse['channelId']}';
203
204
ExchangeProviderLogger.logSuccess(
205
provider: description,
@@ -280,8 +276,7 @@ class ChainflipExchangeProvider extends ExchangeProvider {
276
277
final statusResponse = await _getStatus(statusParams);
278
283
- if (statusResponse == null)
284
- throw Exception('Trade not found for id: $id');
279
+ if (statusResponse == null) throw Exception('Trade not found for id: $id');
280
281
final status = statusResponse['status'];
282
final currentState = _determineState(status['state'].toString());
@@ -294,7 +289,7 @@ class ChainflipExchangeProvider extends ExchangeProvider {
289
290
final from = status['sourceAsset'].toString();
291
final to = status['destinationAsset'].toString();
297
-
292
+
293
final newTrade = Trade(
294
id: id,
295
from: _toCurrency(from),
@@ -304,8 +299,7 @@ class ChainflipExchangeProvider extends ExchangeProvider {
299
receiveAmount: amount,
300
state: currentState,
301
payoutAddress: status['destinationAddress'].toString(),
307
- outputTransaction:
308
- status['swapEgress']?['transactionReference']?.toString(),
302
+ outputTransaction: status['swapEgress']?['transactionReference']?.toString(),
303
isRefund: isRefund,
304
);
305
@@ -331,7 +325,7 @@ class ChainflipExchangeProvider extends ExchangeProvider {
325
return '$title.$tag';
326
}
327
334
- String _normalizeNetworkName (String name) {
328
+ String _normalizeNetworkName(String name) {
329
final networkName = switch (name) {
330
'BITCOIN' => 'Bitcoin',
331
'ETHEREUM' => 'Ethereum',
@@ -344,7 +338,6 @@ class ChainflipExchangeProvider extends ExchangeProvider {
338
return networkName;
339
}
340
347
-
341
CryptoCurrency? _toCurrency(String name) {
342
final currency = switch (name) {
343
'btc.btc' => CryptoCurrency.btc,
@@ -372,8 +365,7 @@ class ChainflipExchangeProvider extends ExchangeProvider {
365
double _amountFromNative(String amount, CryptoCurrency currency) =>
366
double.parse(amount) / pow(10, currency.decimals);
367
375
- Future<Map<String, dynamic>> _getAssets() async =>
376
- _getRequest(_assetsPath, {});
368
+ Future<Map<String, dynamic>> _getAssets() async => _getRequest(_assetsPath, {});
369
370
Future<Map<String, dynamic>> _openDepositChannel(Map<String, String> params) async =>
371
_getRequest(_swapPath, params);
@@ -384,7 +376,8 @@ class ChainflipExchangeProvider extends ExchangeProvider {
376
final response = await ProxyWrapper().get(clearnetUri: uri);
377
378
if ((response.statusCode != 200) || (response.body.contains('error'))) {
387
- throw Exception('Unexpected response: ${response.statusCode} / ${uri.toString()} / ${response.body}');
379
+ throw Exception(
380
+ 'Unexpected response: ${response.statusCode} / ${uri.toString()} / ${response.body}');
381
}
382
383
return json.decode(response.body) as Map<String, dynamic>;
@@ -396,12 +389,13 @@ class ChainflipExchangeProvider extends ExchangeProvider {
389
final response = await ProxyWrapper().get(clearnetUri: uri);
390
391
if ((response.statusCode != 200) || (response.body.contains('error'))) {
399
- throw Exception('Unexpected response: ${response.statusCode} / ${uri.toString()} / ${response.body}');
392
+ throw Exception(
393
+ 'Unexpected response: ${response.statusCode} / ${uri.toString()} / ${response.body}');
394
}
395
396
final List<dynamic> jsonList = json.decode(response.body) as List<dynamic>;
397
final List<Map<String, dynamic>> quotes =
404
- jsonList.map((e) => e as Map<String, dynamic>).toList();
398
+ jsonList.map((e) => e as Map<String, dynamic>).toList();
399
400
Map<String, dynamic> highestQuote = quotes.reduce((current, next) {
401
double currentAmount = current['egressAmount'] as double;
@@ -421,7 +415,8 @@ class ChainflipExchangeProvider extends ExchangeProvider {
415
if (response.statusCode == 404) return null;
416
417
if ((response.statusCode != 200) || (response.body.contains('error'))) {
424
- throw Exception('Unexpected response: ${response.statusCode} / ${uri.toString()} / ${response.body}');
418
+ throw Exception(
419
+ 'Unexpected response: ${response.statusCode} / ${uri.toString()} / ${response.body}');
420
}
421
422
return json.decode(response.body) as Map<String, dynamic>;
lib/exchange/provider/exolix_exchange_provider.dart
+21
-25
@@ -69,8 +69,7 @@ class ExolixExchangeProvider extends ExchangeProvider {
69
for (int i = 0; i < 2; i++) {
70
final uri = Uri.https(apiBaseUrl, ratePath, params);
71
final response = await ProxyWrapper().get(clearnetUri: uri);
72
-
73
-
72
+
73
if (response.statusCode == 200) {
74
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
75
final minAmount = responseJSON['minAmount'];
@@ -92,13 +91,12 @@ class ExolixExchangeProvider extends ExchangeProvider {
91
}
92
93
@override
95
- Future<double> fetchRate({
96
- required CryptoCurrency from,
97
- required CryptoCurrency to,
98
- required double amount,
99
- required bool isFixedRateMode,
100
- required bool isReceiveAmount
101
- }) async {
94
+ Future<double> fetchRate(
95
+ {required CryptoCurrency from,
96
+ required CryptoCurrency to,
97
+ required double amount,
98
+ required bool isFixedRateMode,
99
+ required bool isReceiveAmount}) async {
100
try {
101
if (amount == 0) return 0.0;
102
@@ -118,12 +116,12 @@ class ExolixExchangeProvider extends ExchangeProvider {
116
117
final uri = Uri.https(apiBaseUrl, ratePath, params);
118
final response = await ProxyWrapper().get(clearnetUri: uri);
121
-
119
+
120
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
121
122
if (response.statusCode != 200) {
123
final message = responseJSON['message'] as String?;
126
-
124
+
125
ExchangeProviderLogger.logError(
126
provider: description,
127
function: 'fetchRate',
@@ -139,7 +137,7 @@ class ExolixExchangeProvider extends ExchangeProvider {
137
'url': uri.toString(),
138
},
139
);
142
-
140
+
141
throw Exception(message);
142
}
143
@@ -194,12 +192,12 @@ class ExolixExchangeProvider extends ExchangeProvider {
192
final headers = {'Content-Type': 'application/json'};
193
final body = {
194
'coinFrom': _normalizeCurrency(_overrideFromCryptoCurrency(request.fromCurrency)),
197
- 'coinTo': _normalizeCurrency(_overrideToCryptoCurrency(request.toCurrency, request.toAddress)),
195
+ 'coinTo':
196
+ _normalizeCurrency(_overrideToCryptoCurrency(request.toCurrency, request.toAddress)),
197
'networkFrom': _networkFor(request.fromCurrency),
198
'networkTo': _networkFor(request.toCurrency),
199
'withdrawalAddress': await _normalizeAddress(request.toAddress),
201
- if (request.toAddressExtraId.isNotEmpty)
202
- 'withdrawalExtraId': request.toAddressExtraId,
200
+ if (request.toAddressExtraId.isNotEmpty) 'withdrawalExtraId': request.toAddressExtraId,
201
'refundAddress': await _normalizeAddress(request.refundAddress),
202
'rateType': _getRateType(isFixedRateMode),
203
'apiToken': apiKey,
@@ -221,7 +219,7 @@ class ExolixExchangeProvider extends ExchangeProvider {
219
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
220
final errors = responseJSON['error'] as Map<String, String>;
221
final errorMessage = errors.values.join(', ');
224
-
222
+
223
ExchangeProviderLogger.logError(
224
provider: description,
225
function: 'createTrade',
@@ -240,7 +238,7 @@ class ExolixExchangeProvider extends ExchangeProvider {
238
'url': uri.toString(),
239
},
240
);
243
-
241
+
242
throw Exception(errorMessage);
243
}
244
@@ -326,7 +324,7 @@ class ExolixExchangeProvider extends ExchangeProvider {
324
final findTradeByIdPath = '$transactionsPath/$id';
325
final uri = Uri.https(apiBaseUrl, findTradeByIdPath);
326
final response = await ProxyWrapper().get(clearnetUri: uri);
329
-
327
+
328
if (response.statusCode == 404) throw TradeNotFoundException(id, provider: description);
329
330
if (response.statusCode == 400) {
@@ -346,7 +344,8 @@ class ExolixExchangeProvider extends ExchangeProvider {
344
final coinFrom = responseJSON['coinFrom']['coinCode'] as String;
345
final coinFromNetwork = responseJSON['coinFrom']['network'] as String?;
346
final _normalizedFromNetwork = _normalizeNetworkType(coinFromNetwork ?? '');
349
- final fromTag = coinFrom.toUpperCase() == _normalizedFromNetwork.toUpperCase() ? null : coinFromNetwork;
347
+ final fromTag =
348
+ coinFrom.toUpperCase() == _normalizedFromNetwork.toUpperCase() ? null : coinFromNetwork;
349
final from = CryptoCurrency.safeParseCurrencyFromString(coinFrom, tag: fromTag);
350
351
// Parsing 'to' currency
@@ -438,7 +437,7 @@ class ExolixExchangeProvider extends ExchangeProvider {
437
switch (tag) {
438
case 'POLY':
439
return 'Polygon';
441
- case 'ARB':
440
+ case 'ARB':
441
return 'Arbitrum';
442
default:
443
return tag;
@@ -446,17 +445,14 @@ class ExolixExchangeProvider extends ExchangeProvider {
445
}
446
447
Future<String> _normalizeAddress(String address) async {
449
- if (address.startsWith('bitcoincash:'))
450
- return address.replaceFirst('bitcoincash:', '');
448
+ if (address.startsWith('bitcoincash:')) return address.replaceFirst('bitcoincash:', '');
449
450
// Lightning addresses
453
- if(address.contains("@"))
454
- return await getBolt11FromLightingAddress(address) ?? address;
451
+ if (address.contains("@")) return await getBolt11FromLightingAddress(address) ?? address;
452
453
return address;
454
}
455
459
-
456
static double? _toDouble(dynamic value) {
457
if (value is int) {
458
return value.toDouble();
lib/exchange/provider/jupiter_exchange_provider.dart
+1
-2
@@ -226,8 +226,7 @@ class JupiterExchangeProvider extends ExchangeProvider {
226
}) async {
227
try {
228
// must support both
229
- if (!_isSolanaCurrency(request.fromCurrency) ||
230
- !_isSolanaCurrency(request.toCurrency)) {
229
+ if (!_isSolanaCurrency(request.fromCurrency) || !_isSolanaCurrency(request.toCurrency)) {
230
throw 'not supported currencies';
231
}
232
lib/exchange/provider/near_Intents_exchange_provider.dart
+27
-48
@@ -92,8 +92,7 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
92
bool get supportsMemoOrDestinationTag => false;
93
94
@override
95
- ExchangeProviderDescription get description =>
96
- ExchangeProviderDescription.nearIntents;
95
+ ExchangeProviderDescription get description => ExchangeProviderDescription.nearIntents;
96
97
@override
98
Future<bool> checkIsAvailable() async => true;
@@ -132,8 +131,8 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
131
throw Exception('fetchRate: Unsupported currency pair');
132
}
133
135
- final formattedAmount = AmountConverter.toBaseUnits(amount.toString(),
136
- isFixedRateMode ? destinationToken.decimals : originToken.decimals);
134
+ final formattedAmount = AmountConverter.toBaseUnits(
135
+ amount.toString(), isFixedRateMode ? destinationToken.decimals : originToken.decimals);
136
137
final dummyAddrFrom = getNearDummyAddress(from);
138
final dummyAddrTo = getNearDummyAddress(to);
@@ -156,10 +155,8 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
155
}
156
157
final q = quote['quote'] as Map<String, dynamic>;
159
- final amountIn =
160
- double.tryParse(q['amountInFormatted']?.toString() ?? '0') ?? 0.0;
161
- final amountOut =
162
- double.tryParse(q['amountOutFormatted']?.toString() ?? '0') ?? 0.0;
158
+ final amountIn = double.tryParse(q['amountInFormatted']?.toString() ?? '0') ?? 0.0;
159
+ final amountOut = double.tryParse(q['amountOutFormatted']?.toString() ?? '0') ?? 0.0;
160
161
if (amountIn == 0) return 0.0;
162
@@ -214,24 +211,21 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
211
try {
212
final tokens = await _geSupportedTokens();
213
final originToken = currencyToNearAssetId(request.fromCurrency, tokens);
217
- final destinationToken =
218
- currencyToNearAssetId(request.toCurrency, tokens);
214
+ final destinationToken = currencyToNearAssetId(request.toCurrency, tokens);
215
216
if (originToken == null || destinationToken == null) {
217
throw Exception('Unsupported currency pair');
218
}
219
224
- final rawAmountStr =
225
- isFixedRateMode ? request.toAmount : request.fromAmount;
220
+ final rawAmountStr = isFixedRateMode ? request.toAmount : request.fromAmount;
221
222
final baseAmount = AmountConverter.toBaseUnits(
223
rawAmountStr,
229
- isFixedRateMode
230
- ? request.toCurrency.decimals
231
- : request.fromCurrency.decimals,
224
+ isFixedRateMode ? request.toCurrency.decimals : request.fromCurrency.decimals,
225
);
226
234
- final depositMode = _memoRequiredCurrencies.contains(request.fromCurrency) ? "MEMO" : "SIMPLE";
227
+ final depositMode =
228
+ _memoRequiredCurrencies.contains(request.fromCurrency) ? "MEMO" : "SIMPLE";
229
230
final quote = await getSwapQuote(
231
dry: false,
@@ -271,11 +265,9 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
265
throw Exception('Failed to parse to currency from assetId: $toAssetId');
266
}
267
274
- final from = CryptoCurrency.safeParseCurrencyFromString(fromCurrency.$1,
275
- tag: fromCurrency.$2);
276
- final to = CryptoCurrency.safeParseCurrencyFromString(toCurrency.$1,
277
- tag: toCurrency.$2);
278
-
268
+ final from =
269
+ CryptoCurrency.safeParseCurrencyFromString(fromCurrency.$1, tag: fromCurrency.$2);
270
+ final to = CryptoCurrency.safeParseCurrencyFromString(toCurrency.$1, tag: toCurrency.$2);
271
272
final trade = Trade(
273
id: depositAddress,
@@ -345,8 +337,7 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
337
final param = {'depositAddress': id};
338
final uri = Uri.https(_baseUrl, '$_versionPath$_statusPath', param);
339
348
- final response =
349
- await ProxyWrapper().get(clearnetUri: uri, headers: _headers);
340
+ final response = await ProxyWrapper().get(clearnetUri: uri, headers: _headers);
341
342
if (response.statusCode != 200) {
343
throw Exception(
@@ -358,16 +349,14 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
349
final statusRaw = (data['status'] as String?) ?? 'UNKNOWN';
350
351
final quoteResponse = data['quoteResponse'] as Map<String, dynamic>? ?? {};
361
- final quoteRequest =
362
- quoteResponse['quoteRequest'] as Map<String, dynamic>? ?? {};
352
+ final quoteRequest = quoteResponse['quoteRequest'] as Map<String, dynamic>? ?? {};
353
354
final refundTo = quoteRequest['refundTo'] as String? ?? '';
355
final recipient = quoteRequest['recipient'] as String? ?? '';
356
357
// Parsing 'from' currency
358
final originAssetId = quoteRequest['originAsset'] as String? ?? '';
369
- final from =
370
- _nearAssetIdToCurrency(originAssetId, await _geSupportedTokens());
359
+ final from = _nearAssetIdToCurrency(originAssetId, await _geSupportedTokens());
360
361
CryptoCurrency? coinFrom;
362
CryptoCurrency? coinTo;
@@ -377,11 +366,9 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
366
}
367
368
// Parsing 'to' currency
380
- final destinationAssetId =
381
- quoteRequest['destinationAsset'] as String? ?? '';
369
+ final destinationAssetId = quoteRequest['destinationAsset'] as String? ?? '';
370
383
- final to =
384
- _nearAssetIdToCurrency(destinationAssetId, await _geSupportedTokens());
371
+ final to = _nearAssetIdToCurrency(destinationAssetId, await _geSupportedTokens());
372
373
if (to != null) {
374
coinTo = CryptoCurrency.safeParseCurrencyFromString(to.$1, tag: to.$2);
@@ -393,16 +380,13 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
380
final depositAddress = quote['depositAddress'] as String?;
381
final depositMemo = quote['depositMemo'] as String?;
382
396
- final depositAmount = swap['amountInFormatted']?.toString() ??
397
- quote['amountInFormatted']?.toString() ??
398
- '0';
383
+ final depositAmount =
384
+ swap['amountInFormatted']?.toString() ?? quote['amountInFormatted']?.toString() ?? '0';
385
400
- final receiveAmount = swap['amountOutFormatted']?.toString() ??
401
- quote['amountOutFormatted']?.toString();
386
+ final receiveAmount =
387
+ swap['amountOutFormatted']?.toString() ?? quote['amountOutFormatted']?.toString();
388
403
- final originTxHash = (swap['originChainTxHashes'] as List?)
404
- ?.firstOrNull?['hash']
405
- ?.toString();
389
+ final originTxHash = (swap['originChainTxHashes'] as List?)?.firstOrNull?['hash']?.toString();
390
391
return Trade(
392
id: id,
@@ -487,8 +471,7 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
471
"deadline": _isoUtcDeadline,
472
if (connectedWallets != null) "connectedWallets": connectedWallets,
473
if (sessionId != null) "sessionId": sessionId,
490
- if (virtualChainRecipient != null)
491
- "virtualChainRecipient": virtualChainRecipient,
474
+ if (virtualChainRecipient != null) "virtualChainRecipient": virtualChainRecipient,
475
if (virtualChainRefundRecipient != null)
476
"virtualChainRefundRecipient": virtualChainRefundRecipient,
477
if (customRecipientMsg != null) "customRecipientMsg": customRecipientMsg,
@@ -568,24 +551,20 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
551
return token;
552
}
553
571
- (String, String?)? _nearAssetIdToCurrency(
572
- String assetId, List<Token> supported) {
554
+ (String, String?)? _nearAssetIdToCurrency(String assetId, List<Token> supported) {
555
if (supported.isEmpty) return null;
556
557
final token = supported.firstWhereOrNull((t) => t.assetId == assetId);
558
559
if (token == null) return null;
560
579
- final title = token.symbol.toUpperCase()
580
- .replaceAll(RegExp(r'\s*\([^)]*\)'), '');
561
+ final title = token.symbol.toUpperCase().replaceAll(RegExp(r'\s*\([^)]*\)'), '');
562
563
final normalizedNetwork = _normalizeNearBlockchainToTag(token.blockchain);
564
565
final isNativeAsset = assetId.contains(':native:coin');
566
586
- final tag = isNativeAsset || normalizedNetwork == title
587
- ? null
588
- : normalizedNetwork;
567
+ final tag = isNativeAsset || normalizedNetwork == title ? null : normalizedNetwork;
568
569
return (title, tag);
570
}
lib/exchange/provider/sideshift_exchange_provider.dart
+9
-13
@@ -44,7 +44,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
44
const url = apiBaseUrl + permissionPath;
45
final uri = Uri.parse(url);
46
final response = await ProxyWrapper().get(clearnetUri: uri);
47
-
47
+
48
if (response.statusCode == 500) {
49
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
50
final error = responseJSON['error']['message'] as String;
@@ -74,7 +74,6 @@ class SideShiftExchangeProvider extends ExchangeProvider {
74
75
final uri = Uri.parse(url);
76
final response = await ProxyWrapper().get(clearnetUri: uri);
77
-
77
78
if (response.statusCode == 500) {
79
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -103,13 +102,12 @@ class SideShiftExchangeProvider extends ExchangeProvider {
102
}
103
104
@override
106
- Future<double> fetchRate({
107
- required CryptoCurrency from,
108
- required CryptoCurrency to,
109
- required double amount,
110
- required bool isFixedRateMode,
111
- required bool isReceiveAmount
112
- }) async {
105
+ Future<double> fetchRate(
106
+ {required CryptoCurrency from,
107
+ required CryptoCurrency to,
108
+ required double amount,
109
+ required bool isFixedRateMode,
110
+ required bool isReceiveAmount}) async {
111
try {
112
if (amount == 0) return 0.0;
113
@@ -123,7 +121,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
121
122
final uri = Uri.parse(url);
123
final response = await ProxyWrapper().get(clearnetUri: uri);
126
-
124
+
125
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
126
127
if (response.statusCode == 500) {
@@ -240,7 +238,6 @@ class SideShiftExchangeProvider extends ExchangeProvider {
238
headers: headers,
239
body: json.encode(body),
240
);
243
-
241
242
if (response.statusCode != 201) {
243
if (response.statusCode == 400) {
@@ -346,7 +343,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
343
final url = apiBaseUrl + orderPath + '/' + id;
344
final uri = Uri.parse(url);
345
final response = await ProxyWrapper().get(clearnetUri: uri);
349
-
346
+
347
if (response.statusCode == 404) {
348
throw TradeNotFoundException(id, provider: description);
349
}
@@ -415,7 +412,6 @@ class SideShiftExchangeProvider extends ExchangeProvider {
412
headers: headers,
413
body: json.encode(body),
414
);
418
-
415
416
if (response.statusCode != 201) {
417
if (response.statusCode == 400) {
lib/exchange/provider/simpleswap_exchange_provider.dart
+9
-16
@@ -17,7 +17,6 @@ import 'package:cake_wallet/utils/exchange_provider_logger.dart';
17
class SimpleSwapExchangeProvider extends ExchangeProvider {
18
SimpleSwapExchangeProvider();
19
20
-
20
static final apiKey =
21
DeviceInfo.instance.isMobile ? secrets.simpleSwapApiKey : secrets.simpleSwapApiKeyDesktop;
22
static const apiAuthority = 'api.simpleswap.io';
@@ -63,7 +62,6 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
62
final uri = Uri.https(apiAuthority, rangePath, params);
63
64
final response = await ProxyWrapper().get(clearnetUri: uri);
66
-
65
66
if (response.statusCode == 500) {
67
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -84,13 +82,12 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
82
}
83
84
@override
87
- Future<double> fetchRate({
88
- required CryptoCurrency from,
89
- required CryptoCurrency to,
90
- required double amount,
91
- required bool isFixedRateMode,
92
- required bool isReceiveAmount
93
- }) async {
85
+ Future<double> fetchRate(
86
+ {required CryptoCurrency from,
87
+ required CryptoCurrency to,
88
+ required double amount,
89
+ required bool isFixedRateMode,
90
+ required bool isReceiveAmount}) async {
91
try {
92
if (amount == 0) return 0.0;
93
@@ -103,7 +100,6 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
100
};
101
final uri = Uri.https(apiAuthority, getEstimatePath, params);
102
final response = await ProxyWrapper().get(clearnetUri: uri);
106
-
103
104
if (response.body == "null") {
105
ExchangeProviderLogger.logError(
@@ -123,7 +119,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
119
);
120
return 0.00;
121
}
126
-
122
+
123
final data = json.decode(response.body) as String;
124
final rate = double.parse(data) / amount;
125
@@ -190,7 +186,6 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
186
headers: headers,
187
body: json.encode(body),
188
);
193
-
189
190
if (response.statusCode != 200 && response.statusCode != 201) {
191
if (response.statusCode == 400) {
@@ -299,8 +294,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
294
final params = {'api_key': apiKey, 'id': id};
295
final uri = Uri.https(apiAuthority, getExchangePath, params);
296
final response = await ProxyWrapper().get(clearnetUri: uri);
302
-
303
-
297
+
298
if (response.statusCode == 404) {
299
throw TradeNotFoundException(id, provider: description);
300
}
@@ -325,8 +319,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
319
final status = responseJSON['status'] as String;
320
final payoutAddress = responseJSON['address_to'] as String;
321
328
- final fromParsed =
329
- CryptoCurrency.safeParseCurrencyFromString(fromCurrency);
322
+ final fromParsed = CryptoCurrency.safeParseCurrencyFromString(fromCurrency);
323
final toParsed = CryptoCurrency.safeParseCurrencyFromString(toCurrency);
324
return Trade(
325
id: id,
lib/exchange/provider/swapsxyz_exchange_provider.dart
+35
-68
@@ -19,7 +19,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
19
static final List<CryptoCurrency> _notSupportedAsSourceToken = [
20
CryptoCurrency.sol,
21
...CryptoCurrency.all.where(
22
- (c) => (c.tag ?? '').toUpperCase() == 'SOL' || c.tag == CryptoCurrency.bnb.tag,
22
+ (c) => (c.tag ?? '').toUpperCase() == 'SOL' || c.tag == CryptoCurrency.bnb.tag,
23
),
24
];
25
@@ -58,8 +58,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
58
bool get supportsMemoOrDestinationTag => false;
59
60
@override
61
- ExchangeProviderDescription get description =>
62
- ExchangeProviderDescription.swapsXyz;
61
+ ExchangeProviderDescription get description => ExchangeProviderDescription.swapsXyz;
62
63
@override
64
Future<bool> checkIsAvailable() async => true;
@@ -101,8 +100,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
100
101
final body = json.decode(res.body) as Map<String, dynamic>;
102
104
- final paths =
105
- (body['paths'] as List? ?? const []).cast<Map<String, dynamic>>();
103
+ final paths = (body['paths'] as List? ?? const []).cast<Map<String, dynamic>>();
104
if (paths.isEmpty) {
105
throw Exception('No paths for ${fromToUse.title} -> ${toToUse.title}');
106
}
@@ -121,18 +119,14 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
119
);
120
}
121
124
- final supportsExactAmountIn =
125
- path['supportsExactAmountIn'] as bool? ?? false;
126
- final supportsExactAmountOut =
127
- path['supportsExactAmountOut'] as bool? ?? false;
122
+ final supportsExactAmountIn = path['supportsExactAmountIn'] as bool? ?? false;
123
+ final supportsExactAmountOut = path['supportsExactAmountOut'] as bool? ?? false;
124
125
if (isFixedRateMode && !supportsExactAmountOut) {
130
- throw Exception(
131
- 'This route does not support fixed receive (exact-amount-out)');
126
+ throw Exception('This route does not support fixed receive (exact-amount-out)');
127
}
128
if (!isFixedRateMode && !supportsExactAmountIn) {
134
- throw Exception(
135
- 'This route does not support exact send (exact-amount-in)');
129
+ throw Exception('This route does not support exact send (exact-amount-in)');
130
}
131
132
Map<String, dynamic>? useLimits;
@@ -192,8 +186,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
186
final res = await ProxyWrapper().get(clearnetUri: uri, headers: _headers);
187
if (res.statusCode != 200) return null;
188
final body = json.decode(res.body) as Map<String, dynamic>;
195
- final paths =
196
- (body['paths'] as List?)?.cast<Map<String, dynamic>>() ?? const [];
189
+ final paths = (body['paths'] as List?)?.cast<Map<String, dynamic>>() ?? const [];
190
if (paths.isEmpty) return null;
191
final p = paths.first;
192
return _PathInfo(
@@ -210,23 +203,18 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
203
required bool isFixedRateMode,
204
required bool isReceiveAmount}) async {
205
try {
213
-
214
- if(_notSupportedAsSourceToken.contains(from) || _notSupportedAsSourceToken.contains(to)) {
215
- printV(
216
- 'fetchRate: source token ${from.title} is not supported as source token');
206
+ if (_notSupportedAsSourceToken.contains(from) || _notSupportedAsSourceToken.contains(to)) {
207
+ printV('fetchRate: source token ${from.title} is not supported as source token');
208
return 0.0;
209
}
210
220
-
221
-
211
final chains = await _geSupportedChain();
212
if (chains.isEmpty) return 0.0;
213
214
final srcChain = _findChainByCurrency(from, chains);
215
final dstChain = _findChainByCurrency(to, chains);
216
228
- await _ensureTokensCached(
229
- fromChain: srcChain, toChain: dstChain, from: from, to: to);
217
+ await _ensureTokensCached(fromChain: srcChain, toChain: dstChain, from: from, to: to);
218
219
final srcToken = _getTokenAddress(currency: from, chain: srcChain);
220
final dstToken = _getTokenAddress(currency: to, chain: dstChain);
@@ -252,8 +240,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
240
);
241
242
final params = {
255
- 'swapDirection':
256
- isReceiveAmount ? 'exact-amount-out' : 'exact-amount-in',
243
+ 'swapDirection': isReceiveAmount ? 'exact-amount-out' : 'exact-amount-in',
244
'srcToken': srcToken,
245
'dstToken': dstToken,
246
'srcChainId': '${srcChain.chainId}',
@@ -262,8 +249,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
249
};
250
251
final uri = Uri.https(_baseUrl, _getQuotePaths, params);
265
- final response =
266
- await ProxyWrapper().get(clearnetUri: uri, headers: _headers);
252
+ final response = await ProxyWrapper().get(clearnetUri: uri, headers: _headers);
253
254
if (response.statusCode != 200) {
255
printV('fetchRate failed: ${response.body}');
@@ -289,8 +275,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
275
final sender = request.refundAddress.trim();
276
final recipient = request.toAddress.trim();
277
if (sender.isEmpty || recipient.isEmpty) {
292
- throw Exception(
293
- 'Sender (refundAddress) or recipient (toAddress) is empty');
278
+ throw Exception('Sender (refundAddress) or recipient (toAddress) is empty');
279
}
280
281
final chains = await _geSupportedChain();
@@ -305,10 +290,8 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
290
to: request.toCurrency,
291
);
292
308
- final srcToken =
309
- _getTokenAddress(currency: request.fromCurrency, chain: srcChain);
310
- final dstToken =
311
- _getTokenAddress(currency: request.toCurrency, chain: dstChain);
293
+ final srcToken = _getTokenAddress(currency: request.fromCurrency, chain: srcChain);
294
+ final dstToken = _getTokenAddress(currency: request.toCurrency, chain: dstChain);
295
296
final amountStr = isFixedRateMode ? request.toAmount : request.fromAmount;
297
final rawAmount = double.tryParse(amountStr) ?? 0.0;
@@ -316,9 +299,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
299
300
final formattedAmount = AmountConverter.toBaseUnits(
301
amountStr,
319
- isFixedRateMode
320
- ? request.toCurrency.decimals
321
- : request.fromCurrency.decimals,
302
+ isFixedRateMode ? request.toCurrency.decimals : request.fromCurrency.decimals,
303
);
304
305
final params = {
@@ -329,8 +310,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
310
'dstChainId': '${dstChain.chainId}',
311
'dstToken': dstToken,
312
'slippage': '300',
332
- 'swapDirection':
333
- isFixedRateMode ? 'exact-amount-out' : 'exact-amount-in',
313
+ 'swapDirection': isFixedRateMode ? 'exact-amount-out' : 'exact-amount-in',
314
'amount': formattedAmount,
315
'recipient': recipient,
316
};
@@ -375,18 +355,16 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
355
final amtIn = (data['amountIn'] as Map?) ?? const {};
356
final amtInMax = (data['amountInMax'] as Map?) ?? const {};
357
final srcTokenAddr = amtIn['address']?.toString();
378
- final srcTokenDecs =
379
- (amtIn['decimals'] as num?)?.toInt() ?? request.fromCurrency.decimals;
380
- final requiresTokenApproval =
381
- data['requiresTokenApproval'] as bool? ?? false;
358
+ final srcTokenDecs = (amtIn['decimals'] as num?)?.toInt() ?? request.fromCurrency.decimals;
359
+ final requiresTokenApproval = data['requiresTokenApproval'] as bool? ?? false;
360
383
- final reqAmountStr =
384
- (amtInMax['amount'] ?? amtIn['amount'])?.toString() ?? '0';
361
+ final reqAmountStr = (amtInMax['amount'] ?? amtIn['amount'])?.toString() ?? '0';
362
final reqAmountRaw = reqAmountStr.replaceAll('n', '');
363
387
- final needToRegisterInSwapXyz =
388
- vmId == 'alt-vm' || bridgeIds.contains('alt-vm')
389
- || chainId == 'solana' || bridgeIds.contains('solana');
364
+ final needToRegisterInSwapXyz = vmId == 'alt-vm' ||
365
+ bridgeIds.contains('alt-vm') ||
366
+ chainId == 'solana' ||
367
+ bridgeIds.contains('solana');
368
369
final trade = Trade(
370
id: txId,
@@ -452,8 +430,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
430
final List<dynamic> body = json.decode(res.body) as List<dynamic>;
431
if (body.isEmpty) return false;
432
455
- final isSuccess =
456
- (body[0] as Map<String, dynamic>)['success'] as bool? ?? false;
433
+ final isSuccess = (body[0] as Map<String, dynamic>)['success'] as bool? ?? false;
434
435
return isSuccess;
436
} catch (e) {
@@ -482,8 +459,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
459
final error = data['error'] as Map<String, dynamic>?;
460
if (error != null) {
461
final code = error['code']?.toString() ?? 'unknown';
485
- throw Exception(
486
- 'SwapXyzExchangeProvider findTradeById error: ($id) $code');
462
+ throw Exception('SwapXyzExchangeProvider findTradeById error: ($id) $code');
463
}
464
}
465
@@ -499,10 +475,8 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
475
476
final payoutAddress = dstTransaction?['toAddress']?.toString();
477
502
- final srcPaymentToken =
503
- (srcTransaction?['paymentToken'] as Map?)?.cast<String, dynamic>();
504
- final dstPaymentToken =
505
- (dstTransaction?['paymentToken'] as Map?)?.cast<String, dynamic>();
478
+ final srcPaymentToken = (srcTransaction?['paymentToken'] as Map?)?.cast<String, dynamic>();
479
+ final dstPaymentToken = (dstTransaction?['paymentToken'] as Map?)?.cast<String, dynamic>();
480
481
final fromSymbol = (srcPaymentToken?['symbol'] as String?) ?? '';
482
final toSymbol = (dstPaymentToken?['symbol'] as String?) ?? '';
@@ -523,8 +497,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
497
String? receiveAmount;
498
if (dstAmountRaw != null) {
499
final dstAmountMinimal = _stripN(dstAmountRaw);
526
- receiveAmount =
527
- AmountConverter.fromBaseUnits(dstAmountMinimal, dstDecimals);
500
+ receiveAmount = AmountConverter.fromBaseUnits(dstAmountMinimal, dstDecimals);
501
}
502
503
final srcAmountMinimal = _stripN(srcAmountRaw);
@@ -537,8 +510,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
510
final timestamp = srcTs ?? dstTs;
511
512
final createdAt = timestamp != null
540
- ? DateTime.fromMillisecondsSinceEpoch(timestamp * 1000, isUtc: true)
541
- .toLocal()
513
+ ? DateTime.fromMillisecondsSinceEpoch(timestamp * 1000, isUtc: true).toLocal()
514
: null;
515
516
return Trade(
@@ -581,8 +553,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
553
if (_supportedChainList.isNotEmpty) return _supportedChainList;
554
try {
555
final uri = Uri.https(_baseUrl, _getChainList);
584
- final response =
585
- await ProxyWrapper().get(clearnetUri: uri, headers: _headers);
556
+ final response = await ProxyWrapper().get(clearnetUri: uri, headers: _headers);
557
if (response.statusCode != 200) return [];
558
559
final data = json.decode(response.body) as List<dynamic>;
@@ -677,8 +648,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
648
// Case 1: String "all" -> cache empty list to indicate all tokens supported
649
if (tokensField is String) {
650
if (tokensField.toLowerCase() == 'all') {
680
- _tokensCache[pathChainId] =
681
- _tokensCache[pathChainId] ?? <TokenPathInfo>[];
651
+ _tokensCache[pathChainId] = _tokensCache[pathChainId] ?? <TokenPathInfo>[];
652
}
653
continue;
654
}
@@ -705,9 +675,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
675
// Merge by symbol, prefer entries that have a non-empty address/decimals
676
void _mergeCache(int chainId, List<TokenPathInfo> incoming) {
677
final existing = _tokensCache[chainId] ?? const <TokenPathInfo>[];
708
- final bySymbol = <String, TokenPathInfo>{
709
- for (final t in existing) t.symbol: t
710
- };
678
+ final bySymbol = <String, TokenPathInfo>{for (final t in existing) t.symbol: t};
679
680
for (final t in incoming) {
681
final cur = bySymbol[t.symbol];
@@ -758,8 +726,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
726
return symbol;
727
}
728
761
- Map<String, dynamic>? findTokenBySymbol(
762
- {required String title, required List<dynamic> tokens}) {
729
+ Map<String, dynamic>? findTokenBySymbol({required String title, required List<dynamic> tokens}) {
730
final reqSymbol = title.toUpperCase();
731
for (final token in tokens) {
732
final map = token as Map<String, dynamic>;
lib/exchange/provider/swaptrade_exchange_provider.dart
+18
-15
@@ -69,8 +69,8 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
69
final normalized = _normalizeCurrency(from);
70
final coin = coinsInfo.cast<Map<String, dynamic>>().firstWhere(
71
(c) => (c['id']?.toString().toUpperCase() ?? '') == normalized,
72
- orElse: () => <String, dynamic>{},
73
- );
72
+ orElse: () => <String, dynamic>{},
73
+ );
74
75
if (coin.isEmpty) {
76
// Currency not supported by SwapTrade (e.g. USDC, DOGE).
@@ -88,19 +88,18 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
88
}
89
90
@override
91
- Future<double> fetchRate({
92
- required CryptoCurrency from,
93
- required CryptoCurrency to,
94
- required double amount,
95
- required bool isFixedRateMode,
96
- required bool isReceiveAmount
97
- }) async {
91
+ Future<double> fetchRate(
92
+ {required CryptoCurrency from,
93
+ required CryptoCurrency to,
94
+ required double amount,
95
+ required bool isFixedRateMode,
96
+ required bool isReceiveAmount}) async {
97
try {
98
if (amount == 0) return 0.0;
99
if (isFixedRateMode && !supportsFixedRate) {
100
return 0.0;
101
}
103
- if(from == CryptoCurrency.btcln || to == CryptoCurrency.btcln) return 0;
102
+ if (from == CryptoCurrency.btcln || to == CryptoCurrency.btcln) return 0;
103
104
final params = <String, dynamic>{};
105
final body = <String, String>{
@@ -116,7 +115,7 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
115
body: json.encode(body),
116
headers: _headers,
117
);
119
-
118
+
119
final responseBody = json.decode(response.body) as Map<String, dynamic>;
120
121
if (response.statusCode != 200) {
@@ -140,7 +139,11 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
139
140
final data = responseBody['data'] as Map<String, dynamic>;
141
double rate = double.parse(data['price'].toString());
143
- final calculatedRate = rate > 0 ? isFixedRateMode ? amount / rate : rate / amount : 0.0;
142
+ final calculatedRate = rate > 0
143
+ ? isFixedRateMode
144
+ ? amount / rate
145
+ : rate / amount
146
+ : 0.0;
147
148
ExchangeProviderLogger.logSuccess(
149
provider: description,
@@ -208,7 +211,7 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
211
body: json.encode(body),
212
headers: _headers,
213
);
211
-
214
+
215
final responseBody = json.decode(response.body) as Map<String, dynamic>;
216
217
if (response.statusCode == 400 || responseBody["success"] == false) {
@@ -235,7 +238,7 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
238
'url': uri.toString(),
239
},
240
);
238
-
241
+
242
throw TradeNotCreatedException(description, description: error);
243
}
244
@@ -337,7 +340,7 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
340
body: json.encode(body),
341
headers: _headers,
342
);
340
-
343
+
344
final responseBody = json.decode(response.body) as Map<String, dynamic>;
345
346
if (response.statusCode == 400 || responseBody["success"] == false) {
lib/exchange/provider/thorchain_exchange.provider.dart
+38
-40
@@ -46,13 +46,12 @@ class ThorChainExchangeProvider extends ExchangeProvider {
46
Future<bool> checkIsAvailable() async => true;
47
48
@override
49
- Future<double> fetchRate({
50
- required CryptoCurrency from,
51
- required CryptoCurrency to,
52
- required double amount,
53
- required bool isFixedRateMode,
54
- required bool isReceiveAmount
55
- }) async {
49
+ Future<double> fetchRate(
50
+ {required CryptoCurrency from,
51
+ required CryptoCurrency to,
52
+ required double amount,
53
+ required bool isFixedRateMode,
54
+ required bool isReceiveAmount}) async {
55
try {
56
if (amount == 0) return 0.0;
57
@@ -132,8 +131,6 @@ class ThorChainExchangeProvider extends ExchangeProvider {
131
required bool isFixedRateMode,
132
required bool isSendAll,
133
}) async {
135
-
136
-
134
final formattedFromAmount = double.parse(request.fromAmount);
135
136
final params = {
@@ -143,8 +140,9 @@ class ThorChainExchangeProvider extends ExchangeProvider {
140
'destination': _normalizeAddress(request.toAddress),
141
'affiliate': _affiliateName,
142
'affiliate_bps': _affiliateBps,
146
- 'refund_address':
147
- isRefundAddressSupported.contains(request.fromCurrency) ? _normalizeAddress(request.refundAddress) : '',
143
+ 'refund_address': isRefundAddressSupported.contains(request.fromCurrency)
144
+ ? _normalizeAddress(request.refundAddress)
145
+ : '',
146
};
147
148
final responseJSON = await _getSwapQuote(params);
@@ -203,7 +201,6 @@ class ThorChainExchangeProvider extends ExchangeProvider {
201
final formattedId = id.startsWith('0x') ? id.substring(2) : id;
202
final uri = Uri.https(_baseNodeURL, '$_txInfoPath$formattedId');
203
final response = await ProxyWrapper().get(clearnetUri: uri);
206
-
204
205
if (response.statusCode == 404) {
206
throw Exception('Trade not found for id: $formattedId');
@@ -235,7 +232,8 @@ class ThorChainExchangeProvider extends ExchangeProvider {
232
: '';
233
234
final formattedToChain = CryptoCurrency.safeParseCurrencyFromString(toChain);
238
- final toAssetWithChain = CryptoCurrency.safeParseCurrencyFromString(toAsset, walletCurrency: formattedToChain);
235
+ final toAssetWithChain =
236
+ CryptoCurrency.safeParseCurrencyFromString(toAsset, walletCurrency: formattedToChain);
237
238
final plannedOutTxs = responseJSON['planned_out_txs'] as List<dynamic>?;
239
final isRefund = plannedOutTxs?.any((tx) => tx['refund'] == true) ?? false;
@@ -257,39 +255,39 @@ class ThorChainExchangeProvider extends ExchangeProvider {
255
static Future<Map<String, String>?>? lookupAddressByName(String name) async {
256
final uri = Uri.https(_baseURL, '$_nameLookUpPath$name');
257
try {
260
- final response = await ProxyWrapper().get(clearnetUri: uri);
261
-
262
- if (response.statusCode != 200) {
263
- return null;
264
- }
265
-
266
- final body = json.decode(response.body) as Map<String, dynamic>;
267
- final entries = body['entries'] as List<dynamic>?;
268
-
269
- if (entries == null || entries.isEmpty) {
270
- return null;
271
- }
272
-
273
- Map<String, String> chainToAddressMap = {};
274
-
275
- for (final entry in entries) {
276
- final chain = entry['chain'] as String;
277
- final address = entry['address'] as String;
278
- chainToAddressMap[chain] = address;
279
- }
280
-
281
- return chainToAddressMap;
282
-} catch (e) {
283
- printV(e.toString());
284
- return null;
285
-}
258
+ final response = await ProxyWrapper().get(clearnetUri: uri);
259
+
260
+ if (response.statusCode != 200) {
261
+ return null;
262
+ }
263
+
264
+ final body = json.decode(response.body) as Map<String, dynamic>;
265
+ final entries = body['entries'] as List<dynamic>?;
266
+
267
+ if (entries == null || entries.isEmpty) {
268
+ return null;
269
+ }
270
+
271
+ Map<String, String> chainToAddressMap = {};
272
+
273
+ for (final entry in entries) {
274
+ final chain = entry['chain'] as String;
275
+ final address = entry['address'] as String;
276
+ chainToAddressMap[chain] = address;
277
+ }
278
+
279
+ return chainToAddressMap;
280
+ } catch (e) {
281
+ printV(e.toString());
282
+ return null;
283
+ }
284
}
285
286
Future<Map<String, dynamic>> _getSwapQuote(Map<String, String> params) async {
287
Uri uri = Uri.https(_baseNodeURL, _quotePath, params);
288
289
final response = await ProxyWrapper().get(clearnetUri: uri);
292
-
290
+
291
if (response.statusCode != 200) {
292
ExchangeProviderLogger.logError(
293
provider: description,
lib/exchange/provider/xoswap_exchange_provider.dart
+28
-28
@@ -12,6 +12,7 @@ import 'package:cw_core/crypto_currency.dart';
12
import 'package:cw_core/utils/print_verbose.dart';
13
import 'package:cw_core/utils/proxy_wrapper.dart';
14
import 'package:cake_wallet/utils/exchange_provider_logger.dart';
15
+
16
class XOSwapExchangeProvider extends ExchangeProvider {
17
XOSwapExchangeProvider() {
18
_addAppVersionHeader();
@@ -54,7 +55,7 @@ class XOSwapExchangeProvider extends ExchangeProvider {
55
'BASE': 'basemainnet',
56
'ARB': 'arbitrum',
57
};
57
-
58
+
59
static const supportedTags = [
60
'POL',
61
'ETH',
@@ -76,18 +77,21 @@ class XOSwapExchangeProvider extends ExchangeProvider {
77
'ARB',
78
];
79
79
-
80
String _normalizeXOSwapsNetwork(String string) {
81
final lower = string.toLowerCase();
82
83
- if (lower.endsWith('matic0a883d9b')) return string.replaceFirst(RegExp(r'matic0a883d9b$', caseSensitive: false), 'POL');
84
- if (lower.endsWith('matic86e249c1')) return string.replaceFirst(RegExp(r'matic86e249c1$', caseSensitive: false), 'POL');
85
- if (lower.endsWith('bscddedf0f8')) return string.replaceFirst(RegExp(r'bscddedf0f8$', caseSensitive: false), 'BSC');
86
- if (lower.endsWith('basemainnetb5a52617')) return string.replaceFirst(RegExp(r'basemainnetb5a52617$', caseSensitive: false), 'BASE');
83
+ if (lower.endsWith('matic0a883d9b'))
84
+ return string.replaceFirst(RegExp(r'matic0a883d9b$', caseSensitive: false), 'POL');
85
+ if (lower.endsWith('matic86e249c1'))
86
+ return string.replaceFirst(RegExp(r'matic86e249c1$', caseSensitive: false), 'POL');
87
+ if (lower.endsWith('bscddedf0f8'))
88
+ return string.replaceFirst(RegExp(r'bscddedf0f8$', caseSensitive: false), 'BSC');
89
+ if (lower.endsWith('basemainnetb5a52617'))
90
+ return string.replaceFirst(RegExp(r'basemainnetb5a52617$', caseSensitive: false), 'BASE');
91
92
return string;
93
}
90
-
94
+
95
@override
96
String get title => 'XOSwap';
97
@@ -116,7 +120,7 @@ class XOSwapExchangeProvider extends ExchangeProvider {
120
{'networks': normalizedNetwork, 'query': currency.title});
121
122
final response = await ProxyWrapper().get(clearnetUri: uri, headers: _headers);
119
-
123
+
124
if (response.statusCode != 200) {
125
throw Exception('Failed to fetch assets for ${currency.title} on ${currency.tag}');
126
}
@@ -125,7 +129,6 @@ class XOSwapExchangeProvider extends ExchangeProvider {
129
if (decoded is! List) throw const FormatException('Unexpected response format');
130
final assets = decoded.map((e) => Map<String, dynamic>.from(e as Map)).toList();
131
128
-
132
final asset = assets.firstWhere(
133
(asset) => removeNonAlphanumeric((asset['symbol'] ?? '').toString()) == currency.title,
134
orElse: () => const {},
@@ -138,7 +141,8 @@ class XOSwapExchangeProvider extends ExchangeProvider {
141
}
142
}
143
141
- String removeNonAlphanumeric(String str) => str.toUpperCase().replaceAll(RegExp(r'[^A-Z0-9]'), '');
144
+ String removeNonAlphanumeric(String str) =>
145
+ str.toUpperCase().replaceAll(RegExp(r'[^A-Z0-9]'), '');
146
147
Future<List<dynamic>> getRatesForPair({
148
required CryptoCurrency from,
@@ -169,8 +173,8 @@ class XOSwapExchangeProvider extends ExchangeProvider {
173
final rates = await getRatesForPair(from: from, to: to);
174
if (rates.isEmpty) throw Exception('No rates found for $from to $to');
175
172
- double minLimit = double.infinity;
173
- double maxLimit = 0;
176
+ double minLimit = double.infinity;
177
+ double maxLimit = 0;
178
179
for (var rate in rates) {
180
final double currentMin = double.parse(rate['min']['value'].toString());
@@ -186,13 +190,12 @@ class XOSwapExchangeProvider extends ExchangeProvider {
190
}
191
192
@override
189
- Future<double> fetchRate({
190
- required CryptoCurrency from,
191
- required CryptoCurrency to,
192
- required double amount,
193
- required bool isFixedRateMode,
194
- required bool isReceiveAmount
195
- }) async {
193
+ Future<double> fetchRate(
194
+ {required CryptoCurrency from,
195
+ required CryptoCurrency to,
196
+ required double amount,
197
+ required bool isFixedRateMode,
198
+ required bool isReceiveAmount}) async {
199
try {
200
final rates = await getRatesForPair(from: from, to: to);
201
if (rates.isEmpty) {
@@ -337,7 +340,7 @@ class XOSwapExchangeProvider extends ExchangeProvider {
340
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
341
final error = responseJSON['error'] ?? 'Unknown error';
342
final message = responseJSON['message'] ?? '';
340
-
343
+
344
ExchangeProviderLogger.logError(
345
provider: description,
346
function: 'createTrade',
@@ -356,7 +359,7 @@ class XOSwapExchangeProvider extends ExchangeProvider {
359
'url': uri.toString(),
360
},
361
);
359
-
362
+
363
throw Exception('$error\n$message');
364
}
365
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -456,7 +459,7 @@ class XOSwapExchangeProvider extends ExchangeProvider {
459
try {
460
final uri = Uri.https(_apiAuthority, '$_apiPath$_orders/$id');
461
final response = await ProxyWrapper().get(clearnetUri: uri, headers: _headers);
459
-
462
+
463
if (response.statusCode != 200) {
464
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
465
if (responseJSON.containsKey('code') && responseJSON['code'] == 'NOT_FOUND') {
@@ -507,10 +510,10 @@ class XOSwapExchangeProvider extends ExchangeProvider {
510
toAssetTag = 'ETH';
511
toAssetBase = 'BASE';
512
}
510
-
511
- final fromCurrency = CryptoCurrency.safeParseCurrencyFromString(fromAssetBase,tag: fromAssetTag);
512
- final toCurrency = CryptoCurrency.safeParseCurrencyFromString(toAssetBase,tag: toAssetTag);
513
514
+ final fromCurrency =
515
+ CryptoCurrency.safeParseCurrencyFromString(fromAssetBase, tag: fromAssetTag);
516
+ final toCurrency = CryptoCurrency.safeParseCurrencyFromString(toAssetBase, tag: toAssetTag);
517
518
final amount = responseJSON['amount'] as Map<String, dynamic>;
519
final toAmount = responseJSON['toAmount'] as Map<String, dynamic>;
@@ -553,9 +556,6 @@ class XOSwapExchangeProvider extends ExchangeProvider {
556
557
// ensure something remains before tag (at least 2 chars)
558
String? _extractTagFromAsset(String asset) {
556
-
557
-
558
-
559
for (final tag in supportedTags) {
560
if (asset.endsWith(tag)) {
561
final prefixLength = asset.length - tag.length;
lib/exchange/trade_legacy.part.dart
+3
-7
@@ -48,12 +48,10 @@ class TradeLegacyAdapter extends TypeAdapter<TradeLegacy> {
48
chainId: fields[34] as int?,
49
fee: fields[35] as double?,
50
)
51
- ..providerRaw =
52
- fields[1] == null ? 0 : fields[1] as int
51
+ ..providerRaw = fields[1] == null ? 0 : fields[1] as int
52
..fromRaw = (fields[2] as int?) ?? -1
53
..toRaw = (fields[3] as int?) ?? -1
55
- ..stateRaw =
56
- fields[4] == null ? '' : fields[4] as String;
54
+ ..stateRaw = fields[4] == null ? '' : fields[4] as String;
55
}
56
57
@override
@@ -140,7 +138,5 @@ class TradeLegacyAdapter extends TypeAdapter<TradeLegacy> {
138
@override
139
bool operator ==(Object other) =>
140
identical(this, other) ||
143
- other is TradeLegacyAdapter &&
144
- runtimeType == other.runtimeType &&
145
- typeId == other.typeId;
141
+ other is TradeLegacyAdapter && runtimeType == other.runtimeType && typeId == other.typeId;
142
}
lib/haven/cw_haven.dart
-1
@@ -12,7 +12,6 @@ import 'package:cw_core/wallet_type.dart';
12
import 'package:hive/hive.dart';
13
14
class HavenWalletService extends WalletService {
15
-
15
HavenWalletService();
16
17
@override
lib/locales/hausa_intl.dart
+4
-5
@@ -795,11 +795,11 @@ class HaMaterialLocalizations extends GlobalMaterialLocalizations {
795
@override
796
// TODO: implement shareButtonLabel
797
String get shareButtonLabel => "shareButtonLabel";
798
-
798
+
799
@override
800
// TODO: implement clearButtonTooltip
801
String get clearButtonTooltip => "clearButtonTooltip";
802
-
802
+
803
@override
804
// TODO: implement selectedDateLabel
805
String get selectedDateLabel => "selectedDateLabel";
@@ -1028,11 +1028,11 @@ class HaCupertinoLocalizations extends GlobalCupertinoLocalizations {
1028
@override
1029
// TODO: implement shareButtonLabel
1030
String get shareButtonLabel => "shareButtonLabel";
1031
-
1031
+
1032
@override
1033
// TODO: implement backButtonLabel
1034
String get backButtonLabel => "backButtonLabel";
1035
-
1035
+
1036
@override
1037
// TODO: implement cancelButtonLabel
1038
String get cancelButtonLabel => "cancelButtonLabel";
@@ -1054,5 +1054,4 @@ class HaCupertinoLocalizations extends GlobalCupertinoLocalizations {
1054
1055
@override
1056
String get expansionTileExpandedTapHint => "expansionTileExpandedTapHint";
1057
-
1057
}
lib/locales/yoruba_intl.dart
+3
-4
@@ -794,11 +794,11 @@ class YoMaterialLocalizations extends GlobalMaterialLocalizations {
794
@override
795
// TODO: implement shareButtonLabel
796
String get shareButtonLabel => "shareButtonLabel";
797
-
797
+
798
@override
799
// TODO: implement clearButtonTooltip
800
String get clearButtonTooltip => "clearButtonTooltip";
801
-
801
+
802
@override
803
// TODO: implement selectedDateLabel
804
String get selectedDateLabel => "selectedDateLabel";
@@ -1028,7 +1028,7 @@ class YoCupertinoLocalizations extends GlobalCupertinoLocalizations {
1028
@override
1029
// TODO: implement shareButtonLabel
1030
String get shareButtonLabel => "shareButtonLabel";
1031
-
1031
+
1032
@override
1033
// TODO: implement backButtonLabel
1034
String get backButtonLabel => "backButtonLabel";
@@ -1054,5 +1054,4 @@ class YoCupertinoLocalizations extends GlobalCupertinoLocalizations {
1054
1055
@override
1056
String get expansionTileExpandedTapHint => "expansionTileExpandedTapHint";
1057
-
1057
}
lib/main.dart
+2
-5
@@ -167,12 +167,10 @@ Future<void> runAppWithZone({Key? topLevelKey}) async {
167
}
168
169
if (!Platform.isWindows) {
170
- var zcashPassword = await secureStorageShared.read(
171
- key: "com.cakewallet.cw_zcash/zec.db");
170
+ var zcashPassword = await secureStorageShared.read(key: "com.cakewallet.cw_zcash/zec.db");
171
if (zcashPassword == null || zcashPassword.isEmpty) {
172
zcashPassword = generateKey().substring(0, 32);
174
- secureStorageShared.write(
175
- key: "com.cakewallet.cw_zcash/zec.db", value: zcashPassword);
173
+ secureStorageShared.write(key: "com.cakewallet.cw_zcash/zec.db", value: zcashPassword);
174
}
175
zcash?.unlockDatabase(zcashPassword);
176
}
@@ -222,7 +220,6 @@ Future<void> initializeAppConfigs({bool loadWallet = true}) async {
220
CakeHive.registerAdapter(ContactAdapter());
221
}
222
225
-
223
if (!CakeHive.isAdapterRegistered(TransactionDescription.typeId)) {
224
CakeHive.registerAdapter(TransactionDescriptionAdapter());
225
}
lib/monero/cw_monero.dart
+17
-16
@@ -66,12 +66,12 @@ class CWMoneroSubaddressList extends MoneroSubaddressList {
66
final moneroWallet = _wallet as MoneroWallet;
67
final subAddresses = moneroWallet.walletAddresses.subaddressList.subaddresses
68
.map((sub) => Subaddress(
69
- id: sub.id,
70
- address: sub.address,
71
- label: sub.label,
72
- received: sub.balance??"unknown",
73
- txCount: sub.txCount??0,
74
- ))
69
+ id: sub.id,
70
+ address: sub.address,
71
+ label: sub.label,
72
+ received: sub.balance ?? "unknown",
73
+ txCount: sub.txCount ?? 0,
74
+ ))
75
.toList();
76
return ObservableList<Subaddress>.of(subAddresses);
77
}
@@ -91,14 +91,13 @@ class CWMoneroSubaddressList extends MoneroSubaddressList {
91
@override
92
Future<List<Subaddress>> getAll(Object wallet) async {
93
final moneroWallet = wallet as MoneroWallet;
94
- return (await moneroWallet.walletAddresses.subaddressList
95
- .getAll())
94
+ return (await moneroWallet.walletAddresses.subaddressList.getAll())
95
.map((sub) => Subaddress(
97
- id: sub.id,
98
- label: sub.label,
99
- address: sub.address,
100
- txCount: sub.txCount??0,
101
- received: sub.balance??'unknown'))
96
+ id: sub.id,
97
+ label: sub.label,
98
+ address: sub.address,
99
+ txCount: sub.txCount ?? 0,
100
+ received: sub.balance ?? 'unknown'))
101
.toList();
102
}
103
@@ -253,7 +252,11 @@ class CWMonero extends Monero {
252
required int height,
253
required String mnemonic}) =>
254
MoneroRestoreWalletFromSeedCredentials(
256
- name: name, password: password, passphrase: passphrase, height: height, mnemonic: mnemonic);
255
+ name: name,
256
+ password: password,
257
+ passphrase: passphrase,
258
+ height: height,
259
+ mnemonic: mnemonic);
260
261
@override
262
WalletCredentials createMoneroNewWalletCredentials({
@@ -397,7 +400,6 @@ class CWMonero extends Monero {
400
return moneroWallet.importKeyImagesUR(ur);
401
}
402
400
-
403
@override
404
Future<bool> commitTransactionUR(Object wallet, String ur) {
405
final moneroWallet = wallet as MoneroWallet;
@@ -440,7 +442,6 @@ class CWMonero extends Monero {
442
moneroWallet.trezorService = service as MoneroTrezorService;
443
}
444
443
-
445
@override
446
HardwareWalletService getLedgerHardwareWalletService(ledger.LedgerConnection connection) =>
447
MoneroLedgerService(connection);
lib/new-ui/modal_navigator.dart
+24
-15
@@ -9,7 +9,11 @@ import 'package:flutter/material.dart';
9
/// calling Navigator.of(context).pop() will pop the page INSIDE the modal sheet.
10
/// if you want to pop the whole sheet, use Navigator.of(context, rootNavigator: true).pop().
11
class ModalNavigator extends StatefulWidget {
12
- const ModalNavigator({super.key, required this.rootPage, required this.parentContext, this.heightMode = ModalHeightModes.fullScreen});
12
+ const ModalNavigator(
13
+ {super.key,
14
+ required this.rootPage,
15
+ required this.parentContext,
16
+ this.heightMode = ModalHeightModes.fullScreen});
17
18
final Widget rootPage;
19
final BuildContext parentContext;
@@ -22,8 +26,10 @@ class ModalNavigator extends StatefulWidget {
26
enum ModalHeightModes {
27
/// just render as big a modal as possible
28
fullScreen,
29
+
30
/// after first frame, read height and lock to that height
31
autoLock,
32
+
33
/// let the content size itself. jumps around when pushing different-sized pages!
34
natural
35
}
@@ -39,7 +45,7 @@ class _ModalNavigatorState extends State<ModalNavigator> {
45
WidgetsBinding.instance.addPostFrameCallback((_) {
46
final context = _sheetKey.currentContext;
47
if (context == null) return;
42
- if(_sheetHeight != null) return;
48
+ if (_sheetHeight != null) return;
49
50
final box = context.findRenderObject() as RenderBox;
51
setState(() {
@@ -51,16 +57,19 @@ class _ModalNavigatorState extends State<ModalNavigator> {
57
@override
58
Widget build(BuildContext context) {
59
late final double? height;
54
- switch(widget.heightMode) {
60
+ switch (widget.heightMode) {
61
case ModalHeightModes.fullScreen:
56
- height = MediaQuery.of(context).size.height; break;
57
- case ModalHeightModes.autoLock:
58
- height = _sheetHeight; break;
62
+ height = MediaQuery.of(context).size.height;
63
+ break;
64
+ case ModalHeightModes.autoLock:
65
+ height = _sheetHeight;
66
+ break;
67
case ModalHeightModes.natural:
60
- height = null; break;
68
+ height = null;
69
+ break;
70
}
71
return Container(
63
- key:_sheetKey,
72
+ key: _sheetKey,
73
height: height,
74
child: Theme(
75
data: Theme.of(context).copyWith(
@@ -90,16 +99,16 @@ class _ModalNavigatorState extends State<ModalNavigator> {
99
child: Navigator(
100
key: _navigatorKey,
101
onGenerateRoute: (settings) {
93
-
102
printV(settings.name);
103
104
if (settings.name == "/")
97
- return handleRouteWithPlatformAwareness((context) => PopScope(
98
- canPop: false,
99
- onPopInvokedWithResult: (didPop, result) async {
100
- Navigator.of(widget.parentContext).pop();
101
- },
102
- child: widget.rootPage),
105
+ return handleRouteWithPlatformAwareness(
106
+ (context) => PopScope(
107
+ canPop: false,
108
+ onPopInvokedWithResult: (didPop, result) async {
109
+ Navigator.of(widget.parentContext).pop();
110
+ },
111
+ child: widget.rootPage),
112
fullscreenDialog: false);
113
else
114
return createRoute(settings);
lib/new-ui/pages/about_page.dart
+1
-1
@@ -43,7 +43,7 @@ class _AboutPageState extends State<AboutPage> {
43
44
void _easterEgg() {
45
_easterEggCounter++;
46
- if(_easterEggCounter == easterEggTreshold) {
46
+ if (_easterEggCounter == easterEggTreshold) {
47
setState(() {
48
_bottomText = aboutPageEasterEggs.elementAt(Random().nextInt(aboutPageEasterEggs.length));
49
});
lib/new-ui/pages/account_customizer.dart
+4
-8
@@ -63,8 +63,8 @@ class _AccountCustomizerState extends State<AccountCustomizer> {
63
WidgetsBinding.instance.addPostFrameCallback((_) {
64
loadCards();
65
final activeId = monero!.getCurrentAccount(widget.dashboardViewModel.wallet).id;
66
- for (int i = 0; i < _items.length-1; i++) {
67
- if(_items[i].accountListItem.id == activeId) {
66
+ for (int i = 0; i < _items.length - 1; i++) {
67
+ if (_items[i].accountListItem.id == activeId) {
68
final lastIndex = _items.length - 1;
69
final temp = _items[i];
70
_items[i] = _items[lastIndex];
@@ -74,10 +74,7 @@ class _AccountCustomizerState extends State<AccountCustomizer> {
74
break;
75
}
76
}
77
-
77
});
79
-
80
-
78
}
79
80
@override
@@ -93,7 +90,7 @@ class _AccountCustomizerState extends State<AccountCustomizer> {
90
for (int i = 0; i < accounts.length; i++) {
91
final index = widget.dashboardViewModel.cardOrder[i];
92
96
- if(index == null || index >= accounts.length) {
93
+ if (index == null || index >= accounts.length) {
94
// db order broken.
95
reset();
96
break;
@@ -361,7 +358,7 @@ class _AccountCustomizerState extends State<AccountCustomizer> {
358
},
359
actionRightButton: Navigator.of(context).pop);
360
});
364
- if(res != null && res is bool && res) {
361
+ if (res != null && res is bool && res) {
362
reset();
363
}
364
}
@@ -371,7 +368,6 @@ class _AccountCustomizerState extends State<AccountCustomizer> {
368
369
final accounts = widget.accountListViewModel.accounts;
370
for (int i = 0; i < widget.accountListViewModel.accounts.length; i++) {
374
-
371
_items.add(AccountCustomizerListItem(
372
card: BalanceCard(
373
accountName: accounts[i].label,
lib/new-ui/pages/addresses_page.dart
+2
-1
@@ -431,7 +431,8 @@ class AddressRow extends StatelessWidget {
431
fontSize: 12,
432
color: Theme.of(context).colorScheme.onSurfaceVariant),
433
),
434
- Text("${hasReceived ? S.of(context).received : S.of(context).balance}: ${item.balance}",
434
+ Text(
435
+ "${hasReceived ? S.of(context).received : S.of(context).balance}: ${item.balance}",
436
style: TextStyle(
437
fontSize: 12,
438
color: Theme.of(context).colorScheme.onSurfaceVariant)),
lib/new-ui/pages/bridge/bridge_confirm_sheet.dart
+4
-2
@@ -205,9 +205,11 @@ class _BridgeConfirmSheetState extends State<BridgeConfirmSheet> {
205
child: Observer(
206
builder: (_) {
207
if (bridgeViewModel.isExecuting) {
208
- return LoadingBottomWidget(text: "${S.of(context).bridging}...",);
208
+ return LoadingBottomWidget(
209
+ text: "${S.of(context).bridging}...",
210
+ );
211
}
210
- if(bridgeViewModel.isQuoteLoading || bridgeViewModel.quote == null) {
212
+ if (bridgeViewModel.isQuoteLoading || bridgeViewModel.quote == null) {
213
return LoadingBottomWidget(text: "${S.of(context).loading}...");
214
}
215
return ConfirmSwiper(
lib/new-ui/pages/bridge/bridge_network_page.dart
+4
-2
@@ -57,12 +57,14 @@ class BridgeNetworkPage extends StatelessWidget {
57
(chain) {
58
final chainName = chain.name;
59
return ListItemRegularRow(
60
- iconPath: 'assets/new-ui/crypto_full_icons/${chainName.toLowerCase()}.svg',
60
+ iconPath:
61
+ 'assets/new-ui/crypto_full_icons/${chainName.toLowerCase()}.svg',
62
keyValue: chain.chainId.toString(),
63
label: chainName,
64
onTap: () {
65
bridgeViewModel.setDestinationChain(chain.chainId);
65
- Navigator.pushNamed(context, Routes.bridgeReceivingWalletPage, arguments: bridgeViewModel);
66
+ Navigator.pushNamed(context, Routes.bridgeReceivingWalletPage,
67
+ arguments: bridgeViewModel);
68
},
69
);
70
},
lib/new-ui/pages/bridge/bridge_receive_address_input_page.dart
+4
-4
@@ -115,7 +115,8 @@ class _BridgeReceiveAddressInputPageState extends State<BridgeReceiveAddressInpu
115
focusNode: _focusNode,
116
selectedCurrency: bridgeViewModel.wallet.currency,
117
onEditingComplete: () {},
118
- validator: AddressValidator(type: bridgeViewModel.destinationChainInfo!.currency),
118
+ validator:
119
+ AddressValidator(type: bridgeViewModel.destinationChainInfo!.currency),
120
),
121
const Spacer(),
122
Observer(
@@ -124,14 +125,13 @@ class _BridgeReceiveAddressInputPageState extends State<BridgeReceiveAddressInpu
125
onPressed: () {
126
final overlayCtx = Navigator.of(context).overlay?.context;
127
bridgeViewModel.setRecipientAddress(_controller.text.trim());
127
-
128
+
129
WidgetsBinding.instance.addPostFrameCallback((_) {
130
if (overlayCtx != null && overlayCtx.mounted) {
131
showMaterialModalBottomSheet<void>(
132
context: overlayCtx,
133
backgroundColor: Colors.transparent,
133
- builder: (ctx) =>
134
- BridgeConfirmSheet(bridgeViewModel),
134
+ builder: (ctx) => BridgeConfirmSheet(bridgeViewModel),
135
);
136
}
137
});
lib/new-ui/pages/card_customizer.dart
+2
-1
@@ -251,7 +251,8 @@ class _CardCustomizerState extends State<CardCustomizer> {
251
),
252
child: Padding(
253
padding: const EdgeInsets.all(10.0),
254
- child: CakeImageWidget(imageUrl: icon.path),
254
+ child: CakeImageWidget(
255
+ imageUrl: icon.path),
256
),
257
),
258
);
lib/new-ui/pages/coin_control_page.dart
+16
-6
@@ -104,9 +104,12 @@ class _NewCoinControlPageState extends State<NewCoinControlPage> {
104
child: ModalHeader(
105
iconPath: "assets/new-ui/settings_row_icons/coin-control.svg",
106
title: "Coin Control",
107
- message: widget.canEdit ? S.of(context).coin_control_desc : S.of(context).coin_control_desc_no_edit),
107
+ message: widget.canEdit
108
+ ? S.of(context).coin_control_desc
109
+ : S.of(context).coin_control_desc_no_edit),
110
),
109
- if (widget.unspentCoinsListViewModel.items.isNotEmpty && widget.canEdit)
111
+ if (widget.unspentCoinsListViewModel.items.isNotEmpty &&
112
+ widget.canEdit)
113
Padding(
114
padding: const EdgeInsets.all(12.0),
115
child: Row(
@@ -134,7 +137,11 @@ class _NewCoinControlPageState extends State<NewCoinControlPage> {
137
)
138
],
139
),
137
- ) else SizedBox(height: 24,),
140
+ )
141
+ else
142
+ SizedBox(
143
+ height: 24,
144
+ ),
145
if (widget.unspentCoinsListViewModel.nonFrozenItems.isEmpty &&
146
widget.unspentCoinsListViewModel.frozenItems.isEmpty) ...[
147
SizedBox(height: 12),
@@ -154,7 +161,7 @@ class _NewCoinControlPageState extends State<NewCoinControlPage> {
161
: Padding(
162
padding: const EdgeInsets.symmetric(horizontal: 18.0),
163
child: CoinControlListSection(
157
- canEdit: widget.canEdit,
164
+ canEdit: widget.canEdit,
165
items: widget.unspentCoinsListViewModel.nonFrozenItems,
166
unspentCoinsListViewModel:
167
widget.unspentCoinsListViewModel),
@@ -181,7 +188,7 @@ class _NewCoinControlPageState extends State<NewCoinControlPage> {
188
.onSurfaceVariant),
189
),
190
CoinControlListSection(
184
- canEdit: widget.canEdit,
191
+ canEdit: widget.canEdit,
192
items: widget
193
.unspentCoinsListViewModel.frozenItems,
194
unspentCoinsListViewModel:
@@ -206,7 +213,10 @@ class _NewCoinControlPageState extends State<NewCoinControlPage> {
213
214
class CoinControlListSection extends StatelessWidget {
215
const CoinControlListSection(
209
- {super.key, required this.items, required this.unspentCoinsListViewModel, required this.canEdit});
216
+ {super.key,
217
+ required this.items,
218
+ required this.unspentCoinsListViewModel,
219
+ required this.canEdit});
220
221
final List<UnspentCoinsItem> items;
222
final bool canEdit;
lib/new-ui/pages/home_page.dart
+87
-86
@@ -42,7 +42,7 @@ class _NewHomePageState extends State<NewHomePage> {
42
void initState() {
43
super.initState();
44
_setAccountViewModel();
45
- reaction((_)=>widget.dashboardViewModel.wallet, (_) {
45
+ reaction((_) => widget.dashboardViewModel.wallet, (_) {
46
_setAccountViewModel();
47
setState(() {
48
_lightningMode = false;
@@ -59,62 +59,62 @@ class _NewHomePageState extends State<NewHomePage> {
59
@override
60
Widget build(BuildContext context) {
61
return Container(
62
- height: MediaQuery.of(context).size.height,
63
- decoration: BoxDecoration(
64
- gradient: LinearGradient(
65
- colors: [
66
- Theme.of(context).colorScheme.surface,
67
- Theme.of(context).colorScheme.surfaceDim,
68
- ],
69
- begin: Alignment.topCenter,
70
- end: Alignment.bottomCenter,
62
+ height: MediaQuery.of(context).size.height,
63
+ decoration: BoxDecoration(
64
+ gradient: LinearGradient(
65
+ colors: [
66
+ Theme.of(context).colorScheme.surface,
67
+ Theme.of(context).colorScheme.surfaceDim,
68
+ ],
69
+ begin: Alignment.topCenter,
70
+ end: Alignment.bottomCenter,
71
+ ),
72
),
72
- ),
73
- child: Stack(
74
- children: [
75
- CustomScrollView(
76
- physics: BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
77
- slivers:[
78
- SliverPadding(
79
- padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
80
- sliver: CupertinoSliverRefreshControl(
81
- refreshTriggerPullDistance: 160,
82
- refreshIndicatorExtent: 90,
83
- onRefresh: () => widget.dashboardViewModel.refreshDashboard(),
84
- ),
85
- ),
86
- SliverToBoxAdapter(
87
- child: Column(
88
- mainAxisSize: MainAxisSize.max,
89
- mainAxisAlignment: MainAxisAlignment.start,
90
- spacing: 24.0,
91
- children: [
92
- TopBar(
93
- dashboardViewModel: widget.dashboardViewModel,
94
- lightningMode: _lightningMode,
95
- onLightningSwitchPress: () {
96
- setState(() {
97
- _lightningMode = !_lightningMode;
98
- });
99
- },
100
- onSettingsButtonPress: () {
101
- CupertinoScaffold.showCupertinoModalBottomSheet(
102
- context: context,
103
- barrierColor: Colors.black.withAlpha(85),
104
- builder: (context) => FractionallySizedBox(
105
- child: Material(
106
- child: NewSettingsPage(
107
- dashboardViewModel: widget.dashboardViewModel,
108
- authService: getIt.get<AuthService>(),
109
- ))),
110
- );
111
- },
73
+ child: Stack(
74
+ children: [
75
+ CustomScrollView(
76
+ physics: BouncingScrollPhysics(parent: AlwaysScrollableScrollPhysics()),
77
+ slivers: [
78
+ SliverPadding(
79
+ padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top),
80
+ sliver: CupertinoSliverRefreshControl(
81
+ refreshTriggerPullDistance: 160,
82
+ refreshIndicatorExtent: 90,
83
+ onRefresh: () => widget.dashboardViewModel.refreshDashboard(),
84
+ ),
85
),
113
- Observer(
114
- builder: (_)=>WalletInfoBar(
115
- lightningMode: _lightningMode,
116
- hardwareWalletType: widget.dashboardViewModel.wallet.hardwareWalletType,
117
- name: widget.dashboardViewModel.wallet.name,
86
+ SliverToBoxAdapter(
87
+ child: Column(
88
+ mainAxisSize: MainAxisSize.max,
89
+ mainAxisAlignment: MainAxisAlignment.start,
90
+ spacing: 24.0,
91
+ children: [
92
+ TopBar(
93
+ dashboardViewModel: widget.dashboardViewModel,
94
+ lightningMode: _lightningMode,
95
+ onLightningSwitchPress: () {
96
+ setState(() {
97
+ _lightningMode = !_lightningMode;
98
+ });
99
+ },
100
+ onSettingsButtonPress: () {
101
+ CupertinoScaffold.showCupertinoModalBottomSheet(
102
+ context: context,
103
+ barrierColor: Colors.black.withAlpha(85),
104
+ builder: (context) => FractionallySizedBox(
105
+ child: Material(
106
+ child: NewSettingsPage(
107
+ dashboardViewModel: widget.dashboardViewModel,
108
+ authService: getIt.get<AuthService>(),
109
+ ))),
110
+ );
111
+ },
112
+ ),
113
+ Observer(
114
+ builder: (_) => WalletInfoBar(
115
+ lightningMode: _lightningMode,
116
+ hardwareWalletType: widget.dashboardViewModel.wallet.hardwareWalletType,
117
+ name: widget.dashboardViewModel.wallet.name,
118
hasCustomize: accountListViewModel != null,
119
onCustomizeButtonTap: openAccountCustomizer),
120
),
@@ -152,13 +152,15 @@ class _NewHomePageState extends State<NewHomePage> {
152
: SizedBox(width: double.infinity),
153
);
154
}),
155
- UnconfirmedBalanceWidget(dashboardViewModel: widget.dashboardViewModel,),
156
- ],
157
- ),
158
- Observer(
159
- builder: (_) {
160
- return Column(
161
- children: [
155
+ UnconfirmedBalanceWidget(
156
+ dashboardViewModel: widget.dashboardViewModel,
157
+ ),
158
+ ],
159
+ ),
160
+ Observer(
161
+ builder: (_) {
162
+ return Column(
163
+ children: [
164
CoinActionRow(
165
lightningMode: _lightningMode,
166
showSwap: widget.dashboardViewModel.isEnabledSwapAction,
@@ -168,13 +170,12 @@ class _NewHomePageState extends State<NewHomePage> {
170
dashboardViewModel: widget.dashboardViewModel,
171
),
172
],
171
- );
172
- },
173
+ );
174
+ },
175
+ ),
176
+ ],
177
+ ),
178
),
174
-
175
- ],
176
- ),
177
- ),
179
Observer(
180
builder: (_) => AssetsHistorySection(
181
nftViewModel: widget.nftViewModel,
@@ -186,26 +187,26 @@ class _NewHomePageState extends State<NewHomePage> {
187
)
188
]),
189
Container(
189
- height: (MediaQuery.of(context).padding.top),
190
- decoration: BoxDecoration(
191
- gradient: LinearGradient(
192
- begin: Alignment.bottomCenter,
193
- end: Alignment.topCenter,
194
- colors: <Color>[
195
- Theme.of(context).colorScheme.surface.withAlpha(5),
196
- Theme.of(context).colorScheme.surface.withAlpha(25),
197
- Theme.of(context).colorScheme.surface.withAlpha(50),
198
- Theme.of(context).colorScheme.surface.withAlpha(100),
199
- Theme.of(context).colorScheme.surface.withAlpha(150),
200
- Theme.of(context).colorScheme.surface.withAlpha(175),
201
- Theme.of(context).colorScheme.surface.withAlpha(200),
202
- ],
190
+ height: (MediaQuery.of(context).padding.top),
191
+ decoration: BoxDecoration(
192
+ gradient: LinearGradient(
193
+ begin: Alignment.bottomCenter,
194
+ end: Alignment.topCenter,
195
+ colors: <Color>[
196
+ Theme.of(context).colorScheme.surface.withAlpha(5),
197
+ Theme.of(context).colorScheme.surface.withAlpha(25),
198
+ Theme.of(context).colorScheme.surface.withAlpha(50),
199
+ Theme.of(context).colorScheme.surface.withAlpha(100),
200
+ Theme.of(context).colorScheme.surface.withAlpha(150),
201
+ Theme.of(context).colorScheme.surface.withAlpha(175),
202
+ Theme.of(context).colorScheme.surface.withAlpha(200),
203
+ ],
204
+ ),
205
),
206
),
205
- ),
206
- ],
207
- ),
208
- );
207
+ ],
208
+ ),
209
+ );
210
}
211
212
void openAccountCustomizer() async {
lib/new-ui/pages/lightning_username_page.dart
+10
-6
@@ -13,7 +13,11 @@ import 'package:flutter_bloc/flutter_bloc.dart';
13
import 'package:flutter_svg/flutter_svg.dart';
14
15
class LightningUsernamePage extends StatefulWidget {
16
- LightningUsernamePage({super.key, required this.isSetup, required this.themeStore, required this.lightningUsernameBloc});
16
+ LightningUsernamePage(
17
+ {super.key,
18
+ required this.isSetup,
19
+ required this.themeStore,
20
+ required this.lightningUsernameBloc});
21
22
final bool isSetup;
23
@@ -167,8 +171,8 @@ class LightningUsernameInfo extends StatelessWidget {
171
children: [
172
CakeImageWidget(
173
imageUrl: isLightMode
170
- ? "assets/new-ui/lightning_username_setup_light.svg"
171
- : "assets/new-ui/lightning_username_setup.svg"),
174
+ ? "assets/new-ui/lightning_username_setup_light.svg"
175
+ : "assets/new-ui/lightning_username_setup.svg"),
176
Row(
177
mainAxisAlignment: MainAxisAlignment.center,
178
spacing: 2,
@@ -223,8 +227,8 @@ class LightningUsernameEditor extends StatelessWidget {
227
children: [
228
CakeImageWidget(
229
imageUrl: isLightMode
226
- ? "assets/new-ui/lightning_username_setup_light.svg"
227
- : "assets/new-ui/lightning_username_setup.svg"),
230
+ ? "assets/new-ui/lightning_username_setup_light.svg"
231
+ : "assets/new-ui/lightning_username_setup.svg"),
232
if (isSetup)
233
Padding(
234
padding: const EdgeInsets.symmetric(horizontal: 18.0),
@@ -258,7 +262,7 @@ class LightningUsernameEditor extends StatelessWidget {
262
child: InkWell(
263
onTap: onRandomizeButtonTap,
264
child: CakeImageWidget(
261
- imageUrl: "assets/new-ui/randomize.svg",
265
+ imageUrl: "assets/new-ui/randomize.svg",
266
colorFilter: ColorFilter.mode(
267
Theme.of(context).colorScheme.primary, BlendMode.srcIn)),
268
),
lib/new-ui/pages/receive_page.dart
+33
-24
@@ -171,8 +171,11 @@ class _NewReceivePageState extends State<NewReceivePage> {
171
.whereType<CryptoCurrency>()
172
.toList(), onDismissed: () {
173
widget.addressListViewModel.dismissInfobox();
174
- setState(() {});
175
- }, autoGenerateSubaddressStatus: widget.lightningMode ? AutoGenerateSubaddressStatus.disabled : widget.dashboardViewModel.settingsStore.autoGenerateSubaddressStatus);
174
+ setState(() {});
175
+ },
176
+ autoGenerateSubaddressStatus: widget.lightningMode
177
+ ? AutoGenerateSubaddressStatus.disabled
178
+ : widget.dashboardViewModel.settingsStore.autoGenerateSubaddressStatus);
179
180
return Container(
181
decoration: BoxDecoration(
@@ -202,29 +205,35 @@ class _NewReceivePageState extends State<NewReceivePage> {
205
trailingWidget: Observer(
206
builder: (_) => AnimatedSwitcher(
207
duration: Duration(milliseconds: 300),
205
- child: _largeQrMode || widget.addressListViewModel.hasAddressRotation
206
- /* TODO rotating is broken on mweb, disabling for now, fix after mvp*/
207
- &&
208
- !(widget.receiveOptionViewModel.selectedReceiveOption.description ?? "")
209
- .toLowerCase()
210
- .contains("mweb") ? ModernButton(
211
- key: ValueKey(_largeQrMode),
212
- size: 36,
213
- icon: _largeQrMode ? Icon(Icons.share) : widget.addressListViewModel.isRotatingAddress
214
- ? CupertinoActivityIndicator()
215
- : Icon(Icons.refresh),
216
- onPressed: () {
217
- if(_largeQrMode) {
208
+ child: _largeQrMode ||
209
+ widget.addressListViewModel.hasAddressRotation
210
+ /* TODO rotating is broken on mweb, disabling for now, fix after mvp*/
211
+ &&
212
+ !(widget.receiveOptionViewModel.selectedReceiveOption.description ??
213
+ "")
214
+ .toLowerCase()
215
+ .contains("mweb")
216
+ ? ModernButton(
217
+ key: ValueKey(_largeQrMode),
218
+ size: 36,
219
+ icon: _largeQrMode
220
+ ? Icon(Icons.share)
221
+ : widget.addressListViewModel.isRotatingAddress
222
+ ? CupertinoActivityIndicator()
223
+ : Icon(Icons.refresh),
224
+ onPressed: () {
225
+ if (_largeQrMode) {
226
ShareUtil.share(
227
text: widget.addressListViewModel.uri.toString(),
228
context: context,
229
);
222
- } else {
223
- if(widget.addressListViewModel.hasAddressRotation) {
224
- widget.addressListViewModel.rotateAddress();
225
- }
226
- }
227
- }):SizedBox.shrink(),
230
+ } else {
231
+ if (widget.addressListViewModel.hasAddressRotation) {
232
+ widget.addressListViewModel.rotateAddress();
233
+ }
234
+ }
235
+ })
236
+ : SizedBox.shrink(),
237
),
238
),
239
),
@@ -274,9 +283,9 @@ class _NewReceivePageState extends State<NewReceivePage> {
283
copyData: widget.addressListViewModel.hasPayjoin
284
? null
285
: ClipboardData(
277
- text: widget.addressListViewModel.displayAmount.isEmpty
278
- ? widget.addressListViewModel.uri.address
279
- : widget.addressListViewModel.uri.toString()),
286
+ text: widget.addressListViewModel.displayAmount.isEmpty
287
+ ? widget.addressListViewModel.uri.address
288
+ : widget.addressListViewModel.uri.toString()),
289
onCopyButtonPressed: () {
290
if (widget.addressListViewModel.hasPayjoin) {
291
showModalBottomSheet(
lib/new-ui/pages/scan_page.dart
+5
-5
@@ -353,11 +353,10 @@ class _ScanPageState extends State<ScanPage> {
353
),
354
),
355
Positioned(
356
-bottom: 120, left:0,right:0,
356
+ bottom: 120,
357
+ left: 0,
358
+ right: 0,
359
child: IgnorePointer(
358
-
359
-
360
-
360
child: AnimatedOpacity(
361
duration: Duration(milliseconds: 500),
362
opacity: isScanningURQR ? 1 : 0,
@@ -378,7 +377,8 @@ bottom: 120, left:0,right:0,
377
),
378
Text(
379
"${decoder.expectedPartCount()}",
381
- style: TextStyle(fontSize: 45, color: Theme.of(context).colorScheme.onSurface),
380
+ style:
381
+ TextStyle(fontSize: 45, color: Theme.of(context).colorScheme.onSurface),
382
),
383
],
384
),
lib/new-ui/pages/send_page.dart
+32
-31
@@ -187,7 +187,6 @@ class NewSendPage extends StatefulWidget {
187
}
188
189
class _NewSendPageState extends State<NewSendPage> {
190
-
190
int _selectedOutput = 0;
191
192
final _amountControllers = <TextEditingController>[];
@@ -291,7 +290,6 @@ class _NewSendPageState extends State<NewSendPage> {
290
}
291
}
292
294
-
293
@override
294
Widget build(BuildContext context) {
295
return Observer(builder: (_) {
@@ -321,8 +319,8 @@ class _NewSendPageState extends State<NewSendPage> {
319
if (widget.sendViewModel.outputs.length > 1)
320
ModernButton(
321
size: 36,
324
- icon: CakeImageWidget(imageUrl:
325
- "assets/new-ui/remove_recipient.svg",
322
+ icon: CakeImageWidget(
323
+ imageUrl: "assets/new-ui/remove_recipient.svg",
324
colorFilter: ColorFilter.mode(
325
Theme.of(context).colorScheme.primary,
326
BlendMode.srcIn,
@@ -352,8 +350,8 @@ class _NewSendPageState extends State<NewSendPage> {
350
if (widget.mode.helpContent != null)
351
ModernButton(
352
size: 36,
355
- icon: CakeImageWidget(imageUrl:
356
- "assets/new-ui/help.svg",
353
+ icon: CakeImageWidget(
354
+ imageUrl: "assets/new-ui/help.svg",
355
colorFilter: ColorFilter.mode(
356
Theme.of(context).colorScheme.primary, BlendMode.srcIn),
357
),
@@ -420,7 +418,7 @@ class _NewSendPageState extends State<NewSendPage> {
418
output.loadContact(contact);
419
},
420
onPushPasteButton: (context) async {
423
- if(_justHandledPasteButton) return;
421
+ if (_justHandledPasteButton) return;
422
_justHandledPasteButton = true;
423
try {
424
output.resetParsedAddress();
@@ -505,7 +503,8 @@ class _NewSendPageState extends State<NewSendPage> {
503
),
504
],
505
),
508
- if (widget.sendViewModel.isMwebAvailable && widget.mode == SendPageModes.normal)
506
+ if (widget.sendViewModel.isMwebAvailable &&
507
+ widget.mode == SendPageModes.normal)
508
StandardCheckbox(
509
caption: S.of(context).litecoin_mweb_allow_coins,
510
captionColor: Theme.of(context).colorScheme.onSurface,
@@ -516,7 +515,7 @@ class _NewSendPageState extends State<NewSendPage> {
515
onChanged: (value) =>
516
widget.sendViewModel.setAllowMwebCoins(value),
517
),
519
- if(widget.sendViewModel.hasMemos)
518
+ if (widget.sendViewModel.hasMemos)
519
Observer(
520
builder: (_) => NewSendMemoInput(
521
memoController: _memoControllers[_selectedOutput],
@@ -542,14 +541,22 @@ class _NewSendPageState extends State<NewSendPage> {
541
),
542
if (widget.sendViewModel.hasCoinControl)
543
ListItemRegularRowWidget(
545
- keyValue: "",
546
- label: "Coin Control",
547
- onTap: () {
548
- showCupertinoModalBottomSheet(enableDrag: false, useRootNavigator: true, isDismissible: false, context: context, builder: (context){
549
- return NewCoinControlPage(unspentCoinsListViewModel: widget.sendViewModel.unspentCoinsListViewModel,canEdit: true);
550
- });
551
- }
552
- ),
544
+ keyValue: "",
545
+ label: "Coin Control",
546
+ onTap: () {
547
+ showCupertinoModalBottomSheet(
548
+ enableDrag: false,
549
+ useRootNavigator: true,
550
+ isDismissible: false,
551
+ context: context,
552
+ builder: (context) {
553
+ return NewCoinControlPage(
554
+ unspentCoinsListViewModel: widget
555
+ .sendViewModel
556
+ .unspentCoinsListViewModel,
557
+ canEdit: true);
558
+ });
559
+ }),
560
]),
561
)
562
],
@@ -718,7 +725,6 @@ class _NewSendPageState extends State<NewSendPage> {
725
if (memo != output.memo && memo.length <= widget.sendViewModel.maxMemoLength) {
726
output.memo = memo;
727
}
721
-
728
});
729
}
730
@@ -731,8 +737,7 @@ class _NewSendPageState extends State<NewSendPage> {
737
widget.sendViewModel.outputs[i].setFiatAmount(_amountControllers[i].text);
738
} else {
739
final amount = widget.sendViewModel.amountParsingProxy.getCanonicalCryptoAmount(
734
- _amountControllers[i].text.sanitized(),
735
- widget.sendViewModel.selectedCryptoCurrency);
740
+ _amountControllers[i].text.sanitized(), widget.sendViewModel.selectedCryptoCurrency);
741
widget.sendViewModel.outputs[i].setCryptoAmount(amount);
742
}
743
}
@@ -856,9 +861,7 @@ class _NewSendPageState extends State<NewSendPage> {
861
for (final r in widget.sendViewModel.balanceViewModel.formattedBalances)
862
r.asset: CurrencyPickerBalance(
863
amount: '${r.availableBalance} ${r.asset.title}',
859
- fiat: isFiatDisabled
860
- ? null
861
- : '${r.fiatAvailableBalanceRaw} ${r.fiatCurrency?.symbol}',
864
+ fiat: isFiatDisabled ? null : '${r.fiatAvailableBalanceRaw} ${r.fiatCurrency?.symbol}',
865
fiatValue: isFiatDisabled ? null : double.tryParse(r.fiatAvailableBalanceRaw),
866
),
867
};
@@ -1242,13 +1245,11 @@ class _NewSendPageState extends State<NewSendPage> {
1245
}
1246
_addressControllers[_selectedOutput].text = paymentRequest.address;
1247
if (paymentRequest.amount.isNotEmpty) {
1245
- try{
1248
+ try {
1249
_amountControllers[_selectedOutput].text = widget.sendViewModel.amountParsingProxy
1250
.getDisplayCryptoAmount(
1251
paymentRequest.amount, widget.sendViewModel.selectedCryptoCurrency);
1249
- } catch(e) {
1250
-
1251
- }
1252
+ } catch (e) {}
1253
}
1254
_memoControllers[_selectedOutput].text = paymentRequest.note;
1255
}
@@ -1417,7 +1418,7 @@ class SendHelpPage extends StatelessWidget {
1418
mainAxisSize: MainAxisSize.max,
1419
mainAxisAlignment: MainAxisAlignment.center,
1420
children: [
1420
- CakeImageWidget(imageUrl:content.imagePath),
1421
+ CakeImageWidget(imageUrl: content.imagePath),
1422
Text(
1423
content.description,
1424
textAlign: TextAlign.center,
@@ -1466,8 +1467,8 @@ Future<bool> showParsedAddressConfirmationAlert(
1467
? parsedAddress.addressSource.iconPath
1468
: parsedAddress.profileImageUrl,
1469
alertContent: S.of(context).extracted_address_content(
1469
- '${parsedAddress.handle} (${parsedAddress.addressSource.label})',
1470
- ),
1470
+ '${parsedAddress.handle} (${parsedAddress.addressSource.label})',
1471
+ ),
1472
buttonText: S.of(context).ok,
1473
buttonAction: () => Navigator.of(context).pop(true),
1474
);
@@ -1475,4 +1476,4 @@ Future<bool> showParsedAddressConfirmationAlert(
1476
);
1477
1478
return confirmed ?? false;
1478
-}
\ No newline at end of file
1479
+}
lib/new-ui/pages/settings_page.dart
+45
-20
@@ -26,7 +26,8 @@ bool _hasMweb(DashboardViewModel vm) => vm.hasMweb;
26
27
bool _hasWalletConnect(DashboardViewModel vm) => vm.hasWalletConnect;
28
29
-bool _isCupcake(DashboardViewModel vm) => vm.wallet.hardwareWalletType == HardwareWalletType.cupcake;
29
+bool _isCupcake(DashboardViewModel vm) =>
30
+ vm.wallet.hardwareWalletType == HardwareWalletType.cupcake;
31
32
class SettingsListItem {
33
final String iconPath;
@@ -37,7 +38,11 @@ class SettingsListItem {
38
final bool Function(DashboardViewModel) use2fa;
39
final bool Function(DashboardViewModel) condition;
40
40
- const SettingsListItem(this.iconPath, this.title, this.route, {this.routeArgs = null, this.requireAuth = false, this.use2fa = _falseFunc, this.condition = _trueFunc});
41
+ const SettingsListItem(this.iconPath, this.title, this.route,
42
+ {this.routeArgs = null,
43
+ this.requireAuth = false,
44
+ this.use2fa = _falseFunc,
45
+ this.condition = _trueFunc});
46
}
47
48
class SettingsSectionData {
@@ -49,30 +54,49 @@ class SettingsSectionData {
54
55
static SettingsSectionData walletSettings =
56
SettingsSectionData(S.current.wallet_settings, "assets/new-ui/wallet-setting.svg", [
52
- SettingsListItem("assets/new-ui/settings_row_icons/nodes.svg", S.current.nodes, Routes.manageNodes),
53
- SettingsListItem("assets/new-ui/settings_row_icons/privacy.svg", S.current.privacy, Routes.privacyPage),
54
- SettingsListItem("assets/new-ui/settings_row_icons/seed.svg", S.current.seed_and_keys, Routes.showKeys,
55
- routeArgs: true, requireAuth: true, use2fa: (vm)=>vm.settingsStore.shouldRequireTOTP2FAForAllSecurityAndBackupSettings),
56
- SettingsListItem("assets/new-ui/settings_row_icons/lightning_username.svg", "Lightning ${S.current.username}", Routes.lightningUsernamePage, condition: _hasLightning),
57
- SettingsListItem("assets/new-ui/settings_row_icons/wc.svg", S.current.walletConnect, Routes.walletConnectConnectionsListing, condition: _hasWalletConnect),
57
+ SettingsListItem(
58
+ "assets/new-ui/settings_row_icons/nodes.svg", S.current.nodes, Routes.manageNodes),
59
+ SettingsListItem(
60
+ "assets/new-ui/settings_row_icons/privacy.svg", S.current.privacy, Routes.privacyPage),
61
+ SettingsListItem(
62
+ "assets/new-ui/settings_row_icons/seed.svg", S.current.seed_and_keys, Routes.showKeys,
63
+ routeArgs: true,
64
+ requireAuth: true,
65
+ use2fa: (vm) => vm.settingsStore.shouldRequireTOTP2FAForAllSecurityAndBackupSettings),
66
+ SettingsListItem("assets/new-ui/settings_row_icons/lightning_username.svg",
67
+ "Lightning ${S.current.username}", Routes.lightningUsernamePage,
68
+ condition: _hasLightning),
69
+ SettingsListItem("assets/new-ui/settings_row_icons/wc.svg", S.current.walletConnect,
70
+ Routes.walletConnectConnectionsListing,
71
+ condition: _hasWalletConnect),
72
//SettingsListItem("assets/new-ui/settings_row_icons/silent-payments.svg", S.current.silent_payments_settings, Routes.silentPaymentsSettings, condition: _isBtc),
73
//SettingsListItem("assets/new-ui/settings_row_icons/mweb.svg", S.current.litecoin_mweb_settings, Routes.mwebSettings, condition: _hasMweb),
60
- SettingsListItem("assets/new-ui/settings_row_icons/cupcake.svg", S.current.export_outputs, Routes.urqrAnimatedPage, routeArgs: {'export-outputs': 'export-outputs'}, condition: _isCupcake),
61
- SettingsListItem("assets/new-ui/settings_row_icons/other.svg", S.current.other, Routes.otherSettingsPage),
74
+ SettingsListItem("assets/new-ui/settings_row_icons/cupcake.svg", S.current.export_outputs,
75
+ Routes.urqrAnimatedPage,
76
+ routeArgs: {'export-outputs': 'export-outputs'}, condition: _isCupcake),
77
+ SettingsListItem(
78
+ "assets/new-ui/settings_row_icons/other.svg", S.current.other, Routes.otherSettingsPage),
79
]);
80
81
static SettingsSectionData appSettings =
82
SettingsSectionData(S.current.app_settings, "assets/new-ui/cake-setting.svg", [
66
- SettingsListItem("assets/new-ui/settings_row_icons/connections.svg", S.current.connections, Routes.connectionSync),
83
+ SettingsListItem("assets/new-ui/settings_row_icons/connections.svg", S.current.connections,
84
+ Routes.connectionSync),
85
// SettingsListItem("assets/new-ui/settings_row_icons/defaults.svg", "Defaults", ""),
68
- SettingsListItem("assets/new-ui/settings_row_icons/display.svg", S.current.display, Routes.displaySettingsPage),
69
- SettingsListItem("assets/new-ui/settings_row_icons/security.svg", S.current.security, Routes.securityBackupPage),
70
- SettingsListItem("assets/new-ui/settings_row_icons/backup.svg", S.current.backup, Routes.backup, requireAuth: true, use2fa: (vm)=>vm.settingsStore.shouldRequireTOTP2FAForAllSecurityAndBackupSettings),
86
+ SettingsListItem("assets/new-ui/settings_row_icons/display.svg", S.current.display,
87
+ Routes.displaySettingsPage),
88
+ SettingsListItem("assets/new-ui/settings_row_icons/security.svg", S.current.security,
89
+ Routes.securityBackupPage),
90
+ SettingsListItem("assets/new-ui/settings_row_icons/backup.svg", S.current.backup, Routes.backup,
91
+ requireAuth: true,
92
+ use2fa: (vm) => vm.settingsStore.shouldRequireTOTP2FAForAllSecurityAndBackupSettings),
93
]);
94
95
static SettingsSectionData otherSettings = SettingsSectionData("", "", [
74
- SettingsListItem("assets/new-ui/settings_row_icons/support.svg", S.current.settings_support, Routes.support),
75
- SettingsListItem("assets/new-ui/settings_row_icons/info.svg", S.current.about, Routes.aboutPage),
96
+ SettingsListItem(
97
+ "assets/new-ui/settings_row_icons/support.svg", S.current.settings_support, Routes.support),
98
+ SettingsListItem(
99
+ "assets/new-ui/settings_row_icons/info.svg", S.current.about, Routes.aboutPage),
100
]);
101
102
static List<SettingsSectionData> all = [walletSettings, appSettings, otherSettings];
@@ -147,7 +171,8 @@ class SettingsMainPage extends StatelessWidget {
171
child: Row(
172
spacing: 8,
173
children: [
150
- CakeImageWidget(imageUrl: section.titleIconPath,
174
+ CakeImageWidget(
175
+ imageUrl: section.titleIconPath,
176
colorFilter: ColorFilter.mode(
177
Theme.of(context).colorScheme.onSurfaceVariant,
178
BlendMode.srcIn,
@@ -160,10 +185,10 @@ class SettingsMainPage extends StatelessWidget {
185
];
186
}).toList(),
187
),
163
- ),]
164
- ),
188
+ ),
189
+ ]),
190
),
191
]),
192
);
193
}
169
-}
\ No newline at end of file
194
+}
lib/new-ui/pages/swap_page.dart
+26
-21
@@ -51,7 +51,8 @@ import 'package:mobx/mobx.dart';
51
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
52
53
class NewSwapPage extends StatefulWidget {
54
- NewSwapPage(this.exchangeViewModel, this.authService,this.adrResService, this.initialPaymentRequest,
54
+ NewSwapPage(
55
+ this.exchangeViewModel, this.authService, this.adrResService, this.initialPaymentRequest,
56
{required this.walletSwitcherViewModel, CryptoCurrency? initialCurrency}) {
57
depositWalletName = exchangeViewModel.depositCurrency == CryptoCurrency.xmr
58
? exchangeViewModel.wallet.name
@@ -425,11 +426,11 @@ class _NewSwapPageState extends State<NewSwapPage> {
426
Future<String> fetchParsedAddress(
427
BuildContext context, String domain, CryptoCurrency currency) async {
428
printV("$domain");
428
- final parsedAddress = await widget.adrResService.resolve(
429
- query: domain,
430
- wallet: widget.exchangeViewModel.wallet,
431
- currency: currency);
432
- return parsedAddress.isNotEmpty ? parsedAddress.first.parsedAddressByCurrencyMap[currency] ?? '' : '';
429
+ final parsedAddress = await widget.adrResService
430
+ .resolve(query: domain, wallet: widget.exchangeViewModel.wallet, currency: currency);
431
+ return parsedAddress.isNotEmpty
432
+ ? parsedAddress.first.parsedAddressByCurrencyMap[currency] ?? ''
433
+ : '';
434
}
435
436
void _showFeeAlert(BuildContext context) async {
@@ -472,8 +473,8 @@ class _NewSwapPageState extends State<NewSwapPage> {
473
title: S.of(context).swap,
474
leadingIcon: Icon(Icons.close),
475
onLeadingPressed: Navigator.of(context).maybePop,
475
- trailingIcon: CakeImageWidget(imageUrl:
476
- "assets/new-ui/options.svg",
476
+ trailingIcon: CakeImageWidget(
477
+ imageUrl: "assets/new-ui/options.svg",
478
colorFilter:
479
ColorFilter.mode(Theme.of(context).colorScheme.primary, BlendMode.srcIn),
480
),
@@ -543,7 +544,8 @@ class _NewSwapPageState extends State<NewSwapPage> {
544
type: widget.exchangeViewModel.depositCurrency),
545
onPushPasteButton: (context) async {
546
final clipboard = await Clipboard.getData('text/plain');
546
- widget.exchangeViewModel.depositAddress = clipboard?.text ?? '';
547
+ widget.exchangeViewModel.depositAddress =
548
+ clipboard?.text ?? '';
549
550
final domain = widget.exchangeViewModel.depositAddress;
551
widget.exchangeViewModel.depositAddress =
@@ -600,8 +602,10 @@ class _NewSwapPageState extends State<NewSwapPage> {
602
? AmountValidator(
603
isAutovalidate: true,
604
currency: widget.exchangeViewModel.receiveCurrency,
603
- minValue: widget.exchangeViewModel.limits.min.toString(),
604
- maxValue: widget.exchangeViewModel.limits.max.toString(),
605
+ minValue:
606
+ widget.exchangeViewModel.limits.min.toString(),
607
+ maxValue:
608
+ widget.exchangeViewModel.limits.max.toString(),
609
amountParsingProxy:
610
widget.exchangeViewModel.amountParsingProxy,
611
).call(value)
@@ -611,7 +615,8 @@ class _NewSwapPageState extends State<NewSwapPage> {
615
type: widget.exchangeViewModel.receiveCurrency),
616
onPushPasteButton: (context) async {
617
final clipboard = await Clipboard.getData('text/plain');
614
- widget.exchangeViewModel.receiveAddress = clipboard?.text ?? '';
618
+ widget.exchangeViewModel.receiveAddress =
619
+ clipboard?.text ?? '';
620
621
final domain = widget.exchangeViewModel.receiveAddress;
622
widget.exchangeViewModel.receiveAddress =
@@ -783,8 +788,8 @@ class SwapProviderPreview extends StatelessWidget {
788
fontWeight: FontWeight.w400,
789
color: Theme.of(context).colorScheme.onSurfaceVariant),
790
),
786
- CakeImageWidget(imageUrl:
787
- "assets/new-ui/chooser.svg",
791
+ CakeImageWidget(
792
+ imageUrl: "assets/new-ui/chooser.svg",
793
colorFilter: ColorFilter.mode(
794
Theme.of(context).colorScheme.onSurfaceVariant, BlendMode.srcIn),
795
)
@@ -980,8 +985,8 @@ class SwapAmountBoxState extends State<SwapAmountBox> {
985
onTap: _presentCurrencyPicker,
986
child: Container(
987
decoration: BoxDecoration(
983
- color: Theme.of(context).colorScheme.surface,
984
- borderRadius: BorderRadius.circular(999999),
988
+ color: Theme.of(context).colorScheme.surface,
989
+ borderRadius: BorderRadius.circular(999999),
990
),
991
child: Padding(
992
padding: const EdgeInsets.only(top: 4.0, bottom: 4, left: 4, right: 4),
@@ -1013,11 +1018,11 @@ class SwapAmountBoxState extends State<SwapAmountBox> {
1018
] else
1019
const SizedBox(width: 10),
1020
Container(
1016
- width:16,height:16,
1021
+ width: 16,
1022
+ height: 16,
1023
decoration: BoxDecoration(
1018
- borderRadius: BorderRadius.circular(9999999999),
1019
- color: Theme.of(context).colorScheme.surfaceContainerHigh
1020
- ),
1024
+ borderRadius: BorderRadius.circular(9999999999),
1025
+ color: Theme.of(context).colorScheme.surfaceContainerHigh),
1026
child: Padding(
1027
padding: const EdgeInsets.all(4.0),
1028
child: RotatedBox(
@@ -1069,7 +1074,7 @@ class SwapAmountBoxState extends State<SwapAmountBox> {
1074
amountController.text = widget.exchangeViewModel.depositAmount;
1075
}
1076
},
1072
- onAllButtonPressed: (){
1077
+ onAllButtonPressed: () {
1078
setState(() {
1079
_fiatInputMode = false;
1080
});
lib/new-ui/viewmodels/card_customizer/card_customizer_bloc.dart
+6
-12
@@ -19,9 +19,7 @@ class CardCustomizerBloc extends Bloc<CardCustomizerEvent, CardCustomizerState>
19
20
CardCustomizerBloc(this._wallet, {this.lightningMode = false, this.displaySats = false})
21
: super(CardCustomizerNotLoaded(
22
- 0, 0, [CardDesign.genericDefault], [],
23
- "", -1, displaySats, 0)) {
24
-
22
+ 0, 0, [CardDesign.genericDefault], [], "", -1, displaySats, 0)) {
23
on<_Init>(_init);
24
on<CardDesignSelected>(_onDesignSelected);
25
on<ColorSelected>(_onColorSelected);
@@ -29,7 +27,6 @@ class CardCustomizerBloc extends Bloc<CardCustomizerEvent, CardCustomizerState>
27
on<DesignSaved>(_onDesignSaved);
28
on<AccountNameChanged>(_onAccountNameChanged);
29
32
-
30
add(_Init());
31
}
32
@@ -96,15 +93,14 @@ class CardCustomizerBloc extends Bloc<CardCustomizerEvent, CardCustomizerState>
93
}
94
final accountName = (account?.label ?? "") as String;
95
late final int accountIndex;
99
- if(account != null) {
96
+ if (account != null) {
97
accountIndex = account.id as int;
101
- } else if(lightningMode) {
98
+ } else if (lightningMode) {
99
accountIndex = 0;
100
} else {
101
accountIndex = -1;
102
}
106
- final curr =
107
- lightningMode ? CryptoCurrency.btcln : _wallet.currency;
103
+ final curr = lightningMode ? CryptoCurrency.btcln : _wallet.currency;
104
final currentDesignSettings = await _loadCurrentDesignSettings(accountIndex);
105
final currentDesign = CardDesign.fromStyleSettings(currentDesignSettings, curr);
106
final availableDesigns = _initAvailableDesigns(lightningMode: lightningMode);
@@ -112,8 +108,7 @@ class CardCustomizerBloc extends Bloc<CardCustomizerEvent, CardCustomizerState>
108
final selectedDesignIndex = _initSelectedDesign(currentDesign);
109
final selectedColor = _initSelectedColor(currentDesign);
110
final availableIconPaths = CardDesign.iconPathsForWalletType(curr);
115
- final selectedIconIndex = _initSelectedIconIndex(
116
- currentDesignSettings, availableIconPaths);
111
+ final selectedIconIndex = _initSelectedIconIndex(currentDesignSettings, availableIconPaths);
112
113
emit(CardCustomizerInitial(
114
selectedDesignIndex,
@@ -149,8 +144,7 @@ class CardCustomizerBloc extends Bloc<CardCustomizerEvent, CardCustomizerState>
144
emit(state.copyWith(selectedColorIndex: event.newColorIndex));
145
}
146
152
- void _onIconStyleSelected(
153
- IconStyleSelected event, Emitter<CardCustomizerState> emit) {
147
+ void _onIconStyleSelected(IconStyleSelected event, Emitter<CardCustomizerState> emit) {
148
emit(state.copyWith(selectedIconIndex: event.iconIndex));
149
}
150
lib/new-ui/viewmodels/card_customizer/card_customizer_event.dart
-2
@@ -17,14 +17,12 @@ class ColorSelected extends CardCustomizerEvent {
17
ColorSelected(this.newColorIndex);
18
}
19
20
-
20
class AccountNameChanged extends CardCustomizerEvent {
21
final String newAccountName;
22
23
AccountNameChanged(this.newAccountName);
24
}
25
27
-
26
class DesignSaved extends CardCustomizerEvent {}
27
28
class IconStyleSelected extends CardCustomizerEvent {
lib/new-ui/viewmodels/card_customizer/card_customizer_state.dart
+23
-9
@@ -61,7 +61,15 @@ sealed class CardCustomizerState {
61
}
62
63
final class CardCustomizerNotLoaded extends CardCustomizerState {
64
- CardCustomizerNotLoaded(super.selectedDesignIndex, super.selectedColorIndex, super.availableDesigns, super.availableColors, super.accountName, super.accountIndex, super.displaySats, super.cardOrder);
64
+ CardCustomizerNotLoaded(
65
+ super.selectedDesignIndex,
66
+ super.selectedColorIndex,
67
+ super.availableDesigns,
68
+ super.availableColors,
69
+ super.accountName,
70
+ super.accountIndex,
71
+ super.displaySats,
72
+ super.cardOrder);
73
74
@override
75
CardCustomizerState copyWith(
@@ -91,10 +99,9 @@ final class CardCustomizerInitial extends CardCustomizerState {
99
int cardOrder, {
100
List<CardIconPath> availableIconPaths = const [],
101
int selectedIconIndex = 0,
94
- }) : super(selectedDesignIndex, selectedColorIndex, availableDesigns,
95
- availableColors, accountName, accountIndex, displaySats, cardOrder,
96
- availableIconPaths: availableIconPaths,
97
- selectedIconIndex: selectedIconIndex);
102
+ }) : super(selectedDesignIndex, selectedColorIndex, availableDesigns, availableColors,
103
+ accountName, accountIndex, displaySats, cardOrder,
104
+ availableIconPaths: availableIconPaths, selectedIconIndex: selectedIconIndex);
105
106
CardCustomizerInitial copyWith({
107
int? selectedDesignIndex,
@@ -124,10 +131,17 @@ final class CardCustomizerInitial extends CardCustomizerState {
131
}
132
133
final class CardCustomizerSaved extends CardCustomizerState {
127
- CardCustomizerSaved(super.selectedDesignIndex, super.selectedColorIndex,
128
- super.availableDesigns, super.availableColors, super.accountName,
129
- super.accountIndex, super.displaySats, super.cardOrder,
130
- {super.availableIconPaths, super.selectedIconIndex});
134
+ CardCustomizerSaved(
135
+ super.selectedDesignIndex,
136
+ super.selectedColorIndex,
137
+ super.availableDesigns,
138
+ super.availableColors,
139
+ super.accountName,
140
+ super.accountIndex,
141
+ super.displaySats,
142
+ super.cardOrder,
143
+ {super.availableIconPaths,
144
+ super.selectedIconIndex});
145
146
@override
147
CardCustomizerState copyWith(
lib/new-ui/viewmodels/lightning_username/lightning_username_bloc.dart
+4
-2
@@ -52,7 +52,8 @@ class LightningUsernameBloc extends Bloc<LightningUsernameEvent, LightningUserna
52
}
53
}
54
55
- Future<void> onUsernameSaveRequested(RequestUsernameSave event, Emitter<LightningUsernameState> emit) async {
55
+ Future<void> onUsernameSaveRequested(
56
+ RequestUsernameSave event, Emitter<LightningUsernameState> emit) async {
57
emit(LightningUsernameSaving(state.username));
58
try {
59
await bitcoin!.setLightningUsername(_wallet, state.username);
@@ -64,7 +65,8 @@ class LightningUsernameBloc extends Bloc<LightningUsernameEvent, LightningUserna
65
return;
66
}
67
}
67
- emit(LightningUsernameError(state.username, UsernameError(bitcoin!.getBreezSdkError(e) ?? e.toString())));
68
+ emit(LightningUsernameError(
69
+ state.username, UsernameError(bitcoin!.getBreezSdkError(e) ?? e.toString())));
70
}
71
}
72
lib/new-ui/viewmodels/lightning_username/lightning_username_event.dart
+1
-1
@@ -11,4 +11,4 @@ final class ChangeUsername extends LightningUsernameEvent {
11
ChangeUsername(this.newUsername);
12
}
13
14
-final class RequestUsernameSave extends LightningUsernameEvent {}
\ No newline at end of file
14
+final class RequestUsernameSave extends LightningUsernameEvent {}
lib/new-ui/widgets/addresses_page/address_info.dart
+1
-2
@@ -34,8 +34,7 @@ class AddressInfoPopup extends StatelessWidget {
34
children: [
35
Text('Index: ${walletAddressEditOrCreateViewModel.index}'),
36
SizedBox(height: 16),
37
- Text(
38
- 'Derivation Path: ${walletAddressEditOrCreateViewModel.derivationPath}'),
37
+ Text('Derivation Path: ${walletAddressEditOrCreateViewModel.derivationPath}'),
38
],
39
),
40
),
lib/new-ui/widgets/addresses_page/address_label_input.dart
+1
-2
@@ -33,8 +33,7 @@ class _AddressLabelInputPopupState extends State<AddressLabelInputPopup> {
33
(AddressEditOrCreateState state) {
34
if (state is AddressSavedSuccessfully) {
35
WidgetsBinding.instance.addPostFrameCallback((_) {
36
- if (mounted)
37
- Navigator.of(context).pop(widget.walletAddressEditOrCreateViewModel.label);
36
+ if (mounted) Navigator.of(context).pop(widget.walletAddressEditOrCreateViewModel.label);
37
});
38
}
39
});
lib/new-ui/widgets/animated_dropdown.dart
+21
-12
@@ -2,7 +2,7 @@ import 'package:cake_wallet/new-ui/widgets/dropdown_row.dart';
2
import 'package:flutter/material.dart';
3
4
class AnimatedDropdown extends StatefulWidget {
5
- const AnimatedDropdown({super.key,required this.content, required this.dropdownText});
5
+ const AnimatedDropdown({super.key, required this.content, required this.dropdownText});
6
7
final Widget content;
8
final String dropdownText;
@@ -23,21 +23,30 @@ class _AnimatedDropdownState extends State<AnimatedDropdown> {
23
shape: RoundedSuperellipseBorder(
24
borderRadius: BorderRadius.circular(20),
25
),
26
- color: Theme.of(context).colorScheme.surfaceContainer,),
26
+ color: Theme.of(context).colorScheme.surfaceContainer,
27
+ ),
28
child: Column(
29
children: [
29
- DropdownRow(expanded: _expanded, text: widget.dropdownText,onTap: (){
30
- setState(() {
31
- _expanded = !_expanded;
32
- });
33
- },),
34
- AnimatedOpacity(duration:Duration(milliseconds: 150),opacity:_expanded?1:0,child: Divider(height: 1,thickness: 1,)),
30
+ DropdownRow(
31
+ expanded: _expanded,
32
+ text: widget.dropdownText,
33
+ onTap: () {
34
+ setState(() {
35
+ _expanded = !_expanded;
36
+ });
37
+ },
38
+ ),
39
+ AnimatedOpacity(
40
+ duration: Duration(milliseconds: 150),
41
+ opacity: _expanded ? 1 : 0,
42
+ child: Divider(
43
+ height: 1,
44
+ thickness: 1,
45
+ )),
46
AnimatedCrossFade(
36
- firstChild: Container(height:0),
47
+ firstChild: Container(height: 0),
48
secondChild: widget.content,
38
- crossFadeState: _expanded
39
- ? CrossFadeState.showSecond
40
- : CrossFadeState.showFirst,
49
+ crossFadeState: _expanded ? CrossFadeState.showSecond : CrossFadeState.showFirst,
50
duration: const Duration(milliseconds: 300),
51
sizeCurve: Curves.easeOutCubic,
52
)
lib/new-ui/widgets/apps_widget.dart
+7
-7
@@ -94,7 +94,11 @@ class AppsWidget extends StatelessWidget {
94
),
95
softWrap: true,
96
),
97
- isCake == true ? CakeImageWidget(imageUrl: "assets/new-ui/cakelabs-icon.svg", color: Theme.of(context).colorScheme.onSurfaceVariant) : SizedBox(),
97
+ isCake == true
98
+ ? CakeImageWidget(
99
+ imageUrl: "assets/new-ui/cakelabs-icon.svg",
100
+ color: Theme.of(context).colorScheme.onSurfaceVariant)
101
+ : SizedBox(),
102
],
103
),
104
SizedBox(height: 5),
@@ -114,7 +118,6 @@ class AppsWidget extends StatelessWidget {
118
color: Theme.of(context).colorScheme.onSurfaceVariant,
119
size: 20,
120
)
117
-
121
],
122
),
123
if (hint != null) ...[
@@ -137,11 +140,8 @@ class AppsWidget extends StatelessWidget {
140
),
141
],
142
);
140
- }
141
- else {
142
- return Stack(
143
-
144
- );
143
+ } else {
144
+ return Stack();
145
}
146
}
147
}
lib/new-ui/widgets/bridge/confirm_details_card.dart
+3
-2
@@ -17,7 +17,7 @@ class ConfirmDetailsCard extends StatelessWidget {
17
builder: (_) {
18
final feeParts = <String>[
19
bridgeViewModel.quoteNativeFeeFormattedForDisplay,
20
- bridgeViewModel.quoteNativeFiatFeeFormattedForDisplay,
20
+ bridgeViewModel.quoteNativeFiatFeeFormattedForDisplay,
21
];
22
final feeLine = feeParts.join(' ');
23
@@ -40,7 +40,8 @@ class ConfirmDetailsCard extends StatelessWidget {
40
),
41
ExpandableBridgeDetailRow(
42
label: S.of(context).to,
43
- title: bridgeViewModel.destinationWalletName ?? bridgeViewModel.recipientAddress.trim(),
43
+ title: bridgeViewModel.destinationWalletName ??
44
+ bridgeViewModel.recipientAddress.trim(),
45
address: bridgeViewModel.recipientAddress.trim(),
46
showChevron: bridgeViewModel.destinationWalletName != null,
47
),
lib/new-ui/widgets/bridge/transfer_history_row.dart
+4
-2
@@ -88,7 +88,8 @@ class TransferHistoryRow extends StatelessWidget {
88
child: Stack(
89
children: [
90
CakeImageWidget(
91
- imageUrl: 'assets/new-ui/crypto_full_icons/${sourceChainName?.toLowerCase()}.svg',
91
+ imageUrl:
92
+ 'assets/new-ui/crypto_full_icons/${sourceChainName?.toLowerCase()}.svg',
93
width: 28,
94
height: 28,
95
),
@@ -96,7 +97,8 @@ class TransferHistoryRow extends StatelessWidget {
97
top: 14,
98
left: 12,
99
child: CakeImageWidget(
99
- imageUrl: 'assets/new-ui/crypto_full_icons/${destChainName?.toLowerCase()}.svg',
100
+ imageUrl:
101
+ 'assets/new-ui/crypto_full_icons/${destChainName?.toLowerCase()}.svg',
102
width: 28,
103
height: 28,
104
),
lib/new-ui/widgets/changelog_modal.dart
+1
-1
@@ -107,7 +107,7 @@ class _ChangelogModalState extends State<ChangelogModal> {
107
NewPrimaryButton(
108
onPressed: () {
109
try {
110
- launchUrl(Uri.https("blog.cakewallet.com"));
110
+ launchUrl(Uri.https("blog.cakewallet.com"));
111
} catch (_) {}
112
},
113
text: S.of(context).view_more_info,
lib/new-ui/widgets/coin_control_page/coin_control_list_item.dart
+75
-61
@@ -14,10 +14,11 @@ class CoinControlListItem extends StatelessWidget {
14
required this.isFrozen,
15
required this.isChange,
16
required this.isSilentPayment,
17
- required this.isFirst,
17
+ required this.isFirst,
18
required this.isLast,
19
required this.isLoading,
20
- this.onCheckBoxTap, required this.hasCheckbox,
20
+ this.onCheckBoxTap,
21
+ required this.hasCheckbox,
22
});
23
24
final String note;
@@ -37,61 +38,70 @@ class CoinControlListItem extends StatelessWidget {
38
@override
39
Widget build(BuildContext context) {
40
return Container(
40
- height:70,
41
- decoration: BoxDecoration(
42
- color: Theme.of(context).colorScheme.surfaceContainer,
43
- borderRadius: BorderRadius.vertical(
44
- top: isFirst ? Radius.circular(12) : Radius.circular(0),
45
- bottom: isLast ? Radius.circular(12) : Radius.circular(0),
41
+ height: 70,
42
+ decoration: BoxDecoration(
43
+ color: Theme.of(context).colorScheme.surfaceContainer,
44
+ borderRadius: BorderRadius.vertical(
45
+ top: isFirst ? Radius.circular(12) : Radius.circular(0),
46
+ bottom: isLast ? Radius.circular(12) : Radius.circular(0),
47
+ ),
48
),
47
- ),
48
- child: Padding(
49
- padding: const EdgeInsets.symmetric(horizontal: 12.0),
50
- child: Row(
51
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
52
- children: [
53
- Row(
54
- spacing: 12,
55
- children: [
56
- _getLeading(context),
57
- // NewSimpleCheckbox(value: isSending, onChanged: (value){onCheckBoxTap?.call();}),
58
- Column(
59
- crossAxisAlignment: CrossAxisAlignment.start,
60
- mainAxisAlignment: MainAxisAlignment.center,
61
- spacing: 4,
62
- children: [
63
- Row(
64
- spacing:4,
65
- children: [
66
- Text(amount, style: TextStyle(fontSize:14,fontWeight: FontWeight.w400,color: Theme.of(context).colorScheme.onSurface),),
67
- if(address.toLowerCase().contains("mweb")) // hack carried over from old ui, we really should just have a boolean in the object
68
- CakeImageWidget(imageUrl:
69
- "assets/new-ui/address-type-picker-icons/mweb.svg",
49
+ child: Padding(
50
+ padding: const EdgeInsets.symmetric(horizontal: 12.0),
51
+ child: Row(
52
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
53
+ children: [
54
+ Row(
55
+ spacing: 12,
56
+ children: [
57
+ _getLeading(context),
58
+ // NewSimpleCheckbox(value: isSending, onChanged: (value){onCheckBoxTap?.call();}),
59
+ Column(
60
+ crossAxisAlignment: CrossAxisAlignment.start,
61
+ mainAxisAlignment: MainAxisAlignment.center,
62
+ spacing: 4,
63
+ children: [
64
+ Row(
65
+ spacing: 4,
66
+ children: [
67
+ Text(
68
+ amount,
69
+ style: TextStyle(
70
+ fontSize: 14,
71
+ fontWeight: FontWeight.w400,
72
+ color: Theme.of(context).colorScheme.onSurface),
73
+ ),
74
+ if (address.toLowerCase().contains(
75
+ "mweb")) // hack carried over from old ui, we really should just have a boolean in the object
76
+ CakeImageWidget(
77
+ imageUrl: "assets/new-ui/address-type-picker-icons/mweb.svg",
78
+ width: 18,
79
+ height: 18,
80
+ colorFilter: ColorFilter.mode(
81
+ Theme.of(context).colorScheme.onSurfaceVariant, BlendMode.srcIn),
82
+ ),
83
+ if (isSilentPayment)
84
+ CakeImageWidget(
85
+ imageUrl: "assets/new-ui/address-type-picker-icons/silent.svg",
86
width: 18,
87
height: 18,
88
colorFilter: ColorFilter.mode(
89
Theme.of(context).colorScheme.onSurfaceVariant, BlendMode.srcIn),
90
),
75
- if(isSilentPayment)
76
- CakeImageWidget(imageUrl:
77
- "assets/new-ui/address-type-picker-icons/silent.svg",
78
- width: 18,
79
- height: 18,
80
- colorFilter: ColorFilter.mode(
81
- Theme.of(context).colorScheme.onSurfaceVariant, BlendMode.srcIn),
82
- ),
91
],
84
- ),
85
- AutoSizeText(
86
- '${address.substring(0, 5)}...${address.substring(address.length - 5)}',
87
- style: TextStyle(fontSize:12,fontWeight: FontWeight.w400,color: Theme.of(context).colorScheme.onSurfaceVariant),
88
- maxLines: 1,
89
- ),
90
- ],
91
-
92
- )
93
- ],
94
- ),
92
+ ),
93
+ AutoSizeText(
94
+ '${address.substring(0, 5)}...${address.substring(address.length - 5)}',
95
+ style: TextStyle(
96
+ fontSize: 12,
97
+ fontWeight: FontWeight.w400,
98
+ color: Theme.of(context).colorScheme.onSurfaceVariant),
99
+ maxLines: 1,
100
+ ),
101
+ ],
102
+ )
103
+ ],
104
+ ),
105
Row(
106
spacing: 8,
107
children: [
@@ -102,8 +112,8 @@ class CoinControlListItem extends StatelessWidget {
112
fontWeight: FontWeight.w400,
113
color: Theme.of(context).colorScheme.onSurfaceVariant),
114
),
105
- CakeImageWidget(imageUrl:
106
- "assets/new-ui/arrow_right.svg",
115
+ CakeImageWidget(
116
+ imageUrl: "assets/new-ui/arrow_right.svg",
117
colorFilter: ColorFilter.mode(
118
Theme.of(context).colorScheme.onSurfaceVariant, BlendMode.srcIn),
119
),
@@ -111,24 +121,28 @@ class CoinControlListItem extends StatelessWidget {
121
)
122
],
123
),
114
- )
115
- );
124
+ ));
125
}
126
127
Widget _getLeading(BuildContext context) {
119
- if(isLoading) {
120
- return CircularProgressIndicator(color: Theme.of(context).colorScheme.primary,);
128
+ if (isLoading) {
129
+ return CircularProgressIndicator(
130
+ color: Theme.of(context).colorScheme.primary,
131
+ );
132
}
133
123
- if(isFrozen) {
124
- return CakeImageWidget(imageUrl:"assets/new-ui/frozen.svg");
134
+ if (isFrozen) {
135
+ return CakeImageWidget(imageUrl: "assets/new-ui/frozen.svg");
136
}
137
127
- if(!hasCheckbox) {
138
+ if (!hasCheckbox) {
139
return SizedBox.shrink();
140
}
141
131
- return NewSimpleCheckbox(value: isSending, onChanged: (value){onCheckBoxTap?.call();});
132
-
142
+ return NewSimpleCheckbox(
143
+ value: isSending,
144
+ onChanged: (value) {
145
+ onCheckBoxTap?.call();
146
+ });
147
}
148
}
lib/new-ui/widgets/coins_page/action_row/coin_action_row.dart
+67
-68
@@ -27,7 +27,8 @@ import '../../../pages/receive_page.dart';
27
import 'coin_action_button.dart';
28
29
class CoinActionRow extends StatelessWidget {
30
- const CoinActionRow({super.key, this.lightningMode = false, this.showSwap = true, required this.walletType});
30
+ const CoinActionRow(
31
+ {super.key, this.lightningMode = false, this.showSwap = true, required this.walletType});
32
33
final bool lightningMode;
34
final bool showSwap;
@@ -43,8 +44,8 @@ class CoinActionRow extends StatelessWidget {
44
spacing: MediaQuery.of(context).size.width * 0.05,
45
children: [
46
CoinActionButton(
46
- icon: CakeImageWidget(imageUrl:
47
- "assets/new-ui/send.svg",
47
+ icon: CakeImageWidget(
48
+ imageUrl: "assets/new-ui/send.svg",
49
colorFilter: ColorFilter.mode(
50
Theme.of(context).colorScheme.primary,
51
BlendMode.srcIn,
@@ -75,14 +76,14 @@ class CoinActionRow extends StatelessWidget {
76
);
77
} else {
78
Map<String, dynamic>? args;
78
- if (lightningMode) args = {'coinTypeToSpendFrom' : UnspentCoinType.lightning};
79
+ if (lightningMode) args = {'coinTypeToSpendFrom': UnspentCoinType.lightning};
80
Navigator.of(context).pushNamed(Routes.send, arguments: args);
81
}
82
},
83
),
84
CoinActionButton(
84
- icon: CakeImageWidget(imageUrl:
85
- "assets/new-ui/receive.svg",
85
+ icon: CakeImageWidget(
86
+ imageUrl: "assets/new-ui/receive.svg",
87
colorFilter: ColorFilter.mode(
88
Theme.of(context).colorScheme.primary,
89
BlendMode.srcIn,
@@ -96,7 +97,7 @@ class CoinActionRow extends StatelessWidget {
97
context: context,
98
barrierColor: Colors.black.withAlpha(60),
99
builder: (context) {
99
- return Material(child: ModalNavigator(parentContext:context,rootPage: page));
100
+ return Material(child: ModalNavigator(parentContext: context, rootPage: page));
101
},
102
);
103
} else {
@@ -114,8 +115,8 @@ class CoinActionRow extends StatelessWidget {
115
),
116
if (showSwap)
117
CoinActionButton(
117
- icon: CakeImageWidget(imageUrl:
118
- "assets/new-ui/exchange.svg",
118
+ icon: CakeImageWidget(
119
+ imageUrl: "assets/new-ui/exchange.svg",
120
colorFilter: ColorFilter.mode(
121
Theme.of(context).colorScheme.primary,
122
BlendMode.srcIn,
@@ -123,7 +124,8 @@ class CoinActionRow extends StatelessWidget {
124
),
125
label: S.of(context).swap,
126
action: () {
126
- final page = getIt.get<NewSwapPage>(param2: lightningMode ? CryptoCurrency.btcln : null);
127
+ final page =
128
+ getIt.get<NewSwapPage>(param2: lightningMode ? CryptoCurrency.btcln : null);
129
if (FeatureFlag.hasNewUiExtraPages) {
130
CupertinoScaffold.showCupertinoModalBottomSheet(
131
context: context,
@@ -140,8 +142,8 @@ class CoinActionRow extends StatelessWidget {
142
},
143
),
144
CoinActionButton(
143
- icon: CakeImageWidget(imageUrl:
144
- "assets/new-ui/scan.svg",
145
+ icon: CakeImageWidget(
146
+ imageUrl: "assets/new-ui/scan.svg",
147
colorFilter: ColorFilter.mode(
148
Theme.of(context).colorScheme.primary,
149
BlendMode.srcIn,
@@ -156,67 +158,64 @@ class CoinActionRow extends StatelessWidget {
158
}
159
160
Future<void> _onPressedScan(BuildContext context) async {
159
- final code = await presentQRScanner(context, showHelp: true);
161
+ final code = await presentQRScanner(context, showHelp: true);
162
161
- if (code == null || code.isEmpty) return;
163
+ if (code == null || code.isEmpty) return;
164
163
- late final PaymentRequest req;
164
- var unspentCoinType = UnspentCoinType.any;
165
- if (SendViewModelBase.isNonZeroAmountLightningInvoice(code)) {
166
- unspentCoinType = UnspentCoinType.lightning;
167
- final amount = getBolt11Amount(code)?.toString() ?? "0";
168
- req = PaymentRequest(code, amount, "", "", "");
169
- } else if (SendViewModelBase.isLnurlInvoice(code)) {
170
- unspentCoinType = UnspentCoinType.lightning;
171
- final amount = (await LNURL.getPayRequestAmount(code))?.toString() ?? "0";
172
- req = PaymentRequest(code, amount, "", "", "");
173
- } else if (OpenCryptoPayService.isOpenCryptoPayQR(code)) {
174
- req = PaymentRequest(code, "", "", "", "");
175
- } else
176
- if (Uri.tryParse(code)?.scheme == "wc") {
177
- if (!isWalletConnectCompatibleChain(walletType)) {
178
- showPopUp<void>(
179
- context: context,
180
- builder: (context) => AlertWithOneAction(
181
- alertTitle: "WalletConnect",
182
- alertContent: S
183
- .of(context)
184
- .switchToWCCompatibleWallet(walletConnectCompatibleChainsLabel()),
185
- buttonText: "OK",
186
- buttonAction: Navigator.of(context).pop));
187
- return;
188
- }
189
-
190
- Navigator.of(context)
191
- .pushNamed(Routes.walletConnectConnectionsListing, arguments: Uri.parse(code));
192
- return;
193
- } else if(["http", "https", "tcp"].contains(Uri.tryParse(code)?.scheme)) {
194
- Navigator.of(context).pushNamed(Routes.newNode,
195
- arguments: {"editingNode": Node.fromUri(Uri.parse(code), walletType)});
165
+ late final PaymentRequest req;
166
+ var unspentCoinType = UnspentCoinType.any;
167
+ if (SendViewModelBase.isNonZeroAmountLightningInvoice(code)) {
168
+ unspentCoinType = UnspentCoinType.lightning;
169
+ final amount = getBolt11Amount(code)?.toString() ?? "0";
170
+ req = PaymentRequest(code, amount, "", "", "");
171
+ } else if (SendViewModelBase.isLnurlInvoice(code)) {
172
+ unspentCoinType = UnspentCoinType.lightning;
173
+ final amount = (await LNURL.getPayRequestAmount(code))?.toString() ?? "0";
174
+ req = PaymentRequest(code, amount, "", "", "");
175
+ } else if (OpenCryptoPayService.isOpenCryptoPayQR(code)) {
176
+ req = PaymentRequest(code, "", "", "", "");
177
+ } else if (Uri.tryParse(code)?.scheme == "wc") {
178
+ if (!isWalletConnectCompatibleChain(walletType)) {
179
+ showPopUp<void>(
180
+ context: context,
181
+ builder: (context) => AlertWithOneAction(
182
+ alertTitle: "WalletConnect",
183
+ alertContent:
184
+ S.of(context).switchToWCCompatibleWallet(walletConnectCompatibleChainsLabel()),
185
+ buttonText: "OK",
186
+ buttonAction: Navigator.of(context).pop));
187
return;
197
-
198
- }else {
199
- final uri = Uri.tryParse(code);
200
- if (uri == null) return;
201
- req = PaymentRequest.fromUri(uri);
188
}
189
204
- final sendPage = getIt.get<NewSendPage>(
205
- param1: SendPageParams(
206
- initialPaymentRequest: req,
207
- unspentCoinType: unspentCoinType,
208
- ),
209
- );
190
+ Navigator.of(context)
191
+ .pushNamed(Routes.walletConnectConnectionsListing, arguments: Uri.parse(code));
192
+ return;
193
+ } else if (["http", "https", "tcp"].contains(Uri.tryParse(code)?.scheme)) {
194
+ Navigator.of(context).pushNamed(Routes.newNode,
195
+ arguments: {"editingNode": Node.fromUri(Uri.parse(code), walletType)});
196
+ return;
197
+ } else {
198
+ final uri = Uri.tryParse(code);
199
+ if (uri == null) return;
200
+ req = PaymentRequest.fromUri(uri);
201
+ }
202
211
- CupertinoScaffold.showCupertinoModalBottomSheet(
212
- context: context,
213
- barrierColor: Colors.black.withAlpha(60),
214
- builder: (context) => Material(
215
- child: ModalNavigator(
216
- rootPage: sendPage,
217
- parentContext: context,
218
- ),
203
+ final sendPage = getIt.get<NewSendPage>(
204
+ param1: SendPageParams(
205
+ initialPaymentRequest: req,
206
+ unspentCoinType: unspentCoinType,
207
+ ),
208
+ );
209
+
210
+ CupertinoScaffold.showCupertinoModalBottomSheet(
211
+ context: context,
212
+ barrierColor: Colors.black.withAlpha(60),
213
+ builder: (context) => Material(
214
+ child: ModalNavigator(
215
+ rootPage: sendPage,
216
+ parentContext: context,
217
),
220
- );
221
- }
218
+ ),
219
+ );
220
+ }
221
}
lib/new-ui/widgets/coins_page/assets_history/asset_tile.dart
+13
-9
@@ -18,7 +18,10 @@ class AssetTile extends StatelessWidget {
18
this.title,
19
this.trailingText,
20
this.modalMode = AssetDetailsModalModes.normal,
21
- required this.wallet, required this.showSwap, required this.isFirst, required this.isLast});
21
+ required this.wallet,
22
+ required this.showSwap,
23
+ required this.isFirst,
24
+ required this.isLast});
25
26
final BalanceRecord balance;
27
final bool showSecondary;
@@ -37,7 +40,7 @@ class AssetTile extends StatelessWidget {
40
final iconPath = balance.asset.iconPath ?? "";
41
42
return GestureDetector(
40
- onTap: (){
43
+ onTap: () {
44
showModalBottomSheet(
45
context: context,
46
isScrollControlled: true,
@@ -120,11 +123,12 @@ class AssetTile extends StatelessWidget {
123
title ?? balance.asset.fullName ?? balance.asset.name,
124
style: TextStyle(fontWeight: FontWeight.w500),
125
),
123
- if(trailingText != null)
124
- Text(
125
- trailingText!,
126
- style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant),
127
- ),
126
+ if (trailingText != null)
127
+ Text(
128
+ trailingText!,
129
+ style: TextStyle(
130
+ color: Theme.of(context).colorScheme.onSurfaceVariant),
131
+ ),
132
],
133
),
134
Padding(
@@ -133,8 +137,8 @@ class AssetTile extends StatelessWidget {
137
fit: BoxFit.scaleDown,
138
alignment: Alignment.centerLeft,
139
child: Text(
136
- "${showSecondary ?balance.secondAvailableBalance: balance.availableBalance} ${balance.formattedAssetTitle.safeSubString(0, 6)}",
137
- maxLines:1,
140
+ "${showSecondary ? balance.secondAvailableBalance : balance.availableBalance} ${balance.formattedAssetTitle.safeSubString(0, 6)}",
141
+ maxLines: 1,
142
style: TextStyle(
143
color: Theme.of(context).colorScheme.onSurfaceVariant,
144
),
lib/new-ui/widgets/coins_page/assets_history/assets_history_section.dart
+26
-18
@@ -47,7 +47,8 @@ class _AssetsHistorySectionState extends State<AssetsHistorySection> {
47
48
void reloadTabs() {
49
final oldTabLength = tabs.length;
50
- final hasAssetsTab = widget.dashboardViewModel.balanceViewModel.isHomeScreenSettingsEnabled || (widget.dashboardViewModel.hasMweb && widget.dashboardViewModel.mwebEnabled);
50
+ final hasAssetsTab = widget.dashboardViewModel.balanceViewModel.isHomeScreenSettingsEnabled ||
51
+ (widget.dashboardViewModel.hasMweb && widget.dashboardViewModel.mwebEnabled);
52
final hasNftTab = isNFTACtivatedChain(widget.dashboardViewModel.wallet.type,
53
chainId: widget.dashboardViewModel.wallet.chainId);
54
tabs = [
@@ -56,12 +57,14 @@ class _AssetsHistorySectionState extends State<AssetsHistorySection> {
57
S.current.assets,
58
AssetsSection(
59
dashboardViewModel: widget.dashboardViewModel,
59
- ), AssetsHistorySectionActionButton(S.current.tokens, "assets/new-ui/options_slider.svg", (){
60
- Navigator.of(context).pushNamed(
61
- Routes.homeSettings,
62
- arguments: widget.dashboardViewModel.balanceViewModel,
63
- );
64
- })),
60
+ ),
61
+ AssetsHistorySectionActionButton(S.current.tokens, "assets/new-ui/options_slider.svg",
62
+ () {
63
+ Navigator.of(context).pushNamed(
64
+ Routes.homeSettings,
65
+ arguments: widget.dashboardViewModel.balanceViewModel,
66
+ );
67
+ })),
68
AssetsHistorySectionTab(
69
S.current.history,
70
HistorySection(
@@ -69,9 +72,14 @@ class _AssetsHistorySectionState extends State<AssetsHistorySection> {
72
roundedTopSection: hasAssetsTab || hasNftTab,
73
dashboardViewModel: widget.dashboardViewModel,
74
short: true,
72
- ), AssetsHistorySectionActionButton(S.current.all_pascal_case, "assets/new-ui/arrow_right.svg", (){openHistoryModal(context);})),
75
+ ),
76
+ AssetsHistorySectionActionButton(
77
+ S.current.all_pascal_case, "assets/new-ui/arrow_right.svg", () {
78
+ openHistoryModal(context);
79
+ })),
80
if (hasNftTab)
74
- AssetsHistorySectionTab(S.current.nfts, NFTListingPage(nftViewModel: widget.nftViewModel), null)
81
+ AssetsHistorySectionTab(
82
+ S.current.nfts, NFTListingPage(nftViewModel: widget.nftViewModel), null)
83
];
84
if (oldTabLength != tabs.length) {
85
setState(() {
@@ -85,23 +93,23 @@ class _AssetsHistorySectionState extends State<AssetsHistorySection> {
93
super.initState();
94
reloadTabs();
95
88
- reaction((_)=>widget.dashboardViewModel.balanceViewModel.formattedBalances, (value) {
96
+ reaction((_) => widget.dashboardViewModel.balanceViewModel.formattedBalances, (value) {
97
reloadTabs();
98
});
91
- reaction((_)=>widget.dashboardViewModel.mwebEnabled, (_)=>reloadTabs());
99
+ reaction((_) => widget.dashboardViewModel.mwebEnabled, (_) => reloadTabs());
100
}
101
102
@override
103
Widget build(BuildContext context) {
104
return SliverMainAxisGroup(
105
slivers: [
98
- if(tabs.length>1)
99
- AssetsTopBar(
106
+ if (tabs.length > 1)
107
+ AssetsTopBar(
108
onTransactionHistoryOpened: () => openHistoryModal(context),
101
- dashboardViewModel: widget.dashboardViewModel,
102
- tabs: tabs,
103
- onTabChange: (index) {
104
- setState(() {
109
+ dashboardViewModel: widget.dashboardViewModel,
110
+ tabs: tabs,
111
+ onTabChange: (index) {
112
+ setState(() {
113
_selectedTab = index;
114
});
115
},
@@ -109,7 +117,7 @@ class _AssetsHistorySectionState extends State<AssetsHistorySection> {
117
),
118
if (tabs.length == 1)
119
Observer(
112
- builder:(_)=> HistoryTopBar(
120
+ builder: (_) => HistoryTopBar(
121
onTap: () => openHistoryModal(context),
122
roundedBottom: widget.dashboardViewModel.itemsShort.isEmpty,
123
),
lib/new-ui/widgets/coins_page/assets_history/assets_section.dart
+52
-50
@@ -4,7 +4,6 @@ import 'package:cw_core/crypto_currency.dart';
4
import 'package:flutter/material.dart';
5
import 'package:flutter_mobx/flutter_mobx.dart';
6
7
-
7
import 'asset_tile.dart';
8
9
class AssetsSection extends StatelessWidget {
@@ -14,64 +13,65 @@ class AssetsSection extends StatelessWidget {
13
14
@override
15
Widget build(BuildContext context) {
17
-
16
return SliverToBoxAdapter(
17
child: Padding(
18
padding: const EdgeInsets.only(bottom: 64.0),
21
- child: Observer(
22
- builder: (context) {
23
- final hasMweb = dashboardViewModel.hasMweb && dashboardViewModel.mwebEnabled;
24
- return ListView.separated(
25
- shrinkWrap: true,
26
- padding: EdgeInsets.symmetric(vertical: 18),
27
- physics: NeverScrollableScrollPhysics(),
28
- itemCount: dashboardViewModel.balanceViewModel.formattedBalances.length + (hasMweb ? 1 : 0),
29
- separatorBuilder: (context, index) => Padding(
30
- padding: const EdgeInsets.symmetric(horizontal: 18.0),
31
- child: Container(
32
- color: Theme.of(context).colorScheme.surfaceContainer,
33
- height:1,
34
- child: Padding(
35
- padding: const EdgeInsets.symmetric(horizontal: 8.0),
36
- child: Container(color: Theme.of(context).colorScheme.surfaceContainerHigh,),
19
+ child: Observer(builder: (context) {
20
+ final hasMweb = dashboardViewModel.hasMweb && dashboardViewModel.mwebEnabled;
21
+ return ListView.separated(
22
+ shrinkWrap: true,
23
+ padding: EdgeInsets.symmetric(vertical: 18),
24
+ physics: NeverScrollableScrollPhysics(),
25
+ itemCount:
26
+ dashboardViewModel.balanceViewModel.formattedBalances.length + (hasMweb ? 1 : 0),
27
+ separatorBuilder: (context, index) => Padding(
28
+ padding: const EdgeInsets.symmetric(horizontal: 18.0),
29
+ child: Container(
30
+ color: Theme.of(context).colorScheme.surfaceContainer,
31
+ height: 1,
32
+ child: Padding(
33
+ padding: const EdgeInsets.symmetric(horizontal: 8.0),
34
+ child: Container(
35
+ color: Theme.of(context).colorScheme.surfaceContainerHigh,
36
),
37
),
38
),
40
- itemBuilder: (context, index) {
41
- return Observer(builder: (context) {
42
- if (hasMweb) {
43
- return AssetTile(
44
- showSwap: dashboardViewModel.isEnabledSwapAction,
45
- balance: dashboardViewModel.balanceViewModel.formattedBalances.first,
46
- showSecondary: index > 0 ? true : false,
47
- wallet: dashboardViewModel.wallet,
48
- chainIconPath: index > 0 ? dashboardViewModel.wallet.currency.chainIconPath! : "",
49
- trailingText: index > 0 ? "MWEB" : null,
50
- modalMode: index > 0
51
- ? AssetDetailsModalModes.ltcPrivate
52
- : AssetDetailsModalModes.ltcTransparent,
53
- isFirst: index == 0,
54
- isLast: index != 0,
55
- title: index > 0 ? "Litecoin Private" : null,
56
- );
57
- }
58
-
59
- final balance = dashboardViewModel.balanceViewModel.formattedBalances.elementAt(index);
39
+ ),
40
+ itemBuilder: (context, index) {
41
+ return Observer(builder: (context) {
42
+ if (hasMweb) {
43
return AssetTile(
44
showSwap: dashboardViewModel.isEnabledSwapAction,
62
- showBridgeButton: dashboardViewModel.showBridge(balance.asset),
63
- balance: balance,
45
+ balance: dashboardViewModel.balanceViewModel.formattedBalances.first,
46
+ showSecondary: index > 0 ? true : false,
47
wallet: dashboardViewModel.wallet,
48
+ chainIconPath:
49
+ index > 0 ? dashboardViewModel.wallet.currency.chainIconPath! : "",
50
+ trailingText: index > 0 ? "MWEB" : null,
51
+ modalMode: index > 0
52
+ ? AssetDetailsModalModes.ltcPrivate
53
+ : AssetDetailsModalModes.ltcTransparent,
54
isFirst: index == 0,
66
- isLast: index == dashboardViewModel.balanceViewModel.formattedBalances.length-1,
67
- chainIconPath: _getChainIconPath(),
55
+ isLast: index != 0,
56
+ title: index > 0 ? "Litecoin Private" : null,
57
);
69
- });
70
-
71
- },
72
- );
73
- }
74
- ),
58
+ }
59
+
60
+ final balance =
61
+ dashboardViewModel.balanceViewModel.formattedBalances.elementAt(index);
62
+ return AssetTile(
63
+ showSwap: dashboardViewModel.isEnabledSwapAction,
64
+ showBridgeButton: dashboardViewModel.showBridge(balance.asset),
65
+ balance: balance,
66
+ wallet: dashboardViewModel.wallet,
67
+ isFirst: index == 0,
68
+ isLast: index == dashboardViewModel.balanceViewModel.formattedBalances.length - 1,
69
+ chainIconPath: _getChainIconPath(),
70
+ );
71
+ });
72
+ },
73
+ );
74
+ }),
75
),
76
);
77
}
@@ -79,8 +79,10 @@ class AssetsSection extends StatelessWidget {
79
// TODO refactor chainIconPath to get rid of this ugly thing. it's needed because arbitrum's wallet currency isn't arb
80
String _getChainIconPath() {
81
try {
82
- return CryptoCurrency.fromString(dashboardViewModel.wallet.currency.tag ??dashboardViewModel.wallet.currency.title).chainIconPath!;
83
- } catch(e) {
82
+ return CryptoCurrency.fromString(
83
+ dashboardViewModel.wallet.currency.tag ?? dashboardViewModel.wallet.currency.title)
84
+ .chainIconPath!;
85
+ } catch (e) {
86
return dashboardViewModel.wallet.currency.chainIconPath ?? "";
87
}
88
}
lib/new-ui/widgets/coins_page/assets_history/assets_top_bar.dart
+52
-55
@@ -10,7 +10,8 @@ class AssetsTopBar extends StatelessWidget {
10
required this.onTabChange,
11
required this.onTransactionHistoryOpened,
12
required this.selectedTab,
13
- required this.tabs, required this.dashboardViewModel,
13
+ required this.tabs,
14
+ required this.dashboardViewModel,
15
});
16
17
final void Function(int) onTabChange;
@@ -21,77 +22,73 @@ class AssetsTopBar extends StatelessWidget {
22
23
@override
24
Widget build(BuildContext context) {
24
-
25
return SliverToBoxAdapter(
26
child: Padding(
27
padding: const EdgeInsets.only(top: 32.0, bottom: 0.0, left: 12.0, right: 18.0),
28
child: Row(
29
- crossAxisAlignment: CrossAxisAlignment.center,
30
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
31
- children: [
32
- LineTabSwitcher(
33
- tabs: tabs.map((item)=>item.title).toList(),
34
- onTabChange: onTabChange,
35
- selectedTab: selectedTab,
36
- ),
37
- AnimatedSwitcher(
38
- duration: Duration(milliseconds: 300),
39
- layoutBuilder: (currentChild, previousChildren) {
40
- return Stack(
41
- alignment: Alignment.centerRight,
42
- children: <Widget>[
43
- ...previousChildren,
44
- if (currentChild != null) currentChild,
45
- ],
46
- );
47
- },
48
- child: Row(
49
- key: ValueKey(selectedTab),
50
- spacing: 8,
29
+ crossAxisAlignment: CrossAxisAlignment.center,
30
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
31
children: [
52
-
53
- Opacity(
54
- opacity: tabs[selectedTab].actionButton != null ? 1 : 0,
55
- child: GestureDetector(
56
- onTap: () {
57
- if(tabs[selectedTab].actionButton != null) {
58
- tabs[selectedTab].actionButton?.onPressed();
59
- }
60
- },
61
- child: Container(
62
- height: 40,
63
- decoration: BoxDecoration(
64
- borderRadius: BorderRadius.circular(999999),
65
- color: Theme.of(context).colorScheme.surfaceContainer,
66
- ),
67
- child: Padding(
68
- padding: const EdgeInsets.symmetric(horizontal: 12.0),
69
- child: Row(
70
- spacing: 6,
71
- children: [
72
-
73
- if ((tabs[selectedTab].actionButton?.title ?? "").isNotEmpty)
32
+ LineTabSwitcher(
33
+ tabs: tabs.map((item) => item.title).toList(),
34
+ onTabChange: onTabChange,
35
+ selectedTab: selectedTab,
36
+ ),
37
+ AnimatedSwitcher(
38
+ duration: Duration(milliseconds: 300),
39
+ layoutBuilder: (currentChild, previousChildren) {
40
+ return Stack(
41
+ alignment: Alignment.centerRight,
42
+ children: <Widget>[
43
+ ...previousChildren,
44
+ if (currentChild != null) currentChild,
45
+ ],
46
+ );
47
+ },
48
+ child: Row(
49
+ key: ValueKey(selectedTab),
50
+ spacing: 8,
51
+ children: [
52
+ Opacity(
53
+ opacity: tabs[selectedTab].actionButton != null ? 1 : 0,
54
+ child: GestureDetector(
55
+ onTap: () {
56
+ if (tabs[selectedTab].actionButton != null) {
57
+ tabs[selectedTab].actionButton?.onPressed();
58
+ }
59
+ },
60
+ child: Container(
61
+ height: 40,
62
+ decoration: BoxDecoration(
63
+ borderRadius: BorderRadius.circular(999999),
64
+ color: Theme.of(context).colorScheme.surfaceContainer,
65
+ ),
66
+ child: Padding(
67
+ padding: const EdgeInsets.symmetric(horizontal: 12.0),
68
+ child: Row(
69
+ spacing: 6,
70
+ children: [
71
+ if ((tabs[selectedTab].actionButton?.title ?? "").isNotEmpty)
72
Text(
73
tabs[selectedTab].actionButton?.title ?? "",
74
style: TextStyle(color: Theme.of(context).colorScheme.primary),
75
),
78
- CakeImageWidget(
79
- imageUrl: tabs[selectedTab].actionButton?.iconPath,
80
- colorFilter: ColorFilter.mode(
81
- Theme.of(context).colorScheme.primary, BlendMode.srcIn)),
76
+ CakeImageWidget(
77
+ imageUrl: tabs[selectedTab].actionButton?.iconPath,
78
+ colorFilter: ColorFilter.mode(
79
+ Theme.of(context).colorScheme.primary, BlendMode.srcIn)),
80
],
81
),
82
+ ),
83
+ ),
84
+ ),
85
),
85
- ),
86
+ ],
87
),
88
),
89
],
90
),
90
- ),
91
- ],
92
- ),
91
),
92
);
93
}
96
-
94
}
lib/new-ui/widgets/coins_page/assets_history/history_filters_page.dart
+6
-3
@@ -55,7 +55,8 @@ class HistoryFiltersPage extends StatelessWidget {
55
if (dashboardViewModel.tradeFilterStore.displayAllTrades) {
56
subtitle = S.of(context).manage_providers;
57
subtitleColor = Theme.of(context).colorScheme.onSurfaceVariant;
58
- } else if (dashboardViewModel.tradeFilterStore.enabledProvidersCount == 0) {
58
+ } else if (dashboardViewModel.tradeFilterStore.enabledProvidersCount ==
59
+ 0) {
60
subtitle = S.of(context).no_providers_selected;
61
subtitleColor = Color(0xFFFFB84E);
62
} else {
@@ -74,10 +75,12 @@ class HistoryFiltersPage extends StatelessWidget {
75
value: item.value(),
76
onChanged: (val) {
77
if ((val &&
77
- dashboardViewModel.tradeFilterStore.enabledProvidersCount ==
78
+ dashboardViewModel
79
+ .tradeFilterStore.enabledProvidersCount ==
80
0) ||
81
(!val &&
80
- dashboardViewModel.tradeFilterStore.enabledProvidersCount >
82
+ dashboardViewModel
83
+ .tradeFilterStore.enabledProvidersCount >
84
0)) {
85
dashboardViewModel.tradeFilterStore
86
.toggleDisplayExchange(ExchangeProviderDescription.all);
lib/new-ui/widgets/coins_page/assets_history/history_modal.dart
+3
-3
@@ -88,9 +88,9 @@ class HistoryModal extends StatelessWidget {
88
color: Colors.transparent,
89
child: Container(
90
decoration: BoxDecoration(
91
- borderRadius: BorderRadius.circular(18),
92
- border: Border.all(color: Theme.of(context).colorScheme.primary, width: 1)
93
- ),
91
+ borderRadius: BorderRadius.circular(18),
92
+ border: Border.all(
93
+ color: Theme.of(context).colorScheme.primary, width: 1)),
94
height: 56,
95
width: double.infinity,
96
child: Row(
lib/new-ui/widgets/coins_page/assets_history/history_order_tile.dart
+10
-16
@@ -4,15 +4,15 @@ import 'package:cw_core/crypto_currency.dart';
4
import 'package:flutter/material.dart';
5
6
class HistoryOrderTile extends StatelessWidget {
7
- const HistoryOrderTile(
8
- {super.key,
9
- required this.date,
10
- required this.amount,
11
- required this.amountFiat,
12
- required this.roundedTop,
13
- required this.roundedBottom,
14
- required this.bottomSeparator,
15
- });
7
+ const HistoryOrderTile({
8
+ super.key,
9
+ required this.date,
10
+ required this.amount,
11
+ required this.amountFiat,
12
+ required this.roundedTop,
13
+ required this.roundedBottom,
14
+ required this.bottomSeparator,
15
+ });
16
17
final String date;
18
final String amount;
@@ -21,23 +21,17 @@ class HistoryOrderTile extends StatelessWidget {
21
final bool roundedBottom;
22
final bool bottomSeparator;
23
24
-
25
-
26
-
24
@override
25
Widget build(BuildContext context) {
29
-
26
return HistoryTileBase(
27
title: "Order",
28
date: date,
29
amount: amount,
30
amountFiat: amountFiat,
35
- leadingIcon:Image.asset("assets/images/cakepay.png"),
31
+ leadingIcon: Image.asset("assets/images/cakepay.png"),
32
roundedTop: roundedTop,
33
roundedBottom: roundedBottom,
34
bottomSeparator: bottomSeparator,
35
);
40
-
36
}
42
-
37
}
lib/new-ui/widgets/coins_page/assets_history/history_section.dart
+172
-158
@@ -24,7 +24,12 @@ import 'package:flutter_mobx/flutter_mobx.dart';
24
import 'package:intl/intl.dart';
25
26
class HistorySection extends StatelessWidget {
27
- const HistorySection({super.key, required this.dashboardViewModel, required this.short, required this.roundedTopSection, required this.detailsAsPage});
27
+ const HistorySection(
28
+ {super.key,
29
+ required this.dashboardViewModel,
30
+ required this.short,
31
+ required this.roundedTopSection,
32
+ required this.detailsAsPage});
33
34
final DashboardViewModel dashboardViewModel;
35
final bool short;
@@ -33,7 +38,6 @@ class HistorySection extends StatelessWidget {
38
39
@override
40
Widget build(BuildContext context) {
36
-
41
return SliverPadding(
42
padding: EdgeInsets.only(left: 16.0, right: 16, top: short && roundedTopSection ? 18 : 0),
43
sliver: Observer(
@@ -42,170 +46,180 @@ class HistorySection extends StatelessWidget {
46
final items = short ? dashboardViewModel.itemsShort : dashboardViewModel.items;
47
48
return (items.isEmpty)
45
- ? SliverPadding(
46
- padding: EdgeInsets.only(top: 24),
47
- sliver: SliverToBoxAdapter(
48
- child: (dashboardViewModel.status is SyncingSyncStatus)
49
- ? SizedBox.shrink()
50
- : Center(
51
- child: Text(S.of(context).transactions_will_appear_here,
52
- style: TextStyle(
53
- fontSize: 14,
54
- fontWeight: FontWeight.w400,
55
- color: Theme.of(context).colorScheme.onSurfaceVariant)),
56
- ),
57
- ),
58
- )
59
- : SliverPadding(
60
- padding: EdgeInsets.only(bottom: short ? 0 : 144),
61
- sliver: SliverList(
62
- delegate: SliverChildBuilderDelegate(
63
- childCount: items.length,
64
- (context, index) => Observer(builder: (_) {
65
- final prevItem = index == 0 ? null : items[index - 1];
66
- final topPadding = index == 0 ? 0.0 : 18.0;
67
- final item = items[index];
68
- final nextItem = index == items.length - 1
69
- ? null
70
- : items[index + 1];
71
-
72
- final roundedBottom = (nextItem == null || nextItem is DateSectionItem);
73
- final roundedTop = roundedTopSection && (prevItem == null || prevItem is DateSectionItem);
74
-
75
- if (item is TransactionListItem) {
76
- final transaction = item.transaction;
77
- final transactionType = dashboardViewModel.getTransactionType(transaction);
78
-
79
- if (item.hasTokens && item.assetOfTransaction == null) {
80
- return Container();
81
- }
82
-
83
- CryptoCurrency? asset;
84
- if (transaction.additionalInfo["isLightning"] == true)
85
- asset = CryptoCurrency.btcln;
86
- else
87
- asset = item.assetOfTransaction;
88
-
89
- return GestureDetector(
90
- onTap: () {
91
- final page = getIt.get<TransactionDetailsModal>(param1: transaction);
92
- if (detailsAsPage) {
93
- Navigator.of(context).push(
94
- CupertinoPageRoute(builder: (context) => Material(child: page)));
95
- } else {
96
- showModalBottomSheet(
97
- isScrollControlled: true,
98
- context: context,
99
- builder: (context) =>
100
- FractionallySizedBox(heightFactor: 0.9, child: page));
101
- }
102
- },
103
- child: HistoryTile(
104
- title: item.formattedTitle + transactionType,
105
- date: _formatTransactionDate(item.date, localeName),
106
- amount: item.formattedCryptoAmount,
107
- amountFiat: item.formattedFiatAmount,
108
- hasTokens: item.hasTokens,
109
- chainIconPath: _getChainIconPath(),
110
- roundedBottom: roundedBottom,
111
- roundedTop: roundedTop,
112
- bottomSeparator: !roundedBottom,
113
- direction: item.transaction.direction,
114
- pending: item.transaction.isPending,
115
- asset: asset,
116
- ),
117
- );
118
- } else if (item is TradeListItem) {
119
- final trade = item.trade;
120
- final tradeFrom = trade.from;
121
- final tradeTo = trade.to;
122
-
123
- return GestureDetector(
124
- onTap: () => Navigator.of(context)
125
- .pushNamed(Routes.tradeDetails, arguments: trade),
126
- child: HistoryTradeTile(
127
- from: tradeFrom,
128
- to: tradeTo,
129
- provider: trade.provider,
130
- date: _formatTransactionDate(item.trade.createdAt ?? DateTime.now(), localeName),
131
- amount: dashboardViewModel.balanceDisplayMode == BalanceDisplayMode.hiddenBalance ? "---" : trade.amountFormatted(),
132
- receiveAmount: dashboardViewModel.balanceDisplayMode == BalanceDisplayMode.hiddenBalance ? "---" : trade.receiveAmountFormatted(),
133
- roundedBottom: roundedBottom,
134
- roundedTop: roundedTop,
135
- bottomSeparator: !roundedBottom,
136
- swapState: trade.state,
137
- ),
138
- );
139
- } else if (item is SpecificDateSectionItem) {
140
- return Padding(
141
- padding: EdgeInsets.only(left: 8.0, bottom: 8.0, top: topPadding),
142
- child: Text(item.text,
49
+ ? SliverPadding(
50
+ padding: EdgeInsets.only(top: 24),
51
+ sliver: SliverToBoxAdapter(
52
+ child: (dashboardViewModel.status is SyncingSyncStatus)
53
+ ? SizedBox.shrink()
54
+ : Center(
55
+ child: Text(S.of(context).transactions_will_appear_here,
56
style: TextStyle(
144
- color: Theme.of(context).colorScheme.onSurfaceVariant)));
145
- } else if (item is DateSectionItem) {
146
- return Padding(
147
- padding: EdgeInsets.only(left: 8.0, bottom: 8.0, top: topPadding),
148
- child: Text(DateFormat("MMMM yyyy", localeName).format(item.date),
149
- style: TextStyle(
150
- color: Theme.of(context).colorScheme.onSurfaceVariant)));
151
- } else if (item is OrderListItem) {
152
- return GestureDetector(
153
- onTap: () => Navigator.of(context)
154
- .pushNamed(Routes.orderDetails, arguments: item.order),
155
- child: HistoryOrderTile(
156
- date: _formatTransactionDate(item.order.createdAt, localeName),
157
- amount: item.orderFormattedAmount,
158
- amountFiat: "",
159
- roundedBottom: roundedBottom,
160
- roundedTop: roundedTop,
161
- bottomSeparator: !roundedBottom,
162
- ),
163
- );
164
- } else if (item is PayjoinTransactionListItem) {
165
- final session = item.session;
166
-
167
- return GestureDetector(
168
- onTap: () => Navigator.of(context).pushNamed(
169
- Routes.payjoinDetails,
170
- arguments: [item.sessionId, item.transaction],
57
+ fontSize: 14,
58
+ fontWeight: FontWeight.w400,
59
+ color: Theme.of(context).colorScheme.onSurfaceVariant)),
60
),
172
- child: PayjoinHistoryTile(
173
- createdAt: _formatTransactionDate(session.inProgressSince!, localeName),
174
- amount: dashboardViewModel.appStore.amountParsingProxy
175
- .asDisplayString(Money(
176
- session.amount, CryptoCurrency.btc)),
177
- currency: item.transaction?.from ?? "BTC",
178
- state: item.status,
179
- isSending: session.isSenderSession,
180
- roundedTop: roundedTop,
61
+ ),
62
+ )
63
+ : SliverPadding(
64
+ padding: EdgeInsets.only(bottom: short ? 0 : 144),
65
+ sliver: SliverList(
66
+ delegate: SliverChildBuilderDelegate(
67
+ childCount: items.length,
68
+ (context, index) => Observer(builder: (_) {
69
+ final prevItem = index == 0 ? null : items[index - 1];
70
+ final topPadding = index == 0 ? 0.0 : 18.0;
71
+ final item = items[index];
72
+ final nextItem = index == items.length - 1 ? null : items[index + 1];
73
+
74
+ final roundedBottom = (nextItem == null || nextItem is DateSectionItem);
75
+ final roundedTop = roundedTopSection &&
76
+ (prevItem == null || prevItem is DateSectionItem);
77
+
78
+ if (item is TransactionListItem) {
79
+ final transaction = item.transaction;
80
+ final transactionType =
81
+ dashboardViewModel.getTransactionType(transaction);
82
+
83
+ if (item.hasTokens && item.assetOfTransaction == null) {
84
+ return Container();
85
+ }
86
+
87
+ CryptoCurrency? asset;
88
+ if (transaction.additionalInfo["isLightning"] == true)
89
+ asset = CryptoCurrency.btcln;
90
+ else
91
+ asset = item.assetOfTransaction;
92
+
93
+ return GestureDetector(
94
+ onTap: () {
95
+ final page =
96
+ getIt.get<TransactionDetailsModal>(param1: transaction);
97
+ if (detailsAsPage) {
98
+ Navigator.of(context).push(CupertinoPageRoute(
99
+ builder: (context) => Material(child: page)));
100
+ } else {
101
+ showModalBottomSheet(
102
+ isScrollControlled: true,
103
+ context: context,
104
+ builder: (context) =>
105
+ FractionallySizedBox(heightFactor: 0.9, child: page));
106
+ }
107
+ },
108
+ child: HistoryTile(
109
+ title: item.formattedTitle + transactionType,
110
+ date: _formatTransactionDate(item.date, localeName),
111
+ amount: item.formattedCryptoAmount,
112
+ amountFiat: item.formattedFiatAmount,
113
+ hasTokens: item.hasTokens,
114
+ chainIconPath: _getChainIconPath(),
115
roundedBottom: roundedBottom,
182
- bottomSeparator: !roundedBottom),
183
- );
184
- } else if (item is AnonpayTransactionListItem) {
185
- final transactionInfo = item.transaction;
116
+ roundedTop: roundedTop,
117
+ bottomSeparator: !roundedBottom,
118
+ direction: item.transaction.direction,
119
+ pending: item.transaction.isPending,
120
+ asset: asset,
121
+ ),
122
+ );
123
+ } else if (item is TradeListItem) {
124
+ final trade = item.trade;
125
+ final tradeFrom = trade.from;
126
+ final tradeTo = trade.to;
127
187
- return GestureDetector(
128
+ return GestureDetector(
129
+ onTap: () => Navigator.of(context)
130
+ .pushNamed(Routes.tradeDetails, arguments: trade),
131
+ child: HistoryTradeTile(
132
+ from: tradeFrom,
133
+ to: tradeTo,
134
+ provider: trade.provider,
135
+ date: _formatTransactionDate(
136
+ item.trade.createdAt ?? DateTime.now(), localeName),
137
+ amount: dashboardViewModel.balanceDisplayMode ==
138
+ BalanceDisplayMode.hiddenBalance
139
+ ? "---"
140
+ : trade.amountFormatted(),
141
+ receiveAmount: dashboardViewModel.balanceDisplayMode ==
142
+ BalanceDisplayMode.hiddenBalance
143
+ ? "---"
144
+ : trade.receiveAmountFormatted(),
145
+ roundedBottom: roundedBottom,
146
+ roundedTop: roundedTop,
147
+ bottomSeparator: !roundedBottom,
148
+ swapState: trade.state,
149
+ ),
150
+ );
151
+ } else if (item is SpecificDateSectionItem) {
152
+ return Padding(
153
+ padding: EdgeInsets.only(left: 8.0, bottom: 8.0, top: topPadding),
154
+ child: Text(item.text,
155
+ style: TextStyle(
156
+ color: Theme.of(context).colorScheme.onSurfaceVariant)));
157
+ } else if (item is DateSectionItem) {
158
+ return Padding(
159
+ padding: EdgeInsets.only(left: 8.0, bottom: 8.0, top: topPadding),
160
+ child: Text(DateFormat("MMMM yyyy", localeName).format(item.date),
161
+ style: TextStyle(
162
+ color: Theme.of(context).colorScheme.onSurfaceVariant)));
163
+ } else if (item is OrderListItem) {
164
+ return GestureDetector(
165
onTap: () => Navigator.of(context)
189
- .pushNamed(Routes.anonPayDetailsPage, arguments: transactionInfo),
190
- child: AnonpayHistoryTile(
191
- provider: transactionInfo.provider,
192
- createdAt: _formatTransactionDate(transactionInfo.createdAt, localeName),
193
- amount: transactionInfo.fiatAmount?.toString() ??
194
- (transactionInfo.amountTo?.toString() ?? ''),
195
- currency: transactionInfo.fiatAmount != null
196
- ? transactionInfo.fiatEquiv ?? ''
197
- : CryptoCurrency.fromFullName(transactionInfo.coinTo)
198
- .name
199
- .toUpperCase(),
166
+ .pushNamed(Routes.orderDetails, arguments: item.order),
167
+ child: HistoryOrderTile(
168
+ date: _formatTransactionDate(item.order.createdAt, localeName),
169
+ amount: item.orderFormattedAmount,
170
+ amountFiat: "",
171
+ roundedBottom: roundedBottom,
172
+ roundedTop: roundedTop,
173
+ bottomSeparator: !roundedBottom,
174
+ ),
175
+ );
176
+ } else if (item is PayjoinTransactionListItem) {
177
+ final session = item.session;
178
+
179
+ return GestureDetector(
180
+ onTap: () => Navigator.of(context).pushNamed(
181
+ Routes.payjoinDetails,
182
+ arguments: [item.sessionId, item.transaction],
183
+ ),
184
+ child: PayjoinHistoryTile(
185
+ createdAt:
186
+ _formatTransactionDate(session.inProgressSince!, localeName),
187
+ amount: dashboardViewModel.appStore.amountParsingProxy
188
+ .asDisplayString(Money(session.amount, CryptoCurrency.btc)),
189
+ currency: item.transaction?.from ?? "BTC",
190
+ state: item.status,
191
+ isSending: session.isSenderSession,
192
roundedTop: roundedTop,
193
roundedBottom: roundedBottom,
202
- bottomSeparator: !roundedBottom));
203
- } else
204
- return Text(item.runtimeType.toString());
205
- }),
194
+ bottomSeparator: !roundedBottom),
195
+ );
196
+ } else if (item is AnonpayTransactionListItem) {
197
+ final transactionInfo = item.transaction;
198
+
199
+ return GestureDetector(
200
+ onTap: () => Navigator.of(context).pushNamed(
201
+ Routes.anonPayDetailsPage,
202
+ arguments: transactionInfo),
203
+ child: AnonpayHistoryTile(
204
+ provider: transactionInfo.provider,
205
+ createdAt: _formatTransactionDate(
206
+ transactionInfo.createdAt, localeName),
207
+ amount: transactionInfo.fiatAmount?.toString() ??
208
+ (transactionInfo.amountTo?.toString() ?? ''),
209
+ currency: transactionInfo.fiatAmount != null
210
+ ? transactionInfo.fiatEquiv ?? ''
211
+ : CryptoCurrency.fromFullName(transactionInfo.coinTo)
212
+ .name
213
+ .toUpperCase(),
214
+ roundedTop: roundedTop,
215
+ roundedBottom: roundedBottom,
216
+ bottomSeparator: !roundedBottom));
217
+ } else
218
+ return Text(item.runtimeType.toString());
219
+ }),
220
+ ),
221
),
207
- ),
208
- );
222
+ );
223
},
224
));
225
}
lib/new-ui/widgets/coins_page/assets_history/history_swap_providers_page.dart
+4
-2
@@ -42,9 +42,11 @@ class HistorySwapProvidersPage extends StatelessWidget {
42
title: S.of(context).swap_providers,
43
onSelected: (val) {
44
if ((val &&
45
- dashboardViewModel.tradeFilterStore.enabledProvidersCount == 0) ||
45
+ dashboardViewModel.tradeFilterStore.enabledProvidersCount ==
46
+ 0) ||
47
(!val &&
47
- dashboardViewModel.tradeFilterStore.enabledProvidersCount > 0)) {
48
+ dashboardViewModel.tradeFilterStore.enabledProvidersCount >
49
+ 0)) {
50
dashboardViewModel.tradeFilterStore
51
.toggleDisplayExchange(ExchangeProviderDescription.all);
52
}
lib/new-ui/widgets/coins_page/assets_history/history_tile.dart
+31
-29
@@ -60,15 +60,14 @@ class HistoryTile extends StatelessWidget {
60
}
61
}
62
63
- Color? _getPrimaryTextColor() {
64
- }
63
+ Color? _getPrimaryTextColor() {}
64
65
Widget _getLeadingIcon(BuildContext context) {
66
if (asset == CryptoCurrency.btcln) {
67
return Stack(
68
children: [
70
- CakeImageWidget(imageUrl:
71
- "assets/new-ui/lightning-icon.svg",
69
+ CakeImageWidget(
70
+ imageUrl: "assets/new-ui/lightning-icon.svg",
71
width: 34,
72
height: 34,
73
),
@@ -96,36 +95,39 @@ class HistoryTile extends StatelessWidget {
95
);
96
}
97
99
- if(hasTokens) {
100
- return Stack(children: [
101
- Opacity(
102
- opacity: pending ? 0.5 : 1,
103
- child: CakeImageWidget(
98
+ if (hasTokens) {
99
+ return Stack(
100
+ children: [
101
+ Opacity(
102
+ opacity: pending ? 0.5 : 1,
103
+ child: CakeImageWidget(
104
imageUrl: asset?.iconPath ?? "",
105
width: 34,
106
),
107
- ),
108
- Align(
109
- alignment: Alignment.bottomRight,
110
- child: Container(
111
- decoration: ShapeDecoration(
112
- shape: RoundedSuperellipseBorder(
113
- borderRadius: BorderRadius.circular(5),side: BorderSide(color: Colors.black)),
114
- color: Colors.white),
115
- child: Padding(
116
- padding: const EdgeInsets.all(2.0),
117
- child: CakeImageWidget(
118
- imageUrl: chainIconPath,
119
- width: 12,
120
- height: 12,
121
- colorFilter:
122
- ColorFilter.mode(Colors.black, BlendMode.srcIn),
123
- ),
124
- )))
125
- ],);
107
+ ),
108
+ Align(
109
+ alignment: Alignment.bottomRight,
110
+ child: Container(
111
+ decoration: ShapeDecoration(
112
+ shape: RoundedSuperellipseBorder(
113
+ borderRadius: BorderRadius.circular(5),
114
+ side: BorderSide(color: Colors.black)),
115
+ color: Colors.white),
116
+ child: Padding(
117
+ padding: const EdgeInsets.all(2.0),
118
+ child: CakeImageWidget(
119
+ imageUrl: chainIconPath,
120
+ width: 12,
121
+ height: 12,
122
+ colorFilter: ColorFilter.mode(Colors.black, BlendMode.srcIn),
123
+ ),
124
+ )))
125
+ ],
126
+ );
127
}
128
128
- return CakeImageWidget(imageUrl:_getDirectionIcon(),
129
+ return CakeImageWidget(
130
+ imageUrl: _getDirectionIcon(),
131
colorFilter: ColorFilter.mode(
132
direction == TransactionDirection.outgoing
133
? Theme.of(context).colorScheme.inverseSurface.withAlpha(175)
lib/new-ui/widgets/coins_page/assets_history/history_tile_base.dart
+26
-23
@@ -109,24 +109,25 @@ class HistoryTileBase extends StatelessWidget {
109
Expanded(
110
child: Padding(
111
padding: EdgeInsets.only(right: 4),
112
- child: Row(
113
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
114
- children: [
115
- Column(
116
- crossAxisAlignment: CrossAxisAlignment.start,
112
+ child: Row(
113
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
114
+ children: [
115
+ Column(
116
+ crossAxisAlignment: CrossAxisAlignment.start,
117
children: [
118
- if(title != null)
119
- Text(title!,
120
- style: TextStyle(color: Theme.of(context).colorScheme.onSurface))
121
- else if(titleWidget != null) titleWidget!,
118
+ if (title != null)
119
+ Text(title!,
120
+ style: TextStyle(color: Theme.of(context).colorScheme.onSurface))
121
+ else if (titleWidget != null)
122
+ titleWidget!,
123
Text(date,
124
style: TextStyle(
125
color: Theme.of(context).colorScheme.onSurfaceVariant)),
126
],
126
- ),
127
- Column(
128
- crossAxisAlignment: CrossAxisAlignment.end,
129
- children: [
127
+ ),
128
+ Column(
129
+ crossAxisAlignment: CrossAxisAlignment.end,
130
+ children: [
131
if (amount != null)
132
Text(amount!,
133
style: TextStyle(
@@ -141,22 +142,24 @@ class HistoryTileBase extends StatelessWidget {
142
else if (amountFiatWidget != null)
143
amountFiatWidget!
144
],
144
- ),
145
- ],
146
- ),
145
+ ),
146
+ ],
147
+ ),
148
),
149
),
150
],
151
),
152
),
153
),
153
- if(bottomSeparator) Container(
154
- color: Theme.of(context).colorScheme.surfaceContainer,
155
- child: Padding(
156
- padding: EdgeInsets.only(left: 56, right: 16),
157
- child: Container(height: 1, color: Theme.of(context).colorScheme.outlineVariant.withAlpha(175)),
158
- ),
159
- )
154
+ if (bottomSeparator)
155
+ Container(
156
+ color: Theme.of(context).colorScheme.surfaceContainer,
157
+ child: Padding(
158
+ padding: EdgeInsets.only(left: 56, right: 16),
159
+ child: Container(
160
+ height: 1, color: Theme.of(context).colorScheme.outlineVariant.withAlpha(175)),
161
+ ),
162
+ )
163
],
164
);
165
}
lib/new-ui/widgets/coins_page/assets_history/history_top_bar.dart
+10
-10
@@ -19,9 +19,8 @@ class HistoryTopBar extends StatelessWidget {
19
child: Container(
20
decoration: BoxDecoration(
21
borderRadius: BorderRadius.vertical(
22
- top: Radius.circular(18),
23
- bottom: roundedBottom ? Radius.circular(18) : Radius.zero
24
- ),
22
+ top: Radius.circular(18),
23
+ bottom: roundedBottom ? Radius.circular(18) : Radius.zero),
24
color: Theme.of(context).colorScheme.surfaceContainer),
25
child: Padding(
26
padding: EdgeInsets.symmetric(
@@ -43,13 +42,14 @@ class HistoryTopBar extends StatelessWidget {
42
)
43
],
44
),
46
- if(!roundedBottom)
47
- Container(
48
- height: 1,
49
- width: double.infinity,
50
- color: Theme.of(context).colorScheme.outlineVariant.withAlpha(175),
51
- )
52
- else Container(height: 2)
45
+ if (!roundedBottom)
46
+ Container(
47
+ height: 1,
48
+ width: double.infinity,
49
+ color: Theme.of(context).colorScheme.outlineVariant.withAlpha(175),
50
+ )
51
+ else
52
+ Container(height: 2)
53
],
54
),
55
),
lib/new-ui/widgets/coins_page/assets_history/history_trade_tile.dart
+12
-9
@@ -36,7 +36,6 @@ class HistoryTradeTile extends StatelessWidget {
36
return SizedBox(width: 50, height: 50);
37
}
38
39
-
39
double currencyIconSize = 22.0;
40
41
return SizedBox(
@@ -90,7 +89,9 @@ class HistoryTradeTile extends StatelessWidget {
89
style: TextStyle(
90
color: Theme.of(context).colorScheme.onSurfaceVariant,
91
fontWeight: FontWeight.w500)),
93
- if(from?.title != null) Text(from!.title, style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant)),
92
+ if (from?.title != null)
93
+ Text(from!.title,
94
+ style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant)),
95
if (fromChainIcon?.isNotEmpty ?? false)
96
CakeImageWidget(
97
imageUrl: fromChainIcon,
@@ -111,11 +112,12 @@ class HistoryTradeTile extends StatelessWidget {
112
receiveAmount.withMaxDecimals(8),
113
style: TextStyle(fontWeight: FontWeight.w500),
114
),
114
- if(to!=null)
115
- Text(
116
- to!.title,
117
- ),
118
- if (toChainIcon?.isNotEmpty ?? false) CakeImageWidget(imageUrl: toChainIcon, width: 12, height: 12)
115
+ if (to != null)
116
+ Text(
117
+ to!.title,
118
+ ),
119
+ if (toChainIcon?.isNotEmpty ?? false)
120
+ CakeImageWidget(imageUrl: toChainIcon, width: 12, height: 12)
121
],
122
),
123
leadingIcon: _getLeadingStack(context),
@@ -144,10 +146,11 @@ class HistoryTradeTile extends StatelessWidget {
146
}
147
148
String? _getChainIcon(CryptoCurrency? currency) {
147
- if(currency == null) return null;
149
+ if (currency == null) return null;
150
try {
151
if (currency.title.isNotEmpty) {
150
- final parsedCurrency = CryptoCurrency.safeParseCurrencyFromString(currency.title, tag: currency.tag);
152
+ final parsedCurrency =
153
+ CryptoCurrency.safeParseCurrencyFromString(currency.title, tag: currency.tag);
154
if (parsedCurrency?.chainIconPath != null) return parsedCurrency!.chainIconPath!;
155
}
156
lib/new-ui/widgets/coins_page/assets_history/transaction_details_modal.dart
+35
-35
@@ -17,7 +17,8 @@ import 'package:flutter_mobx/flutter_mobx.dart';
17
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
18
19
class TransactionDetailsModal extends StatefulWidget {
20
- const TransactionDetailsModal({super.key, required this.transactionDetailsViewModel, this.highlightNoteField = false});
20
+ const TransactionDetailsModal(
21
+ {super.key, required this.transactionDetailsViewModel, this.highlightNoteField = false});
22
23
final TransactionDetailsViewModel transactionDetailsViewModel;
24
final bool highlightNoteField;
@@ -41,7 +42,7 @@ class _TransactionDetailsModalState extends State<TransactionDetailsModal> {
42
}
43
});
44
44
- if(widget.highlightNoteField) {
45
+ if (widget.highlightNoteField) {
46
noteFocusNode.requestFocus();
47
}
48
}
@@ -73,9 +74,8 @@ class _TransactionDetailsModalState extends State<TransactionDetailsModal> {
74
child: Column(
75
children: [
76
TokenImageWidget(
76
- imageUrl: widget
77
- .transactionDetailsViewModel.transactionAsset.iconPath ??
78
- "",
77
+ imageUrl:
78
+ widget.transactionDetailsViewModel.transactionAsset.iconPath ?? "",
79
size: 64,
80
),
81
SizedBox(height: 10),
@@ -87,12 +87,18 @@ class _TransactionDetailsModalState extends State<TransactionDetailsModal> {
87
CopyWrapper(
88
requireLongPress: true,
89
data: ClipboardData(text: transactionInfoAmount.toString()),
90
- builder: (context, copied)=> AnimatedSwitcher(
90
+ builder: (context, copied) => AnimatedSwitcher(
91
duration: Duration(milliseconds: 300),
92
child: Text(
93
key: ValueKey(copied),
94
- copied ? S.of(context).copied : transactionInfoAmount.toStringWithSymbol(),
95
- style: TextStyle(fontSize: 28, color: copied ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.onSurface),
94
+ copied
95
+ ? S.of(context).copied
96
+ : transactionInfoAmount.toStringWithSymbol(),
97
+ style: TextStyle(
98
+ fontSize: 28,
99
+ color: copied
100
+ ? Theme.of(context).colorScheme.primary
101
+ : Theme.of(context).colorScheme.onSurface),
102
),
103
),
104
),
@@ -104,25 +110,23 @@ class _TransactionDetailsModalState extends State<TransactionDetailsModal> {
110
NewListSections(sections: {
111
"": widget.transactionDetailsViewModel.items
112
.map((item) {
107
- if (item.value.isEmpty) return null;
113
+ if (item.value.isEmpty) return null;
114
109
- final shouldBuildBottomWidget =
110
- item.value.length > 25;
115
+ final shouldBuildBottomWidget = item.value.length > 25;
116
112
- return ListItemRegularRow(
113
- copyableText: item.value,
114
- showArrow: false,
115
- keyValue:
116
- ((item.key as ValueKey?)?.value as String?) ??
117
- item.title,
118
- label: item.title,
119
- trailingWidget: shouldBuildBottomWidget
120
- ? null
121
- : _buildTrailingWIdget(item),
122
- bottomWidget: shouldBuildBottomWidget
123
- ? _buildBottomWidget(item)
124
- : null);
125
- })
117
+ return ListItemRegularRow(
118
+ copyableText: item.value,
119
+ showArrow: false,
120
+ keyValue: ((item.key as ValueKey?)?.value as String?) ??
121
+ item.title,
122
+ label: item.title,
123
+ trailingWidget: shouldBuildBottomWidget
124
+ ? null
125
+ : _buildTrailingWIdget(item),
126
+ bottomWidget: shouldBuildBottomWidget
127
+ ? _buildBottomWidget(item)
128
+ : null);
129
+ })
130
.whereType<ListItem>()
131
.toList(),
132
}),
@@ -157,12 +161,10 @@ class _TransactionDetailsModalState extends State<TransactionDetailsModal> {
161
"view tx": [
162
ListItemRegularRow(
163
keyValue: "view tx on",
160
- label: widget.transactionDetailsViewModel
161
- .explorerDescription,
162
- onTap: widget
163
- .transactionDetailsViewModel.launchExplorer,
164
- foregroundColor:
165
- Theme.of(context).colorScheme.primary,
164
+ label:
165
+ widget.transactionDetailsViewModel.explorerDescription,
166
+ onTap: widget.transactionDetailsViewModel.launchExplorer,
167
+ foregroundColor: Theme.of(context).colorScheme.primary,
168
trailingIconPath: "assets/new-ui/link_arrow.svg",
169
trailingIconSize: 8)
170
],
@@ -174,10 +176,8 @@ class _TransactionDetailsModalState extends State<TransactionDetailsModal> {
176
onTap: () {
177
Navigator.of(context)
178
.pushNamed(Routes.bumpFeePage, arguments: [
177
- widget.transactionDetailsViewModel
178
- .transactionInfo,
179
- widget.transactionDetailsViewModel
180
- .rawTransaction
179
+ widget.transactionDetailsViewModel.transactionInfo,
180
+ widget.transactionDetailsViewModel.rawTransaction
181
]);
182
})
183
]
lib/new-ui/widgets/coins_page/cards/balance_card.dart
+44
-38
@@ -9,30 +9,30 @@ class BalanceCardAction {
9
final VoidCallback onTap;
10
final double? iconSize;
11
12
- const BalanceCardAction({required this.label, required this.icon, required this.onTap, this.iconSize = 16});
12
+ const BalanceCardAction(
13
+ {required this.label, required this.icon, required this.onTap, this.iconSize = 16});
14
}
15
16
class BalanceCard extends StatelessWidget {
16
- const BalanceCard({
17
- super.key,
18
- required this.width,
19
- required this.design,
20
- this.gradient,
21
- this.borderRadius = 20,
22
- this.selected = false,
23
- this.accountName = "",
24
- this.accountBalance = "",
25
- this.balance = "",
26
- this.fiatBalance = "",
27
- this.assetName = "",
28
- this.fiatCurrencyTitle = "",
29
- this.designSwitchDuration = const Duration(),
30
- this.actions = const [],
31
- this.capitalizeAssetName = true,
32
- this.onCustomizeTapped,
33
- this.accountIndex,
34
- this.fiatFirst = false
35
- });
17
+ const BalanceCard(
18
+ {super.key,
19
+ required this.width,
20
+ required this.design,
21
+ this.gradient,
22
+ this.borderRadius = 20,
23
+ this.selected = false,
24
+ this.accountName = "",
25
+ this.accountBalance = "",
26
+ this.balance = "",
27
+ this.fiatBalance = "",
28
+ this.assetName = "",
29
+ this.fiatCurrencyTitle = "",
30
+ this.designSwitchDuration = const Duration(),
31
+ this.actions = const [],
32
+ this.capitalizeAssetName = true,
33
+ this.onCustomizeTapped,
34
+ this.accountIndex,
35
+ this.fiatFirst = false});
36
37
final double width;
38
final double borderRadius;
@@ -89,15 +89,15 @@ class BalanceCard extends StatelessWidget {
89
switchOutCurve: Curves.easeInOut,
90
child: design.backgroundType == CardDesignBackgroundTypes.svgFull
91
? ClipRSuperellipse(
92
- borderRadius: BorderRadius.circular(borderRadius),
93
- key: ValueKey(design.imagePath),
92
+ borderRadius: BorderRadius.circular(borderRadius),
93
+ key: ValueKey(design.imagePath),
94
child: CakeImageWidget(
95
imageUrl: design.imagePath,
96
width: width,
97
height: height,
98
fit: BoxFit.fill,
99
),
100
- )
100
+ )
101
: const SizedBox.shrink(
102
key: ValueKey('svgFullOff'),
103
),
@@ -114,10 +114,10 @@ class BalanceCard extends StatelessWidget {
114
crossAxisAlignment: CrossAxisAlignment.start,
115
mainAxisSize: MainAxisSize.max,
116
children: [
117
- if(leadText.isNotEmpty || accountBalance.isNotEmpty)
118
- Row(
119
- mainAxisSize: MainAxisSize.max,
120
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
117
+ if (leadText.isNotEmpty || accountBalance.isNotEmpty)
118
+ Row(
119
+ mainAxisSize: MainAxisSize.max,
120
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
121
children: [
122
Row(
123
spacing: 4,
@@ -136,7 +136,9 @@ class BalanceCard extends StatelessWidget {
136
AnimatedDefaultTextStyle(
137
duration: designSwitchDuration,
138
style: Theme.of(context).textTheme.titleMedium!.copyWith(
139
- fontWeight: FontWeight.w500, color: design.colors.textColor.withAlpha(leadText == accountName ? 255 : 128)),
139
+ fontWeight: FontWeight.w500,
140
+ color: design.colors.textColor
141
+ .withAlpha(leadText == accountName ? 255 : 128)),
142
child: Text(leadText),
143
),
144
],
@@ -147,10 +149,10 @@ class BalanceCard extends StatelessWidget {
149
child: Text(
150
accountBalance,
151
style: TextStyle(color: design.colors.textColor, fontSize: 14),
152
+ ),
153
),
151
- ),
152
- ],
153
- ),
154
+ ],
155
+ ),
156
AnimatedOpacity(
157
opacity: selected ? 1 : 0,
158
duration: textFadeDuration,
@@ -171,16 +173,20 @@ class BalanceCard extends StatelessWidget {
173
children: [
174
AnimatedDefaultTextStyle(
175
duration: designSwitchDuration,
174
- style: DefaultTextStyle.of(context)
175
- .style
176
- .copyWith(color: design.colors.textColor, fontSize: 28, fontWeight: FontWeight.w500, letterSpacing: -0.4),
176
+ style: DefaultTextStyle.of(context).style.copyWith(
177
+ color: design.colors.textColor,
178
+ fontSize: 28,
179
+ fontWeight: FontWeight.w500,
180
+ letterSpacing: -0.4),
181
child: Text(fiatFirst ? fiatBalance : balance),
182
),
183
AnimatedDefaultTextStyle(
184
duration: designSwitchDuration,
181
- style: DefaultTextStyle.of(context)
182
- .style
183
- .copyWith(color: design.colors.textColorSecondary, fontSize: 28, fontWeight: FontWeight.w400, letterSpacing: -0.4),
185
+ style: DefaultTextStyle.of(context).style.copyWith(
186
+ color: design.colors.textColorSecondary,
187
+ fontSize: 28,
188
+ fontWeight: FontWeight.w400,
189
+ letterSpacing: -0.4),
190
child: Text(resolvedAssetName),
191
),
192
],
lib/new-ui/widgets/coins_page/cards/cards_view.dart
+45
-39
@@ -32,7 +32,8 @@ class CardsView extends StatefulWidget {
32
required this.dashboardViewModel,
33
required this.accountListViewModel,
34
required this.lightningMode,
35
- required this.onCompactModeBackgroundCardsTapped, required this.onCustomizeTapped});
35
+ required this.onCompactModeBackgroundCardsTapped,
36
+ required this.onCustomizeTapped});
37
38
final DashboardViewModel dashboardViewModel;
39
final MoneroAccountListViewModel? accountListViewModel;
@@ -73,7 +74,6 @@ class _CardsViewState extends State<CardsView> {
74
75
final top = baseTop - (howFarBehind * overlapAmount);
76
76
-
77
final left = (parentWidth - effectiveCardWidth) / 2.0;
78
79
return AnimatedPositioned(
@@ -91,7 +91,7 @@ class _CardsViewState extends State<CardsView> {
91
// printV(visualIndex);
92
if (compactMode && visualIndex != 0) {
93
widget.onCompactModeBackgroundCardsTapped();
94
- } else if(!compactMode) {
94
+ } else if (!compactMode) {
95
setState(() {
96
if (widget.accountListViewModel != null)
97
widget.accountListViewModel!
@@ -103,18 +103,20 @@ class _CardsViewState extends State<CardsView> {
103
onLongPress: () {
104
if (_selectedIndex == visualIndex) {
105
widget.dashboardViewModel.balanceViewModel.switchBalanceValue();
106
- };
106
+ }
107
+ ;
108
HapticFeedback.heavyImpact();
109
},
110
child: Observer(builder: (_) {
110
- if(realIndex >= (widget.accountListViewModel?.accounts.length ?? 1)) {
111
+ if (realIndex >= (widget.accountListViewModel?.accounts.length ?? 1)) {
112
return Container();
113
}
114
final account = widget.accountListViewModel?.accounts[realIndex];
115
116
// The second balance should always be the lightning balance
117
// printV(widget.dashboardViewModel.balanceViewModel.formattedBalances.first.availableBalance);
117
- final walletBalanceRecord = widget.dashboardViewModel.balanceViewModel.getMainBalanceRecord(widget.lightningMode);
118
+ final walletBalanceRecord = widget.dashboardViewModel.balanceViewModel
119
+ .getMainBalanceRecord(widget.lightningMode);
120
121
late final String walletBalance;
122
late final String walletFiatBalance;
@@ -141,7 +143,7 @@ class _CardsViewState extends State<CardsView> {
143
if (widget.dashboardViewModel.cardDesigns.isEmpty ||
144
realIndex >= widget.dashboardViewModel.cardDesigns.length)
145
cardDesign = CardDesign.genericDefault;
144
- else if(widget.lightningMode)
146
+ else if (widget.lightningMode)
147
cardDesign = widget.dashboardViewModel.cardDesigns[realIndex + 1];
148
else
149
cardDesign = widget.dashboardViewModel.cardDesigns[realIndex];
@@ -156,7 +158,9 @@ class _CardsViewState extends State<CardsView> {
158
accountBalance = account.balance ?? "0.00";
159
}
160
159
- final assetName = widget.dashboardViewModel.balanceViewModel.showCombinedBalance ? "" : walletBalanceRecord?.formattedAssetTitle ?? assetTitleFallback;
161
+ final assetName = widget.dashboardViewModel.balanceViewModel.showCombinedBalance
162
+ ? ""
163
+ : walletBalanceRecord?.formattedAssetTitle ?? assetTitleFallback;
164
165
final List<BalanceCardAction> actions = widget.lightningMode
166
? [
@@ -205,13 +209,12 @@ class _CardsViewState extends State<CardsView> {
209
);
210
}
211
208
- String get assetTitleFallback => widget.dashboardViewModel.appStore.amountParsingProxy.getCryptoSymbol(
209
- widget.lightningMode
210
- ? CryptoCurrency.btcln
211
- : widget.dashboardViewModel.wallet.currency);
212
+ String get assetTitleFallback =>
213
+ widget.dashboardViewModel.appStore.amountParsingProxy.getCryptoSymbol(
214
+ widget.lightningMode ? CryptoCurrency.btcln : widget.dashboardViewModel.wallet.currency);
215
216
bool _shouldCapitalizeAssetName() {
214
- if(widget.dashboardViewModel.wallet.type != WalletType.bitcoin) {
217
+ if (widget.dashboardViewModel.wallet.type != WalletType.bitcoin) {
218
return true;
219
}
220
@@ -227,7 +230,8 @@ class _CardsViewState extends State<CardsView> {
230
}
231
}
232
230
- double get effectiveCardWidth => min(MediaQuery.of(context).size.width * 0.878, responsiveLayoutUtil.shouldRenderMobileUI ? 768 : 512);
233
+ double get effectiveCardWidth => min(MediaQuery.of(context).size.width * 0.878,
234
+ responsiveLayoutUtil.shouldRenderMobileUI ? 768 : 512);
235
236
double _getBoxHeight(int numCards, double overlapAmount) {
237
return
@@ -243,10 +247,10 @@ class _CardsViewState extends State<CardsView> {
247
final parentWidth = MediaQuery.of(context).size.width;
248
final children = <Widget>[];
249
246
- int numCards = widget.dashboardViewModel.wallet.type == WalletType.bitcoin
247
- ? 1
248
- : widget.dashboardViewModel.cardDesigns.length;
249
- if(numCards == 0) numCards = 1;
250
+ int numCards = widget.dashboardViewModel.wallet.type == WalletType.bitcoin
251
+ ? 1
252
+ : widget.dashboardViewModel.cardDesigns.length;
253
+ if (numCards == 0) numCards = 1;
254
255
if (_selectedIndex >= (numCards)) {
256
_selectedIndex = 0;
@@ -267,7 +271,6 @@ class _CardsViewState extends State<CardsView> {
271
}
272
}
273
270
-
274
final bool compactMode = numCards >= compactModeTreshold;
275
final double overlapAmount = compactMode ? 5.0 : 46.0;
276
for (int i = min(numCards - 1, maxCards); i >= 0; i--) {
@@ -280,8 +283,7 @@ class _CardsViewState extends State<CardsView> {
283
realIndex < widget.accountListViewModel!.accounts.length &&
284
widget.accountListViewModel?.selected.label !=
285
widget.accountListViewModel?.accounts[realIndex].label) {
283
- widget.accountListViewModel!
284
- .select(widget.accountListViewModel!.accounts[realIndex]);
286
+ widget.accountListViewModel!.select(widget.accountListViewModel!.accounts[realIndex]);
287
}
288
289
children.add(_buildCard(
@@ -326,15 +328,17 @@ class _CardsViewState extends State<CardsView> {
328
unspentCoinType: UnspentCoinType.nonMweb,
329
mode: SendPageModes.lightningDeposit,
330
));
329
- showCupertinoModalBottomSheet(context: context, barrierColor: Colors.black.withAlpha(128), builder: (context){
330
- return Padding(
331
- padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
332
- child: SizedBox(
333
- height:MediaQuery.of(context).size.height*0.6,
334
- child:ModalNavigator(parentContext:context,rootPage: Material(child: page))
335
- ),
336
- );
337
- });
331
+ showCupertinoModalBottomSheet(
332
+ context: context,
333
+ barrierColor: Colors.black.withAlpha(128),
334
+ builder: (context) {
335
+ return Padding(
336
+ padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
337
+ child: SizedBox(
338
+ height: MediaQuery.of(context).size.height * 0.6,
339
+ child: ModalNavigator(parentContext: context, rootPage: Material(child: page))),
340
+ );
341
+ });
342
} else {
343
Navigator.pushNamed(
344
context,
@@ -371,15 +375,17 @@ class _CardsViewState extends State<CardsView> {
375
unspentCoinType: unspentCoinType,
376
mode: SendPageModes.lightningWithdrawal,
377
));
374
- showCupertinoModalBottomSheet(context: context, barrierColor: Colors.black.withAlpha(128), builder: (context){
375
- return Padding(
376
- padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
377
- child: SizedBox(
378
-height:MediaQuery.of(context).size.height*0.6,
379
- child:ModalNavigator(parentContext:context,rootPage: Material(child: page))
380
- ),
381
- );
382
- });
378
+ showCupertinoModalBottomSheet(
379
+ context: context,
380
+ barrierColor: Colors.black.withAlpha(128),
381
+ builder: (context) {
382
+ return Padding(
383
+ padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
384
+ child: SizedBox(
385
+ height: MediaQuery.of(context).size.height * 0.6,
386
+ child: ModalNavigator(parentContext: context, rootPage: Material(child: page))),
387
+ );
388
+ });
389
} else {
390
Navigator.pushNamed(
391
context,
lib/new-ui/widgets/coins_page/mweb_ad.dart
+2
-2
@@ -33,8 +33,8 @@ class MwebAd extends StatelessWidget {
33
child: Row(
34
mainAxisAlignment: MainAxisAlignment.spaceBetween,
35
children: [
36
- CakeImageWidget(imageUrl:
37
- "assets/new-ui/settings_row_icons/mweb.svg",
36
+ CakeImageWidget(
37
+ imageUrl: "assets/new-ui/settings_row_icons/mweb.svg",
38
width: 24,
39
height: 24,
40
),
lib/new-ui/widgets/coins_page/top_bar_widget/chain_icon.dart
+3
-3
@@ -7,9 +7,9 @@ import 'package:flutter_svg/svg.dart';
7
class ChainIcon extends StatelessWidget {
8
const ChainIcon(
9
{super.key,
10
- required this.iconPath,
11
- required this.dashboardViewModel,
12
- required this.isSyncHeavy});
10
+ required this.iconPath,
11
+ required this.dashboardViewModel,
12
+ required this.isSyncHeavy});
13
14
final String iconPath;
15
final bool isSyncHeavy;
lib/new-ui/widgets/coins_page/top_bar_widget/lightning_switcher.dart
+5
-3
@@ -48,7 +48,8 @@ class LightningSwitcher extends StatelessWidget {
48
duration: Duration(milliseconds: 150),
49
transitionBuilder: (child, animation) =>
50
FadeTransition(opacity: animation, child: child),
51
- child: CakeImageWidget(imageUrl:'assets/new-ui/switcher-bitcoin.svg',
51
+ child: CakeImageWidget(
52
+ imageUrl: 'assets/new-ui/switcher-bitcoin.svg',
53
key: ValueKey(lightningMode),
54
width: 32,
55
height: 32,
@@ -64,7 +65,8 @@ class LightningSwitcher extends StatelessWidget {
65
duration: Duration(milliseconds: 150),
66
transitionBuilder: (child, animation) =>
67
FadeTransition(opacity: animation, child: child),
67
- child: CakeImageWidget(imageUrl: 'assets/new-ui/switcher-lightning.svg',
68
+ child: CakeImageWidget(
69
+ imageUrl: 'assets/new-ui/switcher-lightning.svg',
70
key: ValueKey(lightningMode),
71
width: 32,
72
height: 32,
@@ -85,4 +87,4 @@ class LightningSwitcher extends StatelessWidget {
87
),
88
);
89
}
88
-}
\ No newline at end of file
90
+}
lib/new-ui/widgets/coins_page/top_bar_widget/pulsing_dot.dart
+6
-6
@@ -1,8 +1,9 @@
1
import 'package:flutter/material.dart';
2
3
class PulsingDot extends StatefulWidget {
4
- const PulsingDot({super.key,});
5
-
4
+ const PulsingDot({
5
+ super.key,
6
+ });
7
8
final double size = 5;
9
final Color color = const Color(0xFFFFC414);
@@ -14,8 +15,7 @@ class PulsingDot extends StatefulWidget {
15
State<PulsingDot> createState() => _PulsingDotState();
16
}
17
17
-class _PulsingDotState extends State<PulsingDot>
18
- with SingleTickerProviderStateMixin {
18
+class _PulsingDotState extends State<PulsingDot> with SingleTickerProviderStateMixin {
19
late final AnimationController controller;
20
21
@override
@@ -38,7 +38,7 @@ class _PulsingDotState extends State<PulsingDot>
38
duration: widget.fadeOutDuration,
39
);
40
await Future.delayed(widget.restDuration);
41
- if(!mounted) return;
41
+ if (!mounted) return;
42
controller.value = 1.0;
43
}
44
}
@@ -63,4 +63,4 @@ class _PulsingDotState extends State<PulsingDot>
63
),
64
);
65
}
66
-}
\ No newline at end of file
66
+}
lib/new-ui/widgets/coins_page/top_bar_widget/sync_bar.dart
+13
-12
@@ -68,7 +68,7 @@ class SyncBar extends StatelessWidget {
68
context: context,
69
barrierColor: Colors.black.withAlpha(85),
70
builder: (context) => FractionallySizedBox(
71
- child: Material(
71
+ child: Material(
72
child: getIt.get<ManageNodesPage>(param1: false),
73
)));
74
},
@@ -147,15 +147,15 @@ class SyncBar extends StatelessWidget {
147
148
Widget? _getIcon(BuildContext context, Type status) {
149
if (status == LostConnectionSyncStatus || status == FailedSyncStatus) {
150
- return CakeImageWidget(imageUrl:
151
- "assets/new-ui/offline.svg",
150
+ return CakeImageWidget(
151
+ imageUrl: "assets/new-ui/offline.svg",
152
colorFilter: ColorFilter.mode(Theme.of(context).colorScheme.error, BlendMode.srcIn),
153
);
154
}
155
156
if (failStatuses.contains(status)) {
157
- return CakeImageWidget(imageUrl:
158
- "assets/new-ui/warning.svg",
157
+ return CakeImageWidget(
158
+ imageUrl: "assets/new-ui/warning.svg",
159
colorFilter: ColorFilter.mode(Theme.of(context).colorScheme.error, BlendMode.srcIn),
160
);
161
}
@@ -163,19 +163,20 @@ class SyncBar extends StatelessWidget {
163
final List<Widget> children = [];
164
165
if (dashboardViewModel.isTorEnabled) {
166
- children.add(CakeImageWidget(imageUrl:"assets/new-ui/tor_sync.svg",
166
+ children.add(CakeImageWidget(
167
+ imageUrl: "assets/new-ui/tor_sync.svg",
168
colorFilter: ColorFilter.mode(Color(0xFF8A38F5), BlendMode.srcIn)));
169
}
170
if (dashboardViewModel.hasMweb) {
170
- children.add(CakeImageWidget(imageUrl:
171
- "assets/new-ui/mweb_sync.svg",
171
+ children.add(CakeImageWidget(
172
+ imageUrl: "assets/new-ui/mweb_sync.svg",
173
colorFilter:
173
- ColorFilter.mode(Theme.of(context).colorScheme.onSurfaceVariant, BlendMode.srcIn),
174
+ ColorFilter.mode(Theme.of(context).colorScheme.onSurfaceVariant, BlendMode.srcIn),
175
));
176
}
177
if (dashboardViewModel.hasSilentPayments) {
177
- children.add(CakeImageWidget(imageUrl:
178
- "assets/new-ui/silent_sync.svg",
178
+ children.add(CakeImageWidget(
179
+ imageUrl: "assets/new-ui/silent_sync.svg",
180
colorFilter: ColorFilter.mode(Color(0xFFEFBA5E), BlendMode.srcIn),
181
));
182
}
@@ -194,4 +195,4 @@ class SyncBar extends StatelessWidget {
195
bool _showDot() {
196
return !isSyncHeavy && progressStatuses.contains(dashboardViewModel.status.runtimeType);
197
}
197
-}
\ No newline at end of file
198
+}
lib/new-ui/widgets/coins_page/top_bar_widget/top_bar.dart
+3
-3
@@ -26,7 +26,8 @@ class TopBar extends StatelessWidget {
26
@override
27
Widget build(BuildContext context) {
28
return Padding(
29
- padding: EdgeInsets.only(bottom: 10, left: 18, right:18, top: 10+_additionalTopPadding(context)),
29
+ padding: EdgeInsets.only(
30
+ bottom: 10, left: 18, right: 18, top: 10 + _additionalTopPadding(context)),
31
child: Observer(
32
builder: (_) => Row(
33
spacing: 12,
@@ -59,10 +60,9 @@ class TopBar extends StatelessWidget {
60
);
61
}
62
62
-
63
//FIXME remove after this gets fixed flutter-side
64
double _additionalTopPadding(BuildContext context) {
65
- if(Platform.isIOS && MediaQuery.of(context).viewPadding.top < 12) return 24;
65
+ if (Platform.isIOS && MediaQuery.of(context).viewPadding.top < 12) return 24;
66
67
return 0;
68
}
lib/new-ui/widgets/coins_page/unconfirmed_balance_widget.dart
+63
-64
@@ -23,83 +23,82 @@ class UnconfirmedBalanceWidget extends StatelessWidget {
23
.hasAdditionalBalance(dashboardViewModel.wallet.currency);
24
25
return AnimatedSize(
26
- duration: const Duration(milliseconds: 300),
27
- curve: Curves.easeOutCubic,
28
- alignment: Alignment.topCenter,
29
- child: show
30
- ? Column(
31
- children: [
32
- const SizedBox(height: 12, width: double.infinity),
33
- Observer(
34
- builder: (context) {
35
- final balance = dashboardViewModel.balanceViewModel.additionalBalance(currency);
26
+ duration: const Duration(milliseconds: 300),
27
+ curve: Curves.easeOutCubic,
28
+ alignment: Alignment.topCenter,
29
+ child: show
30
+ ? Column(
31
+ children: [
32
+ const SizedBox(height: 12, width: double.infinity),
33
+ Observer(builder: (context) {
34
+ final balance = dashboardViewModel.balanceViewModel.additionalBalance(currency);
35
37
- return Container(
38
- width: MediaQuery.of(context).size.width * 0.87,
39
- height: 48,
40
- decoration: BoxDecoration(
41
- color: Theme.of(context).colorScheme.surfaceContainer,
42
- borderRadius: BorderRadius.circular(16.0),
43
- ),
44
- child: Material(
45
- color: Colors.transparent,
46
- child: InkWell(
47
- onTap: () {
48
- showMaterialModalBottomSheet(
49
- backgroundColor: Colors.transparent,
50
- context: context,
51
- builder: (context) => UnconfirmedBalanceModal(
52
- balance: balance.toStringWithSymbol(),
53
- currencyIconPath: currency.iconPath ?? "",
54
- ));
55
- },
56
- child: Padding(
57
- padding: const EdgeInsets.symmetric(horizontal: 12.0),
58
- child: Row(
59
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
36
+ return Container(
37
+ width: MediaQuery.of(context).size.width * 0.87,
38
+ height: 48,
39
+ decoration: BoxDecoration(
40
+ color: Theme.of(context).colorScheme.surfaceContainer,
41
+ borderRadius: BorderRadius.circular(16.0),
42
+ ),
43
+ child: Material(
44
+ color: Colors.transparent,
45
+ child: InkWell(
46
+ onTap: () {
47
+ showMaterialModalBottomSheet(
48
+ backgroundColor: Colors.transparent,
49
+ context: context,
50
+ builder: (context) => UnconfirmedBalanceModal(
51
+ balance: balance.toStringWithSymbol(),
52
+ currencyIconPath: currency.iconPath ?? "",
53
+ ));
54
+ },
55
+ child: Padding(
56
+ padding: const EdgeInsets.symmetric(horizontal: 12.0),
57
+ child: Row(
58
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
59
+ children: [
60
+ Row(
61
+ spacing: 12,
62
children: [
63
+ SizedBox(
64
+ height: 20,
65
+ width: 20,
66
+ child: CircularProgressIndicator(
67
+ strokeWidth: 2,
68
+ backgroundColor:
69
+ Theme.of(context).colorScheme.primary.withAlpha(50),
70
+ color: Theme.of(context).colorScheme.primary,
71
+ value: dashboardViewModel.confirmationProgress,
72
+ ),
73
+ ),
74
Row(
62
- spacing: 12,
75
+ spacing: 4,
76
children: [
64
- SizedBox(
65
- height: 20,
66
- width: 20,
67
- child: CircularProgressIndicator(
68
- strokeWidth: 2,
69
- backgroundColor: Theme.of(context).colorScheme.primary.withAlpha(50),
77
+ Text(
78
+ "$balance ${currency.title}",
79
+ style: TextStyle(
80
color: Theme.of(context).colorScheme.primary,
71
- value: dashboardViewModel.confirmationProgress,
81
),
82
),
74
- Row(
75
- spacing: 4,
76
- children: [
77
- Text(
78
- "$balance ${currency.title}",
79
- style: TextStyle(
80
- color: Theme.of(context).colorScheme.primary,
81
- ),
82
- ),
83
- Text(S.of(context).confirming),
84
- ],
85
- )
83
+ Text(S.of(context).confirming),
84
],
87
- ),
88
- Icon(
89
- Icons.chevron_right,
90
- color: Theme.of(context).colorScheme.onSurfaceVariant,
85
)
86
],
87
),
94
- ),
88
+ Icon(
89
+ Icons.chevron_right,
90
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
91
+ )
92
+ ],
93
),
94
),
97
- );
98
- }
99
- ),
100
- ],
101
- )
102
- : const SizedBox(width: double.infinity),
95
+ ),
96
+ ),
97
+ );
98
+ }),
99
+ ],
100
+ )
101
+ : const SizedBox(width: double.infinity),
102
);
103
});
104
}
lib/new-ui/widgets/coins_page/wallet_info.dart
+8
-6
@@ -11,7 +11,8 @@ class WalletInfoBar extends StatelessWidget {
11
required this.lightningMode,
12
required this.name,
13
required this.hardwareWalletType,
14
- required this.onCustomizeButtonTap, required this.hasCustomize});
14
+ required this.onCustomizeButtonTap,
15
+ required this.hasCustomize});
16
17
final bool lightningMode;
18
final String name;
@@ -31,7 +32,6 @@ class WalletInfoBar extends StatelessWidget {
32
child: Row(
33
mainAxisSize: MainAxisSize.min,
34
mainAxisAlignment: MainAxisAlignment.center,
34
-
35
children: [
36
AnimatedSwitcher(
37
duration: Duration(milliseconds: 150),
@@ -46,8 +46,8 @@ class WalletInfoBar extends StatelessWidget {
46
? const SizedBox.shrink(key: ValueKey("empty"))
47
: Padding(
48
padding: const EdgeInsets.only(right: 8),
49
- child: CakeImageWidget(imageUrl:
50
- hardwareWalletIcon!,
49
+ child: CakeImageWidget(
50
+ imageUrl: hardwareWalletIcon!,
51
key: ValueKey("hardware_wallet_icon"),
52
width: 24,
53
height: 24,
@@ -60,8 +60,10 @@ class WalletInfoBar extends StatelessWidget {
60
),
61
Text(
62
name,
63
- style: Theme.of(context).textTheme.titleLarge?.copyWith(
64
- color: Theme.of(context).colorScheme.onSurface),
63
+ style: Theme.of(context)
64
+ .textTheme
65
+ .titleLarge
66
+ ?.copyWith(color: Theme.of(context).colorScheme.onSurface),
67
),
68
if (hasCustomize) ...[
69
SizedBox(width: 8),
lib/new-ui/widgets/confirm_swiper.dart
+8
-8
@@ -44,8 +44,7 @@ class _ConfirmSwiperState extends State<ConfirmSwiper> {
44
return GestureDetector(
45
onHorizontalDragUpdate: (d) {
46
setState(() {
47
- drag = max(pillHorizontalPadding,
48
- min(maxDrag, drag + d.delta.dx));
47
+ drag = max(pillHorizontalPadding, min(maxDrag, drag + d.delta.dx));
48
});
49
},
50
onHorizontalDragEnd: (_) {
@@ -69,9 +68,7 @@ class _ConfirmSwiperState extends State<ConfirmSwiper> {
68
height: pillSize + pillHorizontalPadding * 2,
69
width: areaWidth,
70
decoration: BoxDecoration(
72
- color: Theme.of(context)
73
- .colorScheme
74
- .surfaceContainerLowest,
71
+ color: Theme.of(context).colorScheme.surfaceContainerLowest,
72
borderRadius: BorderRadius.circular(99999),
73
),
74
child: Center(
@@ -116,8 +113,7 @@ class TrackClipper extends CustomClipper<Path> {
113
Path getClip(Size size) {
114
final left = cut.clamp(0.0, size.width);
115
final rect = Rect.fromLTRB(left, 0, size.width, size.height);
119
- return Path()
120
- ..addRRect(RRect.fromRectAndRadius(rect, Radius.circular(radius)));
116
+ return Path()..addRRect(RRect.fromRectAndRadius(rect, Radius.circular(radius)));
117
}
118
119
@override
@@ -168,7 +164,11 @@ class _FlowingTextState extends State<FlowingText> with SingleTickerProviderStat
164
return LinearGradient(
165
begin: Alignment(-1 + (controller.value) * 2, 0),
166
end: Alignment(controller.value * 2, 0),
171
- colors: [Colors.transparent, Theme.of(context).colorScheme.surfaceContainerHighest, Colors.transparent],
167
+ colors: [
168
+ Colors.transparent,
169
+ Theme.of(context).colorScheme.surfaceContainerHighest,
170
+ Colors.transparent
171
+ ],
172
).createShader(r);
173
},
174
blendMode: BlendMode.srcATop,
lib/new-ui/widgets/copy_wrapper.dart
+1
-1
@@ -9,7 +9,7 @@ class CopyWrapper extends StatefulWidget {
9
const CopyWrapper(
10
{super.key,
11
this.data,
12
- this.requireLongPress = false,
12
+ this.requireLongPress = false,
13
this.isSensitive = false,
14
required this.builder,
15
this.duration = const Duration(milliseconds: 1200)});
lib/new-ui/widgets/currency_picker/currency_picker_args.dart
+4
-4
@@ -16,8 +16,9 @@ final Set<String> _stablecoinSymbols = {
16
};
17
18
bool isTrustedStablecoin(CryptoCurrency c) =>
19
- (c.groups.contains(CurrencyGroups.stablecoin) ||
20
- _stablecoinSymbols.contains(c.title.toUpperCase())) && !c.isPotentialScam;
19
+ (c.groups.contains(CurrencyGroups.stablecoin) ||
20
+ _stablecoinSymbols.contains(c.title.toUpperCase())) &&
21
+ !c.isPotentialScam;
22
23
const _kEvmDefaultTokenNatives = <CryptoCurrency>[
24
CryptoCurrency.baseEth,
@@ -44,8 +45,7 @@ void appendEvmDefaultTokens(List<CryptoCurrency> into) {
45
}
46
47
class CurrencyPickerBalance {
47
- const CurrencyPickerBalance(
48
- {required this.amount, this.fiat, this.fiatValue});
48
+ const CurrencyPickerBalance({required this.amount, this.fiat, this.fiatValue});
49
50
final String amount;
51
final String? fiat;
lib/new-ui/widgets/currency_picker/picker_recents_loader.dart
+1
-3
@@ -39,9 +39,7 @@ class PickerRecentsLoader {
39
int limit,
40
) async {
41
final trades = await Trade.getAll();
42
- final ordered = trades
43
- .where((t) => _executedTradeStates.contains(t.state))
44
- .toList()
42
+ final ordered = trades.where((t) => _executedTradeStates.contains(t.state)).toList()
43
..sort((a, b) => (b.createdAt ?? DateTime.fromMillisecondsSinceEpoch(0))
44
.compareTo(a.createdAt ?? DateTime.fromMillisecondsSinceEpoch(0)));
45
lib/new-ui/widgets/currency_picker/single_network_currency_picker.dart
+2
-4
@@ -47,10 +47,8 @@ class _SingleNetworkCurrencyPickerState extends State<SingleNetworkCurrencyPicke
47
Widget build(BuildContext context) {
48
final native = walletTypeToCryptoCurrency(_network);
49
final query = _searchController.text.trim();
50
- final tokens = _args.items
51
- .where((c) => c != native)
52
- .where((c) => currencyMatchesQuery(c, query))
53
- .toList();
50
+ final tokens =
51
+ _args.items.where((c) => c != native).where((c) => currencyMatchesQuery(c, query)).toList();
52
53
final insertOrder = {for (var i = 0; i < tokens.length; i++) tokens[i]: i};
54
tokens.sort((a, b) {
lib/new-ui/widgets/dropdown_row.dart
+1
-2
@@ -38,8 +38,7 @@ class DropdownRow extends StatelessWidget {
38
turns: expanded ? 0.0 : 0.5,
39
curve: Curves.easeOut,
40
child: CakeImageWidget(
41
- imageUrl:
42
- "assets/new-ui/dropdown_arrow.svg",
41
+ imageUrl: "assets/new-ui/dropdown_arrow.svg",
42
colorFilter:
43
ColorFilter.mode(Theme.of(context).colorScheme.primary, BlendMode.srcIn),
44
))
lib/new-ui/widgets/keyboard_hide_overlay.dart
+1
-2
@@ -75,8 +75,7 @@ class _KeyboardHideButtonState extends State<KeyboardHideButton> {
75
child: Padding(
76
padding: const EdgeInsets.all(8.0),
77
child: CakeImageWidget(
78
- imageUrl:
79
- "assets/new-ui/hide_keyboard.svg",
78
+ imageUrl: "assets/new-ui/hide_keyboard.svg",
79
colorFilter: ColorFilter.mode(
80
Theme.of(context).colorScheme.onPrimary, BlendMode.srcIn),
81
),
lib/new-ui/widgets/line_tab_switcher.dart
+37
-43
@@ -64,15 +64,13 @@ class _LineTabSwitcherState extends State<LineTabSwitcher> {
64
}
65
66
void measure() {
67
- if(textWidgetsMeasured) return;
67
+ if (textWidgetsMeasured) return;
68
setState(() {
69
- textWidgetSizes = textWidgetKeys
70
- .map((k) => k.currentContext!.size)
71
- .whereType<Size>()
72
- .toList();
69
+ textWidgetSizes =
70
+ textWidgetKeys.map((k) => k.currentContext!.size).whereType<Size>().toList();
71
74
- for(final size in textWidgetSizes) {
75
- totalWidth += size.width+itemPadding;
72
+ for (final size in textWidgetSizes) {
73
+ totalWidth += size.width + itemPadding;
74
}
75
totalWidth += barPadding;
76
textWidgetsMeasured = true;
@@ -90,10 +88,9 @@ class _LineTabSwitcherState extends State<LineTabSwitcher> {
88
mainAxisAlignment: MainAxisAlignment.start,
89
children: [
90
Container(
93
- height: 28,
94
- child: Row(
95
- children: widget.tabs.map((item){
96
-
91
+ height: 28,
92
+ child: Row(
93
+ children: widget.tabs.map((item) {
94
final index = widget.tabs.indexOf(item);
95
96
return GestureDetector(
@@ -107,15 +104,15 @@ class _LineTabSwitcherState extends State<LineTabSwitcher> {
104
AnimatedDefaultTextStyle(
105
duration: Duration(milliseconds: 150),
106
style: DefaultTextStyle.of(context).style.copyWith(
110
- inherit: true,
111
- fontSize: 16,
112
- fontWeight: FontWeight.w500,
113
- color: widget.selectedTab == index
114
- ? Theme.of(context).colorScheme.onSurface
115
- : Theme.of(context).colorScheme.onSurfaceVariant,
116
- ),
107
+ inherit: true,
108
+ fontSize: 16,
109
+ fontWeight: FontWeight.w500,
110
+ color: widget.selectedTab == index
111
+ ? Theme.of(context).colorScheme.onSurface
112
+ : Theme.of(context).colorScheme.onSurfaceVariant,
113
+ ),
114
child: Padding(
118
- padding: EdgeInsets.symmetric(horizontal: itemPadding/2),
115
+ padding: EdgeInsets.symmetric(horizontal: itemPadding / 2),
116
child: Text(
117
item,
118
key: textWidgetKeys[index],
@@ -125,34 +122,31 @@ class _LineTabSwitcherState extends State<LineTabSwitcher> {
122
],
123
),
124
);
128
- }).toList()
129
- )
130
- ),
131
- if(widget.tabs.length > 1)
132
- Container(
133
- width: totalWidth,
134
- height: 2,
135
- child: Stack(
136
- children: [
137
- AnimatedPositioned(
138
- curve: Curves.easeOut,
139
- left: _calcBarLeft(),
140
- bottom: 0,
141
- duration: Duration(milliseconds: 150),
142
- child: AnimatedSize(
125
+ }).toList())),
126
+ if (widget.tabs.length > 1)
127
+ Container(
128
+ width: totalWidth,
129
+ height: 2,
130
+ child: Stack(
131
+ children: [
132
+ AnimatedPositioned(
133
+ curve: Curves.easeOut,
134
+ left: _calcBarLeft(),
135
+ bottom: 0,
136
duration: Duration(milliseconds: 150),
144
- child: Container(
145
- height: 2,
146
- width: textWidgetSizes.isEmpty
147
- ? 0
148
- : textWidgetSizes[widget.selectedTab].width,
149
- color: Theme.of(context).colorScheme.onSurface,
137
+ child: AnimatedSize(
138
+ duration: Duration(milliseconds: 150),
139
+ child: Container(
140
+ height: 2,
141
+ width:
142
+ textWidgetSizes.isEmpty ? 0 : textWidgetSizes[widget.selectedTab].width,
143
+ color: Theme.of(context).colorScheme.onSurface,
144
+ ),
145
),
146
),
152
- ),
153
- ],
147
+ ],
148
+ ),
149
),
155
- ),
150
],
151
);
152
}
lib/new-ui/widgets/long_press_menu.dart
+1
-2
@@ -76,8 +76,7 @@ class _LongPressMenuState extends State<LongPressMenu> {
76
spacing: 8,
77
children: [
78
CakeImageWidget(
79
- imageUrl:
80
- item.iconPath,
79
+ imageUrl: item.iconPath,
80
height: 20,
81
width: 20,
82
colorFilter: ColorFilter.mode(color, BlendMode.srcIn),
lib/new-ui/widgets/modal_header.dart
+7
-5
@@ -3,7 +3,11 @@ import 'package:flutter/material.dart';
3
4
class ModalHeader extends StatelessWidget {
5
const ModalHeader(
6
- {super.key, required this.iconPath, required this.message, required this.title, this.bottomWidget});
6
+ {super.key,
7
+ required this.iconPath,
8
+ required this.message,
9
+ required this.title,
10
+ this.bottomWidget});
11
12
final String iconPath;
13
final String title;
@@ -25,8 +29,7 @@ class ModalHeader extends StatelessWidget {
29
mainAxisAlignment: MainAxisAlignment.center,
30
crossAxisAlignment: CrossAxisAlignment.center,
31
children: [
28
- CakeImageWidget(
29
- imageUrl: iconPath, width: 36, height: 36),
32
+ CakeImageWidget(imageUrl: iconPath, width: 36, height: 36),
33
Text(
34
title,
35
style: TextStyle(
@@ -44,7 +47,6 @@ class ModalHeader extends StatelessWidget {
47
color: Theme.of(context).colorScheme.onSurfaceVariant),
48
textAlign: TextAlign.center,
49
)),
47
-
50
],
51
),
52
),
@@ -62,4 +64,4 @@ class ModalHeader extends StatelessWidget {
64
),
65
);
66
}
65
-}
\ No newline at end of file
67
+}
lib/new-ui/widgets/modal_page_wrapper.dart
+7
-9
@@ -3,18 +3,17 @@ import 'package:cake_wallet/new-ui/widgets/receive_page/receive_top_bar.dart';
3
import 'package:flutter/material.dart';
4
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
5
6
-void nothing(){}
6
+void nothing() {}
7
8
class ModalPageWrapper extends StatelessWidget {
9
ModalPageWrapper(
10
{super.key,
11
required this.content,
12
required this.topBar,
13
- this.header,
14
- this.bottomContent,
13
+ this.header,
14
+ this.bottomContent,
15
this.horizontalPadding = 18.0,
16
- this.verticalPadding = 72.0}) {
17
- }
16
+ this.verticalPadding = 72.0}) {}
17
18
final Widget content;
19
final Widget? bottomContent;
@@ -35,8 +34,8 @@ class ModalPageWrapper extends StatelessWidget {
34
alignment: Alignment.topCenter,
35
children: [
36
Positioned.fill(
38
- child: Padding(
39
- padding: EdgeInsets.symmetric(horizontal: horizontalPadding),
37
+ child: Padding(
38
+ padding: EdgeInsets.symmetric(horizontal: horizontalPadding),
39
child: CustomScrollView(
40
controller: ModalScrollController.of(context),
41
physics: ClampingScrollPhysics(),
@@ -49,8 +48,7 @@ class ModalPageWrapper extends StatelessWidget {
48
SliverSafeArea(sliver: SliverToBoxAdapter(child: content)),
49
SliverToBoxAdapter(child: SizedBox(height: verticalPadding)),
50
],
52
- )
53
- )),
51
+ ))),
52
if (bottomContent != null)
53
Positioned(
54
bottom: 12,
lib/new-ui/widgets/modern_button.dart
+1
-1
@@ -83,4 +83,4 @@ class ModernButton extends StatelessWidget {
83
],
84
);
85
}
86
-}
\ No newline at end of file
86
+}
lib/new-ui/widgets/new_primary_button.dart
+17
-16
@@ -26,7 +26,6 @@ class NewPrimaryButton extends StatelessWidget {
26
27
@override
28
Widget build(BuildContext context) {
29
-
29
return SizedBox(
30
height: 52.0,
31
child: TextButton(
@@ -42,23 +41,25 @@ class NewPrimaryButton extends StatelessWidget {
41
),
42
),
43
child: Center(
45
- child: isLoading ? CupertinoActivityIndicator() : Row(
46
- spacing: 10,
47
- mainAxisSize: MainAxisSize.min,
48
- children: <Widget>[
49
- if(image != null) image!,
50
- Text(
51
- text,
52
- style: Theme.of(context).textTheme.bodyMedium?.copyWith(
53
- fontSize: 14,
54
- fontWeight: FontWeight.w600,
55
- color: textColor,
44
+ child: isLoading
45
+ ? CupertinoActivityIndicator()
46
+ : Row(
47
+ spacing: 10,
48
+ mainAxisSize: MainAxisSize.min,
49
+ children: <Widget>[
50
+ if (image != null) image!,
51
+ Text(
52
+ text,
53
+ style: Theme.of(context).textTheme.bodyMedium?.copyWith(
54
+ fontSize: 14,
55
+ fontWeight: FontWeight.w600,
56
+ color: textColor,
57
+ ),
58
+ )
59
+ ],
60
),
57
- )
58
- ],
59
- ),
61
),
62
),
63
);
64
}
64
-}
\ No newline at end of file
65
+}
lib/new-ui/widgets/picker.dart
+95
-52
@@ -67,7 +67,7 @@ class _NewPickerState<Item> extends State<NewPicker<Item>> {
67
@override
68
Widget build(BuildContext context) {
69
return Observer(
70
- builder: (_)=>Container(
70
+ builder: (_) => Container(
71
decoration: BoxDecoration(
72
color: Theme.of(context).colorScheme.surface,
73
borderRadius: BorderRadius.vertical(top: Radius.circular(24))),
@@ -86,11 +86,18 @@ class _NewPickerState<Item> extends State<NewPicker<Item>> {
86
mainAxisSize: MainAxisSize.min,
87
children: [
88
if (widget.description != null && widget.description!.isNotEmpty)
89
- Text(widget.description!,textAlign: TextAlign.center,style: TextStyle(fontSize:14,fontWeight: FontWeight.w400,color: Theme.of(context).colorScheme.onSurfaceVariant),),
90
- SizedBox(height:16),
89
+ Text(
90
+ widget.description!,
91
+ textAlign: TextAlign.center,
92
+ style: TextStyle(
93
+ fontSize: 14,
94
+ fontWeight: FontWeight.w400,
95
+ color: Theme.of(context).colorScheme.onSurfaceVariant),
96
+ ),
97
+ SizedBox(height: 16),
98
...widget.items.map((item) {
99
final isSelected = widget.items.indexOf(item) == widget.selectedIndex;
93
- return Column( children: [
100
+ return Column(children: [
101
if (item.isSliderItem)
102
PickerSliderButton(
103
key: ValueKey(isSelected),
@@ -99,22 +106,23 @@ class _NewPickerState<Item> extends State<NewPicker<Item>> {
106
onSelected: (item) {
107
Navigator.of(context).push(MaterialPageRoute(
108
builder: (context) => Material(
102
- child: PickerSliderPage(
103
- title: widget.sliderPageTitle,
104
- sliderInitialValue: sliderCurrentValue!,
105
- valueDescription: widget.sliderValueDescription ?? "",
106
- sliderMaxValue: widget.sliderMaxValue!,
107
- onSubmitted: (value) {
108
- setState(() {
109
- sliderCurrentValue = value;
110
- });
111
- widget.onSliderChanged?.call(value);
112
- widget.onItemSelected(item);
113
- }),
114
- )));
109
+ child: PickerSliderPage(
110
+ title: widget.sliderPageTitle,
111
+ sliderInitialValue: sliderCurrentValue!,
112
+ valueDescription: widget.sliderValueDescription ?? "",
113
+ sliderMaxValue: widget.sliderMaxValue!,
114
+ onSubmitted: (value) {
115
+ setState(() {
116
+ sliderCurrentValue = value;
117
+ });
118
+ widget.onSliderChanged?.call(value);
119
+ widget.onItemSelected(item);
120
+ }),
121
+ )));
122
},
123
isFirst: widget.items.indexOf(item) == 0,
117
- customSubtitle: "${sliderCurrentValue?.toInt()} ${widget.sliderValueDescription}",
124
+ customSubtitle:
125
+ "${sliderCurrentValue?.toInt()} ${widget.sliderValueDescription}",
126
isLast: widget.items.indexOf(item) == widget.items.length - 1,
127
)
128
else
@@ -169,7 +177,8 @@ class PickerSliderButton<Item> extends StatelessWidget {
177
required this.isSelected,
178
required this.onSelected,
179
required this.isFirst,
172
- required this.isLast, this.customSubtitle});
180
+ required this.isLast,
181
+ this.customSubtitle});
182
183
final PickerItem<Item> item;
184
final bool isSelected;
@@ -186,7 +195,7 @@ class PickerSliderButton<Item> extends StatelessWidget {
195
},
196
child: Container(
197
height: 64,
189
- width: MediaQuery.of(context).size.height*0.9,
198
+ width: MediaQuery.of(context).size.height * 0.9,
199
decoration: BoxDecoration(
200
color: Theme.of(context).colorScheme.surfaceContainer,
201
borderRadius: BorderRadius.vertical(
@@ -217,24 +226,29 @@ class PickerSliderButton<Item> extends StatelessWidget {
226
fontSize: 14,
227
color: Theme.of(context).colorScheme.onSurfaceVariant,
228
fontWeight: FontWeight.w400)),
220
- if(isSelected) CakeImageWidget(imageUrl:
221
- "assets/new-ui/arrow_right.svg",
222
- colorFilter:
223
- ColorFilter.mode(Theme.of(context).colorScheme.primary, BlendMode.srcIn),)
229
+ if (isSelected)
230
+ CakeImageWidget(
231
+ imageUrl: "assets/new-ui/arrow_right.svg",
232
+ colorFilter: ColorFilter.mode(
233
+ Theme.of(context).colorScheme.primary, BlendMode.srcIn),
234
+ )
235
],
236
),
226
- if (customSubtitle != null || item.subtitle != null) Text(customSubtitle ?? item.subtitle!,style: TextStyle(
227
- fontSize: 12,
228
- color: Theme.of(context).colorScheme.onSurfaceVariant,
229
- fontWeight: FontWeight.w400))
237
+ if (customSubtitle != null || item.subtitle != null)
238
+ Text(customSubtitle ?? item.subtitle!,
239
+ style: TextStyle(
240
+ fontSize: 12,
241
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
242
+ fontWeight: FontWeight.w400))
243
],
244
),
232
- isSelected? NewSimpleCheckbox(value: true, onChanged: (val){}):
233
- CakeImageWidget(imageUrl:
234
- "assets/new-ui/arrow_right.svg",
235
- colorFilter:
236
- ColorFilter.mode(Theme.of(context).colorScheme.primary, BlendMode.srcIn),
237
- )
245
+ isSelected
246
+ ? NewSimpleCheckbox(value: true, onChanged: (val) {})
247
+ : CakeImageWidget(
248
+ imageUrl: "assets/new-ui/arrow_right.svg",
249
+ colorFilter:
250
+ ColorFilter.mode(Theme.of(context).colorScheme.primary, BlendMode.srcIn),
251
+ )
252
],
253
),
254
),
@@ -266,7 +280,7 @@ class PickerRow<Item> extends StatelessWidget {
280
},
281
child: Container(
282
height: 64,
269
- width: MediaQuery.of(context).size.height*0.9,
283
+ width: MediaQuery.of(context).size.height * 0.9,
284
decoration: BoxDecoration(
285
color: Theme.of(context).colorScheme.surfaceContainer,
286
borderRadius: BorderRadius.vertical(
@@ -299,19 +313,30 @@ class PickerRow<Item> extends StatelessWidget {
313
fontWeight: FontWeight.w400))
314
],
315
),
302
- item.subtitle != null ? Text(item.subtitle!,style: TextStyle(
303
- fontSize: 12,
304
- color: Theme.of(context).colorScheme.onSurfaceVariant,
305
- fontWeight: FontWeight.w400)) : SizedBox.shrink()
316
+ item.subtitle != null
317
+ ? Text(item.subtitle!,
318
+ style: TextStyle(
319
+ fontSize: 12,
320
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
321
+ fontWeight: FontWeight.w400))
322
+ : SizedBox.shrink()
323
],
324
),
325
AnimatedSwitcher(
309
- duration: Duration(milliseconds: 100),
310
-
326
+ duration: Duration(milliseconds: 100),
327
child: isSelected
312
- ? NewSimpleCheckbox(key: ValueKey(1), value: true, onChanged: (val){onSelected(item.value);})
313
- : NewSimpleCheckbox(key: ValueKey(0), value: false, onChanged: (val){onSelected(item.value);})
314
- )
328
+ ? NewSimpleCheckbox(
329
+ key: ValueKey(1),
330
+ value: true,
331
+ onChanged: (val) {
332
+ onSelected(item.value);
333
+ })
334
+ : NewSimpleCheckbox(
335
+ key: ValueKey(0),
336
+ value: false,
337
+ onChanged: (val) {
338
+ onSelected(item.value);
339
+ }))
340
],
341
),
342
),
@@ -369,10 +394,24 @@ class _PickerSliderPageState<Item> extends State<PickerSliderPage<Item>> {
394
mainAxisAlignment: MainAxisAlignment.center,
395
mainAxisSize: MainAxisSize.max,
396
children: [
372
- Row(mainAxisAlignment:MainAxisAlignment.center,spacing:4,children: [
373
- Text(sliderValue.toStringAsFixed(0), style: TextStyle(fontSize:18,fontWeight: FontWeight.w600,color: Theme.of(context).colorScheme.primary),),
374
- Text(widget.valueDescription, style: TextStyle(fontSize:18,fontWeight: FontWeight.w600,color: Theme.of(context).colorScheme.onSurface)),
375
- ],),
397
+ Row(
398
+ mainAxisAlignment: MainAxisAlignment.center,
399
+ spacing: 4,
400
+ children: [
401
+ Text(
402
+ sliderValue.toStringAsFixed(0),
403
+ style: TextStyle(
404
+ fontSize: 18,
405
+ fontWeight: FontWeight.w600,
406
+ color: Theme.of(context).colorScheme.primary),
407
+ ),
408
+ Text(widget.valueDescription,
409
+ style: TextStyle(
410
+ fontSize: 18,
411
+ fontWeight: FontWeight.w600,
412
+ color: Theme.of(context).colorScheme.onSurface)),
413
+ ],
414
+ ),
415
Padding(
416
padding: const EdgeInsets.symmetric(horizontal: 16.0),
417
child: Slider(
@@ -394,10 +433,14 @@ class _PickerSliderPageState<Item> extends State<PickerSliderPage<Item>> {
433
),
434
Padding(
435
padding: const EdgeInsets.all(16.0),
397
- child: NewPrimaryButton(onPressed: (){
398
- widget.onSubmitted(sliderValue);
399
- Navigator.of(context).pop();
400
- }, text: "Continue", color: Theme.of(context).colorScheme.primary, textColor: Theme.of(context).colorScheme.onPrimary),
436
+ child: NewPrimaryButton(
437
+ onPressed: () {
438
+ widget.onSubmitted(sliderValue);
439
+ Navigator.of(context).pop();
440
+ },
441
+ text: "Continue",
442
+ color: Theme.of(context).colorScheme.primary,
443
+ textColor: Theme.of(context).colorScheme.onPrimary),
444
)
445
],
446
),
lib/new-ui/widgets/receive_page/payjoin_copy_modal.dart
+1
-1
@@ -56,7 +56,7 @@ class PayjoinCopyModal extends StatelessWidget {
56
]
57
}),
58
),
59
- SizedBox(height:128)
59
+ SizedBox(height: 128)
60
],
61
),
62
),
lib/new-ui/widgets/receive_page/receive_address_type.dart
+2
-1
@@ -52,7 +52,8 @@ class ReceiveAddressTypeDisplay extends StatelessWidget {
52
spacing: 12.0,
53
children: [
54
if (iconPath != null)
55
- CakeImageWidget(imageUrl:iconPath,
55
+ CakeImageWidget(
56
+ imageUrl: iconPath,
57
width: 24,
58
height: 24,
59
colorFilter: ColorFilter.mode(
lib/new-ui/widgets/receive_page/receive_address_type_selector.dart
+9
-2
@@ -160,7 +160,8 @@ class _ReceiveAddressTypeSelectorState extends State<ReceiveAddressTypeSelector>
160
ReceiveAddressTypeSelector.otherOptionsExpandDuration,
161
turns: _otherOptionsExpanded ? 0.0 : 0.5,
162
curve: Curves.easeOut,
163
- child: CakeImageWidget(imageUrl:"assets/new-ui/dropdown_arrow.svg"))
163
+ child: CakeImageWidget(
164
+ imageUrl: "assets/new-ui/dropdown_arrow.svg"))
165
],
166
),
167
),
@@ -280,7 +281,13 @@ class ReceiveAddressTypeRow extends StatelessWidget {
281
Row(
282
children: [
283
if (iconPath != null)
283
- CakeImageWidget(imageUrl:iconPath!, width: iconSize, height: iconSize,colorFilter: ColorFilter.mode(Theme.of(context).colorScheme.onSurfaceVariant,BlendMode.srcIn),)
284
+ CakeImageWidget(
285
+ imageUrl: iconPath!,
286
+ width: iconSize,
287
+ height: iconSize,
288
+ colorFilter: ColorFilter.mode(
289
+ Theme.of(context).colorScheme.onSurfaceVariant, BlendMode.srcIn),
290
+ )
291
else
292
Container(width: iconSize, height: iconSize),
293
Padding(
lib/new-ui/widgets/receive_page/receive_amount_display.dart
+52
-56
@@ -3,7 +3,6 @@ import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_v
3
import 'package:flutter/material.dart';
4
import 'package:flutter_mobx/flutter_mobx.dart';
5
6
-
6
class ReceiveAmountDisplay extends StatelessWidget {
7
const ReceiveAmountDisplay(
8
{super.key, required this.walletAddressListViewModel, required this.largeQrMode});
@@ -11,69 +10,66 @@ class ReceiveAmountDisplay extends StatelessWidget {
10
final WalletAddressListViewModel walletAddressListViewModel;
11
final bool largeQrMode;
12
14
-
13
@override
14
Widget build(BuildContext context) {
15
return Observer(
18
- builder: (_) =>
19
- AnimatedOpacity(
20
- duration: Duration(milliseconds: 300),
21
- curve: Curves.easeOutCubic,
22
- opacity: largeQrMode || walletAddressListViewModel.displayAmount.isEmpty ? 0 : 1,
23
- child: AnimatedAlign(
24
- duration: Duration(milliseconds: 300),
25
- curve: Curves.easeOutCubic,
26
- heightFactor: largeQrMode || walletAddressListViewModel.displayAmount.isEmpty ? 0 : 1,
27
- alignment: Alignment.topCenter,
28
- child: Container(
29
- width: double.infinity,
30
- child: Row(
31
- spacing: 4,
32
- mainAxisSize: MainAxisSize.min,
33
- mainAxisAlignment: MainAxisAlignment.center,
34
- children: [
35
- Container(
36
- decoration: BoxDecoration(
37
- borderRadius: BorderRadius.circular(12),
38
- color: Theme
39
- .of(context)
40
- .colorScheme
41
- .surfaceContainer
42
- ),
43
- child:
44
- Padding(
45
- padding: const EdgeInsets.all(8.0),
46
- child: Row(
47
- spacing: 8.0,
48
- children: [
49
- Text(walletAddressListViewModel.displayAmount, style: TextStyle(color: Theme
50
- .of(context)
51
- .colorScheme
52
- .primary, fontSize: 16, fontWeight: FontWeight.w500),),
53
- Text(walletAddressListViewModel.cryptoCurrencySymbol,
54
- style: TextStyle(color: Theme
55
- .of(context)
56
- .colorScheme
57
- .primary, fontSize: 16, fontWeight: FontWeight.w500))
58
- ],
16
+ builder: (_) => AnimatedOpacity(
17
+ duration: Duration(milliseconds: 300),
18
+ curve: Curves.easeOutCubic,
19
+ opacity: largeQrMode || walletAddressListViewModel.displayAmount.isEmpty ? 0 : 1,
20
+ child: AnimatedAlign(
21
+ duration: Duration(milliseconds: 300),
22
+ curve: Curves.easeOutCubic,
23
+ heightFactor: largeQrMode || walletAddressListViewModel.displayAmount.isEmpty ? 0 : 1,
24
+ alignment: Alignment.topCenter,
25
+ child: Container(
26
+ width: double.infinity,
27
+ child: Row(
28
+ spacing: 4,
29
+ mainAxisSize: MainAxisSize.min,
30
+ mainAxisAlignment: MainAxisAlignment.center,
31
+ children: [
32
+ Container(
33
+ decoration: BoxDecoration(
34
+ borderRadius: BorderRadius.circular(12),
35
+ color: Theme.of(context).colorScheme.surfaceContainer),
36
+ child: Padding(
37
+ padding: const EdgeInsets.all(8.0),
38
+ child: Row(
39
+ spacing: 8.0,
40
+ children: [
41
+ Text(
42
+ walletAddressListViewModel.displayAmount,
43
+ style: TextStyle(
44
+ color: Theme.of(context).colorScheme.primary,
45
+ fontSize: 16,
46
+ fontWeight: FontWeight.w500),
47
),
60
- ),
61
-
48
+ Text(walletAddressListViewModel.cryptoCurrencySymbol,
49
+ style: TextStyle(
50
+ color: Theme.of(context).colorScheme.primary,
51
+ fontSize: 16,
52
+ fontWeight: FontWeight.w500))
53
+ ],
54
),
63
- if(!walletAddressListViewModel.isFiatDisabled)
64
- Padding(
65
- padding: const EdgeInsets.all(8.0),
66
- child: Text(_getFiatAmount(),
67
- style: TextStyle(color: Theme
68
- .of(context)
69
- .colorScheme
70
- .onSurfaceVariant, fontSize: 16, fontWeight: FontWeight.w500),),
71
- )
72
- ],
55
+ ),
56
),
74
- ),
57
+ if (!walletAddressListViewModel.isFiatDisabled)
58
+ Padding(
59
+ padding: const EdgeInsets.all(8.0),
60
+ child: Text(
61
+ _getFiatAmount(),
62
+ style: TextStyle(
63
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
64
+ fontSize: 16,
65
+ fontWeight: FontWeight.w500),
66
+ ),
67
+ )
68
+ ],
69
),
70
),
71
+ ),
72
+ ),
73
);
74
}
75
lib/new-ui/widgets/receive_page/receive_amount_modal.dart
+8
-8
@@ -30,7 +30,7 @@ class _ReceiveAmountModalState extends State<ReceiveAmountModal> {
30
@override
31
void initState() {
32
super.initState();
33
- if(widget.walletAddressListViewModel.selectedCurrency is FiatCurrency) {
33
+ if (widget.walletAddressListViewModel.selectedCurrency is FiatCurrency) {
34
_amountController.text = widget.walletAddressListViewModel.fiatAmount;
35
} else {
36
_amountController.text = widget.walletAddressListViewModel.displayAmount;
@@ -103,7 +103,8 @@ class _ReceiveAmountModalState extends State<ReceiveAmountModal> {
103
),
104
RotatedBox(
105
quarterTurns: 2,
106
- child: CakeImageWidget(imageUrl:"assets/new-ui/dropdown_arrow.svg"))
106
+ child: CakeImageWidget(
107
+ imageUrl: "assets/new-ui/dropdown_arrow.svg"))
108
],
109
),
110
),
@@ -137,7 +138,8 @@ class _ReceiveAmountModalState extends State<ReceiveAmountModal> {
138
controller: _amountController,
139
keyboardType: TextInputType.numberWithOptions(
140
signed: false,
140
- decimal: widget.walletAddressListViewModel.selectedCurrencyDecimals > 0,
141
+ decimal:
142
+ widget.walletAddressListViewModel.selectedCurrencyDecimals > 0,
143
),
144
inputFormatters: [
145
DecimalInputFormatter(
@@ -159,7 +161,6 @@ class _ReceiveAmountModalState extends State<ReceiveAmountModal> {
161
border: InputBorder.none,
162
filled: true,
163
fillColor: Colors.transparent,
162
-
164
),
165
style: TextStyle(color: Theme.of(context).colorScheme.onSurface),
166
),
@@ -209,7 +210,7 @@ class _ReceiveAmountModalState extends State<ReceiveAmountModal> {
210
NewPrimaryButton(
211
text: S.of(context).continue_text,
212
onPressed: () {
212
- if(double.tryParse(_amountController.text) != null) {
213
+ if (double.tryParse(_amountController.text) != null) {
214
widget.walletAddressListViewModel.changeAmount(_amountController.text);
215
}
216
Navigator.of(context).pop();
@@ -228,9 +229,8 @@ class _ReceiveAmountModalState extends State<ReceiveAmountModal> {
229
}
230
231
void _presentTokenCurrencyPicker(BuildContext context) {
231
- final items = widget.walletAddressListViewModel.tokenCurrencies
232
- .whereType<CryptoCurrency>()
233
- .toList();
232
+ final items =
233
+ widget.walletAddressListViewModel.tokenCurrencies.whereType<CryptoCurrency>().toList();
234
CurrencyPickerSheet.show(
235
context: context,
236
args: CurrencyPickerArgs(
lib/new-ui/widgets/receive_page/receive_bottom_buttons.dart
+27
-22
@@ -34,7 +34,6 @@ class ReceiveBottomButtons extends StatefulWidget {
34
}
35
36
class _ReceiveBottomButtonsState extends State<ReceiveBottomButtons> {
37
-
37
@override
38
Widget build(BuildContext context) {
39
final double targetOpacity = widget.largeQrMode ? 0 : 1;
@@ -57,27 +56,33 @@ class _ReceiveBottomButtonsState extends State<ReceiveBottomButtons> {
56
spacing: 16,
57
children: [
58
GestureDetector(
60
- onTap: widget.copyData == null ? widget.onCopyButtonPressed : null,
61
- child: IgnorePointer(
62
- ignoring: widget.copyData == null,
63
- child: CopyWrapper(
64
- data: widget.copyData,
65
- builder: (context, copied) => AnimatedSwitcher(
66
- duration: Duration(milliseconds: 200),
67
- child: IgnorePointer(
68
- child: ModernButton.svg(
69
- key: ValueKey(copied),
70
- size: 60,
71
- iconSize: 32,
72
- svgPath: "assets/new-ui/copy.svg",
73
- onPressed: () {},
74
- label: copied ? S.of(context).copied : S.of(context).copy,
75
- iconColor: copied ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.surfaceContainer,
76
- backgroundColor: copied ? Theme.of(context).colorScheme.surfaceContainerHighest : Theme.of(context).colorScheme.primary,
77
- ),
78
- ),
59
+ onTap: widget.copyData == null ? widget.onCopyButtonPressed : null,
60
+ child: IgnorePointer(
61
+ ignoring: widget.copyData == null,
62
+ child: CopyWrapper(
63
+ data: widget.copyData,
64
+ builder: (context, copied) => AnimatedSwitcher(
65
+ duration: Duration(milliseconds: 200),
66
+ child: IgnorePointer(
67
+ child: ModernButton.svg(
68
+ key: ValueKey(copied),
69
+ size: 60,
70
+ iconSize: 32,
71
+ svgPath: "assets/new-ui/copy.svg",
72
+ onPressed: () {},
73
+ label: copied ? S.of(context).copied : S.of(context).copy,
74
+ iconColor: copied
75
+ ? Theme.of(context).colorScheme.primary
76
+ : Theme.of(context).colorScheme.surfaceContainer,
77
+ backgroundColor: copied
78
+ ? Theme.of(context).colorScheme.surfaceContainerHighest
79
+ : Theme.of(context).colorScheme.primary,
80
),
80
- ),),),
81
+ ),
82
+ ),
83
+ ),
84
+ ),
85
+ ),
86
ModernButton.svg(
87
size: 60,
88
iconSize: 32,
@@ -105,4 +110,4 @@ class _ReceiveBottomButtonsState extends State<ReceiveBottomButtons> {
110
),
111
);
112
}
108
-}
\ No newline at end of file
113
+}
lib/new-ui/widgets/receive_page/receive_info_box.dart
+25
-20
@@ -10,9 +10,16 @@ import 'package:flutter/material.dart';
10
11
class ReceiveInfoBox extends StatelessWidget {
12
ReceiveInfoBox(
13
- {super.key, required this.iconPath, required this.message, required this.onDismissed, this.bottomWidget});
13
+ {super.key,
14
+ required this.iconPath,
15
+ required this.message,
16
+ required this.onDismissed,
17
+ this.bottomWidget});
18
15
- static ReceiveInfoBox? forWalletType(WalletType type, {required VoidCallback onDismissed, required AutoGenerateSubaddressStatus autoGenerateSubaddressStatus, List<CryptoCurrency>? supportedCurrencies}) {
19
+ static ReceiveInfoBox? forWalletType(WalletType type,
20
+ {required VoidCallback onDismissed,
21
+ required AutoGenerateSubaddressStatus autoGenerateSubaddressStatus,
22
+ List<CryptoCurrency>? supportedCurrencies}) {
23
switch (type) {
24
case WalletType.nano:
25
return null;
@@ -24,21 +31,18 @@ class ReceiveInfoBox extends StatelessWidget {
31
case WalletType.polygon:
32
case WalletType.zano:
33
case WalletType.bsc:
27
- if(autoGenerateSubaddressStatus == AutoGenerateSubaddressStatus.disabled)
28
- return null;
34
+ if (autoGenerateSubaddressStatus == AutoGenerateSubaddressStatus.disabled) return null;
35
return ReceiveInfoBox(
30
- iconPath: "",
31
- message:
32
- "${S.current.infobox_multichain} ${walletTypeToString(type)}",
33
- onDismissed: onDismissed,
36
+ iconPath: "",
37
+ message: "${S.current.infobox_multichain} ${walletTypeToString(type)}",
38
+ onDismissed: onDismissed,
39
bottomWidget: InfoboxCurrencyRow(
40
currencies: supportedCurrencies ?? [],
41
chainIconPath:
42
"assets/new-ui/chain_badges/${walletTypeToString(type).toLowerCase()}.svg",
43
));
44
default:
40
- if(autoGenerateSubaddressStatus == AutoGenerateSubaddressStatus.disabled)
41
- return null;
45
+ if (autoGenerateSubaddressStatus == AutoGenerateSubaddressStatus.disabled) return null;
46
return ReceiveInfoBox(
47
iconPath: "assets/new-ui/info.svg",
48
message: S.current.infobox_auto_address,
@@ -66,14 +70,14 @@ class ReceiveInfoBox extends StatelessWidget {
70
crossAxisAlignment: CrossAxisAlignment.start,
71
spacing: 10,
72
children: [
69
- if(iconPath.isNotEmpty)
70
- CakeImageWidget(imageUrl:
71
- iconPath,
72
- width: 16,
73
- height: 16,
74
- colorFilter: ColorFilter.mode(
75
- Theme.of(context).colorScheme.onSurfaceVariant, BlendMode.srcIn),
76
- ),
73
+ if (iconPath.isNotEmpty)
74
+ CakeImageWidget(
75
+ imageUrl: iconPath,
76
+ width: 16,
77
+ height: 16,
78
+ colorFilter: ColorFilter.mode(
79
+ Theme.of(context).colorScheme.onSurfaceVariant, BlendMode.srcIn),
80
+ ),
81
Flexible(
82
child: Column(
83
spacing: 10,
@@ -126,8 +130,9 @@ class InfoboxCurrencyRow extends StatelessWidget {
130
131
@override
132
Widget build(BuildContext context) {
129
- final currenciesWithImage = currencies.where((item)=>item.iconPath != null).toList();
130
- final currenciesLimited = currenciesWithImage.sublist(0, min(currenciesWithImage.length, maxCurrencies));
133
+ final currenciesWithImage = currencies.where((item) => item.iconPath != null).toList();
134
+ final currenciesLimited =
135
+ currenciesWithImage.sublist(0, min(currenciesWithImage.length, maxCurrencies));
136
137
final double stackWidth = iconSize + (overlap * (currenciesLimited.length));
138
lib/new-ui/widgets/receive_page/receive_label_modal.dart
+8
-4
@@ -9,8 +9,6 @@ import 'package:flutter/material.dart';
9
import 'package:flutter_mobx/flutter_mobx.dart';
10
import 'package:mobx/mobx.dart';
11
12
-
13
-
12
class ReceiveLabelModal extends StatefulWidget {
13
const ReceiveLabelModal({super.key, required this.walletAddressEditOrCreateViewModel});
14
@@ -45,7 +43,13 @@ class _ReceiveLabelModalState extends State<ReceiveLabelModal> {
43
44
@override
45
Widget build(BuildContext context) {
48
- List<String> defaultLabels = [S.of(context).donation, S.of(context).savings, S.of(context).business, S.of(context).mining, S.of(context).salary];
46
+ List<String> defaultLabels = [
47
+ S.of(context).donation,
48
+ S.of(context).savings,
49
+ S.of(context).business,
50
+ S.of(context).mining,
51
+ S.of(context).salary
52
+ ];
53
54
return Padding(
55
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
@@ -54,7 +58,7 @@ class _ReceiveLabelModalState extends State<ReceiveLabelModal> {
58
color: Theme.of(context).colorScheme.surface,
59
borderRadius: BorderRadius.vertical(top: Radius.circular(16))),
60
child: SafeArea(
57
- top:false,
61
+ top: false,
62
child: Column(
63
spacing: 24,
64
mainAxisSize: MainAxisSize.min,
lib/new-ui/widgets/receive_page/receive_label_widget.dart
+2
-1
@@ -23,7 +23,8 @@ class ReceiveLabelWidget extends StatelessWidget {
23
mainAxisSize: MainAxisSize.min,
24
children: [
25
ClipRect(
26
- child: CakeImageWidget(imageUrl:"assets/new-ui/label.svg",
26
+ child: CakeImageWidget(
27
+ imageUrl: "assets/new-ui/label.svg",
28
width: 24,
29
height: 24,
30
colorFilter: ColorFilter.mode(
lib/new-ui/widgets/receive_page/receive_large_amount_preview.dart
+2
-1
@@ -30,7 +30,8 @@ class ReceiveLargeAmountPreview extends StatelessWidget {
30
mainAxisAlignment: MainAxisAlignment.center,
31
spacing: 12,
32
children: [
33
- CakeImageWidget(imageUrl:"assets/new-ui/send.svg",
33
+ CakeImageWidget(
34
+ imageUrl: "assets/new-ui/send.svg",
35
width: 24,
36
height: 24,
37
colorFilter: ColorFilter.mode(
lib/new-ui/widgets/receive_page/receive_qr_code.dart
+7
-7
@@ -27,11 +27,11 @@ class ReceiveQrCode extends StatelessWidget {
27
static const Duration animDuration = Duration(milliseconds: 500);
28
final bool isLightMode = !(getIt.get<ThemeStore>().currentTheme.isDark);
29
30
-
30
@override
31
Widget build(BuildContext context) {
33
- final double targetY = largeQrMode ? largeQrModeBottomPadding+50 : 0;
34
- final double resolvedSize = min(MediaQuery.of(context).size.width, MediaQuery.of(context).size.height) * 0.5;
32
+ final double targetY = largeQrMode ? largeQrModeBottomPadding + 50 : 0;
33
+ final double resolvedSize =
34
+ min(MediaQuery.of(context).size.width, MediaQuery.of(context).size.height) * 0.5;
35
final double resolvedScale = largeQrMode ? 1.7 : 1;
36
37
return Stack(
@@ -44,8 +44,8 @@ class ReceiveQrCode extends StatelessWidget {
44
child: AnimatedOpacity(
45
duration: animDuration,
46
opacity: largeQrMode ? 1 : 0,
47
- child: CakeImageWidget(imageUrl:
48
- isLightMode
47
+ child: CakeImageWidget(
48
+ imageUrl: isLightMode
49
? "assets/new-ui/cakewallet-wordmark-light.svg"
50
: "assets/new-ui/cakewallet-wordmark.svg",
51
height: 45,
@@ -118,7 +118,7 @@ class ReceiveQrCode extends StatelessWidget {
118
mainAxisAlignment: MainAxisAlignment.center,
119
spacing: 4,
120
children: [
121
- CakeImageWidget(imageUrl:"assets/new-ui/payjoin.svg"),
121
+ CakeImageWidget(imageUrl: "assets/new-ui/payjoin.svg"),
122
Text(S.of(context).payjoin_enabled)
123
],
124
),
@@ -126,7 +126,7 @@ class ReceiveQrCode extends StatelessWidget {
126
AnimatedSize(
127
duration: animDuration,
128
curve: Curves.easeOutCubic,
129
- child: SizedBox(height: largeQrMode ? largeQrModeBottomPadding+40 : 0))
129
+ child: SizedBox(height: largeQrMode ? largeQrModeBottomPadding + 40 : 0))
130
],
131
),
132
)),
lib/new-ui/widgets/receive_page/receive_token_display.dart
+5
-6
@@ -12,8 +12,8 @@ class ReceiveTokenDisplay extends StatelessWidget {
12
13
@override
14
Widget build(BuildContext context) {
15
- return Observer(
16
- builder: (_)=>Row(
15
+ return Observer(
16
+ builder: (_) => Row(
17
mainAxisAlignment: MainAxisAlignment.center,
18
spacing: 8,
19
children: [
@@ -31,16 +31,15 @@ class ReceiveTokenDisplay extends StatelessWidget {
31
child: Padding(
32
padding: const EdgeInsets.all(4.0),
33
child: Row(
34
- spacing:4,
34
+ spacing: 4,
35
children: [
36
CakeImageWidget(
37
imageUrl:
38
"assets/new-ui/chain_badges/${addressListViewModel.wallet.type == WalletType.bsc ? 'bnb' : walletTypeToString(addressListViewModel.wallet.type).toLowerCase()}.svg",
39
width: 16,
40
height: 16,
41
- colorFilter: ColorFilter.mode(
42
- Theme.of(context).colorScheme.primary,
43
- BlendMode.srcIn),
41
+ colorFilter:
42
+ ColorFilter.mode(Theme.of(context).colorScheme.primary, BlendMode.srcIn),
43
),
44
Text(walletTypeToString(addressListViewModel.wallet.type),
45
style: TextStyle(
lib/new-ui/widgets/receive_page/receive_top_bar.dart
+25
-25
@@ -1,24 +1,24 @@
1
import 'package:cake_wallet/new-ui/widgets/modern_button.dart';
2
import 'package:flutter/material.dart';
3
4
-void nothing(){}
4
+void nothing() {}
5
6
class ModalTopBar extends StatelessWidget {
7
ModalTopBar(
8
{super.key,
9
- required this.title,
10
- this.subtitle,
11
- this.onLeadingPressed=nothing,
12
- this.onTrailingPressed=nothing,
13
- this.leadingIcon,
14
- this.trailingIcon,
15
- this.padding,
16
- this.leadingWidget,
17
- this.trailingWidget}) {
18
- if(leadingIcon != null && leadingWidget != null) {
9
+ required this.title,
10
+ this.subtitle,
11
+ this.onLeadingPressed = nothing,
12
+ this.onTrailingPressed = nothing,
13
+ this.leadingIcon,
14
+ this.trailingIcon,
15
+ this.padding,
16
+ this.leadingWidget,
17
+ this.trailingWidget}) {
18
+ if (leadingIcon != null && leadingWidget != null) {
19
throw Exception("Cannot have both leadingIcon and leadingWidget");
20
}
21
- if(trailingIcon != null && trailingWidget != null) {
21
+ if (trailingIcon != null && trailingWidget != null) {
22
throw Exception("Cannot have both trailingIcon and trailingWidget");
23
}
24
}
@@ -38,7 +38,7 @@ class ModalTopBar extends StatelessWidget {
38
@override
39
Widget build(BuildContext context) {
40
return Padding(
41
- padding: padding??EdgeInsets.all(18),
41
+ padding: padding ?? EdgeInsets.all(18),
42
child: Stack(
43
alignment: Alignment.topCenter,
44
children: [
@@ -58,8 +58,7 @@ class ModalTopBar extends StatelessWidget {
58
),
59
),
60
if (subtitle != null && subtitle!.isNotEmpty)
61
- Text(
62
- subtitle!,
61
+ Text(subtitle!,
62
style: Theme.of(context)
63
.textTheme
64
.headlineMedium
@@ -74,11 +73,11 @@ class ModalTopBar extends StatelessWidget {
73
if (leadingIcon != null || leadingWidget != null)
74
leadingIcon != null
75
? ModernButton(
77
- key: ValueKey(leadingIcon.hashCode),
78
- size: buttonSize,
79
- onPressed: onLeadingPressed,
80
- icon: leadingIcon!,
81
- iconColor: Theme.of(context).colorScheme.onSurfaceVariant)
76
+ key: ValueKey(leadingIcon.hashCode),
77
+ size: buttonSize,
78
+ onPressed: onLeadingPressed,
79
+ icon: leadingIcon!,
80
+ iconColor: Theme.of(context).colorScheme.onSurfaceVariant)
81
: leadingWidget!
82
else
83
Container(width: buttonSize),
@@ -87,10 +86,11 @@ class ModalTopBar extends StatelessWidget {
86
duration: const Duration(milliseconds: 200),
87
child: trailingIcon != null
88
? ModernButton(
90
- key: ValueKey(trailingIcon.hashCode),
91
- size: buttonSize,
92
- onPressed: onTrailingPressed,
93
- icon: trailingIcon!,)
89
+ key: ValueKey(trailingIcon.hashCode),
90
+ size: buttonSize,
91
+ onPressed: onTrailingPressed,
92
+ icon: trailingIcon!,
93
+ )
94
: trailingWidget!,
95
)
96
else
@@ -101,4 +101,4 @@ class ModalTopBar extends StatelessWidget {
101
),
102
);
103
}
104
-}
\ No newline at end of file
104
+}
lib/new-ui/widgets/send_page/fiat_amount_bar.dart
+10
-6
@@ -15,7 +15,9 @@ class FiatAmountBar extends StatelessWidget {
15
required this.fiatCurrencySymbol,
16
this.allAmount,
17
this.foregroundElementColor,
18
- this.textColor, this.allAmountColor, this.allAmountTextColor});
18
+ this.textColor,
19
+ this.allAmountColor,
20
+ this.allAmountTextColor});
21
22
final bool fiatInputMode;
23
final VoidCallback onSwitchButtonPressed;
@@ -66,10 +68,11 @@ class FiatAmountBar extends StatelessWidget {
68
style: TextStyle(color: textColor ?? Theme.of(context).colorScheme.onSurface),
69
),
70
Container(
69
- decoration: BoxDecoration(
70
- borderRadius: BorderRadius.circular(999999)),
71
+ decoration: BoxDecoration(borderRadius: BorderRadius.circular(999999)),
72
child: Material(
72
- color: allAmountColor ?? foregroundElementColor ?? Theme.of(context).colorScheme.surfaceContainer,
73
+ color: allAmountColor ??
74
+ foregroundElementColor ??
75
+ Theme.of(context).colorScheme.surfaceContainer,
76
borderRadius: BorderRadius.circular(99999),
77
child: InkWell(
78
borderRadius: BorderRadius.circular(99999),
@@ -78,7 +81,8 @@ class FiatAmountBar extends StatelessWidget {
81
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4),
82
child: Text(
83
formatAmount(allAmount!),
81
- style: TextStyle(color: allAmountTextColor ?? Theme.of(context).colorScheme.primary),
84
+ style: TextStyle(
85
+ color: allAmountTextColor ?? Theme.of(context).colorScheme.primary),
86
),
87
),
88
)),
@@ -92,7 +96,7 @@ class FiatAmountBar extends StatelessWidget {
96
String formatAmount(String amount) {
97
try {
98
return double.parse(amount).toStringAsPrecision(8).replaceFirst(RegExp(r"\.?0+$"), "");
95
- } catch(e) {
99
+ } catch (e) {
100
return amount;
101
}
102
}
lib/new-ui/widgets/send_page/floating_icon_button.dart
+7
-9
@@ -18,15 +18,13 @@ class FloatingIconButton extends StatelessWidget {
18
onTap: onPressed,
19
child: Padding(
20
padding: const EdgeInsets.all(4.0),
21
- child: CakeImageWidget(imageUrl:iconPath,
22
- width: 22, height: 22,
23
- colorFilter: ColorFilter.mode(Theme
24
- .of(context)
25
- .colorScheme
26
- .primary, BlendMode.srcIn),
21
+ child: CakeImageWidget(
22
+ imageUrl: iconPath,
23
+ width: 22,
24
+ height: 22,
25
+ colorFilter: ColorFilter.mode(Theme.of(context).colorScheme.primary, BlendMode.srcIn),
26
),
28
- )
29
- ),
27
+ )),
28
);
29
}
32
-}
\ No newline at end of file
30
+}
lib/new-ui/widgets/send_page/l2_send_external_modal.dart
+21
-18
@@ -34,7 +34,7 @@ class _L2SendExternalModalState extends State<L2SendExternalModal> {
34
if (widget.sendViewModel.wallet.type == WalletType.bitcoin) {
35
await bitcoin!.setAddressType(widget.sendViewModel.wallet,
36
bitcoin!.getOptionToType(bitcoin!.getBitcoinLightningReceivePageOption()));
37
- } else if(widget.sendViewModel.wallet.type == WalletType.litecoin) {
37
+ } else if (widget.sendViewModel.wallet.type == WalletType.litecoin) {
38
await bitcoin!.setAddressType(widget.sendViewModel.wallet,
39
bitcoin!.getOptionToType(bitcoin!.getLitecoinMwebReceivePageOption()));
40
}
@@ -64,8 +64,8 @@ class _L2SendExternalModalState extends State<L2SendExternalModal> {
64
leadingWidget: Row(
65
spacing: 12,
66
children: [
67
- if(widget.sendViewModel.walletType == WalletType.bitcoin)
68
- CakeImageWidget(imageUrl:"assets/new-ui/lightning_deposit_help.svg", height: 36),
67
+ if (widget.sendViewModel.walletType == WalletType.bitcoin)
68
+ CakeImageWidget(imageUrl: "assets/new-ui/lightning_deposit_help.svg", height: 36),
69
Text(
70
S.of(context).bitcoin_lightning_deposit,
71
style: TextStyle(fontWeight: FontWeight.w500, fontSize: 20),
@@ -140,23 +140,25 @@ class _L2SendExternalModalState extends State<L2SendExternalModal> {
140
largeQrMode = !largeQrMode;
141
});
142
},
143
- child: AnimatedContainer(
144
- duration: const Duration(milliseconds: 400),
145
- curve: Curves.easeOutCubic,
146
- width: resolvedSize,
147
- height: resolvedSize,
148
- child: ClipRRect(
149
- borderRadius: BorderRadius.circular(16),
150
- child: QrImage(
151
- embeddedImagePath: widget.sendViewModel.currency.iconPath,
152
- data: uri.toString(),
143
+ child: AnimatedContainer(
144
+ duration: const Duration(milliseconds: 400),
145
+ curve: Curves.easeOutCubic,
146
+ width: resolvedSize,
147
+ height: resolvedSize,
148
+ child: ClipRRect(
149
+ borderRadius: BorderRadius.circular(16),
150
+ child: QrImage(
151
+ embeddedImagePath: widget.sendViewModel.currency.iconPath,
152
+ data: uri.toString(),
153
+ ),
154
+ ),
155
+ ),
156
),
154
- ),
155
- ),
156
- ),
157
AddressFormatter.buildSegmentedAddress(
158
address: output.address,
159
- evenTextStyle: TextStyle(color: Theme.of(context).colorScheme.onSurface,fontFamily: "IBM Plex Mono"),
159
+ evenTextStyle: TextStyle(
160
+ color: Theme.of(context).colorScheme.onSurface,
161
+ fontFamily: "IBM Plex Mono"),
162
textAlign: TextAlign.center),
163
Container(
164
decoration: BoxDecoration(
@@ -179,7 +181,8 @@ class _L2SendExternalModalState extends State<L2SendExternalModal> {
181
children: [
182
Flexible(
183
child: NewPrimaryButton(
182
- onPressed: () => ClipboardUtil.copyToClipboard(context, output.address),
184
+ onPressed: () =>
185
+ ClipboardUtil.copyToClipboard(context, output.address),
186
text: S.of(context).copy,
187
color: Theme.of(context).colorScheme.primary,
188
textColor: Theme.of(context).colorScheme.onPrimary),
lib/new-ui/widgets/send_page/recipient_dot_row.dart
+14
-12
@@ -42,7 +42,6 @@ class _RecipientDotRowState extends State<RecipientDotRow> {
42
43
@override
44
Widget build(BuildContext context) {
45
-
45
return LayoutBuilder(
46
builder: (context, constraints) {
47
final viewportWidth = constraints.maxWidth;
@@ -51,11 +50,11 @@ class _RecipientDotRowState extends State<RecipientDotRow> {
50
final totalContentWidth = (widget.numDots * itemExtent) - _outputDotSpacing;
51
final isScrollable = totalContentWidth > viewportWidth;
52
54
- final sidePadding = isScrollable ? viewportWidth * (_deadzoneSize/2) : 0.0;
53
+ final sidePadding = isScrollable ? viewportWidth * (_deadzoneSize / 2) : 0.0;
54
55
if (isScrollable && !_wasScrollable) {
57
- _outputDotsController
58
- .jumpTo((widget.numDots * (_deadzoneSize/2)) * itemExtent - (_outputDotSpacing * (_deadzoneSize+1)));
56
+ _outputDotsController.jumpTo((widget.numDots * (_deadzoneSize / 2)) * itemExtent -
57
+ (_outputDotSpacing * (_deadzoneSize + 1)));
58
}
59
60
_wasScrollable = isScrollable;
@@ -141,7 +140,8 @@ class RecipientDot extends StatefulWidget {
140
required this.spacing,
141
required this.index,
142
required this.onTap,
144
- required this.selected, required this.textOpacity});
143
+ required this.selected,
144
+ required this.textOpacity});
145
146
final double size;
147
final double spacing;
@@ -197,13 +197,15 @@ class _RecipientDotState extends State<RecipientDot> {
197
alignment: Alignment.center,
198
child: Opacity(
199
opacity: widget.textOpacity,
200
- child: Text((widget.index+1).toString(),
201
- style: TextStyle(
202
- color: widget.selected
203
- ? Theme.of(context).colorScheme.onPrimary
204
- : Theme.of(context).colorScheme.onSurface,
205
- fontSize:14,fontWeight: FontWeight.w500
206
- ),),
200
+ child: Text(
201
+ (widget.index + 1).toString(),
202
+ style: TextStyle(
203
+ color: widget.selected
204
+ ? Theme.of(context).colorScheme.onPrimary
205
+ : Theme.of(context).colorScheme.onSurface,
206
+ fontSize: 14,
207
+ fontWeight: FontWeight.w500),
208
+ ),
209
),
210
),
211
),
lib/new-ui/widgets/send_page/send_address_input.dart
+1
-1
@@ -38,7 +38,7 @@ class NewSendAddressInput extends StatefulWidget {
38
final FormFieldValidator<String>? validator;
39
final FocusNode? focusNode;
40
final String? hintText;
41
-
41
+
42
@override
43
State<NewSendAddressInput> createState() => _NewSendAddressInputState();
44
}
lib/new-ui/widgets/send_page/send_amount_input.dart
+16
-14
@@ -7,16 +7,16 @@ import 'package:flutter/services.dart';
7
import 'package:flutter_mobx/flutter_mobx.dart';
8
9
class NewSendAmountInput extends StatefulWidget {
10
- const NewSendAmountInput(
11
- {super.key,
12
- required this.currency,
13
- required this.maxDecimals,
14
- required this.hasPicker,
15
- required this.onPickerClicked,
16
- required this.currencyIconPath,
17
- required this.amountController,
18
- this.validator,
19
- });
10
+ const NewSendAmountInput({
11
+ super.key,
12
+ required this.currency,
13
+ required this.maxDecimals,
14
+ required this.hasPicker,
15
+ required this.onPickerClicked,
16
+ required this.currencyIconPath,
17
+ required this.amountController,
18
+ this.validator,
19
+ });
20
21
final String currency;
22
final String currencyIconPath;
@@ -35,7 +35,8 @@ class _NewSendAmountInputState extends State<NewSendAmountInput> {
35
36
@override
37
void initState() {
38
- widget.amountController.addListener(()=>formFieldKey.currentState?.didChange(widget.amountController.text));
38
+ widget.amountController
39
+ .addListener(() => formFieldKey.currentState?.didChange(widget.amountController.text));
40
super.initState();
41
}
42
@@ -124,11 +125,12 @@ class _NewSendAmountInputState extends State<NewSendAmountInput> {
125
spacing: 8,
126
children: [
127
if (widget.hasPicker && widget.currencyIconPath.isNotEmpty)
127
- TokenImageWidget(imageUrl: widget.currencyIconPath, size: 24),
128
+ TokenImageWidget(
129
+ imageUrl: widget.currencyIconPath, size: 24),
130
Text(widget.currency),
131
if (widget.hasPicker)
130
- CakeImageWidget(imageUrl:
131
- "assets/new-ui/chooser.svg",
132
+ CakeImageWidget(
133
+ imageUrl: "assets/new-ui/chooser.svg",
134
width: 12,
135
height: 12,
136
colorFilter: ColorFilter.mode(
lib/new-ui/widgets/send_page/send_confirm_bottom_widget.dart
+2
-2
@@ -120,8 +120,8 @@ class TransactionErrorActions extends StatelessWidget {
120
mainAxisAlignment: MainAxisAlignment.center,
121
spacing: 8,
122
children: [
123
- CakeImageWidget(imageUrl:
124
- "assets/new-ui/warning.svg",
123
+ CakeImageWidget(
124
+ imageUrl: "assets/new-ui/warning.svg",
125
height: 24,
126
width: 24,
127
colorFilter:
lib/new-ui/widgets/send_page/send_confirm_sheet.dart
+69
-62
@@ -27,7 +27,8 @@ import 'package:flutter_mobx/flutter_mobx.dart';
27
import 'package:mobx/mobx.dart';
28
29
class SendConfirmSheet extends StatefulWidget {
30
- const SendConfirmSheet({super.key, required this.sendViewModel, this.isPage = false, this.title, this.iconPath});
30
+ const SendConfirmSheet(
31
+ {super.key, required this.sendViewModel, this.isPage = false, this.title, this.iconPath});
32
33
final SendViewModel sendViewModel;
34
final bool isPage;
@@ -43,8 +44,8 @@ class _SendConfirmSheetState extends State<SendConfirmSheet> {
44
45
void initState() {
46
super.initState();
46
- reaction((_)=>widget.sendViewModel.state, (state){
47
- if(state is TransactionCommitted) {
47
+ reaction((_) => widget.sendViewModel.state, (state) {
48
+ if (state is TransactionCommitted) {
49
setState(() {
50
_committed = true;
51
});
@@ -62,57 +63,55 @@ class _SendConfirmSheetState extends State<SendConfirmSheet> {
63
}
64
},
65
child: SafeArea(
65
- bottom:false,
66
+ bottom: false,
67
minimum: widget.isPage ? EdgeInsets.zero : EdgeInsets.only(top: 64),
68
child: Container(
69
decoration: BoxDecoration(
70
color: Theme.of(context).colorScheme.surface,
71
borderRadius: BorderRadius.vertical(top: Radius.circular(16)),
72
),
72
- child: SafeArea(
73
- child: Observer(
74
- builder: (_) {
75
- return AnimatedSize(
76
- duration: const Duration(milliseconds: 300),
77
- curve: Curves.easeOutCubic,
78
- alignment: Alignment.topCenter,
79
- clipBehavior: Clip.hardEdge,
80
- child: Stack(
81
- clipBehavior: Clip.none,
82
- children: [
83
- Align(
84
- alignment: Alignment.topCenter,
85
- heightFactor: _committed ? 0.0 : 1.0,
86
- child: AnimatedSlide(
87
- offset: _committed ? const Offset(-1, 0) : Offset.zero,
88
- duration: const Duration(milliseconds: 300),
89
- curve: Curves.easeOutCubic,
90
- child: SendTransactionDetails(
91
- sendViewModel: widget.sendViewModel,
92
- isPage: widget.isPage,
93
- title: widget.title,
94
- iconPath: widget.iconPath,
95
- ),
73
+ child: SafeArea(child: Observer(
74
+ builder: (_) {
75
+ return AnimatedSize(
76
+ duration: const Duration(milliseconds: 300),
77
+ curve: Curves.easeOutCubic,
78
+ alignment: Alignment.topCenter,
79
+ clipBehavior: Clip.hardEdge,
80
+ child: Stack(
81
+ clipBehavior: Clip.none,
82
+ children: [
83
+ Align(
84
+ alignment: Alignment.topCenter,
85
+ heightFactor: _committed ? 0.0 : 1.0,
86
+ child: AnimatedSlide(
87
+ offset: _committed ? const Offset(-1, 0) : Offset.zero,
88
+ duration: const Duration(milliseconds: 300),
89
+ curve: Curves.easeOutCubic,
90
+ child: SendTransactionDetails(
91
+ sendViewModel: widget.sendViewModel,
92
+ isPage: widget.isPage,
93
+ title: widget.title,
94
+ iconPath: widget.iconPath,
95
),
96
),
98
- Align(
99
- alignment: Alignment.topCenter,
100
- heightFactor: _committed ? 1.0 : 0.0,
101
- child: AnimatedSlide(
102
- offset: _committed ? Offset.zero : const Offset(1, 0),
103
- duration: const Duration(milliseconds: 300),
104
- curve: Curves.easeOutCubic,
105
- child: TransactionCommitedScreen(
106
- sendViewModel: widget.sendViewModel,
107
- ),
97
+ ),
98
+ Align(
99
+ alignment: Alignment.topCenter,
100
+ heightFactor: _committed ? 1.0 : 0.0,
101
+ child: AnimatedSlide(
102
+ offset: _committed ? Offset.zero : const Offset(1, 0),
103
+ duration: const Duration(milliseconds: 300),
104
+ curve: Curves.easeOutCubic,
105
+ child: TransactionCommitedScreen(
106
+ sendViewModel: widget.sendViewModel,
107
),
108
),
110
- ],
111
- ),
112
- );
113
- },
114
- )
115
- ),
109
+ ),
110
+ ],
111
+ ),
112
+ );
113
+ },
114
+ )),
115
),
116
),
117
);
@@ -120,14 +119,14 @@ class _SendConfirmSheetState extends State<SendConfirmSheet> {
119
}
120
121
class SendTransactionDetails extends StatelessWidget {
123
- const SendTransactionDetails({super.key, required this.sendViewModel, required this.isPage, this.title, this.iconPath});
122
+ const SendTransactionDetails(
123
+ {super.key, required this.sendViewModel, required this.isPage, this.title, this.iconPath});
124
125
final SendViewModel sendViewModel;
126
final bool isPage;
127
final String? title;
128
final String? iconPath;
129
130
-
130
@override
131
Widget build(BuildContext context) {
132
final resolvedIconPath = iconPath ?? sendViewModel.currency.iconPath ?? "";
@@ -144,8 +143,8 @@ class SendTransactionDetails extends StatelessWidget {
143
spacing: 8,
144
children: [
145
if (resolvedIconPath.toLowerCase().endsWith(".svg"))
147
- CakeImageWidget(imageUrl:
148
- resolvedIconPath,
146
+ CakeImageWidget(
147
+ imageUrl: resolvedIconPath,
148
width: 28,
149
height: 28,
150
)
@@ -164,7 +163,9 @@ class SendTransactionDetails extends StatelessWidget {
163
trailingIcon: Icon(Icons.close),
164
onTrailingPressed: Navigator.of(context).maybePop,
165
),
167
- isPage ? Expanded(child: _buildMainContent(context)) : Flexible(child: _buildMainContent(context))
166
+ isPage
167
+ ? Expanded(child: _buildMainContent(context))
168
+ : Flexible(child: _buildMainContent(context))
169
]);
170
},
171
);
@@ -176,8 +177,7 @@ class SendTransactionDetails extends StatelessWidget {
177
Money sumByMoney<T>(List<T> list, Money Function(T) picker, CryptoCurrency currency) =>
178
list.map(picker).fold(Money.zero(currency), (a, b) => a + b);
179
179
- String sumStr<T>(List<T> list, double Function(T) picker) =>
180
- sumBy(list, picker).toString();
180
+ String sumStr<T>(List<T> list, double Function(T) picker) => sumBy(list, picker).toString();
181
182
String sumWithUnit<T>(List<T> list, double Function(T) picker, String unit, {int? decimals}) {
183
final str = sumStr(list, picker);
@@ -227,14 +227,17 @@ class SendTransactionDetails extends StatelessWidget {
227
decimals: 2)
228
: sendViewModel.pendingTransactionFeeFiatAmountFormatted;
229
230
- final showAddress = !sendViewModel.outputs.any((e) =>
231
- RegExp(AddressValidator.bolt11InvoiceMatcher).hasMatch(e.address.toLowerCase()) ||
232
- RegExp(AddressValidator.lnurlMatcher).hasMatch(e.address.toLowerCase()) ||
233
- (e.isParsedAddress &&
234
- e.parsedAddress.parsedAddressByCurrencyMap[sendViewModel.selectedCryptoCurrency] != null &&
235
- e.parsedAddress.parsedAddressByCurrencyMap[sendViewModel.selectedCryptoCurrency]!.isNotEmpty &&
236
- RegExp(AddressValidator.lnurlMatcher)
237
- .hasMatch(e.parsedAddress.parsedAddressByCurrencyMap[sendViewModel.selectedCryptoCurrency]!.toLowerCase())));
230
+ final showAddress = !sendViewModel.outputs.any((e) =>
231
+ RegExp(AddressValidator.bolt11InvoiceMatcher).hasMatch(e.address.toLowerCase()) ||
232
+ RegExp(AddressValidator.lnurlMatcher).hasMatch(e.address.toLowerCase()) ||
233
+ (e.isParsedAddress &&
234
+ e.parsedAddress.parsedAddressByCurrencyMap[sendViewModel.selectedCryptoCurrency] !=
235
+ null &&
236
+ e.parsedAddress.parsedAddressByCurrencyMap[sendViewModel.selectedCryptoCurrency]!
237
+ .isNotEmpty &&
238
+ RegExp(AddressValidator.lnurlMatcher).hasMatch(e
239
+ .parsedAddress.parsedAddressByCurrencyMap[sendViewModel.selectedCryptoCurrency]!
240
+ .toLowerCase())));
241
242
final outputs = sendViewModel.outputs;
243
@@ -426,7 +429,7 @@ class SendTransactionDetails extends StatelessWidget {
429
String formatAmount(String amount) {
430
try {
431
return amount.withMaxDecimals(8);
429
- } catch(e) {
432
+ } catch (e) {
433
return amount;
434
}
435
}
@@ -452,7 +455,9 @@ class _TransactionCommitedScreenState extends State<TransactionCommitedScreen> {
455
mainAxisSize: MainAxisSize.min,
456
mainAxisAlignment: MainAxisAlignment.spaceAround,
457
children: [
455
- SizedBox(height: 12,),
458
+ SizedBox(
459
+ height: 12,
460
+ ),
461
Text(
462
S.of(context).transaction_sent_new,
463
style: TextStyle(fontSize: 24, fontWeight: FontWeight.w600),
@@ -517,7 +522,9 @@ class _TransactionCommitedScreenState extends State<TransactionCommitedScreen> {
522
text: S.of(context).done,
523
color: Theme.of(context).colorScheme.primary,
524
textColor: Theme.of(context).colorScheme.onPrimary),
520
- SizedBox(height: 12,)
525
+ SizedBox(
526
+ height: 12,
527
+ )
528
],
529
),
530
),
lib/new-ui/widgets/send_page/send_memo_input.dart
+1
-2
@@ -59,8 +59,7 @@ class NewSendMemoInput extends StatelessWidget {
59
Expanded(
60
child: Text(disclaimerText ?? S.of(context).memo_disclaimer,
61
style: TextStyle(
62
- fontSize: 12,
63
- color: Theme.of(context).colorScheme.onSurfaceVariant)),
62
+ fontSize: 12, color: Theme.of(context).colorScheme.onSurfaceVariant)),
63
),
64
Text("${memoController.text.length} / ${maxMemoLength}",
65
style: TextStyle(fontSize: 12, color: Theme.of(context).colorScheme.primary))
lib/new-ui/widgets/send_page/send_syncing_indicator.dart
+15
-20
@@ -9,40 +9,35 @@ class SendSyncingIndicator extends StatelessWidget {
9
static const outlineColor = Color(0xFFFFB84E);
10
static const backgroundColor = Color(0xFF8E5800);
11
12
-
12
@override
13
Widget build(BuildContext context) {
14
late final String eta;
16
- if(status is SyncingSyncStatus) {
17
- eta = (status as SyncingSyncStatus).getFormattedEta()??"";
15
+ if (status is SyncingSyncStatus) {
16
+ eta = (status as SyncingSyncStatus).getFormattedEta() ?? "";
17
} else {
18
eta = "";
19
}
20
21
return Container(
23
- height:48,
24
- decoration: BoxDecoration(
25
- color: backgroundColor,
26
- borderRadius: BorderRadius.circular(99999)
27
- ),
28
- child:
29
- Padding(
22
+ height: 48,
23
+ decoration: BoxDecoration(color: backgroundColor, borderRadius: BorderRadius.circular(99999)),
24
+ child: Padding(
25
padding: const EdgeInsets.symmetric(horizontal: 12.0),
26
child: Row(
27
mainAxisSize: MainAxisSize.min,
28
spacing: 10,
29
children: [
35
- if(status.progress() > 0)
36
- SizedBox(
37
- width: 24,
38
- height: 24,
39
- child: CircularProgressIndicator(
40
- value: status.progress(),
41
- strokeWidth: 3,
42
- strokeCap: StrokeCap.round,
43
- color: outlineColor,
30
+ if (status.progress() > 0)
31
+ SizedBox(
32
+ width: 24,
33
+ height: 24,
34
+ child: CircularProgressIndicator(
35
+ value: status.progress(),
36
+ strokeWidth: 3,
37
+ strokeCap: StrokeCap.round,
38
+ color: outlineColor,
39
+ ),
40
),
45
- ),
41
Text("Synchronizing... ${eta}", style: TextStyle(color: outlineColor)),
42
],
43
),
lib/new-ui/widgets/swap_page/provider_options_page.dart
+9
-5
@@ -162,10 +162,14 @@ class ProviderOptionsPage extends StatelessWidget {
162
label: item.title,
163
showArrow: item.title == "Trocador",
164
value: exchangeViewModel.selectedProviders.contains(item),
165
- subtitle: item.title == "Trocador" ? S.of(context).manage_providers : null,
166
- onTap: item.title == "Trocador" ? (){
167
- _openTrocadorProvidersPage(context);
168
- } : null,
165
+ subtitle: item.title == "Trocador"
166
+ ? S.of(context).manage_providers
167
+ : null,
168
+ onTap: item.title == "Trocador"
169
+ ? () {
170
+ _openTrocadorProvidersPage(context);
171
+ }
172
+ : null,
173
onChanged: (val) {
174
_switchProviderStatus(item, val, context);
175
});
@@ -180,7 +184,7 @@ class ProviderOptionsPage extends StatelessWidget {
184
))
185
],
186
),
183
- SizedBox(height:36)
187
+ SizedBox(height: 36)
188
],
189
),
190
),
lib/new-ui/widgets/swap_page/refund_address_modal.dart
+5
-3
@@ -53,7 +53,7 @@ class _RefundAddressModalState extends State<RefundAddressModal> {
53
spacing: 24,
54
children: [
55
CakeImageWidget(
56
- imageUrl:"assets/new-ui/refund_address.svg",
56
+ imageUrl: "assets/new-ui/refund_address.svg",
57
colorFilter:
58
ColorFilter.mode(Theme.of(context).colorScheme.primary, BlendMode.srcIn),
59
),
@@ -72,7 +72,7 @@ class _RefundAddressModalState extends State<RefundAddressModal> {
72
spacing: 12,
73
children: [
74
NewSendAddressInput(
75
- bottomPadding: true,
75
+ bottomPadding: true,
76
addressController: addressController,
77
selectedCurrency: widget.selectedCurrency,
78
onEditingComplete: () {}),
@@ -81,7 +81,9 @@ class _RefundAddressModalState extends State<RefundAddressModal> {
81
onPressed: () {
82
Navigator.of(context).pop(addressController.text);
83
},
84
- text: !_textEntered ? S.of(context).skip_set_later : S.of(context).continue_text,
84
+ text: !_textEntered
85
+ ? S.of(context).skip_set_later
86
+ : S.of(context).continue_text,
87
color: addressController.text.isEmpty
88
? Theme.of(context).colorScheme.surfaceContainer
89
: Theme.of(context).colorScheme.primary,
lib/new-ui/widgets/swap_page/swap_address_selection_modal.dart
+45
-36
@@ -64,7 +64,9 @@ class _SwapAddressSelectionModalState extends State<SwapAddressSelectionModal> {
64
65
@override
66
Widget build(BuildContext context) {
67
- final currency = widget.isSelectingReceiver ? widget.exchangeViewModel.receiveCurrency : widget.exchangeViewModel.depositCurrency;
67
+ final currency = widget.isSelectingReceiver
68
+ ? widget.exchangeViewModel.receiveCurrency
69
+ : widget.exchangeViewModel.depositCurrency;
70
71
if (!_itemsLoaded) return SizedBox.shrink();
72
return Container(
@@ -76,7 +78,9 @@ class _SwapAddressSelectionModalState extends State<SwapAddressSelectionModal> {
78
mainAxisSize: MainAxisSize.min,
79
children: [
80
ModalTopBar(
79
- title: widget.isSelectingReceiver ? "${S.of(context).receive_to}..." : "${S.of(context).send_from}...",
81
+ title: widget.isSelectingReceiver
82
+ ? "${S.of(context).receive_to}..."
83
+ : "${S.of(context).send_from}...",
84
leadingIcon: Icon(Icons.close),
85
onLeadingPressed: Navigator.of(context).pop,
86
),
@@ -90,46 +94,47 @@ class _SwapAddressSelectionModalState extends State<SwapAddressSelectionModal> {
94
style: TextStyle(color: Theme.of(context).colorScheme.onSurfaceVariant),
95
))
96
: ListView.builder(
93
- padding: EdgeInsets.only(bottom: 12),
94
- shrinkWrap: true,
97
+ padding: EdgeInsets.only(bottom: 12),
98
+ shrinkWrap: true,
99
controller: ModalScrollController.of(context),
100
itemCount: items.length,
97
- itemBuilder: (context, index) {
98
- final item = items[index];
101
+ itemBuilder: (context, index) {
102
+ final item = items[index];
103
100
- late final bool selected;
101
- if (widget.isSelectingReceiver) {
102
- selected = widget.exchangeViewModel.receiveAddress == item.address;
103
- } else {
104
- selected = widget.exchangeViewModel.wallet.name == item.name &&
105
- !widget.exchangeViewModel.isSendFromExternal;
106
- }
104
+ late final bool selected;
105
+ if (widget.isSelectingReceiver) {
106
+ selected = widget.exchangeViewModel.receiveAddress == item.address;
107
+ } else {
108
+ selected = widget.exchangeViewModel.wallet.name == item.name &&
109
+ !widget.exchangeViewModel.isSendFromExternal;
110
+ }
111
108
- final String currencyIconPath = getCryptoCurrencyIconForWalletListItem(item.type);
112
+ final String currencyIconPath =
113
+ getCryptoCurrencyIconForWalletListItem(item.type);
114
115
final bool hasAccounts =
116
item.type == WalletType.monero && widget.isSelectingReceiver;
117
118
List<WalletInfoAddressInfo>? accounts =
114
- hasAccounts ? this.accounts[item.id] : null;
119
+ hasAccounts ? this.accounts[item.id] : null;
120
116
- return Padding(
117
- padding: const EdgeInsets.symmetric(vertical: 6.0),
118
- child: SwapAddressSelectionModalRow(
119
- wallet: item,
120
- iconPath: currencyIconPath,
121
- isSelected: selected,
122
- accounts: accounts,
123
- onAddressChosen: (address, accountName) {
121
+ return Padding(
122
+ padding: const EdgeInsets.symmetric(vertical: 6.0),
123
+ child: SwapAddressSelectionModalRow(
124
+ wallet: item,
125
+ iconPath: currencyIconPath,
126
+ isSelected: selected,
127
+ accounts: accounts,
128
+ onAddressChosen: (address, accountName) {
129
Navigator.of(context).pop(SwapAddressSelectionResult(
130
address: address,
131
walletInfo: item,
132
accountName: accountName));
133
},
134
+ ),
135
+ );
136
+ },
137
),
130
- );
131
- },
132
- ),
138
),
139
),
140
Container(
@@ -137,7 +142,7 @@ class _SwapAddressSelectionModalState extends State<SwapAddressSelectionModal> {
142
color: Theme.of(context).colorScheme.surfaceContainerHigh,
143
),
144
Padding(
140
- padding: const EdgeInsets.symmetric(horizontal: 24.0,vertical: 18),
145
+ padding: const EdgeInsets.symmetric(horizontal: 24.0, vertical: 18),
146
child: !widget.isSelectingReceiver
147
? GestureDetector(
148
behavior: HitTestBehavior.opaque,
@@ -153,7 +158,8 @@ class _SwapAddressSelectionModalState extends State<SwapAddressSelectionModal> {
158
mainAxisAlignment: MainAxisAlignment.center,
159
spacing: 10,
160
children: [
156
- CakeImageWidget(imageUrl:"assets/new-ui/send_from_external.svg",
161
+ CakeImageWidget(
162
+ imageUrl: "assets/new-ui/send_from_external.svg",
163
colorFilter: ColorFilter.mode(
164
Theme.of(context).colorScheme.primary, BlendMode.srcIn)),
165
Text(S.of(context).send_from_external,
@@ -169,9 +175,11 @@ class _SwapAddressSelectionModalState extends State<SwapAddressSelectionModal> {
175
children: [
176
Flexible(
177
child: NewSendAddressInput(
172
- addressController: addressController,
173
- selectedCurrency: widget.exchangeViewModel.receiveCurrency,
174
- onEditingComplete: () {}, bottomPadding: true,),
178
+ addressController: addressController,
179
+ selectedCurrency: widget.exchangeViewModel.receiveCurrency,
180
+ onEditingComplete: () {},
181
+ bottomPadding: true,
182
+ ),
183
),
184
AnimatedScale(
185
alignment: Alignment.centerLeft,
@@ -183,7 +191,8 @@ class _SwapAddressSelectionModalState extends State<SwapAddressSelectionModal> {
191
SizedBox(width: textEntered ? 8 : 0),
192
GestureDetector(
193
onTap: () {
186
- Navigator.of(context).pop(SwapAddressSelectionResult(address:addressController.text));
194
+ Navigator.of(context).pop(SwapAddressSelectionResult(
195
+ address: addressController.text));
196
},
197
child: AnimatedContainer(
198
duration: const Duration(milliseconds: 200),
@@ -272,8 +281,8 @@ class _SwapAddressSelectionModalRowState extends State<SwapAddressSelectionModal
281
duration: Duration(milliseconds: 200),
282
curve: Curves.easeOutCubic,
283
turns: _isExpanded ? 0 : 0.5,
275
- child:CakeImageWidget(imageUrl:
276
- "assets/new-ui/dropdown_arrow.svg",
284
+ child: CakeImageWidget(
285
+ imageUrl: "assets/new-ui/dropdown_arrow.svg",
286
colorFilter: ColorFilter.mode(
287
Theme.of(context).colorScheme.onSurfaceVariant, BlendMode.srcIn),
288
))
@@ -316,8 +325,8 @@ class _SwapAddressSelectionModalRowState extends State<SwapAddressSelectionModal
325
child: Row(
326
spacing: 12,
327
children: [
319
- CakeImageWidget(imageUrl:
320
- "assets/new-ui/account.svg",
328
+ CakeImageWidget(
329
+ imageUrl: "assets/new-ui/account.svg",
330
colorFilter: ColorFilter.mode(
331
Theme.of(context).colorScheme.onSurfaceVariant,
332
BlendMode.srcIn),
lib/new-ui/widgets/swap_page/swap_options_page.dart
+13
-4
@@ -75,7 +75,7 @@ class SwapOptionsPage extends StatelessWidget {
75
label: S.of(context).set_refund_address,
76
onTap: () {
77
showModalBottomSheet(
78
- isScrollControlled: true,
78
+ isScrollControlled: true,
79
context: context,
80
builder: (context) {
81
return RefundAddressModal(
@@ -101,9 +101,18 @@ class SwapOptionsPage extends StatelessWidget {
101
keyValue: "coin control",
102
label: "Coin Control",
103
onTap: () {
104
- showCupertinoModalBottomSheet(enableDrag: false, useRootNavigator: true, isDismissible: false, context: context, builder: (context){
105
- return NewCoinControlPage(unspentCoinsListViewModel: exchangeViewModel.unspentCoinsListViewModel,canEdit: true,);
106
- });
104
+ showCupertinoModalBottomSheet(
105
+ enableDrag: false,
106
+ useRootNavigator: true,
107
+ isDismissible: false,
108
+ context: context,
109
+ builder: (context) {
110
+ return NewCoinControlPage(
111
+ unspentCoinsListViewModel:
112
+ exchangeViewModel.unspentCoinsListViewModel,
113
+ canEdit: true,
114
+ );
115
+ });
116
}),
117
ListItemSelector(
118
keyValue: "curr",
lib/new-ui/widgets/swap_page/swap_provider_initial_preference_modal.dart
+1
-1
@@ -24,7 +24,7 @@ class SwapProviderInitialPreferenceModal extends StatelessWidget {
24
child: Column(
25
spacing: 12,
26
children: [
27
- CakeImageWidget(imageUrl:"assets/new-ui/exchange_providers.svg"),
27
+ CakeImageWidget(imageUrl: "assets/new-ui/exchange_providers.svg"),
28
Text(
29
"${S.of(context).swap_provider_initial_desc} Cake Wallet.",
30
textAlign: TextAlign.center,
lib/new-ui/widgets/swap_page/swap_send_external_modal.dart
+6
-4
@@ -16,7 +16,8 @@ class SwapSendExternalModal extends StatefulWidget {
16
required this.amount,
17
required this.from,
18
required this.to,
19
- required this.address, required this.exchangeTradeViewModel});
19
+ required this.address,
20
+ required this.exchangeTradeViewModel});
21
22
final String amount;
23
final ExchangeTradeViewModel exchangeTradeViewModel;
@@ -164,18 +165,19 @@ class _SwapSendExternalModalState extends State<SwapSendExternalModal> {
165
color: warningTextColor, fontSize: 14, fontWeight: FontWeight.w500),
166
),
167
)),
167
- if(widget.exchangeTradeViewModel.trade.extraId != null)
168
+ if (widget.exchangeTradeViewModel.trade.extraId != null)
169
Text(
170
"${S.of(context).destination_tag} ${widget.exchangeTradeViewModel.trade.extraId}",
171
style: TextStyle(
172
fontSize: 12, color: Theme.of(context).colorScheme.onSurfaceVariant),
173
),
174
Row(
174
- spacing:8,
175
+ spacing: 8,
176
children: [
177
Flexible(
178
child: NewPrimaryButton(
178
- onPressed: () => ClipboardUtil.copyToClipboard(context, widget.address),
179
+ onPressed: () =>
180
+ ClipboardUtil.copyToClipboard(context, widget.address),
181
text: S.of(context).copy,
182
color: Theme.of(context).colorScheme.primary,
183
textColor: Theme.of(context).colorScheme.onPrimary),
lib/new-ui/widgets/swap_page/trocador_providers_settings.dart
+1
-2
@@ -39,8 +39,7 @@ class TrocadorProvidersSettings extends StatelessWidget {
39
ModalHeader(
40
title: "${S.of(context).about} Trocador",
41
iconPath: "assets/new-ui/trade_providers/trocador.svg",
42
- message:
43
- "Trocador ${S.of(context).trocador_desc}"),
42
+ message: "Trocador ${S.of(context).trocador_desc}"),
43
SizedBox(),
44
Text(S.of(context).providers),
45
Text(
lib/order/order.part.dart
+1
-3
@@ -71,7 +71,5 @@ class OrderAdapter extends TypeAdapter<Order> {
71
@override
72
bool operator ==(Object other) =>
73
identical(this, other) ||
74
- other is OrderAdapter &&
75
- runtimeType == other.runtimeType &&
76
- typeId == other.typeId;
74
+ other is OrderAdapter && runtimeType == other.runtimeType && typeId == other.typeId;
75
}
lib/order/order_provider_description.dart
+2
-2
@@ -9,8 +9,8 @@ class OrderProviderDescription extends EnumerableItem<int> with Serializable<int
9
10
final String image;
11
12
- static const cakePay = OrderProviderDescription(
13
- title: 'Cake Pay', raw: 0, image: 'assets/images/cake_pay_icon.png');
12
+ static const cakePay =
13
+ OrderProviderDescription(title: 'Cake Pay', raw: 0, image: 'assets/images/cake_pay_icon.png');
14
15
static OrderProviderDescription deserialize({required int raw}) {
16
switch (raw) {
lib/order/order_source_description.dart
+1
-1
@@ -17,4 +17,4 @@ class OrderSourceDescription extends EnumerableItem<int> with Serializable<int>
17
throw Exception('Invalid OrderSourceDescription raw value: $raw');
18
}
19
}
20
-}
\ No newline at end of file
20
+}
lib/reactions/bootstrap.dart
+1
-1
@@ -46,4 +46,4 @@ void bootstrapOnline(GlobalKey<NavigatorState> navigatorKey, {required bool load
46
if (FeatureFlag.isAutomaticNodeSwitchingEnabled) {
47
getIt.get<NodeSwitchingService>().startHealthCheckTimer();
48
}
49
-}
\ No newline at end of file
49
+}
lib/reactions/fiat_rate_update.dart
+1
-2
@@ -35,8 +35,7 @@ Future<void> startFiatRateUpdate(
35
36
Iterable<CryptoCurrency>? currencies;
37
if (isEVMCompatibleChain(appStore.wallet!.type)) {
38
- currencies =
39
- evm!.getERC20Currencies(appStore.wallet!).where((element) => element.enabled);
38
+ currencies = evm!.getERC20Currencies(appStore.wallet!).where((element) => element.enabled);
39
}
40
41
if (appStore.wallet!.type == WalletType.solana) {
lib/reactions/on_authentication_state_change.dart
+1
-2
@@ -25,8 +25,7 @@ import 'package:rxdart/subjects.dart';
25
ReactionDisposer? _onAuthenticationStateChange;
26
27
dynamic loginError;
28
-StreamController<dynamic> authenticatedErrorStreamController =
29
- BehaviorSubject<dynamic>();
28
+StreamController<dynamic> authenticatedErrorStreamController = BehaviorSubject<dynamic>();
29
30
void startAuthenticationStateChange(
31
AuthenticationStore authenticationStore,
lib/reactions/on_current_fiat_api_mode_change.dart
+8
-9
@@ -7,19 +7,18 @@ import 'package:cake_wallet/store/app_store.dart';
7
8
ReactionDisposer? _onCurrentFiatCurrencyChangeDisposer;
9
10
-void startCurrentFiatApiModeChangeReaction(AppStore appStore,
11
- SettingsStore settingsStore, FiatConversionStore fiatConversionStore) {
10
+void startCurrentFiatApiModeChangeReaction(
11
+ AppStore appStore, SettingsStore settingsStore, FiatConversionStore fiatConversionStore) {
12
_onCurrentFiatCurrencyChangeDisposer?.reaction.dispose();
13
- _onCurrentFiatCurrencyChangeDisposer = reaction(
14
- (_) => settingsStore.fiatApiMode, (FiatApiMode fiatApiMode) async {
13
+ _onCurrentFiatCurrencyChangeDisposer =
14
+ reaction((_) => settingsStore.fiatApiMode, (FiatApiMode fiatApiMode) async {
15
if (appStore.wallet == null || fiatApiMode == FiatApiMode.disabled) {
16
return;
17
}
18
19
- fiatConversionStore.prices[appStore.wallet!.currency] =
20
- await FiatConversionService.fetchPrice(
21
- crypto: appStore.wallet!.currency,
22
- fiat: settingsStore.fiatCurrency,
23
- torOnly: fiatApiMode == FiatApiMode.torOnly);
19
+ fiatConversionStore.prices[appStore.wallet!.currency] = await FiatConversionService.fetchPrice(
20
+ crypto: appStore.wallet!.currency,
21
+ fiat: settingsStore.fiatCurrency,
22
+ torOnly: fiatApiMode == FiatApiMode.torOnly);
23
});
24
}
lib/reactions/on_current_fiat_change.dart
+8
-9
@@ -8,20 +8,19 @@ import 'package:cake_wallet/entities/fiat_currency.dart';
8
9
ReactionDisposer? _onCurrentFiatCurrencyChangeDisposer;
10
11
-void startCurrentFiatChangeReaction(AppStore appStore,
12
- SettingsStore settingsStore, FiatConversionStore fiatConversionStore) {
11
+void startCurrentFiatChangeReaction(
12
+ AppStore appStore, SettingsStore settingsStore, FiatConversionStore fiatConversionStore) {
13
_onCurrentFiatCurrencyChangeDisposer?.reaction.dispose();
14
- _onCurrentFiatCurrencyChangeDisposer = reaction(
15
- (_) => settingsStore.fiatCurrency, (FiatCurrency fiatCurrency) async {
14
+ _onCurrentFiatCurrencyChangeDisposer =
15
+ reaction((_) => settingsStore.fiatCurrency, (FiatCurrency fiatCurrency) async {
16
if (appStore.wallet == null || settingsStore.fiatApiMode == FiatApiMode.disabled) {
17
return;
18
}
19
20
final cryptoCurrency = appStore.wallet!.currency;
21
- fiatConversionStore.prices[cryptoCurrency] =
22
- await FiatConversionService.fetchPrice(
23
- crypto: cryptoCurrency,
24
- fiat: fiatCurrency,
25
- torOnly: settingsStore.fiatApiMode == FiatApiMode.torOnly);
21
+ fiatConversionStore.prices[cryptoCurrency] = await FiatConversionService.fetchPrice(
22
+ crypto: cryptoCurrency,
23
+ fiat: fiatCurrency,
24
+ torOnly: settingsStore.fiatApiMode == FiatApiMode.torOnly);
25
});
26
}
lib/reactions/on_current_wallet_change.dart
+1
-2
@@ -113,8 +113,7 @@ void startCurrentWalletChangeReaction(
113
}
114
115
if (wallet.type == WalletType.solana) {
116
- await solana!
117
- .discoverAndAddWalletTokens(wallet);
116
+ await solana!.discoverAndAddWalletTokens(wallet);
117
}
118
} catch (e) {
119
printV(e.toString());
lib/router.dart
+18
-16
@@ -172,13 +172,15 @@ late RouteSettings currentRouteSettings;
172
173
Route<T> handleRouteWithPlatformAwareness<T>(
174
Widget Function(BuildContext) builder, {
175
- RouteSettings? settings,
175
+ RouteSettings? settings,
176
bool fullscreenDialog = false,
177
}) {
178
if (Platform.isIOS) {
179
- return CupertinoPageRoute<T>(builder: builder, fullscreenDialog: fullscreenDialog, settings: settings);
179
+ return CupertinoPageRoute<T>(
180
+ builder: builder, fullscreenDialog: fullscreenDialog, settings: settings);
181
} else {
181
- return MaterialPageRoute<T>(builder: builder, fullscreenDialog: fullscreenDialog, settings: settings);
182
+ return MaterialPageRoute<T>(
183
+ builder: builder, fullscreenDialog: fullscreenDialog, settings: settings);
184
}
185
}
186
@@ -446,7 +448,9 @@ Route<dynamic> createRoute(RouteSettings settings) {
448
return handleRouteWithPlatformAwareness(
449
(context) => Material(
450
child: getIt.get<NewSendPage>(
449
- param1: SendPageParams(initialPaymentRequest: initialPaymentRequest,unspentCoinType: coinTypeToSpendFrom ?? UnspentCoinType.any),
451
+ param1: SendPageParams(
452
+ initialPaymentRequest: initialPaymentRequest,
453
+ unspentCoinType: coinTypeToSpendFrom ?? UnspentCoinType.any),
454
),
455
),
456
settings: settings,
@@ -457,11 +461,12 @@ Route<dynamic> createRoute(RouteSettings settings) {
461
fullscreenDialog: true, builder: (_) => getIt.get<SendTemplatePage>());
462
463
case Routes.receive:
460
- return CupertinoPageRoute<void>(builder: (context) => getIt.get<ReceivePage>(), settings: settings);
464
+ return CupertinoPageRoute<void>(
465
+ builder: (context) => getIt.get<ReceivePage>(), settings: settings);
466
467
case Routes.addressPage:
463
- return handleRouteWithPlatformAwareness(
464
- (context) => getIt.get<AddressPage>(), settings: settings);
468
+ return handleRouteWithPlatformAwareness((context) => getIt.get<AddressPage>(),
469
+ settings: settings);
470
471
case Routes.transactionDetails:
472
return CupertinoPageRoute<void>(
@@ -586,10 +591,9 @@ Route<dynamic> createRoute(RouteSettings settings) {
591
592
case Routes.securityBackupDuressPin:
593
return handleRouteWithPlatformAwareness(
589
- (context) => getIt.get<SecurityBackupPage>(),
594
+ (context) => getIt.get<SecurityBackupPage>(),
595
);
596
592
-
597
case Routes.privacyPage:
598
return handleRouteWithPlatformAwareness(
599
(context) => getIt.get<PrivacyPage>(),
@@ -616,9 +620,8 @@ Route<dynamic> createRoute(RouteSettings settings) {
620
case Routes.newNode:
621
final args = settings.arguments as Map<String, dynamic>?;
622
final page = getIt.get<NodeCreateOrEditPage>(
619
- param1: args?['editingNode'] as Node?, param2: args?['isSelected'] as bool?);
620
- return CupertinoPageRoute<void>(
621
- builder: (_) => page);
623
+ param1: args?['editingNode'] as Node?, param2: args?['isSelected'] as bool?);
624
+ return CupertinoPageRoute<void>(builder: (_) => page);
625
626
case Routes.login:
627
return CupertinoPageRoute<void>(
@@ -635,9 +638,8 @@ Route<dynamic> createRoute(RouteSettings settings) {
638
case Routes.newPowNode:
639
final args = settings.arguments as Map<String, dynamic>?;
640
final page = getIt.get<PowNodeCreateOrEditPage>(
638
- param1: args?['editingNode'] as Node?, param2: args?['isSelected'] as bool?);
639
- return CupertinoPageRoute<void>(
640
- builder: (_) => page);
641
+ param1: args?['editingNode'] as Node?, param2: args?['isSelected'] as bool?);
642
+ return CupertinoPageRoute<void>(builder: (_) => page);
643
644
case Routes.accountCreation:
645
return CupertinoPageRoute<String>(
@@ -822,7 +824,7 @@ Route<dynamic> createRoute(RouteSettings settings) {
824
final toggleTestnet = args['toggleTestnet'] as Function(bool? val);
825
final restoredWallet = args['restoredWallet'] as RestoredWallet?;
826
825
- final viewModelParam = {'type' : type, 'isPow' : false};
827
+ final viewModelParam = {'type': type, 'isPow': false};
828
829
return handleRouteWithPlatformAwareness(
830
(context) => AdvancedPrivacySettingsPage(
lib/solana/cw_solana.dart
+2
-2
@@ -123,8 +123,8 @@ class CWSolana extends Solana {
123
}
124
125
return (wallet as SolanaWallet).splTokenCurrencies.firstWhere(
126
- (element) => transaction.amount.currency.symbol == element.symbol,
127
- );
126
+ (element) => transaction.amount.currency.symbol == element.symbol,
127
+ );
128
}
129
130
@override
lib/src/screens/Info_page.dart
+1
-1
@@ -26,7 +26,7 @@ abstract class InfoPage extends BasePage {
26
27
@override
28
Widget Function(BuildContext, Widget) get rootWrapper =>
29
- (BuildContext context, Widget scaffold) => GradientBackground(scaffold: scaffold);
29
+ (BuildContext context, Widget scaffold) => GradientBackground(scaffold: scaffold);
30
31
@override
32
Widget? leading(BuildContext context) => null;
lib/src/screens/auth/auth_page.dart
+6
-2
@@ -97,7 +97,7 @@ class AuthPagePinCodeStateImpl extends AuthPageState<AuthPage> {
97
@override
98
void changeProcessText(String text) {
99
dismissFlushBar(_authBar);
100
- _progressBar = createBar<void>(text,context, duration: null)..show(_key.currentContext!);
100
+ _progressBar = createBar<void>(text, context, duration: null)..show(_key.currentContext!);
101
}
102
103
@override
@@ -137,7 +137,11 @@ class AuthPagePinCodeStateImpl extends AuthPageState<AuthPage> {
137
key: _key,
138
appBar: CupertinoNavigationBar(
139
leading: widget.closable
140
- ? ModernButton(size: 36, icon: Icon(Icons.close), onPressed: Navigator.of(context).pop, iconColor: Theme.of(context).colorScheme.onSurfaceVariant)
140
+ ? ModernButton(
141
+ size: 36,
142
+ icon: Icon(Icons.close),
143
+ onPressed: Navigator.of(context).pop,
144
+ iconColor: Theme.of(context).colorScheme.onSurfaceVariant)
145
: Container(),
146
backgroundColor: Theme.of(context).colorScheme.surface,
147
border: null),
lib/src/screens/backup/backup_page.dart
+5
-6
@@ -108,7 +108,7 @@ class BackupPage extends BasePage {
108
}
109
110
void onExportBackup(BuildContext context) {
111
- if(backupViewModelBase.backupPassword.isEmpty) return;
111
+ if (backupViewModelBase.backupPassword.isEmpty) return;
112
showPopUp<void>(
113
context: context,
114
builder: (dialogContext) {
@@ -175,11 +175,10 @@ class BackupPage extends BasePage {
175
}
176
177
Future<void> _saveFile(BackupExportFile backup) async {
178
- String? outputFile = await FilePicker.platform
179
- .saveFile(
180
- dialogTitle: 'Save Your File to desired location',
181
- fileName: backup.name,
182
- lockParentWindow: true);
178
+ String? outputFile = await FilePicker.platform.saveFile(
179
+ dialogTitle: 'Save Your File to desired location',
180
+ fileName: backup.name,
181
+ lockParentWindow: true);
182
183
if (outputFile == null) return;
184
lib/src/screens/backup/edit_backup_password_page.dart
+2
-3
@@ -23,9 +23,8 @@ class _EditBackupPasswordPageState extends State<EditBackupPasswordPage> {
23
void initState() {
24
super.initState();
25
textEditingController.text = widget.editBackupPasswordViewModel.backupPassword;
26
- textEditingController
27
- .addListener(() {
28
- if(textEditingController.text != widget.editBackupPasswordViewModel.backupPassword) {
26
+ textEditingController.addListener(() {
27
+ if (textEditingController.text != widget.editBackupPasswordViewModel.backupPassword) {
28
widget.editBackupPasswordViewModel.backupPassword = textEditingController.text;
29
}
30
});
lib/src/screens/buy/buy_sell_page.dart
+6
-11
@@ -276,8 +276,7 @@ class BuySellPage extends BasePage {
276
(_) => _onWalletNameChange(
277
buySellViewModel, buySellViewModel.cryptoCurrency, cryptoCurrencyKey));
278
279
- reaction(
280
- (_) => buySellViewModel.cryptoCurrency,
279
+ reaction((_) => buySellViewModel.cryptoCurrency,
280
(currency) => _onCurrencyChange(currency, buySellViewModel, cryptoCurrencyKey));
281
282
reaction((_) => buySellViewModel.fiatCurrency,
@@ -360,8 +359,7 @@ class BuySellPage extends BasePage {
359
key.currentState!.changeWalletName(isCurrentTypeWallet ? buySellViewModel.wallet.name : '');
360
361
key.currentState!.changeAddress(
363
- address:
364
- isCurrentTypeWallet ? buySellViewModel.wallet.walletAddresses.addressForBuy : '');
362
+ address: isCurrentTypeWallet ? buySellViewModel.wallet.walletAddresses.addressForBuy : '');
363
364
key.currentState!.changeAmount(amount: '');
365
}
@@ -414,17 +412,14 @@ class BuySellPage extends BasePage {
412
borderColor: Theme.of(context).colorScheme.outlineVariant,
413
onPushPasteButton: (context) async {
414
final domain = cryptoCurrencyKey.currentState!.addressController.text;
417
- final parsed =
418
- await fetchParsedAddress(context, domain, buySellViewModel.cryptoCurrency);
415
+ final parsed = await fetchParsedAddress(context, domain, buySellViewModel.cryptoCurrency);
416
if (parsed.isNotEmpty) {
417
buySellViewModel.cryptoCurrencyAddress = parsed;
418
}
419
},
423
-
420
onPushAddressBookButton: (context) async {
421
final domain = cryptoCurrencyKey.currentState!.addressController.text;
426
- final parsed =
427
- await fetchParsedAddress(context, domain, buySellViewModel.cryptoCurrency);
422
+ final parsed = await fetchParsedAddress(context, domain, buySellViewModel.cryptoCurrency);
423
if (parsed.isNotEmpty) {
424
buySellViewModel.cryptoCurrencyAddress = parsed;
425
}
@@ -554,8 +549,8 @@ class BuySellPage extends BasePage {
549
String domain,
550
CryptoCurrency currency,
551
) async {
557
- final parsedAddresses = await _resolver.resolve(
558
- query: domain, wallet: buySellViewModel.wallet, currency: currency);
552
+ final parsedAddresses =
553
+ await _resolver.resolve(query: domain, wallet: buySellViewModel.wallet, currency: currency);
554
return parsedAddresses.isNotEmpty
555
? parsedAddresses.first.parsedAddressByCurrencyMap[currency] ?? ''
556
: '';
lib/src/screens/buy/webview_page.dart
+2
-3
@@ -78,9 +78,8 @@ class WebViewPageBodyState extends State<WebViewPageBody> {
78
79
return PermissionResponse(
80
resources: request.resources,
81
- action: permissionGranted
82
- ? PermissionResponseAction.GRANT
83
- : PermissionResponseAction.DENY,
81
+ action:
82
+ permissionGranted ? PermissionResponseAction.GRANT : PermissionResponseAction.DENY,
83
);
84
},
85
);
lib/src/screens/connect_device/connect_device_page.dart
+2
-1
@@ -164,7 +164,8 @@ class ConnectDevicePageBodyState extends State<ConnectDevicePageBody> {
164
final isConnected = await widget.hardwareWalletVM.connectDevice(device, widget.walletType);
165
166
WidgetsBinding.instance.addPostFrameCallback((_) {
167
- if (isConnected) widget.onConnectDevice(navigatorKey.currentContext!, widget.hardwareWalletVM);
167
+ if (isConnected)
168
+ widget.onConnectDevice(navigatorKey.currentContext!, widget.hardwareWalletVM);
169
});
170
}
171
lib/src/screens/connect_device/monero_hardware_wallet_options_page.dart
+1
-1
@@ -31,7 +31,7 @@ class _MoneroHardwareWalletOptionsForm extends StatefulWidget {
31
const _MoneroHardwareWalletOptionsForm(this._walletHardwareRestoreVM);
32
33
final WalletHardwareRestoreViewModel _walletHardwareRestoreVM;
34
-
34
+
35
@override
36
_MoneroHardwareWalletOptionsFormState createState() =>
37
_MoneroHardwareWalletOptionsFormState(_walletHardwareRestoreVM);
lib/src/screens/connect_device/widgets/device_tile.dart
+3
-3
@@ -56,9 +56,9 @@ class DeviceTile extends StatelessWidget {
56
child: Text(
57
title,
58
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
59
- fontSize: 20,
60
- fontWeight: FontWeight.w500,
61
- ),
59
+ fontSize: 20,
60
+ fontWeight: FontWeight.w500,
61
+ ),
62
),
63
),
64
),
lib/src/screens/contact/contact_list_page.dart
+30
-30
@@ -41,7 +41,7 @@ class ContactListPage extends BasePage {
41
42
@override
43
Widget? trailing(BuildContext context) {
44
- if(!showAddButton) return SizedBox.shrink();
44
+ if (!showAddButton) return SizedBox.shrink();
45
return MergeSemantics(
46
child: Container(
47
width: 36.0,
@@ -417,32 +417,32 @@ class _ContactListBodyState extends State<ContactListBody> {
417
418
ActionPane _actionPane(BuildContext context, ContactRecord contact) {
419
return ActionPane(
420
- motion: const ScrollMotion(),
421
- extentRatio: 0.4,
422
- children: [
423
- SlidableAction(
424
- onPressed: (_) async => await Navigator.of(context)
425
- .pushNamed(Routes.addressBookAddContact, arguments: contact),
426
- backgroundColor: Theme.of(context).colorScheme.primary,
427
- foregroundColor: Theme.of(context).colorScheme.onSurface,
428
- icon: Icons.edit,
429
- label: S.of(context).edit,
430
- ),
431
- SlidableAction(
432
- onPressed: (_) async {
433
- final isDelete = await DialogService.showAlertDialog(context);
434
-
435
- if (isDelete) {
436
- await widget.contactListViewModel.delete(contact);
437
- }
438
- },
439
- backgroundColor: Theme.of(context).colorScheme.error,
440
- foregroundColor: Theme.of(context).colorScheme.onSurface,
441
- icon: CupertinoIcons.delete,
442
- label: S.of(context).delete,
443
- ),
444
- ],
445
- );
420
+ motion: const ScrollMotion(),
421
+ extentRatio: 0.4,
422
+ children: [
423
+ SlidableAction(
424
+ onPressed: (_) async => await Navigator.of(context)
425
+ .pushNamed(Routes.addressBookAddContact, arguments: contact),
426
+ backgroundColor: Theme.of(context).colorScheme.primary,
427
+ foregroundColor: Theme.of(context).colorScheme.onSurface,
428
+ icon: Icons.edit,
429
+ label: S.of(context).edit,
430
+ ),
431
+ SlidableAction(
432
+ onPressed: (_) async {
433
+ final isDelete = await DialogService.showAlertDialog(context);
434
+
435
+ if (isDelete) {
436
+ await widget.contactListViewModel.delete(contact);
437
+ }
438
+ },
439
+ backgroundColor: Theme.of(context).colorScheme.error,
440
+ foregroundColor: Theme.of(context).colorScheme.onSurface,
441
+ icon: CupertinoIcons.delete,
442
+ label: S.of(context).delete,
443
+ ),
444
+ ],
445
+ );
446
}
447
448
Widget filterButtonWidget(BuildContext context, ContactListViewModel contactListViewModel) {
@@ -525,9 +525,9 @@ class DialogService {
525
textAlign: TextAlign.center,
526
walletType: cryptoCurrencyOrTokenToWalletType(contact.type),
527
evenTextStyle: Theme.of(context).textTheme.bodyMedium!.copyWith(
528
- fontSize: 16,
529
- decoration: TextDecoration.none,
530
- ),
528
+ fontSize: 16,
529
+ decoration: TextDecoration.none,
530
+ ),
531
),
532
rightButtonText: S.of(context).copy,
533
leftButtonText: S.of(context).cancel,
lib/src/screens/contact/contact_page.dart
+17
-16
@@ -24,7 +24,7 @@ class ContactPage extends BasePage {
24
_nameController = TextEditingController(),
25
_addressController = TextEditingController(),
26
_currencyTypeController = TextEditingController(),
27
- addressFocusNode = FocusNode(){
27
+ addressFocusNode = FocusNode() {
28
_nameController.text = contactViewModel.name;
29
_addressController.text = contactViewModel.address;
30
_nameController.addListener(() => contactViewModel.name = _nameController.text);
@@ -38,7 +38,8 @@ class ContactPage extends BasePage {
38
contactViewModel.address = address;
39
});
40
41
- autorun((_) => _currencyTypeController.text = "${contactViewModel.currency?.toString() ?? ""} ${contactViewModel.currency?.tag != null ? "(${contactViewModel.currency?.tag})" : ""}");
41
+ autorun((_) => _currencyTypeController.text =
42
+ "${contactViewModel.currency?.toString() ?? ""} ${contactViewModel.currency?.tag != null ? "(${contactViewModel.currency?.tag})" : ""}");
43
}
44
45
@override
@@ -105,13 +106,13 @@ class ContactPage extends BasePage {
106
builder: (_) {
107
return NewSendAddressInput(
108
focusNode: addressFocusNode,
108
- displayName: contactViewModel.displayName,
109
- addressController: _addressController,
110
- onEditingComplete: () {},
111
- onPushPasteButton: (context) => _extractParsedAddress(context),
112
- validator: AddressValidator(type: contactViewModel.currency!),
113
- selectedCurrency: contactViewModel.currency!,
114
- );
109
+ displayName: contactViewModel.displayName,
110
+ addressController: _addressController,
111
+ onEditingComplete: () {},
112
+ onPushPasteButton: (context) => _extractParsedAddress(context),
113
+ validator: AddressValidator(type: contactViewModel.currency!),
114
+ selectedCurrency: contactViewModel.currency!,
115
+ );
116
},
117
),
118
)
@@ -216,17 +217,17 @@ class ContactPage extends BasePage {
217
}
218
});
219
219
- reaction((_)=>contactViewModel.address, (val){
220
- if(val != _addressController.text) {
220
+ reaction((_) => contactViewModel.address, (val) {
221
+ if (val != _addressController.text) {
222
_addressController.text = val;
223
}
224
});
225
}
226
227
Future<bool> showParsedAddressConfirmationAlert(
227
- BuildContext context,
228
- ParsedAddress parsedAddress,
229
- ) async {
228
+ BuildContext context,
229
+ ParsedAddress parsedAddress,
230
+ ) async {
231
final confirmed = await showPopUp<bool>(
232
context: context,
233
builder: (BuildContext context) {
@@ -237,8 +238,8 @@ class ContactPage extends BasePage {
238
? parsedAddress.addressSource.iconPath
239
: parsedAddress.profileImageUrl,
240
alertContent: S.of(context).extracted_address_content(
240
- '${parsedAddress.handle} (${parsedAddress.addressSource.label})',
241
- ),
241
+ '${parsedAddress.handle} (${parsedAddress.addressSource.label})',
242
+ ),
243
buttonText: S.of(context).ok,
244
buttonAction: () => Navigator.of(context).pop(true),
245
);
lib/src/screens/dashboard/dashboard_page.dart
+3
-4
@@ -305,10 +305,9 @@ class _DashboardPageView extends BasePage {
305
),
306
),
307
NewMainNavBar(
308
- dashboardViewModel: dashboardViewModel,
309
- selectedIndex: 0,
310
- onItemTap: (index) {}
311
- ),
308
+ dashboardViewModel: dashboardViewModel,
309
+ selectedIndex: 0,
310
+ onItemTap: (index) {}),
311
],
312
),
313
],
lib/src/screens/dashboard/desktop_dashboard_page.dart
+1
-1
@@ -121,7 +121,7 @@ class DesktopDashboardPage extends StatelessWidget {
121
if (affectedWalletNames.isNotEmpty) {
122
Future<void>.delayed(
123
Duration(seconds: 1),
124
- () {
124
+ () {
125
showPopUp<void>(
126
context: context,
127
builder: (BuildContext context) {
lib/src/screens/dashboard/desktop_widgets/desktop_action_button.dart
+7
-7
@@ -50,13 +50,13 @@ class DesktopActionButton extends StatelessWidget {
50
AutoSizeText(
51
title,
52
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
53
- fontSize: 24,
54
- fontWeight: FontWeight.bold,
55
- color: isEnabled
56
- ? Theme.of(context).colorScheme.onPrimaryContainer
57
- : Theme.of(context).colorScheme.onSurfaceVariant,
58
- height: 1,
59
- ),
53
+ fontSize: 24,
54
+ fontWeight: FontWeight.bold,
55
+ color: isEnabled
56
+ ? Theme.of(context).colorScheme.onPrimaryContainer
57
+ : Theme.of(context).colorScheme.onSurfaceVariant,
58
+ height: 1,
59
+ ),
60
maxLines: 1,
61
textAlign: TextAlign.center,
62
)
lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_actions.dart
+57
-57
@@ -16,72 +16,72 @@ class DesktopDashboardActions extends StatelessWidget {
16
Widget build(BuildContext context) {
17
return Container(
18
color: Theme.of(context).colorScheme.surface,
19
- child: Observer(
20
- builder: (_) {
21
- return Column(
22
- children: [
23
- const SizedBox(height: 16),
24
- DesktopActionButton(
25
- title: MainActions.showWalletsAction.name(context),
26
- image: MainActions.showWalletsAction.image,
27
- canShow: MainActions.showWalletsAction.canShow?.call(dashboardViewModel),
28
- isEnabled: MainActions.showWalletsAction.isEnabled?.call(dashboardViewModel),
29
- onTap: () async =>
30
- await MainActions.showWalletsAction.onTap(context, dashboardViewModel),
31
- ),
32
- DesktopActionButton(
33
- title: MainActions.swapAction.name(context),
34
- image: MainActions.swapAction.image,
35
- canShow: MainActions.swapAction.canShow?.call(dashboardViewModel),
36
- isEnabled: MainActions.swapAction.isEnabled?.call(dashboardViewModel),
37
- onTap: () async => await MainActions.swapAction.onTap(context, dashboardViewModel),
38
- ),
39
- Row(
40
- children: [
41
- Expanded(
42
- child: DesktopActionButton(
43
- title: MainActions.receiveAction.name(context),
44
- image: MainActions.receiveAction.image,
45
- canShow: MainActions.receiveAction.canShow?.call(dashboardViewModel),
46
- isEnabled: MainActions.receiveAction.isEnabled?.call(dashboardViewModel),
47
- onTap: () async =>
48
- await MainActions.receiveAction.onTap(context, dashboardViewModel),
49
- ),
19
+ child: Observer(builder: (_) {
20
+ return Column(
21
+ children: [
22
+ const SizedBox(height: 16),
23
+ DesktopActionButton(
24
+ title: MainActions.showWalletsAction.name(context),
25
+ image: MainActions.showWalletsAction.image,
26
+ canShow: MainActions.showWalletsAction.canShow?.call(dashboardViewModel),
27
+ isEnabled: MainActions.showWalletsAction.isEnabled?.call(dashboardViewModel),
28
+ onTap: () async =>
29
+ await MainActions.showWalletsAction.onTap(context, dashboardViewModel),
30
+ ),
31
+ DesktopActionButton(
32
+ title: MainActions.swapAction.name(context),
33
+ image: MainActions.swapAction.image,
34
+ canShow: MainActions.swapAction.canShow?.call(dashboardViewModel),
35
+ isEnabled: MainActions.swapAction.isEnabled?.call(dashboardViewModel),
36
+ onTap: () async => await MainActions.swapAction.onTap(context, dashboardViewModel),
37
+ ),
38
+ Row(
39
+ children: [
40
+ Expanded(
41
+ child: DesktopActionButton(
42
+ title: MainActions.receiveAction.name(context),
43
+ image: MainActions.receiveAction.image,
44
+ canShow: MainActions.receiveAction.canShow?.call(dashboardViewModel),
45
+ isEnabled: MainActions.receiveAction.isEnabled?.call(dashboardViewModel),
46
+ onTap: () async =>
47
+ await MainActions.receiveAction.onTap(context, dashboardViewModel),
48
),
51
- Expanded(
52
- child: DesktopActionButton(
53
- title: MainActions.sendAction.name(context),
54
- image: MainActions.sendAction.image,
55
- canShow: MainActions.sendAction.canShow?.call(dashboardViewModel),
56
- isEnabled: MainActions.sendAction.isEnabled?.call(dashboardViewModel),
57
- onTap: () async => await MainActions.sendAction.onTap(context, dashboardViewModel),
58
- ),
49
+ ),
50
+ Expanded(
51
+ child: DesktopActionButton(
52
+ title: MainActions.sendAction.name(context),
53
+ image: MainActions.sendAction.image,
54
+ canShow: MainActions.sendAction.canShow?.call(dashboardViewModel),
55
+ isEnabled: MainActions.sendAction.isEnabled?.call(dashboardViewModel),
56
+ onTap: () async =>
57
+ await MainActions.sendAction.onTap(context, dashboardViewModel),
58
),
60
- ],
61
- ),
62
- Row(
63
- children: [
64
- Expanded(
65
- child: DesktopActionButton(
66
- title: MainActions.tradeAction.name(context),
67
- image: MainActions.tradeAction.image,
68
- canShow: MainActions.tradeAction.canShow?.call(dashboardViewModel),
69
- isEnabled: MainActions.tradeAction.isEnabled?.call(dashboardViewModel),
70
- onTap: () async => await MainActions.tradeAction.onTap(context, dashboardViewModel),
71
- ),
59
+ ),
60
+ ],
61
+ ),
62
+ Row(
63
+ children: [
64
+ Expanded(
65
+ child: DesktopActionButton(
66
+ title: MainActions.tradeAction.name(context),
67
+ image: MainActions.tradeAction.image,
68
+ canShow: MainActions.tradeAction.canShow?.call(dashboardViewModel),
69
+ isEnabled: MainActions.tradeAction.isEnabled?.call(dashboardViewModel),
70
+ onTap: () async =>
71
+ await MainActions.tradeAction.onTap(context, dashboardViewModel),
72
),
73
- ],
74
- ),
73
+ ),
74
+ ],
75
+ ),
76
Expanded(
77
child: CakeFeaturesPage(
78
dashboardViewModel: dashboardViewModel,
79
cakeFeaturesViewModel: getIt.get<CakeFeaturesViewModel>(),
80
),
81
),
81
- ],
82
- );
83
- }
84
- ),
82
+ ],
83
+ );
84
+ }),
85
);
86
}
87
}
lib/src/screens/dashboard/desktop_widgets/desktop_dashboard_navbar.dart
+1
-2
@@ -20,7 +20,6 @@ class DesktopDashboardNavbar extends StatelessWidget implements ObstructingPrefe
20
21
@override
22
Widget build(BuildContext context) {
23
-
23
return Container(
24
padding: const EdgeInsetsDirectional.only(end: 24),
25
color: Theme.of(context).colorScheme.surfaceContainerLowest.withOpacity(0.1),
@@ -40,7 +39,7 @@ class DesktopDashboardNavbar extends StatelessWidget implements ObstructingPrefe
39
40
@override
41
Size get preferredSize => Size.fromHeight(60);
43
-
42
+
43
@override
44
bool shouldFullyObstruct(BuildContext context) => false;
45
}
lib/src/screens/dashboard/desktop_widgets/desktop_sidebar/side_menu.dart
+1
-1
@@ -8,7 +8,7 @@ class SideMenu extends StatelessWidget {
8
required this.bottomItems,
9
required this.width,
10
});
11
-
11
+
12
final List<SideMenuItem> topItems;
13
final List<SideMenuItem> bottomItems;
14
final double width;
lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart
+23
-12
@@ -31,25 +31,36 @@ class DesktopWalletSelectionDropDown extends StatefulWidget {
31
}
32
33
class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionDropDown> {
34
- final moneroIcon = Image.asset('assets/new-ui/crypto_full_icons/monero.svg', height: 24, width: 24);
35
- final bitcoinIcon = Image.asset('assets/new-ui/crypto_full_icons/bitcoin.svg', height: 24, width: 24);
34
+ final moneroIcon =
35
+ Image.asset('assets/new-ui/crypto_full_icons/monero.svg', height: 24, width: 24);
36
+ final bitcoinIcon =
37
+ Image.asset('assets/new-ui/crypto_full_icons/bitcoin.svg', height: 24, width: 24);
38
final tBitcoinIcon = Image.asset('assets/images/tbtc.png', height: 24, width: 24);
37
- final litecoinIcon = Image.asset('assets/new-ui/crypto_full_icons/litecoin.svg', height: 24, width: 24);
39
+ final litecoinIcon =
40
+ Image.asset('assets/new-ui/crypto_full_icons/litecoin.svg', height: 24, width: 24);
41
final havenIcon = Image.asset('assets/images/haven_logo.webp', height: 24, width: 24);
39
- final ethereumIcon = Image.asset('assets/new-ui/crypto_full_icons/ethereum.svg', height: 24, width: 24);
40
- final polygonIcon = Image.asset('assets/new-ui/crypto_full_icons/polygon.svg', height: 24, width: 24);
41
- final bitcoinCashIcon = Image.asset('assets/new-ui/crypto_full_icons/bitcoin-cash.svg', height: 24, width: 24);
42
+ final ethereumIcon =
43
+ Image.asset('assets/new-ui/crypto_full_icons/ethereum.svg', height: 24, width: 24);
44
+ final polygonIcon =
45
+ Image.asset('assets/new-ui/crypto_full_icons/polygon.svg', height: 24, width: 24);
46
+ final bitcoinCashIcon =
47
+ Image.asset('assets/new-ui/crypto_full_icons/bitcoin-cash.svg', height: 24, width: 24);
48
final baseIcon = Image.asset('assets/new-ui/crypto_full_icons/base.svg', height: 24, width: 24);
43
- final arbitrumIcon = Image.asset('assets/new-ui/crypto_full_icons/arbitrum.svg', height: 24, width: 24);
49
+ final arbitrumIcon =
50
+ Image.asset('assets/new-ui/crypto_full_icons/arbitrum.svg', height: 24, width: 24);
51
final bscIcon = Image.asset('assets/new-ui/crypto_full_icons/bnb.svg', height: 24, width: 24);
52
final nanoIcon = Image.asset('assets/new-ui/crypto_full_icons/nano.svg', height: 24, width: 24);
53
final bananoIcon = Image.asset('assets/new-ui/crypto_full_icons/nano.svg', height: 24, width: 24);
47
- final solanaIcon = Image.asset('assets/new-ui/crypto_full_icons/solana.svg', height: 24, width: 24);
54
+ final solanaIcon =
55
+ Image.asset('assets/new-ui/crypto_full_icons/solana.svg', height: 24, width: 24);
56
final tronIcon = Image.asset('assets/new-ui/crypto_full_icons/tron.svg', height: 24, width: 24);
49
- final wowneroIcon = Image.asset('assets/new-ui/crypto_full_icons/wownero.svg', height: 24, width: 24);
57
+ final wowneroIcon =
58
+ Image.asset('assets/new-ui/crypto_full_icons/wownero.svg', height: 24, width: 24);
59
final zanoIcon = Image.asset('assets/new-ui/crypto_full_icons/zano.svg', height: 24, width: 24);
51
- final decredIcon = Image.asset('assets/new-ui/crypto_full_icons/decred.svg', height: 24, width: 24);
52
- final dogeIcon = Image.asset('assets/new-ui/crypto_full_icons/dogecoin.svg', height: 24, width: 24);
60
+ final decredIcon =
61
+ Image.asset('assets/new-ui/crypto_full_icons/decred.svg', height: 24, width: 24);
62
+ final dogeIcon =
63
+ Image.asset('assets/new-ui/crypto_full_icons/dogecoin.svg', height: 24, width: 24);
64
final zcashIcon = Image.asset('assets/new-ui/crypto_full_icons/zcash.svg', height: 24, width: 24);
65
final nonWalletTypeIcon = Image.asset('assets/images/close.png', height: 24, width: 24);
66
@@ -264,7 +275,7 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
275
}
276
277
void changeProcessText(String text) {
267
- _progressBar = createBar<void>(text,context, duration: null)..show(context);
278
+ _progressBar = createBar<void>(text, context, duration: null)..show(context);
279
}
280
281
void hideProgressText() {
lib/src/screens/dashboard/favorite_token_modal.dart
+2
-3
@@ -14,9 +14,8 @@ class FavoriteTokenModal extends StatelessWidget {
14
Widget build(BuildContext context) {
15
return Container(
16
decoration: BoxDecoration(
17
- color: Theme.of(context).colorScheme.surface,
18
- borderRadius: BorderRadius.vertical(top: Radius.circular(18))
19
- ),
17
+ color: Theme.of(context).colorScheme.surface,
18
+ borderRadius: BorderRadius.vertical(top: Radius.circular(18))),
19
child: SafeArea(
20
child: Column(
21
children: [
lib/src/screens/dashboard/pages/balance/balance_page.dart
+2
-1
@@ -22,7 +22,8 @@ class BalancePage extends StatelessWidget {
22
Widget build(BuildContext context) {
23
return Observer(
24
builder: (context) {
25
- final isNFTActivated = isNFTACtivatedChain(dashboardViewModel.type, chainId: dashboardViewModel.wallet.chainId);
25
+ final isNFTActivated = isNFTACtivatedChain(dashboardViewModel.type,
26
+ chainId: dashboardViewModel.wallet.chainId);
27
return DefaultTabController(
28
key: ValueKey<bool>(isNFTActivated),
29
length: isNFTActivated ? 2 : 1,
lib/src/screens/dashboard/pages/balance/crypto_balance_widget.dart
+5
-5
@@ -334,7 +334,7 @@ class CryptoBalanceWidget extends StatelessWidget {
334
),
335
),
336
],
337
- if (dashboardViewModel.showZcashMissingFundsCard) ...[
337
+ if (dashboardViewModel.showZcashMissingFundsCard) ...[
338
SizedBox(height: 10),
339
Padding(
340
padding: const EdgeInsets.fromLTRB(16, 0, 16, 8),
@@ -349,7 +349,8 @@ class CryptoBalanceWidget extends StatelessWidget {
349
hintWidget: GestureDetector(
350
behavior: HitTestBehavior.opaque,
351
onTap: () => launchUrl(
352
- Uri.parse("https://docs.cakewallet.com/tutorials/zashi/#creating-a-new-zcash-wallet-on-cake"),
352
+ Uri.parse(
353
+ "https://docs.cakewallet.com/tutorials/zashi/#creating-a-new-zcash-wallet-on-cake"),
354
mode: LaunchMode.externalApplication,
355
),
356
child: Text(
@@ -492,7 +493,7 @@ class CryptoBalanceWidget extends StatelessWidget {
493
}
494
dashboardViewModel.setMwebEnabled();
495
}
495
-
496
+
497
Future<void> _rescanInternalChangeZcash(BuildContext context) async {
498
dashboardViewModel.rescanInternalChangeZcash();
499
await showPopUp<void>(
@@ -507,7 +508,6 @@ class CryptoBalanceWidget extends StatelessWidget {
508
),
509
);
510
}
510
-
511
512
Future<void> _dismissMweb(BuildContext context) async {
513
await showPopUp<void>(
@@ -522,7 +522,7 @@ class CryptoBalanceWidget extends StatelessWidget {
522
));
523
dashboardViewModel.dismissMweb();
524
}
525
-
525
+
526
Future<void> _dismissZcash(BuildContext context) async {
527
await showPopUp<void>(
528
context: context,
lib/src/screens/dashboard/pages/cake_features_page.dart
+35
-31
@@ -27,27 +27,27 @@ class CakeFeaturesPage extends StatelessWidget {
27
Widget build(BuildContext context) {
28
return GradientBackground(
29
scaffold: SafeArea(
30
- child: Column(
31
- crossAxisAlignment: CrossAxisAlignment.start,
32
- children: [
33
- _buildHeader(context),
34
- Expanded(
35
- child: LayoutBuilder(
36
- builder: (context, constraints) {
37
- return SingleChildScrollView(
38
- child: ConstrainedBox(
39
- constraints: BoxConstraints(minHeight: constraints.maxHeight),
40
- child: IntrinsicHeight(
41
- child: !FeatureFlag.hasNewUi ? _buildOldUi(context) : _buildNewUi(context),
42
- ),
30
+ child: Column(
31
+ crossAxisAlignment: CrossAxisAlignment.start,
32
+ children: [
33
+ _buildHeader(context),
34
+ Expanded(
35
+ child: LayoutBuilder(
36
+ builder: (context, constraints) {
37
+ return SingleChildScrollView(
38
+ child: ConstrainedBox(
39
+ constraints: BoxConstraints(minHeight: constraints.maxHeight),
40
+ child: IntrinsicHeight(
41
+ child: !FeatureFlag.hasNewUi ? _buildOldUi(context) : _buildNewUi(context),
42
),
44
- );
45
- },
46
- ),
43
+ ),
44
+ );
45
+ },
46
),
48
- ],
49
- ),
47
+ ),
48
+ ],
49
),
50
+ ),
51
);
52
}
53
@@ -58,9 +58,9 @@ class CakeFeaturesPage extends StatelessWidget {
58
child: Text(
59
S.of(context).apps,
60
style: Theme.of(context).textTheme.headlineLarge?.copyWith(
61
- fontWeight: FontWeight.w500,
62
- color: Theme.of(context).colorScheme.onSurface,
63
- ),
61
+ fontWeight: FontWeight.w500,
62
+ color: Theme.of(context).colorScheme.onSurface,
63
+ ),
64
),
65
);
66
}
@@ -72,10 +72,10 @@ class CakeFeaturesPage extends StatelessWidget {
72
child: Text(
73
S.of(context).apps,
74
style: Theme.of(context).textTheme.titleLarge?.copyWith(
75
- fontSize: 18.0,
76
- fontWeight: FontWeight.w600,
77
- color: Theme.of(context).colorScheme.onSurface,
78
- ),
75
+ fontSize: 18.0,
76
+ fontWeight: FontWeight.w600,
77
+ color: Theme.of(context).colorScheme.onSurface,
78
+ ),
79
),
80
),
81
);
@@ -101,7 +101,8 @@ class CakeFeaturesPage extends StatelessWidget {
101
onTap: () => Navigator.of(context).pushNamed(Routes.dEuroSavings),
102
title: S.of(context).deuro_savings,
103
subTitle: S.of(context).deuro_savings_subtitle,
104
- image: Image.asset('assets/images/deuro_icon.png', height: 80, width: 80, fit: BoxFit.cover),
104
+ image: Image.asset('assets/images/deuro_icon.png',
105
+ height: 80, width: 80, fit: BoxFit.cover),
106
);
107
}
108
return const SizedBox();
@@ -128,7 +129,10 @@ class CakeFeaturesPage extends StatelessWidget {
129
alignment: Alignment.centerLeft,
130
child: Padding(
131
padding: const EdgeInsets.only(left: 24, bottom: 8),
131
- child: CakeImageWidget(imageUrl: "assets/new-ui/by-cakelabs.svg", height: 20, color: Theme.of(context).colorScheme.onSurfaceVariant),
132
+ child: CakeImageWidget(
133
+ imageUrl: "assets/new-ui/by-cakelabs.svg",
134
+ height: 20,
135
+ color: Theme.of(context).colorScheme.onSurfaceVariant),
136
),
137
),
138
AppsWidget(
@@ -163,9 +167,9 @@ class CakeFeaturesPage extends StatelessWidget {
167
child: Text(
168
"Featured Apps",
169
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
166
- fontWeight: FontWeight.w500,
167
- color: Theme.of(context).colorScheme.onSurface,
168
- ),
170
+ fontWeight: FontWeight.w500,
171
+ color: Theme.of(context).colorScheme.onSurface,
172
+ ),
173
),
174
),
175
AppsWidget(
@@ -225,4 +229,4 @@ class CakeFeaturesPage extends StatelessWidget {
229
Navigator.pushNamed(context, Routes.cakePayCardsPage);
230
}
231
}
228
-}
\ No newline at end of file
232
+}
lib/src/screens/dashboard/pages/navigation_dock.dart
+8
-19
@@ -42,39 +42,28 @@ class NavigationDock extends StatelessWidget {
42
mainAxisAlignment: MainAxisAlignment.spaceBetween,
43
crossAxisAlignment: CrossAxisAlignment.center,
44
children: MainActions.all
45
- .where((element) =>
46
- element.canShow?.call(dashboardViewModel) ??
47
- true)
45
+ .where((element) => element.canShow?.call(dashboardViewModel) ?? true)
46
.map(
47
(action) => Expanded(
48
child: Semantics(
49
button: true,
52
- enabled: (action.isEnabled
53
- ?.call(dashboardViewModel) ??
54
- true),
50
+ enabled: (action.isEnabled?.call(dashboardViewModel) ?? true),
51
child: ActionButton(
52
key: action.key,
53
image: Image.asset(
54
action.image,
55
height: 24,
56
width: 24,
61
- color:
62
- Theme.of(context).colorScheme.primary,
57
+ color: Theme.of(context).colorScheme.primary,
58
),
59
title: action.name(context),
65
- onClick: (action.isEnabled
66
- ?.call(dashboardViewModel) ??
67
- true)
68
- ? () async => await action.onTap(
69
- context, dashboardViewModel)
60
+ onClick: (action.isEnabled?.call(dashboardViewModel) ?? true)
61
+ ? () async =>
62
+ await action.onTap(context, dashboardViewModel)
63
: null,
71
- textColor: action.isEnabled
72
- ?.call(dashboardViewModel) ??
73
- true
64
+ textColor: action.isEnabled?.call(dashboardViewModel) ?? true
65
? null
75
- : Theme.of(context)
76
- .colorScheme
77
- .onSurface,
66
+ : Theme.of(context).colorScheme.onSurface,
67
),
68
),
69
),
lib/src/screens/dashboard/pages/nft_listing_page.dart
+2
-4
@@ -94,8 +94,7 @@ class NFTListWidget extends StatelessWidget {
94
if (nftViewModel.solanaNftAssetModels.isEmpty) return emptyMessage;
95
96
return Padding(
97
- padding: EdgeInsets.only(
98
- bottom: 64),
97
+ padding: EdgeInsets.only(bottom: 64),
98
child: ListView.separated(
99
shrinkWrap: true,
100
physics: NeverScrollableScrollPhysics(),
@@ -112,8 +111,7 @@ class NFTListWidget extends StatelessWidget {
111
if (nftViewModel.nftAssetByWalletModels.isEmpty) return emptyMessage;
112
113
return Padding(
115
- padding: EdgeInsets.only(
116
- bottom: 64),
114
+ padding: EdgeInsets.only(bottom: 64),
115
child: ListView.separated(
116
shrinkWrap: true,
117
physics: NeverScrollableScrollPhysics(),
lib/src/screens/dashboard/pages/transactions_page.dart
+4
-5
@@ -66,8 +66,7 @@ class TransactionsPage extends StatelessWidget {
66
}),
67
HeaderRow(
68
dashboardViewModel: dashboardViewModel,
69
- onExportCsv: () =>
70
- CsvExportService().exportToCsv(dashboardViewModel.items, context),
69
+ onExportCsv: () => CsvExportService().exportToCsv(dashboardViewModel.items, context),
70
key: ValueKey('transactions_page_header_row_key'),
71
),
72
Expanded(
@@ -159,7 +158,8 @@ class TransactionsPage extends StatelessWidget {
158
currency: "BTC",
159
state: item.status,
160
amount: dashboardViewModel.appStore.amountParsingProxy
162
- .getDisplayCryptoString(session.amount.toInt(), CryptoCurrency.btc),
161
+ .getDisplayCryptoString(
162
+ session.amount.toInt(), CryptoCurrency.btc),
163
createdAt: DateFormat('HH:mm').format(session.inProgressSince!),
164
isSending: session.isSenderSession,
165
);
@@ -168,8 +168,7 @@ class TransactionsPage extends StatelessWidget {
168
if (item is TradeListItem) {
169
final trade = item.trade;
170
171
- final tradeFrom =
172
- trade.from;
171
+ final tradeFrom = trade.from;
172
173
final tradeTo = trade.to;
174
lib/src/screens/dashboard/sign_page.dart
+6
-8
@@ -17,10 +17,8 @@ import 'package:smooth_page_indicator/smooth_page_indicator.dart';
17
class SignPage extends StatefulWidget {
18
SignPage(this.signViewModel);
19
20
-
20
final SignViewModel signViewModel;
21
23
-
22
@override
23
State<SignPage> createState() => _SignPageState();
24
}
@@ -29,7 +27,7 @@ class _SignPageState extends State<SignPage> {
27
List<Widget> _pages = [];
28
final signFormKey = GlobalKey<SignFormState>();
29
final verifyFormKey = GlobalKey<VerifyFormState>();
32
- final PageController _controller = PageController(initialPage: 0) ;
30
+ final PageController _controller = PageController(initialPage: 0);
31
32
bool _isEffectsInstalled = false;
33
@@ -55,14 +53,14 @@ class _SignPageState extends State<SignPage> {
53
return Container(
54
color: Theme.of(context).colorScheme.surface,
55
child: SafeArea(
58
- top:false,
56
+ top: false,
57
child: Column(
58
children: [
61
- ModalTopBar(title: S.current.sign_verify_title,
59
+ ModalTopBar(
60
+ title: S.current.sign_verify_title,
61
leadingIcon: Icon(Icons.arrow_back_ios_new),
63
- onLeadingPressed: Navigator
64
- .of(context)
65
- .pop,),
62
+ onLeadingPressed: Navigator.of(context).pop,
63
+ ),
64
Expanded(
65
child: KeyboardHideOverlay(
66
child: Container(
lib/src/screens/dashboard/widgets/action_button.dart
+1
-2
@@ -53,8 +53,7 @@ class ActionButton extends StatelessWidget {
53
softWrap: false,
54
textAlign: TextAlign.center,
55
style: Theme.of(context).textTheme.labelSmall?.copyWith(
56
- color: textColor ??
57
- Theme.of(context).colorScheme.onSurface,
56
+ color: textColor ?? Theme.of(context).colorScheme.onSurface,
57
),
58
),
59
),
lib/src/screens/dashboard/widgets/date_section_raw.dart
+2
-2
@@ -17,8 +17,8 @@ class DateSectionRaw extends StatelessWidget {
17
child: Text(
18
title,
19
style: Theme.of(context).textTheme.bodySmall?.copyWith(
20
- color: Theme.of(context).colorScheme.onSurfaceVariant,
21
- ),
20
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
21
+ ),
22
),
23
);
24
}
lib/src/screens/dashboard/widgets/filter_tile.dart
+1
-1
@@ -13,4 +13,4 @@ class FilterTile extends StatelessWidget {
13
child: child,
14
);
15
}
16
-}
\ No newline at end of file
16
+}
lib/src/screens/dashboard/widgets/filter_widget.dart
+10
-9
@@ -71,9 +71,9 @@ class _FilterWidgetState extends State<FilterWidget> {
71
child: Text(
72
S.of(context).filter_by,
73
style: Theme.of(context).textTheme.titleMedium?.copyWith(
74
- color: Theme.of(context).colorScheme.onSurface,
75
- fontWeight: FontWeight.bold,
76
- ),
74
+ color: Theme.of(context).colorScheme.onSurface,
75
+ fontWeight: FontWeight.bold,
76
+ ),
77
),
78
),
79
),
@@ -97,14 +97,15 @@ class _FilterWidgetState extends State<FilterWidget> {
97
child: Text(
98
title,
99
style: Theme.of(context).textTheme.titleMedium?.copyWith(
100
- color: Theme.of(context).colorScheme.onSurface,
101
- fontWeight: FontWeight.bold,
102
- decoration: TextDecoration.none,
103
- ),
100
+ color: Theme.of(context).colorScheme.onSurface,
101
+ fontWeight: FontWeight.bold,
102
+ decoration: TextDecoration.none,
103
+ ),
104
),
105
),
106
ListView.builder(
107
- padding: const EdgeInsets.symmetric(horizontal: 28.0, vertical: 8.0),
107
+ padding:
108
+ const EdgeInsets.symmetric(horizontal: 28.0, vertical: 8.0),
109
shrinkWrap: true,
110
physics: const NeverScrollableScrollPhysics(),
111
itemCount: section.length,
@@ -138,4 +139,4 @@ class _FilterWidgetState extends State<FilterWidget> {
139
),
140
);
141
}
141
-}
\ No newline at end of file
142
+}
lib/src/screens/dashboard/widgets/header_row.dart
+3
-5
@@ -26,8 +26,7 @@ class HeaderRow extends StatelessWidget {
26
Text(
27
S.of(context).history,
28
style: Theme.of(context).textTheme.titleLarge?.copyWith(
29
- fontWeight: FontWeight.w500,
30
- color: Theme.of(context).colorScheme.onSurface),
29
+ fontWeight: FontWeight.w500, color: Theme.of(context).colorScheme.onSurface),
30
),
31
Row(
32
children: [
@@ -61,8 +60,7 @@ class HeaderRow extends StatelessWidget {
60
container: true,
61
child: GestureDetector(
62
key: ValueKey('transactions_page_header_row_transaction_filter_button_key'),
64
- onTap: () {
65
- },
63
+ onTap: () {},
64
child: Semantics(
65
label: 'Transaction Filter',
66
button: true,
@@ -85,4 +83,4 @@ class HeaderRow extends StatelessWidget {
83
),
84
);
85
}
88
-}
\ No newline at end of file
86
+}
lib/src/screens/dashboard/widgets/new_main_navbar_widget.dart
+98
-95
@@ -27,8 +27,6 @@ class NewMainNavBar extends StatefulWidget {
27
}
28
29
class _NEWNewMainNavBarState extends State<NewMainNavBar> {
30
-
31
-
30
static const iconBoxWidth = 48.0;
31
static const iconWidth = 28.0;
32
static const iconHeight = 28.0;
@@ -82,9 +80,7 @@ class _NEWNewMainNavBarState extends State<NewMainNavBar> {
80
}
81
82
// Estimate pill width based on text length
85
- double _estimatePillWidthForAction(
86
- BuildContext context, NewMainActions action,
87
- {Color? color}) {
83
+ double _estimatePillWidthForAction(BuildContext context, NewMainActions action, {Color? color}) {
84
final text = action.name(context);
85
final textPainter = TextPainter(
86
text: TextSpan(
@@ -94,10 +90,7 @@ class _NEWNewMainNavBarState extends State<NewMainNavBar> {
90
maxLines: 1,
91
textDirection: TextDirection.ltr,
92
)..layout();
97
- return pillIconWidth +
98
- pillIconSpacing +
99
- textPainter.width +
100
- pillHorizontalPadding;
93
+ return pillIconWidth + pillIconSpacing + textPainter.width + pillHorizontalPadding;
94
}
95
96
double calcLeft(int index, double pillWidth) {
@@ -113,7 +106,11 @@ class _NEWNewMainNavBarState extends State<NewMainNavBar> {
106
}
107
108
double calcBarWidth(double pillWidth, int visibleActionsLength) {
116
- return (iconWidth + iconHorizontalPadding) * visibleActionsLength + (pillWidth - iconWidth) + barHorizontalPadding + pillIconSpacing / double.infinity - 2;
109
+ return (iconWidth + iconHorizontalPadding) * visibleActionsLength +
110
+ (pillWidth - iconWidth) +
111
+ barHorizontalPadding +
112
+ pillIconSpacing / double.infinity -
113
+ 2;
114
}
115
116
@override
@@ -138,86 +135,92 @@ class _NEWNewMainNavBarState extends State<NewMainNavBar> {
135
final currentAction = visibleActions[widget.selectedIndex];
136
137
return Align(
141
- alignment: Alignment.bottomCenter,
142
- child: SafeArea(
143
- bottom: !(Platform.isIOS),
144
- top: false,
145
- child: Padding(
146
- // tux PLEASE consult me (malik) before removing this padding.
147
- padding: EdgeInsets.only(bottom: NewMainNavBar.barBottomPadding),
148
- child: AnimatedContainer(
149
- duration: barResizeDuration,
150
- curve: Curves.easeOutCubic,
151
- width: barWidth,
152
- child: ClipRSuperellipse(
153
- borderRadius: BorderRadius.circular(barBorderRadius),
154
- child: BackdropFilter(
155
- filter: ImageFilter.blur(sigmaX: 3, sigmaY: 3),
156
- child: Container(
157
- height: NewMainNavBar.barHeight,
158
- decoration: ShapeDecoration(
159
- color: backgroundColor,
160
- shape: RoundedSuperellipseBorder(borderRadius: BorderRadius.circular(barBorderRadius),
161
- side: const BorderSide(color: Color(0x14FFFFFF), width: 1),
138
+ alignment: Alignment.bottomCenter,
139
+ child: SafeArea(
140
+ bottom: !(Platform.isIOS),
141
+ top: false,
142
+ child: Padding(
143
+ // tux PLEASE consult me (malik) before removing this padding.
144
+ padding: EdgeInsets.only(bottom: NewMainNavBar.barBottomPadding),
145
+ child: AnimatedContainer(
146
+ duration: barResizeDuration,
147
+ curve: Curves.easeOutCubic,
148
+ width: barWidth,
149
+ child: ClipRSuperellipse(
150
+ borderRadius: BorderRadius.circular(barBorderRadius),
151
+ child: BackdropFilter(
152
+ filter: ImageFilter.blur(sigmaX: 3, sigmaY: 3),
153
+ child: Container(
154
+ height: NewMainNavBar.barHeight,
155
+ decoration: ShapeDecoration(
156
+ color: backgroundColor,
157
+ shape: RoundedSuperellipseBorder(
158
+ borderRadius: BorderRadius.circular(barBorderRadius),
159
+ side: const BorderSide(color: Color(0x14FFFFFF), width: 1),
160
+ ),
161
),
163
- ),
164
- child: Padding(
165
- padding: const EdgeInsets.symmetric(horizontal: barHorizontalPadding),
166
- child: Stack(
167
- alignment: Alignment.center,
168
- children: [
169
- AnimatedPill(
170
- left: calcLeft(widget.selectedIndex, pillWidth),
171
- pillColor: pillColor,
172
- currentAction: currentAction,
173
- pillIconHeight: pillIconHeight,
174
- pillIconWidth: pillIconWidth,
175
- pillIconSpacing: pillIconSpacing,
176
- pillBorderRadius: pillBorderRadius,
177
- contentColor: activeColor,
178
- estimateWidthForAction: pillWidth,
179
- pillTextStyle: pillTextStyle,
180
- pillMoveDuration: pillMoveDuration,
181
- pillResizeDuration: pillResizeDuration,
182
- ),
183
- for (int i = 0; i < visibleActions.length; i++)
184
- AnimatedPositioned(
185
- duration: pillResizeDuration,
186
- width: iconBoxWidth,
187
- left: calcLeft(i, pillWidth)+((i == widget.selectedIndex) ? iconHorizontalPadding/100 : 0),
188
- curve: Curves.easeOutCubic,
189
- child: InkWell(
190
- splashFactory: NoSplash.splashFactory,
191
- splashColor: Colors.transparent,
192
- borderRadius: BorderRadius.circular(pillBorderRadius),
193
- onTap: () => _onItemTap(i),
194
- child: AnimatedContainer(
195
- duration: _firstFrame
196
- ? Duration.zero
197
- : inactiveIconMoveDuration,
198
- curve: Curves.easeOutCubic,
199
- width:
200
- i == widget.selectedIndex ? pillWidth : iconBoxWidth,
201
- alignment: Alignment.center,
202
- child: AnimatedAlign(
203
- duration: inactiveIconFadeDuration,
162
+ child: Padding(
163
+ padding: const EdgeInsets.symmetric(horizontal: barHorizontalPadding),
164
+ child: Stack(
165
+ alignment: Alignment.center,
166
+ children: [
167
+ AnimatedPill(
168
+ left: calcLeft(widget.selectedIndex, pillWidth),
169
+ pillColor: pillColor,
170
+ currentAction: currentAction,
171
+ pillIconHeight: pillIconHeight,
172
+ pillIconWidth: pillIconWidth,
173
+ pillIconSpacing: pillIconSpacing,
174
+ pillBorderRadius: pillBorderRadius,
175
+ contentColor: activeColor,
176
+ estimateWidthForAction: pillWidth,
177
+ pillTextStyle: pillTextStyle,
178
+ pillMoveDuration: pillMoveDuration,
179
+ pillResizeDuration: pillResizeDuration,
180
+ ),
181
+ for (int i = 0; i < visibleActions.length; i++)
182
+ AnimatedPositioned(
183
+ duration: pillResizeDuration,
184
+ width: iconBoxWidth,
185
+ left: calcLeft(i, pillWidth) +
186
+ ((i == widget.selectedIndex)
187
+ ? iconHorizontalPadding / 100
188
+ : 0),
189
+ curve: Curves.easeOutCubic,
190
+ child: InkWell(
191
+ splashFactory: NoSplash.splashFactory,
192
+ splashColor: Colors.transparent,
193
+ borderRadius: BorderRadius.circular(pillBorderRadius),
194
+ onTap: () => _onItemTap(i),
195
+ child: AnimatedContainer(
196
+ duration:
197
+ _firstFrame ? Duration.zero : inactiveIconMoveDuration,
198
curve: Curves.easeOutCubic,
199
+ width: i == widget.selectedIndex ? pillWidth : iconBoxWidth,
200
alignment: Alignment.center,
206
- child: AnimatedScale(
207
- duration: inactiveIconAppearDuration,
201
+ child: AnimatedAlign(
202
+ duration: inactiveIconFadeDuration,
203
curve: Curves.easeOutCubic,
209
- scale: (i == widget.selectedIndex) ? 0.857 : 1.0,
210
- child: TweenAnimationBuilder<Color?>(
211
- tween: ColorTween(
212
- begin: (i == widget.selectedIndex) ? inactiveColor : activeColor,
213
- end: (i==widget.selectedIndex) ? activeColor : inactiveColor,
214
- ),
215
- duration: iconColorChangeDuration,
216
- builder: (context, value, child) {
217
- return Container(
218
- height: NewMainNavBar.barHeight,
219
- child: CakeImageWidget(imageUrl:
220
- visibleActions[i].image,
204
+ alignment: Alignment.center,
205
+ child: AnimatedScale(
206
+ duration: inactiveIconAppearDuration,
207
+ curve: Curves.easeOutCubic,
208
+ scale: (i == widget.selectedIndex) ? 0.857 : 1.0,
209
+ child: TweenAnimationBuilder<Color?>(
210
+ tween: ColorTween(
211
+ begin: (i == widget.selectedIndex)
212
+ ? inactiveColor
213
+ : activeColor,
214
+ end: (i == widget.selectedIndex)
215
+ ? activeColor
216
+ : inactiveColor,
217
+ ),
218
+ duration: iconColorChangeDuration,
219
+ builder: (context, value, child) {
220
+ return Container(
221
+ height: NewMainNavBar.barHeight,
222
+ child: CakeImageWidget(
223
+ imageUrl: visibleActions[i].image,
224
width: iconWidth,
225
height: iconHeight,
226
//fit: BoxFit.scaleDown,
@@ -226,23 +229,22 @@ class _NEWNewMainNavBarState extends State<NewMainNavBar> {
229
BlendMode.srcIn,
230
),
231
),
229
- );
230
- }
232
+ );
233
+ }),
234
),
235
),
236
),
237
),
238
),
236
- ),
237
- ],
238
- ),
239
- )),
239
+ ],
240
+ ),
241
+ )),
242
+ ),
243
),
244
),
245
),
246
),
244
- ),
245
- );
247
+ );
248
},
249
);
250
}
@@ -302,7 +304,8 @@ class AnimatedPill extends StatelessWidget {
304
mainAxisSize: MainAxisSize.min,
305
mainAxisAlignment: MainAxisAlignment.center,
306
children: [
305
- Padding(padding: EdgeInsets.only(left: pillIconWidth + 2),
307
+ Padding(
308
+ padding: EdgeInsets.only(left: pillIconWidth + 2),
309
child: Text(
310
currentAction.name(context),
311
style: pillTextStyle.copyWith(color: contentColor),
lib/src/screens/dashboard/widgets/order_row.dart
+10
-10
@@ -44,18 +44,18 @@ class OrderRow extends StatelessWidget {
44
children: [
45
_ProviderIcon(path: providerIconPath, title: providerTitle),
46
if (state != null)
47
- Positioned(
48
- right: 0,
49
- bottom: 2,
50
- child: Container(
51
- height: 8,
52
- width: 8,
53
- decoration: BoxDecoration(
54
- color: _statusColor(context, state!),
55
- borderRadius: BorderRadius.circular(12),
47
+ Positioned(
48
+ right: 0,
49
+ bottom: 2,
50
+ child: Container(
51
+ height: 8,
52
+ width: 8,
53
+ decoration: BoxDecoration(
54
+ color: _statusColor(context, state!),
55
+ borderRadius: BorderRadius.circular(12),
56
+ ),
57
),
58
),
58
- ),
59
],
60
),
61
const SizedBox(width: 12),
lib/src/screens/dashboard/widgets/page_indicator.dart
+20
-44
@@ -76,8 +76,7 @@ class _PageIndicatorState extends State<PageIndicator> {
76
);
77
}
78
79
- double _estimateItemWidthForAction(
80
- BuildContext context, PageIndicatorActions action,
79
+ double _estimateItemWidthForAction(BuildContext context, PageIndicatorActions action,
80
{Color? color}) {
81
final text = action.name(context);
82
final textPainter = TextPainter(
@@ -86,15 +85,11 @@ class _PageIndicatorState extends State<PageIndicator> {
85
textDirection: Directionality.of(context),
86
textScaler: MediaQuery.of(context).textScaler,
87
)..layout();
89
- return iconWidth +
90
- iconSpacing +
91
- textPainter.width +
92
- pillHorizontalPadding * 2;
88
+ return iconWidth + iconSpacing + textPainter.width + pillHorizontalPadding * 2;
89
}
90
91
@override
92
Widget build(BuildContext context) {
97
-
93
final visibleActions = PageIndicatorActions.all.where((action) {
94
return action.isEnabled?.call(widget.dashboardViewModel) ?? true;
95
}).toList();
@@ -127,34 +122,28 @@ class _PageIndicatorState extends State<PageIndicator> {
122
];
123
124
final totalItemsWidth =
130
- actionWidths.fold(0.0, (sum, width) => sum + width) +
131
- barHorizontalPadding * 2;
125
+ actionWidths.fold(0.0, (sum, width) => sum + width) + barHorizontalPadding * 2;
126
127
final barWidth = math.min(totalItemsWidth, screenWidth * 0.95);
128
129
final count = visibleActions.length;
130
final firstLeft = edgePadding;
137
- final secondLeft =
138
- barWidth - (isRTL ? actionWidths.first : actionWidths[1]) - edgePadding;
131
+ final secondLeft = barWidth - (isRTL ? actionWidths.first : actionWidths[1]) - edgePadding;
132
133
final List<double> positions;
134
135
if (count == 2) {
136
positions = [firstLeft, secondLeft];
137
} else {
145
- final lastLeft = barWidth -
146
- (isRTL ? actionWidths.first : actionWidths.last) -
147
- edgePadding;
138
+ final lastLeft = barWidth - (isRTL ? actionWidths.first : actionWidths.last) - edgePadding;
139
149
- final centerLeft = (isRTL
150
- ? actionWidths.last + edgePadding
151
- : actionWidths.first + edgePadding);
140
+ final centerLeft =
141
+ (isRTL ? actionWidths.last + edgePadding : actionWidths.first + edgePadding);
142
143
positions = [firstLeft, centerLeft, lastLeft];
144
}
145
156
- final left =
157
- (isRTL ? positions.reversed.toList() : positions)[selectedIndex];
146
+ final left = (isRTL ? positions.reversed.toList() : positions)[selectedIndex];
147
final currentAction = visibleActions[selectedIndex];
148
149
return Align(
@@ -191,8 +180,7 @@ class _PageIndicatorState extends State<PageIndicator> {
180
pillResizeDuration: pillResizeDuration,
181
),
182
Padding(
194
- padding: const EdgeInsets.symmetric(
195
- horizontal: barHorizontalPadding),
183
+ padding: const EdgeInsets.symmetric(horizontal: barHorizontalPadding),
184
child: Row(
185
mainAxisAlignment: MainAxisAlignment.spaceBetween,
186
children: [
@@ -210,47 +198,36 @@ class _PageIndicatorState extends State<PageIndicator> {
198
height: barHeight,
199
width: i == selectedIndex
200
? pillWidth
213
- : _estimateItemWidthForAction(
214
- context, visibleActions[i]),
201
+ : _estimateItemWidthForAction(context, visibleActions[i]),
202
alignment: Alignment.center,
203
child: Row(
204
mainAxisSize: MainAxisSize.min,
205
children: [
206
TweenAnimationBuilder<Color?>(
220
- duration: const Duration(
221
- milliseconds: 300),
207
+ duration: const Duration(milliseconds: 300),
208
curve: Curves.easeOutCubic,
209
tween: ColorTween(
210
begin: inactiveColor,
225
- end: i == selectedIndex
226
- ? activeColor
227
- : inactiveColor,
211
+ end: i == selectedIndex ? activeColor : inactiveColor,
212
),
229
- builder: (context, color, _) =>
230
- SvgPicture.asset(
213
+ builder: (context, color, _) => SvgPicture.asset(
214
visibleActions[i].image,
215
width: iconWidth,
216
height: iconHeight,
234
- colorFilter: ColorFilter.mode(
235
- color!, BlendMode.srcIn),
217
+ colorFilter: ColorFilter.mode(color!, BlendMode.srcIn),
218
),
219
),
220
SizedBox(width: iconSpacing),
221
TweenAnimationBuilder<Color?>(
240
- duration: const Duration(
241
- milliseconds: 300),
222
+ duration: const Duration(milliseconds: 300),
223
curve: Curves.easeOutCubic,
224
tween: ColorTween(
225
begin: inactiveColor,
245
- end: i == selectedIndex
246
- ? activeColor
247
- : inactiveColor,
226
+ end: i == selectedIndex ? activeColor : inactiveColor,
227
),
249
- builder: (context, color, _) =>
250
- Text(
228
+ builder: (context, color, _) => Text(
229
visibleActions[i].name(context),
252
- style: textStyle.copyWith(
253
- color: color),
230
+ style: textStyle.copyWith(color: color),
231
overflow: TextOverflow.fade,
232
softWrap: false,
233
),
@@ -315,9 +292,8 @@ class AnimatedPill extends StatelessWidget {
292
duration: pillResizeDuration,
293
curve: Curves.easeOutCubic,
294
width: estimateWidthForAction,
318
- decoration: BoxDecoration(
319
- color: pillColor,
320
- borderRadius: BorderRadius.circular(pillBorderRadius)),
295
+ decoration:
296
+ BoxDecoration(color: pillColor, borderRadius: BorderRadius.circular(pillBorderRadius)),
297
clipBehavior: Clip.hardEdge,
298
alignment: Alignment.center,
299
),
lib/src/screens/dashboard/widgets/sign_form.dart
+4
-6
@@ -18,7 +18,7 @@ class SignForm extends StatefulWidget {
18
final WalletType type;
19
final bool includeAddress;
20
final int? chainId;
21
-
21
+
22
@override
23
SignFormState createState() => SignFormState();
24
}
@@ -66,15 +66,13 @@ class SignFormState extends State<SignForm> with AutomaticKeepAliveClientMixin {
66
const SizedBox(height: 20),
67
AddressTextField(
68
controller: addressController,
69
- options: [
70
- AddressTextFieldOption.paste,
71
- AddressTextFieldOption.walletAddresses
72
- ],
69
+ options: [AddressTextFieldOption.paste, AddressTextFieldOption.walletAddresses],
70
buttonColor: Theme.of(context).colorScheme.surfaceContainerHighest,
71
onSelectedContact: (contact) {
72
addressController.text = contact.address;
73
},
77
- selectedCurrency: walletTypeToCryptoCurrency(widget.type, chainId: widget.chainId),
74
+ selectedCurrency:
75
+ walletTypeToCryptoCurrency(widget.type, chainId: widget.chainId),
76
fillColor: Theme.of(context).colorScheme.surface,
77
),
78
],
lib/src/screens/dashboard/widgets/solana_nft_tile_widget.dart
+7
-7
@@ -61,9 +61,9 @@ class SolanaNFTTileWidget extends StatelessWidget {
61
Text(
62
'Symbol: ${nftAsset.symbol ?? '---'}',
63
style: Theme.of(context).textTheme.bodySmall?.copyWith(
64
- color: Theme.of(context).colorScheme.onSurfaceVariant,
65
- height: 1,
66
- ),
64
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
65
+ height: 1,
66
+ ),
67
),
68
const SizedBox(height: 8),
69
Text(
@@ -71,10 +71,10 @@ class SolanaNFTTileWidget extends StatelessWidget {
71
? nftAsset.name!
72
: (nftAsset.symbol ?? '---'),
73
style: Theme.of(context).textTheme.titleLarge?.copyWith(
74
- fontWeight: FontWeight.w900,
75
- color: Theme.of(context).colorScheme.onSurface,
76
- height: 1,
77
- ),
74
+ fontWeight: FontWeight.w900,
75
+ color: Theme.of(context).colorScheme.onSurface,
76
+ height: 1,
77
+ ),
78
),
79
],
80
),
lib/src/screens/dashboard/widgets/sync_indicator.dart
+2
-1
@@ -20,7 +20,8 @@ class SyncIndicator extends StatelessWidget {
20
return Observer(builder: (_) {
21
final syncIndicatorWidth = 237.0;
22
final status = dashboardViewModel.status;
23
- final statusText = syncStatusTitle(status, dashboardViewModel.settingsStore.syncStatusDisplayMode);
23
+ final statusText =
24
+ syncStatusTitle(status, dashboardViewModel.settingsStore.syncStatusDisplayMode);
25
final progress = status.progress();
26
final indicatorOffset = progress * syncIndicatorWidth;
27
final indicatorWidth = progress < 1
lib/src/screens/dashboard/widgets/transaction_raw.dart
+9
-8
@@ -42,13 +42,14 @@ class TransactionRow extends StatelessWidget {
42
shape: BoxShape.circle,
43
color: Theme.of(context).colorScheme.surfaceContainerHighest,
44
),
45
- child: (isShield) ? Padding(
46
- padding: const EdgeInsets.all(8.0),
47
- child: SvgPicture.asset('assets/images/tx_shield.svg'),
48
- ) :
49
- Image.asset(direction == TransactionDirection.incoming
50
- ? 'assets/images/down_arrow.png'
51
- : 'assets/images/up_arrow.png'),
45
+ child: (isShield)
46
+ ? Padding(
47
+ padding: const EdgeInsets.all(8.0),
48
+ child: SvgPicture.asset('assets/images/tx_shield.svg'),
49
+ )
50
+ : Image.asset(direction == TransactionDirection.incoming
51
+ ? 'assets/images/down_arrow.png'
52
+ : 'assets/images/up_arrow.png'),
53
),
54
SizedBox(width: 12),
55
Expanded(
@@ -66,7 +67,7 @@ class TransactionRow extends StatelessWidget {
67
title,
68
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
69
fontWeight: FontWeight.w600,
69
- overflow: TextOverflow.fade,
70
+ overflow: TextOverflow.fade,
71
),
72
),
73
),
lib/src/screens/dashboard/widgets/verify_form.dart
+1
-1
@@ -13,7 +13,7 @@ class VerifyForm extends StatefulWidget {
13
14
final WalletType type;
15
final int? chainId;
16
-
16
+
17
@override
18
VerifyFormState createState() => VerifyFormState();
19
}
lib/src/screens/dev/moneroc_cache_debug.dart
+20
-25
@@ -100,7 +100,8 @@ class JsonExplorerPage extends StatelessWidget {
100
final appDir = await getAppDir();
101
final filePath = appDir.path + '/.json_dump_temp.json';
102
await File(filePath).writeAsString(jsonString);
103
- await ShareUtil.shareFile(filePath: filePath, fileName: path.basename(filePath), context: context);
103
+ await ShareUtil.shareFile(
104
+ filePath: filePath, fileName: path.basename(filePath), context: context);
105
} catch (e) {
106
ScaffoldMessenger.of(context).showSnackBar(
107
SnackBar(content: Text('Failed to share file: $e')),
@@ -143,11 +144,11 @@ class _JsonExplorerState extends State<JsonExplorer> {
144
145
void _buildItemList() {
146
_allItems.clear();
146
-
147
+
148
if (widget.data is Map) {
149
final map = widget.data as Map<String, dynamic>;
150
final sortedKeys = map.keys.toList()..sort();
150
-
151
+
152
for (final key in sortedKeys) {
153
_allItems.add(CacheItem(
154
key: key,
@@ -165,7 +166,7 @@ class _JsonExplorerState extends State<JsonExplorer> {
166
));
167
}
168
}
168
-
169
+
170
_applyFilter();
171
}
172
@@ -175,7 +176,7 @@ class _JsonExplorerState extends State<JsonExplorer> {
176
} else {
177
_filteredItems = _allItems.where((item) {
178
return item.displayKey.toLowerCase().contains(_searchQuery.toLowerCase()) ||
178
- _valueContainsSearch(item.value, _searchQuery.toLowerCase());
179
+ _valueContainsSearch(item.value, _searchQuery.toLowerCase());
180
}).toList();
181
}
182
}
@@ -210,10 +211,10 @@ class _JsonExplorerState extends State<JsonExplorer> {
211
@override
212
Widget build(BuildContext context) {
213
final theme = Theme.of(context);
213
- final totalItems = widget.data is Map
214
- ? (widget.data as Map).length
215
- : widget.data is List
216
- ? (widget.data as List).length
214
+ final totalItems = widget.data is Map
215
+ ? (widget.data as Map).length
216
+ : widget.data is List
217
+ ? (widget.data as List).length
218
: 0;
219
220
return Column(
@@ -230,9 +231,7 @@ class _JsonExplorerState extends State<JsonExplorer> {
231
prefixIcon: const Icon(Icons.search),
232
border: const OutlineInputBorder(),
233
isDense: true,
233
- suffixText: _searchQuery.isNotEmpty
234
- ? '${_filteredItems.length} found'
235
- : null,
234
+ suffixText: _searchQuery.isNotEmpty ? '${_filteredItems.length} found' : null,
235
),
236
onChanged: (value) {
237
setState(() {
@@ -245,7 +244,6 @@ class _JsonExplorerState extends State<JsonExplorer> {
244
],
245
),
246
),
248
-
247
Expanded(
248
child: _filteredItems.isEmpty && _searchQuery.isNotEmpty
249
? Center(
@@ -311,11 +309,11 @@ class CacheItemTile extends StatelessWidget {
309
Color _getTypeColor(BuildContext context, dynamic value) {
310
final theme = Theme.of(context);
311
final isDark = theme.brightness == Brightness.dark;
314
-
312
+
313
if (value == null) {
314
return Colors.grey;
315
}
318
-
316
+
317
switch (value.runtimeType) {
318
case String:
319
return Colors.green;
@@ -337,22 +335,22 @@ class CacheItemTile extends StatelessWidget {
335
336
String _getValuePreview(dynamic value) {
337
if (value == null) return 'null';
340
-
338
+
339
if (value is Map) {
340
return '{${value.length} items}';
341
}
344
-
342
+
343
if (value is List) {
344
return '[${value.length} items]';
345
}
348
-
346
+
347
if (value is String) {
348
if (value.length > 100) {
349
return '"${value.substring(0, 97)}..."';
350
}
351
return '"$value"';
352
}
355
-
353
+
354
final str = value.toString();
355
if (str.length > 100) {
356
return '${str.substring(0, 97)}...';
@@ -407,9 +405,7 @@ class CacheItemTile extends StatelessWidget {
405
margin: const EdgeInsets.symmetric(horizontal: 8, vertical: 2),
406
child: ListTile(
407
leading: Icon(
410
- canNavigate
411
- ? (item.value is Map ? Icons.folder : Icons.list)
412
- : Icons.description,
408
+ canNavigate ? (item.value is Map ? Icons.folder : Icons.list) : Icons.description,
409
color: _getTypeColor(context, item.value),
410
),
411
title: _buildHighlightedText(
@@ -433,8 +429,7 @@ class CacheItemTile extends StatelessWidget {
429
icon: const Icon(Icons.copy, size: 18),
430
tooltip: 'Copy ${item.displayKey}',
431
),
436
- if (canNavigate)
437
- const Icon(Icons.chevron_right),
432
+ if (canNavigate) const Icon(Icons.chevron_right),
433
],
434
),
435
onTap: canNavigate ? onTap : null,
@@ -442,4 +437,4 @@ class CacheItemTile extends StatelessWidget {
437
),
438
);
439
}
445
-}
\ No newline at end of file
440
+}
lib/src/screens/dev/moneroc_call_profiler.dart
+8
-17
@@ -24,8 +24,6 @@ class DevMoneroCallProfilerPage extends BasePage {
24
}
25
}
26
27
-
28
-
27
class PerformanceDebug extends StatefulWidget {
28
const PerformanceDebug({super.key});
29
@@ -68,7 +66,7 @@ class _PerformanceDebugState extends State<PerformanceDebug> {
66
return debugCallLength["MONERO_Wallet_init"]!.last;
67
}
68
71
-late final String perfInfo = """
69
+ late final String perfInfo = """
70
---- Performance tuning
71
This page lists all calls that take place during the app runtime.-
72
As per Flutter docs we can read:
@@ -93,8 +91,8 @@ min: fastest execution (% of frame)
91
max: slowest execution (% of frame)
92
95th: 95% of the time, the function is faster than this amount of time (% of frame)
93
"""
96
- .split("-\n")
97
- .join(" ");
94
+ .split("-\n")
95
+ .join(" ");
96
97
late final frameTime = 8333;
98
late final frameGreenTier = frameTime ~/ 100;
@@ -113,7 +111,6 @@ max: slowest execution (% of frame)
111
return Colors.red;
112
}
113
116
-
114
@override
115
void initState() {
116
super.initState();
@@ -144,9 +141,7 @@ max: slowest execution (% of frame)
141
],
142
));
143
final keys = debugCallLength.keys.toList();
147
- keys.sort((s1, s2) =>
148
- _n95th(debugCallLength[s2]!) -
149
- _n95th(debugCallLength[s1]!));
144
+ keys.sort((s1, s2) => _n95th(debugCallLength[s2]!) - _n95th(debugCallLength[s1]!));
145
for (var key in keys) {
146
final value = debugCallLength[key];
147
if (value == null) continue;
@@ -172,14 +167,10 @@ max: slowest execution (% of frame)
167
const Spacer(),
168
cw("${_str(total / 1000)}ms", perfc(total)),
169
]),
175
- cw("average: ${_str(avg)}µs (~${_str(avg / (frameTime))}f)",
176
- perfc(avg)),
177
- cw("min: $minµs (~${_str(min / (frameTime) * 100)})",
178
- perfc(min)),
179
- cw("max: $maxµs (~${_str(max / (frameTime) * 100)}%)",
180
- perfc(max)),
181
- cw("95th: $npµs (~${_str(np / (frameTime) * 100)}%)",
182
- perfc(np)),
170
+ cw("average: ${_str(avg)}µs (~${_str(avg / (frameTime))}f)", perfc(avg)),
171
+ cw("min: $minµs (~${_str(min / (frameTime) * 100)})", perfc(min)),
172
+ cw("max: $maxµs (~${_str(max / (frameTime) * 100)}%)", perfc(max)),
173
+ cw("95th: $npµs (~${_str(np / (frameTime) * 100)}%)", perfc(np)),
174
],
175
),
176
),
lib/src/screens/dev/network_requests.dart
+25
-33
@@ -75,14 +75,16 @@ class DevNetworkRequests extends BasePage {
75
RequestMethod.delete => Text("DELETE"),
76
RequestMethod.newHttpClient ||
77
RequestMethod.newHttpIOClient ||
78
- RequestMethod.newProxySocket => null,
78
+ RequestMethod.newProxySocket =>
79
+ null,
80
},
81
title: Text(item.time.toIso8601String()),
82
subtitle: switch (item.method) {
83
RequestMethod.get ||
84
RequestMethod.post ||
85
RequestMethod.put ||
85
- RequestMethod.delete => Text("${item.uri}"),
86
+ RequestMethod.delete =>
87
+ Text("${item.uri}"),
88
RequestMethod.newHttpClient => Text("newHttpClient"),
89
RequestMethod.newHttpIOClient => Text("newHttpIOClient"),
90
RequestMethod.newProxySocket => Text("newProxySocket"),
@@ -115,35 +117,26 @@ class DevRequestDetails extends BasePage {
117
children: [
118
_sectionTitle("Time"),
119
SelectableText(req.time.toString()),
118
-
120
_sectionTitle("Method"),
121
SelectableText(req.method.toString()),
121
-
122
_sectionTitle("URI"),
123
SelectableText(req.uri?.toString() ?? "null"),
124
-
124
_sectionTitle("Network"),
125
SelectableText(req.network.toString()),
127
-
128
- if (req.network == RequestNetwork.tor)
129
- ...[
130
- _sectionTitle("Tor socks server"),
131
- SelectableText(CakeTor.instance.runtimeType.toString()),
132
- _sectionTitle("Tor socks details"),
133
- SelectableText(CakeTor.instance.toString()),
134
- ],
135
-
126
+ if (req.network == RequestNetwork.tor) ...[
127
+ _sectionTitle("Tor socks server"),
128
+ SelectableText(CakeTor.instance.runtimeType.toString()),
129
+ _sectionTitle("Tor socks details"),
130
+ SelectableText(CakeTor.instance.toString()),
131
+ ],
132
_sectionTitle("Body (as UTF-8)"),
133
SelectableText(_tryDecodeBody(req.body)),
134
_buildJsonExplorer(context, _tryDecodeBody(req.body)),
139
-
135
_sectionTitle("Response"),
136
SelectableText(req.response?.body ?? "null"),
137
_buildJsonExplorer(context, req.response?.body ?? "{}"),
143
-
138
_sectionTitle("Error"),
139
SelectableText(req.error ?? "No error"),
146
-
140
_sectionTitle("Stack Trace"),
141
SelectableText(req.trace.toString()),
142
],
@@ -152,22 +145,21 @@ class DevRequestDetails extends BasePage {
145
146
Widget _buildJsonExplorer(BuildContext context, String body) {
147
try {
155
- final jsonData = json.decode(body);
156
- return PrimaryButton(
157
- text: "View JSON",
158
- color: Colors.blue,
159
- textColor: Colors.white,
160
- onPressed: () {
161
- Navigator.of(context).push(
162
- MaterialPageRoute(
163
- builder: (context) {
164
- return JsonExplorerPage(data: jsonData, title: "body");
165
- },
166
- ),
167
- );
168
- },
169
- );
170
-
148
+ final jsonData = json.decode(body);
149
+ return PrimaryButton(
150
+ text: "View JSON",
151
+ color: Colors.blue,
152
+ textColor: Colors.white,
153
+ onPressed: () {
154
+ Navigator.of(context).push(
155
+ MaterialPageRoute(
156
+ builder: (context) {
157
+ return JsonExplorerPage(data: jsonData, title: "body");
158
+ },
159
+ ),
160
+ );
161
+ },
162
+ );
163
} catch (e) {
164
return SelectableText("Invalid JSON: $e");
165
}
lib/src/screens/dev/qr_tools_page.dart
+8
-9
@@ -19,21 +19,20 @@ class DevQRToolsPage extends BasePage {
19
mainAxisSize: MainAxisSize.min,
20
children: [
21
TextField(
22
- controller: textCtrl,
23
- maxLines: 8,
24
- onChanged: (value) {
25
- viewModel.input = value;
26
- }
27
- ),
22
+ controller: textCtrl,
23
+ maxLines: 8,
24
+ onChanged: (value) {
25
+ viewModel.input = value;
26
+ }),
27
Observer(
28
builder: (_) {
29
return Expanded(
31
- child: JsonExplorer(data: viewModel.data, title: "result"),
32
- );
30
+ child: JsonExplorer(data: viewModel.data, title: "result"),
31
+ );
32
},
33
),
34
],
35
),
36
);
37
}
39
-}
\ No newline at end of file
38
+}
lib/src/screens/dev/secure_preferences_page.dart
+14
-8
@@ -38,10 +38,14 @@ class DevSecurePreferencesPage extends BasePage {
38
Clipboard.setData(ClipboardData(text: key + ": " + values[key].toString()));
39
},
40
title: switch (type) {
41
- PreferenceType.bool => Text(key, style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: Colors.blue)),
42
- PreferenceType.int => Text(key, style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: Colors.green)),
43
- PreferenceType.double => Text(key, style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: Colors.yellow)),
44
- PreferenceType.listString => Text(key, style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: Colors.purple)),
41
+ PreferenceType.bool => Text(key,
42
+ style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: Colors.blue)),
43
+ PreferenceType.int => Text(key,
44
+ style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: Colors.green)),
45
+ PreferenceType.double => Text(key,
46
+ style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: Colors.yellow)),
47
+ PreferenceType.listString => Text(key,
48
+ style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: Colors.purple)),
49
PreferenceType.string => Text(key),
50
PreferenceType.unknown => Text(key),
51
},
@@ -49,9 +53,12 @@ class DevSecurePreferencesPage extends BasePage {
53
PreferenceType.bool => Text("bool: ${values[key]}"),
54
PreferenceType.int => Text("int: ${values[key]}"),
55
PreferenceType.double => Text("double: ${values[key]}"),
52
- PreferenceType.listString => values[key].isEmpty as bool ? Text("listString: []") : Text("listString:\n- ${values[key].join("\n- ")}"),
56
+ PreferenceType.listString => values[key].isEmpty as bool
57
+ ? Text("listString: []")
58
+ : Text("listString:\n- ${values[key].join("\n- ")}"),
59
PreferenceType.string => Text("string: ${values[key]}"),
54
- PreferenceType.unknown => Text("UNKNOWN(${values[key].runtimeType}): ${values[key]}"),
60
+ PreferenceType.unknown =>
61
+ Text("UNKNOWN(${values[key].runtimeType}): ${values[key]}"),
62
},
63
);
64
},
@@ -59,5 +66,4 @@ class DevSecurePreferencesPage extends BasePage {
66
},
67
);
68
}
62
-
63
-}
\ No newline at end of file
69
+}
lib/src/screens/dev/shared_preferences_page.dart
+40
-33
@@ -50,10 +50,14 @@ class DevSharedPreferencesPage extends BasePage {
50
_showEditDialog(context, key, type, values[key]);
51
},
52
title: switch (type) {
53
- PreferenceType.bool => Text(key, style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: Colors.blue)),
54
- PreferenceType.int => Text(key, style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: Colors.green)),
55
- PreferenceType.double => Text(key, style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: Colors.yellow)),
56
- PreferenceType.listString => Text(key, style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: Colors.purple)),
53
+ PreferenceType.bool => Text(key,
54
+ style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: Colors.blue)),
55
+ PreferenceType.int => Text(key,
56
+ style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: Colors.green)),
57
+ PreferenceType.double => Text(key,
58
+ style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: Colors.yellow)),
59
+ PreferenceType.listString => Text(key,
60
+ style: Theme.of(context).textTheme.bodyMedium!.copyWith(color: Colors.purple)),
61
PreferenceType.string => Text(key),
62
PreferenceType.unknown => Text(key),
63
},
@@ -61,9 +65,12 @@ class DevSharedPreferencesPage extends BasePage {
65
PreferenceType.bool => Text("bool: ${values[key]}"),
66
PreferenceType.int => Text("int: ${values[key]}"),
67
PreferenceType.double => Text("double: ${values[key]}"),
64
- PreferenceType.listString => values[key].isEmpty as bool ? Text("listString: []") : Text("listString:\n- ${values[key].join("\n- ")}"),
68
+ PreferenceType.listString => values[key].isEmpty as bool
69
+ ? Text("listString: []")
70
+ : Text("listString:\n- ${values[key].join("\n- ")}"),
71
PreferenceType.string => Text("string: ${values[key]}"),
66
- PreferenceType.unknown => Text("UNKNOWN(${values[key].runtimeType}): ${values[key]}"),
72
+ PreferenceType.unknown =>
73
+ Text("UNKNOWN(${values[key].runtimeType}): ${values[key]}"),
74
},
75
);
76
},
@@ -72,12 +79,14 @@ class DevSharedPreferencesPage extends BasePage {
79
);
80
}
81
75
- void _showEditDialog(BuildContext context, String key, PreferenceType type, dynamic currentValue) {
82
+ void _showEditDialog(
83
+ BuildContext context, String key, PreferenceType type, dynamic currentValue) {
84
dynamic newValue = currentValue;
85
bool isListString = type == PreferenceType.listString;
78
- List<String> listItems = isListString ? List<String>.from(currentValue as Iterable<dynamic>) : [];
79
- TextEditingController textController = TextEditingController(
80
- text: isListString ? '' : currentValue?.toString() ?? '');
86
+ List<String> listItems =
87
+ isListString ? List<String>.from(currentValue as Iterable<dynamic>) : [];
88
+ TextEditingController textController =
89
+ TextEditingController(text: isListString ? '' : currentValue?.toString() ?? '');
90
91
showDialog(
92
context: context,
@@ -91,10 +100,10 @@ class DevSharedPreferencesPage extends BasePage {
100
height: double.maxFinite,
101
child: SingleChildScrollView(
102
child: _buildDialogContent(
94
- type,
95
- newValue,
96
- listItems,
97
- textController,
103
+ type,
104
+ newValue,
105
+ listItems,
106
+ textController,
107
(value) => setState(() => newValue = value),
108
(items) => setState(() => listItems = items),
109
),
@@ -116,12 +125,7 @@ class DevSharedPreferencesPage extends BasePage {
125
child: Text('Save'),
126
onPressed: () async {
127
if (_validateAndUpdateValue(
119
- context,
120
- type,
121
- textController,
122
- listItems,
123
- (value) => newValue = value
124
- )) {
128
+ context, type, textController, listItems, (value) => newValue = value)) {
129
await viewModel.set(key, type, newValue);
130
Navigator.of(context).pop();
131
}
@@ -210,9 +214,8 @@ class DevSharedPreferencesPage extends BasePage {
214
BaseTextFormField(
215
controller: controller,
216
hintText: label,
213
- keyboardType: isInteger
214
- ? TextInputType.number
215
- : TextInputType.numberWithOptions(decimal: true),
217
+ keyboardType:
218
+ isInteger ? TextInputType.number : TextInputType.numberWithOptions(decimal: true),
219
inputFormatters: isInteger
220
? [FilteringTextInputFormatter.digitsOnly]
221
: [FilteringTextInputFormatter.allow(RegExp(r'^\d*\.?\d*$'))],
@@ -222,7 +225,7 @@ class DevSharedPreferencesPage extends BasePage {
225
}
226
227
Widget _buildListEditor(
225
- List<String> items,
228
+ List<String> items,
229
TextEditingController controller,
230
Function(List<String>) onListChanged,
231
) {
@@ -358,7 +361,8 @@ class DevSharedPreferencesPage extends BasePage {
361
DropdownMenuItem(value: PreferenceType.bool, child: Text('Boolean')),
362
DropdownMenuItem(value: PreferenceType.int, child: Text('Integer')),
363
DropdownMenuItem(value: PreferenceType.double, child: Text('Double')),
361
- DropdownMenuItem(value: PreferenceType.listString, child: Text('List of Strings')),
364
+ DropdownMenuItem(
365
+ value: PreferenceType.listString, child: Text('List of Strings')),
366
],
367
onChanged: (value) {
368
if (value != null) {
@@ -384,14 +388,17 @@ class DevSharedPreferencesPage extends BasePage {
388
return;
389
}
390
387
- viewModel.set(keyController.text, selectedType, switch (selectedType) {
388
- PreferenceType.bool => false,
389
- PreferenceType.int => 0,
390
- PreferenceType.double => 0.0,
391
- PreferenceType.string => '',
392
- PreferenceType.listString => [],
393
- PreferenceType.unknown => null,
394
- });
391
+ viewModel.set(
392
+ keyController.text,
393
+ selectedType,
394
+ switch (selectedType) {
395
+ PreferenceType.bool => false,
396
+ PreferenceType.int => 0,
397
+ PreferenceType.double => 0.0,
398
+ PreferenceType.string => '',
399
+ PreferenceType.listString => [],
400
+ PreferenceType.unknown => null,
401
+ });
402
Navigator.of(context).pop();
403
},
404
),
lib/src/screens/disclaimer/disclaimer_page.dart
+1
-1
@@ -147,7 +147,7 @@ class DisclaimerBodyState extends State<DisclaimerPageBody> {
147
EdgeInsets.only(left: 24.0, top: 10.0, right: 24.0, bottom: 10.0),
148
child: InkWell(
149
key: ValueKey('disclaimer_check_key'),
150
- onTap: () => setState(() =>_checked = !_checked),
150
+ onTap: () => setState(() => _checked = !_checked),
151
child: Row(
152
mainAxisAlignment: MainAxisAlignment.start,
153
children: <Widget>[
lib/src/screens/exchange/exchange_page.dart
+7
-3
@@ -40,7 +40,8 @@ import 'package:cake_wallet/src/screens/exchange/widgets/present_provider_picker
40
import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator_icon.dart';
41
42
class ExchangePage extends BasePage {
43
- ExchangePage(this.exchangeViewModel, this.authService, this.adrResService, this.initialPaymentRequest) {
43
+ ExchangePage(
44
+ this.exchangeViewModel, this.authService, this.adrResService, this.initialPaymentRequest) {
45
depositWalletName = exchangeViewModel.depositCurrency == CryptoCurrency.xmr
46
? exchangeViewModel.wallet.name
47
: null;
@@ -655,8 +656,11 @@ class ExchangePage extends BasePage {
656
657
Future<String> fetchParsedAddress(
658
BuildContext context, String domain, CryptoCurrency currency) async {
658
- final parsedAddresses = await adrResService.resolve(query: domain, wallet:exchangeViewModel.wallet, currency: currency);
659
- return parsedAddresses.isNotEmpty ? parsedAddresses.first.parsedAddressByCurrencyMap[currency] ?? '' : '';
659
+ final parsedAddresses = await adrResService.resolve(
660
+ query: domain, wallet: exchangeViewModel.wallet, currency: currency);
661
+ return parsedAddresses.isNotEmpty
662
+ ? parsedAddresses.first.parsedAddressByCurrencyMap[currency] ?? ''
663
+ : '';
664
}
665
666
void _showFeeAlert(BuildContext context) async {
lib/src/screens/exchange/widgets/currency_picker_widget.dart
+1
-1
@@ -39,7 +39,7 @@ class CurrencyPickerWidget extends StatelessWidget {
39
pickListItem(index);
40
},
41
title: pickerItemsList[index].name,
42
- iconPath: pickerItemsList[index].iconPath,
42
+ iconPath: pickerItemsList[index].iconPath,
43
tag: pickerItemsList[index].tag,
44
);
45
}),
lib/src/screens/exchange/widgets/mobile_exchange_cards_section.dart
+2
-2
@@ -86,7 +86,7 @@ class _BuySellOptionButtonsState extends State<BuySellOptionButtons> {
86
Expanded(
87
flex: 5,
88
child: SelectButton(
89
- center:true,
89
+ center: true,
90
height: 44,
91
text: S.of(context).buy,
92
isSelected: isBuySelected,
@@ -108,7 +108,7 @@ class _BuySellOptionButtonsState extends State<BuySellOptionButtons> {
108
Expanded(
109
flex: 5,
110
child: SelectButton(
111
- center:true,
111
+ center: true,
112
height: 44,
113
text: S.of(context).sell,
114
isSelected: !isBuySelected,
lib/src/screens/exchange/widgets/picker_item.dart
+1
-4
@@ -1,9 +1,6 @@
1
class PickerItem<T> {
2
PickerItem(this.original,
3
- {required this.title,
4
- required this.iconPath,
5
- required this.tag,
6
- required this.description});
3
+ {required this.title, required this.iconPath, required this.tag, required this.description});
4
5
final String title;
6
final String iconPath;
lib/src/screens/exchange_trade/exchange_trade_external_send_page.dart
+4
-2
@@ -72,7 +72,8 @@ class ExchangeTradeExternalSendPage extends BasePage {
72
context,
73
Routes.fullscreenQR,
74
arguments: QrViewData(
75
- embeddedImagePath: exchangeTradeViewModel.trade.from?.iconPath,
75
+ embeddedImagePath:
76
+ exchangeTradeViewModel.trade.from?.iconPath,
77
data: exchangeTradeViewModel.paymentUri?.toString() ??
78
exchangeTradeViewModel.trade.inputAddress ??
79
fetchingLabel,
@@ -96,7 +97,8 @@ class ExchangeTradeExternalSendPage extends BasePage {
97
data: exchangeTradeViewModel.paymentUri?.toString() ??
98
exchangeTradeViewModel.trade.inputAddress ??
99
fetchingLabel,
99
- embeddedImagePath: exchangeTradeViewModel.trade.from?.iconPath,
100
+ embeddedImagePath:
101
+ exchangeTradeViewModel.trade.from?.iconPath,
102
size: 230,
103
),
104
),
lib/src/screens/exchange_trade/exchange_trade_item.dart
+1
-1
@@ -12,4 +12,4 @@ class ExchangeTradeItem {
12
bool isCopied;
13
bool isReceiveDetail;
14
bool isExternalSendDetail;
15
-}
\ No newline at end of file
15
+}
lib/src/screens/exchange_trade/exchange_trade_page.dart
+12
-7
@@ -177,7 +177,6 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
177
? Theme.of(context).colorScheme.onSecondaryContainer
178
: Theme.of(context).colorScheme.onPrimary,
179
),
180
-
180
SizedBox(height: 16),
181
Observer(
182
builder: (_) {
@@ -297,12 +296,17 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
296
final isSwapsXyz = trade.provider == ExchangeProviderDescription.swapsXyz;
297
final isEVMWallet = widget.exchangeTradeViewModel.sendViewModel.isEVMWallet;
298
300
- final amountValue = isSwapsXyz && isEVMWallet && !widget.exchangeTradeViewModel.isSwapsXYZCanSendFromExternal
299
+ final amountValue = isSwapsXyz &&
300
+ isEVMWallet &&
301
+ !widget.exchangeTradeViewModel.isSwapsXYZCanSendFromExternal
302
? trade.amount
303
: widget.exchangeTradeViewModel.sendViewModel.pendingTransaction!.amountFormatted;
304
304
- final fiatAmountValue = isSwapsXyz && isEVMWallet && !widget.exchangeTradeViewModel.isSwapsXYZCanSendFromExternal
305
- ? widget.exchangeTradeViewModel.sendViewModel.calculateTransactionFiatAmount(amountValue)
305
+ final fiatAmountValue = isSwapsXyz &&
306
+ isEVMWallet &&
307
+ !widget.exchangeTradeViewModel.isSwapsXYZCanSendFromExternal
308
+ ? widget.exchangeTradeViewModel.sendViewModel
309
+ .calculateTransactionFiatAmount(amountValue)
310
: widget.exchangeTradeViewModel.sendViewModel.pendingTransactionFiatAmountFormatted;
311
312
if (context.mounted) {
@@ -328,12 +332,13 @@ class ExchangeTradeState extends State<ExchangeTradeForm> {
332
fee: isEVMCompatibleChain(sendVM.walletType)
333
? S.of(bottomSheetContext).send_estimated_fee
334
: S.of(bottomSheetContext).send_fee,
331
- feeValue: sendVM.amountParsingProxy.asDisplayStringWithSymbol(
332
- sendVM.pendingTransaction!.fee),
335
+ feeValue: sendVM.amountParsingProxy
336
+ .asDisplayStringWithSymbol(sendVM.pendingTransaction!.fee),
337
feeFiatAmount: sendVM.pendingTransactionFeeFiatAmountFormatted,
338
outputs: sendVM.outputs,
339
onSlideActionComplete: () async {
336
- if (bottomSheetContext.mounted && Navigator.canPop(bottomSheetContext)) Navigator.of(bottomSheetContext).pop(true);
340
+ if (bottomSheetContext.mounted && Navigator.canPop(bottomSheetContext))
341
+ Navigator.of(bottomSheetContext).pop(true);
342
343
sendVM.commitTransaction(context);
344
},
lib/src/screens/exchange_trade/widgets/timer_widget.dart
+3
-3
@@ -59,9 +59,9 @@ class TimerWidgetState extends State<TimerWidget> {
59
? Text(
60
S.of(context).expired,
61
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
62
- fontWeight: FontWeight.w500,
63
- color: Theme.of(context).colorScheme.errorContainer,
64
- ),
62
+ fontWeight: FontWeight.w500,
63
+ color: Theme.of(context).colorScheme.errorContainer,
64
+ ),
65
)
66
: Text(
67
S.of(context).time(_minutes.toString(), _seconds.toString()),
lib/src/screens/integrations/deuro/savings_page.dart
+2
-4
@@ -149,7 +149,7 @@ class DEuroSavingsPage extends BasePage {
149
await _requireHardwareWallet(context);
150
_dEuroViewModel.prepareSavingsEdit(amount, false);
151
}
152
- _editSheetIsOpen = false;
152
+ _editSheetIsOpen = false;
153
}
154
155
Future<void> _onReinvestInterest(BuildContext context) async {
@@ -425,9 +425,7 @@ class DEuroSavingsPage extends BasePage {
425
balanceTitle: isAdding
426
? S.of(context).deuro_savings_available_to_add
427
: S.of(context).deuro_savings_available_to_remove,
428
- balance: isAdding
429
- ? _dEuroViewModel.accountBalance
430
- : _dEuroViewModel.savingsBalance,
428
+ balance: isAdding ? _dEuroViewModel.accountBalance : _dEuroViewModel.savingsBalance,
429
footerType: FooterType.none,
430
maxHeight: MediaQuery.of(context).size.height * 0.8,
431
),
lib/src/screens/integrations/deuro/widgets/numpad.dart
+6
-8
@@ -25,8 +25,7 @@ class NumberPad extends StatelessWidget {
25
return onDeletePressed();
26
}
27
28
- if ([".", ","].contains(keyEvent.logicalKey.keyLabel) &&
29
- onDecimalPressed != null) {
28
+ if ([".", ","].contains(keyEvent.logicalKey.keyLabel) && onDecimalPressed != null) {
29
return onDecimalPressed!();
30
}
31
@@ -50,10 +49,10 @@ class NumberPad extends StatelessWidget {
49
child: Text(
50
'.',
51
style: Theme.of(context).textTheme.headlineMedium?.copyWith(
53
- fontWeight: FontWeight.w600,
54
- fontSize: 30,
55
- color: Theme.of(context).colorScheme.onSurfaceVariant,
56
- ),
52
+ fontWeight: FontWeight.w600,
53
+ fontSize: 30,
54
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
55
+ ),
56
textAlign: TextAlign.center,
57
),
58
),
@@ -70,8 +69,7 @@ class NumberPad extends StatelessWidget {
69
child: TextButton(
70
onPressed: onDeletePressed,
71
style: TextButton.styleFrom(
73
- backgroundColor:
74
- Colors.transparent,
72
+ backgroundColor: Colors.transparent,
73
shape: CircleBorder(),
74
),
75
child: Image.asset(
lib/src/screens/monero_accounts/widgets/account_tile.dart
+1
-1
@@ -64,7 +64,7 @@ class AccountTile extends StatelessWidget {
64
? Theme.of(context).colorScheme.onSurface
65
: Theme.of(context).colorScheme.onSurfaceVariant,
66
decoration: TextDecoration.none,
67
- ),
67
+ ),
68
),
69
),
70
],
lib/src/screens/new_wallet/wallet_group_description_page.dart
+1
-1
@@ -18,7 +18,7 @@ class WalletGroupDescriptionPage extends BasePage {
18
19
@override
20
Widget Function(BuildContext, Widget) get rootWrapper =>
21
- (BuildContext context, Widget scaffold) => GradientBackground(scaffold: scaffold);
21
+ (BuildContext context, Widget scaffold) => GradientBackground(scaffold: scaffold);
22
23
@override
24
String get title => S.current.wallet_list_create_new_wallet;
lib/src/screens/new_wallet/wallet_group_existing_seed_description_page.dart
+9
-8
@@ -14,7 +14,7 @@ class WalletGroupExistingSeedDescriptionPage extends BasePage {
14
15
@override
16
Widget Function(BuildContext, Widget) get rootWrapper =>
17
- (BuildContext context, Widget scaffold) => GradientBackground(scaffold: scaffold);
17
+ (BuildContext context, Widget scaffold) => GradientBackground(scaffold: scaffold);
18
19
@override
20
String get title => S.current.wallet_group;
@@ -34,9 +34,10 @@ class WalletGroupExistingSeedDescriptionPage extends BasePage {
34
child: Column(
35
children: [
36
CakeImageWidget(
37
- imageUrl: currentTheme.isDark ? walletGroupConfirmedImageDark : walletGroupConfirmedImageLight,
38
- height: 200
39
- ),
37
+ imageUrl: currentTheme.isDark
38
+ ? walletGroupConfirmedImageDark
39
+ : walletGroupConfirmedImageLight,
40
+ height: 200),
41
SizedBox(height: 32),
42
Expanded(
43
child: SingleChildScrollView(
@@ -55,10 +56,10 @@ class WalletGroupExistingSeedDescriptionPage extends BasePage {
56
TextSpan(
57
text: S.current.seed_display_path,
58
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
58
- fontSize: 16,
59
- fontWeight: FontWeight.w800,
60
- color: Theme.of(context).colorScheme.onSurfaceVariant,
61
- ),
59
+ fontSize: 16,
60
+ fontWeight: FontWeight.w800,
61
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
62
+ ),
63
),
64
],
65
),
lib/src/screens/new_wallet/widgets/select_button.dart
+12
-8
@@ -17,7 +17,8 @@ class SelectButton extends StatelessWidget {
17
this.deviceConnectionTypes,
18
this.borderRadius,
19
this.padding,
20
- super.key, this.center = false,
20
+ super.key,
21
+ this.center = false,
22
});
23
24
final Widget? image;
@@ -38,7 +39,10 @@ class SelectButton extends StatelessWidget {
39
40
@override
41
Widget build(BuildContext context) {
41
- final backgroundColor = color ?? (isSelected ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.surfaceContainer);
42
+ final backgroundColor = color ??
43
+ (isSelected
44
+ ? Theme.of(context).colorScheme.primary
45
+ : Theme.of(context).colorScheme.surfaceContainer);
46
final effectiveTextColor = textColor ??
47
(isSelected
48
? Theme.of(context).colorScheme.onPrimary
@@ -81,24 +85,24 @@ class SelectButton extends StatelessWidget {
85
mainAxisAlignment: center ? MainAxisAlignment.center : MainAxisAlignment.start,
86
crossAxisAlignment: CrossAxisAlignment.center,
87
children: <Widget>[
84
- if(!center) SizedBox(width:16),
88
+ if (!center) SizedBox(width: 16),
89
image ?? Offstage(),
90
Padding(
91
padding: image != null ? EdgeInsets.only(left: 14) : EdgeInsets.only(left: 0),
92
child: Text(
93
text,
94
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
91
- fontSize: textSize,
92
- fontWeight: FontWeight.w500,
93
- color: effectiveTextColor,
94
- ),
95
+ fontSize: textSize,
96
+ fontWeight: FontWeight.w500,
97
+ color: effectiveTextColor,
98
+ ),
99
),
100
)
101
],
102
),
103
),
104
...trailingIcons,
101
- if(!center) SizedBox(width:16),
105
+ if (!center) SizedBox(width: 16),
106
],
107
),
108
),
lib/src/screens/nodes/node_create_or_edit_page.dart
+54
-50
@@ -37,16 +37,15 @@ class NodeCreateOrEditPage extends StatefulWidget {
37
class _NodeCreateOrEditPageState extends State<NodeCreateOrEditPage> {
38
final _nodeFormKey = GlobalKey<NodeFormState>();
39
40
-
40
@override
41
void initState() {
42
super.initState();
43
reaction(
45
- (_) => widget.nodeCreateOrEditViewModel.connectionState,
46
- (ExecutionState state) {
44
+ (_) => widget.nodeCreateOrEditViewModel.connectionState,
45
+ (ExecutionState state) {
46
if (state is ExecutedSuccessfullyState) {
47
WidgetsBinding.instance.addPostFrameCallback(
49
- (_) => showPopUp<void>(
48
+ (_) => showPopUp<void>(
49
context: context,
50
builder: (context) => AlertWithOneAction(
51
alertTitle: S.of(context).new_node_testing,
@@ -62,7 +61,7 @@ class _NodeCreateOrEditPageState extends State<NodeCreateOrEditPage> {
61
62
if (state is FailureState) {
63
WidgetsBinding.instance.addPostFrameCallback(
65
- (_) => showPopUp<void>(
64
+ (_) => showPopUp<void>(
65
context: context,
66
builder: (context) => AlertWithOneAction(
67
alertTitle: S.of(context).error,
@@ -76,19 +75,16 @@ class _NodeCreateOrEditPageState extends State<NodeCreateOrEditPage> {
75
},
76
);
77
79
-
80
- reaction((_)=>widget.nodeCreateOrEditViewModel.state, (state) async {
81
- if(state is ExecutedSuccessfullyState) {
78
+ reaction((_) => widget.nodeCreateOrEditViewModel.state, (state) async {
79
+ if (state is ExecutedSuccessfullyState) {
80
await Future.delayed(Duration(milliseconds: 100));
81
if (mounted) Navigator.of(context).pop(widget.nodeCreateOrEditViewModel.editingNode);
82
}
85
-
83
});
84
}
85
86
@override
87
Widget build(BuildContext context) {
91
-
88
return Container(
89
color: Theme.of(context).colorScheme.surface,
90
child: SafeArea(
@@ -112,49 +108,57 @@ class _NodeCreateOrEditPageState extends State<NodeCreateOrEditPage> {
108
child: KeyboardHideOverlay(
109
child: Container(
110
padding: const EdgeInsets.only(left: 18, right: 18),
115
- child: Column(
116
- spacing: 18,
117
- children: [NodeForm(
111
+ child: Column(spacing: 18, children: [
112
+ NodeForm(
113
key: _nodeFormKey,
114
nodeViewModel: widget.nodeCreateOrEditViewModel,
115
),
121
- NewListSections(sections: {"":[
122
- if(widget.editingNode != null)
123
-
124
- ListItemRegularRow(keyValue: "share", label: S.of(context).share_this_node, foregroundColor: Theme.of(context).colorScheme.primary, showArrow: false, onTap: (){
125
-
126
- Navigator.of(context).push(CupertinoPageRoute(builder: (context)=>NodeSharePage(uri: widget.editingNode!.uri, currency: walletTypeToCryptoCurrency(widget.type!))));
127
-
128
-
129
- }),
130
- if(!(widget.editingNode == null ||
131
- !widget.nodeCreateOrEditViewModel.isReady ||
132
- widget.editingNode!.isBuiltin ||
133
- (widget.isSelected ?? false)))
134
- ListItemRegularRow(keyValue: "delete", label: S.of(context).delete_this_node, foregroundColor: Theme.of(context).colorScheme.errorContainer, showArrow: false, onTap: ()async{
135
- final confirmed = await showPopUp<bool>(
136
- context: context,
137
- builder: (context) => AlertWithTwoActions(
138
- alertTitle: S.of(context).remove_node,
139
- alertContent: S.of(context).remove_node_message,
140
- rightButtonText: S.of(context).remove,
141
- leftButtonText: S.of(context).cancel,
142
- actionRightButton: () => Navigator.pop(context, true),
143
- actionLeftButton: () => Navigator.pop(context, false),
144
- ),
145
- ) ??
146
- false;
147
-
148
- if (confirmed) {
149
- await widget.nodeCreateOrEditViewModel.delete(editingNode: widget.editingNode!);
150
- Navigator.of(context).pop();
151
- }
152
-
153
- })
154
- ]})
155
-
156
- ]
157
- ),
116
+ NewListSections(sections: {
117
+ "": [
118
+ if (widget.editingNode != null)
119
+ ListItemRegularRow(
120
+ keyValue: "share",
121
+ label: S.of(context).share_this_node,
122
+ foregroundColor: Theme.of(context).colorScheme.primary,
123
+ showArrow: false,
124
+ onTap: () {
125
+ Navigator.of(context).push(CupertinoPageRoute(
126
+ builder: (context) => NodeSharePage(
127
+ uri: widget.editingNode!.uri,
128
+ currency: walletTypeToCryptoCurrency(widget.type!))));
129
+ }),
130
+ if (!(widget.editingNode == null ||
131
+ !widget.nodeCreateOrEditViewModel.isReady ||
132
+ widget.editingNode!.isBuiltin ||
133
+ (widget.isSelected ?? false)))
134
+ ListItemRegularRow(
135
+ keyValue: "delete",
136
+ label: S.of(context).delete_this_node,
137
+ foregroundColor: Theme.of(context).colorScheme.errorContainer,
138
+ showArrow: false,
139
+ onTap: () async {
140
+ final confirmed = await showPopUp<bool>(
141
+ context: context,
142
+ builder: (context) => AlertWithTwoActions(
143
+ alertTitle: S.of(context).remove_node,
144
+ alertContent: S.of(context).remove_node_message,
145
+ rightButtonText: S.of(context).remove,
146
+ leftButtonText: S.of(context).cancel,
147
+ actionRightButton: () => Navigator.pop(context, true),
148
+ actionLeftButton: () => Navigator.pop(context, false),
149
+ ),
150
+ ) ??
151
+ false;
152
+
153
+ if (confirmed) {
154
+ await widget.nodeCreateOrEditViewModel
155
+ .delete(editingNode: widget.editingNode!);
156
+ Navigator.of(context).pop();
157
+ }
158
+ })
159
+ ]
160
+ })
161
+ ]),
162
),
163
),
164
),
lib/src/screens/nodes/pow_node_create_or_edit_page.dart
+23
-20
@@ -18,11 +18,7 @@ import 'package:cake_wallet/src/widgets/scrollable_with_bottom_section.dart';
18
19
class PowNodeCreateOrEditPage extends StatefulWidget {
20
PowNodeCreateOrEditPage(
21
- {required this.nodeCreateOrEditViewModel, this.editingNode, this.isSelected})
22
- ;
23
-
24
-
25
-
21
+ {required this.nodeCreateOrEditViewModel, this.editingNode, this.isSelected});
22
23
final NodeCreateOrEditViewModel nodeCreateOrEditViewModel;
24
final Node? editingNode;
@@ -35,7 +31,6 @@ class PowNodeCreateOrEditPage extends StatefulWidget {
31
class _PowNodeCreateOrEditPageState extends State<PowNodeCreateOrEditPage> {
32
final _formKey = GlobalKey<NodeFormState>();
33
38
-
34
@override
35
void initState() {
36
super.initState();
@@ -72,7 +67,6 @@ class _PowNodeCreateOrEditPageState extends State<PowNodeCreateOrEditPage> {
67
68
@override
69
Widget build(BuildContext context) {
75
-
70
return Container(
71
color: Theme.of(context).colorScheme.surface,
72
child: KeyboardHideOverlay(
@@ -82,11 +76,15 @@ class _PowNodeCreateOrEditPageState extends State<PowNodeCreateOrEditPage> {
76
title: widget.editingNode != null ? S.current.edit_node : S.current.node_new,
77
leadingIcon: Icon(Icons.arrow_back_ios_new),
78
onLeadingPressed: Navigator.of(context).pop,
85
- trailingIcon: CakeImageWidget(imageUrl:
86
- "assets/new-ui/scan.svg",width:24,height:24,
87
- colorFilter: ColorFilter.mode(Theme.of(context).colorScheme.primary, BlendMode.srcIn),
79
+ trailingIcon: CakeImageWidget(
80
+ imageUrl: "assets/new-ui/scan.svg",
81
+ width: 24,
82
+ height: 24,
83
+ colorFilter:
84
+ ColorFilter.mode(Theme.of(context).colorScheme.primary, BlendMode.srcIn),
85
),
89
- onTrailingPressed: () => widget.nodeCreateOrEditViewModel.scanQRCodeForNewNode(context),
86
+ onTrailingPressed: () =>
87
+ widget.nodeCreateOrEditViewModel.scanQRCodeForNewNode(context),
88
),
89
Expanded(
90
child: Container(
@@ -112,21 +110,25 @@ class _PowNodeCreateOrEditPageState extends State<PowNodeCreateOrEditPage> {
110
builder: (BuildContext context) {
111
return AlertWithTwoActions(
112
alertTitle: S.of(context).remove_node,
115
- alertContent: S.of(context).remove_node_message,
113
+ alertContent:
114
+ S.of(context).remove_node_message,
115
rightButtonText: S.of(context).remove,
116
leftButtonText: S.of(context).cancel,
118
- actionRightButton: () => Navigator.pop(context, true),
119
- actionLeftButton: () => Navigator.pop(context, false));
117
+ actionRightButton: () =>
118
+ Navigator.pop(context, true),
119
+ actionLeftButton: () =>
120
+ Navigator.pop(context, false));
121
}) ??
122
false;
122
-
123
+
124
if (confirmed) {
125
await widget.editingNode!.delete();
126
Navigator.of(context).pop();
127
}
128
},
129
text: S.of(context).delete,
129
- isDisabled: !widget.nodeCreateOrEditViewModel.isReady || (widget.isSelected ?? false),
130
+ isDisabled: !widget.nodeCreateOrEditViewModel.isReady ||
131
+ (widget.isSelected ?? false),
132
color: Theme.of(context).colorScheme.errorContainer,
133
textColor: Theme.of(context).colorScheme.onPrimary,
134
),
@@ -141,16 +143,17 @@ class _PowNodeCreateOrEditPageState extends State<PowNodeCreateOrEditPage> {
143
!_formKey.currentState!.validate()) {
144
return;
145
}
144
-
145
- await widget.nodeCreateOrEditViewModel.save(
146
- saveAsCurrent: widget.isSelected ?? false);
146
+
147
+ await widget.nodeCreateOrEditViewModel
148
+ .save(saveAsCurrent: widget.isSelected ?? false);
149
Navigator.of(context).pop();
150
},
151
text: S.of(context).save,
152
color: Theme.of(context).colorScheme.primary,
153
textColor: Theme.of(context).colorScheme.onPrimary,
154
isDisabled: (!widget.nodeCreateOrEditViewModel.isReady) ||
153
- (widget.nodeCreateOrEditViewModel.connectionState is IsExecutingState),
155
+ (widget.nodeCreateOrEditViewModel.connectionState
156
+ is IsExecutingState),
157
),
158
)),
159
],
lib/src/screens/nodes/widgets/node_form.dart
+90
-93
@@ -34,7 +34,7 @@ class NodeFormState extends State<NodeForm> {
34
void initState() {
35
super.initState();
36
37
- for(final key in vm.textFieldKeys) {
37
+ for (final key in vm.textFieldKeys) {
38
_controllers[key] = TextEditingController();
39
40
_controllers[key]!.text = vm.getTextValue(key);
@@ -61,114 +61,112 @@ class NodeFormState extends State<NodeForm> {
61
@override
62
Widget build(BuildContext context) {
63
return Observer(
64
- builder: (_)=>Form(
64
+ builder: (_) => Form(
65
key: _formKey,
66
child: NewListSections(
67
- sections: {
68
- if(!(vm.editingNode?.isBuiltin ?? false)) ...{
69
- 'main': [
70
- ListItemTextField(
71
- keyValue: vm.nodeLabelUIKey,
72
- label: 'Node label',
73
- initialValue: vm.label,
74
- ),
75
- ListItemTextField(
76
- keyValue: vm.nodeAddressUIKey,
77
- label: S.current.node_address,
78
- initialValue: vm.address,
79
- validator: vm.walletType == WalletType.decred
80
- ? NodeAddressValidatorDecredBlankException()
81
- : NodeAddressValidator(),
82
- ),
83
- if (vm.hasPathSupport)
67
+ sections: {
68
+ if (!(vm.editingNode?.isBuiltin ?? false)) ...{
69
+ 'main': [
70
ListItemTextField(
85
- keyValue: vm.nodePathUIKey,
86
- label: '/path',
87
- initialValue: vm.path,
88
- validator: NodePathValidator(),
71
+ keyValue: vm.nodeLabelUIKey,
72
+ label: 'Node label',
73
+ initialValue: vm.label,
74
),
90
- ListItemTextField(
91
- keyValue: vm.nodePortUIKey,
92
- label: S.current.node_port,
93
- initialValue: '',
94
- //keyboardType: TextInputType.numberWithOptions(signed: false, decimal: false),
95
- validator: NodePortValidator(),
96
- ),
97
- if (vm.hasAuthCredentials) ...[
75
ListItemTextField(
99
- keyValue: vm.nodeUsernameUIKey,
100
- label: S.current.login,
101
- initialValue: vm.login,
76
+ keyValue: vm.nodeAddressUIKey,
77
+ label: S.current.node_address,
78
+ initialValue: vm.address,
79
+ validator: vm.walletType == WalletType.decred
80
+ ? NodeAddressValidatorDecredBlankException()
81
+ : NodeAddressValidator(),
82
),
83
+ if (vm.hasPathSupport)
84
+ ListItemTextField(
85
+ keyValue: vm.nodePathUIKey,
86
+ label: '/path',
87
+ initialValue: vm.path,
88
+ validator: NodePathValidator(),
89
+ ),
90
ListItemTextField(
104
- keyValue: vm.nodePasswordUIKey,
105
- label: S.current.password,
106
- initialValue: vm.password,
91
+ keyValue: vm.nodePortUIKey,
92
+ label: S.current.node_port,
93
+ initialValue: '',
94
+ //keyboardType: TextInputType.numberWithOptions(signed: false, decimal: false),
95
+ validator: NodePortValidator(),
96
),
108
- ]
109
- ],
110
- 'advanced': [
111
- ListItemCheckbox(
112
- keyValue: vm.useSSLUIKey,
113
- label: S.current.use_ssl,
114
- value: vm.useSSL,
115
- onChanged: (value) => vm.useSSL = value),
97
+ if (vm.hasAuthCredentials) ...[
98
+ ListItemTextField(
99
+ keyValue: vm.nodeUsernameUIKey,
100
+ label: S.current.login,
101
+ initialValue: vm.login,
102
+ ),
103
+ ListItemTextField(
104
+ keyValue: vm.nodePasswordUIKey,
105
+ label: S.current.password,
106
+ initialValue: vm.password,
107
+ ),
108
+ ]
109
+ ],
110
+ 'advanced': [
111
+ ListItemCheckbox(
112
+ keyValue: vm.useSSLUIKey,
113
+ label: S.current.use_ssl,
114
+ value: vm.useSSL,
115
+ onChanged: (value) => vm.useSSL = value),
116
+ ListItemCheckbox(
117
+ keyValue: vm.nodeTrustedUIKey,
118
+ label: S.current.trusted,
119
+ value: vm.trusted,
120
+ onChanged: (value) => vm.trusted = value,
121
+ ),
122
+ if (vm.usesEmbeddedProxy)
123
+ ListItemCheckbox(
124
+ keyValue: vm.nodeEmbeddedTorProxyUIKey,
125
+ label: 'Embedded Tor SOCKS Proxy',
126
+ value: vm.usesEmbeddedProxy,
127
+ onChanged: (_) {},
128
+ ),
129
+ if (FeatureFlag.isAutomaticNodeSwitchingEnabled)
130
+ ListItemCheckbox(
131
+ keyValue: vm.autoSwitchingUIKey,
132
+ label: S.current.enable_for_auto_switching,
133
+ value: vm.isEnabledForAutoSwitching,
134
+ onChanged: (value) => vm.isEnabledForAutoSwitching = value),
135
+ ],
136
+ },
137
+ "proxy": [
138
ListItemCheckbox(
117
- keyValue: vm.nodeTrustedUIKey,
118
- label: S.current.trusted,
119
- value: vm.trusted,
120
- onChanged: (value) => vm.trusted = value,
139
+ keyValue: vm.useSocksProxyUIKey,
140
+ label: 'Use SOCKS Proxy',
141
+ value: vm.useSocksProxy,
142
+ onChanged: (value) {
143
+ vm.socksProxyAddress = '';
144
+ vm.useSocksProxy = value;
145
+ },
146
),
122
- if (vm.usesEmbeddedProxy)
123
- ListItemCheckbox(
124
- keyValue: vm.nodeEmbeddedTorProxyUIKey,
125
- label: 'Embedded Tor SOCKS Proxy',
126
- value: vm.usesEmbeddedProxy,
127
- onChanged: (_) {},
147
+ if (vm.useSocksProxy)
148
+ ListItemTextField(
149
+ keyValue: vm.socksProxyAddressUIKey,
150
+ label: 'host:port',
151
+ initialValue: vm.socksProxyAddress,
152
+ validator: SocksProxyNodeAddressValidator(),
153
),
129
- if(FeatureFlag.isAutomaticNodeSwitchingEnabled)
130
- ListItemCheckbox(
131
- keyValue: vm.autoSwitchingUIKey,
132
- label: S.current.enable_for_auto_switching,
133
- value: vm.isEnabledForAutoSwitching,
134
- onChanged: (value) => vm.isEnabledForAutoSwitching = value),
135
- ],
154
+ ]
155
},
137
-
138
- "proxy" : [
139
- ListItemCheckbox(
140
- keyValue: vm.useSocksProxyUIKey,
141
- label: 'Use SOCKS Proxy',
142
- value: vm.useSocksProxy,
143
- onChanged: (value) {
144
- vm.socksProxyAddress = '';
145
- vm.useSocksProxy = value;
146
- },
147
- ),
148
- if (vm.useSocksProxy)
149
- ListItemTextField(
150
- keyValue: vm.socksProxyAddressUIKey,
151
- label: 'host:port',
152
- initialValue: vm.socksProxyAddress,
153
- validator: SocksProxyNodeAddressValidator(),
154
- ),
155
- ]
156
- },
157
- controllers: _controllers,
158
- getCheckboxValue: vm.getCheckboxValue,
159
- updateCheckboxValue: vm.updateCheckboxValue,
160
- tapHandlers: tapHandlers
161
- ),
156
+ controllers: _controllers,
157
+ getCheckboxValue: vm.getCheckboxValue,
158
+ updateCheckboxValue: vm.updateCheckboxValue,
159
+ tapHandlers: tapHandlers),
160
),
161
);
162
}
163
164
Map<String, VoidCallback> get tapHandlers => {
167
- 'node_regular_with_drill_in_row_key': () => _showToast('Regular with drill-in row tapped'),
168
- 'node_tall_row_key': () => _showToast('Tall row tapped'),
169
- 'node_regular_with_trailing_row_key': () => _showToast('Regular with trailing row tapped'),
170
- 'node_item_selector_row_key': () => _showToast('Item selector row tapped'),
171
- };
165
+ 'node_regular_with_drill_in_row_key': () => _showToast('Regular with drill-in row tapped'),
166
+ 'node_tall_row_key': () => _showToast('Tall row tapped'),
167
+ 'node_regular_with_trailing_row_key': () => _showToast('Regular with trailing row tapped'),
168
+ 'node_item_selector_row_key': () => _showToast('Item selector row tapped'),
169
+ };
170
171
void _showToast(String msg) async {
172
try {
@@ -179,7 +177,6 @@ class NodeFormState extends State<NodeForm> {
177
} catch (_) {}
178
}
179
182
-
180
void _setupReactions() {
181
_bindController(() => vm.label, vm.nodeLabelUIKey);
182
_bindController(() => vm.address, vm.nodeAddressUIKey);
lib/src/screens/nodes/widgets/node_list_row.dart
+35
-18
@@ -8,7 +8,7 @@ class NodeListRow extends StatelessWidget {
8
NodeListRow(
9
{required this.node,
10
required this.onTap,
11
- required this.onEditComplete,
11
+ required this.onEditComplete,
12
required this.isSelected,
13
required this.isPow,
14
this.speed,
@@ -42,20 +42,36 @@ class NodeListRow extends StatelessWidget {
42
mainAxisAlignment: MainAxisAlignment.spaceBetween,
43
children: <Widget>[
44
leading,
45
- Expanded(
46
- child: Column(crossAxisAlignment:CrossAxisAlignment.start,spacing:4,children: [
47
- Row(
48
- spacing: 4,
49
- mainAxisAlignment: MainAxisAlignment.start,
50
- children: [
51
- Text(hasLabel ? node.label! : uriText, style: TextStyle(fontSize: 12),),
52
- if(badgePath != null)
53
- CakeImageWidget(imageUrl: badgePath, colorFilter: ColorFilter.mode(Theme.of(context).colorScheme.primary,BlendMode.srcIn),)
54
- ],
55
- ),
56
- if(hasLabel) Text(uriText, style: TextStyle(fontSize: 12, color: Theme.of(context).colorScheme.onSurfaceVariant),),
57
- ],),
58
- ),
45
+ Expanded(
46
+ child: Column(
47
+ crossAxisAlignment: CrossAxisAlignment.start,
48
+ spacing: 4,
49
+ children: [
50
+ Row(
51
+ spacing: 4,
52
+ mainAxisAlignment: MainAxisAlignment.start,
53
+ children: [
54
+ Text(
55
+ hasLabel ? node.label! : uriText,
56
+ style: TextStyle(fontSize: 12),
57
+ ),
58
+ if (badgePath != null)
59
+ CakeImageWidget(
60
+ imageUrl: badgePath,
61
+ colorFilter: ColorFilter.mode(
62
+ Theme.of(context).colorScheme.primary, BlendMode.srcIn),
63
+ )
64
+ ],
65
+ ),
66
+ if (hasLabel)
67
+ Text(
68
+ uriText,
69
+ style: TextStyle(
70
+ fontSize: 12, color: Theme.of(context).colorScheme.onSurfaceVariant),
71
+ ),
72
+ ],
73
+ ),
74
+ ),
75
trailing,
76
],
77
),
@@ -89,7 +105,8 @@ class NodeListRow extends StatelessWidget {
105
GestureDetector(
106
behavior: HitTestBehavior.opaque,
107
onTap: () async {
92
- final res = await Navigator.of(context).pushNamed(isPow ? Routes.newPowNode : Routes.newNode,
108
+ final res = await Navigator.of(context).pushNamed(
109
+ isPow ? Routes.newPowNode : Routes.newNode,
110
arguments: {'editingNode': node, 'isSelected': isSelected});
111
await onEditComplete(res);
112
},
@@ -107,8 +124,8 @@ class NodeListRow extends StatelessWidget {
124
}
125
126
String? get badgePath {
110
- if(node.isOfficial) return "assets/new-ui/official_node.svg";
111
- if(node.isBuiltin) return "assets/new-ui/default_node.svg";
127
+ if (node.isOfficial) return "assets/new-ui/official_node.svg";
128
+ if (node.isBuiltin) return "assets/new-ui/default_node.svg";
129
return null;
130
}
131
}
lib/src/screens/pin_code/pin_code.dart
+2
-6
@@ -2,12 +2,8 @@ import 'package:flutter/foundation.dart';
2
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
3
4
class PinCode extends PinCodeWidget {
5
- PinCode(
6
- void Function(String pin, PinCodeState state) onFullPin,
7
- void Function(String pin) onChangedPin,
8
- int initialPinLength,
9
- bool hasLengthSwitcher,
10
- Key key)
5
+ PinCode(void Function(String pin, PinCodeState state) onFullPin,
6
+ void Function(String pin) onChangedPin, int initialPinLength, bool hasLengthSwitcher, Key key)
7
: super(
8
key: key,
9
onFullPin: onFullPin,
lib/src/screens/pin_code/pin_code_widget.dart
+4
-2
@@ -231,7 +231,8 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
231
child: TextButton(
232
onPressed: () => {_pop(), HapticFeedback.mediumImpact()},
233
style: TextButton.styleFrom(
234
- backgroundColor: Theme.of(context).colorScheme.surfaceContainer,
234
+ backgroundColor:
235
+ Theme.of(context).colorScheme.surfaceContainer,
236
shape: CircleBorder(),
237
),
238
child: deleteIconImage,
@@ -249,7 +250,8 @@ class PinCodeState<T extends PinCodeWidget> extends State<T> {
250
key: ValueKey('pin_code_button_${index}_key'),
251
onPressed: () => {_push(index), HapticFeedback.mediumImpact()},
252
style: TextButton.styleFrom(
252
- backgroundColor: Theme.of(context).colorScheme.surfaceContainer,
253
+ backgroundColor:
254
+ Theme.of(context).colorScheme.surfaceContainer,
255
shape: CircleBorder(),
256
),
257
child: Text('$index',
lib/src/screens/receive/widgets/anonpay_status_section.dart
+12
-12
@@ -28,9 +28,9 @@ class AnonInvoiceStatusSection extends StatelessWidget {
28
Text(
29
S.current.status,
30
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
31
- fontWeight: FontWeight.w500,
32
- color: Theme.of(context).colorScheme.onSurfaceVariant,
33
- ),
31
+ fontWeight: FontWeight.w500,
32
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
33
+ ),
34
),
35
Container(
36
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
@@ -50,9 +50,9 @@ class AnonInvoiceStatusSection extends StatelessWidget {
50
Text(
51
invoiceInfo.status,
52
style: Theme.of(context).textTheme.bodySmall?.copyWith(
53
- fontWeight: FontWeight.w600,
54
- color: Theme.of(context).colorScheme.onSecondaryContainer,
55
- ),
53
+ fontWeight: FontWeight.w600,
54
+ color: Theme.of(context).colorScheme.onSecondaryContainer,
55
+ ),
56
),
57
],
58
),
@@ -66,16 +66,16 @@ class AnonInvoiceStatusSection extends StatelessWidget {
66
Text(
67
'ID',
68
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
69
- fontWeight: FontWeight.w500,
70
- color: Theme.of(context).colorScheme.onSurfaceVariant,
71
- ),
69
+ fontWeight: FontWeight.w500,
70
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
71
+ ),
72
),
73
Text(
74
invoiceInfo.invoiceId,
75
style: Theme.of(context).textTheme.bodySmall?.copyWith(
76
- fontWeight: FontWeight.w600,
77
- color: Theme.of(context).colorScheme.onSurface,
78
- ),
76
+ fontWeight: FontWeight.w600,
77
+ color: Theme.of(context).colorScheme.onSurface,
78
+ ),
79
),
80
],
81
),
lib/src/screens/receive/widgets/copy_link_item.dart
+2
-2
@@ -20,8 +20,8 @@ class CopyLinkItem extends StatelessWidget {
20
Text(
21
title,
22
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
23
- color: Theme.of(context).colorScheme.onSurface,
24
- ),
23
+ color: Theme.of(context).colorScheme.onSurface,
24
+ ),
25
),
26
SizedBox(width: 50),
27
Row(
lib/src/screens/release_notes/release_notes_screen.dart
+9
-11
@@ -47,12 +47,11 @@ class ReleaseNotesScreen extends StatelessWidget {
47
alignment: Alignment.bottomCenter,
48
child: DefaultTextStyle(
49
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
50
- decoration: TextDecoration.none,
51
- fontSize: 24.0,
52
- fontWeight: FontWeight.bold,
53
-
54
- color: Theme.of(context).colorScheme.onSurface,
55
- ),
50
+ decoration: TextDecoration.none,
51
+ fontSize: 24.0,
52
+ fontWeight: FontWeight.bold,
53
+ color: Theme.of(context).colorScheme.onSurface,
54
+ ),
55
child: Text(title),
56
),
57
),
@@ -115,11 +114,10 @@ class ReleaseNotesScreen extends StatelessWidget {
114
children: [
115
DefaultTextStyle(
116
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
118
- decoration: TextDecoration.none,
119
- fontSize: 16.0,
120
-
121
- color: Theme.of(context).colorScheme.onSurface,
122
- ),
117
+ decoration: TextDecoration.none,
118
+ fontSize: 16.0,
119
+ color: Theme.of(context).colorScheme.onSurface,
120
+ ),
121
child: Row(
122
crossAxisAlignment: CrossAxisAlignment.start,
123
children: [
lib/src/screens/rescan/rescan_page.dart
-1
@@ -25,7 +25,6 @@ class RescanPage extends StatefulWidget {
25
class _RescanPageState extends State<RescanPage> {
26
final TextEditingController _heightController = TextEditingController();
27
28
-
28
@override
29
Widget build(BuildContext context) {
30
Widget child;
lib/src/screens/restore/restore_from_backup_page.dart
+8
-8
@@ -207,14 +207,14 @@ class RestoreFromBackupPage extends BasePage {
207
}
208
} catch (e) {
209
await showPopUp<void>(
210
- context: context,
211
- builder: (_) {
212
- return AlertWithOneAction(
213
- alertTitle: S.current.error,
214
- alertContent: e.toString(),
215
- buttonText: S.of(context).ok,
216
- buttonAction: () => Navigator.of(context).pop());
217
- });
210
+ context: context,
211
+ builder: (_) {
212
+ return AlertWithOneAction(
213
+ alertTitle: S.current.error,
214
+ alertContent: e.toString(),
215
+ buttonText: S.of(context).ok,
216
+ buttonAction: () => Navigator.of(context).pop());
217
+ });
218
}
219
textEditingController.text = '';
220
}
lib/src/screens/restore/restore_options_page.dart
+5
-5
@@ -23,9 +23,9 @@ class RestoreOptionsPage extends BasePage {
23
24
@override
25
Widget body(BuildContext context) => _RestoreOptionsBody(
26
- isNewInstall: isNewInstall,
27
- themeType: currentTheme.type,
28
- );
26
+ isNewInstall: isNewInstall,
27
+ themeType: currentTheme.type,
28
+ );
29
}
30
31
class _RestoreOptionsBody extends StatefulWidget {
@@ -157,7 +157,7 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> {
157
158
Future<void> _onScanQRCode(BuildContext context) async {
159
final isCameraPermissionGranted =
160
- await PermissionHandler.checkPermission(Permission.camera, context);
160
+ await PermissionHandler.checkPermission(Permission.camera, context);
161
162
if (!isCameraPermissionGranted) return;
163
try {
@@ -180,4 +180,4 @@ class _RestoreOptionsBodyState extends State<_RestoreOptionsBody> {
180
_showQRScanError(context, e.toString());
181
}
182
}
183
-}
\ No newline at end of file
183
+}
lib/src/screens/restore/wallet_restore_choose_derivation.dart
+4
-3
@@ -11,9 +11,10 @@ class WalletRestoreChooseDerivationPage extends BasePage {
11
@override
12
Widget middle(BuildContext context) => Text(
13
S.current.choose_derivation,
14
- style: Theme.of(context).textTheme.titleLarge?.copyWith(
15
- fontWeight: FontWeight.bold,
16
- color: Theme.of(context).colorScheme.primary),
14
+ style: Theme.of(context)
15
+ .textTheme
16
+ .titleLarge
17
+ ?.copyWith(fontWeight: FontWeight.bold, color: Theme.of(context).colorScheme.primary),
18
);
19
20
final WalletRestoreChooseDerivationViewModel walletRestoreChooseDerivationViewModel;
lib/src/screens/restore/wallet_restore_from_keys_form.dart
+18
-20
@@ -232,27 +232,25 @@ class WalletRestoreFromKeysFormState extends State<WalletRestoreFromKeysForm> {
232
233
bool nanoBased = widget.walletRestoreViewModel.type == WalletType.nano ||
234
widget.walletRestoreViewModel.type == WalletType.banano;
235
- return Column(
236
- children: [
237
- AddressTextField(
238
- addressKey: ValueKey('wallet_restore_from_key_private_key_textfield_key'),
239
- controller: privateKeyController,
240
- placeholder: nanoBased ? S.of(context).seed_hex_form : S.of(context).private_key,
241
- options: [AddressTextFieldOption.paste],
242
- onPushPasteButton: (_) {
243
- _pasteText();
244
- },
235
+ return Column(children: [
236
+ AddressTextField(
237
+ addressKey: ValueKey('wallet_restore_from_key_private_key_textfield_key'),
238
+ controller: privateKeyController,
239
+ placeholder: nanoBased ? S.of(context).seed_hex_form : S.of(context).private_key,
240
+ options: [AddressTextFieldOption.paste],
241
+ onPushPasteButton: (_) {
242
+ _pasteText();
243
+ },
244
+ ),
245
+ if (widget.walletRestoreViewModel.hasBlockchainHeightSelector)
246
+ BlockchainHeightWidget(
247
+ key: blockchainHeightKey,
248
+ hasDatePicker: widget.walletRestoreViewModel.type != WalletType.haven,
249
+ onHeightChange: (_) => null,
250
+ onHeightOrDateEntered: widget.onHeightOrDateEntered,
251
+ walletType: widget.walletRestoreViewModel.type,
252
),
246
- if (widget.walletRestoreViewModel.hasBlockchainHeightSelector)
247
- BlockchainHeightWidget(
248
- key: blockchainHeightKey,
249
- hasDatePicker: widget.walletRestoreViewModel.type != WalletType.haven,
250
- onHeightChange: (_) => null,
251
- onHeightOrDateEntered: widget.onHeightOrDateEntered,
252
- walletType: widget.walletRestoreViewModel.type,
253
- ),
254
- ]
255
- );
253
+ ]);
254
}
255
256
return Column(
lib/src/screens/restore/wallet_restore_from_seed_form.dart
+1
-1
@@ -161,7 +161,7 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
161
onPressed: () async {
162
final rName = await generateName();
163
FocusManager.instance.primaryFocus?.unfocus();
164
-
164
+
165
setState(() {
166
nameTextEditingController.text = rName;
167
nameTextEditingController.selection = TextSelection.fromPosition(
lib/src/screens/restore/wallet_restore_page.dart
+2
-3
@@ -298,8 +298,7 @@ class WalletRestorePage extends BasePage {
298
"m/49'/0'/0'",
299
};
300
301
- final shouldSkipChooseDerivationScreen =
302
- derivationPathsWithHistory.isNotEmpty &&
301
+ final shouldSkipChooseDerivationScreen = derivationPathsWithHistory.isNotEmpty &&
302
derivationPathsWithHistory.every(scanDerivationPaths.contains);
303
304
if (derivationsWithHistory > 1 && !shouldSkipChooseDerivationScreen) {
@@ -537,7 +536,7 @@ class _WalletRestorePageBodyState extends State<_WalletRestorePageBody>
536
},
537
onViewKeyEntered: (bool entered) {
538
if (widget.walletRestoreViewModel.onlyViewKeyRestore ||
540
- walletRestoreViewModel.type == WalletType.litecoin) {
539
+ walletRestoreViewModel.type == WalletType.litecoin) {
540
walletRestoreViewModel.isButtonEnabled = entered;
541
}
542
},
lib/src/screens/root/root.dart
-2
@@ -118,7 +118,6 @@ class RootState extends State<Root> with WidgetsBindingObserver {
118
final uri = Uri.parse('cakewallet://quickaction/${widget.initialQuickAction}');
119
handleDeepLinking(uri);
120
}
121
-
121
} catch (e) {
122
printV(e);
123
}
@@ -136,7 +135,6 @@ class RootState extends State<Root> with WidgetsBindingObserver {
135
136
bool requireAuth = await widget.authService.requireAuth();
137
139
-
138
if (widget.authenticationStore.state == AuthenticationState.allowedCreate) {
139
requireAuth = false;
140
}
lib/src/screens/seed/seed_verification/seed_verification_success_view.dart
+9
-7
@@ -21,12 +21,12 @@ class SeedVerificationSuccessView extends StatelessWidget {
21
children: [
22
ConstrainedBox(
23
constraints: BoxConstraints(maxHeight: MediaQuery.of(context).size.height * 0.3),
24
- child: CakeImageWidget(
25
- height: 128,
26
- imageUrl: currentTheme.isDark
27
- ? 'assets/images/seed_verified_dark.png'
28
- : 'assets/images/seed_verified_light.png',
29
- ),
24
+ child: CakeImageWidget(
25
+ height: 128,
26
+ imageUrl: currentTheme.isDark
27
+ ? 'assets/images/seed_verified_dark.png'
28
+ : 'assets/images/seed_verified_light.png',
29
+ ),
30
),
31
SizedBox(height: 40),
32
Text(
@@ -72,7 +72,9 @@ class SeedVerificationSuccessView extends StatelessWidget {
72
Navigator.of(context).popUntil((route) => route.isFirst);
73
}
74
},
75
- text: (walletType == WalletType.bitcoin) ? S.current.continue_text : S.current.open_wallet,
75
+ text: (walletType == WalletType.bitcoin)
76
+ ? S.current.continue_text
77
+ : S.current.open_wallet,
78
color: Theme.of(context).colorScheme.primary,
79
textColor: Theme.of(context).colorScheme.onPrimary,
80
),
lib/src/screens/seed/wallet_seed_page.dart
+10
-9
@@ -21,7 +21,8 @@ class WalletSeedPage extends BasePage {
21
WalletSeedPage(this.walletSeedViewModel, {required this.isNewWalletCreated});
22
23
@override
24
- String get title => '${walletTypeToString(walletSeedViewModel.walletType)} ${S.current.seed_title}';
24
+ String get title =>
25
+ '${walletTypeToString(walletSeedViewModel.walletType)} ${S.current.seed_title}';
26
27
final bool isNewWalletCreated;
28
final WalletSeedViewModel walletSeedViewModel;
@@ -144,14 +145,14 @@ class WalletSeedPage extends BasePage {
145
}
146
147
void _shareSeed(BuildContext context) async {
147
- switch(defaultTargetPlatform) {
148
+ switch (defaultTargetPlatform) {
149
case TargetPlatform.android:
150
case TargetPlatform.iOS:
150
- ShareUtil.share(
151
- text: walletSeedViewModel.seed,
152
- context: context,
153
- );
154
- break;
151
+ ShareUtil.share(
152
+ text: walletSeedViewModel.seed,
153
+ context: context,
154
+ );
155
+ break;
156
case TargetPlatform.macOS:
157
case TargetPlatform.windows:
158
case TargetPlatform.linux:
@@ -160,12 +161,12 @@ class WalletSeedPage extends BasePage {
161
fileName: "${walletSeedViewModel.name}-seed.txt",
162
lockParentWindow: true,
163
);
163
- if(path != null) {
164
+ if (path != null) {
165
final file = File(path);
166
await file.writeAsString(walletSeedViewModel.seed);
167
}
168
default:
168
-break;
169
+ break;
170
}
171
}
172
}
lib/src/screens/send/send_page.dart
+337
-328
@@ -67,7 +67,6 @@ class SendPage extends BasePage {
67
68
final currentPage = ValueNotifier<int>(0);
69
70
-
70
bool _effectsInstalled = false;
71
ContactRecord? newContactAddress;
72
@@ -176,323 +175,334 @@ class SendPage extends BasePage {
175
_setEffects(context);
176
177
return ValueListenableBuilder(
179
- valueListenable: currentPage,
180
- builder: (context, value, child) {
181
- return Observer(builder: (_) {
182
- List<Widget> sendCards = [];
183
- List<KeyboardActionsItem> keyboardActions = [];
184
- for (final output in sendViewModel.outputs) {
185
- final isCurrent = sendViewModel.outputs.indexOf(output) == value;
186
- sendCards.add(
187
- SendCard(
188
- currentTheme: currentTheme,
189
- key: output.key,
190
- output: output,
191
- sendViewModel: sendViewModel,
192
- paymentViewModel: paymentViewModel,
193
- walletSwitcherViewModel: walletSwitcherViewModel,
194
- initialPaymentRequest: initialPaymentRequest,
195
- cryptoAmountFocus: isCurrent ? _cryptoAmountFocus : null,
196
- fiatAmountFocus: isCurrent ? _fiatAmountFocus : null,
197
- ),
198
- );
199
- keyboardActions.add(
200
- KeyboardActionsItem(
201
- focusNode: _cryptoAmountFocus,
202
- toolbarButtons: [(_) => KeyboardDoneButton()],
203
- ),
204
- );
205
- keyboardActions.add(
206
- KeyboardActionsItem(
207
- focusNode: _fiatAmountFocus,
208
- toolbarButtons: [(_) => KeyboardDoneButton()],
209
- ),
210
- );
211
- }
212
- return Stack(
213
- children: [
214
- KeyboardActions(
215
- config: KeyboardActionsConfig(
216
- keyboardActionsPlatform: KeyboardActionsPlatform.ALL,
217
- keyboardBarColor: Theme.of(context).colorScheme.surface,
218
- nextFocus: false,
219
- actions: keyboardActions,
178
+ valueListenable: currentPage,
179
+ builder: (context, value, child) {
180
+ return Observer(builder: (_) {
181
+ List<Widget> sendCards = [];
182
+ List<KeyboardActionsItem> keyboardActions = [];
183
+ for (final output in sendViewModel.outputs) {
184
+ final isCurrent = sendViewModel.outputs.indexOf(output) == value;
185
+ sendCards.add(
186
+ SendCard(
187
+ currentTheme: currentTheme,
188
+ key: output.key,
189
+ output: output,
190
+ sendViewModel: sendViewModel,
191
+ paymentViewModel: paymentViewModel,
192
+ walletSwitcherViewModel: walletSwitcherViewModel,
193
+ initialPaymentRequest: initialPaymentRequest,
194
+ cryptoAmountFocus: isCurrent ? _cryptoAmountFocus : null,
195
+ fiatAmountFocus: isCurrent ? _fiatAmountFocus : null,
196
),
221
- child: Container(
222
- height: 0,
223
- color: Colors.transparent,
197
+ );
198
+ keyboardActions.add(
199
+ KeyboardActionsItem(
200
+ focusNode: _cryptoAmountFocus,
201
+ toolbarButtons: [(_) => KeyboardDoneButton()],
202
),
225
- ),
226
- GestureDetector(
227
- onLongPress: () => sendViewModel.balanceViewModel.isReversing =
228
- !sendViewModel.balanceViewModel.isReversing,
229
- onLongPressUp: () => sendViewModel.balanceViewModel.isReversing =
230
- !sendViewModel.balanceViewModel.isReversing,
231
- child: RepaintBoundary(
232
- child: Form(
233
- key: _formKey,
234
- child: ScrollableWithBottomSection(
235
- contentPadding: EdgeInsets.only(bottom: 24),
236
- content: FocusTraversalGroup(
237
- policy: OrderedTraversalPolicy(),
238
- child: Column(
239
- children: <Widget>[
240
- PageViewHeightAdaptable(
241
- controller: controller,
242
- children: sendCards,
243
- ),
244
- SizedBox(height: 10),
245
- Padding(
246
- padding: EdgeInsets.only(left: 24, right: 24, bottom: 10),
247
- child: Container(
248
- height: 10,
249
- child: Observer(
250
- builder: (_) {
251
- final count = sendViewModel.outputs.length;
252
-
253
- return count > 1
254
- ? Semantics(
255
- label: 'Page Indicator',
256
- hint: 'Swipe to change receiver',
257
- excludeSemantics: true,
258
- child: SmoothPageIndicator(
259
- controller: controller,
260
- count: count,
261
- effect: ScrollingDotsEffect(
262
- spacing: 6.0,
263
- radius: 6.0,
264
- dotWidth: 6.0,
265
- dotHeight: 6.0,
266
- dotColor: Theme.of(context)
267
- .colorScheme
268
- .primary
269
- .withAlpha(100),
270
- activeDotColor: Theme.of(context).colorScheme.primary,
203
+ );
204
+ keyboardActions.add(
205
+ KeyboardActionsItem(
206
+ focusNode: _fiatAmountFocus,
207
+ toolbarButtons: [(_) => KeyboardDoneButton()],
208
+ ),
209
+ );
210
+ }
211
+ return Stack(
212
+ children: [
213
+ KeyboardActions(
214
+ config: KeyboardActionsConfig(
215
+ keyboardActionsPlatform: KeyboardActionsPlatform.ALL,
216
+ keyboardBarColor: Theme.of(context).colorScheme.surface,
217
+ nextFocus: false,
218
+ actions: keyboardActions,
219
+ ),
220
+ child: Container(
221
+ height: 0,
222
+ color: Colors.transparent,
223
+ ),
224
+ ),
225
+ GestureDetector(
226
+ onLongPress: () => sendViewModel.balanceViewModel.isReversing =
227
+ !sendViewModel.balanceViewModel.isReversing,
228
+ onLongPressUp: () => sendViewModel.balanceViewModel.isReversing =
229
+ !sendViewModel.balanceViewModel.isReversing,
230
+ child: RepaintBoundary(
231
+ child: Form(
232
+ key: _formKey,
233
+ child: ScrollableWithBottomSection(
234
+ contentPadding: EdgeInsets.only(bottom: 24),
235
+ content: FocusTraversalGroup(
236
+ policy: OrderedTraversalPolicy(),
237
+ child: Column(
238
+ children: <Widget>[
239
+ PageViewHeightAdaptable(
240
+ controller: controller,
241
+ children: sendCards,
242
+ ),
243
+ SizedBox(height: 10),
244
+ Padding(
245
+ padding: EdgeInsets.only(left: 24, right: 24, bottom: 10),
246
+ child: Container(
247
+ height: 10,
248
+ child: Observer(
249
+ builder: (_) {
250
+ final count = sendViewModel.outputs.length;
251
+
252
+ return count > 1
253
+ ? Semantics(
254
+ label: 'Page Indicator',
255
+ hint: 'Swipe to change receiver',
256
+ excludeSemantics: true,
257
+ child: SmoothPageIndicator(
258
+ controller: controller,
259
+ count: count,
260
+ effect: ScrollingDotsEffect(
261
+ spacing: 6.0,
262
+ radius: 6.0,
263
+ dotWidth: 6.0,
264
+ dotHeight: 6.0,
265
+ dotColor: Theme.of(context)
266
+ .colorScheme
267
+ .primary
268
+ .withAlpha(100),
269
+ activeDotColor:
270
+ Theme.of(context).colorScheme.primary,
271
+ ),
272
),
272
- ),
273
- )
274
- : Offstage();
275
- },
273
+ )
274
+ : Offstage();
275
+ },
276
+ ),
277
),
278
),
278
- ),
279
- Container(
280
- height: 40,
281
- width: double.infinity,
282
- padding: EdgeInsets.only(left: 24),
283
- child: SingleChildScrollView(
284
- scrollDirection: Axis.horizontal,
285
- child: Observer(
286
- builder: (_) {
287
- final templates = sendViewModel.templates;
288
- final itemCount = templates.length;
289
-
290
- return Row(
291
- children: <Widget>[
292
- AddTemplateButton(
293
- key: ValueKey('send_page_add_template_button_key'),
294
- onTap: () =>
295
- Navigator.of(context).pushNamed(Routes.sendTemplate),
296
- currentTemplatesLength: templates.length,
297
- ),
298
- ListView.builder(
299
- scrollDirection: Axis.horizontal,
300
- shrinkWrap: true,
301
- physics: NeverScrollableScrollPhysics(),
302
- itemCount: itemCount,
303
- itemBuilder: (context, index) {
304
- final template = templates[index];
305
- return TemplateTile(
306
- key: UniqueKey(),
307
- to: template.name,
308
- hasMultipleRecipients:
309
- template.additionalRecipients != null &&
310
- template.additionalRecipients!.length > 1,
311
- amount: template.isCurrencySelected
312
- ? template.amount
313
- : template.amountFiat,
314
- from: template.isCurrencySelected
315
- ? template.cryptoCurrency
316
- : template.fiatCurrency,
317
- onTap: () async {
318
- sendViewModel.state = LoadingTemplateExecutingState();
319
- if (template.additionalRecipients?.isNotEmpty ??
320
- false) {
321
- sendViewModel.clearOutputs();
322
-
323
- for (int i = 0;
324
- i < template.additionalRecipients!.length;
325
- i++) {
326
- Output output;
327
- try {
328
- output = sendViewModel.outputs[i];
329
- } catch (e) {
330
- sendViewModel.addOutput();
331
- output = sendViewModel.outputs[i];
279
+ Container(
280
+ height: 40,
281
+ width: double.infinity,
282
+ padding: EdgeInsets.only(left: 24),
283
+ child: SingleChildScrollView(
284
+ scrollDirection: Axis.horizontal,
285
+ child: Observer(
286
+ builder: (_) {
287
+ final templates = sendViewModel.templates;
288
+ final itemCount = templates.length;
289
+
290
+ return Row(
291
+ children: <Widget>[
292
+ AddTemplateButton(
293
+ key: ValueKey('send_page_add_template_button_key'),
294
+ onTap: () => Navigator.of(context)
295
+ .pushNamed(Routes.sendTemplate),
296
+ currentTemplatesLength: templates.length,
297
+ ),
298
+ ListView.builder(
299
+ scrollDirection: Axis.horizontal,
300
+ shrinkWrap: true,
301
+ physics: NeverScrollableScrollPhysics(),
302
+ itemCount: itemCount,
303
+ itemBuilder: (context, index) {
304
+ final template = templates[index];
305
+ return TemplateTile(
306
+ key: UniqueKey(),
307
+ to: template.name,
308
+ hasMultipleRecipients:
309
+ template.additionalRecipients != null &&
310
+ template.additionalRecipients!.length > 1,
311
+ amount: template.isCurrencySelected
312
+ ? template.amount
313
+ : template.amountFiat,
314
+ from: template.isCurrencySelected
315
+ ? template.cryptoCurrency
316
+ : template.fiatCurrency,
317
+ onTap: () async {
318
+ sendViewModel.state =
319
+ LoadingTemplateExecutingState();
320
+ if (template.additionalRecipients?.isNotEmpty ??
321
+ false) {
322
+ sendViewModel.clearOutputs();
323
+
324
+ for (int i = 0;
325
+ i < template.additionalRecipients!.length;
326
+ i++) {
327
+ Output output;
328
+ try {
329
+ output = sendViewModel.outputs[i];
330
+ } catch (e) {
331
+ sendViewModel.addOutput();
332
+ output = sendViewModel.outputs[i];
333
+ }
334
+
335
+ await _setInputsFromTemplate(
336
+ context,
337
+ output: output,
338
+ template:
339
+ template.additionalRecipients![i],
340
+ );
341
}
333
-
342
+ } else {
343
+ final output = _defineCurrentOutput();
344
await _setInputsFromTemplate(
345
context,
346
output: output,
337
- template: template.additionalRecipients![i],
347
+ template: template,
348
);
349
}
340
- } else {
341
- final output = _defineCurrentOutput();
342
- await _setInputsFromTemplate(
343
- context,
344
- output: output,
345
- template: template,
350
+ sendViewModel.state = InitialExecutionState();
351
+ },
352
+ onRemove: () {
353
+ showPopUp<void>(
354
+ context: context,
355
+ builder: (dialogContext) {
356
+ return AlertWithTwoActions(
357
+ alertTitle: S.of(context).template,
358
+ alertContent: S
359
+ .of(context)
360
+ .confirm_delete_template,
361
+ rightButtonText: S.of(context).delete,
362
+ leftButtonText: S.of(context).cancel,
363
+ actionRightButton: () {
364
+ Navigator.of(dialogContext).pop();
365
+ sendViewModel.sendTemplateViewModel
366
+ .removeTemplate(
367
+ template: template);
368
+ },
369
+ actionLeftButton: () =>
370
+ Navigator.of(dialogContext).pop());
371
+ },
372
);
347
- }
348
- sendViewModel.state = InitialExecutionState();
349
- },
350
- onRemove: () {
351
- showPopUp<void>(
352
- context: context,
353
- builder: (dialogContext) {
354
- return AlertWithTwoActions(
355
- alertTitle: S.of(context).template,
356
- alertContent:
357
- S.of(context).confirm_delete_template,
358
- rightButtonText: S.of(context).delete,
359
- leftButtonText: S.of(context).cancel,
360
- actionRightButton: () {
361
- Navigator.of(dialogContext).pop();
362
- sendViewModel.sendTemplateViewModel
363
- .removeTemplate(template: template);
364
- },
365
- actionLeftButton: () =>
366
- Navigator.of(dialogContext).pop());
367
- },
368
- );
369
- },
370
- );
371
- },
372
- ),
373
- ],
374
- );
375
- },
373
+ },
374
+ );
375
+ },
376
+ ),
377
+ ],
378
+ );
379
+ },
380
+ ),
381
),
382
),
378
- ),
379
- ],
383
+ ],
384
+ ),
385
),
381
- ),
382
- bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
383
- bottomSection: Column(
384
- children: [
385
- if (sendViewModel.sendTemplateViewModel.hasMultiRecipient)
386
- Padding(
387
- padding: EdgeInsets.only(bottom: 12),
388
- child: PrimaryButton(
389
- key: ValueKey('send_page_add_receiver_button_key'),
390
- onPressed: () {
391
- sendViewModel.addOutput();
392
- Future.delayed(const Duration(milliseconds: 250), () {
393
- controller.jumpToPage(sendViewModel.outputs.length - 1);
394
- });
395
- },
396
- text: S.of(context).add_receiver,
397
- color: Colors.transparent,
398
- textColor: Theme.of(context).colorScheme.onSurfaceVariant,
399
- isDottedBorder: true,
400
- borderColor: Theme.of(context).colorScheme.outline,
401
- )),
402
- Observer(
403
- builder: (_) {
404
- return LoadingPrimaryButton(
405
- key: ValueKey('send_page_send_button_key'),
406
- onPressed: () async {
407
- //Request dummy node to get the focus out of the text fields
408
- FocusScope.of(context).requestFocus(FocusNode());
409
-
410
- if (sendViewModel.state is IsExecutingState) return;
411
- if (_formKey.currentState != null &&
412
- !_formKey.currentState!.validate()) {
413
- if (sendViewModel.outputs.length > 1) {
414
- showErrorValidationAlert(context);
415
- }
416
-
417
- return;
418
- }
419
-
420
- final hasInvalidItems = sendViewModel.outputs.any((item) =>
421
- item.address.isEmpty ||
422
- (item.cryptoAmount.isEmpty && !item.sendAll));
423
-
424
- if (hasInvalidItems) {
425
- showErrorValidationAlert(context);
426
- return;
427
- }
428
-
429
- if (sendViewModel.wallet.isHardwareWallet) {
430
- if (!sendViewModel.hardwareWalletViewModel!.isConnected(sendViewModel.walletType)) {
431
- await Navigator.of(context).pushNamed(Routes.connectDevices,
432
- arguments: ConnectDevicePageParams(
433
- walletType: sendViewModel.walletType,
434
- hardwareWalletType:
435
- sendViewModel.wallet.walletInfo.hardwareWalletType!,
436
- onConnectDevice: (BuildContext context, _) {
437
- sendViewModel.hardwareWalletViewModel!
438
- .initWallet(sendViewModel.wallet);
439
- Navigator.of(context).pop();
440
- },
441
- ));
442
- } else {
443
- sendViewModel.hardwareWalletViewModel!
444
- .initWallet(sendViewModel.wallet);
445
- }
446
- }
447
-
448
- if (sendViewModel.wallet.type == WalletType.monero) {
449
- var amount = Money.zero(sendViewModel.wallet.currency);
450
- for (var item in sendViewModel.outputs) {
451
- amount += item.cryptoAmountMoney;
452
- }
453
- if (monero!.needExportOutputs(sendViewModel.wallet, amount)) {
454
- await Navigator.of(context).pushNamed(Routes.urqrAnimatedPage,
455
- arguments: monero!.exportOutputsUR(sendViewModel.wallet));
456
- await Future.delayed(
457
- Duration(seconds: 1)); // wait for monero to refresh the state
386
+ bottomSectionPadding: EdgeInsets.only(left: 24, right: 24, bottom: 24),
387
+ bottomSection: Column(
388
+ children: [
389
+ if (sendViewModel.sendTemplateViewModel.hasMultiRecipient)
390
+ Padding(
391
+ padding: EdgeInsets.only(bottom: 12),
392
+ child: PrimaryButton(
393
+ key: ValueKey('send_page_add_receiver_button_key'),
394
+ onPressed: () {
395
+ sendViewModel.addOutput();
396
+ Future.delayed(const Duration(milliseconds: 250), () {
397
+ controller.jumpToPage(sendViewModel.outputs.length - 1);
398
+ });
399
+ },
400
+ text: S.of(context).add_receiver,
401
+ color: Colors.transparent,
402
+ textColor: Theme.of(context).colorScheme.onSurfaceVariant,
403
+ isDottedBorder: true,
404
+ borderColor: Theme.of(context).colorScheme.outline,
405
+ )),
406
+ Observer(
407
+ builder: (_) {
408
+ return LoadingPrimaryButton(
409
+ key: ValueKey('send_page_send_button_key'),
410
+ onPressed: () async {
411
+ //Request dummy node to get the focus out of the text fields
412
+ FocusScope.of(context).requestFocus(FocusNode());
413
+
414
+ if (sendViewModel.state is IsExecutingState) return;
415
+ if (_formKey.currentState != null &&
416
+ !_formKey.currentState!.validate()) {
417
+ if (sendViewModel.outputs.length > 1) {
418
+ showErrorValidationAlert(context);
419
+ }
420
+
421
+ return;
422
}
459
- if (monero!.needExportOutputs(sendViewModel.wallet, amount)) {
423
+
424
+ final hasInvalidItems = sendViewModel.outputs.any((item) =>
425
+ item.address.isEmpty ||
426
+ (item.cryptoAmount.isEmpty && !item.sendAll));
427
+
428
+ if (hasInvalidItems) {
429
+ showErrorValidationAlert(context);
430
return;
431
}
462
- }
463
-
464
- final check = sendViewModel.shouldDisplayTotp();
465
- authService.authenticateAction(
466
- context,
467
- conditionToDetermineIfToUse2FA: check,
468
- onAuthSuccess: (value) async {
469
- if (value) {
470
- await sendViewModel.createTransaction();
432
+
433
+ if (sendViewModel.wallet.isHardwareWallet) {
434
+ if (!sendViewModel.hardwareWalletViewModel!
435
+ .isConnected(sendViewModel.walletType)) {
436
+ await Navigator.of(context)
437
+ .pushNamed(Routes.connectDevices,
438
+ arguments: ConnectDevicePageParams(
439
+ walletType: sendViewModel.walletType,
440
+ hardwareWalletType: sendViewModel
441
+ .wallet.walletInfo.hardwareWalletType!,
442
+ onConnectDevice: (BuildContext context, _) {
443
+ sendViewModel.hardwareWalletViewModel!
444
+ .initWallet(sendViewModel.wallet);
445
+ Navigator.of(context).pop();
446
+ },
447
+ ));
448
+ } else {
449
+ sendViewModel.hardwareWalletViewModel!
450
+ .initWallet(sendViewModel.wallet);
451
}
472
- },
473
- );
474
- },
475
- text: _sendButtonText(context),
476
- color: Theme.of(context).colorScheme.primary,
477
- textColor: Theme.of(context).colorScheme.onPrimary,
478
- isLoading: sendViewModel.state is IsExecutingState ||
479
- sendViewModel.state is TransactionCommitting ||
480
- sendViewModel.state is IsAwaitingDeviceResponseState ||
481
- sendViewModel.state is LoadingTemplateExecutingState,
482
- isDisabled: !sendViewModel.isReadyForSend || sendViewModel.state is ExecutedSuccessfullyState,
483
- );
484
- },
485
- )
486
- ],
487
- )),
452
+ }
453
+
454
+ if (sendViewModel.wallet.type == WalletType.monero) {
455
+ var amount = Money.zero(sendViewModel.wallet.currency);
456
+ for (var item in sendViewModel.outputs) {
457
+ amount += item.cryptoAmountMoney;
458
+ }
459
+ if (monero!
460
+ .needExportOutputs(sendViewModel.wallet, amount)) {
461
+ await Navigator.of(context).pushNamed(
462
+ Routes.urqrAnimatedPage,
463
+ arguments:
464
+ monero!.exportOutputsUR(sendViewModel.wallet));
465
+ await Future.delayed(Duration(
466
+ seconds: 1)); // wait for monero to refresh the state
467
+ }
468
+ if (monero!
469
+ .needExportOutputs(sendViewModel.wallet, amount)) {
470
+ return;
471
+ }
472
+ }
473
+
474
+ final check = sendViewModel.shouldDisplayTotp();
475
+ authService.authenticateAction(
476
+ context,
477
+ conditionToDetermineIfToUse2FA: check,
478
+ onAuthSuccess: (value) async {
479
+ if (value) {
480
+ await sendViewModel.createTransaction();
481
+ }
482
+ },
483
+ );
484
+ },
485
+ text: _sendButtonText(context),
486
+ color: Theme.of(context).colorScheme.primary,
487
+ textColor: Theme.of(context).colorScheme.onPrimary,
488
+ isLoading: sendViewModel.state is IsExecutingState ||
489
+ sendViewModel.state is TransactionCommitting ||
490
+ sendViewModel.state is IsAwaitingDeviceResponseState ||
491
+ sendViewModel.state is LoadingTemplateExecutingState,
492
+ isDisabled: !sendViewModel.isReadyForSend ||
493
+ sendViewModel.state is ExecutedSuccessfullyState,
494
+ );
495
+ },
496
+ )
497
+ ],
498
+ )),
499
+ ),
500
),
501
),
490
- ),
491
- ],
492
- );
502
+ ],
503
+ );
504
+ });
505
});
494
- }
495
- );
506
}
507
508
BuildContext? dialogContext;
@@ -505,7 +515,7 @@ class SendPage extends BasePage {
515
bitcoin!.updateFeeRates(sendViewModel.wallet);
516
}
517
508
- controller.addListener((){
518
+ controller.addListener(() {
519
if (!controller.hasClients) return;
520
currentPage.value = controller.page!.round();
521
});
@@ -572,37 +582,36 @@ class SendPage extends BasePage {
582
isScrollControlled: true,
583
builder: (BuildContext bottomSheetContext) {
584
return Observer(
575
- builder: (_) => ConfirmSendingBottomSheet(
576
- key: ValueKey('send_page_confirm_sending_bottom_sheet_key'),
577
- titleText: S.of(bottomSheetContext).confirm_transaction,
578
- accessibleNavigationModeSlideActionButtonText: S.of(bottomSheetContext).send,
579
- footerType: FooterType.slideActionButton,
580
- isSlideActionEnabled: sendViewModel.isReadyForSend,
581
- walletType: sendViewModel.walletType,
582
- titleIconPath: sendViewModel.selectedCryptoCurrency.iconPath,
583
- currency: sendViewModel.selectedCryptoCurrency,
584
- amount: S.of(bottomSheetContext).send_amount,
585
- amountValue: sendViewModel.amountParsingProxy.getDisplayCryptoAmount(
586
- sendViewModel.pendingTransaction!.amountFormatted,
587
- sendViewModel.selectedCryptoCurrency),
588
- fiatAmountValue: sendViewModel.pendingTransactionFiatAmountFormatted,
589
- fee: isEVMCompatibleChain(sendViewModel.walletType)
590
- ? S.of(bottomSheetContext).send_estimated_fee
591
- : S.of(bottomSheetContext).send_fee,
592
- feeValue: "${sendViewModel.amountParsingProxy.getDisplayCryptoAmount(
593
- sendViewModel.pendingTransaction!.feeFormattedValue,
594
- sendViewModel.selectedCryptoCurrency)} ${sendViewModel.amountParsingProxy
595
- .getCryptoSymbol(sendViewModel.wallet.currency)}",
596
- feeFiatAmount: sendViewModel.pendingTransactionFeeFiatAmountFormatted,
597
- outputs: sendViewModel.outputs,
598
- onSlideActionComplete: () async {
599
- Navigator.of(bottomSheetContext).pop(true);
600
- sendViewModel.commitTransaction(context);
601
- },
602
- change: sendViewModel.pendingTransaction!.change,
603
- isOpenCryptoPay: sendViewModel.ocpRequest != null,
604
- amountParsingProxy: sendViewModel.amountParsingProxy,
605
- ),);
585
+ builder: (_) => ConfirmSendingBottomSheet(
586
+ key: ValueKey('send_page_confirm_sending_bottom_sheet_key'),
587
+ titleText: S.of(bottomSheetContext).confirm_transaction,
588
+ accessibleNavigationModeSlideActionButtonText: S.of(bottomSheetContext).send,
589
+ footerType: FooterType.slideActionButton,
590
+ isSlideActionEnabled: sendViewModel.isReadyForSend,
591
+ walletType: sendViewModel.walletType,
592
+ titleIconPath: sendViewModel.selectedCryptoCurrency.iconPath,
593
+ currency: sendViewModel.selectedCryptoCurrency,
594
+ amount: S.of(bottomSheetContext).send_amount,
595
+ amountValue: sendViewModel.amountParsingProxy.getDisplayCryptoAmount(
596
+ sendViewModel.pendingTransaction!.amountFormatted,
597
+ sendViewModel.selectedCryptoCurrency),
598
+ fiatAmountValue: sendViewModel.pendingTransactionFiatAmountFormatted,
599
+ fee: isEVMCompatibleChain(sendViewModel.walletType)
600
+ ? S.of(bottomSheetContext).send_estimated_fee
601
+ : S.of(bottomSheetContext).send_fee,
602
+ feeValue:
603
+ "${sendViewModel.amountParsingProxy.getDisplayCryptoAmount(sendViewModel.pendingTransaction!.feeFormattedValue, sendViewModel.selectedCryptoCurrency)} ${sendViewModel.amountParsingProxy.getCryptoSymbol(sendViewModel.wallet.currency)}",
604
+ feeFiatAmount: sendViewModel.pendingTransactionFeeFiatAmountFormatted,
605
+ outputs: sendViewModel.outputs,
606
+ onSlideActionComplete: () async {
607
+ Navigator.of(bottomSheetContext).pop(true);
608
+ sendViewModel.commitTransaction(context);
609
+ },
610
+ change: sendViewModel.pendingTransaction!.change,
611
+ isOpenCryptoPay: sendViewModel.ocpRequest != null,
612
+ amountParsingProxy: sendViewModel.amountParsingProxy,
613
+ ),
614
+ );
615
},
616
);
617
lib/src/screens/send/widgets/choose_yat_address_alert.dart
+5
-6
@@ -90,12 +90,11 @@ class ChooseYatAddressButtonsState extends State<ChooseYatAddressButtons> {
90
maxLines: 1,
91
overflow: TextOverflow.ellipsis,
92
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
93
- fontSize: 15,
94
- fontWeight: FontWeight.w600,
95
-
96
- color: Theme.of(context).colorScheme.onSurfaceVariant,
97
- decoration: TextDecoration.none,
98
- ),
93
+ fontSize: 15,
94
+ fontWeight: FontWeight.w600,
95
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
96
+ decoration: TextDecoration.none,
97
+ ),
98
),
99
)
100
],
lib/src/screens/send/widgets/send_card.dart
+9
-8
@@ -640,8 +640,7 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
640
onPushAddressBookButton: (context) async {
641
output.resetParsedAddress();
642
},
643
- onSelectedContact: (contact) {
644
- },
643
+ onSelectedContact: (contact) {},
644
validator: validator,
645
selectedCurrency: sendViewModel.selectedCryptoCurrency,
646
);
@@ -671,8 +670,10 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
670
sendAllButtonKey: ValueKey('send_page_send_all_button_key'),
671
currencyAmountTextFieldWidgetKey:
672
ValueKey('send_page_crypto_currency_amount_textfield_widget_key'),
674
- selectedCurrency: output.useSatoshi ? "SATS" : sendViewModel.selectedCryptoCurrency.title,
675
- selectedCurrencyDecimals: output.useSatoshi ? 0 : sendViewModel.selectedCryptoCurrency.decimals,
673
+ selectedCurrency:
674
+ output.useSatoshi ? "SATS" : sendViewModel.selectedCryptoCurrency.title,
675
+ selectedCurrencyDecimals:
676
+ output.useSatoshi ? 0 : sendViewModel.selectedCryptoCurrency.decimals,
677
amountFocusNode: widget.cryptoAmountFocus,
678
amountController: cryptoAmountController,
679
isAmountEditable: true,
@@ -976,8 +977,8 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
977
output.setSendAll(await sendViewModel.sendingBalance);
978
}
979
979
- output.setCryptoAmount(sendViewModel.amountParsingProxy
980
- .getCanonicalCryptoAmount(cryptoAmountController.text, sendViewModel.selectedCryptoCurrency));
980
+ output.setCryptoAmount(sendViewModel.amountParsingProxy.getCanonicalCryptoAmount(
981
+ cryptoAmountController.text, sendViewModel.selectedCryptoCurrency));
982
});
983
984
reaction((_) => output.fiatAmount, (String amount) {
@@ -991,8 +992,8 @@ class SendCardState extends State<SendCard> with AutomaticKeepAliveClientMixin<S
992
output.sendAll = false;
993
}
994
994
- final cryptoAmount = sendViewModel.amountParsingProxy
995
- .getCanonicalCryptoAmount(cryptoAmountController.text, sendViewModel.selectedCryptoCurrency);
995
+ final cryptoAmount = sendViewModel.amountParsingProxy.getCanonicalCryptoAmount(
996
+ cryptoAmountController.text, sendViewModel.selectedCryptoCurrency);
997
if (amount != cryptoAmount) {
998
cryptoAmountController.text = sendViewModel.amountParsingProxy
999
.getDisplayCryptoAmount(amount, sendViewModel.selectedCryptoCurrency);
lib/src/screens/settings/attributes.dart
+1
-1
@@ -1 +1 @@
1
-enum Attributes {arrow, header, link, switcher, widget, rawWidget}
\ No newline at end of file
1
+enum Attributes { arrow, header, link, switcher, widget, rawWidget }
lib/src/screens/settings/connection_sync_page.dart
+153
-158
@@ -43,89 +43,87 @@ class ConnectionSyncPage extends BasePage {
43
mainAxisSize: MainAxisSize.min,
44
children: [
45
Observer(
46
- builder: (context) =>
47
- NewListSections(
48
- sections: {
49
- "": [
50
- if (FeatureFlag.isInAppTorEnabled)
51
- ListItemToggle(
52
- keyValue: "enable_builtin_tor",
53
- label: S.of(context).enable_builtin_tor,
54
- value: _connectionSyncViewModel.builtinTor,
55
- onChanged: (val) {
56
- _connectionSyncViewModel.setBuiltinTor(val, context);
57
- }),
58
- ListItemToggle(
59
- keyValue: "disable_automatic_exchange_status_updates",
60
- label: S.of(context).disable_automatic_exchange_status_updates,
61
- value: _connectionSyncViewModel.disableAutomaticExchangeStatusUpdates,
62
- onChanged: (val) {
63
- _connectionSyncViewModel.setDisableAutomaticExchangeStatusUpdates(val);
64
- }),
65
- if (_connectionSyncViewModel.canUseBlinkProtection)
66
- ListItemToggle(
67
- keyValue: "can_use_blink_protection",
68
- label: S.of(context).use_blink_protection,
69
- value: _connectionSyncViewModel.useBlinkProtection,
70
- onChanged: (val) {
71
- _connectionSyncViewModel.setUseBlinkProtection(val);
72
- }),
73
- if (_connectionSyncViewModel.canUseEtherscan)
74
- ListItemToggle(
75
- keyValue: "can_use_etherscan",
76
- label: S.of(context).etherscan_history,
77
- value: _connectionSyncViewModel.useEtherscan,
78
- onChanged: (val) {
79
- _connectionSyncViewModel.setUseEtherscan(val);
80
- }),
81
- if (_connectionSyncViewModel.canUsePolygonScan)
82
- ListItemToggle(
83
- keyValue: "can_use_polygonscan",
84
- label: S.of(context).polygonscan_history,
85
- value: _connectionSyncViewModel.usePolygonScan,
86
- onChanged: (val) {
87
- _connectionSyncViewModel.setUsePolygonScan(val);
88
- }),
89
- if (_connectionSyncViewModel.canUseBaseScan)
90
- ListItemToggle(
91
- keyValue: "can_use_basescan",
92
- label: S.of(context).basescan_history,
93
- value: _connectionSyncViewModel.canUseBaseScan,
94
- onChanged: (val) {
95
- _connectionSyncViewModel.setUseBaseScan(val);
96
- }),
97
- if (_connectionSyncViewModel.canUseArbiScan)
98
- ListItemToggle(
99
- keyValue: "can_use_arbiscan",
100
- label: S.of(context).arbiscan_history,
101
- value: _connectionSyncViewModel.useArbiScan,
102
- onChanged: (val) {
103
- _connectionSyncViewModel.setUseArbiScan(val);
104
- }),
105
- if (_connectionSyncViewModel.canUseBscScan)
106
- ListItemToggle(
107
- keyValue: "can_use_bscscan",
108
- label: S.of(context).bscscan_history,
109
- value: _connectionSyncViewModel.useBscScan,
110
- onChanged: (val) {
111
- _connectionSyncViewModel.setUseBscScan(val);
112
- }),
113
- if (_connectionSyncViewModel.canUseTronGrid)
114
- ListItemToggle(
115
- keyValue: "can_use_trongrid",
116
- label: S.of(context).trongrid_history,
117
- value: _connectionSyncViewModel.useTronGrid,
118
- onChanged: (val) {
119
- _connectionSyncViewModel.setUseTronGrid(val);
120
- }),
121
- if (_connectionSyncViewModel.canUseMempoolFeeAPI)
122
- ListItemToggle(
123
- keyValue: "enable_mempool_api",
124
- label: S.of(context).enable_mempool_api,
125
- value: _connectionSyncViewModel.useMempoolFeeAPI,
126
- onChanged: (bool isEnabled) async {
127
- if (!isEnabled) {
128
- final bool confirmation = await showPopUp<bool>(
46
+ builder: (context) => NewListSections(sections: {
47
+ "": [
48
+ if (FeatureFlag.isInAppTorEnabled)
49
+ ListItemToggle(
50
+ keyValue: "enable_builtin_tor",
51
+ label: S.of(context).enable_builtin_tor,
52
+ value: _connectionSyncViewModel.builtinTor,
53
+ onChanged: (val) {
54
+ _connectionSyncViewModel.setBuiltinTor(val, context);
55
+ }),
56
+ ListItemToggle(
57
+ keyValue: "disable_automatic_exchange_status_updates",
58
+ label: S.of(context).disable_automatic_exchange_status_updates,
59
+ value: _connectionSyncViewModel.disableAutomaticExchangeStatusUpdates,
60
+ onChanged: (val) {
61
+ _connectionSyncViewModel.setDisableAutomaticExchangeStatusUpdates(val);
62
+ }),
63
+ if (_connectionSyncViewModel.canUseBlinkProtection)
64
+ ListItemToggle(
65
+ keyValue: "can_use_blink_protection",
66
+ label: S.of(context).use_blink_protection,
67
+ value: _connectionSyncViewModel.useBlinkProtection,
68
+ onChanged: (val) {
69
+ _connectionSyncViewModel.setUseBlinkProtection(val);
70
+ }),
71
+ if (_connectionSyncViewModel.canUseEtherscan)
72
+ ListItemToggle(
73
+ keyValue: "can_use_etherscan",
74
+ label: S.of(context).etherscan_history,
75
+ value: _connectionSyncViewModel.useEtherscan,
76
+ onChanged: (val) {
77
+ _connectionSyncViewModel.setUseEtherscan(val);
78
+ }),
79
+ if (_connectionSyncViewModel.canUsePolygonScan)
80
+ ListItemToggle(
81
+ keyValue: "can_use_polygonscan",
82
+ label: S.of(context).polygonscan_history,
83
+ value: _connectionSyncViewModel.usePolygonScan,
84
+ onChanged: (val) {
85
+ _connectionSyncViewModel.setUsePolygonScan(val);
86
+ }),
87
+ if (_connectionSyncViewModel.canUseBaseScan)
88
+ ListItemToggle(
89
+ keyValue: "can_use_basescan",
90
+ label: S.of(context).basescan_history,
91
+ value: _connectionSyncViewModel.canUseBaseScan,
92
+ onChanged: (val) {
93
+ _connectionSyncViewModel.setUseBaseScan(val);
94
+ }),
95
+ if (_connectionSyncViewModel.canUseArbiScan)
96
+ ListItemToggle(
97
+ keyValue: "can_use_arbiscan",
98
+ label: S.of(context).arbiscan_history,
99
+ value: _connectionSyncViewModel.useArbiScan,
100
+ onChanged: (val) {
101
+ _connectionSyncViewModel.setUseArbiScan(val);
102
+ }),
103
+ if (_connectionSyncViewModel.canUseBscScan)
104
+ ListItemToggle(
105
+ keyValue: "can_use_bscscan",
106
+ label: S.of(context).bscscan_history,
107
+ value: _connectionSyncViewModel.useBscScan,
108
+ onChanged: (val) {
109
+ _connectionSyncViewModel.setUseBscScan(val);
110
+ }),
111
+ if (_connectionSyncViewModel.canUseTronGrid)
112
+ ListItemToggle(
113
+ keyValue: "can_use_trongrid",
114
+ label: S.of(context).trongrid_history,
115
+ value: _connectionSyncViewModel.useTronGrid,
116
+ onChanged: (val) {
117
+ _connectionSyncViewModel.setUseTronGrid(val);
118
+ }),
119
+ if (_connectionSyncViewModel.canUseMempoolFeeAPI)
120
+ ListItemToggle(
121
+ keyValue: "enable_mempool_api",
122
+ label: S.of(context).enable_mempool_api,
123
+ value: _connectionSyncViewModel.useMempoolFeeAPI,
124
+ onChanged: (bool isEnabled) async {
125
+ if (!isEnabled) {
126
+ final bool confirmation = await showPopUp<bool>(
127
context: context,
128
builder: (BuildContext context) {
129
return AlertWithTwoActions(
@@ -133,91 +131,88 @@ class ConnectionSyncPage extends BasePage {
131
alertContent: S.of(context).disable_fee_api_warning,
132
rightButtonText: S.of(context).confirm,
133
leftButtonText: S.of(context).cancel,
136
- actionRightButton: () => Navigator.of(context).pop(true),
137
- actionLeftButton: () => Navigator.of(context).pop(false));
134
+ actionRightButton: () =>
135
+ Navigator.of(context).pop(true),
136
+ actionLeftButton: () =>
137
+ Navigator.of(context).pop(false));
138
}) ??
139
- false;
140
- if (confirmation) {
141
- _connectionSyncViewModel.setUseMempoolFeeAPI(isEnabled);
142
- }
143
- return;
144
- }
145
-
139
+ false;
140
+ if (confirmation) {
141
_connectionSyncViewModel.setUseMempoolFeeAPI(isEnabled);
147
- }),
148
- if (Platform.isAndroid && FeatureFlag.isBackgroundSyncEnabled)
149
- ListItemRegularRow(
150
- keyValue: "background_sync",
151
- label: S.of(context).background_sync,
152
- onTap: () => Navigator.of(context).pushNamed(Routes.backgroundSync)
153
- ),
154
- if (_connectionSyncViewModel.hasPowNodes)
155
- ListItemRegularRow(
156
- keyValue: "manage_pow_nodes",
157
- label: S.of(context).manage_pow_nodes,
158
- onTap: () => Navigator.of(context).pushNamed(Routes.managePowNodes),
159
- ),
160
- ListItemSelector(
161
- keyValue: "fiat_api",
162
- label: S.of(context).fiat_api,
163
- options: [_connectionSyncViewModel.fiatApiMode.title],
164
- onTap: () async {
165
- final items = FiatApiMode.all;
142
+ }
143
+ return;
144
+ }
145
+
146
+ _connectionSyncViewModel.setUseMempoolFeeAPI(isEnabled);
147
+ }),
148
+ if (Platform.isAndroid && FeatureFlag.isBackgroundSyncEnabled)
149
+ ListItemRegularRow(
150
+ keyValue: "background_sync",
151
+ label: S.of(context).background_sync,
152
+ onTap: () => Navigator.of(context).pushNamed(Routes.backgroundSync)),
153
+ if (_connectionSyncViewModel.hasPowNodes)
154
+ ListItemRegularRow(
155
+ keyValue: "manage_pow_nodes",
156
+ label: S.of(context).manage_pow_nodes,
157
+ onTap: () => Navigator.of(context).pushNamed(Routes.managePowNodes),
158
+ ),
159
+ ListItemSelector(
160
+ keyValue: "fiat_api",
161
+ label: S.of(context).fiat_api,
162
+ options: [_connectionSyncViewModel.fiatApiMode.title],
163
+ onTap: () async {
164
+ final items = FiatApiMode.all;
165
167
- final selectedAtIndex =
166
+ final selectedAtIndex =
167
items.indexOf(_connectionSyncViewModel.fiatApiMode);
168
170
- await showPopUp<void>(
171
- context: context,
172
- builder: (_) => Picker(
173
- items: items,
174
- selectedAtIndex: selectedAtIndex,
175
- mainAxisAlignment: MainAxisAlignment.start,
176
- onItemSelected: (FiatApiMode fiatApiMode) {
177
- _connectionSyncViewModel.setFiatMode(fiatApiMode);
178
- },
179
- isSeparated: false,
180
- ),
181
- );
182
- }),
183
- ListItemSelector(
184
- keyValue: "swap",
185
- label: S.of(context).swap,
186
- options: [_connectionSyncViewModel.exchangeStatus.title],
187
- onTap: () async {
188
- final items = ExchangeApiMode.all;
169
+ await showPopUp<void>(
170
+ context: context,
171
+ builder: (_) => Picker(
172
+ items: items,
173
+ selectedAtIndex: selectedAtIndex,
174
+ mainAxisAlignment: MainAxisAlignment.start,
175
+ onItemSelected: (FiatApiMode fiatApiMode) {
176
+ _connectionSyncViewModel.setFiatMode(fiatApiMode);
177
+ },
178
+ isSeparated: false,
179
+ ),
180
+ );
181
+ }),
182
+ ListItemSelector(
183
+ keyValue: "swap",
184
+ label: S.of(context).swap,
185
+ options: [_connectionSyncViewModel.exchangeStatus.title],
186
+ onTap: () async {
187
+ final items = ExchangeApiMode.all;
188
190
- final selectedAtIndex =
189
+ final selectedAtIndex =
190
items.indexOf(_connectionSyncViewModel.exchangeStatus);
191
193
- await showPopUp<void>(
194
- context: context,
195
- builder: (_) => Picker(
196
- items: items,
197
- selectedAtIndex: selectedAtIndex,
198
- mainAxisAlignment: MainAxisAlignment.start,
199
- onItemSelected: (ExchangeApiMode mode) {
200
- _connectionSyncViewModel.setExchangeApiMode(mode);
201
- },
202
- isSeparated: false,
203
- ),
204
- );
205
- }),
206
- ListItemRegularRow(
207
- keyValue: "domain_lookups",
208
- label: S.of(context).domain_looks_up,
209
- onTap: () => Navigator.of(context).pushNamed(Routes.domainLookupsPage)
210
- ),
211
- if(_connectionSyncViewModel.hasRescan)
212
- ListItemRegularRow(
192
+ await showPopUp<void>(
193
+ context: context,
194
+ builder: (_) => Picker(
195
+ items: items,
196
+ selectedAtIndex: selectedAtIndex,
197
+ mainAxisAlignment: MainAxisAlignment.start,
198
+ onItemSelected: (ExchangeApiMode mode) {
199
+ _connectionSyncViewModel.setExchangeApiMode(mode);
200
+ },
201
+ isSeparated: false,
202
+ ),
203
+ );
204
+ }),
205
+ ListItemRegularRow(
206
+ keyValue: "domain_lookups",
207
+ label: S.of(context).domain_looks_up,
208
+ onTap: () => Navigator.of(context).pushNamed(Routes.domainLookupsPage)),
209
+ if (_connectionSyncViewModel.hasRescan)
210
+ ListItemRegularRow(
211
keyValue: "rescan",
212
label: S.of(context).rescan,
215
- onTap: ()=>Navigator.of(context).pushNamed(Routes.rescan)
216
- )
217
- ],
218
- }
219
- )
220
- ),
213
+ onTap: () => Navigator.of(context).pushNamed(Routes.rescan))
214
+ ],
215
+ })),
216
],
217
),
218
);
lib/src/screens/settings/desktop_settings/desktop_settings_page.dart
+5
-7
@@ -61,9 +61,9 @@ class _DesktopSettingsPageState extends State<DesktopSettingsPage> {
61
}
62
63
if ((!widget.dashboardViewModel.isMoneroViewOnly &&
64
- item.name(context) == S.of(context).export_outputs) ||
65
- (!widget.dashboardViewModel.hasMweb &&
66
- item.name(context) == S.of(context).litecoin_mweb_settings)) {
64
+ item.name(context) == S.of(context).export_outputs) ||
65
+ (!widget.dashboardViewModel.hasMweb &&
66
+ item.name(context) == S.of(context).litecoin_mweb_settings)) {
67
return Container();
68
}
69
@@ -103,11 +103,9 @@ class _DesktopSettingsPageState extends State<DesktopSettingsPage> {
103
key: _settingsNavigatorKey,
104
initialRoute: Routes.empty_no_route,
105
onGenerateRoute: (settings) => Router.createRoute(settings),
106
- onGenerateInitialRoutes:
107
- (NavigatorState navigator, String initialRouteName) {
106
+ onGenerateInitialRoutes: (NavigatorState navigator, String initialRouteName) {
107
return [
109
- navigator
110
- .widget.onGenerateRoute!(RouteSettings(name: initialRouteName))!
108
+ navigator.widget.onGenerateRoute!(RouteSettings(name: initialRouteName))!
109
];
110
},
111
),
lib/src/screens/settings/display_settings_page.dart
+174
-176
@@ -27,7 +27,6 @@ import 'package:image_picker/image_picker.dart';
27
class DisplaySettingsPage extends StatelessWidget {
28
DisplaySettingsPage(this._displaySettingsViewModel);
29
30
-
30
final DisplaySettingsViewModel _displaySettingsViewModel;
31
32
@override
@@ -38,198 +37,197 @@ class DisplaySettingsPage extends StatelessWidget {
37
leadingIcon: Icon(Icons.arrow_back_ios_new),
38
onLeadingPressed: () => Navigator.of(context).pop(),
39
),
41
- content: Column(
42
- spacing: 16,
43
- crossAxisAlignment: CrossAxisAlignment.start,
44
- children: [
45
- if (responsiveLayoutUtil.shouldRenderMobileUI &&
46
- DeviceInfo.instance.isMobile) ...[
47
- Padding(
48
- padding: const EdgeInsets.only(left: 14, top: 14),
49
- child: Text(
50
- S.of(context).appearance,
51
- style: Theme.of(context).textTheme.labelLarge?.copyWith(
40
+ content: Column(
41
+ spacing: 16,
42
+ crossAxisAlignment: CrossAxisAlignment.start,
43
+ children: [
44
+ if (responsiveLayoutUtil.shouldRenderMobileUI && DeviceInfo.instance.isMobile) ...[
45
+ Padding(
46
+ padding: const EdgeInsets.only(left: 14, top: 14),
47
+ child: Text(
48
+ S.of(context).appearance,
49
+ style: Theme.of(context).textTheme.labelLarge?.copyWith(
50
height: 0.2,
51
color: Theme.of(context).colorScheme.onSurfaceVariant,
52
),
53
+ ),
54
+ ),
55
+ Container(
56
+ decoration: ShapeDecoration(
57
+ color: Theme.of(context).colorScheme.surfaceContainerHigh,
58
+ shape: RoundedSuperellipseBorder(borderRadius: BorderRadius.circular(18))),
59
+ child: Column(
60
+ children: [
61
+ SettingsChoicesCell(
62
+ ChoicesListItem<ThemeMode>(
63
+ title: "",
64
+ items: ThemeMode.values,
65
+ selectedItem: _displaySettingsViewModel.themeMode,
66
+ onItemSelected: (ThemeMode themeMode) =>
67
+ _displaySettingsViewModel.setThemeMode(themeMode),
68
+ displayItem: (ThemeMode themeMode) {
69
+ return themeMode.name[0].toUpperCase() +
70
+ themeMode.name.substring(1).toLowerCase();
71
+ },
72
+ ),
73
+ useGenericColor: false,
74
+ padding: EdgeInsets.all(14),
75
),
56
- ),
57
- Container(
58
- decoration: ShapeDecoration(
59
- color: Theme.of(context).colorScheme.surfaceContainerHigh,
60
- shape: RoundedSuperellipseBorder(
61
- borderRadius: BorderRadius.circular(18))),
62
- child: Column(
63
- children: [
64
- SettingsChoicesCell(
65
- ChoicesListItem<ThemeMode>(
66
- title: "",
67
- items: ThemeMode.values,
68
- selectedItem: _displaySettingsViewModel.themeMode,
69
- onItemSelected: (ThemeMode themeMode) =>
70
- _displaySettingsViewModel.setThemeMode(themeMode),
71
- displayItem: (ThemeMode themeMode) {
72
- return themeMode.name[0].toUpperCase() +
73
- themeMode.name.substring(1).toLowerCase();
74
- },
76
+ Container(
77
+ decoration: ShapeDecoration(
78
+ color: Theme.of(context).colorScheme.surfaceContainer,
79
+ shape: RoundedSuperellipseBorder(borderRadius: BorderRadius.circular(18))),
80
+ child: Column(
81
+ children: [
82
+ Semantics(
83
+ label: S.of(context).color_theme,
84
+ child: SettingsThemeChoicesCell(_displaySettingsViewModel),
85
),
76
- useGenericColor: false,
77
- padding: EdgeInsets.all(14),
78
- ),
79
- Container(
80
- decoration: ShapeDecoration(
81
- color: Theme.of(context).colorScheme.surfaceContainer,
82
- shape: RoundedSuperellipseBorder(
83
- borderRadius: BorderRadius.circular(18))),
84
- child: Column(
85
- children: [
86
- Semantics(
87
- label: S.of(context).color_theme,
88
- child: SettingsThemeChoicesCell(_displaySettingsViewModel),
89
- ),
90
- ],
91
- ),
92
- ),
93
- ],
86
+ ],
87
+ ),
88
),
95
- ),
96
- ],
97
- Observer(
98
- builder: (_) => NewListSections(
99
- sections: {
100
- "": [
101
- ListItemToggle(
102
- keyValue: "apps",
103
- label: S.of(context).apps,
104
- value: _displaySettingsViewModel.shouldShowMarketPlaceInDashboard,
105
- onChanged: (val) {
106
- _displaySettingsViewModel.setShouldShowMarketPlaceInDashbaord(val);
107
- }),
108
- ListItemToggle(
109
- keyValue: "display_settings_show_address_book_popup",
110
- label: S.of(context).show_address_book_popup,
111
- value: _displaySettingsViewModel.showAddressBookPopup,
112
- onChanged: (val) {
113
- _displaySettingsViewModel.setShowAddressBookPopup(val);
114
- }),
115
- ListItemToggle(
116
- keyValue: "display_settings_disable_buy_button",
117
- label: S.of(context).disable_buy,
118
- value: _displaySettingsViewModel.disableTradeOption,
119
- onChanged: (val) {
120
- _displaySettingsViewModel.setDisableTradeOption(val);
121
- }),
122
- if (_displaySettingsViewModel.showZcashCardSetting)
123
- ListItemToggle(
124
- keyValue: "display_settings_show_zcashcard",
125
- label: S.of(context).show_zcash_card,
126
- value: _displaySettingsViewModel.showZcashCard,
127
- onChanged: (val) {
128
- _displaySettingsViewModel.setShowZcashCard(val);
129
- }),
130
- ListItemSelector(
131
- keyValue: "display_settings_sync_status_display",
132
- label: S.of(context).sync_status_display_mode,
133
- options: [_displaySettingsViewModel.syncStatusDisplayMode.title],
134
- onTap: () async {
135
- final items = SyncStatusDisplayMode.values.toList();
89
+ ],
90
+ ),
91
+ ),
92
+ ],
93
+ Observer(
94
+ builder: (_) => NewListSections(
95
+ sections: {
96
+ "": [
97
+ ListItemToggle(
98
+ keyValue: "apps",
99
+ label: S.of(context).apps,
100
+ value: _displaySettingsViewModel.shouldShowMarketPlaceInDashboard,
101
+ onChanged: (val) {
102
+ _displaySettingsViewModel.setShouldShowMarketPlaceInDashbaord(val);
103
+ }),
104
+ ListItemToggle(
105
+ keyValue: "display_settings_show_address_book_popup",
106
+ label: S.of(context).show_address_book_popup,
107
+ value: _displaySettingsViewModel.showAddressBookPopup,
108
+ onChanged: (val) {
109
+ _displaySettingsViewModel.setShowAddressBookPopup(val);
110
+ }),
111
+ ListItemToggle(
112
+ keyValue: "display_settings_disable_buy_button",
113
+ label: S.of(context).disable_buy,
114
+ value: _displaySettingsViewModel.disableTradeOption,
115
+ onChanged: (val) {
116
+ _displaySettingsViewModel.setDisableTradeOption(val);
117
+ }),
118
+ if (_displaySettingsViewModel.showZcashCardSetting)
119
+ ListItemToggle(
120
+ keyValue: "display_settings_show_zcashcard",
121
+ label: S.of(context).show_zcash_card,
122
+ value: _displaySettingsViewModel.showZcashCard,
123
+ onChanged: (val) {
124
+ _displaySettingsViewModel.setShowZcashCard(val);
125
+ }),
126
+ ListItemSelector(
127
+ keyValue: "display_settings_sync_status_display",
128
+ label: S.of(context).sync_status_display_mode,
129
+ options: [_displaySettingsViewModel.syncStatusDisplayMode.title],
130
+ onTap: () async {
131
+ final items = SyncStatusDisplayMode.values.toList();
132
137
- final selectedAtIndex =
133
+ final selectedAtIndex =
134
items.indexOf(_displaySettingsViewModel.syncStatusDisplayMode);
135
140
- await showPopUp<void>(
141
- context: context,
142
- builder: (_) => Picker(
143
- items: items,
144
- selectedAtIndex: selectedAtIndex,
145
- mainAxisAlignment: MainAxisAlignment.start,
146
- onItemSelected: (SyncStatusDisplayMode mode) {
147
- _displaySettingsViewModel.setSyncStatusDisplayMode(mode);
148
- },
149
- displayItem: (SyncStatusDisplayMode mode) => mode.title,
150
- isSeparated: false,
151
- ),
152
- );
153
- }),
154
- if (_displaySettingsViewModel.showDisplayAmountsInSatoshiSetting)
155
- ListItemRegularRow(
156
- keyValue: "display_settings_bitcoin_amount_display",
157
- label: S.of(context).bitcoin_amount_display,
158
- trailingText: _displaySettingsViewModel.displayAmountsInSatoshi.title,
159
- onTap: () async {
160
- final items = BitcoinAmountDisplayMode.all;
136
+ await showPopUp<void>(
137
+ context: context,
138
+ builder: (_) => Picker(
139
+ items: items,
140
+ selectedAtIndex: selectedAtIndex,
141
+ mainAxisAlignment: MainAxisAlignment.start,
142
+ onItemSelected: (SyncStatusDisplayMode mode) {
143
+ _displaySettingsViewModel.setSyncStatusDisplayMode(mode);
144
+ },
145
+ displayItem: (SyncStatusDisplayMode mode) => mode.title,
146
+ isSeparated: false,
147
+ ),
148
+ );
149
+ }),
150
+ if (_displaySettingsViewModel.showDisplayAmountsInSatoshiSetting)
151
+ ListItemRegularRow(
152
+ keyValue: "display_settings_bitcoin_amount_display",
153
+ label: S.of(context).bitcoin_amount_display,
154
+ trailingText: _displaySettingsViewModel.displayAmountsInSatoshi.title,
155
+ onTap: () async {
156
+ final items = BitcoinAmountDisplayMode.all;
157
162
- final selectedAtIndex =
158
+ final selectedAtIndex =
159
items.indexOf(_displaySettingsViewModel.displayAmountsInSatoshi);
160
165
- await showPopUp<void>(
166
- context: context,
167
- builder: (_) => Picker(
168
- items: items,
169
- selectedAtIndex: selectedAtIndex,
170
- mainAxisAlignment: MainAxisAlignment.start,
171
- onItemSelected: _displaySettingsViewModel.setDisplayAmountsInSatoshi,
172
- displayItem: (BitcoinAmountDisplayMode mode) => mode.title,
173
- isSeparated: false,
174
- ),
175
- );
176
- }),
177
- if (!_displaySettingsViewModel.disabledFiatApiMode)
178
- ListItemSelector(
179
- keyValue: "display_settings_fiat_currency",
180
- label: S.of(context).settings_currency,
181
- options: [_displaySettingsViewModel.fiatCurrency.title],
182
- onTap: () => FiatCurrencyPickerSheet.show(
183
- context: context,
184
- selected: _displaySettingsViewModel.fiatCurrency,
185
- onSelected: _displaySettingsViewModel.setFiatCurrency,
186
- )),
187
- ListItemSelector(
188
- keyValue: "display_settings_language",
189
- label: S.of(context).settings_change_language,
190
- options: [LanguageService.list[_displaySettingsViewModel.languageCode] ?? ''],
191
- onTap: () async {
192
- final items = LanguageService.list.keys.toList();
161
+ await showPopUp<void>(
162
+ context: context,
163
+ builder: (_) => Picker(
164
+ items: items,
165
+ selectedAtIndex: selectedAtIndex,
166
+ mainAxisAlignment: MainAxisAlignment.start,
167
+ onItemSelected: _displaySettingsViewModel.setDisplayAmountsInSatoshi,
168
+ displayItem: (BitcoinAmountDisplayMode mode) => mode.title,
169
+ isSeparated: false,
170
+ ),
171
+ );
172
+ }),
173
+ if (!_displaySettingsViewModel.disabledFiatApiMode)
174
+ ListItemSelector(
175
+ keyValue: "display_settings_fiat_currency",
176
+ label: S.of(context).settings_currency,
177
+ options: [_displaySettingsViewModel.fiatCurrency.title],
178
+ onTap: () => FiatCurrencyPickerSheet.show(
179
+ context: context,
180
+ selected: _displaySettingsViewModel.fiatCurrency,
181
+ onSelected: _displaySettingsViewModel.setFiatCurrency,
182
+ )),
183
+ ListItemSelector(
184
+ keyValue: "display_settings_language",
185
+ label: S.of(context).settings_change_language,
186
+ options: [LanguageService.list[_displaySettingsViewModel.languageCode] ?? ''],
187
+ onTap: () async {
188
+ final items = LanguageService.list.keys.toList();
189
194
- final selectedAtIndex =
190
+ final selectedAtIndex =
191
items.indexOf(_displaySettingsViewModel.languageCode);
192
197
- await showPopUp<void>(
198
- context: context,
199
- builder: (_) => Picker(
200
- displayItem: (dynamic code) {
201
- return LanguageService.list[code] ?? '';
202
- },
203
- items: items,
204
- selectedAtIndex: selectedAtIndex,
205
- mainAxisAlignment: MainAxisAlignment.start,
206
- onItemSelected: _displaySettingsViewModel.onLanguageSelected,
207
- images: LanguageService.list.keys
208
- .map((e) => Image.asset(
193
+ await showPopUp<void>(
194
+ context: context,
195
+ builder: (_) => Picker(
196
+ displayItem: (dynamic code) {
197
+ return LanguageService.list[code] ?? '';
198
+ },
199
+ items: items,
200
+ selectedAtIndex: selectedAtIndex,
201
+ mainAxisAlignment: MainAxisAlignment.start,
202
+ onItemSelected: _displaySettingsViewModel.onLanguageSelected,
203
+ images: LanguageService.list.keys
204
+ .map((e) => Image.asset(
205
"assets/images/flags/${LanguageService.localeCountryCode[e]}.png"))
210
- .toList(),
211
- hintText: S.of(context).search_language,
212
- matchingCriteria: (String code, String searchText) {
213
- return LanguageService.list[code]?.toLowerCase().contains(searchText) ?? false;
214
- },
215
- isSeparated: true,
216
-
217
- ),
218
- );
219
- }),
220
- ],
221
- },
222
- ),
223
- ),
224
- if (FeatureFlag.customBackgroundEnabled)
225
- StandardListRow(
226
- title: "Custom background",
227
- isSelected: false,
228
- onTap: (_) => _pickImage(context),
229
- ),
230
- ],
206
+ .toList(),
207
+ hintText: S.of(context).search_language,
208
+ matchingCriteria: (String code, String searchText) {
209
+ return LanguageService.list[code]
210
+ ?.toLowerCase()
211
+ .contains(searchText) ??
212
+ false;
213
+ },
214
+ isSeparated: true,
215
+ ),
216
+ );
217
+ }),
218
+ ],
219
+ },
220
+ ),
221
),
232
- );
222
+ if (FeatureFlag.customBackgroundEnabled)
223
+ StandardListRow(
224
+ title: "Custom background",
225
+ isSelected: false,
226
+ onTap: (_) => _pickImage(context),
227
+ ),
228
+ ],
229
+ ),
230
+ );
231
}
232
233
// Function to pick an image from the gallery
lib/src/screens/settings/domain_lookups_page.dart
+7
-5
@@ -25,11 +25,13 @@ class DomainLookupsPage extends BasePage {
25
.map(
26
(source) => SettingsSwitcherCell(
27
title: source.label,
28
- leading: source.iconPath.isNotEmpty ? CakeImageWidget(
29
- imageUrl: source.iconPath,
30
- width: 24,
31
- height: 24,
32
- ) : SizedBox(width: 24, height: 24),
28
+ leading: source.iconPath.isNotEmpty
29
+ ? CakeImageWidget(
30
+ imageUrl: source.iconPath,
31
+ width: 24,
32
+ height: 24,
33
+ )
34
+ : SizedBox(width: 24, height: 24),
35
value: _connectionsSyncViewModel.lookupValue(source),
36
onValueChange: (_, bool value) =>
37
_connectionsSyncViewModel.setLookupValue(source, value),
lib/src/screens/settings/items/item_headers.dart
+1
-1
@@ -15,4 +15,4 @@ class ItemHeaders {
15
static const termsAndConditions = 'Terms and conditions';
16
static const faq = 'FAQ';
17
static const version = 'Version';
18
-}
\ No newline at end of file
18
+}
lib/src/screens/settings/manage_nodes_page.dart
+10
-11
@@ -55,10 +55,10 @@ class _ManageNodesPageState extends State<ManageNodesPage> {
55
ModernButton(
56
size: 36,
57
icon: Icon(Icons.add),
58
- onPressed: ()async {
58
+ onPressed: () async {
59
final res = await Navigator.of(context)
60
- .pushNamed(widget.isPow ? Routes.newPowNode : Routes.newNode);
61
- if(res != null && res is Node) {
60
+ .pushNamed(widget.isPow ? Routes.newPowNode : Routes.newNode);
61
+ if (res != null && res is Node) {
62
widget.nodeListViewModel.nodes.add(res);
63
}
64
})
@@ -75,12 +75,11 @@ class _ManageNodesPageState extends State<ManageNodesPage> {
75
// horizontal: 0,
76
node: widget.nodeListViewModel.currentNode,
77
speed: widget.nodeListViewModel.nodeSpeedFor(widget.nodeListViewModel.currentNode),
78
- onEditComplete: (res)async{
79
- if(res != null && res is Node) {
80
- widget.nodeListViewModel.nodes.removeWhere((item)=>item.id == res.id);
78
+ onEditComplete: (res) async {
79
+ if (res != null && res is Node) {
80
+ widget.nodeListViewModel.nodes.removeWhere((item) => item.id == res.id);
81
widget.nodeListViewModel.nodes.add(res);
82
}
83
-
83
},
84
onTap: () {},
85
isSelected: true,
@@ -93,7 +92,7 @@ class _ManageNodesPageState extends State<ManageNodesPage> {
92
color: Theme.of(context).colorScheme.surfaceContainer,
93
borderRadius: BorderRadius.circular(18)),
94
child: ClipRRect(
96
- borderRadius: BorderRadius.circular(18),
95
+ borderRadius: BorderRadius.circular(18),
96
child: Observer(
97
builder: (BuildContext context) {
98
int itemsCount = widget.nodeListViewModel.nonCurrentNodes.length;
@@ -119,11 +118,11 @@ class _ManageNodesPageState extends State<ManageNodesPage> {
118
isPow: widget.isPow,
119
speed: widget.nodeListViewModel.nodeSpeedFor(node),
120
onEditComplete: (res) async {
122
- if(res != null && res is Node) {
123
- widget.nodeListViewModel.nodes.removeWhere((item)=>item.id == res.id);
121
+ if (res != null && res is Node) {
122
+ widget.nodeListViewModel.nodes
123
+ .removeWhere((item) => item.id == res.id);
124
widget.nodeListViewModel.nodes.add(res);
125
}
126
-
126
},
127
onTap: () async {
128
await showPopUp<void>(
lib/src/screens/settings/mweb_logs_page.dart
+6
-6
@@ -38,7 +38,8 @@ class MwebLogsPage extends BasePage {
38
padding: EdgeInsets.all(16.0),
39
child: Text(
40
snapshot.data!,
41
- style: Theme.of(context).textTheme.bodyMedium!.copyWith(fontFamily: 'Monospace'),
41
+ style:
42
+ Theme.of(context).textTheme.bodyMedium!.copyWith(fontFamily: 'Monospace'),
43
),
44
),
45
);
@@ -103,11 +104,10 @@ class MwebLogsPage extends BasePage {
104
}
105
106
Future<void> _saveFile() async {
106
- String? outputFile = await FilePicker.platform
107
- .saveFile(
108
- dialogTitle: 'Save Your File to desired location',
109
- fileName: "debug.log",
110
- lockParentWindow: true);
107
+ String? outputFile = await FilePicker.platform.saveFile(
108
+ dialogTitle: 'Save Your File to desired location',
109
+ fileName: "debug.log",
110
+ lockParentWindow: true);
111
112
if (outputFile == null) return;
113
lib/src/screens/settings/mweb_node_page.dart
+20
-21
@@ -7,6 +7,7 @@ import 'package:cake_wallet/src/widgets/primary_button.dart';
7
import 'package:cake_wallet/generated/i18n.dart';
8
import 'package:cake_wallet/view_model/settings/mweb_settings_view_model.dart';
9
import 'package:flutter/material.dart';
10
+
11
class MwebNodePage extends StatefulWidget {
12
const MwebNodePage(this.mwebSettingsViewModelBase, {super.key});
13
@@ -30,30 +31,28 @@ class _MwebNodePageState extends State<MwebNodePage> {
31
Widget build(BuildContext context) {
32
return SafeArea(
33
child: ModalPageWrapper(
33
- topBar: ModalTopBar(
34
+ topBar: ModalTopBar(
35
title: S.current.litecoin_mweb_settings,
36
onLeadingPressed: Navigator.of(context).pop,
37
leadingIcon: Icon(Icons.arrow_back_ios_new)),
37
- content: Container(
38
- child: NewListSections(
39
- controllers: {
40
- widget.mwebSettingsViewModelBase.mwebNodeUri: _nodeUriController,
41
- },
42
- sections: {
43
- 'main': [
44
- ListItemTextField(
45
- keyValue: widget.mwebSettingsViewModelBase.mwebNodeUri,
46
- label: S.current.node_address,
47
- validator: NodePathValidator(),
48
- ),
49
- ]
50
- }),
51
- ),
52
- bottomContent: LoadingPrimaryButton(
53
- onPressed: () => save(context),
54
- text: S.of(context).save,
55
- color: Theme.of(context).colorScheme.primary,
56
- textColor: Theme.of(context).colorScheme.onPrimary,
38
+ content: Container(
39
+ child: NewListSections(controllers: {
40
+ widget.mwebSettingsViewModelBase.mwebNodeUri: _nodeUriController,
41
+ }, sections: {
42
+ 'main': [
43
+ ListItemTextField(
44
+ keyValue: widget.mwebSettingsViewModelBase.mwebNodeUri,
45
+ label: S.current.node_address,
46
+ validator: NodePathValidator(),
47
+ ),
48
+ ]
49
+ }),
50
+ ),
51
+ bottomContent: LoadingPrimaryButton(
52
+ onPressed: () => save(context),
53
+ text: S.of(context).save,
54
+ color: Theme.of(context).colorScheme.primary,
55
+ textColor: Theme.of(context).colorScheme.onPrimary,
56
),
57
),
58
);
lib/src/screens/settings/mweb_settings.dart
+1
-1
@@ -41,7 +41,7 @@ class MwebSettingsPage extends BasePage {
41
title: S.current.litecoin_mweb_scanning,
42
handler: (BuildContext context) => Navigator.of(context).pushNamed(Routes.rescan),
43
),
44
- SettingsCellWithArrow(
44
+ SettingsCellWithArrow(
45
title: S.current.litecoin_mweb_logs,
46
handler: (BuildContext context) => Navigator.of(context).pushNamed(Routes.mwebLogs),
47
),
lib/src/screens/settings/other_settings_page.dart
+70
-67
@@ -149,7 +149,8 @@ class OtherSettingsPage extends BasePage {
149
Navigator.of(context).pushNamed(Routes.signPage);
150
}),
151
],
152
- if (_otherSettingsViewModel.walletType == WalletType.bitcoin) "btc_logging": [
152
+ if (_otherSettingsViewModel.walletType == WalletType.bitcoin)
153
+ "btc_logging": [
154
ListItemRegularRow(
155
keyValue: "export_lightning_logs",
156
label: S.of(context).export_lightning_logs,
@@ -158,72 +159,74 @@ class OtherSettingsPage extends BasePage {
159
keyValue: "export_payjoin_logs",
160
label: S.of(context).export_payjoin_logs,
161
onTap: () => onExportPJLog(context)),
161
- ],
162
- "dev": FeatureFlag.hasDevOptions == false ? [] : [
163
- if (_otherSettingsViewModel.walletType == WalletType.monero)
164
- ListItemRegularRow(
165
- keyValue: "[dev] monero background sync",
166
- label: "[dev] monero background sync",
167
- onTap: () => Navigator.of(context).pushNamed(Routes.devMoneroBackgroundSync)),
168
- if ([WalletType.monero, WalletType.wownero, WalletType.zano]
169
- .contains(_otherSettingsViewModel.walletType))
170
- ListItemRegularRow(
171
- keyValue: "[dev] xmr call profiler",
172
- label: "[dev] xmr call profiler",
173
- onTap: () => Navigator.of(context).pushNamed(Routes.devMoneroCallProfiler)),
174
- if ([WalletType.monero].contains(_otherSettingsViewModel.walletType))
175
- ListItemRegularRow(
176
- keyValue: '[dev] xmr wallet cache debug',
177
- label: '[dev] xmr wallet cache debug',
178
- onTap: () => Navigator.of(context).pushNamed(Routes.devMoneroWalletCacheDebug)),
179
- ListItemRegularRow(
180
- keyValue: '[dev] shared preferences',
181
- label: '[dev] shared preferences',
182
- onTap: () => Navigator.of(context).pushNamed(Routes.devSharedPreferences)),
183
- ListItemRegularRow(
184
- keyValue: '[dev] secure storage preferences',
185
- label: '[dev] secure storage preferences',
186
- onTap: () => Navigator.of(context).pushNamed(Routes.devSecurePreferences)),
187
- ListItemRegularRow(
188
- keyValue: '[dev] background sync logs',
189
- label: '[dev] background sync logs',
190
- onTap: () => Navigator.of(context).pushNamed(Routes.devBackgroundSyncLogs)),
191
- ListItemRegularRow(
192
- keyValue: '[dev] socket health logs',
193
- label: '[dev] socket health logs',
194
- onTap: () => Navigator.of(context).pushNamed(Routes.devSocketHealthLogs)),
195
- ListItemRegularRow(
196
- keyValue: '[dev] network requests logs',
197
- label: '[dev] network requests logs',
198
- onTap: () => Navigator.of(context).pushNamed(Routes.devNetworkRequests)),
199
- ListItemRegularRow(
200
- keyValue: '[dev] exchange provider logs',
201
- label: '[dev] exchange provider logs',
202
- onTap: () => Navigator.of(context).pushNamed(Routes.devExchangeProviderLogs)),
203
- ListItemRegularRow(
204
- keyValue: '[dev] *QR tools',
205
- label: '[dev] *QR tools',
206
- onTap: () => Navigator.of(context).pushNamed(Routes.devExchangeProviderLogs)),
207
- ListItemRegularRow(
208
- keyValue: '[dev] browse sqlite db',
209
- label: '[dev] browse sqlite db',
210
- onTap: () async {
211
- final data = await dumpDb();
212
- Navigator.of(context).push(
213
- MaterialPageRoute(
214
- builder: (context) => JsonExplorerPage(data: data, title: 'sqlite db'),
215
- ),
216
- );
217
- }),
218
- ListItemRegularRow(
219
- keyValue: '[dev] fake corrupt sqlite db',
220
- label: '[dev] fake corrupt sqlite db',
221
- onTap: () async {
222
- final dbDebugMarker = await sqliteDebugMarkerFile();
223
- dbDebugMarker.create();
224
- }
225
- ),
226
- ]
162
+ ],
163
+ "dev": FeatureFlag.hasDevOptions == false
164
+ ? []
165
+ : [
166
+ if (_otherSettingsViewModel.walletType == WalletType.monero)
167
+ ListItemRegularRow(
168
+ keyValue: "[dev] monero background sync",
169
+ label: "[dev] monero background sync",
170
+ onTap: () => Navigator.of(context).pushNamed(Routes.devMoneroBackgroundSync)),
171
+ if ([WalletType.monero, WalletType.wownero, WalletType.zano]
172
+ .contains(_otherSettingsViewModel.walletType))
173
+ ListItemRegularRow(
174
+ keyValue: "[dev] xmr call profiler",
175
+ label: "[dev] xmr call profiler",
176
+ onTap: () => Navigator.of(context).pushNamed(Routes.devMoneroCallProfiler)),
177
+ if ([WalletType.monero].contains(_otherSettingsViewModel.walletType))
178
+ ListItemRegularRow(
179
+ keyValue: '[dev] xmr wallet cache debug',
180
+ label: '[dev] xmr wallet cache debug',
181
+ onTap: () =>
182
+ Navigator.of(context).pushNamed(Routes.devMoneroWalletCacheDebug)),
183
+ ListItemRegularRow(
184
+ keyValue: '[dev] shared preferences',
185
+ label: '[dev] shared preferences',
186
+ onTap: () => Navigator.of(context).pushNamed(Routes.devSharedPreferences)),
187
+ ListItemRegularRow(
188
+ keyValue: '[dev] secure storage preferences',
189
+ label: '[dev] secure storage preferences',
190
+ onTap: () => Navigator.of(context).pushNamed(Routes.devSecurePreferences)),
191
+ ListItemRegularRow(
192
+ keyValue: '[dev] background sync logs',
193
+ label: '[dev] background sync logs',
194
+ onTap: () => Navigator.of(context).pushNamed(Routes.devBackgroundSyncLogs)),
195
+ ListItemRegularRow(
196
+ keyValue: '[dev] socket health logs',
197
+ label: '[dev] socket health logs',
198
+ onTap: () => Navigator.of(context).pushNamed(Routes.devSocketHealthLogs)),
199
+ ListItemRegularRow(
200
+ keyValue: '[dev] network requests logs',
201
+ label: '[dev] network requests logs',
202
+ onTap: () => Navigator.of(context).pushNamed(Routes.devNetworkRequests)),
203
+ ListItemRegularRow(
204
+ keyValue: '[dev] exchange provider logs',
205
+ label: '[dev] exchange provider logs',
206
+ onTap: () => Navigator.of(context).pushNamed(Routes.devExchangeProviderLogs)),
207
+ ListItemRegularRow(
208
+ keyValue: '[dev] *QR tools',
209
+ label: '[dev] *QR tools',
210
+ onTap: () => Navigator.of(context).pushNamed(Routes.devExchangeProviderLogs)),
211
+ ListItemRegularRow(
212
+ keyValue: '[dev] browse sqlite db',
213
+ label: '[dev] browse sqlite db',
214
+ onTap: () async {
215
+ final data = await dumpDb();
216
+ Navigator.of(context).push(
217
+ MaterialPageRoute(
218
+ builder: (context) => JsonExplorerPage(data: data, title: 'sqlite db'),
219
+ ),
220
+ );
221
+ }),
222
+ ListItemRegularRow(
223
+ keyValue: '[dev] fake corrupt sqlite db',
224
+ label: '[dev] fake corrupt sqlite db',
225
+ onTap: () async {
226
+ final dbDebugMarker = await sqliteDebugMarkerFile();
227
+ dbDebugMarker.create();
228
+ }),
229
+ ]
230
}),
231
);
232
}
lib/src/screens/settings/privacy_page.dart
+45
-47
@@ -38,44 +38,43 @@ class PrivacyPage extends BasePage {
38
return Column(
39
mainAxisSize: MainAxisSize.min,
40
children: [
41
- NewListSections(
42
- sections: {
43
- "1": [
44
- if (_privacySettingsViewModel.isAutoGenerateSubaddressesVisible)
45
- ListItemToggle(
46
- keyValue: "auto_generate_subaddresses",
47
- label: _privacySettingsViewModel.isMoneroWallet
48
- ? S.of(context).auto_generate_subaddresses
49
- : S.of(context).auto_generate_addresses,
50
- value: _privacySettingsViewModel.isAutoGenerateSubaddressesEnabled,
51
- onChanged: (val) {
52
- _privacySettingsViewModel.setAutoGenerateSubaddresses(val);
53
- }),
41
+ NewListSections(sections: {
42
+ "1": [
43
+ if (_privacySettingsViewModel.isAutoGenerateSubaddressesVisible)
44
ListItemToggle(
55
- keyValue: "save_recipient_address",
56
- label: S.of(context).settings_save_recipient_address,
57
- value: _privacySettingsViewModel.shouldSaveRecipientAddress,
45
+ keyValue: "auto_generate_subaddresses",
46
+ label: _privacySettingsViewModel.isMoneroWallet
47
+ ? S.of(context).auto_generate_subaddresses
48
+ : S.of(context).auto_generate_addresses,
49
+ value: _privacySettingsViewModel.isAutoGenerateSubaddressesEnabled,
50
onChanged: (val) {
59
- _privacySettingsViewModel.setShouldSaveRecipientAddress(val);
51
+ _privacySettingsViewModel.setAutoGenerateSubaddresses(val);
52
}),
61
- if (_privacySettingsViewModel.canUsePayjoin)
62
- ListItemToggle(
63
- keyValue: "use_payjoin",
64
- label: S.of(context).use_payjoin,
65
- value: _privacySettingsViewModel.usePayjoin,
66
- onChanged: (val) {
67
- _privacySettingsViewModel.setUsePayjoin(val);
68
- }),
69
- if (_privacySettingsViewModel.canUseLightning)
70
- ListItemToggle(
71
- keyValue: "enable_lightning",
72
- label: S.of(context).enable_lightning,
73
- value: _privacySettingsViewModel.useLightning,
74
- onChanged: (val) {
75
- _privacySettingsViewModel.setUseLightning(val);
76
- }),
77
- ],
78
- "": [
53
+ ListItemToggle(
54
+ keyValue: "save_recipient_address",
55
+ label: S.of(context).settings_save_recipient_address,
56
+ value: _privacySettingsViewModel.shouldSaveRecipientAddress,
57
+ onChanged: (val) {
58
+ _privacySettingsViewModel.setShouldSaveRecipientAddress(val);
59
+ }),
60
+ if (_privacySettingsViewModel.canUsePayjoin)
61
+ ListItemToggle(
62
+ keyValue: "use_payjoin",
63
+ label: S.of(context).use_payjoin,
64
+ value: _privacySettingsViewModel.usePayjoin,
65
+ onChanged: (val) {
66
+ _privacySettingsViewModel.setUsePayjoin(val);
67
+ }),
68
+ if (_privacySettingsViewModel.canUseLightning)
69
+ ListItemToggle(
70
+ keyValue: "enable_lightning",
71
+ label: S.of(context).enable_lightning,
72
+ value: _privacySettingsViewModel.useLightning,
73
+ onChanged: (val) {
74
+ _privacySettingsViewModel.setUseLightning(val);
75
+ }),
76
+ ],
77
+ "": [
78
if (_privacySettingsViewModel.isBitcoin)
79
ListItemRegularRow(
80
iconPath: "assets/new-ui/settings_row_icons/silent-payments.svg",
@@ -83,23 +82,22 @@ class PrivacyPage extends BasePage {
82
label: S.of(context).silent_payments,
83
onTap: () =>
84
Navigator.of(context).pushNamed(Routes.silentPaymentsSettings)),
86
- if (_privacySettingsViewModel.hasMWEB)
87
- ListItemRegularRow(
88
- iconPath: "assets/new-ui/settings_row_icons/mweb.svg",
89
- keyValue: "mweb",
90
- label: "MWEB",
91
- onTap: () =>
92
- Navigator.of(context).pushNamed(Routes.mwebSettings)),
93
- if (_privacySettingsViewModel.hasCoinControl)
85
+ if (_privacySettingsViewModel.hasMWEB)
86
+ ListItemRegularRow(
87
+ iconPath: "assets/new-ui/settings_row_icons/mweb.svg",
88
+ keyValue: "mweb",
89
+ label: "MWEB",
90
+ onTap: () => Navigator.of(context).pushNamed(Routes.mwebSettings)),
91
+ if (_privacySettingsViewModel.hasCoinControl)
92
ListItemRegularRow(
93
iconPath: "assets/new-ui/settings_row_icons/coin-control.svg",
94
keyValue: "coin_control",
95
label: "Coin Control",
98
- onTap: () =>
99
- Navigator.of(context).pushNamed(Routes.unspentCoinsList, arguments: CoinControlPageArgs(canEdit: false, coinTypeToSpendFrom: null))),
96
+ onTap: () => Navigator.of(context).pushNamed(Routes.unspentCoinsList,
97
+ arguments:
98
+ CoinControlPageArgs(canEdit: false, coinTypeToSpendFrom: null))),
99
],
101
- }
102
- ),
100
+ }),
101
],
102
);
103
}),
lib/src/screens/settings/security_backup_page.dart
+10
-11
@@ -73,8 +73,8 @@ class SecurityBackupPage extends BasePage {
73
isAuthenticatedSuccessfully);
74
}
75
} else {
76
- _securitySettingsViewModel.setAllowBiometricalAuthentication(
77
- isAuthenticatedSuccessfully);
76
+ _securitySettingsViewModel
77
+ .setAllowBiometricalAuthentication(isAuthenticatedSuccessfully);
78
}
79
},
80
conditionToDetermineIfToUse2FA: _securitySettingsViewModel
@@ -85,13 +85,13 @@ class SecurityBackupPage extends BasePage {
85
}
86
}),
87
if (DeviceInfo.instance.isMobile)
88
- ListItemToggle(
89
- keyValue: "display_settings_prevent_screen_capture",
90
- label: S.of(context).prevent_screenshots,
91
- value: _securitySettingsViewModel.isAppSecure,
92
- onChanged: (val) {
93
- _securitySettingsViewModel.setIsAppSecure(val);
94
- }),
88
+ ListItemToggle(
89
+ keyValue: "display_settings_prevent_screen_capture",
90
+ label: S.of(context).prevent_screenshots,
91
+ value: _securitySettingsViewModel.isAppSecure,
92
+ onChanged: (val) {
93
+ _securitySettingsViewModel.setIsAppSecure(val);
94
+ }),
95
if (FeatureFlag.duressPinEnabled)
96
ListItemToggle(
97
keyValue: "security_backup_page_duress_pin_button_key",
@@ -114,8 +114,7 @@ class SecurityBackupPage extends BasePage {
114
if (confirmation) {
115
Navigator.of(context).pushNamed(
116
Routes.setupDuressPin,
117
- arguments:
118
- (PinCodeState<PinCodeWidget> pinCtx, String _) async {
117
+ arguments: (PinCodeState<PinCodeWidget> pinCtx, String _) async {
118
pinCtx.close();
119
_securitySettingsViewModel.setEnableDuressPin(true);
120
},
lib/src/screens/settings/silent_payments_logs_page.dart
+4
-5
@@ -105,11 +105,10 @@ class SilentPaymentsLogPage extends BasePage {
105
}
106
107
Future<void> _saveFile() async {
108
- String? outputFile = await FilePicker.platform
109
- .saveFile(
110
- dialogTitle: 'Save Your File to desired location',
111
- fileName: "debug.log",
112
- lockParentWindow: true);
108
+ String? outputFile = await FilePicker.platform.saveFile(
109
+ dialogTitle: 'Save Your File to desired location',
110
+ fileName: "debug.log",
111
+ lockParentWindow: true);
112
113
if (outputFile == null) return;
114
lib/src/screens/settings/silent_payments_settings.dart
+15
-10
@@ -19,7 +19,11 @@ class SilentPaymentsSettingsPage extends StatelessWidget {
19
color: Theme.of(context).colorScheme.surface,
20
child: Column(
21
children: [
22
- ModalTopBar(title: S.current.silent_payments_settings,leadingIcon: Icon(Icons.arrow_back_ios_new),onLeadingPressed: Navigator.of(context).pop,),
22
+ ModalTopBar(
23
+ title: S.current.silent_payments_settings,
24
+ leadingIcon: Icon(Icons.arrow_back_ios_new),
25
+ onLeadingPressed: Navigator.of(context).pop,
26
+ ),
27
Expanded(
28
child: SingleChildScrollView(
29
child: Observer(builder: (_) {
@@ -27,14 +31,14 @@ class SilentPaymentsSettingsPage extends StatelessWidget {
31
padding: EdgeInsets.only(top: 10),
32
child: Column(
33
children: [
30
- if(!FeatureFlag.hasNewUi)
31
- SettingsSwitcherCell(
32
- title: S.current.silent_payments_display_card,
33
- value: _silentPaymentsSettingsViewModel.silentPaymentsCardDisplay,
34
- onValueChange: (_, bool value) {
35
- _silentPaymentsSettingsViewModel.setSilentPaymentsCardDisplay(value);
36
- },
37
- ),
34
+ if (!FeatureFlag.hasNewUi)
35
+ SettingsSwitcherCell(
36
+ title: S.current.silent_payments_display_card,
37
+ value: _silentPaymentsSettingsViewModel.silentPaymentsCardDisplay,
38
+ onValueChange: (_, bool value) {
39
+ _silentPaymentsSettingsViewModel.setSilentPaymentsCardDisplay(value);
40
+ },
41
+ ),
42
SettingsSwitcherCell(
43
title: S.current.silent_payments_always_scan,
44
value: _silentPaymentsSettingsViewModel.silentPaymentsAlwaysScan,
@@ -44,7 +48,8 @@ class SilentPaymentsSettingsPage extends StatelessWidget {
48
),
49
SettingsCellWithArrow(
50
title: S.current.silent_payments_scanning,
47
- handler: (BuildContext context) => Navigator.of(context).pushNamed(Routes.rescan),
51
+ handler: (BuildContext context) =>
52
+ Navigator.of(context).pushNamed(Routes.rescan),
53
),
54
SettingsCellWithArrow(
55
title: S.current.silent_payments_logs,
lib/src/screens/settings/widgets/settings_choices_cell.dart
+3
-4
@@ -44,9 +44,8 @@ class SettingsChoicesCell extends StatelessWidget {
44
color: Theme.of(context).colorScheme.surfaceContainerHighest,
45
width: 1.5,
46
),
47
- color: useGenericColor
48
- ? Theme.of(context).colorScheme.surfaceContainerHighest
49
- : null,
47
+ color:
48
+ useGenericColor ? Theme.of(context).colorScheme.surfaceContainerHighest : null,
49
),
50
child: LayoutBuilder(
51
builder: (context, constraints) {
@@ -106,4 +105,4 @@ class SettingsChoicesCell extends StatelessWidget {
105
),
106
);
107
}
109
-}
\ No newline at end of file
108
+}
lib/src/screens/settings/widgets/settings_picker_row.dart
+1
-1
@@ -6,4 +6,4 @@ class SettingsPickerRaw extends StatelessWidget {
6
// TODO: implement build
7
throw UnimplementedError();
8
}
9
-}
\ No newline at end of file
9
+}
lib/src/screens/settings/widgets/settings_theme_choice.dart
+29
-23
@@ -58,11 +58,13 @@ class SettingsThemeChoicesCell extends StatelessWidget {
58
curve: Curves.easeInOut,
59
margin: EdgeInsets.only(right: 24),
60
decoration: ShapeDecoration(
61
- shape: RoundedSuperellipseBorder(borderRadius: BorderRadius.circular(cellRadius),
62
- side: BorderSide(
63
- color: isSelected ? Theme.of(context).colorScheme.primary : Colors.transparent,
64
- strokeAlign: BorderSide.strokeAlignOutside)
65
- )),
61
+ shape: RoundedSuperellipseBorder(
62
+ borderRadius: BorderRadius.circular(cellRadius),
63
+ side: BorderSide(
64
+ color: isSelected
65
+ ? Theme.of(context).colorScheme.primary
66
+ : Colors.transparent,
67
+ strokeAlign: BorderSide.strokeAlignOutside))),
68
child: ClipRRect(
69
borderRadius: BorderRadius.circular(cellRadius),
70
child: CakeImageWidget(
@@ -97,8 +99,8 @@ class SettingsThemeChoicesCell extends StatelessWidget {
99
children: [
100
Padding(
101
padding: EdgeInsets.only(top: 14),
100
- child: Container(height: 1, color: Theme.of(context).colorScheme.outlineVariant)
101
- ),
102
+ child: Container(
103
+ height: 1, color: Theme.of(context).colorScheme.outlineVariant)),
104
SizedBox(height: cellHeight),
105
Row(
106
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@@ -123,10 +125,14 @@ class SettingsThemeChoicesCell extends StatelessWidget {
125
duration: Duration(milliseconds: 350),
126
opacity: isSelected ? 1 : 0,
127
child: Container(
126
- width:28,height:28,decoration: BoxDecoration(borderRadius: BorderRadius.circular(99999999),border: Border.all(color:Theme.of(context)
127
- .colorScheme
128
- .onSurface))
129
- ),
128
+ width: 28,
129
+ height: 28,
130
+ decoration: BoxDecoration(
131
+ borderRadius: BorderRadius.circular(99999999),
132
+ border: Border.all(
133
+ color: Theme.of(context)
134
+ .colorScheme
135
+ .onSurface))),
136
),
137
AnimatedScale(
138
duration: Duration(milliseconds: 350),
@@ -153,19 +159,19 @@ class SettingsThemeChoicesCell extends StatelessWidget {
159
if (_displaySettingsViewModel.currentTheme is BlackTheme)
160
Padding(
161
padding: EdgeInsets.only(top: 12, bottom: 4),
156
- child: Container(height: 1, color: Theme.of(context).colorScheme.outlineVariant)
157
- ),
162
+ child:
163
+ Container(height: 1, color: Theme.of(context).colorScheme.outlineVariant)),
164
if (_displaySettingsViewModel.currentTheme is BlackTheme)
159
- SettingsSwitcherCell(
160
- height: 40,
161
- title: S.current.oled_mode,
162
- value: _displaySettingsViewModel.isBlackThemeOledEnabled,
163
- onValueChange: (_, bool value) {
164
- _displaySettingsViewModel.setBlackThemeOled(value);
165
- },
166
- padding: EdgeInsets.zero,
167
- switchBackgroundColor: currentTheme.colorScheme.secondaryContainer,
168
- ),
165
+ SettingsSwitcherCell(
166
+ height: 40,
167
+ title: S.current.oled_mode,
168
+ value: _displaySettingsViewModel.isBlackThemeOledEnabled,
169
+ onValueChange: (_, bool value) {
170
+ _displaySettingsViewModel.setBlackThemeOled(value);
171
+ },
172
+ padding: EdgeInsets.zero,
173
+ switchBackgroundColor: currentTheme.colorScheme.secondaryContainer,
174
+ ),
175
],
176
),
177
);
lib/src/screens/settings/widgets/wallet_connect_button.dart
+2
-2
@@ -26,8 +26,8 @@ class WalletConnectTile extends StatelessWidget {
26
child: Text(
27
S.current.walletConnect,
28
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
29
- color: Theme.of(context).colorScheme.onSurface,
30
- ),
29
+ color: Theme.of(context).colorScheme.onSurface,
30
+ ),
31
),
32
),
33
Image.asset(
lib/src/screens/setup_2fa/setup_2fa_enter_code_page.dart
+6
-6
@@ -115,7 +115,6 @@ class TOTPEnterCode extends StatefulWidget {
115
required this.isClosable,
116
});
117
118
-
118
final Setup2FAViewModel setup2FAViewModel;
119
final bool isForSetup;
120
final bool isClosable;
@@ -154,7 +153,6 @@ class _TOTPEnterCodeState extends State<TOTPEnterCode> {
153
),
154
child: Column(
155
children: [
157
-
156
BaseTextFormField(
157
textAlign: TextAlign.left,
158
hintText: S.current.totp_code,
@@ -180,15 +178,17 @@ class _TOTPEnterCodeState extends State<TOTPEnterCode> {
178
return PrimaryButton(
179
isDisabled: widget.setup2FAViewModel.enteredOTPCode.length != 8,
180
onPressed: () async {
183
- final result =
184
- await widget.setup2FAViewModel.totp2FAAuth(totpController.text, widget.isForSetup);
185
- final bannedState = widget.setup2FAViewModel.state is AuthenticationBanned;
181
+ final result = await widget.setup2FAViewModel
182
+ .totp2FAAuth(totpController.text, widget.isForSetup);
183
+ final bannedState =
184
+ widget.setup2FAViewModel.state is AuthenticationBanned;
185
186
await showPopUp<void>(
187
context: context,
188
builder: (BuildContext context) {
189
return PopUpCancellableAlertDialog(
191
- contentText: _textDisplayedInPopupOnResult(result, bannedState, context),
190
+ contentText:
191
+ _textDisplayedInPopupOnResult(result, bannedState, context),
192
actionButtonText: S.of(context).ok,
193
buttonAction: () {
194
result ? widget.setup2FAViewModel.success() : null;
lib/src/screens/setup_2fa/widgets/popup_cancellable_alert.dart
+5
-6
@@ -25,12 +25,11 @@ class PopUpCancellableAlertDialog extends StatelessWidget {
25
contentText,
26
textAlign: TextAlign.center,
27
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
28
- fontSize: 16,
29
- fontWeight: FontWeight.normal,
30
-
31
- color: Theme.of(context).colorScheme.onSurface,
32
- decoration: TextDecoration.none,
33
- ),
28
+ fontSize: 16,
29
+ fontWeight: FontWeight.normal,
30
+ color: Theme.of(context).colorScheme.onSurface,
31
+ decoration: TextDecoration.none,
32
+ ),
33
);
34
}
35
lib/src/screens/setup_pin_code/setup_pin_code.dart
+5
-8
@@ -8,7 +8,7 @@ import 'package:cake_wallet/view_model/setup_pin_code_view_model.dart';
8
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
9
10
class SetupPinCodePage extends BasePage {
11
- SetupPinCodePage(this.pinCodeViewModel,{this.onSuccessfulPinSetup, this.isDuressPin = false})
11
+ SetupPinCodePage(this.pinCodeViewModel, {this.onSuccessfulPinSetup, this.isDuressPin = false})
12
: pinCodeStateKey = GlobalKey<PinCodeState>();
13
14
final SetupPinCodeViewModel pinCodeViewModel;
@@ -24,8 +24,7 @@ class SetupPinCodePage extends BasePage {
24
key: pinCodeStateKey,
25
hasLengthSwitcher: true,
26
onFullPin: (String pin, PinCodeState<PinCodeWidget> state) async {
27
- if (pinCodeViewModel.isOriginalPinCodeFull &&
28
- !pinCodeViewModel.isRepeatedPinCodeFull) {
27
+ if (pinCodeViewModel.isOriginalPinCodeFull && !pinCodeViewModel.isRepeatedPinCodeFull) {
28
state.title = S.current.enter_your_pin_again;
29
state.clear();
30
return;
@@ -64,7 +63,7 @@ class SetupPinCodePage extends BasePage {
63
if (pinCodeStateKey.currentState != null) {
64
onSuccessfulPinSetup?.call(pinCodeStateKey.currentState!, pin);
65
}
67
-
66
+
67
state.reset();
68
},
69
alertBarrierDismissible: false,
@@ -76,8 +75,7 @@ class SetupPinCodePage extends BasePage {
75
builder: (BuildContext context) {
76
return AlertWithOneAction(
77
alertTitle: isDuressPin ? S.current.durres_PIN : S.current.setup_pin,
79
- alertContent:
80
- '${S.current.setup_pin_is_failed} ${e.toString()}',
78
+ alertContent: '${S.current.setup_pin_is_failed} ${e.toString()}',
79
buttonText: S.of(context).ok,
80
buttonAction: () => Navigator.of(context).pop(),
81
alertBarrierDismissible: false,
@@ -108,7 +106,6 @@ class SetupPinCodePage extends BasePage {
106
pinCodeViewModel.reset();
107
}
108
},
111
- onChangedPinLength: (int length) =>
112
- pinCodeViewModel.pinCodeLength = length,
109
+ onChangedPinLength: (int length) => pinCodeViewModel.pinCodeLength = length,
110
initialPinLength: pinCodeViewModel.pinCodeLength);
111
}
lib/src/screens/splash/splash_page.dart
+2
-4
@@ -3,8 +3,6 @@ import 'package:flutter/material.dart';
3
class SplashPage extends StatelessWidget {
4
@override
5
Widget build(BuildContext context) {
6
- return Scaffold(
7
- body: Container()
8
- );
6
+ return Scaffold(body: Container());
7
}
10
-}
\ No newline at end of file
8
+}
lib/src/screens/start_tor/start_tor_page.dart
+2
-2
@@ -34,7 +34,7 @@ class StartTorPage extends BasePage {
34
CircularProgressIndicator(),
35
SizedBox(height: 20),
36
_buildWaitingText(context),
37
- ],
37
+ ],
38
if (startTorViewModel.showOptions) ...[
39
_buildOptionsButtons(context),
40
],
@@ -93,4 +93,4 @@ class StartTorPage extends BasePage {
93
],
94
);
95
}
96
-}
\ No newline at end of file
96
+}
lib/src/screens/support_chat/support_chat_page.dart
+11
-13
@@ -11,15 +11,14 @@ class SupportChatPage extends StatelessWidget {
11
final SupportViewModel supportViewModel;
12
final SecureStorage secureStorage;
13
14
-
14
@override
15
Widget build(BuildContext context) => Container(
17
- color: Theme.of(context).colorScheme.surface,
18
- child: SafeArea(
19
- child: Padding(
20
- padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
21
- child: Column(
22
- children: [
16
+ color: Theme.of(context).colorScheme.surface,
17
+ child: SafeArea(
18
+ child: Padding(
19
+ padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
20
+ child: Column(
21
+ children: [
22
ModalTopBar(
23
title: S.current.settings_support,
24
leadingIcon: Icon(Icons.arrow_back_ios_new),
@@ -42,12 +41,11 @@ class SupportChatPage extends StatelessWidget {
41
return Container();
42
},
43
),
45
- ],
44
+ ],
45
+ ),
46
+ ),
47
),
47
- ),
48
- ),
49
- );
48
+ );
49
51
- Future<String> getCookie() async =>
52
- await secureStorage.read(key: COOKIE_KEY) ?? "";
50
+ Future<String> getCookie() async => await secureStorage.read(key: COOKIE_KEY) ?? "";
51
}
lib/src/screens/support_chat/widgets/chatwoot_widget.dart
+3
-4
@@ -41,11 +41,10 @@ class ChatwootWidgetState extends State<ChatwootWidget> {
41
controller.addWebMessageListener(
42
WebMessageListener(
43
jsObjectName: 'ReactNativeWebView',
44
- onPostMessage: (WebMessage? message, WebUri? sourceOrigin,
45
- bool isMainFrame, PlatformJavaScriptReplyProxy replyProxy) {
44
+ onPostMessage: (WebMessage? message, WebUri? sourceOrigin, bool isMainFrame,
45
+ PlatformJavaScriptReplyProxy replyProxy) {
46
final shortenedMessage = message?.data.toString().substring(16);
47
- if (shortenedMessage != null &&
48
- _isJsonString(shortenedMessage)) {
47
+ if (shortenedMessage != null && _isJsonString(shortenedMessage)) {
48
final parsedMessage = jsonDecode(shortenedMessage);
49
final eventType = parsedMessage["event"];
50
if (eventType == 'loaded') {
lib/src/screens/trade_details/track_trade_list_item.dart
+1
-4
@@ -1,10 +1,7 @@
1
import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
2
3
class TrackTradeListItem extends StandartListItem {
4
- TrackTradeListItem({
5
- required String title,
6
- required String value,
7
- required this.onTap})
4
+ TrackTradeListItem({required String title, required String value, required this.onTap})
5
: super(title: title, value: value);
6
final Function() onTap;
7
}
lib/src/screens/trade_details/trade_details_list_card.dart
+5
-7
@@ -19,13 +19,11 @@ class TradeDetailsListCardItem extends StandartListItem {
19
required CryptoCurrency to,
20
required void Function(BuildContext) onTap,
21
String? extraId}) {
22
-
23
-
24
- final extraIdTitle = from == CryptoCurrency.xrp
25
- ? S.current.destination_tag
26
- : from == CryptoCurrency.xlm
27
- ? S.current.memo
28
- : S.current.extra_id;
22
+ final extraIdTitle = from == CryptoCurrency.xrp
23
+ ? S.current.destination_tag
24
+ : from == CryptoCurrency.xlm
25
+ ? S.current.memo
26
+ : S.current.extra_id;
27
28
return TradeDetailsListCardItem(
29
id: '${S.current.trade_details_id} ${formatAsText(id)}',
lib/src/screens/trade_details/trade_details_page.dart
+4
-4
@@ -74,10 +74,10 @@ class TradeDetailsPageBodyState extends State<TradeDetailsPageBody> {
74
child: Text(
75
'${item.value}',
76
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
77
- fontSize: 16,
78
- fontWeight: FontWeight.w500,
79
- color: Theme.of(context).colorScheme.onSurface,
80
- ),
77
+ fontSize: 16,
78
+ fontWeight: FontWeight.w500,
79
+ color: Theme.of(context).colorScheme.onSurface,
80
+ ),
81
),
82
),
83
image: GestureDetector(
lib/src/screens/trade_details/trade_details_status_item.dart
+1
-2
@@ -1,8 +1,7 @@
1
import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
2
3
class DetailsListStatusItem extends StandartListItem {
4
- DetailsListStatusItem(
5
- {required String title, required String value, this.status})
4
+ DetailsListStatusItem({required String title, required String value, this.status})
5
: super(title: title, value: value);
6
7
final String? status; // waiting, action required, created, fetching, finished, success
lib/src/screens/transaction_details/address_list_item.dart
+1
-1
@@ -2,4 +2,4 @@ import 'package:cake_wallet/src/screens/transaction_details/transaction_details_
2
3
class AddressListItem extends TransactionDetailsListItem {
4
AddressListItem({required super.title, required super.value, super.key});
5
-}
\ No newline at end of file
5
+}
lib/src/screens/transaction_details/confirmations_list_item.dart
+3
-3
@@ -6,7 +6,7 @@ class ConfirmationsListItem extends TransactionDetailsListItem {
6
7
ConfirmationsListItem({required super.title, required super.value, super.key}) {
8
final parts = value.split("/");
9
- current = int.tryParse(parts.first)??0;
10
- needed = int.tryParse(parts.last)??0;
9
+ current = int.tryParse(parts.first) ?? 0;
10
+ needed = int.tryParse(parts.last) ?? 0;
11
}
12
-}
\ No newline at end of file
12
+}
lib/src/screens/transaction_details/rbf_details_page.dart
+2
-1
@@ -105,7 +105,8 @@ class RBFDetailsPage extends BasePage {
105
text: S.of(context).send,
106
isLoading:
107
transactionDetailsViewModel.sendViewModel.state is IsExecutingState,
108
- isDisabled: transactionDetailsViewModel.sendViewModel.state is ExecutedSuccessfullyState,
108
+ isDisabled: transactionDetailsViewModel.sendViewModel.state
109
+ is ExecutedSuccessfullyState,
110
color: Theme.of(context).colorScheme.primary,
111
textColor: Theme.of(context).colorScheme.onPrimary,
112
))),
lib/src/screens/transaction_details/textfield_list_item.dart
+1
-1
@@ -14,4 +14,4 @@ class TextFieldListItem extends TransactionDetailsListItem {
14
);
15
16
final Function(String value) onSubmitted;
17
-}
\ No newline at end of file
17
+}
lib/src/screens/transaction_details/transaction_details_page.dart
+11
-21
@@ -103,8 +103,10 @@ class TransactionDetailsPage extends BasePage {
103
child: SelectButton(
104
text: S.of(context).bump_fee,
105
onTap: () async {
106
- Navigator.of(context).pushNamed(Routes.bumpFeePage,
107
- arguments: [transactionDetailsViewModel.transactionInfo, transactionDetailsViewModel.rawTransaction]);
106
+ Navigator.of(context).pushNamed(Routes.bumpFeePage, arguments: [
107
+ transactionDetailsViewModel.transactionInfo,
108
+ transactionDetailsViewModel.rawTransaction
109
+ ]);
110
},
111
),
112
);
@@ -123,25 +125,17 @@ class TransactionDetailsPage extends BasePage {
125
required WalletType walletType,
126
}) {
127
final textStyle = Theme.of(context).textTheme.bodyMedium!.copyWith(
126
- fontSize: 16,
127
- fontWeight: FontWeight.w500,
128
- color: Theme.of(context).colorScheme.onSurface,
129
- );
128
+ fontSize: 16,
129
+ fontWeight: FontWeight.w500,
130
+ color: Theme.of(context).colorScheme.onSurface,
131
+ );
132
final List<Widget> children = [];
133
final bool hasDoubleNewline = value.contains('\n\n');
134
135
if (hasDoubleNewline) {
134
- final blocks = value
135
- .split('\n\n')
136
- .map((b) => b.trim())
137
- .where((b) => b.isNotEmpty)
138
- .toList();
136
+ final blocks = value.split('\n\n').map((b) => b.trim()).where((b) => b.isNotEmpty).toList();
137
for (final block in blocks) {
140
- final lines = block
141
- .split('\n')
142
- .map((l) => l.trim())
143
- .where((l) => l.isNotEmpty)
144
- .toList();
138
+ final lines = block.split('\n').map((l) => l.trim()).where((l) => l.isNotEmpty).toList();
139
if (lines.length > 1) {
140
children.add(Text(lines.first, style: textStyle));
141
for (int i = 1; i < lines.length; i++) {
@@ -165,11 +159,7 @@ class TransactionDetailsPage extends BasePage {
159
children.add(SizedBox(height: 8));
160
}
161
} else {
168
- final lines = value
169
- .split('\n')
170
- .map((l) => l.trim())
171
- .where((l) => l.isNotEmpty)
172
- .toList();
162
+ final lines = value.split('\n').map((l) => l.trim()).where((l) => l.isNotEmpty).toList();
163
bool firstLineIsContactName = (lines.length > 1 && lines.first.length < 20);
164
int startIndex = 0;
165
if (firstLineIsContactName) {
lib/src/screens/transaction_details/transaction_expandable_list_item.dart
+1
-1
@@ -7,6 +7,6 @@ class StandardExpandableListItem<T> extends TransactionDetailsListItem {
7
required this.expandableItems,
8
Key? key,
9
}) : super(title: title, value: '', key: key);
10
-
10
+
11
final List<T> expandableItems;
12
}
lib/src/screens/unspent_coins/unspent_coins_list_page.dart
+40
-42
@@ -121,14 +121,14 @@ class UnspentCoinsListFormState extends State<UnspentCoinsListForm> {
121
canPop: false,
122
onPopInvokedWithResult: (bool didPop, Object? result) async {
123
if (didPop) return;
124
- if(mounted)
125
- await widget.handleOnPopInvoked(context);
124
+ if (mounted) await widget.handleOnPopInvoked(context);
125
},
126
child: FutureBuilder<void>(
127
future: _initialization,
128
builder: (context, snapshot) {
129
if (snapshot.connectionState == ConnectionState.waiting) {
131
- return Center(child: CircularProgressIndicator(
130
+ return Center(
131
+ child: CircularProgressIndicator(
132
color: Theme.of(context).colorScheme.primary,
133
));
134
}
@@ -153,10 +153,10 @@ class UnspentCoinsListFormState extends State<UnspentCoinsListForm> {
153
Text(
154
S.current.all_coins,
155
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
156
- fontSize: 16,
157
- fontWeight: FontWeight.bold,
158
- color: Theme.of(context).colorScheme.onSurface,
159
- ),
156
+ fontSize: 16,
157
+ fontWeight: FontWeight.bold,
158
+ color: Theme.of(context).colorScheme.onSurface,
159
+ ),
160
),
161
],
162
),
@@ -165,46 +165,44 @@ class UnspentCoinsListFormState extends State<UnspentCoinsListForm> {
165
child: unspentCoinsListViewModel.items.isEmpty
166
? Center(
167
child: Text(
168
- 'No unspent coins available',
169
- textAlign: TextAlign.center,
170
- style: Theme.of(context).textTheme.bodyMedium!.copyWith(
171
- color: Theme.of(context).colorScheme.onSurfaceVariant,
172
- ),
173
- )
174
- )
168
+ 'No unspent coins available',
169
+ textAlign: TextAlign.center,
170
+ style: Theme.of(context).textTheme.bodyMedium!.copyWith(
171
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
172
+ ),
173
+ ))
174
: ListView.separated(
175
itemCount: unspentCoinsListViewModel.items.length,
176
separatorBuilder: (_, __) => SizedBox(height: 15),
177
itemBuilder: (_, int index) {
178
final item = unspentCoinsListViewModel.items[index];
180
- return Observer(
181
- builder: (_) {
182
- final fiatAmount = unspentCoinsListViewModel.fiatAmounts[item.amount] ?? '';
183
- return GestureDetector(
184
- onTap: () => Navigator.of(context).pushNamed(
185
- Routes.unspentCoinsDetails,
186
- arguments: [item, unspentCoinsListViewModel],
187
- ),
188
- child: UnspentCoinsListItem(
189
- note: item.note,
190
- amount: item.amount,
191
- fiatAmount: fiatAmount,
192
- address: item.address,
193
- isSending: item.isSending,
194
- isFrozen: item.isFrozen,
195
- isChange: item.isChange,
196
- isSilentPayment: item.isSilentPayment,
197
- onCheckBoxTap: item.isFrozen
198
- ? null
199
- : () async {
200
- item.isSending = !item.isSending;
201
- await unspentCoinsListViewModel
202
- .saveUnspentCoinInfo(item);
203
- },
204
- ),
205
- );
206
- }
207
- );
179
+ return Observer(builder: (_) {
180
+ final fiatAmount =
181
+ unspentCoinsListViewModel.fiatAmounts[item.amount] ?? '';
182
+ return GestureDetector(
183
+ onTap: () => Navigator.of(context).pushNamed(
184
+ Routes.unspentCoinsDetails,
185
+ arguments: [item, unspentCoinsListViewModel],
186
+ ),
187
+ child: UnspentCoinsListItem(
188
+ note: item.note,
189
+ amount: item.amount,
190
+ fiatAmount: fiatAmount,
191
+ address: item.address,
192
+ isSending: item.isSending,
193
+ isFrozen: item.isFrozen,
194
+ isChange: item.isChange,
195
+ isSilentPayment: item.isSilentPayment,
196
+ onCheckBoxTap: item.isFrozen
197
+ ? null
198
+ : () async {
199
+ item.isSending = !item.isSending;
200
+ await unspentCoinsListViewModel
201
+ .saveUnspentCoinInfo(item);
202
+ },
203
+ ),
204
+ );
205
+ });
206
},
207
),
208
),
lib/src/screens/unspent_coins/widgets/unspent_coins_list_item.dart
+24
-24
@@ -73,19 +73,19 @@ class UnspentCoinsListItem extends StatelessWidget {
73
AutoSizeText(
74
note,
75
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
76
- color: amountColor,
77
- fontSize: 15,
78
- fontWeight: FontWeight.w600,
79
- ),
76
+ color: amountColor,
77
+ fontSize: 15,
78
+ fontWeight: FontWeight.w600,
79
+ ),
80
maxLines: 1,
81
),
82
AutoSizeText(
83
amount,
84
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
85
- color: amountColor,
86
- fontSize: 15,
87
- fontWeight: FontWeight.w600,
88
- ),
85
+ color: amountColor,
86
+ fontSize: 15,
87
+ fontWeight: FontWeight.w600,
88
+ ),
89
maxLines: 1,
90
)
91
],
@@ -111,21 +111,21 @@ class UnspentCoinsListItem extends StatelessWidget {
111
],
112
),
113
if (fiatAmount.isNotEmpty)
114
- Row(
115
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
116
- crossAxisAlignment: CrossAxisAlignment.start,
117
- children: [
118
- AutoSizeText(
119
- fiatAmount,
120
- style: Theme.of(context).textTheme.bodyMedium!.copyWith(
121
- color: amountColor,
122
- fontSize: 1,
123
- fontWeight: FontWeight.w600,
114
+ Row(
115
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
116
+ crossAxisAlignment: CrossAxisAlignment.start,
117
+ children: [
118
+ AutoSizeText(
119
+ fiatAmount,
120
+ style: Theme.of(context).textTheme.bodyMedium!.copyWith(
121
+ color: amountColor,
122
+ fontSize: 1,
123
+ fontWeight: FontWeight.w600,
124
+ ),
125
+ maxLines: 1,
126
),
125
- maxLines: 1,
126
- ),
127
- ],
128
- ),
127
+ ],
128
+ ),
129
Expanded(
130
child: Row(
131
crossAxisAlignment: CrossAxisAlignment.center,
@@ -134,8 +134,8 @@ class UnspentCoinsListItem extends StatelessWidget {
134
AutoSizeText(
135
'${address.substring(0, 5)}...${address.substring(address.length - 5)}', // ToDo: Maybe use address label
136
style: Theme.of(context).textTheme.bodySmall!.copyWith(
137
- color: addressColor,
138
- ),
137
+ color: addressColor,
138
+ ),
139
maxLines: 1,
140
),
141
Row(
lib/src/screens/ur/animated_ur_page.dart
+4
-8
@@ -64,8 +64,7 @@ class AnimatedURPage extends BasePage {
64
hardwareWalletType: animatedURmodel.wallet.hardwareWalletType,
65
),
66
),
67
- if (["ur:xmr-txunsigned", "ur:xmr-output", "ur:psbt", BBQR.header]
68
- .contains(urQrType)) ...{
67
+ if (["ur:xmr-txunsigned", "ur:xmr-output", "ur:psbt", BBQR.header].contains(urQrType)) ...{
68
Padding(
69
padding: const EdgeInsets.all(16.0),
70
child: SizedBox(
@@ -89,8 +88,7 @@ class AnimatedURPage extends BasePage {
88
case "ur:xmr-txunsigned": // ur:xmr-txsigned
89
final ur = await presentQRScanner(context, showManualInput: false);
90
if (ur == null) return;
92
- final result =
93
- await monero!.commitTransactionUR(animatedURmodel.wallet, ur);
91
+ final result = await monero!.commitTransactionUR(animatedURmodel.wallet, ur);
92
if (result) {
93
Navigator.of(context).pop(true);
94
}
@@ -98,8 +96,7 @@ class AnimatedURPage extends BasePage {
96
case "ur:xmr-output": // xmr-keyimage
97
final ur = await presentQRScanner(context, showManualInput: false);
98
if (ur == null) return;
101
- final result =
102
- await monero!.importKeyImagesUR(animatedURmodel.wallet, ur);
99
+ final result = await monero!.importKeyImagesUR(animatedURmodel.wallet, ur);
100
if (result) {
101
Navigator.of(context).pop(true);
102
}
@@ -107,8 +104,7 @@ class AnimatedURPage extends BasePage {
104
case "ur:psbt": // psbt
105
final ur = await presentQRScanner(context, showManualInput: false);
106
if (ur == null) return;
110
- await bitcoin!
111
- .commitPsbtUR(animatedURmodel.wallet, ur.trim().split("\n"));
107
+ await bitcoin!.commitPsbtUR(animatedURmodel.wallet, ur.trim().split("\n"));
108
Navigator.of(context).pop(true);
109
default:
110
throw UnimplementedError("unable to handle UR: ${urQrType}");
lib/src/screens/ur/widgets/qr_format_info_bottom_sheet.dart
+1
-4
@@ -24,10 +24,7 @@ class QRFormatInfoBottomSheet extends StatelessWidget {
24
width: 40,
25
height: 4,
26
decoration: BoxDecoration(
27
- color: Theme.of(context)
28
- .colorScheme
29
- .onSurface
30
- .withOpacity(0.3),
27
+ color: Theme.of(context).colorScheme.onSurface.withOpacity(0.3),
28
borderRadius: BorderRadius.circular(2),
29
),
30
),
lib/src/screens/ur/widgets/qr_selection_dialog.dart
+2
-7
@@ -90,9 +90,7 @@ class QRFormatSelectionDialog extends BaseAlertDialog {
90
fontSize: 14,
91
fontWeight: FontWeight.w600,
92
color: isSelected
93
- ? Theme.of(context)
94
- .colorScheme
95
- .onPrimaryContainer
93
+ ? Theme.of(context).colorScheme.onPrimaryContainer
94
: Theme.of(context).colorScheme.onSurface,
95
),
96
),
@@ -105,10 +103,7 @@ class QRFormatSelectionDialog extends BaseAlertDialog {
103
.colorScheme
104
.onPrimaryContainer
105
.withOpacity(0.6)
108
- : Theme.of(context)
109
- .colorScheme
110
- .onSurface
111
- .withOpacity(0.6),
106
+ : Theme.of(context).colorScheme.onSurface.withOpacity(0.6),
107
),
108
),
109
],
lib/src/screens/ur/widgets/urqr.dart
+5
-9
@@ -53,19 +53,17 @@ class _URQRState extends State<URQR> {
53
54
String get nextLabel => widget.urqr.keys.toList()[(selectedInt + 1) % widget.urqr.length];
55
void next() => setState(() {
56
- final keys = widget.urqr.keys.toList();
56
+ final keys = widget.urqr.keys.toList();
57
58
- selectedInt++;
59
- selected = keys[(selectedInt) % keys.length];
60
- });
58
+ selectedInt++;
59
+ selected = keys[(selectedInt) % keys.length];
60
+ });
61
62
late String selected = (widget.urqr.isEmpty) ? "unknown" : widget.urqr.keys.first;
63
64
-
64
List<String> get frames => widget.urqr[selected]?.split("\n") ?? [];
65
void _nextFrame() => setState(() => frame++);
66
68
-
67
@override
68
Widget build(BuildContext context) {
69
return Column(
@@ -85,9 +83,7 @@ class _URQRState extends State<URQR> {
83
),
84
),
85
if (widget.urqr.values.length > 1)
88
- widget.walletType == WalletType.monero
89
- ? _legacySwitch(context)
90
- : _newSwitch(context),
86
+ widget.walletType == WalletType.monero ? _legacySwitch(context) : _newSwitch(context),
87
if (FeatureFlag.hasDevOptions) ...{
88
TextButton(
89
onPressed: () {
lib/src/screens/wallet_connect/services/chain_service/eth/evm_supported_methods.dart
+1
-1
@@ -28,4 +28,4 @@ enum EVMSupportedMethods {
28
return 'eth_sendTransaction';
29
}
30
}
31
-}
\ No newline at end of file
31
+}
lib/src/screens/wallet_connect/services/walletkit_service.dart
+19
-20
@@ -133,9 +133,9 @@ abstract class WalletKitServiceBase with Store {
133
if (!isInitialized) {
134
try {
135
await _walletKit.init().timeout(
136
- const Duration(seconds: 8),
137
- onTimeout: () => throw TimeoutException('walletKit init timed out'),
138
- );
136
+ const Duration(seconds: 8),
137
+ onTimeout: () => throw TimeoutException('walletKit init timed out'),
138
+ );
139
debugPrint('Initialized');
140
isInitialized = true;
141
} catch (e) {
@@ -202,14 +202,16 @@ abstract class WalletKitServiceBase with Store {
202
namespaces: session.namespaces,
203
);
204
if (events.contains('accountsChanged')) {
205
- await _walletKit.emitSessionEvent(
206
- topic: session.topic,
207
- chainId: chainID,
208
- event: SessionEventParams(
209
- name: 'accountsChanged',
210
- data: [chain.publicKey],
211
- ),
212
- ).timeout(const Duration(seconds: 3));
205
+ await _walletKit
206
+ .emitSessionEvent(
207
+ topic: session.topic,
208
+ chainId: chainID,
209
+ event: SessionEventParams(
210
+ name: 'accountsChanged',
211
+ data: [chain.publicKey],
212
+ ),
213
+ )
214
+ .timeout(const Duration(seconds: 3));
215
}
216
} on ReownSignError catch (e) {
217
if (e.code == 6) {
@@ -433,12 +435,10 @@ abstract class WalletKitServiceBase with Store {
435
}
436
437
final requesterMetadata = args.requester.metadata;
436
- final requesterIcon = requesterMetadata.icons.isNotEmpty
437
- ? requesterMetadata.icons.first
438
- : null;
438
+ final requesterIcon =
439
+ requesterMetadata.icons.isNotEmpty ? requesterMetadata.icons.first : null;
440
final chainKeysForAuth = walletKeyService.getKeysForChain(appStore.wallet!);
440
- final addressForAuth =
441
- chainKeysForAuth.isNotEmpty ? chainKeysForAuth.first.publicKey : '';
441
+ final addressForAuth = chainKeysForAuth.isNotEmpty ? chainKeysForAuth.first.publicKey : '';
442
final combinedMessageBody =
443
formattedMessages.map((m) => m.values.first as String).join('\n\n');
444
@@ -521,8 +521,7 @@ abstract class WalletKitServiceBase with Store {
521
522
@action
523
Future<void> deletePairing({required String topic}) async {
524
- final topicSessions =
525
- sessions.where((element) => element.pairingTopic == topic).toList();
524
+ final topicSessions = sessions.where((element) => element.pairingTopic == topic).toList();
525
526
await _walletKit.core.pairing.disconnect(topic: topic);
527
for (var session in topicSessions) {
@@ -557,7 +556,7 @@ abstract class WalletKitServiceBase with Store {
556
reason: Errors.getSdkError(Errors.USER_DISCONNECTED).toSignError(),
557
);
558
} catch (e) {
560
- printV('disconnectSession: $e');
559
+ printV('disconnectSession: $e');
560
}
561
562
sessions.clear();
@@ -622,7 +621,7 @@ abstract class WalletKitServiceBase with Store {
621
622
@action
623
List<SessionData> getSessionsForPairingInfo(PairingInfo pairing) {
625
- return sessions.where((element) => element.pairingTopic == pairing.topic).toList();
624
+ return sessions.where((element) => element.pairingTopic == pairing.topic).toList();
625
}
626
627
String getKeyForStoringTopicsForWallet() {
lib/src/screens/wallet_connect/utils/method_utils.dart
+4
-9
@@ -13,7 +13,7 @@ import 'package:reown_walletkit/reown_walletkit.dart';
13
class MethodsUtils {
14
static final walletKit = getIt.get<WalletKitService>().walletKit;
15
static final bottomSheetService = getIt.get<BottomSheetService>();
16
-
16
+
17
static const _transactionMethods = {
18
'eth_sendTransaction',
19
'eth_signTransaction',
@@ -34,18 +34,13 @@ class MethodsUtils {
34
}) async {
35
final appStore = getIt.get<AppStore>();
36
final pending = walletKit.pendingRequests.getAll();
37
- final session = pending.isNotEmpty
38
- ? walletKit.sessions.get(pending.last.topic)
39
- : null;
37
+ final session = pending.isNotEmpty ? walletKit.sessions.get(pending.last.topic) : null;
38
final dAppMetadata = session?.peer.metadata;
39
40
final isTransaction = method != null && _transactionMethods.contains(method);
41
final resolvedTitle = title ??
44
- (isTransaction
45
- ? S.current.wc_approve_request_title
46
- : S.current.wc_signing_request_title);
47
- final swipeLabel =
48
- isTransaction ? S.current.wc_swipe_to_approve : S.current.wc_swipe_to_sign;
42
+ (isTransaction ? S.current.wc_approve_request_title : S.current.wc_signing_request_title);
43
+ final swipeLabel = isTransaction ? S.current.wc_swipe_to_approve : S.current.wc_swipe_to_sign;
44
45
final extraRows = <WCMessageRow>[];
46
if (method != null && method.isNotEmpty) {
lib/src/screens/wallet_connect/utils/wc_permissions_mapper.dart
+2
-1
@@ -39,7 +39,8 @@ class WCPermissionsMapper {
39
}
40
41
final permissions = <WCPermission>[
42
- WCPermission(iconUrl: "assets/new-ui/global_view.svg", label: S.current.wc_permission_view_balance),
42
+ WCPermission(
43
+ iconUrl: "assets/new-ui/global_view.svg", label: S.current.wc_permission_view_balance),
44
];
45
46
final wantsTransactionApproval = methods.any(_transactionMethods.contains);
lib/src/screens/wallet_connect/wc_connections_listing_view.dart
+1
-1
@@ -227,4 +227,4 @@ class WalletConnectConnectionsView extends StatelessWidget {
227
),
228
);
229
}
230
-}
\ No newline at end of file
230
+}
lib/src/screens/wallet_connect/widgets/enter_wallet_connect_uri_widget.dart
+2
-2
@@ -78,12 +78,12 @@ class EnterWalletConnectURIWidget extends BaseAlertDialog {
78
width: 36,
79
height: 36,
80
padding: EdgeInsets.only(top: 0),
81
- child: Semantics(
81
+ child: Semantics(
82
label: S.of(context).paste,
83
child: InkWell(
84
onTap: () => _pasteWalletConnectURI(),
85
child: Container(
86
- padding: EdgeInsets.all(8),
86
+ padding: EdgeInsets.all(8),
87
decoration: BoxDecoration(
88
borderRadius: BorderRadius.all(Radius.circular(6)),
89
),
lib/src/screens/wallet_connect/widgets/wc_hero_card.dart
-1
@@ -1,4 +1,3 @@
1
-
1
import 'package:cake_wallet/generated/i18n.dart';
2
import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
3
import 'package:flutter/material.dart';
lib/src/screens/wallet_keys/wallet_keys_page.dart
+1
-1
@@ -184,7 +184,7 @@ class _WalletKeysPageBodyState extends State<WalletKeysPageBody>
184
Widget _buildSeedTab(BuildContext context, bool isLegacySeed) {
185
return Column(
186
children: [
187
- if (isLegacySeedOnly || isLegacySeed ||widget.walletKeysViewModel.shouldShowHeightBox) ...[
187
+ if (isLegacySeedOnly || isLegacySeed || widget.walletKeysViewModel.shouldShowHeightBox) ...[
188
_buildHeightBox(),
189
const SizedBox(height: 20),
190
],
lib/src/screens/wallet_list/wallet_list_page.dart
+42
-44
@@ -143,7 +143,7 @@ class WalletListBodyState extends State<WalletListBody> {
143
@override
144
Widget build(BuildContext context) {
145
return GradientBackground(
146
- scaffold: Container(
146
+ scaffold: Container(
147
height: double.infinity,
148
padding: EdgeInsets.only(top: 16),
149
child: Stack(
@@ -339,45 +339,45 @@ class WalletListBodyState extends State<WalletListBody> {
339
Stack(
340
alignment: Alignment.bottomCenter,
341
children: [
342
- !FeatureFlag.hasNewUi
343
- ? IgnorePointer(
344
- child: Container(
345
- alignment: Alignment.bottomCenter,
346
- height: 185,
347
- decoration: BoxDecoration(
348
- gradient: LinearGradient(
349
- begin: Alignment.topCenter,
350
- end: Alignment.bottomCenter,
351
- colors: <Color>[
352
- Theme.of(context).colorScheme.surface.withAlpha(10),
353
- Theme.of(context).colorScheme.surface,
354
- Theme.of(context).colorScheme.surface,
355
- Theme.of(context).colorScheme.surface
356
- ],
357
- ),
358
- ),
359
- ),
360
- )
361
- : IgnorePointer(
362
- child: Container(
363
- height: 275,
364
- decoration: BoxDecoration(
365
- gradient: LinearGradient(
366
- begin: Alignment.topCenter,
367
- end: Alignment.bottomCenter,
368
- colors: <Color>[
369
- Theme.of(context).colorScheme.surfaceDim.withAlpha(10),
370
- Theme.of(context).colorScheme.surfaceDim.withAlpha(150),
371
- Theme.of(context).colorScheme.surfaceDim.withAlpha(255),
372
- Theme.of(context).colorScheme.surfaceDim.withAlpha(255),
373
- Theme.of(context).colorScheme.surfaceDim.withAlpha(255),
374
- Theme.of(context).colorScheme.surfaceDim.withAlpha(255),
375
- Theme.of(context).colorScheme.surfaceDim.withAlpha(255)
376
- ],
342
+ !FeatureFlag.hasNewUi
343
+ ? IgnorePointer(
344
+ child: Container(
345
+ alignment: Alignment.bottomCenter,
346
+ height: 185,
347
+ decoration: BoxDecoration(
348
+ gradient: LinearGradient(
349
+ begin: Alignment.topCenter,
350
+ end: Alignment.bottomCenter,
351
+ colors: <Color>[
352
+ Theme.of(context).colorScheme.surface.withAlpha(10),
353
+ Theme.of(context).colorScheme.surface,
354
+ Theme.of(context).colorScheme.surface,
355
+ Theme.of(context).colorScheme.surface
356
+ ],
357
+ ),
358
+ ),
359
+ ),
360
+ )
361
+ : IgnorePointer(
362
+ child: Container(
363
+ height: 275,
364
+ decoration: BoxDecoration(
365
+ gradient: LinearGradient(
366
+ begin: Alignment.topCenter,
367
+ end: Alignment.bottomCenter,
368
+ colors: <Color>[
369
+ Theme.of(context).colorScheme.surfaceDim.withAlpha(10),
370
+ Theme.of(context).colorScheme.surfaceDim.withAlpha(150),
371
+ Theme.of(context).colorScheme.surfaceDim.withAlpha(255),
372
+ Theme.of(context).colorScheme.surfaceDim.withAlpha(255),
373
+ Theme.of(context).colorScheme.surfaceDim.withAlpha(255),
374
+ Theme.of(context).colorScheme.surfaceDim.withAlpha(255),
375
+ Theme.of(context).colorScheme.surfaceDim.withAlpha(255)
376
+ ],
377
+ ),
378
+ ),
379
+ ),
380
),
378
- ),
379
- ),
380
- ),
381
Container(
382
height: 240,
383
width: MediaQuery.of(context).size.width,
@@ -464,8 +464,7 @@ class WalletListBodyState extends State<WalletListBody> {
464
color: Theme.of(context).colorScheme.primary,
465
textColor: Theme.of(context).colorScheme.onPrimary,
466
),
467
- if(FeatureFlag.hasNewUi)
468
- SizedBox(height:52.0)
467
+ if (FeatureFlag.hasNewUi) SizedBox(height: 52.0)
468
],
469
),
470
),
@@ -578,9 +577,8 @@ class WalletListBodyState extends State<WalletListBody> {
577
if (_progressBar != null) {
578
_progressBar!.dismiss();
579
}
581
- _progressBar = createBar<void>(text, context, duration: null)
582
- ..show(context);
583
- }catch(e){}
580
+ _progressBar = createBar<void>(text, context, duration: null)..show(context);
581
+ } catch (e) {}
582
}
583
584
Future<void> hideProgressText() async {
lib/src/screens/wallet_unlock/wallet_unlock_arguments.dart
+1
-4
@@ -5,10 +5,7 @@ typedef AuthPasswordHandler = Future<void> Function(String);
5
6
class WalletUnlockArguments {
7
WalletUnlockArguments(
8
- {required this.callback,
9
- this.walletName,
10
- this.walletType,
11
- this.authPasswordHandler});
8
+ {required this.callback, this.walletName, this.walletType, this.authPasswordHandler});
9
10
final OnAuthenticationFinished callback;
11
final AuthPasswordHandler? authPasswordHandler;
lib/src/screens/welcome/create_pin_welcome_page.dart
+2
-1
@@ -228,7 +228,8 @@ class CreatePinWelcomePage extends BasePage {
228
child: PrimaryButton(
229
key: ValueKey('create_pin_welcome_page_create_a_pin_button_key'),
230
onPressed: () => Navigator.pushNamed(context, Routes.welcomeWallet),
231
- text: isWalletPasswordDirectInput ? S.current.set_up_a_wallet : S.current.set_a_pin,
231
+ text:
232
+ isWalletPasswordDirectInput ? S.current.set_up_a_wallet : S.current.set_a_pin,
233
color: Theme.of(context).colorScheme.primary,
234
textColor: Theme.of(context).colorScheme.onPrimary,
235
),
lib/src/screens/welcome/welcome_page.dart
+6
-4
@@ -22,17 +22,19 @@ class WelcomePage extends BasePage {
22
23
@override
24
Widget Function(BuildContext, Widget) get rootWrapper =>
25
- (BuildContext context, Widget scaffold) => GradientBackground(scaffold: scaffold);
25
+ (BuildContext context, Widget scaffold) => GradientBackground(scaffold: scaffold);
26
27
@override
28
bool get resizeToAvoidBottomInset => false;
29
30
@override
31
Widget trailing(BuildContext context) {
32
- final Uri _url =
33
- Uri.parse('https://docs.cakewallet.com/get-started/setup/');
32
+ final Uri _url = Uri.parse('https://docs.cakewallet.com/get-started/setup/');
33
return IconButton(
35
- icon: Icon(Icons.info_outline, size: 26,),
34
+ icon: Icon(
35
+ Icons.info_outline,
36
+ size: 26,
37
+ ),
38
onPressed: () async {
39
await launchUrl(_url);
40
},
lib/src/screens/yat/widgets/first_introduction.dart
+37
-58
@@ -25,65 +25,44 @@ class FirstIntroduction extends StatelessWidget {
25
color: Theme.of(context).colorScheme.surfaceContainer,
26
child: ScrollableWithBottomSection(
27
contentPadding: EdgeInsets.only(top: 40, bottom: 40),
28
- content: Column(
29
- children: [
30
- Container(
31
- height: 45,
32
- padding: EdgeInsets.only(left: 24, right: 24),
33
- child: YatBar(onClose: () => Navigator.of(context).pop())
34
- ),
35
- animation,
36
- Container(
37
- padding: EdgeInsets.only(left: 30, right: 30),
38
- child: Column(
39
- children: [
40
- Text(
41
- S.of(context).yat_alert_title,
42
- textAlign: TextAlign.center,
43
- style: Theme.of(context).textTheme.bodyMedium!.copyWith(
44
- fontSize: 24,
45
- fontWeight: FontWeight.bold,
46
-
28
+ content: Column(children: [
29
+ Container(
30
+ height: 45,
31
+ padding: EdgeInsets.only(left: 24, right: 24),
32
+ child: YatBar(onClose: () => Navigator.of(context).pop())),
33
+ animation,
34
+ Container(
35
+ padding: EdgeInsets.only(left: 30, right: 30),
36
+ child: Column(children: [
37
+ Text(S.of(context).yat_alert_title,
38
+ textAlign: TextAlign.center,
39
+ style: Theme.of(context).textTheme.bodyMedium!.copyWith(
40
+ fontSize: 24,
41
+ fontWeight: FontWeight.bold,
42
+ color: Theme.of(context).colorScheme.onSurface,
43
+ decoration: TextDecoration.none,
44
+ )),
45
+ Padding(
46
+ padding: EdgeInsets.only(top: 20),
47
+ child: Text(S.of(context).yat_alert_content,
48
+ textAlign: TextAlign.center,
49
+ style: Theme.of(context).textTheme.bodyMedium!.copyWith(
50
+ fontSize: 16,
51
+ fontWeight: FontWeight.normal,
52
color: Theme.of(context).colorScheme.onSurface,
53
decoration: TextDecoration.none,
49
- )
50
- ),
51
- Padding(
52
- padding: EdgeInsets.only(top: 20),
53
- child: Text(
54
- S.of(context).yat_alert_content,
55
- textAlign: TextAlign.center,
56
- style: Theme.of(context).textTheme.bodyMedium!.copyWith(
57
- fontSize: 16,
58
- fontWeight: FontWeight.normal,
59
-
60
- color: Theme.of(context).colorScheme.onSurface,
61
- decoration: TextDecoration.none,
62
- )
63
- )
64
- )
65
- ]
66
- )
67
- )
68
- ]
69
- ),
54
+ )))
55
+ ]))
56
+ ]),
57
bottomSectionPadding: EdgeInsets.fromLTRB(24, 0, 24, 24),
71
- bottomSection: Column(
72
- crossAxisAlignment: CrossAxisAlignment.center,
73
- children: [
74
- PrimaryButton(
75
- text: S.of(context).restore_next,
76
- textColor: Theme.of(context).colorScheme.onPrimary,
77
- color: Theme.of(context).colorScheme.primary,
78
- onPressed: onNext
79
- ),
80
- Padding(
81
- padding: EdgeInsets.only(top: 24),
82
- child: YatPageIndicator(filled: 0)
83
- )
84
- ]
85
- ),
86
- )
87
- );
58
+ bottomSection: Column(crossAxisAlignment: CrossAxisAlignment.center, children: [
59
+ PrimaryButton(
60
+ text: S.of(context).restore_next,
61
+ textColor: Theme.of(context).colorScheme.onPrimary,
62
+ color: Theme.of(context).colorScheme.primary,
63
+ onPressed: onNext),
64
+ Padding(padding: EdgeInsets.only(top: 24), child: YatPageIndicator(filled: 0))
65
+ ]),
66
+ ));
67
}
89
-}
\ No newline at end of file
68
+}
lib/src/screens/yat/widgets/second_introduction.dart
+23
-41
@@ -29,60 +29,42 @@ class SecondIntroduction extends StatelessWidget {
29
Container(
30
height: 45,
31
padding: EdgeInsets.only(left: 24, right: 24),
32
- child: YatBar(onClose: onClose)
33
- ),
32
+ child: YatBar(onClose: onClose)),
33
animation,
34
Padding(
35
padding: EdgeInsets.only(top: 40, left: 30, right: 30),
37
- child: Column(
38
- children: [
39
- Text(
40
- S.of(context).second_intro_title,
41
- textAlign: TextAlign.center,
42
- style: Theme.of(context).textTheme.bodyMedium!.copyWith(
36
+ child: Column(children: [
37
+ Text(S.of(context).second_intro_title,
38
+ textAlign: TextAlign.center,
39
+ style: Theme.of(context).textTheme.bodyMedium!.copyWith(
40
fontSize: 24,
41
fontWeight: FontWeight.bold,
45
-
42
color: Theme.of(context).colorScheme.onSurface,
43
decoration: TextDecoration.none,
48
- )
49
- ),
50
- Padding(
51
- padding: EdgeInsets.only(top: 20),
52
- child: Text(
53
- S.of(context).second_intro_content,
54
- textAlign: TextAlign.center,
55
- style: Theme.of(context).textTheme.bodyMedium!.copyWith(
44
+ )),
45
+ Padding(
46
+ padding: EdgeInsets.only(top: 20),
47
+ child: Text(S.of(context).second_intro_content,
48
+ textAlign: TextAlign.center,
49
+ style: Theme.of(context).textTheme.bodyMedium!.copyWith(
50
fontSize: 16,
51
fontWeight: FontWeight.normal,
58
-
52
color: Theme.of(context).colorScheme.onSurface,
53
decoration: TextDecoration.none,
61
- )
62
- )
63
- )
64
- ]
65
- ),
54
+ )))
55
+ ]),
56
),
57
],
58
),
59
bottomSectionPadding: EdgeInsets.fromLTRB(24, 0, 24, 24),
70
- bottomSection: Column(
71
- crossAxisAlignment: CrossAxisAlignment.center,
72
- children: [
73
- PrimaryButton(
74
- text: S.of(context).restore_next,
75
- textColor: Theme.of(context).colorScheme.onPrimary,
76
- color: Theme.of(context).colorScheme.primary,
77
- onPressed: onNext
78
- ),
79
- Padding(
80
- padding: EdgeInsets.only(top: 24),
81
- child: YatPageIndicator(filled: 1)
82
- )
83
- ]
84
- ),
85
- )
86
- );
60
+ bottomSection: Column(crossAxisAlignment: CrossAxisAlignment.center, children: [
61
+ PrimaryButton(
62
+ text: S.of(context).restore_next,
63
+ textColor: Theme.of(context).colorScheme.onPrimary,
64
+ color: Theme.of(context).colorScheme.primary,
65
+ onPressed: onNext),
66
+ Padding(padding: EdgeInsets.only(top: 24), child: YatPageIndicator(filled: 1))
67
+ ]),
68
+ ));
69
}
88
-}
\ No newline at end of file
70
+}
lib/src/screens/yat/widgets/third_introduction.dart
+10
-12
@@ -39,23 +39,21 @@ class ThirdIntroduction extends StatelessWidget {
39
Text(S.of(context).third_intro_title,
40
textAlign: TextAlign.center,
41
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
42
- fontSize: 24,
43
- fontWeight: FontWeight.bold,
44
-
45
- color: Theme.of(context).colorScheme.onSurface,
46
- decoration: TextDecoration.none,
47
- )),
42
+ fontSize: 24,
43
+ fontWeight: FontWeight.bold,
44
+ color: Theme.of(context).colorScheme.onSurface,
45
+ decoration: TextDecoration.none,
46
+ )),
47
Padding(
48
padding: EdgeInsets.only(top: 20),
49
child: Text(S.of(context).third_intro_content,
50
textAlign: TextAlign.center,
51
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
53
- fontSize: 16,
54
- fontWeight: FontWeight.normal,
55
-
56
- color: Theme.of(context).colorScheme.onSurface,
57
- decoration: TextDecoration.none,
58
- )))
52
+ fontSize: 16,
53
+ fontWeight: FontWeight.normal,
54
+ color: Theme.of(context).colorScheme.onSurface,
55
+ decoration: TextDecoration.none,
56
+ )))
57
])),
58
],
59
),
lib/src/screens/yat/widgets/yat_bar.dart
+5
-15
@@ -9,19 +9,9 @@ class YatBar extends StatelessWidget {
9
10
@override
11
Widget build(BuildContext context) {
12
- return Stack(
13
- alignment: Alignment.bottomCenter,
14
- children: [
15
- Positioned(
16
- top: 0,
17
- right: 0,
18
- child: YatCloseButton(onClose: onClose)
19
- ),
20
- Positioned(
21
- top: 16,
22
- child: image
23
- )
24
- ]
25
- );
12
+ return Stack(alignment: Alignment.bottomCenter, children: [
13
+ Positioned(top: 0, right: 0, child: YatCloseButton(onClose: onClose)),
14
+ Positioned(top: 16, child: image)
15
+ ]);
16
}
27
-}
\ No newline at end of file
17
+}
lib/src/screens/yat/widgets/yat_page_indicator.dart
+3
-7
@@ -22,11 +22,7 @@ class YatPageIndicator extends StatelessWidget {
22
shape: BoxShape.circle,
23
color: isFilled
24
? Theme.of(context).colorScheme.primary
25
- : Theme.of(context).colorScheme.onSurfaceVariant.withOpacity(0.1)
26
- )
27
- );
28
- })
29
- )
30
- );
25
+ : Theme.of(context).colorScheme.onSurfaceVariant.withOpacity(0.1)));
26
+ })));
27
}
32
-}
\ No newline at end of file
28
+}
lib/src/widgets/adaptable_page_view.dart
+1
-2
@@ -156,7 +156,6 @@ class _RenderSizingContainer extends RenderProxyBox {
156
final double t = (page - floorPage).clamp(0.0, 1.0);
157
final double height = lerpDouble(a.height, b.height, t) ?? a.height;
158
159
-
159
child.layout(
160
constraints.copyWith(minHeight: height, maxHeight: height),
161
parentUsesSize: true,
@@ -214,4 +213,4 @@ class _RenderSizeAware extends RenderProxyBox {
213
),
214
);
215
}
217
-}
\ No newline at end of file
216
+}
lib/src/widgets/alert_with_picker_option.dart
-1
@@ -48,7 +48,6 @@ class AlertWithPickerOption extends BaseAlertDialog {
48
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
49
fontSize: 10,
50
fontWeight: FontWeight.w500,
51
-
51
color: Theme.of(context).colorScheme.onSurface,
52
decoration: TextDecoration.none,
53
),
lib/src/widgets/base_alert_dialog.dart
+45
-52
@@ -5,36 +5,30 @@ import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
5
import 'package:cake_wallet/src/widgets/section_divider.dart';
6
import 'package:flutter/material.dart';
7
8
-
8
class AlertButtonStyle {
9
final Color backgroundColor;
10
final Color textColor;
11
final FontWeight fontWeight;
12
14
- const AlertButtonStyle({
15
- required this.backgroundColor,
16
- required this.textColor,
17
- this.fontWeight = FontWeight.w400
18
- });
13
+ const AlertButtonStyle(
14
+ {required this.backgroundColor, required this.textColor, this.fontWeight = FontWeight.w400});
15
16
factory AlertButtonStyle.primary(BuildContext context) => AlertButtonStyle(
21
- backgroundColor: Theme.of(context).colorScheme.primary,
22
- textColor: Theme.of(context).colorScheme.onPrimary,
23
- );
17
+ backgroundColor: Theme.of(context).colorScheme.primary,
18
+ textColor: Theme.of(context).colorScheme.onPrimary,
19
+ );
20
21
factory AlertButtonStyle.secondary(BuildContext context) => AlertButtonStyle(
26
- backgroundColor: Theme.of(context).colorScheme.surfaceContainer,
27
- textColor: Theme.of(context).colorScheme.primary,
28
- );
22
+ backgroundColor: Theme.of(context).colorScheme.surfaceContainer,
23
+ textColor: Theme.of(context).colorScheme.primary,
24
+ );
25
26
factory AlertButtonStyle.error(BuildContext context) => AlertButtonStyle(
31
- backgroundColor: Theme.of(context).colorScheme.errorContainer,
32
- textColor: Theme.of(context).colorScheme.error,
33
- fontWeight: FontWeight.w500
34
- );
27
+ backgroundColor: Theme.of(context).colorScheme.errorContainer,
28
+ textColor: Theme.of(context).colorScheme.error,
29
+ fontWeight: FontWeight.w500);
30
}
31
37
-
32
class BaseAlertDialog extends StatelessWidget {
33
String? get headerText => '';
34
@@ -67,7 +61,7 @@ class BaseAlertDialog extends StatelessWidget {
61
Key? rightActionButtonKey;
62
63
Key? dialogKey;
70
-
64
+
65
AlertButtonStyle? get leftAlertButtonStyle => null;
66
67
AlertButtonStyle? get rightAlertButtonStyle => null;
@@ -129,29 +123,30 @@ class BaseAlertDialog extends StatelessWidget {
123
return Row(
124
mainAxisAlignment: MainAxisAlignment.center,
125
mainAxisSize: MainAxisSize.max,
132
- spacing:8,
126
+ spacing: 8,
127
children: <Widget>[
134
- if(showLeftButton)
135
- Expanded(
136
- child: GestureDetector(
137
- key: leftActionButtonKey,
138
- onTap: actionLeft,
139
- child: Container(
140
- decoration: BoxDecoration(
141
- borderRadius: BorderRadius.circular(999999),
142
- color: leftButtonStyle.backgroundColor
143
- ),
144
- child: Padding(
145
- padding: EdgeInsets.symmetric(vertical: 16, horizontal: 8),
146
- child: AutoSizeText(
147
- maxLines:1,
148
- leftActionButtonText,
149
- textAlign: TextAlign.center,
150
- style: TextStyle(fontSize: 16, color: leftButtonStyle.textColor, fontWeight: leftButtonStyle.fontWeight)
128
+ if (showLeftButton)
129
+ Expanded(
130
+ child: GestureDetector(
131
+ key: leftActionButtonKey,
132
+ onTap: actionLeft,
133
+ child: Container(
134
+ decoration: BoxDecoration(
135
+ borderRadius: BorderRadius.circular(999999),
136
+ color: leftButtonStyle.backgroundColor),
137
+ child: Padding(
138
+ padding: EdgeInsets.symmetric(vertical: 16, horizontal: 8),
139
+ child: AutoSizeText(
140
+ maxLines: 1,
141
+ leftActionButtonText,
142
+ textAlign: TextAlign.center,
143
+ style: TextStyle(
144
+ fontSize: 16,
145
+ color: leftButtonStyle.textColor,
146
+ fontWeight: leftButtonStyle.fontWeight)),
147
),
152
- ),
153
- )),
154
- ),
148
+ )),
149
+ ),
150
Expanded(
151
child: GestureDetector(
152
key: rightActionButtonKey,
@@ -159,16 +154,17 @@ class BaseAlertDialog extends StatelessWidget {
154
child: Container(
155
decoration: BoxDecoration(
156
borderRadius: BorderRadius.circular(999999),
162
- color: rightButtonStyle.backgroundColor
163
- ),
157
+ color: rightButtonStyle.backgroundColor),
158
child: Padding(
159
padding: EdgeInsets.symmetric(vertical: 16, horizontal: 8),
160
child: AutoSizeText(
167
- maxLines: 1,
168
- rightActionButtonText,
169
- textAlign: TextAlign.center,
170
- style: TextStyle(fontSize: 16, color: rightButtonStyle.textColor, fontWeight: rightButtonStyle.fontWeight)
171
- ),
161
+ maxLines: 1,
162
+ rightActionButtonText,
163
+ textAlign: TextAlign.center,
164
+ style: TextStyle(
165
+ fontSize: 16,
166
+ color: rightButtonStyle.textColor,
167
+ fontWeight: rightButtonStyle.fontWeight)),
168
),
169
)),
170
),
@@ -185,7 +181,7 @@ class BaseAlertDialog extends StatelessWidget {
181
radius: 50,
182
backgroundColor: Theme.of(context).colorScheme.surfaceContainerHighest,
183
child: ClipOval(
188
- child: CakeImageWidget (imageUrl: imageUrl, width: 100, height: 100, fit: BoxFit.cover),
184
+ child: CakeImageWidget(imageUrl: imageUrl, width: 100, height: 100, fit: BoxFit.cover),
185
),
186
),
187
);
@@ -201,8 +197,7 @@ class BaseAlertDialog extends StatelessWidget {
197
child: BackdropFilter(
198
filter: ImageFilter.blur(sigmaX: 3.0, sigmaY: 3.0),
199
child: Container(
204
- decoration:
205
- BoxDecoration(color: Theme.of(context).colorScheme.onSurface.withAlpha(25)),
200
+ decoration: BoxDecoration(color: Theme.of(context).colorScheme.onSurface.withAlpha(25)),
201
child: Center(
202
child: Padding(
203
padding: const EdgeInsets.all(16.0),
@@ -229,9 +224,7 @@ class BaseAlertDialog extends StatelessWidget {
224
crossAxisAlignment: CrossAxisAlignment.center,
225
children: <Widget>[
226
if (headerText?.isNotEmpty ?? false) headerTitle(context),
232
- titleText != null
233
- ? title(context)
234
- : SizedBox(height: 16),
227
+ titleText != null ? title(context) : SizedBox(height: 16),
228
isDividerExists
229
? Padding(
230
padding: EdgeInsets.only(top: 16, bottom: 8),
lib/src/widgets/base_text_form_field.dart
+2
-1
@@ -47,7 +47,8 @@ class BaseTextFormField extends StatelessWidget {
47
this.suffixIconConstraints,
48
super.key,
49
this.suffixText,
50
- this.borderRadius = const BorderRadius.all(Radius.circular(18)), this.onEditingComplete,
50
+ this.borderRadius = const BorderRadius.all(Radius.circular(18)),
51
+ this.onEditingComplete,
52
});
53
54
final TextEditingController? controller;
lib/src/widgets/blockchain_height_widget.dart
+1
-1
@@ -195,7 +195,7 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
195
height = decred!.heightByDate(date);
196
} else if (widget.walletType == WalletType.monero) {
197
height = monero!.getHeightByDate(date: date);
198
- } else if (widget.walletType == WalletType.wownero){
198
+ } else if (widget.walletType == WalletType.wownero) {
199
height = wownero!.getHeightByDate(date: date);
200
} else if (widget.walletType == WalletType.zcash) {
201
height = await zcash!.getHeightByDate(date);
lib/src/widgets/bottom_sheet/cake_pay_transaction_sent_bottom_sheet.dart
+6
-15
@@ -49,8 +49,7 @@ class CakePayTransactionSentBottomSheet extends StatelessWidget {
49
color: Theme.of(ctx).colorScheme.onSurfaceVariant,
50
);
51
52
- Widget _buildHeader(BuildContext ctx) =>
53
- Column(
52
+ Widget _buildHeader(BuildContext ctx) => Column(
53
children: [
54
const SizedBox(height: 12),
55
Container(
@@ -81,8 +80,7 @@ class CakePayTransactionSentBottomSheet extends StatelessWidget {
80
],
81
);
82
84
- Widget _buildBody(BuildContext context) =>
85
- Padding(
83
+ Widget _buildBody(BuildContext context) => Padding(
84
padding: const EdgeInsets.symmetric(horizontal: 8),
85
child: Column(
86
children: [
@@ -123,7 +121,6 @@ class CakePayTransactionSentBottomSheet extends StatelessWidget {
121
copyButtonOnPressed: () async =>
122
await Clipboard.setData(ClipboardData(text: paymentIdValue)),
123
),
126
-
124
Padding(
125
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
126
child: Column(
@@ -157,10 +154,7 @@ class CakePayTransactionSentBottomSheet extends StatelessWidget {
154
return ClipRRect(
155
borderRadius: const BorderRadius.vertical(top: Radius.circular(30)),
156
child: Material(
160
- color: Theme
161
- .of(context)
162
- .colorScheme
163
- .surface,
157
+ color: Theme.of(context).colorScheme.surface,
158
child: ConstrainedBox(
159
constraints: BoxConstraints(maxHeight: maxHeight),
160
child: SingleChildScrollView(
@@ -210,17 +204,14 @@ class _StandardTile extends StatelessWidget {
204
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
205
decoration: BoxDecoration(
206
borderRadius: BorderRadius.circular(10),
213
- color: Theme
214
- .of(context)
215
- .colorScheme
216
- .surfaceContainerLowest
217
- .withAlpha(80)),
207
+ color: Theme.of(context).colorScheme.surfaceContainerLowest.withAlpha(80)),
208
child: Row(
209
mainAxisAlignment: MainAxisAlignment.spaceBetween,
210
children: [
211
Expanded(
212
child: Row(
223
- mainAxisAlignment: copyButton ? MainAxisAlignment.spaceBetween : MainAxisAlignment.start,
213
+ mainAxisAlignment:
214
+ copyButton ? MainAxisAlignment.spaceBetween : MainAxisAlignment.start,
215
children: [
216
if (imagePath != null)
217
Padding(
lib/src/widgets/bottom_sheet/confirm_sending_bottom_sheet_widget.dart
+2
-1
@@ -168,7 +168,8 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet {
168
final batchContactTitle =
169
'${index + 1}/${outputs.length} - ${contactName.isEmpty ? 'Address' : contactName}';
170
final _address = item.isParsedAddress ? item.extractedAddress : item.address;
171
- final _amount = '${item.cryptoAmount.sanitized()} ${amountParsingProxy?.getCryptoSymbol(currency) ?? currency.title}';
171
+ final _amount =
172
+ '${item.cryptoAmount.sanitized()} ${amountParsingProxy?.getCryptoSymbol(currency) ?? currency.title}';
173
return isBatchSending || (contactName.isNotEmpty && !isCakePayName)
174
? ExpansionAddressTile(
175
contactType: isOpenCryptoPay ? 'Open CryptoPay' : S.of(context).contact,
lib/src/widgets/bottom_sheet/info_bottom_sheet_widget.dart
+3
-1
@@ -100,7 +100,9 @@ class InfoBottomSheet extends BaseBottomSheet {
100
)
101
else
102
Container(),
103
- SizedBox(height: 24,),
103
+ SizedBox(
104
+ height: 24,
105
+ ),
106
if (content != null)
107
Expanded(
108
flex: 2,
lib/src/widgets/bottom_sheet/info_steps_bottom_sheet_widget.dart
+11
-11
@@ -34,7 +34,7 @@ class InfoStepsBottomSheet extends BaseBottomSheet {
34
),
35
child: SingleChildScrollView(
36
child: Column(
37
- children: [
37
+ children: [
38
Padding(
39
padding: const EdgeInsets.symmetric(horizontal: 28.0),
40
child: Column(
@@ -96,18 +96,18 @@ class InfoStepsBottomSheet extends BaseBottomSheet {
96
))
97
.toList(),
98
),
99
- ),
100
- Padding(
101
- padding: const EdgeInsets.all(16),
102
- child: PrimaryButton(
103
- text: S.of(context).close,
104
- color: context.currentTheme.colorScheme.primary,
99
+ ),
100
+ Padding(
101
+ padding: const EdgeInsets.all(16),
102
+ child: PrimaryButton(
103
+ text: S.of(context).close,
104
+ color: context.currentTheme.colorScheme.primary,
105
textColor: context.currentTheme.colorScheme.onPrimary,
106
onPressed: () => Navigator.of(context).pop(),
107
- ),
108
- )
109
- ],
110
- ),
107
+ ),
108
+ )
109
+ ],
110
+ ),
111
),
112
),
113
);
lib/src/widgets/bottom_sheet/payment_confirmation_bottom_sheet.dart
+1
-2
@@ -139,8 +139,7 @@ class _PaymentConfirmationContent extends StatelessWidget {
139
clipBehavior: Clip.none,
140
children: [
141
Image.asset(
142
- paymentFlowResult.addressDetectionResult?.detectedCurrency?.iconPath ??
143
- '',
142
+ paymentFlowResult.addressDetectionResult?.detectedCurrency?.iconPath ?? '',
143
width: 70,
144
height: 70,
145
errorBuilder: (context, error, stackTrace) => Icon(
lib/src/widgets/bottom_sheet/swap_confirmation_bottom_sheet.dart
+2
-1
@@ -288,7 +288,8 @@ class SwapConfirmationContentState extends State<SwapConfirmationContent> {
288
SwapConfirmationTextfield(
289
key: ValueKey('swap_confirmation_bottomsheet_address_textfield_key'),
290
isAddress: true,
291
- walletType: cryptoCurrencyOrTokenToWalletType(widget.exchangeViewModel.receiveCurrency),
291
+ walletType:
292
+ cryptoCurrencyOrTokenToWalletType(widget.exchangeViewModel.receiveCurrency),
293
hintText: 'Destination Address',
294
focusNode: _addressFocus,
295
controller: _addressController,
lib/src/widgets/bottom_sheet/swap_details_bottom_sheet.dart
+5
-6
@@ -112,7 +112,7 @@ class _SwapDetailsBottomSheetState extends State<SwapDetailsBottomSheet> {
112
buttonAction: () {
113
_showingFailureDialog = false;
114
Navigator.of(popupContext).pop();
115
- if(mounted) {
115
+ if (mounted) {
116
Navigator.of(context, rootNavigator: true).pop();
117
}
118
},
@@ -318,15 +318,13 @@ class _SwapDetailsContent extends StatelessWidget {
318
children: [
319
_SwapDetailsTile(
320
label: 'You Send',
321
- value:
322
- '${trade.amount} ${trade.from?.title ?? ''}',
321
+ value: '${trade.amount} ${trade.from?.title ?? ''}',
322
valueFiatFormatted: exchangeTradeViewModel.sendAmountFiatFormatted,
323
),
324
const SizedBox(height: 8),
325
_SwapDetailsTile(
326
label: 'You Get',
328
- value:
329
- '${trade.receiveAmount ?? '0'} ${trade.to?.title ?? ''}',
327
+ value: '${trade.receiveAmount ?? '0'} ${trade.to?.title ?? ''}',
328
valueFiatFormatted: exchangeTradeViewModel
329
.getReceiveAmountFiatFormatted(trade.receiveAmount ?? '0.0'),
330
),
@@ -351,7 +349,8 @@ class _SwapDetailsContent extends StatelessWidget {
349
const SizedBox(height: 4),
350
AddressFormatter.buildSegmentedAddress(
351
address: trade.payoutAddress ?? '',
354
- walletType: trade.to != null ? cryptoCurrencyOrTokenToWalletType(trade.to!) : null,
352
+ walletType:
353
+ trade.to != null ? cryptoCurrencyOrTokenToWalletType(trade.to!) : null,
354
evenTextStyle: Theme.of(context)
355
.textTheme
356
.bodyMedium!
lib/src/widgets/bottom_sheet/token_selection_bottom_sheet.dart
+8
-5
@@ -78,7 +78,8 @@ class _TokenSelectionContentState extends State<_TokenSelectionContent> {
78
void initState() {
79
super.initState();
80
final baseNetwork = widget.fixedNetwork ?? WalletType.ethereum;
81
- selectedNetwork = _resolveGenericETHDetectionResultToSpecificChain(baseNetwork, widget.paymentRequest.scheme.isNotEmpty);
81
+ selectedNetwork = _resolveGenericETHDetectionResultToSpecificChain(
82
+ baseNetwork, widget.paymentRequest.scheme.isNotEmpty);
83
_autoSelectToken();
84
}
85
@@ -101,9 +102,10 @@ class _TokenSelectionContentState extends State<_TokenSelectionContent> {
102
return null;
103
}
104
104
- WalletType _resolveGenericETHDetectionResultToSpecificChain(WalletType network, bool hasURIScheme) {
105
- if(hasURIScheme || network != WalletType.ethereum) return network;
106
-
105
+ WalletType _resolveGenericETHDetectionResultToSpecificChain(
106
+ WalletType network, bool hasURIScheme) {
107
+ if (hasURIScheme || network != WalletType.ethereum) return network;
108
+
109
final current = widget.paymentViewModel.currentWalletType;
110
if (isEVMCompatibleChain(current)) return current;
111
return network;
@@ -113,7 +115,8 @@ class _TokenSelectionContentState extends State<_TokenSelectionContent> {
115
final initialNetwork = selectedNetwork;
116
if (initialNetwork == null || !mounted) return;
117
116
- final network = _resolveGenericETHDetectionResultToSpecificChain(initialNetwork, widget.paymentRequest.scheme.isNotEmpty);
118
+ final network = _resolveGenericETHDetectionResultToSpecificChain(
119
+ initialNetwork, widget.paymentRequest.scheme.isNotEmpty);
120
121
setState(() {
122
selectedNetwork = network;
lib/src/widgets/check_box_picker.dart
+5
-6
@@ -40,12 +40,11 @@ class CheckBoxPickerState extends State<CheckBoxPicker> {
40
widget.title,
41
textAlign: TextAlign.center,
42
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
43
- fontSize: 18,
44
-
45
- fontWeight: FontWeight.bold,
46
- decoration: TextDecoration.none,
47
- color: Theme.of(context).colorScheme.onSurface,
48
- ),
43
+ fontSize: 18,
44
+ fontWeight: FontWeight.bold,
45
+ decoration: TextDecoration.none,
46
+ color: Theme.of(context).colorScheme.onSurface,
47
+ ),
48
),
49
),
50
Padding(
lib/src/widgets/checkbox_widget.dart
+1
@@ -1,4 +1,5 @@
1
import 'package:flutter/material.dart';
2
+
3
class CheckboxWidget extends StatefulWidget {
4
CheckboxWidget({required this.value, required this.caption, required this.onChanged});
5
lib/src/widgets/evm_switcher.dart
+1
-2
@@ -83,8 +83,7 @@ class _EvmSwitcherState extends State<EvmSwitcher> {
83
.toList(growable: false);
84
}
85
86
- bool _hiddenSetsEqual(Set<int> a, Set<int> b) =>
87
- a.length == b.length && a.containsAll(b);
86
+ bool _hiddenSetsEqual(Set<int> a, Set<int> b) => a.length == b.length && a.containsAll(b);
87
88
int get _selectedIndex {
89
if (widget.currentChain == null) return -1;
lib/src/widgets/haven_wallet_removal_popup.dart
+9
-11
@@ -36,12 +36,11 @@ class HavenWalletRemovalPopup extends StatelessWidget {
36
alignment: Alignment.bottomCenter,
37
child: DefaultTextStyle(
38
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
39
- decoration: TextDecoration.none,
40
- fontSize: 24.0,
41
- fontWeight: FontWeight.bold,
42
-
43
- color: Theme.of(context).colorScheme.onSurfaceVariant,
44
- ),
39
+ decoration: TextDecoration.none,
40
+ fontSize: 24.0,
41
+ fontWeight: FontWeight.bold,
42
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
43
+ ),
44
child: Text("Emergency Notice"),
45
),
46
),
@@ -61,11 +60,10 @@ class HavenWalletRemovalPopup extends StatelessWidget {
60
child: Text(
61
"It looks like you have Haven wallets in your list. Haven is getting removed in next release of Cake Wallet, and you currently have Haven in the following wallets:\n\n[${affectedWalletNames.join(", ")}]\n\nPlease move your funds to other wallet, as you will lose access to your Haven funds in next update.\n\nFor assistance, please use the in-app support or email support@cakewallet.com",
62
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
64
- decoration: TextDecoration.none,
65
- fontSize: 16.0,
66
-
67
- color: Theme.of(context).colorScheme.onSurfaceVariant,
68
- ),
63
+ decoration: TextDecoration.none,
64
+ fontSize: 16.0,
65
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
66
+ ),
67
),
68
)
69
],
lib/src/widgets/index.dart
+1
@@ -0,0 +1 @@
1
+
lib/src/widgets/new_list_row/list_Item_style_wrapper.dart
+21
-19
@@ -45,26 +45,28 @@ class ListItemStyleWrapper extends StatelessWidget {
45
bottom: Radius.circular(isLastInSection ? 18 : 0),
46
);
47
48
- return ClipRSuperellipse(
49
- borderRadius: radius,
50
- child: Column(
51
- children: [
52
- Container(
53
- height: height,
54
- decoration: ShapeDecoration(
55
- shape: RoundedSuperellipseBorder(
56
- borderRadius: radius,
57
- ),
58
- color: backgroundColor ?? theme.colorScheme.surfaceContainer,
48
+ return ClipRSuperellipse(
49
+ borderRadius: radius,
50
+ child: Column(
51
+ children: [
52
+ Container(
53
+ height: height,
54
+ decoration: ShapeDecoration(
55
+ shape: RoundedSuperellipseBorder(
56
+ borderRadius: radius,
57
),
60
- child: Material(
61
- color: Colors.transparent,
62
- child: InkWell(
63
- onTap: onTap,
64
- child: Padding(
65
- padding: EdgeInsets.symmetric(horizontal: 12, vertical: height == null ? 11 : 0),
66
- child: builder(context, textStyle, labelStyle))))),
67
- if(iconPath != null && isLastInSection == false) Container(
58
+ color: backgroundColor ?? theme.colorScheme.surfaceContainer,
59
+ ),
60
+ child: Material(
61
+ color: Colors.transparent,
62
+ child: InkWell(
63
+ onTap: onTap,
64
+ child: Padding(
65
+ padding: EdgeInsets.symmetric(
66
+ horizontal: 12, vertical: height == null ? 11 : 0),
67
+ child: builder(context, textStyle, labelStyle))))),
68
+ if (iconPath != null && isLastInSection == false)
69
+ Container(
70
color: theme.colorScheme.surfaceContainer,
71
child: Padding(
72
padding: const EdgeInsets.only(left: 50, right: 13),
lib/src/widgets/new_list_row/list_item_checkbox_widget.dart
+34
-30
@@ -14,7 +14,10 @@ class ListItemCheckboxWidget extends StatefulWidget {
14
this.subtitleColor,
15
this.onTap,
16
this.isFirstInSection = false,
17
- this.isLastInSection = false, this.subtitle, this.iconPath, this.showArrow = false,
17
+ this.isLastInSection = false,
18
+ this.subtitle,
19
+ this.iconPath,
20
+ this.showArrow = false,
21
});
22
23
final String keyValue;
@@ -34,15 +37,14 @@ class ListItemCheckboxWidget extends StatefulWidget {
37
}
38
39
class _ListItemCheckboxWidgetState extends State<ListItemCheckboxWidget> {
37
-
38
-
40
@override
41
Widget build(BuildContext context) {
42
return ListItemStyleWrapper(
43
iconPath: widget.iconPath,
43
- onTap: widget.onTap ?? () {
44
- widget.onChanged(!widget.value);
45
- },
44
+ onTap: widget.onTap ??
45
+ () {
46
+ widget.onChanged(!widget.value);
47
+ },
48
isFirstInSection: widget.isFirstInSection,
49
height: widget.subtitle != null ? 64 : 50,
50
isLastInSection: widget.isLastInSection,
@@ -56,7 +58,7 @@ class _ListItemCheckboxWidgetState extends State<ListItemCheckboxWidget> {
58
children: [
59
if (widget.iconPath != null)
60
widget.iconPath!.toLowerCase().endsWith("svg")
59
- ? CakeImageWidget(imageUrl:widget.iconPath!, height: 26, width: 26)
61
+ ? CakeImageWidget(imageUrl: widget.iconPath!, height: 26, width: 26)
62
: Image.asset(
63
widget.iconPath!,
64
width: 26,
@@ -64,29 +66,31 @@ class _ListItemCheckboxWidgetState extends State<ListItemCheckboxWidget> {
66
),
67
Expanded(
68
child: Column(
67
- mainAxisSize: MainAxisSize.max,
68
- crossAxisAlignment: CrossAxisAlignment.start,
69
- mainAxisAlignment: MainAxisAlignment.center,
70
- children: [
71
- Row(
72
- children: [
73
- Flexible(child: Text(widget.label)),
74
- if (widget.showArrow)
75
- Icon(
76
- Icons.chevron_right,
77
- size: 18,
78
- color: Theme.of(context).colorScheme.onSurfaceVariant,
79
- )
80
- ],
81
- ),
82
- if (widget.subtitle != null)
83
- Text(
84
- widget.subtitle!,
85
- style: TextStyle(
86
- fontSize: 12, color: widget.subtitleColor ?? Theme.of(context).colorScheme.onSurfaceVariant),
87
- )
88
- ],
89
- ),
69
+ mainAxisSize: MainAxisSize.max,
70
+ crossAxisAlignment: CrossAxisAlignment.start,
71
+ mainAxisAlignment: MainAxisAlignment.center,
72
+ children: [
73
+ Row(
74
+ children: [
75
+ Flexible(child: Text(widget.label)),
76
+ if (widget.showArrow)
77
+ Icon(
78
+ Icons.chevron_right,
79
+ size: 18,
80
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
81
+ )
82
+ ],
83
+ ),
84
+ if (widget.subtitle != null)
85
+ Text(
86
+ widget.subtitle!,
87
+ style: TextStyle(
88
+ fontSize: 12,
89
+ color: widget.subtitleColor ??
90
+ Theme.of(context).colorScheme.onSurfaceVariant),
91
+ )
92
+ ],
93
+ ),
94
),
95
],
96
),
lib/src/widgets/new_list_row/list_item_regular_row_widget.dart
+1
-1
@@ -85,7 +85,7 @@ class ListItemRegularRowWidget extends StatelessWidget {
85
86
final imageWidget = badgeIconPath != null
87
? Stack(
88
- clipBehavior: Clip.none,
88
+ clipBehavior: Clip.none,
89
children: [
90
leadingIcon!,
91
Positioned(
lib/src/widgets/new_list_row/list_item_selector_widget.dart
+7
-6
@@ -12,7 +12,8 @@ class ListItemSelectorWidget extends StatelessWidget {
12
required this.selectedIndex,
13
required this.onChanged,
14
this.isFirstInSection = false,
15
- this.isLastInSection = false, this.onTap,
15
+ this.isLastInSection = false,
16
+ this.onTap,
17
});
18
19
final String keyValue;
@@ -45,16 +46,16 @@ class ListItemSelectorWidget extends StatelessWidget {
46
options[selectedIndex],
47
style: labelStyle,
48
),
48
- CakeImageWidget(imageUrl:
49
- "assets/new-ui/chooser.svg",
49
+ CakeImageWidget(
50
+ imageUrl: "assets/new-ui/chooser.svg",
51
colorFilter:
51
- ColorFilter.mode(theme.colorScheme.onSurfaceVariant, BlendMode.srcIn),
52
+ ColorFilter.mode(theme.colorScheme.onSurfaceVariant, BlendMode.srcIn),
53
),
54
],
55
),
56
),
57
],
57
- );
58
+ );
59
});
60
}
60
-}
\ No newline at end of file
61
+}
lib/src/widgets/new_list_row/list_item_text_field_widget.dart
+2
-3
@@ -26,8 +26,7 @@ class ListItemTextFieldWidget extends StatefulWidget {
26
final bool isLastInSection;
27
28
@override
29
- State<ListItemTextFieldWidget> createState() =>
30
- _ListItemTextFieldWidgetState();
29
+ State<ListItemTextFieldWidget> createState() => _ListItemTextFieldWidgetState();
30
}
31
32
class _ListItemTextFieldWidgetState extends State<ListItemTextFieldWidget> {
@@ -36,7 +35,7 @@ class _ListItemTextFieldWidgetState extends State<ListItemTextFieldWidget> {
35
return ListItemStyleWrapper(
36
isFirstInSection: widget.isFirstInSection,
37
isLastInSection: widget.isLastInSection,
39
- height:50,
38
+ height: 50,
39
builder: (context, textStyle, labelStyle) {
40
return Row(
41
children: [
lib/src/widgets/new_list_row/list_item_toggle_widget.dart
+1
-2
@@ -27,7 +27,6 @@ class ListItemToggleWidget extends StatefulWidget {
27
}
28
29
class _ListItemToggleWidgetState extends State<ListItemToggleWidget> {
30
-
30
@override
31
void initState() {
32
super.initState();
@@ -52,7 +51,7 @@ class _ListItemToggleWidgetState extends State<ListItemToggleWidget> {
51
Flexible(
52
child: Text(widget.label, style: textStyle, softWrap: true),
53
),
55
- if(widget.leadingEndWidget != null) widget.leadingEndWidget!
54
+ if (widget.leadingEndWidget != null) widget.leadingEndWidget!
55
],
56
),
57
),
lib/src/widgets/new_list_row/new_list_section.dart
+8
-9
@@ -14,15 +14,14 @@ import 'package:cake_wallet/src/widgets/new_list_row/list_item_toggle_widget.dar
14
import 'package:flutter/material.dart';
15
16
class NewListSections extends StatelessWidget {
17
- const NewListSections({
18
- super.key,
19
- required this.sections,
20
- this.controllers = const {},
21
- this.tapHandlers = const {},
22
- this.getCheckboxValue,
23
- this.updateCheckboxValue,
24
- this.showHeader = false
25
- });
17
+ const NewListSections(
18
+ {super.key,
19
+ required this.sections,
20
+ this.controllers = const {},
21
+ this.tapHandlers = const {},
22
+ this.getCheckboxValue,
23
+ this.updateCheckboxValue,
24
+ this.showHeader = false});
25
26
final Map<String, List<ListItem>> sections;
27
final Map<String, TextEditingController> controllers;
lib/src/widgets/number_text_fild_widget.dart
+5
-5
@@ -56,7 +56,7 @@ class _NumberTextFieldState extends State<NumberTextField> {
56
57
@override
58
Widget build(BuildContext context) => TextField(
59
- style: Theme.of(context).textTheme.titleMedium!,
59
+ style: Theme.of(context).textTheme.titleMedium!,
60
enableInteractiveSelection: false,
61
textAlign: TextAlign.center,
62
textAlignVertical: TextAlignVertical.bottom,
@@ -78,16 +78,16 @@ class _NumberTextFieldState extends State<NumberTextField> {
78
type: MaterialType.transparency,
79
child: InkWell(
80
child: Container(
81
- width: widget.arrowsWidth,
81
+ width: widget.arrowsWidth,
82
alignment: Alignment.bottomCenter,
83
- child: Icon(Icons.keyboard_arrow_left_outlined ,size: widget.arrowsWidth)),
83
+ child: Icon(Icons.keyboard_arrow_left_outlined, size: widget.arrowsWidth)),
84
onTap: _canGoDown ? () => _update(false) : null)),
85
suffixIcon: Material(
86
type: MaterialType.transparency,
87
child: InkWell(
88
child: Container(
89
- width: widget.arrowsWidth,
90
- alignment: Alignment.bottomCenter,
89
+ width: widget.arrowsWidth,
90
+ alignment: Alignment.bottomCenter,
91
child: Icon(Icons.keyboard_arrow_right_outlined, size: widget.arrowsWidth)),
92
onTap: _canGoUp ? () => _update(true) : null))),
93
maxLines: 1,
lib/src/widgets/picker.dart
+2
-1
@@ -345,7 +345,8 @@ class _PickerState<Item> extends State<Picker<Item>> {
345
Flexible(
346
child: Text(
347
key: ValueKey('picker_items_index_${itemName}_text_key'),
348
- widget.displayItem?.call(item) ?? (item == CryptoCurrency.btcln ? "BTC (LN)" : item.toString()),
348
+ widget.displayItem?.call(item) ??
349
+ (item == CryptoCurrency.btcln ? "BTC (LN)" : item.toString()),
350
softWrap: true,
351
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
352
fontWeight: FontWeight.w600,
lib/src/widgets/picker_inner_wrapper_widget.dart
+4
-6
@@ -3,8 +3,7 @@ import 'package:cake_wallet/src/widgets/picker_wrapper_widget.dart';
3
import 'package:cake_wallet/utils/responsive_layout_util.dart';
4
5
class PickerInnerWrapperWidget extends StatelessWidget {
6
- PickerInnerWrapperWidget(
7
- {required this.children, this.title, this.itemsHeight});
6
+ PickerInnerWrapperWidget({required this.children, this.title, this.itemsHeight});
7
8
final List<Widget> children;
9
final String? title;
@@ -48,10 +47,9 @@ class PickerInnerWrapperWidget extends StatelessWidget {
47
color: Theme.of(context).colorScheme.surfaceContainerHighest,
48
child: ConstrainedBox(
49
constraints: BoxConstraints(
51
- maxHeight:
52
- itemsHeight != null && itemsHeight! <= containerHeight
53
- ? itemsHeight!
54
- : containerHeight,
50
+ maxHeight: itemsHeight != null && itemsHeight! <= containerHeight
51
+ ? itemsHeight!
52
+ : containerHeight,
53
maxWidth: ResponsiveLayoutUtilBase.kPopupWidth,
54
),
55
child: Column(
lib/src/widgets/provider_optoin_tile.dart
+2
-2
@@ -105,8 +105,8 @@ class ProviderOptionTile extends StatelessWidget {
105
children: [
106
Row(
107
children: [
108
- ImageUtil.getImageFromPath(imagePath:imagePath,
109
- height: imageHeight, width: imageWidth),
108
+ ImageUtil.getImageFromPath(
109
+ imagePath: imagePath, height: imageHeight, width: imageWidth),
110
SizedBox(width: 8),
111
Expanded(
112
child: Container(
lib/src/widgets/rounded_checkbox.dart
+14
-14
@@ -9,19 +9,19 @@ class RoundedCheckbox extends StatelessWidget {
9
10
@override
11
Widget build(BuildContext context) {
12
- return value
13
- ? Container(
14
- height: 20.0,
15
- width: 20.0,
16
- decoration: BoxDecoration(
17
- borderRadius: BorderRadius.all(Radius.circular(50.0)),
18
- color: Theme.of(context).colorScheme.primary,
19
- ),
20
- child: Icon(
21
- Icons.check,
22
- color: Theme.of(context).colorScheme.surface,
23
- size: 14.0,
24
- ))
25
- : Offstage();
12
+ return value
13
+ ? Container(
14
+ height: 20.0,
15
+ width: 20.0,
16
+ decoration: BoxDecoration(
17
+ borderRadius: BorderRadius.all(Radius.circular(50.0)),
18
+ color: Theme.of(context).colorScheme.primary,
19
+ ),
20
+ child: Icon(
21
+ Icons.check,
22
+ color: Theme.of(context).colorScheme.surface,
23
+ size: 14.0,
24
+ ))
25
+ : Offstage();
26
}
27
}
lib/src/widgets/rounded_icon_button.dart
+1
-1
@@ -27,7 +27,7 @@ class RoundedIconButton extends StatelessWidget {
27
onPressed: onPressed,
28
fillColor: fillColor ?? colorScheme.surfaceContainerHighest,
29
elevation: 0,
30
- constraints: BoxConstraints.tightFor(width: width ?? 30, height: height ?? 30),
30
+ constraints: BoxConstraints.tightFor(width: width ?? 30, height: height ?? 30),
31
padding: EdgeInsets.zero,
32
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
33
shape: shape ?? const CircleBorder(),
lib/src/widgets/scrollable_with_bottom_section.dart
+1
-1
@@ -52,4 +52,4 @@ class ScrollableWithBottomSectionState extends State<ScrollableWithBottomSection
52
],
53
);
54
}
55
-}
\ No newline at end of file
55
+}
lib/src/widgets/seed_widget.dart
+7
-6
@@ -105,11 +105,11 @@ class SeedWidgetState extends State<SeedWidget> {
105
cursorColor: Theme.of(context).colorScheme.primary,
106
backgroundCursorColor: Theme.of(context).colorScheme.primary,
107
validStyle: Theme.of(context).textTheme.bodyMedium!.copyWith(
108
- color: Theme.of(context).colorScheme.onSurfaceVariant,
109
- backgroundColor: Colors.transparent,
110
- fontWeight: FontWeight.normal,
111
- fontSize: 16,
112
- ),
108
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
109
+ backgroundColor: Colors.transparent,
110
+ fontWeight: FontWeight.normal,
111
+ fontSize: 16,
112
+ ),
113
invalidStyle: Theme.of(context).textTheme.bodyMedium!.copyWith(
114
color: Theme.of(context).colorScheme.errorContainer,
115
backgroundColor: Colors.transparent,
@@ -157,7 +157,8 @@ class SeedWidgetState extends State<SeedWidget> {
157
padding: EdgeInsets.all(6),
158
decoration: ShapeDecoration(
159
color: Theme.of(context).colorScheme.surface,
160
- shape: RoundedSuperellipseBorder(borderRadius: BorderRadius.circular(18)),
160
+ shape: RoundedSuperellipseBorder(
161
+ borderRadius: BorderRadius.circular(18)),
162
),
163
child: Image.asset(
164
'assets/images/paste_ios.png',
lib/src/widgets/seedphrase_grid_widget.dart
+2
-6
@@ -9,8 +9,6 @@ class SeedPhraseGridWidget extends StatelessWidget {
9
10
final List<String> list;
11
12
-
13
-
12
@override
13
Widget build(BuildContext context) {
14
int minTiles = 1;
@@ -23,7 +21,6 @@ class SeedPhraseGridWidget extends StatelessWidget {
21
int crossAxisCount =
22
((screenWidth + spacing - (2 * padding)) / (desiredTileWidth + spacing)).floor();
23
26
-
24
if (crossAxisCount > maxTiles) crossAxisCount = maxTiles;
25
if (crossAxisCount < minTiles) crossAxisCount = minTiles;
26
@@ -44,9 +41,8 @@ class SeedPhraseGridWidget extends StatelessWidget {
41
padding: const EdgeInsets.symmetric(horizontal: 8),
42
alignment: Alignment.center,
43
decoration: BoxDecoration(
47
- borderRadius: BorderRadius.circular(8),
48
- color: Theme.of(context).colorScheme.surfaceContainerHigh
49
- ),
44
+ borderRadius: BorderRadius.circular(8),
45
+ color: Theme.of(context).colorScheme.surfaceContainerHigh),
46
child: Row(
47
crossAxisAlignment: CrossAxisAlignment.center,
48
children: [
lib/src/widgets/simple_checkbox.dart
+3
-3
@@ -26,9 +26,9 @@ class _SimpleCheckboxState extends State<SimpleCheckbox> {
26
checkColor: Theme.of(context).textTheme.titleLarge!.color,
27
activeColor: Colors.transparent,
28
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
29
- side: WidgetStateBorderSide.resolveWith((states) => BorderSide(
30
- color: Theme.of(context).textTheme.titleLarge!.color!, width: 1.0)),
29
+ side: WidgetStateBorderSide.resolveWith((states) =>
30
+ BorderSide(color: Theme.of(context).textTheme.titleLarge!.color!, width: 1.0)),
31
),
32
);
33
}
34
-}
\ No newline at end of file
34
+}
lib/src/widgets/standard_checkbox.dart
+5
-6
@@ -66,12 +66,11 @@ class StandardCheckbox extends StatelessWidget {
66
caption,
67
softWrap: true,
68
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
69
- fontSize: 16.0,
70
-
71
- fontWeight: FontWeight.normal,
72
- color: captionColor ?? Theme.of(context).colorScheme.onSurface,
73
- decoration: TextDecoration.none,
74
- ),
69
+ fontSize: 16.0,
70
+ fontWeight: FontWeight.normal,
71
+ color: captionColor ?? Theme.of(context).colorScheme.onSurface,
72
+ decoration: TextDecoration.none,
73
+ ),
74
),
75
),
76
)
lib/src/widgets/standard_list.dart
+9
-10
@@ -50,7 +50,6 @@ class StandardListRow extends StatelessWidget {
50
Widget? buildLeading(BuildContext context) => null;
51
52
Widget buildCenter(BuildContext context, {required bool hasLeftOffset}) {
53
-
53
return Expanded(
54
child: Row(
55
mainAxisAlignment: MainAxisAlignment.start,
@@ -84,17 +83,17 @@ class StandardListRow extends StatelessWidget {
83
),
84
),
85
)
87
- else
88
- Align(
89
- alignment: Alignment.centerLeft,
90
- child: Text(
91
- title,
92
- style: Theme.of(context).textTheme.bodyMedium?.copyWith(
93
- color: titleColor(context),
94
- fontWeight: isSelected ? FontWeight.w800 : FontWeight.w400,
86
+ else
87
+ Align(
88
+ alignment: Alignment.centerLeft,
89
+ child: Text(
90
+ title,
91
+ style: Theme.of(context).textTheme.bodyMedium?.copyWith(
92
+ color: titleColor(context),
93
+ fontWeight: isSelected ? FontWeight.w800 : FontWeight.w400,
94
+ ),
95
),
96
),
97
- ),
97
],
98
),
99
)
lib/src/widgets/standard_list_status_row.dart
+3
-3
@@ -47,9 +47,9 @@ class StandardListStatusRow extends StatelessWidget {
47
Text(
48
value,
49
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
50
- fontSize: 16,
51
- fontWeight: FontWeight.w500,
52
- ),
50
+ fontSize: 16,
51
+ fontWeight: FontWeight.w500,
52
+ ),
53
)
54
],
55
),
lib/src/widgets/standard_slide_button_widget.dart
+3
-1
@@ -113,7 +113,9 @@ class StandardSlideButtonState extends State<StandardSlideButton> {
113
child: Icon(
114
key: ValueKey('standard_slide_button_widget_slider_icon_key'),
115
Icons.arrow_forward,
116
- color: widget.isDisabled ? Theme.of(context).colorScheme.onSurface.withOpacity(0.2) : Theme.of(context).colorScheme.onSurface,
116
+ color: widget.isDisabled
117
+ ? Theme.of(context).colorScheme.onSurface.withOpacity(0.2)
118
+ : Theme.of(context).colorScheme.onSurface,
119
),
120
),
121
),
lib/src/widgets/validable_annotated_editable_text.dart
+9
-10
@@ -65,7 +65,6 @@ class ValidatableAnnotatedEditableText extends EditableText {
65
backgroundCursorColor: backgroundCursorColor,
66
onChanged: onChanged,
67
onSubmitted: onSubmitted,
68
-
68
toolbarOptions: const ToolbarOptions(
69
copy: true,
70
cut: true,
@@ -120,17 +119,17 @@ class ValidatableAnnotatedEditableTextState extends EditableTextState {
119
annotation = Annotation(
120
range: TextRange(start: 0, end: item.range.start),
121
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
123
- color: Theme.of(context).colorScheme.onSurfaceVariant,
124
- backgroundColor: Colors.transparent,
125
- ),
122
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
123
+ backgroundColor: Colors.transparent,
124
+ ),
125
);
126
} else if (prev.range.end < item.range.start) {
127
annotation = Annotation(
128
range: TextRange(start: prev.range.end, end: item.range.start),
129
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
131
- color: Theme.of(context).colorScheme.onError,
132
- backgroundColor: Colors.transparent,
133
- ),
130
+ color: Theme.of(context).colorScheme.onError,
131
+ backgroundColor: Colors.transparent,
132
+ ),
133
);
134
}
135
@@ -146,9 +145,9 @@ class ValidatableAnnotatedEditableTextState extends EditableTextState {
145
Annotation(
146
range: TextRange(start: result.last.range.end, end: text.length),
147
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
149
- color: Theme.of(context).colorScheme.onSurfaceVariant,
150
- backgroundColor: Colors.transparent,
151
- ),
148
+ color: Theme.of(context).colorScheme.onSurfaceVariant,
149
+ backgroundColor: Colors.transparent,
150
+ ),
151
),
152
);
153
}
lib/src/widgets/vulnerable_seeds_popup.dart
+9
-12
@@ -36,12 +36,11 @@ class VulnerableSeedsPopup extends StatelessWidget {
36
alignment: Alignment.bottomCenter,
37
child: DefaultTextStyle(
38
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
39
- decoration: TextDecoration.none,
40
- fontSize: 24.0,
41
- fontWeight: FontWeight.bold,
42
-
43
- color: Theme.of(context).colorScheme.onSurface,
44
- ),
39
+ decoration: TextDecoration.none,
40
+ fontSize: 24.0,
41
+ fontWeight: FontWeight.bold,
42
+ color: Theme.of(context).colorScheme.onSurface,
43
+ ),
44
child: Text("Emergency Notice"),
45
),
46
),
@@ -61,12 +60,10 @@ class VulnerableSeedsPopup extends StatelessWidget {
60
child: Text(
61
"Your Bitcoin wallet(s) below use a legacy seed format that is vulnerable, which MAY result in you losing money from these wallet(s) if no action is taken.\nWe recommend that you IMMEDIATELY create wallet(s) in Cake Wallet and immediately transfer the funds to these wallet(s).\nVulnerable wallet name(s):\n\n[${affectedWalletNames.join(", ")}]\n\nFor assistance, please use the in-app support or email support@cakewallet.com",
62
style: Theme.of(context).textTheme.bodyMedium!.copyWith(
64
- decoration: TextDecoration.none,
65
- fontSize: 16.0,
66
-
67
- color: Theme.of(context)
68
- .colorScheme.onSurface,
69
- ),
63
+ decoration: TextDecoration.none,
64
+ fontSize: 16.0,
65
+ color: Theme.of(context).colorScheme.onSurface,
66
+ ),
67
),
68
)
69
],
lib/store/app_store.dart
-1
@@ -48,7 +48,6 @@ abstract class AppStoreBase with Store {
48
49
SettingsStore settingsStore;
50
51
-
51
ThemeStore themeStore;
52
53
@observable
lib/store/dashboard/order_filter_store.dart
+2
-3
@@ -30,8 +30,7 @@ abstract class OrderFilterStoreBase with Store {
30
required List<OrderListItem> orders,
31
required WalletBase wallet,
32
}) {
33
- final walletOrders =
34
- orders.where((item) => item.order.walletId == wallet.id).toList();
33
+ final walletOrders = orders.where((item) => item.order.walletId == wallet.id).toList();
34
35
final cakePayOrders = walletOrders.where((item) {
36
final order = item.order;
@@ -43,4 +42,4 @@ abstract class OrderFilterStoreBase with Store {
42
if (!displayCakePay) return <OrderListItem>[];
43
return cakePayOrders;
44
}
46
-}
\ No newline at end of file
45
+}
lib/store/dashboard/payjoin_transactions_store.dart
+1
-2
@@ -8,8 +8,7 @@ import 'package:mobx/mobx.dart';
8
9
part 'payjoin_transactions_store.g.dart';
10
11
-class PayjoinTransactionsStore = PayjoinTransactionsStoreBase
12
- with _$PayjoinTransactionsStore;
11
+class PayjoinTransactionsStore = PayjoinTransactionsStoreBase with _$PayjoinTransactionsStore;
12
13
abstract class PayjoinTransactionsStoreBase with Store {
14
PayjoinTransactionsStoreBase({
lib/store/dashboard/trade_filter_store.dart
+27
-25
@@ -71,20 +71,20 @@ abstract class TradeFilterStoreBase with Store {
71
72
@computed
73
int get enabledProvidersCount => [
74
- displayChangeNow,
75
- displaySideShift,
76
- displaySimpleSwap,
77
- displayTrocador,
78
- displayExolix,
79
- displayChainflip,
80
- displayThorChain,
81
- displayLetsExchange,
82
- displayStealthEx,
83
- displayXOSwap,
84
- displaySwapTrade,
85
- displaySwapXyz,
86
- displayNearIntents
87
- ].where((item) => item).length;
74
+ displayChangeNow,
75
+ displaySideShift,
76
+ displaySimpleSwap,
77
+ displayTrocador,
78
+ displayExolix,
79
+ displayChainflip,
80
+ displayThorChain,
81
+ displayLetsExchange,
82
+ displayStealthEx,
83
+ displayXOSwap,
84
+ displaySwapTrade,
85
+ displaySwapXyz,
86
+ displayNearIntents
87
+ ].where((item) => item).length;
88
89
@computed
90
bool get displayAllTrades =>
@@ -189,12 +189,12 @@ abstract class TradeFilterStoreBase with Store {
189
}
190
191
List<TradeListItem> filtered({required List<TradeListItem> trades, required WalletBase wallet}) {
192
- final _trades = trades
193
- .where((item) {
194
- final isSameChain = item.trade.chainId != null ? item.trade.chainId == wallet.chainId : true; // returning default as true here so it falls back to the default checks if there's no chainId
195
- return item.trade.walletId == wallet.id && isTradeInAccount(item, wallet) && isSameChain;
196
- })
197
- .toList();
192
+ final _trades = trades.where((item) {
193
+ final isSameChain = item.trade.chainId != null
194
+ ? item.trade.chainId == wallet.chainId
195
+ : true; // returning default as true here so it falls back to the default checks if there's no chainId
196
+ return item.trade.walletId == wallet.id && isTradeInAccount(item, wallet) && isSameChain;
197
+ }).toList();
198
final needToFilter = !displayAllTrades;
199
200
return needToFilter
@@ -217,12 +217,14 @@ abstract class TradeFilterStoreBase with Store {
217
item.trade.provider == ExchangeProviderDescription.thorChain) ||
218
(displayLetsExchange &&
219
item.trade.provider == ExchangeProviderDescription.letsExchange) ||
220
- (displayStealthEx && item.trade.provider == ExchangeProviderDescription.stealthEx) ||
220
+ (displayStealthEx &&
221
+ item.trade.provider == ExchangeProviderDescription.stealthEx) ||
222
(displayXOSwap && item.trade.provider == ExchangeProviderDescription.xoSwap) ||
222
- (displaySwapTrade && item.trade.provider == ExchangeProviderDescription.swapTrade) ||
223
- (displaySwapXyz &&
224
- item.trade.provider == ExchangeProviderDescription.swapsXyz) ||
225
- (displayNearIntents && item.trade.provider == ExchangeProviderDescription.nearIntents))
223
+ (displaySwapTrade &&
224
+ item.trade.provider == ExchangeProviderDescription.swapTrade) ||
225
+ (displaySwapXyz && item.trade.provider == ExchangeProviderDescription.swapsXyz) ||
226
+ (displayNearIntents &&
227
+ item.trade.provider == ExchangeProviderDescription.nearIntents))
228
.toList()
229
: _trades;
230
}
lib/store/node_list_store.dart
+1
@@ -0,0 +1 @@
1
+
lib/store/seed_settings_store.dart
-1
@@ -5,7 +5,6 @@ part 'seed_settings_store.g.dart';
5
class SeedSettingsStore = SeedSettingsStoreBase with _$SeedSettingsStore;
6
7
abstract class SeedSettingsStoreBase with Store {
8
-
8
@observable
9
String? passphrase;
10
}
lib/store/settings_store.dart
+72
-88
@@ -247,7 +247,6 @@ abstract class SettingsStoreBase with Store {
247
priority[WalletType.ethereum] = initialEthereumTransactionPriority;
248
}
249
250
-
250
if (initialPolygonTransactionPriority != null) {
251
priority[WalletType.polygon] = initialPolygonTransactionPriority;
252
}
@@ -302,7 +301,8 @@ abstract class SettingsStoreBase with Store {
301
reaction((_) => shouldShowRepWarning,
302
(bool val) => sharedPreferences.setBool(PreferencesKey.shouldShowRepWarning, val));
303
305
- reaction((_)=>mwebAdDismissed, (val)=>sharedPreferences.setBool(PreferencesKey.mwebAdDismissed, val));
304
+ reaction((_) => mwebAdDismissed,
305
+ (val) => sharedPreferences.setBool(PreferencesKey.mwebAdDismissed, val));
306
307
priority.observe((change) {
308
final String? key;
@@ -570,42 +570,40 @@ abstract class SettingsStoreBase with Store {
570
571
reaction(
572
(_) => lookupsZcashNames,
573
- (bool looksUpZcashNames) => _sharedPreferences.setBool(
574
- PreferencesKey.lookupsZcashNames, looksUpZcashNames));
573
+ (bool looksUpZcashNames) =>
574
+ _sharedPreferences.setBool(PreferencesKey.lookupsZcashNames, looksUpZcashNames));
575
576
reaction(
577
- (_) => lookupsZcashAddress,
578
- (bool lookupsZcashAddress) => _sharedPreferences.setBool(
579
- PreferencesKey.lookupsZcashAddress, lookupsZcashAddress));
577
+ (_) => lookupsZcashAddress,
578
+ (bool lookupsZcashAddress) =>
579
+ _sharedPreferences.setBool(PreferencesKey.lookupsZcashAddress, lookupsZcashAddress));
580
581
reaction(
582
(_) => lookupsWellKnown,
583
(bool looksUpWellKnown) =>
584
_sharedPreferences.setBool(PreferencesKey.lookupsWellKnown, looksUpWellKnown));
585
586
- reaction(
587
- (_) => lookupsFio,
588
- (bool lookupsFio) =>
589
- _sharedPreferences.setBool(PreferencesKey.lookupsFio, lookupsFio));
586
+ reaction((_) => lookupsFio,
587
+ (bool lookupsFio) => _sharedPreferences.setBool(PreferencesKey.lookupsFio, lookupsFio));
588
589
reaction(
592
- (_) => lookupsNostr,
593
- (bool lookupsNostr) =>
590
+ (_) => lookupsNostr,
591
+ (bool lookupsNostr) =>
592
_sharedPreferences.setBool(PreferencesKey.lookupsNostr, lookupsNostr));
593
594
reaction(
597
- (_) => lookupsThorChain,
598
- (bool lookupsThorChain) =>
595
+ (_) => lookupsThorChain,
596
+ (bool lookupsThorChain) =>
597
_sharedPreferences.setBool(PreferencesKey.lookupsThorChain, lookupsThorChain));
598
599
reaction(
602
- (_) => lookupsBip353,
603
- (bool lookupsBip353) =>
600
+ (_) => lookupsBip353,
601
+ (bool lookupsBip353) =>
602
_sharedPreferences.setBool(PreferencesKey.lookupsBip353, lookupsBip353));
603
604
reaction(
607
- (_) => lookupsLNUrl,
608
- (bool lookupsLNUrl) =>
605
+ (_) => lookupsLNUrl,
606
+ (bool lookupsLNUrl) =>
607
_sharedPreferences.setBool(PreferencesKey.lookupsLNUrl, lookupsLNUrl));
608
609
reaction((_) => usePayjoin,
@@ -726,8 +724,8 @@ abstract class SettingsStoreBase with Store {
724
725
reaction(
726
(_) => showZcashMissingFundsCard,
729
- (bool showZcashMissingFundsCard) =>
730
- _sharedPreferences.setBool(PreferencesKey.showZcashMissingFundsCard, showZcashMissingFundsCard));
727
+ (bool showZcashMissingFundsCard) => _sharedPreferences.setBool(
728
+ PreferencesKey.showZcashMissingFundsCard, showZcashMissingFundsCard));
729
730
reaction((_) => mwebEnabled,
731
(bool mwebEnabled) => _sharedPreferences.setBool(PreferencesKey.mwebEnabled, mwebEnabled));
@@ -765,8 +763,8 @@ abstract class SettingsStoreBase with Store {
763
764
reaction(
765
(_) => balanceHideCounter,
768
- (int balanceHideCounter) => _sharedPreferences.setInt(PreferencesKey.balanceHideCounter, balanceHideCounter)
769
- );
766
+ (int balanceHideCounter) =>
767
+ _sharedPreferences.setInt(PreferencesKey.balanceHideCounter, balanceHideCounter));
768
769
this.nodes.observe((change) {
770
if (change.newValue != null && change.key != null) {
@@ -1147,7 +1145,8 @@ abstract class SettingsStoreBase with Store {
1145
return priority[walletType];
1146
}
1147
1150
- void setPriority(WalletType walletType, TransactionPriority priority, {int? chainId}) => this.priority[walletType] = priority;
1148
+ void setPriority(WalletType walletType, TransactionPriority priority, {int? chainId}) =>
1149
+ this.priority[walletType] = priority;
1150
1151
bool isBitcoinBuyEnabled;
1152
@@ -1158,8 +1157,7 @@ abstract class SettingsStoreBase with Store {
1157
_sharedPreferences.setBool(PreferencesKey.shouldShowReceiveWarning, value);
1158
1159
static Future<SettingsStore> load(
1161
- {
1162
- required bool isBitcoinBuyEnabled,
1160
+ {required bool isBitcoinBuyEnabled,
1161
FiatCurrency initialFiatCurrency = FiatCurrency.usd,
1162
BalanceDisplayMode initialBalanceDisplayMode = BalanceDisplayMode.availableBalance}) async {
1163
final sharedPreferences = await getIt.getAsync<SharedPreferences>();
@@ -1281,10 +1279,14 @@ abstract class SettingsStoreBase with Store {
1279
sharedPreferences.getBool(PreferencesKey.shouldShowMarketPlaceInDashboard) ?? true;
1280
final showAddressBookPopupEnabled =
1281
sharedPreferences.getBool(PreferencesKey.showAddressBookPopupEnabled) ?? true;
1284
- final forceDecentralizedExchanges = await sharedPreferences.getBool(PreferencesKey.forceDecentralizedExchanges) ?? false;
1285
- final decentralizedExchangesPromptDismissed = await sharedPreferences.getBool(PreferencesKey.decentralizedExchangesPromptDismissed) ?? false;
1282
+ final forceDecentralizedExchanges =
1283
+ await sharedPreferences.getBool(PreferencesKey.forceDecentralizedExchanges) ?? false;
1284
+ final decentralizedExchangesPromptDismissed =
1285
+ await sharedPreferences.getBool(PreferencesKey.decentralizedExchangesPromptDismissed) ??
1286
+ false;
1287
final syncStatusDisplayMode = SyncStatusDisplayModeExtension.fromString(
1287
- sharedPreferences.getString(PreferencesKey.syncStatusDisplayMode) ?? SyncStatusDisplayMode.blocksRemaining.name);
1288
+ sharedPreferences.getString(PreferencesKey.syncStatusDisplayMode) ??
1289
+ SyncStatusDisplayMode.blocksRemaining.name);
1290
final exchangeStatus = ExchangeApiMode.deserialize(
1291
raw: sharedPreferences.getInt(PreferencesKey.exchangeStatusKey) ??
1292
ExchangeApiMode.enabled.raw);
@@ -1323,7 +1325,8 @@ abstract class SettingsStoreBase with Store {
1325
final lookupsOpenAlias = sharedPreferences.getBool(PreferencesKey.lookupsOpenAlias) ?? true;
1326
final lookupsENS = sharedPreferences.getBool(PreferencesKey.lookupsENS) ?? true;
1327
final lookupsZcashNames = sharedPreferences.getBool(PreferencesKey.lookupsZcashNames) ?? true;
1326
- final lookupsZcashAddress = sharedPreferences.getBool(PreferencesKey.lookupsZcashAddress) ?? true;
1328
+ final lookupsZcashAddress =
1329
+ sharedPreferences.getBool(PreferencesKey.lookupsZcashAddress) ?? true;
1330
final lookupsWellKnown = sharedPreferences.getBool(PreferencesKey.lookupsWellKnown) ?? true;
1331
final lookupsFio = sharedPreferences.getBool(PreferencesKey.lookupsFio) ?? true;
1332
final lookupsNostr = sharedPreferences.getBool(PreferencesKey.lookupsNostr) ?? true;
@@ -1337,7 +1340,8 @@ abstract class SettingsStoreBase with Store {
1340
sharedPreferences.getBool(PreferencesKey.silentPaymentsCardDisplay) ?? true;
1341
final mwebAlwaysScan = sharedPreferences.getBool(PreferencesKey.mwebAlwaysScan) ?? false;
1342
final mwebCardDisplay = sharedPreferences.getBool(PreferencesKey.mwebCardDisplay) ?? true;
1340
- final showZcashMissingFundsCard = sharedPreferences.getBool(PreferencesKey.showZcashMissingFundsCard) ?? true;
1343
+ final showZcashMissingFundsCard =
1344
+ sharedPreferences.getBool(PreferencesKey.showZcashMissingFundsCard) ?? true;
1345
final mwebEnabled = sharedPreferences.getBool(PreferencesKey.mwebEnabled) ?? false;
1346
final hasEnabledMwebBefore =
1347
sharedPreferences.getBool(PreferencesKey.hasEnabledMwebBefore) ?? false;
@@ -1376,7 +1380,6 @@ abstract class SettingsStoreBase with Store {
1380
final decredNodeId = sharedPreferences.getInt(PreferencesKey.currentDecredNodeIdKey);
1381
final dogecoinNodeId = sharedPreferences.getInt(PreferencesKey.currentDogecoinNodeIdKey);
1382
1379
-
1383
final nodeSource = await Node.getAll();
1384
final powNodeSource = await Node.getAllPow();
1385
@@ -1389,52 +1392,36 @@ abstract class SettingsStoreBase with Store {
1392
final litecoinElectrumServer =
1393
nodeSource.firstWhereOrNull((e) => e.id == litecoinElectrumServerId) ??
1394
nodeSource.firstWhereOrNull((e) => e.uriRaw == cakeWalletLitecoinElectrumUri);
1392
- final ethereumNode =
1393
- nodeSource.firstWhereOrNull((e) => e.id == ethereumNodeId) ??
1394
- nodeSource.firstWhereOrNull((e) => e.uriRaw == ethereumDefaultNodeUri);
1395
- final polygonNode =
1396
- nodeSource.firstWhereOrNull((e) => e.id == polygonNodeId) ??
1397
- nodeSource.firstWhereOrNull((e) => e.uriRaw == polygonDefaultNodeUri);
1398
- final baseNode =
1399
- nodeSource.firstWhereOrNull((e) => e.id == baseNodeId) ??
1400
- nodeSource.firstWhereOrNull((e) => e.uriRaw == baseDefaultNodeUri);
1401
- final arbitrumNode =
1402
- nodeSource.firstWhereOrNull((e) => e.id == arbitrumNodeId) ??
1403
- nodeSource.firstWhereOrNull((e) => e.uriRaw == arbitrumDefaultNodeUri);
1395
+ final ethereumNode = nodeSource.firstWhereOrNull((e) => e.id == ethereumNodeId) ??
1396
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == ethereumDefaultNodeUri);
1397
+ final polygonNode = nodeSource.firstWhereOrNull((e) => e.id == polygonNodeId) ??
1398
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == polygonDefaultNodeUri);
1399
+ final baseNode = nodeSource.firstWhereOrNull((e) => e.id == baseNodeId) ??
1400
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == baseDefaultNodeUri);
1401
+ final arbitrumNode = nodeSource.firstWhereOrNull((e) => e.id == arbitrumNodeId) ??
1402
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == arbitrumDefaultNodeUri);
1403
final bitcoinCashElectrumServer =
1404
nodeSource.firstWhereOrNull((e) => e.id == bitcoinCashElectrumServerId) ??
1406
- nodeSource.firstWhereOrNull(
1407
- (e) => e.uriRaw == cakeWalletBitcoinCashDefaultNodeUri);
1408
- final nanoNode =
1409
- nodeSource.firstWhereOrNull((e) => e.id == nanoNodeId) ??
1410
- nodeSource.firstWhereOrNull((e) => e.uriRaw == nanoDefaultNodeUri);
1411
- final decredNode =
1412
- nodeSource.firstWhereOrNull((e) => e.id == decredNodeId) ??
1413
- nodeSource.firstWhereOrNull((e) => e.uriRaw == decredDefaultUri);
1414
- final nanoPowNode =
1415
- powNodeSource.firstWhereOrNull((e) => e.id == nanoPowNodeId) ??
1416
- powNodeSource.firstWhereOrNull(
1417
- (e) => e.uriRaw == nanoDefaultPowNodeUri);
1418
- final solanaNode =
1419
- nodeSource.firstWhereOrNull((e) => e.id == solanaNodeId) ??
1420
- nodeSource.firstWhereOrNull((e) => e.uriRaw == solanaDefaultNodeUri);
1421
- final tronNode =
1422
- nodeSource.firstWhereOrNull((e) => e.id == tronNodeId) ??
1423
- nodeSource.firstWhereOrNull((e) => e.uriRaw == tronDefaultNodeUri);
1424
- final wowneroNode =
1425
- nodeSource.firstWhereOrNull((e) => e.id == wowneroNodeId) ??
1426
- nodeSource.firstWhereOrNull((e) => e.uriRaw == wowneroDefaultNodeUri);
1427
- final zanoNode =
1428
- nodeSource.firstWhereOrNull((e) => e.id == zanoNodeId) ??
1429
- nodeSource.firstWhereOrNull((e) => e.uriRaw == zanoDefaultNodeUri);
1430
- final dogecoinNode =
1431
- nodeSource.firstWhereOrNull((e) => e.id == dogecoinNodeId) ??
1432
- nodeSource.firstWhereOrNull((e) => e.uriRaw == dogecoinDefaultNodeUri);
1433
- final zcashNode =
1434
- nodeSource.firstWhereOrNull((e) => e.id == zcashNodeId) ??
1405
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == cakeWalletBitcoinCashDefaultNodeUri);
1406
+ final nanoNode = nodeSource.firstWhereOrNull((e) => e.id == nanoNodeId) ??
1407
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == nanoDefaultNodeUri);
1408
+ final decredNode = nodeSource.firstWhereOrNull((e) => e.id == decredNodeId) ??
1409
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == decredDefaultUri);
1410
+ final nanoPowNode = powNodeSource.firstWhereOrNull((e) => e.id == nanoPowNodeId) ??
1411
+ powNodeSource.firstWhereOrNull((e) => e.uriRaw == nanoDefaultPowNodeUri);
1412
+ final solanaNode = nodeSource.firstWhereOrNull((e) => e.id == solanaNodeId) ??
1413
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == solanaDefaultNodeUri);
1414
+ final tronNode = nodeSource.firstWhereOrNull((e) => e.id == tronNodeId) ??
1415
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == tronDefaultNodeUri);
1416
+ final wowneroNode = nodeSource.firstWhereOrNull((e) => e.id == wowneroNodeId) ??
1417
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == wowneroDefaultNodeUri);
1418
+ final zanoNode = nodeSource.firstWhereOrNull((e) => e.id == zanoNodeId) ??
1419
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == zanoDefaultNodeUri);
1420
+ final dogecoinNode = nodeSource.firstWhereOrNull((e) => e.id == dogecoinNodeId) ??
1421
+ nodeSource.firstWhereOrNull((e) => e.uriRaw == dogecoinDefaultNodeUri);
1422
+ final zcashNode = nodeSource.firstWhereOrNull((e) => e.id == zcashNodeId) ??
1423
nodeSource.firstWhereOrNull((e) => e.uriRaw == zcashDefaultNodeUri);
1436
- final bscNode =
1437
- nodeSource.firstWhereOrNull((e) => e.id == bscNodeId) ??
1424
+ final bscNode = nodeSource.firstWhereOrNull((e) => e.id == bscNodeId) ??
1425
nodeSource.firstWhereOrNull((e) => e.uriRaw == bscDefaultNodeUri);
1426
1427
final packageInfo = await PackageInfo.fromPlatform();
@@ -1654,7 +1641,8 @@ abstract class SettingsStoreBase with Store {
1641
final mwebAdDismissed =
1642
await sharedPreferences.getBool(PreferencesKey.mwebAdDismissed) ?? false;
1643
1657
- final balanceHideCounter = await sharedPreferences.getInt(PreferencesKey.balanceHideCounter) ?? 0;
1644
+ final balanceHideCounter =
1645
+ await sharedPreferences.getInt(PreferencesKey.balanceHideCounter) ?? 0;
1646
1647
return SettingsStore(
1648
secureStorage: secureStorage,
@@ -1899,7 +1887,8 @@ abstract class SettingsStoreBase with Store {
1887
sharedPreferences.getBool(PreferencesKey.showAddressBookPopupEnabled) ??
1888
showAddressBookPopupEnabled;
1889
syncStatusDisplayMode = SyncStatusDisplayModeExtension.fromString(
1902
- sharedPreferences.getString(PreferencesKey.syncStatusDisplayMode) ?? SyncStatusDisplayMode.blocksRemaining.name);
1890
+ sharedPreferences.getString(PreferencesKey.syncStatusDisplayMode) ??
1891
+ SyncStatusDisplayMode.blocksRemaining.name);
1892
exchangeStatus = ExchangeApiMode.deserialize(
1893
raw: sharedPreferences.getInt(PreferencesKey.exchangeStatusKey) ??
1894
ExchangeApiMode.enabled.raw);
@@ -1950,15 +1939,15 @@ abstract class SettingsStoreBase with Store {
1939
sharedPreferences.getBool(PreferencesKey.lookupsUnstoppableDomains) ?? true;
1940
lookupsOpenAlias = sharedPreferences.getBool(PreferencesKey.lookupsOpenAlias) ?? true;
1941
lookupsENS = sharedPreferences.getBool(PreferencesKey.lookupsENS) ?? true;
1953
- lookupsZcashNames =
1954
- sharedPreferences.getBool(PreferencesKey.lookupsZcashNames) ?? true;
1942
+ lookupsZcashNames = sharedPreferences.getBool(PreferencesKey.lookupsZcashNames) ?? true;
1943
lookupsWellKnown = sharedPreferences.getBool(PreferencesKey.lookupsWellKnown) ?? true;
1944
customBitcoinFeeRate = sharedPreferences.getInt(PreferencesKey.customBitcoinFeeRate) ?? 1;
1945
silentPaymentsCardDisplay =
1946
sharedPreferences.getBool(PreferencesKey.silentPaymentsCardDisplay) ?? true;
1947
mwebAlwaysScan = sharedPreferences.getBool(PreferencesKey.mwebAlwaysScan) ?? false;
1948
mwebCardDisplay = sharedPreferences.getBool(PreferencesKey.mwebCardDisplay) ?? true;
1961
- showZcashMissingFundsCard = sharedPreferences.getBool(PreferencesKey.showZcashMissingFundsCard) ?? true;
1949
+ showZcashMissingFundsCard =
1950
+ sharedPreferences.getBool(PreferencesKey.showZcashMissingFundsCard) ?? true;
1951
mwebEnabled = sharedPreferences.getBool(PreferencesKey.mwebEnabled) ?? false;
1952
hasEnabledMwebBefore = sharedPreferences.getBool(PreferencesKey.hasEnabledMwebBefore) ?? false;
1953
final nodeId = sharedPreferences.getInt(PreferencesKey.currentNodeIdKey);
@@ -2001,7 +1990,6 @@ abstract class SettingsStoreBase with Store {
1990
final decredNode = await Node.get(decredNodeId ?? -1);
1991
final dogecoinNode = await Node.get(dogecoinNodeId ?? -1);
1992
2004
-
1993
if (moneroNode != null) {
1994
nodes[WalletType.monero] = moneroNode;
1995
}
@@ -2173,15 +2161,12 @@ abstract class SettingsStoreBase with Store {
2161
}
2162
2163
Future<void> _saveCurrentNode(Node node, WalletType walletType) async {
2176
-
2164
switch (walletType) {
2165
case WalletType.bitcoin:
2179
- await _sharedPreferences.setInt(
2180
- PreferencesKey.currentBitcoinElectrumSererIdKey, node.id);
2166
+ await _sharedPreferences.setInt(PreferencesKey.currentBitcoinElectrumSererIdKey, node.id);
2167
break;
2168
case WalletType.litecoin:
2183
- await _sharedPreferences.setInt(
2184
- PreferencesKey.currentLitecoinElectrumSererIdKey, node.id);
2169
+ await _sharedPreferences.setInt(PreferencesKey.currentLitecoinElectrumSererIdKey, node.id);
2170
break;
2171
case WalletType.monero:
2172
await _sharedPreferences.setInt(PreferencesKey.currentNodeIdKey, node.id);
@@ -2200,8 +2185,7 @@ abstract class SettingsStoreBase with Store {
2185
nodes[node.type] = node;
2186
break;
2187
case WalletType.bitcoinCash:
2203
- await _sharedPreferences.setInt(
2204
- PreferencesKey.currentBitcoinCashNodeIdKey, node.id);
2188
+ await _sharedPreferences.setInt(PreferencesKey.currentBitcoinCashNodeIdKey, node.id);
2189
break;
2190
case WalletType.nano:
2191
await _sharedPreferences.setInt(PreferencesKey.currentNanoNodeIdKey, node.id);
lib/store/templates/send_template_store.dart
+2
-4
@@ -8,8 +8,7 @@ part 'send_template_store.g.dart';
8
class SendTemplateStore = SendTemplateBase with _$SendTemplateStore;
9
10
abstract class SendTemplateBase with Store {
11
- SendTemplateBase({required this.templateSource})
12
- : templates = ObservableList<Template>() {
11
+ SendTemplateBase({required this.templateSource}) : templates = ObservableList<Template>() {
12
update();
13
}
14
@@ -19,8 +18,7 @@ abstract class SendTemplateBase with Store {
18
Box<Template> templateSource;
19
20
@action
22
- void update() =>
23
- templates.replaceRange(0, templates.length, templateSource.values.toList());
21
+ void update() => templates.replaceRange(0, templates.length, templateSource.values.toList());
22
23
@action
24
Future<void> addTemplate(
lib/store/wallet_list_store.dart
+1
-1
@@ -10,4 +10,4 @@ abstract class WalletListStoreBase with Store {
10
11
@observable
12
ObservableList<WalletDescription> wallets;
13
-}
\ No newline at end of file
13
+}
lib/themes/core/theme_store.dart
+2
-2
@@ -255,14 +255,14 @@ abstract class ThemeStoreBase with Store {
255
return savedDark;
256
}
257
} catch (_) {}
258
-
258
+
259
// If no saved dark theme, check if current theme is BlackTheme with accent colors
260
// and preserve it when switching to dark mode
261
if (_currentTheme is BlackTheme) {
262
final currentBlackTheme = _currentTheme as BlackTheme;
263
return BlackTheme(currentBlackTheme.accentColor, isOled: currentBlackTheme.isOled);
264
}
265
-
265
+
266
return ThemeList.darkTheme;
267
}
268
lib/themes/custom_theme_colors/light_theme_custom_colors.dart
+6
-6
@@ -4,25 +4,25 @@ import 'package:cake_wallet/themes/core/custom_theme_colors.dart';
4
class LightThemeCustomColors extends CustomThemeColors {
5
@override
6
Color get warningContainerColor => const Color(0xFFFFCC00);
7
-
7
+
8
@override
9
Color get warningOutlineColor => const Color(0xFF312938);
10
11
@override
12
Color get backgroundMainColor => const Color(0xFF000000);
13
-
13
+
14
@override
15
Color get backgroundGradientColor => const Color(0xFFE7E7FD);
16
-
16
+
17
@override
18
Color get cardGradientColorPrimary => const Color(0xFFFFFFFF);
19
-
19
+
20
@override
21
Color get cardGradientColorSecondary => const Color(0xFFF3F3FF);
22
-
22
+
23
@override
24
Color get toggleKnobStateColor => const Color(0xFFFFFFFF);
25
-
25
+
26
@override
27
Color get toggleColorOffState => const Color(0xFFCACAE7);
28
}
lib/tron/cw_tron.dart
+2
-1
@@ -158,7 +158,8 @@ class CWTron extends Tron {
158
String? from,
159
required bool isPending,
160
}) =>
161
- TronTransactionInfo(id: id,
161
+ TronTransactionInfo(
162
+ id: id,
163
amount: amount,
164
fee: fee,
165
direction: direction,
lib/utils/address_formatter.dart
+6
-9
@@ -11,7 +11,6 @@ class AddressFormatter {
11
TextAlign? textAlign,
12
bool shouldTruncate = false,
13
}) {
14
-
14
final cleanAddress = address.replaceAll('bitcoincash:', '');
15
final isMWEB = address.startsWith('ltcmweb');
16
final chunkSize = walletType != null ? _getChunkSize(walletType) : 4;
@@ -27,7 +26,8 @@ class AddressFormatter {
26
isMWEB: isMWEB,
27
chunkSize: chunkSize,
28
evenTextStyle: evenTextStyle,
30
- oddTextStyle: oddTextStyle ?? evenTextStyle.copyWith(color: evenTextStyle.color!.withAlpha(150)),
29
+ oddTextStyle:
30
+ oddTextStyle ?? evenTextStyle.copyWith(color: evenTextStyle.color!.withAlpha(150)),
31
textAlign: textAlign,
32
);
33
} else {
@@ -36,7 +36,8 @@ class AddressFormatter {
36
isMWEB: isMWEB,
37
chunkSize: chunkSize,
38
evenTextStyle: evenTextStyle,
39
- oddTextStyle: oddTextStyle ?? evenTextStyle.copyWith(color: evenTextStyle.color!.withAlpha(128)),
39
+ oddTextStyle:
40
+ oddTextStyle ?? evenTextStyle.copyWith(color: evenTextStyle.color!.withAlpha(128)),
41
textAlign: textAlign,
42
);
43
}
@@ -50,7 +51,6 @@ class AddressFormatter {
51
required TextStyle oddTextStyle,
52
TextAlign? textAlign,
53
}) {
53
-
54
final chunks = <String>[];
55
56
if (isMWEB) {
@@ -95,7 +95,6 @@ class AddressFormatter {
95
required TextStyle oddTextStyle,
96
TextAlign? textAlign,
97
}) {
98
-
98
if (isMWEB) {
99
const fixedPrefix = 'ltcmweb';
100
final secondChunkStart = fixedPrefix.length;
@@ -133,10 +132,8 @@ class AddressFormatter {
132
}
133
134
final String firstPart = address.substring(0, digitCount);
136
- final String secondPart =
137
- address.substring(digitCount, digitCount * 2);
138
- final String lastPart =
139
- address.substring(address.length - digitCount);
135
+ final String secondPart = address.substring(digitCount, digitCount * 2);
136
+ final String lastPart = address.substring(address.length - digitCount);
137
138
final spans = <TextSpan>[
139
TextSpan(text: '$firstPart ', style: evenTextStyle),
lib/utils/brightness_util.dart
+1
-1
@@ -17,4 +17,4 @@ class BrightnessUtil {
17
// ignore: unawaited_futures
18
DeviceDisplayBrightness.resetBrightness();
19
}
20
-}
\ No newline at end of file
20
+}
lib/utils/clipboard_util.dart
+2
-1
@@ -6,7 +6,8 @@ import 'package:flutter/services.dart';
6
import 'package:sensitive_clipboard/sensitive_clipboard.dart';
7
8
class ClipboardUtil {
9
- static Future<void> setSensitiveDataToClipboard(ClipboardData data, {bool isSensitive = true}) async {
9
+ static Future<void> setSensitiveDataToClipboard(ClipboardData data,
10
+ {bool isSensitive = true}) async {
11
if (isSensitive && DeviceInfo.instance.isMobile) {
12
await SensitiveClipboard.copy(data.text);
13
return;
lib/utils/date_picker.dart
+9
-17
@@ -3,12 +3,11 @@ import 'package:cake_wallet/main.dart';
3
import 'package:flutter/cupertino.dart';
4
import 'package:flutter/material.dart';
5
6
-Future<DateTime?> getDate({
7
- required BuildContext context,
8
- required DateTime initialDate,
9
- required DateTime firstDate,
10
- required DateTime lastDate}) {
11
-
6
+Future<DateTime?> getDate(
7
+ {required BuildContext context,
8
+ required DateTime initialDate,
9
+ required DateTime firstDate,
10
+ required DateTime lastDate}) {
11
if (Platform.isIOS) {
12
return _buildCupertinoDataPicker(context, initialDate, firstDate, lastDate);
13
}
@@ -17,10 +16,7 @@ Future<DateTime?> getDate({
16
}
17
18
Future<DateTime?> _buildMaterialDataPicker(
20
- BuildContext context,
21
- DateTime initialDate,
22
- DateTime firstDate,
23
- DateTime lastDate) async {
19
+ BuildContext context, DateTime initialDate, DateTime firstDate, DateTime lastDate) async {
20
return await showDatePicker(
21
context: context,
22
initialDate: initialDate,
@@ -30,10 +26,7 @@ Future<DateTime?> _buildMaterialDataPicker(
26
}
27
28
Future<DateTime?> _buildCupertinoDataPicker(
33
- BuildContext context,
34
- DateTime initialDate,
35
- DateTime firstDate,
36
- DateTime lastDate) async {
29
+ BuildContext context, DateTime initialDate, DateTime firstDate, DateTime lastDate) async {
30
DateTime? date;
31
await showModalBottomSheet<void>(
32
context: navigatorKey.currentState!.context,
@@ -48,7 +41,6 @@ Future<DateTime?> _buildCupertinoDataPicker(
41
maximumDate: lastDate,
42
),
43
);
51
- }
52
- );
44
+ });
45
return date;
54
-}
\ No newline at end of file
46
+}
lib/utils/debounce.dart
+3
-3
@@ -3,12 +3,12 @@ import 'package:flutter/foundation.dart';
3
4
class Debounce {
5
Debounce(this.duration);
6
-
6
+
7
final Duration duration;
8
Timer? _timer;
9
-
9
+
10
void run(VoidCallback action) {
11
_timer?.cancel();
12
_timer = Timer(duration, action);
13
}
14
-}
\ No newline at end of file
14
+}
lib/utils/device_info.dart
+2
-2
@@ -6,6 +6,6 @@ class DeviceInfo {
6
static DeviceInfo get instance => DeviceInfo._();
7
8
bool get isMobile => Platform.isAndroid || Platform.isIOS;
9
-
9
+
10
bool get isDesktop => Platform.isMacOS || Platform.isWindows || Platform.isLinux;
11
-}
\ No newline at end of file
11
+}
lib/utils/feature_flag.dart
+2
-1
@@ -10,7 +10,8 @@ class FeatureFlag {
10
static const bool isBackgroundSyncEnabled = true;
11
static bool get isInAppTorEnabled => CakeTor.instance is! CakeTorDisabled;
12
static const int verificationWordsCount = kDebugMode || kProfileMode ? 0 : 2;
13
- static const bool hasDevOptions = bool.fromEnvironment('hasDevOptions', defaultValue: kDebugMode || kProfileMode);
13
+ static const bool hasDevOptions =
14
+ bool.fromEnvironment('hasDevOptions', defaultValue: kDebugMode || kProfileMode);
15
static const bool hasBitcoinViewOnly = true;
16
static const bool customBackgroundEnabled = false;
17
static const bool duressPinEnabled = true;
lib/utils/item_cell.dart
+1
-3
@@ -7,9 +7,7 @@ import 'package:cw_core/keyable.dart';
7
// class NodeListViewModel = NodeListViewModelBase with _$NodeListViewModel;
8
9
class ItemCell<Item> with Keyable {
10
- ItemCell(this.value, {
11
- required this.isSelectedBuilder,
12
- required dynamic key}) {
10
+ ItemCell(this.value, {required this.isSelectedBuilder, required dynamic key}) {
11
keyIndex = key;
12
}
13
lib/utils/list_item.dart
+1
-1
@@ -1,3 +1,3 @@
1
abstract class ListItem {
2
const ListItem();
3
-}
\ No newline at end of file
3
+}
lib/utils/list_section.dart
+1
-1
@@ -2,4 +2,4 @@ class ListSection<Item> {
2
const ListSection({required this.items});
3
4
final List<Item> items;
5
-}
\ No newline at end of file
5
+}
lib/utils/mobx.dart
+4
-8
@@ -4,15 +4,13 @@ import 'package:mobx/mobx.dart';
4
import 'package:cw_core/keyable.dart';
5
6
void connectMapToListWithTransform<T extends Keyable, Y extends Keyable>(
7
- ObservableMap<dynamic, T> source,
8
- ObservableList<Y> dest,
9
- Y Function(T?) transform,
7
+ ObservableMap<dynamic, T> source, ObservableList<Y> dest, Y Function(T?) transform,
8
{bool Function(T?)? filter}) {
9
source.observe((MapChange<dynamic, T> change) {
10
if (change.type == null) {
11
return;
12
}
15
-
13
+
14
switch (change.type) {
15
case OperationType.add:
16
if (filter?.call(change.newValue) ?? true) {
@@ -21,8 +19,7 @@ void connectMapToListWithTransform<T extends Keyable, Y extends Keyable>(
19
break;
20
case OperationType.remove:
21
// Hive could has equal index and key
24
- dest.removeWhere((elem) =>
25
- elem.keyIndex == (change.key ?? change.newValue?.keyIndex));
22
+ dest.removeWhere((elem) => elem.keyIndex == (change.key ?? change.newValue?.keyIndex));
23
break;
24
case OperationType.update:
25
for (var i = 0; i < dest.length; i++) {
@@ -88,8 +85,7 @@ extension MobxBindable<T extends Keyable> on Box<T> {
85
return;
86
}
87
91
- dest.acceptBoxChange(event,
92
- transformed: event.deleted ? null : transform(event.value as T));
88
+ dest.acceptBoxChange(event, transformed: event.deleted ? null : transform(event.value as T));
89
});
90
}
91
}
lib/utils/package_info.dart
+36
-41
@@ -2,53 +2,48 @@ import 'dart:io';
2
import 'package:package_info_plus/package_info_plus.dart' as __package_info__;
3
4
abstract class _EnvKeys {
5
- static const kWinAppName = 'CW_WIN_APP_NAME';
6
- static const kWinAppPackageName = 'CW_WIN_APP_PACKAGE_NAME';
7
- static const kWinAppVersion = 'CW_WIN_APP_VERSION';
8
- static const kWinAppBuildNumber = 'CW_WIN_APP_BUILD_NUMBER';
5
+ static const kWinAppName = 'CW_WIN_APP_NAME';
6
+ static const kWinAppPackageName = 'CW_WIN_APP_PACKAGE_NAME';
7
+ static const kWinAppVersion = 'CW_WIN_APP_VERSION';
8
+ static const kWinAppBuildNumber = 'CW_WIN_APP_BUILD_NUMBER';
9
}
10
11
class PackageInfo {
12
- static Future<PackageInfo> fromPlatform() async {
13
- if (Platform.isWindows) {
14
- return _windowsPackageInfo;
15
- }
16
-
17
- final packageInfo = await __package_info__.PackageInfo.fromPlatform();
18
- return PackageInfo._(
19
- appName: packageInfo.appName,
20
- packageName: packageInfo.packageName,
21
- version: packageInfo.version,
22
- buildNumber: packageInfo.buildNumber);
12
+ static Future<PackageInfo> fromPlatform() async {
13
+ if (Platform.isWindows) {
14
+ return _windowsPackageInfo;
15
}
16
25
- static const _defaultCWAppName = 'Cake Wallet';
26
- static const _defaultCWAppPackageName = 'com.cakewallet.cake_wallet';
27
- static const _defaultCWAppVersion = '1.0.0';
28
- static const _defaultCWAppBuildNumber = '1';
17
+ final packageInfo = await __package_info__.PackageInfo.fromPlatform();
18
+ return PackageInfo._(
19
+ appName: packageInfo.appName,
20
+ packageName: packageInfo.packageName,
21
+ version: packageInfo.version,
22
+ buildNumber: packageInfo.buildNumber);
23
+ }
24
+
25
+ static const _defaultCWAppName = 'Cake Wallet';
26
+ static const _defaultCWAppPackageName = 'com.cakewallet.cake_wallet';
27
+ static const _defaultCWAppVersion = '1.0.0';
28
+ static const _defaultCWAppBuildNumber = '1';
29
30
- static const _windowsPackageInfo = PackageInfo._(
31
- appName: const String
32
- .fromEnvironment(_EnvKeys.kWinAppName,
33
- defaultValue: _defaultCWAppName),
34
- packageName: const String
35
- .fromEnvironment(_EnvKeys.kWinAppPackageName,
36
- defaultValue: _defaultCWAppPackageName),
37
- version: const String
38
- .fromEnvironment(_EnvKeys.kWinAppVersion,
39
- defaultValue: _defaultCWAppVersion),
40
- buildNumber: const String
41
- .fromEnvironment(_EnvKeys.kWinAppBuildNumber,
42
- defaultValue: _defaultCWAppBuildNumber));
30
+ static const _windowsPackageInfo = PackageInfo._(
31
+ appName: const String.fromEnvironment(_EnvKeys.kWinAppName, defaultValue: _defaultCWAppName),
32
+ packageName: const String.fromEnvironment(_EnvKeys.kWinAppPackageName,
33
+ defaultValue: _defaultCWAppPackageName),
34
+ version:
35
+ const String.fromEnvironment(_EnvKeys.kWinAppVersion, defaultValue: _defaultCWAppVersion),
36
+ buildNumber: const String.fromEnvironment(_EnvKeys.kWinAppBuildNumber,
37
+ defaultValue: _defaultCWAppBuildNumber));
38
44
- final String appName;
45
- final String packageName;
46
- final String version;
47
- final String buildNumber;
39
+ final String appName;
40
+ final String packageName;
41
+ final String version;
42
+ final String buildNumber;
43
49
- const PackageInfo._({
50
- required this.appName,
51
- required this.packageName,
52
- required this.version,
53
- required this.buildNumber});
44
+ const PackageInfo._(
45
+ {required this.appName,
46
+ required this.packageName,
47
+ required this.version,
48
+ required this.buildNumber});
49
}
lib/utils/tor.dart
+8
-8
@@ -59,13 +59,13 @@ Future<BuildContext> showFullscreenDialog(BuildContext context) async {
59
builder: (context) {
60
dialogContext = context;
61
return PopScope(
62
- canPop: false,
63
- child: Container(
64
- color: Colors.transparent,
65
- child: Center(
66
- child: CircularProgressIndicator(
67
- color: Colors.white,
68
- ),
62
+ canPop: false,
63
+ child: Container(
64
+ color: Colors.transparent,
65
+ child: Center(
66
+ child: CircularProgressIndicator(
67
+ color: Colors.white,
68
+ ),
69
),
70
),
71
);
@@ -79,4 +79,4 @@ Future<BuildContext> showFullscreenDialog(BuildContext context) async {
79
Future<void> dismissFullscreenDialog(BuildContext context) async {
80
await Future.delayed(const Duration(seconds: 1));
81
Navigator.of(context).pop();
82
-}
\ No newline at end of file
82
+}
lib/utils/totp_utils.dart
+1
-1
@@ -22,7 +22,7 @@ String generateRandomBase32SecretKey(int byteLength) {
22
String generateOTP({required String secretKey, required int input}) {
23
/// base32 decode the secret
24
var hmacKey = base32.decode(secretKey);
25
-
25
+
26
/// initial the HMAC-SHA1 object
27
var hmacSha = Hmac(sha512, hmacKey);
28
lib/view_model/animated_ur_model.dart
+2
-3
@@ -3,8 +3,7 @@ import 'package:cw_core/wallet_base.dart';
3
import 'package:mobx/mobx.dart';
4
5
class AnimatedURModel with Store {
6
- AnimatedURModel(this.appStore)
7
- : wallet = appStore.wallet!;
6
+ AnimatedURModel(this.appStore) : wallet = appStore.wallet!;
7
final AppStore appStore;
8
final WalletBase wallet;
10
-}
\ No newline at end of file
9
+}
lib/view_model/auth_state.dart
-1
@@ -5,4 +5,3 @@ class AuthenticationBanned extends ExecutionState {
5
6
final String error;
7
}
8
-
lib/view_model/auth_view_model.dart
+1
-1
@@ -121,4 +121,4 @@ abstract class AuthViewModelBase with Store {
121
_authService.saveLastAuthTime();
122
}
123
}
124
-}
\ No newline at end of file
124
+}
lib/view_model/backup_view_model.dart
+3
-3
@@ -30,13 +30,13 @@ abstract class BackupViewModelBase with Store {
30
init();
31
32
reaction((_) => editBackupPasswordViewModel.backupPassword, (value) {
33
- if(value != backupPassword) {
33
+ if (value != backupPassword) {
34
backupPassword = value;
35
}
36
});
37
38
- reaction((_)=>backupPassword, (value){
39
- if(value != editBackupPasswordViewModel.backupPassword) {
38
+ reaction((_) => backupPassword, (value) {
39
+ if (value != editBackupPasswordViewModel.backupPassword) {
40
editBackupPasswordViewModel.backupPassword = value;
41
}
42
});
lib/view_model/bridge/bridge_details_view_model.dart
+2
-2
@@ -98,8 +98,8 @@ abstract class BridgeDetailsViewModelBase with Store {
98
99
final sourceName =
100
evm?.getChainInfoByChainId(transfer.sourceChainId)?.name ?? '${transfer.sourceChainId}';
101
- final destName =
102
- evm?.getChainInfoByChainId(transfer.destinationChainId)?.name ?? '${transfer.destinationChainId}';
101
+ final destName = evm?.getChainInfoByChainId(transfer.destinationChainId)?.name ??
102
+ '${transfer.destinationChainId}';
103
104
items.add(
105
StandartListItem(
lib/view_model/bridge/bridge_view_model.dart
+8
-12
@@ -142,13 +142,13 @@ abstract class BridgeViewModelBase extends WalletChangeListenerViewModel with St
142
143
@computed
144
String get amountDisplayFormatted {
145
- if (selectedToken == null) return "0.00";
145
+ if (selectedToken == null) return "0.00";
146
147
- return amountParsingProxy.getDisplayCryptoAmount(
148
- amount.replaceAll(',', '.'),
149
- selectedToken!,
150
- );
151
- }
147
+ return amountParsingProxy.getDisplayCryptoAmount(
148
+ amount.replaceAll(',', '.'),
149
+ selectedToken!,
150
+ );
151
+ }
152
153
DecimalAmountValidator get decimalAmountValidator => DecimalAmountValidator(
154
currency: selectedToken!,
@@ -176,8 +176,7 @@ abstract class BridgeViewModelBase extends WalletChangeListenerViewModel with St
176
String get quoteNativeFee {
177
if (quote == null) return '—';
178
179
- return amountParsingProxy.asDisplayString(
180
- Money(quote!.nativeFee, wallet.currency));
179
+ return amountParsingProxy.asDisplayString(Money(quote!.nativeFee, wallet.currency));
180
}
181
182
@computed
@@ -281,10 +280,7 @@ abstract class BridgeViewModelBase extends WalletChangeListenerViewModel with St
280
return;
281
}
282
setAmount(
284
- amountParsingProxy.asDisplayString(Money(
285
- selectedTokenBalance,
286
- token)
287
- ),
283
+ amountParsingProxy.asDisplayString(Money(selectedTokenBalance, token)),
284
);
285
}
286
lib/view_model/buy/buy_amount_view_model.dart
+2
-2
@@ -11,8 +11,8 @@ abstract class BuyAmountViewModelBase with Store {
11
BuyAmountViewModelBase()
12
: amount = '',
13
fiatCurrency = FiatCurrency.usd {
14
- int selectedIndex = FiatCurrency.currenciesAvailableToBuyWith
15
- .indexOf(getIt.get<SettingsStore>().fiatCurrency);
14
+ int selectedIndex =
15
+ FiatCurrency.currenciesAvailableToBuyWith.indexOf(getIt.get<SettingsStore>().fiatCurrency);
16
17
if (selectedIndex != -1) {
18
fiatCurrency = FiatCurrency.currenciesAvailableToBuyWith[selectedIndex];
lib/view_model/buy/buy_item.dart
+2
-3
@@ -18,8 +18,7 @@ class BuyItem {
18
BuyAmount _buyAmount;
19
20
try {
21
- _buyAmount = await provider
22
- .calculateAmount(amount?.toString() ?? '', fiatCurrency.title);
21
+ _buyAmount = await provider.calculateAmount(amount?.toString() ?? '', fiatCurrency.title);
22
} catch (e) {
23
_buyAmount = BuyAmount(sourceAmount: 0.0, destAmount: 0.0);
24
printV(e.toString());
@@ -27,4 +26,4 @@ class BuyItem {
26
27
return _buyAmount;
28
}
30
-}
\ No newline at end of file
29
+}
lib/view_model/buy/buy_sell_view_model.dart
+10
-8
@@ -476,8 +476,7 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S
476
validQuotes.where((element) => !uniqueProviderQuotes.contains(element)).toList());
477
478
if (sortedRecommendedQuotes.isNotEmpty) {
479
- sortedRecommendedQuotes.first
480
- ..setIsBestRate = true;
479
+ sortedRecommendedQuotes.first..setIsBestRate = true;
480
bestRateQuote = sortedRecommendedQuotes.first;
481
482
sortedRecommendedQuotes.sort((a, b) {
@@ -486,14 +485,17 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S
485
return 0;
486
});
487
489
- final Quote effectiveBestRateQuote =
490
- sortedRecommendedQuotes.reduce((a, b) {
491
- return isBuyAction ? a.rate < b.rate ? a : b : a.rate > b.rate ? a : b;
488
+ final Quote effectiveBestRateQuote = sortedRecommendedQuotes.reduce((a, b) {
489
+ return isBuyAction
490
+ ? a.rate < b.rate
491
+ ? a
492
+ : b
493
+ : a.rate > b.rate
494
+ ? a
495
+ : b;
496
});
497
494
-
495
- effectiveBestRateQuote.recommendations
496
- .add(ProviderRecommendation.bestRate);
498
+ effectiveBestRateQuote.recommendations.add(ProviderRecommendation.bestRate);
499
500
selectedQuote = sortedRecommendedQuotes.first;
501
sortedRecommendedQuotes.first.setIsSelected = true;
lib/view_model/cake_pay/cake_pay_buy_card_view_model.dart
+4
-3
@@ -162,8 +162,9 @@ abstract class CakePayBuyCardViewModelBase with Store {
162
confirmsVoidedRefund: confirmsVoidedRefund,
163
confirmsTermsAgreed: confirmsTermsAgreed,
164
);
165
- final paymentData =
166
- CakePayOrder.getPaymentDataFor(method: selectedPaymentMethod, order: order); // TODO should hande other currencies if added
165
+ final paymentData = CakePayOrder.getPaymentDataFor(
166
+ method: selectedPaymentMethod,
167
+ order: order); // TODO should hande other currencies if added
168
if (paymentData == null || order == null)
169
throw Exception('Payment data or order is not available.');
170
@@ -240,7 +241,7 @@ abstract class CakePayBuyCardViewModelBase with Store {
241
formattedRemainingTime = formatDuration(remainingTime!);
242
}
243
}
243
-
244
+
245
Future<void> logout() async => await _cakePayService.logout();
246
247
void _startExpirationTimer() {
lib/view_model/cake_pay/cake_pay_cards_list_view_model.dart
-1
@@ -153,7 +153,6 @@ abstract class CakePayCardsListViewModelBase with Store {
153
.toList(growable: false);
154
}
155
156
-
156
bool get hasFiltersChanged {
157
return selectedCountry != _initialSelectedCountry ||
158
displayPrepaidCards != _initialDisplayPrepaidCards ||
lib/view_model/contact_list/contact_view_model.dart
+12
-14
@@ -19,8 +19,7 @@ part 'contact_view_model.g.dart';
19
class ContactViewModel = ContactViewModelBase with _$ContactViewModel;
20
21
abstract class ContactViewModelBase with Store {
22
- ContactViewModelBase(this._contacts, this.appStore,this.adrResService,
23
- {ContactRecord? contact})
22
+ ContactViewModelBase(this._contacts, this.appStore, this.adrResService, {ContactRecord? contact})
23
: state = InitialExecutionState(),
24
currencies = CryptoCurrency.all,
25
_contact = contact,
@@ -33,7 +32,6 @@ abstract class ContactViewModelBase with Store {
32
final AppStore appStore;
33
final AddressResolverService adrResService;
34
36
-
35
@observable
36
ExecutionState state;
37
@@ -53,9 +51,7 @@ abstract class ContactViewModelBase with Store {
51
52
@computed
53
bool get isReady =>
56
- name.isNotEmpty &&
57
- (currency?.toString().isNotEmpty ?? false) &&
58
- address.isNotEmpty;
54
+ name.isNotEmpty && (currency?.toString().isNotEmpty ?? false) && address.isNotEmpty;
55
56
final List<CryptoCurrency> currencies;
57
final Box<Contact> _contacts;
@@ -78,7 +74,6 @@ abstract class ContactViewModelBase with Store {
74
if (currentCurrency == null) return null;
75
if (query.isEmpty) return null;
76
81
-
77
// Check if the address is valid for the current currency (except for Zano, which can use handles as addresses)
78
if (currentCurrency != CryptoCurrency.zano) {
79
final isValidAddress = AddressValidator(type: currentCurrency).isValid(query);
@@ -108,9 +103,8 @@ abstract class ContactViewModelBase with Store {
103
if (resolvedAddress == null || resolvedAddress.isEmpty) return;
104
105
address = resolvedAddress;
111
- displayName = parsedAddress.profileName.isNotEmpty
112
- ? parsedAddress.profileName
113
- : parsedAddress.handle;
106
+ displayName =
107
+ parsedAddress.profileName.isNotEmpty ? parsedAddress.profileName : parsedAddress.handle;
108
}
109
110
Future<void> save() async {
@@ -135,11 +129,15 @@ abstract class ContactViewModelBase with Store {
129
_contact.lastChange = now;
130
await _contact.save();
131
} else {
138
- await _contacts
139
- .add(Contact(name: name, address: address, type: currency!, lastChange: now, displayName: displayName));
132
+ await _contacts.add(Contact(
133
+ name: name,
134
+ address: address,
135
+ type: currency!,
136
+ lastChange: now,
137
+ displayName: displayName));
138
}
139
142
- lastChange = now;
140
+ lastChange = now;
141
state = ExecutedSuccessfullyState();
142
} catch (e) {
143
state = FailureState(e.toString());
@@ -149,4 +147,4 @@ abstract class ContactViewModelBase with Store {
147
bool doesContactNameExist(String name) {
148
return _contacts.values.any((contact) => contact.name == name);
149
}
152
-}
\ No newline at end of file
150
+}
lib/view_model/dashboard/action_list_item.dart
+1
-1
@@ -5,4 +5,4 @@ abstract class ActionListItem {
5
6
DateTime get date;
7
Key key;
8
-}
\ No newline at end of file
8
+}
lib/view_model/dashboard/dashboard_view_model.dart
+15
-18
@@ -252,7 +252,6 @@ abstract class DashboardViewModelBase with Store {
252
tradeMonitor.monitorActiveTrades(wallet.id);
253
}
254
255
-
255
void loadFilterItems() {
256
filterItems = [
257
// FilterItem(
@@ -276,14 +275,12 @@ abstract class DashboardViewModelBase with Store {
275
SwapFilterItem(
276
enabledProviders: () => tradeFilterStore.enabledProvidersCount,
277
allEnabled: () => tradeFilterStore.displayAllTrades,
279
- value: () => tradeFilterStore.enabledProvidersCount>0,
280
- onChanged: () =>
281
- tradeFilterStore.toggleDisplayExchange(ExchangeProviderDescription.all)),
278
+ value: () => tradeFilterStore.enabledProvidersCount > 0,
279
+ onChanged: () => tradeFilterStore.toggleDisplayExchange(ExchangeProviderDescription.all)),
280
FilterItem(
281
value: () => orderFilterStore.displayCakePay,
282
caption: 'Cake Pay',
285
- onChanged: () =>
286
- orderFilterStore.toggleDisplayOrder(OrderProviderDescription.cakePay)),
283
+ onChanged: () => orderFilterStore.toggleDisplayOrder(OrderProviderDescription.cakePay)),
284
];
285
exchangeFilterItems = [
286
SwapProviderFilterItem(
@@ -354,8 +351,6 @@ abstract class DashboardViewModelBase with Store {
351
];
352
}
353
357
-
358
-
354
bool _isTransactionDisposerCallbackRunning = false;
355
356
@action
@@ -402,9 +397,9 @@ abstract class DashboardViewModelBase with Store {
397
}
398
399
bool showBridge(CryptoCurrency currency) {
405
- if(!isEVMCompatibleChain(wallet.type)) return false;
400
+ if (!isEVMCompatibleChain(wallet.type)) return false;
401
407
- if(evm!.isUSDT0Token(wallet, currency)) return true;
402
+ if (evm!.isUSDT0Token(wallet, currency)) return true;
403
404
return false;
405
}
@@ -513,7 +508,8 @@ abstract class DashboardViewModelBase with Store {
508
// printV("Transaction disposer callback (relevantTxs: ${relevantTxs.length} current: ${transactions.length})");
509
510
// TODO(malik) update this in a saner way during the vm refactor
516
- String _txIdentityString(String txHash, TransactionDirection direction) => "${txHash}_$direction";
511
+ String _txIdentityString(String txHash, TransactionDirection direction) =>
512
+ "${txHash}_$direction";
513
String _txIdentityStringConfirmations(
514
String txHash, TransactionDirection direction, int confirmations, bool isPending) =>
515
"${txHash}_${direction}_${confirmations}_$isPending";
@@ -542,7 +538,8 @@ abstract class DashboardViewModelBase with Store {
538
.toSet();
539
540
transactions.removeWhere(
545
- (item) => newKeys.contains(_txIdentityString(item.transaction.txHash, item.transaction.direction)),
541
+ (item) => newKeys
542
+ .contains(_txIdentityString(item.transaction.txHash, item.transaction.direction)),
543
);
544
545
transactions.addAll(newTransactions);
@@ -684,7 +681,9 @@ abstract class DashboardViewModelBase with Store {
681
}).toList();
682
683
@computed
687
- bool get shouldShowBalanceHiddenMessage => balanceDisplayMode == BalanceDisplayMode.hiddenBalance && appStore.settingsStore.balanceHideCounter < 10;
684
+ bool get shouldShowBalanceHiddenMessage =>
685
+ balanceDisplayMode == BalanceDisplayMode.hiddenBalance &&
686
+ appStore.settingsStore.balanceHideCounter < 10;
687
688
@computed
689
List<OrderListItem> get orders =>
@@ -736,10 +735,8 @@ abstract class DashboardViewModelBase with Store {
735
static const shortHistoryLength = 3;
736
737
@computed
739
- List<ActionListItem> get itemsShort => items
740
- .where((item) => item is! DateSectionItem)
741
- .take(shortHistoryLength)
742
- .toList();
738
+ List<ActionListItem> get itemsShort =>
739
+ items.where((item) => item is! DateSectionItem).take(shortHistoryLength).toList();
740
741
@observable
742
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> wallet;
@@ -809,7 +806,7 @@ abstract class DashboardViewModelBase with Store {
806
// if (wallet.seed == "") "wallet seed is empty",
807
// if (monero!.getSubaddressList(wallet).getAll(wallet)[0].address ==
808
// "41d7FXjswpK1111111111111111111111111111111111111111111111111111111111111111111111111111112KhNi4")
812
- // "primary address is invalid, you won't be able to receive / spend funds",
809
+ // "primary address is invalid, you won't be able to receive / spend funds",
810
];
811
return errors;
812
}
lib/view_model/dashboard/filter_item.dart
+7
-12
@@ -1,10 +1,7 @@
1
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
2
3
class FilterItem {
4
- FilterItem({
5
- required this.value,
6
- required this.caption,
7
- required this.onChanged});
4
+ FilterItem({required this.value, required this.caption, required this.onChanged});
5
6
bool Function() value;
7
String caption;
@@ -24,17 +21,15 @@ class SwapFilterItem extends FilterItem {
21
bool Function() allEnabled;
22
}
23
27
-
24
class SwapProviderFilterItem extends FilterItem {
29
- SwapProviderFilterItem({
30
- required super.value,
31
- required super.onChanged,
32
- required this.providerDescription,
33
- super.caption = ""
34
-});
25
+ SwapProviderFilterItem(
26
+ {required super.value,
27
+ required super.onChanged,
28
+ required this.providerDescription,
29
+ super.caption = ""});
30
31
@override
32
String get caption => providerDescription.title;
33
34
final ExchangeProviderDescription providerDescription;
40
-}
\ No newline at end of file
35
+}
lib/view_model/dashboard/home_settings_view_model.dart
+11
-13
@@ -34,10 +34,9 @@ abstract class HomeSettingsViewModelBase with Store {
34
showCombinedBalance = _balanceViewModel.wallet.walletInfo.showCombinedBalance,
35
favoriteToken = _balanceViewModel.wallet.currency {
36
_updateTokensList();
37
- _updateLocalFavoriteToken();
38
-
37
+ _updateLocalFavoriteToken();
38
40
- // React to wallet changes
39
+ // React to wallet changes
40
reaction((_) => _balanceViewModel.wallet, (_) {
41
_updateTokensList();
42
});
@@ -61,7 +60,8 @@ abstract class HomeSettingsViewModelBase with Store {
60
final ObservableSet<CryptoCurrency> tokens;
61
62
@computed
64
- List<CryptoCurrency> get enabledTokens => [_balanceViewModel.wallet.currency, ...tokens.where((item)=>item.enabled).toList()];
63
+ List<CryptoCurrency> get enabledTokens =>
64
+ [_balanceViewModel.wallet.currency, ...tokens.where((item) => item.enabled).toList()];
65
66
WalletType get walletType => _balanceViewModel.wallet.type;
67
@@ -413,11 +413,10 @@ abstract class HomeSettingsViewModelBase with Store {
413
void _updateFiatPrices(CryptoCurrency token) async {
414
if (token.isPotentialScam) return; // don't fetch price data for potential scam tokens
415
try {
416
- _balanceViewModel.fiatConversionStore.prices[token] =
417
- await FiatConversionService.fetchPrice(
418
- crypto: token,
419
- fiat: _settingsStore.fiatCurrency,
420
- torOnly: _settingsStore.fiatApiMode == FiatApiMode.torOnly);
416
+ _balanceViewModel.fiatConversionStore.prices[token] = await FiatConversionService.fetchPrice(
417
+ crypto: token,
418
+ fiat: _settingsStore.fiatCurrency,
419
+ torOnly: _settingsStore.fiatApiMode == FiatApiMode.torOnly);
420
} catch (_) {}
421
}
422
@@ -499,7 +498,6 @@ abstract class HomeSettingsViewModelBase with Store {
498
}
499
}
500
502
-
501
// FIXME these two observables cause duplicated state and are needed because mobx. remove them as part of the refactor and replace with proper getters
502
@observable
503
bool showCombinedBalance;
@@ -519,7 +517,7 @@ abstract class HomeSettingsViewModelBase with Store {
517
Future<void> setFavoriteToken(CryptoCurrency token) async {
518
final String? address;
519
522
- if(token == _balanceViewModel.wallet.currency) {
520
+ if (token == _balanceViewModel.wallet.currency) {
521
address = null;
522
} else {
523
address = getTokenAddressBasedOnWallet(token);
@@ -533,11 +531,11 @@ abstract class HomeSettingsViewModelBase with Store {
531
@action
532
Future<void> _updateLocalFavoriteToken() async {
533
favoriteToken = await TokenUtilities.findTokenByAddress(
536
- walletType: _balanceViewModel.wallet.type, address: _balanceViewModel.wallet.walletInfo.favoriteTokenAddress ?? "") ??
534
+ walletType: _balanceViewModel.wallet.type,
535
+ address: _balanceViewModel.wallet.walletInfo.favoriteTokenAddress ?? "") ??
536
_balanceViewModel.wallet.currency;
537
}
538
540
-
539
@action
540
void _refreshTokensList() {
541
final _tokens = Set.of(tokens);
lib/view_model/dashboard/order_list_item.dart
+1
-1
@@ -23,4 +23,4 @@ class OrderListItem extends ActionListItem {
23
24
@override
25
DateTime get date => order.createdAt;
26
-}
\ No newline at end of file
26
+}
lib/view_model/dashboard/receive_option_view_model.dart
-1
@@ -31,7 +31,6 @@ abstract class ReceiveOptionViewModelBase with Store {
31
32
String get walletTypeString => walletTypeToString(_wallet.type);
33
34
-
34
@action
35
void selectReceiveOption(ReceivePageOption option) => selectedReceiveOption = option;
36
}
lib/view_model/dashboard/transaction_list_item.dart
+1
-3
@@ -55,7 +55,6 @@ class TransactionListItem extends ActionListItem with Keyable {
55
}
56
57
String get formattedTitle {
58
-
58
if (balanceViewModel.wallet.type == WalletType.bitcoin &&
59
transaction.additionalInfo['hasMissingInputTx'] == true) {
60
return 'Transaction has missing data';
@@ -90,8 +89,7 @@ class TransactionListItem extends ActionListItem with Keyable {
89
case WalletType.litecoin:
90
bool isPegOut = (transaction.additionalInfo["isPegOut"] as bool?) ?? false;
91
bool fromPegOut = (transaction.additionalInfo["fromPegOut"] as bool?) ?? false;
93
- if(isPegOut || fromPegOut)
94
- return 6;
92
+ if (isPegOut || fromPegOut) return 6;
93
default:
94
return 0;
95
}
lib/view_model/dashboard/wallet_balance.dart
+1
-1
@@ -3,4 +3,4 @@ class WalletBalance {
3
4
String unlockedBalance;
5
String totalBalance;
6
-}
\ No newline at end of file
6
+}
lib/view_model/dev/background_sync_logs_view_model.dart
+5
-3
@@ -2,7 +2,9 @@ import 'package:flutter_daemon/flutter_daemon.dart';
2
import 'package:mobx/mobx.dart';
3
4
part 'background_sync_logs_view_model.g.dart';
5
-class BackgroundSyncLogsViewModel = BackgroundSyncLogsViewModelBase with _$BackgroundSyncLogsViewModel;
5
+
6
+class BackgroundSyncLogsViewModel = BackgroundSyncLogsViewModelBase
7
+ with _$BackgroundSyncLogsViewModel;
8
9
abstract class BackgroundSyncLogsViewModelBase with Store {
10
final FlutterDaemon _daemon = FlutterDaemon();
@@ -26,7 +28,7 @@ abstract class BackgroundSyncLogsViewModelBase with Store {
28
Future<void> loadLogs() async {
29
isLoading = true;
30
error = null;
29
-
31
+
32
try {
33
logData = await _daemon.getLogs();
34
} catch (e) {
@@ -41,4 +43,4 @@ abstract class BackgroundSyncLogsViewModelBase with Store {
43
await _daemon.clearLogs();
44
await loadLogs();
45
}
44
-}
\ No newline at end of file
46
+}
lib/view_model/dev/exchange_provider_logs_view_model.dart
+3
-2
@@ -6,7 +6,8 @@ part 'exchange_provider_logs_view_model.g.dart';
6
7
enum LogFilter { all, success, error }
8
9
-class ExchangeProviderLogsViewModel = ExchangeProviderLogsViewModelBase with _$ExchangeProviderLogsViewModel;
9
+class ExchangeProviderLogsViewModel = ExchangeProviderLogsViewModelBase
10
+ with _$ExchangeProviderLogsViewModel;
11
12
abstract class ExchangeProviderLogsViewModelBase with Store {
13
@observable
@@ -60,7 +61,7 @@ abstract class ExchangeProviderLogsViewModelBase with Store {
61
void loadLogs() {
62
isLoading = true;
63
error = null;
63
-
64
+
65
try {
66
logs.clear();
67
logs.addAll(ExchangeProviderLogger.logs);
lib/view_model/dev/network_requests_view_model.dart
+1
-1
@@ -13,4 +13,4 @@ abstract class NetworkRequestsViewModelBase with Store {
13
Future<void> loadLogs() async {
14
logs = MemoryProxyLogger.logs;
15
}
16
-}
\ No newline at end of file
16
+}
lib/view_model/dev/qr_tools_view_model.dart
+12
-14
@@ -22,8 +22,6 @@ abstract class QRToolsViewModelBase with Store {
22
@observable
23
String input = '';
24
25
-
26
-
25
@computed
26
Map<String, dynamic> get data => _getResult(input);
27
@@ -33,7 +31,6 @@ abstract class QRToolsViewModelBase with Store {
31
return out.$1;
32
}
33
36
-
34
Map<String, dynamic> _getResult(String input) {
35
try {
36
final decoder = URDecoder();
@@ -49,15 +46,17 @@ abstract class QRToolsViewModelBase with Store {
46
decoder.receivePart(part);
47
}
48
return {
52
- "result": (decoder.result != null) ? switch (decoder.result.runtimeType) {
53
- UR => {
54
- "cbor": (decoder.result as UR).cbor,
55
- "_cbor.decode.base64": base64.encode(_decodeCBOR((decoder.result as UR).cbor)),
56
- "type": (decoder.result as UR).type,
57
- "toString": (decoder.result as UR).toString(),
58
- },
59
- _ => "unknown type: ${decoder.result.runtimeType}"
60
- } : null,
49
+ "result": (decoder.result != null)
50
+ ? switch (decoder.result.runtimeType) {
51
+ UR => {
52
+ "cbor": (decoder.result as UR).cbor,
53
+ "_cbor.decode.base64": base64.encode(_decodeCBOR((decoder.result as UR).cbor)),
54
+ "type": (decoder.result as UR).type,
55
+ "toString": (decoder.result as UR).toString(),
56
+ },
57
+ _ => "unknown type: ${decoder.result.runtimeType}"
58
+ }
59
+ : null,
60
"expectedType": decoder.expectedType,
61
"estimatedPercentComplete": decoder.estimatedPercentComplete(),
62
"processedPartsCount": decoder.processedPartsCount(),
@@ -70,7 +69,6 @@ abstract class QRToolsViewModelBase with Store {
69
"resultError": decoder.resultError(),
70
"resultMessage": decoder.resultMessage(),
71
"toString": decoder.toString(),
73
-
72
};
73
} catch (e) {
74
return {
@@ -78,4 +76,4 @@ abstract class QRToolsViewModelBase with Store {
76
};
77
}
78
}
81
-}
\ No newline at end of file
79
+}
lib/view_model/dev/secure_preferences.dart
+4
-15
@@ -6,14 +6,7 @@ part 'secure_preferences.g.dart';
6
7
class DevSecurePreferences = DevSecurePreferencesBase with _$DevSecurePreferences;
8
9
-enum PreferenceType {
10
- unknown,
11
- string,
12
- int,
13
- double,
14
- bool,
15
- listString
16
-}
9
+enum PreferenceType { unknown, string, int, double, bool, listString }
10
11
abstract class DevSecurePreferencesBase with Store {
12
DevSecurePreferencesBase() {
@@ -29,9 +22,7 @@ abstract class DevSecurePreferencesBase with Store {
22
List<String> get keys => values.keys.toList()..sort();
23
24
@action
32
- Future<void> delete(String key) async {
33
-
34
- }
25
+ Future<void> delete(String key) async {}
26
27
dynamic get(String key) {
28
if (!values.containsKey(key)) {
@@ -42,13 +33,11 @@ abstract class DevSecurePreferencesBase with Store {
33
final decodedPassword = decodeWalletPassword(password: values[key]!);
34
return values[key]! + "\n\nDecoded: $decodedPassword";
35
} catch (e) {
45
- return values[key]! +"\n$e";
36
+ return values[key]! + "\n$e";
37
}
38
}
39
49
- Future<void> set(String key, PreferenceType type, dynamic value) async {
50
-
51
- }
40
+ Future<void> set(String key, PreferenceType type, dynamic value) async {}
41
42
PreferenceType getPreferenceType(String key) {
43
if (!values.containsKey(key)) {
lib/view_model/dev/send_network_requests_view_model.dart
+3
-2
@@ -3,7 +3,8 @@ import 'package:mobx/mobx.dart';
3
4
part 'send_network_requests_view_model.g.dart';
5
6
-class SendNetworkRequestsViewModel = SendNetworkRequestsViewModelBase with _$SendNetworkRequestsViewModel;
6
+class SendNetworkRequestsViewModel = SendNetworkRequestsViewModelBase
7
+ with _$SendNetworkRequestsViewModel;
8
9
abstract class SendNetworkRequestsViewModelBase with Store {
10
@observable
@@ -13,4 +14,4 @@ abstract class SendNetworkRequestsViewModelBase with Store {
14
Future<void> loadLogs() async {
15
logs = MemoryProxyLogger.logs;
16
}
16
-}
\ No newline at end of file
17
+}
lib/view_model/dev/shared_preferences.dart
+1
-8
@@ -5,14 +5,7 @@ part 'shared_preferences.g.dart';
5
6
class DevSharedPreferences = DevSharedPreferencesBase with _$DevSharedPreferences;
7
8
-enum PreferenceType {
9
- unknown,
10
- string,
11
- int,
12
- double,
13
- bool,
14
- listString
15
-}
8
+enum PreferenceType { unknown, string, int, double, bool, listString }
9
10
abstract class DevSharedPreferencesBase with Store {
11
DevSharedPreferencesBase() {
lib/view_model/dev/socket_health_logs_view_model.dart
-1
@@ -6,7 +6,6 @@ part 'socket_health_logs_view_model.g.dart';
6
class SocketHealthLogsViewModel = SocketHealthLogsViewModelBase with _$SocketHealthLogsViewModel;
7
8
abstract class SocketHealthLogsViewModelBase with Store {
9
-
9
@observable
10
bool isLoading = false;
11
lib/view_model/edit_backup_password_view_model.dart
+6
-3
@@ -9,9 +9,12 @@ class EditBackupPasswordViewModel = EditBackupPasswordViewModelBase
9
with _$EditBackupPasswordViewModel;
10
11
abstract class EditBackupPasswordViewModelBase with Store {
12
- EditBackupPasswordViewModelBase(this.secureStorage,)
13
- : backupPassword = "",
14
- _originalPassword = ''{init();}
12
+ EditBackupPasswordViewModelBase(
13
+ this.secureStorage,
14
+ ) : backupPassword = "",
15
+ _originalPassword = '' {
16
+ init();
17
+ }
18
19
final SecureStorage secureStorage;
20
lib/view_model/exchange/exchange_trade_view_model.dart
+16
-22
@@ -50,7 +50,8 @@ abstract class ExchangeTradeViewModelBase with Store {
50
required this.feesViewModel,
51
required this.fiatConversionStore,
52
}) : trade = tradesStore.trade!,
53
- isSwapsXYZCanSendFromExternal = _checkIfSwapsXYZCanSendFromExternal(tradesStore.trade!, wallet),
53
+ isSwapsXYZCanSendFromExternal =
54
+ _checkIfSwapsXYZCanSendFromExternal(tradesStore.trade!, wallet),
55
items = ObservableList<ExchangeTradeItem>() {
56
setUpOutput();
57
switch (trade.provider) {
@@ -307,18 +308,17 @@ abstract class ExchangeTradeViewModelBase with Store {
308
items.add(
309
isSwapsXYZCanSendFromExternal
310
? ExchangeTradeItem(
310
- title: S.current.send_to_this_address('${tradeFrom}', tagFrom) +
311
- ':',
312
- data: trade.inputAddress ?? '',
313
- isCopied: false,
314
- isReceiveDetail: false,
315
- isExternalSendDetail: true)
311
+ title: S.current.send_to_this_address('${tradeFrom}', tagFrom) + ':',
312
+ data: trade.inputAddress ?? '',
313
+ isCopied: false,
314
+ isReceiveDetail: false,
315
+ isExternalSendDetail: true)
316
: ExchangeTradeItem(
317
- title: 'Smart contract call (no address required)',
318
- data: 'Wallet will execute a contract call. On-chain transaction',
319
- isCopied: false,
320
- isReceiveDetail: false,
321
- isExternalSendDetail: true),
317
+ title: 'Smart contract call (no address required)',
318
+ data: 'Wallet will execute a contract call. On-chain transaction',
319
+ isCopied: false,
320
+ isReceiveDetail: false,
321
+ isExternalSendDetail: true),
322
);
323
}
324
@@ -369,8 +369,7 @@ abstract class ExchangeTradeViewModelBase with Store {
369
}
370
371
final canSend = _sameCurrency(tradeFrom, wallet.currency) ||
372
- (_sameCurrency(tradeFrom, CryptoCurrency.btcln) &&
373
- wallet.currency == CryptoCurrency.btc) ||
372
+ (_sameCurrency(tradeFrom, CryptoCurrency.btcln) && wallet.currency == CryptoCurrency.btc) ||
373
trade.provider == ExchangeProviderDescription.xmrto ||
374
_isTokenBelongingToWallet(CryptoCurrency.eth) ||
375
_isTokenBelongingToWallet(CryptoCurrency.maticpoly) ||
@@ -408,13 +407,10 @@ abstract class ExchangeTradeViewModelBase with Store {
407
static bool _checkIfSwapsXYZCanSendFromExternal(Trade trade, WalletBase wallet) {
408
final provider = trade.provider;
409
411
- if (provider == ExchangeProviderDescription.swapsXyz &&
412
- isEVMCompatibleChain(wallet.type)) {
413
-
414
- if(trade.routerData != null && trade.routerData != '0x') {
410
+ if (provider == ExchangeProviderDescription.swapsXyz && isEVMCompatibleChain(wallet.type)) {
411
+ if (trade.routerData != null && trade.routerData != '0x') {
412
return false;
413
}
417
-
414
}
415
return true;
416
}
@@ -463,9 +459,7 @@ abstract class ExchangeTradeViewModelBase with Store {
459
case WalletType.monero:
460
return MoneroURI(address: inputAddress, amount: amount);
461
case WalletType.wownero:
466
- return MoneroURI(
467
- address: inputAddress,
468
- amount: amount);
462
+ return MoneroURI(address: inputAddress, amount: amount);
463
case WalletType.litecoin:
464
return LitecoinURI(amount: amount, address: inputAddress);
465
case WalletType.nano:
lib/view_model/exchange/exchange_view_model.dart
+52
-41
@@ -175,7 +175,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
175
useSameWalletAddress(depositCurrency) ? wallet.walletAddresses.addressForExchange : '';
176
177
_disposers.add(reaction((_) => receiveAddress, (_) {
178
- if(!(tradeState is TradeIsCreatedSuccessfully)) {
178
+ if (!(tradeState is TradeIsCreatedSuccessfully)) {
179
receiveAddressDisplayName = null;
180
}
181
}));
@@ -254,8 +254,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
254
c.title == depositCurrency.title &&
255
(c.tag == depositCurrency.tag || c.tag == depositCurrency.title),
256
);
257
- final balanceForCurrency =
258
- balanceCurrency != null ? wallet.balance[balanceCurrency] : null;
257
+ final balanceForCurrency = balanceCurrency != null ? wallet.balance[balanceCurrency] : null;
258
if (depositCurrency == currency && balanceForCurrency != null) {
259
depositAvailableAmount =
260
_appStore.amountParsingProxy.asDisplayStringWithSymbol(balanceForCurrency.available);
@@ -281,7 +280,9 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
280
281
bool useSameWalletAddress(CryptoCurrency currency) =>
282
currency == wallet.currency ||
284
- (currency == CryptoCurrency.btcln && wallet.currency == CryptoCurrency.btc && wallet.isSoftwareWallet) ||
283
+ (currency == CryptoCurrency.btcln &&
284
+ wallet.currency == CryptoCurrency.btc &&
285
+ wallet.isSoftwareWallet) ||
286
(currency.tag != null && currency.tag == wallet.currency.tag) ||
287
currency.tag == wallet.currency.title;
288
@@ -294,7 +295,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
295
296
bool get hideAddressAfterExchange =>
297
[WalletType.monero, WalletType.wownero, WalletType.zcash].contains(wallet.type) ||
297
- isElectrumWallet;
298
+ isElectrumWallet;
299
300
bool _useTorOnly;
301
final ExchangeTemplateStore _exchangeTemplateStore;
@@ -465,7 +466,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
466
type = cryptoCurrencyOrTokenToWalletType(depositCurrency);
467
if (type == null) {
468
try {
468
- type = cryptoCurrencyOrTokenToWalletType(CryptoCurrency.fromString(depositCurrency.tag ?? ""));
469
+ type =
470
+ cryptoCurrencyOrTokenToWalletType(CryptoCurrency.fromString(depositCurrency.tag ?? ""));
471
} catch (_) {}
472
}
473
@@ -495,7 +497,9 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
497
@computed
498
String? get balanceDisplay {
499
CryptoCurrency? balanceCurrency;
498
- if (isEVMCompatibleChain(wallet.type) || wallet.type == WalletType.solana || wallet.type == WalletType.tron) {
500
+ if (isEVMCompatibleChain(wallet.type) ||
501
+ wallet.type == WalletType.solana ||
502
+ wallet.type == WalletType.tron) {
503
balanceCurrency = wallet.balance.keys.firstWhereOrNull(
504
(c) =>
505
c.title == depositCurrency.title &&
@@ -523,7 +527,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
527
}
528
529
@computed
526
- bool get decentralizedExchangesPromptDismissed => _settingsStore.decentralizedExchangesPromptDismissed;
530
+ bool get decentralizedExchangesPromptDismissed =>
531
+ _settingsStore.decentralizedExchangesPromptDismissed;
532
533
@action
534
void dismissDecentralizedExchangesPrompt() {
@@ -707,7 +712,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
712
}
713
try {
714
return double.parse(depositAmount).toStringAsPrecision(digits);
710
- } catch(e) {
715
+ } catch (e) {
716
return "0";
717
}
718
}
@@ -718,7 +723,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
723
}
724
try {
725
return double.parse(receiveAmount).toStringAsPrecision(digits);
721
- } catch(e) {
726
+ } catch (e) {
727
return "0";
728
}
729
}
@@ -850,6 +855,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
855
_receiveAmount = null;
856
return;
857
}
858
+
859
/// For fixed-rate transactions, we don't want to recalculate receive amount
860
/// as it should remain exactly what the user set
861
if (isFixedRateMode) return;
@@ -1014,9 +1020,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
1020
final entries = await Future.wait(futures);
1021
_providerLimits = Map.fromEntries(entries);
1022
1017
- _providerLimits.values
1018
- .whereType<Limits>()
1019
- .forEach((tempLimits) {
1023
+ _providerLimits.values.whereType<Limits>().forEach((tempLimits) {
1024
if (lowestMin != null && (tempLimits.min ?? -1) < lowestMin!) {
1025
lowestMin = tempLimits.min;
1026
}
@@ -1072,10 +1076,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
1076
? '$depositAmountValue is not a valid amount for depositAmount'
1077
: '$receiveAmountValue is not a valid amount for receiveAmount';
1078
1075
- tradeState = TradeIsCreatedFailure(
1076
- title: S.current.trade_not_created,
1077
- error: invalidAmountError
1078
- );
1079
+ tradeState =
1080
+ TradeIsCreatedFailure(title: S.current.trade_not_created, error: invalidAmountError);
1081
return;
1082
}
1083
@@ -1085,8 +1087,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
1087
1088
if (limits.min != null && amount != null && amount < limits.min!) {
1089
tradeState = TradeIsCreatedFailure(
1088
- title: S.current.trade_not_created,
1089
- error: S.current.amount_is_below_minimum_limit(limits.min!.toString()),
1090
+ title: S.current.trade_not_created,
1091
+ error: S.current.amount_is_below_minimum_limit(limits.min!.toString()),
1092
);
1093
return;
1094
}
@@ -1212,8 +1214,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
1214
}
1215
1216
// Skip Swaps.xyz when sending from external
1215
- if (isSendFromExternal &&
1216
- provider.description == ExchangeProviderDescription.swapsXyz) {
1217
+ if (isSendFromExternal && provider.description == ExchangeProviderDescription.swapsXyz) {
1218
printV('Skipping Swaps.xyz for external send');
1219
continue;
1220
}
@@ -1264,10 +1265,10 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
1265
trade.walletId = wallet.id;
1266
trade.chainId = wallet.chainId;
1267
trade.fromWalletAddress = wallet.walletAddresses.address;
1267
- if(trade.from == null) {
1268
+ if (trade.from == null) {
1269
trade.from = depositCurrency;
1270
}
1270
- if(trade.to == null) {
1271
+ if (trade.to == null) {
1272
trade.to = receiveCurrency;
1273
}
1274
@@ -1385,7 +1386,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
1386
} else if (wallet.type == WalletType.monero) {
1387
final amount = await unspentCoinsListViewModel.getSendingBalance(UnspentCoinType.any);
1388
1388
- changeDepositAmount(amount: wallet.currency.formatAmount(BigInt.from(amount)), isCanonical: true);
1389
+ changeDepositAmount(
1390
+ amount: wallet.currency.formatAmount(BigInt.from(amount)), isCanonical: true);
1391
} else if (isEVMCompatibleChain(wallet.type)) {
1392
final balanceCurrency = wallet.balance.keys.firstWhereOrNull(
1393
(currency) =>
@@ -1399,7 +1401,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
1401
return;
1402
}
1403
1402
- final balanceAmount = _appStore.amountParsingProxy.asDisplayString(balanceForCurrency.available);
1404
+ final balanceAmount =
1405
+ _appStore.amountParsingProxy.asDisplayString(balanceForCurrency.available);
1406
final balanceDouble = double.tryParse(balanceAmount.replaceAll(',', '.')) ?? 0.0;
1407
if (balanceDouble <= 0) {
1408
changeDepositAmount(amount: wallet.currency.formatAmount(BigInt.zero), isCanonical: true);
@@ -1431,7 +1434,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
1434
final feeWei = BigInt.parse(feeString);
1435
final amountAfterFeeWei = balanceWei > feeWei ? balanceWei - feeWei : BigInt.zero;
1436
changeDepositAmount(
1434
- amount: wallet.currency.formatAmount(amountAfterFeeWei), isCanonical: true);
1437
+ amount: wallet.currency.formatAmount(amountAfterFeeWei), isCanonical: true);
1438
} catch (e) {
1439
printV('Error calculating send all for EVM: $e');
1440
changeDepositAmount(amount: balanceAmount, isCanonical: true);
@@ -1588,16 +1591,19 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
1591
}
1592
1593
String? _addressTypeValidation(String refundAddress, String receiveAddress) {
1591
- final isRefundAddressSP = RegExp(AddressValidator.silentPaymentAddressPatternMainnet).hasMatch(refundAddress);
1594
+ final isRefundAddressSP =
1595
+ RegExp(AddressValidator.silentPaymentAddressPatternMainnet).hasMatch(refundAddress);
1596
if (isRefundAddressSP) return 'Silent Payment ${S.current.address_not_allowed_as_refund}';
1597
1594
- final isReceiveAddressSP = RegExp(AddressValidator.silentPaymentAddressPatternMainnet).hasMatch(receiveAddress);
1598
+ final isReceiveAddressSP =
1599
+ RegExp(AddressValidator.silentPaymentAddressPatternMainnet).hasMatch(receiveAddress);
1600
if (isReceiveAddressSP) return 'Silent Payment ${S.current.address_not_allowed_as_receive}';
1601
1602
final isRefundAddressMWEB = RegExp(AddressValidator.mWebAddressPattern).hasMatch(refundAddress);
1603
if (isRefundAddressMWEB) return 'MWEB ${S.current.address_not_allowed_as_refund}';
1604
1600
- final isReceiveAddressMWEB = RegExp(AddressValidator.mWebAddressPattern).hasMatch(receiveAddress);
1605
+ final isReceiveAddressMWEB =
1606
+ RegExp(AddressValidator.mWebAddressPattern).hasMatch(receiveAddress);
1607
if (isReceiveAddressMWEB) return 'MWEB ${S.current.address_not_allowed_as_receive}';
1608
return null;
1609
}
@@ -1678,7 +1684,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
1684
@action
1685
void toggleForceDecentralizedExchanges() {
1686
_settingsStore.forceDecentralizedExchanges = !_settingsStore.forceDecentralizedExchanges;
1681
- if(forceDecentralizedExchanges) {
1687
+ if (forceDecentralizedExchanges) {
1688
final providers = selectedProviders.toList();
1689
for (final provider in providers) {
1690
if (forceDecentralizedExchanges && provider.description.isCentralized) {
@@ -1686,13 +1692,12 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
1692
}
1693
}
1694
} else {
1689
- for(final provider in providerList) {
1690
- if(!selectedProviders.contains(provider) && provider.description.isCentralized) {
1695
+ for (final provider in providerList) {
1696
+ if (!selectedProviders.contains(provider) && provider.description.isCentralized) {
1697
addExchangeProvider(provider);
1698
}
1699
}
1700
}
1695
-
1701
}
1702
1703
void _setAvailableProviders() {
@@ -1714,9 +1719,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
1719
int get receiveMaxDigits => receiveCurrency.decimals;
1720
1721
Future<CreateTradeResult> isCanCreateTrade(Trade trade) async {
1717
-
1722
if (trade.provider == ExchangeProviderDescription.swapsXyz) {
1719
-
1723
final tradeFrom = trade.from;
1724
1725
if (tradeFrom == null) {
@@ -1726,7 +1729,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
1729
);
1730
}
1731
1729
- final isNativeSupportedToken = walletTypes.contains(cryptoCurrencyOrTokenToWalletType(tradeFrom));
1732
+ final isNativeSupportedToken =
1733
+ walletTypes.contains(cryptoCurrencyOrTokenToWalletType(tradeFrom));
1734
1735
if (!isNativeSupportedToken) {
1736
bool _isEthToken() =>
@@ -1734,10 +1738,11 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
1738
1739
bool _isPolygonToken() =>
1740
wallet.currency == CryptoCurrency.maticpoly &&
1737
- tradeFrom.tag == CryptoCurrency.maticpoly.tag;
1741
+ tradeFrom.tag == CryptoCurrency.maticpoly.tag;
1742
1743
bool _isBaseToken() =>
1740
- wallet.currency == CryptoCurrency.baseEth && tradeFrom.tag == CryptoCurrency.baseEth.tag;
1744
+ wallet.currency == CryptoCurrency.baseEth &&
1745
+ tradeFrom.tag == CryptoCurrency.baseEth.tag;
1746
1747
bool _isTronToken() =>
1748
wallet.currency == CryptoCurrency.trx && tradeFrom.tag == CryptoCurrency.trx.title;
@@ -1751,14 +1756,20 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
1756
bool isBscToken() =>
1757
wallet.currency == CryptoCurrency.bnb && tradeFrom.tag == CryptoCurrency.bnb.tag;
1758
1754
- if(!(_isEthToken() || _isPolygonToken() || _isBaseToken() || _isTronToken() || _isSplToken() || isArbitrumToken() || isBscToken())) {
1759
+ if (!(_isEthToken() ||
1760
+ _isPolygonToken() ||
1761
+ _isBaseToken() ||
1762
+ _isTronToken() ||
1763
+ _isSplToken() ||
1764
+ isArbitrumToken() ||
1765
+ isBscToken())) {
1766
return CreateTradeResult(
1767
result: false,
1757
- errorMessage: 'This token isn’t supported on the current wallet/network for Swaps.xyz. Switch to a supported wallet or asset',
1768
+ errorMessage:
1769
+ 'This token isn’t supported on the current wallet/network for Swaps.xyz. Switch to a supported wallet or asset',
1770
);
1771
}
1772
}
1761
-
1773
}
1774
1775
if (trade.provider == ExchangeProviderDescription.thorChain) {
lib/view_model/hardware_wallet/bitbox_view_model.dart
+3
-2
@@ -25,7 +25,7 @@ abstract class BitboxViewModelBase extends HardwareWalletViewModel with Store {
25
BitboxViewModelBase() {
26
if (!Platform.isIOS && !isMoneroOnly) {
27
bitboxManager = sdk.BitboxManager();
28
- }
28
+ }
29
}
30
31
@override
@@ -100,7 +100,8 @@ abstract class BitboxViewModelBase extends HardwareWalletViewModel with Store {
100
switch (wallet.type) {
101
case WalletType.bitcoin:
102
case WalletType.litecoin:
103
- return bitcoin!.setHardwareWalletService(wallet, await getHardwareWalletService(wallet.type));
103
+ return bitcoin!
104
+ .setHardwareWalletService(wallet, await getHardwareWalletService(wallet.type));
105
case WalletType.ethereum:
106
case WalletType.polygon:
107
return evm!.setHardwareWalletService(wallet, await getHardwareWalletService(wallet.type));
lib/view_model/hardware_wallet/hardware_wallet_view_model.dart
-1
@@ -27,4 +27,3 @@ abstract class HardwareWalletViewModel {
27
28
String? interpretErrorCode(String error) => null;
29
}
30
-
lib/view_model/hardware_wallet/ledger_view_model.dart
+9
-11
@@ -120,14 +120,12 @@ abstract class LedgerViewModelBase extends HardwareWalletViewModel with Store {
120
} catch (_) {}
121
}
122
123
- final ledger = device.connectionType == HardwareWalletConnectionType.ble
124
- ? ledgerPlusBLE
125
- : ledgerPlusUSB;
123
+ final ledger =
124
+ device.connectionType == HardwareWalletConnectionType.ble ? ledgerPlusBLE : ledgerPlusUSB;
125
126
if (_connectionChangeSubscription == null) {
128
- _connectionChangeSubscription = ledger
129
- .deviceStateChanges(device.device.id)
130
- .listen(_connectionChangeListener);
127
+ _connectionChangeSubscription =
128
+ ledger.deviceStateChanges(device.device.id).listen(_connectionChangeListener);
129
}
130
131
try {
@@ -182,9 +180,11 @@ abstract class LedgerViewModelBase extends HardwareWalletViewModel with Store {
180
case WalletType.monero:
181
return monero!.setLedgerConnection(wallet, connection);
182
case WalletType.bitcoin:
185
- return bitcoin!.setHardwareWalletService(wallet, await getHardwareWalletService(wallet.type));
183
+ return bitcoin!
184
+ .setHardwareWalletService(wallet, await getHardwareWalletService(wallet.type));
185
case WalletType.litecoin:
187
- return bitcoin!.setHardwareWalletService(wallet, await getHardwareWalletService(wallet.type));
186
+ return bitcoin!
187
+ .setHardwareWalletService(wallet, await getHardwareWalletService(wallet.type));
188
case WalletType.ethereum:
189
case WalletType.polygon:
190
return evm!.setHardwareWalletService(wallet, await getHardwareWalletService(wallet.type));
@@ -210,7 +210,6 @@ abstract class LedgerViewModelBase extends HardwareWalletViewModel with Store {
210
}
211
}
212
213
-
213
@override
214
String? interpretErrorCode(String error) {
215
if (error.contains("Make sure no other program is communicating with the Ledger")) {
@@ -224,8 +223,7 @@ abstract class LedgerViewModelBase extends HardwareWalletViewModel with Store {
223
return S.current.ledger_error_tx_rejected_by_user;
224
} else if (errorCode.contains("5515")) {
225
return S.current.ledger_error_device_locked;
227
- } else
228
- if (["6e01", "6a87", "6d02", "6511", "6e00"].any((e) => errorCode.contains(e))) {
226
+ } else if (["6e01", "6a87", "6d02", "6511", "6e00"].any((e) => errorCode.contains(e))) {
227
return S.current.ledger_error_wrong_app;
228
}
229
return null;
lib/view_model/hardware_wallet/trezor_connect_view_model.dart
+7
-10
@@ -142,12 +142,10 @@ abstract class TrezorConnectViewModelBase extends HardwareWalletViewModel with S
142
isDismissible: false,
143
enableDrag: false,
144
useSafeArea: true,
145
- builder: (context) =>
146
- HardwareWalletProceedOnDeviceSheet(
147
- hardwareWalletType: hardwareWalletType,
148
- trezorConnectVM: this,
149
- onRetry: () => connectDevice(device, type, true)
150
- ),
145
+ builder: (context) => HardwareWalletProceedOnDeviceSheet(
146
+ hardwareWalletType: hardwareWalletType,
147
+ trezorConnectVM: this,
148
+ onRetry: () => connectDevice(device, type, true)),
149
);
150
}
151
@@ -234,7 +232,6 @@ abstract class TrezorConnectViewModelBase extends HardwareWalletViewModel with S
232
}
233
}
234
237
-
235
abstract class TrezorParingState {
236
static TrezorParingState initial = InitialTrezorParingState();
237
static TrezorParingState enterPin = EnterPinTrezorParingState();
@@ -243,11 +240,11 @@ abstract class TrezorParingState {
240
static TrezorParingState fail(String message) => FailTrezorParingState(message);
241
}
242
246
-class InitialTrezorParingState extends TrezorParingState {}
243
+class InitialTrezorParingState extends TrezorParingState {}
244
248
-class EnterPinTrezorParingState extends TrezorParingState {}
245
+class EnterPinTrezorParingState extends TrezorParingState {}
246
250
-class VerifyingPinTrezorParingState extends TrezorParingState {}
247
+class VerifyingPinTrezorParingState extends TrezorParingState {}
248
249
class SuccessTrezorParingState extends TrezorParingState {}
250
lib/view_model/integrations/deuro_view_model.dart
+3
-2
@@ -23,7 +23,8 @@ class DEuroViewModel = DEuroViewModelBase with _$DEuroViewModel;
23
abstract class DEuroViewModelBase with Store {
24
final AppStore _appStore;
25
26
- static Money get MIN_ACCRUED_INTEREST => Money(BigInt.parse("1000000000000"), CryptoCurrency.deuro);
26
+ static Money get MIN_ACCRUED_INTEREST =>
27
+ Money(BigInt.parse("1000000000000"), CryptoCurrency.deuro);
28
29
static Money get ZERO => Money.zero(CryptoCurrency.deuro);
30
@@ -178,7 +179,7 @@ abstract class DEuroViewModelBase with Store {
179
}
180
181
final amount = tryParseFixed(amountRaw, 18);
181
-
182
+
183
if (amount == BigInt.zero || amount == null) {
184
throw Exception("Invalid amount: amount cannot be zero");
185
}
lib/view_model/monero_account_list/account_list_item.dart
+1
-2
@@ -1,6 +1,5 @@
1
class AccountListItem {
2
- AccountListItem(
3
- {required this.label, required this.id, this.balance, this.isSelected = false});
2
+ AccountListItem({required this.label, required this.id, this.balance, this.isSelected = false});
3
4
final String label;
5
final int id;
lib/view_model/monero_account_list/monero_account_edit_or_create_view_model.dart
+7
-16
@@ -21,7 +21,7 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
21
{required WalletBase wallet, AccountListItem? accountListItem})
22
: state = InitialExecutionState(),
23
isEdit = accountListItem != null,
24
- label = accountListItem?.label??'',
24
+ label = accountListItem?.label ?? '',
25
_accountListItem = accountListItem,
26
_wallet = wallet;
27
@@ -76,14 +76,10 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
76
state = IsExecutingState();
77
78
if (_accountListItem != null) {
79
- await _moneroAccountList.setLabelAccount(
80
- _wallet,
81
- accountIndex: _accountListItem.id,
82
- label: label);
79
+ await _moneroAccountList.setLabelAccount(_wallet,
80
+ accountIndex: _accountListItem.id, label: label);
81
} else {
84
- await _moneroAccountList.addAccount(
85
- _wallet,
86
- label: label);
82
+ await _moneroAccountList.addAccount(_wallet, label: label);
83
}
84
85
await _wallet.save();
@@ -98,14 +94,10 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
94
state = IsExecutingState();
95
96
if (_accountListItem != null) {
101
- await _wowneroAccountList?.setLabelAccount(
102
- _wallet,
103
- accountIndex: _accountListItem.id,
104
- label: label);
97
+ await _wowneroAccountList?.setLabelAccount(_wallet,
98
+ accountIndex: _accountListItem.id, label: label);
99
} else {
106
- await _wowneroAccountList?.addAccount(
107
- _wallet,
108
- label: label);
100
+ await _wowneroAccountList?.addAccount(_wallet, label: label);
101
}
102
103
await _wallet.save();
@@ -114,5 +106,4 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
106
state = FailureState(e.toString());
107
}
108
}
117
-
109
}
lib/view_model/monero_account_list/monero_account_list_view_model.dart
+22
-21
@@ -10,11 +10,10 @@ import 'package:cake_wallet/monero/monero.dart';
10
11
part 'monero_account_list_view_model.g.dart';
12
13
-class MoneroAccountListViewModel = MoneroAccountListViewModelBase
14
- with _$MoneroAccountListViewModel;
13
+class MoneroAccountListViewModel = MoneroAccountListViewModelBase with _$MoneroAccountListViewModel;
14
15
abstract class MoneroAccountListViewModelBase with Store {
17
- MoneroAccountListViewModelBase(this._wallet,this.settingsStore) : scrollOffsetFromTop = 0;
16
+ MoneroAccountListViewModelBase(this._wallet, this.settingsStore) : scrollOffsetFromTop = 0;
17
18
final SettingsStore settingsStore;
19
@@ -32,25 +31,27 @@ abstract class MoneroAccountListViewModelBase with Store {
31
List<AccountListItem> get accounts {
32
final hideBalance = settingsStore.balanceDisplayMode == BalanceDisplayMode.hiddenBalance;
33
if (_wallet.type == WalletType.monero) {
35
- return monero
36
- !.getAccountList(_wallet)
37
- .accounts.map((acc) => AccountListItem(
38
- label: acc.label,
39
- id: acc.id,
40
- balance: hideBalance ? '●●●●●●' : acc.balance,
41
- isSelected: acc.id == monero!.getCurrentAccount(_wallet).id))
42
- .toList();
34
+ return monero!
35
+ .getAccountList(_wallet)
36
+ .accounts
37
+ .map((acc) => AccountListItem(
38
+ label: acc.label,
39
+ id: acc.id,
40
+ balance: hideBalance ? '●●●●●●' : acc.balance,
41
+ isSelected: acc.id == monero!.getCurrentAccount(_wallet).id))
42
+ .toList();
43
}
44
45
if (_wallet.type == WalletType.wownero) {
46
- return wownero
47
- !.getAccountList(_wallet)
48
- .accounts.map((acc) => AccountListItem(
49
- label: acc.label,
50
- id: acc.id,
51
- balance: hideBalance ? '●●●●●●' : acc.balance,
52
- isSelected: acc.id == wownero!.getCurrentAccount(_wallet).id))
53
- .toList();
46
+ return wownero!
47
+ .getAccountList(_wallet)
48
+ .accounts
49
+ .map((acc) => AccountListItem(
50
+ label: acc.label,
51
+ id: acc.id,
52
+ balance: hideBalance ? '●●●●●●' : acc.balance,
53
+ isSelected: acc.id == wownero!.getCurrentAccount(_wallet).id))
54
+ .toList();
55
}
56
57
throw Exception('Unexpected wallet type: ${_wallet.type} for monero');
@@ -71,7 +72,7 @@ abstract class MoneroAccountListViewModelBase with Store {
72
item.id,
73
item.label,
74
item.balance,
74
- );
75
+ );
76
}
77
78
if (_wallet.type == WalletType.wownero) {
@@ -80,7 +81,7 @@ abstract class MoneroAccountListViewModelBase with Store {
81
item.id,
82
item.label,
83
item.balance,
83
- );
84
+ );
85
}
86
}
87
}
lib/view_model/node_list/node_create_or_edit_view_model.dart
+11
-20
@@ -12,28 +12,25 @@ import 'package:permission_handler/permission_handler.dart';
12
13
part 'node_create_or_edit_view_model.g.dart';
14
15
-class NodeCreateOrEditViewModel = NodeCreateOrEditViewModelBase
16
- with _$NodeCreateOrEditViewModel;
15
+class NodeCreateOrEditViewModel = NodeCreateOrEditViewModelBase with _$NodeCreateOrEditViewModel;
16
17
abstract class NodeCreateOrEditViewModelBase with Store {
19
- NodeCreateOrEditViewModelBase(
20
- this.isPow, this.walletType, this._settingsStore, {this.editingNode})
18
+ NodeCreateOrEditViewModelBase(this.isPow, this.walletType, this._settingsStore,
19
+ {this.editingNode})
20
: state = InitialExecutionState(),
21
connectionState = InitialExecutionState(),
22
label = editingNode?.label ?? '',
23
address = editingNode?.uri.host.toString() ?? '',
24
path = editingNode?.path.toString() ?? '',
26
- port = (editingNode != null && editingNode.uri.hasPort)
27
- ? editingNode.uri.port.toString()
28
- : '',
25
+ port =
26
+ (editingNode != null && editingNode.uri.hasPort) ? editingNode.uri.port.toString() : '',
27
login = editingNode?.login ?? '',
28
password = editingNode?.password ?? '',
29
socksProxyAddress = editingNode?.socksProxyAddress ?? '',
30
trusted = editingNode?.trusted ?? false,
33
- isEnabledForAutoSwitching =
34
- editingNode?.isEnabledForAutoSwitching ?? false,
35
- useSocksProxy = editingNode?.socksProxyAddress != null &&
36
- editingNode!.socksProxyAddress!.isNotEmpty,
31
+ isEnabledForAutoSwitching = editingNode?.isEnabledForAutoSwitching ?? false,
32
+ useSocksProxy =
33
+ editingNode?.socksProxyAddress != null && editingNode!.socksProxyAddress!.isNotEmpty,
34
useSSL = editingNode?.useSSL ?? false {}
35
36
final nodeLabelUIKey = 'node_label_row_key';
@@ -113,11 +110,9 @@ abstract class NodeCreateOrEditViewModelBase with Store {
110
@observable
111
bool isPow;
112
116
-
113
@computed
114
bool get isReady =>
119
- (address.isNotEmpty) ||
120
- walletType == WalletType.decred; // Allow an empty address.
115
+ (address.isNotEmpty) || walletType == WalletType.decred; // Allow an empty address.
116
117
bool get hasAuthCredentials =>
118
walletType == WalletType.monero ||
@@ -240,8 +235,7 @@ abstract class NodeCreateOrEditViewModelBase with Store {
235
void setTrusted(bool val) => trusted = val;
236
237
@action
243
- void setIsEnabledForAutoSwitching(bool val) =>
244
- isEnabledForAutoSwitching = val;
238
+ void setIsEnabledForAutoSwitching(bool val) => isEnabledForAutoSwitching = val;
239
240
@action
241
void setSocksProxy(bool val) => useSocksProxy = val;
@@ -276,7 +270,6 @@ abstract class NodeCreateOrEditViewModelBase with Store {
270
}
271
272
state = ExecutedSuccessfullyState();
279
-
273
} catch (e) {
274
state = FailureState(e.toString());
275
}
@@ -303,7 +296,6 @@ abstract class NodeCreateOrEditViewModelBase with Store {
296
}
297
}
298
306
-
299
@action
300
void setAsCurrent(Node node) => _settingsStore.nodes[walletType] = node;
301
@@ -320,8 +312,7 @@ abstract class NodeCreateOrEditViewModelBase with Store {
312
throw Exception('Unexpected scan QR code value: value is empty');
313
}
314
323
- if (code.startsWith("monero_node:"))
324
- code = code.replaceFirst("monero_node:", "tcp://");
315
+ if (code.startsWith("monero_node:")) code = code.replaceFirst("monero_node:", "tcp://");
316
if (!code.contains('://')) code = 'tcp://$code';
317
318
final uri = Uri.tryParse(code);
lib/view_model/node_list/node_list_view_model.dart
+14
-20
@@ -16,7 +16,6 @@ import 'package:cake_wallet/reactions/wallet_connect.dart';
16
17
part 'node_list_view_model.g.dart';
18
19
-
19
class NodeSpeed {
20
final String iconPath;
21
final String darkIconPath;
@@ -24,21 +23,20 @@ class NodeSpeed {
23
// fraction of best node ping needed to be classified as this speed.
24
final double treshold;
25
27
- const NodeSpeed._(this.iconPath, this.darkIconPath, this.treshold);
26
+ const NodeSpeed._(this.iconPath, this.darkIconPath, this.treshold);
27
29
- static const disconnected = NodeSpeed._(
30
- "assets/new-ui/node_speed_badges/disconnected.svg", "assets/new-ui/node_speed_badges/disconnected-dark.svg", 0);
31
- static const slow = NodeSpeed._(
32
- "assets/new-ui/node_speed_badges/slow.svg", "assets/new-ui/node_speed_badges/slow-dark.svg", 0);
33
- static const medium = NodeSpeed._(
34
- "assets/new-ui/node_speed_badges/medium.svg", "assets/new-ui/node_speed_badges/medium.svg", 0.5);
28
+ static const disconnected = NodeSpeed._("assets/new-ui/node_speed_badges/disconnected.svg",
29
+ "assets/new-ui/node_speed_badges/disconnected-dark.svg", 0);
30
+ static const slow = NodeSpeed._("assets/new-ui/node_speed_badges/slow.svg",
31
+ "assets/new-ui/node_speed_badges/slow-dark.svg", 0);
32
+ static const medium = NodeSpeed._("assets/new-ui/node_speed_badges/medium.svg",
33
+ "assets/new-ui/node_speed_badges/medium.svg", 0.5);
34
static const fast = NodeSpeed._(
35
"assets/new-ui/node_speed_badges/fast.svg", "assets/new-ui/node_speed_badges/fast.svg", 0.8);
36
37
static const all = [fast, medium, slow, disconnected];
38
}
39
41
-
40
class NodeListViewModel = NodeListViewModelBase with _$NodeListViewModel;
41
42
abstract class NodeListViewModelBase with Store {
@@ -63,7 +61,6 @@ abstract class NodeListViewModelBase with Store {
61
bindNodes();
62
});
63
}
66
-
64
65
@computed
66
Node get currentNode {
@@ -103,9 +100,8 @@ abstract class NodeListViewModelBase with Store {
100
final bool isPow;
101
final ObservableMap<String, int> _nodeSpeeds;
102
106
-
103
@computed
108
- List<Node> get nonCurrentNodes => nodes.where((item)=>item != currentNode).toList();
104
+ List<Node> get nonCurrentNodes => nodes.where((item) => item != currentNode).toList();
105
106
@observable
107
bool isTestingNodeSpeed = false;
@@ -117,9 +113,8 @@ abstract class NodeListViewModelBase with Store {
113
final nodes = this.nodes.toList();
114
await Future.wait(nodes.map((node) async {
115
final sw = Stopwatch()..start();
120
- final res = await node
121
- .requestNode()
122
- .timeout(const Duration(seconds: 10), onTimeout: () => false);
116
+ final res =
117
+ await node.requestNode().timeout(const Duration(seconds: 10), onTimeout: () => false);
118
sw.stop();
119
if (res) {
120
_nodeSpeeds[node.uriRaw] = sw.elapsedMilliseconds;
@@ -163,7 +158,6 @@ abstract class NodeListViewModelBase with Store {
158
Node node;
159
if (walletType == WalletType.bitcoin && wallet.isTestnet) {
160
node = (await getBitcoinTestnetDefaultElectrumServer())!;
166
-
161
} else if (isEVMCompatibleChain(walletType)) {
162
final chainId = evm!.getSelectedChainId(wallet);
163
if (chainId != null) {
@@ -205,12 +199,11 @@ abstract class NodeListViewModelBase with Store {
199
}
200
201
// For non-EVM wallets, use the wallet type directly
208
- if(isPow) {
202
+ if (isPow) {
203
settingsStore.powNodes[walletType] = node;
204
} else {
205
settingsStore.nodes[walletType] = node;
206
}
213
-
207
}
208
209
@action
@@ -235,7 +228,8 @@ abstract class NodeListViewModelBase with Store {
228
}
229
230
// For non-EVM wallets, use the wallet type directly
238
- nodes.addAll(isPow ? await Node.getAllForWalletTypePow(walletType) : await Node.getAllForWalletType(walletType));
239
-
231
+ nodes.addAll(isPow
232
+ ? await Node.getAllForWalletTypePow(walletType)
233
+ : await Node.getAllForWalletType(walletType));
234
}
235
}
lib/view_model/node_list/pow_node_list_view_model.dart
+1
@@ -0,0 +1 @@
1
+
lib/view_model/payjoin_details_view_model.dart
+2
-4
@@ -18,8 +18,7 @@ import 'package:url_launcher/url_launcher.dart';
18
19
part 'payjoin_details_view_model.g.dart';
20
21
-class PayjoinDetailsViewModel = PayjoinDetailsViewModelBase
22
- with _$PayjoinDetailsViewModel;
21
+class PayjoinDetailsViewModel = PayjoinDetailsViewModelBase with _$PayjoinDetailsViewModel;
22
23
abstract class PayjoinDetailsViewModelBase with Store {
24
PayjoinDetailsViewModelBase(
@@ -61,8 +60,7 @@ abstract class PayjoinDetailsViewModelBase with Store {
60
),
61
TradeDetailsListCardItem(
62
id: "${payjoinSession.isSenderSession ? S.current.outgoing : S.current.incoming} Payjoin",
64
- createdAt:
65
- dateFormat.format(payjoinSession.inProgressSince!).toString(),
63
+ createdAt: dateFormat.format(payjoinSession.inProgressSince!).toString(),
64
pair:
65
'${bitcoin!.formatterBitcoinAmountToString(amount: payjoinSession.amount.toInt())} BTC',
66
onTap: (_) {},
lib/view_model/rescan_view_model.dart
+1
-1
@@ -31,7 +31,7 @@ abstract class RescanViewModelBase with Store {
31
32
@computed
33
bool get isMwebScan => wallet.type == WalletType.litecoin;
34
-
34
+
35
Future<bool> get isBitcoinMempoolAPIEnabled async =>
36
wallet.type == WalletType.bitcoin && await bitcoin!.checkIfMempoolAPIIsEnabled(wallet);
37
lib/view_model/restore/restore_mode.dart
+1
-1
@@ -1 +1 @@
1
-enum WalletRestoreMode { seed, keys, txids }
\ No newline at end of file
1
+enum WalletRestoreMode { seed, keys, txids }
lib/view_model/restore_from_backup_view_model.dart
+3
-2
@@ -32,7 +32,7 @@ abstract class RestoreFromBackupViewModelBase with Store {
32
void reset() => filePath = '';
33
34
@action
35
- Future<void> import(String password,{bool checkBackupApp = true}) async {
35
+ Future<void> import(String password, {bool checkBackupApp = true}) async {
36
try {
37
state = IsExecutingState();
38
@@ -49,7 +49,8 @@ abstract class RestoreFromBackupViewModelBase with Store {
49
rethrow;
50
} catch (e, s) {
51
if (e.toString().contains("unknown_backup_version")) {
52
- state = FailureState('This is not a valid backup file, please make sure you have selected the correct one');
52
+ state = FailureState(
53
+ 'This is not a valid backup file, please make sure you have selected the correct one');
54
} else {
55
state = FailureState(e.toString() + "\n" + s.toString());
56
}
lib/view_model/seed_settings_view_model.dart
+2
-1
@@ -14,7 +14,8 @@ abstract class SeedSettingsViewModelBase with Store {
14
MoneroSeedType get moneroSeedType => _appStore.settingsStore.moneroSeedType;
15
16
@action
17
- void setMoneroSeedType(MoneroSeedType seedType) => _appStore.settingsStore.moneroSeedType = seedType;
17
+ void setMoneroSeedType(MoneroSeedType seedType) =>
18
+ _appStore.settingsStore.moneroSeedType = seedType;
19
20
@computed
21
BitcoinSeedType get bitcoinSeedType => _appStore.settingsStore.bitcoinSeedType;
lib/view_model/send/output.dart
+8
-7
@@ -37,8 +37,7 @@ class Output = OutputBase with _$Output;
37
38
abstract class OutputBase with Store {
39
OutputBase(this._wallet, this._appStore, this._fiatConversationStore, this.cryptoCurrencyHandler)
40
- :
41
- key = UniqueKey(),
40
+ : key = UniqueKey(),
41
sendAll = false,
42
cryptoAmount = '',
43
cryptoFullBalance = '',
@@ -57,7 +56,6 @@ abstract class OutputBase with Store {
56
});
57
}
58
60
-
59
Key key;
60
61
bool get useSatoshi => _appStore.amountParsingProxy.useSatoshi(cryptoCurrencyHandler());
@@ -98,7 +96,6 @@ abstract class OutputBase with Store {
96
@observable
97
String extractedAddress;
98
101
-
99
@computed
100
bool get isParsedAddress =>
101
parsedAddress.addressSource != AddressSource.notParsed && parsedAddress.handle.isNotEmpty;
@@ -172,9 +169,11 @@ abstract class OutputBase with Store {
169
break;
170
case WalletType.tron:
171
if (cryptoCurrencyHandler() == CryptoCurrency.trx) {
175
- estimatedFee = tron!.getTronNativeEstimatedFee(_wallet) ?? Money.zero(CryptoCurrency.trx);
172
+ estimatedFee =
173
+ tron!.getTronNativeEstimatedFee(_wallet) ?? Money.zero(CryptoCurrency.trx);
174
} else {
177
- estimatedFee = tron!.getTronTRC20EstimatedFee(_wallet) ?? Money.zero(CryptoCurrency.trx);
175
+ estimatedFee =
176
+ tron!.getTronTRC20EstimatedFee(_wallet) ?? Money.zero(CryptoCurrency.trx);
177
}
178
break;
179
@@ -200,7 +199,8 @@ abstract class OutputBase with Store {
199
? evm!.getEVMNativeEstimatedFee(_wallet)
200
: evm!.getEVMERC20EstimatedFee(_wallet);
201
203
- estimatedFee = Money(BigInt.parse(fee ?? '0.0'), walletTypeToCryptoCurrency(_wallet.type));
202
+ estimatedFee =
203
+ Money(BigInt.parse(fee ?? '0.0'), walletTypeToCryptoCurrency(_wallet.type));
204
break;
205
206
/// end EVMs
@@ -293,6 +293,7 @@ abstract class OutputBase with Store {
293
}
294
295
@action
296
+
297
/// [setCryptoAmount] always takes in the canonical representation eg. Bitcoin and not Sats
298
void setCryptoAmount(String amount) {
299
if (amount.toUpperCase() != S.current.all) sendAll = false;
lib/view_model/send/send_template_view_model.dart
+1
-3
@@ -35,9 +35,7 @@ abstract class SendTemplateViewModelBase with Store {
35
@action
36
void addRecipient() {
37
recipients.add(TemplateViewModel(
38
- wallet: _wallet,
39
- appStore: _appStore,
40
- fiatConversationStore: _fiatConversationStore));
38
+ wallet: _wallet, appStore: _appStore, fiatConversationStore: _fiatConversationStore));
39
}
40
41
@action
lib/view_model/send/send_view_model.dart
+60
-84
@@ -85,8 +85,8 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
85
currencies = wallet.balance.keys.toList();
86
selectedCryptoCurrency =
87
coinTypeToSpendFrom == UnspentCoinType.lightning ? CryptoCurrency.btcln : wallet.currency;
88
- hasMultipleTokens = isEVMWallet ||
89
- [WalletType.solana, WalletType.tron, WalletType.zano].contains(wallet.type);
88
+ hasMultipleTokens =
89
+ isEVMWallet || [WalletType.solana, WalletType.tron, WalletType.zano].contains(wallet.type);
90
91
for (final output in outputs) {
92
output.updateWallet(wallet);
@@ -195,7 +195,6 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
195
if (isValidAddress) return null;
196
}
197
198
-
198
final results = await _adrResService.resolve(
199
query: query,
200
wallet: wallet,
@@ -411,9 +410,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
410
411
final sp = RegExp(AddressValidator.silentPaymentAddressPatternMainnet);
412
414
- final address = output.extractedAddress.isNotEmpty
415
- ? output.extractedAddress
416
- : output.address;
413
+ final address = output.extractedAddress.isNotEmpty ? output.extractedAddress : output.address;
414
415
return sp.hasMatch(address);
416
}
@@ -467,7 +464,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
464
FiatCurrency get fiatCurrency => _settingsStore.fiatCurrency;
465
466
set fiatCurrency(FiatCurrency value) {
470
- _settingsStore.fiatCurrency = value;
467
+ _settingsStore.fiatCurrency = value;
468
}
469
470
List<FiatCurrency> fiatCurrencies;
@@ -530,7 +527,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
527
528
@computed
529
TransactionInfo? get transactionInfo {
533
- if(isEVMCompatibleChain(walletType)) {
530
+ if (isEVMCompatibleChain(walletType)) {
531
return wallet.transactionHistory.transactions[pendingTransaction?.evmTxHashFromRawHex];
532
}
533
if (walletType == WalletType.monero) {
@@ -633,7 +630,9 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
630
clearOutputs();
631
632
outputs.first.address = paymentRequest.address;
636
- outputs.first.parsedAddress = ParsedAddress(parsedAddressByCurrencyMap: {currency:paymentRequest.address}, handle: ocpRequest!.receiverName);
633
+ outputs.first.parsedAddress = ParsedAddress(
634
+ parsedAddressByCurrencyMap: {currency: paymentRequest.address},
635
+ handle: ocpRequest!.receiverName);
636
outputs.first.setCryptoAmount(paymentRequest.amount);
637
outputs.first.note = ocpRequest!.receiverName;
638
@@ -694,13 +693,10 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
693
final routerTo = trade.inputAddress;
694
final routerData = trade.routerData;
695
697
-
696
if (routerData != null && routerData != '0x') {
697
final tokenContract = (trade.sourceTokenAddress ?? '').toLowerCase();
700
- final priority = _settingsStore.getPriority(
701
- walletType, chainId: selectedChainId);
702
- final routerValueWei = BigInt.tryParse(trade.routerValue ?? '0') ??
703
- BigInt.zero;
698
+ final priority = _settingsStore.getPriority(walletType, chainId: selectedChainId);
699
+ final routerValueWei = BigInt.tryParse(trade.routerValue ?? '0') ?? BigInt.zero;
700
701
if (routerTo == null || routerTo.isEmpty) {
702
state = FailureState('Invalid router address');
@@ -730,33 +726,26 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
726
727
// Smart Swap (Requires Approval)
728
if (selector == swapAndExecuteSig) {
733
- final requiredAmount = BigInt.tryParse(
734
- (trade.sourceTokenAmountRaw ?? '0').replaceAll('n', '')) ??
735
- BigInt.zero;
736
-
737
- final needsApproval = tokenContract.isNotEmpty &&
738
- requiredAmount > BigInt.zero
739
- ? await evm!.isApprovalRequired(
740
- wallet, tokenContract, routerTo, requiredAmount)
729
+ final requiredAmount =
730
+ BigInt.tryParse((trade.sourceTokenAmountRaw ?? '0').replaceAll('n', '')) ??
731
+ BigInt.zero;
732
+
733
+ final needsApproval = tokenContract.isNotEmpty && requiredAmount > BigInt.zero
734
+ ? await evm!.isApprovalRequired(wallet, tokenContract, routerTo, requiredAmount)
735
: false;
736
737
printV(
744
- '[Swaps.xyz sending flow] Approval required: $needsApproval for token ${trade
745
- .from?.title} ${trade.from?.tag ??
746
- ''} with amount $requiredAmount');
738
+ '[Swaps.xyz sending flow] Approval required: $needsApproval for token ${trade.from?.title} ${trade.from?.tag ?? ''} with amount $requiredAmount');
739
740
if (needsApproval) {
741
// USDT Approval Flow (Special Case). We must reset allowance to 0 first.
742
final isUSDTMainnet = selectedChainId == 1 &&
751
- tokenContract.toLowerCase() ==
752
- '0xdac17f958d2ee523a2206206994597c13d831ec7';
743
+ tokenContract.toLowerCase() == '0xdac17f958d2ee523a2206206994597c13d831ec7';
744
745
if (isUSDTMainnet) {
755
- final currentAllowance = await evm!.getAllowance(
756
- wallet, tokenContract, routerTo);
746
+ final currentAllowance = await evm!.getAllowance(wallet, tokenContract, routerTo);
747
758
- if (currentAllowance != null &&
759
- currentAllowance > BigInt.zero) {
748
+ if (currentAllowance != null && currentAllowance > BigInt.zero) {
749
printV(
750
'[Swaps.xyz sending flow] currentAllowance USDT: $currentAllowance. Resetting to 0 before setting new allowance.');
751
@@ -766,8 +755,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
755
requiredAmount: BigInt.zero,
756
// Approve 0
757
sourceTokenDecimals: trade.sourceTokenDecimals,
769
- priority: priority
770
- );
758
+ priority: priority);
759
760
if (resetTx != null) {
761
await resetTx.commit();
@@ -780,8 +768,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
768
);
769
770
if (!resetConfirmed) {
783
- state = FailureState(
784
- 'Failed to reset USDT allowance. Please try again.');
771
+ state = FailureState('Failed to reset USDT allowance. Please try again.');
772
return null;
773
}
774
printV(
@@ -796,8 +783,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
783
tokenContract: tokenContract,
784
requiredAmount: requiredAmount,
785
sourceTokenDecimals: trade.sourceTokenDecimals,
799
- priority: priority
800
- );
786
+ priority: priority);
787
788
if (approvalTx == null) {
789
state = FailureState('Failed to build approval transaction');
@@ -808,8 +794,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
794
795
try {
796
printV(
811
- '[Swaps.xyz sending flow] Submitting approval transaction for token ${trade
812
- .from?.title} ${trade.from?.tag ?? ''} ');
797
+ '[Swaps.xyz sending flow] Submitting approval transaction for token ${trade.from?.title} ${trade.from?.tag ?? ''} ');
798
await approvalTx.commit();
799
800
// Wait for the approval to be mined on-chain
@@ -827,10 +812,8 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
812
printV(
813
'[Swaps.xyz sending flow] Approval transaction confirmed on-chain. Proceeding with swap execution.');
814
} catch (e, s) {
830
- printV(
831
- '[Swaps.xyz sending flow] Approval transaction error: $e\n$s');
832
- state = FailureState(
833
- translateErrorMessage(e, wallet.type, wallet.currency));
815
+ printV('[Swaps.xyz sending flow] Approval transaction error: $e\n$s');
816
+ state = FailureState(translateErrorMessage(e, wallet.type, wallet.currency));
817
return null;
818
}
819
}
@@ -859,8 +842,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
842
} catch (e, s) {
843
printV('Swaps.xyz transaction error: $e\n$s');
844
state = FailureState(
862
- 'Failed to create Swaps.xyz transaction - ${translateErrorMessage(
863
- e, wallet.type, wallet.currency)}');
845
+ 'Failed to create Swaps.xyz transaction - ${translateErrorMessage(e, wallet.type, wallet.currency)}');
846
return null;
847
}
848
}
@@ -902,14 +884,12 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
884
885
// Regular flow
886
905
-
887
final isSendAll = outputs.any((output) => output.sendAll);
907
-
888
+
889
if (!isSendAll) {
909
- final estimateTxAmountDouble = outputs.fold<double>(0, (acc, output) =>
910
- acc + (double.tryParse(output.cryptoAmount) ?? 0));
911
- if (estimateTxAmountDouble <= 0) throw Exception(
912
- 'Amount must be greater than 0');
890
+ final estimateTxAmountDouble = outputs.fold<double>(
891
+ 0, (acc, output) => acc + (double.tryParse(output.cryptoAmount) ?? 0));
892
+ if (estimateTxAmountDouble <= 0) throw Exception('Amount must be greater than 0');
893
}
894
895
pendingTransaction = await wallet.createTransaction(_credentials(provider));
@@ -942,7 +922,6 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
922
}
923
}
924
945
-
925
if (wallet.type == WalletType.bitcoin) {
926
final updatedOutputs = bitcoin!.updateOutputs(pendingTransaction!, outputs);
927
@@ -1030,7 +1009,6 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
1009
throw Exception("Pending transaction doesn't exist. It should not be happened.");
1010
}
1011
1033
-
1012
try {
1013
state = wallet.isHardwareWallet && walletType == WalletType.monero
1014
? IsAwaitingDeviceResponseState()
@@ -1124,7 +1102,9 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
1102
}
1103
1104
// Immediate transaction update for EVM chains, Tron, and Nano
1127
- if (isEVMWallet || [WalletType.bitcoin, WalletType.solana, WalletType.tron, WalletType.nano].contains(walletType)) {
1105
+ if (isEVMWallet ||
1106
+ [WalletType.bitcoin, WalletType.solana, WalletType.tron, WalletType.nano]
1107
+ .contains(walletType)) {
1108
Future.delayed(Duration(seconds: 4), () async {
1109
try {
1110
await Future.wait([
@@ -1140,7 +1120,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
1120
// FIXME(malik) ideally, this should be done wallet-side.
1121
// it is required because evm, solana and tron don't actually save the transaction info when you send something.
1122
// instead, they rely on the tx to eventually get fetched at sync time, which can take a while
1143
- if(isEVMWallet) {
1123
+ if (isEVMWallet) {
1124
wallet.transactionHistory.addOne(evm!.getTransactionInfo(
1125
id: pendingTransaction!.evmTxHashFromRawHex!,
1126
height: 0,
@@ -1154,8 +1134,8 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
1134
chainId: wallet.chainId ?? 0,
1135
));
1136
}
1157
-
1158
- if(walletType == WalletType.solana) {
1137
+
1138
+ if (walletType == WalletType.solana) {
1139
wallet.transactionHistory.addOne(solana!.getTransactionInfo(
1140
id: pendingTransaction!.id,
1141
blockTime: DateTime.now(),
@@ -1211,7 +1191,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
1191
Future<void> updateWalletBalance() async => await wallet.updateBalance();
1192
1193
Future<void> _addTransactionDescription() async {
1214
- String address = outputs.fold('', (acc, value) {
1194
+ String address = outputs.fold('', (acc, value) {
1195
final canonical = value.extractedAddress.trim().isNotEmpty
1196
? value.extractedAddress.trim()
1197
: value.address.trim();
@@ -1360,15 +1340,15 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
1340
@computed
1341
int get maxMemoLength => _maxMemoLengths[wallet.type] ?? 9999999;
1342
1363
-
1343
ContactRecord? newContactAddress() {
1344
final Set<String> contactAddresses =
1345
Set.from(contactListViewModel.contacts.map((contact) => contact.address))
1346
..addAll(contactListViewModel.walletContacts.map((contact) => contact.address));
1347
1348
for (final output in outputs) {
1370
- final address =
1371
- output.isParsedAddress ? output.parsedAddress.parsedAddressByCurrencyMap[selectedCryptoCurrency] ?? '' : output.address;
1349
+ final address = output.isParsedAddress
1350
+ ? output.parsedAddress.parsedAddressByCurrencyMap[selectedCryptoCurrency] ?? ''
1351
+ : output.address;
1352
1353
if (address.isNotEmpty &&
1354
!contactAddresses.contains(address) &&
@@ -1400,14 +1380,16 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
1380
int attempts = 0;
1381
const int maxAttempts = 30; // ~60 seconds
1382
1403
- printV('[Swaps.xyz sending flow] Starting allowance check. Target: $requiredAmount (Exact match: $waitForExactMatch)');
1383
+ printV(
1384
+ '[Swaps.xyz sending flow] Starting allowance check. Target: $requiredAmount (Exact match: $waitForExactMatch)');
1385
1386
while (attempts < maxAttempts) {
1387
try {
1388
final currentAllowance = await evm!.getAllowance(wallet, tokenContract, spender);
1389
1390
if (currentAllowance != null) {
1410
- printV('[Swaps.xyz sending flow] Current Allowance: $currentAllowance / Target: $requiredAmount');
1391
+ printV(
1392
+ '[Swaps.xyz sending flow] Current Allowance: $currentAllowance / Target: $requiredAmount');
1393
1394
if (waitForExactMatch) {
1395
// For Reset (Target 0): We need it to be exactly 0 (or less, though it can't be negative)
@@ -1443,17 +1425,16 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
1425
required TransactionPriority? priority,
1426
int? sourceTokenDecimals,
1427
}) async {
1446
-
1428
final erc20Token = wallet.balance.keys.whereType<Erc20Token>().firstWhere(
1429
(t) => t.contractAddress.toLowerCase() == tokenContract.toLowerCase(),
1449
- orElse: () => Erc20Token(
1450
- name: '',
1451
- symbol: '',
1452
- contractAddress: tokenContract,
1453
- decimal: sourceTokenDecimals ?? 18,
1454
- enabled: true,
1455
- ),
1456
- );
1430
+ orElse: () => Erc20Token(
1431
+ name: '',
1432
+ symbol: '',
1433
+ contractAddress: tokenContract,
1434
+ decimal: sourceTokenDecimals ?? 18,
1435
+ enabled: true,
1436
+ ),
1437
+ );
1438
1439
return await evm!.createTokenApproval(
1440
wallet,
@@ -1461,7 +1442,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
1442
spender,
1443
priority,
1444
useBlinkProtection:
1464
- canSupportBlinkProtection(selectedChainId) ? _settingsStore.useBlinkProtection : false,
1445
+ canSupportBlinkProtection(selectedChainId) ? _settingsStore.useBlinkProtection : false,
1446
);
1447
}
1448
@@ -1646,9 +1627,9 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
1627
return S.current.tx_invalid_input;
1628
}
1629
1649
- if(wallet.type == WalletType.bitcoin) {
1630
+ if (wallet.type == WalletType.bitcoin) {
1631
final lnError = getLightningErrorMessage(error);
1651
- if(lnError != null) return lnError;
1632
+ if (lnError != null) return lnError;
1633
}
1634
1635
return errorMessage;
@@ -1656,12 +1637,10 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
1637
1638
String? getLightningErrorMessage(Object error) {
1639
// TODO add more patterns
1659
- Map<String, String> errorPatterns = {
1660
- "insufficient funds": S.current.insufficient_funds_for_tx
1661
- };
1640
+ Map<String, String> errorPatterns = {"insufficient funds": S.current.insufficient_funds_for_tx};
1641
1663
- for(final pattern in errorPatterns.keys) {
1664
- if(error.toString().contains(pattern)) return errorPatterns[pattern]!;
1642
+ for (final pattern in errorPatterns.keys) {
1643
+ if (error.toString().contains(pattern)) return errorPatterns[pattern]!;
1644
}
1645
1646
return null;
@@ -1677,7 +1656,6 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
1656
1657
Future<void> registerSwapsXyzTransaction(Trade trade) async {
1658
try {
1680
-
1659
// register only for vmId is alt-vm or bridgeId is alt-vm (trade.needToRegisterInSwapXyz)
1660
final needToRegister = trade.needToRegisterInSwapXyz ?? false;
1661
if (!needToRegister) return;
@@ -1688,9 +1666,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
1666
return;
1667
}
1668
1691
- final txHash = pendingTransaction?.evmTxHashFromRawHex
1692
- ?? pendingTransaction?.id
1693
- ?? '';
1669
+ final txHash = pendingTransaction?.evmTxHashFromRawHex ?? pendingTransaction?.id ?? '';
1670
1671
if (txHash.isEmpty) {
1672
printV('SwapsXyz: transaction register: skipped (txHash empty)');
lib/view_model/send/send_view_model_state.dart
+3
@@ -1,6 +1,9 @@
1
import 'package:cake_wallet/core/execution_state.dart';
2
3
class IsDeviceSigningResponseState extends IsExecutingState {}
4
+
5
class IsAwaitingDeviceResponseState extends IsExecutingState {}
6
+
7
class TransactionCommitting extends ExecutionState {}
8
+
9
class TransactionCommitted extends ExecutionState {}
lib/view_model/settings/connection_sync_view_model.dart
+4
-2
@@ -232,7 +232,6 @@ abstract class ConnectionSyncViewModelBase with Store {
232
@computed
233
bool get canUseTronGrid => _wallet.type == WalletType.tron;
234
235
-
235
@action
236
void setUseMempoolFeeAPI(bool value) => _settingsStore.useMempoolFeeAPI = value;
237
@@ -249,7 +248,10 @@ abstract class ConnectionSyncViewModelBase with Store {
248
@action
249
void setUseBlinkProtection(bool value) => _settingsStore.useBlinkProtection = value;
250
252
- bool get hasRescan => _wallet.hasRescan && _wallet.type != WalletType.bitcoin && _wallet.type != WalletType.litecoin;
251
+ bool get hasRescan =>
252
+ _wallet.hasRescan &&
253
+ _wallet.type != WalletType.bitcoin &&
254
+ _wallet.type != WalletType.litecoin;
255
256
@action
257
void setUseEtherscan(bool value) {
lib/view_model/settings/display_settings_view_model.dart
+3
-2
@@ -59,7 +59,7 @@ abstract class DisplaySettingsViewModelBase with Store {
59
60
@computed
61
bool get showAddressBookPopup => _settingsStore.showAddressBookPopupEnabled;
62
-
62
+
63
@computed
64
bool get showZcashCard => _settingsStore.showZcashMissingFundsCard;
65
@@ -126,7 +126,8 @@ abstract class DisplaySettingsViewModelBase with Store {
126
bool get showZcashCardSetting => _appStore.wallet?.type == WalletType.zcash;
127
128
@action
129
- void setDisplayAmountsInSatoshi(BitcoinAmountDisplayMode value) => _settingsStore.displayAmountsInSatoshi = value;
129
+ void setDisplayAmountsInSatoshi(BitcoinAmountDisplayMode value) =>
130
+ _settingsStore.displayAmountsInSatoshi = value;
131
132
@action
133
void setShowZcashCard(bool value) => _settingsStore.showZcashMissingFundsCard = value;
lib/view_model/settings/link_list_item.dart
+6
-6
@@ -5,11 +5,11 @@ import 'package:flutter/material.dart';
5
class LinkListItem extends SettingsListItem {
6
LinkListItem(
7
{required String title,
8
- required this.link,
9
- required this.linkTitle,
10
- this.icon,
11
- this.lightIcon,
12
- this.hasIconColor = false})
8
+ required this.link,
9
+ required this.linkTitle,
10
+ this.icon,
11
+ this.lightIcon,
12
+ this.hasIconColor = false})
13
: super(title);
14
15
final String? icon;
@@ -17,4 +17,4 @@ class LinkListItem extends SettingsListItem {
17
final String link;
18
final String linkTitle;
19
final bool hasIconColor;
20
-}
\ No newline at end of file
20
+}
lib/view_model/settings/other_settings_view_model.dart
+9
-9
@@ -66,18 +66,18 @@ abstract class OtherSettingsViewModelBase with Store {
66
void setAutoGenerateSubaddresses(bool value) {
67
_wallet.isEnabledAutoGenerateSubaddress = value;
68
_settingsStore.autoGenerateSubaddressStatus =
69
- value ? AutoGenerateSubaddressStatus.enabled : AutoGenerateSubaddressStatus.disabled;
69
+ value ? AutoGenerateSubaddressStatus.enabled : AutoGenerateSubaddressStatus.disabled;
70
}
71
72
bool get isAutoGenerateSubaddressesVisible => [
73
- WalletType.monero,
74
- WalletType.wownero,
75
- WalletType.bitcoin,
76
- WalletType.litecoin,
77
- WalletType.bitcoinCash,
78
- WalletType.dogecoin,
79
- WalletType.decred
80
- ].contains(_wallet.type);
73
+ WalletType.monero,
74
+ WalletType.wownero,
75
+ WalletType.bitcoin,
76
+ WalletType.litecoin,
77
+ WalletType.bitcoinCash,
78
+ WalletType.dogecoin,
79
+ WalletType.decred
80
+ ].contains(_wallet.type);
81
82
@computed
83
bool get isMoneroWallet => _wallet.type == WalletType.monero;
lib/view_model/settings/privacy_settings_view_model.dart
+3
-3
@@ -49,8 +49,7 @@ abstract class PrivacySettingsViewModelBase with Store {
49
].contains(_wallet.type);
50
51
@computed
52
- bool get hasCoinControl =>
53
- [
52
+ bool get hasCoinControl => [
53
WalletType.bitcoin,
54
WalletType.litecoin,
55
WalletType.monero,
@@ -112,7 +111,8 @@ abstract class PrivacySettingsViewModelBase with Store {
111
bool get canUsePayjoin => _wallet.type == WalletType.bitcoin && DeviceInfo.instance.isMobile;
112
113
@computed
115
- bool get canUseLightning => _wallet.type == WalletType.bitcoin && !Platform.isWindows && !Platform.isLinux;
114
+ bool get canUseLightning =>
115
+ _wallet.type == WalletType.bitcoin && !Platform.isWindows && !Platform.isLinux;
116
117
@computed
118
bool get useLightning => _wallet.type == WalletType.bitcoin && bitcoin!.useLightning(_wallet);
lib/view_model/settings/regular_list_item.dart
+1
-1
@@ -5,4 +5,4 @@ class RegularListItem extends SettingsListItem {
5
RegularListItem({required String title, this.handler}) : super(title);
6
7
final void Function(BuildContext context)? handler;
8
-}
\ No newline at end of file
8
+}
lib/view_model/settings/security_settings_view_model.dart
+3
-4
@@ -9,7 +9,8 @@ part 'security_settings_view_model.g.dart';
9
class SecuritySettingsViewModel = SecuritySettingsViewModelBase with _$SecuritySettingsViewModel;
10
11
abstract class SecuritySettingsViewModelBase with Store {
12
- SecuritySettingsViewModelBase(this._settingsStore, this._authService) : _biometricAuth = BiometricAuth();
12
+ SecuritySettingsViewModelBase(this._settingsStore, this._authService)
13
+ : _biometricAuth = BiometricAuth();
14
15
final BiometricAuth _biometricAuth;
16
final SettingsStore _settingsStore;
@@ -51,9 +52,7 @@ abstract class SecuritySettingsViewModelBase with Store {
52
_settingsStore.pinTimeOutDuration = duration;
53
54
@action
54
- void setEnableDuressPin(bool value) =>
55
- _settingsStore.enableDuressPin = value;
55
+ void setEnableDuressPin(bool value) => _settingsStore.enableDuressPin = value;
56
57
Future<void> clearDuressPin() async => await _authService.clearDuressPin();
58
-
58
}
lib/view_model/settings/switcher_list_item.dart
+1
-4
@@ -3,10 +3,7 @@ import 'package:flutter/foundation.dart';
3
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})
6
+ SwitcherListItem({required String title, required this.value, required this.onValueChange})
7
: super(title);
8
9
final bool Function() value;
lib/view_model/settings/trocador_providers_view_model.dart
+1
-4
@@ -28,10 +28,7 @@ abstract class TrocadorProvidersViewModelBase with Store {
28
ObservableFuture(trocadorExchangeProvider.fetchProviders().then((providers) {
29
var providerNames = providers.map((e) => e.name).toList();
30
31
- providerRatings = {
32
- for (var provider in providers)
33
- provider.name: provider.rating
34
- };
31
+ providerRatings = {for (var provider in providers) provider.name: provider.rating};
32
33
return _settingsStore
34
.updateAllTrocadorProviderStates(providerNames)
lib/view_model/settings/version_list_item.dart
+1
-1
@@ -3,4 +3,4 @@ import 'package:cake_wallet/view_model/settings/settings_list_item.dart';
3
4
class VersionListItem extends SettingsListItem {
5
VersionListItem({required String title}) : super(title);
6
-}
\ No newline at end of file
6
+}
lib/view_model/setup_pin_code_view_model.dart
+1
-4
@@ -4,8 +4,7 @@ import 'package:cake_wallet/entities/secret_store_key.dart';
4
import 'package:cake_wallet/store/settings_store.dart';
5
6
class SetupPinCodeViewModel {
7
- SetupPinCodeViewModel(this._authService, this._settingsStore,
8
- {this.isDuressPin = false})
7
+ SetupPinCodeViewModel(this._authService, this._settingsStore, {this.isDuressPin = false})
8
: _pinCodeLength = _settingsStore.pinCodeLength;
9
10
String originalPinCode = '';
@@ -46,7 +45,6 @@ class SetupPinCodeViewModel {
45
originalPinCode = pin;
46
47
if (isDuressPin && pin.length == pinCodeLength) {
49
-
48
final regularKey = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
49
final encodedRegularPin = await _authService.secureStorage.read(key: regularKey);
50
@@ -84,7 +82,6 @@ class SetupPinCodeViewModel {
82
return;
83
}
84
87
-
85
await _authService.setPassword(repeatedPinCode);
86
_settingsStore.pinCodeLength = pinCodeLength;
87
}
lib/view_model/start_tor_view_model.dart
+8
-5
@@ -40,7 +40,7 @@ abstract class StartTorViewModelBase with Store {
40
remainingSeconds = waitTimeInSeconds;
41
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
42
remainingSeconds -= 1;
43
-
43
+
44
if (remainingSeconds <= 0) {
45
timer.cancel();
46
timeoutReached = true;
@@ -66,7 +66,8 @@ abstract class StartTorViewModelBase with Store {
66
didStartTor = true;
67
final appStore = getIt.get<AppStore>();
68
bootstrapOnline(navigatorKey, loadWallet: true);
69
- appStore.wallet?.connectToNode(node: appStore.settingsStore.getCurrentNode(appStore.wallet!.type));
69
+ appStore.wallet
70
+ ?.connectToNode(node: appStore.settingsStore.getCurrentNode(appStore.wallet!.type));
71
Navigator.pushReplacementNamed(context, Routes.login);
72
}
73
@@ -76,7 +77,8 @@ abstract class StartTorViewModelBase with Store {
77
settingsStore.currentBuiltinTor = false;
78
bootstrapOnline(navigatorKey, loadWallet: true);
79
final appStore = getIt.get<AppStore>();
79
- appStore.wallet?.connectToNode(node: appStore.settingsStore.getCurrentNode(appStore.wallet!.type));
80
+ appStore.wallet
81
+ ?.connectToNode(node: appStore.settingsStore.getCurrentNode(appStore.wallet!.type));
82
Navigator.pushReplacementNamed(context, Routes.login);
83
}
84
@@ -84,7 +86,8 @@ abstract class StartTorViewModelBase with Store {
86
void ignoreAndLaunchApp(BuildContext context) {
87
bootstrapOnline(navigatorKey, loadWallet: true);
88
final appStore = getIt.get<AppStore>();
87
- appStore.wallet?.connectToNode(node: appStore.settingsStore.getCurrentNode(appStore.wallet!.type));
89
+ appStore.wallet
90
+ ?.connectToNode(node: appStore.settingsStore.getCurrentNode(appStore.wallet!.type));
91
Navigator.pushReplacementNamed(context, Routes.login);
92
}
93
@@ -92,4 +95,4 @@ abstract class StartTorViewModelBase with Store {
95
_timer?.cancel();
96
_timer = null;
97
}
95
-}
\ No newline at end of file
98
+}
lib/view_model/trade_details_view_model.dart
+10
-14
@@ -117,13 +117,13 @@ abstract class TradeDetailsViewModelBase with Store {
117
case ExchangeProviderDescription.chainflip:
118
return 'https://scan.chainflip.io/channels/${trade.id}';
119
case ExchangeProviderDescription.xoSwap:
120
- return 'https://orders.xoswap.com/${trade.id}';
120
+ return 'https://orders.xoswap.com/${trade.id}';
121
case ExchangeProviderDescription.swapsXyz:
122
- return 'https://scan.swaps.xyz/transactions/${trade.id}';
122
+ return 'https://scan.swaps.xyz/transactions/${trade.id}';
123
case ExchangeProviderDescription.jupiter:
124
return 'https://solscan.io/tx/${trade.txId}';
125
case ExchangeProviderDescription.nearIntents:
126
- return 'https://explorer.near-intents.org/transactions/${trade.id}';
126
+ return 'https://explorer.near-intents.org/transactions/${trade.id}';
127
}
128
return null;
129
}
@@ -167,7 +167,7 @@ abstract class TradeDetailsViewModelBase with Store {
167
DetailsListStatusItem(title: S.current.trade_details_state, value: trade.state.toString()));
168
169
final tradeFrom = trade.from;
170
- final tradeTo = trade.to;
170
+ final tradeTo = trade.to;
171
172
if (tradeFrom != null && tradeTo != null) {
173
items.add(TradeDetailsListCardItem.tradeDetails(
@@ -185,9 +185,7 @@ abstract class TradeDetailsViewModelBase with Store {
185
186
final destinationMemo = trade.toAddressExtraId;
187
final destinationCurrency = trade.to;
188
- if (destinationMemo != null &&
189
- destinationMemo.isNotEmpty &&
190
- destinationCurrency != null) {
188
+ if (destinationMemo != null && destinationMemo.isNotEmpty && destinationCurrency != null) {
189
final isDestinationTag =
190
memoLabelTypeFor(destinationCurrency) == MemoLabelType.destinationTag;
191
items.add(StandartListItem(
@@ -205,8 +203,7 @@ abstract class TradeDetailsViewModelBase with Store {
203
}
204
205
if (trade.isRefund == true) {
208
- items.add(StandartListItem(
209
- title: 'Refund', value: trade.refundAddress ?? ''));
206
+ items.add(StandartListItem(title: 'Refund', value: trade.refundAddress ?? ''));
207
}
208
209
if (trade.provider == ExchangeProviderDescription.trocador) {
@@ -220,9 +217,10 @@ abstract class TradeDetailsViewModelBase with Store {
217
}
218
}
219
223
- if (trade.provider == ExchangeProviderDescription.swapsXyz && trade.txId != null && trade.txId!.isNotEmpty) {
224
- items.add(StandartListItem(
225
- title: 'Transaction ID', value: trade.txId!));
220
+ if (trade.provider == ExchangeProviderDescription.swapsXyz &&
221
+ trade.txId != null &&
222
+ trade.txId!.isNotEmpty) {
223
+ items.add(StandartListItem(title: 'Transaction ID', value: trade.txId!));
224
}
225
}
226
@@ -232,6 +230,4 @@ abstract class TradeDetailsViewModelBase with Store {
230
launchUrl(uri, mode: LaunchMode.externalApplication);
231
} catch (e) {}
232
}
235
-
236
-
233
}
lib/view_model/transaction_details_view_model.dart
+13
-39
@@ -76,7 +76,9 @@ class TxDetailRowDefinition {
76
TxDetailRowDefinition(
77
keyString: "standard_list_item_transaction_details_date_key",
78
title: S.current.transaction_details_date,
79
- valueGetter: (vm) => DateFormat("d MMMM yyyy, HH:mm", vm._appStore.settingsStore.languageCode).format(vm.transactionInfo.date)),
79
+ valueGetter: (vm) =>
80
+ DateFormat("d MMMM yyyy, HH:mm", vm._appStore.settingsStore.languageCode)
81
+ .format(vm.transactionInfo.date)),
82
TxDetailRowDefinition(
83
keyString: "standard_list_item_transaction_details_height_key",
84
title: S.current.transaction_details_height,
@@ -85,7 +87,6 @@ class TxDetailRowDefinition {
87
![WalletType.solana, WalletType.tron].contains(vm.wallet.type) ||
88
!isLightning(vm.transactionInfo),
89
),
88
-
90
TxDetailRowDefinition(
91
keyString: "standard_list_item_transaction_details_fee_key",
92
title: S.current.transaction_details_fee,
@@ -93,8 +94,6 @@ class TxDetailRowDefinition {
94
applicable: (vm) =>
95
vm.wallet.type != WalletType.nano &&
96
(vm.transactionInfo.fee?.toStringWithSymbol() ?? "").isNotEmpty),
96
-
97
-
97
TxDetailRowDefinition(
98
keyString: "standard_list_item_transaction_confirmations_key",
99
title: S.current.confirmations,
@@ -104,8 +103,6 @@ class TxDetailRowDefinition {
103
.contains(vm.wallet.type) &&
104
!isLightning(vm.transactionInfo),
105
listItemBuilder: ConfirmationsListItem.new),
107
-
108
-
106
TxDetailRowDefinition(
107
keyString: "standard_list_item_transaction_details_recipient_address_key",
108
title: S.current.transaction_details_recipient_address,
@@ -125,12 +122,12 @@ class TxDetailRowDefinition {
122
.firstOrNull ??
123
"";
124
case WalletType.tron:
128
- if(vm.transactionInfo.to != null)
129
- ret = tron!.getTronBase58Address(vm.transactionInfo.to!, vm.wallet);
125
+ if (vm.transactionInfo.to != null)
126
+ ret = tron!.getTronBase58Address(vm.transactionInfo.to!, vm.wallet);
127
default:
128
break;
129
}
133
- if(ret == null) {
130
+ if (ret == null) {
131
ret = vm.transactionInfo.to ?? "";
132
}
133
final resolvedAddress = _moneroRecipientAddressForDisplay(ret, vm.wallet.type);
@@ -144,8 +141,6 @@ class TxDetailRowDefinition {
141
vm.wallet.type == WalletType.bitcoin &&
142
vm.transactionInfo.direction == TransactionDirection.incoming),
143
listItemBuilder: AddressListItem.new),
147
-
148
-
144
TxDetailRowDefinition(
145
keyString: "standard_list_item_transaction_details_source_address_key",
146
title: S.current.transaction_details_source_address,
@@ -159,7 +154,6 @@ class TxDetailRowDefinition {
154
},
155
applicable: (vm) => vm.transactionInfo.from != null,
156
listItemBuilder: AddressListItem.new),
162
-
157
TxDetailRowDefinition(
158
keyString: "standard_list_item_address_label_key",
159
title: S.current.address_label,
@@ -168,8 +162,6 @@ class TxDetailRowDefinition {
162
vm.transactionInfo.additionalInfo['accountIndex'] as int,
163
vm.transactionInfo.additionalInfo['addressIndex'] as int),
164
applicable: (vm) => vm.wallet.type == WalletType.monero),
171
-
172
-
165
TxDetailRowDefinition(
166
keyString: "standard_list_item_transaction_key",
167
title: S.current.transaction_key,
@@ -185,7 +177,6 @@ class TxDetailRowDefinition {
177
"";
178
},
179
applicable: (vm) => vm.wallet.type == WalletType.monero),
188
-
180
TxDetailRowDefinition(
181
keyString: "standard_list_item_lightning_preimage",
182
title: S.current.transaction_preimage,
@@ -193,14 +184,11 @@ class TxDetailRowDefinition {
184
applicable: (vm) =>
185
hasLightningPreimage(vm.transactionInfo) && isLightning(vm.transactionInfo),
186
),
196
-
187
TxDetailRowDefinition(
188
keyString: "standard_list_item_transaction_confirmed_key",
189
title: S.current.confirmed_tx,
190
valueGetter: (vm) => (vm.transactionInfo.confirmations > 0).toString(),
191
applicable: (vm) => vm.wallet.type == WalletType.nano),
202
-
203
-
192
TxDetailRowDefinition(
193
keyString: "standard_list_item_transaction_details_memo_key",
194
title: S.current.memo,
@@ -208,23 +196,17 @@ class TxDetailRowDefinition {
196
applicable: (vm) =>
197
vm.wallet.type == WalletType.zcash &&
198
vm.transactionInfo.additionalInfo["memo"] != null),
211
-
212
-
199
TxDetailRowDefinition(
200
keyString: "standard_list_item_transaction_details_asset_id_key",
201
title: "Asset ID",
202
valueGetter: (vm) =>
203
vm.transactionInfo.additionalInfo["assetId"] as String? ?? "Unknown asset id",
204
applicable: (vm) => vm.wallet.type == WalletType.zano),
219
-
220
-
205
TxDetailRowDefinition(
206
keyString: "standard_list_item_transaction_details_comment_key",
207
title: S.current.transaction_details_title,
208
valueGetter: (vm) => vm.transactionInfo.additionalInfo['comment'] as String? ?? "",
209
applicable: (vm) => vm.wallet.type == WalletType.zano),
226
-
227
-
210
TxDetailRowDefinition(
211
keyString: "standard_list_item_transaction_details_id_key",
212
title: S.current.transaction_details_transaction_id,
@@ -272,7 +254,8 @@ abstract class TransactionDetailsViewModelBase with Store {
254
final recipientAddress = description.recipientAddress;
255
256
if (recipientAddress?.isNotEmpty ?? false) {
275
- final recipientAddressForDisplay = _moneroRecipientAddressForDisplay(recipientAddress!, wallet.type);
257
+ final recipientAddressForDisplay =
258
+ _moneroRecipientAddressForDisplay(recipientAddress!, wallet.type);
259
items.add(
260
AddressListItem(
261
title: S.current.transaction_details_recipient_address,
@@ -287,7 +270,7 @@ abstract class TransactionDetailsViewModelBase with Store {
270
void updateNote(String note) {
271
final descriptionKey = '${transactionInfo.txHash}_${wallet.walletAddresses.primaryAddress}';
272
final description = transactionDescriptionBox.values.firstWhere(
290
- (val) => val.id == descriptionKey || val.id == transactionInfo.txHash,
273
+ (val) => val.id == descriptionKey || val.id == transactionInfo.txHash,
274
orElse: () => TransactionDescription(id: descriptionKey));
275
276
description.transactionNote = note;
@@ -301,9 +284,9 @@ abstract class TransactionDetailsViewModelBase with Store {
284
285
String get note {
286
final descriptionKey = '${transactionInfo.txHash}_${wallet.walletAddresses.primaryAddress}';
304
- final description = transactionDescriptionBox.values.firstWhereOrNull(
305
- (val) => val.id == descriptionKey || val.id == transactionInfo.txHash);
306
- return description?.transactionNote??"";
287
+ final description = transactionDescriptionBox.values
288
+ .firstWhereOrNull((val) => val.id == descriptionKey || val.id == transactionInfo.txHash);
289
+ return description?.transactionNote ?? "";
290
}
291
292
final TransactionInfo transactionInfo;
@@ -400,16 +383,13 @@ abstract class TransactionDetailsViewModelBase with Store {
383
case WalletType.litecoin:
384
bool isPegOut = (transactionInfo.additionalInfo["isPegOut"] as bool?) ?? false;
385
bool fromPegOut = (transactionInfo.additionalInfo["fromPegOut"] as bool?) ?? false;
403
- if(isPegOut || fromPegOut)
404
- return 6;
386
+ if (isPegOut || fromPegOut) return 6;
387
default:
388
return 0;
389
}
390
return 0;
391
}
392
411
-
412
-
393
String get formattedTitle {
394
if (transactionInfo.additionalInfo['autoShield'] == true) {
395
return "Autoshield";
@@ -425,7 +405,6 @@ abstract class TransactionDetailsViewModelBase with Store {
405
bool canReplaceByFee;
406
407
String get _explorerUrl {
428
-
408
final txId = transactionInfo.txHash;
409
if (wallet.chainId != null) {
410
final explorerUrl = evm!.getExplorerUrlForChainId(wallet.chainId!);
@@ -569,9 +548,6 @@ abstract class TransactionDetailsViewModelBase with Store {
548
}
549
}
550
572
-
573
-
574
-
551
@action
552
Future<void> _checkForRBF(TransactionInfo tx) async {
553
if (wallet.type == WalletType.bitcoin &&
@@ -634,6 +610,4 @@ abstract class TransactionDetailsViewModelBase with Store {
610
String get pendingTransactionFeeFiatAmountFormatted => sendViewModel.isFiatDisabled
611
? ''
612
: sendViewModel.pendingTransactionFeeFiatAmount + ' ' + sendViewModel.fiat.title;
637
-
638
-
613
}
lib/view_model/unspent_coins/unspent_coins_details_view_model.dart
+2
-1
@@ -46,7 +46,8 @@ abstract class UnspentCoinsDetailsViewModelBase with Store {
46
})
47
];
48
49
- if ([WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash, WalletType.dogecoin].contains(_type)) {
49
+ if ([WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash, WalletType.dogecoin]
50
+ .contains(_type)) {
51
items.add(BlockExplorerListItem(
52
title: S.current.view_in_block_explorer,
53
value: _explorerDescription(_type),
lib/view_model/unspent_coins/unspent_coins_item.dart
+13
-15
@@ -6,20 +6,19 @@ part 'unspent_coins_item.g.dart';
6
class UnspentCoinsItem = UnspentCoinsItemBase with _$UnspentCoinsItem;
7
8
abstract class UnspentCoinsItemBase with Store, UnspentComparable {
9
- UnspentCoinsItemBase({
10
- required this.address,
11
- required this.amount,
12
- required this.hash,
13
- required this.isFrozen,
14
- required this.note,
15
- required this.isSending,
16
- required this.isChange,
17
- required this.value,
18
- required this.vout,
19
- required this.keyImage,
20
- required this.isSilentPayment,
21
- this.isBeingSaved = false
22
- });
9
+ UnspentCoinsItemBase(
10
+ {required this.address,
11
+ required this.amount,
12
+ required this.hash,
13
+ required this.isFrozen,
14
+ required this.note,
15
+ required this.isSending,
16
+ required this.isChange,
17
+ required this.value,
18
+ required this.vout,
19
+ required this.keyImage,
20
+ required this.isSilentPayment,
21
+ this.isBeingSaved = false});
22
23
@observable
24
String address;
@@ -54,7 +53,6 @@ abstract class UnspentCoinsItemBase with Store, UnspentComparable {
53
@observable
54
bool isSilentPayment;
55
57
-
56
@observable
57
bool isBeingSaved;
58
}
lib/view_model/unspent_coins/unspent_coins_list_view_model.dart
+5
-5
@@ -50,10 +50,10 @@ abstract class UnspentCoinsListViewModelBase with Store {
50
ObservableList<UnspentCoinsItem> items;
51
52
@computed
53
- List<UnspentCoinsItem> get nonFrozenItems => items.where((e)=>!e.isFrozen).toList();
53
+ List<UnspentCoinsItem> get nonFrozenItems => items.where((e) => !e.isFrozen).toList();
54
55
@computed
56
- List<UnspentCoinsItem> get frozenItems => items.where((e)=>e.isFrozen).toList();
56
+ List<UnspentCoinsItem> get frozenItems => items.where((e) => e.isFrozen).toList();
57
58
final Map<String, Map<String, dynamic>> _originalState;
59
@@ -74,7 +74,6 @@ abstract class UnspentCoinsListViewModelBase with Store {
74
75
@computed
76
Map<String, String> get fiatAmounts {
77
-
77
final currency = wallet.currency;
78
final price = _fiatConversationStore.prices[currency];
79
if (price == null || price == 0.0 || isFiatDisabled) return {};
@@ -149,7 +148,8 @@ abstract class UnspentCoinsListViewModelBase with Store {
148
if (wallet.type == WalletType.wownero) {
149
await wownero!.updateUnspents(wallet);
150
}
152
- if ([WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash, WalletType.dogecoin].contains(wallet.type)) {
151
+ if ([WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash, WalletType.dogecoin]
152
+ .contains(wallet.type)) {
153
await bitcoin!.updateUnspents(wallet);
154
}
155
if (wallet.type == WalletType.decred) {
@@ -176,7 +176,7 @@ abstract class UnspentCoinsListViewModelBase with Store {
176
}
177
}
178
179
- List<Unspent> _getSpecificUnspents(UnspentCoinType overrideCoinTypeToSpendFrom) {
179
+ List<Unspent> _getSpecificUnspents(UnspentCoinType overrideCoinTypeToSpendFrom) {
180
switch (wallet.type) {
181
case WalletType.monero:
182
return monero!.getUnspents(wallet);
lib/view_model/unspent_coins/unspent_coins_switch_item.dart
+7
-6
@@ -1,12 +1,13 @@
1
import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart';
2
3
class UnspentCoinsSwitchItem extends TransactionDetailsListItem {
4
- UnspentCoinsSwitchItem({
5
- required String title,
6
- required String value,
7
- required this.switchValue,
8
- required this.onSwitchValueChange}) : super(title: title, value: value);
4
+ UnspentCoinsSwitchItem(
5
+ {required String title,
6
+ required String value,
7
+ required this.switchValue,
8
+ required this.onSwitchValueChange})
9
+ : super(title: title, value: value);
10
11
final bool Function() switchValue;
12
final void Function(bool value) onSwitchValueChange;
12
-}
\ No newline at end of file
13
+}
lib/view_model/wallet_address_list/wallet_account_list_header.dart
+1
-1
@@ -1,3 +1,3 @@
1
import 'package:cake_wallet/utils/list_item.dart';
2
3
-class WalletAccountListHeader extends ListItem {}
\ No newline at end of file
3
+class WalletAccountListHeader extends ListItem {}
lib/view_model/wallet_address_list/wallet_address_hidden_list_header.dart
+1
-1
@@ -1,3 +1,3 @@
1
import 'package:cake_wallet/utils/list_item.dart';
2
3
-class WalletAddressHiddenListHeader extends ListItem {}
\ No newline at end of file
3
+class WalletAddressHiddenListHeader extends ListItem {}
lib/view_model/wallet_address_list/wallet_address_list_item.dart
+15
-15
@@ -1,21 +1,21 @@
1
import 'package:cake_wallet/utils/list_item.dart';
2
3
class WalletAddressListItem extends ListItem {
4
- WalletAddressListItem({
5
- required this.address,
6
- required this.isPrimary,
7
- this.id,
8
- this.name,
9
- this.txCount,
10
- this.balance,
11
- this.isChange = false,
12
- // Address that is only ever used once, shouldn't be used to receive funds, copy and paste, share etc
13
- this.isOneTimeReceiveAddress = false,
14
- this.isHidden = false,
15
- this.isManual = false,
16
- this.isLegacyDerivation = false,
17
- this.derivationPath
18
- }) : super();
4
+ WalletAddressListItem(
5
+ {required this.address,
6
+ required this.isPrimary,
7
+ this.id,
8
+ this.name,
9
+ this.txCount,
10
+ this.balance,
11
+ this.isChange = false,
12
+ // Address that is only ever used once, shouldn't be used to receive funds, copy and paste, share etc
13
+ this.isOneTimeReceiveAddress = false,
14
+ this.isHidden = false,
15
+ this.isManual = false,
16
+ this.isLegacyDerivation = false,
17
+ this.derivationPath})
18
+ : super();
19
20
final int? id;
21
final bool isPrimary;
lib/view_model/wallet_address_list/wallet_address_list_view_model.dart
+17
-10
@@ -73,8 +73,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
73
74
double? _fiatRate;
75
76
- List<Currency> get currencies =>
77
- [tokenCurrency ?? wallet.currency, ...FiatCurrency.all];
76
+ List<Currency> get currencies => [tokenCurrency ?? wallet.currency, ...FiatCurrency.all];
77
78
List<Currency> get tokenCurrencies => wallet.balance.keys.toList();
79
@@ -86,7 +85,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
85
_appStore.amountParsingProxy.getCryptoSymbol(tokenCurrency ?? wallet.currency);
86
87
void setTokenCurrency(Currency curr) {
89
- if(curr == wallet.currency || curr == CryptoCurrency.btcln) {
88
+ if (curr == wallet.currency || curr == CryptoCurrency.btcln) {
89
tokenCurrency = null;
90
selectedCurrency = wallet.currency;
91
return;
@@ -144,7 +143,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
143
if (_amount.isEmpty) return "";
144
var cryptoCurrency = tokenCurrency ?? wallet.currency;
145
if (cryptoCurrency == CryptoCurrency.btcln) cryptoCurrency = CryptoCurrency.btc;
147
- if(selectedCurrency is FiatCurrency && _fiatRate != null) {
146
+ if (selectedCurrency is FiatCurrency && _fiatRate != null) {
147
return selectedCurrencyFiatAmount;
148
}
149
@@ -168,7 +167,10 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
167
168
// payjoinEndpoint getter is broken, but uri works
169
bool get hasPayjoin =>
171
- wallet.type == WalletType.bitcoin && !isLightning && !isSilentPayments && uri.toString().contains("payjo.in");
170
+ wallet.type == WalletType.bitcoin &&
171
+ !isLightning &&
172
+ !isSilentPayments &&
173
+ uri.toString().contains("payjo.in");
174
175
AmountParsingProxy get amountParsingProxy => _appStore.amountParsingProxy;
176
@@ -461,7 +463,8 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
463
String get walletTypeName => walletTypeToString(type);
464
465
@computed
464
- bool get hasAddressList => [
466
+ bool get hasAddressList =>
467
+ [
468
WalletType.monero,
469
WalletType.wownero,
470
WalletType.haven,
@@ -471,7 +474,9 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
474
WalletType.decred,
475
WalletType.dogecoin,
476
WalletType.zcash
474
- ].contains(wallet.type) && !isLightning && isZCashTransparent;
477
+ ].contains(wallet.type) &&
478
+ !isLightning &&
479
+ isZCashTransparent;
480
481
@computed
482
bool get hasAddressRotation => hasAddressList && wallet.type != WalletType.zcash;
@@ -576,11 +581,13 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
581
wallet.type == WalletType.bitcoin && bitcoin!.hasSelectedSilentPayments(wallet);
582
583
@computed
579
- bool get isLightning => wallet.type == WalletType.bitcoin && (wallet.walletAddresses.getPaymentUri(_amount) is LightningPaymentRequest);
584
+ bool get isLightning =>
585
+ wallet.type == WalletType.bitcoin &&
586
+ (wallet.walletAddresses.getPaymentUri(_amount) is LightningPaymentRequest);
587
588
@computed
589
bool get isZCashTransparent {
583
- if(wallet.type != WalletType.zcash) {
590
+ if (wallet.type != WalletType.zcash) {
591
return true;
592
}
593
receivePageOption;
@@ -619,7 +626,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
626
627
@action
628
Future<void> rotateAddress() async {
622
- if(isRotatingAddress) {
629
+ if (isRotatingAddress) {
630
return;
631
}
632
try {
lib/view_model/wallet_address_list/wallet_address_util.dart
+3
-7
@@ -25,18 +25,14 @@ Future<void> createNewAddress(WalletBase wallet, String label) async {
25
await monero!
26
.getSubaddressList(wallet)
27
.addSubaddress(wallet, accountIndex: monero!.getCurrentAccount(wallet).id, label: label);
28
- final subaddressList = await monero!
29
- .getSubaddressList(wallet)
30
- .subaddresses;
31
- if(subaddressList.isEmpty) {
28
+ final subaddressList = await monero!.getSubaddressList(wallet).subaddresses;
29
+ if (subaddressList.isEmpty) {
30
// this shouldn't happen, we just added an addr.
31
// somehow, it happened once in prod regardless.
32
// we just return instead of crashing, user can press the button again ig
33
return;
34
}
37
- final addr = subaddressList
38
- .first
39
- .address; // first because the order is reversed
35
+ final addr = subaddressList.first.address; // first because the order is reversed
36
wallet.walletAddresses.manualAddresses.add(addr);
37
await wallet.save();
38
}
lib/view_model/wallet_creation_vm.dart
+6
-7
@@ -25,8 +25,7 @@ part 'wallet_creation_vm.g.dart';
25
class WalletCreationVM = WalletCreationVMBase with _$WalletCreationVM;
26
27
abstract class WalletCreationVMBase with Store {
28
- WalletCreationVMBase(this._appStore, this.walletCreationService,
29
- this.seedSettingsViewModel,
28
+ WalletCreationVMBase(this._appStore, this.walletCreationService, this.seedSettingsViewModel,
29
{required this.type, required this.isRecovery})
30
: state = InitialExecutionState(),
31
name = '';
@@ -81,7 +80,6 @@ abstract class WalletCreationVMBase with Store {
80
Future<void> _create({dynamic options}) async {
81
final type = this.type;
82
try {
84
-
83
state = IsExecutingState();
84
if (name.isEmpty) {
85
name = await generateName();
@@ -101,9 +99,9 @@ abstract class WalletCreationVMBase with Store {
99
100
final credentials = getCredentials(options);
101
104
- final di = ((credentials.derivationInfo?.derivationPath??"") == "")
105
- ? getDefaultCreateDerivation()
106
- : credentials.derivationInfo;
102
+ final di = ((credentials.derivationInfo?.derivationPath ?? "") == "")
103
+ ? getDefaultCreateDerivation()
104
+ : credentials.derivationInfo;
105
106
final diId = await di!.save();
107
credentials.derivationInfo = di;
@@ -118,7 +116,8 @@ abstract class WalletCreationVMBase with Store {
116
path: path,
117
dirPath: dirPath,
118
address: '',
121
- showIntroCakePayCard: (!await walletCreationService.typeExists(type)) && type != WalletType.haven,
119
+ showIntroCakePayCard:
120
+ (!await walletCreationService.typeExists(type)) && type != WalletType.haven,
121
derivationInfoId: diId,
122
hardwareWalletType: credentials.hardwareWalletType,
123
);
lib/view_model/wallet_groups_display_view_model.dart
+11
-12
@@ -24,7 +24,7 @@ abstract class WalletGroupsDisplayViewModelBase with Store {
24
this._walletManager,
25
this.walletListViewModel, {
26
required this.type,
27
- }) : isFetchingMnemonic = false {
27
+ }) : isFetchingMnemonic = false {
28
reaction((_) => _appStore.wallet, (_) => unawaited(updateWalletInfoSourceList()));
29
unawaited(updateWalletInfoSourceList());
30
}
@@ -47,7 +47,6 @@ abstract class WalletGroupsDisplayViewModelBase with Store {
47
@observable
48
WalletInfo? selectedSingleWallet;
49
50
-
50
@observable
51
bool isFetchingMnemonic;
52
@@ -116,8 +115,8 @@ abstract class WalletGroupsDisplayViewModelBase with Store {
115
116
// Check for nano derivation type
117
final di = await wallet.getDerivationInfo();
119
- bool isNanoDerivationType = wallet.type == WalletType.nano &&
120
- di.derivationType == DerivationType.nano;
118
+ bool isNanoDerivationType =
119
+ wallet.type == WalletType.nano && di.derivationType == DerivationType.nano;
120
121
// Check for electrum derivation type
122
bool isElectrumDerivationType =
@@ -129,17 +128,17 @@ abstract class WalletGroupsDisplayViewModelBase with Store {
128
129
bool isNonSeedWallet = wallet.isNonSeedWallet;
130
132
- bool isNotMoneroBip39Wallet = wallet.type == WalletType.monero &&
133
- di.derivationType != DerivationType.bip39;
131
+ bool isNotMoneroBip39Wallet =
132
+ wallet.type == WalletType.monero && di.derivationType != DerivationType.bip39;
133
134
// Exclude if any of these conditions are true
135
shouldExcludeGroup = shouldExcludeGroup ||
137
- isNonBIP39Wallet ||
138
- isNanoDerivationType ||
139
- isElectrumDerivationType ||
140
- isSameTypeAsSelectedWallet ||
141
- isNonSeedWallet ||
142
- isNotMoneroBip39Wallet;
136
+ isNonBIP39Wallet ||
137
+ isNanoDerivationType ||
138
+ isElectrumDerivationType ||
139
+ isSameTypeAsSelectedWallet ||
140
+ isNonSeedWallet ||
141
+ isNotMoneroBip39Wallet;
142
}
143
144
if (shouldExcludeGroup) continue;
lib/view_model/wallet_hardware_restore_view_model.dart
+6
-11
@@ -26,14 +26,10 @@ abstract class WalletHardwareRestoreViewModelBase extends WalletCreationVM with
26
27
int _nextIndex = 0;
28
29
- WalletHardwareRestoreViewModelBase(
30
- this.hardwareWalletVM,
31
- AppStore appStore,
32
- WalletCreationService walletCreationService,
33
- SeedSettingsViewModel seedSettingsViewModel,
29
+ WalletHardwareRestoreViewModelBase(this.hardwareWalletVM, AppStore appStore,
30
+ WalletCreationService walletCreationService, SeedSettingsViewModel seedSettingsViewModel,
31
{required WalletType type})
35
- : super(appStore, walletCreationService, seedSettingsViewModel,
36
- type: type, isRecovery: true);
32
+ : super(appStore, walletCreationService, seedSettingsViewModel, type: type, isRecovery: true);
33
34
@observable
35
String name = "";
@@ -54,8 +50,7 @@ abstract class WalletHardwareRestoreViewModelBase extends WalletCreationVM with
50
Future<void> getNextAvailableAccounts(int limit) async {
51
try {
52
final service = await hardwareWalletVM.getHardwareWalletService(type);
57
- final accounts = await service
58
- .getAvailableAccounts(index: _nextIndex, limit: limit);
53
+ final accounts = await service.getAvailableAccounts(index: _nextIndex, limit: limit);
54
55
availableAccounts.addAll(accounts);
56
_nextIndex += limit;
@@ -74,8 +69,8 @@ abstract class WalletHardwareRestoreViewModelBase extends WalletCreationVM with
69
switch (type) {
70
case WalletType.bitcoin:
71
case WalletType.litecoin:
77
- credentials =
78
- bitcoin!.createBitcoinHardwareWalletCredentials(name: name, accountData: selectedAccount!);
72
+ credentials = bitcoin!
73
+ .createBitcoinHardwareWalletCredentials(name: name, accountData: selectedAccount!);
74
break;
75
case WalletType.ethereum:
76
case WalletType.polygon:
lib/view_model/wallet_list/wallet_list_view_model.dart
+3
-4
@@ -70,8 +70,7 @@ abstract class WalletListViewModelBase with Store {
70
WalletType get currentWalletType => _appStore.wallet!.type;
71
72
Future<bool> requireHardwareWalletConnection(WalletListItem walletItem) async =>
73
- _walletLoadingService.requireHardwareWalletConnection(
74
- walletItem.type, walletItem.name);
73
+ _walletLoadingService.requireHardwareWalletConnection(walletItem.type, walletItem.name);
74
75
@action
76
Future<void> loadWallet(WalletListItem walletItem) async {
@@ -89,8 +88,8 @@ abstract class WalletListViewModelBase with Store {
88
89
bool get ascending => _appStore.settingsStore.walletListAscending;
90
92
- /// Serializes updateList() calls: each caller waits for the previous one to finish, then runs.
93
- ///
91
+ /// Serializes updateList() calls: each caller waits for the previous one to finish, then runs.
92
+ ///
93
/// This basically ensures that all calls to updateList() are executed.
94
Future<void> _lastUpdate = Future.value();
95
lib/view_model/wallet_restore_view_model.dart
+12
-14
@@ -255,15 +255,14 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
255
256
case WalletType.monero:
257
return monero!.createMoneroRestoreWalletFromKeysCredentials(
258
- name: name,
259
- height: height,
260
- spendKey: spendKey!,
261
- viewKey: viewKey!,
262
- address: address!,
263
- password: password,
264
- language: 'English',
265
- hardwareWalletType: hardwareWalletType
266
- );
258
+ name: name,
259
+ height: height,
260
+ spendKey: spendKey!,
261
+ viewKey: viewKey!,
262
+ address: address!,
263
+ password: password,
264
+ language: 'English',
265
+ hardwareWalletType: hardwareWalletType);
266
267
case WalletType.nano:
268
return nano!.createNanoRestoreWalletFromKeysCredentials(
@@ -312,11 +311,10 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
311
);
312
case WalletType.zcash:
313
return zcash!.createZcashRestoreWalletFromPrivateKey(
315
- name: name,
316
- privateKey: options['private_key'] as String,
317
- password: password,
318
- height: height
319
- );
314
+ name: name,
315
+ privateKey: options['private_key'] as String,
316
+ password: password,
317
+ height: height);
318
default:
319
break;
320
}
lib/view_model/wallet_seed_view_model.dart
-1
@@ -21,7 +21,6 @@ abstract class WalletSeedViewModelBase with Store {
21
setupSeedVerification();
22
}
23
24
-
24
@observable
25
String name;
26
lib/wallet_type_utils.dart
+8
-10
@@ -2,23 +2,21 @@ import 'package:cw_core/wallet_type.dart';
2
import 'package:cake_wallet/wallet_types.g.dart';
3
4
bool get isMoneroOnly {
5
- return availableWalletTypes.length == 1
6
- && availableWalletTypes.first == WalletType.monero;
5
+ return availableWalletTypes.length == 1 && availableWalletTypes.first == WalletType.monero;
6
}
7
9
-
8
bool get isSingleCoin {
11
- return availableWalletTypes.length == 1;
9
+ return availableWalletTypes.length == 1;
10
}
11
12
bool get hasMonero {
15
- return availableWalletTypes.contains(WalletType.monero);
13
+ return availableWalletTypes.contains(WalletType.monero);
14
}
15
16
String get approximatedAppName {
19
- if (isMoneroOnly) {
20
- return 'Monero.com';
21
- }
22
-
23
- return 'Cake Wallet';
17
+ if (isMoneroOnly) {
18
+ return 'Monero.com';
19
+ }
20
+
21
+ return 'Cake Wallet';
22
}
lib/wownero/cw_wownero.dart
+10
-2
@@ -230,7 +230,11 @@ class CWWownero extends Wownero {
230
required int height,
231
required String mnemonic}) =>
232
WowneroRestoreWalletFromSeedCredentials(
233
- name: name, password: password, passphrase: passphrase, height: height, mnemonic: mnemonic);
233
+ name: name,
234
+ password: password,
235
+ passphrase: passphrase,
236
+ height: height,
237
+ mnemonic: mnemonic);
238
239
@override
240
WalletCredentials createWowneroNewWalletCredentials(
@@ -240,7 +244,11 @@ class CWWownero extends Wownero {
244
String? password,
245
String? passphrase}) =>
246
WowneroNewWalletCredentials(
243
- name: name, password: password, language: language, isPolyseed: isPolyseed, passphrase: passphrase);
247
+ name: name,
248
+ password: password,
249
+ language: language,
250
+ isPolyseed: isPolyseed,
251
+ passphrase: passphrase);
252
253
@override
254
Map<String, String> getKeys(Object wallet) {
lib/zano/cw_zano.dart
+23
-11
@@ -1,17 +1,20 @@
1
part of 'zano.dart';
2
3
class CWZano extends Zano {
4
-
5
- List<ZanoAsset> getZanoAssets(WalletBase wallet) => (wallet as ZanoWallet).zanoAssets.values.toList();
4
+ List<ZanoAsset> getZanoAssets(WalletBase wallet) =>
5
+ (wallet as ZanoWallet).zanoAssets.values.toList();
6
7
@override
8
- Future<CryptoCurrency> addZanoAssetById(WalletBase wallet, String assetId) async => await (wallet as ZanoWallet).addZanoAssetById(assetId);
8
+ Future<CryptoCurrency> addZanoAssetById(WalletBase wallet, String assetId) async =>
9
+ await (wallet as ZanoWallet).addZanoAssetById(assetId);
10
11
@override
11
- Future<void> changeZanoAssetAvailability(WalletBase wallet, CryptoCurrency token) async => await (wallet as ZanoWallet).changeZanoAssetAvailability(token as ZanoAsset);
12
+ Future<void> changeZanoAssetAvailability(WalletBase wallet, CryptoCurrency token) async =>
13
+ await (wallet as ZanoWallet).changeZanoAssetAvailability(token as ZanoAsset);
14
15
@override
14
- Future<void> deleteZanoAsset(WalletBase wallet, CryptoCurrency token) async => await (wallet as ZanoWallet).deleteZanoAsset(token as ZanoAsset);
16
+ Future<void> deleteZanoAsset(WalletBase wallet, CryptoCurrency token) async =>
17
+ await (wallet as ZanoWallet).deleteZanoAsset(token as ZanoAsset);
18
19
@override
20
Future<ZanoAsset?> getZanoAsset(WalletBase wallet, String assetId) async {
@@ -48,12 +51,18 @@ class CWZano extends Zano {
51
52
@override
53
WalletCredentials createZanoRestoreWalletFromSeedCredentials(
51
- {required String name, required String password, required int height, required String passphrase, required String mnemonic}) {
52
- return ZanoRestoreWalletFromSeedCredentials(name: name, password: password, passphrase: passphrase, height: height, mnemonic: mnemonic);
54
+ {required String name,
55
+ required String password,
56
+ required int height,
57
+ required String passphrase,
58
+ required String mnemonic}) {
59
+ return ZanoRestoreWalletFromSeedCredentials(
60
+ name: name, password: password, passphrase: passphrase, height: height, mnemonic: mnemonic);
61
}
62
63
@override
56
- WalletCredentials createZanoNewWalletCredentials({required String name, required String? password, required String? passphrase}) {
64
+ WalletCredentials createZanoNewWalletCredentials(
65
+ {required String name, required String? password, required String? passphrase}) {
66
return ZanoNewWalletCredentials(name: name, password: password, passphrase: passphrase);
67
}
68
@@ -91,10 +100,12 @@ class CWZano extends Zano {
100
);
101
102
@override
94
- double formatterIntAmountToDouble({required int amount, required CryptoCurrency currency, required bool forFee}) {
103
+ double formatterIntAmountToDouble(
104
+ {required int amount, required CryptoCurrency currency, required bool forFee}) {
105
// fee always counted in zano with default decimal points
106
if (forFee) return ZanoFormatter.intAmountToDouble(amount);
97
- if (currency is ZanoAsset) return ZanoFormatter.intAmountToDouble(amount, currency.decimalPoint);
107
+ if (currency is ZanoAsset)
108
+ return ZanoFormatter.intAmountToDouble(amount, currency.decimalPoint);
109
return ZanoFormatter.intAmountToDouble(amount);
110
}
111
@@ -122,7 +133,8 @@ class CWZano extends Zano {
133
return CryptoCurrency.zano;
134
}
135
wallet as ZanoWallet;
125
- final asset = wallet.zanoAssets.values.firstWhereOrNull((element) => element?.ticker == transaction.tokenSymbol);
136
+ final asset = wallet.zanoAssets.values
137
+ .firstWhereOrNull((element) => element?.ticker == transaction.tokenSymbol);
138
return asset;
139
}
140
lib/zcash/cw_zcash.dart
+16
-23
@@ -69,21 +69,20 @@ class CWZcash extends Zcash {
69
{required CryptoCurrency currency, required int feeRate}) {
70
return ZcashTransactionCredentials(
71
outputs: outputs,
72
- priority:
73
- getZcashTransactionPriorityAutomatic() as MoneroTransactionPriority,
72
+ priority: getZcashTransactionPriorityAutomatic() as MoneroTransactionPriority,
73
currency: currency,
74
);
75
}
76
77
@override
79
- WalletService<WalletCredentials, WalletCredentials, WalletCredentials,
80
- WalletCredentials> createZcashWalletService(bool isDirect) {
78
+ WalletService<WalletCredentials, WalletCredentials, WalletCredentials, WalletCredentials>
79
+ createZcashWalletService(bool isDirect) {
80
return ZcashWalletService();
81
}
82
83
@override
84
double formatterZcashAmountToDouble({TransactionInfo? transaction, BigInt? amount}) {
86
- return cryptoAmountToDouble(amount: amount?.toInt()??0, divider: 1e8);
85
+ return cryptoAmountToDouble(amount: amount?.toInt() ?? 0, divider: 1e8);
86
}
87
88
@override
@@ -98,18 +97,14 @@ class CWZcash extends Zcash {
97
98
@override
99
String getAddress(
101
- WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
102
- TransactionInfo>
103
- wallet) {
100
+ WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> wallet) {
101
final zcashWallet = wallet as ZcashWallet;
102
return zcashWallet.walletAddresses.address;
103
}
104
105
@override
106
String getPrivateKey(
110
- WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
111
- TransactionInfo>
112
- wallet) {
107
+ WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> wallet) {
108
final zcashWallet = wallet as ZcashWallet;
109
final seed = zcashWallet.seed;
110
return seed ?? '';
@@ -117,9 +112,7 @@ class CWZcash extends Zcash {
112
113
@override
114
String getPublicKey(
120
- WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
121
- TransactionInfo>
122
- wallet) {
115
+ WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> wallet) {
116
return getAddress(wallet);
117
}
118
@@ -130,7 +123,7 @@ class CWZcash extends Zcash {
123
124
return <String, String>{
125
if (seed != null) 'seed': seed,
133
- ...(zcashWallet.keys as Map<String, String?>).map((final k, final v) => MapEntry(k, v??'')),
126
+ ...(zcashWallet.keys as Map<String, String?>).map((final k, final v) => MapEntry(k, v ?? '')),
127
};
128
}
129
@@ -142,8 +135,7 @@ class CWZcash extends Zcash {
135
@override
136
List<WalletInfoAddressInfo> getAddressInfos(Object wallet) {
137
final zcashWallet = wallet as ZcashWallet;
145
- return (zcashWallet.walletAddresses as ZcashWalletAddresses)
146
- .getAddressInfos();
138
+ return (zcashWallet.walletAddresses as ZcashWalletAddresses).getAddressInfos();
139
}
140
141
@override
@@ -169,7 +161,8 @@ class CWZcash extends Zcash {
161
@override
162
ReceivePageOption getSelectedAddressType(Object wallet) {
163
final zcashWallet = wallet as ZcashWallet;
172
- final t = (zcashWallet.walletAddresses as ZcashWalletAddresses).walletInfo.addressPageType??"";
164
+ final t =
165
+ (zcashWallet.walletAddresses as ZcashWalletAddresses).walletInfo.addressPageType ?? "";
166
return ZcashReceivePageOption.fromType(ZcashReceivePageOption.typeFromString(t));
167
}
168
@@ -177,7 +170,6 @@ class CWZcash extends Zcash {
170
return getSelectedAddressType(wallet) == ZcashReceivePageOption.transparentRotated;
171
}
172
180
-
173
@override
174
dynamic getZcashAddressType(ReceivePageOption option) {
175
switch (option) {
@@ -197,19 +189,20 @@ class CWZcash extends Zcash {
189
@override
190
Future<void> setAddressType(Object wallet, dynamic option) async {
191
final zcashWallet = wallet as ZcashWallet;
200
- await (zcashWallet.walletAddresses as ZcashWalletAddresses).setAddressType(option as ZcashAddressType);
192
+ await (zcashWallet.walletAddresses as ZcashWalletAddresses)
193
+ .setAddressType(option as ZcashAddressType);
194
}
195
196
@override
197
dynamic getOptionToType(ReceivePageOption option) {
198
return (option as ZcashReceivePageOption).toType();
199
}
207
-
200
+
201
@override
202
void unlockDatabase(String password) {
203
return ZcashWalletBase.unlockDatabase(password);
204
}
212
-
205
+
206
@override
207
Future<int> getHeightByDate(DateTime date) {
208
return ZcashWalletBase.getHeightByDate(date);
@@ -220,7 +213,7 @@ class CWZcash extends Zcash {
213
final zcashWallet = wallet as ZcashWallet;
214
return zcashWallet.couldBeZashiWallet();
215
}
223
-
216
+
217
@override
218
Future<void> rescanInternalChange(WalletBase wallet) {
219
final zcashWallet = wallet as ZcashWallet;