spend.cpp
1 // Copyright (c) 2011-2022 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 RPCHelpMan settxfee() 431 { 432 return RPCHelpMan{ 433 "settxfee", 434 "(DEPRECATED) Set the transaction fee rate in " + CURRENCY_UNIT + "/kvB for this wallet. Overrides the global -paytxfee command line parameter.\n" 435 "Can be deactivated by passing 0 as the fee. In that case automatic fee selection will be used by default.\n", 436 { 437 {"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "The transaction fee rate in " + CURRENCY_UNIT + "/kvB"}, 438 }, 439 RPCResult{ 440 RPCResult::Type::BOOL, "", "Returns true if successful" 441 }, 442 RPCExamples{ 443 HelpExampleCli("settxfee", "0.00001") 444 + HelpExampleRpc("settxfee", "0.00001") 445 }, 446 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue 447 { 448 std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request); 449 if (!pwallet) return UniValue::VNULL; 450 451 LOCK(pwallet->cs_wallet); 452 453 if (!pwallet->chain().rpcEnableDeprecated("settxfee")) { 454 throw JSONRPCError(RPC_METHOD_DEPRECATED, "settxfee is deprecated and will be fully removed in v31.0." 455 "\nTo use settxfee restart bitcoind with -deprecatedrpc=settxfee."); 456 } 457 458 CAmount nAmount = AmountFromValue(request.params[0]); 459 CFeeRate tx_fee_rate(nAmount, 1000); 460 CFeeRate max_tx_fee_rate(pwallet->m_default_max_tx_fee, 1000); 461 if (tx_fee_rate == CFeeRate(0)) { 462 // automatic selection 463 } else if (tx_fee_rate < pwallet->chain().relayMinFee()) { 464 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("txfee cannot be less than min relay tx fee (%s)", pwallet->chain().relayMinFee().ToString())); 465 } else if (tx_fee_rate < pwallet->m_min_fee) { 466 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("txfee cannot be less than wallet min fee (%s)", pwallet->m_min_fee.ToString())); 467 } else if (tx_fee_rate > max_tx_fee_rate) { 468 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("txfee cannot be more than wallet max tx fee (%s)", max_tx_fee_rate.ToString())); 469 } 470 471 pwallet->m_pay_tx_fee = tx_fee_rate; 472 return true; 473 }, 474 }; 475 } 476 477 478 // Only includes key documentation where the key is snake_case in all RPC methods. MixedCase keys can be added later. 479 static std::vector<RPCArg> FundTxDoc(bool solving_data = true) 480 { 481 std::vector<RPCArg> args = { 482 {"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks", RPCArgOptions{.also_positional = true}}, 483 {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n" 484 + FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used")), RPCArgOptions{.also_positional = true}}, 485 { 486 "replaceable", RPCArg::Type::BOOL, RPCArg::DefaultHint{"wallet default"}, "Marks this transaction as BIP125-replaceable.\n" 487 "Allows this transaction to be replaced by a transaction with higher fees" 488 }, 489 }; 490 if (solving_data) { 491 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" 492 "Used for fee estimation during coin selection.", 493 { 494 { 495 "pubkeys", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Public keys involved in this transaction.", 496 { 497 {"pubkey", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "A public key"}, 498 } 499 }, 500 { 501 "scripts", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Scripts involved in this transaction.", 502 { 503 {"script", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "A script"}, 504 } 505 }, 506 { 507 "descriptors", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Descriptors that provide solving data for this transaction.", 508 { 509 {"descriptor", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "A descriptor"}, 510 } 511 }, 512 } 513 }); 514 } 515 return args; 516 } 517 518 CreatedTransactionResult FundTransaction(CWallet& wallet, const CMutableTransaction& tx, const std::vector<CRecipient>& recipients, const UniValue& options, CCoinControl& coinControl, bool override_min_fee) 519 { 520 // We want to make sure tx.vout is not used now that we are passing outputs as a vector of recipients. 521 // This sets us up to remove tx completely in a future PR in favor of passing the inputs directly. 522 CHECK_NONFATAL(tx.vout.empty()); 523 // Make sure the results are valid at least up to the most recent block 524 // the user could have gotten from another RPC command prior to now 525 wallet.BlockUntilSyncedToCurrentChain(); 526 527 std::optional<unsigned int> change_position; 528 bool lockUnspents = false; 529 if (!options.isNull()) { 530 if (options.type() == UniValue::VBOOL) { 531 // backward compatibility bool only fallback, does nothing 532 } else { 533 RPCTypeCheckObj(options, 534 { 535 {"add_inputs", UniValueType(UniValue::VBOOL)}, 536 {"include_unsafe", UniValueType(UniValue::VBOOL)}, 537 {"add_to_wallet", UniValueType(UniValue::VBOOL)}, 538 {"changeAddress", UniValueType(UniValue::VSTR)}, 539 {"change_address", UniValueType(UniValue::VSTR)}, 540 {"changePosition", UniValueType(UniValue::VNUM)}, 541 {"change_position", UniValueType(UniValue::VNUM)}, 542 {"change_type", UniValueType(UniValue::VSTR)}, 543 {"includeWatching", UniValueType(UniValue::VBOOL)}, 544 {"include_watching", UniValueType(UniValue::VBOOL)}, 545 {"inputs", UniValueType(UniValue::VARR)}, 546 {"lockUnspents", UniValueType(UniValue::VBOOL)}, 547 {"lock_unspents", UniValueType(UniValue::VBOOL)}, 548 {"locktime", UniValueType(UniValue::VNUM)}, 549 {"fee_rate", UniValueType()}, // will be checked by AmountFromValue() in SetFeeEstimateMode() 550 {"feeRate", UniValueType()}, // will be checked by AmountFromValue() below 551 {"psbt", UniValueType(UniValue::VBOOL)}, 552 {"solving_data", UniValueType(UniValue::VOBJ)}, 553 {"subtractFeeFromOutputs", UniValueType(UniValue::VARR)}, 554 {"subtract_fee_from_outputs", UniValueType(UniValue::VARR)}, 555 {"replaceable", UniValueType(UniValue::VBOOL)}, 556 {"conf_target", UniValueType(UniValue::VNUM)}, 557 {"estimate_mode", UniValueType(UniValue::VSTR)}, 558 {"minconf", UniValueType(UniValue::VNUM)}, 559 {"maxconf", UniValueType(UniValue::VNUM)}, 560 {"input_weights", UniValueType(UniValue::VARR)}, 561 {"max_tx_weight", UniValueType(UniValue::VNUM)}, 562 }, 563 true, true); 564 565 if (options.exists("add_inputs")) { 566 coinControl.m_allow_other_inputs = options["add_inputs"].get_bool(); 567 } 568 569 if (options.exists("changeAddress") || options.exists("change_address")) { 570 const std::string change_address_str = (options.exists("change_address") ? options["change_address"] : options["changeAddress"]).get_str(); 571 CTxDestination dest = DecodeDestination(change_address_str); 572 573 if (!IsValidDestination(dest)) { 574 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Change address must be a valid bitcoin address"); 575 } 576 577 coinControl.destChange = dest; 578 } 579 580 if (options.exists("changePosition") || options.exists("change_position")) { 581 int pos = (options.exists("change_position") ? options["change_position"] : options["changePosition"]).getInt<int>(); 582 if (pos < 0 || (unsigned int)pos > recipients.size()) { 583 throw JSONRPCError(RPC_INVALID_PARAMETER, "changePosition out of bounds"); 584 } 585 change_position = (unsigned int)pos; 586 } 587 588 if (options.exists("change_type")) { 589 if (options.exists("changeAddress") || options.exists("change_address")) { 590 throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both change address and address type options"); 591 } 592 if (std::optional<OutputType> parsed = ParseOutputType(options["change_type"].get_str())) { 593 coinControl.m_change_type.emplace(parsed.value()); 594 } else { 595 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown change type '%s'", options["change_type"].get_str())); 596 } 597 } 598 599 if (options.exists("lockUnspents") || options.exists("lock_unspents")) { 600 lockUnspents = (options.exists("lock_unspents") ? options["lock_unspents"] : options["lockUnspents"]).get_bool(); 601 } 602 603 if (options.exists("include_unsafe")) { 604 coinControl.m_include_unsafe_inputs = options["include_unsafe"].get_bool(); 605 } 606 607 if (options.exists("feeRate")) { 608 if (options.exists("fee_rate")) { 609 throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both fee_rate (" + CURRENCY_ATOM + "/vB) and feeRate (" + CURRENCY_UNIT + "/kvB)"); 610 } 611 if (options.exists("conf_target")) { 612 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."); 613 } 614 if (options.exists("estimate_mode")) { 615 throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both estimate_mode and feeRate"); 616 } 617 coinControl.m_feerate = CFeeRate(AmountFromValue(options["feeRate"])); 618 coinControl.fOverrideFeeRate = true; 619 } 620 621 if (options.exists("replaceable")) { 622 coinControl.m_signal_bip125_rbf = options["replaceable"].get_bool(); 623 } 624 625 if (options.exists("minconf")) { 626 coinControl.m_min_depth = options["minconf"].getInt<int>(); 627 628 if (coinControl.m_min_depth < 0) { 629 throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative minconf"); 630 } 631 } 632 633 if (options.exists("maxconf")) { 634 coinControl.m_max_depth = options["maxconf"].getInt<int>(); 635 636 if (coinControl.m_max_depth < coinControl.m_min_depth) { 637 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("maxconf can't be lower than minconf: %d < %d", coinControl.m_max_depth, coinControl.m_min_depth)); 638 } 639 } 640 SetFeeEstimateMode(wallet, coinControl, options["conf_target"], options["estimate_mode"], options["fee_rate"], override_min_fee); 641 } 642 } 643 644 if (options.exists("solving_data")) { 645 const UniValue solving_data = options["solving_data"].get_obj(); 646 if (solving_data.exists("pubkeys")) { 647 for (const UniValue& pk_univ : solving_data["pubkeys"].get_array().getValues()) { 648 const CPubKey pubkey = HexToPubKey(pk_univ.get_str()); 649 coinControl.m_external_provider.pubkeys.emplace(pubkey.GetID(), pubkey); 650 // Add witness script for pubkeys 651 const CScript wit_script = GetScriptForDestination(WitnessV0KeyHash(pubkey)); 652 coinControl.m_external_provider.scripts.emplace(CScriptID(wit_script), wit_script); 653 } 654 } 655 656 if (solving_data.exists("scripts")) { 657 for (const UniValue& script_univ : solving_data["scripts"].get_array().getValues()) { 658 const std::string& script_str = script_univ.get_str(); 659 if (!IsHex(script_str)) { 660 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("'%s' is not hex", script_str)); 661 } 662 std::vector<unsigned char> script_data(ParseHex(script_str)); 663 const CScript script(script_data.begin(), script_data.end()); 664 coinControl.m_external_provider.scripts.emplace(CScriptID(script), script); 665 } 666 } 667 668 if (solving_data.exists("descriptors")) { 669 for (const UniValue& desc_univ : solving_data["descriptors"].get_array().getValues()) { 670 const std::string& desc_str = desc_univ.get_str(); 671 FlatSigningProvider desc_out; 672 std::string error; 673 std::vector<CScript> scripts_temp; 674 auto descs = Parse(desc_str, desc_out, error, true); 675 if (descs.empty()) { 676 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Unable to parse descriptor '%s': %s", desc_str, error)); 677 } 678 for (auto& desc : descs) { 679 desc->Expand(0, desc_out, scripts_temp, desc_out); 680 } 681 coinControl.m_external_provider.Merge(std::move(desc_out)); 682 } 683 } 684 } 685 686 if (options.exists("input_weights")) { 687 for (const UniValue& input : options["input_weights"].get_array().getValues()) { 688 Txid txid = Txid::FromUint256(ParseHashO(input, "txid")); 689 690 const UniValue& vout_v = input.find_value("vout"); 691 if (!vout_v.isNum()) { 692 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key"); 693 } 694 int vout = vout_v.getInt<int>(); 695 if (vout < 0) { 696 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout cannot be negative"); 697 } 698 699 const UniValue& weight_v = input.find_value("weight"); 700 if (!weight_v.isNum()) { 701 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing weight key"); 702 } 703 int64_t weight = weight_v.getInt<int64_t>(); 704 const int64_t min_input_weight = GetTransactionInputWeight(CTxIn()); 705 CHECK_NONFATAL(min_input_weight == 165); 706 if (weight < min_input_weight) { 707 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)"); 708 } 709 if (weight > MAX_STANDARD_TX_WEIGHT) { 710 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, weight cannot be greater than the maximum standard tx weight of %d", MAX_STANDARD_TX_WEIGHT)); 711 } 712 713 coinControl.SetInputWeight(COutPoint(txid, vout), weight); 714 } 715 } 716 717 if (options.exists("max_tx_weight")) { 718 coinControl.m_max_tx_weight = options["max_tx_weight"].getInt<int>(); 719 } 720 721 if (tx.version == TRUC_VERSION) { 722 if (!coinControl.m_max_tx_weight.has_value() || coinControl.m_max_tx_weight.value() > TRUC_MAX_WEIGHT) { 723 coinControl.m_max_tx_weight = TRUC_MAX_WEIGHT; 724 } 725 } 726 727 if (recipients.empty()) 728 throw JSONRPCError(RPC_INVALID_PARAMETER, "TX must have at least one output"); 729 730 auto txr = FundTransaction(wallet, tx, recipients, change_position, lockUnspents, coinControl); 731 if (!txr) { 732 throw JSONRPCError(RPC_WALLET_ERROR, ErrorString(txr).original); 733 } 734 return *txr; 735 } 736 737 static void SetOptionsInputWeights(const UniValue& inputs, UniValue& options) 738 { 739 if (options.exists("input_weights")) { 740 throw JSONRPCError(RPC_INVALID_PARAMETER, "Input weights should be specified in inputs rather than in options."); 741 } 742 if (inputs.size() == 0) { 743 return; 744 } 745 UniValue weights(UniValue::VARR); 746 for (const UniValue& input : inputs.getValues()) { 747 if (input.exists("weight")) { 748 weights.push_back(input); 749 } 750 } 751 options.pushKV("input_weights", std::move(weights)); 752 } 753 754 RPCHelpMan fundrawtransaction() 755 { 756 return RPCHelpMan{ 757 "fundrawtransaction", 758 "If the transaction has no inputs, they will be automatically selected to meet its out value.\n" 759 "It will add at most one change output to the outputs.\n" 760 "No existing outputs will be modified unless \"subtractFeeFromOutputs\" is specified.\n" 761 "Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n" 762 "The inputs added will not be signed, use signrawtransactionwithkey\n" 763 "or signrawtransactionwithwallet for that.\n" 764 "All existing inputs must either have their previous output transaction be in the wallet\n" 765 "or be in the UTXO set. Solving data must be provided for non-wallet inputs.\n" 766 "Note that all inputs selected must be of standard form and P2SH scripts must be\n" 767 "in the wallet using importdescriptors (to calculate fees).\n" 768 "You can see whether this is the case by checking the \"solvable\" field in the listunspent output.\n" 769 "Note that if specifying an exact fee rate, the resulting transaction may have a higher fee rate\n" 770 "if the transaction has unconfirmed inputs. This is because the wallet will attempt to make the\n" 771 "entire package have the given fee rate, not the resulting transaction.\n", 772 { 773 {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of the raw transaction"}, 774 {"options", RPCArg::Type::OBJ_NAMED_PARAMS, RPCArg::Optional::OMITTED, "", 775 Cat<std::vector<RPCArg>>( 776 { 777 {"add_inputs", RPCArg::Type::BOOL, RPCArg::Default{true}, "For a transaction with existing inputs, automatically include more if they are not enough."}, 778 {"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" 779 "Warning: the resulting transaction may become invalid if one of the unsafe inputs disappears.\n" 780 "If that happens, you will need to fund the transaction with different inputs and republish it."}, 781 {"minconf", RPCArg::Type::NUM, RPCArg::Default{0}, "If add_inputs is specified, require inputs with at least this many confirmations."}, 782 {"maxconf", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "If add_inputs is specified, require inputs with at most this many confirmations."}, 783 {"changeAddress", RPCArg::Type::STR, RPCArg::DefaultHint{"automatic"}, "The bitcoin address to receive the change"}, 784 {"changePosition", RPCArg::Type::NUM, RPCArg::DefaultHint{"random"}, "The index of the change output"}, 785 {"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() + "."}, 786 {"includeWatching", RPCArg::Type::BOOL, RPCArg::Default{false}, "(DEPRECATED) No longer used"}, 787 {"lockUnspents", RPCArg::Type::BOOL, RPCArg::Default{false}, "Lock selected unspent outputs"}, 788 {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."}, 789 {"feeRate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_UNIT + "/kvB."}, 790 {"subtractFeeFromOutputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "The integers.\n" 791 "The fee will be equally deducted from the amount of each specified output.\n" 792 "Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n" 793 "If no outputs are specified here, the sender pays the fee.", 794 { 795 {"vout_index", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The zero-based output index, before a change output is added."}, 796 }, 797 }, 798 {"input_weights", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "Inputs and their corresponding weights", 799 { 800 {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", 801 { 802 {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"}, 803 {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output index"}, 804 {"weight", RPCArg::Type::NUM, RPCArg::Optional::NO, "The maximum weight for this input, " 805 "including the weight of the outpoint and sequence number. " 806 "Note that serialized signature sizes are not guaranteed to be consistent, " 807 "so the maximum DER signatures size of 73 bytes should be used when considering ECDSA signatures." 808 "Remember to convert serialized sizes to weight units when necessary."}, 809 }, 810 }, 811 }, 812 }, 813 {"max_tx_weight", RPCArg::Type::NUM, RPCArg::Default{MAX_STANDARD_TX_WEIGHT}, "The maximum acceptable transaction weight.\n" 814 "Transaction building will fail if this can not be satisfied."}, 815 }, 816 FundTxDoc()), 817 RPCArgOptions{ 818 .skip_type_check = true, 819 .oneline_description = "options", 820 }}, 821 {"iswitness", RPCArg::Type::BOOL, RPCArg::DefaultHint{"depends on heuristic tests"}, "Whether the transaction hex is a serialized witness transaction.\n" 822 "If iswitness is not present, heuristic tests will be used in decoding.\n" 823 "If true, only witness deserialization will be tried.\n" 824 "If false, only non-witness deserialization will be tried.\n" 825 "This boolean should reflect whether the transaction has inputs\n" 826 "(e.g. fully valid, or on-chain transactions), if known by the caller." 827 }, 828 }, 829 RPCResult{ 830 RPCResult::Type::OBJ, "", "", 831 { 832 {RPCResult::Type::STR_HEX, "hex", "The resulting raw transaction (hex-encoded string)"}, 833 {RPCResult::Type::STR_AMOUNT, "fee", "Fee in " + CURRENCY_UNIT + " the resulting transaction pays"}, 834 {RPCResult::Type::NUM, "changepos", "The position of the added change output, or -1"}, 835 } 836 }, 837 RPCExamples{ 838 "\nCreate a transaction with no inputs\n" 839 + HelpExampleCli("createrawtransaction", "\"[]\" \"{\\\"myaddress\\\":0.01}\"") + 840 "\nAdd sufficient unsigned inputs to meet the output value\n" 841 + HelpExampleCli("fundrawtransaction", "\"rawtransactionhex\"") + 842 "\nSign the transaction\n" 843 + HelpExampleCli("signrawtransactionwithwallet", "\"fundedtransactionhex\"") + 844 "\nSend the transaction\n" 845 + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"") 846 }, 847 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue 848 { 849 std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request); 850 if (!pwallet) return UniValue::VNULL; 851 852 // parse hex string from parameter 853 CMutableTransaction tx; 854 bool try_witness = request.params[2].isNull() ? true : request.params[2].get_bool(); 855 bool try_no_witness = request.params[2].isNull() ? true : !request.params[2].get_bool(); 856 if (!DecodeHexTx(tx, request.params[0].get_str(), try_no_witness, try_witness)) { 857 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); 858 } 859 UniValue options = request.params[1]; 860 std::vector<std::pair<CTxDestination, CAmount>> destinations; 861 for (const auto& tx_out : tx.vout) { 862 CTxDestination dest; 863 ExtractDestination(tx_out.scriptPubKey, dest); 864 destinations.emplace_back(dest, tx_out.nValue); 865 } 866 std::vector<std::string> dummy(destinations.size(), "dummy"); 867 std::vector<CRecipient> recipients = CreateRecipients( 868 destinations, 869 InterpretSubtractFeeFromOutputInstructions(options["subtractFeeFromOutputs"], dummy) 870 ); 871 CCoinControl coin_control; 872 // Automatically select (additional) coins. Can be overridden by options.add_inputs. 873 coin_control.m_allow_other_inputs = true; 874 // Clear tx.vout since it is not meant to be used now that we are passing outputs directly. 875 // This sets us up for a future PR to completely remove tx from the function signature in favor of passing inputs directly 876 tx.vout.clear(); 877 auto txr = FundTransaction(*pwallet, tx, recipients, options, coin_control, /*override_min_fee=*/true); 878 879 UniValue result(UniValue::VOBJ); 880 result.pushKV("hex", EncodeHexTx(*txr.tx)); 881 result.pushKV("fee", ValueFromAmount(txr.fee)); 882 result.pushKV("changepos", txr.change_pos ? (int)*txr.change_pos : -1); 883 884 return result; 885 }, 886 }; 887 } 888 889 RPCHelpMan signrawtransactionwithwallet() 890 { 891 return RPCHelpMan{ 892 "signrawtransactionwithwallet", 893 "Sign inputs for raw transaction (serialized, hex-encoded).\n" 894 "The second optional argument (may be null) is an array of previous transaction outputs that\n" 895 "this transaction depends on but may not yet be in the block chain." + 896 HELP_REQUIRING_PASSPHRASE, 897 { 898 {"hexstring", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction hex string"}, 899 {"prevtxs", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "The previous dependent transaction outputs", 900 { 901 {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", 902 { 903 {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"}, 904 {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"}, 905 {"scriptPubKey", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The output script"}, 906 {"redeemScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2SH) redeem script"}, 907 {"witnessScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2WSH or P2SH-P2WSH) witness script"}, 908 {"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::OMITTED, "(required for Segwit inputs) the amount spent"}, 909 }, 910 }, 911 }, 912 }, 913 {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"DEFAULT for Taproot, ALL otherwise"}, "The signature hash type. Must be one of\n" 914 " \"DEFAULT\"\n" 915 " \"ALL\"\n" 916 " \"NONE\"\n" 917 " \"SINGLE\"\n" 918 " \"ALL|ANYONECANPAY\"\n" 919 " \"NONE|ANYONECANPAY\"\n" 920 " \"SINGLE|ANYONECANPAY\""}, 921 }, 922 RPCResult{ 923 RPCResult::Type::OBJ, "", "", 924 { 925 {RPCResult::Type::STR_HEX, "hex", "The hex-encoded raw transaction with signature(s)"}, 926 {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"}, 927 {RPCResult::Type::ARR, "errors", /*optional=*/true, "Script verification errors (if there are any)", 928 { 929 {RPCResult::Type::OBJ, "", "", 930 { 931 {RPCResult::Type::STR_HEX, "txid", "The hash of the referenced, previous transaction"}, 932 {RPCResult::Type::NUM, "vout", "The index of the output to spent and used as input"}, 933 {RPCResult::Type::ARR, "witness", "", 934 { 935 {RPCResult::Type::STR_HEX, "witness", ""}, 936 }}, 937 {RPCResult::Type::STR_HEX, "scriptSig", "The hex-encoded signature script"}, 938 {RPCResult::Type::NUM, "sequence", "Script sequence number"}, 939 {RPCResult::Type::STR, "error", "Verification or signing error related to the input"}, 940 }}, 941 }}, 942 } 943 }, 944 RPCExamples{ 945 HelpExampleCli("signrawtransactionwithwallet", "\"myhex\"") 946 + HelpExampleRpc("signrawtransactionwithwallet", "\"myhex\"") 947 }, 948 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue 949 { 950 const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request); 951 if (!pwallet) return UniValue::VNULL; 952 953 CMutableTransaction mtx; 954 if (!DecodeHexTx(mtx, request.params[0].get_str())) { 955 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input."); 956 } 957 958 // Sign the transaction 959 LOCK(pwallet->cs_wallet); 960 EnsureWalletIsUnlocked(*pwallet); 961 962 // Fetch previous transactions (inputs): 963 std::map<COutPoint, Coin> coins; 964 for (const CTxIn& txin : mtx.vin) { 965 coins[txin.prevout]; // Create empty map entry keyed by prevout. 966 } 967 pwallet->chain().findCoins(coins); 968 969 // Parse the prevtxs array 970 ParsePrevouts(request.params[1], nullptr, coins); 971 972 std::optional<int> nHashType = ParseSighashString(request.params[2]); 973 if (!nHashType) { 974 nHashType = SIGHASH_DEFAULT; 975 } 976 977 // Script verification errors 978 std::map<int, bilingual_str> input_errors; 979 980 bool complete = pwallet->SignTransaction(mtx, coins, *nHashType, input_errors); 981 UniValue result(UniValue::VOBJ); 982 SignTransactionResultToJSON(mtx, complete, coins, input_errors, result); 983 return result; 984 }, 985 }; 986 } 987 988 // Definition of allowed formats of specifying transaction outputs in 989 // `bumpfee`, `psbtbumpfee`, `send` and `walletcreatefundedpsbt` RPCs. 990 static std::vector<RPCArg> OutputsDoc() 991 { 992 return 993 { 994 {"", RPCArg::Type::OBJ_USER_KEYS, RPCArg::Optional::OMITTED, "", 995 { 996 {"address", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "A key-value pair. The key (string) is the bitcoin address,\n" 997 "the value (float or string) is the amount in " + CURRENCY_UNIT + ""}, 998 }, 999 }, 1000 {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", 1001 { 1002 {"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"}, 1003 }, 1004 }, 1005 }; 1006 } 1007 1008 static RPCHelpMan bumpfee_helper(std::string method_name) 1009 { 1010 const bool want_psbt = method_name == "psbtbumpfee"; 1011 const std::string incremental_fee{CFeeRate(DEFAULT_INCREMENTAL_RELAY_FEE).ToString(FeeEstimateMode::SAT_VB)}; 1012 1013 return RPCHelpMan{method_name, 1014 "Bumps the fee of a transaction T, replacing it with a new transaction B.\n" 1015 + std::string(want_psbt ? "Returns a PSBT instead of creating and signing a new transaction.\n" : "") + 1016 "A transaction with the given txid must be in the wallet.\n" 1017 "The command will pay the additional fee by reducing change outputs or adding inputs when necessary.\n" 1018 "It may add a new change output if one does not already exist.\n" 1019 "All inputs in the original transaction will be included in the replacement transaction.\n" 1020 "The command will fail if the wallet or mempool contains a transaction that spends one of T's outputs.\n" 1021 "By default, the new fee will be calculated automatically using the estimatesmartfee RPC.\n" 1022 "The user can specify a confirmation target for estimatesmartfee.\n" 1023 "Alternatively, the user can specify a fee rate in " + CURRENCY_ATOM + "/vB for the new transaction.\n" 1024 "At a minimum, the new fee rate must be high enough to pay an additional new relay fee (incrementalfee\n" 1025 "returned by getnetworkinfo) to enter the node's mempool.\n" 1026 "* WARNING: before version 0.21, fee_rate was in " + CURRENCY_UNIT + "/kvB. As of 0.21, fee_rate is in " + CURRENCY_ATOM + "/vB. *\n", 1027 { 1028 {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The txid to be bumped"}, 1029 {"options", RPCArg::Type::OBJ_NAMED_PARAMS, RPCArg::Optional::OMITTED, "", 1030 { 1031 {"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks\n"}, 1032 {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, 1033 "\nSpecify a fee rate in " + CURRENCY_ATOM + "/vB instead of relying on the built-in fee estimator.\n" 1034 "Must be at least " + incremental_fee + " higher than the current transaction fee rate.\n" 1035 "WARNING: before version 0.21, fee_rate was in " + CURRENCY_UNIT + "/kvB. As of 0.21, fee_rate is in " + CURRENCY_ATOM + "/vB.\n"}, 1036 {"replaceable", RPCArg::Type::BOOL, RPCArg::Default{true}, 1037 "Whether the new transaction should be\n" 1038 "marked bip-125 replaceable. If true, the sequence numbers in the transaction will\n" 1039 "be set to 0xfffffffd. If false, any input sequence numbers in the\n" 1040 "transaction will be set to 0xfffffffe\n" 1041 "so the new transaction will not be explicitly bip-125 replaceable (though it may\n" 1042 "still be replaceable in practice, for example if it has unconfirmed ancestors which\n" 1043 "are replaceable).\n"}, 1044 {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n" 1045 + FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used"))}, 1046 {"outputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "The outputs specified as key-value pairs.\n" 1047 "Each key may only appear once, i.e. there can only be one 'data' output, and no address may be duplicated.\n" 1048 "At least one output of either type must be specified.\n" 1049 "Cannot be provided if 'original_change_index' is specified.", 1050 OutputsDoc(), 1051 RPCArgOptions{.skip_type_check = true}}, 1052 {"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. " 1053 "The indicated output will be recycled into the new change output on the bumped transaction. " 1054 "The remainder after paying the recipients and fees will be sent to the output script of the " 1055 "original change output. The change output’s amount can increase if bumping the transaction " 1056 "adds new inputs, otherwise it will decrease. Cannot be used in combination with the 'outputs' option."}, 1057 }, 1058 RPCArgOptions{.oneline_description="options"}}, 1059 }, 1060 RPCResult{ 1061 RPCResult::Type::OBJ, "", "", Cat( 1062 want_psbt ? 1063 std::vector<RPCResult>{{RPCResult::Type::STR, "psbt", "The base64-encoded unsigned PSBT of the new transaction."}} : 1064 std::vector<RPCResult>{{RPCResult::Type::STR_HEX, "txid", "The id of the new transaction."}}, 1065 { 1066 {RPCResult::Type::STR_AMOUNT, "origfee", "The fee of the replaced transaction."}, 1067 {RPCResult::Type::STR_AMOUNT, "fee", "The fee of the new transaction."}, 1068 {RPCResult::Type::ARR, "errors", "Errors encountered during processing (may be empty).", 1069 { 1070 {RPCResult::Type::STR, "", ""}, 1071 }}, 1072 }) 1073 }, 1074 RPCExamples{ 1075 "\nBump the fee, get the new transaction\'s " + std::string(want_psbt ? "psbt" : "txid") + "\n" + 1076 HelpExampleCli(method_name, "<txid>") 1077 }, 1078 [want_psbt](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue 1079 { 1080 std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request); 1081 if (!pwallet) return UniValue::VNULL; 1082 1083 if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && !pwallet->IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER) && !want_psbt) { 1084 throw JSONRPCError(RPC_WALLET_ERROR, "bumpfee is not available with wallets that have private keys disabled. Use psbtbumpfee instead."); 1085 } 1086 1087 Txid hash{Txid::FromUint256(ParseHashV(request.params[0], "txid"))}; 1088 1089 CCoinControl coin_control; 1090 // optional parameters 1091 coin_control.m_signal_bip125_rbf = true; 1092 std::vector<CTxOut> outputs; 1093 1094 std::optional<uint32_t> original_change_index; 1095 1096 if (!request.params[1].isNull()) { 1097 UniValue options = request.params[1]; 1098 RPCTypeCheckObj(options, 1099 { 1100 {"confTarget", UniValueType(UniValue::VNUM)}, 1101 {"conf_target", UniValueType(UniValue::VNUM)}, 1102 {"fee_rate", UniValueType()}, // will be checked by AmountFromValue() in SetFeeEstimateMode() 1103 {"replaceable", UniValueType(UniValue::VBOOL)}, 1104 {"estimate_mode", UniValueType(UniValue::VSTR)}, 1105 {"outputs", UniValueType()}, // will be checked by AddOutputs() 1106 {"original_change_index", UniValueType(UniValue::VNUM)}, 1107 }, 1108 true, true); 1109 1110 if (options.exists("confTarget") && options.exists("conf_target")) { 1111 throw JSONRPCError(RPC_INVALID_PARAMETER, "confTarget and conf_target options should not both be set. Use conf_target (confTarget is deprecated)."); 1112 } 1113 1114 auto conf_target = options.exists("confTarget") ? options["confTarget"] : options["conf_target"]; 1115 1116 if (options.exists("replaceable")) { 1117 coin_control.m_signal_bip125_rbf = options["replaceable"].get_bool(); 1118 } 1119 SetFeeEstimateMode(*pwallet, coin_control, conf_target, options["estimate_mode"], options["fee_rate"], /*override_min_fee=*/false); 1120 1121 // Prepare new outputs by creating a temporary tx and calling AddOutputs(). 1122 if (!options["outputs"].isNull()) { 1123 if (options["outputs"].isArray() && options["outputs"].empty()) { 1124 throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, output argument cannot be an empty array"); 1125 } 1126 CMutableTransaction tempTx; 1127 AddOutputs(tempTx, options["outputs"]); 1128 outputs = tempTx.vout; 1129 } 1130 1131 if (options.exists("original_change_index")) { 1132 original_change_index = options["original_change_index"].getInt<uint32_t>(); 1133 } 1134 } 1135 1136 // Make sure the results are valid at least up to the most recent block 1137 // the user could have gotten from another RPC command prior to now 1138 pwallet->BlockUntilSyncedToCurrentChain(); 1139 1140 LOCK(pwallet->cs_wallet); 1141 1142 EnsureWalletIsUnlocked(*pwallet); 1143 1144 1145 std::vector<bilingual_str> errors; 1146 CAmount old_fee; 1147 CAmount new_fee; 1148 CMutableTransaction mtx; 1149 feebumper::Result res; 1150 // Targeting feerate bump. 1151 res = feebumper::CreateRateBumpTransaction(*pwallet, hash, coin_control, errors, old_fee, new_fee, mtx, /*require_mine=*/ !want_psbt, outputs, original_change_index); 1152 if (res != feebumper::Result::OK) { 1153 switch(res) { 1154 case feebumper::Result::INVALID_ADDRESS_OR_KEY: 1155 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, errors[0].original); 1156 break; 1157 case feebumper::Result::INVALID_REQUEST: 1158 throw JSONRPCError(RPC_INVALID_REQUEST, errors[0].original); 1159 break; 1160 case feebumper::Result::INVALID_PARAMETER: 1161 throw JSONRPCError(RPC_INVALID_PARAMETER, errors[0].original); 1162 break; 1163 case feebumper::Result::WALLET_ERROR: 1164 throw JSONRPCError(RPC_WALLET_ERROR, errors[0].original); 1165 break; 1166 default: 1167 throw JSONRPCError(RPC_MISC_ERROR, errors[0].original); 1168 break; 1169 } 1170 } 1171 1172 UniValue result(UniValue::VOBJ); 1173 1174 // For bumpfee, return the new transaction id. 1175 // For psbtbumpfee, return the base64-encoded unsigned PSBT of the new transaction. 1176 if (!want_psbt) { 1177 if (!feebumper::SignTransaction(*pwallet, mtx)) { 1178 if (pwallet->IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER)) { 1179 throw JSONRPCError(RPC_WALLET_ERROR, "Transaction incomplete. Try psbtbumpfee instead."); 1180 } 1181 throw JSONRPCError(RPC_WALLET_ERROR, "Can't sign transaction."); 1182 } 1183 1184 Txid txid; 1185 if (feebumper::CommitTransaction(*pwallet, hash, std::move(mtx), errors, txid) != feebumper::Result::OK) { 1186 throw JSONRPCError(RPC_WALLET_ERROR, errors[0].original); 1187 } 1188 1189 result.pushKV("txid", txid.GetHex()); 1190 } else { 1191 PartiallySignedTransaction psbtx(mtx); 1192 bool complete = false; 1193 const auto err{pwallet->FillPSBT(psbtx, complete, std::nullopt, /*sign=*/false, /*bip32derivs=*/true)}; 1194 CHECK_NONFATAL(!err); 1195 CHECK_NONFATAL(!complete); 1196 DataStream ssTx{}; 1197 ssTx << psbtx; 1198 result.pushKV("psbt", EncodeBase64(ssTx.str())); 1199 } 1200 1201 result.pushKV("origfee", ValueFromAmount(old_fee)); 1202 result.pushKV("fee", ValueFromAmount(new_fee)); 1203 UniValue result_errors(UniValue::VARR); 1204 for (const bilingual_str& error : errors) { 1205 result_errors.push_back(error.original); 1206 } 1207 result.pushKV("errors", std::move(result_errors)); 1208 1209 return result; 1210 }, 1211 }; 1212 } 1213 1214 RPCHelpMan bumpfee() { return bumpfee_helper("bumpfee"); } 1215 RPCHelpMan psbtbumpfee() { return bumpfee_helper("psbtbumpfee"); } 1216 1217 RPCHelpMan send() 1218 { 1219 return RPCHelpMan{ 1220 "send", 1221 "EXPERIMENTAL warning: this call may be changed in future releases.\n" 1222 "\nSend a transaction.\n", 1223 { 1224 {"outputs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The outputs specified as key-value pairs.\n" 1225 "Each key may only appear once, i.e. there can only be one 'data' output, and no address may be duplicated.\n" 1226 "At least one output of either type must be specified.\n" 1227 "For convenience, a dictionary, which holds the key-value pairs directly, is also accepted.", 1228 OutputsDoc(), 1229 RPCArgOptions{.skip_type_check = true}}, 1230 {"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks"}, 1231 {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n" 1232 + FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used"))}, 1233 {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."}, 1234 {"options", RPCArg::Type::OBJ_NAMED_PARAMS, RPCArg::Optional::OMITTED, "", 1235 Cat<std::vector<RPCArg>>( 1236 { 1237 {"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"}, 1238 {"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" 1239 "Warning: the resulting transaction may become invalid if one of the unsafe inputs disappears.\n" 1240 "If that happens, you will need to fund the transaction with different inputs and republish it."}, 1241 {"minconf", RPCArg::Type::NUM, RPCArg::Default{0}, "If add_inputs is specified, require inputs with at least this many confirmations."}, 1242 {"maxconf", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "If add_inputs is specified, require inputs with at most this many confirmations."}, 1243 {"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"}, 1244 {"change_address", RPCArg::Type::STR, RPCArg::DefaultHint{"automatic"}, "The bitcoin address to receive the change"}, 1245 {"change_position", RPCArg::Type::NUM, RPCArg::DefaultHint{"random"}, "The index of the change output"}, 1246 {"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() + "."}, 1247 {"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}}, 1248 {"include_watching", RPCArg::Type::BOOL, RPCArg::Default{"false"}, "(DEPRECATED) No longer used"}, 1249 {"inputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Specify inputs instead of adding them automatically.", 1250 { 1251 {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", { 1252 {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"}, 1253 {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"}, 1254 {"sequence", RPCArg::Type::NUM, RPCArg::DefaultHint{"depends on the value of the 'replaceable' and 'locktime' arguments"}, "The sequence number"}, 1255 {"weight", RPCArg::Type::NUM, RPCArg::DefaultHint{"Calculated from wallet and solving data"}, "The maximum weight for this input, " 1256 "including the weight of the outpoint and sequence number. " 1257 "Note that signature sizes are not guaranteed to be consistent, " 1258 "so the maximum DER signatures size of 73 bytes should be used when considering ECDSA signatures." 1259 "Remember to convert serialized sizes to weight units when necessary."}, 1260 }}, 1261 }, 1262 }, 1263 {"locktime", RPCArg::Type::NUM, RPCArg::DefaultHint{"locktime close to block height to prevent fee sniping"}, "Raw locktime. Non-0 value also locktime-activates inputs"}, 1264 {"lock_unspents", RPCArg::Type::BOOL, RPCArg::Default{false}, "Lock selected unspent outputs"}, 1265 {"psbt", RPCArg::Type::BOOL, RPCArg::DefaultHint{"automatic"}, "Always return a PSBT, implies add_to_wallet=false."}, 1266 {"subtract_fee_from_outputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Outputs to subtract the fee from, specified as integer indices.\n" 1267 "The fee will be equally deducted from the amount of each specified output.\n" 1268 "Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n" 1269 "If no outputs are specified here, the sender pays the fee.", 1270 { 1271 {"vout_index", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The zero-based output index, before a change output is added."}, 1272 }, 1273 }, 1274 {"max_tx_weight", RPCArg::Type::NUM, RPCArg::Default{MAX_STANDARD_TX_WEIGHT}, "The maximum acceptable transaction weight.\n" 1275 "Transaction building will fail if this can not be satisfied."}, 1276 }, 1277 FundTxDoc()), 1278 RPCArgOptions{.oneline_description="options"}}, 1279 {"version", RPCArg::Type::NUM, RPCArg::Default{DEFAULT_WALLET_TX_VERSION}, "Transaction version"}, 1280 }, 1281 RPCResult{ 1282 RPCResult::Type::OBJ, "", "", 1283 { 1284 {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"}, 1285 {RPCResult::Type::STR_HEX, "txid", /*optional=*/true, "The transaction id for the send. Only 1 transaction is created regardless of the number of addresses."}, 1286 {RPCResult::Type::STR_HEX, "hex", /*optional=*/true, "If add_to_wallet is false, the hex-encoded raw transaction with signature(s)"}, 1287 {RPCResult::Type::STR, "psbt", /*optional=*/true, "If more signatures are needed, or if add_to_wallet is false, the base64-encoded (partially) signed transaction"} 1288 } 1289 }, 1290 RPCExamples{"" 1291 "\nSend 0.1 BTC with a confirmation target of 6 blocks in economical fee estimate mode\n" 1292 + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.1}' 6 economical\n") + 1293 "Send 0.2 BTC with a fee rate of 1.1 " + CURRENCY_ATOM + "/vB using positional arguments\n" 1294 + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.2}' null \"unset\" 1.1\n") + 1295 "Send 0.2 BTC with a fee rate of 1 " + CURRENCY_ATOM + "/vB using the options argument\n" 1296 + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.2}' null \"unset\" null '{\"fee_rate\": 1}'\n") + 1297 "Send 0.3 BTC with a fee rate of 25 " + CURRENCY_ATOM + "/vB using named arguments\n" 1298 + HelpExampleCli("-named send", "outputs='{\"" + EXAMPLE_ADDRESS[0] + "\": 0.3}' fee_rate=25\n") + 1299 "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" 1300 + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.1}' 1 economical '{\"add_to_wallet\": false, \"inputs\": [{\"txid\":\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\", \"vout\":1}]}'") 1301 }, 1302 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue 1303 { 1304 std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request); 1305 if (!pwallet) return UniValue::VNULL; 1306 1307 UniValue options{request.params[4].isNull() ? UniValue::VOBJ : request.params[4]}; 1308 InterpretFeeEstimationInstructions(/*conf_target=*/request.params[1], /*estimate_mode=*/request.params[2], /*fee_rate=*/request.params[3], options); 1309 PreventOutdatedOptions(options); 1310 1311 1312 bool rbf{options.exists("replaceable") ? options["replaceable"].get_bool() : pwallet->m_signal_rbf}; 1313 UniValue outputs(UniValue::VOBJ); 1314 outputs = NormalizeOutputs(request.params[0]); 1315 std::vector<CRecipient> recipients = CreateRecipients( 1316 ParseOutputs(outputs), 1317 InterpretSubtractFeeFromOutputInstructions(options["subtract_fee_from_outputs"], outputs.getKeys()) 1318 ); 1319 CCoinControl coin_control; 1320 coin_control.m_version = self.Arg<uint32_t>("version"); 1321 CMutableTransaction rawTx = ConstructTransaction(options["inputs"], request.params[0], options["locktime"], rbf, coin_control.m_version); 1322 // Automatically select coins, unless at least one is manually selected. Can 1323 // be overridden by options.add_inputs. 1324 coin_control.m_allow_other_inputs = rawTx.vin.size() == 0; 1325 if (options.exists("max_tx_weight")) { 1326 coin_control.m_max_tx_weight = options["max_tx_weight"].getInt<int>(); 1327 } 1328 1329 SetOptionsInputWeights(options["inputs"], options); 1330 // Clear tx.vout since it is not meant to be used now that we are passing outputs directly. 1331 // This sets us up for a future PR to completely remove tx from the function signature in favor of passing inputs directly 1332 rawTx.vout.clear(); 1333 auto txr = FundTransaction(*pwallet, rawTx, recipients, options, coin_control, /*override_min_fee=*/false); 1334 1335 CMutableTransaction tx = CMutableTransaction(*txr.tx); 1336 return FinishTransaction(pwallet, options, tx); 1337 } 1338 }; 1339 } 1340 1341 RPCHelpMan sendall() 1342 { 1343 return RPCHelpMan{"sendall", 1344 "EXPERIMENTAL warning: this call may be changed in future releases.\n" 1345 "\nSpend the value of all (or specific) confirmed UTXOs and unconfirmed change in the wallet to one or more recipients.\n" 1346 "Unconfirmed inbound UTXOs and locked UTXOs will not be spent. Sendall will respect the avoid_reuse wallet flag.\n" 1347 "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", 1348 { 1349 {"recipients", RPCArg::Type::ARR, RPCArg::Optional::NO, "The sendall destinations. Each address may only appear once.\n" 1350 "Optionally some recipients can be specified with an amount to perform payments, but at least one address must appear without a specified amount.\n", 1351 { 1352 {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "A bitcoin address which receives an equal share of the unspecified amount."}, 1353 {"", RPCArg::Type::OBJ_USER_KEYS, RPCArg::Optional::OMITTED, "", 1354 { 1355 {"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 + ""}, 1356 }, 1357 }, 1358 }, 1359 }, 1360 {"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks"}, 1361 {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n" 1362 + FeeModesDetail(std::string("economical mode is used if the transaction is replaceable;\notherwise, conservative mode is used"))}, 1363 {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."}, 1364 { 1365 "options", RPCArg::Type::OBJ_NAMED_PARAMS, RPCArg::Optional::OMITTED, "", 1366 Cat<std::vector<RPCArg>>( 1367 { 1368 {"add_to_wallet", RPCArg::Type::BOOL, RPCArg::Default{true}, "When false, returns the serialized transaction without broadcasting or adding it to the wallet"}, 1369 {"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}}, 1370 {"include_watching", RPCArg::Type::BOOL, RPCArg::Default{false}, "(DEPRECATED) No longer used"}, 1371 {"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.", 1372 { 1373 {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", 1374 { 1375 {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"}, 1376 {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"}, 1377 {"sequence", RPCArg::Type::NUM, RPCArg::DefaultHint{"depends on the value of the 'replaceable' and 'locktime' arguments"}, "The sequence number"}, 1378 }, 1379 }, 1380 }, 1381 }, 1382 {"locktime", RPCArg::Type::NUM, RPCArg::DefaultHint{"locktime close to block height to prevent fee sniping"}, "Raw locktime. Non-0 value also locktime-activates inputs"}, 1383 {"lock_unspents", RPCArg::Type::BOOL, RPCArg::Default{false}, "Lock selected unspent outputs"}, 1384 {"psbt", RPCArg::Type::BOOL, RPCArg::DefaultHint{"automatic"}, "Always return a PSBT, implies add_to_wallet=false."}, 1385 {"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."}, 1386 {"minconf", RPCArg::Type::NUM, RPCArg::Default{0}, "Require inputs with at least this many confirmations."}, 1387 {"maxconf", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "Require inputs with at most this many confirmations."}, 1388 {"version", RPCArg::Type::NUM, RPCArg::Default{DEFAULT_WALLET_TX_VERSION}, "Transaction version"}, 1389 }, 1390 FundTxDoc() 1391 ), 1392 RPCArgOptions{.oneline_description="options"} 1393 }, 1394 }, 1395 RPCResult{ 1396 RPCResult::Type::OBJ, "", "", 1397 { 1398 {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"}, 1399 {RPCResult::Type::STR_HEX, "txid", /*optional=*/true, "The transaction id for the send. Only 1 transaction is created regardless of the number of addresses."}, 1400 {RPCResult::Type::STR_HEX, "hex", /*optional=*/true, "If add_to_wallet is false, the hex-encoded raw transaction with signature(s)"}, 1401 {RPCResult::Type::STR, "psbt", /*optional=*/true, "If more signatures are needed, or if add_to_wallet is false, the base64-encoded (partially) signed transaction"} 1402 } 1403 }, 1404 RPCExamples{"" 1405 "\nSpend all UTXOs from the wallet with a fee rate of 1 " + CURRENCY_ATOM + "/vB using named arguments\n" 1406 + HelpExampleCli("-named sendall", "recipients='[\"" + EXAMPLE_ADDRESS[0] + "\"]' fee_rate=1\n") + 1407 "Spend all UTXOs with a fee rate of 1.1 " + CURRENCY_ATOM + "/vB using positional arguments\n" 1408 + HelpExampleCli("sendall", "'[\"" + EXAMPLE_ADDRESS[0] + "\"]' null \"unset\" 1.1\n") + 1409 "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" 1410 + HelpExampleCli("sendall", "'[\"" + EXAMPLE_ADDRESS[0] + "\", \"" + EXAMPLE_ADDRESS[1] + "\"]' null \"unset\" null '{\"fee_rate\": 1.5}'\n") + 1411 "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" 1412 + HelpExampleCli("sendall", "'[\"" + EXAMPLE_ADDRESS[0] + "\"]' null \"unset\" null '{\"fee_rate\": 10, \"send_max\": true}'\n") + 1413 "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" 1414 + HelpExampleCli("-named sendall", "recipients='[{\"" + EXAMPLE_ADDRESS[1] + "\": 0.25}, \""+ EXAMPLE_ADDRESS[0] + "\"]' fee_rate=1.3\n") 1415 }, 1416 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue 1417 { 1418 std::shared_ptr<CWallet> const pwallet{GetWalletForJSONRPCRequest(request)}; 1419 if (!pwallet) return UniValue::VNULL; 1420 // Make sure the results are valid at least up to the most recent block 1421 // the user could have gotten from another RPC command prior to now 1422 pwallet->BlockUntilSyncedToCurrentChain(); 1423 1424 UniValue options{request.params[4].isNull() ? UniValue::VOBJ : request.params[4]}; 1425 InterpretFeeEstimationInstructions(/*conf_target=*/request.params[1], /*estimate_mode=*/request.params[2], /*fee_rate=*/request.params[3], options); 1426 PreventOutdatedOptions(options); 1427 1428 1429 std::set<std::string> addresses_without_amount; 1430 UniValue recipient_key_value_pairs(UniValue::VARR); 1431 const UniValue& recipients{request.params[0]}; 1432 for (unsigned int i = 0; i < recipients.size(); ++i) { 1433 const UniValue& recipient{recipients[i]}; 1434 if (recipient.isStr()) { 1435 UniValue rkvp(UniValue::VOBJ); 1436 rkvp.pushKV(recipient.get_str(), 0); 1437 recipient_key_value_pairs.push_back(std::move(rkvp)); 1438 addresses_without_amount.insert(recipient.get_str()); 1439 } else { 1440 recipient_key_value_pairs.push_back(recipient); 1441 } 1442 } 1443 1444 if (addresses_without_amount.size() == 0) { 1445 throw JSONRPCError(RPC_INVALID_PARAMETER, "Must provide at least one address without a specified amount"); 1446 } 1447 1448 CCoinControl coin_control; 1449 1450 SetFeeEstimateMode(*pwallet, coin_control, options["conf_target"], options["estimate_mode"], options["fee_rate"], /*override_min_fee=*/false); 1451 1452 if (options.exists("minconf")) { 1453 if (options["minconf"].getInt<int>() < 0) 1454 { 1455 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid minconf (minconf cannot be negative): %s", options["minconf"].getInt<int>())); 1456 } 1457 1458 coin_control.m_min_depth = options["minconf"].getInt<int>(); 1459 } 1460 1461 if (options.exists("maxconf")) { 1462 coin_control.m_max_depth = options["maxconf"].getInt<int>(); 1463 1464 if (coin_control.m_max_depth < coin_control.m_min_depth) { 1465 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)); 1466 } 1467 } 1468 1469 if (options.exists("version")) { 1470 coin_control.m_version = options["version"].getInt<int>(); 1471 } 1472 1473 if (coin_control.m_version == TRUC_VERSION) { 1474 coin_control.m_max_tx_weight = TRUC_MAX_WEIGHT; 1475 } else { 1476 coin_control.m_max_tx_weight = MAX_STANDARD_TX_WEIGHT; 1477 } 1478 1479 const bool rbf{options.exists("replaceable") ? options["replaceable"].get_bool() : pwallet->m_signal_rbf}; 1480 1481 FeeCalculation fee_calc_out; 1482 CFeeRate fee_rate{GetMinimumFeeRate(*pwallet, coin_control, &fee_calc_out)}; 1483 // Do not, ever, assume that it's fine to change the fee rate if the user has explicitly 1484 // provided one 1485 if (coin_control.m_feerate && fee_rate > *coin_control.m_feerate) { 1486 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Fee rate (%s) is lower than the minimum fee rate setting (%s)", coin_control.m_feerate->ToString(FeeEstimateMode::SAT_VB), fee_rate.ToString(FeeEstimateMode::SAT_VB))); 1487 } 1488 if (fee_calc_out.reason == FeeReason::FALLBACK && !pwallet->m_allow_fallback_fee) { 1489 // eventually allow a fallback fee 1490 throw JSONRPCError(RPC_WALLET_ERROR, "Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee."); 1491 } 1492 1493 CMutableTransaction rawTx{ConstructTransaction(options["inputs"], recipient_key_value_pairs, options["locktime"], rbf, coin_control.m_version)}; 1494 LOCK(pwallet->cs_wallet); 1495 1496 CAmount total_input_value(0); 1497 bool send_max{options.exists("send_max") ? options["send_max"].get_bool() : false}; 1498 if (options.exists("inputs") && options.exists("send_max")) { 1499 throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot combine send_max with specific inputs."); 1500 } else if (options.exists("inputs") && (options.exists("minconf") || options.exists("maxconf"))) { 1501 throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot combine minconf or maxconf with specific inputs."); 1502 } else if (options.exists("inputs")) { 1503 for (const CTxIn& input : rawTx.vin) { 1504 if (pwallet->IsSpent(input.prevout)) { 1505 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Input not available. UTXO (%s:%d) was already spent.", input.prevout.hash.ToString(), input.prevout.n)); 1506 } 1507 const CWalletTx* tx{pwallet->GetWalletTx(input.prevout.hash)}; 1508 if (!tx || input.prevout.n >= tx->tx->vout.size() || !pwallet->IsMine(tx->tx->vout[input.prevout.n])) { 1509 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Input not found. UTXO (%s:%d) is not part of wallet.", input.prevout.hash.ToString(), input.prevout.n)); 1510 } 1511 if (pwallet->GetTxDepthInMainChain(*tx) == 0) { 1512 if (tx->tx->version == TRUC_VERSION && coin_control.m_version != TRUC_VERSION) { 1513 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Can't spend unconfirmed version 3 pre-selected input with a version %d tx", coin_control.m_version)); 1514 } else if (coin_control.m_version == TRUC_VERSION && tx->tx->version != TRUC_VERSION) { 1515 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Can't spend unconfirmed version %d pre-selected input with a version 3 tx", tx->tx->version)); 1516 } 1517 } 1518 total_input_value += tx->tx->vout[input.prevout.n].nValue; 1519 } 1520 } else { 1521 CoinFilterParams coins_params; 1522 coins_params.min_amount = 0; 1523 for (const COutput& output : AvailableCoins(*pwallet, &coin_control, fee_rate, coins_params).All()) { 1524 if (send_max && fee_rate.GetFee(output.input_bytes) > output.txout.nValue) { 1525 continue; 1526 } 1527 // we are spending an unconfirmed TRUC transaction, so lower max weight 1528 if (output.depth == 0 && coin_control.m_version == TRUC_VERSION) { 1529 coin_control.m_max_tx_weight = TRUC_CHILD_MAX_WEIGHT; 1530 } 1531 CTxIn input(output.outpoint.hash, output.outpoint.n, CScript(), rbf ? MAX_BIP125_RBF_SEQUENCE : CTxIn::SEQUENCE_FINAL); 1532 rawTx.vin.push_back(input); 1533 total_input_value += output.txout.nValue; 1534 } 1535 } 1536 1537 std::vector<COutPoint> outpoints_spent; 1538 outpoints_spent.reserve(rawTx.vin.size()); 1539 1540 for (const CTxIn& tx_in : rawTx.vin) { 1541 outpoints_spent.push_back(tx_in.prevout); 1542 } 1543 1544 // estimate final size of tx 1545 const TxSize tx_size{CalculateMaximumSignedTxSize(CTransaction(rawTx), pwallet.get())}; 1546 if (tx_size.vsize == -1) { 1547 throw JSONRPCError(RPC_WALLET_ERROR, "Unable to determine the size of the transaction, the wallet contains unsolvable descriptors"); 1548 } 1549 const CAmount fee_from_size{fee_rate.GetFee(tx_size.vsize)}; 1550 const std::optional<CAmount> total_bump_fees{pwallet->chain().calculateCombinedBumpFee(outpoints_spent, fee_rate)}; 1551 CAmount effective_value = total_input_value - fee_from_size - total_bump_fees.value_or(0); 1552 1553 if (fee_from_size > pwallet->m_default_max_tx_fee) { 1554 throw JSONRPCError(RPC_WALLET_ERROR, TransactionErrorString(TransactionError::MAX_FEE_EXCEEDED).original); 1555 } 1556 1557 if (effective_value <= 0) { 1558 if (send_max) { 1559 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Total value of UTXO pool too low to pay for transaction, try using lower feerate."); 1560 } else { 1561 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."); 1562 } 1563 } 1564 1565 // If this transaction is too large, e.g. because the wallet has many UTXOs, it will be rejected by the node's mempool. 1566 if (tx_size.weight > coin_control.m_max_tx_weight) { 1567 throw JSONRPCError(RPC_WALLET_ERROR, "Transaction too large."); 1568 } 1569 1570 CAmount output_amounts_claimed{0}; 1571 for (const CTxOut& out : rawTx.vout) { 1572 output_amounts_claimed += out.nValue; 1573 } 1574 1575 if (output_amounts_claimed > total_input_value) { 1576 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Assigned more value to outputs than available funds."); 1577 } 1578 1579 const CAmount remainder{effective_value - output_amounts_claimed}; 1580 if (remainder < 0) { 1581 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds for fees after creating specified outputs."); 1582 } 1583 1584 const CAmount per_output_without_amount{remainder / (long)addresses_without_amount.size()}; 1585 1586 bool gave_remaining_to_first{false}; 1587 for (CTxOut& out : rawTx.vout) { 1588 CTxDestination dest; 1589 ExtractDestination(out.scriptPubKey, dest); 1590 std::string addr{EncodeDestination(dest)}; 1591 if (addresses_without_amount.count(addr) > 0) { 1592 out.nValue = per_output_without_amount; 1593 if (!gave_remaining_to_first) { 1594 out.nValue += remainder % addresses_without_amount.size(); 1595 gave_remaining_to_first = true; 1596 } 1597 if (IsDust(out, pwallet->chain().relayDustFee())) { 1598 // Dynamically generated output amount is dust 1599 throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Dynamically assigned remainder results in dust output."); 1600 } 1601 } else { 1602 if (IsDust(out, pwallet->chain().relayDustFee())) { 1603 // Specified output amount is dust 1604 throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Specified output amount to %s is below dust threshold.", addr)); 1605 } 1606 } 1607 } 1608 1609 const bool lock_unspents{options.exists("lock_unspents") ? options["lock_unspents"].get_bool() : false}; 1610 if (lock_unspents) { 1611 for (const CTxIn& txin : rawTx.vin) { 1612 pwallet->LockCoin(txin.prevout, /*persist=*/false); 1613 } 1614 } 1615 1616 return FinishTransaction(pwallet, options, rawTx); 1617 } 1618 }; 1619 } 1620 1621 RPCHelpMan walletprocesspsbt() 1622 { 1623 return RPCHelpMan{ 1624 "walletprocesspsbt", 1625 "Update a PSBT with input information from our wallet and then sign inputs\n" 1626 "that we can sign for." + 1627 HELP_REQUIRING_PASSPHRASE, 1628 { 1629 {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction base64 string"}, 1630 {"sign", RPCArg::Type::BOOL, RPCArg::Default{true}, "Also sign the transaction when updating (requires wallet to be unlocked)"}, 1631 {"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" 1632 " \"DEFAULT\"\n" 1633 " \"ALL\"\n" 1634 " \"NONE\"\n" 1635 " \"SINGLE\"\n" 1636 " \"ALL|ANYONECANPAY\"\n" 1637 " \"NONE|ANYONECANPAY\"\n" 1638 " \"SINGLE|ANYONECANPAY\""}, 1639 {"bip32derivs", RPCArg::Type::BOOL, RPCArg::Default{true}, "Include BIP 32 derivation paths for public keys if we know them"}, 1640 {"finalize", RPCArg::Type::BOOL, RPCArg::Default{true}, "Also finalize inputs if possible"}, 1641 }, 1642 RPCResult{ 1643 RPCResult::Type::OBJ, "", "", 1644 { 1645 {RPCResult::Type::STR, "psbt", "The base64-encoded partially signed transaction"}, 1646 {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"}, 1647 {RPCResult::Type::STR_HEX, "hex", /*optional=*/true, "The hex-encoded network transaction if complete"}, 1648 } 1649 }, 1650 RPCExamples{ 1651 HelpExampleCli("walletprocesspsbt", "\"psbt\"") 1652 }, 1653 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue 1654 { 1655 const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request); 1656 if (!pwallet) return UniValue::VNULL; 1657 1658 const CWallet& wallet{*pwallet}; 1659 // Make sure the results are valid at least up to the most recent block 1660 // the user could have gotten from another RPC command prior to now 1661 wallet.BlockUntilSyncedToCurrentChain(); 1662 1663 // Unserialize the transaction 1664 PartiallySignedTransaction psbtx; 1665 std::string error; 1666 if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) { 1667 throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error)); 1668 } 1669 1670 // Get the sighash type 1671 std::optional<int> nHashType = ParseSighashString(request.params[2]); 1672 1673 // Fill transaction with our data and also sign 1674 bool sign = request.params[1].isNull() ? true : request.params[1].get_bool(); 1675 bool bip32derivs = request.params[3].isNull() ? true : request.params[3].get_bool(); 1676 bool finalize = request.params[4].isNull() ? true : request.params[4].get_bool(); 1677 bool complete = true; 1678 1679 if (sign) EnsureWalletIsUnlocked(*pwallet); 1680 1681 const auto err{wallet.FillPSBT(psbtx, complete, nHashType, sign, bip32derivs, nullptr, finalize)}; 1682 if (err) { 1683 throw JSONRPCPSBTError(*err); 1684 } 1685 1686 UniValue result(UniValue::VOBJ); 1687 DataStream ssTx{}; 1688 ssTx << psbtx; 1689 result.pushKV("psbt", EncodeBase64(ssTx.str())); 1690 result.pushKV("complete", complete); 1691 if (complete) { 1692 CMutableTransaction mtx; 1693 // Returns true if complete, which we already think it is. 1694 CHECK_NONFATAL(FinalizeAndExtractPSBT(psbtx, mtx)); 1695 DataStream ssTx_final; 1696 ssTx_final << TX_WITH_WITNESS(mtx); 1697 result.pushKV("hex", HexStr(ssTx_final)); 1698 } 1699 1700 return result; 1701 }, 1702 }; 1703 } 1704 1705 RPCHelpMan walletcreatefundedpsbt() 1706 { 1707 return RPCHelpMan{ 1708 "walletcreatefundedpsbt", 1709 "Creates and funds a transaction in the Partially Signed Transaction format.\n" 1710 "Implements the Creator and Updater roles.\n" 1711 "All existing inputs must either have their previous output transaction be in the wallet\n" 1712 "or be in the UTXO set. Solving data must be provided for non-wallet inputs.\n", 1713 { 1714 {"inputs", RPCArg::Type::ARR, RPCArg::Optional::OMITTED, "Leave empty to add inputs automatically. See add_inputs option.", 1715 { 1716 {"", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED, "", 1717 { 1718 {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"}, 1719 {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"}, 1720 {"sequence", RPCArg::Type::NUM, RPCArg::DefaultHint{"depends on the value of the 'locktime' and 'options.replaceable' arguments"}, "The sequence number"}, 1721 {"weight", RPCArg::Type::NUM, RPCArg::DefaultHint{"Calculated from wallet and solving data"}, "The maximum weight for this input, " 1722 "including the weight of the outpoint and sequence number. " 1723 "Note that signature sizes are not guaranteed to be consistent, " 1724 "so the maximum DER signatures size of 73 bytes should be used when considering ECDSA signatures." 1725 "Remember to convert serialized sizes to weight units when necessary."}, 1726 }, 1727 }, 1728 }, 1729 }, 1730 {"outputs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The outputs specified as key-value pairs.\n" 1731 "Each key may only appear once, i.e. there can only be one 'data' output, and no address may be duplicated.\n" 1732 "At least one output of either type must be specified.\n" 1733 "For compatibility reasons, a dictionary, which holds the key-value pairs directly, is also\n" 1734 "accepted as second parameter.", 1735 OutputsDoc(), 1736 RPCArgOptions{.skip_type_check = true}}, 1737 {"locktime", RPCArg::Type::NUM, RPCArg::Default{0}, "Raw locktime. Non-0 value also locktime-activates inputs"}, 1738 {"options", RPCArg::Type::OBJ_NAMED_PARAMS, RPCArg::Optional::OMITTED, "", 1739 Cat<std::vector<RPCArg>>( 1740 { 1741 {"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"}, 1742 {"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" 1743 "Warning: the resulting transaction may become invalid if one of the unsafe inputs disappears.\n" 1744 "If that happens, you will need to fund the transaction with different inputs and republish it."}, 1745 {"minconf", RPCArg::Type::NUM, RPCArg::Default{0}, "If add_inputs is specified, require inputs with at least this many confirmations."}, 1746 {"maxconf", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "If add_inputs is specified, require inputs with at most this many confirmations."}, 1747 {"changeAddress", RPCArg::Type::STR, RPCArg::DefaultHint{"automatic"}, "The bitcoin address to receive the change"}, 1748 {"changePosition", RPCArg::Type::NUM, RPCArg::DefaultHint{"random"}, "The index of the change output"}, 1749 {"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() + "."}, 1750 {"includeWatching", RPCArg::Type::BOOL, RPCArg::Default{false}, "(DEPRECATED) No longer used"}, 1751 {"lockUnspents", RPCArg::Type::BOOL, RPCArg::Default{false}, "Lock selected unspent outputs"}, 1752 {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."}, 1753 {"feeRate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_UNIT + "/kvB."}, 1754 {"subtractFeeFromOutputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "The outputs to subtract the fee from.\n" 1755 "The fee will be equally deducted from the amount of each specified output.\n" 1756 "Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n" 1757 "If no outputs are specified here, the sender pays the fee.", 1758 { 1759 {"vout_index", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The zero-based output index, before a change output is added."}, 1760 }, 1761 }, 1762 {"max_tx_weight", RPCArg::Type::NUM, RPCArg::Default{MAX_STANDARD_TX_WEIGHT}, "The maximum acceptable transaction weight.\n" 1763 "Transaction building will fail if this can not be satisfied."}, 1764 }, 1765 FundTxDoc()), 1766 RPCArgOptions{.oneline_description="options"}}, 1767 {"bip32derivs", RPCArg::Type::BOOL, RPCArg::Default{true}, "Include BIP 32 derivation paths for public keys if we know them"}, 1768 {"version", RPCArg::Type::NUM, RPCArg::Default{DEFAULT_WALLET_TX_VERSION}, "Transaction version"}, 1769 }, 1770 RPCResult{ 1771 RPCResult::Type::OBJ, "", "", 1772 { 1773 {RPCResult::Type::STR, "psbt", "The resulting raw transaction (base64-encoded string)"}, 1774 {RPCResult::Type::STR_AMOUNT, "fee", "Fee in " + CURRENCY_UNIT + " the resulting transaction pays"}, 1775 {RPCResult::Type::NUM, "changepos", "The position of the added change output, or -1"}, 1776 } 1777 }, 1778 RPCExamples{ 1779 "\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" 1780 + HelpExampleCli("walletcreatefundedpsbt", "\"[]\" \"[{\\\"" + EXAMPLE_ADDRESS[0] + "\\\":0.5}]\" 0 \"{\\\"add_inputs\\\":true,\\\"fee_rate\\\":2}\"") 1781 + "\nCreate the same PSBT as the above one instead using named arguments:\n" 1782 + HelpExampleCli("-named walletcreatefundedpsbt", "outputs=\"[{\\\"" + EXAMPLE_ADDRESS[0] + "\\\":0.5}]\" add_inputs=true fee_rate=2") 1783 }, 1784 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue 1785 { 1786 std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request); 1787 if (!pwallet) return UniValue::VNULL; 1788 1789 CWallet& wallet{*pwallet}; 1790 // Make sure the results are valid at least up to the most recent block 1791 // the user could have gotten from another RPC command prior to now 1792 wallet.BlockUntilSyncedToCurrentChain(); 1793 1794 UniValue options{request.params[3].isNull() ? UniValue::VOBJ : request.params[3]}; 1795 1796 CCoinControl coin_control; 1797 coin_control.m_version = self.Arg<uint32_t>("version"); 1798 1799 const UniValue &replaceable_arg = options["replaceable"]; 1800 const bool rbf{replaceable_arg.isNull() ? wallet.m_signal_rbf : replaceable_arg.get_bool()}; 1801 CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf, coin_control.m_version); 1802 UniValue outputs(UniValue::VOBJ); 1803 outputs = NormalizeOutputs(request.params[1]); 1804 std::vector<CRecipient> recipients = CreateRecipients( 1805 ParseOutputs(outputs), 1806 InterpretSubtractFeeFromOutputInstructions(options["subtractFeeFromOutputs"], outputs.getKeys()) 1807 ); 1808 // Automatically select coins, unless at least one is manually selected. Can 1809 // be overridden by options.add_inputs. 1810 coin_control.m_allow_other_inputs = rawTx.vin.size() == 0; 1811 SetOptionsInputWeights(request.params[0], options); 1812 // Clear tx.vout since it is not meant to be used now that we are passing outputs directly. 1813 // This sets us up for a future PR to completely remove tx from the function signature in favor of passing inputs directly 1814 rawTx.vout.clear(); 1815 auto txr = FundTransaction(wallet, rawTx, recipients, options, coin_control, /*override_min_fee=*/true); 1816 1817 // Make a blank psbt 1818 PartiallySignedTransaction psbtx(CMutableTransaction(*txr.tx)); 1819 1820 // Fill transaction with out data but don't sign 1821 bool bip32derivs = request.params[4].isNull() ? true : request.params[4].get_bool(); 1822 bool complete = true; 1823 const auto err{wallet.FillPSBT(psbtx, complete, std::nullopt, /*sign=*/false, /*bip32derivs=*/bip32derivs)}; 1824 if (err) { 1825 throw JSONRPCPSBTError(*err); 1826 } 1827 1828 // Serialize the PSBT 1829 DataStream ssTx{}; 1830 ssTx << psbtx; 1831 1832 UniValue result(UniValue::VOBJ); 1833 result.pushKV("psbt", EncodeBase64(ssTx.str())); 1834 result.pushKV("fee", ValueFromAmount(txr.fee)); 1835 result.pushKV("changepos", txr.change_pos ? (int)*txr.change_pos : -1); 1836 return result; 1837 }, 1838 }; 1839 } 1840 } // namespace wallet