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