spend.cpp raw

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