| 234 | } |
| 235 | |
| 236 | RPCHelpMan addmultisigaddress() |
| 237 | { |
| 238 | return RPCHelpMan{"addmultisigaddress", |
| 239 | "\nAdd an nrequired-to-sign multisignature address to the wallet. Requires a new wallet backup.\n" |
| 240 | "Each key is a Bitcoin address or hex-encoded public key.\n" |
| 241 | "This functionality is only intended for use with non-watchonly addresses.\n" |
| 242 | "See `importaddress` for watchonly p2sh address support.\n" |
| 243 | "If 'label' is specified, assign address to that label.\n", |
| 244 | { |
| 245 | {"nrequired", RPCArg::Type::NUM, RPCArg::Optional::NO, "The number of required signatures out of the n keys or addresses."}, |
| 246 | {"keys", RPCArg::Type::ARR, RPCArg::Optional::NO, "The addresses or hex-encoded public keys", |
| 247 | { |
| 248 | {"key", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "address or hex-encoded public key"}, |
| 249 | }, |
| 250 | }, |
| 251 | {"label", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "A label to assign the addresses to."}, |
| 252 | {"address_type", RPCArg::Type::STR, RPCArg::DefaultHint{"set by -addresstype"}, "The address type to use. Options are \"legacy\", \"p2sh-segwit\", and \"bech32\"."}, |
| 253 | }, |
| 254 | RPCResult{ |
| 255 | RPCResult::Type::OBJ, "", "", |
| 256 | { |
| 257 | {RPCResult::Type::STR, "address", "The value of the new multisig address"}, |
| 258 | {RPCResult::Type::STR_HEX, "redeemScript", "The string value of the hex-encoded redemption script"}, |
| 259 | {RPCResult::Type::STR, "descriptor", "The descriptor for this multisig"}, |
| 260 | {RPCResult::Type::ARR, "warnings", /* optional */ true, "Any warnings resulting from the creation of this multisig", |
| 261 | { |
| 262 | {RPCResult::Type::STR, "", ""}, |
| 263 | }}, |
| 264 | } |
| 265 | }, |
| 266 | RPCExamples{ |
| 267 | "\nAdd a multisig address from 2 addresses\n" |
| 268 | + HelpExampleCli("addmultisigaddress", "2 \"[\\\"" + EXAMPLE_ADDRESS[0] + "\\\",\\\"" + EXAMPLE_ADDRESS[1] + "\\\"]\"") + |
| 269 | "\nAs a JSON-RPC call\n" |
| 270 | + HelpExampleRpc("addmultisigaddress", "2, \"[\\\"" + EXAMPLE_ADDRESS[0] + "\\\",\\\"" + EXAMPLE_ADDRESS[1] + "\\\"]\"") |
| 271 | }, |
| 272 | [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue |
| 273 | { |
| 274 | std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request); |
| 275 | if (!pwallet) return NullUniValue; |
| 276 | |
| 277 | LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(*pwallet); |
| 278 | |
| 279 | LOCK2(pwallet->cs_wallet, spk_man.cs_KeyStore); |
| 280 | |
| 281 | std::string label; |
| 282 | if (!request.params[2].isNull()) |
| 283 | label = LabelFromValue(request.params[2]); |
| 284 | |
| 285 | int required = request.params[0].get_int(); |
| 286 | |
| 287 | // Get the public keys |
| 288 | const UniValue& keys_or_addrs = request.params[1].get_array(); |
| 289 | std::vector<CPubKey> pubkeys; |
| 290 | for (unsigned int i = 0; i < keys_or_addrs.size(); ++i) { |
| 291 | if (IsHex(keys_or_addrs[i].get_str()) && (keys_or_addrs[i].get_str().length() == 66 || keys_or_addrs[i].get_str().length() == 130)) { |
| 292 | pubkeys.push_back(HexToPubKey(keys_or_addrs[i].get_str())); |
| 293 | } else { |
nothing calls this directly
no test coverage detected