public static void main(String[] args) throws Exception { OptionParser parser = new OptionParser(); parser.accepts("help"); parser.accepts("force"); parser.accepts("debuglog"); OptionSpec<String> walletFileName = parser.accepts("wallet").withRequiredArg().defaultsTo("wallet"); OptionSpec<NetworkEnum> netFlag = parser .accepts("net") .withOptionalArg() .ofType(NetworkEnum.class) .defaultsTo(NetworkEnum.PROD); dateFlag = parser .accepts("date") .withRequiredArg() .ofType(Date.class) .withValuesConvertedBy(DateConverter.datePattern("yyyy/MM/dd")); OptionSpec<WaitForEnum> waitForFlag = parser.accepts("waitfor").withRequiredArg().ofType(WaitForEnum.class); OptionSpec<ValidationMode> modeFlag = parser .accepts("mode") .withRequiredArg() .ofType(ValidationMode.class) .defaultsTo(ValidationMode.SPV); OptionSpec<String> chainFlag = parser.accepts("chain").withRequiredArg(); // For addkey/delkey. parser.accepts("pubkey").withRequiredArg(); parser.accepts("privkey").withRequiredArg(); parser.accepts("addr").withRequiredArg(); parser.accepts("peers").withRequiredArg(); OptionSpec<String> outputFlag = parser.accepts("output").withRequiredArg(); parser.accepts("value").withRequiredArg(); parser.accepts("fee").withRequiredArg(); unixtimeFlag = parser.accepts("unixtime").withRequiredArg().ofType(Integer.class); OptionSpec<String> conditionFlag = parser.accepts("condition").withRequiredArg(); parser.accepts("locktime").withRequiredArg(); parser.accepts("allow-unconfirmed"); parser.accepts("offline"); parser.accepts("ignore-mandatory-extensions"); OptionSpec<String> passwordFlag = parser.accepts("password").withRequiredArg(); OptionSpec<String> paymentRequestLocation = parser.accepts("payment-request").withRequiredArg(); parser.accepts("no-pki"); options = parser.parse(args); final String HELP_TEXT = Resources.toString(WalletTool.class.getResource("wallet-tool-help.txt"), Charsets.UTF_8); if (args.length == 0 || options.has("help") || options.nonOptionArguments().size() < 1) { System.out.println(HELP_TEXT); return; } ActionEnum action; try { String actionStr = options.nonOptionArguments().get(0); actionStr = actionStr.toUpperCase().replace("-", "_"); action = ActionEnum.valueOf(actionStr); } catch (IllegalArgumentException e) { System.err.println("Could not understand action name " + options.nonOptionArguments().get(0)); return; } if (options.has("debuglog")) { BriefLogFormatter.init(); log.info("Starting up ..."); } else { // Disable logspam unless there is a flag. java.util.logging.Logger logger = LogManager.getLogManager().getLogger(""); logger.setLevel(Level.SEVERE); } switch (netFlag.value(options)) { case PROD: params = MainNetParams.get(); chainFileName = new File("prodnet.chain"); break; case TEST: params = TestNet3Params.get(); chainFileName = new File("testnet.chain"); break; case REGTEST: params = RegTestParams.get(); chainFileName = new File("regtest.chain"); break; default: throw new RuntimeException("Unreachable."); } mode = modeFlag.value(options); // Allow the user to override the name of the chain used. if (options.has(chainFlag)) { chainFileName = new File(chainFlag.value(options)); } if (options.has("condition")) { condition = new Condition(conditionFlag.value(options)); } if (options.has(passwordFlag)) { password = passwordFlag.value(options); } walletFile = new File(walletFileName.value(options)); if (action == ActionEnum.CREATE) { createWallet(options, params, walletFile); return; // We're done. } if (!walletFile.exists()) { System.err.println( "Specified wallet file " + walletFile + " does not exist. Try wallet-tool --wallet=" + walletFile + " create"); return; } if (action == ActionEnum.RAW_DUMP) { // Just parse the protobuf and print, then bail out. Don't try and do a real deserialization. // This is // useful mostly for investigating corrupted wallets. FileInputStream stream = new FileInputStream(walletFile); try { Protos.Wallet proto = WalletProtobufSerializer.parseToProto(stream); System.out.println(proto.toString()); return; } finally { stream.close(); } } try { WalletProtobufSerializer loader = new WalletProtobufSerializer(); if (options.has("ignore-mandatory-extensions")) loader.setRequireMandatoryExtensions(false); wallet = loader.readWallet(new BufferedInputStream(new FileInputStream(walletFile))); if (!wallet.getParams().equals(params)) { System.err.println( "Wallet does not match requested network parameters: " + wallet.getParams().getId() + " vs " + params.getId()); return; } } catch (Exception e) { System.err.println("Failed to load wallet '" + walletFile + "': " + e.getMessage()); e.printStackTrace(); return; } // What should we do? switch (action) { case DUMP: dumpWallet(); break; case ADD_KEY: addKey(); break; case ADD_ADDR: addAddr(); break; case DELETE_KEY: deleteKey(); break; case RESET: reset(); break; case SYNC: syncChain(); break; case SEND: if (options.has(paymentRequestLocation) && options.has(outputFlag)) { System.err.println("--payment-request and --output cannot be used together."); return; } else if (options.has(outputFlag)) { BigInteger fee = BigInteger.ZERO; if (options.has("fee")) { fee = Utils.toNanoCoins((String) options.valueOf("fee")); } String lockTime = null; if (options.has("locktime")) { lockTime = (String) options.valueOf("locktime"); } boolean allowUnconfirmed = options.has("allow-unconfirmed"); send(outputFlag.values(options), fee, lockTime, allowUnconfirmed); } else if (options.has(paymentRequestLocation)) { sendPaymentRequest(paymentRequestLocation.value(options), !options.has("no-pki")); } else { System.err.println( "You must specify a --payment-request or at least one --output=addr:value."); return; } break; } if (!wallet.isConsistent()) { System.err.println("************** WALLET IS INCONSISTENT *****************"); return; } saveWallet(walletFile); if (options.has(waitForFlag)) { WaitForEnum value; try { value = waitForFlag.value(options); } catch (Exception e) { System.err.println( "Could not understand the --waitfor flag: Valid options are WALLET_TX, BLOCK, " + "BALANCE and EVER"); return; } wait(value); if (!wallet.isConsistent()) { System.err.println("************** WALLET IS INCONSISTENT *****************"); return; } saveWallet(walletFile); } shutdown(); }