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