mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-06-28 12:29:51 +00:00
CW-843: Enhance Wallet Groups Implementation (#2045)
* feat: Enhance Wallet Groups Implementation by using hashedIdentifiers instead of parentAddresses * fix: Call updateWalletGroups even if group has an hash identifier * feat: Add secrets to workflow * feat: Enhance Wallet Groups Implementation by using hashedIdentifiers instead of parentAddresses * Handle wallet grouping edgecase where wallet is restored via non seed medium * fix: Valid wallet/wallet groups not showing up when choosing wallet/groups for creating new wallets
This commit is contained in:
parent
e596c19b40
commit
09f20b2a7b
35 changed files with 181 additions and 123 deletions
|
@ -223,6 +223,10 @@ jobs:
|
||||||
echo "const nanoTestWalletReceiveAddress = '${{ secrets.NANO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
|
echo "const nanoTestWalletReceiveAddress = '${{ secrets.NANO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
|
||||||
echo "const wowneroTestWalletReceiveAddress = '${{ secrets.WOWNERO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
|
echo "const wowneroTestWalletReceiveAddress = '${{ secrets.WOWNERO_TEST_WALLET_RECEIVE_ADDRESS }}';" >> lib/.secrets.g.dart
|
||||||
echo "const moneroTestWalletBlockHeight = '${{ secrets.MONERO_TEST_WALLET_BLOCK_HEIGHT }}';" >> lib/.secrets.g.dart
|
echo "const moneroTestWalletBlockHeight = '${{ secrets.MONERO_TEST_WALLET_BLOCK_HEIGHT }}';" >> lib/.secrets.g.dart
|
||||||
|
# end of test secrets
|
||||||
|
echo "const chainflipApiKey = '${{ secrets.CHAINFLIP_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const chainflipAffiliateFee = '${{ secrets.CHAINFLIP_AFFILIATE_FEE }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const walletGroupSalt = '${{ secrets.WALLET_GROUP_SALT }}';" >> lib/.secrets.g.dart
|
||||||
|
|
||||||
- name: Rename app
|
- name: Rename app
|
||||||
run: |
|
run: |
|
||||||
|
|
1
.github/workflows/pr_test_build_android.yml
vendored
1
.github/workflows/pr_test_build_android.yml
vendored
|
@ -172,6 +172,7 @@ jobs:
|
||||||
# end of test secrets
|
# end of test secrets
|
||||||
echo "const chainflipApiKey = '${{ secrets.CHAINFLIP_API_KEY }}';" >> lib/.secrets.g.dart
|
echo "const chainflipApiKey = '${{ secrets.CHAINFLIP_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
echo "const chainflipAffiliateFee = '${{ secrets.CHAINFLIP_AFFILIATE_FEE }}';" >> lib/.secrets.g.dart
|
echo "const chainflipAffiliateFee = '${{ secrets.CHAINFLIP_AFFILIATE_FEE }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const walletGroupSalt = '${{ secrets.WALLET_GROUP_SALT }}';" >> lib/.secrets.g.dart
|
||||||
|
|
||||||
- name: prepare monero_c and cache
|
- name: prepare monero_c and cache
|
||||||
run: |
|
run: |
|
||||||
|
|
1
.github/workflows/pr_test_build_linux.yml
vendored
1
.github/workflows/pr_test_build_linux.yml
vendored
|
@ -168,6 +168,7 @@ jobs:
|
||||||
# end of test secrets
|
# end of test secrets
|
||||||
echo "const chainflipApiKey = '${{ secrets.CHAINFLIP_API_KEY }}';" >> lib/.secrets.g.dart
|
echo "const chainflipApiKey = '${{ secrets.CHAINFLIP_API_KEY }}';" >> lib/.secrets.g.dart
|
||||||
echo "const chainflipAffiliateFee = '${{ secrets.CHAINFLIP_AFFILIATE_FEE }}';" >> lib/.secrets.g.dart
|
echo "const chainflipAffiliateFee = '${{ secrets.CHAINFLIP_AFFILIATE_FEE }}';" >> lib/.secrets.g.dart
|
||||||
|
echo "const walletGroupSalt = '${{ secrets.WALLET_GROUP_SALT }}';" >> lib/.secrets.g.dart
|
||||||
|
|
||||||
- name: prepare monero_c and cache
|
- name: prepare monero_c and cache
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -11,13 +11,11 @@ class BitcoinNewWalletCredentials extends WalletCredentials {
|
||||||
String? derivationPath,
|
String? derivationPath,
|
||||||
String? passphrase,
|
String? passphrase,
|
||||||
this.mnemonic,
|
this.mnemonic,
|
||||||
String? parentAddress,
|
|
||||||
}) : super(
|
}) : super(
|
||||||
name: name,
|
name: name,
|
||||||
walletInfo: walletInfo,
|
walletInfo: walletInfo,
|
||||||
password: password,
|
password: password,
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
parentAddress: parentAddress,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
final String? mnemonic;
|
final String? mnemonic;
|
||||||
|
|
|
@ -8,13 +8,11 @@ class BitcoinCashNewWalletCredentials extends WalletCredentials {
|
||||||
String? password,
|
String? password,
|
||||||
String? passphrase,
|
String? passphrase,
|
||||||
this.mnemonic,
|
this.mnemonic,
|
||||||
String? parentAddress,
|
|
||||||
}) : super(
|
}) : super(
|
||||||
name: name,
|
name: name,
|
||||||
walletInfo: walletInfo,
|
walletInfo: walletInfo,
|
||||||
password: password,
|
password: password,
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
parentAddress: parentAddress
|
|
||||||
);
|
);
|
||||||
final String? mnemonic;
|
final String? mnemonic;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ abstract class WalletCredentials {
|
||||||
this.passphrase,
|
this.passphrase,
|
||||||
this.derivationInfo,
|
this.derivationInfo,
|
||||||
this.hardwareWalletType,
|
this.hardwareWalletType,
|
||||||
this.parentAddress,
|
|
||||||
}) {
|
}) {
|
||||||
if (this.walletInfo != null && derivationInfo != null) {
|
if (this.walletInfo != null && derivationInfo != null) {
|
||||||
this.walletInfo!.derivationInfo = derivationInfo;
|
this.walletInfo!.derivationInfo = derivationInfo;
|
||||||
|
@ -19,7 +18,6 @@ abstract class WalletCredentials {
|
||||||
|
|
||||||
final String name;
|
final String name;
|
||||||
final int? height;
|
final int? height;
|
||||||
String? parentAddress;
|
|
||||||
int? seedPhraseLength;
|
int? seedPhraseLength;
|
||||||
String? password;
|
String? password;
|
||||||
String? passphrase;
|
String? passphrase;
|
||||||
|
|
|
@ -81,6 +81,8 @@ class WalletInfo extends HiveObject {
|
||||||
this.derivationInfo,
|
this.derivationInfo,
|
||||||
this.hardwareWalletType,
|
this.hardwareWalletType,
|
||||||
this.parentAddress,
|
this.parentAddress,
|
||||||
|
this.hashedWalletIdentifier,
|
||||||
|
this.isNonSeedWallet,
|
||||||
) : _yatLastUsedAddressController = StreamController<String>.broadcast();
|
) : _yatLastUsedAddressController = StreamController<String>.broadcast();
|
||||||
|
|
||||||
factory WalletInfo.external({
|
factory WalletInfo.external({
|
||||||
|
@ -99,6 +101,8 @@ class WalletInfo extends HiveObject {
|
||||||
DerivationInfo? derivationInfo,
|
DerivationInfo? derivationInfo,
|
||||||
HardwareWalletType? hardwareWalletType,
|
HardwareWalletType? hardwareWalletType,
|
||||||
String? parentAddress,
|
String? parentAddress,
|
||||||
|
String? hashedWalletIdentifier,
|
||||||
|
bool? isNonSeedWallet,
|
||||||
}) {
|
}) {
|
||||||
return WalletInfo(
|
return WalletInfo(
|
||||||
id,
|
id,
|
||||||
|
@ -116,6 +120,8 @@ class WalletInfo extends HiveObject {
|
||||||
derivationInfo,
|
derivationInfo,
|
||||||
hardwareWalletType,
|
hardwareWalletType,
|
||||||
parentAddress,
|
parentAddress,
|
||||||
|
hashedWalletIdentifier,
|
||||||
|
isNonSeedWallet ?? false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,8 +202,11 @@ class WalletInfo extends HiveObject {
|
||||||
@HiveField(24)
|
@HiveField(24)
|
||||||
List<String>? manualAddresses;
|
List<String>? manualAddresses;
|
||||||
|
|
||||||
|
@HiveField(25)
|
||||||
|
String? hashedWalletIdentifier;
|
||||||
|
|
||||||
|
@HiveField(26, defaultValue: false)
|
||||||
|
bool isNonSeedWallet;
|
||||||
|
|
||||||
String get yatLastUsedAddress => yatLastUsedAddressRaw ?? '';
|
String get yatLastUsedAddress => yatLastUsedAddressRaw ?? '';
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ class EVMChainNewWalletCredentials extends WalletCredentials {
|
||||||
required super.name,
|
required super.name,
|
||||||
super.walletInfo,
|
super.walletInfo,
|
||||||
super.password,
|
super.password,
|
||||||
super.parentAddress,
|
|
||||||
this.mnemonic,
|
this.mnemonic,
|
||||||
super.passphrase,
|
super.passphrase,
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,13 +8,11 @@ class NanoNewWalletCredentials extends WalletCredentials {
|
||||||
String? password,
|
String? password,
|
||||||
DerivationType? derivationType,
|
DerivationType? derivationType,
|
||||||
this.mnemonic,
|
this.mnemonic,
|
||||||
String? parentAddress,
|
|
||||||
String? passphrase,
|
String? passphrase,
|
||||||
}) : super(
|
}) : super(
|
||||||
name: name,
|
name: name,
|
||||||
password: password,
|
password: password,
|
||||||
walletInfo: walletInfo,
|
walletInfo: walletInfo,
|
||||||
parentAddress: parentAddress,
|
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -6,14 +6,12 @@ class SolanaNewWalletCredentials extends WalletCredentials {
|
||||||
required String name,
|
required String name,
|
||||||
WalletInfo? walletInfo,
|
WalletInfo? walletInfo,
|
||||||
String? password,
|
String? password,
|
||||||
String? parentAddress,
|
|
||||||
this.mnemonic,
|
this.mnemonic,
|
||||||
String? passphrase,
|
String? passphrase,
|
||||||
}) : super(
|
}) : super(
|
||||||
name: name,
|
name: name,
|
||||||
walletInfo: walletInfo,
|
walletInfo: walletInfo,
|
||||||
password: password,
|
password: password,
|
||||||
parentAddress: parentAddress,
|
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
);
|
);
|
||||||
final String? mnemonic;
|
final String? mnemonic;
|
||||||
|
|
|
@ -7,13 +7,11 @@ class TronNewWalletCredentials extends WalletCredentials {
|
||||||
WalletInfo? walletInfo,
|
WalletInfo? walletInfo,
|
||||||
String? password,
|
String? password,
|
||||||
this.mnemonic,
|
this.mnemonic,
|
||||||
String? parentAddress,
|
|
||||||
String? passphrase,
|
String? passphrase,
|
||||||
}) : super(
|
}) : super(
|
||||||
name: name,
|
name: name,
|
||||||
walletInfo: walletInfo,
|
walletInfo: walletInfo,
|
||||||
password: password,
|
password: password,
|
||||||
parentAddress: parentAddress,
|
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -277,4 +277,4 @@ SPEC CHECKSUMS:
|
||||||
|
|
||||||
PODFILE CHECKSUM: e448f662d4c41f0c0b1ccbb78afd57dbf895a597
|
PODFILE CHECKSUM: e448f662d4c41f0c0b1ccbb78afd57dbf895a597
|
||||||
|
|
||||||
COCOAPODS: 1.15.2
|
COCOAPODS: 1.15.2
|
|
@ -34,7 +34,6 @@ class CWBitcoin extends Bitcoin {
|
||||||
String? password,
|
String? password,
|
||||||
String? passphrase,
|
String? passphrase,
|
||||||
String? mnemonic,
|
String? mnemonic,
|
||||||
String? parentAddress,
|
|
||||||
}) =>
|
}) =>
|
||||||
BitcoinNewWalletCredentials(
|
BitcoinNewWalletCredentials(
|
||||||
name: name,
|
name: name,
|
||||||
|
@ -42,7 +41,6 @@ class CWBitcoin extends Bitcoin {
|
||||||
password: password,
|
password: password,
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
mnemonic: mnemonic,
|
mnemonic: mnemonic,
|
||||||
parentAddress: parentAddress,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
|
@ -17,14 +17,12 @@ class CWBitcoinCash extends BitcoinCash {
|
||||||
String? password,
|
String? password,
|
||||||
String? passphrase,
|
String? passphrase,
|
||||||
String? mnemonic,
|
String? mnemonic,
|
||||||
String? parentAddress,
|
|
||||||
}) =>
|
}) =>
|
||||||
BitcoinCashNewWalletCredentials(
|
BitcoinCashNewWalletCredentials(
|
||||||
name: name,
|
name: name,
|
||||||
walletInfo: walletInfo,
|
walletInfo: walletInfo,
|
||||||
password: password,
|
password: password,
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
parentAddress: parentAddress,
|
|
||||||
mnemonic: mnemonic,
|
mnemonic: mnemonic,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,10 @@ import 'package:cw_core/wallet_type.dart';
|
||||||
class NewWalletArguments {
|
class NewWalletArguments {
|
||||||
final WalletType type;
|
final WalletType type;
|
||||||
final String? mnemonic;
|
final String? mnemonic;
|
||||||
final String? parentAddress;
|
|
||||||
final bool isChildWallet;
|
final bool isChildWallet;
|
||||||
|
|
||||||
NewWalletArguments({
|
NewWalletArguments({
|
||||||
required this.type,
|
required this.type,
|
||||||
this.parentAddress,
|
|
||||||
this.mnemonic,
|
this.mnemonic,
|
||||||
this.isChildWallet = false,
|
this.isChildWallet = false,
|
||||||
});
|
});
|
||||||
|
|
11
lib/di.dart
11
lib/di.dart
|
@ -392,11 +392,10 @@ Future<void> setup({
|
||||||
getIt.registerFactory<NewWalletTypeViewModel>(() => NewWalletTypeViewModel(_walletInfoSource));
|
getIt.registerFactory<NewWalletTypeViewModel>(() => NewWalletTypeViewModel(_walletInfoSource));
|
||||||
|
|
||||||
getIt.registerFactory<WalletManager>(
|
getIt.registerFactory<WalletManager>(
|
||||||
() {
|
() => WalletManager(
|
||||||
final instance = WalletManager(_walletInfoSource, getIt.get<SharedPreferences>());
|
_walletInfoSource,
|
||||||
instance.updateWalletGroups();
|
getIt.get<SharedPreferences>(),
|
||||||
return instance;
|
),
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
|
||||||
getIt.registerFactoryParam<WalletGroupsDisplayViewModel, WalletType, void>(
|
getIt.registerFactoryParam<WalletGroupsDisplayViewModel, WalletType, void>(
|
||||||
|
@ -812,7 +811,7 @@ Future<void> setup({
|
||||||
editingWallet: arguments.editingWallet,
|
editingWallet: arguments.editingWallet,
|
||||||
isWalletGroup: arguments.isWalletGroup,
|
isWalletGroup: arguments.isWalletGroup,
|
||||||
groupName: arguments.groupName,
|
groupName: arguments.groupName,
|
||||||
parentAddress: arguments.parentAddress,
|
walletGroupKey: arguments.walletGroupKey,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
21
lib/entities/hash_wallet_identifier.dart
Normal file
21
lib/entities/hash_wallet_identifier.dart
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||||
|
import 'package:cw_core/wallet_base.dart';
|
||||||
|
import 'package:hashlib/hashlib.dart';
|
||||||
|
|
||||||
|
String createHashedWalletIdentifier(WalletBase wallet) {
|
||||||
|
if (wallet.seed == null) return '';
|
||||||
|
|
||||||
|
final salt = secrets.walletGroupSalt;
|
||||||
|
final combined = '$salt.${wallet.seed}';
|
||||||
|
|
||||||
|
// Convert to UTF-8 bytes.
|
||||||
|
final bytes = utf8.encode(combined);
|
||||||
|
|
||||||
|
// Perform SHA-256 hash.
|
||||||
|
final digest = sha256.convert(bytes);
|
||||||
|
|
||||||
|
// Return the hex string representation of the hash.
|
||||||
|
return digest.toString();
|
||||||
|
}
|
|
@ -10,7 +10,7 @@ class WalletEditPageArguments {
|
||||||
this.isWalletGroup = false,
|
this.isWalletGroup = false,
|
||||||
this.walletListViewModel,
|
this.walletListViewModel,
|
||||||
this.groupName = '',
|
this.groupName = '',
|
||||||
this.parentAddress = '',
|
this.walletGroupKey = '',
|
||||||
this.walletEditViewModel,
|
this.walletEditViewModel,
|
||||||
this.walletNewVM,
|
this.walletNewVM,
|
||||||
this.authService,
|
this.authService,
|
||||||
|
@ -19,7 +19,7 @@ class WalletEditPageArguments {
|
||||||
final WalletListItem editingWallet;
|
final WalletListItem editingWallet;
|
||||||
final bool isWalletGroup;
|
final bool isWalletGroup;
|
||||||
final String groupName;
|
final String groupName;
|
||||||
final String parentAddress;
|
final String walletGroupKey;
|
||||||
final WalletListViewModel? walletListViewModel;
|
final WalletListViewModel? walletListViewModel;
|
||||||
|
|
||||||
final WalletEditViewModel? walletEditViewModel;
|
final WalletEditViewModel? walletEditViewModel;
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
|
|
||||||
class WalletGroup {
|
class WalletGroup {
|
||||||
WalletGroup(this.parentAddress) : wallets = [];
|
WalletGroup(this.groupKey) : wallets = [];
|
||||||
|
|
||||||
/// Main identifier for each group, compulsory.
|
/// Primary identifier for the group. Previously was `parentAddress`.
|
||||||
final String parentAddress;
|
/// Now we store either the wallet's hash OR fallback to parentAddress/address.
|
||||||
|
final String groupKey;
|
||||||
|
|
||||||
/// Child wallets that share the same parent address within this group
|
/// Child wallets that share the same group key
|
||||||
List<WalletInfo> wallets;
|
final List<WalletInfo> wallets;
|
||||||
|
|
||||||
/// Custom name for the group, editable for multi-child wallet groups
|
/// Custom name for the group, editable for multi-child wallet groups
|
||||||
String? groupName;
|
String? groupName;
|
||||||
|
|
|
@ -1,70 +1,61 @@
|
||||||
|
import 'package:cake_wallet/entities/hash_wallet_identifier.dart';
|
||||||
import 'package:cake_wallet/entities/wallet_group.dart';
|
import 'package:cake_wallet/entities/wallet_group.dart';
|
||||||
|
import 'package:cw_core/wallet_base.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
|
||||||
class WalletManager {
|
class WalletManager {
|
||||||
WalletManager(
|
WalletManager(this._walletInfoSource, this._sharedPreferences);
|
||||||
this._walletInfoSource,
|
|
||||||
this._sharedPreferences,
|
|
||||||
);
|
|
||||||
|
|
||||||
final Box<WalletInfo> _walletInfoSource;
|
final Box<WalletInfo> _walletInfoSource;
|
||||||
final SharedPreferences _sharedPreferences;
|
final SharedPreferences _sharedPreferences;
|
||||||
|
|
||||||
final List<WalletGroup> walletGroups = [];
|
final List<WalletGroup> walletGroups = [];
|
||||||
|
|
||||||
/// Categorize wallets into groups based on their parentAddress.
|
|
||||||
///
|
|
||||||
/// Update the lead wallet for each group and clean up empty groups
|
|
||||||
/// i.e remove group if there's no lead wallet (i.e, no wallets left)
|
|
||||||
void updateWalletGroups() {
|
void updateWalletGroups() {
|
||||||
walletGroups.clear();
|
walletGroups.clear();
|
||||||
|
|
||||||
for (var walletInfo in _walletInfoSource.values) {
|
for (final walletInfo in _walletInfoSource.values) {
|
||||||
final group = _getOrCreateGroup(_resolveParentAddress(walletInfo));
|
final groupKey = _resolveGroupKey(walletInfo);
|
||||||
|
final group = _getOrCreateGroup(groupKey);
|
||||||
group.wallets.add(walletInfo);
|
group.wallets.add(walletInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
walletGroups.removeWhere((group) => group.wallets.isEmpty);
|
walletGroups.removeWhere((g) => g.wallets.isEmpty);
|
||||||
|
|
||||||
_loadCustomGroupNames();
|
_loadCustomGroupNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Function to determine the correct parentAddress for a wallet.
|
String _resolveGroupKey(WalletInfo walletInfo) {
|
||||||
///
|
if (walletInfo.hashedWalletIdentifier != null &&
|
||||||
/// If it's a parent wallet (parentAddress is null),
|
walletInfo.hashedWalletIdentifier!.isNotEmpty) {
|
||||||
/// use its own address as parentAddress.
|
return walletInfo.hashedWalletIdentifier!;
|
||||||
String _resolveParentAddress(WalletInfo walletInfo) {
|
}
|
||||||
|
|
||||||
|
// Fallback to old logic
|
||||||
return walletInfo.parentAddress ?? walletInfo.address;
|
return walletInfo.parentAddress ?? walletInfo.address;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if a group with the parentAddress already exists,
|
WalletGroup _getOrCreateGroup(String groupKey) {
|
||||||
/// If no group exists, create a new one.
|
|
||||||
///
|
|
||||||
WalletGroup _getOrCreateGroup(String parentAddress) {
|
|
||||||
return walletGroups.firstWhere(
|
return walletGroups.firstWhere(
|
||||||
(group) => group.parentAddress == parentAddress,
|
(g) => g.groupKey == groupKey,
|
||||||
orElse: () {
|
orElse: () {
|
||||||
final newGroup = WalletGroup(parentAddress);
|
final newGroup = WalletGroup(groupKey);
|
||||||
walletGroups.add(newGroup);
|
walletGroups.add(newGroup);
|
||||||
return newGroup;
|
return newGroup;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a new wallet and update lead wallet after adding.
|
|
||||||
void addWallet(WalletInfo walletInfo) {
|
void addWallet(WalletInfo walletInfo) {
|
||||||
final group = _getOrCreateGroup(_resolveParentAddress(walletInfo));
|
final groupKey = _resolveGroupKey(walletInfo);
|
||||||
|
final group = _getOrCreateGroup(groupKey);
|
||||||
group.wallets.add(walletInfo);
|
group.wallets.add(walletInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes a wallet from a group i.e when it's deleted.
|
|
||||||
///
|
|
||||||
/// Update lead wallet after removing,
|
|
||||||
/// Remove the group if it's empty (i.e., no lead wallet).
|
|
||||||
void removeWallet(WalletInfo walletInfo) {
|
void removeWallet(WalletInfo walletInfo) {
|
||||||
final group = _getOrCreateGroup(_resolveParentAddress(walletInfo));
|
final groupKey = _resolveGroupKey(walletInfo);
|
||||||
|
final group = _getOrCreateGroup(groupKey);
|
||||||
group.wallets.remove(walletInfo);
|
group.wallets.remove(walletInfo);
|
||||||
|
|
||||||
if (group.wallets.isEmpty) {
|
if (group.wallets.isEmpty) {
|
||||||
|
@ -72,39 +63,99 @@ class WalletManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns all the child wallets within a group.
|
List<WalletInfo> getWalletsInGroup(String groupKey) {
|
||||||
///
|
|
||||||
/// If the group is not found, returns an empty group with no wallets.
|
|
||||||
List<WalletInfo> getWalletsInGroup(String parentAddress) {
|
|
||||||
return walletGroups
|
return walletGroups
|
||||||
.firstWhere(
|
.firstWhere(
|
||||||
(group) => group.parentAddress == parentAddress,
|
(g) => g.groupKey == groupKey,
|
||||||
orElse: () => WalletGroup(parentAddress),
|
orElse: () => WalletGroup(groupKey),
|
||||||
)
|
)
|
||||||
.wallets;
|
.wallets;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterate through all groups and load their custom names from storage
|
|
||||||
void _loadCustomGroupNames() {
|
void _loadCustomGroupNames() {
|
||||||
for (var group in walletGroups) {
|
for (var group in walletGroups) {
|
||||||
final groupName = _sharedPreferences.getString('wallet_group_name_${group.parentAddress}');
|
final key = 'wallet_group_name_${group.groupKey}';
|
||||||
|
final groupName = _sharedPreferences.getString(key);
|
||||||
if (groupName != null && group.wallets.length > 1) {
|
if (groupName != null && group.wallets.length > 1) {
|
||||||
group.groupName = groupName; // Restore custom name
|
group.groupName = groupName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Save custom name for a group
|
void _saveCustomGroupName(String groupKey, String name) {
|
||||||
void _saveCustomGroupName(String parentAddress, String name) {
|
_sharedPreferences.setString('wallet_group_name_$groupKey', name);
|
||||||
_sharedPreferences.setString('wallet_group_name_$parentAddress', name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set custom group name and persist it
|
void setGroupName(String groupKey, String name) {
|
||||||
void setGroupName(String parentAddress, String name) {
|
if (groupKey.isEmpty || name.isEmpty) return;
|
||||||
if (parentAddress.isEmpty || name.isEmpty) return;
|
|
||||||
|
|
||||||
final group = walletGroups.firstWhere((group) => group.parentAddress == parentAddress);
|
final group = walletGroups.firstWhere((g) => g.groupKey == groupKey);
|
||||||
group.setCustomName(name);
|
group.setCustomName(name);
|
||||||
_saveCustomGroupName(parentAddress, name); // Persist the custom name
|
_saveCustomGroupName(groupKey, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// This performs a Group-Based Lazy Migration:
|
||||||
|
// If the user opens a wallet in an old group,
|
||||||
|
// we migrate ALL wallets that share its old group key to a new hash.
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// When a user opens a wallet, check if it has a real hash.
|
||||||
|
/// If not, migrate the ENTIRE old group so they keep the same group name
|
||||||
|
/// and end up with the same new hash (preserving grouping).
|
||||||
|
Future<void> ensureGroupHasHashedIdentifier(WalletBase openedWallet) async {
|
||||||
|
WalletInfo walletInfo = openedWallet.walletInfo;
|
||||||
|
|
||||||
|
// If the openedWallet already has an hash, then there is nothing to do
|
||||||
|
if (walletInfo.hashedWalletIdentifier != null &&
|
||||||
|
walletInfo.hashedWalletIdentifier!.isNotEmpty) {
|
||||||
|
updateWalletGroups(); // Still skeptical of calling this here. Looking for a better spot.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Identify the old group key for this wallet
|
||||||
|
final oldGroupKey = _resolveGroupKey(walletInfo); // parentAddress fallback
|
||||||
|
|
||||||
|
// Find all wallets that share this old group key (i.e the old group)
|
||||||
|
final oldGroupWallets = _walletInfoSource.values.where((w) {
|
||||||
|
final key = w.hashedWalletIdentifier != null && w.hashedWalletIdentifier!.isNotEmpty
|
||||||
|
? w.hashedWalletIdentifier
|
||||||
|
: (w.parentAddress ?? w.address);
|
||||||
|
return key == oldGroupKey;
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
if (oldGroupWallets.isEmpty) {
|
||||||
|
// This shouldn't happen, but just in case it does, we return.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Next, we determine the new group hash for these wallets
|
||||||
|
// Since they share the same seed, we can assign that group hash
|
||||||
|
// to all the wallets to preserve grouping.
|
||||||
|
final newGroupHash = createHashedWalletIdentifier(openedWallet);
|
||||||
|
|
||||||
|
// Migrate the old group name from oldGroupKey(i.e parentAddress) to newGroupHash
|
||||||
|
await _migrateGroupName(oldGroupKey, newGroupHash);
|
||||||
|
|
||||||
|
// Then we assign this new hash to each wallet in that old group and save them
|
||||||
|
for (final wallet in oldGroupWallets) {
|
||||||
|
wallet.hashedWalletIdentifier = newGroupHash;
|
||||||
|
await wallet.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, we rebuild the groups so that these wallets are now in the new group
|
||||||
|
updateWalletGroups();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Copy an old group name to the new group key, then remove the old key.
|
||||||
|
Future<void> _migrateGroupName(String oldGroupKey, String newGroupKey) async {
|
||||||
|
final oldNameKey = 'wallet_group_name_$oldGroupKey';
|
||||||
|
final newNameKey = 'wallet_group_name_$newGroupKey';
|
||||||
|
|
||||||
|
final oldGroupName = _sharedPreferences.getString(oldNameKey);
|
||||||
|
if (oldGroupName != null) {
|
||||||
|
await _sharedPreferences.setString(newNameKey, oldGroupName);
|
||||||
|
await _sharedPreferences.remove(oldNameKey);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ class CWEthereum extends Ethereum {
|
||||||
WalletCredentials createEthereumNewWalletCredentials({
|
WalletCredentials createEthereumNewWalletCredentials({
|
||||||
required String name,
|
required String name,
|
||||||
String? mnemonic,
|
String? mnemonic,
|
||||||
String? parentAddress,
|
|
||||||
WalletInfo? walletInfo,
|
WalletInfo? walletInfo,
|
||||||
String? password,
|
String? password,
|
||||||
String? passphrase,
|
String? passphrase,
|
||||||
|
@ -20,7 +19,6 @@ class CWEthereum extends Ethereum {
|
||||||
name: name,
|
name: name,
|
||||||
walletInfo: walletInfo,
|
walletInfo: walletInfo,
|
||||||
password: password,
|
password: password,
|
||||||
parentAddress: parentAddress,
|
|
||||||
mnemonic: mnemonic,
|
mnemonic: mnemonic,
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
);
|
);
|
||||||
|
|
|
@ -94,14 +94,12 @@ class CWNano extends Nano {
|
||||||
WalletInfo? walletInfo,
|
WalletInfo? walletInfo,
|
||||||
String? password,
|
String? password,
|
||||||
String? mnemonic,
|
String? mnemonic,
|
||||||
String? parentAddress,
|
|
||||||
String? passphrase,
|
String? passphrase,
|
||||||
}) =>
|
}) =>
|
||||||
NanoNewWalletCredentials(
|
NanoNewWalletCredentials(
|
||||||
name: name,
|
name: name,
|
||||||
password: password,
|
password: password,
|
||||||
mnemonic: mnemonic,
|
mnemonic: mnemonic,
|
||||||
parentAddress: parentAddress,
|
|
||||||
walletInfo: walletInfo,
|
walletInfo: walletInfo,
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
);
|
);
|
||||||
|
|
|
@ -11,7 +11,6 @@ class CWPolygon extends Polygon {
|
||||||
WalletCredentials createPolygonNewWalletCredentials({
|
WalletCredentials createPolygonNewWalletCredentials({
|
||||||
required String name,
|
required String name,
|
||||||
String? mnemonic,
|
String? mnemonic,
|
||||||
String? parentAddress,
|
|
||||||
WalletInfo? walletInfo,
|
WalletInfo? walletInfo,
|
||||||
String? password,
|
String? password,
|
||||||
String? passphrase,
|
String? passphrase,
|
||||||
|
@ -21,7 +20,6 @@ class CWPolygon extends Polygon {
|
||||||
walletInfo: walletInfo,
|
walletInfo: walletInfo,
|
||||||
password: password,
|
password: password,
|
||||||
mnemonic: mnemonic,
|
mnemonic: mnemonic,
|
||||||
parentAddress: parentAddress,
|
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
import 'package:cake_wallet/di.dart';
|
||||||
import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
|
import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
|
||||||
import 'package:cake_wallet/entities/fiat_api_mode.dart';
|
import 'package:cake_wallet/entities/fiat_api_mode.dart';
|
||||||
import 'package:cake_wallet/entities/update_haven_rate.dart';
|
import 'package:cake_wallet/entities/update_haven_rate.dart';
|
||||||
|
import 'package:cake_wallet/entities/wallet_manager.dart';
|
||||||
import 'package:cake_wallet/ethereum/ethereum.dart';
|
import 'package:cake_wallet/ethereum/ethereum.dart';
|
||||||
import 'package:cake_wallet/polygon/polygon.dart';
|
import 'package:cake_wallet/polygon/polygon.dart';
|
||||||
import 'package:cake_wallet/solana/solana.dart';
|
import 'package:cake_wallet/solana/solana.dart';
|
||||||
|
@ -59,6 +61,8 @@ void startCurrentWalletChangeReaction(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await getIt.get<WalletManager>().ensureGroupHasHashedIdentifier(wallet);
|
||||||
|
|
||||||
final node = settingsStore.getCurrentNode(wallet.type);
|
final node = settingsStore.getCurrentNode(wallet.type);
|
||||||
|
|
||||||
startWalletSyncStatusChangeReaction(wallet, fiatConversionStore);
|
startWalletSyncStatusChangeReaction(wallet, fiatConversionStore);
|
||||||
|
|
|
@ -11,7 +11,6 @@ class CWSolana extends Solana {
|
||||||
WalletCredentials createSolanaNewWalletCredentials({
|
WalletCredentials createSolanaNewWalletCredentials({
|
||||||
required String name,
|
required String name,
|
||||||
String? mnemonic,
|
String? mnemonic,
|
||||||
String? parentAddress,
|
|
||||||
WalletInfo? walletInfo,
|
WalletInfo? walletInfo,
|
||||||
String? password,
|
String? password,
|
||||||
String? passphrase,
|
String? passphrase,
|
||||||
|
@ -21,7 +20,6 @@ class CWSolana extends Solana {
|
||||||
walletInfo: walletInfo,
|
walletInfo: walletInfo,
|
||||||
password: password,
|
password: password,
|
||||||
mnemonic: mnemonic,
|
mnemonic: mnemonic,
|
||||||
parentAddress: parentAddress,
|
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -150,7 +150,6 @@ class WalletGroupsDisplayBody extends StatelessWidget {
|
||||||
arguments: NewWalletArguments(
|
arguments: NewWalletArguments(
|
||||||
type: walletGroupsDisplayViewModel.type,
|
type: walletGroupsDisplayViewModel.type,
|
||||||
mnemonic: mnemonic,
|
mnemonic: mnemonic,
|
||||||
parentAddress: walletGroupsDisplayViewModel.parentAddress,
|
|
||||||
isChildWallet: true,
|
isChildWallet: true,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -112,7 +112,7 @@ class WalletEditPage extends BasePage {
|
||||||
pageArguments.editingWallet,
|
pageArguments.editingWallet,
|
||||||
password: password,
|
password: password,
|
||||||
isWalletGroup: pageArguments.isWalletGroup,
|
isWalletGroup: pageArguments.isWalletGroup,
|
||||||
groupParentAddress: pageArguments.parentAddress,
|
walletGroupKey: pageArguments.walletGroupKey,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
callback: (bool isAuthenticatedSuccessfully,
|
callback: (bool isAuthenticatedSuccessfully,
|
||||||
|
@ -128,7 +128,7 @@ class WalletEditPage extends BasePage {
|
||||||
await walletEditViewModel.changeName(
|
await walletEditViewModel.changeName(
|
||||||
pageArguments.editingWallet,
|
pageArguments.editingWallet,
|
||||||
isWalletGroup: pageArguments.isWalletGroup,
|
isWalletGroup: pageArguments.isWalletGroup,
|
||||||
groupParentAddress: pageArguments.parentAddress,
|
walletGroupKey: pageArguments.walletGroupKey,
|
||||||
);
|
);
|
||||||
confirmed = true;
|
confirmed = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -227,7 +227,7 @@ class WalletListBodyState extends State<WalletListBody> {
|
||||||
editingWallet: wallet,
|
editingWallet: wallet,
|
||||||
isWalletGroup: true,
|
isWalletGroup: true,
|
||||||
groupName: groupName,
|
groupName: groupName,
|
||||||
parentAddress: group.parentAddress,
|
walletGroupKey: group.groupKey,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,16 +14,15 @@ class CWTron extends Tron {
|
||||||
WalletInfo? walletInfo,
|
WalletInfo? walletInfo,
|
||||||
String? password,
|
String? password,
|
||||||
String? mnemonic,
|
String? mnemonic,
|
||||||
String? parentAddress,
|
|
||||||
String? passphrase,
|
String? passphrase,
|
||||||
}) =>
|
}) =>
|
||||||
TronNewWalletCredentials(
|
TronNewWalletCredentials(
|
||||||
name: name,
|
name: name,
|
||||||
walletInfo: walletInfo,
|
walletInfo: walletInfo,
|
||||||
password: password,
|
password: password,
|
||||||
mnemonic: mnemonic,
|
mnemonic: mnemonic,
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
parentAddress: parentAddress);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
WalletCredentials createTronRestoreWalletFromSeedCredentials({
|
WalletCredentials createTronRestoreWalletFromSeedCredentials({
|
||||||
|
|
|
@ -4,6 +4,7 @@ import 'package:cake_wallet/core/wallet_creation_service.dart';
|
||||||
import 'package:cake_wallet/di.dart';
|
import 'package:cake_wallet/di.dart';
|
||||||
import 'package:cake_wallet/entities/background_tasks.dart';
|
import 'package:cake_wallet/entities/background_tasks.dart';
|
||||||
import 'package:cake_wallet/entities/generate_name.dart';
|
import 'package:cake_wallet/entities/generate_name.dart';
|
||||||
|
import 'package:cake_wallet/entities/hash_wallet_identifier.dart';
|
||||||
import 'package:cake_wallet/generated/i18n.dart';
|
import 'package:cake_wallet/generated/i18n.dart';
|
||||||
import 'package:cake_wallet/nano/nano.dart';
|
import 'package:cake_wallet/nano/nano.dart';
|
||||||
import 'package:cake_wallet/store/app_store.dart';
|
import 'package:cake_wallet/store/app_store.dart';
|
||||||
|
@ -103,13 +104,16 @@ abstract class WalletCreationVMBase with Store {
|
||||||
showIntroCakePayCard: (!walletCreationService.typeExists(type)) && type != WalletType.haven,
|
showIntroCakePayCard: (!walletCreationService.typeExists(type)) && type != WalletType.haven,
|
||||||
derivationInfo: credentials.derivationInfo ?? getDefaultCreateDerivation(),
|
derivationInfo: credentials.derivationInfo ?? getDefaultCreateDerivation(),
|
||||||
hardwareWalletType: credentials.hardwareWalletType,
|
hardwareWalletType: credentials.hardwareWalletType,
|
||||||
parentAddress: credentials.parentAddress,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
credentials.walletInfo = walletInfo;
|
credentials.walletInfo = walletInfo;
|
||||||
final wallet = restoreWallet != null
|
final wallet = restoreWallet != null
|
||||||
? await processFromRestoredWallet(credentials, restoreWallet)
|
? await processFromRestoredWallet(credentials, restoreWallet)
|
||||||
: await process(credentials);
|
: await process(credentials);
|
||||||
|
|
||||||
|
final isNonSeedWallet = isRecovery ? wallet.seed == null : false;
|
||||||
|
walletInfo.isNonSeedWallet = isNonSeedWallet;
|
||||||
|
walletInfo.hashedWalletIdentifier = createHashedWalletIdentifier(wallet);
|
||||||
walletInfo.address = wallet.walletAddresses.address;
|
walletInfo.address = wallet.walletAddresses.address;
|
||||||
await _walletInfoSource.add(walletInfo);
|
await _walletInfoSource.add(walletInfo);
|
||||||
await _appStore.changeCurrentWallet(wallet);
|
await _appStore.changeCurrentWallet(wallet);
|
||||||
|
|
|
@ -47,8 +47,6 @@ abstract class WalletGroupsDisplayViewModelBase with Store {
|
||||||
@observable
|
@observable
|
||||||
WalletInfo? selectedSingleWallet;
|
WalletInfo? selectedSingleWallet;
|
||||||
|
|
||||||
@observable
|
|
||||||
String? parentAddress;
|
|
||||||
|
|
||||||
@observable
|
@observable
|
||||||
bool isFetchingMnemonic;
|
bool isFetchingMnemonic;
|
||||||
|
@ -77,9 +75,6 @@ abstract class WalletGroupsDisplayViewModelBase with Store {
|
||||||
walletToUse.name,
|
walletToUse.name,
|
||||||
);
|
);
|
||||||
|
|
||||||
parentAddress =
|
|
||||||
isGroupSelected ? selectedWalletGroup!.parentAddress : selectedSingleWallet!.address;
|
|
||||||
|
|
||||||
return wallet.seed;
|
return wallet.seed;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -130,11 +125,14 @@ abstract class WalletGroupsDisplayViewModelBase with Store {
|
||||||
// Check that selected wallet type is not present already in group
|
// Check that selected wallet type is not present already in group
|
||||||
bool isSameTypeAsSelectedWallet = wallet.type == type;
|
bool isSameTypeAsSelectedWallet = wallet.type == type;
|
||||||
|
|
||||||
|
bool isNonSeedWallet = wallet.isNonSeedWallet;
|
||||||
|
|
||||||
// Exclude if any of these conditions are true
|
// Exclude if any of these conditions are true
|
||||||
return isNonBIP39Wallet ||
|
return isNonBIP39Wallet ||
|
||||||
isNanoDerivationType ||
|
isNanoDerivationType ||
|
||||||
isElectrumDerivationType ||
|
isElectrumDerivationType ||
|
||||||
isSameTypeAsSelectedWallet;
|
isSameTypeAsSelectedWallet ||
|
||||||
|
isNonSeedWallet;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (shouldExcludeGroup) continue;
|
if (shouldExcludeGroup) continue;
|
||||||
|
|
|
@ -40,7 +40,7 @@ abstract class WalletEditViewModelBase with Store {
|
||||||
Future<void> changeName(
|
Future<void> changeName(
|
||||||
WalletListItem walletItem, {
|
WalletListItem walletItem, {
|
||||||
String? password,
|
String? password,
|
||||||
String? groupParentAddress,
|
String? walletGroupKey,
|
||||||
bool isWalletGroup = false,
|
bool isWalletGroup = false,
|
||||||
}) async {
|
}) async {
|
||||||
state = WalletEditRenamePending();
|
state = WalletEditRenamePending();
|
||||||
|
@ -48,7 +48,7 @@ abstract class WalletEditViewModelBase with Store {
|
||||||
if (isWalletGroup) {
|
if (isWalletGroup) {
|
||||||
_walletManager.updateWalletGroups();
|
_walletManager.updateWalletGroups();
|
||||||
|
|
||||||
_walletManager.setGroupName(groupParentAddress!, newName);
|
_walletManager.setGroupName(walletGroupKey!, newName);
|
||||||
} else {
|
} else {
|
||||||
await _walletLoadingService.renameWallet(
|
await _walletLoadingService.renameWallet(
|
||||||
walletItem.type,
|
walletItem.type,
|
||||||
|
|
|
@ -109,7 +109,6 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
|
||||||
password: walletPassword,
|
password: walletPassword,
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
mnemonic: newWalletArguments!.mnemonic,
|
mnemonic: newWalletArguments!.mnemonic,
|
||||||
parentAddress: newWalletArguments!.parentAddress,
|
|
||||||
);
|
);
|
||||||
case WalletType.haven:
|
case WalletType.haven:
|
||||||
return haven!.createHavenNewWalletCredentials(
|
return haven!.createHavenNewWalletCredentials(
|
||||||
|
@ -119,7 +118,6 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
|
||||||
name: name,
|
name: name,
|
||||||
password: walletPassword,
|
password: walletPassword,
|
||||||
mnemonic: newWalletArguments!.mnemonic,
|
mnemonic: newWalletArguments!.mnemonic,
|
||||||
parentAddress: newWalletArguments!.parentAddress,
|
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
);
|
);
|
||||||
case WalletType.bitcoinCash:
|
case WalletType.bitcoinCash:
|
||||||
|
@ -128,7 +126,6 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
|
||||||
password: walletPassword,
|
password: walletPassword,
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
mnemonic: newWalletArguments!.mnemonic,
|
mnemonic: newWalletArguments!.mnemonic,
|
||||||
parentAddress: newWalletArguments!.parentAddress,
|
|
||||||
);
|
);
|
||||||
case WalletType.nano:
|
case WalletType.nano:
|
||||||
case WalletType.banano:
|
case WalletType.banano:
|
||||||
|
@ -136,7 +133,6 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
|
||||||
name: name,
|
name: name,
|
||||||
password: walletPassword,
|
password: walletPassword,
|
||||||
mnemonic: newWalletArguments!.mnemonic,
|
mnemonic: newWalletArguments!.mnemonic,
|
||||||
parentAddress: newWalletArguments!.parentAddress,
|
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
);
|
);
|
||||||
case WalletType.polygon:
|
case WalletType.polygon:
|
||||||
|
@ -144,7 +140,6 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
|
||||||
name: name,
|
name: name,
|
||||||
password: walletPassword,
|
password: walletPassword,
|
||||||
mnemonic: newWalletArguments!.mnemonic,
|
mnemonic: newWalletArguments!.mnemonic,
|
||||||
parentAddress: newWalletArguments!.parentAddress,
|
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
);
|
);
|
||||||
case WalletType.solana:
|
case WalletType.solana:
|
||||||
|
@ -152,7 +147,6 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
|
||||||
name: name,
|
name: name,
|
||||||
password: walletPassword,
|
password: walletPassword,
|
||||||
mnemonic: newWalletArguments!.mnemonic,
|
mnemonic: newWalletArguments!.mnemonic,
|
||||||
parentAddress: newWalletArguments!.parentAddress,
|
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
);
|
);
|
||||||
case WalletType.tron:
|
case WalletType.tron:
|
||||||
|
@ -160,7 +154,6 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
|
||||||
name: name,
|
name: name,
|
||||||
password: walletPassword,
|
password: walletPassword,
|
||||||
mnemonic: newWalletArguments!.mnemonic,
|
mnemonic: newWalletArguments!.mnemonic,
|
||||||
parentAddress: newWalletArguments!.parentAddress,
|
|
||||||
passphrase: passphrase,
|
passphrase: passphrase,
|
||||||
);
|
);
|
||||||
case WalletType.wownero:
|
case WalletType.wownero:
|
||||||
|
|
|
@ -160,7 +160,7 @@ abstract class Bitcoin {
|
||||||
String? passphrase,
|
String? passphrase,
|
||||||
});
|
});
|
||||||
WalletCredentials createBitcoinRestoreWalletFromWIFCredentials({required String name, required String password, required String wif, WalletInfo? walletInfo});
|
WalletCredentials createBitcoinRestoreWalletFromWIFCredentials({required String name, required String password, required String wif, WalletInfo? walletInfo});
|
||||||
WalletCredentials createBitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? passphrase, String? mnemonic, String? parentAddress});
|
WalletCredentials createBitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? passphrase, String? mnemonic});
|
||||||
WalletCredentials createBitcoinHardwareWalletCredentials({required String name, required HardwareAccountData accountData, WalletInfo? walletInfo});
|
WalletCredentials createBitcoinHardwareWalletCredentials({required String name, required HardwareAccountData accountData, WalletInfo? walletInfo});
|
||||||
List<String> getWordList();
|
List<String> getWordList();
|
||||||
Map<String, String> getWalletKeys(Object wallet);
|
Map<String, String> getWalletKeys(Object wallet);
|
||||||
|
@ -882,7 +882,7 @@ import 'package:eth_sig_util/util/utils.dart';
|
||||||
abstract class Ethereum {
|
abstract class Ethereum {
|
||||||
List<String> getEthereumWordList(String language);
|
List<String> getEthereumWordList(String language);
|
||||||
WalletService createEthereumWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
|
WalletService createEthereumWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
|
||||||
WalletCredentials createEthereumNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? parentAddress, String? passphrase});
|
WalletCredentials createEthereumNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? passphrase});
|
||||||
WalletCredentials createEthereumRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password, String? passphrase});
|
WalletCredentials createEthereumRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password, String? passphrase});
|
||||||
WalletCredentials createEthereumRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password});
|
WalletCredentials createEthereumRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password});
|
||||||
WalletCredentials createEthereumHardwareWalletCredentials({required String name, required HardwareAccountData hwAccountData, WalletInfo? walletInfo});
|
WalletCredentials createEthereumHardwareWalletCredentials({required String name, required HardwareAccountData hwAccountData, WalletInfo? walletInfo});
|
||||||
|
@ -989,7 +989,7 @@ import 'package:eth_sig_util/util/utils.dart';
|
||||||
abstract class Polygon {
|
abstract class Polygon {
|
||||||
List<String> getPolygonWordList(String language);
|
List<String> getPolygonWordList(String language);
|
||||||
WalletService createPolygonWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
|
WalletService createPolygonWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
|
||||||
WalletCredentials createPolygonNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? parentAddress, String? passphrase});
|
WalletCredentials createPolygonNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? passphrase});
|
||||||
WalletCredentials createPolygonRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password, String? passphrase});
|
WalletCredentials createPolygonRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password, String? passphrase});
|
||||||
WalletCredentials createPolygonRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password});
|
WalletCredentials createPolygonRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password});
|
||||||
WalletCredentials createPolygonHardwareWalletCredentials({required String name, required HardwareAccountData hwAccountData, WalletInfo? walletInfo});
|
WalletCredentials createPolygonHardwareWalletCredentials({required String name, required HardwareAccountData hwAccountData, WalletInfo? walletInfo});
|
||||||
|
@ -1077,7 +1077,7 @@ abstract class BitcoinCash {
|
||||||
Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect);
|
Box<WalletInfo> walletInfoSource, Box<UnspentCoinsInfo> unspentCoinSource, bool isDirect);
|
||||||
|
|
||||||
WalletCredentials createBitcoinCashNewWalletCredentials(
|
WalletCredentials createBitcoinCashNewWalletCredentials(
|
||||||
{required String name, WalletInfo? walletInfo, String? password, String? passphrase, String? mnemonic, String? parentAddress});
|
{required String name, WalletInfo? walletInfo, String? password, String? passphrase, String? mnemonic});
|
||||||
|
|
||||||
WalletCredentials createBitcoinCashRestoreWalletFromSeedCredentials(
|
WalletCredentials createBitcoinCashRestoreWalletFromSeedCredentials(
|
||||||
{required String name, required String mnemonic, required String password, String? passphrase});
|
{required String name, required String mnemonic, required String password, String? passphrase});
|
||||||
|
@ -1161,7 +1161,6 @@ abstract class Nano {
|
||||||
required String name,
|
required String name,
|
||||||
String? password,
|
String? password,
|
||||||
String? mnemonic,
|
String? mnemonic,
|
||||||
String? parentAddress,
|
|
||||||
WalletInfo? walletInfo,
|
WalletInfo? walletInfo,
|
||||||
String? passphrase,
|
String? passphrase,
|
||||||
});
|
});
|
||||||
|
@ -1281,7 +1280,7 @@ abstract class Solana {
|
||||||
List<String> getSolanaWordList(String language);
|
List<String> getSolanaWordList(String language);
|
||||||
WalletService createSolanaWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
|
WalletService createSolanaWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
|
||||||
WalletCredentials createSolanaNewWalletCredentials(
|
WalletCredentials createSolanaNewWalletCredentials(
|
||||||
{required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? parentAddress, String? passphrase});
|
{required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? passphrase});
|
||||||
WalletCredentials createSolanaRestoreWalletFromSeedCredentials(
|
WalletCredentials createSolanaRestoreWalletFromSeedCredentials(
|
||||||
{required String name, required String mnemonic, required String password, String? passphrase});
|
{required String name, required String mnemonic, required String password, String? passphrase});
|
||||||
WalletCredentials createSolanaRestoreWalletFromPrivateKey(
|
WalletCredentials createSolanaRestoreWalletFromPrivateKey(
|
||||||
|
@ -1369,7 +1368,7 @@ import 'package:cw_tron/default_tron_tokens.dart';
|
||||||
abstract class Tron {
|
abstract class Tron {
|
||||||
List<String> getTronWordList(String language);
|
List<String> getTronWordList(String language);
|
||||||
WalletService createTronWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
|
WalletService createTronWalletService(Box<WalletInfo> walletInfoSource, bool isDirect);
|
||||||
WalletCredentials createTronNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? parentAddress, String? passphrase});
|
WalletCredentials createTronNewWalletCredentials({required String name, WalletInfo? walletInfo, String? password, String? mnemonic, String? passphrase});
|
||||||
WalletCredentials createTronRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password, String? passphrase});
|
WalletCredentials createTronRestoreWalletFromSeedCredentials({required String name, required String mnemonic, required String password, String? passphrase});
|
||||||
WalletCredentials createTronRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password});
|
WalletCredentials createTronRestoreWalletFromPrivateKey({required String name, required String privateKey, required String password});
|
||||||
String getAddress(WalletBase wallet);
|
String getAddress(WalletBase wallet);
|
||||||
|
|
|
@ -77,6 +77,7 @@ class SecretKey {
|
||||||
SecretKey('moneroTestWalletBlockHeight', () => ''),
|
SecretKey('moneroTestWalletBlockHeight', () => ''),
|
||||||
SecretKey('chainflipApiKey', () => ''),
|
SecretKey('chainflipApiKey', () => ''),
|
||||||
SecretKey('chainflipAffiliateFee', () => ''),
|
SecretKey('chainflipAffiliateFee', () => ''),
|
||||||
|
SecretKey('walletGroupSalt', () => hex.encode(encrypt.Key.fromSecureRandom(16).bytes)),
|
||||||
];
|
];
|
||||||
|
|
||||||
static final evmChainsSecrets = [
|
static final evmChainsSecrets = [
|
||||||
|
@ -88,6 +89,7 @@ class SecretKey {
|
||||||
|
|
||||||
static final solanaSecrets = [
|
static final solanaSecrets = [
|
||||||
SecretKey('ankrApiKey', () => ''),
|
SecretKey('ankrApiKey', () => ''),
|
||||||
|
SecretKey('nowNodesApiKey', () => ''),
|
||||||
SecretKey('chainStackApiKey', () => ''),
|
SecretKey('chainStackApiKey', () => ''),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue