| 408 | |
| 409 | |
| 410 | class DescribeWalletAddressVisitor |
| 411 | { |
| 412 | public: |
| 413 | const SigningProvider * const provider; |
| 414 | |
| 415 | void ProcessSubScript(const CScript& subscript, UniValue& obj) const |
| 416 | { |
| 417 | // Always present: script type and redeemscript |
| 418 | std::vector<std::vector<unsigned char>> solutions_data; |
| 419 | TxoutType which_type = Solver(subscript, solutions_data); |
| 420 | obj.pushKV("script", GetTxnOutputType(which_type)); |
| 421 | obj.pushKV("hex", HexStr(subscript)); |
| 422 | |
| 423 | CTxDestination embedded; |
| 424 | if (ExtractDestination(subscript, embedded)) { |
| 425 | // Only when the script corresponds to an address. |
| 426 | UniValue subobj(UniValue::VOBJ); |
| 427 | UniValue detail = DescribeAddress(embedded); |
| 428 | subobj.pushKVs(detail); |
| 429 | UniValue wallet_detail = std::visit(*this, embedded); |
| 430 | subobj.pushKVs(wallet_detail); |
| 431 | subobj.pushKV("address", EncodeDestination(embedded)); |
| 432 | subobj.pushKV("scriptPubKey", HexStr(subscript)); |
| 433 | // Always report the pubkey at the top level, so that `getnewaddress()['pubkey']` always works. |
| 434 | if (subobj.exists("pubkey")) obj.pushKV("pubkey", subobj["pubkey"]); |
| 435 | obj.pushKV("embedded", std::move(subobj)); |
| 436 | } else if (which_type == TxoutType::MULTISIG) { |
| 437 | // Also report some information on multisig scripts (which do not have a corresponding address). |
| 438 | obj.pushKV("sigsrequired", solutions_data[0][0]); |
| 439 | UniValue pubkeys(UniValue::VARR); |
| 440 | for (size_t i = 1; i < solutions_data.size() - 1; ++i) { |
| 441 | CPubKey key(solutions_data[i].begin(), solutions_data[i].end()); |
| 442 | pubkeys.push_back(HexStr(key)); |
| 443 | } |
| 444 | obj.pushKV("pubkeys", std::move(pubkeys)); |
| 445 | } |
| 446 | } |
| 447 | |
| 448 | explicit DescribeWalletAddressVisitor(const SigningProvider* _provider) : provider(_provider) {} |
| 449 | |
| 450 | UniValue operator()(const CNoDestination& dest) const { return UniValue(UniValue::VOBJ); } |
| 451 | |
| 452 | UniValue operator()(const PKHash& pkhash) const |
| 453 | { |
| 454 | CKeyID keyID{ToKeyID(pkhash)}; |
| 455 | UniValue obj(UniValue::VOBJ); |
| 456 | CPubKey vchPubKey; |
| 457 | if (provider && provider->GetPubKey(keyID, vchPubKey)) { |
| 458 | obj.pushKV("pubkey", HexStr(vchPubKey)); |
| 459 | obj.pushKV("iscompressed", vchPubKey.IsCompressed()); |
| 460 | } |
| 461 | return obj; |
| 462 | } |
| 463 | |
| 464 | UniValue operator()(const ScriptHash& scripthash) const |
| 465 | { |
| 466 | CScriptID scriptID(scripthash); |
| 467 | UniValue obj(UniValue::VOBJ); |
no outgoing calls
no test coverage detected