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