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