Bitcoin Core  22.99.0
P2P Digital Currency
spend.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2021 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 <core_io.h>
6 #include <key_io.h>
7 #include <policy/policy.h>
9 #include <rpc/util.h>
10 #include <util/fees.h>
11 #include <util/translation.h>
12 #include <util/vector.h>
13 #include <wallet/coincontrol.h>
14 #include <wallet/feebumper.h>
15 #include <wallet/rpc/util.h>
16 #include <wallet/spend.h>
17 #include <wallet/wallet.h>
18 
19 #include <univalue.h>
20 
21 
22 namespace wallet {
23 static void ParseRecipients(const UniValue& address_amounts, const UniValue& subtract_fee_outputs, std::vector<CRecipient> &recipients) {
24  std::set<CTxDestination> destinations;
25  int i = 0;
26  for (const std::string& address: address_amounts.getKeys()) {
27  CTxDestination dest = DecodeDestination(address);
28  if (!IsValidDestination(dest)) {
29  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, std::string("Invalid Bitcoin address: ") + address);
30  }
31 
32  if (destinations.count(dest)) {
33  throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + address);
34  }
35  destinations.insert(dest);
36 
37  CScript script_pub_key = GetScriptForDestination(dest);
38  CAmount amount = AmountFromValue(address_amounts[i++]);
39 
40  bool subtract_fee = false;
41  for (unsigned int idx = 0; idx < subtract_fee_outputs.size(); idx++) {
42  const UniValue& addr = subtract_fee_outputs[idx];
43  if (addr.get_str() == address) {
44  subtract_fee = true;
45  }
46  }
47 
48  CRecipient recipient = {script_pub_key, amount, subtract_fee};
49  recipients.push_back(recipient);
50  }
51 }
52 
53 UniValue SendMoney(CWallet& wallet, const CCoinControl &coin_control, std::vector<CRecipient> &recipients, mapValue_t map_value, bool verbose)
54 {
56 
57  // This function is only used by sendtoaddress and sendmany.
58  // This should always try to sign, if we don't have private keys, don't try to do anything here.
59  if (wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
60  throw JSONRPCError(RPC_WALLET_ERROR, "Error: Private keys are disabled for this wallet");
61  }
62 
63  // Shuffle recipient list
64  std::shuffle(recipients.begin(), recipients.end(), FastRandomContext());
65 
66  // Send
67  CAmount nFeeRequired = 0;
68  int nChangePosRet = -1;
70  CTransactionRef tx;
71  FeeCalculation fee_calc_out;
72  const bool fCreated = CreateTransaction(wallet, recipients, tx, nFeeRequired, nChangePosRet, error, coin_control, fee_calc_out, true);
73  if (!fCreated) {
75  }
76  wallet.CommitTransaction(tx, std::move(map_value), {} /* orderForm */);
77  if (verbose) {
78  UniValue entry(UniValue::VOBJ);
79  entry.pushKV("txid", tx->GetHash().GetHex());
80  entry.pushKV("fee_reason", StringForFeeReason(fee_calc_out.reason));
81  return entry;
82  }
83  return tx->GetHash().GetHex();
84 }
85 
86 
100 static void SetFeeEstimateMode(const CWallet& wallet, CCoinControl& cc, const UniValue& conf_target, const UniValue& estimate_mode, const UniValue& fee_rate, bool override_min_fee)
101 {
102  if (!fee_rate.isNull()) {
103  if (!conf_target.isNull()) {
104  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.");
105  }
106  if (!estimate_mode.isNull() && estimate_mode.get_str() != "unset") {
107  throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both estimate_mode and fee_rate");
108  }
109  // Fee rates in sat/vB cannot represent more than 3 significant digits.
110  cc.m_feerate = CFeeRate{AmountFromValue(fee_rate, /* decimals */ 3)};
111  if (override_min_fee) cc.fOverrideFeeRate = true;
112  // Default RBF to true for explicit fee_rate, if unset.
113  if (!cc.m_signal_bip125_rbf) cc.m_signal_bip125_rbf = true;
114  return;
115  }
116  if (!estimate_mode.isNull() && !FeeModeFromString(estimate_mode.get_str(), cc.m_fee_mode)) {
118  }
119  if (!conf_target.isNull()) {
120  cc.m_confirm_target = ParseConfirmTarget(conf_target, wallet.chain().estimateMaxBlocks());
121  }
122 }
123 
125 {
126  return RPCHelpMan{"sendtoaddress",
127  "\nSend an amount to a given address." +
129  {
130  {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to send to."},
131  {"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "The amount in " + CURRENCY_UNIT + " to send. eg 0.1"},
132  {"comment", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "A comment used to store what the transaction is for.\n"
133  "This is not part of the transaction, just kept in your wallet."},
134  {"comment_to", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "A comment to store the name of the person or organization\n"
135  "to which you're sending the transaction. This is not part of the \n"
136  "transaction, just kept in your wallet."},
137  {"subtractfeefromamount", RPCArg::Type::BOOL, RPCArg::Default{false}, "The fee will be deducted from the amount being sent.\n"
138  "The recipient will receive less bitcoins than you enter in the amount field."},
139  {"replaceable", RPCArg::Type::BOOL, RPCArg::DefaultHint{"wallet default"}, "Allow this transaction to be replaced by a transaction with higher fees via BIP 125"},
140  {"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks"},
141  {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, std::string() + "The fee estimate mode, must be one of (case insensitive):\n"
142  " \"" + FeeModes("\"\n\"") + "\""},
143  {"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"
144  "dirty if they have previously been used in a transaction. If true, this also activates avoidpartialspends, grouping outputs by their addresses."},
145  {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."},
146  {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false}, "If true, return extra information about the transaction."},
147  },
148  {
149  RPCResult{"if verbose is not set or set to false",
150  RPCResult::Type::STR_HEX, "txid", "The transaction id."
151  },
152  RPCResult{"if verbose is set to true",
153  RPCResult::Type::OBJ, "", "",
154  {
155  {RPCResult::Type::STR_HEX, "txid", "The transaction id."},
156  {RPCResult::Type::STR, "fee_reason", "The transaction fee reason."}
157  },
158  },
159  },
160  RPCExamples{
161  "\nSend 0.1 BTC\n"
162  + HelpExampleCli("sendtoaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 0.1") +
163  "\nSend 0.1 BTC with a confirmation target of 6 blocks in economical fee estimate mode using positional arguments\n"
164  + HelpExampleCli("sendtoaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 0.1 \"donation\" \"sean's outpost\" false true 6 economical") +
165  "\nSend 0.1 BTC with a fee rate of 1.1 " + CURRENCY_ATOM + "/vB, subtract fee from amount, BIP125-replaceable, using positional arguments\n"
166  + HelpExampleCli("sendtoaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 0.1 \"drinks\" \"room77\" true true null \"unset\" null 1.1") +
167  "\nSend 0.2 BTC with a confirmation target of 6 blocks in economical fee estimate mode using named arguments\n"
168  + HelpExampleCli("-named sendtoaddress", "address=\"" + EXAMPLE_ADDRESS[0] + "\" amount=0.2 conf_target=6 estimate_mode=\"economical\"") +
169  "\nSend 0.5 BTC with a fee rate of 25 " + CURRENCY_ATOM + "/vB using named arguments\n"
170  + HelpExampleCli("-named sendtoaddress", "address=\"" + EXAMPLE_ADDRESS[0] + "\" amount=0.5 fee_rate=25")
171  + 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")
172  },
173  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
174 {
175  std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
176  if (!pwallet) return NullUniValue;
177 
178  // Make sure the results are valid at least up to the most recent block
179  // the user could have gotten from another RPC command prior to now
180  pwallet->BlockUntilSyncedToCurrentChain();
181 
182  LOCK(pwallet->cs_wallet);
183 
184  // Wallet comments
185  mapValue_t mapValue;
186  if (!request.params[2].isNull() && !request.params[2].get_str().empty())
187  mapValue["comment"] = request.params[2].get_str();
188  if (!request.params[3].isNull() && !request.params[3].get_str().empty())
189  mapValue["to"] = request.params[3].get_str();
190 
191  bool fSubtractFeeFromAmount = false;
192  if (!request.params[4].isNull()) {
193  fSubtractFeeFromAmount = request.params[4].get_bool();
194  }
195 
196  CCoinControl coin_control;
197  if (!request.params[5].isNull()) {
198  coin_control.m_signal_bip125_rbf = request.params[5].get_bool();
199  }
200 
201  coin_control.m_avoid_address_reuse = GetAvoidReuseFlag(*pwallet, request.params[8]);
202  // We also enable partial spend avoidance if reuse avoidance is set.
203  coin_control.m_avoid_partial_spends |= coin_control.m_avoid_address_reuse;
204 
205  SetFeeEstimateMode(*pwallet, coin_control, /* conf_target */ request.params[6], /* estimate_mode */ request.params[7], /* fee_rate */ request.params[9], /* override_min_fee */ false);
206 
207  EnsureWalletIsUnlocked(*pwallet);
208 
209  UniValue address_amounts(UniValue::VOBJ);
210  const std::string address = request.params[0].get_str();
211  address_amounts.pushKV(address, request.params[1]);
212  UniValue subtractFeeFromAmount(UniValue::VARR);
213  if (fSubtractFeeFromAmount) {
214  subtractFeeFromAmount.push_back(address);
215  }
216 
217  std::vector<CRecipient> recipients;
218  ParseRecipients(address_amounts, subtractFeeFromAmount, recipients);
219  const bool verbose{request.params[10].isNull() ? false : request.params[10].get_bool()};
220 
221  return SendMoney(*pwallet, coin_control, recipients, mapValue, verbose);
222 },
223  };
224 }
225 
227 {
228  return RPCHelpMan{"sendmany",
229  "\nSend multiple times. Amounts are double-precision floating point numbers." +
231  {
232  {"dummy", RPCArg::Type::STR, RPCArg::Optional::NO, "Must be set to \"\" for backwards compatibility.", "\"\""},
233  {"amounts", RPCArg::Type::OBJ_USER_KEYS, RPCArg::Optional::NO, "The addresses and amounts",
234  {
235  {"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"},
236  },
237  },
238  {"minconf", RPCArg::Type::NUM, RPCArg::Optional::OMITTED_NAMED_ARG, "Ignored dummy value"},
239  {"comment", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "A comment"},
240  {"subtractfeefrom", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "The addresses.\n"
241  "The fee will be equally deducted from the amount of each selected address.\n"
242  "Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
243  "If no addresses are specified here, the sender pays the fee.",
244  {
245  {"address", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Subtract fee from this address"},
246  },
247  },
248  {"replaceable", RPCArg::Type::BOOL, RPCArg::DefaultHint{"wallet default"}, "Allow this transaction to be replaced by a transaction with higher fees via BIP 125"},
249  {"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks"},
250  {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, std::string() + "The fee estimate mode, must be one of (case insensitive):\n"
251  " \"" + FeeModes("\"\n\"") + "\""},
252  {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."},
253  {"verbose", RPCArg::Type::BOOL, RPCArg::Default{false}, "If true, return extra infomration about the transaction."},
254  },
255  {
256  RPCResult{"if verbose is not set or set to false",
257  RPCResult::Type::STR_HEX, "txid", "The transaction id for the send. Only 1 transaction is created regardless of\n"
258  "the number of addresses."
259  },
260  RPCResult{"if verbose is set to true",
261  RPCResult::Type::OBJ, "", "",
262  {
263  {RPCResult::Type::STR_HEX, "txid", "The transaction id for the send. Only 1 transaction is created regardless of\n"
264  "the number of addresses."},
265  {RPCResult::Type::STR, "fee_reason", "The transaction fee reason."}
266  },
267  },
268  },
269  RPCExamples{
270  "\nSend two amounts to two different addresses:\n"
271  + HelpExampleCli("sendmany", "\"\" \"{\\\"" + EXAMPLE_ADDRESS[0] + "\\\":0.01,\\\"" + EXAMPLE_ADDRESS[1] + "\\\":0.02}\"") +
272  "\nSend two amounts to two different addresses setting the confirmation and comment:\n"
273  + HelpExampleCli("sendmany", "\"\" \"{\\\"" + EXAMPLE_ADDRESS[0] + "\\\":0.01,\\\"" + EXAMPLE_ADDRESS[1] + "\\\":0.02}\" 6 \"testing\"") +
274  "\nSend two amounts to two different addresses, subtract fee from amount:\n"
275  + HelpExampleCli("sendmany", "\"\" \"{\\\"" + EXAMPLE_ADDRESS[0] + "\\\":0.01,\\\"" + EXAMPLE_ADDRESS[1] + "\\\":0.02}\" 1 \"\" \"[\\\"" + EXAMPLE_ADDRESS[0] + "\\\",\\\"" + EXAMPLE_ADDRESS[1] + "\\\"]\"") +
276  "\nAs a JSON-RPC call\n"
277  + HelpExampleRpc("sendmany", "\"\", {\"" + EXAMPLE_ADDRESS[0] + "\":0.01,\"" + EXAMPLE_ADDRESS[1] + "\":0.02}, 6, \"testing\"")
278  },
279  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
280 {
281  std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
282  if (!pwallet) return NullUniValue;
283 
284  // Make sure the results are valid at least up to the most recent block
285  // the user could have gotten from another RPC command prior to now
286  pwallet->BlockUntilSyncedToCurrentChain();
287 
288  LOCK(pwallet->cs_wallet);
289 
290  if (!request.params[0].isNull() && !request.params[0].get_str().empty()) {
291  throw JSONRPCError(RPC_INVALID_PARAMETER, "Dummy value must be set to \"\"");
292  }
293  UniValue sendTo = request.params[1].get_obj();
294 
295  mapValue_t mapValue;
296  if (!request.params[3].isNull() && !request.params[3].get_str().empty())
297  mapValue["comment"] = request.params[3].get_str();
298 
299  UniValue subtractFeeFromAmount(UniValue::VARR);
300  if (!request.params[4].isNull())
301  subtractFeeFromAmount = request.params[4].get_array();
302 
303  CCoinControl coin_control;
304  if (!request.params[5].isNull()) {
305  coin_control.m_signal_bip125_rbf = request.params[5].get_bool();
306  }
307 
308  SetFeeEstimateMode(*pwallet, coin_control, /* conf_target */ request.params[6], /* estimate_mode */ request.params[7], /* fee_rate */ request.params[8], /* override_min_fee */ false);
309 
310  std::vector<CRecipient> recipients;
311  ParseRecipients(sendTo, subtractFeeFromAmount, recipients);
312  const bool verbose{request.params[9].isNull() ? false : request.params[9].get_bool()};
313 
314  return SendMoney(*pwallet, coin_control, recipients, std::move(mapValue), verbose);
315 },
316  };
317 }
318 
320 {
321  return RPCHelpMan{"settxfee",
322  "\nSet the transaction fee rate in " + CURRENCY_UNIT + "/kvB for this wallet. Overrides the global -paytxfee command line parameter.\n"
323  "Can be deactivated by passing 0 as the fee. In that case automatic fee selection will be used by default.\n",
324  {
325  {"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::NO, "The transaction fee rate in " + CURRENCY_UNIT + "/kvB"},
326  },
327  RPCResult{
328  RPCResult::Type::BOOL, "", "Returns true if successful"
329  },
330  RPCExamples{
331  HelpExampleCli("settxfee", "0.00001")
332  + HelpExampleRpc("settxfee", "0.00001")
333  },
334  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
335 {
336  std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
337  if (!pwallet) return NullUniValue;
338 
339  LOCK(pwallet->cs_wallet);
340 
341  CAmount nAmount = AmountFromValue(request.params[0]);
342  CFeeRate tx_fee_rate(nAmount, 1000);
343  CFeeRate max_tx_fee_rate(pwallet->m_default_max_tx_fee, 1000);
344  if (tx_fee_rate == CFeeRate(0)) {
345  // automatic selection
346  } else if (tx_fee_rate < pwallet->chain().relayMinFee()) {
347  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("txfee cannot be less than min relay tx fee (%s)", pwallet->chain().relayMinFee().ToString()));
348  } else if (tx_fee_rate < pwallet->m_min_fee) {
349  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("txfee cannot be less than wallet min fee (%s)", pwallet->m_min_fee.ToString()));
350  } else if (tx_fee_rate > max_tx_fee_rate) {
351  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("txfee cannot be more than wallet max tx fee (%s)", max_tx_fee_rate.ToString()));
352  }
353 
354  pwallet->m_pay_tx_fee = tx_fee_rate;
355  return true;
356 },
357  };
358 }
359 
360 
361 // Only includes key documentation where the key is snake_case in all RPC methods. MixedCase keys can be added later.
362 static std::vector<RPCArg> FundTxDoc()
363 {
364  return {
365  {"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks"},
366  {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, std::string() + "The fee estimate mode, must be one of (case insensitive):\n"
367  " \"" + FeeModes("\"\n\"") + "\""},
368  {"replaceable", RPCArg::Type::BOOL, RPCArg::DefaultHint{"wallet default"}, "Marks this transaction as BIP125-replaceable.\n"
369  "Allows this transaction to be replaced by a transaction with higher fees"},
370  {"solving_data", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED_NAMED_ARG, "Keys and scripts needed for producing a final transaction with a dummy signature.\n"
371  "Used for fee estimation during coin selection.",
372  {
373  {"pubkeys", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Public keys involved in this transaction.",
374  {
375  {"pubkey", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "A public key"},
376  }},
377  {"scripts", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Scripts involved in this transaction.",
378  {
379  {"script", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "A script"},
380  }},
381  {"descriptors", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Descriptors that provide solving data for this transaction.",
382  {
383  {"descriptor", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "A descriptor"},
384  }},
385  }},
386  };
387 }
388 
389 void FundTransaction(CWallet& wallet, CMutableTransaction& tx, CAmount& fee_out, int& change_position, const UniValue& options, CCoinControl& coinControl, bool override_min_fee)
390 {
391  // Make sure the results are valid at least up to the most recent block
392  // the user could have gotten from another RPC command prior to now
393  wallet.BlockUntilSyncedToCurrentChain();
394 
395  change_position = -1;
396  bool lockUnspents = false;
397  UniValue subtractFeeFromOutputs;
398  std::set<int> setSubtractFeeFromOutputs;
399 
400  if (!options.isNull()) {
401  if (options.type() == UniValue::VBOOL) {
402  // backward compatibility bool only fallback
403  coinControl.fAllowWatchOnly = options.get_bool();
404  }
405  else {
407  RPCTypeCheckObj(options,
408  {
409  {"add_inputs", UniValueType(UniValue::VBOOL)},
410  {"include_unsafe", UniValueType(UniValue::VBOOL)},
411  {"add_to_wallet", UniValueType(UniValue::VBOOL)},
412  {"changeAddress", UniValueType(UniValue::VSTR)},
413  {"change_address", UniValueType(UniValue::VSTR)},
414  {"changePosition", UniValueType(UniValue::VNUM)},
415  {"change_position", UniValueType(UniValue::VNUM)},
416  {"change_type", UniValueType(UniValue::VSTR)},
417  {"includeWatching", UniValueType(UniValue::VBOOL)},
418  {"include_watching", UniValueType(UniValue::VBOOL)},
419  {"inputs", UniValueType(UniValue::VARR)},
420  {"lockUnspents", UniValueType(UniValue::VBOOL)},
421  {"lock_unspents", UniValueType(UniValue::VBOOL)},
422  {"locktime", UniValueType(UniValue::VNUM)},
423  {"fee_rate", UniValueType()}, // will be checked by AmountFromValue() in SetFeeEstimateMode()
424  {"feeRate", UniValueType()}, // will be checked by AmountFromValue() below
425  {"psbt", UniValueType(UniValue::VBOOL)},
426  {"solving_data", UniValueType(UniValue::VOBJ)},
427  {"subtractFeeFromOutputs", UniValueType(UniValue::VARR)},
428  {"subtract_fee_from_outputs", UniValueType(UniValue::VARR)},
429  {"replaceable", UniValueType(UniValue::VBOOL)},
430  {"conf_target", UniValueType(UniValue::VNUM)},
431  {"estimate_mode", UniValueType(UniValue::VSTR)},
432  },
433  true, true);
434 
435  if (options.exists("add_inputs") ) {
436  coinControl.m_add_inputs = options["add_inputs"].get_bool();
437  }
438 
439  if (options.exists("changeAddress") || options.exists("change_address")) {
440  const std::string change_address_str = (options.exists("change_address") ? options["change_address"] : options["changeAddress"]).get_str();
441  CTxDestination dest = DecodeDestination(change_address_str);
442 
443  if (!IsValidDestination(dest)) {
444  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Change address must be a valid bitcoin address");
445  }
446 
447  coinControl.destChange = dest;
448  }
449 
450  if (options.exists("changePosition") || options.exists("change_position")) {
451  change_position = (options.exists("change_position") ? options["change_position"] : options["changePosition"]).get_int();
452  }
453 
454  if (options.exists("change_type")) {
455  if (options.exists("changeAddress") || options.exists("change_address")) {
456  throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both change address and address type options");
457  }
458  if (std::optional<OutputType> parsed = ParseOutputType(options["change_type"].get_str())) {
459  coinControl.m_change_type.emplace(parsed.value());
460  } else {
461  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("Unknown change type '%s'", options["change_type"].get_str()));
462  }
463  }
464 
465  const UniValue include_watching_option = options.exists("include_watching") ? options["include_watching"] : options["includeWatching"];
466  coinControl.fAllowWatchOnly = ParseIncludeWatchonly(include_watching_option, wallet);
467 
468  if (options.exists("lockUnspents") || options.exists("lock_unspents")) {
469  lockUnspents = (options.exists("lock_unspents") ? options["lock_unspents"] : options["lockUnspents"]).get_bool();
470  }
471 
472  if (options.exists("include_unsafe")) {
473  coinControl.m_include_unsafe_inputs = options["include_unsafe"].get_bool();
474  }
475 
476  if (options.exists("feeRate")) {
477  if (options.exists("fee_rate")) {
478  throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both fee_rate (" + CURRENCY_ATOM + "/vB) and feeRate (" + CURRENCY_UNIT + "/kvB)");
479  }
480  if (options.exists("conf_target")) {
481  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.");
482  }
483  if (options.exists("estimate_mode")) {
484  throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify both estimate_mode and feeRate");
485  }
486  coinControl.m_feerate = CFeeRate(AmountFromValue(options["feeRate"]));
487  coinControl.fOverrideFeeRate = true;
488  }
489 
490  if (options.exists("subtractFeeFromOutputs") || options.exists("subtract_fee_from_outputs") )
491  subtractFeeFromOutputs = (options.exists("subtract_fee_from_outputs") ? options["subtract_fee_from_outputs"] : options["subtractFeeFromOutputs"]).get_array();
492 
493  if (options.exists("replaceable")) {
494  coinControl.m_signal_bip125_rbf = options["replaceable"].get_bool();
495  }
496  SetFeeEstimateMode(wallet, coinControl, options["conf_target"], options["estimate_mode"], options["fee_rate"], override_min_fee);
497  }
498  } else {
499  // if options is null and not a bool
501  }
502 
503  if (options.exists("solving_data")) {
504  const UniValue solving_data = options["solving_data"].get_obj();
505  if (solving_data.exists("pubkeys")) {
506  for (const UniValue& pk_univ : solving_data["pubkeys"].get_array().getValues()) {
507  const std::string& pk_str = pk_univ.get_str();
508  if (!IsHex(pk_str)) {
509  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("'%s' is not hex", pk_str));
510  }
511  const std::vector<unsigned char> data(ParseHex(pk_str));
512  const CPubKey pubkey(data.begin(), data.end());
513  if (!pubkey.IsFullyValid()) {
514  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("'%s' is not a valid public key", pk_str));
515  }
516  coinControl.m_external_provider.pubkeys.emplace(pubkey.GetID(), pubkey);
517  // Add witness script for pubkeys
518  const CScript wit_script = GetScriptForDestination(WitnessV0KeyHash(pubkey));
519  coinControl.m_external_provider.scripts.emplace(CScriptID(wit_script), wit_script);
520  }
521  }
522 
523  if (solving_data.exists("scripts")) {
524  for (const UniValue& script_univ : solving_data["scripts"].get_array().getValues()) {
525  const std::string& script_str = script_univ.get_str();
526  if (!IsHex(script_str)) {
527  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, strprintf("'%s' is not hex", script_str));
528  }
529  std::vector<unsigned char> script_data(ParseHex(script_str));
530  const CScript script(script_data.begin(), script_data.end());
531  coinControl.m_external_provider.scripts.emplace(CScriptID(script), script);
532  }
533  }
534 
535  if (solving_data.exists("descriptors")) {
536  for (const UniValue& desc_univ : solving_data["descriptors"].get_array().getValues()) {
537  const std::string& desc_str = desc_univ.get_str();
538  FlatSigningProvider desc_out;
539  std::string error;
540  std::vector<CScript> scripts_temp;
541  std::unique_ptr<Descriptor> desc = Parse(desc_str, desc_out, error, true);
542  if (!desc) {
543  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Unable to parse descriptor '%s': %s", desc_str, error));
544  }
545  desc->Expand(0, desc_out, scripts_temp, desc_out);
546  coinControl.m_external_provider = Merge(coinControl.m_external_provider, desc_out);
547  }
548  }
549  }
550 
551  if (tx.vout.size() == 0)
552  throw JSONRPCError(RPC_INVALID_PARAMETER, "TX must have at least one output");
553 
554  if (change_position != -1 && (change_position < 0 || (unsigned int)change_position > tx.vout.size()))
555  throw JSONRPCError(RPC_INVALID_PARAMETER, "changePosition out of bounds");
556 
557  for (unsigned int idx = 0; idx < subtractFeeFromOutputs.size(); idx++) {
558  int pos = subtractFeeFromOutputs[idx].get_int();
559  if (setSubtractFeeFromOutputs.count(pos))
560  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, duplicated position: %d", pos));
561  if (pos < 0)
562  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, negative position: %d", pos));
563  if (pos >= int(tx.vout.size()))
564  throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Invalid parameter, position too large: %d", pos));
565  setSubtractFeeFromOutputs.insert(pos);
566  }
567 
568  // Fetch specified UTXOs from the UTXO set to get the scriptPubKeys and values of the outputs being selected
569  // and to match with the given solving_data. Only used for non-wallet outputs.
570  std::map<COutPoint, Coin> coins;
571  for (const CTxIn& txin : tx.vin) {
572  coins[txin.prevout]; // Create empty map entry keyed by prevout.
573  }
574  wallet.chain().findCoins(coins);
575  for (const auto& coin : coins) {
576  if (!coin.second.out.IsNull()) {
577  coinControl.SelectExternal(coin.first, coin.second.out);
578  }
579  }
580 
582 
583  if (!FundTransaction(wallet, tx, fee_out, change_position, error, lockUnspents, setSubtractFeeFromOutputs, coinControl)) {
584  throw JSONRPCError(RPC_WALLET_ERROR, error.original);
585  }
586 }
587 
589 {
590  return RPCHelpMan{"fundrawtransaction",
591  "\nIf the transaction has no inputs, they will be automatically selected to meet its out value.\n"
592  "It will add at most one change output to the outputs.\n"
593  "No existing outputs will be modified unless \"subtractFeeFromOutputs\" is specified.\n"
594  "Note that inputs which were signed may need to be resigned after completion since in/outputs have been added.\n"
595  "The inputs added will not be signed, use signrawtransactionwithkey\n"
596  "or signrawtransactionwithwallet for that.\n"
597  "All existing inputs must either have their previous output transaction be in the wallet\n"
598  "or be in the UTXO set. Solving data must be provided for non-wallet inputs.\n"
599  "Note that all inputs selected must be of standard form and P2SH scripts must be\n"
600  "in the wallet using importaddress or addmultisigaddress (to calculate fees).\n"
601  "You can see whether this is the case by checking the \"solvable\" field in the listunspent output.\n"
602  "Only pay-to-pubkey, multisig, and P2SH versions thereof are currently supported for watch-only\n",
603  {
604  {"hexstring", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The hex string of the raw transaction"},
605  {"options", RPCArg::Type::OBJ, RPCArg::Optional::OMITTED_NAMED_ARG, "for backward compatibility: passing in a true instead of an object will result in {\"includeWatching\":true}",
606  Cat<std::vector<RPCArg>>(
607  {
608  {"add_inputs", RPCArg::Type::BOOL, RPCArg::Default{true}, "For a transaction with existing inputs, automatically include more if they are not enough."},
609  {"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"
610  "Warning: the resulting transaction may become invalid if one of the unsafe inputs disappears.\n"
611  "If that happens, you will need to fund the transaction with different inputs and republish it."},
612  {"changeAddress", RPCArg::Type::STR, RPCArg::DefaultHint{"pool address"}, "The bitcoin address to receive the change"},
613  {"changePosition", RPCArg::Type::NUM, RPCArg::DefaultHint{"random"}, "The index of the change output"},
614  {"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\", and \"bech32\"."},
615  {"includeWatching", RPCArg::Type::BOOL, RPCArg::DefaultHint{"true for watch-only wallets, otherwise false"}, "Also select inputs which are watch only.\n"
616  "Only solvable inputs can be used. Watch-only destinations are solvable if the public key and/or output script was imported,\n"
617  "e.g. with 'importpubkey' or 'importmulti' with the 'pubkeys' or 'desc' field."},
618  {"lockUnspents", RPCArg::Type::BOOL, RPCArg::Default{false}, "Lock selected unspent outputs"},
619  {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."},
620  {"feeRate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_UNIT + "/kvB."},
621  {"subtractFeeFromOutputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "The integers.\n"
622  "The fee will be equally deducted from the amount of each specified output.\n"
623  "Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
624  "If no outputs are specified here, the sender pays the fee.",
625  {
626  {"vout_index", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The zero-based output index, before a change output is added."},
627  },
628  },
629  },
630  FundTxDoc()),
631  "options"},
632  {"iswitness", RPCArg::Type::BOOL, RPCArg::DefaultHint{"depends on heuristic tests"}, "Whether the transaction hex is a serialized witness transaction.\n"
633  "If iswitness is not present, heuristic tests will be used in decoding.\n"
634  "If true, only witness deserialization will be tried.\n"
635  "If false, only non-witness deserialization will be tried.\n"
636  "This boolean should reflect whether the transaction has inputs\n"
637  "(e.g. fully valid, or on-chain transactions), if known by the caller."
638  },
639  },
640  RPCResult{
641  RPCResult::Type::OBJ, "", "",
642  {
643  {RPCResult::Type::STR_HEX, "hex", "The resulting raw transaction (hex-encoded string)"},
644  {RPCResult::Type::STR_AMOUNT, "fee", "Fee in " + CURRENCY_UNIT + " the resulting transaction pays"},
645  {RPCResult::Type::NUM, "changepos", "The position of the added change output, or -1"},
646  }
647  },
648  RPCExamples{
649  "\nCreate a transaction with no inputs\n"
650  + HelpExampleCli("createrawtransaction", "\"[]\" \"{\\\"myaddress\\\":0.01}\"") +
651  "\nAdd sufficient unsigned inputs to meet the output value\n"
652  + HelpExampleCli("fundrawtransaction", "\"rawtransactionhex\"") +
653  "\nSign the transaction\n"
654  + HelpExampleCli("signrawtransactionwithwallet", "\"fundedtransactionhex\"") +
655  "\nSend the transaction\n"
656  + HelpExampleCli("sendrawtransaction", "\"signedtransactionhex\"")
657  },
658  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
659 {
660  std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
661  if (!pwallet) return NullUniValue;
662 
663  RPCTypeCheck(request.params, {UniValue::VSTR, UniValueType(), UniValue::VBOOL});
664 
665  // parse hex string from parameter
667  bool try_witness = request.params[2].isNull() ? true : request.params[2].get_bool();
668  bool try_no_witness = request.params[2].isNull() ? true : !request.params[2].get_bool();
669  if (!DecodeHexTx(tx, request.params[0].get_str(), try_no_witness, try_witness)) {
670  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
671  }
672 
673  CAmount fee;
674  int change_position;
675  CCoinControl coin_control;
676  // Automatically select (additional) coins. Can be overridden by options.add_inputs.
677  coin_control.m_add_inputs = true;
678  FundTransaction(*pwallet, tx, fee, change_position, request.params[1], coin_control, /* override_min_fee */ true);
679 
680  UniValue result(UniValue::VOBJ);
681  result.pushKV("hex", EncodeHexTx(CTransaction(tx)));
682  result.pushKV("fee", ValueFromAmount(fee));
683  result.pushKV("changepos", change_position);
684 
685  return result;
686 },
687  };
688 }
689 
691 {
692  return RPCHelpMan{"signrawtransactionwithwallet",
693  "\nSign inputs for raw transaction (serialized, hex-encoded).\n"
694  "The second optional argument (may be null) is an array of previous transaction outputs that\n"
695  "this transaction depends on but may not yet be in the block chain." +
697  {
698  {"hexstring", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction hex string"},
699  {"prevtxs", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "The previous dependent transaction outputs",
700  {
702  {
703  {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
704  {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},
705  {"scriptPubKey", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "script key"},
706  {"redeemScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2SH) redeem script"},
707  {"witnessScript", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "(required for P2WSH or P2SH-P2WSH) witness script"},
708  {"amount", RPCArg::Type::AMOUNT, RPCArg::Optional::OMITTED, "(required for Segwit inputs) the amount spent"},
709  },
710  },
711  },
712  },
713  {"sighashtype", RPCArg::Type::STR, RPCArg::Default{"DEFAULT for Taproot, ALL otherwise"}, "The signature hash type. Must be one of\n"
714  " \"DEFAULT\"\n"
715  " \"ALL\"\n"
716  " \"NONE\"\n"
717  " \"SINGLE\"\n"
718  " \"ALL|ANYONECANPAY\"\n"
719  " \"NONE|ANYONECANPAY\"\n"
720  " \"SINGLE|ANYONECANPAY\""},
721  },
722  RPCResult{
723  RPCResult::Type::OBJ, "", "",
724  {
725  {RPCResult::Type::STR_HEX, "hex", "The hex-encoded raw transaction with signature(s)"},
726  {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"},
727  {RPCResult::Type::ARR, "errors", /*optional=*/true, "Script verification errors (if there are any)",
728  {
729  {RPCResult::Type::OBJ, "", "",
730  {
731  {RPCResult::Type::STR_HEX, "txid", "The hash of the referenced, previous transaction"},
732  {RPCResult::Type::NUM, "vout", "The index of the output to spent and used as input"},
733  {RPCResult::Type::ARR, "witness", "",
734  {
735  {RPCResult::Type::STR_HEX, "witness", ""},
736  }},
737  {RPCResult::Type::STR_HEX, "scriptSig", "The hex-encoded signature script"},
738  {RPCResult::Type::NUM, "sequence", "Script sequence number"},
739  {RPCResult::Type::STR, "error", "Verification or signing error related to the input"},
740  }},
741  }},
742  }
743  },
744  RPCExamples{
745  HelpExampleCli("signrawtransactionwithwallet", "\"myhex\"")
746  + HelpExampleRpc("signrawtransactionwithwallet", "\"myhex\"")
747  },
748  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
749 {
750  const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
751  if (!pwallet) return NullUniValue;
752 
753  RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VARR, UniValue::VSTR}, true);
754 
756  if (!DecodeHexTx(mtx, request.params[0].get_str())) {
757  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed. Make sure the tx has at least one input.");
758  }
759 
760  // Sign the transaction
761  LOCK(pwallet->cs_wallet);
762  EnsureWalletIsUnlocked(*pwallet);
763 
764  // Fetch previous transactions (inputs):
765  std::map<COutPoint, Coin> coins;
766  for (const CTxIn& txin : mtx.vin) {
767  coins[txin.prevout]; // Create empty map entry keyed by prevout.
768  }
769  pwallet->chain().findCoins(coins);
770 
771  // Parse the prevtxs array
772  ParsePrevouts(request.params[1], nullptr, coins);
773 
774  int nHashType = ParseSighashString(request.params[2]);
775 
776  // Script verification errors
777  std::map<int, bilingual_str> input_errors;
778 
779  bool complete = pwallet->SignTransaction(mtx, coins, nHashType, input_errors);
780  UniValue result(UniValue::VOBJ);
781  SignTransactionResultToJSON(mtx, complete, coins, input_errors, result);
782  return result;
783 },
784  };
785 }
786 
787 static RPCHelpMan bumpfee_helper(std::string method_name)
788 {
789  const bool want_psbt = method_name == "psbtbumpfee";
790  const std::string incremental_fee{CFeeRate(DEFAULT_INCREMENTAL_RELAY_FEE).ToString(FeeEstimateMode::SAT_VB)};
791 
792  return RPCHelpMan{method_name,
793  "\nBumps the fee of an opt-in-RBF transaction T, replacing it with a new transaction B.\n"
794  + std::string(want_psbt ? "Returns a PSBT instead of creating and signing a new transaction.\n" : "") +
795  "An opt-in RBF transaction with the given txid must be in the wallet.\n"
796  "The command will pay the additional fee by reducing change outputs or adding inputs when necessary.\n"
797  "It may add a new change output if one does not already exist.\n"
798  "All inputs in the original transaction will be included in the replacement transaction.\n"
799  "The command will fail if the wallet or mempool contains a transaction that spends one of T's outputs.\n"
800  "By default, the new fee will be calculated automatically using the estimatesmartfee RPC.\n"
801  "The user can specify a confirmation target for estimatesmartfee.\n"
802  "Alternatively, the user can specify a fee rate in " + CURRENCY_ATOM + "/vB for the new transaction.\n"
803  "At a minimum, the new fee rate must be high enough to pay an additional new relay fee (incrementalfee\n"
804  "returned by getnetworkinfo) to enter the node's mempool.\n"
805  "* WARNING: before version 0.21, fee_rate was in " + CURRENCY_UNIT + "/kvB. As of 0.21, fee_rate is in " + CURRENCY_ATOM + "/vB. *\n",
806  {
807  {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The txid to be bumped"},
809  {
810  {"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks\n"},
811  {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"},
812  "\nSpecify a fee rate in " + CURRENCY_ATOM + "/vB instead of relying on the built-in fee estimator.\n"
813  "Must be at least " + incremental_fee + " higher than the current transaction fee rate.\n"
814  "WARNING: before version 0.21, fee_rate was in " + CURRENCY_UNIT + "/kvB. As of 0.21, fee_rate is in " + CURRENCY_ATOM + "/vB.\n"},
815  {"replaceable", RPCArg::Type::BOOL, RPCArg::Default{true}, "Whether the new transaction should still be\n"
816  "marked bip-125 replaceable. If true, the sequence numbers in the transaction will\n"
817  "be left unchanged from the original. If false, any input sequence numbers in the\n"
818  "original transaction that were less than 0xfffffffe will be increased to 0xfffffffe\n"
819  "so the new transaction will not be explicitly bip-125 replaceable (though it may\n"
820  "still be replaceable in practice, for example if it has unconfirmed ancestors which\n"
821  "are replaceable).\n"},
822  {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, "The fee estimate mode, must be one of (case insensitive):\n"
823  "\"" + FeeModes("\"\n\"") + "\""},
824  },
825  "options"},
826  },
827  RPCResult{
828  RPCResult::Type::OBJ, "", "", Cat(
829  want_psbt ?
830  std::vector<RPCResult>{{RPCResult::Type::STR, "psbt", "The base64-encoded unsigned PSBT of the new transaction."}} :
831  std::vector<RPCResult>{{RPCResult::Type::STR_HEX, "txid", "The id of the new transaction."}},
832  {
833  {RPCResult::Type::STR_AMOUNT, "origfee", "The fee of the replaced transaction."},
834  {RPCResult::Type::STR_AMOUNT, "fee", "The fee of the new transaction."},
835  {RPCResult::Type::ARR, "errors", "Errors encountered during processing (may be empty).",
836  {
837  {RPCResult::Type::STR, "", ""},
838  }},
839  })
840  },
841  RPCExamples{
842  "\nBump the fee, get the new transaction\'s " + std::string(want_psbt ? "psbt" : "txid") + "\n" +
843  HelpExampleCli(method_name, "<txid>")
844  },
845  [want_psbt](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
846 {
847  std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
848  if (!pwallet) return NullUniValue;
849 
850  if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && !want_psbt) {
851  throw JSONRPCError(RPC_WALLET_ERROR, "bumpfee is not available with wallets that have private keys disabled. Use psbtbumpfee instead.");
852  }
853 
854  RPCTypeCheck(request.params, {UniValue::VSTR, UniValue::VOBJ});
855  uint256 hash(ParseHashV(request.params[0], "txid"));
856 
857  CCoinControl coin_control;
858  coin_control.fAllowWatchOnly = pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS);
859  // optional parameters
860  coin_control.m_signal_bip125_rbf = true;
861 
862  if (!request.params[1].isNull()) {
863  UniValue options = request.params[1];
864  RPCTypeCheckObj(options,
865  {
866  {"confTarget", UniValueType(UniValue::VNUM)},
867  {"conf_target", UniValueType(UniValue::VNUM)},
868  {"fee_rate", UniValueType()}, // will be checked by AmountFromValue() in SetFeeEstimateMode()
869  {"replaceable", UniValueType(UniValue::VBOOL)},
870  {"estimate_mode", UniValueType(UniValue::VSTR)},
871  },
872  true, true);
873 
874  if (options.exists("confTarget") && options.exists("conf_target")) {
875  throw JSONRPCError(RPC_INVALID_PARAMETER, "confTarget and conf_target options should not both be set. Use conf_target (confTarget is deprecated).");
876  }
877 
878  auto conf_target = options.exists("confTarget") ? options["confTarget"] : options["conf_target"];
879 
880  if (options.exists("replaceable")) {
881  coin_control.m_signal_bip125_rbf = options["replaceable"].get_bool();
882  }
883  SetFeeEstimateMode(*pwallet, coin_control, conf_target, options["estimate_mode"], options["fee_rate"], /* override_min_fee */ false);
884  }
885 
886  // Make sure the results are valid at least up to the most recent block
887  // the user could have gotten from another RPC command prior to now
888  pwallet->BlockUntilSyncedToCurrentChain();
889 
890  LOCK(pwallet->cs_wallet);
891 
892  EnsureWalletIsUnlocked(*pwallet);
893 
894 
895  std::vector<bilingual_str> errors;
896  CAmount old_fee;
897  CAmount new_fee;
899  feebumper::Result res;
900  // Targeting feerate bump.
901  res = feebumper::CreateRateBumpTransaction(*pwallet, hash, coin_control, errors, old_fee, new_fee, mtx);
902  if (res != feebumper::Result::OK) {
903  switch(res) {
905  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, errors[0].original);
906  break;
908  throw JSONRPCError(RPC_INVALID_REQUEST, errors[0].original);
909  break;
911  throw JSONRPCError(RPC_INVALID_PARAMETER, errors[0].original);
912  break;
914  throw JSONRPCError(RPC_WALLET_ERROR, errors[0].original);
915  break;
916  default:
917  throw JSONRPCError(RPC_MISC_ERROR, errors[0].original);
918  break;
919  }
920  }
921 
922  UniValue result(UniValue::VOBJ);
923 
924  // For bumpfee, return the new transaction id.
925  // For psbtbumpfee, return the base64-encoded unsigned PSBT of the new transaction.
926  if (!want_psbt) {
927  if (!feebumper::SignTransaction(*pwallet, mtx)) {
928  throw JSONRPCError(RPC_WALLET_ERROR, "Can't sign transaction.");
929  }
930 
931  uint256 txid;
932  if (feebumper::CommitTransaction(*pwallet, hash, std::move(mtx), errors, txid) != feebumper::Result::OK) {
933  throw JSONRPCError(RPC_WALLET_ERROR, errors[0].original);
934  }
935 
936  result.pushKV("txid", txid.GetHex());
937  } else {
938  PartiallySignedTransaction psbtx(mtx);
939  bool complete = false;
940  const TransactionError err = pwallet->FillPSBT(psbtx, complete, SIGHASH_DEFAULT, false /* sign */, true /* bip32derivs */);
942  CHECK_NONFATAL(!complete);
944  ssTx << psbtx;
945  result.pushKV("psbt", EncodeBase64(ssTx.str()));
946  }
947 
948  result.pushKV("origfee", ValueFromAmount(old_fee));
949  result.pushKV("fee", ValueFromAmount(new_fee));
950  UniValue result_errors(UniValue::VARR);
951  for (const bilingual_str& error : errors) {
952  result_errors.push_back(error.original);
953  }
954  result.pushKV("errors", result_errors);
955 
956  return result;
957 },
958  };
959 }
960 
961 RPCHelpMan bumpfee() { return bumpfee_helper("bumpfee"); }
962 RPCHelpMan psbtbumpfee() { return bumpfee_helper("psbtbumpfee"); }
963 
965 {
966  return RPCHelpMan{"send",
967  "\nEXPERIMENTAL warning: this call may be changed in future releases.\n"
968  "\nSend a transaction.\n",
969  {
970  {"outputs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The outputs (key-value pairs), where none of the keys are duplicated.\n"
971  "That is, each address can only appear once and there can only be one 'data' object.\n"
972  "For convenience, a dictionary, which holds the key-value pairs directly, is also accepted.",
973  {
975  {
976  {"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 + ""},
977  },
978  },
980  {
981  {"data", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "A key-value pair. The key must be \"data\", the value is hex-encoded data"},
982  },
983  },
984  },
985  },
986  {"conf_target", RPCArg::Type::NUM, RPCArg::DefaultHint{"wallet -txconfirmtarget"}, "Confirmation target in blocks"},
987  {"estimate_mode", RPCArg::Type::STR, RPCArg::Default{"unset"}, std::string() + "The fee estimate mode, must be one of (case insensitive):\n"
988  " \"" + FeeModes("\"\n\"") + "\""},
989  {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."},
991  Cat<std::vector<RPCArg>>(
992  {
993  {"add_inputs", RPCArg::Type::BOOL, RPCArg::Default{false}, "If inputs are specified, automatically include more if they are not enough."},
994  {"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"
995  "Warning: the resulting transaction may become invalid if one of the unsafe inputs disappears.\n"
996  "If that happens, you will need to fund the transaction with different inputs and republish it."},
997  {"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"},
998  {"change_address", RPCArg::Type::STR_HEX, RPCArg::DefaultHint{"pool address"}, "The bitcoin address to receive the change"},
999  {"change_position", RPCArg::Type::NUM, RPCArg::DefaultHint{"random"}, "The index of the change output"},
1000  {"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\", and \"bech32\"."},
1001  {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."},
1002  {"include_watching", RPCArg::Type::BOOL, RPCArg::DefaultHint{"true for watch-only wallets, otherwise false"}, "Also select inputs which are watch only.\n"
1003  "Only solvable inputs can be used. Watch-only destinations are solvable if the public key and/or output script was imported,\n"
1004  "e.g. with 'importpubkey' or 'importmulti' with the 'pubkeys' or 'desc' field."},
1005  {"inputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Specify inputs instead of adding them automatically. A JSON array of JSON objects",
1006  {
1007  {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
1008  {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},
1009  {"sequence", RPCArg::Type::NUM, RPCArg::Optional::NO, "The sequence number"},
1010  },
1011  },
1012  {"locktime", RPCArg::Type::NUM, RPCArg::Default{0}, "Raw locktime. Non-0 value also locktime-activates inputs"},
1013  {"lock_unspents", RPCArg::Type::BOOL, RPCArg::Default{false}, "Lock selected unspent outputs"},
1014  {"psbt", RPCArg::Type::BOOL, RPCArg::DefaultHint{"automatic"}, "Always return a PSBT, implies add_to_wallet=false."},
1015  {"subtract_fee_from_outputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "Outputs to subtract the fee from, specified as integer indices.\n"
1016  "The fee will be equally deducted from the amount of each specified output.\n"
1017  "Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
1018  "If no outputs are specified here, the sender pays the fee.",
1019  {
1020  {"vout_index", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The zero-based output index, before a change output is added."},
1021  },
1022  },
1023  },
1024  FundTxDoc()),
1025  "options"},
1026  },
1027  RPCResult{
1028  RPCResult::Type::OBJ, "", "",
1029  {
1030  {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"},
1031  {RPCResult::Type::STR_HEX, "txid", /*optional=*/true, "The transaction id for the send. Only 1 transaction is created regardless of the number of addresses."},
1032  {RPCResult::Type::STR_HEX, "hex", /*optional=*/true, "If add_to_wallet is false, the hex-encoded raw transaction with signature(s)"},
1033  {RPCResult::Type::STR, "psbt", /*optional=*/true, "If more signatures are needed, or if add_to_wallet is false, the base64-encoded (partially) signed transaction"}
1034  }
1035  },
1036  RPCExamples{""
1037  "\nSend 0.1 BTC with a confirmation target of 6 blocks in economical fee estimate mode\n"
1038  + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.1}' 6 economical\n") +
1039  "Send 0.2 BTC with a fee rate of 1.1 " + CURRENCY_ATOM + "/vB using positional arguments\n"
1040  + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.2}' null \"unset\" 1.1\n") +
1041  "Send 0.2 BTC with a fee rate of 1 " + CURRENCY_ATOM + "/vB using the options argument\n"
1042  + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.2}' null \"unset\" null '{\"fee_rate\": 1}'\n") +
1043  "Send 0.3 BTC with a fee rate of 25 " + CURRENCY_ATOM + "/vB using named arguments\n"
1044  + HelpExampleCli("-named send", "outputs='{\"" + EXAMPLE_ADDRESS[0] + "\": 0.3}' fee_rate=25\n") +
1045  "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"
1046  + HelpExampleCli("send", "'{\"" + EXAMPLE_ADDRESS[0] + "\": 0.1}' 1 economical '{\"add_to_wallet\": false, \"inputs\": [{\"txid\":\"a08e6907dbbd3d809776dbfc5d82e371b764ed838b5655e72f463568df1aadf0\", \"vout\":1}]}'")
1047  },
1048  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1049  {
1050  RPCTypeCheck(request.params, {
1051  UniValueType(), // outputs (ARR or OBJ, checked later)
1052  UniValue::VNUM, // conf_target
1053  UniValue::VSTR, // estimate_mode
1054  UniValueType(), // fee_rate, will be checked by AmountFromValue() in SetFeeEstimateMode()
1055  UniValue::VOBJ, // options
1056  }, true
1057  );
1058 
1059  std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
1060  if (!pwallet) return NullUniValue;
1061 
1062  UniValue options{request.params[4].isNull() ? UniValue::VOBJ : request.params[4]};
1063  if (options.exists("conf_target") || options.exists("estimate_mode")) {
1064  if (!request.params[1].isNull() || !request.params[2].isNull()) {
1065  throw JSONRPCError(RPC_INVALID_PARAMETER, "Pass conf_target and estimate_mode either as arguments or in the options object, but not both");
1066  }
1067  } else {
1068  options.pushKV("conf_target", request.params[1]);
1069  options.pushKV("estimate_mode", request.params[2]);
1070  }
1071  if (options.exists("fee_rate")) {
1072  if (!request.params[3].isNull()) {
1073  throw JSONRPCError(RPC_INVALID_PARAMETER, "Pass the fee_rate either as an argument, or in the options object, but not both");
1074  }
1075  } else {
1076  options.pushKV("fee_rate", request.params[3]);
1077  }
1078  if (!options["conf_target"].isNull() && (options["estimate_mode"].isNull() || (options["estimate_mode"].get_str() == "unset"))) {
1079  throw JSONRPCError(RPC_INVALID_PARAMETER, "Specify estimate_mode");
1080  }
1081  if (options.exists("feeRate")) {
1082  throw JSONRPCError(RPC_INVALID_PARAMETER, "Use fee_rate (" + CURRENCY_ATOM + "/vB) instead of feeRate");
1083  }
1084  if (options.exists("changeAddress")) {
1085  throw JSONRPCError(RPC_INVALID_PARAMETER, "Use change_address");
1086  }
1087  if (options.exists("changePosition")) {
1088  throw JSONRPCError(RPC_INVALID_PARAMETER, "Use change_position");
1089  }
1090  if (options.exists("includeWatching")) {
1091  throw JSONRPCError(RPC_INVALID_PARAMETER, "Use include_watching");
1092  }
1093  if (options.exists("lockUnspents")) {
1094  throw JSONRPCError(RPC_INVALID_PARAMETER, "Use lock_unspents");
1095  }
1096  if (options.exists("subtractFeeFromOutputs")) {
1097  throw JSONRPCError(RPC_INVALID_PARAMETER, "Use subtract_fee_from_outputs");
1098  }
1099 
1100  const bool psbt_opt_in = options.exists("psbt") && options["psbt"].get_bool();
1101 
1102  CAmount fee;
1103  int change_position;
1104  bool rbf = pwallet->m_signal_rbf;
1105  if (options.exists("replaceable")) {
1106  rbf = options["replaceable"].get_bool();
1107  }
1108  CMutableTransaction rawTx = ConstructTransaction(options["inputs"], request.params[0], options["locktime"], rbf);
1109  CCoinControl coin_control;
1110  // Automatically select coins, unless at least one is manually selected. Can
1111  // be overridden by options.add_inputs.
1112  coin_control.m_add_inputs = rawTx.vin.size() == 0;
1113  FundTransaction(*pwallet, rawTx, fee, change_position, options, coin_control, /* override_min_fee */ false);
1114 
1115  bool add_to_wallet = true;
1116  if (options.exists("add_to_wallet")) {
1117  add_to_wallet = options["add_to_wallet"].get_bool();
1118  }
1119 
1120  // Make a blank psbt
1121  PartiallySignedTransaction psbtx(rawTx);
1122 
1123  // First fill transaction with our data without signing,
1124  // so external signers are not asked sign more than once.
1125  bool complete;
1126  pwallet->FillPSBT(psbtx, complete, SIGHASH_DEFAULT, false, true);
1127  const TransactionError err = pwallet->FillPSBT(psbtx, complete, SIGHASH_DEFAULT, true, false);
1128  if (err != TransactionError::OK) {
1129  throw JSONRPCTransactionError(err);
1130  }
1131 
1132  CMutableTransaction mtx;
1133  complete = FinalizeAndExtractPSBT(psbtx, mtx);
1134 
1135  UniValue result(UniValue::VOBJ);
1136 
1137  if (psbt_opt_in || !complete || !add_to_wallet) {
1138  // Serialize the PSBT
1140  ssTx << psbtx;
1141  result.pushKV("psbt", EncodeBase64(ssTx.str()));
1142  }
1143 
1144  if (complete) {
1145  std::string err_string;
1146  std::string hex = EncodeHexTx(CTransaction(mtx));
1147  CTransactionRef tx(MakeTransactionRef(std::move(mtx)));
1148  result.pushKV("txid", tx->GetHash().GetHex());
1149  if (add_to_wallet && !psbt_opt_in) {
1150  pwallet->CommitTransaction(tx, {}, {} /* orderForm */);
1151  } else {
1152  result.pushKV("hex", hex);
1153  }
1154  }
1155  result.pushKV("complete", complete);
1156 
1157  return result;
1158  }
1159  };
1160 }
1161 
1163 {
1164  return RPCHelpMan{"walletprocesspsbt",
1165  "\nUpdate a PSBT with input information from our wallet and then sign inputs\n"
1166  "that we can sign for." +
1168  {
1169  {"psbt", RPCArg::Type::STR, RPCArg::Optional::NO, "The transaction base64 string"},
1170  {"sign", RPCArg::Type::BOOL, RPCArg::Default{true}, "Also sign the transaction when updating (requires wallet to be unlocked)"},
1171  {"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"
1172  " \"DEFAULT\"\n"
1173  " \"ALL\"\n"
1174  " \"NONE\"\n"
1175  " \"SINGLE\"\n"
1176  " \"ALL|ANYONECANPAY\"\n"
1177  " \"NONE|ANYONECANPAY\"\n"
1178  " \"SINGLE|ANYONECANPAY\""},
1179  {"bip32derivs", RPCArg::Type::BOOL, RPCArg::Default{true}, "Include BIP 32 derivation paths for public keys if we know them"},
1180  {"finalize", RPCArg::Type::BOOL, RPCArg::Default{true}, "Also finalize inputs if possible"},
1181  },
1182  RPCResult{
1183  RPCResult::Type::OBJ, "", "",
1184  {
1185  {RPCResult::Type::STR, "psbt", "The base64-encoded partially signed transaction"},
1186  {RPCResult::Type::BOOL, "complete", "If the transaction has a complete set of signatures"},
1187  }
1188  },
1189  RPCExamples{
1190  HelpExampleCli("walletprocesspsbt", "\"psbt\"")
1191  },
1192  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1193 {
1194  const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
1195  if (!pwallet) return NullUniValue;
1196 
1197  const CWallet& wallet{*pwallet};
1198  // Make sure the results are valid at least up to the most recent block
1199  // the user could have gotten from another RPC command prior to now
1200  wallet.BlockUntilSyncedToCurrentChain();
1201 
1202  RPCTypeCheck(request.params, {UniValue::VSTR});
1203 
1204  // Unserialize the transaction
1206  std::string error;
1207  if (!DecodeBase64PSBT(psbtx, request.params[0].get_str(), error)) {
1208  throw JSONRPCError(RPC_DESERIALIZATION_ERROR, strprintf("TX decode failed %s", error));
1209  }
1210 
1211  // Get the sighash type
1212  int nHashType = ParseSighashString(request.params[2]);
1213 
1214  // Fill transaction with our data and also sign
1215  bool sign = request.params[1].isNull() ? true : request.params[1].get_bool();
1216  bool bip32derivs = request.params[3].isNull() ? true : request.params[3].get_bool();
1217  bool finalize = request.params[4].isNull() ? true : request.params[4].get_bool();
1218  bool complete = true;
1219 
1220  if (sign) EnsureWalletIsUnlocked(*pwallet);
1221 
1222  const TransactionError err{wallet.FillPSBT(psbtx, complete, nHashType, sign, bip32derivs, nullptr, finalize)};
1223  if (err != TransactionError::OK) {
1224  throw JSONRPCTransactionError(err);
1225  }
1226 
1227  UniValue result(UniValue::VOBJ);
1229  ssTx << psbtx;
1230  result.pushKV("psbt", EncodeBase64(ssTx.str()));
1231  result.pushKV("complete", complete);
1232 
1233  return result;
1234 },
1235  };
1236 }
1237 
1239 {
1240  return RPCHelpMan{"walletcreatefundedpsbt",
1241  "\nCreates and funds a transaction in the Partially Signed Transaction format.\n"
1242  "Implements the Creator and Updater roles.\n"
1243  "All existing inputs must either have their previous output transaction be in the wallet\n"
1244  "or be in the UTXO set. Solving data must be provided for non-wallet inputs.\n",
1245  {
1246  {"inputs", RPCArg::Type::ARR, RPCArg::Optional::OMITTED_NAMED_ARG, "Leave empty to add inputs automatically. See add_inputs option.",
1247  {
1249  {
1250  {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "The transaction id"},
1251  {"vout", RPCArg::Type::NUM, RPCArg::Optional::NO, "The output number"},
1252  {"sequence", RPCArg::Type::NUM, RPCArg::DefaultHint{"depends on the value of the 'locktime' and 'options.replaceable' arguments"}, "The sequence number"},
1253  },
1254  },
1255  },
1256  },
1257  {"outputs", RPCArg::Type::ARR, RPCArg::Optional::NO, "The outputs (key-value pairs), where none of the keys are duplicated.\n"
1258  "That is, each address can only appear once and there can only be one 'data' object.\n"
1259  "For compatibility reasons, a dictionary, which holds the key-value pairs directly, is also\n"
1260  "accepted as second parameter.",
1261  {
1263  {
1264  {"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 + ""},
1265  },
1266  },
1268  {
1269  {"data", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, "A key-value pair. The key must be \"data\", the value is hex-encoded data"},
1270  },
1271  },
1272  },
1273  },
1274  {"locktime", RPCArg::Type::NUM, RPCArg::Default{0}, "Raw locktime. Non-0 value also locktime-activates inputs"},
1276  Cat<std::vector<RPCArg>>(
1277  {
1278  {"add_inputs", RPCArg::Type::BOOL, RPCArg::Default{false}, "If inputs are specified, automatically include more if they are not enough."},
1279  {"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"
1280  "Warning: the resulting transaction may become invalid if one of the unsafe inputs disappears.\n"
1281  "If that happens, you will need to fund the transaction with different inputs and republish it."},
1282  {"changeAddress", RPCArg::Type::STR_HEX, RPCArg::DefaultHint{"pool address"}, "The bitcoin address to receive the change"},
1283  {"changePosition", RPCArg::Type::NUM, RPCArg::DefaultHint{"random"}, "The index of the change output"},
1284  {"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\", and \"bech32\"."},
1285  {"includeWatching", RPCArg::Type::BOOL, RPCArg::DefaultHint{"true for watch-only wallets, otherwise false"}, "Also select inputs which are watch only"},
1286  {"lockUnspents", RPCArg::Type::BOOL, RPCArg::Default{false}, "Lock selected unspent outputs"},
1287  {"fee_rate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_ATOM + "/vB."},
1288  {"feeRate", RPCArg::Type::AMOUNT, RPCArg::DefaultHint{"not set, fall back to wallet fee estimation"}, "Specify a fee rate in " + CURRENCY_UNIT + "/kvB."},
1289  {"subtractFeeFromOutputs", RPCArg::Type::ARR, RPCArg::Default{UniValue::VARR}, "The outputs to subtract the fee from.\n"
1290  "The fee will be equally deducted from the amount of each specified output.\n"
1291  "Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
1292  "If no outputs are specified here, the sender pays the fee.",
1293  {
1294  {"vout_index", RPCArg::Type::NUM, RPCArg::Optional::OMITTED, "The zero-based output index, before a change output is added."},
1295  },
1296  },
1297  },
1298  FundTxDoc()),
1299  "options"},
1300  {"bip32derivs", RPCArg::Type::BOOL, RPCArg::Default{true}, "Include BIP 32 derivation paths for public keys if we know them"},
1301  },
1302  RPCResult{
1303  RPCResult::Type::OBJ, "", "",
1304  {
1305  {RPCResult::Type::STR, "psbt", "The resulting raw transaction (base64-encoded string)"},
1306  {RPCResult::Type::STR_AMOUNT, "fee", "Fee in " + CURRENCY_UNIT + " the resulting transaction pays"},
1307  {RPCResult::Type::NUM, "changepos", "The position of the added change output, or -1"},
1308  }
1309  },
1310  RPCExamples{
1311  "\nCreate a transaction with no inputs\n"
1312  + HelpExampleCli("walletcreatefundedpsbt", "\"[{\\\"txid\\\":\\\"myid\\\",\\\"vout\\\":0}]\" \"[{\\\"data\\\":\\\"00010203\\\"}]\"")
1313  },
1314  [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
1315 {
1316  std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
1317  if (!pwallet) return NullUniValue;
1318 
1319  CWallet& wallet{*pwallet};
1320  // Make sure the results are valid at least up to the most recent block
1321  // the user could have gotten from another RPC command prior to now
1322  wallet.BlockUntilSyncedToCurrentChain();
1323 
1324  RPCTypeCheck(request.params, {
1325  UniValue::VARR,
1326  UniValueType(), // ARR or OBJ, checked later
1327  UniValue::VNUM,
1328  UniValue::VOBJ,
1329  UniValue::VBOOL
1330  }, true
1331  );
1332 
1333  CAmount fee;
1334  int change_position;
1335  bool rbf{wallet.m_signal_rbf};
1336  const UniValue &replaceable_arg = request.params[3]["replaceable"];
1337  if (!replaceable_arg.isNull()) {
1338  RPCTypeCheckArgument(replaceable_arg, UniValue::VBOOL);
1339  rbf = replaceable_arg.isTrue();
1340  }
1341  CMutableTransaction rawTx = ConstructTransaction(request.params[0], request.params[1], request.params[2], rbf);
1342  CCoinControl coin_control;
1343  // Automatically select coins, unless at least one is manually selected. Can
1344  // be overridden by options.add_inputs.
1345  coin_control.m_add_inputs = rawTx.vin.size() == 0;
1346  FundTransaction(wallet, rawTx, fee, change_position, request.params[3], coin_control, /* override_min_fee */ true);
1347 
1348  // Make a blank psbt
1349  PartiallySignedTransaction psbtx(rawTx);
1350 
1351  // Fill transaction with out data but don't sign
1352  bool bip32derivs = request.params[4].isNull() ? true : request.params[4].get_bool();
1353  bool complete = true;
1354  const TransactionError err{wallet.FillPSBT(psbtx, complete, 1, false, bip32derivs)};
1355  if (err != TransactionError::OK) {
1356  throw JSONRPCTransactionError(err);
1357  }
1358 
1359  // Serialize the PSBT
1361  ssTx << psbtx;
1362 
1363  UniValue result(UniValue::VOBJ);
1364  result.pushKV("psbt", EncodeBase64(ssTx.str()));
1365  result.pushKV("fee", ValueFromAmount(fee));
1366  result.pushKV("changepos", change_position);
1367  return result;
1368 },
1369  };
1370 }
1371 } // namespace wallet
RPC_INVALID_REQUEST
@ RPC_INVALID_REQUEST
Standard JSON-RPC 2.0 errors.
Definition: protocol.h:28
CTxIn
An input of a transaction.
Definition: transaction.h:65
RPC_MISC_ERROR
@ RPC_MISC_ERROR
General application defined errors.
Definition: protocol.h:39
wallet::walletcreatefundedpsbt
RPCHelpMan walletcreatefundedpsbt()
Definition: spend.cpp:1238
policy.h
CMutableTransaction::vin
std::vector< CTxIn > vin
Definition: transaction.h:346
wallet::feebumper::Result::INVALID_ADDRESS_OR_KEY
@ INVALID_ADDRESS_OR_KEY
Parse
std::unique_ptr< Descriptor > Parse(const std::string &descriptor, FlatSigningProvider &out, std::string &error, bool require_checksum)
Parse a descriptor string.
Definition: descriptor.cpp:1394
FeeModeFromString
bool FeeModeFromString(const std::string &mode_string, FeeEstimateMode &fee_estimate_mode)
Definition: fees.cpp:57
HelpExampleCli
std::string HelpExampleCli(const std::string &methodname, const std::string &args)
Definition: util.cpp:156
ParseHex
std::vector< unsigned char > ParseHex(const char *psz)
Definition: strencodings.cpp:84
UniValue::VOBJ
@ VOBJ
Definition: univalue.h:19
UniValue::get_bool
bool get_bool() const
Definition: univalue_get.cpp:91
ParseConfirmTarget
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:330
wallet.h
CHECK_NONFATAL
#define CHECK_NONFATAL(condition)
Throw a NonFatalCheckError when the condition evaluates to false.
Definition: check.h:32
key_io.h
wallet::SendMoney
UniValue SendMoney(CWallet &wallet, const CCoinControl &coin_control, std::vector< CRecipient > &recipients, mapValue_t map_value, bool verbose)
Definition: spend.cpp:53
RPCHelpMan
Definition: util.h:345
Cat
V Cat(V v1, V &&v2)
Concatenate two vectors, moving elements.
Definition: vector.h:31
NullUniValue
const UniValue NullUniValue
Definition: univalue.cpp:13
GetScriptForDestination
CScript GetScriptForDestination(const CTxDestination &dest)
Generate a Bitcoin scriptPubKey for the given CTxDestination.
Definition: standard.cpp:310
wallet::fundrawtransaction
RPCHelpMan fundrawtransaction()
Definition: spend.cpp:588
bilingual_str
Bilingual messages:
Definition: translation.h:16
RPC_INVALID_PARAMETER
@ RPC_INVALID_PARAMETER
Invalid, missing or duplicate parameter.
Definition: protocol.h:43
IsHex
bool IsHex(const std::string &str)
Definition: strencodings.cpp:61
ParseHashV
uint256 ParseHashV(const UniValue &v, std::string strName)
Utilities: convert hex-encoded Values (throws error if not hex).
Definition: util.cpp:90
wallet::feebumper::Result
Result
Definition: feebumper.h:21
RPCArg::Optional::NO
@ NO
Required arg.
RPCArg::Type::STR
@ STR
RPCArg::Type::ARR
@ ARR
wallet::CRecipient
Definition: wallet.h:221
wallet::GetWalletForJSONRPCRequest
std::shared_ptr< CWallet > GetWalletForJSONRPCRequest(const JSONRPCRequest &request)
Figures out what wallet, if any, to use for a JSONRPCRequest.
Definition: util.cpp:55
MakeTransactionRef
static CTransactionRef MakeTransactionRef(Tx &&txIn)
Definition: transaction.h:387
wallet::FundTxDoc
static std::vector< RPCArg > FundTxDoc()
Definition: spend.cpp:362
RPCResult::Type::NUM
@ NUM
wallet::bumpfee
RPCHelpMan bumpfee()
Definition: spend.cpp:961
Merge
FlatSigningProvider Merge(const FlatSigningProvider &a, const FlatSigningProvider &b)
Definition: signingprovider.cpp:67
wallet::CCoinControl::m_confirm_target
std::optional< unsigned int > m_confirm_target
Override the default confirmation target if set.
Definition: coincontrol.h:49
wallet
Definition: node.h:38
wallet::CCoinControl::fAllowWatchOnly
bool fAllowWatchOnly
Includes watch only addresses which are solvable.
Definition: coincontrol.h:43
UniValue::isNull
bool isNull() const
Definition: univalue.h:75
EncodeBase64
std::string EncodeBase64(Span< const unsigned char > input)
Definition: strencodings.cpp:131
RPCTypeCheckObj
void RPCTypeCheckObj(const UniValue &o, const std::map< std::string, UniValueType > &typesExpected, bool fAllowNull, bool fStrict)
Definition: util.cpp:48
FinalizeAndExtractPSBT
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:348
RPCArg::Type::OBJ_USER_KEYS
@ OBJ_USER_KEYS
Special type where the user must set the keys e.g. to define multiple addresses; as opposed to e....
CTransactionRef
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:386
RPCTypeCheckArgument
void RPCTypeCheckArgument(const UniValue &value, const UniValueType &typeExpected)
Type-check one argument; throws JSONRPCError if wrong type given.
Definition: util.cpp:41
core_io.h
UniValue::pushKV
bool pushKV(const std::string &key, const UniValue &val)
Definition: univalue.cpp:133
CFeeRate
Fee rate in satoshis per kilobyte: CAmount / kB.
Definition: feerate.h:29
DecodeBase64PSBT
bool DecodeBase64PSBT(PartiallySignedTransaction &psbt, const std::string &base64_tx, std::string &error)
Decode a base64ed PSBT into a PartiallySignedTransaction.
Definition: psbt.cpp:389
ValueFromAmount
UniValue ValueFromAmount(const CAmount amount)
Definition: core_write.cpp:21
wallet::CCoinControl::m_add_inputs
bool m_add_inputs
If false, only selected inputs are used.
Definition: coincontrol.h:37
UniValue
Definition: univalue.h:17
CTransaction
The basic transaction that is broadcasted on the network and contained in blocks.
Definition: transaction.h:259
WitnessV0KeyHash
Definition: standard.h:109
FlatSigningProvider::scripts
std::map< CScriptID, CScript > scripts
Definition: signingprovider.h:74
RPCArg::Type::NUM
@ NUM
UniValue::type
enum VType type() const
Definition: univalue.h:179
wallet::HELP_REQUIRING_PASSPHRASE
const std::string HELP_REQUIRING_PASSPHRASE
Definition: util.cpp:17
FeeCalculation::reason
FeeReason reason
Definition: fees.h:78
ParsePrevouts
void ParsePrevouts(const UniValue &prevTxsUnival, FillableSigningProvider *keystore, std::map< COutPoint, Coin > &coins)
Parse a prevtxs UniValue array and get the map of coins from it.
Definition: rawtransaction_util.cpp:159
UniValue::get_str
const std::string & get_str() const
Definition: univalue_get.cpp:98
RPC_DESERIALIZATION_ERROR
@ RPC_DESERIALIZATION_ERROR
Error parsing or validating structure in raw format.
Definition: protocol.h:45
UniValueType
Wrapper for UniValue::VType, which includes typeAny: Used to denote don't care type.
Definition: util.h:44
wallet::feebumper::Result::INVALID_PARAMETER
@ INVALID_PARAMETER
TransactionError
TransactionError
Definition: error.h:22
DEFAULT_INCREMENTAL_RELAY_FEE
static const unsigned int DEFAULT_INCREMENTAL_RELAY_FEE
Default for -incrementalrelayfee, which sets the minimum feerate increase for mempool limiting or BIP...
Definition: policy.h:34
FeeCalculation
Definition: fees.h:75
prevector::push_back
void push_back(const T &value)
Definition: prevector.h:437
CURRENCY_UNIT
const std::string CURRENCY_UNIT
Definition: feerate.h:14
RPCArg::Type::OBJ
@ OBJ
UniValue::get_obj
const UniValue & get_obj() const
Definition: univalue_get.cpp:135
util.h
FeeEstimateMode::SAT_VB
@ SAT_VB
Use sat/vB fee rate unit.
CTxDestination
std::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:157
RPCArg::DefaultHint
std::string DefaultHint
Definition: util.h:155
IsValidDestination
bool IsValidDestination(const CTxDestination &dest)
Check whether a CTxDestination is a CNoDestination.
Definition: standard.cpp:332
wallet::feebumper::CommitTransaction
Result CommitTransaction(CWallet &wallet, const uint256 &txid, CMutableTransaction &&mtx, std::vector< bilingual_str > &errors, uint256 &bumped_txid)
Commit the bumpfee transaction.
Definition: feebumper.cpp:251
RPCArg::Optional::OMITTED_NAMED_ARG
@ OMITTED_NAMED_ARG
Optional arg that is a named argument and has a default value of null.
wallet::CCoinControl::destChange
CTxDestination destChange
Custom change destination, if not set an address is generated.
Definition: coincontrol.h:33
wallet::feebumper::Result::WALLET_ERROR
@ WALLET_ERROR
wallet::CCoinControl::m_external_provider
FlatSigningProvider m_external_provider
SigningProvider that has pubkeys and scripts to do spend size estimation for external inputs.
Definition: coincontrol.h:63
RPCArg::Type::STR_HEX
@ STR_HEX
Special type that is a STR with only hex chars.
RPCResult::Type::OBJ
@ OBJ
wallet::CWallet
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Definition: wallet.h:232
wallet::CCoinControl::m_avoid_address_reuse
bool m_avoid_address_reuse
Forbids inclusion of dirty (previously used) addresses.
Definition: coincontrol.h:55
UniValue::exists
bool exists(const std::string &key) const
Definition: univalue.h:73
wallet::WALLET_FLAG_DISABLE_PRIVATE_KEYS
@ WALLET_FLAG_DISABLE_PRIVATE_KEYS
Definition: walletutil.h:51
wallet::CCoinControl::m_change_type
std::optional< OutputType > m_change_type
Override the default change type if set, ignored if destChange is set.
Definition: coincontrol.h:35
UniValue::VBOOL
@ VBOOL
Definition: univalue.h:19
univalue.h
wallet::CCoinControl::m_feerate
std::optional< CFeeRate > m_feerate
Override the wallet's m_pay_tx_fee if set.
Definition: coincontrol.h:47
CURRENCY_ATOM
const std::string CURRENCY_ATOM
Definition: feerate.h:15
RPCResult::Type::STR_HEX
@ STR_HEX
Special string with only hex chars.
feebumper.h
InvalidEstimateModeErrorMessage
const std::string InvalidEstimateModeErrorMessage()
Definition: fees.cpp:52
CAmount
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
base_blob::GetHex
std::string GetHex() const
Definition: uint256.cpp:20
RPCExamples
Definition: util.h:335
wallet::CCoinControl::m_avoid_partial_spends
bool m_avoid_partial_spends
Avoid partial use of funds sent to a given address.
Definition: coincontrol.h:53
wallet::CCoinControl::m_signal_bip125_rbf
std::optional< bool > m_signal_bip125_rbf
Override the wallet's m_signal_rbf if set.
Definition: coincontrol.h:51
RPC_WALLET_ERROR
@ RPC_WALLET_ERROR
Wallet errors.
Definition: protocol.h:71
UniValue::getKeys
const std::vector< std::string > & getKeys() const
Definition: univalue_get.cpp:77
RPCResult::Type::STR
@ STR
UniValue::VNUM
@ VNUM
Definition: univalue.h:19
wallet::FundTransaction
void FundTransaction(CWallet &wallet, CMutableTransaction &tx, CAmount &fee_out, int &change_position, const UniValue &options, CCoinControl &coinControl, bool override_min_fee)
Definition: spend.cpp:389
wallet::bumpfee_helper
static RPCHelpMan bumpfee_helper(std::string method_name)
Definition: spend.cpp:787
uint256
256-bit opaque blob.
Definition: uint256.h:124
RPCResult::Type::ARR
@ ARR
CFeeRate::ToString
std::string ToString(const FeeEstimateMode &fee_estimate_mode=FeeEstimateMode::BTC_KVB) const
Definition: feerate.cpp:39
FlatSigningProvider::pubkeys
std::map< CKeyID, CPubKey > pubkeys
Definition: signingprovider.h:75
CScript
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:405
HelpExampleRpc
std::string HelpExampleRpc(const std::string &methodname, const std::string &args)
Definition: util.cpp:174
wallet::feebumper::CreateRateBumpTransaction
Result CreateRateBumpTransaction(CWallet &wallet, const uint256 &txid, const CCoinControl &coin_control, std::vector< bilingual_str > &errors, CAmount &old_fee, CAmount &new_fee, CMutableTransaction &mtx)
Create bumpfee transaction based on feerate estimates.
Definition: feebumper.cpp:157
ConstructTransaction
CMutableTransaction ConstructTransaction(const UniValue &inputs_in, const UniValue &outputs_in, const UniValue &locktime, bool rbf)
Create a transaction from univalue parameters.
Definition: rawtransaction_util.cpp:24
wallet::CCoinControl::m_include_unsafe_inputs
bool m_include_unsafe_inputs
If false, only safe inputs will be used.
Definition: coincontrol.h:39
wallet::signrawtransactionwithwallet
RPCHelpMan signrawtransactionwithwallet()
Definition: spend.cpp:690
wallet::sendtoaddress
RPCHelpMan sendtoaddress()
Definition: spend.cpp:124
JSONRPCTransactionError
UniValue JSONRPCTransactionError(TransactionError terr, const std::string &err_string)
Definition: util.cpp:359
wallet::walletprocesspsbt
RPCHelpMan walletprocesspsbt()
Definition: spend.cpp:1162
wallet::CreateTransaction
bool CreateTransaction(CWallet &wallet, const std::vector< CRecipient > &vecSend, CTransactionRef &tx, CAmount &nFeeRet, int &nChangePosInOut, bilingual_str &error, const CCoinControl &coin_control, FeeCalculation &fee_calc_out, bool sign)
Create a new transaction paying the recipients with a set of coins selected by SelectCoins(); Also cr...
Definition: spend.cpp:933
EncodeHexTx
std::string EncodeHexTx(const CTransaction &tx, const int serializeFlags=0)
Definition: core_write.cpp:138
RPC_INVALID_ADDRESS_OR_KEY
@ RPC_INVALID_ADDRESS_OR_KEY
Invalid address or key.
Definition: protocol.h:41
CMutableTransaction::vout
std::vector< CTxOut > vout
Definition: transaction.h:347
strprintf
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
CPubKey
An encapsulated public key.
Definition: pubkey.h:33
fees.h
wallet::feebumper::SignTransaction
bool SignTransaction(CWallet &wallet, CMutableTransaction &mtx)
Sign the new transaction,.
Definition: feebumper.cpp:246
RPCResult::Type::BOOL
@ BOOL
UniValue::get_int
int get_int() const
Definition: univalue_get.cpp:105
RPC_WALLET_INSUFFICIENT_FUNDS
@ RPC_WALLET_INSUFFICIENT_FUNDS
Not enough funds in wallet or account.
Definition: protocol.h:72
FeeModes
std::string FeeModes(const std::string &delimiter)
Definition: fees.cpp:47
translation.h
RPCTypeCheck
void RPCTypeCheck(const UniValue &params, const std::list< UniValueType > &typesExpected, bool fAllowNull)
Type-check arguments; throws JSONRPCError if wrong type given.
Definition: util.cpp:24
wallet::ParseRecipients
static void ParseRecipients(const UniValue &address_amounts, const UniValue &subtract_fee_outputs, std::vector< CRecipient > &recipients)
Definition: spend.cpp:23
JSONRPCError
UniValue JSONRPCError(int code, const std::string &message)
Definition: request.cpp:51
UniValue::isTrue
bool isTrue() const
Definition: univalue.h:76
PartiallySignedTransaction
A version of CTransaction with the PSBT format.
Definition: psbt.h:668
vector.h
LOCK
#define LOCK(cs)
Definition: sync.h:226
wallet::CCoinControl::SelectExternal
void SelectExternal(const COutPoint &outpoint, const CTxOut &txout)
Definition: coincontrol.h:97
SignTransactionResultToJSON
void SignTransactionResultToJSON(CMutableTransaction &mtx, bool complete, const std::map< COutPoint, Coin > &coins, const std::map< int, bilingual_str > &input_errors, UniValue &result)
Definition: rawtransaction_util.cpp:291
TransactionError::OK
@ OK
No error.
RPCArg::Type::BOOL
@ BOOL
RPCArg::Optional::OMITTED
@ OMITTED
Optional argument with default value omitted because they are implicitly clear.
CTxIn::prevout
COutPoint prevout
Definition: transaction.h:68
wallet::SetFeeEstimateMode
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:100
DecodeDestination
CTxDestination DecodeDestination(const std::string &str, std::string &error_msg, std::vector< int > *error_locations)
Definition: key_io.cpp:281
UniValue::push_back
bool push_back(const UniValue &val)
Definition: univalue.cpp:108
CPubKey::IsFullyValid
bool IsFullyValid() const
fully validate whether this is a valid public key (more expensive than IsValid())
Definition: pubkey.cpp:292
EXAMPLE_ADDRESS
const std::string EXAMPLE_ADDRESS[2]
Example bech32 addresses for the RPCExamples help documentation.
Definition: util.cpp:22
CDataStream
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:184
wallet::CCoinControl::fOverrideFeeRate
bool fOverrideFeeRate
Override automatic min/max checks on fee, m_feerate must be set if true.
Definition: coincontrol.h:45
SER_NETWORK
@ SER_NETWORK
Definition: serialize.h:138
wallet::settxfee
RPCHelpMan settxfee()
Definition: spend.cpp:319
UniValue::size
size_t size() const
Definition: univalue.h:66
wallet::send
RPCHelpMan send()
Definition: spend.cpp:964
RPCArg::Type::AMOUNT
@ AMOUNT
Special type representing a floating point amount (can be either NUM or STR)
JSONRPCRequest
Definition: request.h:28
wallet::psbtbumpfee
RPCHelpMan psbtbumpfee()
Definition: spend.cpp:962
RPCResult
Definition: util.h:231
wallet::feebumper::Result::OK
@ OK
wallet::CCoinControl::m_fee_mode
FeeEstimateMode m_fee_mode
Fee estimation mode to control arguments to estimateSmartFee.
Definition: coincontrol.h:57
error
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
StringForFeeReason
std::string StringForFeeReason(FeeReason reason)
Definition: fees.cpp:17
RPCResult::Type::STR_AMOUNT
@ STR_AMOUNT
Special string to represent a floating point amount.
CMutableTransaction
A mutable version of CTransaction.
Definition: transaction.h:344
UniValue::get_array
const UniValue & get_array() const
Definition: univalue_get.cpp:142
UniValue::VARR
@ VARR
Definition: univalue.h:19
wallet::mapValue_t
std::map< std::string, std::string > mapValue_t
Definition: transaction.h:111
coincontrol.h
AmountFromValue
static CAmount AmountFromValue(const UniValue &value)
Definition: bitcoin-tx.cpp:550
CScriptID
A reference to a CScript: the Hash160 of its serialization (see script.h)
Definition: standard.h:25
CDataStream::str
std::string str() const
Definition: streams.h:222
wallet::feebumper::Result::INVALID_REQUEST
@ INVALID_REQUEST
UniValue::VSTR
@ VSTR
Definition: univalue.h:19
wallet::sendmany
RPCHelpMan sendmany()
Definition: spend.cpp:226
wallet::CCoinControl
Coin Control Features.
Definition: coincontrol.h:29
spend.h
ParseOutputType
std::optional< OutputType > ParseOutputType(const std::string &type)
Definition: outputtype.cpp:24
FastRandomContext
Fast randomness source.
Definition: random.h:119
wallet::ParseIncludeWatchonly
bool ParseIncludeWatchonly(const UniValue &include_watchonly, const CWallet &wallet)
Used by RPC commands that have an include_watchonly parameter.
Definition: util.cpp:34
FlatSigningProvider
Definition: signingprovider.h:72
CPubKey::GetID
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
Definition: pubkey.h:164
wallet::GetAvoidReuseFlag
bool GetAvoidReuseFlag(const CWallet &wallet, const UniValue &param)
Definition: util.cpp:19
wallet::EnsureWalletIsUnlocked
void EnsureWalletIsUnlocked(const CWallet &wallet)
Definition: util.cpp:80
PROTOCOL_VERSION
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:12
DecodeHexTx
bool DecodeHexTx(CMutableTransaction &tx, const std::string &hex_tx, bool try_no_witness=false, bool try_witness=true)
Definition: core_read.cpp:199
ParseSighashString
int ParseSighashString(const UniValue &sighash)
Definition: core_read.cpp:259
SIGHASH_DEFAULT
@ SIGHASH_DEFAULT
Taproot only; implied when sighash byte is missing, and equivalent to SIGHASH_ALL.
Definition: interpreter.h:32
rawtransaction_util.h