From 5f59bd939edb080b730fe3aca22a28225ccd5a87 Mon Sep 17 00:00:00 2001 From: Serhii Date: Fri, 18 Aug 2023 11:48:30 +0300 Subject: [PATCH] fix transaction priority type --- .../bitcoin_cash_transaction_priority.dart | 4 +- .../lib/src/bitcoin_cash_wallet.dart | 72 ++++++++++++++++++- lib/bitcoin/cw_bitcoin.dart | 9 +++ lib/core/address_validator.dart | 1 + lib/entities/preferences_key.dart | 1 + lib/store/settings_store.dart | 16 ++--- lib/view_model/send/send_view_model.dart | 42 +++-------- tool/configure.dart | 6 +- 8 files changed, 106 insertions(+), 45 deletions(-) diff --git a/cw_bitcoin_cash/lib/src/bitcoin_cash_transaction_priority.dart b/cw_bitcoin_cash/lib/src/bitcoin_cash_transaction_priority.dart index a3a1c4729..7a0ae36d1 100644 --- a/cw_bitcoin_cash/lib/src/bitcoin_cash_transaction_priority.dart +++ b/cw_bitcoin_cash/lib/src/bitcoin_cash_transaction_priority.dart @@ -1,6 +1,6 @@ -import 'package:cw_core/transaction_priority.dart'; +import 'package:cw_bitcoin/bitcoin_transaction_priority.dart'; -class BitcoinCashTransactionPriority extends TransactionPriority { +class BitcoinCashTransactionPriority extends BitcoinTransactionPriority { const BitcoinCashTransactionPriority({required String title, required int raw}) : super(title: title, raw: raw); diff --git a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart index eadf30673..dff3b7e7d 100644 --- a/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart +++ b/cw_bitcoin_cash/lib/src/bitcoin_cash_wallet.dart @@ -3,6 +3,7 @@ import 'package:cw_bitcoin/bitcoin_address_record.dart'; import 'package:cw_bitcoin/electrum_balance.dart'; import 'package:cw_bitcoin/electrum_wallet.dart'; import 'package:cw_bitcoin/electrum_wallet_snapshot.dart'; +import 'package:cw_bitcoin/pending_bitcoin_transaction.dart'; import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/unspent_coins_info.dart'; import 'package:cw_core/wallet_info.dart'; @@ -44,7 +45,7 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store { initialChangeAddressIndex: initialChangeAddressIndex, mainHd: hd, sideHd: hd, - //TODO: BCH check if this is correct + //TODO: BCH: check if this is correct networkType: networkType); } @@ -87,4 +88,71 @@ abstract class BitcoinCashWalletBase extends ElectrumWallet with Store { initialRegularAddressIndex: snp.regularAddressIndex, initialChangeAddressIndex: snp.changeAddressIndex); } -} + + @override + Future createTransaction(Object credentials, + [List? unspents, Object? wallet]) async { + + // final utxoSigningData = await fetchBuildTxData(unspents as List, wallet as BitcoinCashWalletBase); + // final builder = bitbox.Bitbox.transactionBuilder(testnet: false); + // final utxosToUse = unspents as List; + // final _wallet = wallet as BitcoinCashWallet; + // print('unspents: ${unspents.first.address}'); + // + // List _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 = []; + // 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(bitcoin.Transaction(), type, + electrumClient: electrumClient, amount: 1, fee: 1); + } + + } diff --git a/lib/bitcoin/cw_bitcoin.dart b/lib/bitcoin/cw_bitcoin.dart index dfd3b1538..c54933404 100644 --- a/lib/bitcoin/cw_bitcoin.dart +++ b/lib/bitcoin/cw_bitcoin.dart @@ -44,9 +44,14 @@ class CWBitcoin extends Bitcoin { List getTransactionPriorities() => BitcoinTransactionPriority.all; + @override List getLitecoinTransactionPriorities() => LitecoinTransactionPriority.all; + @override + List getBitcoinCashTransactionPriorities() + => BitcoinCashTransactionPriority.all; + @override TransactionPriority deserializeBitcoinTransactionPriority(int raw) => BitcoinTransactionPriority.deserialize(raw: raw); @@ -55,6 +60,10 @@ class CWBitcoin extends Bitcoin { TransactionPriority deserializeLitecoinTransactionPriority(int raw) => LitecoinTransactionPriority.deserialize(raw: raw); + @override + TransactionPriority deserializeBitcoinCashTransactionPriority(int raw) + => BitcoinCashTransactionPriority.deserialize(raw: raw); + @override int getFeeRate(Object wallet, TransactionPriority priority) { final bitcoinWallet = wallet as ElectrumWallet; diff --git a/lib/core/address_validator.dart b/lib/core/address_validator.dart index f2a235363..121e6c231 100644 --- a/lib/core/address_validator.dart +++ b/lib/core/address_validator.dart @@ -171,6 +171,7 @@ class AddressValidator extends TextValidator { case CryptoCurrency.shib: case CryptoCurrency.avaxc: case CryptoCurrency.bch: + return [32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44]; //TODO: BCH: replace with correct length case CryptoCurrency.bnb: return [42]; case CryptoCurrency.ltc: diff --git a/lib/entities/preferences_key.dart b/lib/entities/preferences_key.dart index 2025b4356..9b68fd897 100644 --- a/lib/entities/preferences_key.dart +++ b/lib/entities/preferences_key.dart @@ -34,6 +34,7 @@ class PreferencesKey { static const havenTransactionPriority = 'current_fee_priority_haven'; static const litecoinTransactionPriority = 'current_fee_priority_litecoin'; static const ethereumTransactionPriority = 'current_fee_priority_ethereum'; + static const bitcoinCashTransactionPriority = 'current_fee_priority_bitcoin_cash'; static const shouldShowReceiveWarning = 'should_show_receive_warning'; static const shouldShowYatPopup = 'should_show_yat_popup'; static const moneroWalletPasswordUpdateV1Base = 'monero_wallet_update_v1'; diff --git a/lib/store/settings_store.dart b/lib/store/settings_store.dart index 93eeab1d0..8cac26ba6 100644 --- a/lib/store/settings_store.dart +++ b/lib/store/settings_store.dart @@ -140,8 +140,8 @@ abstract class SettingsStoreBase with Store { priority[WalletType.ethereum] = initialEthereumTransactionPriority; } - if (initialBitcoinTransactionPriority != null) { - priority[WalletType.bitcoinCash] = initialBitcoinTransactionPriority; + if (initialBitcoinCashTransactionPriority != null) { + priority[WalletType.bitcoinCash] = initialBitcoinCashTransactionPriority; } reaction( @@ -173,7 +173,7 @@ abstract class SettingsStoreBase with Store { key = PreferencesKey.ethereumTransactionPriority; break; case WalletType.bitcoinCash: - key = PreferencesKey.bitcoinTransactionPriority; + key = PreferencesKey.bitcoinCashTransactionPriority; break; default: key = null; @@ -518,9 +518,9 @@ abstract class SettingsStoreBase with Store { ethereumTransactionPriority = bitcoin?.deserializeLitecoinTransactionPriority( sharedPreferences.getInt(PreferencesKey.ethereumTransactionPriority)!); } - if (sharedPreferences.getInt(PreferencesKey.bitcoinTransactionPriority) != null) { + if (sharedPreferences.getInt(PreferencesKey.bitcoinCashTransactionPriority) != null) { bitcoinCashTransactionPriority = bitcoin?.deserializeLitecoinTransactionPriority( - sharedPreferences.getInt(PreferencesKey.bitcoinTransactionPriority)!); + sharedPreferences.getInt(PreferencesKey.bitcoinCashTransactionPriority)!); } moneroTransactionPriority ??= monero?.getDefaultTransactionPriority(); @@ -730,9 +730,9 @@ abstract class SettingsStoreBase with Store { sharedPreferences.getInt(PreferencesKey.ethereumTransactionPriority)!) ?? priority[WalletType.ethereum]!; } - if (sharedPreferences.getInt(PreferencesKey.bitcoinTransactionPriority) != null) { - priority[WalletType.bitcoinCash] = bitcoinCash?.deserializeBitcoinCashTransactionPriority( - sharedPreferences.getInt(PreferencesKey.bitcoinTransactionPriority)!) ?? + if (sharedPreferences.getInt(PreferencesKey.bitcoinCashTransactionPriority) != null) { + priority[WalletType.bitcoinCash] = bitcoin?.deserializeBitcoinCashTransactionPriority( + sharedPreferences.getInt(PreferencesKey.bitcoinCashTransactionPriority)!) ?? priority[WalletType.bitcoinCash]!; } diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart index 2caf1acb4..1c49c1a7c 100644 --- a/lib/view_model/send/send_view_model.dart +++ b/lib/view_model/send/send_view_model.dart @@ -323,50 +323,30 @@ abstract class SendViewModelBase with Store { _settingsStore.priority[_wallet.type] = priority; Object _credentials() { + final priority = _settingsStore.priority[_wallet.type]; + + if (priority == null) { + throw Exception('Priority is null for wallet type: ${_wallet.type}'); + } + switch (_wallet.type) { case WalletType.bitcoin: - final priority = _settingsStore.priority[_wallet.type]; - - if (priority == null) { - throw Exception('Priority is null for wallet type: ${_wallet.type}'); - } - - return bitcoin!.createBitcoinTransactionCredentials(outputs, priority: priority); case WalletType.litecoin: - final priority = _settingsStore.priority[_wallet.type]; - - if (priority == null) { - throw Exception('Priority is null for wallet type: ${_wallet.type}'); - } - + case WalletType.bitcoinCash: return bitcoin!.createBitcoinTransactionCredentials(outputs, priority: priority); + case WalletType.monero: - final priority = _settingsStore.priority[_wallet.type]; - - if (priority == null) { - throw Exception('Priority is null for wallet type: ${_wallet.type}'); - } - return monero! .createMoneroTransactionCreationCredentials(outputs: outputs, priority: priority); + case WalletType.haven: - final priority = _settingsStore.priority[_wallet.type]; - - if (priority == null) { - throw Exception('Priority is null for wallet type: ${_wallet.type}'); - } - return haven!.createHavenTransactionCreationCredentials( outputs: outputs, priority: priority, assetType: selectedCryptoCurrency.title); + case WalletType.ethereum: - final priority = _settingsStore.priority[_wallet.type]; - - if (priority == null) { - throw Exception('Priority is null for wallet type: ${_wallet.type}'); - } - return ethereum!.createEthereumTransactionCredentials( outputs, priority: priority, currency: selectedCryptoCurrency); + default: throw Exception('Unexpected wallet type: ${_wallet.type}'); } diff --git a/tool/configure.dart b/tool/configure.dart index 88d7d6e8c..89c387e6a 100644 --- a/tool/configure.dart +++ b/tool/configure.dart @@ -28,6 +28,7 @@ Future main(List args) async { Future generateBitcoin(bool hasImplementation) async { final outputFile = File(bitcoinOutputPath); const bitcoinCommonHeaders = """ +import 'package:cw_bitcoin_cash/cw_bitcoin_cash.dart'; import 'package:cw_core/wallet_credentials.dart'; import 'package:cw_core/wallet_info.dart'; import 'package:cw_core/transaction_priority.dart'; @@ -41,7 +42,6 @@ import 'package:cw_bitcoin/electrum_wallet.dart'; import 'package:cw_bitcoin/bitcoin_unspent.dart'; import 'package:cw_bitcoin/bitcoin_mnemonic.dart'; import 'package:cw_bitcoin/bitcoin_transaction_priority.dart'; -import 'package:cw_bitcoin/bitcoin_wallet.dart'; import 'package:cw_bitcoin/bitcoin_wallet_service.dart'; import 'package:cw_bitcoin/bitcoin_wallet_creation_credentials.dart'; import 'package:cw_bitcoin/bitcoin_amount_format.dart'; @@ -79,8 +79,10 @@ abstract class Bitcoin { Map getWalletKeys(Object wallet); List getTransactionPriorities(); List getLitecoinTransactionPriorities(); - TransactionPriority deserializeBitcoinTransactionPriority(int raw); + List getBitcoinCashTransactionPriorities(); + TransactionPriority deserializeBitcoinTransactionPriority(int raw); TransactionPriority deserializeLitecoinTransactionPriority(int raw); + TransactionPriority deserializeBitcoinCashTransactionPriority(int raw); int getFeeRate(Object wallet, TransactionPriority priority); Future generateNewAddress(Object wallet); Object createBitcoinTransactionCredentials(List outputs, {required TransactionPriority priority, int? feeRate});