From b38cd7da9130cbd3428f358b80df41ac1cac2864 Mon Sep 17 00:00:00 2001
From: alex v <alex@encrypt-s.com>
Date: Wed, 7 Aug 2024 22:07:23 +0200
Subject: [PATCH] add getblsctseed rpc command

---
 src/wallet/rpc/backup.cpp | 24 ++++++++++++++++++++++++
 src/wallet/rpc/util.cpp   | 21 +++++++++++++++++++++
 src/wallet/rpc/util.h     |  2 ++
 src/wallet/rpc/wallet.cpp |  2 ++
 4 files changed, 49 insertions(+)

diff --git a/src/wallet/rpc/backup.cpp b/src/wallet/rpc/backup.cpp
index 3059317753b68..634f754f977c4 100644
--- a/src/wallet/rpc/backup.cpp
+++ b/src/wallet/rpc/backup.cpp
@@ -688,6 +688,30 @@ RPCHelpMan dumpprivkey()
 }
 
 
+RPCHelpMan getblsctseed()
+{
+    return RPCHelpMan{
+        "getblsctseed",
+        "\nDumps the BLSCT wallet seed, which can be used to reconstruct the wallet.\n"
+        "Note: This command is only compatible with BLSCT wallets.\n",
+        {},
+        RPCResult{
+            RPCResult::Type::STR, "seed", "The BLSCT wallet seed"},
+        RPCExamples{HelpExampleCli("getblsctseed", "") + HelpExampleRpc("getblsctseed", "")},
+        [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
+            const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
+            if (!pwallet) return UniValue::VNULL;
+
+            const CWallet& wallet = *pwallet;
+            const blsct::KeyMan& blsct_km = EnsureConstBlsctKeyMan(wallet);
+
+            auto seed = blsct_km.GetMasterSeedKey();
+
+            return seed.GetScalar().GetString();
+        },
+    };
+}
+
 RPCHelpMan dumpwallet()
 {
     return RPCHelpMan{"dumpwallet",
diff --git a/src/wallet/rpc/util.cpp b/src/wallet/rpc/util.cpp
index 06ec7db1bc219..446fff87c5733 100644
--- a/src/wallet/rpc/util.cpp
+++ b/src/wallet/rpc/util.cpp
@@ -131,6 +131,27 @@ const LegacyScriptPubKeyMan& EnsureConstLegacyScriptPubKeyMan(const CWallet& wal
     return *spk_man;
 }
 
+blsct::KeyMan& EnsureBlsctKeyMan(CWallet& wallet, bool also_create)
+{
+    blsct::KeyMan* blsct_km = wallet.GetBLSCTKeyMan();
+    if (!blsct_km && also_create) {
+        blsct_km = wallet.GetOrCreateBLSCTKeyMan();
+    }
+    if (!blsct_km) {
+        throw JSONRPCError(RPC_WALLET_ERROR, "Only BLSCT wallets are supported by this command");
+    }
+    return *blsct_km;
+}
+
+const blsct::KeyMan& EnsureConstBlsctKeyMan(const CWallet& wallet)
+{
+    const blsct::KeyMan* blsct_km = wallet.GetBLSCTKeyMan();
+    if (!blsct_km) {
+        throw JSONRPCError(RPC_WALLET_ERROR, "Only BLSCT wallets are supported by this command");
+    }
+    return *blsct_km;
+}
+
 std::string LabelFromValue(const UniValue& value)
 {
     static const std::string empty_string;
diff --git a/src/wallet/rpc/util.h b/src/wallet/rpc/util.h
index 2fdba04352255..180c030f2b3bd 100644
--- a/src/wallet/rpc/util.h
+++ b/src/wallet/rpc/util.h
@@ -41,7 +41,9 @@ bool GetWalletNameFromJSONRPCRequest(const JSONRPCRequest& request, std::string&
 
 void EnsureWalletIsUnlocked(const CWallet&);
 WalletContext& EnsureWalletContext(const std::any& context);
+blsct::KeyMan& EnsureBlsctKeyMan(const CWallet& wallet, bool also_create = false);
 LegacyScriptPubKeyMan& EnsureLegacyScriptPubKeyMan(CWallet& wallet, bool also_create = false);
+const blsct::KeyMan& EnsureConstBlsctKeyMan(const CWallet& wallet);
 const LegacyScriptPubKeyMan& EnsureConstLegacyScriptPubKeyMan(const CWallet& wallet);
 
 bool GetAvoidReuseFlag(const CWallet& wallet, const UniValue& param);
diff --git a/src/wallet/rpc/wallet.cpp b/src/wallet/rpc/wallet.cpp
index abfb9c77cded4..80e46f385fb8a 100644
--- a/src/wallet/rpc/wallet.cpp
+++ b/src/wallet/rpc/wallet.cpp
@@ -827,6 +827,7 @@ RPCHelpMan walletdisplayaddress();
 #endif // ENABLE_EXTERNAL_SIGNER
 
 // backup
+RPCHelpMan getblsctseed();
 RPCHelpMan dumpprivkey();
 RPCHelpMan importprivkey();
 RPCHelpMan importaddress();
@@ -905,6 +906,7 @@ Span<const CRPCCommand> GetWalletRPCCommands()
         {"wallet", &getaddressesbylabel},
         {"wallet", &getaddressinfo},
         {"wallet", &getbalance},
+        {"wallet", &getblsctseed},
         {"wallet", &getnewaddress},
         {"wallet", &getrawchangeaddress},
         {"wallet", &getreceivedbyaddress},