spend.cpp
1 // Copyright (c) 2011-present The Bitcoin Core developers 2 // Distributed under the MIT software license, see the accompanying 3 // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 5 #include <common/messages.h> 6 #include <consensus/validation.h> 7 #include <core_io.h> 8 #include <key_io.h> 9 #include <node/types.h> 10 #include <policy/policy.h> 11 #include <policy/truc_policy.h> 12 #include <rpc/rawtransaction_util.h> 13 #include <rpc/util.h> 14 #include <script/script.h> 15 #include <util/rbf.h> 16 #include <util/translation.h> 17 #include <util/vector.h> 18 #include <wallet/coincontrol.h> 19 #include <wallet/feebumper.h> 20 #include <wallet/fees.h> 21 #include <wallet/rpc/util.h> 22 #include <wallet/spend.h> 23 #include <wallet/wallet.h> 24 25 #include <univalue.h> 26 27 using common::FeeModeFromString; 28 using common::FeeModesDetail; 29 using common::InvalidEstimateModeErrorMessage; 30 using common::StringForFeeReason; 31 using common::TransactionErrorString; 32 using node::TransactionError; 33 34 namespace wallet { 35 std::vector<CRecipient> CreateRecipients(const std::vector<std::pair<CTxDestination, CAmount>>& outputs, const std::set<int>& subtract_fee_outputs) 36 { 37 std::vector<CRecipient> recipients; 38 for (size_t i = 0; i < outputs.size(); ++i) { 39 const auto& [destination, amount] = outputs.at(i); 40 CRecipient recipient{destination, amount, subtract_fee_outputs.contains(i)}; 41 recipients.push_back(recipient); 42 } 43 return recipients; 44 } 45 46 static void InterpretFeeEstimationInstructions(const UniValue& conf_target, const UniValue& estimate_mode, const UniValue& fee_rate, UniValue& options) 47 { 48 if (options.exists("conf_target") || options.exists("estimate_mode")) { 49 if (!conf_target.isNull() || !estimate_mode.isNull()) { 50 throw JSONRPCError(RPC_INVALID_PARAMETER, "Pass conf_target and estimate_mode either as arguments or in the options object, but not both"); 51 } 52 } else { 53 options.pushKV("conf_target", conf_target); 54 options.pushKV("estimate_mode", estimate_mode); 55 } 56 if (options.exists("fee_rate")) { 57 if (!fee_rate.isNull()) { 58 throw JSONRPCError(RPC_INVALID_PARAMETER, "Pass the fee_rate either as an argument, or in the options object, but not both"); 59 } 60 } else { 61 options.pushKV("fee_rate", fee_rate); 62 } 63 if (!options["conf_target"].isNull() && (options["estimate_mode"].isNull() || (options["estimate_mode"].get_str() == "unset"))) { 64 throw JSONRPCError(RPC_INVALID_PARAMETER, "Specify estimate_mode"); 65 } 66 } 67 68 std::set<int> InterpretSubtractFeeFromOutputInstructions(const UniValue& sffo_instructions, const std::vector<std::string>& destinations) 69 { 70 std::set<int> sffo_set; 71 if (sffo_instructions.isNull()) return sffo_set; 72 73 for (const auto& sffo : sffo_instructions.getValues()) { 74 int pos{-1}; 75 if (sffo.isStr()) { 76 auto it = find(destinations.begin(), destinations.end(), sffo.get_str()); 77 if (it == destinations.end()) throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter 'subtract fee from output', destination %s not found in tx outputs", sffo.get_str())); 78 pos = it - destinations.begin(); 79 } else if (sffo.isNum()) { 80 pos = sffo.getInt<int>(); 81 } else { 82 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter 'subtract fee from output', invalid value type: %s", uvTypeName(sffo.type()))); 83 } 84 85 if (sffo_set.contains(pos)) 86 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter 'subtract fee from output', duplicated position: %d", pos)); 87 if (pos < 0) 88 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter 'subtract fee from output', negative position: %d", pos)); 89 if (pos >= int(destinations.size())) 90 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter 'subtract fee from output', position too large: %d", pos)); 91 sffo_set.insert(pos); 92 } 93 return sffo_set; 94 } 95 96 static UniValue FinishTransaction(const std::shared_ptr<CWallet> pwallet, const UniValue& options, CMutableTransaction& rawTx) 97 { 98 bool can_anti_fee_snipe = !options.exists("locktime"); 99 100 for (const CTxIn& tx_in : rawTx.vin) { 101 // Checks sequence values consistent with DiscourageFeeSniping 102 can_anti_fee_snipe = can_anti_fee_snipe && (tx_in.nSequence == CTxIn::MAX_SEQUENCE_NONFINAL || tx_in.nSequence == MAX_BIP125_RBF_SEQUENCE); 103 } 104 105 if (can_anti_fee_snipe) { 106 LOCK(pwallet->cs_wallet); 107 FastRandomContext rng_fast; 108 DiscourageFeeSniping(rawTx, rng_fast, pwallet->chain(), pwallet->GetLastBlockHash(), pwallet->GetLastBlockHeight()); 109 } 110 111 // Make a blank psbt 112 PartiallySignedTransaction psbtx(rawTx); 113 114 // First fill transaction with our data without signing, 115 // so external signers are not asked to sign more than once. 116 bool complete; 117 pwallet->FillPSBT(psbtx, complete, std::nullopt, /*sign=*/false, /*bip32derivs=*/true); 118 const auto err{pwallet->FillPSBT(psbtx, complete, std::nullopt, /*sign=*/true, /*bip32derivs=*/false)}; 119 if (err) { 120 throw JSONRPCPSBTError(*err); 121 } 122 123 CMutableTransaction mtx; 124 complete = FinalizeAndExtractPSBT(psbtx, mtx); 125 126 UniValue result(UniValue::VOBJ); 127 128 const bool psbt_opt_in{options.exists("psbt") && options["psbt"].get_bool()}; 129 bool add_to_wallet{options.exists("add_to_wallet") ? options["add_to_wallet"].get_bool() : true}; 130 if (psbt_opt_in || !complete || !add_to_wallet) { 131 // Serialize the PSBT 132 DataStream ssTx{}; 133 ssTx << psbtx; 134 result.pushKV("psbt", EncodeBase64(ssTx.str())); 135 } 136 137 if (complete) { 138 std::string hex{EncodeHexTx(CTransaction(mtx))}; 139 CTransactionRef tx(MakeTransactionRef(std::move(mtx))); 140 result.pushKV("txid", tx->GetHash().GetHex()); 141 if (add_to_wallet && !psbt_opt_in) { 142 pwallet->CommitTransaction(tx, {}, /*orderForm=*/{}); 143 } else { 144 result.pushKV("hex", hex); 145 } 146 } 147 result.pushKV("complete", complete); 148 149 return result; 150 } 151 152 static void PreventOutdatedOptions(const UniValue& options) 153 { 154 if (options.exists("feeRate")) { 155 throw JSONRPCError(RPC_INVALID_PARAMETER, "Use fee_rate (" + CURRENCY_ATOM + "/vB) instead of feeRate"); 156 } 157 if (options.exists("changeAddress")) { 158 throw JSONRPCError(RPC_INVALID_PARAMETER, "Use change_address instead of changeAddress"); 159 } 160 if (options.exists("changePosition")) { 161 throw JSONRPCError(RPC_INVALID_PARAMETER, "Use change_position instead of changePosition"); 162 } 163 if (options.exists("lockUnspents")) { 164 throw JSONRPCError(RPC_INVALID_PARAMETER, "Use lock_unspents instead of lockUnspents"); 165 } 166 if (options.exists("subtractFeeFromOutputs")) { 167 throw JSONRPCError(RPC_INVALID_PARAMETER, "Use subtract_fee_from_outputs instead of subtractFeeFromOutputs"); 168 } 169 } 170 171 UniValue SendMoney(CWallet& wallet, const CCoinControl &coin_control, std::vector<CRecipient> &recipients, mapValue_t map_value, bool verbose) 172 { 173 EnsureWalletIsUnlocked(wallet); 174 175 // This function is only used by sendtoaddress and sendmany. 176 // This should always try to sign, if we don't have private keys, don't try to do anything here. 177 if (wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) { 178 throw JSONRPCError(RPC_WALLET_ERROR, "Error: Private keys are disabled for this wallet"); 179 } 180 181 // Shuffle recipient list 182 std::shuffle(recipients.begin(), recipients.end(), FastRandomContext()); 183 184 // Send 185 auto res = CreateTransaction(wallet, recipients, /*change_pos=*/std::nullopt, coin_control, true); 186 if (!res) { 187 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, util::ErrorString(res).original); 188 } 189 const CTransactionRef& tx = res->tx; 190 wallet.CommitTransaction(tx, std::move(map_value), /*orderForm=*/{}); 191 if (verbose) { 192 UniValue entry(UniValue::VOBJ); 193 entry.pushKV("txid", tx->GetHash().GetHex()); 194 entry.pushKV("fee_reason", StringForFeeReason(res->fee_calc.reason)); 195 return entry; 196 } 197 return tx->GetHash().GetHex(); 198 } 199 200 201 /** 202 * Update coin control with fee estimation based on the given parameters 203 * 204 * @param[in] wallet Wallet reference 205 * @param[in,out] cc Coin control to be updated 206 * @param[in] conf_target UniValue integer; confirmation target in blocks, values between 1 and 1008 are valid per policy/fees/block_policy_estimator.h; 207 * @param[in] estimate_mode UniValue string; fee estimation mode, valid values are "unset", "economical" or "conservative"; 208 * @param[in] fee_rate UniValue real; fee rate in sat/vB; 209 * if present, both conf_target and estimate_mode must either be null, or "unset" 210 * @param[in] override_min_fee bool; whether to set fOverrideFeeRate to true to disable minimum fee rate checks and instead 211 * verify only that fee_rate is greater than 0 212 * @throws a JSONRPCError if conf_target, estimate_mode, or fee_rate contain invalid values or are in conflict 213 */ 214 static void SetFeeEstimateMode(const CWallet& wallet, CCoinControl& cc, const UniValue& conf_target, const UniValue& estimate_mode, const UniValue& fee_rate, bool override_min_fee) 215 { 216 if (!fee_rate.isNull()) { 217 if (!conf_target.isNull()) { 218 throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both conf_target and fee_rate. Please provide either a confirmation target in blocks for automatic fee estimation, or an explicit fee rate."); 219 } 220 if (!estimate_mode.isNull() && estimate_mode.get_str() != "unset") { 221 throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both estimate_mode and fee_rate"); 222 } 223 // Fee rates in sat/vB cannot represent more than 3 significant digits. 224 cc.m_feerate = CFeeRate{AmountFromValue(fee_rate, /*decimals=*/3)}; 225 if (override_min_fee) cc.fOverrideFeeRate = true; 226 // Default RBF to true for explicit fee_rate, if unset. 227 if (!cc.m_signal_bip125_rbf) cc.m_signal_bip125_rbf = true; 228 return; 229 } 230 if (!estimate_mode.isNull() && !FeeModeFromString(estimate_mode.get_str(), cc.m_fee_mode)) { 231 throw JSONRPCError(RPC_INVALID_PARAMETER, InvalidEstimateModeErrorMessage()); 232 } 233 if (!conf_target.isNull()) { 234 cc.m_confirm_target = ParseConfirmTarget(conf_target, wallet.chain().estimateMaxBlocks()); 235 } 236 } 237 238 RPCHelpMan sendtoaddress() 239 { 240 return RPCHelpMan{ 241 "sendtoaddress", 242 "Send an amount to a given address." + 243 HELP_REQUIRING_PASSPHRASE, 244 { 245 {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to send to."}, 246 {"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "The amount in " + CURRENCY_UNIT + " to send. eg 0.1"}, 247 {"comment", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "A comment used to store what the transaction is for.\n" 248 "This is not part of the transaction, just kept in your wallet."}, 249 {"comment_to", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "A comment to store the name of the person or organization\n" 250 "to which you're sending the transaction. This is not part of the \n" 251 "transaction, just kept in your wallet."}, 252 {"subtractfeefromamount", RPCArg::Type::BOOL, RPCArg::Default{false}, "The fee will be deducted from the amount being sent.\n" 253 "The recipient will receive less bitcoins than you enter in the amount field."}, 254 {"replaceable", RPCArg::Type::BOOL, RPCArg::DefaultHint{"wallet default"}, "Signal that this transaction can be replaced by a transaction (BIP 125)"}, 255 {"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks"}, 256 {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n" 257 + FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used"))}, 258 {"avoid_reuse", RPCArg::Type::BOOL, RPCArg::Default{true}, "(only available if avoid_reuse wallet flag is set) Avoid spending from dirty addresses; addresses are considered\n" 259 "dirty if they have previously been used in a transaction. If true, this also activates avoidpartialspends, grouping outputs by their addresses."}, 260 {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."}, 261 {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false}, "If true, return extra information about the transaction."}, 262 }, 263 { 264 RPCResult{"if verbose is not set or set to false", 265 RPCResult::Type::STR_HEX, "txid", "The transaction id." 266 }, 267 RPCResult{"if verbose is set to true", 268 RPCResult::Type::OBJ, "", "", 269 { 270 {RPCResult::Type::STR_HEX, "txid", "The transaction id."}, 271 {RPCResult::Type::STR, "fee_reason", "The transaction fee reason."} 272 }, 273 }, 274 }, 275 RPCExamples{ 276 "\nSend 0.1 BTC\n" 277 + HelpExampleCli("sendtoaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 0.1") + 278 "\nSend 0.1 BTC with a confirmation target of 6 blocks in economical fee estimate mode using positional arguments\n" 279 + HelpExampleCli("sendtoaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 0.1 \"donation\" \"sean's outpost\" false true 6 economical") + 280 "\nSend 0.1 BTC with a fee rate of 1.1 " + CURRENCY_ATOM + "/vB, subtract fee from amount, BIP125-replaceable, using positional arguments\n" 281 + HelpExampleCli("sendtoaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 0.1 \"drinks\" \"room77\" true true null \"unset\" null 1.1") + 282 "\nSend 0.2 BTC with a confirmation target of 6 blocks in economical fee estimate mode using named arguments\n" 283 + HelpExampleCli("-named sendtoaddress", "address=\"" + EXAMPLE_ADDRESS[0] + "\" amount=0.2 conf_target=6 estimate_mode=\"economical\"") + 284 "\nSend 0.5 BTC with a fee rate of 25 " + CURRENCY_ATOM + "/vB using named arguments\n" 285 + HelpExampleCli("-named sendtoaddress", "address=\"" + EXAMPLE_ADDRESS[0] + "\" amount=0.5 fee_rate=25") 286 + HelpExampleCli("-named sendtoaddress", "address=\"" + EXAMPLE_ADDRESS[0] + "\" amount=0.5 fee_rate=25 subtractfeefromamount=false replaceable=true avoid_reuse=true comment=\"2 pizzas\" comment_to=\"jeremy\" verbose=true") 287 }, 288 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue 289 { 290 std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request); 291 if (!pwallet) return UniValue::VNULL; 292 293 // Make sure the results are valid at least up to the most recent block 294 // the user could have gotten from another RPC command prior to now 295 pwallet->BlockUntilSyncedToCurrentChain(); 296 297 LOCK(pwallet->cs_wallet); 298 299 // Wallet comments 300 mapValue_t mapValue; 301 if (!request.params[2].isNull() && !request.params[2].get_str().empty()) 302 mapValue["comment"] = request.params[2].get_str(); 303 if (!request.params[3].isNull() && !request.params[3].get_str().empty()) 304 mapValue["to"] = request.params[3].get_str(); 305 306 CCoinControl coin_control; 307 if (!request.params[5].isNull()) { 308 coin_control.m_signal_bip125_rbf = request.params[5].get_bool(); 309 } 310 311 coin_control.m_avoid_address_reuse = GetAvoidReuseFlag(*pwallet, request.params[8]); 312 // We also enable partial spend avoidance if reuse avoidance is set. 313 coin_control.m_avoid_partial_spends |= coin_control.m_avoid_address_reuse; 314 315 SetFeeEstimateMode(*pwallet, coin_control, /*conf_target=*/request.params[6], /*estimate_mode=*/request.params[7], /*fee_rate=*/request.params[9], /*override_min_fee=*/false); 316 317 EnsureWalletIsUnlocked(*pwallet); 318 319 UniValue address_amounts(UniValue::VOBJ); 320 const std::string address = request.params[0].get_str(); 321 address_amounts.pushKV(address, request.params[1]); 322 323 std::set<int> sffo_set; 324 if (!request.params[4].isNull() && request.params[4].get_bool()) { 325 sffo_set.insert(0); 326 } 327 328 std::vector<CRecipient> recipients{CreateRecipients(ParseOutputs(address_amounts), sffo_set)}; 329 const bool verbose{request.params[10].isNull() ? false : request.params[10].get_bool()}; 330 331 return SendMoney(*pwallet, coin_control, recipients, mapValue, verbose); 332 }, 333 }; 334 } 335 336 RPCHelpMan sendmany() 337 { 338 return RPCHelpMan{"sendmany", 339 "Send multiple times. Amounts are double-precision floating point numbers." + 340 HELP_REQUIRING_PASSPHRASE, 341 { 342 {"dummy", RPCArg::Type::STR, RPCArg::Default{"\"\""}, "Must be set to \"\" for backwards compatibility.", 343 RPCArgOptions{ 344 .oneline_description = "\"\"", 345 }}, 346 {"amounts", RPCArg::Type::OBJ_USER_KEYS, RPCArg::Optional::NO, "The addresses and amounts", 347 { 348 {"address", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "The bitcoin address is the key, the numeric amount (can be string) in " + CURRENCY_UNIT + " is the value"}, 349 }, 350 }, 351 {"minconf", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "Ignored dummy value"}, 352 {"comment", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "A comment"}, 353 {"subtractfeefrom", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "The addresses.\n" 354 "The fee will be equally deducted from the amount of each selected address.\n" 355 "Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n" 356 "If no addresses are specified here, the sender pays the fee.", 357 { 358 {"address", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Subtract fee from this address"}, 359 }, 360 }, 361 {"replaceable", RPCArg::Type::BOOL, RPCArg::DefaultHint{"wallet default"}, "Signal that this transaction can be replaced by a transaction (BIP 125)"}, 362 {"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks"}, 363 {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n" 364 + FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used"))}, 365 {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."}, 366 {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false}, "If true, return extra information about the transaction."}, 367 }, 368 { 369 RPCResult{"if verbose is not set or set to false", 370 RPCResult::Type::STR_HEX, "txid", "The transaction id for the send. Only 1 transaction is created regardless of\n" 371 "the number of addresses." 372 }, 373 RPCResult{"if verbose is set to true", 374 RPCResult::Type::OBJ, "", "", 375 { 376 {RPCResult::Type::STR_HEX, "txid", "The transaction id for the send. Only 1 transaction is created regardless of\n" 377 "the number of addresses."}, 378 {RPCResult::Type::STR, "fee_reason", "The transaction fee reason."} 379 }, 380 }, 381 }, 382 RPCExamples{ 383 "\nSend two amounts to two different addresses:\n" 384 + HelpExampleCli("sendmany", "\"\" \"{\\\"" + EXAMPLE_ADDRESS[0] + "\\\":0.01,\\\"" + EXAMPLE_ADDRESS[1] + "\\\":0.02}\"") + 385 "\nSend two amounts to two different addresses setting the confirmation and comment:\n" 386 + HelpExampleCli("sendmany", "\"\" \"{\\\"" + EXAMPLE_ADDRESS[0] + "\\\":0.01,\\\"" + EXAMPLE_ADDRESS[1] + "\\\":0.02}\" 6 \"testing\"") + 387 "\nSend two amounts to two different addresses, subtract fee from amount:\n" 388 + HelpExampleCli("sendmany", "\"\" \"{\\\"" + EXAMPLE_ADDRESS[0] + "\\\":0.01,\\\"" + EXAMPLE_ADDRESS[1] + "\\\":0.02}\" 1 \"\" \"[\\\"" + EXAMPLE_ADDRESS[0] + "\\\",\\\"" + EXAMPLE_ADDRESS[1] + "\\\"]\"") + 389 "\nAs a JSON-RPC call\n" 390 + HelpExampleRpc("sendmany", "\"\", {\"" + EXAMPLE_ADDRESS[0] + "\":0.01,\"" + EXAMPLE_ADDRESS[1] + "\":0.02}, 6, \"testing\"") 391 }, 392 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue 393 { 394 std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request); 395 if (!pwallet) return UniValue::VNULL; 396 397 // Make sure the results are valid at least up to the most recent block 398 // the user could have gotten from another RPC command prior to now 399 pwallet->BlockUntilSyncedToCurrentChain(); 400 401 LOCK(pwallet->cs_wallet); 402 403 if (!request.params[0].isNull() && !request.params[0].get_str().empty()) { 404 throw JSONRPCError(RPC_INVALID_PARAMETER, "Dummy value must be set to \"\""); 405 } 406 UniValue sendTo = request.params[1].get_obj(); 407 408 mapValue_t mapValue; 409 if (!request.params[3].isNull() && !request.params[3].get_str().empty()) 410 mapValue["comment"] = request.params[3].get_str(); 411 412 CCoinControl coin_control; 413 if (!request.params[5].isNull()) { 414 coin_control.m_signal_bip125_rbf = request.params[5].get_bool(); 415 } 416 417 SetFeeEstimateMode(*pwallet, coin_control, /*conf_target=*/request.params[6], /*estimate_mode=*/request.params[7], /*fee_rate=*/request.params[8], /*override_min_fee=*/false); 418 419 std::vector<CRecipient> recipients = CreateRecipients( 420 ParseOutputs(sendTo), 421 InterpretSubtractFeeFromOutputInstructions(request.params[4], sendTo.getKeys()) 422 ); 423 const bool verbose{request.params[9].isNull() ? false : request.params[9].get_bool()}; 424 425 return SendMoney(*pwallet, coin_control, recipients, std::move(mapValue), verbose); 426 }, 427 }; 428 } 429 430 // Only includes key documentation where the key is snake_case in all RPC methods. MixedCase keys can be added later. 431 static std::vector<RPCArg> FundTxDoc(bool solving_data = true) 432 { 433 std::vector<RPCArg> args = { 434 {"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks", RPCArgOptions{.also_positional = true}}, 435 {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n" 436 + FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used")), RPCArgOptions{.also_positional = true}}, 437 { 438 "replaceable", RPCArg::Type::BOOL, RPCArg::DefaultHint{"wallet default"}, "Marks this transaction as BIP125-replaceable.\n" 439 "Allows this transaction to be replaced by a transaction with higher fees" 440 }, 441 }; 442 if (solving_data) { 443 args.push_back({"solving_data", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "Keys and scripts needed for producing a final transaction with a dummy signature.\n" 444 "Used for fee estimation during coin selection.", 445 { 446 { 447 "pubkeys", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Public keys involved in this transaction.", 448 { 449 {"pubkey", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "A public key"}, 450 } 451 }, 452 { 453 "scripts", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Scripts involved in this transaction.", 454 { 455 {"script", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "A script"}, 456 } 457 }, 458 { 459 "descriptors", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Descriptors that provide solving data for this transaction.", 460 { 461 {"descriptor", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "A descriptor"}, 462 } 463 }, 464 } 465 }); 466 } 467 return args; 468 } 469 470 CreatedTransactionResult FundTransaction(CWallet& wallet, const CMutableTransaction& tx, const std::vector<CRecipient>& recipients, const UniValue& options, CCoinControl& coinControl, bool override_min_fee) 471 { 472 // We want to make sure tx.vout is not used now that we are passing outputs as a vector of recipients. 473 // This sets us up to remove tx completely in a future PR in favor of passing the inputs directly. 474 CHECK_NONFATAL(tx.vout.empty()); 475 // Make sure the results are valid at least up to the most recent block 476 // the user could have gotten from another RPC command prior to now 477 wallet.BlockUntilSyncedToCurrentChain(); 478 479 std::optional<unsigned int> change_position; 480 bool lockUnspents = false; 481 if (!options.isNull()) { 482 if (options.type() == UniValue::VBOOL) { 483 // backward compatibility bool only fallback, does nothing 484 } else { 485 RPCTypeCheckObj(options, 486 { 487 {"add_inputs", UniValueType(UniValue::VBOOL)}, 488 {"include_unsafe", UniValueType(UniValue::VBOOL)}, 489 {"add_to_wallet", UniValueType(UniValue::VBOOL)}, 490 {"changeAddress", UniValueType(UniValue::VSTR)}, 491 {"change_address", UniValueType(UniValue::VSTR)}, 492 {"changePosition", UniValueType(UniValue::VNUM)}, 493 {"change_position", UniValueType(UniValue::VNUM)}, 494 {"change_type", UniValueType(UniValue::VSTR)}, 495 {"includeWatching", UniValueType(UniValue::VBOOL)}, 496 {"include_watching", UniValueType(UniValue::VBOOL)}, 497 {"inputs", UniValueType(UniValue::VARR)}, 498 {"lockUnspents", UniValueType(UniValue::VBOOL)}, 499 {"lock_unspents", UniValueType(UniValue::VBOOL)}, 500 {"locktime", UniValueType(UniValue::VNUM)}, 501 {"fee_rate", UniValueType()}, // will be checked by AmountFromValue() in SetFeeEstimateMode() 502 {"feeRate", UniValueType()}, // will be checked by AmountFromValue() below 503 {"psbt", UniValueType(UniValue::VBOOL)}, 504 {"solving_data", UniValueType(UniValue::VOBJ)}, 505 {"subtractFeeFromOutputs", UniValueType(UniValue::VARR)}, 506 {"subtract_fee_from_outputs", UniValueType(UniValue::VARR)}, 507 {"replaceable", UniValueType(UniValue::VBOOL)}, 508 {"conf_target", UniValueType(UniValue::VNUM)}, 509 {"estimate_mode", UniValueType(UniValue::VSTR)}, 510 {"minconf", UniValueType(UniValue::VNUM)}, 511 {"maxconf", UniValueType(UniValue::VNUM)}, 512 {"input_weights", UniValueType(UniValue::VARR)}, 513 {"max_tx_weight", UniValueType(UniValue::VNUM)}, 514 }, 515 true, true); 516 517 if (options.exists("add_inputs")) { 518 coinControl.m_allow_other_inputs = options["add_inputs"].get_bool(); 519 } 520 521 if (options.exists("changeAddress") || options.exists("change_address")) { 522 const std::string change_address_str = (options.exists("change_address") ? options["change_address"] : options["changeAddress"]).get_str(); 523 CTxDestination dest = DecodeDestination(change_address_str); 524 525 if (!IsValidDestination(dest)) { 526 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Change address must be a valid bitcoin address"); 527 } 528 529 coinControl.destChange = dest; 530 } 531 532 if (options.exists("changePosition") || options.exists("change_position")) { 533 int pos = (options.exists("change_position") ? options["change_position"] : options["changePosition"]).getInt<int>(); 534 if (pos < 0 || (unsigned int)pos > recipients.size()) { 535 throw JSONRPCError(RPC_INVALID_PARAMETER, "changePosition out of bounds"); 536 } 537 change_position = (unsigned int)pos; 538 } 539 540 if (options.exists("change_type")) { 541 if (options.exists("changeAddress") || options.exists("change_address")) { 542 throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both change address and address type options"); 543 } 544 if (std::optional<OutputType> parsed = ParseOutputType(options["change_type"].get_str())) { 545 coinControl.m_change_type.emplace(parsed.value()); 546 } else { 547 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown change type '%s'", options["change_type"].get_str())); 548 } 549 } 550 551 if (options.exists("lockUnspents") || options.exists("lock_unspents")) { 552 lockUnspents = (options.exists("lock_unspents") ? options["lock_unspents"] : options["lockUnspents"]).get_bool(); 553 } 554 555 if (options.exists("include_unsafe")) { 556 coinControl.m_include_unsafe_inputs = options["include_unsafe"].get_bool(); 557 } 558 559 if (options.exists("feeRate")) { 560 if (options.exists("fee_rate")) { 561 throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both fee_rate (" + CURRENCY_ATOM + "/vB) and feeRate (" + CURRENCY_UNIT + "/kvB)"); 562 } 563 if (options.exists("conf_target")) { 564 throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both conf_target and feeRate. Please provide either a confirmation target in blocks for automatic fee estimation, or an explicit fee rate."); 565 } 566 if (options.exists("estimate_mode")) { 567 throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both estimate_mode and feeRate"); 568 } 569 coinControl.m_feerate = CFeeRate(AmountFromValue(options["feeRate"])); 570 coinControl.fOverrideFeeRate = true; 571 } 572 573 if (options.exists("replaceable")) { 574 coinControl.m_signal_bip125_rbf = options["replaceable"].get_bool(); 575 } 576 577 if (options.exists("minconf")) { 578 coinControl.m_min_depth = options["minconf"].getInt<int>(); 579 580 if (coinControl.m_min_depth < 0) { 581 throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative minconf"); 582 } 583 } 584 585 if (options.exists("maxconf")) { 586 coinControl.m_max_depth = options["maxconf"].getInt<int>(); 587 588 if (coinControl.m_max_depth < coinControl.m_min_depth) { 589 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("maxconf can't be lower than minconf: %d < %d", coinControl.m_max_depth, coinControl.m_min_depth)); 590 } 591 } 592 SetFeeEstimateMode(wallet, coinControl, options["conf_target"], options["estimate_mode"], options["fee_rate"], override_min_fee); 593 } 594 } 595 596 if (options.exists("solving_data")) { 597 const UniValue solving_data = options["solving_data"].get_obj(); 598 if (solving_data.exists("pubkeys")) { 599 for (const UniValue& pk_univ : solving_data["pubkeys"].get_array().getValues()) { 600 const CPubKey pubkey = HexToPubKey(pk_univ.get_str()); 601 coinControl.m_external_provider.pubkeys.emplace(pubkey.GetID(), pubkey); 602 // Add witness script for pubkeys 603 const CScript wit_script = GetScriptForDestination(WitnessV0KeyHash(pubkey)); 604 coinControl.m_external_provider.scripts.emplace(CScriptID(wit_script), wit_script); 605 } 606 } 607 608 if (solving_data.exists("scripts")) { 609 for (const UniValue& script_univ : solving_data["scripts"].get_array().getValues()) { 610 const std::string& script_str = script_univ.get_str(); 611 if (!IsHex(script_str)) { 612 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("'%s' is not hex", script_str)); 613 } 614 std::vector<unsigned char> script_data(ParseHex(script_str)); 615 const CScript script(script_data.begin(), script_data.end()); 616 coinControl.m_external_provider.scripts.emplace(CScriptID(script), script); 617 } 618 } 619 620 if (solving_data.exists("descriptors")) { 621 for (const UniValue& desc_univ : solving_data["descriptors"].get_array().getValues()) { 622 const std::string& desc_str = desc_univ.get_str(); 623 FlatSigningProvider desc_out; 624 std::string error; 625 std::vector<CScript> scripts_temp; 626 auto descs = Parse(desc_str, desc_out, error, true); 627 if (descs.empty()) { 628 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Unable to parse descriptor '%s': %s", desc_str, error)); 629 } 630 for (auto& desc : descs) { 631 desc->Expand(0, desc_out, scripts_temp, desc_out); 632 } 633 coinControl.m_external_provider.Merge(std::move(desc_out)); 634 } 635 } 636 } 637 638 if (options.exists("input_weights")) { 639 for (const UniValue& input : options["input_weights"].get_array().getValues()) { 640 Txid txid = Txid::FromUint256(ParseHashO(input, "txid")); 641 642 const UniValue& vout_v = input.find_value("vout"); 643 if (!vout_v.isNum()) { 644 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key"); 645 } 646 int vout = vout_v.getInt<int>(); 647 if (vout < 0) { 648 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout cannot be negative"); 649 } 650 651 const UniValue& weight_v = input.find_value("weight"); 652 if (!weight_v.isNum()) { 653 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing weight key"); 654 } 655 int64_t weight = weight_v.getInt<int64_t>(); 656 const int64_t min_input_weight = GetTransactionInputWeight(CTxIn()); 657 CHECK_NONFATAL(min_input_weight == 165); 658 if (weight < min_input_weight) { 659 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, weight cannot be less than 165 (41 bytes (size of outpoint + sequence + empty scriptSig) * 4 (witness scaling factor)) + 1 (empty witness)"); 660 } 661 if (weight > MAX_STANDARD_TX_WEIGHT) { 662 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, weight cannot be greater than the maximum standard tx weight of %d", MAX_STANDARD_TX_WEIGHT)); 663 } 664 665 coinControl.SetInputWeight(COutPoint(txid, vout), weight); 666 } 667 } 668 669 if (options.exists("max_tx_weight")) { 670 coinControl.m_max_tx_weight = options["max_tx_weight"].getInt<int>(); 671 } 672 673 if (tx.version == TRUC_VERSION) { 674 if (!coinControl.m_max_tx_weight.has_value() || coinControl.m_max_tx_weight.value() > TRUC_MAX_WEIGHT) { 675 coinControl.m_max_tx_weight = TRUC_MAX_WEIGHT; 676 } 677 } 678 679 if (recipients.empty()) 680 throw JSONRPCError(RPC_INVALID_PARAMETER, "TX must have at least one output"); 681 682 auto txr = FundTransaction(wallet, tx, recipients, change_position, lockUnspents, coinControl); 683 if (!txr) { 684 throw JSONRPCError(RPC_WALLET_ERROR, ErrorString(txr).original); 685 } 686 return *txr; 687 } 688 689 static void SetOptionsInputWeights(const UniValue& inputs, UniValue& options) 690 { 691 if (options.exists("input_weights")) { 692 throw JSONRPCError(RPC_INVALID_PARAMETER, "Input weights should be specified in inputs rather than in options."); 693 } 694 if (inputs.size() == 0) { 695 return; 696 } 697 UniValue weights(UniValue::VARR); 698 for (const UniValue& input : inputs.getValues()) { 699 if (input.exists("weight")) { 700 weights.push_back(input); 701 } 702 } 703 options.pushKV("input_weights", std::move(weights)); 704 } 705 706 RPCHelpMan fundrawtransaction() 707 { 708 return RPCHelpMan{ 709 "fundrawtransaction", 710 "If the transaction has no inputs, they will be automatically selected to meet its out value.\n" 711 "It will add at most one change output to the outputs.\n" 712 "No existing outputs will be modified unless \"subtractFeeFromOutputs\" is specified.\n" 713 "Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n" 714 "The inputs added will not be signed, use signrawtransactionwithkey\n" 715 "or signrawtransactionwithwallet for that.\n" 716 "All existing inputs must either have their previous output transaction be in the wallet\n" 717 "or be in the UTXO set. Solving data must be provided for non-wallet inputs.\n" 718 "Note that all inputs selected must be of standard form and P2SH scripts must be\n" 719 "in the wallet using importdescriptors (to calculate fees).\n" 720 "You can see whether this is the case by checking the \"solvable\" field in the listunspent output.\n" 721 "Note that if specifying an exact fee rate, the resulting transaction may have a higher fee rate\n" 722 "if the transaction has unconfirmed inputs. This is because the wallet will attempt to make the\n" 723 "entire package have the given fee rate, not the resulting transaction.\n", 724 { 725 {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of the raw transaction"}, 726 {"options", RPCArg::Type::OBJ_NAMED_PARAMS, RPCArg::Optional::OMITTED, "", 727 Cat<std::vector<RPCArg>>( 728 { 729 {"add_inputs", RPCArg::Type::BOOL, RPCArg::Default{true}, "For a transaction with existing inputs, automatically include more if they are not enough."}, 730 {"include_unsafe", RPCArg::Type::BOOL, RPCArg::Default{false}, "Include inputs that are not safe to spend (unconfirmed transactions from outside keys and unconfirmed replacement transactions).\n" 731 "Warning: the resulting transaction may become invalid if one of the unsafe inputs disappears.\n" 732 "If that happens, you will need to fund the transaction with different inputs and republish it."}, 733 {"minconf", RPCArg::Type::NUM, RPCArg::Default{0}, "If add_inputs is specified, require inputs with at least this many confirmations."}, 734 {"maxconf", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "If add_inputs is specified, require inputs with at most this many confirmations."}, 735 {"changeAddress", RPCArg::Type::STR, RPCArg::DefaultHint{"automatic"}, "The bitcoin address to receive the change"}, 736 {"changePosition", RPCArg::Type::NUM, RPCArg::DefaultHint{"random"}, "The index of the change output"}, 737 {"change_type", RPCArg::Type::STR, RPCArg::DefaultHint{"set by -changetype"}, "The output type to use. Only valid if changeAddress is not specified. Options are " + FormatAllOutputTypes() + "."}, 738 {"includeWatching", RPCArg::Type::BOOL, RPCArg::Default{false}, "(DEPRECATED) No longer used"}, 739 {"lockUnspents", RPCArg::Type::BOOL, RPCArg::Default{false}, "Lock selected unspent outputs"}, 740 {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."}, 741 {"feeRate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_UNIT + "/kvB."}, 742 {"subtractFeeFromOutputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "The integers.\n" 743 "The fee will be equally deducted from the amount of each specified output.\n" 744 "Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n" 745 "If no outputs are specified here, the sender pays the fee.", 746 { 747 {"vout_index", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The zero-based output index, before a change output is added."}, 748 }, 749 }, 750 {"input_weights", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "Inputs and their corresponding weights", 751 { 752 {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", 753 { 754 {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"}, 755 {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output index"}, 756 {"weight", RPCArg::Type::NUM, RPCArg::Optional::NO, "The maximum weight for this input, " 757 "including the weight of the outpoint and sequence number. " 758 "Note that serialized signature sizes are not guaranteed to be consistent, " 759 "so the maximum DER signatures size of 73 bytes should be used when considering ECDSA signatures." 760 "Remember to convert serialized sizes to weight units when necessary."}, 761 }, 762 }, 763 }, 764 }, 765 {"max_tx_weight", RPCArg::Type::NUM, RPCArg::Default{MAX_STANDARD_TX_WEIGHT}, "The maximum acceptable transaction weight.\n" 766 "Transaction building will fail if this can not be satisfied."}, 767 }, 768 FundTxDoc()), 769 RPCArgOptions{ 770 .skip_type_check = true, 771 .oneline_description = "options", 772 }}, 773 {"iswitness", RPCArg::Type::BOOL, RPCArg::DefaultHint{"depends on heuristic tests"}, "Whether the transaction hex is a serialized witness transaction.\n" 774 "If iswitness is not present, heuristic tests will be used in decoding.\n" 775 "If true, only witness deserialization will be tried.\n" 776 "If false, only non-witness deserialization will be tried.\n" 777 "This boolean should reflect whether the transaction has inputs\n" 778 "(e.g. fully valid, or on-chain transactions), if known by the caller." 779 }, 780 }, 781 RPCResult{ 782 RPCResult::Type::OBJ, "", "", 783 { 784 {RPCResult::Type::STR_HEX, "hex", "The resulting raw transaction (hex-encoded string)"}, 785 {RPCResult::Type::STR_AMOUNT, "fee", "Fee in " + CURRENCY_UNIT + " the resulting transaction pays"}, 786 {RPCResult::Type::NUM, "changepos", "The position of the added change output, or -1"}, 787 } 788 }, 789 RPCExamples{ 790 "\nCreate a transaction with no inputs\n" 791 + HelpExampleCli("createrawtransaction", "\"[]\" \"{\\\"myaddress\\\":0.01}\"") + 792 "\nAdd sufficient unsigned inputs to meet the output value\n" 793 + HelpExampleCli("fundrawtransaction", "\"rawtransactionhex\"") + 794 "\nSign the transaction\n" 795 + HelpExampleCli("signrawtransactionwithwallet", "\"fundedtransactionhex\"") + 796 "\nSend the transaction\n" 797 + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"") 798 }, 799 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue 800 { 801 std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request); 802 if (!pwallet) return UniValue::VNULL; 803 804 // parse hex string from parameter 805 CMutableTransaction tx; 806 bool try_witness = request.params[2].isNull() ? true : request.params[2].get_bool(); 807 bool try_no_witness = request.params[2].isNull() ? true : !request.params[2].get_bool(); 808 if (!DecodeHexTx(tx, request.params[0].get_str(), try_no_witness, try_witness)) { 809 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); 810 } 811 UniValue options = request.params[1]; 812 std::vector<std::pair<CTxDestination, CAmount>> destinations; 813 for (const auto& tx_out : tx.vout) { 814 CTxDestination dest; 815 ExtractDestination(tx_out.scriptPubKey, dest); 816 destinations.emplace_back(dest, tx_out.nValue); 817 } 818 std::vector<std::string> dummy(destinations.size(), "dummy"); 819 std::vector<CRecipient> recipients = CreateRecipients( 820 destinations, 821 InterpretSubtractFeeFromOutputInstructions(options["subtractFeeFromOutputs"], dummy) 822 ); 823 CCoinControl coin_control; 824 // Automatically select (additional) coins. Can be overridden by options.add_inputs. 825 coin_control.m_allow_other_inputs = true; 826 // Clear tx.vout since it is not meant to be used now that we are passing outputs directly. 827 // This sets us up for a future PR to completely remove tx from the function signature in favor of passing inputs directly 828 tx.vout.clear(); 829 auto txr = FundTransaction(*pwallet, tx, recipients, options, coin_control, /*override_min_fee=*/true); 830 831 UniValue result(UniValue::VOBJ); 832 result.pushKV("hex", EncodeHexTx(*txr.tx)); 833 result.pushKV("fee", ValueFromAmount(txr.fee)); 834 result.pushKV("changepos", txr.change_pos ? (int)*txr.change_pos : -1); 835 836 return result; 837 }, 838 }; 839 } 840 841 RPCHelpMan signrawtransactionwithwallet() 842 { 843 return RPCHelpMan{ 844 "signrawtransactionwithwallet", 845 "Sign inputs for raw transaction (serialized, hex-encoded).\n" 846 "The second optional argument (may be null) is an array of previous transaction outputs that\n" 847 "this transaction depends on but may not yet be in the block chain." + 848 HELP_REQUIRING_PASSPHRASE, 849 { 850 {"hexstring", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction hex string"}, 851 {"prevtxs", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "The previous dependent transaction outputs", 852 { 853 {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", 854 { 855 {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"}, 856 {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"}, 857 {"scriptPubKey", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The output script"}, 858 {"redeemScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2SH) redeem script"}, 859 {"witnessScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2WSH or P2SH-P2WSH) witness script"}, 860 {"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::OMITTED, "(required for Segwit inputs) the amount spent"}, 861 }, 862 }, 863 }, 864 }, 865 {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"DEFAULT for Taproot, ALL otherwise"}, "The signature hash type. Must be one of\n" 866 " \"DEFAULT\"\n" 867 " \"ALL\"\n" 868 " \"NONE\"\n" 869 " \"SINGLE\"\n" 870 " \"ALL|ANYONECANPAY\"\n" 871 " \"NONE|ANYONECANPAY\"\n" 872 " \"SINGLE|ANYONECANPAY\""}, 873 }, 874 RPCResult{ 875 RPCResult::Type::OBJ, "", "", 876 { 877 {RPCResult::Type::STR_HEX, "hex", "The hex-encoded raw transaction with signature(s)"}, 878 {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"}, 879 {RPCResult::Type::ARR, "errors", /*optional=*/true, "Script verification errors (if there are any)", 880 { 881 {RPCResult::Type::OBJ, "", "", 882 { 883 {RPCResult::Type::STR_HEX, "txid", "The hash of the referenced, previous transaction"}, 884 {RPCResult::Type::NUM, "vout", "The index of the output to spent and used as input"}, 885 {RPCResult::Type::ARR, "witness", "", 886 { 887 {RPCResult::Type::STR_HEX, "witness", ""}, 888 }}, 889 {RPCResult::Type::STR_HEX, "scriptSig", "The hex-encoded signature script"}, 890 {RPCResult::Type::NUM, "sequence", "Script sequence number"}, 891 {RPCResult::Type::STR, "error", "Verification or signing error related to the input"}, 892 }}, 893 }}, 894 } 895 }, 896 RPCExamples{ 897 HelpExampleCli("signrawtransactionwithwallet", "\"myhex\"") 898 + HelpExampleRpc("signrawtransactionwithwallet", "\"myhex\"") 899 }, 900 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue 901 { 902 const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request); 903 if (!pwallet) return UniValue::VNULL; 904 905 CMutableTransaction mtx; 906 if (!DecodeHexTx(mtx, request.params[0].get_str())) { 907 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input."); 908 } 909 910 // Sign the transaction 911 LOCK(pwallet->cs_wallet); 912 EnsureWalletIsUnlocked(*pwallet); 913 914 // Fetch previous transactions (inputs): 915 std::map<COutPoint, Coin> coins; 916 for (const CTxIn& txin : mtx.vin) { 917 coins[txin.prevout]; // Create empty map entry keyed by prevout. 918 } 919 pwallet->chain().findCoins(coins); 920 921 // Parse the prevtxs array 922 ParsePrevouts(request.params[1], nullptr, coins); 923 924 std::optional<int> nHashType = ParseSighashString(request.params[2]); 925 if (!nHashType) { 926 nHashType = SIGHASH_DEFAULT; 927 } 928 929 // Script verification errors 930 std::map<int, bilingual_str> input_errors; 931 932 bool complete = pwallet->SignTransaction(mtx, coins, *nHashType, input_errors); 933 UniValue result(UniValue::VOBJ); 934 SignTransactionResultToJSON(mtx, complete, coins, input_errors, result); 935 return result; 936 }, 937 }; 938 } 939 940 // Definition of allowed formats of specifying transaction outputs in 941 // `bumpfee`, `psbtbumpfee`, `send` and `walletcreatefundedpsbt` RPCs. 942 static std::vector<RPCArg> OutputsDoc() 943 { 944 return 945 { 946 {"", RPCArg::Type::OBJ_USER_KEYS, RPCArg::Optional::OMITTED, "", 947 { 948 {"address", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "A key-value pair. The key (string) is the bitcoin address,\n" 949 "the value (float or string) is the amount in " + CURRENCY_UNIT + ""}, 950 }, 951 }, 952 {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", 953 { 954 {"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"}, 955 }, 956 }, 957 }; 958 } 959 960 static RPCHelpMan bumpfee_helper(std::string method_name) 961 { 962 const bool want_psbt = method_name == "psbtbumpfee"; 963 const std::string incremental_fee{CFeeRate(DEFAULT_INCREMENTAL_RELAY_FEE).ToString(FeeRateFormat::SAT_VB)}; 964 965 return RPCHelpMan{method_name, 966 "Bumps the fee of a transaction T, replacing it with a new transaction B.\n" 967 + std::string(want_psbt ? "Returns a PSBT instead of creating and signing a new transaction.\n" : "") + 968 "A transaction with the given txid must be in the wallet.\n" 969 "The command will pay the additional fee by reducing change outputs or adding inputs when necessary.\n" 970 "It may add a new change output if one does not already exist.\n" 971 "All inputs in the original transaction will be included in the replacement transaction.\n" 972 "The command will fail if the wallet or mempool contains a transaction that spends one of T's outputs.\n" 973 "By default, the new fee will be calculated automatically using the estimatesmartfee RPC.\n" 974 "The user can specify a confirmation target for estimatesmartfee.\n" 975 "Alternatively, the user can specify a fee rate in " + CURRENCY_ATOM + "/vB for the new transaction.\n" 976 "At a minimum, the new fee rate must be high enough to pay an additional new relay fee (incrementalfee\n" 977 "returned by getnetworkinfo) to enter the node's mempool.\n" 978 "* WARNING: before version 0.21, fee_rate was in " + CURRENCY_UNIT + "/kvB. As of 0.21, fee_rate is in " + CURRENCY_ATOM + "/vB. *\n", 979 { 980 {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The txid to be bumped"}, 981 {"options", RPCArg::Type::OBJ_NAMED_PARAMS, RPCArg::Optional::OMITTED, "", 982 { 983 {"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks\n"}, 984 {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, 985 "\nSpecify a fee rate in " + CURRENCY_ATOM + "/vB instead of relying on the built-in fee estimator.\n" 986 "Must be at least " + incremental_fee + " higher than the current transaction fee rate.\n" 987 "WARNING: before version 0.21, fee_rate was in " + CURRENCY_UNIT + "/kvB. As of 0.21, fee_rate is in " + CURRENCY_ATOM + "/vB.\n"}, 988 {"replaceable", RPCArg::Type::BOOL, RPCArg::Default{true}, 989 "Whether the new transaction should be\n" 990 "marked bip-125 replaceable. If true, the sequence numbers in the transaction will\n" 991 "be set to 0xfffffffd. If false, any input sequence numbers in the\n" 992 "transaction will be set to 0xfffffffe\n" 993 "so the new transaction will not be explicitly bip-125 replaceable (though it may\n" 994 "still be replaceable in practice, for example if it has unconfirmed ancestors which\n" 995 "are replaceable).\n"}, 996 {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n" 997 + FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used"))}, 998 {"outputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "The outputs specified as key-value pairs.\n" 999 "Each key may only appear once, i.e. there can only be one 'data' output, and no address may be duplicated.\n" 1000 "At least one output of either type must be specified.\n" 1001 "Cannot be provided if 'original_change_index' is specified.", 1002 OutputsDoc(), 1003 RPCArgOptions{.skip_type_check = true}}, 1004 {"original_change_index", RPCArg::Type::NUM, RPCArg::DefaultHint{"not set, detect change automatically"}, "The 0-based index of the change output on the original transaction. " 1005 "The indicated output will be recycled into the new change output on the bumped transaction. " 1006 "The remainder after paying the recipients and fees will be sent to the output script of the " 1007 "original change output. The change output’s amount can increase if bumping the transaction " 1008 "adds new inputs, otherwise it will decrease. Cannot be used in combination with the 'outputs' option."}, 1009 }, 1010 RPCArgOptions{.oneline_description="options"}}, 1011 }, 1012 RPCResult{ 1013 RPCResult::Type::OBJ, "", "", Cat( 1014 want_psbt ? 1015 std::vector<RPCResult>{{RPCResult::Type::STR, "psbt", "The base64-encoded unsigned PSBT of the new transaction."}} : 1016 std::vector<RPCResult>{{RPCResult::Type::STR_HEX, "txid", "The id of the new transaction."}}, 1017 { 1018 {RPCResult::Type::STR_AMOUNT, "origfee", "The fee of the replaced transaction."}, 1019 {RPCResult::Type::STR_AMOUNT, "fee", "The fee of the new transaction."}, 1020 {RPCResult::Type::ARR, "errors", "Errors encountered during processing (may be empty).", 1021 { 1022 {RPCResult::Type::STR, "", ""}, 1023 }}, 1024 }) 1025 }, 1026 RPCExamples{ 1027 "\nBump the fee, get the new transaction\'s " + std::string(want_psbt ? "psbt" : "txid") + "\n" + 1028 HelpExampleCli(method_name, "<txid>") 1029 }, 1030 [want_psbt](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue 1031 { 1032 std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request); 1033 if (!pwallet) return UniValue::VNULL; 1034 1035 if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && !pwallet->IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER) && !want_psbt) { 1036 throw JSONRPCError(RPC_WALLET_ERROR, "bumpfee is not available with wallets that have private keys disabled. Use psbtbumpfee instead."); 1037 } 1038 1039 Txid hash{Txid::FromUint256(ParseHashV(request.params[0], "txid"))}; 1040 1041 CCoinControl coin_control; 1042 // optional parameters 1043 coin_control.m_signal_bip125_rbf = true; 1044 std::vector<CTxOut> outputs; 1045 1046 std::optional<uint32_t> original_change_index; 1047 1048 if (!request.params[1].isNull()) { 1049 UniValue options = request.params[1]; 1050 RPCTypeCheckObj(options, 1051 { 1052 {"confTarget", UniValueType(UniValue::VNUM)}, 1053 {"conf_target", UniValueType(UniValue::VNUM)}, 1054 {"fee_rate", UniValueType()}, // will be checked by AmountFromValue() in SetFeeEstimateMode() 1055 {"replaceable", UniValueType(UniValue::VBOOL)}, 1056 {"estimate_mode", UniValueType(UniValue::VSTR)}, 1057 {"outputs", UniValueType()}, // will be checked by AddOutputs() 1058 {"original_change_index", UniValueType(UniValue::VNUM)}, 1059 }, 1060 true, true); 1061 1062 if (options.exists("confTarget") && options.exists("conf_target")) { 1063 throw JSONRPCError(RPC_INVALID_PARAMETER, "confTarget and conf_target options should not both be set. Use conf_target (confTarget is deprecated)."); 1064 } 1065 1066 auto conf_target = options.exists("confTarget") ? options["confTarget"] : options["conf_target"]; 1067 1068 if (options.exists("replaceable")) { 1069 coin_control.m_signal_bip125_rbf = options["replaceable"].get_bool(); 1070 } 1071 SetFeeEstimateMode(*pwallet, coin_control, conf_target, options["estimate_mode"], options["fee_rate"], /*override_min_fee=*/false); 1072 1073 // Prepare new outputs by creating a temporary tx and calling AddOutputs(). 1074 if (!options["outputs"].isNull()) { 1075 if (options["outputs"].isArray() && options["outputs"].empty()) { 1076 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, output argument cannot be an empty array"); 1077 } 1078 CMutableTransaction tempTx; 1079 AddOutputs(tempTx, options["outputs"]); 1080 outputs = tempTx.vout; 1081 } 1082 1083 if (options.exists("original_change_index")) { 1084 original_change_index = options["original_change_index"].getInt<uint32_t>(); 1085 } 1086 } 1087 1088 // Make sure the results are valid at least up to the most recent block 1089 // the user could have gotten from another RPC command prior to now 1090 pwallet->BlockUntilSyncedToCurrentChain(); 1091 1092 LOCK(pwallet->cs_wallet); 1093 1094 EnsureWalletIsUnlocked(*pwallet); 1095 1096 1097 std::vector<bilingual_str> errors; 1098 CAmount old_fee; 1099 CAmount new_fee; 1100 CMutableTransaction mtx; 1101 feebumper::Result res; 1102 // Targeting feerate bump. 1103 res = feebumper::CreateRateBumpTransaction(*pwallet, hash, coin_control, errors, old_fee, new_fee, mtx, /*require_mine=*/ !want_psbt, outputs, original_change_index); 1104 if (res != feebumper::Result::OK) { 1105 switch(res) { 1106 case feebumper::Result::INVALID_ADDRESS_OR_KEY: 1107 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, errors[0].original); 1108 break; 1109 case feebumper::Result::INVALID_REQUEST: 1110 throw JSONRPCError(RPC_INVALID_REQUEST, errors[0].original); 1111 break; 1112 case feebumper::Result::INVALID_PARAMETER: 1113 throw JSONRPCError(RPC_INVALID_PARAMETER, errors[0].original); 1114 break; 1115 case feebumper::Result::WALLET_ERROR: 1116 throw JSONRPCError(RPC_WALLET_ERROR, errors[0].original); 1117 break; 1118 default: 1119 throw JSONRPCError(RPC_MISC_ERROR, errors[0].original); 1120 break; 1121 } 1122 } 1123 1124 UniValue result(UniValue::VOBJ); 1125 1126 // For bumpfee, return the new transaction id. 1127 // For psbtbumpfee, return the base64-encoded unsigned PSBT of the new transaction. 1128 if (!want_psbt) { 1129 if (!feebumper::SignTransaction(*pwallet, mtx)) { 1130 if (pwallet->IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER)) { 1131 throw JSONRPCError(RPC_WALLET_ERROR, "Transaction incomplete. Try psbtbumpfee instead."); 1132 } 1133 throw JSONRPCError(RPC_WALLET_ERROR, "Can't sign transaction."); 1134 } 1135 1136 Txid txid; 1137 if (feebumper::CommitTransaction(*pwallet, hash, std::move(mtx), errors, txid) != feebumper::Result::OK) { 1138 throw JSONRPCError(RPC_WALLET_ERROR, errors[0].original); 1139 } 1140 1141 result.pushKV("txid", txid.GetHex()); 1142 } else { 1143 PartiallySignedTransaction psbtx(mtx); 1144 bool complete = false; 1145 const auto err{pwallet->FillPSBT(psbtx, complete, std::nullopt, /*sign=*/false, /*bip32derivs=*/true)}; 1146 CHECK_NONFATAL(!err); 1147 CHECK_NONFATAL(!complete); 1148 DataStream ssTx{}; 1149 ssTx << psbtx; 1150 result.pushKV("psbt", EncodeBase64(ssTx.str())); 1151 } 1152 1153 result.pushKV("origfee", ValueFromAmount(old_fee)); 1154 result.pushKV("fee", ValueFromAmount(new_fee)); 1155 UniValue result_errors(UniValue::VARR); 1156 for (const bilingual_str& error : errors) { 1157 result_errors.push_back(error.original); 1158 } 1159 result.pushKV("errors", std::move(result_errors)); 1160 1161 return result; 1162 }, 1163 }; 1164 } 1165 1166 RPCHelpMan bumpfee() { return bumpfee_helper("bumpfee"); } 1167 RPCHelpMan psbtbumpfee() { return bumpfee_helper("psbtbumpfee"); } 1168 1169 RPCHelpMan send() 1170 { 1171 return RPCHelpMan{ 1172 "send", 1173 "EXPERIMENTAL warning: this call may be changed in future releases.\n" 1174 "\nSend a transaction.\n", 1175 { 1176 {"outputs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The outputs specified as key-value pairs.\n" 1177 "Each key may only appear once, i.e. there can only be one 'data' output, and no address may be duplicated.\n" 1178 "At least one output of either type must be specified.\n" 1179 "For convenience, a dictionary, which holds the key-value pairs directly, is also accepted.", 1180 OutputsDoc(), 1181 RPCArgOptions{.skip_type_check = true}}, 1182 {"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks"}, 1183 {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n" 1184 + FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used"))}, 1185 {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."}, 1186 {"options", RPCArg::Type::OBJ_NAMED_PARAMS, RPCArg::Optional::OMITTED, "", 1187 Cat<std::vector<RPCArg>>( 1188 { 1189 {"add_inputs", RPCArg::Type::BOOL, RPCArg::DefaultHint{"false when \"inputs\" are specified, true otherwise"},"Automatically include coins from the wallet to cover the target amount.\n"}, 1190 {"include_unsafe", RPCArg::Type::BOOL, RPCArg::Default{false}, "Include inputs that are not safe to spend (unconfirmed transactions from outside keys and unconfirmed replacement transactions).\n" 1191 "Warning: the resulting transaction may become invalid if one of the unsafe inputs disappears.\n" 1192 "If that happens, you will need to fund the transaction with different inputs and republish it."}, 1193 {"minconf", RPCArg::Type::NUM, RPCArg::Default{0}, "If add_inputs is specified, require inputs with at least this many confirmations."}, 1194 {"maxconf", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "If add_inputs is specified, require inputs with at most this many confirmations."}, 1195 {"add_to_wallet", RPCArg::Type::BOOL, RPCArg::Default{true}, "When false, returns a serialized transaction which will not be added to the wallet or broadcast"}, 1196 {"change_address", RPCArg::Type::STR, RPCArg::DefaultHint{"automatic"}, "The bitcoin address to receive the change"}, 1197 {"change_position", RPCArg::Type::NUM, RPCArg::DefaultHint{"random"}, "The index of the change output"}, 1198 {"change_type", RPCArg::Type::STR, RPCArg::DefaultHint{"set by -changetype"}, "The output type to use. Only valid if change_address is not specified. Options are " + FormatAllOutputTypes() + "."}, 1199 {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB.", RPCArgOptions{.also_positional = true}}, 1200 {"include_watching", RPCArg::Type::BOOL, RPCArg::Default{"false"}, "(DEPRECATED) No longer used"}, 1201 {"inputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Specify inputs instead of adding them automatically.", 1202 { 1203 {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", { 1204 {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"}, 1205 {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"}, 1206 {"sequence", RPCArg::Type::NUM, RPCArg::DefaultHint{"depends on the value of the 'replaceable' and 'locktime' arguments"}, "The sequence number"}, 1207 {"weight", RPCArg::Type::NUM, RPCArg::DefaultHint{"Calculated from wallet and solving data"}, "The maximum weight for this input, " 1208 "including the weight of the outpoint and sequence number. " 1209 "Note that signature sizes are not guaranteed to be consistent, " 1210 "so the maximum DER signatures size of 73 bytes should be used when considering ECDSA signatures." 1211 "Remember to convert serialized sizes to weight units when necessary."}, 1212 }}, 1213 }, 1214 }, 1215 {"locktime", RPCArg::Type::NUM, RPCArg::DefaultHint{"locktime close to block height to prevent fee sniping"}, "Raw locktime. Non-0 value also locktime-activates inputs"}, 1216 {"lock_unspents", RPCArg::Type::BOOL, RPCArg::Default{false}, "Lock selected unspent outputs"}, 1217 {"psbt", RPCArg::Type::BOOL, RPCArg::DefaultHint{"automatic"}, "Always return a PSBT, implies add_to_wallet=false."}, 1218 {"subtract_fee_from_outputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Outputs to subtract the fee from, specified as integer indices.\n" 1219 "The fee will be equally deducted from the amount of each specified output.\n" 1220 "Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n" 1221 "If no outputs are specified here, the sender pays the fee.", 1222 { 1223 {"vout_index", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The zero-based output index, before a change output is added."}, 1224 }, 1225 }, 1226 {"max_tx_weight", RPCArg::Type::NUM, RPCArg::Default{MAX_STANDARD_TX_WEIGHT}, "The maximum acceptable transaction weight.\n" 1227 "Transaction building will fail if this can not be satisfied."}, 1228 }, 1229 FundTxDoc()), 1230 RPCArgOptions{.oneline_description="options"}}, 1231 {"version", RPCArg::Type::NUM, RPCArg::Default{DEFAULT_WALLET_TX_VERSION}, "Transaction version"}, 1232 }, 1233 RPCResult{ 1234 RPCResult::Type::OBJ, "", "", 1235 { 1236 {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"}, 1237 {RPCResult::Type::STR_HEX, "txid", /*optional=*/true, "The transaction id for the send. Only 1 transaction is created regardless of the number of addresses."}, 1238 {RPCResult::Type::STR_HEX, "hex", /*optional=*/true, "If add_to_wallet is false, the hex-encoded raw transaction with signature(s)"}, 1239 {RPCResult::Type::STR, "psbt", /*optional=*/true, "If more signatures are needed, or if add_to_wallet is false, the base64-encoded (partially) signed transaction"} 1240 } 1241 }, 1242 RPCExamples{"" 1243 "\nSend 0.1 BTC with a confirmation target of 6 blocks in economical fee estimate mode\n" 1244 + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.1}' 6 economical\n") + 1245 "Send 0.2 BTC with a fee rate of 1.1 " + CURRENCY_ATOM + "/vB using positional arguments\n" 1246 + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.2}' null \"unset\" 1.1\n") + 1247 "Send 0.2 BTC with a fee rate of 1 " + CURRENCY_ATOM + "/vB using the options argument\n" 1248 + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.2}' null \"unset\" null '{\"fee_rate\": 1}'\n") + 1249 "Send 0.3 BTC with a fee rate of 25 " + CURRENCY_ATOM + "/vB using named arguments\n" 1250 + HelpExampleCli("-named send", "outputs='{\"" + EXAMPLE_ADDRESS[0] + "\": 0.3}' fee_rate=25\n") + 1251 "Create a transaction that should confirm the next block, with a specific input, and return result without adding to wallet or broadcasting to the network\n" 1252 + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.1}' 1 economical null '{\"add_to_wallet\": false, \"inputs\": [{\"txid\":\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\", \"vout\":1}]}'") 1253 }, 1254 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue 1255 { 1256 std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request); 1257 if (!pwallet) return UniValue::VNULL; 1258 1259 UniValue options{request.params[4].isNull() ? UniValue::VOBJ : request.params[4]}; 1260 InterpretFeeEstimationInstructions(/*conf_target=*/request.params[1], /*estimate_mode=*/request.params[2], /*fee_rate=*/request.params[3], options); 1261 PreventOutdatedOptions(options); 1262 1263 1264 bool rbf{options.exists("replaceable") ? options["replaceable"].get_bool() : pwallet->m_signal_rbf}; 1265 UniValue outputs(UniValue::VOBJ); 1266 outputs = NormalizeOutputs(request.params[0]); 1267 std::vector<CRecipient> recipients = CreateRecipients( 1268 ParseOutputs(outputs), 1269 InterpretSubtractFeeFromOutputInstructions(options["subtract_fee_from_outputs"], outputs.getKeys()) 1270 ); 1271 CCoinControl coin_control; 1272 coin_control.m_version = self.Arg<uint32_t>("version"); 1273 CMutableTransaction rawTx = ConstructTransaction(options["inputs"], request.params[0], options["locktime"], rbf, coin_control.m_version); 1274 // Automatically select coins, unless at least one is manually selected. Can 1275 // be overridden by options.add_inputs. 1276 coin_control.m_allow_other_inputs = rawTx.vin.size() == 0; 1277 if (options.exists("max_tx_weight")) { 1278 coin_control.m_max_tx_weight = options["max_tx_weight"].getInt<int>(); 1279 } 1280 1281 SetOptionsInputWeights(options["inputs"], options); 1282 // Clear tx.vout since it is not meant to be used now that we are passing outputs directly. 1283 // This sets us up for a future PR to completely remove tx from the function signature in favor of passing inputs directly 1284 rawTx.vout.clear(); 1285 auto txr = FundTransaction(*pwallet, rawTx, recipients, options, coin_control, /*override_min_fee=*/false); 1286 1287 CMutableTransaction tx = CMutableTransaction(*txr.tx); 1288 return FinishTransaction(pwallet, options, tx); 1289 } 1290 }; 1291 } 1292 1293 RPCHelpMan sendall() 1294 { 1295 return RPCHelpMan{"sendall", 1296 "EXPERIMENTAL warning: this call may be changed in future releases.\n" 1297 "\nSpend the value of all (or specific) confirmed UTXOs and unconfirmed change in the wallet to one or more recipients.\n" 1298 "Unconfirmed inbound UTXOs and locked UTXOs will not be spent. Sendall will respect the avoid_reuse wallet flag.\n" 1299 "If your wallet contains many small inputs, either because it received tiny payments or as a result of accumulating change, consider using `send_max` to exclude inputs that are worth less than the fees needed to spend them.\n", 1300 { 1301 {"recipients", RPCArg::Type::ARR, RPCArg::Optional::NO, "The sendall destinations. Each address may only appear once.\n" 1302 "Optionally some recipients can be specified with an amount to perform payments, but at least one address must appear without a specified amount.\n", 1303 { 1304 {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "A bitcoin address which receives an equal share of the unspecified amount."}, 1305 {"", RPCArg::Type::OBJ_USER_KEYS, RPCArg::Optional::OMITTED, "", 1306 { 1307 {"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 + ""}, 1308 }, 1309 }, 1310 }, 1311 }, 1312 {"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks"}, 1313 {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n" 1314 + FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used"))}, 1315 {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."}, 1316 { 1317 "options", RPCArg::Type::OBJ_NAMED_PARAMS, RPCArg::Optional::OMITTED, "", 1318 Cat<std::vector<RPCArg>>( 1319 { 1320 {"add_to_wallet", RPCArg::Type::BOOL, RPCArg::Default{true}, "When false, returns the serialized transaction without broadcasting or adding it to the wallet"}, 1321 {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB.", RPCArgOptions{.also_positional = true}}, 1322 {"include_watching", RPCArg::Type::BOOL, RPCArg::Default{false}, "(DEPRECATED) No longer used"}, 1323 {"inputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Use exactly the specified inputs to build the transaction. Specifying inputs is incompatible with the send_max, minconf, and maxconf options.", 1324 { 1325 {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", 1326 { 1327 {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"}, 1328 {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"}, 1329 {"sequence", RPCArg::Type::NUM, RPCArg::DefaultHint{"depends on the value of the 'replaceable' and 'locktime' arguments"}, "The sequence number"}, 1330 }, 1331 }, 1332 }, 1333 }, 1334 {"locktime", RPCArg::Type::NUM, RPCArg::DefaultHint{"locktime close to block height to prevent fee sniping"}, "Raw locktime. Non-0 value also locktime-activates inputs"}, 1335 {"lock_unspents", RPCArg::Type::BOOL, RPCArg::Default{false}, "Lock selected unspent outputs"}, 1336 {"psbt", RPCArg::Type::BOOL, RPCArg::DefaultHint{"automatic"}, "Always return a PSBT, implies add_to_wallet=false."}, 1337 {"send_max", RPCArg::Type::BOOL, RPCArg::Default{false}, "When true, only use UTXOs that can pay for their own fees to maximize the output amount. When 'false' (default), no UTXO is left behind. send_max is incompatible with providing specific inputs."}, 1338 {"minconf", RPCArg::Type::NUM, RPCArg::Default{0}, "Require inputs with at least this many confirmations."}, 1339 {"maxconf", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "Require inputs with at most this many confirmations."}, 1340 {"version", RPCArg::Type::NUM, RPCArg::Default{DEFAULT_WALLET_TX_VERSION}, "Transaction version"}, 1341 }, 1342 FundTxDoc() 1343 ), 1344 RPCArgOptions{.oneline_description="options"} 1345 }, 1346 }, 1347 RPCResult{ 1348 RPCResult::Type::OBJ, "", "", 1349 { 1350 {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"}, 1351 {RPCResult::Type::STR_HEX, "txid", /*optional=*/true, "The transaction id for the send. Only 1 transaction is created regardless of the number of addresses."}, 1352 {RPCResult::Type::STR_HEX, "hex", /*optional=*/true, "If add_to_wallet is false, the hex-encoded raw transaction with signature(s)"}, 1353 {RPCResult::Type::STR, "psbt", /*optional=*/true, "If more signatures are needed, or if add_to_wallet is false, the base64-encoded (partially) signed transaction"} 1354 } 1355 }, 1356 RPCExamples{"" 1357 "\nSpend all UTXOs from the wallet with a fee rate of 1 " + CURRENCY_ATOM + "/vB using named arguments\n" 1358 + HelpExampleCli("-named sendall", "recipients='[\"" + EXAMPLE_ADDRESS[0] + "\"]' fee_rate=1\n") + 1359 "Spend all UTXOs with a fee rate of 1.1 " + CURRENCY_ATOM + "/vB using positional arguments\n" 1360 + HelpExampleCli("sendall", "'[\"" + EXAMPLE_ADDRESS[0] + "\"]' null \"unset\" 1.1\n") + 1361 "Spend all UTXOs split into equal amounts to two addresses with a fee rate of 1.5 " + CURRENCY_ATOM + "/vB using the options argument\n" 1362 + HelpExampleCli("sendall", "'[\"" + EXAMPLE_ADDRESS[0] + "\", \"" + EXAMPLE_ADDRESS[1] + "\"]' null \"unset\" null '{\"fee_rate\": 1.5}'\n") + 1363 "Leave dust UTXOs in wallet, spend only UTXOs with positive effective value with a fee rate of 10 " + CURRENCY_ATOM + "/vB using the options argument\n" 1364 + HelpExampleCli("sendall", "'[\"" + EXAMPLE_ADDRESS[0] + "\"]' null \"unset\" null '{\"fee_rate\": 10, \"send_max\": true}'\n") + 1365 "Spend all UTXOs with a fee rate of 1.3 " + CURRENCY_ATOM + "/vB using named arguments and sending a 0.25 " + CURRENCY_UNIT + " to another recipient\n" 1366 + HelpExampleCli("-named sendall", "recipients='[{\"" + EXAMPLE_ADDRESS[1] + "\": 0.25}, \""+ EXAMPLE_ADDRESS[0] + "\"]' fee_rate=1.3\n") 1367 }, 1368 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue 1369 { 1370 std::shared_ptr<CWallet> const pwallet{GetWalletForJSONRPCRequest(request)}; 1371 if (!pwallet) return UniValue::VNULL; 1372 // Make sure the results are valid at least up to the most recent block 1373 // the user could have gotten from another RPC command prior to now 1374 pwallet->BlockUntilSyncedToCurrentChain(); 1375 1376 UniValue options{request.params[4].isNull() ? UniValue::VOBJ : request.params[4]}; 1377 InterpretFeeEstimationInstructions(/*conf_target=*/request.params[1], /*estimate_mode=*/request.params[2], /*fee_rate=*/request.params[3], options); 1378 PreventOutdatedOptions(options); 1379 1380 1381 std::set<std::string> addresses_without_amount; 1382 UniValue recipient_key_value_pairs(UniValue::VARR); 1383 const UniValue& recipients{request.params[0]}; 1384 for (unsigned int i = 0; i < recipients.size(); ++i) { 1385 const UniValue& recipient{recipients[i]}; 1386 if (recipient.isStr()) { 1387 UniValue rkvp(UniValue::VOBJ); 1388 rkvp.pushKV(recipient.get_str(), 0); 1389 recipient_key_value_pairs.push_back(std::move(rkvp)); 1390 addresses_without_amount.insert(recipient.get_str()); 1391 } else { 1392 recipient_key_value_pairs.push_back(recipient); 1393 } 1394 } 1395 1396 if (addresses_without_amount.size() == 0) { 1397 throw JSONRPCError(RPC_INVALID_PARAMETER, "Must provide at least one address without a specified amount"); 1398 } 1399 1400 CCoinControl coin_control; 1401 1402 SetFeeEstimateMode(*pwallet, coin_control, options["conf_target"], options["estimate_mode"], options["fee_rate"], /*override_min_fee=*/false); 1403 1404 if (options.exists("minconf")) { 1405 if (options["minconf"].getInt<int>() < 0) 1406 { 1407 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid minconf (minconf cannot be negative): %s", options["minconf"].getInt<int>())); 1408 } 1409 1410 coin_control.m_min_depth = options["minconf"].getInt<int>(); 1411 } 1412 1413 if (options.exists("maxconf")) { 1414 coin_control.m_max_depth = options["maxconf"].getInt<int>(); 1415 1416 if (coin_control.m_max_depth < coin_control.m_min_depth) { 1417 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("maxconf can't be lower than minconf: %d < %d", coin_control.m_max_depth, coin_control.m_min_depth)); 1418 } 1419 } 1420 1421 if (options.exists("version")) { 1422 coin_control.m_version = options["version"].getInt<decltype(coin_control.m_version)>(); 1423 } 1424 1425 if (coin_control.m_version == TRUC_VERSION) { 1426 coin_control.m_max_tx_weight = TRUC_MAX_WEIGHT; 1427 } else { 1428 coin_control.m_max_tx_weight = MAX_STANDARD_TX_WEIGHT; 1429 } 1430 1431 const bool rbf{options.exists("replaceable") ? options["replaceable"].get_bool() : pwallet->m_signal_rbf}; 1432 1433 FeeCalculation fee_calc_out; 1434 CFeeRate fee_rate{GetMinimumFeeRate(*pwallet, coin_control, &fee_calc_out)}; 1435 // Do not, ever, assume that it's fine to change the fee rate if the user has explicitly 1436 // provided one 1437 if (coin_control.m_feerate && fee_rate > *coin_control.m_feerate) { 1438 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Fee rate (%s) is lower than the minimum fee rate setting (%s)", coin_control.m_feerate->ToString(FeeRateFormat::SAT_VB), fee_rate.ToString(FeeRateFormat::SAT_VB))); 1439 } 1440 if (fee_calc_out.reason == FeeReason::FALLBACK && !pwallet->m_allow_fallback_fee) { 1441 // eventually allow a fallback fee 1442 throw JSONRPCError(RPC_WALLET_ERROR, "Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee."); 1443 } 1444 1445 CMutableTransaction rawTx{ConstructTransaction(options["inputs"], recipient_key_value_pairs, options["locktime"], rbf, coin_control.m_version)}; 1446 LOCK(pwallet->cs_wallet); 1447 1448 CAmount total_input_value(0); 1449 bool send_max{options.exists("send_max") ? options["send_max"].get_bool() : false}; 1450 if (options.exists("inputs") && options.exists("send_max")) { 1451 throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot combine send_max with specific inputs."); 1452 } else if (options.exists("inputs") && (options.exists("minconf") || options.exists("maxconf"))) { 1453 throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot combine minconf or maxconf with specific inputs."); 1454 } else if (options.exists("inputs")) { 1455 for (const CTxIn& input : rawTx.vin) { 1456 if (pwallet->IsSpent(input.prevout)) { 1457 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Input not available. UTXO (%s:%d) was already spent.", input.prevout.hash.ToString(), input.prevout.n)); 1458 } 1459 const CWalletTx* tx{pwallet->GetWalletTx(input.prevout.hash)}; 1460 if (!tx || input.prevout.n >= tx->tx->vout.size() || !pwallet->IsMine(tx->tx->vout[input.prevout.n])) { 1461 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Input not found. UTXO (%s:%d) is not part of wallet.", input.prevout.hash.ToString(), input.prevout.n)); 1462 } 1463 if (pwallet->GetTxDepthInMainChain(*tx) == 0) { 1464 if (tx->tx->version == TRUC_VERSION && coin_control.m_version != TRUC_VERSION) { 1465 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Can't spend unconfirmed version 3 pre-selected input with a version %d tx", coin_control.m_version)); 1466 } else if (coin_control.m_version == TRUC_VERSION && tx->tx->version != TRUC_VERSION) { 1467 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Can't spend unconfirmed version %d pre-selected input with a version 3 tx", tx->tx->version)); 1468 } 1469 } 1470 total_input_value += tx->tx->vout[input.prevout.n].nValue; 1471 } 1472 } else { 1473 CoinFilterParams coins_params; 1474 coins_params.min_amount = 0; 1475 for (const COutput& output : AvailableCoins(*pwallet, &coin_control, fee_rate, coins_params).All()) { 1476 if (send_max && fee_rate.GetFee(output.input_bytes) > output.txout.nValue) { 1477 continue; 1478 } 1479 // we are spending an unconfirmed TRUC transaction, so lower max weight 1480 if (output.depth == 0 && coin_control.m_version == TRUC_VERSION) { 1481 coin_control.m_max_tx_weight = TRUC_CHILD_MAX_WEIGHT; 1482 } 1483 CTxIn input(output.outpoint.hash, output.outpoint.n, CScript(), rbf ? MAX_BIP125_RBF_SEQUENCE : CTxIn::SEQUENCE_FINAL); 1484 rawTx.vin.push_back(input); 1485 total_input_value += output.txout.nValue; 1486 } 1487 } 1488 1489 std::vector<COutPoint> outpoints_spent; 1490 outpoints_spent.reserve(rawTx.vin.size()); 1491 1492 for (const CTxIn& tx_in : rawTx.vin) { 1493 outpoints_spent.push_back(tx_in.prevout); 1494 } 1495 1496 // estimate final size of tx 1497 const TxSize tx_size{CalculateMaximumSignedTxSize(CTransaction(rawTx), pwallet.get())}; 1498 if (tx_size.vsize == -1) { 1499 throw JSONRPCError(RPC_WALLET_ERROR, "Unable to determine the size of the transaction, the wallet contains unsolvable descriptors"); 1500 } 1501 const CAmount fee_from_size{fee_rate.GetFee(tx_size.vsize)}; 1502 const std::optional<CAmount> total_bump_fees{pwallet->chain().calculateCombinedBumpFee(outpoints_spent, fee_rate)}; 1503 CAmount effective_value = total_input_value - fee_from_size - total_bump_fees.value_or(0); 1504 1505 if (fee_from_size > pwallet->m_default_max_tx_fee) { 1506 throw JSONRPCError(RPC_WALLET_ERROR, TransactionErrorString(TransactionError::MAX_FEE_EXCEEDED).original); 1507 } 1508 1509 if (effective_value <= 0) { 1510 if (send_max) { 1511 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Total value of UTXO pool too low to pay for transaction, try using lower feerate."); 1512 } else { 1513 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Total value of UTXO pool too low to pay for transaction. Try using lower feerate or excluding uneconomic UTXOs with 'send_max' option."); 1514 } 1515 } 1516 1517 // If this transaction is too large, e.g. because the wallet has many UTXOs, it will be rejected by the node's mempool. 1518 if (tx_size.weight > coin_control.m_max_tx_weight) { 1519 throw JSONRPCError(RPC_WALLET_ERROR, "Transaction too large."); 1520 } 1521 1522 CAmount output_amounts_claimed{0}; 1523 for (const CTxOut& out : rawTx.vout) { 1524 output_amounts_claimed += out.nValue; 1525 } 1526 1527 if (output_amounts_claimed > total_input_value) { 1528 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Assigned more value to outputs than available funds."); 1529 } 1530 1531 const CAmount remainder{effective_value - output_amounts_claimed}; 1532 if (remainder < 0) { 1533 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds for fees after creating specified outputs."); 1534 } 1535 1536 const CAmount per_output_without_amount{remainder / (long)addresses_without_amount.size()}; 1537 1538 bool gave_remaining_to_first{false}; 1539 for (CTxOut& out : rawTx.vout) { 1540 CTxDestination dest; 1541 ExtractDestination(out.scriptPubKey, dest); 1542 std::string addr{EncodeDestination(dest)}; 1543 if (addresses_without_amount.contains(addr)) { 1544 out.nValue = per_output_without_amount; 1545 if (!gave_remaining_to_first) { 1546 out.nValue += remainder % addresses_without_amount.size(); 1547 gave_remaining_to_first = true; 1548 } 1549 if (IsDust(out, pwallet->chain().relayDustFee())) { 1550 // Dynamically generated output amount is dust 1551 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Dynamically assigned remainder results in dust output."); 1552 } 1553 } else { 1554 if (IsDust(out, pwallet->chain().relayDustFee())) { 1555 // Specified output amount is dust 1556 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Specified output amount to %s is below dust threshold.", addr)); 1557 } 1558 } 1559 } 1560 1561 const bool lock_unspents{options.exists("lock_unspents") ? options["lock_unspents"].get_bool() : false}; 1562 if (lock_unspents) { 1563 for (const CTxIn& txin : rawTx.vin) { 1564 pwallet->LockCoin(txin.prevout, /*persist=*/false); 1565 } 1566 } 1567 1568 return FinishTransaction(pwallet, options, rawTx); 1569 } 1570 }; 1571 } 1572 1573 RPCHelpMan walletprocesspsbt() 1574 { 1575 return RPCHelpMan{ 1576 "walletprocesspsbt", 1577 "Update a PSBT with input information from our wallet and then sign inputs\n" 1578 "that we can sign for." + 1579 HELP_REQUIRING_PASSPHRASE, 1580 { 1581 {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction base64 string"}, 1582 {"sign", RPCArg::Type::BOOL, RPCArg::Default{true}, "Also sign the transaction when updating (requires wallet to be unlocked)"}, 1583 {"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" 1584 " \"DEFAULT\"\n" 1585 " \"ALL\"\n" 1586 " \"NONE\"\n" 1587 " \"SINGLE\"\n" 1588 " \"ALL|ANYONECANPAY\"\n" 1589 " \"NONE|ANYONECANPAY\"\n" 1590 " \"SINGLE|ANYONECANPAY\""}, 1591 {"bip32derivs", RPCArg::Type::BOOL, RPCArg::Default{true}, "Include BIP 32 derivation paths for public keys if we know them"}, 1592 {"finalize", RPCArg::Type::BOOL, RPCArg::Default{true}, "Also finalize inputs if possible"}, 1593 }, 1594 RPCResult{ 1595 RPCResult::Type::OBJ, "", "", 1596 { 1597 {RPCResult::Type::STR, "psbt", "The base64-encoded partially signed transaction"}, 1598 {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"}, 1599 {RPCResult::Type::STR_HEX, "hex", /*optional=*/true, "The hex-encoded network transaction if complete"}, 1600 } 1601 }, 1602 RPCExamples{ 1603 HelpExampleCli("walletprocesspsbt", "\"psbt\"") 1604 }, 1605 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue 1606 { 1607 const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request); 1608 if (!pwallet) return UniValue::VNULL; 1609 1610 const CWallet& wallet{*pwallet}; 1611 // Make sure the results are valid at least up to the most recent block 1612 // the user could have gotten from another RPC command prior to now 1613 wallet.BlockUntilSyncedToCurrentChain(); 1614 1615 // Unserialize the transaction 1616 PartiallySignedTransaction psbtx; 1617 std::string error; 1618 if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) { 1619 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error)); 1620 } 1621 1622 // Get the sighash type 1623 std::optional<int> nHashType = ParseSighashString(request.params[2]); 1624 1625 // Fill transaction with our data and also sign 1626 bool sign = request.params[1].isNull() ? true : request.params[1].get_bool(); 1627 bool bip32derivs = request.params[3].isNull() ? true : request.params[3].get_bool(); 1628 bool finalize = request.params[4].isNull() ? true : request.params[4].get_bool(); 1629 bool complete = true; 1630 1631 if (sign) EnsureWalletIsUnlocked(*pwallet); 1632 1633 const auto err{wallet.FillPSBT(psbtx, complete, nHashType, sign, bip32derivs, nullptr, finalize)}; 1634 if (err) { 1635 throw JSONRPCPSBTError(*err); 1636 } 1637 1638 UniValue result(UniValue::VOBJ); 1639 DataStream ssTx{}; 1640 ssTx << psbtx; 1641 result.pushKV("psbt", EncodeBase64(ssTx.str())); 1642 result.pushKV("complete", complete); 1643 if (complete) { 1644 CMutableTransaction mtx; 1645 // Returns true if complete, which we already think it is. 1646 CHECK_NONFATAL(FinalizeAndExtractPSBT(psbtx, mtx)); 1647 DataStream ssTx_final; 1648 ssTx_final << TX_WITH_WITNESS(mtx); 1649 result.pushKV("hex", HexStr(ssTx_final)); 1650 } 1651 1652 return result; 1653 }, 1654 }; 1655 } 1656 1657 RPCHelpMan walletcreatefundedpsbt() 1658 { 1659 return RPCHelpMan{ 1660 "walletcreatefundedpsbt", 1661 "Creates and funds a transaction in the Partially Signed Transaction format.\n" 1662 "Implements the Creator and Updater roles.\n" 1663 "All existing inputs must either have their previous output transaction be in the wallet\n" 1664 "or be in the UTXO set. Solving data must be provided for non-wallet inputs.\n", 1665 { 1666 {"inputs", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "Leave empty to add inputs automatically. See add_inputs option.", 1667 { 1668 {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", 1669 { 1670 {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"}, 1671 {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"}, 1672 {"sequence", RPCArg::Type::NUM, RPCArg::DefaultHint{"depends on the value of the 'locktime' and 'options.replaceable' arguments"}, "The sequence number"}, 1673 {"weight", RPCArg::Type::NUM, RPCArg::DefaultHint{"Calculated from wallet and solving data"}, "The maximum weight for this input, " 1674 "including the weight of the outpoint and sequence number. " 1675 "Note that signature sizes are not guaranteed to be consistent, " 1676 "so the maximum DER signatures size of 73 bytes should be used when considering ECDSA signatures." 1677 "Remember to convert serialized sizes to weight units when necessary."}, 1678 }, 1679 }, 1680 }, 1681 }, 1682 {"outputs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The outputs specified as key-value pairs.\n" 1683 "Each key may only appear once, i.e. there can only be one 'data' output, and no address may be duplicated.\n" 1684 "At least one output of either type must be specified.\n" 1685 "For compatibility reasons, a dictionary, which holds the key-value pairs directly, is also\n" 1686 "accepted as second parameter.", 1687 OutputsDoc(), 1688 RPCArgOptions{.skip_type_check = true}}, 1689 {"locktime", RPCArg::Type::NUM, RPCArg::Default{0}, "Raw locktime. Non-0 value also locktime-activates inputs"}, 1690 {"options", RPCArg::Type::OBJ_NAMED_PARAMS, RPCArg::Optional::OMITTED, "", 1691 Cat<std::vector<RPCArg>>( 1692 { 1693 {"add_inputs", RPCArg::Type::BOOL, RPCArg::DefaultHint{"false when \"inputs\" are specified, true otherwise"}, "Automatically include coins from the wallet to cover the target amount.\n"}, 1694 {"include_unsafe", RPCArg::Type::BOOL, RPCArg::Default{false}, "Include inputs that are not safe to spend (unconfirmed transactions from outside keys and unconfirmed replacement transactions).\n" 1695 "Warning: the resulting transaction may become invalid if one of the unsafe inputs disappears.\n" 1696 "If that happens, you will need to fund the transaction with different inputs and republish it."}, 1697 {"minconf", RPCArg::Type::NUM, RPCArg::Default{0}, "If add_inputs is specified, require inputs with at least this many confirmations."}, 1698 {"maxconf", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "If add_inputs is specified, require inputs with at most this many confirmations."}, 1699 {"changeAddress", RPCArg::Type::STR, RPCArg::DefaultHint{"automatic"}, "The bitcoin address to receive the change"}, 1700 {"changePosition", RPCArg::Type::NUM, RPCArg::DefaultHint{"random"}, "The index of the change output"}, 1701 {"change_type", RPCArg::Type::STR, RPCArg::DefaultHint{"set by -changetype"}, "The output type to use. Only valid if changeAddress is not specified. Options are " + FormatAllOutputTypes() + "."}, 1702 {"includeWatching", RPCArg::Type::BOOL, RPCArg::Default{false}, "(DEPRECATED) No longer used"}, 1703 {"lockUnspents", RPCArg::Type::BOOL, RPCArg::Default{false}, "Lock selected unspent outputs"}, 1704 {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."}, 1705 {"feeRate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_UNIT + "/kvB."}, 1706 {"subtractFeeFromOutputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "The outputs to subtract the fee from.\n" 1707 "The fee will be equally deducted from the amount of each specified output.\n" 1708 "Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n" 1709 "If no outputs are specified here, the sender pays the fee.", 1710 { 1711 {"vout_index", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The zero-based output index, before a change output is added."}, 1712 }, 1713 }, 1714 {"max_tx_weight", RPCArg::Type::NUM, RPCArg::Default{MAX_STANDARD_TX_WEIGHT}, "The maximum acceptable transaction weight.\n" 1715 "Transaction building will fail if this can not be satisfied."}, 1716 }, 1717 FundTxDoc()), 1718 RPCArgOptions{.oneline_description="options"}}, 1719 {"bip32derivs", RPCArg::Type::BOOL, RPCArg::Default{true}, "Include BIP 32 derivation paths for public keys if we know them"}, 1720 {"version", RPCArg::Type::NUM, RPCArg::Default{DEFAULT_WALLET_TX_VERSION}, "Transaction version"}, 1721 }, 1722 RPCResult{ 1723 RPCResult::Type::OBJ, "", "", 1724 { 1725 {RPCResult::Type::STR, "psbt", "The resulting raw transaction (base64-encoded string)"}, 1726 {RPCResult::Type::STR_AMOUNT, "fee", "Fee in " + CURRENCY_UNIT + " the resulting transaction pays"}, 1727 {RPCResult::Type::NUM, "changepos", "The position of the added change output, or -1"}, 1728 } 1729 }, 1730 RPCExamples{ 1731 "\nCreate a PSBT with automatically picked inputs that sends 0.5 BTC to an address and has a fee rate of 2 sat/vB:\n" 1732 + HelpExampleCli("walletcreatefundedpsbt", "\"[]\" \"[{\\\"" + EXAMPLE_ADDRESS[0] + "\\\":0.5}]\" 0 \"{\\\"add_inputs\\\":true,\\\"fee_rate\\\":2}\"") 1733 + "\nCreate the same PSBT as the above one instead using named arguments:\n" 1734 + HelpExampleCli("-named walletcreatefundedpsbt", "outputs=\"[{\\\"" + EXAMPLE_ADDRESS[0] + "\\\":0.5}]\" add_inputs=true fee_rate=2") 1735 }, 1736 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue 1737 { 1738 std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request); 1739 if (!pwallet) return UniValue::VNULL; 1740 1741 CWallet& wallet{*pwallet}; 1742 // Make sure the results are valid at least up to the most recent block 1743 // the user could have gotten from another RPC command prior to now 1744 wallet.BlockUntilSyncedToCurrentChain(); 1745 1746 UniValue options{request.params[3].isNull() ? UniValue::VOBJ : request.params[3]}; 1747 1748 CCoinControl coin_control; 1749 coin_control.m_version = self.Arg<uint32_t>("version"); 1750 1751 const UniValue &replaceable_arg = options["replaceable"]; 1752 const bool rbf{replaceable_arg.isNull() ? wallet.m_signal_rbf : replaceable_arg.get_bool()}; 1753 CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf, coin_control.m_version); 1754 UniValue outputs(UniValue::VOBJ); 1755 outputs = NormalizeOutputs(request.params[1]); 1756 std::vector<CRecipient> recipients = CreateRecipients( 1757 ParseOutputs(outputs), 1758 InterpretSubtractFeeFromOutputInstructions(options["subtractFeeFromOutputs"], outputs.getKeys()) 1759 ); 1760 // Automatically select coins, unless at least one is manually selected. Can 1761 // be overridden by options.add_inputs. 1762 coin_control.m_allow_other_inputs = rawTx.vin.size() == 0; 1763 SetOptionsInputWeights(request.params[0], options); 1764 // Clear tx.vout since it is not meant to be used now that we are passing outputs directly. 1765 // This sets us up for a future PR to completely remove tx from the function signature in favor of passing inputs directly 1766 rawTx.vout.clear(); 1767 auto txr = FundTransaction(wallet, rawTx, recipients, options, coin_control, /*override_min_fee=*/true); 1768 1769 // Make a blank psbt 1770 PartiallySignedTransaction psbtx(CMutableTransaction(*txr.tx)); 1771 1772 // Fill transaction with out data but don't sign 1773 bool bip32derivs = request.params[4].isNull() ? true : request.params[4].get_bool(); 1774 bool complete = true; 1775 const auto err{wallet.FillPSBT(psbtx, complete, std::nullopt, /*sign=*/false, /*bip32derivs=*/bip32derivs)}; 1776 if (err) { 1777 throw JSONRPCPSBTError(*err); 1778 } 1779 1780 // Serialize the PSBT 1781 DataStream ssTx{}; 1782 ssTx << psbtx; 1783 1784 UniValue result(UniValue::VOBJ); 1785 result.pushKV("psbt", EncodeBase64(ssTx.str())); 1786 result.pushKV("fee", ValueFromAmount(txr.fee)); 1787 result.pushKV("changepos", txr.change_pos ? (int)*txr.change_pos : -1); 1788 return result; 1789 }, 1790 }; 1791 } 1792 } // namespace wallet