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