derivation fixes

This commit is contained in:
fosse 2023-09-05 12:04:19 -04:00
parent 1eca22fc5e
commit 0984dbc3d7
4 changed files with 68 additions and 50 deletions

View file

@ -1,12 +1,20 @@
import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/wallet_info.dart';
Map<DerivationType, List<DerivationInfo>> bitcoin_derivations = { Map<DerivationType, List<DerivationInfo>> bitcoin_derivations = {
DerivationType.bip39: [ DerivationType.electrum2: [
DerivationInfo( DerivationInfo(
derivationType: DerivationType.bip39, derivationType: DerivationType.bip39,
derivationPath: "m/0'/1", derivationPath: "m/0'/1",
description: "cake default?", description: "Electrum 2",
script_type: "p2wpkh",// TODO: not really sure what cake uses by default script_type: "p2wpkh",
),
],
DerivationType.bip39: [
DerivationInfo(
derivationType: DerivationType.bip39,
derivationPath: "m/44'/0'/0'/0/0",
description: "Standard BIP44",
script_type: "p2pkh",
), ),
DerivationInfo( DerivationInfo(
derivationType: DerivationType.bip39, derivationType: DerivationType.bip39,
@ -20,6 +28,12 @@ Map<DerivationType, List<DerivationInfo>> bitcoin_derivations = {
description: "Standard BIP49 compatibility segwit", description: "Standard BIP49 compatibility segwit",
script_type: "p2wpkh-p2sh", script_type: "p2wpkh-p2sh",
), ),
DerivationInfo(
derivationType: DerivationType.bip39,
derivationPath: "m/84'/0'/0'/0/0",
description: "Standard BIP84",
script_type: "p2wpkh",
),
DerivationInfo( DerivationInfo(
derivationType: DerivationType.bip39, derivationType: DerivationType.bip39,
derivationPath: "m/84'/0'/0'", derivationPath: "m/84'/0'/0'",
@ -87,5 +101,4 @@ Map<DerivationType, List<DerivationInfo>> bitcoin_derivations = {
script_type: "p2wpkh", script_type: "p2wpkh",
), ),
], ],
}; };

View file

@ -1,4 +1,5 @@
import 'dart:io'; import 'dart:io';
import 'dart:typed_data';
import 'package:cw_bitcoin/address_to_output_script.dart'; import 'package:cw_bitcoin/address_to_output_script.dart';
import 'package:cw_bitcoin/bitcoin_mnemonic.dart'; import 'package:cw_bitcoin/bitcoin_mnemonic.dart';
import 'package:cw_bitcoin/bitcoin_mnemonic_is_incorrect_exception.dart'; import 'package:cw_bitcoin/bitcoin_mnemonic_is_incorrect_exception.dart';
@ -20,6 +21,8 @@ import 'package:collection/collection.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin; import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
import 'package:cw_bitcoin/bitcoin_derivations.dart'; import 'package:cw_bitcoin/bitcoin_derivations.dart';
import 'package:bip32/bip32.dart' as bip32;
import 'package:bip39/bip39.dart' as bip39;
class BitcoinWalletService extends WalletService<BitcoinNewWalletCredentials, class BitcoinWalletService extends WalletService<BitcoinNewWalletCredentials,
BitcoinRestoreWalletFromSeedCredentials, BitcoinRestoreWalletFromWIFCredentials> { BitcoinRestoreWalletFromSeedCredentials, BitcoinRestoreWalletFromWIFCredentials> {
@ -96,7 +99,6 @@ class BitcoinWalletService extends WalletService<BitcoinNewWalletCredentials,
@override @override
Future<BitcoinWallet> restoreFromSeed(BitcoinRestoreWalletFromSeedCredentials credentials) async { Future<BitcoinWallet> restoreFromSeed(BitcoinRestoreWalletFromSeedCredentials credentials) async {
final wallet = await BitcoinWalletBase.create( final wallet = await BitcoinWalletBase.create(
password: credentials.password!, password: credentials.password!,
mnemonic: credentials.mnemonic, mnemonic: credentials.mnemonic,
@ -110,7 +112,6 @@ class BitcoinWalletService extends WalletService<BitcoinNewWalletCredentials,
static Future<List<DerivationType>> compareDerivationMethods( static Future<List<DerivationType>> compareDerivationMethods(
{required String mnemonic, required Node node}) async { {required String mnemonic, required Node node}) async {
if (await checkIfMnemonicIsElectrum2(mnemonic)) { if (await checkIfMnemonicIsElectrum2(mnemonic)) {
return [DerivationType.electrum2]; return [DerivationType.electrum2];
} }
@ -126,54 +127,60 @@ class BitcoinWalletService extends WalletService<BitcoinNewWalletCredentials,
await electrumClient.connectToUri(node.uri); await electrumClient.connectToUri(node.uri);
for (DerivationType dType in bitcoin_derivations.keys) { for (DerivationType dType in bitcoin_derivations.keys) {
if (dType == DerivationType.bip39) { late Uint8List seedBytes;
for (DerivationInfo dInfo in bitcoin_derivations[dType]!) { if (dType == DerivationType.electrum2) {
try { seedBytes = await mnemonicToSeedBytes(mnemonic);
var wallet = bitcoin.HDWallet.fromSeed(await mnemonicToSeedBytes(mnemonic), } else if (dType == DerivationType.bip39) {
network: bitcoin.bitcoin) seedBytes = bip39.mnemonicToSeed(mnemonic);
.derivePath(dInfo.derivationPath!); }
String? address; for (DerivationInfo dInfo in bitcoin_derivations[dType]!) {
switch (dInfo.script_type) { try {
case "p2wpkh": var node = bip32.BIP32.fromSeed(seedBytes);
address = bitcoin node = node.derivePath(dInfo.derivationPath!);
.P2WPKH(
data: generatePaymentData(hd: wallet, index: 0), network: bitcoin.bitcoin)
.data
.address;
break;
case "p2pkh":
address = bitcoin
.P2PKH(
data: generatePaymentData(hd: wallet, index: 0), network: bitcoin.bitcoin)
.data
.address;
break;
case "p2wpkh-p2sh":
default:
address = wallet.address;
break;
}
// print( String? address;
// "${dInfo.derivationType.toString()} : ${dInfo.derivationPath} : ${dInfo.script_type} : ${address}"); switch (dInfo.script_type) {
case "p2wpkh":
final sh = scriptHash(address!, networkType: bitcoin.bitcoin); address = bitcoin
final history = await electrumClient.getHistory(sh); .P2WPKH(
data: new bitcoin.PaymentData(pubkey: node.publicKey),
final balance = await electrumClient.getBalance(sh); network: bitcoin.bitcoin,
dInfo.balance = balance.entries.first.value.toString(); )
dInfo.address = address; .data
dInfo.height = history.length; .address;
break;
list.add(dInfo); case "p2pkh":
} catch (e) { // case "p2wpkh-p2sh":// TODO
print(e); default:
address = bitcoin
.P2PKH(
data: new bitcoin.PaymentData(pubkey: node.publicKey),
network: bitcoin.bitcoin,
)
.data
.address;
break;
} }
final sh = scriptHash(address!, networkType: bitcoin.bitcoin);
final history = await electrumClient.getHistory(sh);
final balance = await electrumClient.getBalance(sh);
dInfo.balance = balance.entries.first.value.toString();
dInfo.address = address;
dInfo.height = history.length;
list.add(dInfo);
} catch (e) {
print(e);
} }
} }
} }
// sort the list such that derivations with the most transactions are first:
list.sort((a, b) => b.height.compareTo(a.height));
return list; return list;
} }

View file

@ -62,7 +62,7 @@ class WalletRestoreChooseDerivationPage extends BasePage {
contentPadding: EdgeInsets.all(16), contentPadding: EdgeInsets.all(16),
title: Center( title: Center(
child: Text( child: Text(
"${derivation.derivationType.toString().split('.').last}", "${derivation.description ?? derivation.derivationType.toString().split('.').last}",
style: Theme.of(context).primaryTextTheme.labelMedium!.copyWith( style: Theme.of(context).primaryTextTheme.labelMedium!.copyWith(
fontSize: 18, fontSize: 18,
fontWeight: FontWeight.w800, fontWeight: FontWeight.w800,

View file

@ -26,6 +26,4 @@ abstract class WalletRestoreChooseDerivationViewModelBase with Store {
@observable @observable
WalletRestoreMode mode; WalletRestoreMode mode;
} }