mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2024-12-23 03:59:23 +00:00
fix create side wallet
This commit is contained in:
parent
d150f06b39
commit
628fb212fb
5 changed files with 270 additions and 194 deletions
|
@ -1,37 +1,32 @@
|
||||||
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
|
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
|
||||||
import 'package:cw_bitcoin/electrum.dart';
|
|
||||||
import 'package:cw_bitcoin/utils.dart';
|
|
||||||
import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
||||||
|
import 'package:cw_bitcoin/electrum.dart';
|
||||||
import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
|
import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
|
||||||
|
import 'package:cw_bitcoin/utils.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
|
|
||||||
part 'bitcoin_wallet_addresses.g.dart';
|
part 'bitcoin_wallet_addresses.g.dart';
|
||||||
|
|
||||||
class BitcoinWalletAddresses = BitcoinWalletAddressesBase
|
class BitcoinWalletAddresses = BitcoinWalletAddressesBase with _$BitcoinWalletAddresses;
|
||||||
with _$BitcoinWalletAddresses;
|
|
||||||
|
|
||||||
abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses
|
abstract class BitcoinWalletAddressesBase extends ElectrumWalletAddresses with Store {
|
||||||
with Store {
|
BitcoinWalletAddressesBase(WalletInfo walletInfo,
|
||||||
BitcoinWalletAddressesBase(
|
|
||||||
WalletInfo walletInfo,
|
|
||||||
{required bitcoin.HDWallet mainHd,
|
{required bitcoin.HDWallet mainHd,
|
||||||
required bitcoin.HDWallet sideHd,
|
required bitcoin.HDWallet sideHd,
|
||||||
required bitcoin.NetworkType networkType,
|
required bitcoin.NetworkType networkType,
|
||||||
required ElectrumClient electrumClient,
|
required ElectrumClient electrumClient,
|
||||||
List<BitcoinAddressRecord>? initialAddresses,
|
List<BitcoinAddressRecord>? initialAddresses,
|
||||||
int initialRegularAddressIndex = 0,
|
int initialRegularAddressIndex = 0,
|
||||||
int initialChangeAddressIndex = 0})
|
int initialChangeAddressIndex = 0})
|
||||||
: super(
|
: super(walletInfo,
|
||||||
walletInfo,
|
initialAddresses: initialAddresses,
|
||||||
initialAddresses: initialAddresses,
|
initialRegularAddressIndex: initialRegularAddressIndex,
|
||||||
initialRegularAddressIndex: initialRegularAddressIndex,
|
initialChangeAddressIndex: initialChangeAddressIndex,
|
||||||
initialChangeAddressIndex: initialChangeAddressIndex,
|
mainHd: mainHd,
|
||||||
mainHd: mainHd,
|
sideHd: sideHd,
|
||||||
sideHd: sideHd,
|
electrumClient: electrumClient,
|
||||||
electrumClient: electrumClient,
|
networkType: networkType);
|
||||||
networkType: networkType);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String getAddress({required int index, required bitcoin.HDWallet hd}) =>
|
String getAddress({required int index, required bitcoin.HDWallet hd}) =>
|
||||||
|
|
|
@ -93,7 +93,7 @@ abstract class ElectrumWalletBase
|
||||||
|
|
||||||
static HDWallet bitcoinCashHDWallet(Uint8List seedBytes) =>
|
static HDWallet bitcoinCashHDWallet(Uint8List seedBytes) =>
|
||||||
bitcoin.HDWallet.fromSeed(seedBytes, network: bitcoinCashNetworkType)
|
bitcoin.HDWallet.fromSeed(seedBytes, network: bitcoinCashNetworkType)
|
||||||
.derivePath("m/44'/145'/0'/0/0");
|
.derivePath("m/44'/145'/0'/0");
|
||||||
|
|
||||||
static int estimatedTransactionSize(int inputsCount, int outputsCounts) =>
|
static int estimatedTransactionSize(int inputsCount, int outputsCounts) =>
|
||||||
inputsCount * 146 + outputsCounts * 33 + 8;
|
inputsCount * 146 + outputsCounts * 33 + 8;
|
||||||
|
@ -154,9 +154,7 @@ abstract class ElectrumWalletBase
|
||||||
Future<void> startSync() async {
|
Future<void> startSync() async {
|
||||||
try {
|
try {
|
||||||
syncStatus = AttemptingSyncStatus();
|
syncStatus = AttemptingSyncStatus();
|
||||||
if (walletInfo.type != WalletType.bitcoinCash) { //TODO: BCH: remove this check when supported
|
await walletAddresses.discoverAddresses();
|
||||||
await walletAddresses.discoverAddresses();
|
|
||||||
}
|
|
||||||
await updateTransactions();
|
await updateTransactions();
|
||||||
_subscribeForUpdates();
|
_subscribeForUpdates();
|
||||||
await updateUnspent();
|
await updateUnspent();
|
||||||
|
|
|
@ -108,8 +108,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||||
updateChangeAddresses();
|
updateChangeAddresses();
|
||||||
|
|
||||||
if (changeAddresses.isEmpty) {
|
if (changeAddresses.isEmpty) {
|
||||||
final newAddresses = await _createNewAddresses(
|
final newAddresses = await _createNewAddresses(gap,
|
||||||
(walletInfo.type != WalletType.bitcoinCash ? gap : 0), //TODO: BCH: Fix this
|
|
||||||
hd: sideHd,
|
hd: sideHd,
|
||||||
startIndex: totalCountOfChangeAddresses > 0
|
startIndex: totalCountOfChangeAddresses > 0
|
||||||
? totalCountOfChangeAddresses - 1
|
? totalCountOfChangeAddresses - 1
|
||||||
|
@ -180,8 +179,8 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||||
} else {
|
} else {
|
||||||
addrs = await _createNewAddresses(
|
addrs = await _createNewAddresses(
|
||||||
isHidden
|
isHidden
|
||||||
? walletInfo.type != WalletType.bitcoinCash ? defaultChangeAddressesCount : 0 //TODO: BCH: Fix this
|
? defaultChangeAddressesCount
|
||||||
: walletInfo.type != WalletType.bitcoinCash ? defaultReceiveAddressesCount : 1, //TODO: BCH: Fix this
|
: defaultReceiveAddressesCount,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
hd: hd,
|
hd: hd,
|
||||||
isHidden: isHidden);
|
isHidden: isHidden);
|
||||||
|
@ -196,7 +195,7 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||||
}
|
}
|
||||||
|
|
||||||
final start = addrs.length;
|
final start = addrs.length;
|
||||||
final count = start + (walletInfo.type != WalletType.bitcoinCash ? gap : 0); //TODO: BCH: Fix this
|
final count = start + gap;
|
||||||
final batch = await _createNewAddresses(
|
final batch = await _createNewAddresses(
|
||||||
count,
|
count,
|
||||||
startIndex: start,
|
startIndex: start,
|
||||||
|
@ -223,8 +222,8 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||||
countOfReceiveAddresses += 1;
|
countOfReceiveAddresses += 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (countOfReceiveAddresses < (walletInfo.type != WalletType.bitcoinCash ? defaultReceiveAddressesCount : 1)) { //TODO: BCH: Fix this
|
if (countOfReceiveAddresses < defaultReceiveAddressesCount) {
|
||||||
final addressesCount = (walletInfo.type != WalletType.bitcoinCash ? defaultReceiveAddressesCount : 1) - countOfReceiveAddresses;
|
final addressesCount = defaultReceiveAddressesCount - countOfReceiveAddresses;
|
||||||
final newAddresses = await _createNewAddresses(
|
final newAddresses = await _createNewAddresses(
|
||||||
addressesCount,
|
addressesCount,
|
||||||
startIndex: countOfReceiveAddresses,
|
startIndex: countOfReceiveAddresses,
|
||||||
|
@ -233,8 +232,8 @@ abstract class ElectrumWalletAddressesBase extends WalletAddresses with Store {
|
||||||
addresses.addAll(newAddresses);
|
addresses.addAll(newAddresses);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (countOfHiddenAddresses < (walletInfo.type != WalletType.bitcoinCash ? defaultChangeAddressesCount : 0)) { //TODO: BCH: Fix this
|
if (countOfHiddenAddresses < defaultChangeAddressesCount) {
|
||||||
final addressesCount = (walletInfo.type != WalletType.bitcoinCash ? defaultChangeAddressesCount : 0) - countOfHiddenAddresses;
|
final addressesCount = defaultChangeAddressesCount - countOfHiddenAddresses;
|
||||||
final newAddresses = await _createNewAddresses(
|
final newAddresses = await _createNewAddresses(
|
||||||
addressesCount,
|
addressesCount,
|
||||||
startIndex: countOfHiddenAddresses,
|
startIndex: countOfHiddenAddresses,
|
||||||
|
|
|
@ -10,6 +10,7 @@ import 'package:cw_bitcoin/bitcoin_unspent.dart';
|
||||||
import 'package:cw_bitcoin/electrum_balance.dart';
|
import 'package:cw_bitcoin/electrum_balance.dart';
|
||||||
import 'package:cw_bitcoin/electrum_wallet.dart';
|
import 'package:cw_bitcoin/electrum_wallet.dart';
|
||||||
import 'package:cw_bitcoin/electrum_wallet_snapshot.dart';
|
import 'package:cw_bitcoin/electrum_wallet_snapshot.dart';
|
||||||
|
import 'package:cw_bitcoin/pending_bitcoin_transaction.dart';
|
||||||
import 'package:cw_bitcoin_cash/src/pending_bitcoin_cash_transaction.dart';
|
import 'package:cw_bitcoin_cash/src/pending_bitcoin_cash_transaction.dart';
|
||||||
import 'package:cw_core/crypto_currency.dart';
|
import 'package:cw_core/crypto_currency.dart';
|
||||||
import 'package:cw_core/pending_transaction.dart';
|
import 'package:cw_core/pending_transaction.dart';
|
||||||
|
@ -53,11 +54,22 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
|
||||||
initialRegularAddressIndex: initialRegularAddressIndex,
|
initialRegularAddressIndex: initialRegularAddressIndex,
|
||||||
initialChangeAddressIndex: initialChangeAddressIndex,
|
initialChangeAddressIndex: initialChangeAddressIndex,
|
||||||
mainHd: hd,
|
mainHd: hd,
|
||||||
sideHd: hd,
|
sideHd: bitcoin.HDWallet.fromSeed(seedBytes, network: bitcoinCashNetworkType)
|
||||||
//TODO: BCH: check if this is correct
|
.derivePath("m/44'/145'/0'/1"),
|
||||||
networkType: networkType);
|
networkType: networkType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bitcoin.NetworkType bitcoinCashNetworkType = bitcoin.NetworkType(
|
||||||
|
messagePrefix: '\x18Bitcoin Signed Message:\n',
|
||||||
|
bech32: 'bc',
|
||||||
|
bip32: bitcoin.Bip32Type(
|
||||||
|
public: 0x0488b21e,
|
||||||
|
private: 0x0488ade4,
|
||||||
|
),
|
||||||
|
pubKeyHash: 0x00,
|
||||||
|
scriptHash: 0x05,
|
||||||
|
wif: 0x80);
|
||||||
|
|
||||||
static Future<BitcoinCashWallet> create(
|
static Future<BitcoinCashWallet> create(
|
||||||
{required String mnemonic,
|
{required String mnemonic,
|
||||||
required String password,
|
required String password,
|
||||||
|
@ -98,158 +110,219 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store {
|
||||||
initialChangeAddressIndex: snp.changeAddressIndex);
|
initialChangeAddressIndex: snp.changeAddressIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
// @override
|
||||||
Future<PendingTransaction> createTransaction(Object credentials) async {
|
// Future<PendingTransaction> createTransaction(Object credentials) async {
|
||||||
final transactionCredentials = credentials as BitcoinTransactionCredentials;
|
// final transactionCredentials = credentials as BitcoinTransactionCredentials;
|
||||||
|
//
|
||||||
const minAmount = 546;
|
// const minAmount = 546;
|
||||||
final inputs = <BitcoinUnspent>[];
|
// final inputs = <BitcoinUnspent>[];
|
||||||
var allInputsAmount = 0;
|
// var allInputsAmount = 0;
|
||||||
final outputs = transactionCredentials.outputs;
|
// final outputs = transactionCredentials.outputs;
|
||||||
final hasMultiDestination = outputs.length > 1;
|
// final hasMultiDestination = outputs.length > 1;
|
||||||
|
//
|
||||||
if (unspentCoins.isEmpty) {
|
// if (unspentCoins.isEmpty) {
|
||||||
await updateUnspent();
|
// await updateUnspent();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
for (final utx in unspentCoins) {
|
// for (final utx in unspentCoins) {
|
||||||
if (utx.isSending) {
|
// if (utx.isSending) {
|
||||||
allInputsAmount += utx.value;
|
// allInputsAmount += utx.value;
|
||||||
inputs.add(utx);
|
// inputs.add(utx);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if (inputs.isEmpty) throw BitcoinTransactionNoInputsException();
|
// if (inputs.isEmpty) throw BitcoinTransactionNoInputsException();
|
||||||
|
//
|
||||||
final int feeRate = transactionCredentials.feeRate ??
|
// final int feeRate = transactionCredentials.feeRate ??
|
||||||
BitcoinCashFeeRates.feeRate(transactionCredentials.priority!);
|
// BitcoinCashFeeRates.feeRate(transactionCredentials.priority!);
|
||||||
|
//
|
||||||
final int allAmountFee =
|
// final int allAmountFee =
|
||||||
bitbox.BitcoinCash.getByteCount(inputs.length, transactionCredentials.outputs.length) *
|
// bitbox.BitcoinCash.getByteCount(inputs.length, transactionCredentials.outputs.length) *
|
||||||
feeRate;
|
// feeRate;
|
||||||
|
//
|
||||||
final allAmount = allInputsAmount - allAmountFee;
|
// final allAmount = allInputsAmount - allAmountFee;
|
||||||
var credentialsAmount = 0;
|
// var credentialsAmount = 0;
|
||||||
var amount = 0;
|
// var amount = 0;
|
||||||
var fee = 0;
|
// var fee = 0;
|
||||||
|
//
|
||||||
if (hasMultiDestination) {
|
// if (hasMultiDestination) {
|
||||||
if (outputs.any((item) => item.sendAll || item.formattedCryptoAmount! <= 0)) {
|
// if (outputs.any((item) => item.sendAll || item.formattedCryptoAmount! <= 0)) {
|
||||||
throw BitcoinTransactionWrongBalanceException(currency);
|
// throw BitcoinTransactionWrongBalanceException(currency);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
credentialsAmount = outputs.fold(0, (acc, value) {
|
// credentialsAmount = outputs.fold(0, (acc, value) {
|
||||||
return acc + value.formattedCryptoAmount!;
|
// return acc + value.formattedCryptoAmount!;
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
if (allAmount - credentialsAmount < minAmount) {
|
// if (allAmount - credentialsAmount < minAmount) {
|
||||||
throw BitcoinTransactionWrongBalanceException(currency);
|
// throw BitcoinTransactionWrongBalanceException(currency);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
amount = credentialsAmount;
|
// amount = credentialsAmount;
|
||||||
|
//
|
||||||
if (transactionCredentials.feeRate != null) {
|
// if (transactionCredentials.feeRate != null) {
|
||||||
fee = calculateEstimatedFeeWithFeeRate(transactionCredentials.feeRate!, amount,
|
// fee = calculateEstimatedFeeWithFeeRate(transactionCredentials.feeRate!, amount,
|
||||||
outputsCount: outputs.length + 1);
|
// outputsCount: outputs.length + 1);
|
||||||
} else {
|
// } else {
|
||||||
fee = calculateEstimatedFee(transactionCredentials.priority, amount,
|
// fee = calculateEstimatedFee(transactionCredentials.priority, amount,
|
||||||
outputsCount: outputs.length + 1);
|
// outputsCount: outputs.length + 1);
|
||||||
}
|
// }
|
||||||
} else {
|
// } else {
|
||||||
final output = outputs.first;
|
// final output = outputs.first;
|
||||||
credentialsAmount = !output.sendAll ? output.formattedCryptoAmount! : 0;
|
// credentialsAmount = !output.sendAll ? output.formattedCryptoAmount! : 0;
|
||||||
|
//
|
||||||
if (credentialsAmount > allAmount) throw BitcoinTransactionWrongBalanceException(currency);
|
// if (credentialsAmount > allAmount) throw BitcoinTransactionWrongBalanceException(currency);
|
||||||
|
//
|
||||||
amount = output.sendAll || allAmount - credentialsAmount < minAmount
|
// amount = output.sendAll || allAmount - credentialsAmount < minAmount
|
||||||
? allAmount
|
// ? allAmount
|
||||||
: credentialsAmount;
|
// : credentialsAmount;
|
||||||
|
//
|
||||||
if (output.sendAll || amount == allAmount) {
|
// if (output.sendAll || amount == allAmount) {
|
||||||
fee = allAmountFee;
|
// fee = allAmountFee;
|
||||||
} else if (transactionCredentials.feeRate != null) {
|
// } else if (transactionCredentials.feeRate != null) {
|
||||||
fee = calculateEstimatedFeeWithFeeRate(transactionCredentials.feeRate!, amount);
|
// fee = calculateEstimatedFeeWithFeeRate(transactionCredentials.feeRate!, amount);
|
||||||
} else {
|
// } else {
|
||||||
fee = calculateEstimatedFee(transactionCredentials.priority, amount);
|
// fee = calculateEstimatedFee(transactionCredentials.priority, amount);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if (fee == 0) throw BitcoinTransactionWrongBalanceException(currency);
|
// if (fee == 0) throw BitcoinTransactionWrongBalanceException(currency);
|
||||||
|
//
|
||||||
final totalAmount = amount + fee;
|
// final totalAmount = amount + fee;
|
||||||
|
//
|
||||||
if (totalAmount > balance[currency]!.confirmed || totalAmount > allInputsAmount) {
|
// if (totalAmount > balance[currency]!.confirmed || totalAmount > allInputsAmount) {
|
||||||
throw BitcoinTransactionWrongBalanceException(currency);
|
// throw BitcoinTransactionWrongBalanceException(currency);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
// final changeAddress = await walletAddresses.getChangeAddress(); TODO: BCH: implement change address
|
// // final changeAddress = await walletAddresses.getChangeAddress(); TODO: BCH: implement change address
|
||||||
var leftAmount = totalAmount;
|
// var leftAmount = totalAmount;
|
||||||
var totalInputAmount = 0;
|
// var totalInputAmount = 0;
|
||||||
|
//
|
||||||
inputs.clear();
|
// inputs.clear();
|
||||||
|
//
|
||||||
for (final utx in unspentCoins) {
|
// for (final utx in unspentCoins) {
|
||||||
if (utx.isSending) {
|
// if (utx.isSending) {
|
||||||
leftAmount = leftAmount - utx.value;
|
// leftAmount = leftAmount - utx.value;
|
||||||
totalInputAmount += utx.value;
|
// totalInputAmount += utx.value;
|
||||||
inputs.add(utx);
|
// inputs.add(utx);
|
||||||
|
//
|
||||||
if (leftAmount <= 0) break;
|
// if (leftAmount <= 0) break;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if (inputs.isEmpty) throw BitcoinTransactionNoInputsException();
|
// if (inputs.isEmpty) throw BitcoinTransactionNoInputsException();
|
||||||
|
//
|
||||||
if (amount <= 0 || totalInputAmount < totalAmount) {
|
// if (amount <= 0 || totalInputAmount < totalAmount) {
|
||||||
throw BitcoinTransactionWrongBalanceException(currency);
|
// throw BitcoinTransactionWrongBalanceException(currency);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
final builder = bitbox.Bitbox.transactionBuilder(testnet: false);
|
// final builder = bitbox.Bitbox.transactionBuilder(testnet: false);
|
||||||
final _wallet = hd;
|
// final _wallet = hd;
|
||||||
|
//
|
||||||
final utxoSigningData = await fetchBuildTxData(inputs, _wallet);
|
// final utxoSigningData = await fetchBuildTxData(inputs, _wallet);
|
||||||
|
//
|
||||||
List<bitbox.Utxo> _utxos = [];
|
// List<bitbox.Utxo> _utxos = [];
|
||||||
for (var element in inputs) {
|
// for (var element in inputs) {
|
||||||
_utxos.add(bitbox.Utxo(element.hash, element.vout,
|
// _utxos.add(bitbox.Utxo(element.hash, element.vout,
|
||||||
bitbox.BitcoinCash.fromSatoshi(element.value), element.value, 0, 1));
|
// bitbox.BitcoinCash.fromSatoshi(element.value), element.value, 0, 1));
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
final signatures = <Map>[];
|
// final signatures = <Map>[];
|
||||||
int totalBalance = 0;
|
// int totalBalance = 0;
|
||||||
|
//
|
||||||
_utxos.forEach((bitbox.Utxo utxo) {
|
// _utxos.forEach((bitbox.Utxo utxo) {
|
||||||
builder.addInput(utxo.txid, utxo.vout);
|
// builder.addInput(utxo.txid, utxo.vout);
|
||||||
|
//
|
||||||
final ec = utxoSigningData.firstWhere((e) => e.utxo.hash == utxo.txid).keyPair!;
|
// final ec = utxoSigningData.firstWhere((e) => e.utxo.hash == utxo.txid).keyPair!;
|
||||||
|
//
|
||||||
final bitboxEC = bitbox.ECPair.fromWIF(ec.toWIF());
|
// final bitboxEC = bitbox.ECPair.fromWIF(ec.toWIF());
|
||||||
|
//
|
||||||
signatures
|
// signatures
|
||||||
.add({"vin": signatures.length, "key_pair": bitboxEC, "original_amount": utxo.satoshis});
|
// .add({"vin": signatures.length, "key_pair": bitboxEC, "original_amount": utxo.satoshis});
|
||||||
|
//
|
||||||
totalBalance += utxo.satoshis;
|
// totalBalance += utxo.satoshis;
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
outputs.forEach((item) {
|
// outputs.forEach((item) {
|
||||||
final outputAmount = hasMultiDestination ? item.formattedCryptoAmount : amount;
|
// final outputAmount = hasMultiDestination ? item.formattedCryptoAmount : amount;
|
||||||
final outputAddress = item.isParsedAddress ? item.extractedAddress! : item.address;
|
// final outputAddress = item.isParsedAddress ? item.extractedAddress! : item.address;
|
||||||
builder.addOutput(outputAddress, outputAmount!);
|
// builder.addOutput(outputAddress, outputAmount!);
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
signatures.forEach((signature) {
|
// signatures.forEach((signature) {
|
||||||
builder.sign(signature["vin"], signature["key_pair"], signature["original_amount"]);
|
// builder.sign(signature["vin"], signature["key_pair"], signature["original_amount"]);
|
||||||
});
|
// });
|
||||||
|
//
|
||||||
// build the transaction
|
// // build the transaction
|
||||||
final tx = builder.build();
|
// final tx = builder.build();
|
||||||
return PendingBitcoinCashTransaction(tx, type,
|
// return PendingBitcoinCashTransaction(tx, type,
|
||||||
electrumClient: electrumClient, amount: amount, fee: fee)
|
// electrumClient: electrumClient, amount: amount, fee: fee)
|
||||||
..addListener((transaction) async {
|
// ..addListener((transaction) async {
|
||||||
transactionHistory.addOne(transaction);
|
// transactionHistory.addOne(transaction);
|
||||||
await updateBalance();
|
// await updateBalance();
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
// @override
|
||||||
|
// Future<PendingBitcoinTransaction> createTransaction(Object credentials) async {
|
||||||
|
// final utxosToUse = unspentCoins.where((utxo) => utxo.isSending).toList();
|
||||||
|
// final utxoSigningData = await fetchBuildTxData(utxosToUse, hd);
|
||||||
|
// final builder = bitbox.Bitbox.transactionBuilder(testnet: false);
|
||||||
|
//
|
||||||
|
// List<bitbox.Utxo> _utxos = [];
|
||||||
|
// for (var element in utxosToUse) {
|
||||||
|
// _utxos.add(bitbox.Utxo(element.hash, element.vout,
|
||||||
|
// bitbox.BitcoinCash.fromSatoshi(element.value), element.value, 0, 1));
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// final signatures = <Map>[];
|
||||||
|
// int totalBalance = 0;
|
||||||
|
//
|
||||||
|
// _utxos.forEach((bitbox.Utxo utxo) {
|
||||||
|
// // add the utxo as an input for the transaction
|
||||||
|
// builder.addInput(utxo.txid, utxo.vout);
|
||||||
|
//
|
||||||
|
// final ec = utxoSigningData.firstWhere((e) => e.utxo.hash == utxo.txid).keyPair!;
|
||||||
|
//
|
||||||
|
// final bitboxEC = bitbox.ECPair.fromWIF(ec.toWIF());
|
||||||
|
//
|
||||||
|
// // add a signature to the list to be used later
|
||||||
|
// signatures
|
||||||
|
// .add({"vin": signatures.length, "key_pair": bitboxEC, "original_amount": utxo.satoshis});
|
||||||
|
//
|
||||||
|
// totalBalance += utxo.satoshis;
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// // set an address to send the remaining balance to
|
||||||
|
// final outputAddress = "13Hvge9HRduGiXMfcJHFn6sggequmaKqsZ";
|
||||||
|
//
|
||||||
|
// // if there is an unspent balance, create a spending transaction
|
||||||
|
// if (totalBalance > 0 && outputAddress != "") {
|
||||||
|
// // calculate the fee based on number of inputs and one expected output
|
||||||
|
// final fee = bitbox.BitcoinCash.getByteCount(signatures.length, 1);
|
||||||
|
//
|
||||||
|
// // calculate how much balance will be left over to spend after the fee
|
||||||
|
// final sendAmount = totalBalance - fee;
|
||||||
|
//
|
||||||
|
// // add the output based on the address provided in the testing data
|
||||||
|
// builder.addOutput(outputAddress, sendAmount);
|
||||||
|
//
|
||||||
|
// // sign all inputs
|
||||||
|
// signatures.forEach((signature) {
|
||||||
|
// builder.sign(signature["vin"], signature["key_pair"], signature["original_amount"]);
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// // build the transaction
|
||||||
|
// final tx = builder.build();
|
||||||
|
//
|
||||||
|
// // broadcast the transaction
|
||||||
|
// final result = await electrumClient.broadcastTransaction(transactionRaw: tx.toHex());
|
||||||
|
//
|
||||||
|
// // Yatta!
|
||||||
|
// print("Transaction broadcasted: $result");
|
||||||
|
// }
|
||||||
|
// return PendingBitcoinTransaction(Transaction(), type,
|
||||||
|
// electrumClient: electrumClient, amount: 1, fee: 1);
|
||||||
|
// }
|
||||||
|
|
||||||
Future<List<SigningData>> fetchBuildTxData(
|
Future<List<SigningData>> fetchBuildTxData(
|
||||||
List<BitcoinUnspent> utxosToUse, HDWallet wallet) async {
|
List<BitcoinUnspent> utxosToUse, HDWallet wallet) async {
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import 'package:bitbox/bitbox.dart' as Bitbox;
|
|
||||||
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
|
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
|
||||||
import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
||||||
import 'package:cw_bitcoin/electrum.dart';
|
import 'package:cw_bitcoin/electrum.dart';
|
||||||
import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
|
import 'package:cw_bitcoin/electrum_wallet_addresses.dart';
|
||||||
|
import 'package:cw_bitcoin/utils.dart';
|
||||||
import 'package:cw_core/wallet_info.dart';
|
import 'package:cw_core/wallet_info.dart';
|
||||||
import 'package:mobx/mobx.dart';
|
import 'package:mobx/mobx.dart';
|
||||||
|
|
||||||
|
@ -30,5 +30,16 @@ abstract class BitcoinCashWalletAddressesBase extends ElectrumWalletAddresses wi
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String getAddress({required int index, required bitcoin.HDWallet hd}) =>
|
String getAddress({required int index, required bitcoin.HDWallet hd}) =>
|
||||||
hd.address!;
|
generateP2PKHAddress(hd: hd, index: index, networkType: bitcoinCashNetworkType);
|
||||||
|
|
||||||
|
static bitcoin.NetworkType bitcoinCashNetworkType = bitcoin.NetworkType(
|
||||||
|
messagePrefix: '\x18Bitcoin Signed Message:\n',
|
||||||
|
bech32: 'bc',
|
||||||
|
bip32: bitcoin.Bip32Type(
|
||||||
|
public: 0x0488b21e,
|
||||||
|
private: 0x0488ade4,
|
||||||
|
),
|
||||||
|
pubKeyHash: 0x00,
|
||||||
|
scriptHash: 0x05,
|
||||||
|
wif: 0x80);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue