diff --git a/doc/release-notes-28414.md b/doc/release-notes-28414.md index 7fca11f822..3f83a73252 100644 --- a/doc/release-notes-28414.md +++ b/doc/release-notes-28414.md @@ -1,5 +1,6 @@ RPC Wallet ---------- -- RPC `walletprocesspsbt` return object now includes field `hex` (if the transaction -is complete) containing the serialized transaction suitable for RPC `sendrawtransaction`. (#28414) +- RPC `walletprocesspsbt`, and `descriptorprocesspsbt` return object now includes field `hex` (if the transaction +is complete) containing the serialized transaction suitable for RPC `sendrawtransaction`. + diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index bb4b89f8ba..c3a3455c16 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -3219,6 +3219,7 @@ RPCHelpMan descriptorprocesspsbt() { {RPCResult::Type::STR, "psbt", "The base64-encoded partially signed transaction"}, {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"}, + {RPCResult::Type::STR_HEX, "hex", /*optional=*/true, "The hex-encoded network transaction if complete"}, } }, RPCExamples{ @@ -3259,7 +3260,14 @@ RPCHelpMan descriptorprocesspsbt() result.pushKV("psbt", EncodeBase64(ssTx)); result.pushKV("complete", complete); - + if (complete) { + CMutableTransaction mtx; + PartiallySignedTransaction psbtx_copy = psbtx; + CHECK_NONFATAL(FinalizeAndExtractPSBT(psbtx_copy, mtx)); + CDataStream ssTx_final(SER_NETWORK, PROTOCOL_VERSION); + ssTx_final << mtx; + result.pushKV("hex", HexStr(ssTx_final)); + } return result; }, }; diff --git a/test/functional/rpc_psbt.py b/test/functional/rpc_psbt.py index 72959ce9e1..0daed94ecd 100755 --- a/test/functional/rpc_psbt.py +++ b/test/functional/rpc_psbt.py @@ -1493,17 +1493,22 @@ class PSBTTest(BitcoinTestFramework): # test_psbt_input_keys(decoded['inputs'][0], ['witness_utxo', 'non_witness_utxo']) # Test that the psbt is not finalized and does not have bip32_derivs unless specified - # psbt = self.nodes[2].descriptorprocesspsbt(psbt=psbt, descriptors=[descriptor], sighashtype="ALL", bip32derivs=True, finalize=False)["psbt"] - # decoded = self.nodes[2].decodepsbt(psbt) + # processed_psbt = self.nodes[2].descriptorprocesspsbt(psbt=psbt, descriptors=[descriptor], sighashtype="ALL", bip32derivs=True, finalize=False) + # decoded = self.nodes[2].decodepsbt(processed_psbt['psbt']) # test_psbt_input_keys(decoded['inputs'][0], ['witness_utxo', 'non_witness_utxo', 'partial_signatures', 'bip32_derivs']) - # psbt = self.nodes[2].descriptorprocesspsbt(psbt=psbt, descriptors=[descriptor], sighashtype="ALL", bip32derivs=False, finalize=True)["psbt"] - # decoded = self.nodes[2].decodepsbt(psbt) + # If psbt not finalized, test that result does not have hex + # assert "hex" not in processed_psbt + + # processed_psbt = self.nodes[2].descriptorprocesspsbt(psbt=psbt, descriptors=[descriptor], sighashtype="ALL", bip32derivs=False, finalize=True) + # decoded = self.nodes[2].decodepsbt(processed_psbt['psbt']) # test_psbt_input_keys(decoded['inputs'][0], ['witness_utxo', 'non_witness_utxo', 'final_scriptwitness']) + # Test psbt is complete + # assert_equal(processed_psbt['complete'], True) + # Broadcast transaction - # rawtx = self.nodes[2].finalizepsbt(psbt)["hex"] - # self.nodes[2].sendrawtransaction(rawtx) + # self.nodes[2].sendrawtransaction(processed_psbt['hex']) self.log.info("Test descriptorprocesspsbt raises if an invalid sighashtype is passed") assert_raises_rpc_error(-8, "all is not a valid sighash parameter.", self.nodes[2].descriptorprocesspsbt, psbt, [descriptor], sighashtype="all")