CW-580: BIP39 Wallets Shared Seed Implementation: "One Seed - Multiple Wallets" (#1307)

* feat: Implement creating new BIP39 wallet with same seed used for other owned BIP39 wallets * feat: Use same seed for BIP39 Wallets * Update pre_existing_seeds_page.dart * Feat: BIP39 Same seed wallet creation using the Common Parent Wallet Strategy * feat: Finalize implementing preexisting seeds * feat: Implement shared bip39 wallet seed for Bitcoin wallet type * feat: Implement shared bip39 wallet seed for Litecoin wallet type * feat: Implement shared bip39 wallet seed for BitcoinCash wallet type * feat: Implement shared bip39 wallet seed for Nano wallet type, although disabled entry for now * fix: Remove non bip39 seed wallet type from listing * feat: Implement grouped and single wallets lists in wallets listing page and implement editing and saving group names * fix: Issue where the ontap always references the leadwallet, also make shared seed wallets section header only display when the multi wallet groups list is not empty * fix: Add translation and adjust the way the groups display * feat: Activate bip39 as an option for creating Nano wallet types * fix: Handle edgecase with creating new wallet with group address, handle case where only bip39 derivation type is allowed with child wallets, activate nano wallet type for shared seed * chore: Modify the UI to fit adjustment made on figma * fix: Disposed box triggering error in hive and causing wallet list view to display error * fix: Switch wallet groups title in wallets list page and also fix issue with renaming groups * Update lib/reactions/bip39_wallet_utils.dart [skip ci] Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com> * Update lib/router.dart [skip ci] Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com> * fix: Review fixes: Combine New Wallet Page Type arguments into a single model * fix: Review fixes: Add failure guard when fetching mnemonic for selected wallet in pre-existing wallets page * fix: Review fixes - Add loading indicator when mnemonic is being selected for wallet * fix: Review fixes - Modify variable name to avoid clashes * fix: Review fixes - Access WalletManager through dependency injection instead of service location * fix: Review fixes - Add testnet to convertWalletInfoToWalletlistItem function, and adjust according where used * fix: Review fixes - Add walletPassword to nano, tron and wownero wallets and confirm it is properly handled as it should be * fix: Remove leadWallet, modify filtering flow to reflect this and not depend on leadWallet, and adjust privacy settings * fix: Review Fixes - Modify restore flow to reflect current nature of bip39 as default for majority of wallet types * fix: QA Fixes - Modify preexisting page to display wallet group names if set, and display them in incremental order if not set * fix: Add wallet group description page and rename pre-existingseeds page to wallet group display page * fix: Product Fix - Rename pre-existing seeds file name to wallet group display filename * fix: Product fix - Separate multiwallets groups from single wallets and display separately * fix - Product Fix - Add empty state for wallet group listing when creating a new wallet, adjust CTAs across buttons relating to the flow also --------- Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

David Adegoke committed Sep 20, 2024 at 19:25 UTC 4e2e5e708c1d6cea0e4fe25444748c6468b974c6
87 files changed +2149 -427
assets/images/wallet_group.png
Binary files /dev/null and b/assets/images/wallet_group.png differ
cw_bitcoin/lib/bitcoin_wallet_creation_credentials.dart
+5
@@ -10,12 +10,17 @@ class BitcoinNewWalletCredentials extends WalletCredentials {
10 DerivationType? derivationType,
11 String? derivationPath,
12 String? passphrase,
13 + this.mnemonic,
14 + String? parentAddress,
15 }) : super(
16 name: name,
17 walletInfo: walletInfo,
18 password: password,
19 passphrase: passphrase,
20 + parentAddress: parentAddress,
21 );
22 +
23 + final String? mnemonic;
24 }
25
26 class BitcoinRestoreWalletFromSeedCredentials extends WalletCredentials {
cw_bitcoin/lib/bitcoin_wallet_service.dart
+1 -1
@@ -41,7 +41,7 @@ class BitcoinWalletService extends WalletService<
41 case DerivationType.bip39:
42 final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
43
44 - mnemonic = await MnemonicBip39.generate(strength: strength);
44 + mnemonic = credentials.mnemonic ?? await MnemonicBip39.generate(strength: strength);
45 break;
46 case DerivationType.electrum:
47 default:
cw_bitcoin/lib/litecoin_wallet_service.dart
+2 -2
@@ -32,11 +32,11 @@ class LitecoinWalletService extends WalletService<
32 @override
33 Future<LitecoinWallet> create(BitcoinNewWalletCredentials credentials, {bool? isTestnet}) async {
34 final String mnemonic;
35 - switch ( credentials.walletInfo?.derivationInfo?.derivationType) {
35 + switch (credentials.walletInfo?.derivationInfo?.derivationType) {
36 case DerivationType.bip39:
37 final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
38
39 - mnemonic = await MnemonicBip39.generate(strength: strength);
39 + mnemonic = credentials.mnemonic ?? await MnemonicBip39.generate(strength: strength);
40 break;
41 case DerivationType.electrum:
42 default:
cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_creation_credentials.dart
+15 -3
@@ -2,9 +2,21 @@ import 'package:cw_core/wallet_credentials.dart';
2 import 'package:cw_core/wallet_info.dart';
3
4 class BitcoinCashNewWalletCredentials extends WalletCredentials {
5 - BitcoinCashNewWalletCredentials(
6 - {required String name, WalletInfo? walletInfo, String? password, String? passphrase})
7 - : super(name: name, walletInfo: walletInfo, password: password, passphrase: passphrase);
5 + BitcoinCashNewWalletCredentials({
6 + required String name,
7 + WalletInfo? walletInfo,
8 + String? password,
9 + String? passphrase,
10 + this.mnemonic,
11 + String? parentAddress,
12 + }) : super(
13 + name: name,
14 + walletInfo: walletInfo,
15 + password: password,
16 + passphrase: passphrase,
17 + parentAddress: parentAddress
18 + );
19 + final String? mnemonic;
20 }
21
22 class BitcoinCashRestoreWalletFromSeedCredentials extends WalletCredentials {
cw_bitcoin_cash/lib/src/bitcoin_cash_wallet_service.dart
+1 -1
@@ -36,7 +36,7 @@ class BitcoinCashWalletService extends WalletService<
36 final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
37
38 final wallet = await BitcoinCashWalletBase.create(
39 - mnemonic: await MnemonicBip39.generate(strength: strength),
39 + mnemonic: credentials.mnemonic ?? await MnemonicBip39.generate(strength: strength),
40 password: credentials.password!,
41 walletInfo: credentials.walletInfo!,
42 unspentCoinsInfo: unspentCoinsInfoSource,
cw_core/lib/wallet_credentials.dart
+2
@@ -10,6 +10,7 @@ abstract class WalletCredentials {
10 this.passphrase,
11 this.derivationInfo,
12 this.hardwareWalletType,
13 + this.parentAddress,
14 }) {
15 if (this.walletInfo != null && derivationInfo != null) {
16 this.walletInfo!.derivationInfo = derivationInfo;
@@ -18,6 +19,7 @@ abstract class WalletCredentials {
19
20 final String name;
21 final int? height;
22 + String? parentAddress;
23 int? seedPhraseLength;
24 String? password;
25 String? passphrase;
cw_core/lib/wallet_info.dart
+6
@@ -80,6 +80,7 @@ class WalletInfo extends HiveObject {
80 this.showIntroCakePayCard,
81 this.derivationInfo,
82 this.hardwareWalletType,
83 + this.parentAddress,
84 ) : _yatLastUsedAddressController = StreamController<String>.broadcast();
85
86 factory WalletInfo.external({
@@ -97,6 +98,7 @@ class WalletInfo extends HiveObject {
98 String yatLastUsedAddressRaw = '',
99 DerivationInfo? derivationInfo,
100 HardwareWalletType? hardwareWalletType,
101 + String? parentAddress,
102 }) {
103 return WalletInfo(
104 id,
@@ -113,6 +115,7 @@ class WalletInfo extends HiveObject {
115 showIntroCakePayCard,
116 derivationInfo,
117 hardwareWalletType,
118 + parentAddress,
119 );
120 }
121
@@ -184,6 +187,9 @@ class WalletInfo extends HiveObject {
187 @HiveField(21)
188 HardwareWalletType? hardwareWalletType;
189
190 + @HiveField(22)
191 + String? parentAddress;
192 +
193 String get yatLastUsedAddress => yatLastUsedAddressRaw ?? '';
194
195 set yatLastUsedAddress(String address) {
cw_ethereum/lib/ethereum_wallet_service.dart
+1 -1
@@ -21,7 +21,7 @@ class EthereumWalletService extends EVMChainWalletService<EthereumWallet> {
21 Future<EthereumWallet> create(EVMChainNewWalletCredentials credentials, {bool? isTestnet}) async {
22 final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
23
24 - final mnemonic = bip39.generateMnemonic(strength: strength);
24 + final mnemonic = credentials.mnemonic ?? bip39.generateMnemonic(strength: strength);
25
26 final wallet = EthereumWallet(
27 walletInfo: credentials.walletInfo!,
cw_evm/lib/evm_chain_wallet_creation_credentials.dart
+14 -2
@@ -3,8 +3,20 @@ import 'package:cw_core/wallet_credentials.dart';
3 import 'package:cw_core/wallet_info.dart';
4
5 class EVMChainNewWalletCredentials extends WalletCredentials {
6 - EVMChainNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password})
7 - : super(name: name, walletInfo: walletInfo, password: password);
6 + EVMChainNewWalletCredentials({
7 + required String name,
8 + WalletInfo? walletInfo,
9 + String? password,
10 + String? parentAddress,
11 + this.mnemonic,
12 + }) : super(
13 + name: name,
14 + walletInfo: walletInfo,
15 + password: password,
16 + parentAddress: parentAddress,
17 + );
18 +
19 + final String? mnemonic;
20 }
21
22 class EVMChainRestoreWalletFromSeedCredentials extends WalletCredentials {
cw_nano/lib/nano_wallet_creation_credentials.dart
+7 -1
@@ -4,13 +4,19 @@ import 'package:cw_core/wallet_info.dart';
4 class NanoNewWalletCredentials extends WalletCredentials {
5 NanoNewWalletCredentials({
6 required String name,
7 + WalletInfo? walletInfo,
8 String? password,
9 DerivationType? derivationType,
10 + this.mnemonic,
11 + String? parentAddress,
12 }) : super(
13 name: name,
14 password: password,
12 - derivationInfo: DerivationInfo(derivationType: derivationType),
15 + walletInfo: walletInfo,
16 + parentAddress: parentAddress,
17 );
18 +
19 + final String? mnemonic;
20 }
21
22 class NanoRestoreWalletFromSeedCredentials extends WalletCredentials {
cw_nano/lib/nano_wallet_service.dart
+11 -9
@@ -32,15 +32,17 @@ class NanoWalletService extends WalletService<
32
33 @override
34 Future<WalletBase> create(NanoNewWalletCredentials credentials, {bool? isTestnet}) async {
35 - // nano standard:
36 - String seedKey = NanoSeeds.generateSeed();
37 - String mnemonic = NanoDerivations.standardSeedToMnemonic(seedKey);
38 -
39 - // should never happen but just in case:
40 - if (credentials.walletInfo!.derivationInfo == null) {
41 - credentials.walletInfo!.derivationInfo = DerivationInfo(derivationType: DerivationType.nano);
42 - } else if (credentials.walletInfo!.derivationInfo!.derivationType == null) {
43 - credentials.walletInfo!.derivationInfo!.derivationType = DerivationType.nano;
35 + final String mnemonic;
36 + switch (credentials.walletInfo?.derivationInfo?.derivationType) {
37 + case DerivationType.nano:
38 + String seedKey = NanoSeeds.generateSeed();
39 + mnemonic = credentials.mnemonic ?? NanoDerivations.standardSeedToMnemonic(seedKey);
40 + break;
41 + case DerivationType.bip39:
42 + default:
43 + final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
44 + mnemonic = credentials.mnemonic ?? bip39.generateMnemonic(strength: strength);
45 + break;
46 }
47
48 final wallet = NanoWallet(
cw_polygon/lib/polygon_wallet_service.dart
+1 -1
@@ -24,7 +24,7 @@ class PolygonWalletService extends EVMChainWalletService<PolygonWallet> {
24 Future<PolygonWallet> create(EVMChainNewWalletCredentials credentials, {bool? isTestnet}) async {
25 final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
26
27 - final mnemonic = bip39.generateMnemonic(strength: strength);
27 + final mnemonic = credentials.mnemonic ?? bip39.generateMnemonic(strength: strength);
28
29 final wallet = PolygonWallet(
30 walletInfo: credentials.walletInfo!,
cw_solana/lib/solana_wallet_creation_credentials.dart
+13 -2
@@ -2,8 +2,19 @@ import 'package:cw_core/wallet_credentials.dart';
2 import 'package:cw_core/wallet_info.dart';
3
4 class SolanaNewWalletCredentials extends WalletCredentials {
5 - SolanaNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password})
6 - : super(name: name, walletInfo: walletInfo, password: password);
5 + SolanaNewWalletCredentials({
6 + required String name,
7 + WalletInfo? walletInfo,
8 + String? password,
9 + String? parentAddress,
10 + this.mnemonic,
11 + }) : super(
12 + name: name,
13 + walletInfo: walletInfo,
14 + password: password,
15 + parentAddress: parentAddress,
16 + );
17 + final String? mnemonic;
18 }
19
20 class SolanaRestoreWalletFromSeedCredentials extends WalletCredentials {
cw_solana/lib/solana_wallet_service.dart
+1 -1
@@ -27,7 +27,7 @@ class SolanaWalletService extends WalletService<SolanaNewWalletCredentials,
27 Future<SolanaWallet> create(SolanaNewWalletCredentials credentials, {bool? isTestnet}) async {
28 final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
29
30 - final mnemonic = bip39.generateMnemonic(strength: strength);
30 + final mnemonic = credentials.mnemonic ?? bip39.generateMnemonic(strength: strength);
31
32 final wallet = SolanaWallet(
33 walletInfo: credentials.walletInfo!,
cw_tron/lib/tron_wallet_creation_credentials.dart
+14 -2
@@ -2,8 +2,20 @@ import 'package:cw_core/wallet_credentials.dart';
2 import 'package:cw_core/wallet_info.dart';
3
4 class TronNewWalletCredentials extends WalletCredentials {
5 - TronNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password})
6 - : super(name: name, walletInfo: walletInfo, password: password);
5 + TronNewWalletCredentials({
6 + required String name,
7 + WalletInfo? walletInfo,
8 + String? password,
9 + this.mnemonic,
10 + String? parentAddress,
11 + }) : super(
12 + name: name,
13 + walletInfo: walletInfo,
14 + password: password,
15 + parentAddress: parentAddress,
16 + );
17 +
18 + final String? mnemonic;
19 }
20
21 class TronRestoreWalletFromSeedCredentials extends WalletCredentials {
cw_tron/lib/tron_wallet_service.dart
+1 -1
@@ -39,7 +39,7 @@ class TronWalletService extends WalletService<
39 }) async {
40 final strength = credentials.seedPhraseLength == 24 ? 256 : 128;
41
42 - final mnemonic = bip39.generateMnemonic(strength: strength);
42 + final mnemonic = credentials.mnemonic ?? bip39.generateMnemonic(strength: strength);
43
44 final wallet = TronWallet(
45 walletInfo: credentials.walletInfo!,
ios/Podfile.lock
+1 -54
@@ -3,41 +3,10 @@ PODS:
3 - Flutter
4 - MTBBarcodeScanner
5 - SwiftProtobuf
6 - - BigInt (5.2.0)
6 - connectivity_plus (0.0.1):
7 - Flutter
8 - ReachabilitySwift
9 - CryptoSwift (1.8.2)
11 - - cw_haven (0.0.1):
12 - - cw_haven/Boost (= 0.0.1)
13 - - cw_haven/Haven (= 0.0.1)
14 - - cw_haven/OpenSSL (= 0.0.1)
15 - - cw_haven/Sodium (= 0.0.1)
16 - - cw_shared_external
17 - - Flutter
18 - - cw_haven/Boost (0.0.1):
19 - - cw_shared_external
20 - - Flutter
21 - - cw_haven/Haven (0.0.1):
22 - - cw_shared_external
23 - - Flutter
24 - - cw_haven/OpenSSL (0.0.1):
25 - - cw_shared_external
26 - - Flutter
27 - - cw_haven/Sodium (0.0.1):
28 - - cw_shared_external
29 - - Flutter
30 - - cw_shared_external (0.0.1):
31 - - cw_shared_external/Boost (= 0.0.1)
32 - - cw_shared_external/OpenSSL (= 0.0.1)
33 - - cw_shared_external/Sodium (= 0.0.1)
34 - - Flutter
35 - - cw_shared_external/Boost (0.0.1):
36 - - Flutter
37 - - cw_shared_external/OpenSSL (0.0.1):
38 - - Flutter
39 - - cw_shared_external/Sodium (0.0.1):
40 - - Flutter
10 - device_display_brightness (0.0.1):
11 - Flutter
12 - device_info_plus (0.0.1):
@@ -99,8 +68,6 @@ PODS:
68 - Flutter
69 - MTBBarcodeScanner (5.0.11)
70 - OrderedSet (5.0.0)
102 - - package_info (0.0.1):
103 - - Flutter
71 - package_info_plus (0.4.5):
72 - Flutter
73 - path_provider_foundation (0.0.1):
@@ -131,9 +98,6 @@ PODS:
98 - Toast (4.1.1)
99 - uni_links (0.0.1):
100 - Flutter
134 - - UnstoppableDomainsResolution (4.0.0):
135 - - BigInt
136 - - CryptoSwift
101 - url_launcher_ios (0.0.1):
102 - Flutter
103 - wakelock_plus (0.0.1):
@@ -145,8 +109,6 @@ DEPENDENCIES:
109 - barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`)
110 - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`)
111 - CryptoSwift
148 - - cw_haven (from `.symlinks/plugins/cw_haven/ios`)
149 - - cw_shared_external (from `.symlinks/plugins/cw_shared_external/ios`)
112 - device_display_brightness (from `.symlinks/plugins/device_display_brightness/ios`)
113 - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
114 - devicelocale (from `.symlinks/plugins/devicelocale/ios`)
@@ -158,7 +120,6 @@ DEPENDENCIES:
120 - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
121 - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
122 - in_app_review (from `.symlinks/plugins/in_app_review/ios`)
161 - - package_info (from `.symlinks/plugins/package_info/ios`)
123 - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
124 - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
125 - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
@@ -168,14 +129,12 @@ DEPENDENCIES:
129 - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
130 - sp_scanner (from `.symlinks/plugins/sp_scanner/ios`)
131 - uni_links (from `.symlinks/plugins/uni_links/ios`)
171 - - UnstoppableDomainsResolution (~> 4.0.0)
132 - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
133 - wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
134 - workmanager (from `.symlinks/plugins/workmanager/ios`)
135
136 SPEC REPOS:
137 https://github.com/CocoaPods/Specs.git:
178 - - BigInt
138 - CryptoSwift
139 - DKImagePickerController
140 - DKPhotoGallery
@@ -187,17 +146,12 @@ SPEC REPOS:
146 - SwiftProtobuf
147 - SwiftyGif
148 - Toast
190 - - UnstoppableDomainsResolution
149
150 EXTERNAL SOURCES:
151 barcode_scan2:
152 :path: ".symlinks/plugins/barcode_scan2/ios"
153 connectivity_plus:
154 :path: ".symlinks/plugins/connectivity_plus/ios"
197 - cw_haven:
198 - :path: ".symlinks/plugins/cw_haven/ios"
199 - cw_shared_external:
200 - :path: ".symlinks/plugins/cw_shared_external/ios"
155 device_display_brightness:
156 :path: ".symlinks/plugins/device_display_brightness/ios"
157 device_info_plus:
@@ -220,8 +174,6 @@ EXTERNAL SOURCES:
174 :path: ".symlinks/plugins/fluttertoast/ios"
175 in_app_review:
176 :path: ".symlinks/plugins/in_app_review/ios"
223 - package_info:
224 - :path: ".symlinks/plugins/package_info/ios"
177 package_info_plus:
178 :path: ".symlinks/plugins/package_info_plus/ios"
179 path_provider_foundation:
@@ -249,11 +201,8 @@ EXTERNAL SOURCES:
201
202 SPEC CHECKSUMS:
203 barcode_scan2: 0af2bb63c81b4565aab6cd78278e4c0fa136dbb0
252 - BigInt: f668a80089607f521586bbe29513d708491ef2f7
204 connectivity_plus: bf0076dd84a130856aa636df1c71ccaff908fa1d
205 CryptoSwift: c63a805d8bb5e5538e88af4e44bb537776af11ea
255 - cw_haven: b3e54e1fbe7b8e6fda57a93206bc38f8e89b898a
256 - cw_shared_external: 2972d872b8917603478117c9957dfca611845a92
206 device_display_brightness: 1510e72c567a1f6ce6ffe393dcd9afd1426034f7
207 device_info_plus: c6fb39579d0f423935b0c9ce7ee2f44b71b9fce6
208 devicelocale: b22617f40038496deffba44747101255cee005b0
@@ -269,7 +218,6 @@ SPEC CHECKSUMS:
218 in_app_review: 318597b3a06c22bb46dc454d56828c85f444f99d
219 MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
220 OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c
272 - package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
221 package_info_plus: 58f0028419748fad15bf008b270aaa8e54380b1c
222 path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
223 permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
@@ -285,11 +233,10 @@ SPEC CHECKSUMS:
233 SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
234 Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e
235 uni_links: d97da20c7701486ba192624d99bffaaffcfc298a
288 - UnstoppableDomainsResolution: c3c67f4d0a5e2437cb00d4bd50c2e00d6e743841
236 url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
237 wakelock_plus: 78ec7c5b202cab7761af8e2b2b3d0671be6c4ae1
238 workmanager: 0afdcf5628bbde6924c21af7836fed07b42e30e6
239
293 -PODFILE CHECKSUM: a2fe518be61cdbdc5b0e2da085ab543d556af2d3
240 +PODFILE CHECKSUM: e448f662d4c41f0c0b1ccbb78afd57dbf895a597
241
242 COCOAPODS: 1.15.2
lib/bitcoin/cw_bitcoin.dart
+15 -3
@@ -28,10 +28,22 @@ class CWBitcoin extends Bitcoin {
28 name: name, password: password, wif: wif, walletInfo: walletInfo);
29
30 @override
31 - WalletCredentials createBitcoinNewWalletCredentials(
32 - {required String name, WalletInfo? walletInfo, String? password, String? passphrase}) =>
31 + WalletCredentials createBitcoinNewWalletCredentials({
32 + required String name,
33 + WalletInfo? walletInfo,
34 + String? password,
35 + String? passphrase,
36 + String? mnemonic,
37 + String? parentAddress,
38 + }) =>
39 BitcoinNewWalletCredentials(
34 - name: name, walletInfo: walletInfo, password: password, passphrase: passphrase);
40 + name: name,
41 + walletInfo: walletInfo,
42 + password: password,
43 + passphrase: passphrase,
44 + mnemonic: mnemonic,
45 + parentAddress: parentAddress,
46 + );
47
48 @override
49 WalletCredentials createBitcoinHardwareWalletCredentials(
lib/bitcoin_cash/cw_bitcoin_cash.dart
+9 -1
@@ -16,9 +16,17 @@ class CWBitcoinCash extends BitcoinCash {
16 WalletInfo? walletInfo,
17 String? password,
18 String? passphrase,
19 + String? mnemonic,
20 + String? parentAddress,
21 }) =>
22 BitcoinCashNewWalletCredentials(
21 - name: name, walletInfo: walletInfo, password: password, passphrase: passphrase);
23 + name: name,
24 + walletInfo: walletInfo,
25 + password: password,
26 + passphrase: passphrase,
27 + parentAddress: parentAddress,
28 + mnemonic: mnemonic,
29 + );
30
31 @override
32 WalletCredentials createBitcoinCashRestoreWalletFromSeedCredentials(
lib/core/new_wallet_arguments.dart new
+15
@@ -0,0 +1,15 @@
1 +import 'package:cw_core/wallet_type.dart';
2 +
3 +class NewWalletArguments {
4 + final WalletType type;
5 + final String? mnemonic;
6 + final String? parentAddress;
7 + final bool isChildWallet;
8 +
9 + NewWalletArguments({
10 + required this.type,
11 + this.parentAddress,
12 + this.mnemonic,
13 + this.isChildWallet = false,
14 + });
15 +}
lib/core/new_wallet_type_arguments.dart new
+14
@@ -0,0 +1,14 @@
1 +import 'package:cw_core/wallet_type.dart';
2 +import 'package:flutter/material.dart';
3 +
4 +class NewWalletTypeArguments {
5 + final void Function(BuildContext, WalletType)? onTypeSelected;
6 + final bool isCreate;
7 + final bool isHardwareWallet;
8 +
9 + NewWalletTypeArguments({
10 + required this.onTypeSelected,
11 + required this.isCreate,
12 + required this.isHardwareWallet,
13 + });
14 +}
lib/di.dart
+53 -21
@@ -12,10 +12,12 @@ import 'package:cake_wallet/buy/moonpay/moonpay_provider.dart';
12 import 'package:cake_wallet/buy/onramper/onramper_buy_provider.dart';
13 import 'package:cake_wallet/buy/order.dart';
14 import 'package:cake_wallet/buy/payfura/payfura_buy_provider.dart';
15 +import 'package:cake_wallet/core/new_wallet_arguments.dart';
16 import 'package:cake_wallet/buy/robinhood/robinhood_buy_provider.dart';
17 import 'package:cake_wallet/core/auth_service.dart';
18 import 'package:cake_wallet/core/backup_service.dart';
19 import 'package:cake_wallet/core/key_service.dart';
20 +import 'package:cake_wallet/core/new_wallet_type_arguments.dart';
21 import 'package:cake_wallet/core/secure_storage.dart';
22 import 'package:cake_wallet/core/totp_request_details.dart';
23 import 'package:cake_wallet/core/wallet_connect/wallet_connect_key_service.dart';
@@ -30,6 +32,8 @@ import 'package:cake_wallet/entities/contact.dart';
32 import 'package:cake_wallet/entities/contact_record.dart';
33 import 'package:cake_wallet/entities/exchange_api_mode.dart';
34 import 'package:cake_wallet/entities/parse_address_from_domain.dart';
35 +import 'package:cake_wallet/entities/wallet_edit_page_arguments.dart';
36 +import 'package:cake_wallet/entities/wallet_manager.dart';
37 import 'package:cake_wallet/src/screens/receive/address_list_page.dart';
38 import 'package:cake_wallet/view_model/link_view_model.dart';
39 import 'package:cake_wallet/tron/tron.dart';
@@ -145,7 +149,9 @@ import 'package:cake_wallet/view_model/cake_pay/cake_pay_cards_list_view_model.d
149 import 'package:cake_wallet/view_model/cake_pay/cake_pay_purchase_view_model.dart';
150 import 'package:cake_wallet/view_model/nano_account_list/nano_account_edit_or_create_view_model.dart';
151 import 'package:cake_wallet/view_model/nano_account_list/nano_account_list_view_model.dart';
152 +import 'package:cake_wallet/view_model/new_wallet_type_view_model.dart';
153 import 'package:cake_wallet/view_model/node_list/pow_node_list_view_model.dart';
154 +import 'package:cake_wallet/view_model/wallet_groups_display_view_model.dart';
155 import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
156 import 'package:cake_wallet/view_model/set_up_2fa_viewmodel.dart';
157 import 'package:cake_wallet/view_model/restore/restore_from_qr_vm.dart';
@@ -157,7 +163,6 @@ import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart
163 import 'package:cake_wallet/view_model/settings/trocador_providers_view_model.dart';
164 import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_item.dart';
165 import 'package:cake_wallet/view_model/wallet_list/wallet_edit_view_model.dart';
160 -import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
166 import 'package:cake_wallet/view_model/wallet_restore_choose_derivation_view_model.dart';
167 import 'package:cw_core/nano_account.dart';
168 import 'package:cw_core/unspent_coins_info.dart';
@@ -358,13 +363,31 @@ Future<void> setup({
363 getIt.get<KeyService>(),
364 (WalletType type) => getIt.get<WalletService>(param1: type)));
365
361 - getIt.registerFactoryParam<WalletNewVM, WalletType, void>((type, _) => WalletNewVM(
366 + getIt.registerFactoryParam<WalletNewVM, NewWalletArguments, void>(
367 + (newWalletArgs, _) => WalletNewVM(
368 getIt.get<AppStore>(),
363 - getIt.get<WalletCreationService>(param1: type),
369 + getIt.get<WalletCreationService>(param1:newWalletArgs.type),
370 _walletInfoSource,
365 - getIt.get<AdvancedPrivacySettingsViewModel>(param1: type),
371 + getIt.get<AdvancedPrivacySettingsViewModel>(param1: newWalletArgs.type),
372 getIt.get<SeedSettingsViewModel>(),
367 - type: type));
373 + newWalletArguments: newWalletArgs,));
374 +
375 +
376 + getIt.registerFactory<NewWalletTypeViewModel>(() => NewWalletTypeViewModel(_walletInfoSource));
377 +
378 + getIt.registerFactory<WalletManager>(
379 + () => WalletManager(_walletInfoSource, getIt.get<SharedPreferences>()),
380 + );
381 +
382 + getIt.registerFactoryParam<WalletGroupsDisplayViewModel, WalletType, void>(
383 + (type, _) => WalletGroupsDisplayViewModel(
384 + getIt.get<AppStore>(),
385 + getIt.get<WalletLoadingService>(),
386 + getIt.get<WalletManager>(),
387 + getIt.get<WalletListViewModel>(),
388 + type: type,
389 + ),
390 + );
391
392 getIt.registerFactoryParam<WalletUnlockPage, WalletUnlockArguments, bool>((args, closable) {
393 return WalletUnlockPage(
@@ -723,6 +746,7 @@ Future<void> setup({
746 _walletInfoSource,
747 getIt.get<AppStore>(),
748 getIt.get<WalletLoadingService>(),
749 + getIt.get<WalletManager>(),
750 ),
751 );
752 } else {
@@ -733,6 +757,7 @@ Future<void> setup({
757 _walletInfoSource,
758 getIt.get<AppStore>(),
759 getIt.get<WalletLoadingService>(),
760 + getIt.get<WalletManager>(),
761 ),
762 );
763 }
@@ -743,17 +768,28 @@ Future<void> setup({
768 ));
769
770 getIt.registerFactoryParam<WalletEditViewModel, WalletListViewModel, void>(
746 - (WalletListViewModel walletListViewModel, _) =>
747 - WalletEditViewModel(walletListViewModel, getIt.get<WalletLoadingService>()));
771 + (WalletListViewModel walletListViewModel, _) => WalletEditViewModel(
772 + walletListViewModel,
773 + getIt.get<WalletLoadingService>(),
774 + getIt.get<WalletManager>(),
775 + ),
776 + );
777 +
778 + getIt.registerFactoryParam<WalletEditPage, WalletEditPageArguments, void>((arguments, _) {
779
749 - getIt.registerFactoryParam<WalletEditPage, List<dynamic>, void>((args, _) {
750 - final walletListViewModel = args.first as WalletListViewModel;
751 - final editingWallet = args.last as WalletListItem;
780 return WalletEditPage(
753 - walletEditViewModel: getIt.get<WalletEditViewModel>(param1: walletListViewModel),
781 + pageArguments: WalletEditPageArguments(
782 + walletEditViewModel: getIt.get<WalletEditViewModel>(param1: arguments.walletListViewModel),
783 authService: getIt.get<AuthService>(),
755 - walletNewVM: getIt.get<WalletNewVM>(param1: editingWallet.type),
756 - editingWallet: editingWallet);
784 + walletNewVM: getIt.get<WalletNewVM>(
785 + param1: NewWalletArguments(type: arguments.editingWallet.type),
786 + ),
787 + editingWallet: arguments.editingWallet,
788 + isWalletGroup: arguments.isWalletGroup,
789 + groupName: arguments.groupName,
790 + parentAddress: arguments.parentAddress,
791 + ),
792 + );
793 });
794
795 getIt.registerFactory<NanoAccountListViewModel>(() {
@@ -1060,15 +1096,11 @@ Future<void> setup({
1096 transactionDetailsViewModel:
1097 getIt.get<TransactionDetailsViewModel>(param1: transactionInfo)));
1098
1063 - getIt.registerFactoryParam<NewWalletTypePage, void Function(BuildContext, WalletType),
1064 - List<bool>?>((param1, additionalParams) {
1065 - final isCreate = additionalParams?[0] ?? true;
1066 - final isHardwareWallet = additionalParams?[1] ?? false;
1067 -
1099 + getIt.registerFactoryParam<NewWalletTypePage, NewWalletTypeArguments, void>(
1100 + (newWalletTypeArguments, _) {
1101 return NewWalletTypePage(
1069 - onTypeSelected: param1,
1070 - isCreate: isCreate,
1071 - isHardwareWallet: isHardwareWallet,
1102 + newWalletTypeArguments: newWalletTypeArguments,
1103 + newWalletTypeViewModel: getIt.get<NewWalletTypeViewModel>(),
1104 );
1105 });
1106
lib/entities/preferences_key.dart
+1
@@ -79,6 +79,7 @@ class PreferencesKey {
79 static const autoGenerateSubaddressStatusKey = 'auto_generate_subaddress_status';
80 static const moneroSeedType = 'monero_seed_type';
81 static const bitcoinSeedType = 'bitcoin_seed_type';
82 + static const nanoSeedType = 'nano_seed_type';
83 static const clearnetDonationLink = 'clearnet_donation_link';
84 static const onionDonationLink = 'onion_donation_link';
85 static const donationLinkWalletName = 'donation_link_wallet_name';
lib/entities/seed_type.dart
+25
@@ -65,3 +65,28 @@ class BitcoinSeedType extends EnumerableItem<int> with Serializable<int> {
65 }
66 }
67 }
68 +
69 +class NanoSeedType extends EnumerableItem<int> with Serializable<int> {
70 + const NanoSeedType(this.type, {required String title, required int raw})
71 + : super(title: title, raw: raw);
72 +
73 + final DerivationType type;
74 +
75 + static const all = [NanoSeedType.nanoStandard, NanoSeedType.bip39];
76 +
77 + static const defaultDerivationType = bip39;
78 +
79 + static const nanoStandard = NanoSeedType(DerivationType.nano, raw: 0, title: 'Nano');
80 + static const bip39 = NanoSeedType(DerivationType.bip39, raw: 1, title: 'BIP39');
81 +
82 + static NanoSeedType deserialize({required int raw}) {
83 + switch (raw) {
84 + case 0:
85 + return nanoStandard;
86 + case 1:
87 + return bip39;
88 + default:
89 + throw Exception('Unexpected token: $raw for SeedType deserialize');
90 + }
91 + }
92 +}
lib/entities/wallet_edit_page_arguments.dart new
+28
@@ -0,0 +1,28 @@
1 +import 'package:cake_wallet/core/auth_service.dart';
2 +import 'package:cake_wallet/view_model/wallet_list/wallet_edit_view_model.dart';
3 +import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
4 +import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
5 +import 'package:cake_wallet/view_model/wallet_new_vm.dart';
6 +
7 +class WalletEditPageArguments {
8 + WalletEditPageArguments({
9 + required this.editingWallet,
10 + this.isWalletGroup = false,
11 + this.walletListViewModel,
12 + this.groupName = '',
13 + this.parentAddress = '',
14 + this.walletEditViewModel,
15 + this.walletNewVM,
16 + this.authService,
17 + });
18 +
19 + final WalletListItem editingWallet;
20 + final bool isWalletGroup;
21 + final String groupName;
22 + final String parentAddress;
23 + final WalletListViewModel? walletListViewModel;
24 +
25 + final WalletEditViewModel? walletEditViewModel;
26 + final WalletNewVM? walletNewVM;
27 + final AuthService? authService;
28 +}
lib/entities/wallet_group.dart new
+21
@@ -0,0 +1,21 @@
1 +import 'package:cw_core/wallet_info.dart';
2 +
3 +class WalletGroup {
4 + WalletGroup(this.parentAddress) : wallets = [];
5 +
6 + /// Main identifier for each group, compulsory.
7 + final String parentAddress;
8 +
9 + /// Child wallets that share the same parent address within this group
10 + List<WalletInfo> wallets;
11 +
12 + /// Custom name for the group, editable for multi-child wallet groups
13 + String? groupName;
14 +
15 + /// Allows editing of the group name (only for multi-child groups).
16 + void setCustomName(String name) {
17 + if (wallets.length > 1) {
18 + groupName = name;
19 + }
20 + }
21 +}
lib/entities/wallet_manager.dart new
+110
@@ -0,0 +1,110 @@
1 +import 'package:cake_wallet/entities/wallet_group.dart';
2 +import 'package:cw_core/wallet_info.dart';
3 +import 'package:hive/hive.dart';
4 +import 'package:shared_preferences/shared_preferences.dart';
5 +
6 +class WalletManager {
7 + WalletManager(
8 + this._walletInfoSource,
9 + this._sharedPreferences,
10 + );
11 +
12 + final Box<WalletInfo> _walletInfoSource;
13 + final SharedPreferences _sharedPreferences;
14 +
15 + final List<WalletGroup> walletGroups = [];
16 +
17 + /// Categorize wallets into groups based on their parentAddress.
18 + ///
19 + /// Update the lead wallet for each group and clean up empty groups
20 + /// i.e remove group if there's no lead wallet (i.e, no wallets left)
21 + void updateWalletGroups() {
22 + walletGroups.clear();
23 +
24 + for (var walletInfo in _walletInfoSource.values) {
25 + final group = _getOrCreateGroup(_resolveParentAddress(walletInfo));
26 + group.wallets.add(walletInfo);
27 + }
28 +
29 + walletGroups.removeWhere((group) => group.wallets.isEmpty);
30 +
31 + _loadCustomGroupNames();
32 + }
33 +
34 + /// Function to determine the correct parentAddress for a wallet.
35 + ///
36 + /// If it's a parent wallet (parentAddress is null),
37 + /// use its own address as parentAddress.
38 + String _resolveParentAddress(WalletInfo walletInfo) {
39 + return walletInfo.parentAddress ?? walletInfo.address;
40 + }
41 +
42 + /// Check if a group with the parentAddress already exists,
43 + /// If no group exists, create a new one.
44 + ///
45 + WalletGroup _getOrCreateGroup(String parentAddress) {
46 + return walletGroups.firstWhere(
47 + (group) => group.parentAddress == parentAddress,
48 + orElse: () {
49 + final newGroup = WalletGroup(parentAddress);
50 + walletGroups.add(newGroup);
51 + return newGroup;
52 + },
53 + );
54 + }
55 +
56 + /// Add a new wallet and update lead wallet after adding.
57 + void addWallet(WalletInfo walletInfo) {
58 + final group = _getOrCreateGroup(_resolveParentAddress(walletInfo));
59 + group.wallets.add(walletInfo);
60 + }
61 +
62 + /// Removes a wallet from a group i.e when it's deleted.
63 + ///
64 + /// Update lead wallet after removing,
65 + /// Remove the group if it's empty (i.e., no lead wallet).
66 + void removeWallet(WalletInfo walletInfo) {
67 + final group = _getOrCreateGroup(_resolveParentAddress(walletInfo));
68 + group.wallets.remove(walletInfo);
69 +
70 + if (group.wallets.isEmpty) {
71 + walletGroups.remove(group);
72 + }
73 + }
74 +
75 + /// Returns all the child wallets within a group.
76 + ///
77 + /// If the group is not found, returns an empty group with no wallets.
78 + List<WalletInfo> getWalletsInGroup(String parentAddress) {
79 + return walletGroups
80 + .firstWhere(
81 + (group) => group.parentAddress == parentAddress,
82 + orElse: () => WalletGroup(parentAddress),
83 + )
84 + .wallets;
85 + }
86 +
87 + /// Iterate through all groups and load their custom names from storage
88 + void _loadCustomGroupNames() {
89 + for (var group in walletGroups) {
90 + final groupName = _sharedPreferences.getString('wallet_group_name_${group.parentAddress}');
91 + if (groupName != null && group.wallets.length > 1) {
92 + group.groupName = groupName; // Restore custom name
93 + }
94 + }
95 + }
96 +
97 + /// Save custom name for a group
98 + void _saveCustomGroupName(String parentAddress, String name) {
99 + _sharedPreferences.setString('wallet_group_name_$parentAddress', name);
100 + }
101 +
102 + // Set custom group name and persist it
103 + void setGroupName(String parentAddress, String name) {
104 + if (parentAddress.isEmpty || name.isEmpty) return;
105 +
106 + final group = walletGroups.firstWhere((group) => group.parentAddress == parentAddress);
107 + group.setCustomName(name);
108 + _saveCustomGroupName(parentAddress, name); // Persist the custom name
109 + }
110 +}
lib/ethereum/cw_ethereum.dart
+9 -1
@@ -10,10 +10,18 @@ class CWEthereum extends Ethereum {
10 @override
11 WalletCredentials createEthereumNewWalletCredentials({
12 required String name,
13 + String? mnemonic,
14 + String? parentAddress,
15 WalletInfo? walletInfo,
16 String? password,
17 }) =>
16 - EVMChainNewWalletCredentials(name: name, walletInfo: walletInfo, password: password);
18 + EVMChainNewWalletCredentials(
19 + name: name,
20 + walletInfo: walletInfo,
21 + password: password,
22 + parentAddress: parentAddress,
23 + mnemonic: mnemonic,
24 + );
25
26 @override
27 WalletCredentials createEthereumRestoreWalletFromSeedCredentials({
lib/nano/cw_nano.dart
+6 -1
@@ -91,12 +91,17 @@ class CWNano extends Nano {
91 @override
92 WalletCredentials createNanoNewWalletCredentials({
93 required String name,
94 + WalletInfo? walletInfo,
95 String? password,
96 + String? mnemonic,
97 + String? parentAddress,
98 }) =>
99 NanoNewWalletCredentials(
100 name: name,
101 password: password,
99 - derivationType: DerivationType.nano,
102 + mnemonic: mnemonic,
103 + parentAddress: parentAddress,
104 + walletInfo: walletInfo,
105 );
106
107 @override
lib/polygon/cw_polygon.dart
+28 -21
@@ -8,12 +8,19 @@ class CWPolygon extends Polygon {
8 PolygonWalletService(walletInfoSource, isDirect, client: PolygonClient());
9
10 @override
11 - WalletCredentials createPolygonNewWalletCredentials({
12 - required String name,
13 - WalletInfo? walletInfo,
14 - String? password
15 - }) =>
16 - EVMChainNewWalletCredentials(name: name, walletInfo: walletInfo, password: password);
11 + WalletCredentials createPolygonNewWalletCredentials(
12 + {required String name,
13 + String? mnemonic,
14 + String? parentAddress,
15 + WalletInfo? walletInfo,
16 + String? password}) =>
17 + EVMChainNewWalletCredentials(
18 + name: name,
19 + walletInfo: walletInfo,
20 + password: password,
21 + mnemonic: mnemonic,
22 + parentAddress: parentAddress,
23 + );
24
25 @override
26 WalletCredentials createPolygonRestoreWalletFromSeedCredentials({
@@ -77,21 +84,21 @@ class CWPolygon extends Polygon {
84 int? feeRate,
85 }) =>
86 EVMChainTransactionCredentials(
80 - outputs
81 - .map((out) => OutputInfo(
82 - fiatAmount: out.fiatAmount,
83 - cryptoAmount: out.cryptoAmount,
84 - address: out.address,
85 - note: out.note,
86 - sendAll: out.sendAll,
87 - extractedAddress: out.extractedAddress,
88 - isParsedAddress: out.isParsedAddress,
89 - formattedCryptoAmount: out.formattedCryptoAmount))
90 - .toList(),
91 - priority: priority as EVMChainTransactionPriority,
92 - currency: currency,
93 - feeRate: feeRate,
94 - );
87 + outputs
88 + .map((out) => OutputInfo(
89 + fiatAmount: out.fiatAmount,
90 + cryptoAmount: out.cryptoAmount,
91 + address: out.address,
92 + note: out.note,
93 + sendAll: out.sendAll,
94 + extractedAddress: out.extractedAddress,
95 + isParsedAddress: out.isParsedAddress,
96 + formattedCryptoAmount: out.formattedCryptoAmount))
97 + .toList(),
98 + priority: priority as EVMChainTransactionPriority,
99 + currency: currency,
100 + feeRate: feeRate,
101 + );
102
103 Object createPolygonTransactionCredentialsRaw(
104 List<OutputInfo> outputs, {
lib/reactions/bip39_wallet_utils.dart new
+21
@@ -0,0 +1,21 @@
1 +import 'package:cw_core/wallet_type.dart';
2 +
3 +bool isBIP39Wallet(WalletType walletType) {
4 + switch (walletType) {
5 + case WalletType.ethereum:
6 + case WalletType.polygon:
7 + case WalletType.solana:
8 + case WalletType.tron:
9 + case WalletType.bitcoin:
10 + case WalletType.litecoin:
11 + case WalletType.bitcoinCash:
12 + case WalletType.nano:
13 + case WalletType.banano:
14 + return true;
15 + case WalletType.monero:
16 + case WalletType.wownero:
17 + case WalletType.haven:
18 + case WalletType.none:
19 + return false;
20 + }
21 +}
lib/router.dart
+100 -32
@@ -1,11 +1,14 @@
1 import 'package:cake_wallet/anonpay/anonpay_info_base.dart';
2 import 'package:cake_wallet/anonpay/anonpay_invoice_info.dart';
3 +import 'package:cake_wallet/core/new_wallet_arguments.dart';
4 import 'package:cake_wallet/buy/order.dart';
5 +import 'package:cake_wallet/core/new_wallet_type_arguments.dart';
6 import 'package:cake_wallet/core/totp_request_details.dart';
7 import 'package:cake_wallet/core/wallet_connect/web3wallet_service.dart';
8 import 'package:cake_wallet/di.dart';
9 import 'package:cake_wallet/entities/contact_record.dart';
10 import 'package:cake_wallet/entities/qr_view_data.dart';
11 +import 'package:cake_wallet/entities/wallet_edit_page_arguments.dart';
12 import 'package:cake_wallet/entities/wallet_nft_response.dart';
13 import 'package:cake_wallet/exchange/trade.dart';
14 import 'package:cake_wallet/generated/i18n.dart';
@@ -40,9 +43,11 @@ import 'package:cake_wallet/src/screens/faq/faq_page.dart';
43 import 'package:cake_wallet/src/screens/monero_accounts/monero_account_edit_or_create_page.dart';
44 import 'package:cake_wallet/src/screens/nano/nano_change_rep_page.dart';
45 import 'package:cake_wallet/src/screens/nano_accounts/nano_account_edit_or_create_page.dart';
46 +import 'package:cake_wallet/src/screens/new_wallet/wallet_group_display_page.dart';
47 import 'package:cake_wallet/src/screens/new_wallet/advanced_privacy_settings_page.dart';
48 import 'package:cake_wallet/src/screens/new_wallet/new_wallet_page.dart';
49 import 'package:cake_wallet/src/screens/new_wallet/new_wallet_type_page.dart';
50 +import 'package:cake_wallet/src/screens/new_wallet/wallet_group_description_page.dart';
51 import 'package:cake_wallet/src/screens/nodes/node_create_or_edit_page.dart';
52 import 'package:cake_wallet/src/screens/nodes/pow_node_create_or_edit_page.dart';
53 import 'package:cake_wallet/src/screens/order_details/order_details_page.dart';
@@ -104,6 +109,7 @@ import 'package:cake_wallet/view_model/dashboard/sign_view_model.dart';
109 import 'package:cake_wallet/view_model/hardware_wallet/ledger_view_model.dart';
110 import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
111 import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
112 +import 'package:cake_wallet/view_model/wallet_groups_display_view_model.dart';
113 import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
114 import 'package:cake_wallet/view_model/wallet_hardware_restore_view_model.dart';
115 import 'package:cake_wallet/view_model/wallet_new_vm.dart';
@@ -134,7 +140,11 @@ Route<dynamic> createRoute(RouteSettings settings) {
140 if (SettingsStoreBase.walletPasswordDirectInput) {
141 if (availableWalletTypes.length == 1) {
142 return createRoute(
137 - RouteSettings(name: Routes.newWallet, arguments: availableWalletTypes.first));
143 + RouteSettings(
144 + name: Routes.newWallet,
145 + arguments: NewWalletArguments(type: availableWalletTypes.first),
146 + ),
147 + );
148 } else {
149 return createRoute(RouteSettings(name: Routes.newWalletType));
150 }
@@ -144,8 +154,10 @@ Route<dynamic> createRoute(RouteSettings settings) {
154 builder: (_) =>
155 getIt.get<SetupPinCodePage>(param1: (PinCodeState<PinCodeWidget> context, dynamic _) {
156 if (availableWalletTypes.length == 1) {
147 - Navigator.of(context.context)
148 - .pushNamed(Routes.newWallet, arguments: availableWalletTypes.first);
157 + Navigator.of(context.context).pushNamed(
158 + Routes.newWallet,
159 + arguments: NewWalletArguments(type: availableWalletTypes.first),
160 + );
161 } else {
162 Navigator.of(context.context).pushNamed(Routes.newWalletType);
163 }
@@ -154,17 +166,38 @@ Route<dynamic> createRoute(RouteSettings settings) {
166
167 case Routes.newWalletType:
168 return CupertinoPageRoute<void>(
157 - builder: (_) => getIt.get<NewWalletTypePage>(
158 - param1: (BuildContext context, WalletType type) =>
159 - Navigator.of(context).pushNamed(Routes.newWallet, arguments: type)));
169 + builder: (_) => getIt.get<NewWalletTypePage>(
170 + param1: NewWalletTypeArguments(
171 + onTypeSelected: (BuildContext context, WalletType type) =>
172 + Navigator.of(context).pushNamed(
173 + Routes.newWallet,
174 + arguments: NewWalletArguments(type: type),
175 + ),
176 + isCreate: true,
177 + isHardwareWallet: false,
178 + ),
179 + ),
180 + );
181
161 - case Routes.newWallet:
182 + case Routes.walletGroupsDisplayPage:
183 final type = settings.arguments as WalletType;
163 - final walletNewVM = getIt.get<WalletNewVM>(param1: type);
184 + final walletGroupsDisplayVM = getIt.get<WalletGroupsDisplayViewModel>(param1: type);
185 +
186 + return CupertinoPageRoute<void>(builder: (_) => WalletGroupsDisplayPage(walletGroupsDisplayVM));
187 +
188 + case Routes.newWallet:
189 + final args = settings.arguments as NewWalletArguments;
190 +
191 + final walletNewVM = getIt.get<WalletNewVM>(param1: args);
192 final seedSettingsViewModel = getIt.get<SeedSettingsViewModel>();
193
194 return CupertinoPageRoute<void>(
167 - builder: (_) => NewWalletPage(walletNewVM, seedSettingsViewModel));
195 + builder: (_) => NewWalletPage(
196 + walletNewVM,
197 + seedSettingsViewModel,
198 + isChildWallet: args.isChildWallet,
199 + ),
200 + );
201
202 case Routes.chooseHardwareWalletAccount:
203 final arguments = settings.arguments as List<dynamic>;
@@ -185,10 +218,15 @@ Route<dynamic> createRoute(RouteSettings settings) {
218
219 case Routes.restoreWalletType:
220 return CupertinoPageRoute<void>(
188 - builder: (_) => getIt.get<NewWalletTypePage>(
189 - param1: (BuildContext context, WalletType type) =>
190 - Navigator.of(context).pushNamed(Routes.restoreWallet, arguments: type),
191 - param2: [false, false]));
221 + builder: (_) => getIt.get<NewWalletTypePage>(
222 + param1: NewWalletTypeArguments(
223 + onTypeSelected: (BuildContext context, WalletType type) =>
224 + Navigator.of(context).pushNamed(Routes.restoreWallet, arguments: type),
225 + isCreate: false,
226 + isHardwareWallet: false,
227 + ),
228 + ),
229 + );
230
231 case Routes.restoreOptions:
232 if (SettingsStoreBase.walletPasswordDirectInput) {
@@ -220,10 +258,15 @@ Route<dynamic> createRoute(RouteSettings settings) {
258 builder: (_) => getIt.get<WalletRestorePage>(param1: availableWalletTypes.first));
259 } else {
260 return CupertinoPageRoute<void>(
223 - builder: (_) => getIt.get<NewWalletTypePage>(
224 - param1: (BuildContext context, WalletType type) =>
225 - Navigator.of(context).pushNamed(Routes.restoreWallet, arguments: type),
226 - param2: [false, false]));
261 + builder: (_) => getIt.get<NewWalletTypePage>(
262 + param1: NewWalletTypeArguments(
263 + onTypeSelected: (BuildContext context, WalletType type) =>
264 + Navigator.of(context).pushNamed(Routes.restoreWallet, arguments: type),
265 + isCreate: false,
266 + isHardwareWallet: false,
267 + ),
268 + ),
269 + );
270 }
271
272 case Routes.restoreWalletFromHardwareWallet:
@@ -252,23 +295,35 @@ Route<dynamic> createRoute(RouteSettings settings) {
295 ));
296 } else {
297 return CupertinoPageRoute<void>(
255 - builder: (_) => getIt.get<NewWalletTypePage>(
256 - param1: (BuildContext context, WalletType type) {
257 - final arguments = ConnectDevicePageParams(
258 - walletType: type,
259 - onConnectDevice: (BuildContext context, _) => Navigator.of(context)
260 - .pushNamed(Routes.chooseHardwareWalletAccount, arguments: [type]),
261 - );
262 -
263 - Navigator.of(context).pushNamed(Routes.connectDevices, arguments: arguments);
264 - },
265 - param2: [false, true]));
298 + builder: (_) => getIt.get<NewWalletTypePage>(
299 + param1: NewWalletTypeArguments(
300 + onTypeSelected: (BuildContext context, WalletType type) {
301 + final arguments = ConnectDevicePageParams(
302 + walletType: type,
303 + onConnectDevice: (BuildContext context, _) => Navigator.of(context)
304 + .pushNamed(Routes.chooseHardwareWalletAccount, arguments: [type]),
305 + );
306 +
307 + Navigator.of(context).pushNamed(Routes.connectDevices, arguments: arguments);
308 + },
309 + isCreate: false,
310 + isHardwareWallet: true,
311 + ),
312 + ),
313 + );
314 }
315
316 case Routes.restoreWalletTypeFromQR:
317 return CupertinoPageRoute<void>(
270 - builder: (_) => getIt.get<NewWalletTypePage>(
271 - param1: (BuildContext context, WalletType type) => Navigator.of(context).pop(type)));
318 + builder: (_) => getIt.get<NewWalletTypePage>(
319 + param1: NewWalletTypeArguments(
320 + onTypeSelected: (BuildContext context, WalletType type) =>
321 + Navigator.of(context).pop(type),
322 + isCreate: false,
323 + isHardwareWallet: false,
324 + ),
325 + ),
326 + );
327
328 case Routes.seed:
329 return MaterialPageRoute<void>(
@@ -341,8 +396,10 @@ Route<dynamic> createRoute(RouteSettings settings) {
396
397 case Routes.walletEdit:
398 return MaterialPageRoute<void>(
344 - fullscreenDialog: true,
345 - builder: (_) => getIt.get<WalletEditPage>(param1: settings.arguments as List<dynamic>));
399 + fullscreenDialog: true,
400 + builder: (_) =>
401 + getIt.get<WalletEditPage>(param1: settings.arguments as WalletEditPageArguments),
402 + );
403
404 case Routes.auth:
405 return MaterialPageRoute<void>(
@@ -592,12 +649,14 @@ Route<dynamic> createRoute(RouteSettings settings) {
649 final args = settings.arguments as Map<String, dynamic>;
650 final type = args['type'] as WalletType;
651 final isFromRestore = args['isFromRestore'] as bool? ?? false;
652 + final isChildWallet = args['isChildWallet'] as bool? ?? false;
653 final useTestnet = args['useTestnet'] as bool;
654 final toggleTestnet = args['toggleTestnet'] as Function(bool? val);
655
656 return CupertinoPageRoute<void>(
657 builder: (_) => AdvancedPrivacySettingsPage(
658 isFromRestore: isFromRestore,
659 + isChildWallet: isChildWallet,
660 useTestnet: useTestnet,
661 toggleUseTestnet: toggleTestnet,
662 advancedPrivacySettingsViewModel:
@@ -712,6 +771,15 @@ Route<dynamic> createRoute(RouteSettings settings) {
771 return MaterialPageRoute<void>(
772 builder: (_) => ConnectDevicePage(params, getIt.get<LedgerViewModel>()));
773
774 + case Routes.walletGroupDescription:
775 + final walletType = settings.arguments as WalletType;
776 +
777 + return MaterialPageRoute<void>(
778 + builder: (_) => WalletGroupDescriptionPage(
779 + selectedWalletType: walletType,
780 + ),
781 + );
782 +
783 default:
784 return MaterialPageRoute<void>(
785 builder: (_) => Scaffold(
lib/routes.dart
+5 -4
@@ -8,8 +8,7 @@ class Routes {
8 static const restoreWalletFromSeedKeys = '/restore_wallet_from_seeds_keys';
9 static const restoreWalletFromHardwareWallet = '/restore/hardware_wallet';
10 static const restoreWalletTypeFromQR = '/restore_wallet_from_qr_code';
11 - static const restoreWalletChooseDerivation =
12 - '/restore_wallet_choose_derivation';
11 + static const restoreWalletChooseDerivation = '/restore_wallet_choose_derivation';
12 static const chooseHardwareWalletAccount = '/restore/hardware_wallet/accounts';
13 static const dashboard = '/dashboard';
14 static const send = '/send';
@@ -99,11 +98,13 @@ class Routes {
98 static const editToken = '/edit_token';
99 static const manageNodes = '/manage_nodes';
100 static const managePowNodes = '/manage_pow_nodes';
102 - static const walletConnectConnectionsListing =
103 - '/wallet-connect-connections-listing';
101 + static const walletConnectConnectionsListing = '/wallet-connect-connections-listing';
102 static const nftDetailsPage = '/nft_details_page';
103 static const importNFTPage = '/import_nft_page';
104 static const torPage = '/tor_page';
105 +
106 static const signPage = '/sign_page';
107 static const connectDevices = '/device/connect';
108 + static const walletGroupsDisplayPage = '/wallet_groups_display_page';
109 + static const walletGroupDescription = '/wallet_group_description';
110 }
lib/solana/cw_solana.dart
+9 -1
@@ -10,10 +10,18 @@ class CWSolana extends Solana {
10 @override
11 WalletCredentials createSolanaNewWalletCredentials({
12 required String name,
13 + String? mnemonic,
14 + String? parentAddress,
15 WalletInfo? walletInfo,
16 String? password,
17 }) =>
16 - SolanaNewWalletCredentials(name: name, walletInfo: walletInfo, password: password);
18 + SolanaNewWalletCredentials(
19 + name: name,
20 + walletInfo: walletInfo,
21 + password: password,
22 + mnemonic: mnemonic,
23 + parentAddress: parentAddress,
24 + );
25
26 @override
27 WalletCredentials createSolanaRestoreWalletFromSeedCredentials({
lib/src/screens/dashboard/desktop_widgets/desktop_wallet_selection_dropdown.dart
+3 -1
@@ -1,4 +1,6 @@
1 import 'package:another_flushbar/flushbar.dart';
2 +import 'package:cake_wallet/core/new_wallet_arguments.dart';
3 +import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
4 import 'package:cake_wallet/core/auth_service.dart';
5 import 'package:cake_wallet/entities/desktop_dropdown_item.dart';
6 import 'package:cake_wallet/generated/i18n.dart';
@@ -219,7 +221,7 @@ class _DesktopWalletSelectionDropDownState extends State<DesktopWalletSelectionD
221 widget._authService.authenticateAction(
222 context,
223 route: Routes.newWallet,
222 - arguments: widget.walletListViewModel.currentWalletType,
224 + arguments: NewWalletArguments(type: widget.walletListViewModel.currentWalletType),
225 conditionToDetermineIfToUse2FA:
226 widget.walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets,
227 );
lib/src/screens/new_wallet/advanced_privacy_settings_page.dart
+73 -10
@@ -9,10 +9,12 @@ import 'package:cake_wallet/src/screens/nodes/widgets/node_form.dart';
9 import 'package:cake_wallet/src/screens/settings/widgets/settings_choices_cell.dart';
10 import 'package:cake_wallet/src/screens/settings/widgets/settings_picker_cell.dart';
11 import 'package:cake_wallet/src/screens/settings/widgets/settings_switcher_cell.dart';
12 +import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
13 import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
14 import 'package:cake_wallet/src/widgets/primary_button.dart';
15 import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart';
16 import 'package:cake_wallet/themes/extensions/new_wallet_theme.dart';
17 +import 'package:cake_wallet/utils/show_pop_up.dart';
18 import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart';
19 import 'package:cake_wallet/view_model/node_list/node_create_or_edit_view_model.dart';
20 import 'package:cake_wallet/view_model/seed_settings_view_model.dart';
@@ -24,6 +26,7 @@ import 'package:flutter_mobx/flutter_mobx.dart';
26 class AdvancedPrivacySettingsPage extends BasePage {
27 AdvancedPrivacySettingsPage({
28 required this.isFromRestore,
29 + required this.isChildWallet,
30 required this.useTestnet,
31 required this.toggleUseTestnet,
32 required this.advancedPrivacySettingsViewModel,
@@ -39,25 +42,40 @@ class AdvancedPrivacySettingsPage extends BasePage {
42 String get title => S.current.privacy_settings;
43
44 final bool isFromRestore;
45 + final bool isChildWallet;
46 final bool useTestnet;
47 final Function(bool? val) toggleUseTestnet;
48
49 @override
46 - Widget body(BuildContext context) => _AdvancedPrivacySettingsBody(isFromRestore, useTestnet,
47 - toggleUseTestnet, advancedPrivacySettingsViewModel, nodeViewModel, seedSettingsViewModel);
50 + Widget body(BuildContext context) => _AdvancedPrivacySettingsBody(
51 + isFromRestore,
52 + isChildWallet,
53 + useTestnet,
54 + toggleUseTestnet,
55 + advancedPrivacySettingsViewModel,
56 + nodeViewModel,
57 + seedSettingsViewModel,
58 + );
59 }
60
61 class _AdvancedPrivacySettingsBody extends StatefulWidget {
51 - const _AdvancedPrivacySettingsBody(this.isFromRestore, this.useTestnet, this.toggleUseTestnet,
52 - this.privacySettingsViewModel, this.nodeViewModel, this.seedTypeViewModel,
53 - {Key? key})
54 - : super(key: key);
62 + const _AdvancedPrivacySettingsBody(
63 + this.isFromRestore,
64 + this.isChildWallet,
65 + this.useTestnet,
66 + this.toggleUseTestnet,
67 + this.privacySettingsViewModel,
68 + this.nodeViewModel,
69 + this.seedTypeViewModel, {
70 + Key? key,
71 + }) : super(key: key);
72
73 final AdvancedPrivacySettingsViewModel privacySettingsViewModel;
74 final NodeCreateOrEditViewModel nodeViewModel;
75 final SeedSettingsViewModel seedTypeViewModel;
76
77 final bool isFromRestore;
78 + final bool isChildWallet;
79 final bool useTestnet;
80 final Function(bool? val) toggleUseTestnet;
81
@@ -78,6 +96,16 @@ class _AdvancedPrivacySettingsBodyState extends State<_AdvancedPrivacySettingsBo
96
97 passphraseController
98 .addListener(() => widget.seedTypeViewModel.setPassphrase(passphraseController.text));
99 +
100 + if (widget.isChildWallet) {
101 + if (widget.privacySettingsViewModel.type == WalletType.bitcoin) {
102 + widget.seedTypeViewModel.setBitcoinSeedType(BitcoinSeedType.bip39);
103 + }
104 +
105 + if (widget.privacySettingsViewModel.type == WalletType.nano) {
106 + widget.seedTypeViewModel.setNanoSeedType(NanoSeedType.bip39);
107 + }
108 + }
109 super.initState();
110 }
111
@@ -116,7 +144,7 @@ class _AdvancedPrivacySettingsBodyState extends State<_AdvancedPrivacySettingsBo
144 ),
145 );
146 }),
119 - if (widget.privacySettingsViewModel.hasSeedTypeOption)
147 + if (widget.privacySettingsViewModel.isMoneroSeedTypeOptionsEnabled)
148 Observer(builder: (_) {
149 return SettingsChoicesCell(
150 ChoicesListItem<MoneroSeedType>(
@@ -127,15 +155,37 @@ class _AdvancedPrivacySettingsBodyState extends State<_AdvancedPrivacySettingsBo
155 ),
156 );
157 }),
130 - if ([WalletType.bitcoin, WalletType.litecoin]
131 - .contains(widget.privacySettingsViewModel.type))
158 + if (widget.privacySettingsViewModel.isBitcoinSeedTypeOptionsEnabled)
159 Observer(builder: (_) {
160 return SettingsChoicesCell(
161 ChoicesListItem<BitcoinSeedType>(
162 title: S.current.seedtype,
163 items: BitcoinSeedType.all,
164 selectedItem: widget.seedTypeViewModel.bitcoinSeedType,
138 - onItemSelected: widget.seedTypeViewModel.setBitcoinSeedType,
165 + onItemSelected: (type) {
166 + if (widget.isChildWallet && type != BitcoinSeedType.bip39) {
167 + showAlertForSelectingNonBIP39DerivationTypeForChildWallets();
168 + } else {
169 + widget.seedTypeViewModel.setBitcoinSeedType(type);
170 + }
171 + },
172 + ),
173 + );
174 + }),
175 + if (widget.privacySettingsViewModel.isNanoSeedTypeOptionsEnabled)
176 + Observer(builder: (_) {
177 + return SettingsChoicesCell(
178 + ChoicesListItem<NanoSeedType>(
179 + title: S.current.seedtype,
180 + items: NanoSeedType.all,
181 + selectedItem: widget.seedTypeViewModel.nanoSeedType,
182 + onItemSelected: (type) {
183 + if (widget.isChildWallet && type != NanoSeedType.bip39) {
184 + showAlertForSelectingNonBIP39DerivationTypeForChildWallets();
185 + } else {
186 + widget.seedTypeViewModel.setNanoSeedType(type);
187 + }
188 + },
189 ),
190 );
191 }),
@@ -256,6 +306,19 @@ class _AdvancedPrivacySettingsBodyState extends State<_AdvancedPrivacySettingsBo
306 );
307 }
308
309 + void showAlertForSelectingNonBIP39DerivationTypeForChildWallets() {
310 + showPopUp<void>(
311 + context: context,
312 + builder: (BuildContext context) {
313 + return AlertWithOneAction(
314 + alertTitle: S.current.seedtype_alert_title,
315 + alertContent: S.current.seedtype_alert_content,
316 + buttonText: S.of(context).ok,
317 + buttonAction: () => Navigator.of(context).pop(),
318 + );
319 + });
320 + }
321 +
322 @override
323 void dispose() {
324 passphraseController
lib/src/screens/new_wallet/new_wallet_page.dart
+20 -6
@@ -26,10 +26,15 @@ import 'package:flutter_mobx/flutter_mobx.dart';
26 import 'package:mobx/mobx.dart';
27
28 class NewWalletPage extends BasePage {
29 - NewWalletPage(this._walletNewVM, this._seedSettingsViewModel);
29 + NewWalletPage(
30 + this._walletNewVM,
31 + this._seedSettingsViewModel, {
32 + this.isChildWallet = false,
33 + });
34
35 final WalletNewVM _walletNewVM;
36 final SeedSettingsViewModel _seedSettingsViewModel;
37 + final bool isChildWallet;
38
39 final walletNameImage = Image.asset('assets/images/wallet_name.png');
40
@@ -48,15 +53,23 @@ class NewWalletPage extends BasePage {
53
54 @override
55 Widget body(BuildContext context) => WalletNameForm(
51 - _walletNewVM,
52 - currentTheme.type == ThemeType.dark ? walletNameImage : walletNameLightImage,
53 - _seedSettingsViewModel);
56 + _walletNewVM,
57 + currentTheme.type == ThemeType.dark ? walletNameImage : walletNameLightImage,
58 + _seedSettingsViewModel,
59 + isChildWallet,
60 + );
61 }
62
63 class WalletNameForm extends StatefulWidget {
57 - WalletNameForm(this._walletNewVM, this.walletImage, this._seedSettingsViewModel);
64 + WalletNameForm(
65 + this._walletNewVM,
66 + this.walletImage,
67 + this._seedSettingsViewModel,
68 + this.isChildWallet,
69 + );
70
71 final WalletNewVM _walletNewVM;
72 + final bool isChildWallet;
73 final Image walletImage;
74 final SeedSettingsViewModel _seedSettingsViewModel;
75
@@ -338,7 +351,8 @@ class _WalletNameFormState extends State<WalletNameForm> {
351 Navigator.of(context).pushNamed(Routes.advancedPrivacySettings, arguments: {
352 "type": _walletNewVM.type,
353 "useTestnet": _walletNewVM.useTestnet,
341 - "toggleTestnet": _walletNewVM.toggleUseTestnet
354 + "toggleTestnet": _walletNewVM.toggleUseTestnet,
355 + "isChildWallet": widget.isChildWallet,
356 });
357 },
358 child: Text(S.of(context).advanced_settings),
lib/src/screens/new_wallet/new_wallet_type_page.dart
+34 -15
@@ -1,6 +1,10 @@
1 +import 'package:cake_wallet/core/new_wallet_arguments.dart';
2 +import 'package:cake_wallet/core/new_wallet_type_arguments.dart';
3 import 'dart:io';
4
5 import 'package:cake_wallet/generated/i18n.dart';
6 +import 'package:cake_wallet/reactions/bip39_wallet_utils.dart';
7 +import 'package:cake_wallet/routes.dart';
8 import 'package:cake_wallet/src/screens/base_page.dart';
9 import 'package:cake_wallet/src/screens/new_wallet/widgets/select_button.dart';
10 import 'package:cake_wallet/src/screens/setup_2fa/widgets/popup_cancellable_alert.dart';
@@ -11,6 +15,7 @@ import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
15 import 'package:cake_wallet/themes/theme_base.dart';
16 import 'package:cake_wallet/utils/responsive_layout_util.dart';
17 import 'package:cake_wallet/utils/show_pop_up.dart';
18 +import 'package:cake_wallet/view_model/new_wallet_type_view_model.dart';
19 import 'package:cake_wallet/wallet_types.g.dart';
20 import 'package:cw_core/hardware/device_connection_type.dart';
21 import 'package:cw_core/wallet_type.dart';
@@ -18,21 +23,20 @@ import 'package:flutter/material.dart';
23
24 class NewWalletTypePage extends BasePage {
25 NewWalletTypePage({
21 - required this.onTypeSelected,
22 - required this.isCreate,
23 - required this.isHardwareWallet,
26 + required this.newWalletTypeViewModel,
27 + required this.newWalletTypeArguments,
28 });
29
26 - final void Function(BuildContext, WalletType) onTypeSelected;
27 - final bool isCreate;
28 - final bool isHardwareWallet;
30 + final NewWalletTypeViewModel newWalletTypeViewModel;
31 + final NewWalletTypeArguments newWalletTypeArguments;
32
33 final walletTypeImage = Image.asset('assets/images/wallet_type.png');
34 final walletTypeLightImage = Image.asset('assets/images/wallet_type_light.png');
35
36 @override
34 - String get title =>
35 - isCreate ? S.current.wallet_list_create_new_wallet : S.current.wallet_list_restore_wallet;
37 + String get title => newWalletTypeArguments.isCreate
38 + ? S.current.wallet_list_create_new_wallet
39 + : S.current.wallet_list_restore_wallet;
40
41 @override
42 Function(BuildContext)? get pushToNextWidget => (context) {
@@ -44,24 +48,27 @@ class NewWalletTypePage extends BasePage {
48
49 @override
50 Widget body(BuildContext context) => WalletTypeForm(
47 - onTypeSelected: onTypeSelected,
51 walletImage: currentTheme.type == ThemeType.dark ? walletTypeImage : walletTypeLightImage,
49 - isCreate: isCreate,
50 - isHardwareWallet: isHardwareWallet,
52 + isCreate: newWalletTypeArguments.isCreate,
53 + newWalletTypeViewModel: newWalletTypeViewModel,
54 + onTypeSelected: newWalletTypeArguments.onTypeSelected,
55 + isHardwareWallet: newWalletTypeArguments.isHardwareWallet,
56 );
57 }
58
59 class WalletTypeForm extends StatefulWidget {
60 WalletTypeForm({
56 - required this.onTypeSelected,
61 required this.walletImage,
62 required this.isCreate,
63 + required this.newWalletTypeViewModel,
64 + this.onTypeSelected,
65 required this.isHardwareWallet,
66 });
67
62 - final void Function(BuildContext, WalletType) onTypeSelected;
63 - final Image walletImage;
68 final bool isCreate;
69 + final Image walletImage;
70 + final NewWalletTypeViewModel newWalletTypeViewModel;
71 + final void Function(BuildContext, WalletType)? onTypeSelected;
72 final bool isHardwareWallet;
73
74 @override
@@ -179,6 +186,18 @@ class WalletTypeFormState extends State<WalletTypeForm> {
186 );
187 }
188
182 - widget.onTypeSelected(context, selected!);
189 + // If it's a restore flow, trigger the external callback
190 + // If it's not a BIP39 Wallet or if there are no other wallets, route to the newWallet page
191 + // Any other scenario, route to pre-existing seed page
192 + if (!widget.isCreate) {
193 + widget.onTypeSelected!(context, selected!);
194 + } else if (!isBIP39Wallet(selected!) || !widget.newWalletTypeViewModel.hasExisitingWallet) {
195 + Navigator.of(context).pushNamed(
196 + Routes.newWallet,
197 + arguments: NewWalletArguments(type: selected!),
198 + );
199 + } else {
200 + Navigator.of(context).pushNamed(Routes.walletGroupDescription, arguments: selected!);
201 + }
202 }
203 }
lib/src/screens/new_wallet/wallet_group_description_page.dart new
+90
@@ -0,0 +1,90 @@
1 +import 'package:cake_wallet/core/new_wallet_arguments.dart';
2 +import 'package:cake_wallet/src/widgets/primary_button.dart';
3 +import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
4 +import 'package:cw_core/wallet_type.dart';
5 +import 'package:flutter/material.dart';
6 +
7 +import 'package:cake_wallet/generated/i18n.dart';
8 +import 'package:cake_wallet/routes.dart';
9 +import 'package:cake_wallet/src/screens/base_page.dart';
10 +
11 +class WalletGroupDescriptionPage extends BasePage {
12 + WalletGroupDescriptionPage({required this.selectedWalletType});
13 +
14 + final WalletType selectedWalletType;
15 +
16 + @override
17 + String get title => S.current.wallet_group;
18 +
19 + @override
20 + Widget body(BuildContext context) {
21 + return Container(
22 + alignment: Alignment.center,
23 + padding: EdgeInsets.all(24),
24 + child: Column(
25 + children: [
26 + Image.asset(
27 + 'assets/images/wallet_group.png',
28 + scale: 0.8,
29 + ),
30 + SizedBox(height: 32),
31 + Expanded(
32 + child: Text.rich(
33 + TextSpan(
34 + children: [
35 + TextSpan(text: '${S.of(context).wallet_group_description_one} '),
36 + TextSpan(
37 + text: '${S.of(context).wallet_group.toLowerCase()} ',
38 + style: TextStyle(fontWeight: FontWeight.w700),
39 + ),
40 + TextSpan(
41 + text: '${S.of(context).wallet_group_description_two} ',
42 + ),
43 + TextSpan(
44 + text: '${S.of(context).choose_wallet_group} ',
45 + style: TextStyle(fontWeight: FontWeight.w700),
46 + ),
47 + TextSpan(
48 + text: '${S.of(context).wallet_group_description_three} ',
49 + ),
50 + TextSpan(
51 + text: '${S.of(context).create_new_seed} ',
52 + style: TextStyle(fontWeight: FontWeight.w700),
53 + ),
54 + TextSpan(text: S.of(context).wallet_group_description_four),
55 + ],
56 + ),
57 + textAlign: TextAlign.center,
58 + style: TextStyle(
59 + height: 1.5,
60 + fontSize: 16,
61 + fontWeight: FontWeight.w400,
62 + color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor,
63 + ),
64 + ),
65 + ),
66 + PrimaryButton(
67 + onPressed: () => Navigator.of(context).pushNamed(
68 + Routes.newWallet,
69 + arguments: NewWalletArguments(type: selectedWalletType),
70 + ),
71 + text: S.of(context).create_new_seed,
72 + color: Theme.of(context).cardColor,
73 + textColor: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
74 + ),
75 + SizedBox(height: 12),
76 + PrimaryButton(
77 + onPressed: () => Navigator.of(context).pushNamed(
78 + Routes.walletGroupsDisplayPage,
79 + arguments: selectedWalletType,
80 + ),
81 + text: S.of(context).choose_wallet_group,
82 + color: Theme.of(context).primaryColor,
83 + textColor: Colors.white,
84 + ),
85 + SizedBox(height: 32),
86 + ],
87 + ),
88 + );
89 + }
90 +}
lib/src/screens/new_wallet/wallet_group_display_page.dart new
+192
@@ -0,0 +1,192 @@
1 +import 'package:cake_wallet/core/new_wallet_arguments.dart';
2 +import 'package:cake_wallet/generated/i18n.dart';
3 +import 'package:cake_wallet/routes.dart';
4 +import 'package:cake_wallet/src/screens/base_page.dart';
5 +import 'package:cake_wallet/src/screens/new_wallet/widgets/grouped_wallet_expansion_tile.dart';
6 +import 'package:cake_wallet/src/widgets/primary_button.dart';
7 +import 'package:cake_wallet/view_model/wallet_groups_display_view_model.dart';
8 +import 'package:cw_core/wallet_type.dart';
9 +import 'package:flutter/material.dart';
10 +import 'package:flutter_mobx/flutter_mobx.dart';
11 +
12 +import '../../../themes/extensions/cake_text_theme.dart';
13 +
14 +class WalletGroupsDisplayPage extends BasePage {
15 + WalletGroupsDisplayPage(this.walletGroupsDisplayViewModel);
16 +
17 + final WalletGroupsDisplayViewModel walletGroupsDisplayViewModel;
18 +
19 + final walletTypeImage = Image.asset('assets/images/wallet_type.png');
20 + final walletTypeLightImage = Image.asset('assets/images/wallet_type_light.png');
21 +
22 + @override
23 + String get title => S.current.wallet_group;
24 +
25 + @override
26 + Widget body(BuildContext context) => WalletGroupsDisplayBody(
27 + walletGroupsDisplayViewModel: walletGroupsDisplayViewModel,
28 + );
29 +}
30 +
31 +class WalletGroupsDisplayBody extends StatelessWidget {
32 + WalletGroupsDisplayBody({required this.walletGroupsDisplayViewModel});
33 +
34 + final WalletGroupsDisplayViewModel walletGroupsDisplayViewModel;
35 +
36 + @override
37 + Widget build(BuildContext context) {
38 + return Center(
39 + child: Padding(
40 + padding: EdgeInsets.all(24),
41 + child: Column(
42 + children: [
43 + Expanded(
44 + child: SingleChildScrollView(
45 + child: Observer(
46 + builder: (context) {
47 + return Column(
48 + children: [
49 + if (walletGroupsDisplayViewModel.hasNoFilteredWallet) ...{
50 + WalletGroupEmptyStateWidget(),
51 + },
52 + ...walletGroupsDisplayViewModel.multiWalletGroups.map(
53 + (walletGroup) {
54 + return Observer(builder: (context) {
55 + final index = walletGroupsDisplayViewModel.multiWalletGroups
56 + .indexOf(walletGroup);
57 + final group = walletGroupsDisplayViewModel.multiWalletGroups[index];
58 + final groupName =
59 + group.groupName ?? '${S.of(context).wallet_group} ${index + 1}';
60 + return GroupedWalletExpansionTile(
61 + leadingWidget:
62 + Icon(Icons.account_balance_wallet_outlined, size: 28),
63 + borderRadius: BorderRadius.all(Radius.circular(16)),
64 + title: groupName,
65 + childWallets: group.wallets.map((walletInfo) {
66 + return walletGroupsDisplayViewModel
67 + .convertWalletInfoToWalletListItem(walletInfo);
68 + }).toList(),
69 + isSelected:
70 + walletGroupsDisplayViewModel.selectedWalletGroup == group,
71 + onTitleTapped: () =>
72 + walletGroupsDisplayViewModel.selectWalletGroup(group),
73 + onChildItemTapped: (_) =>
74 + walletGroupsDisplayViewModel.selectWalletGroup(group),
75 + );
76 + });
77 + },
78 + ).toList(),
79 + ...walletGroupsDisplayViewModel.singleWalletsList.map((singleWallet) {
80 + return Observer(
81 + builder: (context) {
82 + final index = walletGroupsDisplayViewModel.singleWalletsList
83 + .indexOf(singleWallet);
84 + final wallet = walletGroupsDisplayViewModel.singleWalletsList[index];
85 + return GroupedWalletExpansionTile(
86 + borderRadius: BorderRadius.all(Radius.circular(16)),
87 + title: wallet.name,
88 + isSelected:
89 + walletGroupsDisplayViewModel.selectedSingleWallet == wallet,
90 + leadingWidget: Image.asset(
91 + walletTypeToCryptoCurrency(wallet.type).iconPath!,
92 + width: 32,
93 + height: 32,
94 + ),
95 + onTitleTapped: () =>
96 + walletGroupsDisplayViewModel.selectSingleWallet(wallet),
97 + );
98 + },
99 + );
100 + }).toList(),
101 + ],
102 + );
103 + },
104 + ),
105 + ),
106 + ),
107 + Observer(
108 + builder: (context) {
109 + return LoadingPrimaryButton(
110 + isLoading: walletGroupsDisplayViewModel.isFetchingMnemonic,
111 + onPressed: () {
112 + if (walletGroupsDisplayViewModel.hasNoFilteredWallet) {
113 + Navigator.of(context).pushNamed(
114 + Routes.newWallet,
115 + arguments: NewWalletArguments(type: walletGroupsDisplayViewModel.type),
116 + );
117 + } else {
118 + onTypeSelected(context);
119 + }
120 + },
121 + text: walletGroupsDisplayViewModel.hasNoFilteredWallet
122 + ? S.of(context).create_new_seed
123 + : S.of(context).seed_language_next,
124 + color: Theme.of(context).primaryColor,
125 + textColor: Colors.white,
126 + isDisabled: !walletGroupsDisplayViewModel.hasNoFilteredWallet
127 + ? (walletGroupsDisplayViewModel.selectedWalletGroup == null &&
128 + walletGroupsDisplayViewModel.selectedSingleWallet == null)
129 + : false,
130 + );
131 + },
132 + ),
133 + SizedBox(height: 32),
134 + ],
135 + ),
136 + ),
137 + );
138 + }
139 +
140 + Future<void> onTypeSelected(BuildContext context) async {
141 + final mnemonic = await walletGroupsDisplayViewModel.getSelectedWalletMnemonic();
142 + Navigator.of(context).pushNamed(
143 + Routes.newWallet,
144 + arguments: NewWalletArguments(
145 + type: walletGroupsDisplayViewModel.type,
146 + mnemonic: mnemonic,
147 + parentAddress: walletGroupsDisplayViewModel.parentAddress,
148 + isChildWallet: true,
149 + ),
150 + );
151 + }
152 +}
153 +
154 +class WalletGroupEmptyStateWidget extends StatelessWidget {
155 + const WalletGroupEmptyStateWidget({
156 + super.key,
157 + });
158 +
159 + @override
160 + Widget build(BuildContext context) {
161 + return Column(
162 + children: [
163 + Image.asset(
164 + 'assets/images/wallet_group.png',
165 + scale: 0.8,
166 + ),
167 + SizedBox(height: 32),
168 + Text.rich(
169 + TextSpan(
170 + children: [
171 + TextSpan(
172 + text: '${S.of(context).wallet_group_empty_state_text_one} ',
173 + ),
174 + TextSpan(
175 + text: '${S.of(context).create_new_seed} ',
176 + style: TextStyle(fontWeight: FontWeight.w700),
177 + ),
178 + TextSpan(text: S.of(context).wallet_group_empty_state_text_two),
179 + ],
180 + ),
181 + textAlign: TextAlign.center,
182 + style: TextStyle(
183 + height: 1.5,
184 + fontSize: 16,
185 + fontWeight: FontWeight.w400,
186 + color: Theme.of(context).extension<CakeTextTheme>()!.secondaryTextColor,
187 + ),
188 + ),
189 + ],
190 + );
191 + }
192 +}
lib/src/screens/new_wallet/widgets/grouped_wallet_expansion_tile.dart new
+119
@@ -0,0 +1,119 @@
1 +import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
2 +import 'package:cake_wallet/themes/extensions/filter_theme.dart';
3 +import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
4 +import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
5 +import 'package:cw_core/wallet_type.dart';
6 +import 'package:flutter/material.dart';
7 +
8 +class GroupedWalletExpansionTile extends StatelessWidget {
9 + GroupedWalletExpansionTile({
10 + required this.title,
11 + required this.isSelected,
12 + this.childWallets = const [],
13 + this.onTitleTapped,
14 + this.onChildItemTapped = _defaultVoidCallback,
15 + this.leadingWidget,
16 + this.trailingWidget,
17 + this.childTrailingWidget,
18 + this.decoration,
19 + this.color,
20 + this.textColor,
21 + this.arrowColor,
22 + this.borderRadius,
23 + this.margin,
24 + this.tileKey,
25 + }) : super(key: tileKey);
26 +
27 + final Key? tileKey;
28 + final bool isSelected;
29 +
30 + final VoidCallback? onTitleTapped;
31 + final void Function(WalletListItem item) onChildItemTapped;
32 +
33 + final String title;
34 + final Widget? leadingWidget;
35 + final Widget? trailingWidget;
36 + final Widget Function(WalletListItem)? childTrailingWidget;
37 +
38 + final List<WalletListItem> childWallets;
39 +
40 + final Color? color;
41 + final Color? textColor;
42 + final Color? arrowColor;
43 + final EdgeInsets? margin;
44 + final Decoration? decoration;
45 + final BorderRadius? borderRadius;
46 +
47 + static void _defaultVoidCallback(WalletListItem ITEM) {}
48 +
49 + @override
50 + Widget build(BuildContext context) {
51 + final backgroundColor = color ?? (isSelected ? Colors.green : Theme.of(context).cardColor);
52 + final effectiveTextColor = textColor ??
53 + (isSelected
54 + ? Theme.of(context).extension<WalletListTheme>()!.restoreWalletButtonTextColor
55 + : Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor);
56 +
57 + final effectiveArrowColor = arrowColor ??
58 + (isSelected
59 + ? Theme.of(context).extension<WalletListTheme>()!.restoreWalletButtonTextColor
60 + : Theme.of(context).extension<FilterTheme>()!.titlesColor);
61 + return Container(
62 + decoration: BoxDecoration(
63 + borderRadius: borderRadius ?? BorderRadius.all(Radius.circular(30)),
64 + color: backgroundColor,
65 + ),
66 + margin: margin ?? const EdgeInsets.only(bottom: 12.0),
67 + child: Theme(
68 + data: Theme.of(context).copyWith(
69 + dividerColor: Colors.transparent,
70 + splashFactory: NoSplash.splashFactory,
71 + ),
72 + child: ExpansionTile(
73 + key: tileKey,
74 + tilePadding: EdgeInsets.symmetric(vertical: 1, horizontal: 16),
75 + iconColor: effectiveArrowColor,
76 + collapsedIconColor: effectiveArrowColor,
77 + leading: leadingWidget,
78 + trailing: trailingWidget ?? (childWallets.isEmpty ? SizedBox.shrink() : null),
79 + title: GestureDetector(
80 + onTap: onTitleTapped,
81 + child: Text(
82 + title,
83 + style: TextStyle(
84 + fontSize: 18,
85 + fontWeight: FontWeight.w500,
86 + color: effectiveTextColor,
87 + ),
88 + textAlign: TextAlign.left,
89 + ),
90 + ),
91 + children: childWallets.map(
92 + (item) {
93 + final walletTypeToCrypto = walletTypeToCryptoCurrency(item.type);
94 + return ListTile(
95 + key: ValueKey(item.name),
96 + trailing: childTrailingWidget?.call(item),
97 + onTap: () => onChildItemTapped(item),
98 + leading: Image.asset(
99 + walletTypeToCrypto.iconPath!,
100 + width: 32,
101 + height: 32,
102 + ),
103 + title: Text(
104 + item.name,
105 + maxLines: 1,
106 + style: TextStyle(
107 + fontSize: 18,
108 + fontWeight: FontWeight.w500,
109 + color: effectiveTextColor,
110 + ),
111 + ),
112 + );
113 + },
114 + ).toList(),
115 + ),
116 + ),
117 + );
118 + }
119 +}
lib/src/screens/new_wallet/widgets/select_button.dart
+7 -3
@@ -18,9 +18,11 @@ class SelectButton extends StatelessWidget {
18 this.arrowColor,
19 this.borderColor,
20 this.deviceConnectionTypes,
21 + this.borderRadius,
22 + this.padding,
23 });
24
23 - final Image? image;
25 + final Widget? image;
26 final String text;
27 final double textSize;
28 final bool isSelected;
@@ -32,6 +34,8 @@ class SelectButton extends StatelessWidget {
34 final Color? textColor;
35 final Color? arrowColor;
36 final Color? borderColor;
37 + final BorderRadius? borderRadius;
38 + final EdgeInsets? padding;
39
40 @override
41 Widget build(BuildContext context) {
@@ -62,10 +66,10 @@ class SelectButton extends StatelessWidget {
66 child: Container(
67 width: double.infinity,
68 height: height,
65 - padding: EdgeInsets.only(left: 30, right: 30),
69 + padding: padding ?? EdgeInsets.only(left: 30, right: 30),
70 alignment: Alignment.center,
71 decoration: BoxDecoration(
68 - borderRadius: BorderRadius.all(Radius.circular(30)),
72 + borderRadius: borderRadius ?? BorderRadius.all(Radius.circular(30)),
73 color: backgroundColor,
74 border: borderColor != null ? Border.all(color: borderColor!) : null,
75 ),
lib/src/screens/restore/wallet_restore_page.dart
+1 -8
@@ -281,16 +281,9 @@ class WalletRestorePage extends BasePage {
281 return false;
282 }
283
284 - if ((walletRestoreViewModel.type == WalletType.litecoin) &&
285 - (seedWords.length != WalletRestoreViewModelBase.electrumSeedMnemonicLength &&
286 - seedWords.length != WalletRestoreViewModelBase.electrumShortSeedMnemonicLength)) {
287 - return false;
288 - }
289 -
284 // bip39:
285 const validSeedLengths = [12, 18, 24];
292 - if (walletRestoreViewModel.type == WalletType.bitcoin &&
293 - !(validSeedLengths.contains(seedWords.length))) {
286 + if (!(validSeedLengths.contains(seedWords.length))) {
287 return false;
288 }
289
lib/src/screens/wallet/wallet_edit_page.dart
+60 -49
@@ -1,20 +1,16 @@
1 import 'package:another_flushbar/flushbar.dart';
2 -import 'package:cake_wallet/core/auth_service.dart';
2 import 'package:cake_wallet/core/wallet_name_validator.dart';
3 +import 'package:cake_wallet/entities/wallet_edit_page_arguments.dart';
4 import 'package:cake_wallet/palette.dart';
5 import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
6 import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
7 import 'package:cake_wallet/routes.dart';
8 import 'package:cake_wallet/src/screens/auth/auth_page.dart';
9 import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart';
10 -import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
11 -import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
10 import 'package:cake_wallet/store/settings_store.dart';
11 import 'package:cake_wallet/utils/show_bar.dart';
12 import 'package:cake_wallet/utils/show_pop_up.dart';
13 import 'package:cake_wallet/view_model/wallet_list/wallet_edit_view_model.dart';
16 -import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
17 -import 'package:cake_wallet/view_model/wallet_new_vm.dart';
14 import 'package:flutter/material.dart';
15 import 'package:cake_wallet/generated/i18n.dart';
16 import 'package:cake_wallet/src/widgets/primary_button.dart';
@@ -22,29 +18,29 @@ import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
18 import 'package:cake_wallet/src/screens/base_page.dart';
19 import 'package:flutter_mobx/flutter_mobx.dart';
20
21 +
22 class WalletEditPage extends BasePage {
26 - WalletEditPage(
27 - {required this.walletEditViewModel,
28 - required this.editingWallet,
29 - required this.walletNewVM,
30 - required this.authService})
31 - : _formKey = GlobalKey<FormState>(),
23 + WalletEditPage({
24 + required this.pageArguments,
25 + }) : _formKey = GlobalKey<FormState>(),
26 _labelController = TextEditingController(),
27 + walletEditViewModel = pageArguments.walletEditViewModel!,
28 super() {
34 - _labelController.text = editingWallet.name;
29 + _labelController.text =
30 + pageArguments.isWalletGroup ? pageArguments.groupName : pageArguments.editingWallet.name;
31 _labelController.addListener(() => walletEditViewModel.newName = _labelController.text);
32 }
33
34 final GlobalKey<FormState> _formKey;
35 final TextEditingController _labelController;
36
37 + final WalletEditPageArguments pageArguments;
38 final WalletEditViewModel walletEditViewModel;
42 - final WalletNewVM walletNewVM;
43 - final WalletListItem editingWallet;
44 - final AuthService authService;
39
40 @override
47 - String get title => S.current.wallet_list_edit_wallet;
41 + String get title => pageArguments.isWalletGroup
42 + ? S.current.wallet_list_edit_group_name
43 + : S.current.wallet_list_edit_wallet;
44
45 Flushbar<void>? _progressBar;
46
@@ -57,11 +53,14 @@ class WalletEditPage extends BasePage {
53 child: Column(
54 children: <Widget>[
55 Expanded(
60 - child: Center(
61 - child: BaseTextFormField(
62 - controller: _labelController,
63 - hintText: S.of(context).wallet_list_wallet_name,
64 - validator: WalletNameValidator()))),
56 + child: Center(
57 + child: BaseTextFormField(
58 + controller: _labelController,
59 + hintText: S.of(context).wallet_list_wallet_name,
60 + validator: WalletNameValidator(),
61 + ),
62 + ),
63 + ),
64 Observer(
65 builder: (_) {
66 final isLoading = walletEditViewModel.state is WalletEditRenamePending ||
@@ -69,24 +68,26 @@ class WalletEditPage extends BasePage {
68
69 return Row(
70 children: <Widget>[
72 - Flexible(
73 - child: Container(
74 - padding: EdgeInsets.only(right: 8.0),
75 - child: LoadingPrimaryButton(
76 - isDisabled: isLoading,
77 - onPressed: () => _removeWallet(context),
78 - text: S.of(context).delete,
79 - color: Palette.red,
80 - textColor: Colors.white),
71 + if (!pageArguments.isWalletGroup)
72 + Flexible(
73 + child: Container(
74 + padding: EdgeInsets.only(right: 8.0),
75 + child: LoadingPrimaryButton(
76 + isDisabled: isLoading,
77 + onPressed: () => _removeWallet(context),
78 + text: S.of(context).delete,
79 + color: Palette.red,
80 + textColor: Colors.white),
81 + ),
82 ),
82 - ),
83 Flexible(
84 child: Container(
85 padding: EdgeInsets.only(left: 8.0),
86 child: LoadingPrimaryButton(
87 onPressed: () async {
88 if (_formKey.currentState?.validate() ?? false) {
89 - if (walletNewVM.nameExists(walletEditViewModel.newName)) {
89 + if (pageArguments.walletNewVM!
90 + .nameExists(walletEditViewModel.newName)) {
91 showPopUp<void>(
92 context: context,
93 builder: (_) {
@@ -102,29 +103,33 @@ class WalletEditPage extends BasePage {
103 try {
104 bool confirmed = false;
105
105 - if (SettingsStoreBase
106 - .walletPasswordDirectInput) {
106 + if (SettingsStoreBase.walletPasswordDirectInput) {
107 await Navigator.of(context).pushNamed(
108 Routes.walletUnlockLoadable,
109 arguments: WalletUnlockArguments(
110 - authPasswordHandler:
111 - (String password) async {
112 - await walletEditViewModel
113 - .changeName(editingWallet,
114 - password: password);
110 + authPasswordHandler: (String password) async {
111 + await walletEditViewModel.changeName(
112 + pageArguments.editingWallet,
113 + password: password,
114 + isWalletGroup: pageArguments.isWalletGroup,
115 + groupParentAddress: pageArguments.parentAddress,
116 + );
117 },
116 - callback: (bool
117 - isAuthenticatedSuccessfully,
118 + callback: (bool isAuthenticatedSuccessfully,
119 AuthPageState auth) async {
120 if (isAuthenticatedSuccessfully) {
121 auth.close();
122 confirmed = true;
123 }
124 },
124 - walletName: editingWallet.name,
125 - walletType: editingWallet.type));
125 + walletName: pageArguments.editingWallet.name,
126 + walletType: pageArguments.editingWallet.type));
127 } else {
127 - await walletEditViewModel.changeName(editingWallet);
128 + await walletEditViewModel.changeName(
129 + pageArguments.editingWallet,
130 + isWalletGroup: pageArguments.isWalletGroup,
131 + groupParentAddress: pageArguments.parentAddress,
132 + );
133 confirmed = true;
134 }
135
@@ -154,7 +159,9 @@ class WalletEditPage extends BasePage {
159 }
160
161 Future<void> _removeWallet(BuildContext context) async {
157 - authService.authenticateAction(context, onAuthSuccess: (isAuthenticatedSuccessfully) async {
162 + pageArguments.authService!.authenticateAction(
163 + context,
164 + onAuthSuccess: (isAuthenticatedSuccessfully) async {
165 if (!isAuthenticatedSuccessfully) {
166 return;
167 }
@@ -173,7 +180,8 @@ class WalletEditPage extends BasePage {
180 builder: (BuildContext dialogContext) {
181 return AlertWithTwoActions(
182 alertTitle: S.of(context).delete_wallet,
176 - alertContent: S.of(context).delete_wallet_confirm_message(editingWallet.name),
183 + alertContent:
184 + S.of(context).delete_wallet_confirm_message(pageArguments.editingWallet.name),
185 leftButtonText: S.of(context).cancel,
186 rightButtonText: S.of(context).delete,
187 actionLeftButton: () => Navigator.of(dialogContext).pop(),
@@ -187,13 +195,16 @@ class WalletEditPage extends BasePage {
195 Navigator.of(context).pop();
196
197 try {
190 - changeProcessText(context, S.of(context).wallet_list_removing_wallet(editingWallet.name));
191 - await walletEditViewModel.remove(editingWallet);
198 + changeProcessText(
199 + context, S.of(context).wallet_list_removing_wallet(pageArguments.editingWallet.name));
200 + await walletEditViewModel.remove(pageArguments.editingWallet);
201 hideProgressText();
202 } catch (e) {
203 changeProcessText(
204 context,
196 - S.of(context).wallet_list_failed_to_remove(editingWallet.name, e.toString()),
205 + S
206 + .of(context)
207 + .wallet_list_failed_to_remove(pageArguments.editingWallet.name, e.toString()),
208 );
209 }
210 }
lib/src/screens/wallet_list/edit_wallet_button_widget.dart new
+54
@@ -0,0 +1,54 @@
1 +import 'package:cake_wallet/themes/extensions/filter_theme.dart';
2 +import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
3 +import 'package:flutter/material.dart';
4 +
5 +class EditWalletButtonWidget extends StatelessWidget {
6 + const EditWalletButtonWidget({
7 + required this.width,
8 + required this.onTap,
9 + this.isGroup = false,
10 + super.key,
11 + });
12 +
13 + final bool isGroup;
14 + final double width;
15 + final VoidCallback onTap;
16 +
17 + @override
18 + Widget build(BuildContext context) {
19 + return Container(
20 + width: width,
21 + child: Row(
22 + children: [
23 + GestureDetector(
24 + onTap: onTap,
25 + child: Center(
26 + child: Container(
27 + height: 40,
28 + width: 44,
29 + padding: EdgeInsets.all(10),
30 + decoration: BoxDecoration(
31 + shape: BoxShape.circle,
32 + color: Theme.of(context).extension<ReceivePageTheme>()!.iconsBackgroundColor,
33 + ),
34 + child: Icon(
35 + Icons.edit,
36 + size: 14,
37 + color: Theme.of(context).extension<ReceivePageTheme>()!.iconsColor,
38 + ),
39 + ),
40 + ),
41 + ),
42 + if (isGroup) ...{
43 + SizedBox(width: 6),
44 + Icon(
45 + Icons.keyboard_arrow_down,
46 + size: 24,
47 + color: Theme.of(context).extension<FilterTheme>()!.titlesColor,
48 + ),
49 + },
50 + ],
51 + ),
52 + );
53 + }
54 +}
lib/src/screens/wallet_list/filtered_list.dart
+3
@@ -7,11 +7,13 @@ class FilteredList extends StatefulWidget {
7 required this.list,
8 required this.itemBuilder,
9 required this.updateFunction,
10 + this.shrinkWrap = false,
11 });
12
13 final ObservableList<dynamic> list;
14 final Widget Function(BuildContext, int) itemBuilder;
15 final Function updateFunction;
16 + final bool shrinkWrap;
17
18 @override
19 FilteredListState createState() => FilteredListState();
@@ -22,6 +24,7 @@ class FilteredListState extends State<FilteredList> {
24 Widget build(BuildContext context) {
25 return Observer(
26 builder: (_) => ReorderableListView.builder(
27 + shrinkWrap: widget.shrinkWrap,
28 physics: const BouncingScrollPhysics(),
29 itemBuilder: widget.itemBuilder,
30 itemCount: widget.list.length,
lib/src/screens/wallet_list/wallet_list_page.dart
+142 -106
@@ -1,5 +1,9 @@
1 +import 'package:cake_wallet/core/new_wallet_arguments.dart';
2 +import 'package:cake_wallet/entities/wallet_edit_page_arguments.dart';
3 import 'package:cake_wallet/entities/wallet_list_order_types.dart';
4 import 'package:cake_wallet/src/screens/dashboard/widgets/filter_list_widget.dart';
5 +import 'package:cake_wallet/src/screens/new_wallet/widgets/grouped_wallet_expansion_tile.dart';
6 +import 'package:cake_wallet/src/screens/wallet_list/edit_wallet_button_widget.dart';
7 import 'package:cake_wallet/src/screens/wallet_list/filtered_list.dart';
8 import 'package:cake_wallet/src/screens/wallet_unlock/wallet_unlock_arguments.dart';
9 import 'package:cake_wallet/store/settings_store.dart';
@@ -7,8 +11,6 @@ import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
11 import 'package:cake_wallet/src/screens/auth/auth_page.dart';
12 import 'package:cake_wallet/core/auth_service.dart';
13 import 'package:cake_wallet/themes/extensions/filter_theme.dart';
10 -import 'package:cake_wallet/themes/extensions/receive_page_theme.dart';
11 -import 'package:cake_wallet/utils/device_info.dart';
14 import 'package:cake_wallet/utils/responsive_layout_util.dart';
15 import 'package:cake_wallet/utils/show_bar.dart';
16 import 'package:cake_wallet/utils/show_pop_up.dart';
@@ -23,7 +25,6 @@ import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
25 import 'package:cake_wallet/src/widgets/primary_button.dart';
26 import 'package:cake_wallet/src/screens/base_page.dart';
27 import 'package:cake_wallet/wallet_type_utils.dart';
26 -import 'package:cake_wallet/themes/extensions/wallet_list_theme.dart';
28
29 class WalletListPage extends BasePage {
30 WalletListPage({required this.walletListViewModel, required this.authService});
@@ -128,112 +129,143 @@ class WalletListBodyState extends State<WalletListBody> {
129 child: Column(
130 children: [
131 Expanded(
131 - child: Container(
132 - child: Observer(
133 - builder: (_) => FilteredList(
134 - list: widget.walletListViewModel.wallets,
135 - updateFunction: widget.walletListViewModel.reorderAccordingToWalletList,
136 - itemBuilder: (__, index) {
137 - final wallet = widget.walletListViewModel.wallets[index];
138 - final currentColor = wallet.isCurrent
139 - ? Theme.of(context)
140 - .extension<WalletListTheme>()!
141 - .createNewWalletButtonBackgroundColor
142 - : Theme.of(context).colorScheme.background;
143 - final row = GestureDetector(
144 - key: ValueKey(wallet.name),
145 - onTap: () => wallet.isCurrent ? null : _loadWallet(wallet),
146 - child: Container(
147 - height: tileHeight,
148 - width: double.infinity,
149 - child: Row(
150 - children: <Widget>[
151 - Container(
152 - height: tileHeight,
153 - width: 4,
154 - decoration: BoxDecoration(
155 - borderRadius: BorderRadius.only(
156 - topRight: Radius.circular(4),
157 - bottomRight: Radius.circular(4)),
158 - color: currentColor),
159 - ),
160 - Expanded(
161 - child: Container(
162 - height: tileHeight,
163 - padding: EdgeInsets.only(left: 20, right: 20),
164 - color: Theme.of(context).colorScheme.background,
165 - alignment: Alignment.centerLeft,
166 - child: Row(
167 - crossAxisAlignment: CrossAxisAlignment.center,
168 - children: <Widget>[
169 - wallet.isEnabled
170 - ? _imageFor(
171 - type: wallet.type,
172 - isTestnet: wallet.isTestnet,
173 - )
174 - : nonWalletTypeIcon,
175 - SizedBox(width: 10),
176 - Flexible(
177 - child: Text(
178 - wallet.name,
179 - maxLines: null,
180 - softWrap: true,
181 - style: TextStyle(
182 - fontSize: DeviceInfo.instance.isDesktop ? 18 : 20,
183 - fontWeight: FontWeight.w500,
184 - color: Theme.of(context)
185 - .extension<CakeTextTheme>()!
186 - .titleColor,
187 - ),
188 - ),
132 + child: SingleChildScrollView(
133 + child: Column(
134 + crossAxisAlignment: CrossAxisAlignment.start,
135 + children: [
136 + if (widget.walletListViewModel.multiWalletGroups.isNotEmpty) ...{
137 + Padding(
138 + padding: const EdgeInsets.only(left: 24),
139 + child: Text(
140 + S.current.shared_seed_wallet_groups,
141 + style: TextStyle(
142 + fontSize: 18,
143 + fontWeight: FontWeight.w500,
144 + color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
145 + ),
146 + ),
147 + ),
148 + SizedBox(height: 16),
149 + Container(
150 + child: Observer(
151 + builder: (_) => FilteredList(
152 + shrinkWrap: true,
153 + list: widget.walletListViewModel.multiWalletGroups,
154 + updateFunction: widget.walletListViewModel.reorderAccordingToWalletList,
155 + itemBuilder: (context, index) {
156 + final group = widget.walletListViewModel.multiWalletGroups[index];
157 + final groupName = group.groupName ??
158 + '${S.current.wallet_group} ${index + 1}';
159 + return GroupedWalletExpansionTile(
160 + borderRadius: BorderRadius.all(Radius.circular(16)),
161 + margin: EdgeInsets.only(left: 20, right: 20, bottom: 12),
162 + title: groupName,
163 + tileKey: ValueKey('group_wallets_expansion_tile_widget_$index'),
164 + leadingWidget: Icon(
165 + Icons.account_balance_wallet_outlined,
166 + size: 28,
167 + ),
168 + trailingWidget: EditWalletButtonWidget(
169 + width: 74,
170 + isGroup: true,
171 + onTap: () {
172 + final wallet = widget.walletListViewModel
173 + .convertWalletInfoToWalletListItem(group.wallets.first);
174 + Navigator.of(context).pushNamed(
175 + Routes.walletEdit,
176 + arguments: WalletEditPageArguments(
177 + walletListViewModel: widget.walletListViewModel,
178 + editingWallet: wallet,
179 + isWalletGroup: true,
180 + groupName: groupName,
181 + parentAddress: group.parentAddress,
182 ),
190 - ],
191 - ),
183 + );
184 + },
185 ),
193 - ),
194 - ],
186 + childWallets: group.wallets.map((walletInfo) {
187 + return widget.walletListViewModel
188 + .convertWalletInfoToWalletListItem(walletInfo);
189 + }).toList(),
190 + isSelected: false,
191 + onChildItemTapped: (wallet) =>
192 + wallet.isCurrent ? null : _loadWallet(wallet),
193 + childTrailingWidget: (item) {
194 + return item.isCurrent
195 + ? SizedBox.shrink()
196 + : EditWalletButtonWidget(
197 + width: 44,
198 + onTap: () => Navigator.of(context).pushNamed(
199 + Routes.walletEdit,
200 + arguments: WalletEditPageArguments(
201 + walletListViewModel: widget.walletListViewModel,
202 + editingWallet: item,
203 + ),
204 + ),
205 + );
206 + },
207 + );
208 + },
209 + ),
210 + ),
211 + ),
212 + SizedBox(height: 24),
213 + },
214 + if (widget.walletListViewModel.singleWalletsList.isNotEmpty) ...{
215 + Padding(
216 + padding: const EdgeInsets.only(left: 24),
217 + child: Text(
218 + S.current.single_seed_wallets_group,
219 + style: TextStyle(
220 + fontSize: 18,
221 + fontWeight: FontWeight.w500,
222 + color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
223 ),
224 ),
197 - );
225 + ),
226 + SizedBox(height: 16),
227 + Container(
228 + child: Observer(
229 + builder: (_) => FilteredList(
230 + shrinkWrap: true,
231 + list: widget.walletListViewModel.singleWalletsList,
232 + updateFunction: widget.walletListViewModel.reorderAccordingToWalletList,
233 + itemBuilder: (context, index) {
234 + final wallet = widget.walletListViewModel.singleWalletsList[index];
235
199 - return wallet.isCurrent
200 - ? row
201 - : Row(
202 - key: ValueKey(wallet.name),
203 - children: [
204 - Expanded(child: row),
205 - GestureDetector(
206 - onTap: () => Navigator.of(context).pushNamed(Routes.walletEdit,
207 - arguments: [widget.walletListViewModel, wallet]),
208 - child: Container(
209 - padding: EdgeInsets.only(
210 - right: DeviceInfo.instance.isMobile ? 20 : 40),
211 - child: Center(
212 - child: Container(
213 - height: 40,
236 + return GroupedWalletExpansionTile(
237 + tileKey: ValueKey('single_wallets_expansion_tile_widget_$index'),
238 + leadingWidget: Image.asset(
239 + walletTypeToCryptoCurrency(wallet.type).iconPath!,
240 + width: 32,
241 + height: 32,
242 + ),
243 + title: wallet.name,
244 + isSelected: false,
245 + borderRadius: BorderRadius.all(Radius.circular(16)),
246 + margin: EdgeInsets.only(left: 20, right: 20, bottom: 12),
247 + onTitleTapped: () => wallet.isCurrent ? null : _loadWallet(wallet),
248 + trailingWidget: wallet.isCurrent
249 + ? null
250 + : EditWalletButtonWidget(
251 width: 44,
215 - padding: EdgeInsets.all(10),
216 - decoration: BoxDecoration(
217 - shape: BoxShape.circle,
218 - color: Theme.of(context)
219 - .extension<ReceivePageTheme>()!
220 - .iconsBackgroundColor,
221 - ),
222 - child: Icon(
223 - Icons.edit,
224 - size: 14,
225 - color: Theme.of(context)
226 - .extension<ReceivePageTheme>()!
227 - .iconsColor,
228 - ),
252 + onTap: () {
253 + Navigator.of(context).pushNamed(
254 + Routes.walletEdit,
255 + arguments: WalletEditPageArguments(
256 + walletListViewModel: widget.walletListViewModel,
257 + editingWallet: wallet,
258 + ),
259 + );
260 + },
261 ),
230 - ),
231 - ),
232 - ),
233 - ],
234 - );
262 + );
263 + },
264 + ),
265 + ),
266 + ),
267 },
236 - ),
268 + ],
269 ),
270 ),
271 ),
@@ -249,14 +281,18 @@ class WalletListBodyState extends State<WalletListBody> {
281 widget.authService.authenticateAction(
282 context,
283 route: Routes.newWallet,
252 - arguments: widget.walletListViewModel.currentWalletType,
284 + arguments: NewWalletArguments(
285 + type: widget.walletListViewModel.currentWalletType,
286 + ),
287 conditionToDetermineIfToUse2FA:
288 widget.walletListViewModel.shouldRequireTOTP2FAForCreatingNewWallets,
289 );
290 } else {
291 Navigator.of(context).pushNamed(
292 Routes.newWallet,
259 - arguments: widget.walletListViewModel.currentWalletType,
293 + arguments: NewWalletArguments(
294 + type: widget.walletListViewModel.currentWalletType,
295 + ),
296 );
297 }
298 } else {
@@ -340,15 +376,15 @@ class WalletListBodyState extends State<WalletListBody> {
376
377 Future<void> _loadWallet(WalletListItem wallet) async {
378 if (SettingsStoreBase.walletPasswordDirectInput) {
343 - Navigator.of(context).pushNamed(
344 - Routes.walletUnlockLoadable,
379 + Navigator.of(context).pushNamed(Routes.walletUnlockLoadable,
380 arguments: WalletUnlockArguments(
381 callback: (bool isAuthenticatedSuccessfully, AuthPageState auth) async {
382 if (isAuthenticatedSuccessfully) {
383 auth.close();
384 setState(() {});
385 }
351 - }, walletName: wallet.name,
386 + },
387 + walletName: wallet.name,
388 walletType: wallet.type));
389 return;
390 }
lib/store/settings_store.dart
+22
@@ -58,6 +58,7 @@ abstract class SettingsStoreBase with Store {
58 required AutoGenerateSubaddressStatus initialAutoGenerateSubaddressStatus,
59 required MoneroSeedType initialMoneroSeedType,
60 required BitcoinSeedType initialBitcoinSeedType,
61 + required NanoSeedType initialNanoSeedType,
62 required bool initialAppSecure,
63 required bool initialDisableBuy,
64 required bool initialDisableSell,
@@ -132,6 +133,7 @@ abstract class SettingsStoreBase with Store {
133 autoGenerateSubaddressStatus = initialAutoGenerateSubaddressStatus,
134 moneroSeedType = initialMoneroSeedType,
135 bitcoinSeedType = initialBitcoinSeedType,
136 + nanoSeedType = initialNanoSeedType,
137 fiatApiMode = initialFiatMode,
138 allowBiometricalAuthentication = initialAllowBiometricalAuthentication,
139 selectedCake2FAPreset = initialCake2FAPresetOptions,
@@ -341,6 +343,11 @@ abstract class SettingsStoreBase with Store {
343 (BitcoinSeedType bitcoinSeedType) => sharedPreferences.setInt(
344 PreferencesKey.bitcoinSeedType, bitcoinSeedType.raw));
345
346 + reaction(
347 + (_) => nanoSeedType,
348 + (NanoSeedType nanoSeedType) =>
349 + sharedPreferences.setInt(PreferencesKey.nanoSeedType, nanoSeedType.raw));
350 +
351 reaction(
352 (_) => fiatApiMode,
353 (FiatApiMode mode) =>
@@ -569,6 +576,7 @@ abstract class SettingsStoreBase with Store {
576 static const defaultSeedPhraseLength = SeedPhraseLength.twelveWords;
577 static const defaultMoneroSeedType = MoneroSeedType.defaultSeedType;
578 static const defaultBitcoinSeedType = BitcoinSeedType.defaultDerivationType;
579 + static const defaultNanoSeedType = NanoSeedType.defaultDerivationType;
580
581 @observable
582 FiatCurrency fiatCurrency;
@@ -603,6 +611,9 @@ abstract class SettingsStoreBase with Store {
611 @observable
612 BitcoinSeedType bitcoinSeedType;
613
614 + @observable
615 + NanoSeedType nanoSeedType;
616 +
617 @observable
618 bool isAppSecure;
619
@@ -974,6 +985,11 @@ abstract class SettingsStoreBase with Store {
985 ? BitcoinSeedType.deserialize(raw: _bitcoinSeedType)
986 : defaultBitcoinSeedType;
987
988 + final _nanoSeedType = sharedPreferences.getInt(PreferencesKey.nanoSeedType);
989 +
990 + final nanoSeedType =
991 + _nanoSeedType != null ? NanoSeedType.deserialize(raw: _nanoSeedType) : defaultNanoSeedType;
992 +
993 final nodes = <WalletType, Node>{};
994 final powNodes = <WalletType, Node>{};
995
@@ -1138,6 +1154,7 @@ abstract class SettingsStoreBase with Store {
1154 initialAutoGenerateSubaddressStatus: autoGenerateSubaddressStatus,
1155 initialMoneroSeedType: moneroSeedType,
1156 initialBitcoinSeedType: bitcoinSeedType,
1157 + initialNanoSeedType: nanoSeedType,
1158 initialAppSecure: isAppSecure,
1159 initialDisableBuy: disableBuy,
1160 initialDisableSell: disableSell,
@@ -1270,6 +1287,11 @@ abstract class SettingsStoreBase with Store {
1287 ? BitcoinSeedType.deserialize(raw: _bitcoinSeedType)
1288 : defaultBitcoinSeedType;
1289
1290 + final _nanoSeedType = sharedPreferences.getInt(PreferencesKey.nanoSeedType);
1291 +
1292 + nanoSeedType =
1293 + _nanoSeedType != null ? NanoSeedType.deserialize(raw: _nanoSeedType) : defaultNanoSeedType;
1294 +
1295 balanceDisplayMode = BalanceDisplayMode.deserialize(
1296 raw: sharedPreferences.getInt(PreferencesKey.currentBalanceDisplayModeKey)!);
1297 shouldSaveRecipientAddress =
lib/tron/cw_tron.dart
+11 -4
@@ -13,8 +13,15 @@ class CWTron extends Tron {
13 required String name,
14 WalletInfo? walletInfo,
15 String? password,
16 + String? mnemonic,
17 + String? parentAddress,
18 }) =>
17 - TronNewWalletCredentials(name: name, walletInfo: walletInfo, password: password);
19 + TronNewWalletCredentials(
20 + name: name,
21 + walletInfo: walletInfo,
22 + password: password,
23 + mnemonic: mnemonic,
24 + parentAddress: parentAddress);
25
26 @override
27 WalletCredentials createTronRestoreWalletFromSeedCredentials({
@@ -34,7 +41,7 @@ class CWTron extends Tron {
41
42 @override
43 String getAddress(WalletBase wallet) => (wallet as TronWallet).walletAddresses.address;
37 -
44 +
45 Object createTronTransactionCredentials(
46 List<Output> outputs, {
47 required CryptoCurrency currency,
@@ -63,10 +70,10 @@ class CWTron extends Tron {
70
71 @override
72 Future<void> addTronToken(WalletBase wallet, CryptoCurrency token, String contractAddress) async {
66 - final tronToken = TronToken(
73 + final tronToken = TronToken(
74 name: token.name,
75 symbol: token.title,
69 - contractAddress: contractAddress,
76 + contractAddress: contractAddress,
77 decimal: token.decimals,
78 enabled: token.enabled,
79 iconPath: token.iconPath,
lib/view_model/advanced_privacy_settings_view_model.dart
+16 -3
@@ -46,17 +46,30 @@ abstract class AdvancedPrivacySettingsViewModelBase with Store {
46 case WalletType.litecoin:
47 return _settingsStore.bitcoinSeedType == BitcoinSeedType.bip39;
48
49 + case WalletType.nano:
50 + case WalletType.banano:
51 + return _settingsStore.nanoSeedType == NanoSeedType.bip39;
52 +
53 case WalletType.monero:
54 case WalletType.wownero:
55 case WalletType.none:
56 case WalletType.haven:
53 - case WalletType.nano:
54 - case WalletType.banano:
57 return false;
58 }
59 }
60
59 - bool get hasSeedTypeOption => [WalletType.monero, WalletType.wownero].contains(type);
61 +
62 + bool get isMoneroSeedTypeOptionsEnabled => [
63 + WalletType.monero,
64 + WalletType.wownero,
65 + ].contains(type);
66 +
67 + bool get isBitcoinSeedTypeOptionsEnabled => [
68 + WalletType.bitcoin,
69 + WalletType.litecoin,
70 + ].contains(type);
71 +
72 + bool get isNanoSeedTypeOptionsEnabled => [WalletType.nano].contains(type);
73
74 bool get hasPassphraseOption => [
75 WalletType.bitcoin,
lib/view_model/new_wallet_type_view_model.dart new
+16
@@ -0,0 +1,16 @@
1 +import 'package:cw_core/wallet_info.dart';
2 +import 'package:hive/hive.dart';
3 +import 'package:mobx/mobx.dart';
4 +
5 +part 'new_wallet_type_view_model.g.dart';
6 +
7 +class NewWalletTypeViewModel = NewWalletTypeViewModelBase with _$NewWalletTypeViewModel;
8 +
9 +abstract class NewWalletTypeViewModelBase with Store {
10 + NewWalletTypeViewModelBase(this._walletInfoSource);
11 +
12 + @computed
13 + bool get hasExisitingWallet => _walletInfoSource.isNotEmpty;
14 +
15 + final Box<WalletInfo> _walletInfoSource;
16 +}
lib/view_model/seed_settings_view_model.dart
+7
@@ -23,6 +23,13 @@ abstract class SeedSettingsViewModelBase with Store {
23 void setBitcoinSeedType(BitcoinSeedType derivationType) =>
24 _appStore.settingsStore.bitcoinSeedType = derivationType;
25
26 + @computed
27 + NanoSeedType get nanoSeedType => _appStore.settingsStore.nanoSeedType;
28 +
29 + @action
30 + void setNanoSeedType(NanoSeedType derivationType) =>
31 + _appStore.settingsStore.nanoSeedType = derivationType;
32 +
33 @computed
34 String? get passphrase => this._seedSettingsStore.passphrase;
35
lib/view_model/wallet_creation_vm.dart
+13 -4
@@ -99,6 +99,7 @@ abstract class WalletCreationVMBase with Store {
99 showIntroCakePayCard: (!walletCreationService.typeExists(type)) && type != WalletType.haven,
100 derivationInfo: credentials.derivationInfo ?? getDefaultCreateDerivation(),
101 hardwareWalletType: credentials.hardwareWalletType,
102 + parentAddress: credentials.parentAddress,
103 );
104
105 credentials.walletInfo = walletInfo;
@@ -117,12 +118,16 @@ abstract class WalletCreationVMBase with Store {
118 }
119
120 DerivationInfo? getDefaultCreateDerivation() {
120 - final useBip39 = seedSettingsViewModel.bitcoinSeedType.type == DerivationType.bip39;
121 + final useBip39ForBitcoin = seedSettingsViewModel.bitcoinSeedType.type == DerivationType.bip39;
122 + final useBip39ForNano = seedSettingsViewModel.nanoSeedType.type == DerivationType.bip39;
123 switch (type) {
124 case WalletType.nano:
125 + if (useBip39ForNano) {
126 + return DerivationInfo(derivationType: DerivationType.bip39);
127 + }
128 return DerivationInfo(derivationType: DerivationType.nano);
129 case WalletType.bitcoin:
125 - if (useBip39) {
130 + if (useBip39ForBitcoin) {
131 return DerivationInfo(
132 derivationType: DerivationType.bip39,
133 derivationPath: "m/84'/0'/0'",
@@ -132,7 +137,7 @@ abstract class WalletCreationVMBase with Store {
137 }
138 return bitcoin!.getElectrumDerivations()[DerivationType.electrum]!.first;
139 case WalletType.litecoin:
135 - if (useBip39) {
140 + if (useBip39ForBitcoin) {
141 return DerivationInfo(
142 derivationType: DerivationType.bip39,
143 derivationPath: "m/84'/2'/0'",
@@ -148,9 +153,13 @@ abstract class WalletCreationVMBase with Store {
153
154 DerivationInfo? getCommonRestoreDerivation() {
155 final useElectrum = seedSettingsViewModel.bitcoinSeedType.type == DerivationType.electrum;
156 + final useNanoStandard = seedSettingsViewModel.nanoSeedType.type == DerivationType.nano;
157 switch (this.type) {
158 case WalletType.nano:
153 - return DerivationInfo(derivationType: DerivationType.nano);
159 + if (useNanoStandard) {
160 + return DerivationInfo(derivationType: DerivationType.nano);
161 + }
162 + return DerivationInfo(derivationType: DerivationType.bip39);
163 case WalletType.bitcoin:
164 if (useElectrum) {
165 return bitcoin!.getElectrumDerivations()[DerivationType.electrum]!.first;
lib/view_model/wallet_groups_display_view_model.dart new
+165
@@ -0,0 +1,165 @@
1 +import 'package:cake_wallet/core/wallet_loading_service.dart';
2 +import 'package:cake_wallet/entities/wallet_group.dart';
3 +import 'package:cake_wallet/entities/wallet_manager.dart';
4 +import 'package:cake_wallet/reactions/bip39_wallet_utils.dart';
5 +import 'package:cake_wallet/store/app_store.dart';
6 +import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
7 +import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
8 +import 'package:cake_wallet/wallet_types.g.dart';
9 +import 'package:cw_core/wallet_info.dart';
10 +import 'package:cw_core/wallet_type.dart';
11 +import 'package:mobx/mobx.dart';
12 +
13 +part 'wallet_groups_display_view_model.g.dart';
14 +
15 +class WalletGroupsDisplayViewModel = WalletGroupsDisplayViewModelBase
16 + with _$WalletGroupsDisplayViewModel;
17 +
18 +abstract class WalletGroupsDisplayViewModelBase with Store {
19 + WalletGroupsDisplayViewModelBase(
20 + this._appStore,
21 + this._walletLoadingService,
22 + this._walletManager,
23 + this.walletListViewModel, {
24 + required this.type,
25 + }) : isFetchingMnemonic = false,
26 + multiWalletGroups = ObservableList<WalletGroup>(),
27 + singleWalletsList = ObservableList<WalletInfo>() {
28 + reaction((_) => _appStore.wallet, (_) => updateWalletInfoSourceList());
29 + updateWalletInfoSourceList();
30 + }
31 +
32 + final WalletType type;
33 + final AppStore _appStore;
34 + final WalletManager _walletManager;
35 + final WalletLoadingService _walletLoadingService;
36 + final WalletListViewModel walletListViewModel;
37 +
38 + @observable
39 + ObservableList<WalletGroup> multiWalletGroups;
40 +
41 + @observable
42 + ObservableList<WalletInfo> singleWalletsList;
43 +
44 + @observable
45 + WalletGroup? selectedWalletGroup;
46 +
47 + @observable
48 + WalletInfo? selectedSingleWallet;
49 +
50 + @observable
51 + String? parentAddress;
52 +
53 + @observable
54 + bool isFetchingMnemonic;
55 +
56 + @computed
57 + bool get hasNoFilteredWallet {
58 + return singleWalletsList.isEmpty && multiWalletGroups.isEmpty;
59 + }
60 +
61 + @action
62 + Future<String?> getSelectedWalletMnemonic() async {
63 + WalletListItem walletToUse;
64 +
65 + bool isGroupSelected = selectedWalletGroup != null;
66 +
67 + if (isGroupSelected) {
68 + walletToUse = convertWalletInfoToWalletListItem(selectedWalletGroup!.wallets.first);
69 + } else {
70 + walletToUse = convertWalletInfoToWalletListItem(selectedSingleWallet!);
71 + }
72 +
73 + try {
74 + isFetchingMnemonic = true;
75 + final wallet = await _walletLoadingService.load(
76 + walletToUse.type,
77 + walletToUse.name,
78 + );
79 +
80 + parentAddress =
81 + isGroupSelected ? selectedWalletGroup!.parentAddress : selectedSingleWallet!.address;
82 +
83 + return wallet.seed;
84 + } catch (e) {
85 + return null;
86 + } finally {
87 + isFetchingMnemonic = false;
88 + }
89 + }
90 +
91 + @action
92 + void selectWalletGroup(WalletGroup walletGroup) {
93 + selectedWalletGroup = walletGroup;
94 + selectedSingleWallet = null;
95 + }
96 +
97 + @action
98 + void selectSingleWallet(WalletInfo singleWallet) {
99 + selectedSingleWallet = singleWallet;
100 + selectedWalletGroup = null;
101 + }
102 +
103 + @action
104 + void updateWalletInfoSourceList() {
105 + List<WalletGroup> wallets = [];
106 +
107 + multiWalletGroups.clear();
108 + singleWalletsList.clear();
109 +
110 + _walletManager.updateWalletGroups();
111 +
112 + final walletGroups = _walletManager.walletGroups;
113 +
114 + // Iterate through the wallet groups to filter and categorize wallets
115 + for (var group in walletGroups) {
116 + // Handle group wallet filtering
117 + bool shouldExcludeGroup = group.wallets.any((wallet) {
118 + // Check for non-BIP39 wallet types
119 + bool isNonBIP39Wallet = !isBIP39Wallet(wallet.type);
120 +
121 + // Check for nano derivation type
122 + bool isNanoDerivationType = wallet.type == WalletType.nano &&
123 + wallet.derivationInfo?.derivationType == DerivationType.nano;
124 +
125 + // Check for electrum derivation type
126 + bool isElectrumDerivationType =
127 + (wallet.type == WalletType.bitcoin || wallet.type == WalletType.litecoin) &&
128 + wallet.derivationInfo?.derivationType == DerivationType.electrum;
129 +
130 + // Check that selected wallet type is not present already in group
131 + bool isSameTypeAsSelectedWallet = wallet.type == type;
132 +
133 + // Exclude if any of these conditions are true
134 + return isNonBIP39Wallet ||
135 + isNanoDerivationType ||
136 + isElectrumDerivationType ||
137 + isSameTypeAsSelectedWallet;
138 + });
139 +
140 + if (shouldExcludeGroup) continue;
141 +
142 + // If the group passes the filters, add it to the wallets list
143 + wallets.add(group);
144 + }
145 +
146 + for (var group in wallets) {
147 + if (group.wallets.length == 1) {
148 + singleWalletsList.add(group.wallets.first);
149 + } else {
150 + multiWalletGroups.add(group);
151 + }
152 + }
153 + }
154 +
155 + WalletListItem convertWalletInfoToWalletListItem(WalletInfo info) {
156 + return WalletListItem(
157 + name: info.name,
158 + type: info.type,
159 + key: info.key,
160 + isCurrent: info.name == _appStore.wallet?.name && info.type == _appStore.wallet?.type,
161 + isEnabled: availableWalletTypes.contains(info.type),
162 + isTestnet: info.network?.toLowerCase().contains('testnet') ?? false,
163 + );
164 + }
165 +}
lib/view_model/wallet_list/wallet_edit_view_model.dart
+27 -6
@@ -1,4 +1,5 @@
1 import 'package:cake_wallet/core/wallet_loading_service.dart';
2 +import 'package:cake_wallet/entities/wallet_manager.dart';
3 import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
4 import 'package:mobx/mobx.dart';
5 import 'package:cake_wallet/di.dart';
@@ -18,8 +19,11 @@ class WalletEditRenamePending extends WalletEditViewModelState {}
19 class WalletEditDeletePending extends WalletEditViewModelState {}
20
21 abstract class WalletEditViewModelBase with Store {
21 - WalletEditViewModelBase(this._walletListViewModel, this._walletLoadingService)
22 - : state = WalletEditViewModelInitialState(),
22 + WalletEditViewModelBase(
23 + this._walletListViewModel,
24 + this._walletLoadingService,
25 + this._walletManager,
26 + ) : state = WalletEditViewModelInitialState(),
27 newName = '';
28
29 @observable
@@ -30,13 +34,30 @@ abstract class WalletEditViewModelBase with Store {
34
35 final WalletListViewModel _walletListViewModel;
36 final WalletLoadingService _walletLoadingService;
37 + final WalletManager _walletManager;
38
39 @action
35 - Future<void> changeName(WalletListItem walletItem, {String? password}) async {
40 + Future<void> changeName(
41 + WalletListItem walletItem, {
42 + String? password,
43 + String? groupParentAddress,
44 + bool isWalletGroup = false,
45 + }) async {
46 state = WalletEditRenamePending();
37 - await _walletLoadingService.renameWallet(
38 - walletItem.type, walletItem.name, newName,
39 - password: password);
47 +
48 + if (isWalletGroup) {
49 + _walletManager.updateWalletGroups();
50 +
51 + _walletManager.setGroupName(groupParentAddress!, newName);
52 + } else {
53 + await _walletLoadingService.renameWallet(
54 + walletItem.type,
55 + walletItem.name,
56 + newName,
57 + password: password,
58 + );
59 + }
60 +
61 _walletListViewModel.updateList();
62 }
63
lib/view_model/wallet_list/wallet_list_view_model.dart
+42 -11
@@ -1,5 +1,7 @@
1 import 'package:cake_wallet/core/wallet_loading_service.dart';
2 +import 'package:cake_wallet/entities/wallet_group.dart';
3 import 'package:cake_wallet/entities/wallet_list_order_types.dart';
4 +import 'package:cake_wallet/entities/wallet_manager.dart';
5 import 'package:hive/hive.dart';
6 import 'package:mobx/mobx.dart';
7 import 'package:cake_wallet/store/app_store.dart';
@@ -17,7 +19,10 @@ abstract class WalletListViewModelBase with Store {
19 this._walletInfoSource,
20 this._appStore,
21 this._walletLoadingService,
20 - ) : wallets = ObservableList<WalletListItem>() {
22 + this._walletManager,
23 + ) : wallets = ObservableList<WalletListItem>(),
24 + multiWalletGroups = ObservableList<WalletGroup>(),
25 + singleWalletsList = ObservableList<WalletListItem>() {
26 setOrderType(_appStore.settingsStore.walletListOrder);
27 reaction((_) => _appStore.wallet, (_) => updateList());
28 updateList();
@@ -26,6 +31,15 @@ abstract class WalletListViewModelBase with Store {
31 @observable
32 ObservableList<WalletListItem> wallets;
33
34 + // @observable
35 + // ObservableList<WalletGroup> walletGroups;
36 +
37 + @observable
38 + ObservableList<WalletGroup> multiWalletGroups;
39 +
40 + @observable
41 + ObservableList<WalletListItem> singleWalletsList;
42 +
43 @computed
44 bool get shouldRequireTOTP2FAForAccessingWallet =>
45 _appStore.settingsStore.shouldRequireTOTP2FAForAccessingWallet;
@@ -35,6 +49,7 @@ abstract class WalletListViewModelBase with Store {
49 _appStore.settingsStore.shouldRequireTOTP2FAForCreatingNewWallets;
50
51 final AppStore _appStore;
52 + final WalletManager _walletManager;
53 final Box<WalletInfo> _walletInfoSource;
54 final WalletLoadingService _walletLoadingService;
55
@@ -53,18 +68,23 @@ abstract class WalletListViewModelBase with Store {
68 @action
69 void updateList() {
70 wallets.clear();
71 + multiWalletGroups.clear();
72 + singleWalletsList.clear();
73 +
74 wallets.addAll(
57 - _walletInfoSource.values.map(
58 - (info) => WalletListItem(
59 - name: info.name,
60 - type: info.type,
61 - key: info.key,
62 - isCurrent: info.name == _appStore.wallet?.name && info.type == _appStore.wallet?.type,
63 - isEnabled: availableWalletTypes.contains(info.type),
64 - isTestnet: info.network?.toLowerCase().contains('testnet') ?? false,
65 - ),
66 - ),
75 + _walletInfoSource.values.map((info) => convertWalletInfoToWalletListItem(info)),
76 );
77 +
78 + //========== Split into shared seed groups and single wallets list
79 + _walletManager.updateWalletGroups();
80 +
81 + for (var group in _walletManager.walletGroups) {
82 + if (group.wallets.length == 1) {
83 + singleWalletsList.add(convertWalletInfoToWalletListItem(group.wallets.first));
84 + } else {
85 + multiWalletGroups.add(group);
86 + }
87 + }
88 }
89
90 Future<void> reorderAccordingToWalletList() async {
@@ -158,4 +178,15 @@ abstract class WalletListViewModelBase with Store {
178 break;
179 }
180 }
181 +
182 + WalletListItem convertWalletInfoToWalletListItem(WalletInfo info) {
183 + return WalletListItem(
184 + name: info.name,
185 + type: info.type,
186 + key: info.key,
187 + isCurrent: info.name == _appStore.wallet?.name && info.type == _appStore.wallet?.type,
188 + isEnabled: availableWalletTypes.contains(info.type),
189 + isTestnet: info.network?.toLowerCase().contains('testnet') ?? false,
190 + );
191 + }
192 }
lib/view_model/wallet_new_vm.dart
+62 -19
@@ -1,8 +1,9 @@
1 +import 'package:cake_wallet/core/new_wallet_arguments.dart';
2 +import 'package:cake_wallet/ethereum/ethereum.dart';
3 import 'package:cake_wallet/bitcoin/bitcoin.dart';
4 import 'package:cake_wallet/bitcoin_cash/bitcoin_cash.dart';
5 import 'package:cake_wallet/core/wallet_creation_service.dart';
6 import 'package:cake_wallet/entities/seed_type.dart';
5 -import 'package:cake_wallet/ethereum/ethereum.dart';
7 import 'package:cake_wallet/haven/haven.dart';
8 import 'package:cake_wallet/monero/monero.dart';
9 import 'package:cake_wallet/nano/nano.dart';
@@ -28,16 +29,17 @@ class WalletNewVM = WalletNewVMBase with _$WalletNewVM;
29
30 abstract class WalletNewVMBase extends WalletCreationVM with Store {
31 WalletNewVMBase(
31 - AppStore appStore,
32 - WalletCreationService walletCreationService,
33 - Box<WalletInfo> walletInfoSource,
34 - this.advancedPrivacySettingsViewModel,
35 - SeedSettingsViewModel seedSettingsViewModel,
36 - {required WalletType type})
37 - : selectedMnemonicLanguage = '',
32 + AppStore appStore,
33 + WalletCreationService walletCreationService,
34 + Box<WalletInfo> walletInfoSource,
35 + this.advancedPrivacySettingsViewModel,
36 + SeedSettingsViewModel seedSettingsViewModel, {
37 + required this.newWalletArguments,
38 + }) : selectedMnemonicLanguage = '',
39 super(appStore, walletInfoSource, walletCreationService, seedSettingsViewModel,
39 - type: type, isRecovery: false);
40 + type: newWalletArguments!.type, isRecovery: false);
41
42 + final NewWalletArguments? newWalletArguments;
43 final AdvancedPrivacySettingsViewModel advancedPrivacySettingsViewModel;
44
45 @observable
@@ -62,6 +64,10 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
64 return seedSettingsViewModel.bitcoinSeedType == BitcoinSeedType.bip39
65 ? advancedPrivacySettingsViewModel.seedPhraseLength.value
66 : 24;
67 + case WalletType.nano:
68 + return seedSettingsViewModel.nanoSeedType == NanoSeedType.bip39
69 + ? advancedPrivacySettingsViewModel.seedPhraseLength.value
70 + : 24;
71 default:
72 return 24;
73 }
@@ -83,31 +89,68 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
89 password: walletPassword,
90 isPolyseed: options.last as bool);
91 case WalletType.bitcoin:
86 - return bitcoin!.createBitcoinNewWalletCredentials(
87 - name: name, password: walletPassword, passphrase: passphrase);
92 case WalletType.litecoin:
93 return bitcoin!.createBitcoinNewWalletCredentials(
90 - name: name, password: walletPassword, passphrase: passphrase);
94 + name: name,
95 + password: walletPassword,
96 + passphrase: passphrase,
97 + mnemonic: newWalletArguments!.mnemonic,
98 + parentAddress: newWalletArguments!.parentAddress,
99 + );
100 case WalletType.haven:
101 return haven!.createHavenNewWalletCredentials(
102 name: name, language: options!.first as String, password: walletPassword);
103 case WalletType.ethereum:
95 - return ethereum!.createEthereumNewWalletCredentials(name: name, password: walletPassword);
104 + return ethereum!.createEthereumNewWalletCredentials(
105 + name: name,
106 + password: walletPassword,
107 + mnemonic: newWalletArguments!.mnemonic,
108 + parentAddress: newWalletArguments!.parentAddress,
109 + );
110 case WalletType.bitcoinCash:
111 return bitcoinCash!.createBitcoinCashNewWalletCredentials(
98 - name: name, password: walletPassword, passphrase: passphrase);
112 + name: name,
113 + password: walletPassword,
114 + passphrase: passphrase,
115 + mnemonic: newWalletArguments!.mnemonic,
116 + parentAddress: newWalletArguments!.parentAddress,
117 + );
118 case WalletType.nano:
119 case WalletType.banano:
101 - return nano!.createNanoNewWalletCredentials(name: name);
120 + return nano!.createNanoNewWalletCredentials(
121 + name: name,
122 + password: walletPassword,
123 + mnemonic: newWalletArguments!.mnemonic,
124 + parentAddress: newWalletArguments!.parentAddress,
125 + );
126 case WalletType.polygon:
103 - return polygon!.createPolygonNewWalletCredentials(name: name, password: walletPassword);
127 + return polygon!.createPolygonNewWalletCredentials(
128 + name: name,
129 + password: walletPassword,
130 + mnemonic: newWalletArguments!.mnemonic,
131 + parentAddress: newWalletArguments!.parentAddress,
132 + );
133 case WalletType.solana:
105 - return solana!.createSolanaNewWalletCredentials(name: name, password: walletPassword);
134 + return solana!.createSolanaNewWalletCredentials(
135 + name: name,
136 + password: walletPassword,
137 + mnemonic: newWalletArguments!.mnemonic,
138 + parentAddress: newWalletArguments!.parentAddress,
139 + );
140 case WalletType.tron:
107 - return tron!.createTronNewWalletCredentials(name: name);
141 + return tron!.createTronNewWalletCredentials(
142 + name: name,
143 + password: walletPassword,
144 + mnemonic: newWalletArguments!.mnemonic,
145 + parentAddress: newWalletArguments!.parentAddress,
146 + );
147 case WalletType.wownero:
148 return wownero!.createWowneroNewWalletCredentials(
110 - name: name, language: options!.first as String, isPolyseed: options.last as bool);
149 + name: name,
150 + password: walletPassword,
151 + language: options!.first as String,
152 + isPolyseed: options.last as bool,
153 + );
154 case WalletType.none:
155 throw Exception('Unexpected type: ${type.toString()}');
156 }
res/values/strings_ar.arb
+14 -1
@@ -129,7 +129,7 @@
129 "choose_from_available_options": "اختر من بين الخيارات المتاحة:",
130 "choose_one": "اختر واحدة",
131 "choose_relay": "ﻡﺍﺪﺨﺘﺳﻼﻟ ﻊﺑﺎﺘﺘﻟﺍ ﺭﺎﻴﺘﺧﺍ ءﺎﺟﺮﻟﺍ",
132 - "choose_wallet_currency": "الرجاء اختيار عملة المحفظة:",
132 + "choose_wallet_group": "اختر مجموعة المحفظة",
133 "clear": "مسح",
134 "clearnet_link": "رابط Clearnet",
135 "close": "يغلق",
@@ -176,6 +176,7 @@
176 "create_invoice": "إنشاء فاتورة",
177 "create_new": "إنشاء محفظة جديدة",
178 "create_new_account": "انشاء حساب جديد",
179 + "create_new_seed": "إنشاء بذرة جديدة",
180 "creating_new_wallet": "يتم إنشاء محفظة جديدة",
181 "creating_new_wallet_error": "خطأ: ${description}",
182 "creation_date": "تاريخ الإنشاء",
@@ -600,6 +601,8 @@
601 "seed_share": "شارك السييد",
602 "seed_title": "سييد",
603 "seedtype": "البذور",
604 + "seedtype_alert_content": "مشاركة البذور مع محافظ أخرى ممكن فقط مع BIP39 Seedtype.",
605 + "seedtype_alert_title": "تنبيه البذور",
606 "seedtype_legacy": "إرث (25 كلمة)",
607 "seedtype_polyseed": "بوليسيد (16 كلمة)",
608 "select_backup_file": "حدد ملف النسخ الاحتياطي",
@@ -666,6 +669,7 @@
669 "setup_your_debit_card": "قم بإعداد بطاقة ائتمان الخاصة بك",
670 "share": "يشارك",
671 "share_address": "شارك العنوان",
672 + "shared_seed_wallet_groups": "مجموعات محفظة البذور المشتركة",
673 "show_details": "اظهر التفاصيل",
674 "show_keys": "اظهار السييد / المفاتيح",
675 "show_market_place": "إظهار السوق",
@@ -690,6 +694,7 @@
694 "silent_payments_scanned_tip": "ممسوح ليفحص! (${tip})",
695 "silent_payments_scanning": "المدفوعات الصامتة المسح الضوئي",
696 "silent_payments_settings": "إعدادات المدفوعات الصامتة",
697 + "single_seed_wallets_group": "محافظ بذرة واحدة",
698 "slidable": "قابل للانزلاق",
699 "sort_by": "ترتيب حسب",
700 "spend_key_private": "مفتاح الإنفاق (خاص)",
@@ -849,8 +854,16 @@
854 "view_transaction_on": "عرض العملية على",
855 "voting_weight": "وزن التصويت",
856 "waitFewSecondForTxUpdate": "ﺕﻼﻣﺎﻌﻤﻟﺍ ﻞﺠﺳ ﻲﻓ ﺔﻠﻣﺎﻌﻤﻟﺍ ﺲﻜﻌﻨﺗ ﻰﺘﺣ ﻥﺍﻮﺛ ﻊﻀﺒﻟ ﺭﺎﻈﺘﻧﻻﺍ ﻰﺟﺮﻳ",
857 + "wallet_group": "مجموعة محفظة",
858 + "wallet_group_description_four": "لإنشاء محفظة مع بذرة جديدة تماما.",
859 + "wallet_group_description_one": "في محفظة الكيك ، يمكنك إنشاء ملف",
860 + "wallet_group_description_three": "لرؤية المحافظ المتاحة و/أو شاشة مجموعات المحفظة. أو اختر",
861 + "wallet_group_description_two": "عن طريق اختيار محفظة موجودة لتبادل البذور مع. يمكن أن تحتوي كل مجموعة محفظة على محفظة واحدة من كل نوع من العملة. \n\n يمكنك تحديدها",
862 + "wallet_group_empty_state_text_one": "يبدو أنه ليس لديك أي مجموعات محفظة متوافقة !\n\n انقر",
863 + "wallet_group_empty_state_text_two": "أدناه لجعل واحدة جديدة.",
864 "wallet_keys": "سييد المحفظة / المفاتيح",
865 "wallet_list_create_new_wallet": "إنشاء محفظة جديدة",
866 + "wallet_list_edit_group_name": "تحرير اسم المجموعة",
867 "wallet_list_edit_wallet": "تحرير المحفظة",
868 "wallet_list_failed_to_load": "فشل تحميل محفظة ${wallet_name}. ${error}",
869 "wallet_list_failed_to_remove": "فشلت إزالة محفظة ${wallet_name}. ${error}",
res/values/strings_bg.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "Изберете едно",
131 "choose_relay": "Моля, изберете реле, което да използвате",
132 "choose_wallet_currency": "Изберете валута за портфейла:",
133 + "choose_wallet_group": "Изберете Group Wallet",
134 "clear": "Изчисти",
135 "clearnet_link": "Clearnet връзка",
136 "close": "затвори",
@@ -176,6 +177,7 @@
177 "create_invoice": "Създайте фактура",
178 "create_new": "Създаване на нов портфейл",
179 "create_new_account": "Създаване на нов профил",
180 + "create_new_seed": "Създайте нови семена",
181 "creating_new_wallet": "Създаване на нов портфейл",
182 "creating_new_wallet_error": "Грешка: ${description}",
183 "creation_date": "Дата на създаване",
@@ -600,6 +602,8 @@
602 "seed_share": "Споделяне на seed",
603 "seed_title": "Seed",
604 "seedtype": "Семенна тип",
605 + "seedtype_alert_content": "Споделянето на семена с други портфейли е възможно само с BIP39 Seedtype.",
606 + "seedtype_alert_title": "Сигнал за семена",
607 "seedtype_legacy": "Наследство (25 думи)",
608 "seedtype_polyseed": "Поли семе (16 думи)",
609 "select_backup_file": "Избор на резервно копие",
@@ -666,6 +670,7 @@
670 "setup_your_debit_card": "Настройте своята дебитна карта",
671 "share": "Дял",
672 "share_address": "Сподели адрес",
673 + "shared_seed_wallet_groups": "Споделени групи за портфейли за семена",
674 "show_details": "Показване на подробностите",
675 "show_keys": "Покажи seed/keys",
676 "show_market_place": "Покажи пазар",
@@ -690,6 +695,7 @@
695 "silent_payments_scanned_tip": "Сканиран за съвет! (${tip})",
696 "silent_payments_scanning": "Безшумни плащания за сканиране",
697 "silent_payments_settings": "Настройки за безшумни плащания",
698 + "single_seed_wallets_group": "Портфейли с единични семена",
699 "slidable": "Плъзгащ се",
700 "sort_by": "Сортирай по",
701 "spend_key_private": "Spend key (таен)",
@@ -849,8 +855,16 @@
855 "view_transaction_on": "Вижте транзакция на ",
856 "voting_weight": "Тегло на гласуване",
857 "waitFewSecondForTxUpdate": "Моля, изчакайте няколко секунди, докато транзакцията се отрази в историята на транзакциите",
858 + "wallet_group": "Група на портфейла",
859 + "wallet_group_description_four": "За да създадете портфейл с изцяло ново семе.",
860 + "wallet_group_description_one": "В портфейла за торта можете да създадете a",
861 + "wallet_group_description_three": "За да видите наличния екран за портфейли и/или групи за портфейли. Или изберете",
862 + "wallet_group_description_two": "Чрез избора на съществуващ портфейл, с който да споделите семе. Всяка група за портфейл може да съдържа по един портфейл от всеки тип валута. \n\n Можете да изберете",
863 + "wallet_group_empty_state_text_one": "Изглежда, че нямате съвместими групи портфейли !\n\n tap",
864 + "wallet_group_empty_state_text_two": "по -долу, за да се направи нов.",
865 "wallet_keys": "Seed/keys на портфейла",
866 "wallet_list_create_new_wallet": "Създаване на нов портфейл",
867 + "wallet_list_edit_group_name": "Редактиране на име на групата",
868 "wallet_list_edit_wallet": "Редактиране на портфейла",
869 "wallet_list_failed_to_load": "Грешка при зареждането на портфейл ${wallet_name}. ${error}",
870 "wallet_list_failed_to_remove": "Грешка при премахването на портфейл${wallet_name}. ${error}",
res/values/strings_cs.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "Zvolte si",
131 "choose_relay": "Vyberte relé, které chcete použít",
132 "choose_wallet_currency": "Prosím zvolte si měnu pro peněženku:",
133 + "choose_wallet_group": "Vyberte skupinu peněženky",
134 "clear": "Smazat",
135 "clearnet_link": "Odkaz na Clearnet",
136 "close": "zavřít",
@@ -176,6 +177,7 @@
177 "create_invoice": "Vytvořit fakturu",
178 "create_new": "Vytvořit novou peněženku",
179 "create_new_account": "Vytvořit nový účet",
180 + "create_new_seed": "Vytvořte nové semeno",
181 "creating_new_wallet": "Vytvářím novou peněženku",
182 "creating_new_wallet_error": "Chyba: ${description}",
183 "creation_date": "Datum vzniku",
@@ -600,6 +602,8 @@
602 "seed_share": "Sdílet seed",
603 "seed_title": "Seed",
604 "seedtype": "SeedType",
605 + "seedtype_alert_content": "Sdílení semen s jinými peněženkami je možné pouze u BIP39 SeedType.",
606 + "seedtype_alert_title": "Upozornění seedtype",
607 "seedtype_legacy": "Legacy (25 slov)",
608 "seedtype_polyseed": "Polyseed (16 slov)",
609 "select_backup_file": "Vybrat soubor se zálohou",
@@ -666,6 +670,7 @@
670 "setup_your_debit_card": "Nastavit debetní kartu",
671 "share": "Podíl",
672 "share_address": "Sdílet adresu",
673 + "shared_seed_wallet_groups": "Skupiny sdílených semen",
674 "show_details": "Zobrazit detaily",
675 "show_keys": "Zobrazit seed/klíče",
676 "show_market_place": "Zobrazit trh",
@@ -690,6 +695,7 @@
695 "silent_payments_scanned_tip": "Naskenované na tip! (${tip})",
696 "silent_payments_scanning": "Skenování tichých plateb",
697 "silent_payments_settings": "Nastavení tichých plateb",
698 + "single_seed_wallets_group": "Jednorázové peněženky",
699 "slidable": "Posuvné",
700 "sort_by": "Seřazeno podle",
701 "spend_key_private": "Klíč pro platby (soukromý)",
@@ -849,8 +855,16 @@
855 "view_transaction_on": "Zobrazit transakci na ",
856 "voting_weight": "Hlasová váha",
857 "waitFewSecondForTxUpdate": "Počkejte několik sekund, než se transakce projeví v historii transakcí",
858 + "wallet_group": "Skupina peněženky",
859 + "wallet_group_description_four": "Vytvoření peněženky s zcela novým semenem.",
860 + "wallet_group_description_one": "V peněžence dortu můžete vytvořit a",
861 + "wallet_group_description_three": "Chcete -li zobrazit dostupnou obrazovku Skupina skupin peněženek a/nebo skupin peněženek. Nebo zvolit",
862 + "wallet_group_description_two": "Výběrem existující peněženky pro sdílení semeno. Každá skupina peněženek může obsahovat jednu peněženku každého typu měny. \n\n Můžete si vybrat",
863 + "wallet_group_empty_state_text_one": "Vypadá to, že nemáte žádné kompatibilní skupiny peněženky !\n\n",
864 + "wallet_group_empty_state_text_two": "Níže vytvořit nový.",
865 "wallet_keys": "Seed/klíče peněženky",
866 "wallet_list_create_new_wallet": "Vytvořit novou peněženku",
867 + "wallet_list_edit_group_name": "Upravit název skupiny",
868 "wallet_list_edit_wallet": "Upravit peněženku",
869 "wallet_list_failed_to_load": "Chyba při načítání ${wallet_name} peněženky. ${error}",
870 "wallet_list_failed_to_remove": "Chyba při odstraňování ${wallet_name} peněženky. ${error}",
res/values/strings_de.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "Wähle ein",
131 "choose_relay": "Bitte wählen Sie ein zu verwendendes Relais aus",
132 "choose_wallet_currency": "Bitte wählen Sie die Währung der Wallet:",
133 + "choose_wallet_group": "Wählen Sie Brieftaschengruppe",
134 "clear": "Zurücksetzen",
135 "clearnet_link": "Clearnet-Link",
136 "close": "Schließen",
@@ -176,6 +177,7 @@
177 "create_invoice": "Rechnung erstellen",
178 "create_new": "Neue Wallet erstellen",
179 "create_new_account": "Neues Konto erstellen",
180 + "create_new_seed": "Neue Samen erstellen",
181 "creating_new_wallet": "Neue Wallet erstellen",
182 "creating_new_wallet_error": "Fehler: ${description}",
183 "creation_date": "Erstellungsdatum",
@@ -601,6 +603,8 @@
603 "seed_share": "Seed teilen",
604 "seed_title": "Seed",
605 "seedtype": "Seedtyp",
606 + "seedtype_alert_content": "Das Teilen von Samen mit anderen Brieftaschen ist nur mit bip39 Seedype möglich.",
607 + "seedtype_alert_title": "Seedype -Alarm",
608 "seedtype_legacy": "Veraltet (25 Wörter)",
609 "seedtype_polyseed": "Polyseed (16 Wörter)",
610 "select_backup_file": "Sicherungsdatei auswählen",
@@ -667,6 +671,7 @@
671 "setup_your_debit_card": "Richten Sie Ihre Debitkarte ein",
672 "share": "Teilen",
673 "share_address": "Adresse teilen ",
674 + "shared_seed_wallet_groups": "Gemeinsame Samenbrieftaschengruppen",
675 "show_details": "Details anzeigen",
676 "show_keys": "Seed/Schlüssel anzeigen",
677 "show_market_place": "Marktplatz anzeigen",
@@ -691,6 +696,7 @@
696 "silent_payments_scanned_tip": "Gescannt zum Trinkgeld! (${tip})",
697 "silent_payments_scanning": "Stille Zahlungen scannen",
698 "silent_payments_settings": "Einstellungen für stille Zahlungen",
699 + "single_seed_wallets_group": "Einzelne Samenbriefen",
700 "slidable": "Verschiebbar",
701 "sort_by": "Sortiere nach",
702 "spend_key_private": "Spend Key (geheim)",
@@ -852,8 +858,16 @@
858 "voting_weight": "Stimmgewicht",
859 "waitFewSecondForTxUpdate": "Bitte warten Sie einige Sekunden, bis die Transaktion im Transaktionsverlauf angezeigt wird",
860 "waiting_payment_confirmation": "Warte auf Zahlungsbestätigung",
861 + "wallet_group": "Brieftaschengruppe",
862 + "wallet_group_description_four": "eine Brieftasche mit einem völlig neuen Samen schaffen.",
863 + "wallet_group_description_one": "In Kuchenbrieftasche können Sie eine erstellen",
864 + "wallet_group_description_three": "Sehen Sie den Bildschirm zur verfügbaren Brieftaschen und/oder Brieftaschengruppen. Oder wählen",
865 + "wallet_group_description_two": "Durch die Auswahl einer vorhandenen Brieftasche, mit der ein Samen geteilt werden kann. Jede Brieftaschengruppe kann eine einzelne Brieftasche jedes Währungstyps enthalten. \n\n Sie können auswählen",
866 + "wallet_group_empty_state_text_one": "Sieht so aus, als hätten Sie keine kompatiblen Brieftaschengruppen !\n\n TAP",
867 + "wallet_group_empty_state_text_two": "unten, um einen neuen zu machen.",
868 "wallet_keys": "Wallet-Seed/-Schlüssel",
869 "wallet_list_create_new_wallet": "Neue Wallet erstellen",
870 + "wallet_list_edit_group_name": "Gruppenname bearbeiten",
871 "wallet_list_edit_wallet": "Wallet bearbeiten",
872 "wallet_list_failed_to_load": "Laden der Wallet ${wallet_name} fehlgeschlagen. ${error}",
873 "wallet_list_failed_to_remove": "Fehler beim Entfernen der Wallet ${wallet_name}. ${error}",
res/values/strings_en.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "Choose one",
131 "choose_relay": "Please choose a relay to use",
132 "choose_wallet_currency": "Please choose wallet currency:",
133 + "choose_wallet_group": "Choose Wallet Group",
134 "clear": "Clear",
135 "clearnet_link": "Clearnet link",
136 "close": "Close",
@@ -176,6 +177,7 @@
177 "create_invoice": "Create invoice",
178 "create_new": "Create New Wallet",
179 "create_new_account": "Create new account",
180 + "create_new_seed": "Create New Seed",
181 "creating_new_wallet": "Creating new wallet",
182 "creating_new_wallet_error": "Error: ${description}",
183 "creation_date": "Creation Date",
@@ -600,6 +602,8 @@
602 "seed_share": "Share seed",
603 "seed_title": "Seed",
604 "seedtype": "Seedtype",
605 + "seedtype_alert_content": "Sharing seeds with other wallets is only possible with BIP39 SeedType.",
606 + "seedtype_alert_title": "SeedType Alert",
607 "seedtype_legacy": "Legacy (25 words)",
608 "seedtype_polyseed": "Polyseed (16 words)",
609 "seedtype_wownero": "Wownero (14 words)",
@@ -667,6 +671,7 @@
671 "setup_your_debit_card": "Set up your debit card",
672 "share": "Share",
673 "share_address": "Share address",
674 + "shared_seed_wallet_groups": "Shared Seed Wallet Groups",
675 "show_details": "Show Details",
676 "show_keys": "Show seed/keys",
677 "show_market_place": "Show Marketplace",
@@ -691,6 +696,7 @@
696 "silent_payments_scanned_tip": "SCANNED TO TIP! (${tip})",
697 "silent_payments_scanning": "Silent Payments Scanning",
698 "silent_payments_settings": "Silent Payments settings",
699 + "single_seed_wallets_group": "Single Seed Wallets",
700 "slidable": "Slidable",
701 "sort_by": "Sort by",
702 "spend_key_private": "Spend key (private)",
@@ -850,8 +856,16 @@
856 "view_transaction_on": "View Transaction on ",
857 "voting_weight": "Voting Weight",
858 "waitFewSecondForTxUpdate": "Kindly wait for a few seconds for transaction to reflect in transactions history",
859 + "wallet_group": "Wallet Group",
860 + "wallet_group_description_four": "to create a wallet with an entirely new seed.",
861 + "wallet_group_description_one": "In Cake Wallet, you can create a",
862 + "wallet_group_description_three": "to see the available wallets and/or wallet groups screen. Or choose",
863 + "wallet_group_description_two": "by selecting an existing wallet to share a seed with. Each wallet group can contain a single wallet of each currency type.\n\nYou can select",
864 + "wallet_group_empty_state_text_one": "Looks like you don't have any compatible wallet groups!\n\nTap",
865 + "wallet_group_empty_state_text_two": "below to make a new one.",
866 "wallet_keys": "Wallet seed/keys",
867 "wallet_list_create_new_wallet": "Create New Wallet",
868 + "wallet_list_edit_group_name": "Edit Group Name",
869 "wallet_list_edit_wallet": "Edit wallet",
870 "wallet_list_failed_to_load": "Failed to load ${wallet_name} wallet. ${error}",
871 "wallet_list_failed_to_remove": "Failed to remove ${wallet_name} wallet. ${error}",
res/values/strings_es.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "Elige uno",
131 "choose_relay": "Por favor elija un relé para usar",
132 "choose_wallet_currency": "Por favor, elija la moneda de la billetera:",
133 + "choose_wallet_group": "Elija el grupo de billetera",
134 "clear": "Claro",
135 "clearnet_link": "enlace Clearnet",
136 "close": "Cerca",
@@ -176,6 +177,7 @@
177 "create_invoice": "Crear factura",
178 "create_new": "Crear nueva billetera",
179 "create_new_account": "Crear una nueva cuenta",
180 + "create_new_seed": "Crear nueva semilla",
181 "creating_new_wallet": "Creando nueva billetera",
182 "creating_new_wallet_error": "Error: ${description}",
183 "creation_date": "Fecha de creación",
@@ -601,6 +603,8 @@
603 "seed_share": "Compartir semillas",
604 "seed_title": "Semilla",
605 "seedtype": "Type de semillas",
606 + "seedtype_alert_content": "Compartir semillas con otras billeteras solo es posible con Bip39 Seed Type.",
607 + "seedtype_alert_title": "Alerta de type de semillas",
608 "seedtype_legacy": "Legado (25 palabras)",
609 "seedtype_polyseed": "Polieta (16 palabras)",
610 "select_backup_file": "Seleccionar archivo de respaldo",
@@ -667,6 +671,7 @@
671 "setup_your_debit_card": "Configura tu tarjeta de débito",
672 "share": "Compartir",
673 "share_address": "Compartir dirección",
674 + "shared_seed_wallet_groups": "Grupos de billetera de semillas compartidas",
675 "show_details": "Mostrar detalles",
676 "show_keys": "Mostrar semilla/claves",
677 "show_market_place": "Mostrar mercado",
@@ -691,6 +696,7 @@
696 "silent_payments_scanned_tip": "Escaneado hasta la punta! (${tip})",
697 "silent_payments_scanning": "Escaneo de pagos silenciosos",
698 "silent_payments_settings": "Configuración de pagos silenciosos",
699 + "single_seed_wallets_group": "Billeteras de semillas individuales",
700 "slidable": "deslizable",
701 "sort_by": "Ordenar por",
702 "spend_key_private": "Spend clave (privado)",
@@ -850,8 +856,16 @@
856 "view_transaction_on": "View Transaction on ",
857 "voting_weight": "Peso de votación",
858 "waitFewSecondForTxUpdate": "Espere unos segundos para que la transacción se refleje en el historial de transacciones.",
859 + "wallet_group": "Grupo de billetera",
860 + "wallet_group_description_four": "para crear una billetera con una semilla completamente nueva.",
861 + "wallet_group_description_one": "En la billetera de pastel, puedes crear un",
862 + "wallet_group_description_three": "Para ver las billeteras disponibles y/o la pantalla de grupos de billeteras. O elegir",
863 + "wallet_group_description_two": "seleccionando una billetera existente para compartir una semilla con. Cada grupo de billetera puede contener una sola billetera de cada tipo de moneda. \n\n puede seleccionar",
864 + "wallet_group_empty_state_text_one": "Parece que no tienes ningún grupo de billetera compatible !\n\n toque",
865 + "wallet_group_empty_state_text_two": "a continuación para hacer uno nuevo.",
866 "wallet_keys": "Billetera semilla/claves",
867 "wallet_list_create_new_wallet": "Crear nueva billetera",
868 + "wallet_list_edit_group_name": "Editar nombre de grupo",
869 "wallet_list_edit_wallet": "Editar billetera",
870 "wallet_list_failed_to_load": "No se pudo cargar ${wallet_name} la billetera. ${error}",
871 "wallet_list_failed_to_remove": "Error al elimina ${wallet_name} billetera. ${error}",
res/values/strings_fr.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "Choisissez-en un",
131 "choose_relay": "Veuillez choisir un relais à utiliser",
132 "choose_wallet_currency": "Merci de choisir la devise du portefeuille (wallet) :",
133 + "choose_wallet_group": "Choisissez un groupe de portefeuille",
134 "clear": "Effacer",
135 "clearnet_link": "Lien Clearnet",
136 "close": "Fermer",
@@ -176,6 +177,7 @@
177 "create_invoice": "Créer une facture",
178 "create_new": "Créer un Nouveau Portefeuille (Wallet)",
179 "create_new_account": "Créer un nouveau compte",
180 + "create_new_seed": "Créer de nouvelles graines",
181 "creating_new_wallet": "Création d'un nouveau portefeuille (wallet)",
182 "creating_new_wallet_error": "Erreur : ${description}",
183 "creation_date": "Date de création",
@@ -600,6 +602,8 @@
602 "seed_share": "Partager la phrase secrète (seed)",
603 "seed_title": "Phrase secrète (seed)",
604 "seedtype": "Type de type graine",
605 + "seedtype_alert_content": "Le partage de graines avec d'autres portefeuilles n'est possible qu'avec Bip39 SeedType.",
606 + "seedtype_alert_title": "Alerte de type SeedType",
607 "seedtype_legacy": "Héritage (25 mots)",
608 "seedtype_polyseed": "Polyseed (16 mots)",
609 "select_backup_file": "Sélectionnez le fichier de sauvegarde",
@@ -666,6 +670,7 @@
670 "setup_your_debit_card": "Configurer votre carte de débit",
671 "share": "Partager",
672 "share_address": "Partager l'adresse",
673 + "shared_seed_wallet_groups": "Groupes de portefeuilles partagés",
674 "show_details": "Afficher les détails",
675 "show_keys": "Visualiser la phrase secrète (seed) et les clefs",
676 "show_market_place": "Afficher la place de marché",
@@ -690,6 +695,7 @@
695 "silent_payments_scanned_tip": "Scanné à la pointe! (${tip})",
696 "silent_payments_scanning": "Payments silencieux SCANNING",
697 "silent_payments_settings": "Paramètres de paiement silencieux",
698 + "single_seed_wallets_group": "Portefeuilles de semences simples",
699 "slidable": "Glissable",
700 "sort_by": "Trier par",
701 "spend_key_private": "Clef de dépense (spend key) (privée)",
@@ -849,8 +855,16 @@
855 "view_transaction_on": "Voir la Transaction sur ",
856 "voting_weight": "Poids de vote",
857 "waitFewSecondForTxUpdate": "Veuillez attendre quelques secondes pour que la transaction soit reflétée dans l'historique des transactions.",
858 + "wallet_group": "Groupe de portefeuille",
859 + "wallet_group_description_four": "Pour créer un portefeuille avec une graine entièrement nouvelle.",
860 + "wallet_group_description_one": "Dans Cake Wallet, vous pouvez créer un",
861 + "wallet_group_description_three": "Pour voir les portefeuilles et / ou les groupes de portefeuilles disponibles. Ou choisir",
862 + "wallet_group_description_two": "En sélectionnant un portefeuille existant pour partager une graine avec. Chaque groupe de portefeuille peut contenir un seul portefeuille de chaque type de devise. \n\n Vous pouvez sélectionner",
863 + "wallet_group_empty_state_text_one": "On dirait que vous n'avez pas de groupes de portefeuilles compatibles !\n\n Tap",
864 + "wallet_group_empty_state_text_two": "Ci-dessous pour en faire un nouveau.",
865 "wallet_keys": "Phrase secrète (seed)/Clefs du portefeuille (wallet)",
866 "wallet_list_create_new_wallet": "Créer un Nouveau Portefeuille (Wallet)",
867 + "wallet_list_edit_group_name": "Modifier le nom du groupe",
868 "wallet_list_edit_wallet": "Modifier le portefeuille",
869 "wallet_list_failed_to_load": "Échec de chargement du portefeuille (wallet) ${wallet_name}. ${error}",
870 "wallet_list_failed_to_remove": "Échec de la suppression du portefeuille (wallet) ${wallet_name}. ${error}",
res/values/strings_ha.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "Zaɓi ɗaya",
131 "choose_relay": "Da fatan za a zaɓi gudun ba da sanda don amfani",
132 "choose_wallet_currency": "Da fatan za a zaɓi kuɗin walat:",
133 + "choose_wallet_group": "Zabi kungiyar walat",
134 "clear": "Share",
135 "clearnet_link": "Lambar makomar kwayoyi",
136 "close": "Rufa",
@@ -176,6 +177,7 @@
177 "create_invoice": "Sanya bayanin wadannan",
178 "create_new": "Ƙirƙira Sabon Kwalinku",
179 "create_new_account": "Ƙirƙiri sabon asusu",
180 + "create_new_seed": "Irƙiri sabon iri",
181 "creating_new_wallet": "Haliccin walat sabuwa",
182 "creating_new_wallet_error": "Kuskure: ${description}",
183 "creation_date": "Ranar halitta",
@@ -602,6 +604,8 @@
604 "seed_share": "Raba iri",
605 "seed_title": "iri",
606 "seedtype": "Seedtype",
607 + "seedtype_alert_content": "Raba tsaba tare da sauran wallets yana yiwuwa ne kawai tare da Bip39 seedtype.",
608 + "seedtype_alert_title": "Seedtype farke",
609 "seedtype_legacy": "Legacy (25 kalmomi)",
610 "seedtype_polyseed": "Polyseed (16 kalmomi)",
611 "select_backup_file": "Zaɓi fayil ɗin madadin",
@@ -668,6 +672,7 @@
672 "setup_your_debit_card": "Saita katin zare kudi",
673 "share": "Raba",
674 "share_address": "Raba adireshin",
675 + "shared_seed_wallet_groups": "Raba ƙungiya walat",
676 "show_details": "Nuna Cikakkun bayanai",
677 "show_keys": "Nuna iri/maɓallai",
678 "show_market_place": "Nuna dan kasuwa",
@@ -692,6 +697,7 @@
697 "silent_payments_scanned_tip": "Bincika don tip! (${tip})",
698 "silent_payments_scanning": "Silent biya scanning",
699 "silent_payments_settings": "Saitunan Silent",
700 + "single_seed_wallets_group": "Guaro",
701 "slidable": "Mai iya zamewa",
702 "sort_by": "Kasa",
703 "spend_key_private": "makullin biya (maɓallin kalmar sirri)",
@@ -851,8 +857,16 @@
857 "view_transaction_on": "Dubo aikace-aikacen akan",
858 "voting_weight": "Nauyi mai nauyi",
859 "waitFewSecondForTxUpdate": "Da fatan za a jira ƴan daƙiƙa don ciniki don yin tunani a tarihin ma'amala",
860 + "wallet_group": "Wallet kungiyar",
861 + "wallet_group_description_four": "Don ƙirƙirar walat tare da sabon iri.",
862 + "wallet_group_description_one": "A cikin walat walat, zaka iya ƙirƙirar",
863 + "wallet_group_description_three": "Don ganin wallets da / ko allon walat din. Ko zabi",
864 + "wallet_group_description_two": "ta hanyar zabar walat mai gudana don raba iri tare da. Kowane rukunin walat na iya ƙunsar watsarin kowane nau'in kuɗi. \n\n Zaka iya zaɓar",
865 + "wallet_group_empty_state_text_one": "Kamar dai ba ku da wata ƙungiya matattara !\n\n Taɓa",
866 + "wallet_group_empty_state_text_two": "da ke ƙasa don yin sabo.",
867 "wallet_keys": "Iri/maɓalli na walat",
868 "wallet_list_create_new_wallet": "Ƙirƙiri Sabon Wallet",
869 + "wallet_list_edit_group_name": "Shirya sunan rukuni",
870 "wallet_list_edit_wallet": "Gyara walat",
871 "wallet_list_failed_to_load": "An kasa loda ${wallet_name} walat. ${error}",
872 "wallet_list_failed_to_remove": "Ba a iya cirewa ${wallet_name} walat. ${error}",
res/values/strings_hi.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "एक का चयन",
131 "choose_relay": "कृपया उपयोग करने के लिए एक रिले चुनें",
132 "choose_wallet_currency": "कृपया बटुआ मुद्रा चुनें:",
133 + "choose_wallet_group": "वॉलेट ग्रुप चुनें",
134 "clear": "स्पष्ट",
135 "clearnet_link": "क्लियरनेट लिंक",
136 "close": "बंद करना",
@@ -176,6 +177,7 @@
177 "create_invoice": "इनवॉयस बनाएँ",
178 "create_new": "नया बटुआ बनाएँ",
179 "create_new_account": "नया खाता बनाएँ",
180 + "create_new_seed": "नया बीज बनाएं",
181 "creating_new_wallet": "नया बटुआ बनाना",
182 "creating_new_wallet_error": "त्रुटि: ${description}",
183 "creation_date": "निर्माण तिथि",
@@ -602,6 +604,8 @@
604 "seed_share": "बीज साझा करें",
605 "seed_title": "बीज",
606 "seedtype": "बीज",
607 + "seedtype_alert_content": "अन्य बटुए के साथ बीज साझा करना केवल BIP39 SEEDTYPE के साथ संभव है।",
608 + "seedtype_alert_title": "बीजगणित अलर्ट",
609 "seedtype_legacy": "विरासत (25 शब्द)",
610 "seedtype_polyseed": "पॉलीसीड (16 शब्द)",
611 "select_backup_file": "बैकअप फ़ाइल का चयन करें",
@@ -668,6 +672,7 @@
672 "setup_your_debit_card": "अपना डेबिट कार्ड सेट करें",
673 "share": "शेयर करना",
674 "share_address": "पता साझा करें",
675 + "shared_seed_wallet_groups": "साझा बीज बटुए समूह",
676 "show_details": "विवरण दिखाएं",
677 "show_keys": "बीज / कुंजियाँ दिखाएँ",
678 "show_market_place": "बाज़ार दिखाएँ",
@@ -692,6 +697,7 @@
697 "silent_payments_scanned_tip": "टिप करने के लिए स्कैन किया! (${tip})",
698 "silent_payments_scanning": "मूक भुगतान स्कैनिंग",
699 "silent_payments_settings": "मूक भुगतान सेटिंग्स",
700 + "single_seed_wallets_group": "एकल बीज बटुए",
701 "slidable": "फिसलने लायक",
702 "sort_by": "इसके अनुसार क्रमबद्ध करें",
703 "spend_key_private": "खर्च करना (निजी)",
@@ -851,8 +857,16 @@
857 "view_transaction_on": "View Transaction on ",
858 "voting_weight": "वोटिंग वेट",
859 "waitFewSecondForTxUpdate": "लेन-देन इतिहास में लेन-देन प्रतिबिंबित होने के लिए कृपया कुछ सेकंड प्रतीक्षा करें",
860 + "wallet_group": "बटुए समूह",
861 + "wallet_group_description_four": "एक पूरी तरह से नए बीज के साथ एक बटुआ बनाने के लिए।",
862 + "wallet_group_description_one": "केक बटुए में, आप एक बना सकते हैं",
863 + "wallet_group_description_three": "उपलब्ध वॉलेट और/या वॉलेट समूह स्क्रीन देखने के लिए। या चुनें",
864 + "wallet_group_description_two": "एक बीज साझा करने के लिए एक मौजूदा बटुए का चयन करके। प्रत्येक वॉलेट समूह में प्रत्येक मुद्रा प्रकार का एक एकल वॉलेट हो सकता है। \n\n आप चयन कर सकते हैं",
865 + "wallet_group_empty_state_text_one": "लगता है कि आपके पास कोई संगत बटुआ समूह नहीं है !\n\n टैप करें",
866 + "wallet_group_empty_state_text_two": "नीचे एक नया बनाने के लिए।",
867 "wallet_keys": "बटुआ बीज / चाबियाँ",
868 "wallet_list_create_new_wallet": "नया बटुआ बनाएँ",
869 + "wallet_list_edit_group_name": "समूह का नाम संपादित करें",
870 "wallet_list_edit_wallet": "बटुआ संपादित करें",
871 "wallet_list_failed_to_load": "लोड करने में विफल ${wallet_name} बटुआ. ${error}",
872 "wallet_list_failed_to_remove": "निकालने में विफल ${wallet_name} बटुआ. ${error}",
res/values/strings_hr.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "Izaberi jedan",
131 "choose_relay": "Odaberite relej za korištenje",
132 "choose_wallet_currency": "Molimo odaberite valutu novčanika:",
133 + "choose_wallet_group": "Odaberite grupu novčanika",
134 "clear": "Izbriši",
135 "clearnet_link": "Clearnet veza",
136 "close": "Zatvoriti",
@@ -176,6 +177,7 @@
177 "create_invoice": "Izradite fakturu",
178 "create_new": "Izradi novi novčanik",
179 "create_new_account": "Izradi novi račun",
180 + "create_new_seed": "Stvorite novo sjeme",
181 "creating_new_wallet": "Stvaranje novog novčanika",
182 "creating_new_wallet_error": "Greška: ${description}",
183 "creation_date": "Datum stvaranja",
@@ -600,6 +602,8 @@
602 "seed_share": "Podijeli pristupni izraz",
603 "seed_title": "Prisupni izraz",
604 "seedtype": "Sjemenska vrsta",
605 + "seedtype_alert_content": "Dijeljenje sjemena s drugim novčanicima moguće je samo s BIP39 sjemenom.",
606 + "seedtype_alert_title": "Upozorenje o sjemenu",
607 "seedtype_legacy": "Nasljeđe (25 riječi)",
608 "seedtype_polyseed": "Poliseed (16 riječi)",
609 "select_backup_file": "Odaberite datoteku sigurnosne kopije",
@@ -666,6 +670,7 @@
670 "setup_your_debit_card": "Postavite svoju debitnu karticu",
671 "share": "Udio",
672 "share_address": "Podijeli adresu",
673 + "shared_seed_wallet_groups": "Zajedničke grupe za sjeme novčanika",
674 "show_details": "Prikaži pojedinosti",
675 "show_keys": "Prikaži pristupni izraz/ključ",
676 "show_market_place": "Prikaži tržište",
@@ -690,6 +695,7 @@
695 "silent_payments_scanned_tip": "Skenirano na savjet! (${tip})",
696 "silent_payments_scanning": "Skeniranje tihih plaćanja",
697 "silent_payments_settings": "Postavke tihih plaćanja",
698 + "single_seed_wallets_group": "Jednostruki novčanici",
699 "slidable": "Klizna",
700 "sort_by": "Poredaj po",
701 "spend_key_private": "Spend key (privatni)",
@@ -849,8 +855,16 @@
855 "view_transaction_on": "View Transaction on ",
856 "voting_weight": "Težina glasanja",
857 "waitFewSecondForTxUpdate": "Pričekajte nekoliko sekundi da se transakcija prikaže u povijesti transakcija",
858 + "wallet_group": "Skupina novčanika",
859 + "wallet_group_description_four": "Da biste stvorili novčanik s potpuno novim sjemenom.",
860 + "wallet_group_description_one": "U novčaniku kolača možete stvoriti a",
861 + "wallet_group_description_three": "Da biste vidjeli zaslon dostupnih novčanika i/ili grupa novčanika. Ili odaberite",
862 + "wallet_group_description_two": "Odabirom postojećeg novčanika s kojim ćete dijeliti sjeme. Svaka grupa novčanika može sadržavati jedan novčanik svake vrste valute. \n\n",
863 + "wallet_group_empty_state_text_one": "Izgleda da nemate nikakve kompatibilne grupe novčanika !\n\n",
864 + "wallet_group_empty_state_text_two": "Ispod da napravite novi.",
865 "wallet_keys": "Pristupni izraz/ključ novčanika",
866 "wallet_list_create_new_wallet": "Izradi novi novčanik",
867 + "wallet_list_edit_group_name": "Uredi naziv grupe",
868 "wallet_list_edit_wallet": "Uredi novčanik",
869 "wallet_list_failed_to_load": "Neuspješno učitavanje novčanika ${wallet_name}. ${error}",
870 "wallet_list_failed_to_remove": "Neuspješno uklanjanje novčanika ${wallet_name}. ${error}",
res/values/strings_hy.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "Ընտրեք մեկը",
131 "choose_relay": "Խնդրում ենք ընտրեք փոխանցման կետ",
132 "choose_wallet_currency": "Խնդրում ենք ընտրեք դրամապանակի արժույթը",
133 + "choose_wallet_group": "Ընտրեք դրամապանակների խումբ",
134 "clear": "Մաքրել",
135 "clearnet_link": "Բաց ցանցի հղում",
136 "close": "Փակել",
@@ -176,6 +177,7 @@
177 "create_invoice": "Ստեղծել հաշիվ-ապրանքագիր",
178 "create_new": "Ստեղծել նոր դրամապանակ",
179 "create_new_account": "Ստեղծել նոր հաշիվ",
180 + "create_new_seed": "Ստեղծեք նոր սերունդ",
181 "creating_new_wallet": "Նոր դրամապանակ ստեղծվում է",
182 "creating_new_wallet_error": "Սխալ: ${description}",
183 "creation_date": "Ստեղծման ամսաթիվ",
@@ -599,6 +601,8 @@
601 "seed_share": "Կիսվել սերմով",
602 "seed_title": "Սերմ",
603 "seedtype": "Սերմի տեսակ",
604 + "seedtype_alert_content": "Այլ դրամապանակներով սերմերի փոխանակումը հնարավոր է միայն BIP39 SEEDTYPE- ով:",
605 + "seedtype_alert_title": "SEEDTYPE ALERT",
606 "seedtype_legacy": "Legacy (25 բառ)",
607 "seedtype_polyseed": "Polyseed (16 բառ)",
608 "seedtype_wownero": "Wownero (14 բառ)",
@@ -666,6 +670,7 @@
670 "setup_your_debit_card": "Հավատարմագրել ձեր դեբետային քարտ",
671 "share": "Կիսվել",
672 "share_address": "Կիսվել հասցեով",
673 + "shared_seed_wallet_groups": "Համօգտագործված սերմերի դրամապանակների խմբեր",
674 "show_details": "Ցուցադրել մանրամասներ",
675 "show_keys": "Ցուցադրել բանալիներ",
676 "show_market_place": "Ցուցադրել շուկան",
@@ -690,6 +695,7 @@
695 "silent_payments_scanned_tip": "ՍԿԱՆԱՎՈՐՎԵՑ ԹԵՅԱՎՃԱՐ! (${tip})",
696 "silent_payments_scanning": "Լուռ Վճարումներ Սկանավորում",
697 "silent_payments_settings": "Լուռ Վճարումներ Կարգավորումներ",
698 + "single_seed_wallets_group": "Մեկ սերմերի դրամապանակներ",
699 "slidable": "Սահելի",
700 "sort_by": "Դասավորել ըստ",
701 "spend_key_private": "Վճարման բանալի (գախտնի)",
@@ -849,8 +855,16 @@
855 "view_transaction_on": "Դիտել Գործարքը ",
856 "voting_weight": "Քվեարկության Քաշ",
857 "waitFewSecondForTxUpdate": "Խնդրում ենք սպասել մի քանի վայրկյան, որպեսզի գործարքը արտացոլվի գործարքների պատմության մեջ",
858 + "wallet_group": "Դրամապանակների խումբ",
859 + "wallet_group_description_four": "Ամբողջովին նոր սերմով դրամապանակ ստեղծելու համար:",
860 + "wallet_group_description_one": "Տորթի դրամապանակում կարող եք ստեղծել ա",
861 + "wallet_group_description_three": "Տեսնել առկա դրամապանակներն ու (կամ) դրամապանակների խմբերի էկրանը: Կամ ընտրել",
862 + "wallet_group_description_two": "ընտրելով գոյություն ունեցող դրամապանակ `սերմը կիսելու համար: Դրամապանակների յուրաքանչյուր խումբ կարող է պարունակել յուրաքանչյուր արժույթի տիպի մեկ դրամապանակ: \n\n Կարող եք ընտրել",
863 + "wallet_group_empty_state_text_one": "Կարծես թե դուք չունեք որեւէ համատեղելի դրամապանակների խմբեր !\n\n թակել",
864 + "wallet_group_empty_state_text_two": "ներքեւում `նորը կազմելու համար:",
865 "wallet_keys": "Դրամապանակի սերմ/բանալիներ",
866 "wallet_list_create_new_wallet": "Ստեղծել Նոր Դրամապանակ",
867 + "wallet_list_edit_group_name": "Խմբագրել խմբի անվանումը",
868 "wallet_list_edit_wallet": "Խմբագրել դրամապանակը",
869 "wallet_list_failed_to_load": "Չհաջողվեց բեռնել ${wallet_name} դրամապանակը։ ${error}",
870 "wallet_list_failed_to_remove": "Չհաջողվեց հեռացնել ${wallet_name} դրամապանակը։ ${error}",
res/values/strings_id.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "Pilih satu",
131 "choose_relay": "Silakan pilih relai yang akan digunakan",
132 "choose_wallet_currency": "Silahkan pilih mata uang dompet:",
133 + "choose_wallet_group": "Pilih Grup Dompet",
134 "clear": "Hapus",
135 "clearnet_link": "Tautan clearnet",
136 "close": "Menutup",
@@ -176,6 +177,7 @@
177 "create_invoice": "Buat faktur",
178 "create_new": "Buat Dompet Baru",
179 "create_new_account": "Buat akun baru",
180 + "create_new_seed": "Buat benih baru",
181 "creating_new_wallet": "Membuat dompet baru",
182 "creating_new_wallet_error": "Error: ${description}",
183 "creation_date": "Tanggal Pembuatan",
@@ -603,6 +605,8 @@
605 "seed_share": "Bagikan bibit",
606 "seed_title": "Bibit",
607 "seedtype": "Seedtype",
608 + "seedtype_alert_content": "Berbagi biji dengan dompet lain hanya dimungkinkan dengan BIP39 seedtype.",
609 + "seedtype_alert_title": "Peringatan seedtype",
610 "seedtype_legacy": "Legacy (25 kata)",
611 "seedtype_polyseed": "Polyseed (16 kata)",
612 "select_backup_file": "Pilih file cadangan",
@@ -669,6 +673,7 @@
673 "setup_your_debit_card": "Pasang kartu debit Anda",
674 "share": "Membagikan",
675 "share_address": "Bagikan alamat",
676 + "shared_seed_wallet_groups": "Kelompok dompet benih bersama",
677 "show_details": "Tampilkan Rincian",
678 "show_keys": "Tampilkan seed/kunci",
679 "show_market_place": "Tampilkan Pasar",
@@ -693,6 +698,7 @@
698 "silent_payments_scanned_tip": "Pindai untuk memberi tip! (${tip})",
699 "silent_payments_scanning": "Pemindaian pembayaran diam",
700 "silent_payments_settings": "Pengaturan pembayaran diam",
701 + "single_seed_wallets_group": "Dompet biji tunggal",
702 "slidable": "Dapat digeser",
703 "sort_by": "Sortir dengan",
704 "spend_key_private": "Kunci pengeluaran (privat)",
@@ -852,8 +858,16 @@
858 "view_transaction_on": "Lihat Transaksi di ",
859 "voting_weight": "Berat voting",
860 "waitFewSecondForTxUpdate": "Mohon tunggu beberapa detik hingga transaksi terlihat di riwayat transaksi",
861 + "wallet_group": "Kelompok dompet",
862 + "wallet_group_description_four": "Untuk membuat dompet dengan benih yang sama sekali baru.",
863 + "wallet_group_description_one": "Di dompet kue, Anda dapat membuat file",
864 + "wallet_group_description_three": "Untuk melihat layar dompet dan/atau grup dompet yang tersedia. Atau pilih",
865 + "wallet_group_description_two": "dengan memilih dompet yang ada untuk berbagi benih dengan. Setiap grup dompet dapat berisi satu dompet dari setiap jenis mata uang. \n\n Anda dapat memilih",
866 + "wallet_group_empty_state_text_one": "Sepertinya Anda tidak memiliki grup dompet yang kompatibel !\n\n tap",
867 + "wallet_group_empty_state_text_two": "di bawah ini untuk membuat yang baru.",
868 "wallet_keys": "Seed/kunci dompet",
869 "wallet_list_create_new_wallet": "Buat Dompet Baru",
870 + "wallet_list_edit_group_name": "Edit Nama Grup",
871 "wallet_list_edit_wallet": "Edit dompet",
872 "wallet_list_failed_to_load": "Gagal memuat ${wallet_name} dompet. ${error}",
873 "wallet_list_failed_to_remove": "Gagal menghapus ${wallet_name} dompet. ${error}",
res/values/strings_it.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "Scegline uno",
131 "choose_relay": "Scegli un relè da utilizzare",
132 "choose_wallet_currency": "Gentilmente scegli la moneta del portafoglio:",
133 + "choose_wallet_group": "Scegli il gruppo del portafoglio",
134 "clear": "Pulisci",
135 "clearnet_link": "Collegamento Clearnet",
136 "close": "Chiudere",
@@ -177,6 +178,7 @@
178 "create_invoice": "Crea fattura",
179 "create_new": "Genera nuovo Portafoglio",
180 "create_new_account": "Crea nuovo account",
181 + "create_new_seed": "Crea nuovo seme",
182 "creating_new_wallet": "Creazione nuovo portafoglio",
183 "creating_new_wallet_error": "Errore: ${description}",
184 "creation_date": "Data di creazione",
@@ -602,6 +604,8 @@
604 "seed_share": "Condividi seme",
605 "seed_title": "Seme",
606 "seedtype": "Seedtype",
607 + "seedtype_alert_content": "La condivisione di semi con altri portafogli è possibile solo con Bip39 SeedType.",
608 + "seedtype_alert_title": "Avviso seedType",
609 "seedtype_legacy": "Legacy (25 parole)",
610 "seedtype_polyseed": "Polyseed (16 parole)",
611 "select_backup_file": "Seleziona file di backup",
@@ -668,6 +672,7 @@
672 "setup_your_debit_card": "Configura la tua carta di debito",
673 "share": "Condividere",
674 "share_address": "Condividi indirizzo",
675 + "shared_seed_wallet_groups": "Gruppi di portafoglio di semi condivisi",
676 "show_details": "Mostra dettagli",
677 "show_keys": "Mostra seme/chiavi",
678 "show_market_place": "Mostra mercato",
@@ -692,6 +697,7 @@
697 "silent_payments_scanned_tip": "Scansionato per dare la mancia! (${tip})",
698 "silent_payments_scanning": "Scansione di pagamenti silenziosi",
699 "silent_payments_settings": "Impostazioni di pagamenti silenziosi",
700 + "single_seed_wallets_group": "Portafogli singoli",
701 "slidable": "Scorrevole",
702 "sort_by": "Ordina per",
703 "spend_key_private": "Chiave di spesa (privata)",
@@ -852,8 +858,16 @@
858 "voting_weight": "Peso di voto",
859 "waitFewSecondForTxUpdate": "Attendi qualche secondo affinché la transazione venga riflessa nella cronologia delle transazioni",
860 "waiting_payment_confirmation": "In attesa di conferma del pagamento",
861 + "wallet_group": "Gruppo di portafoglio",
862 + "wallet_group_description_four": "Per creare un portafoglio con un seme completamente nuovo.",
863 + "wallet_group_description_one": "Nel portafoglio di torte, puoi creare un",
864 + "wallet_group_description_three": "Per vedere la schermata di portafogli e/o gruppi di portafogli disponibili. O scegli",
865 + "wallet_group_description_two": "Selezionando un portafoglio esistente con cui condividere un seme. Ogni gruppo di portafoglio può contenere un singolo portafoglio di ciascun tipo di valuta. \n\n È possibile selezionare",
866 + "wallet_group_empty_state_text_one": "Sembra che tu non abbia alcun gruppo di portafoglio compatibile !\n\n TAP",
867 + "wallet_group_empty_state_text_two": "Di seguito per crearne uno nuovo.",
868 "wallet_keys": "Seme Portafoglio /chiavi",
869 "wallet_list_create_new_wallet": "Crea Nuovo Portafoglio",
870 + "wallet_list_edit_group_name": "Modifica nome del gruppo",
871 "wallet_list_edit_wallet": "Modifica portafoglio",
872 "wallet_list_failed_to_load": "Caricamento portafoglio ${wallet_name} fallito. ${error}",
873 "wallet_list_failed_to_remove": "Rimozione portafoglio ${wallet_name} fallita. ${error}",
res/values/strings_ja.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "1 つ選択してください",
131 "choose_relay": "使用するリレーを選択してください",
132 "choose_wallet_currency": "ウォレット通貨を選択してください:",
133 + "choose_wallet_group": "ウォレットグループを選択してください",
134 "clear": "クリア",
135 "clearnet_link": "クリアネット リンク",
136 "close": "近い",
@@ -176,6 +177,7 @@
177 "create_invoice": "請求書の作成",
178 "create_new": "新しいウォレットを作成",
179 "create_new_account": "新しいアカウントを作成する",
180 + "create_new_seed": "新しい種を作成します",
181 "creating_new_wallet": "新しいウォレットの作成",
182 "creating_new_wallet_error": "エラー: ${description}",
183 "creation_date": "作成日",
@@ -601,6 +603,8 @@
603 "seed_share": "シードを共有する",
604 "seed_title": "シード",
605 "seedtype": "SeedType",
606 + "seedtype_alert_content": "他の財布と種子を共有することは、BIP39 SeedTypeでのみ可能です。",
607 + "seedtype_alert_title": "SeedTypeアラート",
608 "seedtype_legacy": "レガシー(25語)",
609 "seedtype_polyseed": "ポリシード(16語)",
610 "select_backup_file": "バックアップファイルを選択",
@@ -667,6 +671,7 @@
671 "setup_your_debit_card": "デビットカードを設定してください",
672 "share": "共有",
673 "share_address": "住所を共有する",
674 + "shared_seed_wallet_groups": "共有シードウォレットグループ",
675 "show_details": "詳細を表示",
676 "show_keys": "シード/キーを表示する",
677 "show_market_place": "マーケットプレイスを表示",
@@ -691,6 +696,7 @@
696 "silent_payments_scanned_tip": "チップをスキャンしました! (${tip})",
697 "silent_payments_scanning": "サイレントペイメントスキャン",
698 "silent_payments_settings": "サイレントペイメント設定",
699 + "single_seed_wallets_group": "シングルシードウォレット",
700 "slidable": "スライド可能",
701 "sort_by": "並び替え",
702 "spend_key_private": "キーを使う (プライベート)",
@@ -850,8 +856,16 @@
856 "view_transaction_on": "View Transaction on ",
857 "voting_weight": "投票重み",
858 "waitFewSecondForTxUpdate": "取引履歴に取引が反映されるまで数秒お待ちください。",
859 + "wallet_group": "ウォレットグループ",
860 + "wallet_group_description_four": "まったく新しい種子の財布を作成します。",
861 + "wallet_group_description_one": "ケーキウォレットでは、aを作成できます",
862 + "wallet_group_description_three": "利用可能なウォレットおよび/またはウォレットグループの画面を表示します。または選択します",
863 + "wallet_group_description_two": "既存のウォレットを選択して種子を共有します。各ウォレットグループには、各通貨タイプの単一のウォレットを含めることができます。\n\n選択できます",
864 + "wallet_group_empty_state_text_one": "互換性のあるウォレットグループがないようです!\n\nタップ",
865 + "wallet_group_empty_state_text_two": "以下に新しいものを作るために。",
866 "wallet_keys": "ウォレットシード/キー",
867 "wallet_list_create_new_wallet": "新しいウォレットを作成",
868 + "wallet_list_edit_group_name": "グループ名を編集します",
869 "wallet_list_edit_wallet": "ウォレットを編集する",
870 "wallet_list_failed_to_load": "読み込みに失敗しました ${wallet_name} 財布. ${error}",
871 "wallet_list_failed_to_remove": "削除できませんでした ${wallet_name} 財布. ${error}",
res/values/strings_ko.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "하나 선택",
131 "choose_relay": "사용할 릴레이를 선택해주세요",
132 "choose_wallet_currency": "지갑 통화를 선택하십시오:",
133 + "choose_wallet_group": "지갑 그룹을 선택하십시오",
134 "clear": "명확한",
135 "clearnet_link": "클리어넷 링크",
136 "close": "닫다",
@@ -176,6 +177,7 @@
177 "create_invoice": "인보이스 생성",
178 "create_new": "새 월렛 만들기",
179 "create_new_account": "새 계정을 만들",
180 + "create_new_seed": "새 씨앗을 만듭니다",
181 "creating_new_wallet": "새 지갑 생성",
182 "creating_new_wallet_error": "오류: ${description}",
183 "creation_date": "생산 일",
@@ -601,6 +603,8 @@
603 "seed_share": "시드 공유",
604 "seed_title": "씨",
605 "seedtype": "시드 타입",
606 + "seedtype_alert_content": "다른 지갑과 씨앗을 공유하는 것은 BIP39 SeedType에서만 가능합니다.",
607 + "seedtype_alert_title": "종자 경보",
608 "seedtype_legacy": "레거시 (25 단어)",
609 "seedtype_polyseed": "다문 (16 단어)",
610 "select_backup_file": "백업 파일 선택",
@@ -667,6 +671,7 @@
671 "setup_your_debit_card": "직불카드 설정",
672 "share": "공유하다",
673 "share_address": "주소 공유",
674 + "shared_seed_wallet_groups": "공유 종자 지갑 그룹",
675 "show_details": "세부정보 표시",
676 "show_keys": "시드 / 키 표시",
677 "show_market_place": "마켓플레이스 표시",
@@ -691,6 +696,7 @@
696 "silent_payments_scanned_tip": "팁을 스캔했습니다! (${tip})",
697 "silent_payments_scanning": "조용한 지불 스캔",
698 "silent_payments_settings": "조용한 지불 설정",
699 + "single_seed_wallets_group": "단일 씨앗 지갑",
700 "slidable": "슬라이딩 가능",
701 "sort_by": "정렬 기준",
702 "spend_key_private": "지출 키 (은밀한)",
@@ -850,8 +856,16 @@
856 "view_transaction_on": "View Transaction on ",
857 "voting_weight": "투표 중량",
858 "waitFewSecondForTxUpdate": "거래 내역에 거래가 반영될 때까지 몇 초 정도 기다려 주세요.",
859 + "wallet_group": "지갑 그룹",
860 + "wallet_group_description_four": "완전히 새로운 씨앗으로 지갑을 만듭니다.",
861 + "wallet_group_description_one": "케이크 지갑에서는 a를 만들 수 있습니다",
862 + "wallet_group_description_three": "사용 가능한 지갑 및/또는 지갑 그룹 스크린을 볼 수 있습니다. 또는 선택하십시오",
863 + "wallet_group_description_two": "씨앗을 공유 할 기존 지갑을 선택함으로써. 각 지갑 그룹은 각 통화 유형의 단일 지갑을 포함 할 수 있습니다. \n\n",
864 + "wallet_group_empty_state_text_one": "호환 지갑 그룹이없는 것 같습니다 !\n\n TAP",
865 + "wallet_group_empty_state_text_two": "아래에서 새로운 것을 만들기 위해.",
866 "wallet_keys": "지갑 시드 / 키",
867 "wallet_list_create_new_wallet": "새 월렛 만들기",
868 + "wallet_list_edit_group_name": "그룹 이름 편집",
869 "wallet_list_edit_wallet": "지갑 수정",
870 "wallet_list_failed_to_load": "불러 오지 못했습니다 ${wallet_name} 지갑. ${error}",
871 "wallet_list_failed_to_remove": "제거하지 못했습니다 ${wallet_name} 지갑. ${error}",
res/values/strings_my.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "တစ်ခုရွေးပါ။",
131 "choose_relay": "အသုံးပြုရန် relay ကိုရွေးချယ်ပါ။",
132 "choose_wallet_currency": "ပိုက်ဆံအိတ်ငွေကြေးကို ရွေးပါ-",
133 + "choose_wallet_group": "ပိုက်ဆံအိတ်အုပ်စုရွေးပါ",
134 "clear": "ရှင်းလင်းသော",
135 "clearnet_link": "Clearnet လင့်ခ်",
136 "close": "အနီးကပ်",
@@ -176,6 +177,7 @@
177 "create_invoice": "ပြေစာဖန်တီးပါ။",
178 "create_new": "Wallet အသစ်ဖန်တီးပါ။",
179 "create_new_account": "အကောင့်အသစ်ဖန်တီးပါ။",
180 + "create_new_seed": "မျိုးစေ့အသစ်ကိုဖန်တီးပါ",
181 "creating_new_wallet": "ပိုက်ဆံအိတ်အသစ်ဖန်တီးခြင်း။",
182 "creating_new_wallet_error": "အမှား- ${description}",
183 "creation_date": "ဖန်တီးမှုနေ့စွဲ",
@@ -600,6 +602,8 @@
602 "seed_share": "မျိုးစေ့မျှဝေပါ။",
603 "seed_title": "မျိုးစေ့",
604 "seedtype": "မျိုးပွားခြင်း",
605 + "seedtype_alert_content": "အခြားပိုက်ဆံအိတ်များနှင့်မျိုးစေ့များကိုမျှဝေခြင်းသည် BIP39 sebyspe ဖြင့်သာဖြစ်သည်။",
606 + "seedtype_alert_title": "ပျိုးပင်သတိပေးချက်",
607 "seedtype_legacy": "အမွေအနှစ် (စကားလုံး 25 လုံး)",
608 "seedtype_polyseed": "polyseed (စကားလုံး 16 လုံး)",
609 "select_backup_file": "အရန်ဖိုင်ကို ရွေးပါ။",
@@ -666,6 +670,7 @@
670 "setup_your_debit_card": "သင့်ဒက်ဘစ်ကတ်ကို စနစ်ထည့်သွင်းပါ။",
671 "share": "မျှဝေပါ။",
672 "share_address": "လိပ်စာမျှဝေပါ။",
673 + "shared_seed_wallet_groups": "shared မျိုးစေ့ပိုက်ဆံအိတ်အုပ်စုများ",
674 "show_details": "အသေးစိတ်ပြ",
675 "show_keys": "မျိုးစေ့ /သော့များကို ပြပါ။",
676 "show_market_place": "စျေးကွက်ကိုပြသပါ။",
@@ -690,6 +695,7 @@
695 "silent_payments_scanned_tip": "အစွန်အဖျားမှ scan ဖတ်! (${tip})",
696 "silent_payments_scanning": "အသံတိတ်ငွေပေးချေမှု scanning",
697 "silent_payments_settings": "အသံတိတ်ငွေပေးချေမှုဆက်တင်များ",
698 + "single_seed_wallets_group": "တစ်ခုတည်းမျိုးစေ့ပိုက်ဆံအိတ်",
699 "slidable": "လျှောချနိုင်သည်။",
700 "sort_by": "အလိုက်စဥ်သည်",
701 "spend_key_private": "သော့သုံးရန် (သီးသန့်)",
@@ -849,8 +855,16 @@
855 "view_transaction_on": "ငွေလွှဲခြင်းကို ဖွင့်ကြည့်ပါ။",
856 "voting_weight": "မဲပေးအလေးချိန်",
857 "waitFewSecondForTxUpdate": "ငွေပေးငွေယူ မှတ်တမ်းတွင် ရောင်ပြန်ဟပ်ရန် စက္ကန့်အနည်းငယ်စောင့်ပါ။",
858 + "wallet_group": "ပိုက်ဆံအိတ်အုပ်စု",
859 + "wallet_group_description_four": "လုံးဝအသစ်သောမျိုးစေ့နှင့်အတူပိုက်ဆံအိတ်ဖန်တီးရန်။",
860 + "wallet_group_description_one": "ကိတ်မုန့်၌, သင်တစ် ဦး ဖန်တီးနိုင်ပါတယ်",
861 + "wallet_group_description_three": "ရရှိနိုင်သည့်ပိုက်ဆံအိတ်နှင့် / သို့မဟုတ်ပိုက်ဆံအိတ်အုပ်စုများမြင်ကွင်းကိုကြည့်ရှုရန်။ သို့မဟုတ်ရွေးချယ်ပါ",
862 + "wallet_group_description_two": "နှင့်အတူမျိုးစေ့ဝေမျှဖို့ရှိပြီးသားပိုက်ဆံအိတ်တစ်ခုရွေးချယ်ခြင်းအားဖြင့်။ ပိုက်ဆံအိတ်အုပ်စုတစ်ခုစီတွင်ငွေကြေးအမျိုးအစားတစ်ခုစီ၏တစ်ခုတည်းသောပိုက်ဆံအိတ်တစ်ခုပါ 0 င်နိုင်သည်။ \n\n သင်ရွေးချယ်နိုင်သည်",
863 + "wallet_group_empty_state_text_one": "သင့်တွင်သဟဇာတဖြစ်သောပိုက်ဆံအိတ်အုပ်စုများမရှိပါ။ !\n\n ကိုအသာပုတ်ပါ",
864 + "wallet_group_empty_state_text_two": "အသစ်တစ်ခုကိုတစ်ခုလုပ်ဖို့အောက်တွင်ဖော်ပြထားသော။",
865 "wallet_keys": "ပိုက်ဆံအိတ် အစေ့/သော့များ",
866 "wallet_list_create_new_wallet": "Wallet အသစ်ဖန်တီးပါ။",
867 + "wallet_list_edit_group_name": "အုပ်စုအမည်ကိုတည်းဖြတ်ပါ",
868 "wallet_list_edit_wallet": "ပိုက်ဆံအိတ်ကို တည်းဖြတ်ပါ။",
869 "wallet_list_failed_to_load": "${wallet_name} ပိုက်ဆံအိတ်ကို ဖွင့်၍မရပါ။ ${error}",
870 "wallet_list_failed_to_remove": "${wallet_name} ပိုက်ဆံအိတ်ကို ဖယ်ရှား၍မရပါ။ ${error}",
res/values/strings_nl.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "Kies er een",
131 "choose_relay": "Kies een relais dat u wilt gebruiken",
132 "choose_wallet_currency": "Kies een portemonnee-valuta:",
133 + "choose_wallet_group": "Kies portemonnee groep",
134 "clear": "Duidelijk",
135 "clearnet_link": "Clearnet-link",
136 "close": "Dichtbij",
@@ -176,6 +177,7 @@
177 "create_invoice": "Factuur maken",
178 "create_new": "Maak een nieuwe portemonnee",
179 "create_new_account": "Creëer een nieuw account",
180 + "create_new_seed": "Maak nieuw zaadje",
181 "creating_new_wallet": "Nieuwe portemonnee aanmaken",
182 "creating_new_wallet_error": "Fout: ${description}",
183 "creation_date": "Aanmaakdatum",
@@ -600,6 +602,8 @@
602 "seed_share": "Deel zaad",
603 "seed_title": "Zaad",
604 "seedtype": "Zaadtype",
605 + "seedtype_alert_content": "Het delen van zaden met andere portefeuilles is alleen mogelijk met BIP39 SeedType.",
606 + "seedtype_alert_title": "Zaadtype alert",
607 "seedtype_legacy": "Legacy (25 woorden)",
608 "seedtype_polyseed": "Polyseed (16 woorden)",
609 "select_backup_file": "Selecteer een back-upbestand",
@@ -666,6 +670,7 @@
670 "setup_your_debit_card": "Stel uw debetkaart in",
671 "share": "Deel",
672 "share_address": "Deel adres",
673 + "shared_seed_wallet_groups": "Gedeelde zaadportelgroepen",
674 "show_details": "Toon details",
675 "show_keys": "Toon zaad/sleutels",
676 "show_market_place": "Toon Marktplaats",
@@ -690,6 +695,7 @@
695 "silent_payments_scanned_tip": "Gescand om te fooien! (${tip})",
696 "silent_payments_scanning": "Stille betalingen scannen",
697 "silent_payments_settings": "Stille betalingsinstellingen",
698 + "single_seed_wallets_group": "Enkele zaadportefeuilles",
699 "slidable": "Verschuifbaar",
700 "sort_by": "Sorteer op",
701 "spend_key_private": "Sleutel uitgeven (privaat)",
@@ -850,8 +856,16 @@
856 "voting_weight": "Stemgewicht",
857 "waitFewSecondForTxUpdate": "Wacht een paar seconden totdat de transactie wordt weergegeven in de transactiegeschiedenis",
858 "waiting_payment_confirmation": "In afwachting van betalingsbevestiging",
859 + "wallet_group": "Portemonnee",
860 + "wallet_group_description_four": "om een ​​portemonnee te maken met een geheel nieuw zaadje.",
861 + "wallet_group_description_one": "In cakeballet kun je een",
862 + "wallet_group_description_three": "Om de beschikbare portefeuilles en/of portefeuillegroepen te zien. Of kies",
863 + "wallet_group_description_two": "Door een bestaande portemonnee te selecteren om een ​​zaadje mee te delen. Elke portemonnee -groep kan een enkele portemonnee van elk valutietype bevatten. \n\n U kunt selecteren",
864 + "wallet_group_empty_state_text_one": "Het lijkt erop dat je geen compatibele portemonnee -groepen hebt !\n\n TAP",
865 + "wallet_group_empty_state_text_two": "hieronder om een ​​nieuwe te maken.",
866 "wallet_keys": "Portemonnee zaad/sleutels",
867 "wallet_list_create_new_wallet": "Maak een nieuwe portemonnee",
868 + "wallet_list_edit_group_name": "Groepsnaam bewerken",
869 "wallet_list_edit_wallet": "Portemonnee bewerken",
870 "wallet_list_failed_to_load": "Laden mislukt ${wallet_name} portemonnee. ${error}",
871 "wallet_list_failed_to_remove": "Verwijderen mislukt ${wallet_name} portemonnee. ${error}",
res/values/strings_pl.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "Wybierz jeden",
131 "choose_relay": "Wybierz przekaźnik, którego chcesz użyć",
132 "choose_wallet_currency": "Wybierz walutę portfela:",
133 + "choose_wallet_group": "Wybierz grupę portfela",
134 "clear": "Wyczyść",
135 "clearnet_link": "łącze Clearnet",
136 "close": "Zamknąć",
@@ -176,6 +177,7 @@
177 "create_invoice": "Wystaw fakturę",
178 "create_new": "Utwórz nowy portfel",
179 "create_new_account": "Stwórz nowe konto",
180 + "create_new_seed": "Utwórz nowe ziarno",
181 "creating_new_wallet": "Tworzenie nowego portfela",
182 "creating_new_wallet_error": "Błąd: ${description}",
183 "creation_date": "Data utworzenia",
@@ -600,6 +602,8 @@
602 "seed_share": "Udostępnij seed",
603 "seed_title": "Seed",
604 "seedtype": "Sedtype",
605 + "seedtype_alert_content": "Dzielenie się nasionami z innymi portfelami jest możliwe tylko z BIP39 sededType.",
606 + "seedtype_alert_title": "Ustanowienie typu sedype",
607 "seedtype_legacy": "Dziedzictwo (25 słów)",
608 "seedtype_polyseed": "Poliqueed (16 słów)",
609 "select_backup_file": "Wybierz plik kopii zapasowej",
@@ -666,6 +670,7 @@
670 "setup_your_debit_card": "Skonfiguruj swoją kartę debetową",
671 "share": "Udział",
672 "share_address": "Udostępnij adres",
673 + "shared_seed_wallet_groups": "Wspólne grupy portfeli nasion",
674 "show_details": "Pokaż szczegóły",
675 "show_keys": "Pokaż seed/klucze",
676 "show_market_place": "Pokaż rynek",
@@ -690,6 +695,7 @@
695 "silent_payments_scanned_tip": "Zeskanowany do napiwku! (${tip})",
696 "silent_payments_scanning": "Skanowanie cichych płatności",
697 "silent_payments_settings": "Ustawienia o cichej płatności",
698 + "single_seed_wallets_group": "Pojedyncze portfele nasion",
699 "slidable": "Przesuwne",
700 "sort_by": "Sortuj według",
701 "spend_key_private": "Klucz prywatny",
@@ -849,8 +855,16 @@
855 "view_transaction_on": "Zobacz transakcje na ",
856 "voting_weight": "Waga głosu",
857 "waitFewSecondForTxUpdate": "Poczekaj kilka sekund, aż transakcja zostanie odzwierciedlona w historii transakcji",
858 + "wallet_group": "Grupa portfela",
859 + "wallet_group_description_four": "Aby stworzyć portfel z zupełnie nowym ziarnem.",
860 + "wallet_group_description_one": "W portfelu ciasta możesz stworzyć",
861 + "wallet_group_description_three": "Aby zobaczyć dostępny ekran portfeli i/lub grup portfeli. Lub wybierz",
862 + "wallet_group_description_two": "Wybierając istniejący portfel do podzielenia nasion. Każda grupa portfela może zawierać pojedynczy portfel każdego typu waluty. \n\n możesz wybrać",
863 + "wallet_group_empty_state_text_one": "Wygląda na to, że nie masz żadnych kompatybilnych grup portfeli !\n\n Tap",
864 + "wallet_group_empty_state_text_two": "poniżej, aby zrobić nowy.",
865 "wallet_keys": "Klucze portfela",
866 "wallet_list_create_new_wallet": "Utwórz nowy portfel",
867 + "wallet_list_edit_group_name": "Edytuj nazwę grupy",
868 "wallet_list_edit_wallet": "Edytuj portfel",
869 "wallet_list_failed_to_load": "Nie udało się załadować ${wallet_name} portfel. ${error}",
870 "wallet_list_failed_to_remove": "Nie udało się usunąć ${wallet_name} portfel. ${error}",
res/values/strings_pt.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "Escolha um",
131 "choose_relay": "Escolha um relé para usar",
132 "choose_wallet_currency": "Escolha a moeda da carteira:",
133 + "choose_wallet_group": "Escolha o Grupo de Wallet",
134 "clear": "Limpar",
135 "clearnet_link": "link clear net",
136 "close": "Fechar",
@@ -176,6 +177,7 @@
177 "create_invoice": "Criar recibo",
178 "create_new": "Criar nova carteira",
179 "create_new_account": "Criar nova conta",
180 + "create_new_seed": "Crie nova semente",
181 "creating_new_wallet": "Criando nova carteira",
182 "creating_new_wallet_error": "Erro: ${description}",
183 "creation_date": "Data de criação",
@@ -602,6 +604,8 @@
604 "seed_share": "Compartilhar semente",
605 "seed_title": "Semente",
606 "seedtype": "SeedType",
607 + "seedtype_alert_content": "Compartilhar sementes com outras carteiras só é possível com o BIP39 SeedType.",
608 + "seedtype_alert_title": "Alerta de SeedType",
609 "seedtype_legacy": "Legado (25 palavras)",
610 "seedtype_polyseed": "Polyseed (16 palavras)",
611 "select_backup_file": "Selecione o arquivo de backup",
@@ -668,6 +672,7 @@
672 "setup_your_debit_card": "Configure seu cartão de débito",
673 "share": "Compartilhar",
674 "share_address": "Compartilhar endereço",
675 + "shared_seed_wallet_groups": "Grupos de carteira de sementes compartilhados",
676 "show_details": "Mostrar detalhes",
677 "show_keys": "Mostrar semente/chaves",
678 "show_market_place": "Mostrar mercado",
@@ -692,6 +697,7 @@
697 "silent_payments_scanned_tip": "Escaneado até o fim! (${tip})",
698 "silent_payments_scanning": "Escanear Pagamentos Silenciosos",
699 "silent_payments_settings": "Configurações de pagamentos silenciosos",
700 + "single_seed_wallets_group": "Carteiras de sementes únicas",
701 "slidable": "Deslizável",
702 "sort_by": "Ordenar por",
703 "spend_key_private": "Chave de gastos (privada)",
@@ -852,8 +858,16 @@
858 "voting_weight": "Peso de votação",
859 "waitFewSecondForTxUpdate": "Aguarde alguns segundos para que a transação seja refletida no histórico de transações",
860 "waiting_payment_confirmation": "Aguardando confirmação de pagamento",
861 + "wallet_group": "Grupo de carteira",
862 + "wallet_group_description_four": "Para criar uma carteira com uma semente totalmente nova.",
863 + "wallet_group_description_one": "Na carteira de bolo, você pode criar um",
864 + "wallet_group_description_three": "Para ver as carteiras disponíveis e/ou os grupos de carteiras. Ou escolha",
865 + "wallet_group_description_two": "Selecionando uma carteira existente para compartilhar uma semente. Cada grupo de carteira pode conter uma única carteira de cada tipo de moeda. \n\n você pode selecionar",
866 + "wallet_group_empty_state_text_one": "Parece que você não tem nenhum grupo de carteira compatível !\n\n Toque",
867 + "wallet_group_empty_state_text_two": "abaixo para fazer um novo.",
868 "wallet_keys": "Semente/chaves da carteira",
869 "wallet_list_create_new_wallet": "Criar nova carteira",
870 + "wallet_list_edit_group_name": "Editar o nome do grupo",
871 "wallet_list_edit_wallet": "Editar carteira",
872 "wallet_list_failed_to_load": "Falha ao abrir a carteira ${wallet_name}. ${error}",
873 "wallet_list_failed_to_remove": "Falha ao remover a carteira ${wallet_name}. ${error}",
res/values/strings_ru.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "Выбери один",
131 "choose_relay": "Пожалуйста, выберите реле для использования",
132 "choose_wallet_currency": "Пожалуйста, выберите валюту кошелька:",
133 + "choose_wallet_group": "Выберите группу кошелька",
134 "clear": "Очистить",
135 "clearnet_link": "Клирнет ссылка",
136 "close": "Закрывать",
@@ -176,6 +177,7 @@
177 "create_invoice": "Создать счет",
178 "create_new": "Создать новый кошелёк",
179 "create_new_account": "Создать новый аккаунт",
180 + "create_new_seed": "Создать новое семя",
181 "creating_new_wallet": "Создание нового кошелька",
182 "creating_new_wallet_error": "Ошибка: ${description}",
183 "creation_date": "Дата создания",
@@ -601,6 +603,8 @@
603 "seed_share": "Поделиться мнемонической фразой",
604 "seed_title": "Мнемоническая фраза",
605 "seedtype": "SEEDTYPE",
606 + "seedtype_alert_content": "Обмен семенами с другими кошельками возможно только с BIP39 SeedType.",
607 + "seedtype_alert_title": "SEEDTYPE ALERT",
608 "seedtype_legacy": "Наследие (25 слов)",
609 "seedtype_polyseed": "Полиса (16 слов)",
610 "select_backup_file": "Выберите файл резервной копии",
@@ -667,6 +671,7 @@
671 "setup_your_debit_card": "Настройте свою дебетовую карту",
672 "share": "Делиться",
673 "share_address": "Поделиться адресом",
674 + "shared_seed_wallet_groups": "Общие группы кошелька семян",
675 "show_details": "Показать детали",
676 "show_keys": "Показать мнемоническую фразу/ключи",
677 "show_market_place": "Показать торговую площадку",
@@ -691,6 +696,7 @@
696 "silent_payments_scanned_tip": "Оканируется, чтобы чаевые! (${tip})",
697 "silent_payments_scanning": "Сканирование безмолвных платежей",
698 "silent_payments_settings": "Silent Payments Settings",
699 + "single_seed_wallets_group": "Одиночные кошельки",
700 "slidable": "Скользящий",
701 "sort_by": "Сортировать по",
702 "spend_key_private": "Приватный ключ траты",
@@ -850,8 +856,16 @@
856 "view_transaction_on": "View Transaction on ",
857 "voting_weight": "Вес голоса",
858 "waitFewSecondForTxUpdate": "Пожалуйста, подождите несколько секунд, чтобы транзакция отразилась в истории транзакций.",
859 + "wallet_group": "Группа кошелька",
860 + "wallet_group_description_four": "создать кошелек с совершенно новым семенем.",
861 + "wallet_group_description_one": "В кошельке для торта вы можете создать",
862 + "wallet_group_description_three": "Чтобы увидеть доступные кошельки и/или экраны групп кошельков. Или выберите",
863 + "wallet_group_description_two": "выбирая существующий кошелек, чтобы поделиться семенами. Каждая группа кошелька может содержать один кошелек каждого типа валюты. \n\n Вы можете выбрать",
864 + "wallet_group_empty_state_text_one": "Похоже, у вас нет никаких совместимых групп кошелька !\n\n tap",
865 + "wallet_group_empty_state_text_two": "ниже, чтобы сделать новый.",
866 "wallet_keys": "Мнемоническая фраза/ключи кошелька",
867 "wallet_list_create_new_wallet": "Создать новый кошелёк",
868 + "wallet_list_edit_group_name": "Редактировать название группы",
869 "wallet_list_edit_wallet": "Изменить кошелек",
870 "wallet_list_failed_to_load": "Ошибка при загрузке ${wallet_name} кошелька. ${error}",
871 "wallet_list_failed_to_remove": "Ошибка при удалении ${wallet_name} кошелька. ${error}",
res/values/strings_th.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "เลือกหนึ่งรายการ",
131 "choose_relay": "กรุณาเลือกรีเลย์ที่จะใช้",
132 "choose_wallet_currency": "โปรดเลือกสกุลเงินของกระเป๋า:",
133 + "choose_wallet_group": "เลือกกลุ่มกระเป๋าเงิน",
134 "clear": "ล้าง",
135 "clearnet_link": "ลิงค์เคลียร์เน็ต",
136 "close": "ปิด",
@@ -176,6 +177,7 @@
177 "create_invoice": "สร้างใบแจ้งหนี้",
178 "create_new": "สร้างกระเป๋าใหม่",
179 "create_new_account": "สร้างบัญชีใหม่",
180 + "create_new_seed": "สร้างเมล็ดพันธุ์ใหม่",
181 "creating_new_wallet": "กำลังสร้างกระเป๋าใหม่",
182 "creating_new_wallet_error": "ข้อผิดพลาด: ${description}",
183 "creation_date": "วันที่สร้าง",
@@ -600,6 +602,8 @@
602 "seed_share": "แบ่งปัน seed",
603 "seed_title": "Seed",
604 "seedtype": "เมล็ดพันธุ์",
605 + "seedtype_alert_content": "การแบ่งปันเมล็ดกับกระเป๋าเงินอื่น ๆ เป็นไปได้เฉพาะกับ bip39 seedtype",
606 + "seedtype_alert_title": "การแจ้งเตือน seedtype",
607 "seedtype_legacy": "มรดก (25 คำ)",
608 "seedtype_polyseed": "โพลีส (16 คำ)",
609 "select_backup_file": "เลือกไฟล์สำรอง",
@@ -666,6 +670,7 @@
670 "setup_your_debit_card": "ตั้งค่าบัตรเดบิตของคุณ",
671 "share": "แบ่งปัน",
672 "share_address": "แชร์ที่อยู่",
673 + "shared_seed_wallet_groups": "กลุ่มกระเป๋าเงินที่ใช้ร่วมกัน",
674 "show_details": "แสดงรายละเอียด",
675 "show_keys": "แสดงซีด/คีย์",
676 "show_market_place": "แสดงตลาดกลาง",
@@ -690,6 +695,7 @@
695 "silent_payments_scanned_tip": "สแกนไปที่ปลาย! (${tip})",
696 "silent_payments_scanning": "การสแกนการชำระเงินแบบเงียบ",
697 "silent_payments_settings": "การตั้งค่าการชำระเงินแบบเงียบ",
698 + "single_seed_wallets_group": "กระเป๋าเงินเดียว",
699 "slidable": "เลื่อนได้",
700 "sort_by": "เรียงตาม",
701 "spend_key_private": "คีย์จ่าย (ส่วนตัว)",
@@ -849,8 +855,16 @@
855 "view_transaction_on": "ดูการทำธุรกรรมบน ",
856 "voting_weight": "น้ำหนักโหวต",
857 "waitFewSecondForTxUpdate": "กรุณารอสักครู่เพื่อให้ธุรกรรมปรากฏในประวัติการทำธุรกรรม",
858 + "wallet_group": "กลุ่มกระเป๋าเงิน",
859 + "wallet_group_description_four": "เพื่อสร้างกระเป๋าเงินที่มีเมล็ดพันธุ์ใหม่ทั้งหมด",
860 + "wallet_group_description_one": "ในกระเป๋าเงินเค้กคุณสามารถสร้างไฟล์",
861 + "wallet_group_description_three": "หากต้องการดูกระเป๋าเงินและ/หรือกลุ่มกระเป๋าเงินที่มีอยู่ หรือเลือก",
862 + "wallet_group_description_two": "โดยการเลือกกระเป๋าเงินที่มีอยู่เพื่อแบ่งปันเมล็ดด้วย แต่ละกลุ่มกระเป๋าเงินสามารถมีกระเป๋าเงินเดียวของแต่ละประเภทสกุลเงิน \n\n คุณสามารถเลือกได้",
863 + "wallet_group_empty_state_text_one": "ดูเหมือนว่าคุณจะไม่มีกลุ่มกระเป๋าเงินที่เข้ากันได้ !\n\n แตะ",
864 + "wallet_group_empty_state_text_two": "ด้านล่างเพื่อสร้างใหม่",
865 "wallet_keys": "ซีดของกระเป๋า/คีย์",
866 "wallet_list_create_new_wallet": "สร้างกระเป๋าใหม่",
867 + "wallet_list_edit_group_name": "แก้ไขชื่อกลุ่ม",
868 "wallet_list_edit_wallet": "แก้ไขกระเป๋าสตางค์",
869 "wallet_list_failed_to_load": "ไม่สามารถโหลดกระเป๋า ${wallet_name} ได้ ${error}",
870 "wallet_list_failed_to_remove": "ไม่สามารถลบกระเป๋า ${wallet_name} ได้ ${error}",
res/values/strings_tl.arb
+22 -8
@@ -129,8 +129,9 @@
129 "choose_from_available_options": "Pumili mula sa magagamit na mga pagpipilian:",
130 "choose_one": "Pumili ng isa",
131 "choose_relay": "Mangyaring pumili ng relay na gagamitin",
132 - "choose_wallet_currency": "Mangyaring piliin ang pera ng wallet:",
133 - "clear": "Burahin",
132 + "choose_wallet_currency": "Mangyaring piliin ang Pera ng Wallet:",
133 + "choose_wallet_group": "Piliin ang pangkat ng Wallet",
134 + "clear": "Malinaw",
135 "clearnet_link": "Link ng Clearnet",
136 "close": "Isara",
137 "coin_control": "Coin control (opsyonal)",
@@ -176,6 +177,7 @@
177 "create_invoice": "Lumikha ng invoice",
178 "create_new": "Lumikha ng Bagong Wallet",
179 "create_new_account": "Lumikha ng bagong account",
180 + "create_new_seed": "Lumikha ng bagong binhi",
181 "creating_new_wallet": "Lumikha ng bagong wallet",
182 "creating_new_wallet_error": "Error: ${description}",
183 "creation_date": "Petsa ng paglikha",
@@ -469,13 +471,13 @@
471 "please_try_to_connect_to_another_node": "Pakisubukang kumonekta sa iba pang node",
472 "please_wait": "Mangyaring maghintay",
473 "polygonscan_history": "Kasaysayan ng PolygonScan",
472 - "powered_by": "Pinapatakbo ng${title}",
473 - "pre_seed_button_text": "Naiitindihan ko. Ipakita ang aking seed",
474 - "pre_seed_description": "Sa susunod na pahina ay makikita mo ang isang serye ng ${words} na salita. Ito ang iyong natatangi at pribadong seed at ito ang tanging paraan upang mabawi ang iyong wallet kung sakaling mawala o hindi gumana. Responsibilidad mong isulat ito sa isang ligtas na lugar sa labas ng Cake Wallet app.",
475 - "pre_seed_title": "MAHALAGA",
474 + "powered_by": "Pinapagana ng ${title}",
475 + "pre_seed_button_text": "Naiintindihan ko. Ipakita sa akin ang aking binhi",
476 + "pre_seed_description": "Sa susunod na pahina makikita mo ang isang serye ng mga ${words} na mga salita. Ito ang iyong natatangi at pribadong binhi at ito ang tanging paraan upang mabawi ang iyong pitaka kung sakaling mawala o madepektong paggawa. Responsibilidad mong isulat ito at itago ito sa isang ligtas na lugar sa labas ng cake wallet app.",
477 + "pre_seed_title": "Mahalaga",
478 "prepaid_cards": "Mga Prepaid Card",
477 - "prevent_screenshots": "Maiwasan ang mga screenshot at pag-record ng screen",
478 - "privacy": "Pagkapribado",
479 + "prevent_screenshots": "Maiwasan ang mga screenshot at pag -record ng screen",
480 + "privacy": "Privacy",
481 "privacy_policy": "Patakaran sa Pagkapribado",
482 "privacy_settings": "Settings para sa pagsasa-pribado",
483 "private_key": "Private key",
@@ -600,6 +602,8 @@
602 "seed_share": "Ibahagi ang seed",
603 "seed_title": "Seed",
604 "seedtype": "Seed type",
605 + "seedtype_alert_content": "Ang pagbabahagi ng mga buto sa iba pang mga pitaka ay posible lamang sa bip39 seedtype.",
606 + "seedtype_alert_title": "Alerto ng Seedtype",
607 "seedtype_legacy": "Legacy (25 na salita)",
608 "seedtype_polyseed": "Polyseed (16 na salita)",
609 "select_backup_file": "Piliin ang backup na file",
@@ -666,6 +670,7 @@
670 "setup_your_debit_card": "I-set up ang iyong debit card",
671 "share": "Ibahagi",
672 "share_address": "Ibahagi ang address",
673 + "shared_seed_wallet_groups": "Ibinahaging mga pangkat ng pitaka ng binhi",
674 "show_details": "Ipakita ang mga detalye",
675 "show_keys": "Ipakita ang mga seed/key",
676 "show_market_place": "Ipakita ang Marketplace",
@@ -690,6 +695,7 @@
695 "silent_payments_scanned_tip": "Na-scan sa tip! (${tip})",
696 "silent_payments_scanning": "Pag-scan ng tahimik na pagbabayad",
697 "silent_payments_settings": "Mga setting ng tahimik na pagbabayad",
698 + "single_seed_wallets_group": "Solong mga pitaka ng binhi",
699 "slidable": "Slidable",
700 "sort_by": "Pag-uri-uriin sa pamamagitan ng",
701 "spend_key_private": "Spend key (private)",
@@ -849,8 +855,16 @@
855 "view_transaction_on": "Tingnan ang transaksyon sa ",
856 "voting_weight": "Bigat ng pagboto",
857 "waitFewSecondForTxUpdate": "Mangyaring maghintay ng ilang segundo para makita ang transaksyon sa history ng mga transaksyon",
858 + "wallet_group": "Group ng Wallet",
859 + "wallet_group_description_four": "Upang lumikha ng isang pitaka na may ganap na bagong binhi.",
860 + "wallet_group_description_one": "Sa cake wallet, maaari kang lumikha ng isang",
861 + "wallet_group_description_three": "Upang makita ang magagamit na mga wallets at/o screen ng mga pangkat ng pitaka. O pumili",
862 + "wallet_group_description_two": "Sa pamamagitan ng pagpili ng isang umiiral na pitaka upang magbahagi ng isang binhi. Ang bawat pangkat ng pitaka ay maaaring maglaman ng isang solong pitaka ng bawat uri ng pera.\n\nMaaari kang pumili",
863 + "wallet_group_empty_state_text_one": "Mukhang wala kang anumang mga katugmang pangkat ng pitaka!\n\ntap",
864 + "wallet_group_empty_state_text_two": "sa ibaba upang gumawa ng bago.",
865 "wallet_keys": "Wallet seed/keys",
866 "wallet_list_create_new_wallet": "Lumikha ng bagong wallet",
867 + "wallet_list_edit_group_name": "I -edit ang Pangalan ng Grupo",
868 "wallet_list_edit_wallet": "I-edit ang wallet",
869 "wallet_list_failed_to_load": "Nabigong na-load ang ${wallet_name} na wallet. ${error}",
870 "wallet_list_failed_to_remove": "Nabigong alisin ang ${wallet_name} wallet. ${error}",
res/values/strings_tr.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "Birini seç",
131 "choose_relay": "Lütfen kullanmak için bir röle seçin",
132 "choose_wallet_currency": "Lütfen cüzdanın para birimini seç:",
133 + "choose_wallet_group": "Cüzdan Grubu Seçin",
134 "clear": "Temizle",
135 "clearnet_link": "Net bağlantı",
136 "close": "Kapalı",
@@ -176,6 +177,7 @@
177 "create_invoice": "Fatura oluşturmak",
178 "create_new": "Yeni Cüzdan Oluştur",
179 "create_new_account": "Yeni hesap oluştur",
180 + "create_new_seed": "Yeni Tohum Oluştur",
181 "creating_new_wallet": "Cüzdan oluşturuluyor",
182 "creating_new_wallet_error": "Hata: ${description}",
183 "creation_date": "Oluşturulma tarihi",
@@ -600,6 +602,8 @@
602 "seed_share": "Tohumu paylaş",
603 "seed_title": "Tohum",
604 "seedtype": "Tohum",
605 + "seedtype_alert_content": "Tohumları diğer cüzdanlarla paylaşmak sadece BIP39 tohumu ile mümkündür.",
606 + "seedtype_alert_title": "SeedType uyarısı",
607 "seedtype_legacy": "Miras (25 kelime)",
608 "seedtype_polyseed": "Polyseed (16 kelime)",
609 "select_backup_file": "Yedek dosyası seç",
@@ -666,6 +670,7 @@
670 "setup_your_debit_card": "Banka kartını ayarla",
671 "share": "Paylaşmak",
672 "share_address": "Adresi paylaş",
673 + "shared_seed_wallet_groups": "Paylaşılan tohum cüzdan grupları",
674 "show_details": "Detayları Göster",
675 "show_keys": "Tohumları/anahtarları göster",
676 "show_market_place": "Pazar Yerini Göster",
@@ -690,6 +695,7 @@
695 "silent_payments_scanned_tip": "Bahşiş için tarandı! (${tip})",
696 "silent_payments_scanning": "Sessiz Ödemeler Taraması",
697 "silent_payments_settings": "Sessiz Ödeme Ayarları",
698 + "single_seed_wallets_group": "Tek tohum cüzdanları",
699 "slidable": "kaydırılabilir",
700 "sort_by": "Göre sırala",
701 "spend_key_private": "Harcama anahtarı (özel)",
@@ -849,8 +855,16 @@
855 "view_transaction_on": "İşlemi şurada görüntüle ",
856 "voting_weight": "Oy kullanma",
857 "waitFewSecondForTxUpdate": "İşlemin işlem geçmişine yansıması için lütfen birkaç saniye bekleyin",
858 + "wallet_group": "Cüzdan grubu",
859 + "wallet_group_description_four": "Tamamen yeni bir tohumla bir cüzdan oluşturmak için.",
860 + "wallet_group_description_one": "Kek cüzdanında bir",
861 + "wallet_group_description_three": "Mevcut cüzdan ve/veya cüzdan grupları ekranını görmek için. Veya seç",
862 + "wallet_group_description_two": "Bir tohumu paylaşmak için mevcut bir cüzdan seçerek. Her cüzdan grubu, her para türünün tek bir cüzdanı içerebilir. \n\n Seçebilirsiniz",
863 + "wallet_group_empty_state_text_one": "Herhangi bir uyumlu cüzdan grubunuz yok gibi görünüyor !\n\n TAP",
864 + "wallet_group_empty_state_text_two": "Yeni bir tane yapmak için aşağıda.",
865 "wallet_keys": "Cüzdan tohumu/anahtarları",
866 "wallet_list_create_new_wallet": "Yeni Cüzdan Oluştur",
867 + "wallet_list_edit_group_name": "Grup Adını Düzenle",
868 "wallet_list_edit_wallet": "Cüzdanı düzenle",
869 "wallet_list_failed_to_load": "Failed to load ${wallet_name} wallet. ${error}",
870 "wallet_list_failed_to_remove": "${wallet_name} cüzdanı yüklenirken hata oluştu. ${error}",
res/values/strings_uk.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "Вибери один",
131 "choose_relay": "Будь ласка, виберіть реле для використання",
132 "choose_wallet_currency": "Будь ласка, виберіть валюту гаманця:",
133 + "choose_wallet_group": "Виберіть групу гаманця",
134 "clear": "Очистити",
135 "clearnet_link": "Посилання Clearnet",
136 "close": "Закрити",
@@ -176,6 +177,7 @@
177 "create_invoice": "Створити рахунок-фактуру",
178 "create_new": "Створити новий гаманець",
179 "create_new_account": "Створити новий акаунт",
180 + "create_new_seed": "Створіть нове насіння",
181 "creating_new_wallet": "Створення нового гаманця",
182 "creating_new_wallet_error": "Помилка: ${description}",
183 "creation_date": "Дата створення",
@@ -601,6 +603,8 @@
603 "seed_share": "Поділитися мнемонічною фразою",
604 "seed_title": "Мнемонічна фраза",
605 "seedtype": "Насіннєвий тип",
606 + "seedtype_alert_content": "Спільний доступ до інших гаманців можливе лише за допомогою BIP39 Seedtype.",
607 + "seedtype_alert_title": "Попередження насінника",
608 "seedtype_legacy": "Спадщина (25 слів)",
609 "seedtype_polyseed": "Полісей (16 слів)",
610 "select_backup_file": "Виберіть файл резервної копії",
@@ -667,6 +671,7 @@
671 "setup_your_debit_card": "Налаштуйте свою дебетову картку",
672 "share": "Поділіться",
673 "share_address": "Поділитися адресою",
674 + "shared_seed_wallet_groups": "Спільні групи насіннєвих гаманців",
675 "show_details": "Показати деталі",
676 "show_keys": "Показати мнемонічну фразу/ключі",
677 "show_market_place": "Відображати маркетплейс",
@@ -691,6 +696,7 @@
696 "silent_payments_scanned_tip": "Сканований на підказку! (${tip})",
697 "silent_payments_scanning": "Мовчазні платежі сканування",
698 "silent_payments_settings": "Налаштування мовчазних платежів",
699 + "single_seed_wallets_group": "Поодинокі насінні гаманці",
700 "slidable": "Розсувний",
701 "sort_by": "Сортувати за",
702 "spend_key_private": "Приватний ключ витрати",
@@ -850,8 +856,16 @@
856 "view_transaction_on": "View Transaction on ",
857 "voting_weight": "Вага голосування",
858 "waitFewSecondForTxUpdate": "Будь ласка, зачекайте кілька секунд, поки транзакція відобразиться в історії транзакцій",
859 + "wallet_group": "Група гаманців",
860 + "wallet_group_description_four": "створити гаманець з абсолютно новим насінням.",
861 + "wallet_group_description_one": "У гаманці тортів ви можете створити a",
862 + "wallet_group_description_three": "Щоб побачити наявні гаманці та/або екран групи гаманців. Або вибрати",
863 + "wallet_group_description_two": "Вибираючи існуючий гаманець, щоб поділитися насінням. Кожна група гаманця може містити один гаманець кожного типу валюти. \n\n Ви можете вибрати",
864 + "wallet_group_empty_state_text_one": "Схоже, у вас немає сумісних груп гаманця !\n\n Торкніться",
865 + "wallet_group_empty_state_text_two": "нижче, щоб зробити новий.",
866 "wallet_keys": "Мнемонічна фраза/ключі гаманця",
867 "wallet_list_create_new_wallet": "Створити новий гаманець",
868 + "wallet_list_edit_group_name": "Назва групи редагування",
869 "wallet_list_edit_wallet": "Редагувати гаманець",
870 "wallet_list_failed_to_load": "Помилка при завантаженні ${wallet_name} гаманця. ${error}",
871 "wallet_list_failed_to_remove": "Помилка при видаленні ${wallet_name} гаманця. ${error}",
res/values/strings_ur.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "ایک کا انتخاب کریں",
131 "choose_relay": "۔ﮟﯾﺮﮐ ﺏﺎﺨﺘﻧﺍ ﺎﮐ ﮯﻠﯾﺭ ﮯﯿﻟ ﮯﮐ ﮯﻧﺮﮐ ﻝﺎﻤﻌﺘﺳﺍ ﻡﺮﮐ ﮦﺍﺮﺑ",
132 "choose_wallet_currency": "براہ کرم والیٹ کرنسی کا انتخاب کریں:",
133 + "choose_wallet_group": "پرس گروپ کا انتخاب کریں",
134 "clear": "صاف",
135 "clearnet_link": "کلیرنیٹ لنک",
136 "close": "بند کریں",
@@ -176,6 +177,7 @@
177 "create_invoice": "انوائس بنائیں",
178 "create_new": "نیا والیٹ بنائیں",
179 "create_new_account": "نیا اکاؤنٹ بنانے",
180 + "create_new_seed": "نیا بیج بنائیں",
181 "creating_new_wallet": "نیا پرس بنانا",
182 "creating_new_wallet_error": "خرابی: ${description}",
183 "creation_date": "بنانے کی تاریخ",
@@ -602,6 +604,8 @@
604 "seed_share": "بیج بانٹیں۔",
605 "seed_title": "بیج",
606 "seedtype": "سیڈ ٹائپ",
607 + "seedtype_alert_content": "دوسرے بٹوے کے ساتھ بیجوں کا اشتراک صرف BIP39 بیج ٹائپ کے ساتھ ہی ممکن ہے۔",
608 + "seedtype_alert_title": "سیڈ ٹائپ الرٹ",
609 "seedtype_legacy": "میراث (25 الفاظ)",
610 "seedtype_polyseed": "پالیسیڈ (16 الفاظ)",
611 "select_backup_file": "بیک اپ فائل کو منتخب کریں۔",
@@ -668,6 +672,7 @@
672 "setup_your_debit_card": "اپنا ڈیبٹ کارڈ ترتیب دیں۔",
673 "share": "بانٹیں",
674 "share_address": "پتہ شیئر کریں۔",
675 + "shared_seed_wallet_groups": "مشترکہ بیج پرس گروپ",
676 "show_details": "تفصیلات دکھائیں",
677 "show_keys": "بیج / چابیاں دکھائیں۔",
678 "show_market_place": "بازار دکھائیں۔",
@@ -692,6 +697,7 @@
697 "silent_payments_scanned_tip": "نوکنے کے لئے اسکین! (${tip})",
698 "silent_payments_scanning": "خاموش ادائیگی اسکیننگ",
699 "silent_payments_settings": "خاموش ادائیگی کی ترتیبات",
700 + "single_seed_wallets_group": "سنگل بیج کے بٹوے",
701 "slidable": "سلائیڈ ایبل",
702 "sort_by": "ترتیب دیں",
703 "spend_key_private": "خرچ کی کلید (نجی)",
@@ -851,8 +857,16 @@
857 "view_transaction_on": "لین دین دیکھیں آن",
858 "voting_weight": "ووٹ کا وزن",
859 "waitFewSecondForTxUpdate": "۔ﮟﯾﺮﮐ ﺭﺎﻈﺘﻧﺍ ﺎﮐ ﮉﻨﮑﯿﺳ ﺪﻨﭼ ﻡﺮﮐ ﮦﺍﺮﺑ ﮯﯿﻟ ﮯﮐ ﮯﻧﺮﮐ ﯽﺳﺎﮑﻋ ﯽﮐ ﻦﯾﺩ ﻦﯿﻟ ﮟﯿﻣ ﺦﯾﺭﺎﺗ ﯽﮐ ﻦ",
860 + "wallet_group": "پرس گروپ",
861 + "wallet_group_description_four": "مکمل طور پر نئے بیج کے ساتھ پرس بنانے کے ل.",
862 + "wallet_group_description_one": "کیک پرس میں ، آپ بنا سکتے ہیں",
863 + "wallet_group_description_three": "دستیاب بٹوے اور/یا پرس گروپوں کی اسکرین کو دیکھنے کے لئے۔ یا منتخب کریں",
864 + "wallet_group_description_two": "بیج کے ساتھ بانٹنے کے لئے موجودہ پرس کا انتخاب کرکے۔ ہر بٹوے گروپ میں ہر کرنسی کی قسم کا ایک بٹوے شامل ہوسکتا ہے۔ \n\n آپ منتخب کرسکتے ہیں",
865 + "wallet_group_empty_state_text_one": "ایسا لگتا ہے کہ آپ کے پاس کوئی مطابقت پذیر والیٹ گروپس نہیں ہیں !\n\n نل",
866 + "wallet_group_empty_state_text_two": "ایک نیا بنانے کے لئے ذیل میں.",
867 "wallet_keys": "بٹوے کے بیج / چابیاں",
868 "wallet_list_create_new_wallet": "نیا والیٹ بنائیں",
869 + "wallet_list_edit_group_name": "گروپ کے نام میں ترمیم کریں",
870 "wallet_list_edit_wallet": "بٹوے میں ترمیم کریں۔",
871 "wallet_list_failed_to_load": "${wallet_name} والیٹ لوڈ کرنے میں ناکام۔ ${error}",
872 "wallet_list_failed_to_remove": "${wallet_name} والیٹ کو ہٹانے میں ناکام۔ ${error}",
res/values/strings_vi.arb
+8
@@ -130,6 +130,7 @@
130 "choose_one": "Chọn một",
131 "choose_relay": "Vui lòng chọn một relay để sử dụng",
132 "choose_wallet_currency": "Vui lòng chọn tiền tệ của ví:",
133 + "choose_wallet_group": "Chọn nhóm ví",
134 "clear": "Xóa",
135 "clearnet_link": "Liên kết Clearnet",
136 "close": "Đóng",
@@ -175,6 +176,7 @@
176 "create_invoice": "Tạo hóa đơn",
177 "create_new": "Tạo Ví Mới",
178 "create_new_account": "Tạo tài khoản mới",
179 + "create_new_seed": "Tạo hạt giống mới",
180 "creating_new_wallet": "Đang tạo ví mới",
181 "creating_new_wallet_error": "Lỗi: ${description}",
182 "creation_date": "Ngày Tạo",
@@ -844,6 +846,12 @@
846 "view_transaction_on": "Xem giao dịch trên",
847 "voting_weight": "Trọng số bỏ phiếu",
848 "waitFewSecondForTxUpdate": "Vui lòng đợi vài giây để giao dịch được phản ánh trong lịch sử giao dịch",
849 + "wallet_group_description_four": "Để tạo ra một ví với một hạt giống hoàn toàn mới.",
850 + "wallet_group_description_one": "Trong ví bánh, bạn có thể tạo",
851 + "wallet_group_description_three": "Để xem ví trên ví và/hoặc màn hình nhóm ví. Hoặc chọn",
852 + "wallet_group_description_two": "Bằng cách chọn một ví hiện có để chia sẻ một hạt giống với. Mỗi nhóm ví có thể chứa một ví của mỗi loại tiền tệ. \n\n Bạn có thể chọn",
853 + "wallet_group_empty_state_text_one": "Có vẻ như bạn không có bất kỳ nhóm ví tương thích nào !\n\n Tap",
854 + "wallet_group_empty_state_text_two": "Dưới đây để làm một cái mới.",
855 "wallet_keys": "Hạt giống/khóa ví",
856 "wallet_list_create_new_wallet": "Tạo ví mới",
857 "wallet_list_edit_wallet": "Chỉnh sửa ví",
res/values/strings_yo.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "Ẹ yàn kan",
131 "choose_relay": "Jọwọ yan yii lati lo",
132 "choose_wallet_currency": "Ẹ jọ̀wọ́, yàn irú owó ti àpamọ́wọ́ yín:",
133 + "choose_wallet_group": "Yan ẹgbẹ ogiri",
134 "clear": "Pa gbogbo nǹkan",
135 "clearnet_link": "Kọja ilọ oke",
136 "close": "sunmo",
@@ -176,6 +177,7 @@
177 "create_invoice": "Ṣe iwe iwe",
178 "create_new": "Dá àpamọ́wọ́ tuntun",
179 "create_new_account": "Dá àkáǹtì títun",
180 + "create_new_seed": "Ṣẹda irugbin tuntun",
181 "creating_new_wallet": "Ń dá àpamọ́wọ́ títun",
182 "creating_new_wallet_error": "Àṣìṣe: ${description}",
183 "creation_date": "Ọjọ ẹda",
@@ -601,6 +603,8 @@
603 "seed_share": "Pín hóró",
604 "seed_title": "Hóró",
605 "seedtype": "Irugbin-seetypu",
606 + "seedtype_alert_content": "Pinpin awọn irugbin pẹlu awọn gedo miiran ṣee ṣe pẹlu Bip39 irugbin.",
607 + "seedtype_alert_title": "Ṣajọpọ Seeytype",
608 "seedtype_legacy": "Legacy (awọn ọrọ 25)",
609 "seedtype_polyseed": "Polyseed (awọn ọrọ 16)",
610 "select_backup_file": "Select backup file",
@@ -667,6 +671,7 @@
671 "setup_your_debit_card": "Dá àwọn káàdì ìrajà yín",
672 "share": "Pinpin",
673 "share_address": "Pín àdírẹ́sì",
674 + "shared_seed_wallet_groups": "Awọn ẹgbẹ ti a pin irugbin",
675 "show_details": "Fi ìsọfúnni kékeré hàn",
676 "show_keys": "Wo hóró / àwọn kọ́kọ́rọ́",
677 "show_market_place": "Wa Sopọ Pataki",
@@ -691,6 +696,7 @@
696 "silent_payments_scanned_tip": "Ṣayẹwo si sample! (${tip})",
697 "silent_payments_scanning": "Awọn sisanwo ipalọlọ",
698 "silent_payments_settings": "Awọn eto isanwo ti o dakẹ",
699 + "single_seed_wallets_group": "Awọn Wowei Awọn gige",
700 "slidable": "Slidable",
701 "sort_by": "Sa pelu",
702 "spend_key_private": "Kọ́kọ́rọ́ sísan (àdáni)",
@@ -850,8 +856,16 @@
856 "view_transaction_on": "Wo pàṣípààrọ̀ lórí ",
857 "voting_weight": "Idibo iwuwo",
858 "waitFewSecondForTxUpdate": "Fi inurere duro fun awọn iṣeju diẹ fun idunadura lati ṣe afihan ninu itan-akọọlẹ iṣowo",
859 + "wallet_group": "Ẹgbẹ apamọwọ",
860 + "wallet_group_description_four": "Lati ṣẹda apamọwọ kan pẹlu irugbin tuntun tuntun.",
861 + "wallet_group_description_one": "Ni apamọwọ akara oyinbo, o le ṣẹda a",
862 + "wallet_group_description_three": "Lati wo awọn Woleti ti o wa ati / tabi Iboju Wallt. Tabi yan",
863 + "wallet_group_description_two": "nipa yiyan apamọwọ ti o wa tẹlẹ lati pin irugbin kan pẹlu. Ẹgbẹ apamọwọ kọọkan le ni apamọwọ kan ti iru owo kọọkan. \n\n O le yan",
864 + "wallet_group_empty_state_text_one": "O dabi pe o ko ni eyikeyi awọn ẹgbẹ ti o ni ibamu!\n\ntẹ ni kia kia",
865 + "wallet_group_empty_state_text_two": "ni isalẹ lati ṣe ọkan titun.",
866 "wallet_keys": "Hóró/kọ́kọ́rọ́ àpamọ́wọ́",
867 "wallet_list_create_new_wallet": "Ṣe àpamọ́wọ́ títun",
868 + "wallet_list_edit_group_name": "Ṣatunṣe Orukọ Ẹgbẹ",
869 "wallet_list_edit_wallet": "Ṣatunkọ apamọwọ",
870 "wallet_list_failed_to_load": "Ti kùnà ṣí́ àpamọ́wọ́ ${wallet_name}. ${error}",
871 "wallet_list_failed_to_remove": "Ti kùnà yọ ${wallet_name} àpamọ́wọ́ kúrò. ${error}",
res/values/strings_zh.arb
+14
@@ -130,6 +130,7 @@
130 "choose_one": "选一个",
131 "choose_relay": "请选择要使用的继电器",
132 "choose_wallet_currency": "请选择钱包货币:",
133 + "choose_wallet_group": "选择钱包组",
134 "clear": "清空",
135 "clearnet_link": "明网链接",
136 "close": "关闭",
@@ -176,6 +177,7 @@
177 "create_invoice": "创建发票",
178 "create_new": "创建新钱包",
179 "create_new_account": "建立新账户",
180 + "create_new_seed": "创建新种子",
181 "creating_new_wallet": "创建新钱包",
182 "creating_new_wallet_error": "错误: ${description}",
183 "creation_date": "创建日期",
@@ -600,6 +602,8 @@
602 "seed_share": "分享种子",
603 "seed_title": "种子",
604 "seedtype": "籽粒",
605 + "seedtype_alert_content": "只有BIP39籽粒可以与其他钱包共享种子。",
606 + "seedtype_alert_title": "籽粒警报",
607 "seedtype_legacy": "遗产(25个单词)",
608 "seedtype_polyseed": "多种物品(16个单词)",
609 "select_backup_file": "选择备份文件",
@@ -666,6 +670,7 @@
670 "setup_your_debit_card": "设置你的借记卡",
671 "share": "分享",
672 "share_address": "分享地址",
673 + "shared_seed_wallet_groups": "共享种子钱包组",
674 "show_details": "显示详细信息",
675 "show_keys": "显示种子/密钥",
676 "show_market_place": "显示市场",
@@ -690,6 +695,7 @@
695 "silent_payments_scanned_tip": "扫描到小费! (${tip})",
696 "silent_payments_scanning": "无声付款扫描",
697 "silent_payments_settings": "无声付款设置",
698 + "single_seed_wallets_group": "单个种子钱包",
699 "slidable": "可滑动",
700 "sort_by": "排序方式",
701 "spend_key_private": "Spend 密钥 (私钥)",
@@ -849,8 +855,16 @@
855 "view_transaction_on": "View Transaction on ",
856 "voting_weight": "投票权重",
857 "waitFewSecondForTxUpdate": "请等待几秒钟,交易才会反映在交易历史记录中",
858 + "wallet_group": "钱包组",
859 + "wallet_group_description_four": "创建一个带有全新种子的钱包。",
860 + "wallet_group_description_one": "在蛋糕钱包中,您可以创建一个",
861 + "wallet_group_description_three": "查看可用的钱包和/或钱包组屏幕。或选择",
862 + "wallet_group_description_two": "通过选择现有的钱包与种子共享。每个钱包组都可以包含每种货币类型的单个钱包。\n\n您可以选择",
863 + "wallet_group_empty_state_text_one": "看起来您没有任何兼容的钱包组!\n\n tap",
864 + "wallet_group_empty_state_text_two": "下面是一个新的。",
865 "wallet_keys": "钱包种子/密钥",
866 "wallet_list_create_new_wallet": "创建新钱包",
867 + "wallet_list_edit_group_name": "编辑组名称",
868 "wallet_list_edit_wallet": "编辑钱包",
869 "wallet_list_failed_to_load": "加载失败 ${wallet_name} 钱包. ${error}",
870 "wallet_list_failed_to_remove": "删除失败 ${wallet_name} 钱包. ${error}",
tool/configure.dart
+11 -7
@@ -151,7 +151,7 @@ abstract class Bitcoin {
151 String? passphrase,
152 });
153 WalletCredentials createBitcoinRestoreWalletFromWIFCredentials({required String name, required String password, required String wif, WalletInfo? walletInfo});
154 - WalletCredentials createBitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? passphrase});
154 + WalletCredentials createBitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? passphrase, String? mnemonic, String? parentAddress});
155 WalletCredentials createBitcoinHardwareWalletCredentials({required String name, required HardwareAccountData accountData, WalletInfo? walletInfo});
156 List<String> getWordList();
157 Map<String, String> getWalletKeys(Object wallet);
@@ -558,7 +558,7 @@ abstract class Wownero {
558 required String language,
559 required int height});
560 WalletCredentials createWowneroRestoreWalletFromSeedCredentials({required String name, required String password, required int height, required String mnemonic});
561 - WalletCredentials createWowneroNewWalletCredentials({required String name, required String language, required bool isPolyseed, String password});
561 + WalletCredentials createWowneroNewWalletCredentials({required String name, required String language, required bool isPolyseed, String? password});
562 Map<String, String> getKeys(Object wallet);
563 Object createWowneroTransactionCreationCredentials({required List<Output> outputs, required TransactionPriority priority});
564 Object createWowneroTransactionCreationCredentialsRaw({required List<OutputInfo> outputs, required TransactionPriority priority});
@@ -833,7 +833,7 @@ import 'package:eth_sig_util/util/utils.dart';
833 abstract class Ethereum {
834 List<String> getEthereumWordList(String language);
835 WalletService createEthereumWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
836 - WalletCredentials createEthereumNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password});
836 + WalletCredentials createEthereumNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? parentAddress});
837 WalletCredentials createEthereumRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password});
838 WalletCredentials createEthereumRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password});
839 WalletCredentials createEthereumHardwareWalletCredentials({required String name, required HardwareAccountData hwAccountData, WalletInfo? walletInfo});
@@ -937,7 +937,7 @@ import 'package:eth_sig_util/util/utils.dart';
937 abstract class Polygon {
938 List<String> getPolygonWordList(String language);
939 WalletService createPolygonWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
940 - WalletCredentials createPolygonNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password});
940 + WalletCredentials createPolygonNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? parentAddress});
941 WalletCredentials createPolygonRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password});
942 WalletCredentials createPolygonRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password});
943 WalletCredentials createPolygonHardwareWalletCredentials({required String name, required HardwareAccountData hwAccountData, WalletInfo? walletInfo});
@@ -1024,7 +1024,7 @@ abstract class BitcoinCash {
1024 Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect);
1025
1026 WalletCredentials createBitcoinCashNewWalletCredentials(
1027 - {required String name, WalletInfo? walletInfo, String? password, String? passphrase});
1027 + {required String name, WalletInfo? walletInfo, String? password, String? passphrase, String? mnemonic, String? parentAddress});
1028
1029 WalletCredentials createBitcoinCashRestoreWalletFromSeedCredentials(
1030 {required String name, required String mnemonic, required String password, String? passphrase});
@@ -1106,6 +1106,9 @@ abstract class Nano {
1106 WalletCredentials createNanoNewWalletCredentials({
1107 required String name,
1108 String? password,
1109 + String? mnemonic,
1110 + String? parentAddress,
1111 + WalletInfo? walletInfo,
1112 });
1113
1114 WalletCredentials createNanoRestoreWalletFromSeedCredentials({
@@ -1221,7 +1224,7 @@ abstract class Solana {
1224 List<String> getSolanaWordList(String language);
1225 WalletService createSolanaWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
1226 WalletCredentials createSolanaNewWalletCredentials(
1224 - {required String name, WalletInfo? walletInfo, String? password});
1227 + {required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? parentAddress,});
1228 WalletCredentials createSolanaRestoreWalletFromSeedCredentials(
1229 {required String name, required String mnemonic, required String password});
1230 WalletCredentials createSolanaRestoreWalletFromPrivateKey(
@@ -1307,7 +1310,8 @@ import 'package:cw_tron/tron_wallet_service.dart';
1310 abstract class Tron {
1311 List<String> getTronWordList(String language);
1312 WalletService createTronWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
1310 - WalletCredentials createTronNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password});
1313 + WalletCredentials createTronNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic,
1314 + String? parentAddress});
1315 WalletCredentials createTronRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password});
1316 WalletCredentials createTronRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password});
1317 String getAddress(WalletBase wallet);