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