| 32 | static string EncodeDumpTime(int64_t nTime) { return DateTimeStrFormat("%Y-%m-%dT%H:%M:%SZ", nTime); } |
| 33 | |
| 34 | Value dumpwallet(const Array& params, bool fHelp) { |
| 35 | if (fHelp || params.size() != 1) |
| 36 | throw runtime_error( |
| 37 | "dumpwallet \"filename\"\n" |
| 38 | "\nDumps all wallet keys in a human-readable format.\n" |
| 39 | "\nArguments:\n" |
| 40 | "1. \"filename\" (string, required) The filename\n" |
| 41 | "\nExamples:\n" + |
| 42 | HelpExampleCli("dumpwallet", "target_dumpwallet_filepath") + "\nAs a json rpc call\n" + |
| 43 | HelpExampleRpc("dumpwallet", "target_dumpwallet_filepath")); |
| 44 | |
| 45 | EnsureWalletIsUnlocked(); |
| 46 | |
| 47 | string dumpFilePath = params[0].get_str().c_str(); |
| 48 | if (dumpFilePath.find(GetDataDir().string()) != std::string::npos) |
| 49 | throw JSONRPCError(RPC_WALLET_FILEPATH_INVALID, |
| 50 | "Wallet file shall not be saved into the Data dir to avoid likely file overwrite."); |
| 51 | |
| 52 | ofstream file; |
| 53 | file.open(dumpFilePath); |
| 54 | if (!file.is_open()) |
| 55 | throw JSONRPCError(RPC_INVALID_PARAMETER, "Failed to open dump file."); |
| 56 | |
| 57 | Object reply; |
| 58 | reply.push_back(Pair("created_version", CLIENT_BUILD + CLIENT_DATE)); |
| 59 | reply.push_back(Pair("created_time", EncodeDumpTime(GetTime()))); |
| 60 | reply.push_back(Pair("tip_block_height", chainActive.Height())); |
| 61 | reply.push_back(Pair("tip_block_hash", chainActive.Tip()->GetBlockHash().ToString())); |
| 62 | |
| 63 | set<CKeyID> setKeyIds; |
| 64 | pWalletMain->GetKeys(setKeyIds); |
| 65 | Array arrKeys; |
| 66 | for (auto & keyId : setKeyIds) { |
| 67 | CKeyCombi keyCombi; |
| 68 | pWalletMain->GetKeyCombi(keyId, keyCombi); |
| 69 | Object obj = keyCombi.ToJsonObj(); |
| 70 | obj.push_back(Pair("keyid", keyId.ToString())); |
| 71 | arrKeys.push_back(obj); |
| 72 | } |
| 73 | |
| 74 | reply.push_back(Pair("key", arrKeys)); |
| 75 | file << write_string(Value(reply), true); |
| 76 | file.close(); |
| 77 | |
| 78 | Object reply2; |
| 79 | reply2.push_back(Pair("info", "successfully dumped wallet")); |
| 80 | reply2.push_back(Pair("count", (int32_t)setKeyIds.size())); |
| 81 | return reply2; |
| 82 | } |
| 83 | |
| 84 | Value importwallet(const Array& params, bool fHelp) { |
| 85 | if (fHelp || params.size() != 1) |
nothing calls this directly
no test coverage detected