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