mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-23 03:59:23 +00:00
debatably better refactoring of derivationInfo, migration needed
This commit is contained in:
parent
d4c8a1d8f6
commit
ae97e50bf4
15 changed files with 127 additions and 106 deletions
|
@ -38,7 +38,6 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
|||
initialBalance: initialBalance,
|
||||
seedBytes: seedBytes,
|
||||
currency: CryptoCurrency.btc) {
|
||||
|
||||
// in a standard BIP44 wallet, mainHd derivation path = m/84'/0'/0'/0 (account 0, index unspecified here)
|
||||
// the sideHd derivation path = m/84'/0'/0'/1 (account 1, index unspecified here)
|
||||
walletAddresses = BitcoinWalletAddresses(walletInfo,
|
||||
|
@ -47,9 +46,11 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
|||
initialRegularAddressIndex: initialRegularAddressIndex,
|
||||
initialChangeAddressIndex: initialChangeAddressIndex,
|
||||
mainHd: bitcoin.HDWallet.fromSeed(seedBytes, network: networkType)
|
||||
.derivePath(walletInfo.derivationPath!),
|
||||
sideHd: bitcoin.HDWallet.fromSeed(seedBytes, network: networkType).derivePath(
|
||||
walletInfo.derivationPath!.substring(0, walletInfo.derivationPath!.length - 1) + "1"),
|
||||
.derivePath(walletInfo.derivationInfo!.derivationPath!),
|
||||
sideHd: bitcoin.HDWallet.fromSeed(seedBytes, network: networkType).derivePath(walletInfo
|
||||
.derivationInfo!.derivationPath!
|
||||
.substring(0, walletInfo.derivationInfo!.derivationPath!.length - 1) +
|
||||
"1"),
|
||||
networkType: networkType);
|
||||
}
|
||||
|
||||
|
@ -64,14 +65,14 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
|||
int initialChangeAddressIndex = 0}) async {
|
||||
late Uint8List seedBytes;
|
||||
|
||||
switch (walletInfo.derivationType) {
|
||||
case DerivationType.electrum2:
|
||||
seedBytes = await mnemonicToSeedBytes(mnemonic);
|
||||
break;
|
||||
switch (walletInfo.derivationInfo?.derivationType) {
|
||||
case DerivationType.bip39:
|
||||
default:
|
||||
seedBytes = await bip39.mnemonicToSeed(mnemonic);
|
||||
break;
|
||||
case DerivationType.electrum2:
|
||||
default:
|
||||
seedBytes = await mnemonicToSeedBytes(mnemonic);
|
||||
break;
|
||||
}
|
||||
|
||||
return BitcoinWallet(
|
||||
|
@ -94,20 +95,17 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
|||
}) async {
|
||||
final snp = await ElectrumWallletSnapshot.load(name, walletInfo.type, password);
|
||||
|
||||
walletInfo.derivationType = snp.derivationType;
|
||||
walletInfo.derivationPath = snp.derivationPath;
|
||||
walletInfo.derivationInfo ??= DerivationInfo(
|
||||
derivationType: snp.derivationType ?? DerivationType.electrum2,
|
||||
derivationPath: snp.derivationPath,
|
||||
);
|
||||
|
||||
// set the default if not present:
|
||||
if (walletInfo.derivationPath == null) {
|
||||
walletInfo.derivationPath = "m/0'/1";
|
||||
}
|
||||
if (walletInfo.derivationType == null) {
|
||||
walletInfo.derivationType = DerivationType.electrum2;
|
||||
}
|
||||
walletInfo.derivationInfo!.derivationPath = snp.derivationPath ?? "m/0'/1";
|
||||
|
||||
late Uint8List seedBytes;
|
||||
|
||||
switch (walletInfo.derivationType) {
|
||||
switch (walletInfo.derivationInfo!.derivationType) {
|
||||
case DerivationType.electrum2:
|
||||
seedBytes = await mnemonicToSeedBytes(snp.mnemonic);
|
||||
break;
|
||||
|
|
|
@ -2,8 +2,11 @@ import 'package:cw_core/wallet_credentials.dart';
|
|||
import 'package:cw_core/wallet_info.dart';
|
||||
|
||||
class BitcoinNewWalletCredentials extends WalletCredentials {
|
||||
BitcoinNewWalletCredentials({required String name, WalletInfo? walletInfo})
|
||||
BitcoinNewWalletCredentials(
|
||||
{required String name, WalletInfo? walletInfo, this.derivationType, this.derivationPath})
|
||||
: super(name: name, walletInfo: walletInfo);
|
||||
DerivationType? derivationType;
|
||||
String? derivationPath;
|
||||
}
|
||||
|
||||
class BitcoinRestoreWalletFromSeedCredentials extends WalletCredentials {
|
||||
|
@ -11,16 +14,17 @@ class BitcoinRestoreWalletFromSeedCredentials extends WalletCredentials {
|
|||
required String name,
|
||||
required String password,
|
||||
required this.mnemonic,
|
||||
WalletInfo? walletInfo,
|
||||
DerivationType? derivationType,
|
||||
String? derivationPath,
|
||||
WalletInfo? walletInfo,
|
||||
}) : super(
|
||||
name: name,
|
||||
password: password,
|
||||
walletInfo: walletInfo,
|
||||
derivationType: derivationType,
|
||||
derivationPath: derivationPath,
|
||||
);
|
||||
name: name,
|
||||
password: password,
|
||||
walletInfo: walletInfo,
|
||||
derivationInfo: DerivationInfo(
|
||||
derivationType: derivationType,
|
||||
derivationPath: derivationPath,
|
||||
));
|
||||
|
||||
final String mnemonic;
|
||||
}
|
||||
|
|
|
@ -46,13 +46,13 @@ class BitcoinWalletService extends WalletService<BitcoinNewWalletCredentials,
|
|||
|
||||
@override
|
||||
Future<BitcoinWallet> create(BitcoinNewWalletCredentials credentials) async {
|
||||
// default derivation type/path for bitcoin wallets:
|
||||
if (credentials.walletInfo!.derivationType == null) {
|
||||
credentials.walletInfo!.derivationType = DerivationType.electrum2;
|
||||
}
|
||||
if (credentials.walletInfo!.derivationPath == null) {
|
||||
credentials.walletInfo!.derivationPath = "m/0'/1";
|
||||
}
|
||||
// set default if not present:
|
||||
DerivationType derivationType = credentials.derivationType ?? DerivationType.electrum2;
|
||||
String derivationPath = credentials.derivationPath ?? "m/0'/1";
|
||||
// only set if not in the walletInfo already:
|
||||
credentials.walletInfo!.derivationInfo ??=
|
||||
DerivationInfo(derivationType: derivationType, derivationPath: derivationPath);
|
||||
|
||||
final wallet = await BitcoinWalletBase.create(
|
||||
mnemonic: await generateElectrumMnemonic(strength: 132),
|
||||
password: credentials.password!,
|
||||
|
|
|
@ -14,3 +14,4 @@ const ERC20_TOKEN_TYPE_ID = 12;
|
|||
const NANO_ACCOUNT_TYPE_ID = 13;
|
||||
const POW_NODE_TYPE_ID = 14;
|
||||
const DERIVATION_TYPE_TYPE_ID = 15;
|
||||
const DERIVATION_INFO_TYPE_ID = 16;
|
|
@ -6,14 +6,12 @@ abstract class WalletCredentials {
|
|||
this.height,
|
||||
this.walletInfo,
|
||||
this.password,
|
||||
this.derivationType,
|
||||
this.derivationPath,
|
||||
this.derivationInfo,
|
||||
});
|
||||
|
||||
final String name;
|
||||
final int? height;
|
||||
String? password;
|
||||
DerivationType? derivationType;
|
||||
String? derivationPath;
|
||||
WalletInfo? walletInfo;
|
||||
DerivationInfo? derivationInfo;
|
||||
}
|
||||
|
|
|
@ -21,10 +21,10 @@ enum DerivationType {
|
|||
@HiveField(5)
|
||||
electrum2,
|
||||
}
|
||||
|
||||
class DerivationInfo {
|
||||
@HiveType(typeId: DerivationInfo.typeId)
|
||||
class DerivationInfo extends HiveObject {
|
||||
DerivationInfo({
|
||||
required this.derivationType,
|
||||
this.derivationType,
|
||||
this.derivationPath,
|
||||
this.balance = "",
|
||||
this.address = "",
|
||||
|
@ -33,10 +33,12 @@ class DerivationInfo {
|
|||
this.description,
|
||||
});
|
||||
|
||||
static const typeId = DERIVATION_INFO_TYPE_ID;
|
||||
|
||||
String balance;
|
||||
String address;
|
||||
int height;
|
||||
final DerivationType derivationType;
|
||||
DerivationType? derivationType;
|
||||
String? derivationPath;
|
||||
final String? script_type;
|
||||
final String? description;
|
||||
|
@ -57,8 +59,7 @@ class WalletInfo extends HiveObject {
|
|||
this.yatEid,
|
||||
this.yatLastUsedAddressRaw,
|
||||
this.showIntroCakePayCard,
|
||||
this.derivationType,
|
||||
this.derivationPath)
|
||||
this.derivationInfo)
|
||||
: _yatLastUsedAddressController = StreamController<String>.broadcast();
|
||||
|
||||
factory WalletInfo.external({
|
||||
|
@ -74,8 +75,7 @@ class WalletInfo extends HiveObject {
|
|||
bool? showIntroCakePayCard,
|
||||
String yatEid = '',
|
||||
String yatLastUsedAddressRaw = '',
|
||||
DerivationType? derivationType,
|
||||
String? derivationPath,
|
||||
DerivationInfo? derivationInfo,
|
||||
}) {
|
||||
return WalletInfo(
|
||||
id,
|
||||
|
@ -90,8 +90,7 @@ class WalletInfo extends HiveObject {
|
|||
yatEid,
|
||||
yatLastUsedAddressRaw,
|
||||
showIntroCakePayCard,
|
||||
derivationType,
|
||||
derivationPath);
|
||||
derivationInfo);
|
||||
}
|
||||
|
||||
static const typeId = WALLET_INFO_TYPE_ID;
|
||||
|
@ -143,10 +142,7 @@ class WalletInfo extends HiveObject {
|
|||
List<String>? usedAddresses;
|
||||
|
||||
@HiveField(16)
|
||||
DerivationType? derivationType;
|
||||
|
||||
@HiveField(17)
|
||||
String? derivationPath;
|
||||
DerivationInfo? derivationInfo;
|
||||
|
||||
String get yatLastUsedAddress => yatLastUsedAddressRaw ?? '';
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ abstract class NanoWalletBase
|
|||
}) : syncStatus = NotConnectedSyncStatus(),
|
||||
_password = password,
|
||||
_mnemonic = mnemonic,
|
||||
_derivationType = walletInfo.derivationType!,
|
||||
_derivationType = walletInfo.derivationInfo!.derivationType!,
|
||||
_isTransactionUpdating = false,
|
||||
_client = NanoClient(),
|
||||
walletAddresses = NanoWalletAddresses(walletInfo),
|
||||
|
@ -354,7 +354,7 @@ abstract class NanoWalletBase
|
|||
derivationType = DerivationType.nano;
|
||||
}
|
||||
|
||||
walletInfo.derivationType = derivationType;
|
||||
walletInfo.derivationInfo ??= DerivationInfo(derivationType: derivationType);
|
||||
|
||||
return NanoWallet(
|
||||
walletInfo: walletInfo,
|
||||
|
|
|
@ -2,8 +2,15 @@ import 'package:cw_core/wallet_credentials.dart';
|
|||
import 'package:cw_core/wallet_info.dart';
|
||||
|
||||
class NanoNewWalletCredentials extends WalletCredentials {
|
||||
NanoNewWalletCredentials({required String name, String? password})
|
||||
: super(name: name, password: password);
|
||||
NanoNewWalletCredentials({
|
||||
required String name,
|
||||
String? password,
|
||||
DerivationType? derivationType,
|
||||
}) : super(
|
||||
name: name,
|
||||
password: password,
|
||||
derivationInfo: DerivationInfo(derivationType: derivationType),
|
||||
);
|
||||
}
|
||||
|
||||
class NanoRestoreWalletFromSeedCredentials extends WalletCredentials {
|
||||
|
@ -14,11 +21,13 @@ class NanoRestoreWalletFromSeedCredentials extends WalletCredentials {
|
|||
String? password,
|
||||
DerivationType? derivationType,
|
||||
}) : super(
|
||||
name: name,
|
||||
password: password,
|
||||
height: height,
|
||||
derivationType: derivationType,
|
||||
);
|
||||
name: name,
|
||||
password: password,
|
||||
height: height,
|
||||
derivationInfo: DerivationInfo(
|
||||
derivationType: derivationType,
|
||||
height: height,
|
||||
));
|
||||
|
||||
final String mnemonic;
|
||||
}
|
||||
|
|
|
@ -28,11 +28,12 @@ class NanoWalletService extends WalletService<NanoNewWalletCredentials,
|
|||
@override
|
||||
Future<WalletBase> create(NanoNewWalletCredentials credentials) async {
|
||||
// nano standard:
|
||||
DerivationType derivationType = DerivationType.nano;
|
||||
String seedKey = NanoSeeds.generateSeed();
|
||||
String mnemonic = NanoUtil.seedToMnemonic(seedKey);
|
||||
|
||||
credentials.walletInfo!.derivationType = derivationType;
|
||||
// set default if not present:
|
||||
DerivationType derivationType = credentials.derivationInfo?.derivationType ?? DerivationType.nano;
|
||||
credentials.walletInfo!.derivationInfo ??= DerivationInfo(derivationType: derivationType);
|
||||
|
||||
final wallet = NanoWallet(
|
||||
walletInfo: credentials.walletInfo!,
|
||||
|
@ -88,7 +89,7 @@ class NanoWalletService extends WalletService<NanoNewWalletCredentials,
|
|||
}
|
||||
|
||||
DerivationType derivationType = credentials.derivationType ?? DerivationType.nano;
|
||||
credentials.walletInfo!.derivationType = derivationType;
|
||||
credentials.walletInfo!.derivationInfo ??= DerivationInfo(derivationType: derivationType);
|
||||
|
||||
String? mnemonic;
|
||||
|
||||
|
@ -127,9 +128,10 @@ class NanoWalletService extends WalletService<NanoNewWalletCredentials,
|
|||
}
|
||||
}
|
||||
|
||||
DerivationType derivationType = credentials.derivationType ?? DerivationType.nano;
|
||||
DerivationType derivationType =
|
||||
credentials.walletInfo?.derivationInfo?.derivationType ?? DerivationType.nano;
|
||||
|
||||
credentials.walletInfo!.derivationType = derivationType;
|
||||
credentials.walletInfo!.derivationInfo ??= DerivationInfo(derivationType: derivationType);
|
||||
|
||||
final wallet = await NanoWallet(
|
||||
password: credentials.password!,
|
||||
|
|
|
@ -101,6 +101,10 @@ Future<void> initializeAppConfigs() async {
|
|||
CakeHive.registerAdapter(DerivationTypeAdapter());
|
||||
}
|
||||
|
||||
if (!Hive.isAdapterRegistered(DERIVATION_INFO_TYPE_ID)) {
|
||||
CakeHive.registerAdapter(DerivationInfoAdapter());
|
||||
}
|
||||
|
||||
if (!CakeHive.isAdapterRegistered(WALLET_TYPE_TYPE_ID)) {
|
||||
CakeHive.registerAdapter(WalletTypeAdapter());
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@ class CWNano extends Nano {
|
|||
NanoNewWalletCredentials(
|
||||
name: name,
|
||||
password: password,
|
||||
derivationType: DerivationType.nano,
|
||||
);
|
||||
|
||||
@override
|
||||
|
|
|
@ -110,8 +110,9 @@ class WalletRestorePage extends BasePage {
|
|||
final GlobalKey<WalletRestoreFromSeedFormState> walletRestoreFromSeedFormKey;
|
||||
final GlobalKey<WalletRestoreFromKeysFromState> walletRestoreFromKeysFormKey;
|
||||
final FocusNode _blockHeightFocusNode;
|
||||
DerivationType derivationType = DerivationType.unknown;
|
||||
String? derivationPath = null;
|
||||
// DerivationType derivationType = DerivationType.unknown;
|
||||
// String? derivationPath = null;
|
||||
DerivationInfo? derivationInfo;
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
|
@ -294,8 +295,7 @@ class WalletRestorePage extends BasePage {
|
|||
}
|
||||
}
|
||||
|
||||
credentials['derivationType'] = this.derivationType;
|
||||
credentials['derivationPath'] = this.derivationPath;
|
||||
credentials['derivationInfo'] = this.derivationInfo;
|
||||
credentials['walletType'] = walletRestoreViewModel.type;
|
||||
return credentials;
|
||||
}
|
||||
|
@ -330,10 +330,12 @@ class WalletRestorePage extends BasePage {
|
|||
|
||||
List<DerivationType> derivationTypes =
|
||||
await walletRestoreViewModel.getDerivationTypes(_credentials());
|
||||
DerivationInfo? dInfo;
|
||||
|
||||
if (derivationTypes[0] == DerivationType.unknown || derivationTypes.length > 1) {
|
||||
if (derivationTypes.length > 1) {
|
||||
// push screen to choose the derivation type:
|
||||
List<DerivationInfo> derivations = await walletRestoreViewModel.getDerivationInfo(_credentials());
|
||||
List<DerivationInfo> derivations =
|
||||
await walletRestoreViewModel.getDerivationInfo(_credentials());
|
||||
|
||||
int derivationsWithHistory = 0;
|
||||
int derivationWithHistoryIndex = 0;
|
||||
|
@ -344,33 +346,24 @@ class WalletRestorePage extends BasePage {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
DerivationInfo? derivationInfo;
|
||||
|
||||
if (derivationsWithHistory > 1) {
|
||||
derivationInfo = await Navigator.of(context).pushNamed(Routes.restoreWalletChooseDerivation,
|
||||
dInfo = await Navigator.of(context).pushNamed(Routes.restoreWalletChooseDerivation,
|
||||
arguments: derivations) as DerivationInfo?;
|
||||
} else if (derivationsWithHistory == 1) {
|
||||
derivationInfo = derivations[derivationWithHistoryIndex];
|
||||
} else if (derivationsWithHistory == 0) {
|
||||
// default derivation:
|
||||
derivationInfo = DerivationInfo(
|
||||
derivationType: derivationTypes[0],
|
||||
derivationPath: "m/0'/1",
|
||||
height: 0,
|
||||
);
|
||||
dInfo = derivations[derivationWithHistoryIndex];
|
||||
}
|
||||
|
||||
if (derivationInfo == null) {
|
||||
if (dInfo == null) {
|
||||
walletRestoreViewModel.state = InitialExecutionState();
|
||||
return;
|
||||
}
|
||||
this.derivationType = derivationInfo.derivationType;
|
||||
this.derivationPath = derivationInfo.derivationPath;
|
||||
} else {
|
||||
// electrum derivation:
|
||||
this.derivationType = derivationTypes[0];
|
||||
this.derivationPath = "m/0'/1";
|
||||
|
||||
this.derivationInfo = dInfo;
|
||||
}
|
||||
|
||||
// get the default derivation for this wallet type:
|
||||
if (this.derivationInfo == null) {
|
||||
this.derivationInfo = walletRestoreViewModel.getDefaultDerivation();
|
||||
}
|
||||
|
||||
walletRestoreViewModel.state = InitialExecutionState();
|
||||
|
|
|
@ -65,8 +65,7 @@ abstract class WalletCreationVMBase with Store {
|
|||
dirPath: dirPath,
|
||||
address: '',
|
||||
showIntroCakePayCard: (!walletCreationService.typeExists(type)) && type != WalletType.haven,
|
||||
derivationPath: credentials.derivationPath,
|
||||
derivationType: credentials.derivationType,
|
||||
derivationInfo: credentials.derivationInfo,
|
||||
);
|
||||
credentials.walletInfo = walletInfo;
|
||||
final wallet = restoreWallet != null
|
||||
|
|
|
@ -35,21 +35,20 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
|
|||
WalletCredentials getCredentials(dynamic options) {
|
||||
switch (type) {
|
||||
case WalletType.monero:
|
||||
return monero!.createMoneroNewWalletCredentials(
|
||||
name: name, language: options as String);
|
||||
return monero!.createMoneroNewWalletCredentials(name: name, language: options as String);
|
||||
case WalletType.bitcoin:
|
||||
return bitcoin!.createBitcoinNewWalletCredentials(name: name);
|
||||
case WalletType.litecoin:
|
||||
return bitcoin!.createBitcoinNewWalletCredentials(name: name);
|
||||
case WalletType.haven:
|
||||
return haven!.createHavenNewWalletCredentials(
|
||||
name: name, language: options as String);
|
||||
return haven!.createHavenNewWalletCredentials(name: name, language: options as String);
|
||||
case WalletType.ethereum:
|
||||
return ethereum!.createEthereumNewWalletCredentials(name: name);
|
||||
case WalletType.nano:
|
||||
return nano!.createNanoNewWalletCredentials(name: name);
|
||||
default:
|
||||
throw Exception('Unexpected type: ${type.toString()}');;
|
||||
throw Exception('Unexpected type: ${type.toString()}');
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -70,8 +70,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
|||
final password = generateWalletPassword();
|
||||
final height = options['height'] as int? ?? 0;
|
||||
name = options['name'] as String;
|
||||
DerivationType? derivationType = options["derivationType"] as DerivationType?;
|
||||
String? derivationPath = options["derivationPath"] as String?;
|
||||
DerivationInfo? derivationInfo = options["derivationInfo"] as DerivationInfo?;
|
||||
|
||||
if (mode == WalletRestoreMode.seed) {
|
||||
final seed = options['seed'] as String;
|
||||
|
@ -84,8 +83,8 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
|||
name: name,
|
||||
mnemonic: seed,
|
||||
password: password,
|
||||
derivationType: derivationType,
|
||||
derivationPath: derivationPath,
|
||||
derivationType: derivationInfo?.derivationType,
|
||||
derivationPath: derivationInfo?.derivationPath,
|
||||
);
|
||||
case WalletType.litecoin:
|
||||
return bitcoin!.createBitcoinRestoreWalletFromSeedCredentials(
|
||||
|
@ -101,7 +100,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
|||
name: name,
|
||||
mnemonic: seed,
|
||||
password: password,
|
||||
derivationType: derivationType,
|
||||
derivationType: derivationInfo?.derivationType,
|
||||
);
|
||||
default:
|
||||
break;
|
||||
|
@ -223,6 +222,8 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
|||
privateKey: seedKey,
|
||||
node: node,
|
||||
);
|
||||
case WalletType.litecoin:
|
||||
return [DerivationType.electrum2];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -231,6 +232,22 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
|||
return [DerivationType.def];
|
||||
}
|
||||
|
||||
DerivationInfo getDefaultDerivation() {
|
||||
switch (type) {
|
||||
case WalletType.nano:
|
||||
return DerivationInfo(
|
||||
derivationType: DerivationType.nano,
|
||||
);
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.litecoin:
|
||||
default:
|
||||
return DerivationInfo(
|
||||
derivationType: DerivationType.electrum2,
|
||||
derivationPath: "m/0'/1",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<WalletBase> process(WalletCredentials credentials) async {
|
||||
if (mode == WalletRestoreMode.keys) {
|
||||
|
|
Loading…
Reference in a new issue