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