From a9a30439b8270332b116481613431f8e87ece1d3 Mon Sep 17 00:00:00 2001 From: Konstantin Ullrich Date: Wed, 8 Jan 2025 14:17:57 +0100 Subject: [PATCH] Minor cleanup --- cw_bitcoin/lib/bitcoin_payjoin.dart | 2 +- cw_bitcoin/lib/bitcoin_wallet.dart | 102 ++++++++++++++- cw_bitcoin/lib/electrum_wallet.dart | 122 ------------------ lib/src/screens/send/widgets/send_card.dart | 4 +- lib/utils/payment_request.dart | 10 +- .../dashboard/dashboard_view_model.dart | 13 -- lib/view_model/send/send_view_model.dart | 6 +- 7 files changed, 107 insertions(+), 152 deletions(-) diff --git a/cw_bitcoin/lib/bitcoin_payjoin.dart b/cw_bitcoin/lib/bitcoin_payjoin.dart index c289fbcca1..1a1d3460a8 100644 --- a/cw_bitcoin/lib/bitcoin_payjoin.dart +++ b/cw_bitcoin/lib/bitcoin_payjoin.dart @@ -410,7 +410,7 @@ class BitcoinPayjoin { Object credentials, dynamic pjUri ) async { - final bitcoinWallet = wallet as ElectrumWallet; + final bitcoinWallet = wallet as BitcoinWallet; final pendingTx = await bitcoinWallet.psbtToPendingTx(psbtString, credentials, pjUri); diff --git a/cw_bitcoin/lib/bitcoin_wallet.dart b/cw_bitcoin/lib/bitcoin_wallet.dart index 715d3ab503..be5934b9a1 100644 --- a/cw_bitcoin/lib/bitcoin_wallet.dart +++ b/cw_bitcoin/lib/bitcoin_wallet.dart @@ -5,10 +5,13 @@ import 'package:bitcoin_base/bitcoin_base.dart'; import 'package:blockchain_utils/blockchain_utils.dart'; import 'package:cw_bitcoin/bitcoin_address_record.dart'; import 'package:cw_bitcoin/bitcoin_mnemonic.dart'; +import 'package:cw_bitcoin/bitcoin_unspent.dart'; +import 'package:cw_bitcoin/pending_bitcoin_transaction.dart'; import 'package:cw_bitcoin/psbt_finalizer_v0.dart'; import 'package:cw_bitcoin/psbt_signer.dart'; import 'package:cw_bitcoin/psbt_transaction_builder.dart'; import 'package:cw_bitcoin/psbt_v0_deserialize.dart'; +import 'package:cw_bitcoin/utils.dart'; import 'package:cw_core/encryption_file_utils.dart'; import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart'; import 'package:cw_bitcoin/bitcoin_wallet_addresses.dart'; @@ -252,7 +255,6 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store { derivationPath: walletInfo.derivationInfo!.derivationPath!); } - @override Future buildPayjoinTransaction({ required List outputs, required BigInt fee, @@ -421,6 +423,104 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store { } } + Future psbtToPendingTx( + String preProcessedPsbt, + Object credentials, + dynamic pjUri, + ) async { + + final unspent = unspentCoins.where((e) => (e.isSending || !e.isFrozen)); + + List utxos = []; + + for (BitcoinUnspent input in unspent) { + final address = RegexUtils.addressTypeFromStr(input.address, BitcoinNetwork.mainnet); + + final newHd = input.bitcoinAddressRecord.isHidden + ? sideHd + : hd; + + ECPrivate privkey; + if (input.bitcoinAddressRecord is BitcoinSilentPaymentAddressRecord) { + final unspentAddress = input.bitcoinAddressRecord as BitcoinSilentPaymentAddressRecord; + privkey = walletAddresses.silentAddress!.b_spend.tweakAdd( + BigintUtils.fromBytes( + BytesUtils.fromHexString(unspentAddress.silentPaymentTweak!), + ), + ); + } else { + privkey = + generateECPrivate(hd: newHd, index: input.bitcoinAddressRecord.index, network: BitcoinNetwork.mainnet); + } + + utxos.add( + UtxoWithPrivateKey( + utxo: BitcoinUtxo( + txHash: input.hash, + value: BigInt.from(input.value), + vout: input.vout, + scriptType: input.bitcoinAddressRecord.type, + isSilentPayment: input.bitcoinAddressRecord is BitcoinSilentPaymentAddressRecord, + ), + ownerDetails: UtxoAddressDetails( + publicKey: newHd.publicKey.toHex(), + address: address, + ), + privateKey: privkey + ), + ); + } + + final psbt = PsbtV2()..deserializeV0(base64.decode(preProcessedPsbt)); + + final inputCount = psbt.getGlobalInputCount(); + + final unsignedTx = []; + for (var i = 0; i < inputCount; i++) { + if (psbt.getInputFinalScriptsig(i) == null) { + try { + psbt.getInputFinalScriptwitness(i); + } catch (_) { + unsignedTx.add(BytesUtils.toHexString(psbt.getInputPreviousTxid(i).reversed.toList())); + } + } + } + + psbt.signWithUTXO(utxos.where((e) => unsignedTx.contains(e.utxo.txHash)).toList(), (txDigest, utxo, key, sighash) { + if (utxo.utxo.isP2tr()) { + return key.signTapRoot( + txDigest, + sighash: sighash, + tweak: utxo.utxo.isSilentPayment != true, + ); + } else { + return key.signInput(txDigest, sigHash: sighash); + } + }); + + psbt.finalizeV0(); + + final btcTx = BtcTransaction.fromRaw(hex.encode(psbt.extract())); + + return PendingBitcoinTransaction( + btcTx, + type, + electrumClient: electrumClient, + amount: psbt.getOutputAmount(0), // ToDo + fee: 0,// ToDo + feeRate: "Payjoin", // ToDo + network: network, + hasChange: true, + isSendAll: true, + hasTaprootInputs: false, // ToDo: (Konsti) Support Taproot + )..addListener( + (transaction) async { + transactionHistory.addOne(transaction); + await updateBalance(); + }, + ); + } + Future signPsbt(String preProcessedPsbt, List utxos) async { final psbt = PsbtV2()..deserializeV0(base64Decode(preProcessedPsbt)); diff --git a/cw_bitcoin/lib/electrum_wallet.dart b/cw_bitcoin/lib/electrum_wallet.dart index 61726a7aef..09f200183d 100644 --- a/cw_bitcoin/lib/electrum_wallet.dart +++ b/cw_bitcoin/lib/electrum_wallet.dart @@ -1,18 +1,12 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:developer'; import 'dart:io'; import 'dart:isolate'; import 'package:bitcoin_base/bitcoin_base.dart'; -import 'package:cw_bitcoin/psbt_finalizer_v0.dart'; -import 'package:cw_bitcoin/psbt_signer.dart'; -import 'package:cw_bitcoin/psbt_transaction_builder.dart'; -import 'package:cw_bitcoin/psbt_v0_deserialize.dart'; import 'package:cw_core/utils/print_verbose.dart'; import 'package:cw_bitcoin/bitcoin_wallet.dart'; import 'package:cw_bitcoin/litecoin_wallet.dart'; -import 'package:ledger_bitcoin/psbt.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:blockchain_utils/blockchain_utils.dart'; import 'package:collection/collection.dart'; @@ -1208,122 +1202,6 @@ abstract class ElectrumWalletBase } } - Future psbtToPendingTx( - String preProcessedPsbt, - Object credentials, - dynamic pjUri, - ) async { - - final unspent = unspentCoins.where((e) => (e.isSending || !e.isFrozen)); - - List utxos = []; - - for (BitcoinUnspent input in unspent) { - final address = RegexUtils.addressTypeFromStr(input.address, BitcoinNetwork.mainnet); - - final newHd = input.bitcoinAddressRecord.isHidden - ? sideHd - : hd; - - ECPrivate privkey; - if (input.bitcoinAddressRecord is BitcoinSilentPaymentAddressRecord) { - final unspentAddress = input.bitcoinAddressRecord as BitcoinSilentPaymentAddressRecord; - privkey = walletAddresses.silentAddress!.b_spend.tweakAdd( - BigintUtils.fromBytes( - BytesUtils.fromHexString(unspentAddress.silentPaymentTweak!), - ), - ); - } else { - privkey = - generateECPrivate(hd: newHd, index: input.bitcoinAddressRecord.index, network: BitcoinNetwork.mainnet); - } - - utxos.add( - UtxoWithPrivateKey( - utxo: BitcoinUtxo( - txHash: input.hash, - value: BigInt.from(input.value), - vout: input.vout, - scriptType: input.bitcoinAddressRecord.type, - isSilentPayment: input.bitcoinAddressRecord is BitcoinSilentPaymentAddressRecord, - ), - ownerDetails: UtxoAddressDetails( - publicKey: newHd.publicKey.toHex(), - address: address, - ), - privateKey: privkey - ), - ); - } - - log(preProcessedPsbt); - final psbt = PsbtV2()..deserializeV0(base64.decode(preProcessedPsbt)); - - final inputCount = psbt.getGlobalInputCount(); - - final unsignedTx = []; - for (var i = 0; i < inputCount; i++) { - if (psbt.getInputFinalScriptsig(i) == null) { - try { - psbt.getInputFinalScriptwitness(i); - } catch (_) { - unsignedTx.add(BytesUtils.toHexString(psbt.getInputPreviousTxid(i).reversed.toList())); - } - } - } - - psbt.signWithUTXO(utxos.where((e) => unsignedTx.contains(e.utxo.txHash)).toList(), (txDigest, utxo, key, sighash) { - if (utxo.utxo.isP2tr()) { - return key.signTapRoot( - txDigest, - sighash: sighash, - tweak: utxo.utxo.isSilentPayment != true, - ); - } else { - return key.signInput(txDigest, sigHash: sighash); - } - }); - - psbt.finalizeV0(); - - final btcTx = BtcTransaction.fromRaw(hex.encode(psbt.extract())); - - return PendingBitcoinTransaction( - btcTx, - type, - electrumClient: electrumClient, - amount: psbt.getOutputAmount(0), // ToDo - fee: 0,// ToDo - feeRate: "Payjoin", // ToDo - network: network, - hasChange: true, - isSendAll: true, - hasTaprootInputs: false, // ToDo: (Konsti) Support Taproot - )..addListener( - (transaction) async { - transactionHistory.addOne(transaction); - await updateBalance(); - }, - ); - } - - Future getBtcTransactionFromPsbt( - String preProcessedPsbt) async => - throw UnimplementedError(); - - Future buildPayjoinTransaction({ - required List outputs, - required BigInt fee, - required BasedUtxoNetwork network, - required List utxos, - required Map publicKeys, - String? memo, - bool enableRBF = false, - BitcoinOrdering inputOrdering = BitcoinOrdering.bip69, - BitcoinOrdering outputOrdering = BitcoinOrdering.bip69, - }) async => - throw UnimplementedError(); - void setLedgerConnection(ledger.LedgerConnection connection) => throw UnimplementedError(); Future buildHardwareWalletTransaction({ diff --git a/lib/src/screens/send/widgets/send_card.dart b/lib/src/screens/send/widgets/send_card.dart index d9c22231e5..90e0f021e7 100644 --- a/lib/src/screens/send/widgets/send_card.dart +++ b/lib/src/screens/send/widgets/send_card.dart @@ -162,9 +162,7 @@ class SendCardState extends State with AutomaticKeepAliveClientMixin wallet.type == WalletType.bitcoin; - - @observable - bool payjoinPaymentsScanningActive = false; - - @action - void setPayjoinPaymentsScanning(bool active) { - payjoinPaymentsScanningActive = active; - - /// TODO: Set Payjoin receive polling - } - @computed bool get hasMweb => wallet.type == WalletType.litecoin && diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart index 11bae5e4d9..3ae5d5f5a4 100644 --- a/lib/view_model/send/send_view_model.dart +++ b/lib/view_model/send/send_view_model.dart @@ -390,11 +390,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor @action Future createTransaction({ExchangeProvider? provider}) async { - if (pjUri != null) { - debugPrint( - '[+] SENDPAGE => onAuthSuccess - INITIATE PAYJOIN SEND'); - return performPayjoinSend(); - } + if (pjUri != null) return performPayjoinSend(); // ToDo: Remove try { state = IsExecutingState();