From a1d7df32360605724d8f0ea4b7aebfa7aea24c97 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Thu, 9 Jul 2015 22:47:36 -0700 Subject: [PATCH] Add importpubkey method to import a watch-only pubkey --- src/rpcclient.cpp | 1 + src/rpcserver.cpp | 1 + src/rpcserver.h | 1 + src/wallet/rpcdump.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+) diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 450f33b3e..0c8e6d6d6 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -88,6 +88,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "importprivkey", 2 }, { "importaddress", 2 }, { "importaddress", 3 }, + { "importpubkey", 2 }, { "verifychain", 0 }, { "verifychain", 1 }, { "keypoolrefill", 0 }, diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index bcad06a0c..158603b14 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -359,6 +359,7 @@ static const CRPCCommand vRPCCommands[] = { "wallet", "importprivkey", &importprivkey, true }, { "wallet", "importwallet", &importwallet, true }, { "wallet", "importaddress", &importaddress, true }, + { "wallet", "importpubkey", &importpubkey, true }, { "wallet", "keypoolrefill", &keypoolrefill, true }, { "wallet", "listaccounts", &listaccounts, false }, { "wallet", "listaddressgroupings", &listaddressgroupings, false }, diff --git a/src/rpcserver.h b/src/rpcserver.h index 89d398022..3a71fd510 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -161,6 +161,7 @@ extern UniValue clearbanned(const UniValue& params, bool fHelp); extern UniValue dumpprivkey(const UniValue& params, bool fHelp); // in rpcdump.cpp extern UniValue importprivkey(const UniValue& params, bool fHelp); extern UniValue importaddress(const UniValue& params, bool fHelp); +extern UniValue importpubkey(const UniValue& params, bool fHelp); extern UniValue dumpwallet(const UniValue& params, bool fHelp); extern UniValue importwallet(const UniValue& params, bool fHelp); diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 3493efc8f..7efabbfeb 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -237,6 +237,63 @@ UniValue importaddress(const UniValue& params, bool fHelp) return NullUniValue; } +UniValue importpubkey(const UniValue& params, bool fHelp) +{ + if (!EnsureWalletIsAvailable(fHelp)) + return NullUniValue; + + if (fHelp || params.size() < 1 || params.size() > 4) + throw runtime_error( + "importpubkey \"pubkey\" ( \"label\" rescan )\n" + "\nAdds a public key (in hex) that can be watched as if it were in your wallet but cannot be used to spend.\n" + "\nArguments:\n" + "1. \"pubkey\" (string, required) The hex-encoded public key\n" + "2. \"label\" (string, optional, default=\"\") An optional label\n" + "3. rescan (boolean, optional, default=true) Rescan the wallet for transactions\n" + "\nNote: This call can take minutes to complete if rescan is true.\n" + "\nExamples:\n" + "\nImport a public key with rescan\n" + + HelpExampleCli("importpubkey", "\"mypubkey\"") + + "\nImport using a label without rescan\n" + + HelpExampleCli("importpubkey", "\"mypubkey\" \"testing\" false") + + "\nAs a JSON-RPC call\n" + + HelpExampleRpc("importpubkey", "\"mypubkey\", \"testing\", false") + ); + + if (fPruneMode) + throw JSONRPCError(RPC_WALLET_ERROR, "Importing public keys is disabled in pruned mode"); + + string strLabel = ""; + if (params.size() > 1) + strLabel = params[1].get_str(); + + // Whether to perform rescan after import + bool fRescan = true; + if (params.size() > 2) + fRescan = params[2].get_bool(); + + if (!IsHex(params[0].get_str())) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey must be a hex string"); + std::vector data(ParseHex(params[0].get_str())); + CPubKey pubKey(data.begin(), data.end()); + if (!pubKey.IsFullyValid()) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Pubkey is not a valid public key"); + + LOCK2(cs_main, pwalletMain->cs_wallet); + + ImportAddress(CBitcoinAddress(pubKey.GetID()), strLabel); + ImportScript(GetScriptForRawPubKey(pubKey), strLabel, false); + + if (fRescan) + { + pwalletMain->ScanForWalletTransactions(chainActive.Genesis(), true); + pwalletMain->ReacceptWalletTransactions(); + } + + return NullUniValue; +} + + UniValue importwallet(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp))