Coverage Report

Created: 2025-06-10 13:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/bitcoin/src/rpc/rawtransaction.cpp
Line
Count
Source
1
// Copyright (c) 2010 Satoshi Nakamoto
2
// Copyright (c) 2009-present The Bitcoin Core developers
3
// Distributed under the MIT software license, see the accompanying
4
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6
#include <base58.h>
7
#include <chain.h>
8
#include <coins.h>
9
#include <consensus/amount.h>
10
#include <consensus/validation.h>
11
#include <core_io.h>
12
#include <index/txindex.h>
13
#include <key_io.h>
14
#include <node/blockstorage.h>
15
#include <node/coin.h>
16
#include <node/context.h>
17
#include <node/psbt.h>
18
#include <node/transaction.h>
19
#include <node/types.h>
20
#include <policy/packages.h>
21
#include <policy/policy.h>
22
#include <policy/rbf.h>
23
#include <primitives/transaction.h>
24
#include <psbt.h>
25
#include <random.h>
26
#include <rpc/blockchain.h>
27
#include <rpc/rawtransaction_util.h>
28
#include <rpc/server.h>
29
#include <rpc/server_util.h>
30
#include <rpc/util.h>
31
#include <script/script.h>
32
#include <script/sign.h>
33
#include <script/signingprovider.h>
34
#include <script/solver.h>
35
#include <uint256.h>
36
#include <undo.h>
37
#include <util/bip32.h>
38
#include <util/check.h>
39
#include <util/strencodings.h>
40
#include <util/string.h>
41
#include <util/vector.h>
42
#include <validation.h>
43
#include <validationinterface.h>
44
45
#include <numeric>
46
#include <stdint.h>
47
48
#include <univalue.h>
49
50
using node::AnalyzePSBT;
51
using node::FindCoins;
52
using node::GetTransaction;
53
using node::NodeContext;
54
using node::PSBTAnalysis;
55
56
static void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry,
57
                     Chainstate& active_chainstate, const CTxUndo* txundo = nullptr,
58
                     TxVerbosity verbosity = TxVerbosity::SHOW_DETAILS)
59
0
{
60
0
    CHECK_NONFATAL(verbosity >= TxVerbosity::SHOW_DETAILS);
61
    // Call into TxToUniv() in bitcoin-common to decode the transaction hex.
62
    //
63
    // Blockchain contextual information (confirmations and blocktime) is not
64
    // available to code in bitcoin-common, so we query them here and push the
65
    // data into the returned UniValue.
66
0
    TxToUniv(tx, /*block_hash=*/uint256(), entry, /*include_hex=*/true, txundo, verbosity);
67
68
0
    if (!hashBlock.IsNull()) {
  Branch (68:9): [True: 0, False: 0]
69
0
        LOCK(cs_main);
70
71
0
        entry.pushKV("blockhash", hashBlock.GetHex());
72
0
        const CBlockIndex* pindex = active_chainstate.m_blockman.LookupBlockIndex(hashBlock);
73
0
        if (pindex) {
  Branch (73:13): [True: 0, False: 0]
74
0
            if (active_chainstate.m_chain.Contains(pindex)) {
  Branch (74:17): [True: 0, False: 0]
75
0
                entry.pushKV("confirmations", 1 + active_chainstate.m_chain.Height() - pindex->nHeight);
76
0
                entry.pushKV("time", pindex->GetBlockTime());
77
0
                entry.pushKV("blocktime", pindex->GetBlockTime());
78
0
            }
79
0
            else
80
0
                entry.pushKV("confirmations", 0);
81
0
        }
82
0
    }
83
0
}
84
85
static std::vector<RPCResult> DecodeTxDoc(const std::string& txid_field_doc)
86
44.3k
{
87
44.3k
    return {
88
44.3k
        {RPCResult::Type::STR_HEX, "txid", txid_field_doc},
89
44.3k
        {RPCResult::Type::STR_HEX, "hash", "The transaction hash (differs from txid for witness transactions)"},
90
44.3k
        {RPCResult::Type::NUM, "size", "The serialized transaction size"},
91
44.3k
        {RPCResult::Type::NUM, "vsize", "The virtual transaction size (differs from size for witness transactions)"},
92
44.3k
        {RPCResult::Type::NUM, "weight", "The transaction's weight (between vsize*4-3 and vsize*4)"},
93
44.3k
        {RPCResult::Type::NUM, "version", "The version"},
94
44.3k
        {RPCResult::Type::NUM_TIME, "locktime", "The lock time"},
95
44.3k
        {RPCResult::Type::ARR, "vin", "",
96
44.3k
        {
97
44.3k
            {RPCResult::Type::OBJ, "", "",
98
44.3k
            {
99
44.3k
                {RPCResult::Type::STR_HEX, "coinbase", /*optional=*/true, "The coinbase value (only if coinbase transaction)"},
100
44.3k
                {RPCResult::Type::STR_HEX, "txid", /*optional=*/true, "The transaction id (if not coinbase transaction)"},
101
44.3k
                {RPCResult::Type::NUM, "vout", /*optional=*/true, "The output number (if not coinbase transaction)"},
102
44.3k
                {RPCResult::Type::OBJ, "scriptSig", /*optional=*/true, "The script (if not coinbase transaction)",
103
44.3k
                {
104
44.3k
                    {RPCResult::Type::STR, "asm", "Disassembly of the signature script"},
105
44.3k
                    {RPCResult::Type::STR_HEX, "hex", "The raw signature script bytes, hex-encoded"},
106
44.3k
                }},
107
44.3k
                {RPCResult::Type::ARR, "txinwitness", /*optional=*/true, "",
108
44.3k
                {
109
44.3k
                    {RPCResult::Type::STR_HEX, "hex", "hex-encoded witness data (if any)"},
110
44.3k
                }},
111
44.3k
                {RPCResult::Type::NUM, "sequence", "The script sequence number"},
112
44.3k
            }},
113
44.3k
        }},
114
44.3k
        {RPCResult::Type::ARR, "vout", "",
115
44.3k
        {
116
44.3k
            {RPCResult::Type::OBJ, "", "",
117
44.3k
            {
118
44.3k
                {RPCResult::Type::STR_AMOUNT, "value", "The value in " + CURRENCY_UNIT},
119
44.3k
                {RPCResult::Type::NUM, "n", "index"},
120
44.3k
                {RPCResult::Type::OBJ, "scriptPubKey", "", ScriptPubKeyDoc()},
121
44.3k
            }},
122
44.3k
        }},
123
44.3k
    };
124
44.3k
}
125
126
static std::vector<RPCArg> CreateTxDoc()
127
44.3k
{
128
44.3k
    return {
129
44.3k
        {"inputs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The inputs",
130
44.3k
            {
131
44.3k
                {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "",
132
44.3k
                    {
133
44.3k
                        {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
134
44.3k
                        {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},
135
44.3k
                        {"sequence", RPCArg::Type::NUM, RPCArg::DefaultHint{"depends on the value of the 'replaceable' and 'locktime' arguments"}, "The sequence number"},
136
44.3k
                    },
137
44.3k
                },
138
44.3k
            },
139
44.3k
        },
140
44.3k
        {"outputs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The outputs specified as key-value pairs.\n"
141
44.3k
                "Each key may only appear once, i.e. there can only be one 'data' output, and no address may be duplicated.\n"
142
44.3k
                "At least one output of either type must be specified.\n"
143
44.3k
                "For compatibility reasons, a dictionary, which holds the key-value pairs directly, is also\n"
144
44.3k
                "                             accepted as second parameter.",
145
44.3k
            {
146
44.3k
                {"", RPCArg::Type::OBJ_USER_KEYS, RPCArg::Optional::OMITTED, "",
147
44.3k
                    {
148
44.3k
                        {"address", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "A key-value pair. The key (string) is the bitcoin address, the value (float or string) is the amount in " + CURRENCY_UNIT},
149
44.3k
                    },
150
44.3k
                },
151
44.3k
                {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "",
152
44.3k
                    {
153
44.3k
                        {"data", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "A key-value pair. The key must be \"data\", the value is hex-encoded data that becomes a part of an OP_RETURN output"},
154
44.3k
                    },
155
44.3k
                },
156
44.3k
            },
157
44.3k
         RPCArgOptions{.skip_type_check = true}},
158
44.3k
        {"locktime", RPCArg::Type::NUM, RPCArg::Default{0}, "Raw locktime. Non-0 value also locktime-activates inputs"},
159
44.3k
        {"replaceable", RPCArg::Type::BOOL, RPCArg::Default{true}, "Marks this transaction as BIP125-replaceable.\n"
160
44.3k
                "Allows this transaction to be replaced by a transaction with higher fees. If provided, it is an error if explicit sequence numbers are incompatible."},
161
44.3k
    };
162
44.3k
}
163
164
// Update PSBT with information from the mempool, the UTXO set, the txindex, and the provided descriptors.
165
// Optionally, sign the inputs that we can using information from the descriptors.
166
PartiallySignedTransaction ProcessPSBT(const std::string& psbt_string, const std::any& context, const HidingSigningProvider& provider, std::optional<int> sighash_type, bool finalize)
167
0
{
168
    // Unserialize the transactions
169
0
    PartiallySignedTransaction psbtx;
170
0
    std::string error;
171
0
    if (!DecodeBase64PSBT(psbtx, psbt_string, error)) {
  Branch (171:9): [True: 0, False: 0]
172
0
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
173
0
    }
174
175
0
    if (g_txindex) g_txindex->BlockUntilSyncedToCurrentChain();
  Branch (175:9): [True: 0, False: 0]
176
0
    const NodeContext& node = EnsureAnyNodeContext(context);
177
178
    // If we can't find the corresponding full transaction for all of our inputs,
179
    // this will be used to find just the utxos for the segwit inputs for which
180
    // the full transaction isn't found
181
0
    std::map<COutPoint, Coin> coins;
182
183
    // Fetch previous transactions:
184
    // First, look in the txindex and the mempool
185
0
    for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
  Branch (185:30): [True: 0, False: 0]
186
0
        PSBTInput& psbt_input = psbtx.inputs.at(i);
187
0
        const CTxIn& tx_in = psbtx.tx->vin.at(i);
188
189
        // The `non_witness_utxo` is the whole previous transaction
190
0
        if (psbt_input.non_witness_utxo) continue;
  Branch (190:13): [True: 0, False: 0]
191
192
0
        CTransactionRef tx;
193
194
        // Look in the txindex
195
0
        if (g_txindex) {
  Branch (195:13): [True: 0, False: 0]
196
0
            uint256 block_hash;
197
0
            g_txindex->FindTx(tx_in.prevout.hash, block_hash, tx);
198
0
        }
199
        // If we still don't have it look in the mempool
200
0
        if (!tx) {
  Branch (200:13): [True: 0, False: 0]
201
0
            tx = node.mempool->get(tx_in.prevout.hash);
202
0
        }
203
0
        if (tx) {
  Branch (203:13): [True: 0, False: 0]
204
0
            psbt_input.non_witness_utxo = tx;
205
0
        } else {
206
0
            coins[tx_in.prevout]; // Create empty map entry keyed by prevout
207
0
        }
208
0
    }
209
210
    // If we still haven't found all of the inputs, look for the missing ones in the utxo set
211
0
    if (!coins.empty()) {
  Branch (211:9): [True: 0, False: 0]
212
0
        FindCoins(node, coins);
213
0
        for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
  Branch (213:34): [True: 0, False: 0]
214
0
            PSBTInput& input = psbtx.inputs.at(i);
215
216
            // If there are still missing utxos, add them if they were found in the utxo set
217
0
            if (!input.non_witness_utxo) {
  Branch (217:17): [True: 0, False: 0]
218
0
                const CTxIn& tx_in = psbtx.tx->vin.at(i);
219
0
                const Coin& coin = coins.at(tx_in.prevout);
220
0
                if (!coin.out.IsNull() && IsSegWitOutput(provider, coin.out.scriptPubKey)) {
  Branch (220:21): [True: 0, False: 0]
  Branch (220:43): [True: 0, False: 0]
221
0
                    input.witness_utxo = coin.out;
222
0
                }
223
0
            }
224
0
        }
225
0
    }
226
227
0
    const PrecomputedTransactionData& txdata = PrecomputePSBTData(psbtx);
228
229
0
    for (unsigned int i = 0; i < psbtx.tx->vin.size(); ++i) {
  Branch (229:30): [True: 0, False: 0]
230
0
        if (PSBTInputSigned(psbtx.inputs.at(i))) {
  Branch (230:13): [True: 0, False: 0]
231
0
            continue;
232
0
        }
233
234
        // Update script/keypath information using descriptor data.
235
        // Note that SignPSBTInput does a lot more than just constructing ECDSA signatures.
236
        // We only actually care about those if our signing provider doesn't hide private
237
        // information, as is the case with `descriptorprocesspsbt`
238
        // Only error for mismatching sighash types as it is critical that the sighash to sign with matches the PSBT's
239
0
        if (SignPSBTInput(provider, psbtx, /*index=*/i, &txdata, sighash_type, /*out_sigdata=*/nullptr, finalize) == common::PSBTError::SIGHASH_MISMATCH) {
  Branch (239:13): [True: 0, False: 0]
240
0
            throw JSONRPCPSBTError(common::PSBTError::SIGHASH_MISMATCH);
241
0
        }
242
0
    }
243
244
    // Update script/keypath information using descriptor data.
245
0
    for (unsigned int i = 0; i < psbtx.tx->vout.size(); ++i) {
  Branch (245:30): [True: 0, False: 0]
246
0
        UpdatePSBTOutput(provider, psbtx, i);
247
0
    }
248
249
0
    RemoveUnnecessaryTransactions(psbtx);
250
251
0
    return psbtx;
252
0
}
253
254
static RPCHelpMan getrawtransaction()
255
22.1k
{
256
22.1k
    return RPCHelpMan{
257
22.1k
                "getrawtransaction",
258
259
22.1k
                "By default, this call only returns a transaction if it is in the mempool. If -txindex is enabled\n"
260
22.1k
                "and no blockhash argument is passed, it will return the transaction if it is in the mempool or any block.\n"
261
22.1k
                "If a blockhash argument is passed, it will return the transaction if\n"
262
22.1k
                "the specified block is available and the transaction is in that block.\n\n"
263
22.1k
                "Hint: Use gettransaction for wallet transactions.\n\n"
264
265
22.1k
                "If verbosity is 0 or omitted, returns the serialized transaction as a hex-encoded string.\n"
266
22.1k
                "If verbosity is 1, returns a JSON Object with information about the transaction.\n"
267
22.1k
                "If verbosity is 2, returns a JSON Object with information about the transaction, including fee and prevout information.",
268
22.1k
                {
269
22.1k
                    {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
270
22.1k
                    {"verbosity|verbose", RPCArg::Type::NUM, RPCArg::Default{0}, "0 for hex-encoded data, 1 for a JSON object, and 2 for JSON object with fee and prevout",
271
22.1k
                     RPCArgOptions{.skip_type_check = true}},
272
22.1k
                    {"blockhash", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "The block in which to look for the transaction"},
273
22.1k
                },
274
22.1k
                {
275
22.1k
                    RPCResult{"if verbosity is not set or set to 0",
276
22.1k
                         RPCResult::Type::STR, "data", "The serialized transaction as a hex-encoded string for 'txid'"
277
22.1k
                     },
278
22.1k
                     RPCResult{"if verbosity is set to 1",
279
22.1k
                         RPCResult::Type::OBJ, "", "",
280
22.1k
                         Cat<std::vector<RPCResult>>(
281
22.1k
                         {
282
22.1k
                             {RPCResult::Type::BOOL, "in_active_chain", /*optional=*/true, "Whether specified block is in the active chain or not (only present with explicit \"blockhash\" argument)"},
283
22.1k
                             {RPCResult::Type::STR_HEX, "blockhash", /*optional=*/true, "the block hash"},
284
22.1k
                             {RPCResult::Type::NUM, "confirmations", /*optional=*/true, "The confirmations"},
285
22.1k
                             {RPCResult::Type::NUM_TIME, "blocktime", /*optional=*/true, "The block time expressed in " + UNIX_EPOCH_TIME},
286
22.1k
                             {RPCResult::Type::NUM, "time", /*optional=*/true, "Same as \"blocktime\""},
287
22.1k
                             {RPCResult::Type::STR_HEX, "hex", "The serialized, hex-encoded data for 'txid'"},
288
22.1k
                         },
289
22.1k
                         DecodeTxDoc(/*txid_field_doc=*/"The transaction id (same as provided)")),
290
22.1k
                    },
291
22.1k
                    RPCResult{"for verbosity = 2",
292
22.1k
                        RPCResult::Type::OBJ, "", "",
293
22.1k
                        {
294
22.1k
                            {RPCResult::Type::ELISION, "", "Same output as verbosity = 1"},
295
22.1k
                            {RPCResult::Type::NUM, "fee", /*optional=*/true, "transaction fee in " + CURRENCY_UNIT + ", omitted if block undo data is not available"},
296
22.1k
                            {RPCResult::Type::ARR, "vin", "",
297
22.1k
                            {
298
22.1k
                                {RPCResult::Type::OBJ, "", "utxo being spent",
299
22.1k
                                {
300
22.1k
                                    {RPCResult::Type::ELISION, "", "Same output as verbosity = 1"},
301
22.1k
                                    {RPCResult::Type::OBJ, "prevout", /*optional=*/true, "The previous output, omitted if block undo data is not available",
302
22.1k
                                    {
303
22.1k
                                        {RPCResult::Type::BOOL, "generated", "Coinbase or not"},
304
22.1k
                                        {RPCResult::Type::NUM, "height", "The height of the prevout"},
305
22.1k
                                        {RPCResult::Type::STR_AMOUNT, "value", "The value in " + CURRENCY_UNIT},
306
22.1k
                                        {RPCResult::Type::OBJ, "scriptPubKey", "", ScriptPubKeyDoc()},
307
22.1k
                                    }},
308
22.1k
                                }},
309
22.1k
                            }},
310
22.1k
                        }},
311
22.1k
                },
312
22.1k
                RPCExamples{
313
22.1k
                    HelpExampleCli("getrawtransaction", "\"mytxid\"")
314
22.1k
            + HelpExampleCli("getrawtransaction", "\"mytxid\" 1")
315
22.1k
            + HelpExampleRpc("getrawtransaction", "\"mytxid\", 1")
316
22.1k
            + HelpExampleCli("getrawtransaction", "\"mytxid\" 0 \"myblockhash\"")
317
22.1k
            + HelpExampleCli("getrawtransaction", "\"mytxid\" 1 \"myblockhash\"")
318
22.1k
            + HelpExampleCli("getrawtransaction", "\"mytxid\" 2 \"myblockhash\"")
319
22.1k
                },
320
22.1k
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
321
22.1k
{
322
0
    const NodeContext& node = EnsureAnyNodeContext(request.context);
323
0
    ChainstateManager& chainman = EnsureChainman(node);
324
325
0
    uint256 hash = ParseHashV(request.params[0], "parameter 1");
326
0
    const CBlockIndex* blockindex = nullptr;
327
328
0
    if (hash == chainman.GetParams().GenesisBlock().hashMerkleRoot) {
  Branch (328:9): [True: 0, False: 0]
329
        // Special exception for the genesis block coinbase transaction
330
0
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "The genesis block coinbase is not considered an ordinary transaction and cannot be retrieved");
331
0
    }
332
333
0
    int verbosity{ParseVerbosity(request.params[1], /*default_verbosity=*/0, /*allow_bool=*/true)};
334
335
0
    if (!request.params[2].isNull()) {
  Branch (335:9): [True: 0, False: 0]
336
0
        LOCK(cs_main);
337
338
0
        uint256 blockhash = ParseHashV(request.params[2], "parameter 3");
339
0
        blockindex = chainman.m_blockman.LookupBlockIndex(blockhash);
340
0
        if (!blockindex) {
  Branch (340:13): [True: 0, False: 0]
341
0
            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block hash not found");
342
0
        }
343
0
    }
344
345
0
    bool f_txindex_ready = false;
346
0
    if (g_txindex && !blockindex) {
  Branch (346:9): [True: 0, False: 0]
  Branch (346:22): [True: 0, False: 0]
347
0
        f_txindex_ready = g_txindex->BlockUntilSyncedToCurrentChain();
348
0
    }
349
350
0
    uint256 hash_block;
351
0
    const CTransactionRef tx = GetTransaction(blockindex, node.mempool.get(), hash, hash_block, chainman.m_blockman);
352
0
    if (!tx) {
  Branch (352:9): [True: 0, False: 0]
353
0
        std::string errmsg;
354
0
        if (blockindex) {
  Branch (354:13): [True: 0, False: 0]
355
0
            const bool block_has_data = WITH_LOCK(::cs_main, return blockindex->nStatus & BLOCK_HAVE_DATA);
356
0
            if (!block_has_data) {
  Branch (356:17): [True: 0, False: 0]
357
0
                throw JSONRPCError(RPC_MISC_ERROR, "Block not available");
358
0
            }
359
0
            errmsg = "No such transaction found in the provided block";
360
0
        } else if (!g_txindex) {
  Branch (360:20): [True: 0, False: 0]
361
0
            errmsg = "No such mempool transaction. Use -txindex or provide a block hash to enable blockchain transaction queries";
362
0
        } else if (!f_txindex_ready) {
  Branch (362:20): [True: 0, False: 0]
363
0
            errmsg = "No such mempool transaction. Blockchain transactions are still in the process of being indexed";
364
0
        } else {
365
0
            errmsg = "No such mempool or blockchain transaction";
366
0
        }
367
0
        throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, errmsg + ". Use gettransaction for wallet transactions.");
368
0
    }
369
370
0
    if (verbosity <= 0) {
  Branch (370:9): [True: 0, False: 0]
371
0
        return EncodeHexTx(*tx);
372
0
    }
373
374
0
    UniValue result(UniValue::VOBJ);
375
0
    if (blockindex) {
  Branch (375:9): [True: 0, False: 0]
376
0
        LOCK(cs_main);
377
0
        result.pushKV("in_active_chain", chainman.ActiveChain().Contains(blockindex));
378
0
    }
379
    // If request is verbosity >= 1 but no blockhash was given, then look up the blockindex
380
0
    if (request.params[2].isNull()) {
  Branch (380:9): [True: 0, False: 0]
381
0
        LOCK(cs_main);
382
0
        blockindex = chainman.m_blockman.LookupBlockIndex(hash_block); // May be nullptr for mempool transactions
383
0
    }
384
0
    if (verbosity == 1) {
  Branch (384:9): [True: 0, False: 0]
385
0
        TxToJSON(*tx, hash_block, result, chainman.ActiveChainstate());
386
0
        return result;
387
0
    }
388
389
0
    CBlockUndo blockUndo;
390
0
    CBlock block;
391
392
0
    if (tx->IsCoinBase() || !blockindex || WITH_LOCK(::cs_main, return !(blockindex->nStatus & BLOCK_HAVE_MASK))) {
  Branch (392:9): [True: 0, False: 0]
  Branch (392:9): [True: 0, False: 0]
  Branch (392:29): [True: 0, False: 0]
393
0
        TxToJSON(*tx, hash_block, result, chainman.ActiveChainstate());
394
0
        return result;
395
0
    }
396
0
    if (!chainman.m_blockman.ReadBlockUndo(blockUndo, *blockindex)) {
  Branch (396:9): [True: 0, False: 0]
397
0
        throw JSONRPCError(RPC_INTERNAL_ERROR, "Undo data expected but can't be read. This could be due to disk corruption or a conflict with a pruning event.");
398
0
    }
399
0
    if (!chainman.m_blockman.ReadBlock(block, *blockindex)) {
  Branch (399:9): [True: 0, False: 0]
400
0
        throw JSONRPCError(RPC_INTERNAL_ERROR, "Block data expected but can't be read. This could be due to disk corruption or a conflict with a pruning event.");
401
0
    }
402
403
0
    CTxUndo* undoTX {nullptr};
404
0
    auto it = std::find_if(block.vtx.begin(), block.vtx.end(), [tx](CTransactionRef t){ return *t == *tx; });
405
0
    if (it != block.vtx.end()) {
  Branch (405:9): [True: 0, False: 0]
406
        // -1 as blockundo does not have coinbase tx
407
0
        undoTX = &blockUndo.vtxundo.at(it - block.vtx.begin() - 1);
408
0
    }
409
0
    TxToJSON(*tx, hash_block, result, chainman.ActiveChainstate(), undoTX, TxVerbosity::SHOW_DETAILS_AND_PREVOUT);
410
0
    return result;
411
0
},
412
22.1k
    };
413
22.1k
}
414
415
static RPCHelpMan createrawtransaction()
416
22.1k
{
417
22.1k
    return RPCHelpMan{
418
22.1k
        "createrawtransaction",
419
22.1k
        "Create a transaction spending the given inputs and creating new outputs.\n"
420
22.1k
                "Outputs can be addresses or data.\n"
421
22.1k
                "Returns hex-encoded raw transaction.\n"
422
22.1k
                "Note that the transaction's inputs are not signed, and\n"
423
22.1k
                "it is not stored in the wallet or transmitted to the network.\n",
424
22.1k
                CreateTxDoc(),
425
22.1k
                RPCResult{
426
22.1k
                    RPCResult::Type::STR_HEX, "transaction", "hex string of the transaction"
427
22.1k
                },
428
22.1k
                RPCExamples{
429
22.1k
                    HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"address\\\":0.01}]\"")
430
22.1k
            + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"")
431
22.1k
            + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"[{\\\"address\\\":0.01}]\"")
432
22.1k
            + HelpExampleRpc("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\", \"[{\\\"data\\\":\\\"00010203\\\"}]\"")
433
22.1k
                },
434
22.1k
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
435
22.1k
{
436
0
    std::optional<bool> rbf;
437
0
    if (!request.params[3].isNull()) {
  Branch (437:9): [True: 0, False: 0]
438
0
        rbf = request.params[3].get_bool();
439
0
    }
440
0
    CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf);
441
442
0
    return EncodeHexTx(CTransaction(rawTx));
443
0
},
444
22.1k
    };
445
22.1k
}
446
447
static RPCHelpMan decoderawtransaction()
448
22.1k
{
449
22.1k
    return RPCHelpMan{"decoderawtransaction",
450
22.1k
                "Return a JSON object representing the serialized, hex-encoded transaction.",
451
22.1k
                {
452
22.1k
                    {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction hex string"},
453
22.1k
                    {"iswitness", RPCArg::Type::BOOL, RPCArg::DefaultHint{"depends on heuristic tests"}, "Whether the transaction hex is a serialized witness transaction.\n"
454
22.1k
                        "If iswitness is not present, heuristic tests will be used in decoding.\n"
455
22.1k
                        "If true, only witness deserialization will be tried.\n"
456
22.1k
                        "If false, only non-witness deserialization will be tried.\n"
457
22.1k
                        "This boolean should reflect whether the transaction has inputs\n"
458
22.1k
                        "(e.g. fully valid, or on-chain transactions), if known by the caller."
459
22.1k
                    },
460
22.1k
                },
461
22.1k
                RPCResult{
462
22.1k
                    RPCResult::Type::OBJ, "", "",
463
22.1k
                    DecodeTxDoc(/*txid_field_doc=*/"The transaction id"),
464
22.1k
                },
465
22.1k
                RPCExamples{
466
22.1k
                    HelpExampleCli("decoderawtransaction", "\"hexstring\"")
467
22.1k
            + HelpExampleRpc("decoderawtransaction", "\"hexstring\"")
468
22.1k
                },
469
22.1k
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
470
22.1k
{
471
0
    CMutableTransaction mtx;
472
473
0
    bool try_witness = request.params[1].isNull() ? true : request.params[1].get_bool();
  Branch (473:24): [True: 0, False: 0]
474
0
    bool try_no_witness = request.params[1].isNull() ? true : !request.params[1].get_bool();
  Branch (474:27): [True: 0, False: 0]
475
476
0
    if (!DecodeHexTx(mtx, request.params[0].get_str(), try_no_witness, try_witness)) {
  Branch (476:9): [True: 0, False: 0]
477
0
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
478
0
    }
479
480
0
    UniValue result(UniValue::VOBJ);
481
0
    TxToUniv(CTransaction(std::move(mtx)), /*block_hash=*/uint256(), /*entry=*/result, /*include_hex=*/false);
482
483
0
    return result;
484
0
},
485
22.1k
    };
486
22.1k
}
487
488
static RPCHelpMan decodescript()
489
22.1k
{
490
22.1k
    return RPCHelpMan{
491
22.1k
        "decodescript",
492
22.1k
        "Decode a hex-encoded script.\n",
493
22.1k
        {
494
22.1k
            {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "the hex-encoded script"},
495
22.1k
        },
496
22.1k
        RPCResult{
497
22.1k
            RPCResult::Type::OBJ, "", "",
498
22.1k
            {
499
22.1k
                {RPCResult::Type::STR, "asm", "Disassembly of the script"},
500
22.1k
                {RPCResult::Type::STR, "desc", "Inferred descriptor for the script"},
501
22.1k
                {RPCResult::Type::STR, "type", "The output type (e.g. " + GetAllOutputTypes() + ")"},
502
22.1k
                {RPCResult::Type::STR, "address", /*optional=*/true, "The Bitcoin address (only if a well-defined address exists)"},
503
22.1k
                {RPCResult::Type::STR, "p2sh", /*optional=*/true,
504
22.1k
                 "address of P2SH script wrapping this redeem script (not returned for types that should not be wrapped)"},
505
22.1k
                {RPCResult::Type::OBJ, "segwit", /*optional=*/true,
506
22.1k
                 "Result of a witness output script wrapping this redeem script (not returned for types that should not be wrapped)",
507
22.1k
                 {
508
22.1k
                     {RPCResult::Type::STR, "asm", "Disassembly of the output script"},
509
22.1k
                     {RPCResult::Type::STR_HEX, "hex", "The raw output script bytes, hex-encoded"},
510
22.1k
                     {RPCResult::Type::STR, "type", "The type of the output script (e.g. witness_v0_keyhash or witness_v0_scripthash)"},
511
22.1k
                     {RPCResult::Type::STR, "address", /*optional=*/true, "The Bitcoin address (only if a well-defined address exists)"},
512
22.1k
                     {RPCResult::Type::STR, "desc", "Inferred descriptor for the script"},
513
22.1k
                     {RPCResult::Type::STR, "p2sh-segwit", "address of the P2SH script wrapping this witness redeem script"},
514
22.1k
                 }},
515
22.1k
            },
516
22.1k
        },
517
22.1k
        RPCExamples{
518
22.1k
            HelpExampleCli("decodescript", "\"hexstring\"")
519
22.1k
          + HelpExampleRpc("decodescript", "\"hexstring\"")
520
22.1k
        },
521
22.1k
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
522
22.1k
{
523
0
    UniValue r(UniValue::VOBJ);
524
0
    CScript script;
525
0
    if (request.params[0].get_str().size() > 0){
  Branch (525:9): [True: 0, False: 0]
526
0
        std::vector<unsigned char> scriptData(ParseHexV(request.params[0], "argument"));
527
0
        script = CScript(scriptData.begin(), scriptData.end());
528
0
    } else {
529
        // Empty scripts are valid
530
0
    }
531
0
    ScriptToUniv(script, /*out=*/r, /*include_hex=*/false, /*include_address=*/true);
532
533
0
    std::vector<std::vector<unsigned char>> solutions_data;
534
0
    const TxoutType which_type{Solver(script, solutions_data)};
535
536
0
    const bool can_wrap{[&] {
537
0
        switch (which_type) {
  Branch (537:17): [True: 0, False: 0]
538
0
        case TxoutType::MULTISIG:
  Branch (538:9): [True: 0, False: 0]
539
0
        case TxoutType::NONSTANDARD:
  Branch (539:9): [True: 0, False: 0]
540
0
        case TxoutType::PUBKEY:
  Branch (540:9): [True: 0, False: 0]
541
0
        case TxoutType::PUBKEYHASH:
  Branch (541:9): [True: 0, False: 0]
542
0
        case TxoutType::WITNESS_V0_KEYHASH:
  Branch (542:9): [True: 0, False: 0]
543
0
        case TxoutType::WITNESS_V0_SCRIPTHASH:
  Branch (543:9): [True: 0, False: 0]
544
            // Can be wrapped if the checks below pass
545
0
            break;
546
0
        case TxoutType::NULL_DATA:
  Branch (546:9): [True: 0, False: 0]
547
0
        case TxoutType::SCRIPTHASH:
  Branch (547:9): [True: 0, False: 0]
548
0
        case TxoutType::WITNESS_UNKNOWN:
  Branch (548:9): [True: 0, False: 0]
549
0
        case TxoutType::WITNESS_V1_TAPROOT:
  Branch (549:9): [True: 0, False: 0]
550
0
        case TxoutType::ANCHOR:
  Branch (550:9): [True: 0, False: 0]
551
            // Should not be wrapped
552
0
            return false;
553
0
        } // no default case, so the compiler can warn about missing cases
554
0
        if (!script.HasValidOps() || script.IsUnspendable()) {
  Branch (554:13): [True: 0, False: 0]
  Branch (554:38): [True: 0, False: 0]
555
0
            return false;
556
0
        }
557
0
        for (CScript::const_iterator it{script.begin()}; it != script.end();) {
  Branch (557:58): [True: 0, False: 0]
558
0
            opcodetype op;
559
0
            CHECK_NONFATAL(script.GetOp(it, op));
560
0
            if (op == OP_CHECKSIGADD || IsOpSuccess(op)) {
  Branch (560:17): [True: 0, False: 0]
  Branch (560:41): [True: 0, False: 0]
561
0
                return false;
562
0
            }
563
0
        }
564
0
        return true;
565
0
    }()};
566
567
0
    if (can_wrap) {
  Branch (567:9): [True: 0, False: 0]
568
0
        r.pushKV("p2sh", EncodeDestination(ScriptHash(script)));
569
        // P2SH and witness programs cannot be wrapped in P2WSH, if this script
570
        // is a witness program, don't return addresses for a segwit programs.
571
0
        const bool can_wrap_P2WSH{[&] {
572
0
            switch (which_type) {
  Branch (572:21): [True: 0, False: 0]
573
0
            case TxoutType::MULTISIG:
  Branch (573:13): [True: 0, False: 0]
574
0
            case TxoutType::PUBKEY:
  Branch (574:13): [True: 0, False: 0]
575
            // Uncompressed pubkeys cannot be used with segwit checksigs.
576
            // If the script contains an uncompressed pubkey, skip encoding of a segwit program.
577
0
                for (const auto& solution : solutions_data) {
  Branch (577:43): [True: 0, False: 0]
578
0
                    if ((solution.size() != 1) && !CPubKey(solution).IsCompressed()) {
  Branch (578:25): [True: 0, False: 0]
  Branch (578:25): [True: 0, False: 0]
  Branch (578:51): [True: 0, False: 0]
579
0
                        return false;
580
0
                    }
581
0
                }
582
0
                return true;
583
0
            case TxoutType::NONSTANDARD:
  Branch (583:13): [True: 0, False: 0]
584
0
            case TxoutType::PUBKEYHASH:
  Branch (584:13): [True: 0, False: 0]
585
                // Can be P2WSH wrapped
586
0
                return true;
587
0
            case TxoutType::NULL_DATA:
  Branch (587:13): [True: 0, False: 0]
588
0
            case TxoutType::SCRIPTHASH:
  Branch (588:13): [True: 0, False: 0]
589
0
            case TxoutType::WITNESS_UNKNOWN:
  Branch (589:13): [True: 0, False: 0]
590
0
            case TxoutType::WITNESS_V0_KEYHASH:
  Branch (590:13): [True: 0, False: 0]
591
0
            case TxoutType::WITNESS_V0_SCRIPTHASH:
  Branch (591:13): [True: 0, False: 0]
592
0
            case TxoutType::WITNESS_V1_TAPROOT:
  Branch (592:13): [True: 0, False: 0]
593
0
            case TxoutType::ANCHOR:
  Branch (593:13): [True: 0, False: 0]
594
                // Should not be wrapped
595
0
                return false;
596
0
            } // no default case, so the compiler can warn about missing cases
597
0
            NONFATAL_UNREACHABLE();
598
0
        }()};
599
0
        if (can_wrap_P2WSH) {
  Branch (599:13): [True: 0, False: 0]
600
0
            UniValue sr(UniValue::VOBJ);
601
0
            CScript segwitScr;
602
0
            FlatSigningProvider provider;
603
0
            if (which_type == TxoutType::PUBKEY) {
  Branch (603:17): [True: 0, False: 0]
604
0
                segwitScr = GetScriptForDestination(WitnessV0KeyHash(Hash160(solutions_data[0])));
605
0
            } else if (which_type == TxoutType::PUBKEYHASH) {
  Branch (605:24): [True: 0, False: 0]
606
0
                segwitScr = GetScriptForDestination(WitnessV0KeyHash(uint160{solutions_data[0]}));
607
0
            } else {
608
                // Scripts that are not fit for P2WPKH are encoded as P2WSH.
609
0
                provider.scripts[CScriptID(script)] = script;
610
0
                segwitScr = GetScriptForDestination(WitnessV0ScriptHash(script));
611
0
            }
612
0
            ScriptToUniv(segwitScr, /*out=*/sr, /*include_hex=*/true, /*include_address=*/true, /*provider=*/&provider);
613
0
            sr.pushKV("p2sh-segwit", EncodeDestination(ScriptHash(segwitScr)));
614
0
            r.pushKV("segwit", std::move(sr));
615
0
        }
616
0
    }
617
618
0
    return r;
619
0
},
620
22.1k
    };
621
22.1k
}
622
623
static RPCHelpMan combinerawtransaction()
624
22.1k
{
625
22.1k
    return RPCHelpMan{
626
22.1k
        "combinerawtransaction",
627
22.1k
        "Combine multiple partially signed transactions into one transaction.\n"
628
22.1k
                "The combined transaction may be another partially signed transaction or a \n"
629
22.1k
                "fully signed transaction.",
630
22.1k
                {
631
22.1k
                    {"txs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The hex strings of partially signed transactions",
632
22.1k
                        {
633
22.1k
                            {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "A hex-encoded raw transaction"},
634
22.1k
                        },
635
22.1k
                        },
636
22.1k
                },
637
22.1k
                RPCResult{
638
22.1k
                    RPCResult::Type::STR, "", "The hex-encoded raw transaction with signature(s)"
639
22.1k
                },
640
22.1k
                RPCExamples{
641
22.1k
                    HelpExampleCli("combinerawtransaction", R"('["myhex1", "myhex2", "myhex3"]')")
642
22.1k
                },
643
22.1k
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
644
22.1k
{
645
646
0
    UniValue txs = request.params[0].get_array();
647
0
    std::vector<CMutableTransaction> txVariants(txs.size());
648
649
0
    for (unsigned int idx = 0; idx < txs.size(); idx++) {
  Branch (649:32): [True: 0, False: 0]
650
0
        if (!DecodeHexTx(txVariants[idx], txs[idx].get_str())) {
  Branch (650:13): [True: 0, False: 0]
651
0
            throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed for tx %d. Make sure the tx has at least one input.", idx));
652
0
        }
653
0
    }
654
655
0
    if (txVariants.empty()) {
  Branch (655:9): [True: 0, False: 0]
656
0
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transactions");
657
0
    }
658
659
    // mergedTx will end up with all the signatures; it
660
    // starts as a clone of the rawtx:
661
0
    CMutableTransaction mergedTx(txVariants[0]);
662
663
    // Fetch previous transactions (inputs):
664
0
    CCoinsView viewDummy;
665
0
    CCoinsViewCache view(&viewDummy);
666
0
    {
667
0
        NodeContext& node = EnsureAnyNodeContext(request.context);
668
0
        const CTxMemPool& mempool = EnsureMemPool(node);
669
0
        ChainstateManager& chainman = EnsureChainman(node);
670
0
        LOCK2(cs_main, mempool.cs);
671
0
        CCoinsViewCache &viewChain = chainman.ActiveChainstate().CoinsTip();
672
0
        CCoinsViewMemPool viewMempool(&viewChain, mempool);
673
0
        view.SetBackend(viewMempool); // temporarily switch cache backend to db+mempool view
674
675
0
        for (const CTxIn& txin : mergedTx.vin) {
  Branch (675:32): [True: 0, False: 0]
676
0
            view.AccessCoin(txin.prevout); // Load entries from viewChain into view; can fail.
677
0
        }
678
679
0
        view.SetBackend(viewDummy); // switch back to avoid locking mempool for too long
680
0
    }
681
682
    // Use CTransaction for the constant parts of the
683
    // transaction to avoid rehashing.
684
0
    const CTransaction txConst(mergedTx);
685
    // Sign what we can:
686
0
    for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
  Branch (686:30): [True: 0, False: 0]
687
0
        CTxIn& txin = mergedTx.vin[i];
688
0
        const Coin& coin = view.AccessCoin(txin.prevout);
689
0
        if (coin.IsSpent()) {
  Branch (689:13): [True: 0, False: 0]
690
0
            throw JSONRPCError(RPC_VERIFY_ERROR, "Input not found or already spent");
691
0
        }
692
0
        SignatureData sigdata;
693
694
        // ... and merge in other signatures:
695
0
        for (const CMutableTransaction& txv : txVariants) {
  Branch (695:45): [True: 0, False: 0]
696
0
            if (txv.vin.size() > i) {
  Branch (696:17): [True: 0, False: 0]
697
0
                sigdata.MergeSignatureData(DataFromTransaction(txv, i, coin.out));
698
0
            }
699
0
        }
700
0
        ProduceSignature(DUMMY_SIGNING_PROVIDER, MutableTransactionSignatureCreator(mergedTx, i, coin.out.nValue, 1), coin.out.scriptPubKey, sigdata);
701
702
0
        UpdateInput(txin, sigdata);
703
0
    }
704
705
0
    return EncodeHexTx(CTransaction(mergedTx));
706
0
},
707
22.1k
    };
708
22.1k
}
709
710
static RPCHelpMan signrawtransactionwithkey()
711
22.1k
{
712
22.1k
    return RPCHelpMan{
713
22.1k
        "signrawtransactionwithkey",
714
22.1k
        "Sign inputs for raw transaction (serialized, hex-encoded).\n"
715
22.1k
                "The second argument is an array of base58-encoded private\n"
716
22.1k
                "keys that will be the only keys used to sign the transaction.\n"
717
22.1k
                "The third optional argument (may be null) is an array of previous transaction outputs that\n"
718
22.1k
                "this transaction depends on but may not yet be in the block chain.\n",
719
22.1k
                {
720
22.1k
                    {"hexstring", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction hex string"},
721
22.1k
                    {"privkeys", RPCArg::Type::ARR, RPCArg::Optional::NO, "The base58-encoded private keys for signing",
722
22.1k
                        {
723
22.1k
                            {"privatekey", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "private key in base58-encoding"},
724
22.1k
                        },
725
22.1k
                        },
726
22.1k
                    {"prevtxs", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "The previous dependent transaction outputs",
727
22.1k
                        {
728
22.1k
                            {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "",
729
22.1k
                                {
730
22.1k
                                    {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
731
22.1k
                                    {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},
732
22.1k
                                    {"scriptPubKey", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "output script"},
733
22.1k
                                    {"redeemScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2SH) redeem script"},
734
22.1k
                                    {"witnessScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2WSH or P2SH-P2WSH) witness script"},
735
22.1k
                                    {"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::OMITTED, "(required for Segwit inputs) the amount spent"},
736
22.1k
                                },
737
22.1k
                                },
738
22.1k
                        },
739
22.1k
                        },
740
22.1k
                    {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"DEFAULT for Taproot, ALL otherwise"}, "The signature hash type. Must be one of:\n"
741
22.1k
            "       \"DEFAULT\"\n"
742
22.1k
            "       \"ALL\"\n"
743
22.1k
            "       \"NONE\"\n"
744
22.1k
            "       \"SINGLE\"\n"
745
22.1k
            "       \"ALL|ANYONECANPAY\"\n"
746
22.1k
            "       \"NONE|ANYONECANPAY\"\n"
747
22.1k
            "       \"SINGLE|ANYONECANPAY\"\n"
748
22.1k
                    },
749
22.1k
                },
750
22.1k
                RPCResult{
751
22.1k
                    RPCResult::Type::OBJ, "", "",
752
22.1k
                    {
753
22.1k
                        {RPCResult::Type::STR_HEX, "hex", "The hex-encoded raw transaction with signature(s)"},
754
22.1k
                        {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"},
755
22.1k
                        {RPCResult::Type::ARR, "errors", /*optional=*/true, "Script verification errors (if there are any)",
756
22.1k
                        {
757
22.1k
                            {RPCResult::Type::OBJ, "", "",
758
22.1k
                            {
759
22.1k
                                {RPCResult::Type::STR_HEX, "txid", "The hash of the referenced, previous transaction"},
760
22.1k
                                {RPCResult::Type::NUM, "vout", "The index of the output to spent and used as input"},
761
22.1k
                                {RPCResult::Type::ARR, "witness", "",
762
22.1k
                                {
763
22.1k
                                    {RPCResult::Type::STR_HEX, "witness", ""},
764
22.1k
                                }},
765
22.1k
                                {RPCResult::Type::STR_HEX, "scriptSig", "The hex-encoded signature script"},
766
22.1k
                                {RPCResult::Type::NUM, "sequence", "Script sequence number"},
767
22.1k
                                {RPCResult::Type::STR, "error", "Verification or signing error related to the input"},
768
22.1k
                            }},
769
22.1k
                        }},
770
22.1k
                    }
771
22.1k
                },
772
22.1k
                RPCExamples{
773
22.1k
                    HelpExampleCli("signrawtransactionwithkey", "\"myhex\" \"[\\\"key1\\\",\\\"key2\\\"]\"")
774
22.1k
            + HelpExampleRpc("signrawtransactionwithkey", "\"myhex\", \"[\\\"key1\\\",\\\"key2\\\"]\"")
775
22.1k
                },
776
22.1k
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
777
22.1k
{
778
0
    CMutableTransaction mtx;
779
0
    if (!DecodeHexTx(mtx, request.params[0].get_str())) {
  Branch (779:9): [True: 0, False: 0]
780
0
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input.");
781
0
    }
782
783
0
    FlatSigningProvider keystore;
784
0
    const UniValue& keys = request.params[1].get_array();
785
0
    for (unsigned int idx = 0; idx < keys.size(); ++idx) {
  Branch (785:32): [True: 0, False: 0]
786
0
        UniValue k = keys[idx];
787
0
        CKey key = DecodeSecret(k.get_str());
788
0
        if (!key.IsValid()) {
  Branch (788:13): [True: 0, False: 0]
789
0
            throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
790
0
        }
791
792
0
        CPubKey pubkey = key.GetPubKey();
793
0
        CKeyID key_id = pubkey.GetID();
794
0
        keystore.pubkeys.emplace(key_id, pubkey);
795
0
        keystore.keys.emplace(key_id, key);
796
0
    }
797
798
    // Fetch previous transactions (inputs):
799
0
    std::map<COutPoint, Coin> coins;
800
0
    for (const CTxIn& txin : mtx.vin) {
  Branch (800:28): [True: 0, False: 0]
801
0
        coins[txin.prevout]; // Create empty map entry keyed by prevout.
802
0
    }
803
0
    NodeContext& node = EnsureAnyNodeContext(request.context);
804
0
    FindCoins(node, coins);
805
806
    // Parse the prevtxs array
807
0
    ParsePrevouts(request.params[2], &keystore, coins);
808
809
0
    UniValue result(UniValue::VOBJ);
810
0
    SignTransaction(mtx, &keystore, coins, request.params[3], result);
811
0
    return result;
812
0
},
813
22.1k
    };
814
22.1k
}
815
816
const RPCResult decodepsbt_inputs{
817
    RPCResult::Type::ARR, "inputs", "",
818
    {
819
        {RPCResult::Type::OBJ, "", "",
820
        {
821
            {RPCResult::Type::OBJ, "non_witness_utxo", /*optional=*/true, "Decoded network transaction for non-witness UTXOs",
822
            {
823
                {RPCResult::Type::ELISION, "",""},
824
            }},
825
            {RPCResult::Type::OBJ, "witness_utxo", /*optional=*/true, "Transaction output for witness UTXOs",
826
            {
827
                {RPCResult::Type::NUM, "amount", "The value in " + CURRENCY_UNIT},
828
                {RPCResult::Type::OBJ, "scriptPubKey", "",
829
                {
830
                    {RPCResult::Type::STR, "asm", "Disassembly of the output script"},
831
                    {RPCResult::Type::STR, "desc", "Inferred descriptor for the output"},
832
                    {RPCResult::Type::STR_HEX, "hex", "The raw output script bytes, hex-encoded"},
833
                    {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
834
                    {RPCResult::Type::STR, "address", /*optional=*/true, "The Bitcoin address (only if a well-defined address exists)"},
835
                }},
836
            }},
837
            {RPCResult::Type::OBJ_DYN, "partial_signatures", /*optional=*/true, "",
838
            {
839
                {RPCResult::Type::STR, "pubkey", "The public key and signature that corresponds to it."},
840
            }},
841
            {RPCResult::Type::STR, "sighash", /*optional=*/true, "The sighash type to be used"},
842
            {RPCResult::Type::OBJ, "redeem_script", /*optional=*/true, "",
843
            {
844
                {RPCResult::Type::STR, "asm", "Disassembly of the redeem script"},
845
                {RPCResult::Type::STR_HEX, "hex", "The raw redeem script bytes, hex-encoded"},
846
                {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
847
            }},
848
            {RPCResult::Type::OBJ, "witness_script", /*optional=*/true, "",
849
            {
850
                {RPCResult::Type::STR, "asm", "Disassembly of the witness script"},
851
                {RPCResult::Type::STR_HEX, "hex", "The raw witness script bytes, hex-encoded"},
852
                {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
853
            }},
854
            {RPCResult::Type::ARR, "bip32_derivs", /*optional=*/true, "",
855
            {
856
                {RPCResult::Type::OBJ, "", "",
857
                {
858
                    {RPCResult::Type::STR, "pubkey", "The public key with the derivation path as the value."},
859
                    {RPCResult::Type::STR, "master_fingerprint", "The fingerprint of the master key"},
860
                    {RPCResult::Type::STR, "path", "The path"},
861
                }},
862
            }},
863
            {RPCResult::Type::OBJ, "final_scriptSig", /*optional=*/true, "",
864
            {
865
                {RPCResult::Type::STR, "asm", "Disassembly of the final signature script"},
866
                {RPCResult::Type::STR_HEX, "hex", "The raw final signature script bytes, hex-encoded"},
867
            }},
868
            {RPCResult::Type::ARR, "final_scriptwitness", /*optional=*/true, "",
869
            {
870
                {RPCResult::Type::STR_HEX, "", "hex-encoded witness data (if any)"},
871
            }},
872
            {RPCResult::Type::OBJ_DYN, "ripemd160_preimages", /*optional=*/ true, "",
873
            {
874
                {RPCResult::Type::STR, "hash", "The hash and preimage that corresponds to it."},
875
            }},
876
            {RPCResult::Type::OBJ_DYN, "sha256_preimages", /*optional=*/ true, "",
877
            {
878
                {RPCResult::Type::STR, "hash", "The hash and preimage that corresponds to it."},
879
            }},
880
            {RPCResult::Type::OBJ_DYN, "hash160_preimages", /*optional=*/ true, "",
881
            {
882
                {RPCResult::Type::STR, "hash", "The hash and preimage that corresponds to it."},
883
            }},
884
            {RPCResult::Type::OBJ_DYN, "hash256_preimages", /*optional=*/ true, "",
885
            {
886
                {RPCResult::Type::STR, "hash", "The hash and preimage that corresponds to it."},
887
            }},
888
            {RPCResult::Type::STR_HEX, "taproot_key_path_sig", /*optional=*/ true, "hex-encoded signature for the Taproot key path spend"},
889
            {RPCResult::Type::ARR, "taproot_script_path_sigs", /*optional=*/ true, "",
890
            {
891
                {RPCResult::Type::OBJ, "signature", /*optional=*/ true, "The signature for the pubkey and leaf hash combination",
892
                {
893
                    {RPCResult::Type::STR, "pubkey", "The x-only pubkey for this signature"},
894
                    {RPCResult::Type::STR, "leaf_hash", "The leaf hash for this signature"},
895
                    {RPCResult::Type::STR, "sig", "The signature itself"},
896
                }},
897
            }},
898
            {RPCResult::Type::ARR, "taproot_scripts", /*optional=*/ true, "",
899
            {
900
                {RPCResult::Type::OBJ, "", "",
901
                {
902
                    {RPCResult::Type::STR_HEX, "script", "A leaf script"},
903
                    {RPCResult::Type::NUM, "leaf_ver", "The version number for the leaf script"},
904
                    {RPCResult::Type::ARR, "control_blocks", "The control blocks for this script",
905
                    {
906
                        {RPCResult::Type::STR_HEX, "control_block", "A hex-encoded control block for this script"},
907
                    }},
908
                }},
909
            }},
910
            {RPCResult::Type::ARR, "taproot_bip32_derivs", /*optional=*/ true, "",
911
            {
912
                {RPCResult::Type::OBJ, "", "",
913
                {
914
                    {RPCResult::Type::STR, "pubkey", "The x-only public key this path corresponds to"},
915
                    {RPCResult::Type::STR, "master_fingerprint", "The fingerprint of the master key"},
916
                    {RPCResult::Type::STR, "path", "The path"},
917
                    {RPCResult::Type::ARR, "leaf_hashes", "The hashes of the leaves this pubkey appears in",
918
                    {
919
                        {RPCResult::Type::STR_HEX, "hash", "The hash of a leaf this pubkey appears in"},
920
                    }},
921
                }},
922
            }},
923
            {RPCResult::Type::STR_HEX, "taproot_internal_key", /*optional=*/ true, "The hex-encoded Taproot x-only internal key"},
924
            {RPCResult::Type::STR_HEX, "taproot_merkle_root", /*optional=*/ true, "The hex-encoded Taproot merkle root"},
925
            {RPCResult::Type::ARR, "musig2_participant_pubkeys", /*optional=*/true, "",
926
            {
927
                {RPCResult::Type::OBJ, "", "",
928
                {
929
                    {RPCResult::Type::STR_HEX, "aggregate_pubkey", "The compressed aggregate public key for which the participants create."},
930
                    {RPCResult::Type::ARR, "participant_pubkeys", "",
931
                    {
932
                        {RPCResult::Type::STR_HEX, "pubkey", "The compressed public keys that are aggregated for aggregate_pubkey."},
933
                    }},
934
                }},
935
            }},
936
            {RPCResult::Type::ARR, "musig2_pubnonces", /*optional=*/true, "",
937
            {
938
                {RPCResult::Type::OBJ, "", "",
939
                {
940
                    {RPCResult::Type::STR_HEX, "participant_pubkey", "The compressed public key of the participant that created this pubnonce."},
941
                    {RPCResult::Type::STR_HEX, "aggregate_pubkey", "The compressed aggregate public key for which this pubnonce is for."},
942
                    {RPCResult::Type::STR_HEX, "leaf_hash", /*optional=*/true, "The hash of the leaf script that contains the aggregate pubkey being signed for. Omitted when signing for the internal key."},
943
                    {RPCResult::Type::STR_HEX, "pubnonce", "The public nonce itself."},
944
                }},
945
            }},
946
            {RPCResult::Type::ARR, "musig2_partial_sigs", /*optional=*/true, "",
947
            {
948
                {RPCResult::Type::OBJ, "", "",
949
                {
950
                    {RPCResult::Type::STR_HEX, "participant_pubkey", "The compressed public key of the participant that created this partial signature."},
951
                    {RPCResult::Type::STR_HEX, "aggregate_pubkey", "The compressed aggregate public key for which this partial signature is for."},
952
                    {RPCResult::Type::STR_HEX, "leaf_hash", /*optional=*/true, "The hash of the leaf script that contains the aggregate pubkey being signed for. Omitted when signing for the internal key."},
953
                    {RPCResult::Type::STR_HEX, "partial_sig", "The partial signature itself."},
954
                }},
955
            }},
956
            {RPCResult::Type::OBJ_DYN, "unknown", /*optional=*/ true, "The unknown input fields",
957
            {
958
                {RPCResult::Type::STR_HEX, "key", "(key-value pair) An unknown key-value pair"},
959
            }},
960
            {RPCResult::Type::ARR, "proprietary", /*optional=*/true, "The input proprietary map",
961
            {
962
                {RPCResult::Type::OBJ, "", "",
963
                {
964
                    {RPCResult::Type::STR_HEX, "identifier", "The hex string for the proprietary identifier"},
965
                    {RPCResult::Type::NUM, "subtype", "The number for the subtype"},
966
                    {RPCResult::Type::STR_HEX, "key", "The hex for the key"},
967
                    {RPCResult::Type::STR_HEX, "value", "The hex for the value"},
968
                }},
969
            }},
970
        }},
971
    }
972
};
973
974
const RPCResult decodepsbt_outputs{
975
    RPCResult::Type::ARR, "outputs", "",
976
    {
977
        {RPCResult::Type::OBJ, "", "",
978
        {
979
            {RPCResult::Type::OBJ, "redeem_script", /*optional=*/true, "",
980
            {
981
                {RPCResult::Type::STR, "asm", "Disassembly of the redeem script"},
982
                {RPCResult::Type::STR_HEX, "hex", "The raw redeem script bytes, hex-encoded"},
983
                {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
984
            }},
985
            {RPCResult::Type::OBJ, "witness_script", /*optional=*/true, "",
986
            {
987
                {RPCResult::Type::STR, "asm", "Disassembly of the witness script"},
988
                {RPCResult::Type::STR_HEX, "hex", "The raw witness script bytes, hex-encoded"},
989
                {RPCResult::Type::STR, "type", "The type, eg 'pubkeyhash'"},
990
            }},
991
            {RPCResult::Type::ARR, "bip32_derivs", /*optional=*/true, "",
992
            {
993
                {RPCResult::Type::OBJ, "", "",
994
                {
995
                    {RPCResult::Type::STR, "pubkey", "The public key this path corresponds to"},
996
                    {RPCResult::Type::STR, "master_fingerprint", "The fingerprint of the master key"},
997
                    {RPCResult::Type::STR, "path", "The path"},
998
                }},
999
            }},
1000
            {RPCResult::Type::STR_HEX, "taproot_internal_key", /*optional=*/ true, "The hex-encoded Taproot x-only internal key"},
1001
            {RPCResult::Type::ARR, "taproot_tree", /*optional=*/ true, "The tuples that make up the Taproot tree, in depth first search order",
1002
            {
1003
                {RPCResult::Type::OBJ, "tuple", /*optional=*/ true, "A single leaf script in the taproot tree",
1004
                {
1005
                    {RPCResult::Type::NUM, "depth", "The depth of this element in the tree"},
1006
                    {RPCResult::Type::NUM, "leaf_ver", "The version of this leaf"},
1007
                    {RPCResult::Type::STR, "script", "The hex-encoded script itself"},
1008
                }},
1009
            }},
1010
            {RPCResult::Type::ARR, "taproot_bip32_derivs", /*optional=*/ true, "",
1011
            {
1012
                {RPCResult::Type::OBJ, "", "",
1013
                {
1014
                    {RPCResult::Type::STR, "pubkey", "The x-only public key this path corresponds to"},
1015
                    {RPCResult::Type::STR, "master_fingerprint", "The fingerprint of the master key"},
1016
                    {RPCResult::Type::STR, "path", "The path"},
1017
                    {RPCResult::Type::ARR, "leaf_hashes", "The hashes of the leaves this pubkey appears in",
1018
                    {
1019
                        {RPCResult::Type::STR_HEX, "hash", "The hash of a leaf this pubkey appears in"},
1020
                    }},
1021
                }},
1022
            }},
1023
            {RPCResult::Type::ARR, "musig2_participant_pubkeys", /*optional=*/true, "",
1024
            {
1025
                {RPCResult::Type::OBJ, "", "",
1026
                {
1027
                    {RPCResult::Type::STR_HEX, "aggregate_pubkey", "The compressed aggregate public key for which the participants create."},
1028
                    {RPCResult::Type::ARR, "participant_pubkeys", "",
1029
                    {
1030
                        {RPCResult::Type::STR_HEX, "pubkey", "The compressed public keys that are aggregated for aggregate_pubkey."},
1031
                    }},
1032
                }},
1033
            }},
1034
            {RPCResult::Type::OBJ_DYN, "unknown", /*optional=*/true, "The unknown output fields",
1035
            {
1036
                {RPCResult::Type::STR_HEX, "key", "(key-value pair) An unknown key-value pair"},
1037
            }},
1038
            {RPCResult::Type::ARR, "proprietary", /*optional=*/true, "The output proprietary map",
1039
            {
1040
                {RPCResult::Type::OBJ, "", "",
1041
                {
1042
                    {RPCResult::Type::STR_HEX, "identifier", "The hex string for the proprietary identifier"},
1043
                    {RPCResult::Type::NUM, "subtype", "The number for the subtype"},
1044
                    {RPCResult::Type::STR_HEX, "key", "The hex for the key"},
1045
                    {RPCResult::Type::STR_HEX, "value", "The hex for the value"},
1046
                }},
1047
            }},
1048
        }},
1049
    }
1050
};
1051
1052
static RPCHelpMan decodepsbt()
1053
22.1k
{
1054
22.1k
    return RPCHelpMan{
1055
22.1k
        "decodepsbt",
1056
22.1k
        "Return a JSON object representing the serialized, base64-encoded partially signed Bitcoin transaction.",
1057
22.1k
                {
1058
22.1k
                    {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The PSBT base64 string"},
1059
22.1k
                },
1060
22.1k
                RPCResult{
1061
22.1k
                    RPCResult::Type::OBJ, "", "",
1062
22.1k
                    {
1063
22.1k
                        {RPCResult::Type::OBJ, "tx", "The decoded network-serialized unsigned transaction.",
1064
22.1k
                        {
1065
22.1k
                            {RPCResult::Type::ELISION, "", "The layout is the same as the output of decoderawtransaction."},
1066
22.1k
                        }},
1067
22.1k
                        {RPCResult::Type::ARR, "global_xpubs", "",
1068
22.1k
                        {
1069
22.1k
                            {RPCResult::Type::OBJ, "", "",
1070
22.1k
                            {
1071
22.1k
                                {RPCResult::Type::STR, "xpub", "The extended public key this path corresponds to"},
1072
22.1k
                                {RPCResult::Type::STR_HEX, "master_fingerprint", "The fingerprint of the master key"},
1073
22.1k
                                {RPCResult::Type::STR, "path", "The path"},
1074
22.1k
                            }},
1075
22.1k
                        }},
1076
22.1k
                        {RPCResult::Type::NUM, "psbt_version", "The PSBT version number. Not to be confused with the unsigned transaction version"},
1077
22.1k
                        {RPCResult::Type::ARR, "proprietary", "The global proprietary map",
1078
22.1k
                        {
1079
22.1k
                            {RPCResult::Type::OBJ, "", "",
1080
22.1k
                            {
1081
22.1k
                                {RPCResult::Type::STR_HEX, "identifier", "The hex string for the proprietary identifier"},
1082
22.1k
                                {RPCResult::Type::NUM, "subtype", "The number for the subtype"},
1083
22.1k
                                {RPCResult::Type::STR_HEX, "key", "The hex for the key"},
1084
22.1k
                                {RPCResult::Type::STR_HEX, "value", "The hex for the value"},
1085
22.1k
                            }},
1086
22.1k
                        }},
1087
22.1k
                        {RPCResult::Type::OBJ_DYN, "unknown", "The unknown global fields",
1088
22.1k
                        {
1089
22.1k
                             {RPCResult::Type::STR_HEX, "key", "(key-value pair) An unknown key-value pair"},
1090
22.1k
                        }},
1091
22.1k
                        decodepsbt_inputs,
1092
22.1k
                        decodepsbt_outputs,
1093
22.1k
                        {RPCResult::Type::STR_AMOUNT, "fee", /*optional=*/true, "The transaction fee paid if all UTXOs slots in the PSBT have been filled."},
1094
22.1k
                    }
1095
22.1k
                },
1096
22.1k
                RPCExamples{
1097
22.1k
                    HelpExampleCli("decodepsbt", "\"psbt\"")
1098
22.1k
                },
1099
22.1k
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1100
22.1k
{
1101
    // Unserialize the transactions
1102
0
    PartiallySignedTransaction psbtx;
1103
0
    std::string error;
1104
0
    if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
  Branch (1104:9): [True: 0, False: 0]
1105
0
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
1106
0
    }
1107
1108
0
    UniValue result(UniValue::VOBJ);
1109
1110
    // Add the decoded tx
1111
0
    UniValue tx_univ(UniValue::VOBJ);
1112
0
    TxToUniv(CTransaction(*psbtx.tx), /*block_hash=*/uint256(), /*entry=*/tx_univ, /*include_hex=*/false);
1113
0
    result.pushKV("tx", std::move(tx_univ));
1114
1115
    // Add the global xpubs
1116
0
    UniValue global_xpubs(UniValue::VARR);
1117
0
    for (std::pair<KeyOriginInfo, std::set<CExtPubKey>> xpub_pair : psbtx.m_xpubs) {
  Branch (1117:67): [True: 0, False: 0]
1118
0
        for (auto& xpub : xpub_pair.second) {
  Branch (1118:25): [True: 0, False: 0]
1119
0
            std::vector<unsigned char> ser_xpub;
1120
0
            ser_xpub.assign(BIP32_EXTKEY_WITH_VERSION_SIZE, 0);
1121
0
            xpub.EncodeWithVersion(ser_xpub.data());
1122
1123
0
            UniValue keypath(UniValue::VOBJ);
1124
0
            keypath.pushKV("xpub", EncodeBase58Check(ser_xpub));
1125
0
            keypath.pushKV("master_fingerprint", HexStr(std::span<unsigned char>(xpub_pair.first.fingerprint, xpub_pair.first.fingerprint + 4)));
1126
0
            keypath.pushKV("path", WriteHDKeypath(xpub_pair.first.path));
1127
0
            global_xpubs.push_back(std::move(keypath));
1128
0
        }
1129
0
    }
1130
0
    result.pushKV("global_xpubs", std::move(global_xpubs));
1131
1132
    // PSBT version
1133
0
    result.pushKV("psbt_version", static_cast<uint64_t>(psbtx.GetVersion()));
1134
1135
    // Proprietary
1136
0
    UniValue proprietary(UniValue::VARR);
1137
0
    for (const auto& entry : psbtx.m_proprietary) {
  Branch (1137:28): [True: 0, False: 0]
1138
0
        UniValue this_prop(UniValue::VOBJ);
1139
0
        this_prop.pushKV("identifier", HexStr(entry.identifier));
1140
0
        this_prop.pushKV("subtype", entry.subtype);
1141
0
        this_prop.pushKV("key", HexStr(entry.key));
1142
0
        this_prop.pushKV("value", HexStr(entry.value));
1143
0
        proprietary.push_back(std::move(this_prop));
1144
0
    }
1145
0
    result.pushKV("proprietary", std::move(proprietary));
1146
1147
    // Unknown data
1148
0
    UniValue unknowns(UniValue::VOBJ);
1149
0
    for (auto entry : psbtx.unknown) {
  Branch (1149:21): [True: 0, False: 0]
1150
0
        unknowns.pushKV(HexStr(entry.first), HexStr(entry.second));
1151
0
    }
1152
0
    result.pushKV("unknown", std::move(unknowns));
1153
1154
    // inputs
1155
0
    CAmount total_in = 0;
1156
0
    bool have_all_utxos = true;
1157
0
    UniValue inputs(UniValue::VARR);
1158
0
    for (unsigned int i = 0; i < psbtx.inputs.size(); ++i) {
  Branch (1158:30): [True: 0, False: 0]
1159
0
        const PSBTInput& input = psbtx.inputs[i];
1160
0
        UniValue in(UniValue::VOBJ);
1161
        // UTXOs
1162
0
        bool have_a_utxo = false;
1163
0
        CTxOut txout;
1164
0
        if (!input.witness_utxo.IsNull()) {
  Branch (1164:13): [True: 0, False: 0]
1165
0
            txout = input.witness_utxo;
1166
1167
0
            UniValue o(UniValue::VOBJ);
1168
0
            ScriptToUniv(txout.scriptPubKey, /*out=*/o, /*include_hex=*/true, /*include_address=*/true);
1169
1170
0
            UniValue out(UniValue::VOBJ);
1171
0
            out.pushKV("amount", ValueFromAmount(txout.nValue));
1172
0
            out.pushKV("scriptPubKey", std::move(o));
1173
1174
0
            in.pushKV("witness_utxo", std::move(out));
1175
1176
0
            have_a_utxo = true;
1177
0
        }
1178
0
        if (input.non_witness_utxo) {
  Branch (1178:13): [True: 0, False: 0]
1179
0
            txout = input.non_witness_utxo->vout[psbtx.tx->vin[i].prevout.n];
1180
1181
0
            UniValue non_wit(UniValue::VOBJ);
1182
0
            TxToUniv(*input.non_witness_utxo, /*block_hash=*/uint256(), /*entry=*/non_wit, /*include_hex=*/false);
1183
0
            in.pushKV("non_witness_utxo", std::move(non_wit));
1184
1185
0
            have_a_utxo = true;
1186
0
        }
1187
0
        if (have_a_utxo) {
  Branch (1187:13): [True: 0, False: 0]
1188
0
            if (MoneyRange(txout.nValue) && MoneyRange(total_in + txout.nValue)) {
  Branch (1188:17): [True: 0, False: 0]
  Branch (1188:17): [True: 0, False: 0]
  Branch (1188:45): [True: 0, False: 0]
1189
0
                total_in += txout.nValue;
1190
0
            } else {
1191
                // Hack to just not show fee later
1192
0
                have_all_utxos = false;
1193
0
            }
1194
0
        } else {
1195
0
            have_all_utxos = false;
1196
0
        }
1197
1198
        // Partial sigs
1199
0
        if (!input.partial_sigs.empty()) {
  Branch (1199:13): [True: 0, False: 0]
1200
0
            UniValue partial_sigs(UniValue::VOBJ);
1201
0
            for (const auto& sig : input.partial_sigs) {
  Branch (1201:34): [True: 0, False: 0]
1202
0
                partial_sigs.pushKV(HexStr(sig.second.first), HexStr(sig.second.second));
1203
0
            }
1204
0
            in.pushKV("partial_signatures", std::move(partial_sigs));
1205
0
        }
1206
1207
        // Sighash
1208
0
        if (input.sighash_type != std::nullopt) {
  Branch (1208:13): [True: 0, False: 0]
1209
0
            in.pushKV("sighash", SighashToStr((unsigned char)*input.sighash_type));
1210
0
        }
1211
1212
        // Redeem script and witness script
1213
0
        if (!input.redeem_script.empty()) {
  Branch (1213:13): [True: 0, False: 0]
1214
0
            UniValue r(UniValue::VOBJ);
1215
0
            ScriptToUniv(input.redeem_script, /*out=*/r);
1216
0
            in.pushKV("redeem_script", std::move(r));
1217
0
        }
1218
0
        if (!input.witness_script.empty()) {
  Branch (1218:13): [True: 0, False: 0]
1219
0
            UniValue r(UniValue::VOBJ);
1220
0
            ScriptToUniv(input.witness_script, /*out=*/r);
1221
0
            in.pushKV("witness_script", std::move(r));
1222
0
        }
1223
1224
        // keypaths
1225
0
        if (!input.hd_keypaths.empty()) {
  Branch (1225:13): [True: 0, False: 0]
1226
0
            UniValue keypaths(UniValue::VARR);
1227
0
            for (auto entry : input.hd_keypaths) {
  Branch (1227:29): [True: 0, False: 0]
1228
0
                UniValue keypath(UniValue::VOBJ);
1229
0
                keypath.pushKV("pubkey", HexStr(entry.first));
1230
1231
0
                keypath.pushKV("master_fingerprint", strprintf("%08x", ReadBE32(entry.second.fingerprint)));
1232
0
                keypath.pushKV("path", WriteHDKeypath(entry.second.path));
1233
0
                keypaths.push_back(std::move(keypath));
1234
0
            }
1235
0
            in.pushKV("bip32_derivs", std::move(keypaths));
1236
0
        }
1237
1238
        // Final scriptSig and scriptwitness
1239
0
        if (!input.final_script_sig.empty()) {
  Branch (1239:13): [True: 0, False: 0]
1240
0
            UniValue scriptsig(UniValue::VOBJ);
1241
0
            scriptsig.pushKV("asm", ScriptToAsmStr(input.final_script_sig, true));
1242
0
            scriptsig.pushKV("hex", HexStr(input.final_script_sig));
1243
0
            in.pushKV("final_scriptSig", std::move(scriptsig));
1244
0
        }
1245
0
        if (!input.final_script_witness.IsNull()) {
  Branch (1245:13): [True: 0, False: 0]
1246
0
            UniValue txinwitness(UniValue::VARR);
1247
0
            for (const auto& item : input.final_script_witness.stack) {
  Branch (1247:35): [True: 0, False: 0]
1248
0
                txinwitness.push_back(HexStr(item));
1249
0
            }
1250
0
            in.pushKV("final_scriptwitness", std::move(txinwitness));
1251
0
        }
1252
1253
        // Ripemd160 hash preimages
1254
0
        if (!input.ripemd160_preimages.empty()) {
  Branch (1254:13): [True: 0, False: 0]
1255
0
            UniValue ripemd160_preimages(UniValue::VOBJ);
1256
0
            for (const auto& [hash, preimage] : input.ripemd160_preimages) {
  Branch (1256:47): [True: 0, False: 0]
1257
0
                ripemd160_preimages.pushKV(HexStr(hash), HexStr(preimage));
1258
0
            }
1259
0
            in.pushKV("ripemd160_preimages", std::move(ripemd160_preimages));
1260
0
        }
1261
1262
        // Sha256 hash preimages
1263
0
        if (!input.sha256_preimages.empty()) {
  Branch (1263:13): [True: 0, False: 0]
1264
0
            UniValue sha256_preimages(UniValue::VOBJ);
1265
0
            for (const auto& [hash, preimage] : input.sha256_preimages) {
  Branch (1265:47): [True: 0, False: 0]
1266
0
                sha256_preimages.pushKV(HexStr(hash), HexStr(preimage));
1267
0
            }
1268
0
            in.pushKV("sha256_preimages", std::move(sha256_preimages));
1269
0
        }
1270
1271
        // Hash160 hash preimages
1272
0
        if (!input.hash160_preimages.empty()) {
  Branch (1272:13): [True: 0, False: 0]
1273
0
            UniValue hash160_preimages(UniValue::VOBJ);
1274
0
            for (const auto& [hash, preimage] : input.hash160_preimages) {
  Branch (1274:47): [True: 0, False: 0]
1275
0
                hash160_preimages.pushKV(HexStr(hash), HexStr(preimage));
1276
0
            }
1277
0
            in.pushKV("hash160_preimages", std::move(hash160_preimages));
1278
0
        }
1279
1280
        // Hash256 hash preimages
1281
0
        if (!input.hash256_preimages.empty()) {
  Branch (1281:13): [True: 0, False: 0]
1282
0
            UniValue hash256_preimages(UniValue::VOBJ);
1283
0
            for (const auto& [hash, preimage] : input.hash256_preimages) {
  Branch (1283:47): [True: 0, False: 0]
1284
0
                hash256_preimages.pushKV(HexStr(hash), HexStr(preimage));
1285
0
            }
1286
0
            in.pushKV("hash256_preimages", std::move(hash256_preimages));
1287
0
        }
1288
1289
        // Taproot key path signature
1290
0
        if (!input.m_tap_key_sig.empty()) {
  Branch (1290:13): [True: 0, False: 0]
1291
0
            in.pushKV("taproot_key_path_sig", HexStr(input.m_tap_key_sig));
1292
0
        }
1293
1294
        // Taproot script path signatures
1295
0
        if (!input.m_tap_script_sigs.empty()) {
  Branch (1295:13): [True: 0, False: 0]
1296
0
            UniValue script_sigs(UniValue::VARR);
1297
0
            for (const auto& [pubkey_leaf, sig] : input.m_tap_script_sigs) {
  Branch (1297:49): [True: 0, False: 0]
1298
0
                const auto& [xonly, leaf_hash] = pubkey_leaf;
1299
0
                UniValue sigobj(UniValue::VOBJ);
1300
0
                sigobj.pushKV("pubkey", HexStr(xonly));
1301
0
                sigobj.pushKV("leaf_hash", HexStr(leaf_hash));
1302
0
                sigobj.pushKV("sig", HexStr(sig));
1303
0
                script_sigs.push_back(std::move(sigobj));
1304
0
            }
1305
0
            in.pushKV("taproot_script_path_sigs", std::move(script_sigs));
1306
0
        }
1307
1308
        // Taproot leaf scripts
1309
0
        if (!input.m_tap_scripts.empty()) {
  Branch (1309:13): [True: 0, False: 0]
1310
0
            UniValue tap_scripts(UniValue::VARR);
1311
0
            for (const auto& [leaf, control_blocks] : input.m_tap_scripts) {
  Branch (1311:53): [True: 0, False: 0]
1312
0
                const auto& [script, leaf_ver] = leaf;
1313
0
                UniValue script_info(UniValue::VOBJ);
1314
0
                script_info.pushKV("script", HexStr(script));
1315
0
                script_info.pushKV("leaf_ver", leaf_ver);
1316
0
                UniValue control_blocks_univ(UniValue::VARR);
1317
0
                for (const auto& control_block : control_blocks) {
  Branch (1317:48): [True: 0, False: 0]
1318
0
                    control_blocks_univ.push_back(HexStr(control_block));
1319
0
                }
1320
0
                script_info.pushKV("control_blocks", std::move(control_blocks_univ));
1321
0
                tap_scripts.push_back(std::move(script_info));
1322
0
            }
1323
0
            in.pushKV("taproot_scripts", std::move(tap_scripts));
1324
0
        }
1325
1326
        // Taproot bip32 keypaths
1327
0
        if (!input.m_tap_bip32_paths.empty()) {
  Branch (1327:13): [True: 0, False: 0]
1328
0
            UniValue keypaths(UniValue::VARR);
1329
0
            for (const auto& [xonly, leaf_origin] : input.m_tap_bip32_paths) {
  Branch (1329:51): [True: 0, False: 0]
1330
0
                const auto& [leaf_hashes, origin] = leaf_origin;
1331
0
                UniValue path_obj(UniValue::VOBJ);
1332
0
                path_obj.pushKV("pubkey", HexStr(xonly));
1333
0
                path_obj.pushKV("master_fingerprint", strprintf("%08x", ReadBE32(origin.fingerprint)));
1334
0
                path_obj.pushKV("path", WriteHDKeypath(origin.path));
1335
0
                UniValue leaf_hashes_arr(UniValue::VARR);
1336
0
                for (const auto& leaf_hash : leaf_hashes) {
  Branch (1336:44): [True: 0, False: 0]
1337
0
                    leaf_hashes_arr.push_back(HexStr(leaf_hash));
1338
0
                }
1339
0
                path_obj.pushKV("leaf_hashes", std::move(leaf_hashes_arr));
1340
0
                keypaths.push_back(std::move(path_obj));
1341
0
            }
1342
0
            in.pushKV("taproot_bip32_derivs", std::move(keypaths));
1343
0
        }
1344
1345
        // Taproot internal key
1346
0
        if (!input.m_tap_internal_key.IsNull()) {
  Branch (1346:13): [True: 0, False: 0]
1347
0
            in.pushKV("taproot_internal_key", HexStr(input.m_tap_internal_key));
1348
0
        }
1349
1350
        // Write taproot merkle root
1351
0
        if (!input.m_tap_merkle_root.IsNull()) {
  Branch (1351:13): [True: 0, False: 0]
1352
0
            in.pushKV("taproot_merkle_root", HexStr(input.m_tap_merkle_root));
1353
0
        }
1354
1355
        // Write MuSig2 fields
1356
0
        if (!input.m_musig2_participants.empty()) {
  Branch (1356:13): [True: 0, False: 0]
1357
0
            UniValue musig_pubkeys(UniValue::VARR);
1358
0
            for (const auto& [agg, parts] : input.m_musig2_participants) {
  Branch (1358:43): [True: 0, False: 0]
1359
0
                UniValue musig_part(UniValue::VOBJ);
1360
0
                musig_part.pushKV("aggregate_pubkey", HexStr(agg));
1361
0
                UniValue part_pubkeys(UniValue::VARR);
1362
0
                for (const auto& pub : parts) {
  Branch (1362:38): [True: 0, False: 0]
1363
0
                    part_pubkeys.push_back(HexStr(pub));
1364
0
                }
1365
0
                musig_part.pushKV("participant_pubkeys", part_pubkeys);
1366
0
                musig_pubkeys.push_back(musig_part);
1367
0
            }
1368
0
            in.pushKV("musig2_participant_pubkeys", musig_pubkeys);
1369
0
        }
1370
0
        if (!input.m_musig2_pubnonces.empty()) {
  Branch (1370:13): [True: 0, False: 0]
1371
0
            UniValue musig_pubnonces(UniValue::VARR);
1372
0
            for (const auto& [agg_lh, part_pubnonce] : input.m_musig2_pubnonces) {
  Branch (1372:54): [True: 0, False: 0]
1373
0
                const auto& [agg, lh] = agg_lh;
1374
0
                for (const auto& [part, pubnonce] : part_pubnonce) {
  Branch (1374:51): [True: 0, False: 0]
1375
0
                    UniValue info(UniValue::VOBJ);
1376
0
                    info.pushKV("participant_pubkey", HexStr(part));
1377
0
                    info.pushKV("aggregate_pubkey", HexStr(agg));
1378
0
                    if (!lh.IsNull()) info.pushKV("leaf_hash", HexStr(lh));
  Branch (1378:25): [True: 0, False: 0]
1379
0
                    info.pushKV("pubnonce", HexStr(pubnonce));
1380
0
                    musig_pubnonces.push_back(info);
1381
0
                }
1382
0
            }
1383
0
            in.pushKV("musig2_pubnonces", musig_pubnonces);
1384
0
        }
1385
0
        if (!input.m_musig2_partial_sigs.empty()) {
  Branch (1385:13): [True: 0, False: 0]
1386
0
            UniValue musig_partial_sigs(UniValue::VARR);
1387
0
            for (const auto& [agg_lh, part_psig] : input.m_musig2_partial_sigs) {
  Branch (1387:50): [True: 0, False: 0]
1388
0
                const auto& [agg, lh] = agg_lh;
1389
0
                for (const auto& [part, psig] : part_psig) {
  Branch (1389:47): [True: 0, False: 0]
1390
0
                    UniValue info(UniValue::VOBJ);
1391
0
                    info.pushKV("participant_pubkey", HexStr(part));
1392
0
                    info.pushKV("aggregate_pubkey", HexStr(agg));
1393
0
                    if (!lh.IsNull()) info.pushKV("leaf_hash", HexStr(lh));
  Branch (1393:25): [True: 0, False: 0]
1394
0
                    info.pushKV("partial_sig", HexStr(psig));
1395
0
                    musig_partial_sigs.push_back(info);
1396
0
                }
1397
0
            }
1398
0
            in.pushKV("musig2_partial_sigs", musig_partial_sigs);
1399
0
        }
1400
1401
        // Proprietary
1402
0
        if (!input.m_proprietary.empty()) {
  Branch (1402:13): [True: 0, False: 0]
1403
0
            UniValue proprietary(UniValue::VARR);
1404
0
            for (const auto& entry : input.m_proprietary) {
  Branch (1404:36): [True: 0, False: 0]
1405
0
                UniValue this_prop(UniValue::VOBJ);
1406
0
                this_prop.pushKV("identifier", HexStr(entry.identifier));
1407
0
                this_prop.pushKV("subtype", entry.subtype);
1408
0
                this_prop.pushKV("key", HexStr(entry.key));
1409
0
                this_prop.pushKV("value", HexStr(entry.value));
1410
0
                proprietary.push_back(std::move(this_prop));
1411
0
            }
1412
0
            in.pushKV("proprietary", std::move(proprietary));
1413
0
        }
1414
1415
        // Unknown data
1416
0
        if (input.unknown.size() > 0) {
  Branch (1416:13): [True: 0, False: 0]
1417
0
            UniValue unknowns(UniValue::VOBJ);
1418
0
            for (auto entry : input.unknown) {
  Branch (1418:29): [True: 0, False: 0]
1419
0
                unknowns.pushKV(HexStr(entry.first), HexStr(entry.second));
1420
0
            }
1421
0
            in.pushKV("unknown", std::move(unknowns));
1422
0
        }
1423
1424
0
        inputs.push_back(std::move(in));
1425
0
    }
1426
0
    result.pushKV("inputs", std::move(inputs));
1427
1428
    // outputs
1429
0
    CAmount output_value = 0;
1430
0
    UniValue outputs(UniValue::VARR);
1431
0
    for (unsigned int i = 0; i < psbtx.outputs.size(); ++i) {
  Branch (1431:30): [True: 0, False: 0]
1432
0
        const PSBTOutput& output = psbtx.outputs[i];
1433
0
        UniValue out(UniValue::VOBJ);
1434
        // Redeem script and witness script
1435
0
        if (!output.redeem_script.empty()) {
  Branch (1435:13): [True: 0, False: 0]
1436
0
            UniValue r(UniValue::VOBJ);
1437
0
            ScriptToUniv(output.redeem_script, /*out=*/r);
1438
0
            out.pushKV("redeem_script", std::move(r));
1439
0
        }
1440
0
        if (!output.witness_script.empty()) {
  Branch (1440:13): [True: 0, False: 0]
1441
0
            UniValue r(UniValue::VOBJ);
1442
0
            ScriptToUniv(output.witness_script, /*out=*/r);
1443
0
            out.pushKV("witness_script", std::move(r));
1444
0
        }
1445
1446
        // keypaths
1447
0
        if (!output.hd_keypaths.empty()) {
  Branch (1447:13): [True: 0, False: 0]
1448
0
            UniValue keypaths(UniValue::VARR);
1449
0
            for (auto entry : output.hd_keypaths) {
  Branch (1449:29): [True: 0, False: 0]
1450
0
                UniValue keypath(UniValue::VOBJ);
1451
0
                keypath.pushKV("pubkey", HexStr(entry.first));
1452
0
                keypath.pushKV("master_fingerprint", strprintf("%08x", ReadBE32(entry.second.fingerprint)));
1453
0
                keypath.pushKV("path", WriteHDKeypath(entry.second.path));
1454
0
                keypaths.push_back(std::move(keypath));
1455
0
            }
1456
0
            out.pushKV("bip32_derivs", std::move(keypaths));
1457
0
        }
1458
1459
        // Taproot internal key
1460
0
        if (!output.m_tap_internal_key.IsNull()) {
  Branch (1460:13): [True: 0, False: 0]
1461
0
            out.pushKV("taproot_internal_key", HexStr(output.m_tap_internal_key));
1462
0
        }
1463
1464
        // Taproot tree
1465
0
        if (!output.m_tap_tree.empty()) {
  Branch (1465:13): [True: 0, False: 0]
1466
0
            UniValue tree(UniValue::VARR);
1467
0
            for (const auto& [depth, leaf_ver, script] : output.m_tap_tree) {
  Branch (1467:56): [True: 0, False: 0]
1468
0
                UniValue elem(UniValue::VOBJ);
1469
0
                elem.pushKV("depth", (int)depth);
1470
0
                elem.pushKV("leaf_ver", (int)leaf_ver);
1471
0
                elem.pushKV("script", HexStr(script));
1472
0
                tree.push_back(std::move(elem));
1473
0
            }
1474
0
            out.pushKV("taproot_tree", std::move(tree));
1475
0
        }
1476
1477
        // Taproot bip32 keypaths
1478
0
        if (!output.m_tap_bip32_paths.empty()) {
  Branch (1478:13): [True: 0, False: 0]
1479
0
            UniValue keypaths(UniValue::VARR);
1480
0
            for (const auto& [xonly, leaf_origin] : output.m_tap_bip32_paths) {
  Branch (1480:51): [True: 0, False: 0]
1481
0
                const auto& [leaf_hashes, origin] = leaf_origin;
1482
0
                UniValue path_obj(UniValue::VOBJ);
1483
0
                path_obj.pushKV("pubkey", HexStr(xonly));
1484
0
                path_obj.pushKV("master_fingerprint", strprintf("%08x", ReadBE32(origin.fingerprint)));
1485
0
                path_obj.pushKV("path", WriteHDKeypath(origin.path));
1486
0
                UniValue leaf_hashes_arr(UniValue::VARR);
1487
0
                for (const auto& leaf_hash : leaf_hashes) {
  Branch (1487:44): [True: 0, False: 0]
1488
0
                    leaf_hashes_arr.push_back(HexStr(leaf_hash));
1489
0
                }
1490
0
                path_obj.pushKV("leaf_hashes", std::move(leaf_hashes_arr));
1491
0
                keypaths.push_back(std::move(path_obj));
1492
0
            }
1493
0
            out.pushKV("taproot_bip32_derivs", std::move(keypaths));
1494
0
        }
1495
1496
        // Write MuSig2 fields
1497
0
        if (!output.m_musig2_participants.empty()) {
  Branch (1497:13): [True: 0, False: 0]
1498
0
            UniValue musig_pubkeys(UniValue::VARR);
1499
0
            for (const auto& [agg, parts] : output.m_musig2_participants) {
  Branch (1499:43): [True: 0, False: 0]
1500
0
                UniValue musig_part(UniValue::VOBJ);
1501
0
                musig_part.pushKV("aggregate_pubkey", HexStr(agg));
1502
0
                UniValue part_pubkeys(UniValue::VARR);
1503
0
                for (const auto& pub : parts) {
  Branch (1503:38): [True: 0, False: 0]
1504
0
                    part_pubkeys.push_back(HexStr(pub));
1505
0
                }
1506
0
                musig_part.pushKV("participant_pubkeys", part_pubkeys);
1507
0
                musig_pubkeys.push_back(musig_part);
1508
0
            }
1509
0
            out.pushKV("musig2_participant_pubkeys", musig_pubkeys);
1510
0
        }
1511
1512
        // Proprietary
1513
0
        if (!output.m_proprietary.empty()) {
  Branch (1513:13): [True: 0, False: 0]
1514
0
            UniValue proprietary(UniValue::VARR);
1515
0
            for (const auto& entry : output.m_proprietary) {
  Branch (1515:36): [True: 0, False: 0]
1516
0
                UniValue this_prop(UniValue::VOBJ);
1517
0
                this_prop.pushKV("identifier", HexStr(entry.identifier));
1518
0
                this_prop.pushKV("subtype", entry.subtype);
1519
0
                this_prop.pushKV("key", HexStr(entry.key));
1520
0
                this_prop.pushKV("value", HexStr(entry.value));
1521
0
                proprietary.push_back(std::move(this_prop));
1522
0
            }
1523
0
            out.pushKV("proprietary", std::move(proprietary));
1524
0
        }
1525
1526
        // Unknown data
1527
0
        if (output.unknown.size() > 0) {
  Branch (1527:13): [True: 0, False: 0]
1528
0
            UniValue unknowns(UniValue::VOBJ);
1529
0
            for (auto entry : output.unknown) {
  Branch (1529:29): [True: 0, False: 0]
1530
0
                unknowns.pushKV(HexStr(entry.first), HexStr(entry.second));
1531
0
            }
1532
0
            out.pushKV("unknown", std::move(unknowns));
1533
0
        }
1534
1535
0
        outputs.push_back(std::move(out));
1536
1537
        // Fee calculation
1538
0
        if (MoneyRange(psbtx.tx->vout[i].nValue) && MoneyRange(output_value + psbtx.tx->vout[i].nValue)) {
  Branch (1538:13): [True: 0, False: 0]
  Branch (1538:13): [True: 0, False: 0]
  Branch (1538:53): [True: 0, False: 0]
1539
0
            output_value += psbtx.tx->vout[i].nValue;
1540
0
        } else {
1541
            // Hack to just not show fee later
1542
0
            have_all_utxos = false;
1543
0
        }
1544
0
    }
1545
0
    result.pushKV("outputs", std::move(outputs));
1546
0
    if (have_all_utxos) {
  Branch (1546:9): [True: 0, False: 0]
1547
0
        result.pushKV("fee", ValueFromAmount(total_in - output_value));
1548
0
    }
1549
1550
0
    return result;
1551
0
},
1552
22.1k
    };
1553
22.1k
}
1554
1555
static RPCHelpMan combinepsbt()
1556
22.1k
{
1557
22.1k
    return RPCHelpMan{
1558
22.1k
        "combinepsbt",
1559
22.1k
        "Combine multiple partially signed Bitcoin transactions into one transaction.\n"
1560
22.1k
                "Implements the Combiner role.\n",
1561
22.1k
                {
1562
22.1k
                    {"txs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The base64 strings of partially signed transactions",
1563
22.1k
                        {
1564
22.1k
                            {"psbt", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "A base64 string of a PSBT"},
1565
22.1k
                        },
1566
22.1k
                        },
1567
22.1k
                },
1568
22.1k
                RPCResult{
1569
22.1k
                    RPCResult::Type::STR, "", "The base64-encoded partially signed transaction"
1570
22.1k
                },
1571
22.1k
                RPCExamples{
1572
22.1k
                    HelpExampleCli("combinepsbt", R"('["mybase64_1", "mybase64_2", "mybase64_3"]')")
1573
22.1k
                },
1574
22.1k
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1575
22.1k
{
1576
    // Unserialize the transactions
1577
0
    std::vector<PartiallySignedTransaction> psbtxs;
1578
0
    UniValue txs = request.params[0].get_array();
1579
0
    if (txs.empty()) {
  Branch (1579:9): [True: 0, False: 0]
1580
0
        throw JSONRPCError(RPC_INVALID_PARAMETER, "Parameter 'txs' cannot be empty");
1581
0
    }
1582
0
    for (unsigned int i = 0; i < txs.size(); ++i) {
  Branch (1582:30): [True: 0, False: 0]
1583
0
        PartiallySignedTransaction psbtx;
1584
0
        std::string error;
1585
0
        if (!DecodeBase64PSBT(psbtx, txs[i].get_str(), error)) {
  Branch (1585:13): [True: 0, False: 0]
1586
0
            throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
1587
0
        }
1588
0
        psbtxs.push_back(psbtx);
1589
0
    }
1590
1591
0
    PartiallySignedTransaction merged_psbt;
1592
0
    if (!CombinePSBTs(merged_psbt, psbtxs)) {
  Branch (1592:9): [True: 0, False: 0]
1593
0
        throw JSONRPCError(RPC_INVALID_PARAMETER, "PSBTs not compatible (different transactions)");
1594
0
    }
1595
1596
0
    DataStream ssTx{};
1597
0
    ssTx << merged_psbt;
1598
0
    return EncodeBase64(ssTx);
1599
0
},
1600
22.1k
    };
1601
22.1k
}
1602
1603
static RPCHelpMan finalizepsbt()
1604
22.1k
{
1605
22.1k
    return RPCHelpMan{"finalizepsbt",
1606
22.1k
                "Finalize the inputs of a PSBT. If the transaction is fully signed, it will produce a\n"
1607
22.1k
                "network serialized transaction which can be broadcast with sendrawtransaction. Otherwise a PSBT will be\n"
1608
22.1k
                "created which has the final_scriptSig and final_scriptWitness fields filled for inputs that are complete.\n"
1609
22.1k
                "Implements the Finalizer and Extractor roles.\n",
1610
22.1k
                {
1611
22.1k
                    {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"},
1612
22.1k
                    {"extract", RPCArg::Type::BOOL, RPCArg::Default{true}, "If true and the transaction is complete,\n"
1613
22.1k
            "                             extract and return the complete transaction in normal network serialization instead of the PSBT."},
1614
22.1k
                },
1615
22.1k
                RPCResult{
1616
22.1k
                    RPCResult::Type::OBJ, "", "",
1617
22.1k
                    {
1618
22.1k
                        {RPCResult::Type::STR, "psbt", /*optional=*/true, "The base64-encoded partially signed transaction if not extracted"},
1619
22.1k
                        {RPCResult::Type::STR_HEX, "hex", /*optional=*/true, "The hex-encoded network transaction if extracted"},
1620
22.1k
                        {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"},
1621
22.1k
                    }
1622
22.1k
                },
1623
22.1k
                RPCExamples{
1624
22.1k
                    HelpExampleCli("finalizepsbt", "\"psbt\"")
1625
22.1k
                },
1626
22.1k
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1627
22.1k
{
1628
    // Unserialize the transactions
1629
0
    PartiallySignedTransaction psbtx;
1630
0
    std::string error;
1631
0
    if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
  Branch (1631:9): [True: 0, False: 0]
1632
0
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
1633
0
    }
1634
1635
0
    bool extract = request.params[1].isNull() || (!request.params[1].isNull() && request.params[1].get_bool());
  Branch (1635:20): [True: 0, False: 0]
  Branch (1635:51): [True: 0, False: 0]
  Branch (1635:82): [True: 0, False: 0]
1636
1637
0
    CMutableTransaction mtx;
1638
0
    bool complete = FinalizeAndExtractPSBT(psbtx, mtx);
1639
1640
0
    UniValue result(UniValue::VOBJ);
1641
0
    DataStream ssTx{};
1642
0
    std::string result_str;
1643
1644
0
    if (complete && extract) {
  Branch (1644:9): [True: 0, False: 0]
  Branch (1644:21): [True: 0, False: 0]
1645
0
        ssTx << TX_WITH_WITNESS(mtx);
1646
0
        result_str = HexStr(ssTx);
1647
0
        result.pushKV("hex", result_str);
1648
0
    } else {
1649
0
        ssTx << psbtx;
1650
0
        result_str = EncodeBase64(ssTx.str());
1651
0
        result.pushKV("psbt", result_str);
1652
0
    }
1653
0
    result.pushKV("complete", complete);
1654
1655
0
    return result;
1656
0
},
1657
22.1k
    };
1658
22.1k
}
1659
1660
static RPCHelpMan createpsbt()
1661
22.1k
{
1662
22.1k
    return RPCHelpMan{
1663
22.1k
        "createpsbt",
1664
22.1k
        "Creates a transaction in the Partially Signed Transaction format.\n"
1665
22.1k
                "Implements the Creator role.\n"
1666
22.1k
                "Note that the transaction's inputs are not signed, and\n"
1667
22.1k
                "it is not stored in the wallet or transmitted to the network.\n",
1668
22.1k
                CreateTxDoc(),
1669
22.1k
                RPCResult{
1670
22.1k
                    RPCResult::Type::STR, "", "The resulting raw transaction (base64-encoded string)"
1671
22.1k
                },
1672
22.1k
                RPCExamples{
1673
22.1k
                    HelpExampleCli("createpsbt", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"address\\\":0.01}]\"")
1674
22.1k
                },
1675
22.1k
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1676
22.1k
{
1677
1678
0
    std::optional<bool> rbf;
1679
0
    if (!request.params[3].isNull()) {
  Branch (1679:9): [True: 0, False: 0]
1680
0
        rbf = request.params[3].get_bool();
1681
0
    }
1682
0
    CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf);
1683
1684
    // Make a blank psbt
1685
0
    PartiallySignedTransaction psbtx;
1686
0
    psbtx.tx = rawTx;
1687
0
    for (unsigned int i = 0; i < rawTx.vin.size(); ++i) {
  Branch (1687:30): [True: 0, False: 0]
1688
0
        psbtx.inputs.emplace_back();
1689
0
    }
1690
0
    for (unsigned int i = 0; i < rawTx.vout.size(); ++i) {
  Branch (1690:30): [True: 0, False: 0]
1691
0
        psbtx.outputs.emplace_back();
1692
0
    }
1693
1694
    // Serialize the PSBT
1695
0
    DataStream ssTx{};
1696
0
    ssTx << psbtx;
1697
1698
0
    return EncodeBase64(ssTx);
1699
0
},
1700
22.1k
    };
1701
22.1k
}
1702
1703
static RPCHelpMan converttopsbt()
1704
22.1k
{
1705
22.1k
    return RPCHelpMan{
1706
22.1k
        "converttopsbt",
1707
22.1k
        "Converts a network serialized transaction to a PSBT. This should be used only with createrawtransaction and fundrawtransaction\n"
1708
22.1k
                "createpsbt and walletcreatefundedpsbt should be used for new applications.\n",
1709
22.1k
                {
1710
22.1k
                    {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of a raw transaction"},
1711
22.1k
                    {"permitsigdata", RPCArg::Type::BOOL, RPCArg::Default{false}, "If true, any signatures in the input will be discarded and conversion\n"
1712
22.1k
                            "                              will continue. If false, RPC will fail if any signatures are present."},
1713
22.1k
                    {"iswitness", RPCArg::Type::BOOL, RPCArg::DefaultHint{"depends on heuristic tests"}, "Whether the transaction hex is a serialized witness transaction.\n"
1714
22.1k
                        "If iswitness is not present, heuristic tests will be used in decoding.\n"
1715
22.1k
                        "If true, only witness deserialization will be tried.\n"
1716
22.1k
                        "If false, only non-witness deserialization will be tried.\n"
1717
22.1k
                        "This boolean should reflect whether the transaction has inputs\n"
1718
22.1k
                        "(e.g. fully valid, or on-chain transactions), if known by the caller."
1719
22.1k
                    },
1720
22.1k
                },
1721
22.1k
                RPCResult{
1722
22.1k
                    RPCResult::Type::STR, "", "The resulting raw transaction (base64-encoded string)"
1723
22.1k
                },
1724
22.1k
                RPCExamples{
1725
22.1k
                            "\nCreate a transaction\n"
1726
22.1k
                            + HelpExampleCli("createrawtransaction", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"") +
1727
22.1k
                            "\nConvert the transaction to a PSBT\n"
1728
22.1k
                            + HelpExampleCli("converttopsbt", "\"rawtransaction\"")
1729
22.1k
                },
1730
22.1k
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1731
22.1k
{
1732
    // parse hex string from parameter
1733
0
    CMutableTransaction tx;
1734
0
    bool permitsigdata = request.params[1].isNull() ? false : request.params[1].get_bool();
  Branch (1734:26): [True: 0, False: 0]
1735
0
    bool witness_specified = !request.params[2].isNull();
1736
0
    bool iswitness = witness_specified ? request.params[2].get_bool() : false;
  Branch (1736:22): [True: 0, False: 0]
1737
0
    const bool try_witness = witness_specified ? iswitness : true;
  Branch (1737:30): [True: 0, False: 0]
1738
0
    const bool try_no_witness = witness_specified ? !iswitness : true;
  Branch (1738:33): [True: 0, False: 0]
1739
0
    if (!DecodeHexTx(tx, request.params[0].get_str(), try_no_witness, try_witness)) {
  Branch (1739:9): [True: 0, False: 0]
1740
0
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
1741
0
    }
1742
1743
    // Remove all scriptSigs and scriptWitnesses from inputs
1744
0
    for (CTxIn& input : tx.vin) {
  Branch (1744:23): [True: 0, False: 0]
1745
0
        if ((!input.scriptSig.empty() || !input.scriptWitness.IsNull()) && !permitsigdata) {
  Branch (1745:14): [True: 0, False: 0]
  Branch (1745:42): [True: 0, False: 0]
  Branch (1745:76): [True: 0, False: 0]
1746
0
            throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Inputs must not have scriptSigs and scriptWitnesses");
1747
0
        }
1748
0
        input.scriptSig.clear();
1749
0
        input.scriptWitness.SetNull();
1750
0
    }
1751
1752
    // Make a blank psbt
1753
0
    PartiallySignedTransaction psbtx;
1754
0
    psbtx.tx = tx;
1755
0
    for (unsigned int i = 0; i < tx.vin.size(); ++i) {
  Branch (1755:30): [True: 0, False: 0]
1756
0
        psbtx.inputs.emplace_back();
1757
0
    }
1758
0
    for (unsigned int i = 0; i < tx.vout.size(); ++i) {
  Branch (1758:30): [True: 0, False: 0]
1759
0
        psbtx.outputs.emplace_back();
1760
0
    }
1761
1762
    // Serialize the PSBT
1763
0
    DataStream ssTx{};
1764
0
    ssTx << psbtx;
1765
1766
0
    return EncodeBase64(ssTx);
1767
0
},
1768
22.1k
    };
1769
22.1k
}
1770
1771
static RPCHelpMan utxoupdatepsbt()
1772
22.1k
{
1773
22.1k
    return RPCHelpMan{
1774
22.1k
        "utxoupdatepsbt",
1775
22.1k
        "Updates all segwit inputs and outputs in a PSBT with data from output descriptors, the UTXO set, txindex, or the mempool.\n",
1776
22.1k
            {
1777
22.1k
                {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"},
1778
22.1k
                {"descriptors", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "An array of either strings or objects", {
1779
22.1k
                    {"", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "An output descriptor"},
1780
22.1k
                    {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "An object with an output descriptor and extra information", {
1781
22.1k
                         {"desc", RPCArg::Type::STR, RPCArg::Optional::NO, "An output descriptor"},
1782
22.1k
                         {"range", RPCArg::Type::RANGE, RPCArg::Default{1000}, "Up to what index HD chains should be explored (either end or [begin,end])"},
1783
22.1k
                    }},
1784
22.1k
                }},
1785
22.1k
            },
1786
22.1k
            RPCResult {
1787
22.1k
                    RPCResult::Type::STR, "", "The base64-encoded partially signed transaction with inputs updated"
1788
22.1k
            },
1789
22.1k
            RPCExamples {
1790
22.1k
                HelpExampleCli("utxoupdatepsbt", "\"psbt\"")
1791
22.1k
            },
1792
22.1k
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1793
22.1k
{
1794
    // Parse descriptors, if any.
1795
0
    FlatSigningProvider provider;
1796
0
    if (!request.params[1].isNull()) {
  Branch (1796:9): [True: 0, False: 0]
1797
0
        auto descs = request.params[1].get_array();
1798
0
        for (size_t i = 0; i < descs.size(); ++i) {
  Branch (1798:28): [True: 0, False: 0]
1799
0
            EvalDescriptorStringOrObject(descs[i], provider);
1800
0
        }
1801
0
    }
1802
1803
    // We don't actually need private keys further on; hide them as a precaution.
1804
0
    const PartiallySignedTransaction& psbtx = ProcessPSBT(
1805
0
        request.params[0].get_str(),
1806
0
        request.context,
1807
0
        HidingSigningProvider(&provider, /*hide_secret=*/true, /*hide_origin=*/false),
1808
0
        /*sighash_type=*/std::nullopt,
1809
0
        /*finalize=*/false);
1810
1811
0
    DataStream ssTx{};
1812
0
    ssTx << psbtx;
1813
0
    return EncodeBase64(ssTx);
1814
0
},
1815
22.1k
    };
1816
22.1k
}
1817
1818
static RPCHelpMan joinpsbts()
1819
22.1k
{
1820
22.1k
    return RPCHelpMan{
1821
22.1k
        "joinpsbts",
1822
22.1k
        "Joins multiple distinct PSBTs with different inputs and outputs into one PSBT with inputs and outputs from all of the PSBTs\n"
1823
22.1k
            "No input in any of the PSBTs can be in more than one of the PSBTs.\n",
1824
22.1k
            {
1825
22.1k
                {"txs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The base64 strings of partially signed transactions",
1826
22.1k
                    {
1827
22.1k
                        {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"}
1828
22.1k
                    }}
1829
22.1k
            },
1830
22.1k
            RPCResult {
1831
22.1k
                    RPCResult::Type::STR, "", "The base64-encoded partially signed transaction"
1832
22.1k
            },
1833
22.1k
            RPCExamples {
1834
22.1k
                HelpExampleCli("joinpsbts", "\"psbt\"")
1835
22.1k
            },
1836
22.1k
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1837
22.1k
{
1838
    // Unserialize the transactions
1839
0
    std::vector<PartiallySignedTransaction> psbtxs;
1840
0
    UniValue txs = request.params[0].get_array();
1841
1842
0
    if (txs.size() <= 1) {
  Branch (1842:9): [True: 0, False: 0]
1843
0
        throw JSONRPCError(RPC_INVALID_PARAMETER, "At least two PSBTs are required to join PSBTs.");
1844
0
    }
1845
1846
0
    uint32_t best_version = 1;
1847
0
    uint32_t best_locktime = 0xffffffff;
1848
0
    for (unsigned int i = 0; i < txs.size(); ++i) {
  Branch (1848:30): [True: 0, False: 0]
1849
0
        PartiallySignedTransaction psbtx;
1850
0
        std::string error;
1851
0
        if (!DecodeBase64PSBT(psbtx, txs[i].get_str(), error)) {
  Branch (1851:13): [True: 0, False: 0]
1852
0
            throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
1853
0
        }
1854
0
        psbtxs.push_back(psbtx);
1855
        // Choose the highest version number
1856
0
        if (psbtx.tx->version > best_version) {
  Branch (1856:13): [True: 0, False: 0]
1857
0
            best_version = psbtx.tx->version;
1858
0
        }
1859
        // Choose the lowest lock time
1860
0
        if (psbtx.tx->nLockTime < best_locktime) {
  Branch (1860:13): [True: 0, False: 0]
1861
0
            best_locktime = psbtx.tx->nLockTime;
1862
0
        }
1863
0
    }
1864
1865
    // Create a blank psbt where everything will be added
1866
0
    PartiallySignedTransaction merged_psbt;
1867
0
    merged_psbt.tx = CMutableTransaction();
1868
0
    merged_psbt.tx->version = best_version;
1869
0
    merged_psbt.tx->nLockTime = best_locktime;
1870
1871
    // Merge
1872
0
    for (auto& psbt : psbtxs) {
  Branch (1872:21): [True: 0, False: 0]
1873
0
        for (unsigned int i = 0; i < psbt.tx->vin.size(); ++i) {
  Branch (1873:34): [True: 0, False: 0]
1874
0
            if (!merged_psbt.AddInput(psbt.tx->vin[i], psbt.inputs[i])) {
  Branch (1874:17): [True: 0, False: 0]
1875
0
                throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Input %s:%d exists in multiple PSBTs", psbt.tx->vin[i].prevout.hash.ToString(), psbt.tx->vin[i].prevout.n));
1876
0
            }
1877
0
        }
1878
0
        for (unsigned int i = 0; i < psbt.tx->vout.size(); ++i) {
  Branch (1878:34): [True: 0, False: 0]
1879
0
            merged_psbt.AddOutput(psbt.tx->vout[i], psbt.outputs[i]);
1880
0
        }
1881
0
        for (auto& xpub_pair : psbt.m_xpubs) {
  Branch (1881:30): [True: 0, False: 0]
1882
0
            if (merged_psbt.m_xpubs.count(xpub_pair.first) == 0) {
  Branch (1882:17): [True: 0, False: 0]
1883
0
                merged_psbt.m_xpubs[xpub_pair.first] = xpub_pair.second;
1884
0
            } else {
1885
0
                merged_psbt.m_xpubs[xpub_pair.first].insert(xpub_pair.second.begin(), xpub_pair.second.end());
1886
0
            }
1887
0
        }
1888
0
        merged_psbt.unknown.insert(psbt.unknown.begin(), psbt.unknown.end());
1889
0
    }
1890
1891
    // Generate list of shuffled indices for shuffling inputs and outputs of the merged PSBT
1892
0
    std::vector<int> input_indices(merged_psbt.inputs.size());
1893
0
    std::iota(input_indices.begin(), input_indices.end(), 0);
1894
0
    std::vector<int> output_indices(merged_psbt.outputs.size());
1895
0
    std::iota(output_indices.begin(), output_indices.end(), 0);
1896
1897
    // Shuffle input and output indices lists
1898
0
    std::shuffle(input_indices.begin(), input_indices.end(), FastRandomContext());
1899
0
    std::shuffle(output_indices.begin(), output_indices.end(), FastRandomContext());
1900
1901
0
    PartiallySignedTransaction shuffled_psbt;
1902
0
    shuffled_psbt.tx = CMutableTransaction();
1903
0
    shuffled_psbt.tx->version = merged_psbt.tx->version;
1904
0
    shuffled_psbt.tx->nLockTime = merged_psbt.tx->nLockTime;
1905
0
    for (int i : input_indices) {
  Branch (1905:16): [True: 0, False: 0]
1906
0
        shuffled_psbt.AddInput(merged_psbt.tx->vin[i], merged_psbt.inputs[i]);
1907
0
    }
1908
0
    for (int i : output_indices) {
  Branch (1908:16): [True: 0, False: 0]
1909
0
        shuffled_psbt.AddOutput(merged_psbt.tx->vout[i], merged_psbt.outputs[i]);
1910
0
    }
1911
0
    shuffled_psbt.unknown.insert(merged_psbt.unknown.begin(), merged_psbt.unknown.end());
1912
1913
0
    DataStream ssTx{};
1914
0
    ssTx << shuffled_psbt;
1915
0
    return EncodeBase64(ssTx);
1916
0
},
1917
22.1k
    };
1918
22.1k
}
1919
1920
static RPCHelpMan analyzepsbt()
1921
22.1k
{
1922
22.1k
    return RPCHelpMan{
1923
22.1k
        "analyzepsbt",
1924
22.1k
        "Analyzes and provides information about the current status of a PSBT and its inputs\n",
1925
22.1k
            {
1926
22.1k
                {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "A base64 string of a PSBT"}
1927
22.1k
            },
1928
22.1k
            RPCResult {
1929
22.1k
                RPCResult::Type::OBJ, "", "",
1930
22.1k
                {
1931
22.1k
                    {RPCResult::Type::ARR, "inputs", /*optional=*/true, "",
1932
22.1k
                    {
1933
22.1k
                        {RPCResult::Type::OBJ, "", "",
1934
22.1k
                        {
1935
22.1k
                            {RPCResult::Type::BOOL, "has_utxo", "Whether a UTXO is provided"},
1936
22.1k
                            {RPCResult::Type::BOOL, "is_final", "Whether the input is finalized"},
1937
22.1k
                            {RPCResult::Type::OBJ, "missing", /*optional=*/true, "Things that are missing that are required to complete this input",
1938
22.1k
                            {
1939
22.1k
                                {RPCResult::Type::ARR, "pubkeys", /*optional=*/true, "",
1940
22.1k
                                {
1941
22.1k
                                    {RPCResult::Type::STR_HEX, "keyid", "Public key ID, hash160 of the public key, of a public key whose BIP 32 derivation path is missing"},
1942
22.1k
                                }},
1943
22.1k
                                {RPCResult::Type::ARR, "signatures", /*optional=*/true, "",
1944
22.1k
                                {
1945
22.1k
                                    {RPCResult::Type::STR_HEX, "keyid", "Public key ID, hash160 of the public key, of a public key whose signature is missing"},
1946
22.1k
                                }},
1947
22.1k
                                {RPCResult::Type::STR_HEX, "redeemscript", /*optional=*/true, "Hash160 of the redeem script that is missing"},
1948
22.1k
                                {RPCResult::Type::STR_HEX, "witnessscript", /*optional=*/true, "SHA256 of the witness script that is missing"},
1949
22.1k
                            }},
1950
22.1k
                            {RPCResult::Type::STR, "next", /*optional=*/true, "Role of the next person that this input needs to go to"},
1951
22.1k
                        }},
1952
22.1k
                    }},
1953
22.1k
                    {RPCResult::Type::NUM, "estimated_vsize", /*optional=*/true, "Estimated vsize of the final signed transaction"},
1954
22.1k
                    {RPCResult::Type::STR_AMOUNT, "estimated_feerate", /*optional=*/true, "Estimated feerate of the final signed transaction in " + CURRENCY_UNIT + "/kvB. Shown only if all UTXO slots in the PSBT have been filled"},
1955
22.1k
                    {RPCResult::Type::STR_AMOUNT, "fee", /*optional=*/true, "The transaction fee paid. Shown only if all UTXO slots in the PSBT have been filled"},
1956
22.1k
                    {RPCResult::Type::STR, "next", "Role of the next person that this psbt needs to go to"},
1957
22.1k
                    {RPCResult::Type::STR, "error", /*optional=*/true, "Error message (if there is one)"},
1958
22.1k
                }
1959
22.1k
            },
1960
22.1k
            RPCExamples {
1961
22.1k
                HelpExampleCli("analyzepsbt", "\"psbt\"")
1962
22.1k
            },
1963
22.1k
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1964
22.1k
{
1965
    // Unserialize the transaction
1966
0
    PartiallySignedTransaction psbtx;
1967
0
    std::string error;
1968
0
    if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
  Branch (1968:9): [True: 0, False: 0]
1969
0
        throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
1970
0
    }
1971
1972
0
    PSBTAnalysis psbta = AnalyzePSBT(psbtx);
1973
1974
0
    UniValue result(UniValue::VOBJ);
1975
0
    UniValue inputs_result(UniValue::VARR);
1976
0
    for (const auto& input : psbta.inputs) {
  Branch (1976:28): [True: 0, False: 0]
1977
0
        UniValue input_univ(UniValue::VOBJ);
1978
0
        UniValue missing(UniValue::VOBJ);
1979
1980
0
        input_univ.pushKV("has_utxo", input.has_utxo);
1981
0
        input_univ.pushKV("is_final", input.is_final);
1982
0
        input_univ.pushKV("next", PSBTRoleName(input.next));
1983
1984
0
        if (!input.missing_pubkeys.empty()) {
  Branch (1984:13): [True: 0, False: 0]
1985
0
            UniValue missing_pubkeys_univ(UniValue::VARR);
1986
0
            for (const CKeyID& pubkey : input.missing_pubkeys) {
  Branch (1986:39): [True: 0, False: 0]
1987
0
                missing_pubkeys_univ.push_back(HexStr(pubkey));
1988
0
            }
1989
0
            missing.pushKV("pubkeys", std::move(missing_pubkeys_univ));
1990
0
        }
1991
0
        if (!input.missing_redeem_script.IsNull()) {
  Branch (1991:13): [True: 0, False: 0]
1992
0
            missing.pushKV("redeemscript", HexStr(input.missing_redeem_script));
1993
0
        }
1994
0
        if (!input.missing_witness_script.IsNull()) {
  Branch (1994:13): [True: 0, False: 0]
1995
0
            missing.pushKV("witnessscript", HexStr(input.missing_witness_script));
1996
0
        }
1997
0
        if (!input.missing_sigs.empty()) {
  Branch (1997:13): [True: 0, False: 0]
1998
0
            UniValue missing_sigs_univ(UniValue::VARR);
1999
0
            for (const CKeyID& pubkey : input.missing_sigs) {
  Branch (1999:39): [True: 0, False: 0]
2000
0
                missing_sigs_univ.push_back(HexStr(pubkey));
2001
0
            }
2002
0
            missing.pushKV("signatures", std::move(missing_sigs_univ));
2003
0
        }
2004
0
        if (!missing.getKeys().empty()) {
  Branch (2004:13): [True: 0, False: 0]
2005
0
            input_univ.pushKV("missing", std::move(missing));
2006
0
        }
2007
0
        inputs_result.push_back(std::move(input_univ));
2008
0
    }
2009
0
    if (!inputs_result.empty()) result.pushKV("inputs", std::move(inputs_result));
  Branch (2009:9): [True: 0, False: 0]
2010
2011
0
    if (psbta.estimated_vsize != std::nullopt) {
  Branch (2011:9): [True: 0, False: 0]
2012
0
        result.pushKV("estimated_vsize", (int)*psbta.estimated_vsize);
2013
0
    }
2014
0
    if (psbta.estimated_feerate != std::nullopt) {
  Branch (2014:9): [True: 0, False: 0]
2015
0
        result.pushKV("estimated_feerate", ValueFromAmount(psbta.estimated_feerate->GetFeePerK()));
2016
0
    }
2017
0
    if (psbta.fee != std::nullopt) {
  Branch (2017:9): [True: 0, False: 0]
2018
0
        result.pushKV("fee", ValueFromAmount(*psbta.fee));
2019
0
    }
2020
0
    result.pushKV("next", PSBTRoleName(psbta.next));
2021
0
    if (!psbta.error.empty()) {
  Branch (2021:9): [True: 0, False: 0]
2022
0
        result.pushKV("error", psbta.error);
2023
0
    }
2024
2025
0
    return result;
2026
0
},
2027
22.1k
    };
2028
22.1k
}
2029
2030
RPCHelpMan descriptorprocesspsbt()
2031
22.1k
{
2032
22.1k
    return RPCHelpMan{
2033
22.1k
        "descriptorprocesspsbt",
2034
22.1k
        "Update all segwit inputs in a PSBT with information from output descriptors, the UTXO set or the mempool. \n"
2035
22.1k
                "Then, sign the inputs we are able to with information from the output descriptors. ",
2036
22.1k
                {
2037
22.1k
                    {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction base64 string"},
2038
22.1k
                    {"descriptors", RPCArg::Type::ARR, RPCArg::Optional::NO, "An array of either strings or objects", {
2039
22.1k
                        {"", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "An output descriptor"},
2040
22.1k
                        {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "An object with an output descriptor and extra information", {
2041
22.1k
                             {"desc", RPCArg::Type::STR, RPCArg::Optional::NO, "An output descriptor"},
2042
22.1k
                             {"range", RPCArg::Type::RANGE, RPCArg::Default{1000}, "Up to what index HD chains should be explored (either end or [begin,end])"},
2043
22.1k
                        }},
2044
22.1k
                    }},
2045
22.1k
                    {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"DEFAULT for Taproot, ALL otherwise"}, "The signature hash type to sign with if not specified by the PSBT. Must be one of\n"
2046
22.1k
            "       \"DEFAULT\"\n"
2047
22.1k
            "       \"ALL\"\n"
2048
22.1k
            "       \"NONE\"\n"
2049
22.1k
            "       \"SINGLE\"\n"
2050
22.1k
            "       \"ALL|ANYONECANPAY\"\n"
2051
22.1k
            "       \"NONE|ANYONECANPAY\"\n"
2052
22.1k
            "       \"SINGLE|ANYONECANPAY\""},
2053
22.1k
                    {"bip32derivs", RPCArg::Type::BOOL, RPCArg::Default{true}, "Include BIP 32 derivation paths for public keys if we know them"},
2054
22.1k
                    {"finalize", RPCArg::Type::BOOL, RPCArg::Default{true}, "Also finalize inputs if possible"},
2055
22.1k
                },
2056
22.1k
                RPCResult{
2057
22.1k
                    RPCResult::Type::OBJ, "", "",
2058
22.1k
                    {
2059
22.1k
                        {RPCResult::Type::STR, "psbt", "The base64-encoded partially signed transaction"},
2060
22.1k
                        {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"},
2061
22.1k
                        {RPCResult::Type::STR_HEX, "hex", /*optional=*/true, "The hex-encoded network transaction if complete"},
2062
22.1k
                    }
2063
22.1k
                },
2064
22.1k
                RPCExamples{
2065
22.1k
                    HelpExampleCli("descriptorprocesspsbt", "\"psbt\" \"[\\\"descriptor1\\\", \\\"descriptor2\\\"]\"") +
2066
22.1k
                    HelpExampleCli("descriptorprocesspsbt", "\"psbt\" \"[{\\\"desc\\\":\\\"mydescriptor\\\", \\\"range\\\":21}]\"")
2067
22.1k
                },
2068
22.1k
        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
2069
22.1k
{
2070
    // Add descriptor information to a signing provider
2071
0
    FlatSigningProvider provider;
2072
2073
0
    auto descs = request.params[1].get_array();
2074
0
    for (size_t i = 0; i < descs.size(); ++i) {
  Branch (2074:24): [True: 0, False: 0]
2075
0
        EvalDescriptorStringOrObject(descs[i], provider, /*expand_priv=*/true);
2076
0
    }
2077
2078
0
    std::optional<int> sighash_type = ParseSighashString(request.params[2]);
2079
0
    bool bip32derivs = request.params[3].isNull() ? true : request.params[3].get_bool();
  Branch (2079:24): [True: 0, False: 0]
2080
0
    bool finalize = request.params[4].isNull() ? true : request.params[4].get_bool();
  Branch (2080:21): [True: 0, False: 0]
2081
2082
0
    const PartiallySignedTransaction& psbtx = ProcessPSBT(
2083
0
        request.params[0].get_str(),
2084
0
        request.context,
2085
0
        HidingSigningProvider(&provider, /*hide_secret=*/false, !bip32derivs),
2086
0
        sighash_type,
2087
0
        finalize);
2088
2089
    // Check whether or not all of the inputs are now signed
2090
0
    bool complete = true;
2091
0
    for (const auto& input : psbtx.inputs) {
  Branch (2091:28): [True: 0, False: 0]
2092
0
        complete &= PSBTInputSigned(input);
2093
0
    }
2094
2095
0
    DataStream ssTx{};
2096
0
    ssTx << psbtx;
2097
2098
0
    UniValue result(UniValue::VOBJ);
2099
2100
0
    result.pushKV("psbt", EncodeBase64(ssTx));
2101
0
    result.pushKV("complete", complete);
2102
0
    if (complete) {
  Branch (2102:9): [True: 0, False: 0]
2103
0
        CMutableTransaction mtx;
2104
0
        PartiallySignedTransaction psbtx_copy = psbtx;
2105
0
        CHECK_NONFATAL(FinalizeAndExtractPSBT(psbtx_copy, mtx));
2106
0
        DataStream ssTx_final;
2107
0
        ssTx_final << TX_WITH_WITNESS(mtx);
2108
0
        result.pushKV("hex", HexStr(ssTx_final));
2109
0
    }
2110
0
    return result;
2111
0
},
2112
22.1k
    };
2113
22.1k
}
2114
2115
void RegisterRawTransactionRPCCommands(CRPCTable& t)
2116
11.0k
{
2117
11.0k
    static const CRPCCommand commands[]{
2118
11.0k
        {"rawtransactions", &getrawtransaction},
2119
11.0k
        {"rawtransactions", &createrawtransaction},
2120
11.0k
        {"rawtransactions", &decoderawtransaction},
2121
11.0k
        {"rawtransactions", &decodescript},
2122
11.0k
        {"rawtransactions", &combinerawtransaction},
2123
11.0k
        {"rawtransactions", &signrawtransactionwithkey},
2124
11.0k
        {"rawtransactions", &decodepsbt},
2125
11.0k
        {"rawtransactions", &combinepsbt},
2126
11.0k
        {"rawtransactions", &finalizepsbt},
2127
11.0k
        {"rawtransactions", &createpsbt},
2128
11.0k
        {"rawtransactions", &converttopsbt},
2129
11.0k
        {"rawtransactions", &utxoupdatepsbt},
2130
11.0k
        {"rawtransactions", &descriptorprocesspsbt},
2131
11.0k
        {"rawtransactions", &joinpsbts},
2132
11.0k
        {"rawtransactions", &analyzepsbt},
2133
11.0k
    };
2134
166k
    for (const auto& c : commands) {
  Branch (2134:24): [True: 166k, False: 11.0k]
2135
166k
        t.appendCommand(c.name, &c);
2136
166k
    }
2137
11.0k
}