| 263 | } |
| 264 | |
| 265 | static RPCHelpMan deriveaddresses() |
| 266 | { |
| 267 | const std::string EXAMPLE_DESCRIPTOR = "wpkh([d34db33f/84h/0h/0h]xpub6DJ2dNUysrn5Vt36jH2KLBT2i1auw1tTSSomg8PhqNiUtx8QX2SvC9nrHu81fT41fvDUnhMjEzQgXnQjKEu3oaqMSzhSrHMxyyoEAmUHQbY/0/*)#cjjspncu"; |
| 268 | |
| 269 | return RPCHelpMan{"deriveaddresses", |
| 270 | {"\nDerives one or more addresses corresponding to an output descriptor.\n" |
| 271 | "Examples of output descriptors are:\n" |
| 272 | " pkh(<pubkey>) P2PKH outputs for the given pubkey\n" |
| 273 | " wpkh(<pubkey>) Native segwit P2PKH outputs for the given pubkey\n" |
| 274 | " sh(multi(<n>,<pubkey>,<pubkey>,...)) P2SH-multisig outputs for the given threshold and pubkeys\n" |
| 275 | " raw(<hex script>) Outputs whose scriptPubKey equals the specified hex scripts\n" |
| 276 | "\nIn the above, <pubkey> either refers to a fixed public key in hexadecimal notation, or to an xpub/xprv optionally followed by one\n" |
| 277 | "or more path elements separated by \"/\", where \"h\" represents a hardened child key.\n" |
| 278 | "For more information on output descriptors, see the documentation in the doc/descriptors.md file.\n"}, |
| 279 | { |
| 280 | {"descriptor", RPCArg::Type::STR, RPCArg::Optional::NO, "The descriptor."}, |
| 281 | {"range", RPCArg::Type::RANGE, RPCArg::Optional::OMITTED_NAMED_ARG, "If a ranged descriptor is used, this specifies the end or the range (in [begin,end] notation) to derive."}, |
| 282 | }, |
| 283 | RPCResult{ |
| 284 | RPCResult::Type::ARR, "", "", |
| 285 | { |
| 286 | {RPCResult::Type::STR, "address", "the derived addresses"}, |
| 287 | } |
| 288 | }, |
| 289 | RPCExamples{ |
| 290 | "First three native segwit receive addresses\n" + |
| 291 | HelpExampleCli("deriveaddresses", "\"" + EXAMPLE_DESCRIPTOR + "\" \"[0,2]\"") + |
| 292 | HelpExampleRpc("deriveaddresses", "\"" + EXAMPLE_DESCRIPTOR + "\", \"[0,2]\"") |
| 293 | }, |
| 294 | [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue |
| 295 | { |
| 296 | RPCTypeCheck(request.params, {UniValue::VSTR, UniValueType()}); // Range argument is checked later |
| 297 | const std::string desc_str = request.params[0].get_str(); |
| 298 | |
| 299 | int64_t range_begin = 0; |
| 300 | int64_t range_end = 0; |
| 301 | |
| 302 | if (request.params.size() >= 2 && !request.params[1].isNull()) { |
| 303 | std::tie(range_begin, range_end) = ParseDescriptorRange(request.params[1]); |
| 304 | } |
| 305 | |
| 306 | FlatSigningProvider key_provider; |
| 307 | std::string error; |
| 308 | auto desc = Parse(desc_str, key_provider, error, /* require_checksum = */ true); |
| 309 | if (!desc) { |
| 310 | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, error); |
| 311 | } |
| 312 | |
| 313 | if (!desc->IsRange() && request.params.size() > 1) { |
| 314 | throw JSONRPCError(RPC_INVALID_PARAMETER, "Range should not be specified for an un-ranged descriptor"); |
| 315 | } |
| 316 | |
| 317 | if (desc->IsRange() && request.params.size() == 1) { |
| 318 | throw JSONRPCError(RPC_INVALID_PARAMETER, "Range must be specified for a ranged descriptor"); |
| 319 | } |
| 320 | |
| 321 | UniValue addresses(UniValue::VARR); |
| 322 |
nothing calls this directly
no test coverage detected