mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-31 06:55:59 +00:00
feat: store labeled silent addresses and restore from snapshot
This commit is contained in:
parent
5939b310a0
commit
b04b262761
5 changed files with 61 additions and 23 deletions
|
@ -26,9 +26,11 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
||||||
bitcoin.NetworkType? networkType,
|
bitcoin.NetworkType? networkType,
|
||||||
required Uint8List seedBytes,
|
required Uint8List seedBytes,
|
||||||
List<BitcoinAddressRecord>? initialAddresses,
|
List<BitcoinAddressRecord>? initialAddresses,
|
||||||
|
List<BitcoinAddressRecord>? initialSilentAddresses,
|
||||||
ElectrumBalance? initialBalance,
|
ElectrumBalance? initialBalance,
|
||||||
int initialRegularAddressIndex = 0,
|
int initialRegularAddressIndex = 0,
|
||||||
int initialChangeAddressIndex = 0,
|
int initialChangeAddressIndex = 0,
|
||||||
|
int initialSilentAddressIndex = 0,
|
||||||
bitcoin.SilentPaymentReceiver? silentAddress})
|
bitcoin.SilentPaymentReceiver? silentAddress})
|
||||||
: super(
|
: super(
|
||||||
networkType: networkType ?? bitcoin.bitcoin,
|
networkType: networkType ?? bitcoin.bitcoin,
|
||||||
|
@ -41,24 +43,29 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
||||||
walletAddresses = BitcoinWalletAddresses(walletInfo,
|
walletAddresses = BitcoinWalletAddresses(walletInfo,
|
||||||
transactionHistory: super.transactionHistory,
|
transactionHistory: super.transactionHistory,
|
||||||
initialAddresses: initialAddresses,
|
initialAddresses: initialAddresses,
|
||||||
|
initialSilentAddresses: initialSilentAddresses,
|
||||||
initialRegularAddressIndex: initialRegularAddressIndex,
|
initialRegularAddressIndex: initialRegularAddressIndex,
|
||||||
initialChangeAddressIndex: initialChangeAddressIndex,
|
initialChangeAddressIndex: initialChangeAddressIndex,
|
||||||
|
initialSilentAddressIndex: initialSilentAddressIndex,
|
||||||
mainHd: hd,
|
mainHd: hd,
|
||||||
sideHd: bitcoin.HDWallet.fromSeed(seedBytes, network: networkType).derivePath("m/0'/1"),
|
sideHd: bitcoin.HDWallet.fromSeed(seedBytes, network: networkType).derivePath("m/0'/1"),
|
||||||
networkType: networkType ?? bitcoin.bitcoin,
|
networkType: networkType ?? bitcoin.bitcoin,
|
||||||
silentAddress: silentAddress);
|
silentAddress: silentAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<BitcoinWallet> create(
|
static Future<BitcoinWallet> create({
|
||||||
{required String mnemonic,
|
required String mnemonic,
|
||||||
required String password,
|
required String password,
|
||||||
required WalletInfo walletInfo,
|
required WalletInfo walletInfo,
|
||||||
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
required Box<UnspentCoinsInfo> unspentCoinsInfo,
|
||||||
bitcoin.NetworkType? networkType,
|
bitcoin.NetworkType? networkType,
|
||||||
List<BitcoinAddressRecord>? initialAddresses,
|
List<BitcoinAddressRecord>? initialAddresses,
|
||||||
|
List<BitcoinAddressRecord>? initialSilentAddresses,
|
||||||
ElectrumBalance? initialBalance,
|
ElectrumBalance? initialBalance,
|
||||||
int initialRegularAddressIndex = 0,
|
int initialRegularAddressIndex = 0,
|
||||||
int initialChangeAddressIndex = 0}) async {
|
int initialChangeAddressIndex = 0,
|
||||||
|
int initialSilentAddressIndex = 0,
|
||||||
|
}) async {
|
||||||
return BitcoinWallet(
|
return BitcoinWallet(
|
||||||
mnemonic: mnemonic,
|
mnemonic: mnemonic,
|
||||||
password: password,
|
password: password,
|
||||||
|
@ -66,10 +73,12 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
||||||
unspentCoinsInfo: unspentCoinsInfo,
|
unspentCoinsInfo: unspentCoinsInfo,
|
||||||
networkType: networkType,
|
networkType: networkType,
|
||||||
initialAddresses: initialAddresses,
|
initialAddresses: initialAddresses,
|
||||||
|
initialSilentAddresses: initialSilentAddresses,
|
||||||
initialBalance: initialBalance,
|
initialBalance: initialBalance,
|
||||||
seedBytes: await mnemonicToSeedBytes(mnemonic),
|
seedBytes: await mnemonicToSeedBytes(mnemonic),
|
||||||
initialRegularAddressIndex: initialRegularAddressIndex,
|
initialRegularAddressIndex: initialRegularAddressIndex,
|
||||||
initialChangeAddressIndex: initialChangeAddressIndex,
|
initialChangeAddressIndex: initialChangeAddressIndex,
|
||||||
|
initialSilentAddressIndex: initialSilentAddressIndex,
|
||||||
silentAddress: await bitcoin.SilentPaymentReceiver.fromMnemonic(mnemonic,
|
silentAddress: await bitcoin.SilentPaymentReceiver.fromMnemonic(mnemonic,
|
||||||
hrp: networkType == bitcoin.bitcoin ? 'sp' : 'tsp'));
|
hrp: networkType == bitcoin.bitcoin ? 'sp' : 'tsp'));
|
||||||
}
|
}
|
||||||
|
@ -88,10 +97,12 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
||||||
unspentCoinsInfo: unspentCoinsInfo,
|
unspentCoinsInfo: unspentCoinsInfo,
|
||||||
networkType: snp.networkType,
|
networkType: snp.networkType,
|
||||||
initialAddresses: snp.addresses,
|
initialAddresses: snp.addresses,
|
||||||
|
initialSilentAddresses: snp.silentAddresses,
|
||||||
initialBalance: snp.balance,
|
initialBalance: snp.balance,
|
||||||
seedBytes: await mnemonicToSeedBytes(snp.mnemonic),
|
seedBytes: await mnemonicToSeedBytes(snp.mnemonic),
|
||||||
initialRegularAddressIndex: snp.regularAddressIndex,
|
initialRegularAddressIndex: snp.regularAddressIndex,
|
||||||
initialChangeAddressIndex: snp.changeAddressIndex,
|
initialChangeAddressIndex: snp.changeAddressIndex,
|
||||||
|
initialSilentAddressIndex: snp.silentAddressIndex,
|
||||||
silentAddress: await bitcoin.SilentPaymentReceiver.fromMnemonic(snp.mnemonic,
|
silentAddress: await bitcoin.SilentPaymentReceiver.fromMnemonic(snp.mnemonic,
|
||||||
hrp: snp.networkType == bitcoin.bitcoin ? 'sp' : 'tsp'));
|
hrp: snp.networkType == bitcoin.bitcoin ? 'sp' : 'tsp'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,10 @@ abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses with S
|
||||||
required super.networkType,
|
required super.networkType,
|
||||||
required super.transactionHistory,
|
required super.transactionHistory,
|
||||||
super.initialAddresses,
|
super.initialAddresses,
|
||||||
|
super.initialSilentAddresses,
|
||||||
super.initialRegularAddressIndex = 0,
|
super.initialRegularAddressIndex = 0,
|
||||||
super.initialChangeAddressIndex = 0,
|
super.initialChangeAddressIndex = 0,
|
||||||
|
super.initialSilentAddressIndex = 0,
|
||||||
super.silentAddress,
|
super.silentAddress,
|
||||||
}) : super(walletInfo);
|
}) : super(walletInfo);
|
||||||
|
|
||||||
|
|
|
@ -533,7 +533,9 @@ abstract class ElectrumWalletBase
|
||||||
'mnemonic': mnemonic,
|
'mnemonic': mnemonic,
|
||||||
'account_index': walletAddresses.currentReceiveAddressIndex.toString(),
|
'account_index': walletAddresses.currentReceiveAddressIndex.toString(),
|
||||||
'change_address_index': walletAddresses.currentChangeAddressIndex.toString(),
|
'change_address_index': walletAddresses.currentChangeAddressIndex.toString(),
|
||||||
|
'silent_address_index': walletAddresses.currentSilentAddressIndex.toString(),
|
||||||
'addresses': walletAddresses.addresses.map((addr) => addr.toJSON()).toList(),
|
'addresses': walletAddresses.addresses.map((addr) => addr.toJSON()).toList(),
|
||||||
|
'silent_addresses': walletAddresses.silentAddresses.map((addr) => addr.toJSON()).toList(),
|
||||||
'balance': balance[currency]?.toJSON(),
|
'balance': balance[currency]?.toJSON(),
|
||||||
'network_type': networkType == bitcoin.bitcoin ? 'mainnet' : 'testnet',
|
'network_type': networkType == bitcoin.bitcoin ? 'mainnet' : 'testnet',
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,8 +19,10 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||||
required this.transactionHistory,
|
required this.transactionHistory,
|
||||||
required this.networkType,
|
required this.networkType,
|
||||||
List<BitcoinAddressRecord>? initialAddresses,
|
List<BitcoinAddressRecord>? initialAddresses,
|
||||||
|
List<BitcoinAddressRecord>? initialSilentAddresses,
|
||||||
int initialRegularAddressIndex = 0,
|
int initialRegularAddressIndex = 0,
|
||||||
int initialChangeAddressIndex = 0,
|
int initialChangeAddressIndex = 0,
|
||||||
|
int initialSilentAddressIndex = 0,
|
||||||
bitcoin.SilentPaymentReceiver? silentAddress,
|
bitcoin.SilentPaymentReceiver? silentAddress,
|
||||||
}) : addresses = ObservableList<BitcoinAddressRecord>.of((initialAddresses ?? []).toSet()),
|
}) : addresses = ObservableList<BitcoinAddressRecord>.of((initialAddresses ?? []).toSet()),
|
||||||
primarySilentAddress = silentAddress,
|
primarySilentAddress = silentAddress,
|
||||||
|
@ -30,11 +32,14 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||||
changeAddresses = ObservableList<BitcoinAddressRecord>.of((initialAddresses ?? [])
|
changeAddresses = ObservableList<BitcoinAddressRecord>.of((initialAddresses ?? [])
|
||||||
.where((addressRecord) => addressRecord.isHidden && !addressRecord.isUsed)
|
.where((addressRecord) => addressRecord.isHidden && !addressRecord.isUsed)
|
||||||
.toSet()),
|
.toSet()),
|
||||||
silentAddresses = ObservableList<BitcoinAddressRecord>.of((initialAddresses ?? [])
|
silentAddresses = ObservableList<BitcoinAddressRecord>.of((initialSilentAddresses ?? [])
|
||||||
.where((addressRecord) => addressRecord.silentAddressLabel != null)
|
.where((addressRecord) =>
|
||||||
|
addressRecord.silentAddressLabel != null &&
|
||||||
|
addressRecord.silentPaymentTweak != null)
|
||||||
.toSet()),
|
.toSet()),
|
||||||
currentReceiveAddressIndex = initialRegularAddressIndex,
|
currentReceiveAddressIndex = initialRegularAddressIndex,
|
||||||
currentChangeAddressIndex = initialChangeAddressIndex,
|
currentChangeAddressIndex = initialChangeAddressIndex,
|
||||||
|
currentSilentAddressIndex = initialSilentAddressIndex,
|
||||||
super(walletInfo);
|
super(walletInfo);
|
||||||
|
|
||||||
static const defaultReceiveAddressesCount = 22;
|
static const defaultReceiveAddressesCount = 22;
|
||||||
|
@ -106,7 +111,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||||
|
|
||||||
int currentReceiveAddressIndex;
|
int currentReceiveAddressIndex;
|
||||||
int currentChangeAddressIndex;
|
int currentChangeAddressIndex;
|
||||||
int currentSilentAddressIndex = 0;
|
int currentSilentAddressIndex;
|
||||||
|
|
||||||
@computed
|
@computed
|
||||||
int get totalCountOfReceiveAddresses => addresses.fold(0, (acc, addressRecord) {
|
int get totalCountOfReceiveAddresses => addresses.fold(0, (acc, addressRecord) {
|
||||||
|
|
|
@ -13,10 +13,12 @@ class ElectrumWalletSnapshot {
|
||||||
required this.password,
|
required this.password,
|
||||||
required this.mnemonic,
|
required this.mnemonic,
|
||||||
required this.addresses,
|
required this.addresses,
|
||||||
|
required this.silentAddresses,
|
||||||
required this.balance,
|
required this.balance,
|
||||||
required this.networkType,
|
required this.networkType,
|
||||||
required this.regularAddressIndex,
|
required this.regularAddressIndex,
|
||||||
required this.changeAddressIndex,
|
required this.changeAddressIndex,
|
||||||
|
required this.silentAddressIndex,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String name;
|
final String name;
|
||||||
|
@ -25,30 +27,43 @@ class ElectrumWalletSnapshot {
|
||||||
|
|
||||||
String mnemonic;
|
String mnemonic;
|
||||||
List<BitcoinAddressRecord> addresses;
|
List<BitcoinAddressRecord> addresses;
|
||||||
|
List<BitcoinAddressRecord> silentAddresses;
|
||||||
ElectrumBalance balance;
|
ElectrumBalance balance;
|
||||||
bitcoin.NetworkType networkType;
|
bitcoin.NetworkType networkType;
|
||||||
int regularAddressIndex;
|
int regularAddressIndex;
|
||||||
int changeAddressIndex;
|
int changeAddressIndex;
|
||||||
|
int silentAddressIndex;
|
||||||
|
|
||||||
static Future<ElectrumWalletSnapshot> load(String name, WalletType type, String password) async {
|
static Future<ElectrumWalletSnapshot> load(String name, WalletType type, String password) async {
|
||||||
final path = await pathForWallet(name: name, type: type);
|
final path = await pathForWallet(name: name, type: type);
|
||||||
final jsonSource = await read(path: path, password: password);
|
final jsonSource = await read(path: path, password: password);
|
||||||
final data = json.decode(jsonSource) as Map;
|
final data = json.decode(jsonSource) as Map;
|
||||||
final addressesTmp = data['addresses'] as List? ?? <Object>[];
|
|
||||||
final mnemonic = data['mnemonic'] as String;
|
final mnemonic = data['mnemonic'] as String;
|
||||||
|
|
||||||
|
final addressesTmp = data['addresses'] as List? ?? <Object>[];
|
||||||
final addresses = addressesTmp
|
final addresses = addressesTmp
|
||||||
.whereType<String>()
|
.whereType<String>()
|
||||||
.map((addr) => BitcoinAddressRecord.fromJSON(addr))
|
.map((addr) => BitcoinAddressRecord.fromJSON(addr))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
|
final silentAddressesTmp = data['silent_addresses'] as List? ?? <Object>[];
|
||||||
|
final silentAddresses = silentAddressesTmp
|
||||||
|
.whereType<String>()
|
||||||
|
.map((addr) => BitcoinAddressRecord.fromJSON(addr))
|
||||||
|
.toList();
|
||||||
|
|
||||||
final balance = ElectrumBalance.fromJSON(data['balance'] as String) ??
|
final balance = ElectrumBalance.fromJSON(data['balance'] as String) ??
|
||||||
ElectrumBalance(confirmed: 0, unconfirmed: 0, frozen: 0);
|
ElectrumBalance(confirmed: 0, unconfirmed: 0, frozen: 0);
|
||||||
final networkType = data['network_type'] == 'testnet' ? bitcoin.testnet : bitcoin.bitcoin;
|
final networkType = data['network_type'] == 'testnet' ? bitcoin.testnet : bitcoin.bitcoin;
|
||||||
|
|
||||||
var regularAddressIndex = 0;
|
var regularAddressIndex = 0;
|
||||||
var changeAddressIndex = 0;
|
var changeAddressIndex = 0;
|
||||||
|
var silentAddressIndex = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
regularAddressIndex = int.parse(data['account_index'] as String? ?? '0');
|
regularAddressIndex = int.parse(data['account_index'] as String? ?? '0');
|
||||||
changeAddressIndex = int.parse(data['change_address_index'] as String? ?? '0');
|
changeAddressIndex = int.parse(data['change_address_index'] as String? ?? '0');
|
||||||
|
silentAddressIndex = int.parse(data['silent_address_index'] as String? ?? '0');
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
|
|
||||||
return ElectrumWalletSnapshot(
|
return ElectrumWalletSnapshot(
|
||||||
|
@ -57,9 +72,12 @@ class ElectrumWalletSnapshot {
|
||||||
password: password,
|
password: password,
|
||||||
mnemonic: mnemonic,
|
mnemonic: mnemonic,
|
||||||
addresses: addresses,
|
addresses: addresses,
|
||||||
|
silentAddresses: silentAddresses,
|
||||||
balance: balance,
|
balance: balance,
|
||||||
networkType: networkType,
|
networkType: networkType,
|
||||||
regularAddressIndex: regularAddressIndex,
|
regularAddressIndex: regularAddressIndex,
|
||||||
changeAddressIndex: changeAddressIndex);
|
changeAddressIndex: changeAddressIndex,
|
||||||
|
silentAddressIndex: silentAddressIndex,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue