1 // Copyright (c) 2016-2020 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5 #if defined(HAVE_CONFIG_H)
6 #include <config/bitcoin-config.h>
7 #endif
8
9 #include <chainparams.h>
10 #include <chainparamsbase.h>
11 #include <logging.h>
12 #include <util/system.h>
13 #include <util/translation.h>
14 #include <util/url.h>
15 #include <wallet/wallettool.h>
16
17 #include <functional>
18
19 const std::function<std::string(const char*)> G_TRANSLATION_FUN = nullptr;
20 UrlDecodeFn* const URL_DECODE = nullptr;
21
SetupWalletToolArgs(ArgsManager & argsman)22 static void SetupWalletToolArgs(ArgsManager& argsman)
23 {
24 SetupHelpOptions(argsman);
25 SetupChainParamsBaseOptions(argsman);
26
27 argsman.AddArg("-datadir=<dir>", "Specify data directory", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
28 argsman.AddArg("-wallet=<wallet-name>", "Specify wallet name", ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::OPTIONS);
29 argsman.AddArg("-debug=<category>", "Output debugging information (default: 0).", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
30 argsman.AddArg("-printtoconsole", "Send trace/debug info to console (default: 1 when no -debug is true, 0 otherwise).", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
31
32 argsman.AddArg("info", "Get wallet info", ArgsManager::ALLOW_ANY, OptionsCategory::COMMANDS);
33 argsman.AddArg("create", "Create new wallet file", ArgsManager::ALLOW_ANY, OptionsCategory::COMMANDS);
34 argsman.AddArg("salvage", "Attempt to recover private keys from a corrupt wallet. Warning: 'salvage' is experimental.", ArgsManager::ALLOW_ANY, OptionsCategory::COMMANDS);
35 }
36
WalletAppInit(int argc,char * argv[])37 static bool WalletAppInit(int argc, char* argv[])
38 {
39 SetupWalletToolArgs(gArgs);
40 std::string error_message;
41 if (!gArgs.ParseParameters(argc, argv, error_message)) {
42 tfm::format(std::cerr, "Error parsing command line arguments: %s\n", error_message);
43 return false;
44 }
45 if (argc < 2 || HelpRequested(gArgs)) {
46 std::string usage = strprintf("%s namecoin-wallet version", PACKAGE_NAME) + " " + FormatFullVersion() + "\n\n" +
47 "namecoin-wallet is an offline tool for creating and interacting with " PACKAGE_NAME " wallet files.\n" +
48 "By default namecoin-wallet will act on wallets in the default mainnet wallet directory in the datadir.\n" +
49 "To change the target wallet, use the -datadir, -wallet and -testnet/-regtest arguments.\n\n" +
50 "Usage:\n" +
51 " namecoin-wallet [options] <command>\n\n" +
52 gArgs.GetHelpMessage();
53
54 tfm::format(std::cout, "%s", usage);
55 return false;
56 }
57
58 // check for printtoconsole, allow -debug
59 LogInstance().m_print_to_console = gArgs.GetBoolArg("-printtoconsole", gArgs.GetBoolArg("-debug", false));
60
61 if (!CheckDataDirOption()) {
62 tfm::format(std::cerr, "Error: Specified data directory \"%s\" does not exist.\n", gArgs.GetArg("-datadir", ""));
63 return false;
64 }
65 // Check for chain settings (Params() calls are only valid after this clause)
66 SelectParams(gArgs.GetChainName());
67
68 return true;
69 }
70
main(int argc,char * argv[])71 int main(int argc, char* argv[])
72 {
73 #ifdef WIN32
74 util::WinCmdLineArgs winArgs;
75 std::tie(argc, argv) = winArgs.get();
76 #endif
77 SetupEnvironment();
78 RandomInit();
79 try {
80 if (!WalletAppInit(argc, argv)) return EXIT_FAILURE;
81 } catch (const std::exception& e) {
82 PrintExceptionContinue(&e, "WalletAppInit()");
83 return EXIT_FAILURE;
84 } catch (...) {
85 PrintExceptionContinue(nullptr, "WalletAppInit()");
86 return EXIT_FAILURE;
87 }
88
89 std::string method {};
90 for(int i = 1; i < argc; ++i) {
91 if (!IsSwitchChar(argv[i][0])) {
92 if (!method.empty()) {
93 tfm::format(std::cerr, "Error: two methods provided (%s and %s). Only one method should be provided.\n", method, argv[i]);
94 return EXIT_FAILURE;
95 }
96 method = argv[i];
97 }
98 }
99
100 if (method.empty()) {
101 tfm::format(std::cerr, "No method provided. Run `namecoin-wallet -help` for valid methods.\n");
102 return EXIT_FAILURE;
103 }
104
105 // A name must be provided when creating a file
106 if (method == "create" && !gArgs.IsArgSet("-wallet")) {
107 tfm::format(std::cerr, "Wallet name must be provided when creating a new wallet.\n");
108 return EXIT_FAILURE;
109 }
110
111 std::string name = gArgs.GetArg("-wallet", "");
112
113 ECCVerifyHandle globalVerifyHandle;
114 ECC_Start();
115 if (!WalletTool::ExecuteWalletToolFunc(method, name))
116 return EXIT_FAILURE;
117 ECC_Stop();
118 return EXIT_SUCCESS;
119 }
120