| 1784 | } |
| 1785 | |
| 1786 | RPCHelpMan listdescriptors() |
| 1787 | { |
| 1788 | return RPCHelpMan{ |
| 1789 | "listdescriptors", |
| 1790 | "\nList descriptors imported into a descriptor-enabled wallet.\n", |
| 1791 | { |
| 1792 | {"private", RPCArg::Type::BOOL, RPCArg::Default{false}, "Show private descriptors."} |
| 1793 | }, |
| 1794 | RPCResult{RPCResult::Type::OBJ, "", "", { |
| 1795 | {RPCResult::Type::STR, "wallet_name", "Name of wallet this operation was performed on"}, |
| 1796 | {RPCResult::Type::ARR, "descriptors", "Array of descriptor objects", |
| 1797 | { |
| 1798 | {RPCResult::Type::OBJ, "", "", { |
| 1799 | {RPCResult::Type::STR, "desc", "Descriptor string representation"}, |
| 1800 | {RPCResult::Type::NUM, "timestamp", "The creation time of the descriptor"}, |
| 1801 | {RPCResult::Type::BOOL, "active", "Activeness flag"}, |
| 1802 | {RPCResult::Type::BOOL, "internal", true, "Whether this is an internal or external descriptor; defined only for active descriptors"}, |
| 1803 | {RPCResult::Type::ARR_FIXED, "range", true, "Defined only for ranged descriptors", { |
| 1804 | {RPCResult::Type::NUM, "", "Range start inclusive"}, |
| 1805 | {RPCResult::Type::NUM, "", "Range end inclusive"}, |
| 1806 | }}, |
| 1807 | {RPCResult::Type::NUM, "next", true, "The next index to generate addresses from; defined only for ranged descriptors"}, |
| 1808 | }}, |
| 1809 | }} |
| 1810 | }}, |
| 1811 | RPCExamples{ |
| 1812 | HelpExampleCli("listdescriptors", "") + HelpExampleRpc("listdescriptors", "") |
| 1813 | + HelpExampleCli("listdescriptors", "true") + HelpExampleRpc("listdescriptors", "true") |
| 1814 | }, |
| 1815 | [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue |
| 1816 | { |
| 1817 | const std::shared_ptr<const CWallet> wallet = GetWalletForJSONRPCRequest(request); |
| 1818 | if (!wallet) return NullUniValue; |
| 1819 | |
| 1820 | if (!wallet->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) { |
| 1821 | throw JSONRPCError(RPC_WALLET_ERROR, "listdescriptors is not available for non-descriptor wallets"); |
| 1822 | } |
| 1823 | |
| 1824 | const bool priv = !request.params[0].isNull() && request.params[0].get_bool(); |
| 1825 | if (priv) { |
| 1826 | EnsureWalletIsUnlocked(*wallet); |
| 1827 | } |
| 1828 | |
| 1829 | LOCK(wallet->cs_wallet); |
| 1830 | |
| 1831 | UniValue descriptors(UniValue::VARR); |
| 1832 | const auto active_spk_mans = wallet->GetActiveScriptPubKeyMans(); |
| 1833 | for (const auto& spk_man : wallet->GetAllScriptPubKeyMans()) { |
| 1834 | const auto desc_spk_man = dynamic_cast<DescriptorScriptPubKeyMan*>(spk_man); |
| 1835 | if (!desc_spk_man) { |
| 1836 | throw JSONRPCError(RPC_WALLET_ERROR, "Unexpected ScriptPubKey manager type."); |
| 1837 | } |
| 1838 | UniValue spk(UniValue::VOBJ); |
| 1839 | LOCK(desc_spk_man->cs_desc_man); |
| 1840 | const auto& wallet_descriptor = desc_spk_man->GetWalletDescriptor(); |
| 1841 | std::string descriptor; |
| 1842 | |
| 1843 | if (!desc_spk_man->GetDescriptorString(descriptor, priv)) { |
nothing calls this directly
no test coverage detected