|
32 | 32 | #include <script/descriptor.h> // getwalletpakinfo
|
33 | 33 | #include <rpc/util.h> // IsBlindDestination
|
34 | 34 |
|
| 35 | +namespace { |
| 36 | + static secp256k1_context *secp256k1_ctx; |
35 | 37 |
|
| 38 | + class CSecp256k1Init { |
| 39 | + public: |
| 40 | + CSecp256k1Init() { |
| 41 | + secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN); |
| 42 | + } |
| 43 | + ~CSecp256k1Init() { |
| 44 | + secp256k1_context_destroy(secp256k1_ctx); |
| 45 | + } |
| 46 | + }; |
| 47 | + static CSecp256k1Init instance_of_csecp256k1; |
| 48 | +} |
36 | 49 |
|
37 | 50 | using interfaces::FoundBlock;
|
38 | 51 |
|
@@ -2000,6 +2013,7 @@ RPCHelpMan getwalletpakinfo()
|
2000 | 2013 | {
|
2001 | 2014 | {RPCResult::Type::STR, "bip32_counter", "next index to be used by the wallet for `sendtomainchain`"},
|
2002 | 2015 | {RPCResult::Type::STR, "bitcoin_descriptor", "Bitcoin script descriptor loaded in the wallet for pegouts"},
|
| 2016 | + {RPCResult::Type::STR, "pakentry", "PAK entry to be used at network initialization time in the form of: `pak=<bitcoin_pak>:<liquid_pak>`"}, |
2003 | 2017 | {RPCResult::Type::STR_HEX, "liquid_pak", "pubkey corresponding to the Liquid PAK loaded in the wallet for pegouts"},
|
2004 | 2018 | {RPCResult::Type::STR, "liquid_pak_address", "corresponding address for `liquid_pak`. Useful for `dumpprivkey` for wallet backup or transfer"},
|
2005 | 2019 | {RPCResult::Type::ARR_FIXED, "address_lookahead", "the three next Bitcoin addresses the wallet will use for `sendtomainchain` based on the internal counter",
|
@@ -2032,6 +2046,28 @@ RPCHelpMan getwalletpakinfo()
|
2032 | 2046 | const auto& desc = Parse(desc_str, provider, error);
|
2033 | 2047 |
|
2034 | 2048 | ret.pushKV("bitcoin_descriptor", desc_str);
|
| 2049 | + { |
| 2050 | + CPubKey masterpub = pwallet->offline_xpub.pubkey; |
| 2051 | + secp256k1_pubkey masterpub_secp; |
| 2052 | + int secp256k1_ret = secp256k1_ec_pubkey_parse(secp256k1_ctx, &masterpub_secp, masterpub.begin(), masterpub.size()); |
| 2053 | + if (secp256k1_ret != 1) { |
| 2054 | + throw JSONRPCError(RPC_WALLET_ERROR, "bitcoin_descriptor could not be parsed."); |
| 2055 | + } |
| 2056 | + |
| 2057 | + |
| 2058 | + // Negate the pubkey |
| 2059 | + secp256k1_ret = secp256k1_ec_pubkey_negate(secp256k1_ctx, &masterpub_secp); |
| 2060 | + |
| 2061 | + std::vector<unsigned char> negatedpubkeybytes; |
| 2062 | + negatedpubkeybytes.resize(33); |
| 2063 | + size_t len = 33; |
| 2064 | + secp256k1_ret = secp256k1_ec_pubkey_serialize(secp256k1_ctx, &negatedpubkeybytes[0], &len, &masterpub_secp, SECP256K1_EC_COMPRESSED); |
| 2065 | + CHECK_NONFATAL(secp256k1_ret == 1); |
| 2066 | + CHECK_NONFATAL(len == 33); |
| 2067 | + CHECK_NONFATAL(negatedpubkeybytes.size() == 33); |
| 2068 | + |
| 2069 | + ret.pushKV("pakentry", "pak=" + HexStr(negatedpubkeybytes) + ":" + HexStr(pwallet->online_key)); |
| 2070 | + } |
2035 | 2071 | ret.pushKV("liquid_pak", HexStr(pwallet->online_key));
|
2036 | 2072 | ret.pushKV("liquid_pak_address", EncodeDestination(PKHash(pwallet->online_key)));
|
2037 | 2073 |
|
|
0 commit comments