Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/rpcdump.cpp
Show First 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | static void RescanWallet(CWallet &wallet, const WalletRescanReserver &reserver, | ||||
} else if (scanned_time > time_begin) { | } else if (scanned_time > time_begin) { | ||||
throw JSONRPCError(RPC_WALLET_ERROR, | throw JSONRPCError(RPC_WALLET_ERROR, | ||||
"Rescan was unable to fully rescan the blockchain. " | "Rescan was unable to fully rescan the blockchain. " | ||||
"Some transactions may be missing."); | "Some transactions may be missing."); | ||||
} | } | ||||
} | } | ||||
UniValue importprivkey(const Config &config, const JSONRPCRequest &request) { | UniValue importprivkey(const Config &config, const JSONRPCRequest &request) { | ||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | |||||
if (!wallet) { | |||||
return NullUniValue; | |||||
} | |||||
CWallet *const pwallet = wallet.get(); | |||||
RPCHelpMan{ | RPCHelpMan{ | ||||
"importprivkey", | "importprivkey", | ||||
"Adds a private key (as returned by dumpprivkey) to your wallet. " | "Adds a private key (as returned by dumpprivkey) to your wallet. " | ||||
"Requires a new wallet backup.\n" | "Requires a new wallet backup.\n" | ||||
"Hint: use importmulti to import more than one private key.\n" | "Hint: use importmulti to import more than one private key.\n" | ||||
"\nNote: This call can take minutes to complete if rescan is true, " | "\nNote: This call can take minutes to complete if rescan is true, " | ||||
"during that time, other rpc calls\n" | "during that time, other rpc calls\n" | ||||
"may report that the imported key exists but related transactions are " | "may report that the imported key exists but related transactions are " | ||||
Show All 19 Lines | RPCHelpMan{ | ||||
HelpExampleCli("importprivkey", "\"mykey\" \"testing\" false") + | HelpExampleCli("importprivkey", "\"mykey\" \"testing\" false") + | ||||
"\nImport using default blank label and without rescan\n" + | "\nImport using default blank label and without rescan\n" + | ||||
HelpExampleCli("importprivkey", "\"mykey\" \"\" false") + | HelpExampleCli("importprivkey", "\"mykey\" \"\" false") + | ||||
"\nAs a JSON-RPC call\n" + | "\nAs a JSON-RPC call\n" + | ||||
HelpExampleRpc("importprivkey", "\"mykey\", \"testing\", false")}, | HelpExampleRpc("importprivkey", "\"mykey\", \"testing\", false")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | |||||
if (!wallet) { | |||||
return NullUniValue; | |||||
} | |||||
CWallet *const pwallet = wallet.get(); | |||||
if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) { | if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) { | ||||
throw JSONRPCError(RPC_WALLET_ERROR, | throw JSONRPCError(RPC_WALLET_ERROR, | ||||
"Cannot import private keys to a wallet with " | "Cannot import private keys to a wallet with " | ||||
"private keys disabled"); | "private keys disabled"); | ||||
} | } | ||||
EnsureLegacyScriptPubKeyMan(*wallet, true); | EnsureLegacyScriptPubKeyMan(*wallet, true); | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | UniValue importprivkey(const Config &config, const JSONRPCRequest &request) { | ||||
if (fRescan) { | if (fRescan) { | ||||
RescanWallet(*pwallet, reserver); | RescanWallet(*pwallet, reserver); | ||||
} | } | ||||
return NullUniValue; | return NullUniValue; | ||||
} | } | ||||
UniValue abortrescan(const Config &config, const JSONRPCRequest &request) { | UniValue abortrescan(const Config &config, const JSONRPCRequest &request) { | ||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | |||||
if (!wallet) { | |||||
return NullUniValue; | |||||
} | |||||
CWallet *const pwallet = wallet.get(); | |||||
RPCHelpMan{ | RPCHelpMan{ | ||||
"abortrescan", | "abortrescan", | ||||
"Stops current wallet rescan triggered by an RPC call, e.g. by an " | "Stops current wallet rescan triggered by an RPC call, e.g. by an " | ||||
"importprivkey call.\n" | "importprivkey call.\n" | ||||
"Note: Use \"getwalletinfo\" to query the scanning progress.\n", | "Note: Use \"getwalletinfo\" to query the scanning progress.\n", | ||||
{}, | {}, | ||||
RPCResult{RPCResult::Type::BOOL, "", | RPCResult{RPCResult::Type::BOOL, "", | ||||
"Whether the abort was successful"}, | "Whether the abort was successful"}, | ||||
RPCExamples{"\nImport a private key\n" + | RPCExamples{"\nImport a private key\n" + | ||||
HelpExampleCli("importprivkey", "\"mykey\"") + | HelpExampleCli("importprivkey", "\"mykey\"") + | ||||
"\nAbort the running wallet rescan\n" + | "\nAbort the running wallet rescan\n" + | ||||
HelpExampleCli("abortrescan", "") + | HelpExampleCli("abortrescan", "") + | ||||
"\nAs a JSON-RPC call\n" + | "\nAs a JSON-RPC call\n" + | ||||
HelpExampleRpc("abortrescan", "")}, | HelpExampleRpc("abortrescan", "")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | |||||
if (!wallet) { | |||||
return NullUniValue; | |||||
} | |||||
CWallet *const pwallet = wallet.get(); | |||||
if (!pwallet->IsScanning() || pwallet->IsAbortingRescan()) { | if (!pwallet->IsScanning() || pwallet->IsAbortingRescan()) { | ||||
return false; | return false; | ||||
} | } | ||||
pwallet->AbortRescan(); | pwallet->AbortRescan(); | ||||
return true; | return true; | ||||
} | } | ||||
UniValue importaddress(const Config &config, const JSONRPCRequest &request) { | UniValue importaddress(const Config &config, const JSONRPCRequest &request) { | ||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | |||||
if (!wallet) { | |||||
return NullUniValue; | |||||
} | |||||
CWallet *const pwallet = wallet.get(); | |||||
RPCHelpMan{ | RPCHelpMan{ | ||||
"importaddress", | "importaddress", | ||||
"Adds an address or script (in hex) that can be watched as if it " | "Adds an address or script (in hex) that can be watched as if it " | ||||
"were in your wallet but cannot be used to spend. Requires a new " | "were in your wallet but cannot be used to spend. Requires a new " | ||||
"wallet backup.\n" | "wallet backup.\n" | ||||
"\nNote: This call can take minutes to complete if rescan is true, " | "\nNote: This call can take minutes to complete if rescan is true, " | ||||
"during that time, other rpc calls\n" | "during that time, other rpc calls\n" | ||||
"may report that the imported address exists but related transactions " | "may report that the imported address exists but related transactions " | ||||
Show All 23 Lines | RPCHelpMan{ | ||||
"\nImport using a label without rescan\n" + | "\nImport using a label without rescan\n" + | ||||
HelpExampleCli("importaddress", "\"myaddress\" \"testing\" false") + | HelpExampleCli("importaddress", "\"myaddress\" \"testing\" false") + | ||||
"\nAs a JSON-RPC call\n" + | "\nAs a JSON-RPC call\n" + | ||||
HelpExampleRpc("importaddress", | HelpExampleRpc("importaddress", | ||||
"\"myaddress\", \"testing\", false")}, | "\"myaddress\", \"testing\", false")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | |||||
if (!wallet) { | |||||
return NullUniValue; | |||||
} | |||||
CWallet *const pwallet = wallet.get(); | |||||
EnsureLegacyScriptPubKeyMan(*pwallet, true); | EnsureLegacyScriptPubKeyMan(*pwallet, true); | ||||
std::string strLabel; | std::string strLabel; | ||||
if (!request.params[1].isNull()) { | if (!request.params[1].isNull()) { | ||||
strLabel = request.params[1].get_str(); | strLabel = request.params[1].get_str(); | ||||
} | } | ||||
// Whether to perform rescan after import | // Whether to perform rescan after import | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | if (fRescan) { | ||||
} | } | ||||
} | } | ||||
return NullUniValue; | return NullUniValue; | ||||
} | } | ||||
UniValue importprunedfunds(const Config &config, | UniValue importprunedfunds(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | |||||
if (!wallet) { | |||||
return NullUniValue; | |||||
} | |||||
CWallet *const pwallet = wallet.get(); | |||||
RPCHelpMan{ | RPCHelpMan{ | ||||
"importprunedfunds", | "importprunedfunds", | ||||
"Imports funds without rescan. Corresponding address or script must " | "Imports funds without rescan. Corresponding address or script must " | ||||
"previously be included in wallet. Aimed towards pruned wallets. The " | "previously be included in wallet. Aimed towards pruned wallets. The " | ||||
"end-user is responsible to import additional transactions that " | "end-user is responsible to import additional transactions that " | ||||
"subsequently spend the imported outputs or rescan after the point in " | "subsequently spend the imported outputs or rescan after the point in " | ||||
"the blockchain the transaction is included.\n", | "the blockchain the transaction is included.\n", | ||||
{ | { | ||||
{"rawtransaction", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, | {"rawtransaction", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, | ||||
"A raw transaction in hex funding an already-existing address in " | "A raw transaction in hex funding an already-existing address in " | ||||
"wallet"}, | "wallet"}, | ||||
{"txoutproof", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, | {"txoutproof", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, | ||||
"The hex output from gettxoutproof that contains the transaction"}, | "The hex output from gettxoutproof that contains the transaction"}, | ||||
}, | }, | ||||
RPCResult{RPCResult::Type::NONE, "", ""}, | RPCResult{RPCResult::Type::NONE, "", ""}, | ||||
RPCExamples{""}, | RPCExamples{""}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | |||||
if (!wallet) { | |||||
return NullUniValue; | |||||
} | |||||
CWallet *const pwallet = wallet.get(); | |||||
CMutableTransaction tx; | CMutableTransaction tx; | ||||
if (!DecodeHexTx(tx, request.params[0].get_str())) { | if (!DecodeHexTx(tx, request.params[0].get_str())) { | ||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); | throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); | ||||
} | } | ||||
uint256 txid = tx.GetId(); | uint256 txid = tx.GetId(); | ||||
CDataStream ssMB(ParseHexV(request.params[1], "proof"), SER_NETWORK, | CDataStream ssMB(ParseHexV(request.params[1], "proof"), SER_NETWORK, | ||||
PROTOCOL_VERSION); | PROTOCOL_VERSION); | ||||
Show All 38 Lines | UniValue importprunedfunds(const Config &config, | ||||
throw JSONRPCError( | throw JSONRPCError( | ||||
RPC_INVALID_ADDRESS_OR_KEY, | RPC_INVALID_ADDRESS_OR_KEY, | ||||
"No addresses in wallet correspond to included transaction"); | "No addresses in wallet correspond to included transaction"); | ||||
} | } | ||||
UniValue removeprunedfunds(const Config &config, | UniValue removeprunedfunds(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | |||||
if (!wallet) { | |||||
return NullUniValue; | |||||
} | |||||
CWallet *const pwallet = wallet.get(); | |||||
RPCHelpMan{ | RPCHelpMan{ | ||||
"removeprunedfunds", | "removeprunedfunds", | ||||
"Deletes the specified transaction from the wallet. Meant for use " | "Deletes the specified transaction from the wallet. Meant for use " | ||||
"with pruned wallets and as a companion to importprunedfunds. This " | "with pruned wallets and as a companion to importprunedfunds. This " | ||||
"will affect wallet balances.\n", | "will affect wallet balances.\n", | ||||
{ | { | ||||
{"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, | {"txid", RPCArg::Type::STR_HEX, RPCArg::Optional::NO, | ||||
"The hex-encoded id of the transaction you are deleting"}, | "The hex-encoded id of the transaction you are deleting"}, | ||||
}, | }, | ||||
RPCResult{RPCResult::Type::NONE, "", ""}, | RPCResult{RPCResult::Type::NONE, "", ""}, | ||||
RPCExamples{HelpExampleCli("removeprunedfunds", | RPCExamples{HelpExampleCli("removeprunedfunds", | ||||
"\"a8d0c0184dde994a09ec054286f1ce581bebf4644" | "\"a8d0c0184dde994a09ec054286f1ce581bebf4644" | ||||
"6a512166eae7628734ea0a5\"") + | "6a512166eae7628734ea0a5\"") + | ||||
"\nAs a JSON-RPC call\n" + | "\nAs a JSON-RPC call\n" + | ||||
HelpExampleRpc("removeprunedfunds", | HelpExampleRpc("removeprunedfunds", | ||||
"\"a8d0c0184dde994a09ec054286f1ce581bebf4644" | "\"a8d0c0184dde994a09ec054286f1ce581bebf4644" | ||||
"6a512166eae7628734ea0a5\"")}, | "6a512166eae7628734ea0a5\"")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | |||||
if (!wallet) { | |||||
return NullUniValue; | |||||
} | |||||
CWallet *const pwallet = wallet.get(); | |||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
TxId txid(ParseHashV(request.params[0], "txid")); | TxId txid(ParseHashV(request.params[0], "txid")); | ||||
std::vector<TxId> txIds; | std::vector<TxId> txIds; | ||||
txIds.push_back(txid); | txIds.push_back(txid); | ||||
std::vector<TxId> txIdsOut; | std::vector<TxId> txIdsOut; | ||||
if (pwallet->ZapSelectTx(txIds, txIdsOut) != DBErrors::LOAD_OK) { | if (pwallet->ZapSelectTx(txIds, txIdsOut) != DBErrors::LOAD_OK) { | ||||
throw JSONRPCError(RPC_WALLET_ERROR, | throw JSONRPCError(RPC_WALLET_ERROR, | ||||
"Could not properly delete the transaction."); | "Could not properly delete the transaction."); | ||||
} | } | ||||
if (txIdsOut.empty()) { | if (txIdsOut.empty()) { | ||||
throw JSONRPCError(RPC_INVALID_PARAMETER, | throw JSONRPCError(RPC_INVALID_PARAMETER, | ||||
"Transaction does not exist in wallet."); | "Transaction does not exist in wallet."); | ||||
} | } | ||||
return NullUniValue; | return NullUniValue; | ||||
} | } | ||||
UniValue importpubkey(const Config &config, const JSONRPCRequest &request) { | UniValue importpubkey(const Config &config, const JSONRPCRequest &request) { | ||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | |||||
if (!wallet) { | |||||
return NullUniValue; | |||||
} | |||||
CWallet *const pwallet = wallet.get(); | |||||
RPCHelpMan{ | RPCHelpMan{ | ||||
"importpubkey", | "importpubkey", | ||||
"Adds a public key (in hex) that can be watched as if it were in " | "Adds a public key (in hex) that can be watched as if it were in " | ||||
"your wallet but cannot be used to spend. Requires a new wallet " | "your wallet but cannot be used to spend. Requires a new wallet " | ||||
"backup.\n" | "backup.\n" | ||||
"Hint: use importmulti to import more than one public key.\n" | "Hint: use importmulti to import more than one public key.\n" | ||||
"\nNote: This call can take minutes to complete if rescan is true, " | "\nNote: This call can take minutes to complete if rescan is true, " | ||||
"during that time, other rpc calls\n" | "during that time, other rpc calls\n" | ||||
Show All 15 Lines | RPCHelpMan{ | ||||
HelpExampleCli("importpubkey", "\"mypubkey\"") + | HelpExampleCli("importpubkey", "\"mypubkey\"") + | ||||
"\nImport using a label without rescan\n" + | "\nImport using a label without rescan\n" + | ||||
HelpExampleCli("importpubkey", "\"mypubkey\" \"testing\" false") + | HelpExampleCli("importpubkey", "\"mypubkey\" \"testing\" false") + | ||||
"\nAs a JSON-RPC call\n" + | "\nAs a JSON-RPC call\n" + | ||||
HelpExampleRpc("importpubkey", "\"mypubkey\", \"testing\", false")}, | HelpExampleRpc("importpubkey", "\"mypubkey\", \"testing\", false")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | |||||
if (!wallet) { | |||||
return NullUniValue; | |||||
} | |||||
CWallet *const pwallet = wallet.get(); | |||||
EnsureLegacyScriptPubKeyMan(*wallet, true); | EnsureLegacyScriptPubKeyMan(*wallet, true); | ||||
std::string strLabel; | std::string strLabel; | ||||
if (!request.params[1].isNull()) { | if (!request.params[1].isNull()) { | ||||
strLabel = request.params[1].get_str(); | strLabel = request.params[1].get_str(); | ||||
} | } | ||||
// Whether to perform rescan after import | // Whether to perform rescan after import | ||||
▲ Show 20 Lines • Show All 53 Lines • ▼ Show 20 Lines | if (fRescan) { | ||||
pwallet->ReacceptWalletTransactions(); | pwallet->ReacceptWalletTransactions(); | ||||
} | } | ||||
} | } | ||||
return NullUniValue; | return NullUniValue; | ||||
} | } | ||||
UniValue importwallet(const Config &config, const JSONRPCRequest &request) { | UniValue importwallet(const Config &config, const JSONRPCRequest &request) { | ||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | |||||
if (!wallet) { | |||||
return NullUniValue; | |||||
} | |||||
CWallet *const pwallet = wallet.get(); | |||||
RPCHelpMan{ | RPCHelpMan{ | ||||
"importwallet", | "importwallet", | ||||
"Imports keys from a wallet dump file (see dumpwallet). Requires a " | "Imports keys from a wallet dump file (see dumpwallet). Requires a " | ||||
"new wallet backup to include imported keys.\n" | "new wallet backup to include imported keys.\n" | ||||
"Note: Use \"getwalletinfo\" to query the scanning progress.\n", | "Note: Use \"getwalletinfo\" to query the scanning progress.\n", | ||||
{ | { | ||||
{"filename", RPCArg::Type::STR, RPCArg::Optional::NO, | {"filename", RPCArg::Type::STR, RPCArg::Optional::NO, | ||||
"The wallet file"}, | "The wallet file"}, | ||||
}, | }, | ||||
RPCResult{RPCResult::Type::NONE, "", ""}, | RPCResult{RPCResult::Type::NONE, "", ""}, | ||||
RPCExamples{"\nDump the wallet\n" + | RPCExamples{"\nDump the wallet\n" + | ||||
HelpExampleCli("dumpwallet", "\"test\"") + | HelpExampleCli("dumpwallet", "\"test\"") + | ||||
"\nImport the wallet\n" + | "\nImport the wallet\n" + | ||||
HelpExampleCli("importwallet", "\"test\"") + | HelpExampleCli("importwallet", "\"test\"") + | ||||
"\nImport using the json rpc call\n" + | "\nImport using the json rpc call\n" + | ||||
HelpExampleRpc("importwallet", "\"test\"")}, | HelpExampleRpc("importwallet", "\"test\"")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | |||||
if (!wallet) { | |||||
return NullUniValue; | |||||
} | |||||
CWallet *const pwallet = wallet.get(); | |||||
EnsureLegacyScriptPubKeyMan(*wallet, true); | EnsureLegacyScriptPubKeyMan(*wallet, true); | ||||
if (pwallet->chain().havePruned()) { | if (pwallet->chain().havePruned()) { | ||||
// Exit early and print an error. | // Exit early and print an error. | ||||
// If a block is pruned after this check, we will import the key(s), | // If a block is pruned after this check, we will import the key(s), | ||||
// but fail the rescan with a generic error. | // but fail the rescan with a generic error. | ||||
throw JSONRPCError( | throw JSONRPCError( | ||||
RPC_WALLET_ERROR, | RPC_WALLET_ERROR, | ||||
▲ Show 20 Lines • Show All 162 Lines • ▼ Show 20 Lines | if (!fGood) { | ||||
throw JSONRPCError(RPC_WALLET_ERROR, | throw JSONRPCError(RPC_WALLET_ERROR, | ||||
"Error adding some keys/scripts to wallet"); | "Error adding some keys/scripts to wallet"); | ||||
} | } | ||||
return NullUniValue; | return NullUniValue; | ||||
} | } | ||||
UniValue dumpprivkey(const Config &config, const JSONRPCRequest &request) { | UniValue dumpprivkey(const Config &config, const JSONRPCRequest &request) { | ||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | |||||
if (!wallet) { | |||||
return NullUniValue; | |||||
} | |||||
const CWallet *const pwallet = wallet.get(); | |||||
RPCHelpMan{ | RPCHelpMan{ | ||||
"dumpprivkey", | "dumpprivkey", | ||||
"Reveals the private key corresponding to 'address'.\n" | "Reveals the private key corresponding to 'address'.\n" | ||||
"Then the importprivkey can be used with this output\n", | "Then the importprivkey can be used with this output\n", | ||||
{ | { | ||||
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, | {"address", RPCArg::Type::STR, RPCArg::Optional::NO, | ||||
"The bitcoin address for the private key"}, | "The bitcoin address for the private key"}, | ||||
}, | }, | ||||
RPCResult{RPCResult::Type::STR, "key", "The private key"}, | RPCResult{RPCResult::Type::STR, "key", "The private key"}, | ||||
RPCExamples{HelpExampleCli("dumpprivkey", "\"myaddress\"") + | RPCExamples{HelpExampleCli("dumpprivkey", "\"myaddress\"") + | ||||
HelpExampleCli("importprivkey", "\"mykey\"") + | HelpExampleCli("importprivkey", "\"mykey\"") + | ||||
HelpExampleRpc("dumpprivkey", "\"myaddress\"")}, | HelpExampleRpc("dumpprivkey", "\"myaddress\"")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
std::shared_ptr<CWallet> const wallet = GetWalletForJSONRPCRequest(request); | |||||
if (!wallet) { | |||||
return NullUniValue; | |||||
} | |||||
const CWallet *const pwallet = wallet.get(); | |||||
LegacyScriptPubKeyMan &spk_man = EnsureLegacyScriptPubKeyMan(*wallet); | LegacyScriptPubKeyMan &spk_man = EnsureLegacyScriptPubKeyMan(*wallet); | ||||
LOCK2(pwallet->cs_wallet, spk_man.cs_KeyStore); | LOCK2(pwallet->cs_wallet, spk_man.cs_KeyStore); | ||||
EnsureWalletIsUnlocked(pwallet); | EnsureWalletIsUnlocked(pwallet); | ||||
std::string strAddress = request.params[0].get_str(); | std::string strAddress = request.params[0].get_str(); | ||||
CTxDestination dest = | CTxDestination dest = | ||||
Show All 10 Lines | UniValue dumpprivkey(const Config &config, const JSONRPCRequest &request) { | ||||
if (!spk_man.GetKey(keyid, vchSecret)) { | if (!spk_man.GetKey(keyid, vchSecret)) { | ||||
throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + | throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + | ||||
strAddress + " is not known"); | strAddress + " is not known"); | ||||
} | } | ||||
return EncodeSecret(vchSecret); | return EncodeSecret(vchSecret); | ||||
} | } | ||||
UniValue dumpwallet(const Config &config, const JSONRPCRequest &request) { | UniValue dumpwallet(const Config &config, const JSONRPCRequest &request) { | ||||
std::shared_ptr<CWallet> const pwallet = | |||||
GetWalletForJSONRPCRequest(request); | |||||
if (!pwallet) { | |||||
return NullUniValue; | |||||
} | |||||
RPCHelpMan{ | RPCHelpMan{ | ||||
"dumpwallet", | "dumpwallet", | ||||
"Dumps all wallet keys in a human-readable format to a server-side " | "Dumps all wallet keys in a human-readable format to a server-side " | ||||
"file. This does not allow overwriting existing files.\n" | "file. This does not allow overwriting existing files.\n" | ||||
"Imported scripts are included in the dumpsfile, but corresponding " | "Imported scripts are included in the dumpsfile, but corresponding " | ||||
"addresses may not be added automatically by importwallet.\n" | "addresses may not be added automatically by importwallet.\n" | ||||
"Note that if your wallet contains keys which are not derived from " | "Note that if your wallet contains keys which are not derived from " | ||||
"your HD seed (e.g. imported keys), these are not covered by\n" | "your HD seed (e.g. imported keys), these are not covered by\n" | ||||
Show All 10 Lines | RPCHelpMan{ | ||||
{RPCResult::Type::STR, "filename", | {RPCResult::Type::STR, "filename", | ||||
"The filename with full absolute path"}, | "The filename with full absolute path"}, | ||||
}}, | }}, | ||||
RPCExamples{HelpExampleCli("dumpwallet", "\"test\"") + | RPCExamples{HelpExampleCli("dumpwallet", "\"test\"") + | ||||
HelpExampleRpc("dumpwallet", "\"test\"")}, | HelpExampleRpc("dumpwallet", "\"test\"")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
std::shared_ptr<CWallet> const pwallet = | |||||
GetWalletForJSONRPCRequest(request); | |||||
if (!pwallet) { | |||||
return NullUniValue; | |||||
} | |||||
CWallet &wallet = *pwallet; | CWallet &wallet = *pwallet; | ||||
LegacyScriptPubKeyMan &spk_man = EnsureLegacyScriptPubKeyMan(wallet); | LegacyScriptPubKeyMan &spk_man = EnsureLegacyScriptPubKeyMan(wallet); | ||||
// Make sure the results are valid at least up to the most recent block | // Make sure the results are valid at least up to the most recent block | ||||
// the user could have gotten from another RPC command prior to now | // the user could have gotten from another RPC command prior to now | ||||
wallet.BlockUntilSyncedToCurrentChain(); | wallet.BlockUntilSyncedToCurrentChain(); | ||||
LOCK2(wallet.cs_wallet, spk_man.cs_KeyStore); | LOCK2(wallet.cs_wallet, spk_man.cs_KeyStore); | ||||
▲ Show 20 Lines • Show All 113 Lines • ▼ Show 20 Lines | UniValue dumpwallet(const Config &config, const JSONRPCRequest &request) { | ||||
UniValue reply(UniValue::VOBJ); | UniValue reply(UniValue::VOBJ); | ||||
reply.pushKV("filename", filepath.string()); | reply.pushKV("filename", filepath.string()); | ||||
return reply; | return reply; | ||||
} | } | ||||
static UniValue dumpcoins(const Config &config, const JSONRPCRequest &request) { | static UniValue dumpcoins(const Config &config, const JSONRPCRequest &request) { | ||||
std::shared_ptr<CWallet> const pwallet = | |||||
GetWalletForJSONRPCRequest(request); | |||||
if (!pwallet) { | |||||
return NullUniValue; | |||||
} | |||||
RPCHelpMan{ | RPCHelpMan{ | ||||
"dumpcoins", | "dumpcoins", | ||||
"dump all the UTXO tracked by the wallet.\n", | "dump all the UTXO tracked by the wallet.\n", | ||||
{}, | {}, | ||||
RPCResult{ | RPCResult{ | ||||
RPCResult::Type::OBJ_DYN, | RPCResult::Type::OBJ_DYN, | ||||
"", | "", | ||||
"", | "", | ||||
Show All 16 Lines | RPCHelpMan{ | ||||
}}, | }}, | ||||
}}, | }}, | ||||
}, | }, | ||||
RPCExamples{HelpExampleCli("dumpcoins", "") + | RPCExamples{HelpExampleCli("dumpcoins", "") + | ||||
HelpExampleRpc("dumpcoins", "")}, | HelpExampleRpc("dumpcoins", "")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
std::shared_ptr<CWallet> const pwallet = | |||||
GetWalletForJSONRPCRequest(request); | |||||
if (!pwallet) { | |||||
return NullUniValue; | |||||
} | |||||
CWallet &wallet = *pwallet; | CWallet &wallet = *pwallet; | ||||
// Make sure the results are valid at least up to the most recent block | // Make sure the results are valid at least up to the most recent block | ||||
// the user could have gotten from another RPC command prior to now | // the user could have gotten from another RPC command prior to now | ||||
wallet.BlockUntilSyncedToCurrentChain(); | wallet.BlockUntilSyncedToCurrentChain(); | ||||
LOCK(wallet.cs_wallet); | LOCK(wallet.cs_wallet); | ||||
▲ Show 20 Lines • Show All 516 Lines • ▼ Show 20 Lines | if (data.exists("timestamp")) { | ||||
"value for key. got type %s", | "value for key. got type %s", | ||||
uvTypeName(timestamp.type()))); | uvTypeName(timestamp.type()))); | ||||
} | } | ||||
throw JSONRPCError(RPC_TYPE_ERROR, | throw JSONRPCError(RPC_TYPE_ERROR, | ||||
"Missing required timestamp field for key"); | "Missing required timestamp field for key"); | ||||
} | } | ||||
UniValue importmulti(const Config &config, const JSONRPCRequest &mainRequest) { | UniValue importmulti(const Config &config, const JSONRPCRequest &mainRequest) { | ||||
std::shared_ptr<CWallet> const wallet = | |||||
GetWalletForJSONRPCRequest(mainRequest); | |||||
if (!wallet) { | |||||
return NullUniValue; | |||||
} | |||||
CWallet *const pwallet = wallet.get(); | |||||
RPCHelpMan{ | RPCHelpMan{ | ||||
"importmulti", | "importmulti", | ||||
"\nImport addresses/scripts (with private or public keys, redeem " | "\nImport addresses/scripts (with private or public keys, redeem " | ||||
"script (P2SH)), optionally rescanning the blockchain from the " | "script (P2SH)), optionally rescanning the blockchain from the " | ||||
"earliest creation time of the imported scripts. Requires a new wallet " | "earliest creation time of the imported scripts. Requires a new wallet " | ||||
"backup.\n" | "backup.\n" | ||||
"If an address/script is imported without all of the private keys " | "If an address/script is imported without all of the private keys " | ||||
"required to spend from that address, it will be watchonly. The " | "required to spend from that address, it will be watchonly. The " | ||||
▲ Show 20 Lines • Show All 161 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
"importmulti", | "importmulti", | ||||
"'[{ \"scriptPubKey\": { \"address\": \"<my address>\" }, " | "'[{ \"scriptPubKey\": { \"address\": \"<my address>\" }, " | ||||
"\"timestamp\":1455191478 }]' '{ \"rescan\": false}'") | "\"timestamp\":1455191478 }]' '{ \"rescan\": false}'") | ||||
}, | }, | ||||
} | } | ||||
.Check(mainRequest); | .Check(mainRequest); | ||||
std::shared_ptr<CWallet> const wallet = | |||||
GetWalletForJSONRPCRequest(mainRequest); | |||||
if (!wallet) { | |||||
return NullUniValue; | |||||
} | |||||
CWallet *const pwallet = wallet.get(); | |||||
RPCTypeCheck(mainRequest.params, {UniValue::VARR, UniValue::VOBJ}); | RPCTypeCheck(mainRequest.params, {UniValue::VARR, UniValue::VOBJ}); | ||||
EnsureLegacyScriptPubKeyMan(*wallet, true); | EnsureLegacyScriptPubKeyMan(*wallet, true); | ||||
const UniValue &requests = mainRequest.params[0]; | const UniValue &requests = mainRequest.params[0]; | ||||
// Default options | // Default options | ||||
bool fRescan = true; | bool fRescan = true; | ||||
▲ Show 20 Lines • Show All 287 Lines • ▼ Show 20 Lines | static UniValue ProcessDescriptorImport(CWallet *const pwallet, | ||||
if (warnings.size()) { | if (warnings.size()) { | ||||
result.pushKV("warnings", warnings); | result.pushKV("warnings", warnings); | ||||
} | } | ||||
return result; | return result; | ||||
} | } | ||||
UniValue importdescriptors(const Config &config, | UniValue importdescriptors(const Config &config, | ||||
const JSONRPCRequest &main_request) { | const JSONRPCRequest &main_request) { | ||||
// Acquire the wallet | |||||
std::shared_ptr<CWallet> const wallet = | |||||
GetWalletForJSONRPCRequest(main_request); | |||||
if (!wallet) { | |||||
return NullUniValue; | |||||
} | |||||
CWallet *const pwallet = wallet.get(); | |||||
RPCHelpMan{ | RPCHelpMan{ | ||||
"importdescriptors", | "importdescriptors", | ||||
"\nImport descriptors. This will trigger a rescan of the blockchain " | "\nImport descriptors. This will trigger a rescan of the blockchain " | ||||
"based on the earliest timestamp of all descriptors being imported. " | "based on the earliest timestamp of all descriptors being imported. " | ||||
"Requires a new wallet backup.\n" | "Requires a new wallet backup.\n" | ||||
"\nNote: This call can take over an hour to complete if using an early " | "\nNote: This call can take over an hour to complete if using an early " | ||||
"timestamp; during that time, other rpc calls\n" | "timestamp; during that time, other rpc calls\n" | ||||
"may report that the imported keys, addresses or scripts exist but " | "may report that the imported keys, addresses or scripts exist but " | ||||
▲ Show 20 Lines • Show All 94 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
HelpExampleCli( | HelpExampleCli( | ||||
"importdescriptors", | "importdescriptors", | ||||
"'[{ \"desc\": \"<my descriptor>\", \"timestamp\":1455191478, " | "'[{ \"desc\": \"<my descriptor>\", \"timestamp\":1455191478, " | ||||
"\"active\": true, \"range\": [0,100], \"label\": \"<my " | "\"active\": true, \"range\": [0,100], \"label\": \"<my " | ||||
"cashaddr wallet>\" }]'")}, | "cashaddr wallet>\" }]'")}, | ||||
} | } | ||||
.Check(main_request); | .Check(main_request); | ||||
std::shared_ptr<CWallet> const wallet = | |||||
GetWalletForJSONRPCRequest(main_request); | |||||
if (!wallet) { | |||||
return NullUniValue; | |||||
} | |||||
CWallet *const pwallet = wallet.get(); | |||||
// Make sure wallet is a descriptor wallet | // Make sure wallet is a descriptor wallet | ||||
if (!pwallet->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) { | if (!pwallet->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) { | ||||
throw JSONRPCError( | throw JSONRPCError( | ||||
RPC_WALLET_ERROR, | RPC_WALLET_ERROR, | ||||
"importdescriptors is not available for non-descriptor wallets"); | "importdescriptors is not available for non-descriptor wallets"); | ||||
} | } | ||||
RPCTypeCheck(main_request.params, {UniValue::VARR, UniValue::VOBJ}); | RPCTypeCheck(main_request.params, {UniValue::VARR, UniValue::VOBJ}); | ||||
▲ Show 20 Lines • Show All 127 Lines • Show Last 20 Lines |