mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-03-12 09:32:33 +00:00
updates & fixes
This commit is contained in:
parent
2cc115e557
commit
d39ffe5ce1
8 changed files with 126 additions and 111 deletions
|
@ -6,7 +6,7 @@ Map<DerivationType, List<DerivationInfo>> bitcoin_derivations = {
|
|||
derivationType: DerivationType.electrum,
|
||||
derivationPath: "m/0'/0",
|
||||
description: "Electrum",
|
||||
script_type: "p2wpkh",
|
||||
scriptType: "p2wpkh",
|
||||
),
|
||||
],
|
||||
DerivationType.bip39: [
|
||||
|
@ -14,79 +14,79 @@ Map<DerivationType, List<DerivationInfo>> bitcoin_derivations = {
|
|||
derivationType: DerivationType.bip39,
|
||||
derivationPath: "m/44'/0'/0'",
|
||||
description: "Standard BIP44",
|
||||
script_type: "p2pkh",
|
||||
scriptType: "p2pkh",
|
||||
),
|
||||
DerivationInfo(
|
||||
derivationType: DerivationType.bip39,
|
||||
derivationPath: "m/49'/0'/0'",
|
||||
description: "Standard BIP49 compatibility segwit",
|
||||
script_type: "p2wpkh-p2sh",
|
||||
scriptType: "p2wpkh-p2sh",
|
||||
),
|
||||
DerivationInfo(
|
||||
derivationType: DerivationType.bip39,
|
||||
derivationPath: "m/84'/0'/0'",
|
||||
description: "Standard BIP84 native segwit",
|
||||
script_type: "p2wpkh",
|
||||
scriptType: "p2wpkh",
|
||||
),
|
||||
DerivationInfo(
|
||||
derivationType: DerivationType.bip39,
|
||||
derivationPath: "m/0'",
|
||||
description: "Non-standard legacy",
|
||||
script_type: "p2pkh",
|
||||
scriptType: "p2pkh",
|
||||
),
|
||||
DerivationInfo(
|
||||
derivationType: DerivationType.bip39,
|
||||
derivationPath: "m/0'",
|
||||
description: "Non-standard compatibility segwit",
|
||||
script_type: "p2wpkh-p2sh",
|
||||
scriptType: "p2wpkh-p2sh",
|
||||
),
|
||||
DerivationInfo(
|
||||
derivationType: DerivationType.bip39,
|
||||
derivationPath: "m/0'",
|
||||
description: "Non-standard native segwit",
|
||||
script_type: "p2wpkh",
|
||||
scriptType: "p2wpkh",
|
||||
),
|
||||
DerivationInfo(
|
||||
derivationType: DerivationType.bip39,
|
||||
derivationPath: "m/44'/0'/0'",
|
||||
description: "Copay native segwit",
|
||||
script_type: "p2wpkh",
|
||||
scriptType: "p2wpkh",
|
||||
),
|
||||
DerivationInfo(
|
||||
derivationType: DerivationType.bip39,
|
||||
derivationPath: "m/84'/0'/2147483644'",
|
||||
description: "Samourai Bad Bank (toxic change)",
|
||||
script_type: "p2wpkh",
|
||||
scriptType: "p2wpkh",
|
||||
),
|
||||
DerivationInfo(
|
||||
derivationType: DerivationType.bip39,
|
||||
derivationPath: "m/84'/0'/2147483645'",
|
||||
description: "Samourai Whirlpool Pre Mix",
|
||||
script_type: "p2wpkh",
|
||||
scriptType: "p2wpkh",
|
||||
),
|
||||
DerivationInfo(
|
||||
derivationType: DerivationType.bip39,
|
||||
derivationPath: "m/84'/0'/2147483646'",
|
||||
description: "Samourai Whirlpool Post Mix",
|
||||
script_type: "p2wpkh",
|
||||
scriptType: "p2wpkh",
|
||||
),
|
||||
DerivationInfo(
|
||||
derivationType: DerivationType.bip39,
|
||||
derivationPath: "m/44'/0'/2147483647'",
|
||||
description: "Samourai Ricochet legacy",
|
||||
script_type: "p2pkh",
|
||||
scriptType: "p2pkh",
|
||||
),
|
||||
DerivationInfo(
|
||||
derivationType: DerivationType.bip39,
|
||||
derivationPath: "m/49'/0'/2147483647'",
|
||||
description: "Samourai Ricochet compatibility segwit",
|
||||
script_type: "p2wpkh-p2sh",
|
||||
scriptType: "p2wpkh-p2sh",
|
||||
),
|
||||
DerivationInfo(
|
||||
derivationType: DerivationType.bip39,
|
||||
derivationPath: "m/84'/0'/2147483647'",
|
||||
description: "Samourai Ricochet native segwit",
|
||||
script_type: "p2wpkh",
|
||||
scriptType: "p2wpkh",
|
||||
),
|
||||
],
|
||||
};
|
||||
|
|
|
@ -97,9 +97,6 @@ Future<String> generateElectrumMnemonic({int strength = 264, String prefix = seg
|
|||
var result = '';
|
||||
|
||||
do {
|
||||
// final originalBytes = await secRandom(byteCount);
|
||||
// // create a modifiable copy, however I'm not sure why this is necessary
|
||||
// final bytes = Uint8List.fromList(originalBytes);
|
||||
final bytes = await secRandom(byteCount);
|
||||
maskBytes(bytes, strength);
|
||||
result = encode(bytes);
|
||||
|
|
|
@ -45,23 +45,19 @@ 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)
|
||||
String derivationPath = walletInfo.derivationInfo!.derivationPath!;
|
||||
String sideDerivationPath = derivationPath.substring(0, derivationPath.length - 1) + "1";
|
||||
final hd = bitcoin.HDWallet.fromSeed(seedBytes, network: networkType);
|
||||
walletAddresses = BitcoinWalletAddresses(
|
||||
walletInfo,
|
||||
electrumClient: electrumClient,
|
||||
initialAddresses: initialAddresses,
|
||||
initialRegularAddressIndex: initialRegularAddressIndex,
|
||||
initialChangeAddressIndex: initialChangeAddressIndex,
|
||||
// mainHd: hd,
|
||||
// sideHd: bitcoin.HDWallet.fromSeed(seedBytes, network: networkType).derivePath("m/0'/1"),
|
||||
mainHd: bitcoin.HDWallet.fromSeed(seedBytes, network: networkType)
|
||||
.derivePath(walletInfo.derivationInfo!.derivationPath!),
|
||||
sideHd: bitcoin.HDWallet.fromSeed(seedBytes, network: networkType).derivePath(walletInfo
|
||||
.derivationInfo!.derivationPath!
|
||||
.substring(0, walletInfo.derivationInfo!.derivationPath!.length - 1) +
|
||||
"1"),
|
||||
mainHd: hd.derivePath(derivationPath),
|
||||
sideHd: hd.derivePath(sideDerivationPath),
|
||||
network: networkParam ?? network,
|
||||
);
|
||||
autorun((_) {
|
||||
|
@ -69,7 +65,6 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
static Future<BitcoinWallet> create({
|
||||
required String mnemonic,
|
||||
required String password,
|
||||
|
@ -82,7 +77,6 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
|
|||
Map<String, int>? initialRegularAddressIndex,
|
||||
Map<String, int>? initialChangeAddressIndex,
|
||||
}) async {
|
||||
|
||||
late Uint8List seedBytes;
|
||||
|
||||
switch (walletInfo.derivationInfo?.derivationType) {
|
||||
|
|
|
@ -5,29 +5,58 @@ import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
|
|||
import 'package:bitcoin_flutter/src/payments/index.dart' show PaymentData;
|
||||
import 'package:hex/hex.dart';
|
||||
|
||||
bitcoin.PaymentData generatePaymentData({required bitcoin.HDWallet hd, required int index}) =>
|
||||
PaymentData(pubkey: Uint8List.fromList(HEX.decode(hd.derive(index).pubKey!)));
|
||||
bitcoin.PaymentData generatePaymentData({required bitcoin.HDWallet hd, int? index}) {
|
||||
final pubKey = index != null ? hd.derive(index).pubKey! : hd.pubKey!;
|
||||
return PaymentData(pubkey: Uint8List.fromList(HEX.decode(pubKey)));
|
||||
}
|
||||
|
||||
ECPrivate generateECPrivate(
|
||||
{required bitcoin.HDWallet hd, required int index, required BasedUtxoNetwork network}) =>
|
||||
ECPrivate.fromWif(hd.derive(index).wif!, netVersion: network.wifNetVer);
|
||||
{required bitcoin.HDWallet hd, required BasedUtxoNetwork network, int? index}) {
|
||||
final wif = index != null ? hd.derive(index).wif! : hd.wif!;
|
||||
return ECPrivate.fromWif(wif, netVersion: network.wifNetVer);
|
||||
}
|
||||
|
||||
String generateP2WPKHAddress(
|
||||
{required bitcoin.HDWallet hd, required int index, required BasedUtxoNetwork network}) =>
|
||||
ECPublic.fromHex(hd.derive(index).pubKey!).toP2wpkhAddress().toAddress(network);
|
||||
String generateP2WPKHAddress({
|
||||
required bitcoin.HDWallet hd,
|
||||
required BasedUtxoNetwork network,
|
||||
int? index,
|
||||
}) {
|
||||
final pubKey = index != null ? hd.derive(index).pubKey! : hd.pubKey!;
|
||||
return ECPublic.fromHex(pubKey).toP2wpkhAddress().toAddress(network);
|
||||
}
|
||||
|
||||
String generateP2SHAddress(
|
||||
{required bitcoin.HDWallet hd, required int index, required BasedUtxoNetwork network}) =>
|
||||
ECPublic.fromHex(hd.derive(index).pubKey!).toP2wpkhInP2sh().toAddress(network);
|
||||
String generateP2SHAddress({
|
||||
required bitcoin.HDWallet hd,
|
||||
required BasedUtxoNetwork network,
|
||||
int? index,
|
||||
}) {
|
||||
final pubKey = index != null ? hd.derive(index).pubKey! : hd.pubKey!;
|
||||
return ECPublic.fromHex(pubKey).toP2wpkhInP2sh().toAddress(network);
|
||||
}
|
||||
|
||||
String generateP2WSHAddress(
|
||||
{required bitcoin.HDWallet hd, required int index, required BasedUtxoNetwork network}) =>
|
||||
ECPublic.fromHex(hd.derive(index).pubKey!).toP2wshAddress().toAddress(network);
|
||||
String generateP2WSHAddress({
|
||||
required bitcoin.HDWallet hd,
|
||||
required BasedUtxoNetwork network,
|
||||
int? index,
|
||||
}) {
|
||||
final pubKey = index != null ? hd.derive(index).pubKey! : hd.pubKey!;
|
||||
return ECPublic.fromHex(pubKey).toP2wshAddress().toAddress(network);
|
||||
}
|
||||
|
||||
String generateP2PKHAddress(
|
||||
{required bitcoin.HDWallet hd, required int index, required BasedUtxoNetwork network}) =>
|
||||
ECPublic.fromHex(hd.derive(index).pubKey!).toP2pkhAddress().toAddress(network);
|
||||
String generateP2PKHAddress({
|
||||
required bitcoin.HDWallet hd,
|
||||
required BasedUtxoNetwork network,
|
||||
int? index,
|
||||
}) {
|
||||
final pubKey = index != null ? hd.derive(index).pubKey! : hd.pubKey!;
|
||||
return ECPublic.fromHex(pubKey).toP2pkhAddress().toAddress(network);
|
||||
}
|
||||
|
||||
String generateP2TRAddress(
|
||||
{required bitcoin.HDWallet hd, required int index, required BasedUtxoNetwork network}) =>
|
||||
ECPublic.fromHex(hd.derive(index).pubKey!).toTaprootAddress().toAddress(network);
|
||||
String generateP2TRAddress({
|
||||
required bitcoin.HDWallet hd,
|
||||
required BasedUtxoNetwork network,
|
||||
int? index,
|
||||
}) {
|
||||
final pubKey = index != null ? hd.derive(index).pubKey! : hd.pubKey!;
|
||||
return ECPublic.fromHex(pubKey).toTaprootAddress().toAddress(network);
|
||||
}
|
||||
|
|
|
@ -27,18 +27,32 @@ class DerivationInfo extends HiveObject {
|
|||
this.balance = "",
|
||||
this.address = "",
|
||||
this.transactionsCount = 0,
|
||||
this.script_type,
|
||||
this.scriptType,
|
||||
this.description,
|
||||
});
|
||||
|
||||
static const typeId = DERIVATION_INFO_TYPE_ID;
|
||||
|
||||
String balance;
|
||||
|
||||
@HiveField(0)
|
||||
String address;
|
||||
|
||||
@HiveField(1)
|
||||
String balance;
|
||||
|
||||
@HiveField(2)
|
||||
int transactionsCount;
|
||||
|
||||
@HiveField(3)
|
||||
DerivationType? derivationType;
|
||||
|
||||
@HiveField(4)
|
||||
String? derivationPath;
|
||||
final String? script_type;
|
||||
|
||||
@HiveField(5)
|
||||
final String? scriptType;
|
||||
|
||||
@HiveField(6)
|
||||
final String? description;
|
||||
}
|
||||
|
||||
|
|
|
@ -284,6 +284,20 @@ class CWBitcoin extends Bitcoin {
|
|||
final electrumClient = ElectrumClient();
|
||||
await electrumClient.connectToUri(node.uri);
|
||||
|
||||
late BasedUtxoNetwork network;
|
||||
btc.NetworkType networkType;
|
||||
switch (node.type) {
|
||||
case WalletType.litecoin:
|
||||
network = LitecoinNetwork.mainnet;
|
||||
networkType = litecoinNetwork;
|
||||
break;
|
||||
case WalletType.bitcoin:
|
||||
default:
|
||||
network = BitcoinNetwork.mainnet;
|
||||
networkType = btc.bitcoin;
|
||||
break;
|
||||
}
|
||||
|
||||
for (DerivationType dType in bitcoin_derivations.keys) {
|
||||
late Uint8List seedBytes;
|
||||
if (dType == DerivationType.electrum) {
|
||||
|
@ -298,80 +312,47 @@ class CWBitcoin extends Bitcoin {
|
|||
derivationType: dInfo.derivationType,
|
||||
derivationPath: dInfo.derivationPath,
|
||||
description: dInfo.description,
|
||||
script_type: dInfo.script_type,
|
||||
scriptType: dInfo.scriptType,
|
||||
);
|
||||
var hd = bip32.BIP32.fromSeed(seedBytes);
|
||||
|
||||
String derivationPath = dInfoCopy.derivationPath!;
|
||||
int derivationDepth = _countOccurrences(derivationPath, "/");
|
||||
|
||||
// the correct derivation depth is dependant on the derivation type:
|
||||
// the derivation paths defined in bitcoin_derivations are at the ROOT level, i.e.:
|
||||
// electrum's format doesn't specify subaddresses, just subaccounts:
|
||||
|
||||
// for BIP44
|
||||
if (derivationDepth == 3) {
|
||||
// we add "/0/0" so that we generate account 0, index 0 and correctly get balance
|
||||
derivationPath += "/0/0";
|
||||
// we don't support sub-ACCOUNTS in bitcoin like we do monero, and so the path dInfoCopy
|
||||
// expects should be ACCOUNT 0, index unspecified:
|
||||
dInfoCopy.derivationPath = dInfoCopy.derivationPath! + "/0";
|
||||
}
|
||||
hd = hd.derivePath(derivationPath);
|
||||
|
||||
// var hd = btc.HDWallet.fromSeed(
|
||||
// seedBytes,
|
||||
// network: node.type == WalletType.bitcoin ? btc.bitcoin : litecoinNetwork,
|
||||
// ).derivePath(dInfoCopy.derivationPath!);
|
||||
|
||||
// if (addressType == P2pkhAddressType.p2pkh)
|
||||
// return generateP2PKHAddress(hd: hd, index: index, network: network);
|
||||
//
|
||||
// if (addressType == SegwitAddresType.p2tr)
|
||||
// return generateP2TRAddress(hd: hd, index: index, network: network);
|
||||
//
|
||||
// if (addressType == SegwitAddresType.p2wsh)
|
||||
// return generateP2WSHAddress(hd: hd, index: index, network: network);
|
||||
//
|
||||
// if (addressType == P2shAddressType.p2wpkhInP2sh)
|
||||
// return generateP2SHAddress(hd: hd, index: index, network: network);
|
||||
// var hd = bip32.BIP32.fromSeed(seedBytes).derivePath(derivationPath);
|
||||
final hd = btc.HDWallet.fromSeed(
|
||||
seedBytes,
|
||||
network: networkType,
|
||||
).derivePath(derivationPath);
|
||||
|
||||
String? address;
|
||||
switch (dInfoCopy.script_type) {
|
||||
switch (dInfoCopy.scriptType) {
|
||||
case "p2wpkh":
|
||||
// address = generateP2WPKHAddress(
|
||||
// hd: hd,
|
||||
// index: 0,
|
||||
// network: node.type == WalletType.bitcoin
|
||||
// ? BitcoinNetwork.mainnet
|
||||
// : LitecoinNetwork.mainnet);
|
||||
address = btc
|
||||
.P2WPKH(
|
||||
data: new btc.PaymentData(pubkey: hd.publicKey),
|
||||
network: btc.bitcoin,
|
||||
)
|
||||
.data
|
||||
.address;
|
||||
address = generateP2WPKHAddress(hd: hd, network: network);
|
||||
break;
|
||||
case "p2pkh":
|
||||
// address = generateP2PKHAddress(
|
||||
// hd: hd,
|
||||
// index: 0,
|
||||
// network: node.type == WalletType.bitcoin
|
||||
// ? BitcoinNetwork.mainnet
|
||||
// : LitecoinNetwork.mainnet);
|
||||
address = btc
|
||||
.P2PKH(
|
||||
data: new btc.PaymentData(pubkey: hd.publicKey),
|
||||
network: btc.bitcoin,
|
||||
)
|
||||
.data
|
||||
.address;
|
||||
address = generateP2PKHAddress(hd: hd, network: network);
|
||||
break;
|
||||
case "p2wpkh-p2sh":
|
||||
address = generateP2SHAddress(hd: hd, network: network);
|
||||
break;
|
||||
// case "p2wpkh-p2sh":
|
||||
// address = generateP2SHAddress(
|
||||
// hd: hd,
|
||||
// index: 0,
|
||||
// network: node.type == WalletType.bitcoin
|
||||
// ? BitcoinNetwork.mainnet
|
||||
// : LitecoinNetwork.mainnet);
|
||||
// break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
final sh = scriptHash(address!, network: BitcoinNetwork.mainnet);
|
||||
final sh = scriptHash(address, network: network);
|
||||
final history = await electrumClient.getHistory(sh);
|
||||
|
||||
final balance = await electrumClient.getBalance(sh);
|
||||
|
@ -388,7 +369,6 @@ class CWBitcoin extends Bitcoin {
|
|||
|
||||
// sort the list such that derivations with the most transactions are first:
|
||||
list.sort((a, b) => b.transactionsCount.compareTo(a.transactionsCount));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
|
|
@ -113,10 +113,10 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
|||
name: name, mnemonic: seed, password: password);
|
||||
case WalletType.nano:
|
||||
return nano!.createNanoRestoreWalletFromSeedCredentials(
|
||||
name: name,
|
||||
mnemonic: seed,
|
||||
password: password,
|
||||
derivationType: derivationInfo!.derivationType!,
|
||||
name: name,
|
||||
mnemonic: seed,
|
||||
password: password,
|
||||
derivationType: derivationInfo!.derivationType!,
|
||||
);
|
||||
case WalletType.polygon:
|
||||
return polygon!.createPolygonRestoreWalletFromSeedCredentials(
|
||||
|
@ -274,7 +274,6 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
|||
if (mode == WalletRestoreMode.keys) {
|
||||
return walletCreationService.restoreFromKeys(credentials, isTestnet: useTestnet);
|
||||
}
|
||||
|
||||
return walletCreationService.restoreFromSeed(credentials, isTestnet: useTestnet);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,6 +82,8 @@ import 'package:bip39/bip39.dart' as bip39;
|
|||
import 'package:hive/hive.dart';
|
||||
""";
|
||||
const bitcoinCWHeaders = """
|
||||
import 'package:cw_bitcoin/utils.dart';
|
||||
import 'package:cw_bitcoin/litecoin_network.dart';
|
||||
import 'package:cw_bitcoin/bitcoin_derivations.dart';
|
||||
import 'package:cw_bitcoin/electrum.dart';
|
||||
import 'package:cw_bitcoin/pending_bitcoin_transaction.dart';
|
||||
|
|
Loading…
Reference in a new issue