feat: add unsignedPsbt to PendingBitcoinTransaction

This commit is contained in:
Konstantin Ullrich 2025-05-28 13:19:33 +02:00 committed by cyan
parent 355218753d
commit a9df2ee285
3 changed files with 43 additions and 22 deletions

View file

@ -372,8 +372,13 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
publicKeys: tx.publicKeys!,
masterFingerprint: Uint8List(0));
final originalPsbt = await signPsbt(
base64.encode(transaction.asPsbtV0()), getUtxoWithPrivateKeys());
if (tx.isViewOnly) {
tx.unsignedPsbt = transaction.serialize();
return tx;
}
final originalPsbt =
await signPsbt(base64.encode(transaction.asPsbtV0()), getUtxoWithPrivateKeys());
tx.commitOverride = () async {
final sender = await payjoinManager.initSender(
@ -405,6 +410,7 @@ abstract class BitcoinWalletBase extends ElectrumWallet with Store {
feeRate: "",
network: network,
hasChange: true,
isViewOnly: false,
).commit();
}

View file

@ -1119,7 +1119,8 @@ abstract class ElectrumWalletBase
network: network,
hasChange: estimatedTx.hasChange,
isSendAll: estimatedTx.isSendAll,
hasTaprootInputs: false, // ToDo: (Konsti) Support Taproot
hasTaprootInputs: false, // ToDo: (Konsti) Support Taproot,
isViewOnly: false,
)..addListener((transaction) async {
transactionHistory.addOne(transaction);
await updateBalance();
@ -1190,18 +1191,21 @@ abstract class ElectrumWalletBase
}
});
return PendingBitcoinTransaction(transaction, type,
electrumClient: electrumClient,
amount: estimatedTx.amount,
fee: estimatedTx.fee,
feeRate: feeRateInt.toString(),
network: network,
hasChange: estimatedTx.hasChange,
isSendAll: estimatedTx.isSendAll,
hasTaprootInputs: hasTaprootInputs,
utxos: estimatedTx.utxos,
publicKeys: estimatedTx.publicKeys)
..addListener((transaction) async {
return PendingBitcoinTransaction(
transaction,
type,
electrumClient: electrumClient,
amount: estimatedTx.amount,
fee: estimatedTx.fee,
feeRate: feeRateInt.toString(),
network: network,
hasChange: estimatedTx.hasChange,
isSendAll: estimatedTx.isSendAll,
hasTaprootInputs: hasTaprootInputs,
utxos: estimatedTx.utxos,
publicKeys: estimatedTx.publicKeys,
isViewOnly: keys.privateKey.isEmpty,
)..addListener((transaction) async {
transactionHistory.addOne(transaction);
if (estimatedTx.spendsSilentPayment) {
transactionHistory.transactions.values.forEach((tx) {
@ -1862,6 +1866,7 @@ abstract class ElectrumWalletBase
network: network,
hasChange: changeOutputs.isNotEmpty,
feeRate: newFee.toString(),
isViewOnly: keys.privateKey.isEmpty,
)..addListener((transaction) async {
transactionHistory.transactions.values.forEach((tx) {
if (tx.id == hash) {

View file

@ -34,6 +34,8 @@ class PendingBitcoinTransaction with PendingTransaction {
this.utxos = const [],
this.publicKeys,
this.commitOverride,
this.unsignedPsbt,
required this.isViewOnly,
}) : _listeners = <void Function(ElectrumTransactionInfo transaction)>[];
final WalletType type;
@ -46,6 +48,7 @@ class PendingBitcoinTransaction with PendingTransaction {
final bool isSendAll;
final bool hasChange;
final bool hasTaprootInputs;
final bool isViewOnly;
List<UtxoWithAddress> utxos;
bool isMweb;
String? changeAddressOverride;
@ -55,6 +58,8 @@ class PendingBitcoinTransaction with PendingTransaction {
final Map<String, PublicKeyWithDerivationPath>? publicKeys;
Future<void> Function()? commitOverride;
Uint8List? unsignedPsbt;
@override
String get id => idOverride ?? _tx.txId();
@ -78,9 +83,11 @@ class PendingBitcoinTransaction with PendingTransaction {
try {
final change = _tx.outputs.firstWhere((out) => out.isChange);
if (changeAddressOverride != null) {
return PendingChange(changeAddressOverride!, BtcUtils.fromSatoshi(change.amount));
return PendingChange(
changeAddressOverride!, BtcUtils.fromSatoshi(change.amount));
}
return PendingChange(change.scriptPubKey.toAddress(), BtcUtils.fromSatoshi(change.amount));
return PendingChange(
change.scriptPubKey.toAddress(), BtcUtils.fromSatoshi(change.amount));
} catch (_) {
return null;
}
@ -129,12 +136,14 @@ class PendingBitcoinTransaction with PendingTransaction {
Future<void> _ltcCommit() async {
try {
final resp = await CwMweb.broadcast(BroadcastRequest(rawTx: BytesUtils.fromHexString(hex)));
final resp = await CwMweb.broadcast(
BroadcastRequest(rawTx: BytesUtils.fromHexString(hex)));
idOverride = resp.txid;
} on GrpcError catch (e) {
throw BitcoinTransactionCommitFailed(errorMessage: e.message);
} catch (e) {
throw BitcoinTransactionCommitFailed(errorMessage: "Unknown error: ${e.toString()}");
throw BitcoinTransactionCommitFailed(
errorMessage: "Unknown error: ${e.toString()}");
}
}
@ -153,7 +162,8 @@ class PendingBitcoinTransaction with PendingTransaction {
_listeners.forEach((listener) => listener(transactionInfo()));
}
void addListener(void Function(ElectrumTransactionInfo transaction) listener) =>
void addListener(
void Function(ElectrumTransactionInfo transaction) listener) =>
_listeners.add(listener);
ElectrumTransactionInfo transactionInfo() => ElectrumTransactionInfo(type,
@ -171,7 +181,7 @@ class PendingBitcoinTransaction with PendingTransaction {
@override
Future<String?> commitUR() {
var sourceBytes = Uint8List.fromList(utf8.encode(hex));
var sourceBytes = unsignedPsbt!;
var cborEncoder = CBOREncoder();
cborEncoder.encodeBytes(sourceBytes);
var ur = UR("psbt", cborEncoder.getBytes());