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