diff --git a/jmclient/test/test_wallet.py b/jmclient/test/test_wallet.py index a2f4596cc..4b0c87a7f 100644 --- a/jmclient/test/test_wallet.py +++ b/jmclient/test/test_wallet.py @@ -12,11 +12,14 @@ SegwitLegacyWallet,BIP32Wallet, BIP49Wallet, LegacyWallet,\ VolatileStorage, get_network, cryptoengine, WalletError,\ SegwitWallet, WalletService, SegwitLegacyWalletFidelityBonds,\ - BTC_P2PKH, BTC_P2SH_P2WPKH,\ + BTC_P2PKH, BTC_P2SH_P2WPKH, create_wallet, open_test_wallet_maybe, \ FidelityBondMixin, FidelityBondWatchonlyWallet, wallet_gettimelockaddress from test_blockchaininterface import sync_test_wallet testdir = os.path.dirname(os.path.realpath(__file__)) + +test_create_wallet_filename = "testwallet_for_create_wallet_test" + log = get_log() @@ -815,10 +818,38 @@ def test_watchonly_wallet(setup_wallet): assert script == watchonly_script assert burn_pubkey == watchonly_burn_pubkey +@pytest.mark.parametrize('password, wallet_cls', [ + ["hunter2", SegwitLegacyWallet], + ["hunter2", SegwitWallet], +]) +def test_create_wallet(setup_wallet, password, wallet_cls): + wallet_name = test_create_wallet_filename + password = password.encode("utf-8") + # test mainnet (we are not transacting) + btc.select_chain_params("bitcoin") + wallet = create_wallet(wallet_name, password, 4, wallet_cls) + mnemonic = wallet.get_mnemonic_words()[0] + firstkey = wallet.get_key_from_addr(wallet.get_addr(0,0,0)) + print("Created mnemonic, firstkey: ", mnemonic, firstkey) + wallet.close() + # ensure that the wallet file created is openable with the password, + # and has the parameters that were claimed on creation: + new_wallet = open_test_wallet_maybe(wallet_name, "", 4, + password=password, ask_for_password=False) + assert new_wallet.get_mnemonic_words()[0] == mnemonic + assert new_wallet.get_key_from_addr( + new_wallet.get_addr(0,0,0)) == firstkey + os.remove(wallet_name) + btc.select_chain_params("bitcoin/regtest") + @pytest.fixture(scope='module') -def setup_wallet(): +def setup_wallet(request): load_test_config() btc.select_chain_params("bitcoin/regtest") #see note in cryptoengine.py: cryptoengine.BTC_P2WPKH.VBYTE = 100 jm_single().bc_interface.tick_forward_chain_interval = 2 + def teardown(): + if os.path.exists(test_create_wallet_filename): + os.remove(test_create_wallet_filename) + request.addfinalizer(teardown) diff --git a/scripts/README.md b/scripts/README.md index 01a621438..8f492da65 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -73,3 +73,7 @@ of the `commitments.json` file, explained above. ### sendtomany.py As above. + +### genwallet.py + +Non-interactively generate a wallet, giving only wallet name and password. Returns wallet seed as `recovery_seed:`. Useful for automating JoinMarket deployments. diff --git a/scripts/genwallet.py b/scripts/genwallet.py new file mode 100755 index 000000000..e3c069541 --- /dev/null +++ b/scripts/genwallet.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 + +import sys +import os +from optparse import OptionParser +from jmclient import load_program_config, add_base_options, SegwitLegacyWallet, create_wallet, jm_single +from jmbase.support import get_log, jmprint + +log = get_log() + +def main(): + parser = OptionParser( + usage='usage: %prog [options] wallet_file_name password', + description='Create a wallet with the given wallet name and password.') + add_base_options(parser) + (options, args) = parser.parse_args() + if options.wallet_password_stdin: + stdin = sys.stdin.read() + password = stdin.encode("utf-8") + else: + assert len(args) > 1, "must provide password via stdin (see --help), or as second argument." + password = args[1].encode("utf-8") + load_program_config(config_path=options.datadir) + wallet_root_path = os.path.join(jm_single().datadir, "wallets") + wallet_name = os.path.join(wallet_root_path, args[0]) + wallet = create_wallet(wallet_name, password, 4, SegwitLegacyWallet) + jmprint("recovery_seed:{}" + .format(wallet.get_mnemonic_words()[0]), "important") + wallet.close() + +if __name__ == "__main__": + main()