Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
2001{RPCResult::Type::STR_HEX, "witnessscript", /*optional=*/true, "SHA256 of the witness script that is missing"},2002}},2003{RPCResult::Type::STR, "next", /*optional=*/true, "Role of the next person that this input needs to go to"},2004}},2005}},2006{RPCResult::Type::NUM, "estimated_vsize", /*optional=*/true, "Estimated vsize of the final signed transaction"},2007{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"},2008{RPCResult::Type::STR_AMOUNT, "fee", /*optional=*/true, "The transaction fee paid. Shown only if all UTXO slots in the PSBT have been filled"},2009{RPCResult::Type::STR, "next", "Role of the next person that this psbt needs to go to"},2010{RPCResult::Type::STR, "error", /*optional=*/true, "Error message (if there is one)"},2011}2012},2013RPCExamples {2014HelpExampleCli("analyzepsbt", "\"psbt\"")2015},2016[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue2017{2018// Unserialize the transaction2019util::Result<PartiallySignedTransaction> psbt_res = DecodeBase64PSBT(request.params[0].get_str());2020if (!psbt_res) {2021throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", util::ErrorString(psbt_res).original));2022}2023const PartiallySignedTransaction& psbtx = *psbt_res;2025PSBTAnalysis psbta = AnalyzePSBT(psbtx);2027UniValue result(UniValue::VOBJ);2028UniValue inputs_result(UniValue::VARR);2029for (const auto& input : psbta.inputs) {2030UniValue input_univ(UniValue::VOBJ);2031UniValue missing(UniValue::VOBJ);2033input_univ.pushKV("has_utxo", input.has_utxo);2034input_univ.pushKV("is_final", input.is_final);2035input_univ.pushKV("next", PSBTRoleName(input.next));2037if (!input.missing_pubkeys.empty()) {2038UniValue missing_pubkeys_univ(UniValue::VARR);2039for (const CKeyID& pubkey : input.missing_pubkeys) {2040missing_pubkeys_univ.push_back(HexStr(pubkey));2041}2042missing.pushKV("pubkeys", std::move(missing_pubkeys_univ));2043}2044if (!input.missing_redeem_script.IsNull()) {2045missing.pushKV("redeemscript", HexStr(input.missing_redeem_script));2046}2047if (!input.missing_witness_script.IsNull()) {2048missing.pushKV("witnessscript", HexStr(input.missing_witness_script));2049}2050if (!input.missing_sigs.empty()) {2051UniValue missing_sigs_univ(UniValue::VARR);2052for (const CKeyID& pubkey : input.missing_sigs) {2053missing_sigs_univ.push_back(HexStr(pubkey));2054}2055missing.pushKV("signatures", std::move(missing_sigs_univ));2056}2057if (!missing.getKeys().empty()) {2058input_univ.pushKV("missing", std::move(missing));2059}2060inputs_result.push_back(std::move(input_univ));2061}2062if (!inputs_result.empty()) result.pushKV("inputs", std::move(inputs_result));2064if (psbta.estimated_vsize != std::nullopt) {2065result.pushKV("estimated_vsize", *psbta.estimated_vsize);2066}2067if (psbta.estimated_feerate != std::nullopt) {2068result.pushKV("estimated_feerate", ValueFromAmount(psbta.estimated_feerate->GetFeePerK()));2069}2070if (psbta.fee != std::nullopt) {2071result.pushKV("fee", ValueFromAmount(*psbta.fee));2072}2073result.pushKV("next", PSBTRoleName(psbta.next));2074if (!psbta.error.empty()) {2075result.pushKV("error", psbta.error);2076}2078return result;2079},2080};2081}2083RPCMethod descriptorprocesspsbt()2084{2085return RPCMethod{2086"descriptorprocesspsbt",2087"Update all segwit inputs in a PSBT with information from output descriptors, the UTXO set or the mempool. \n"2088"Then, sign the inputs we are able to with information from the output descriptors. ",2089{2090{"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction base64 string"},2091{"descriptors", RPCArg::Type::ARR, RPCArg::Optional::NO, "An array of either strings or objects", {2092{"", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "An output descriptor"},2093{"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "An object with an output descriptor and extra information", {2094{"desc", RPCArg::Type::STR, RPCArg::Optional::NO, "An output descriptor"},2095{"range", RPCArg::Type::RANGE, RPCArg::Default{1000}, "Up to what index HD chains should be explored (either end or [begin,end])"},2096}},2097}},2098{"sighashtype", RPCArg::Type::STR, RPCArg::DefaultHint{"DEFAULT for Taproot, ALL otherwise"}, "The signature hash type to sign with if not specified by the PSBT. Must be one of\n"2099" \"DEFAULT\"\n"2100" \"ALL\"\n"2101" \"NONE\"\n"2102" \"SINGLE\"\n"2103" \"ALL|ANYONECANPAY\"\n"2104" \"NONE|ANYONECANPAY\"\n"2105" \"SINGLE|ANYONECANPAY\""},2106{"bip32derivs", RPCArg::Type::BOOL, RPCArg::Default{true}, "Include BIP 32 derivation paths for public keys if we know them"},2107{"finalize", RPCArg::Type::BOOL, RPCArg::Default{true}, "Also finalize inputs if possible"},2108},2109RPCResult{2110RPCResult::Type::OBJ, "", "",2111{2112{RPCResult::Type::STR, "psbt", "The base64-encoded partially signed transaction"},2113{RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"},2114{RPCResult::Type::STR_HEX, "hex", /*optional=*/true, "The hex-encoded network transaction if complete"},2115}2116},2117RPCExamples{2118HelpExampleCli("descriptorprocesspsbt", "\"psbt\" \"[\\\"descriptor1\\\", \\\"descriptor2\\\"]\"") +2119HelpExampleCli("descriptorprocesspsbt", "\"psbt\" \"[{\\\"desc\\\":\\\"mydescriptor\\\", \\\"range\\\":21}]\"")2120},2121[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue2122{2123// Add descriptor information to a signing provider2124FlatSigningProvider provider;2126auto descs = request.params[1].get_array();2127for (size_t i = 0; i < descs.size(); ++i) {2128EvalDescriptorStringOrObject(descs[i], provider, /*expand_priv=*/true);2129}2131std::optional<int> sighash_type = ParseSighashString(request.params[2]);2132bool bip32derivs = request.params[3].isNull() ? true : request.params[3].get_bool();2133bool finalize = request.params[4].isNull() ? true : request.params[4].get_bool();2135const PartiallySignedTransaction& psbtx = ProcessPSBT(2136request.params[0].get_str(),2137request.context,2138HidingSigningProvider(&provider, /*hide_secret=*/false, !bip32derivs),2139sighash_type,2140finalize);2142// Check whether or not all of the inputs are now correctly signed2143bool complete = true;2144const std::optional<PrecomputedTransactionData> txdata_opt{PrecomputePSBTData(psbtx)};2145const PrecomputedTransactionData txdata{*CHECK_NONFATAL(txdata_opt)};2146for (unsigned int i = 0; i < psbtx.inputs.size(); ++i) {2147complete = complete && PSBTInputSignedAndVerified(psbtx, i, &txdata);2148}2150DataStream ssTx{};2151ssTx << psbtx;2153UniValue result(UniValue::VOBJ);2155result.pushKV("psbt", EncodeBase64(ssTx));2156result.pushKV("complete", complete);2157if (complete) {2158CMutableTransaction mtx;2159PartiallySignedTransaction psbtx_copy = psbtx;2160CHECK_NONFATAL(FinalizeAndExtractPSBT(psbtx_copy, mtx));2161DataStream ssTx_final;2162ssTx_final << TX_WITH_WITNESS(mtx);2163result.pushKV("hex", HexStr(ssTx_final));2164}2165return result;2166},2167};2168}2170void RegisterRawTransactionRPCCommands(CRPCTable& t)2171{2172static const CRPCCommand commands[]{2173{"rawtransactions", &getrawtransaction},2174{"rawtransactions", &createrawtransaction},2175{"rawtransactions", &decoderawtransaction},2176{"rawtransactions", &decodescript},2177{"rawtransactions", &combinerawtransaction},2178{"rawtransactions", &signrawtransactionwithkey},2179{"rawtransactions", &decodepsbt},2180{"rawtransactions", &combinepsbt},2181{"rawtransactions", &finalizepsbt},2182{"rawtransactions", &createpsbt},2183{"rawtransactions", &converttopsbt},2184{"rawtransactions", &utxoupdatepsbt},2185{"rawtransactions", &descriptorprocesspsbt},2186{"rawtransactions", &joinpsbts},2187{"rawtransactions", &analyzepsbt},2188};2189for (const auto& c : commands) {2190t.appendCommand(c.name, &c);2191}2192}