import pytest from unittest import IsolatedAsyncioTestCase from unittest_parametrize import parametrize, ParametrizedTestCase from jmbitcoin import select_chain_params from jmclient import (SegwitLegacyWallet, SegwitWallet, get_network, jm_single, VolatileStorage, load_test_config) from jmclient.wallet_utils import (bip32pathparse, WalletView, WalletViewAccount, WalletViewBranch, WalletViewEntry, wallet_signmessage) pytestmark = pytest.mark.usefixtures("setup_regtest_bitcoind") class AsyncioTestCase(IsolatedAsyncioTestCase, ParametrizedTestCase): # The below signatures have all been verified against Electrum 4.0.9: @parametrize( 'seed, hdpath, walletcls, message, sig, addr', [ (b"\x01"*16, "m/84'/0'/0'/0/0", SegwitWallet, "hello", "IOLk6ct/8aKtvTNnEAc+xojIWKv5FOwnzHGcnHkTJJwRBAyhrZ2ZyB0Re+dKS4SEav3qgjQeqMYRm+7mHi4sFKA=", "bc1qq53d9372u8d50jfd5agq9zv7m7zdnzwducuqgz"), (b"\x01"*16, "m/49'/0'/0'/0/0", SegwitLegacyWallet, "hello", "HxVaQuXyBpl1UKutiusJjeLfKHwJYBzUiWuu6hEbmNFeSZGt/mbXKJ071ANR1gvdICbS/AnEa2RKDq9xMd/nU8s=", "3AdTcqdoLHFGNq6znkahJDT41u65HAwiRv"), (b"\x02"*16, "m/84'/0'/2'/1/0", SegwitWallet, "sign me", "IA/V5DG7u108aNzCnpNPHqfrJAL8pF4GQ0sSqpf4Vlg5UWizauXzh2KskoD6Usl13hzqXBi4XDXl7Xxo5z6M298=", "bc1q8mm69xs740sr0l2umrhmpl4ewhxfudxg2zvjw5"), (b"\x02"*16, "m/49'/0'/2'/1/0", SegwitLegacyWallet, "sign me", "H4cAtoE+zL+Mr+U8jm9DiYxZlym5xeZM3mcgymLz+TF4YYr4lgnM8qTZhFwlK4izcPaLuF27LFEoGJ/ltleIHUI=", "3Qan1D4Vcy1yMGHfR9j7szDuC8QxSFVScA"), ]) async def test_signmessage(self, seed, hdpath, walletcls, message, sig, addr): load_test_config() jm_single().config.set('BLOCKCHAIN', 'network', 'mainnet') select_chain_params("bitcoin/mainnet") storage = VolatileStorage() walletcls.initialize( storage, get_network(), entropy=seed, max_mixdepth=3) wallet = walletcls(storage) await wallet.async_init(storage) s, m, a = await wallet_signmessage( wallet, hdpath, message, out_str=False) assert (s, m, a) == (sig, message, addr) jm_single().config.set("BLOCKCHAIN", "network", "testnet") select_chain_params("bitcoin/regtest") async def test_bip32_pathparse(self): assert bip32pathparse("m/2/1/0017") assert not bip32pathparse("n/1/1/1/1") assert bip32pathparse("m/0/1'/100'/3'/2/2/21/004/005") assert not bip32pathparse("m/0/0/00k") async def test_walletview(self): rootpath = "m/0" walletbranch = 0 accounts = range(3) acctlist = [] for a in accounts: branches = [] for address_type in range(2): entries = [] for i in range(4): entries.append(WalletViewEntry(rootpath, a, address_type, i, "DUMMYADDRESS" + str(i+a), [i*10000000, i*10000000])) branches.append(WalletViewBranch(rootpath, a, address_type, branchentries=entries, xpub="xpubDUMMYXPUB" + str(a + address_type))) acctlist.append(WalletViewAccount(rootpath, a, branches=branches)) wallet = WalletView(rootpath + "/" + str(walletbranch), accounts=acctlist) assert(wallet.serialize() == ( 'JM wallet\n' 'mixdepth\t0\n' 'external addresses\tm/0\txpubDUMMYXPUB0\n' 'm/0 \tDUMMYADDRESS0\t0.00000000\tnew\t\t\n' 'm/0 \tDUMMYADDRESS1\t0.10000000\tnew\t\t\n' 'm/0 \tDUMMYADDRESS2\t0.20000000\tnew\t\t\n' 'm/0 \tDUMMYADDRESS3\t0.30000000\tnew\t\t\n' 'Balance:\t0.60000000\n' 'internal addresses\tm/0\txpubDUMMYXPUB1\n' 'm/0 \tDUMMYADDRESS0\t0.00000000\tnew\t\t\n' 'm/0 \tDUMMYADDRESS1\t0.10000000\tnew\t\t\n' 'm/0 \tDUMMYADDRESS2\t0.20000000\tnew\t\t\n' 'm/0 \tDUMMYADDRESS3\t0.30000000\tnew\t\t\n' 'Balance:\t0.60000000\n' 'Balance for mixdepth 0:\t1.20000000\n' 'mixdepth\t1\n' 'external addresses\tm/0\txpubDUMMYXPUB1\n' 'm/0 \tDUMMYADDRESS1\t0.00000000\tnew\t\t\n' 'm/0 \tDUMMYADDRESS2\t0.10000000\tnew\t\t\n' 'm/0 \tDUMMYADDRESS3\t0.20000000\tnew\t\t\n' 'm/0 \tDUMMYADDRESS4\t0.30000000\tnew\t\t\n' 'Balance:\t0.60000000\n' 'internal addresses\tm/0\txpubDUMMYXPUB2\n' 'm/0 \tDUMMYADDRESS1\t0.00000000\tnew\t\t\n' 'm/0 \tDUMMYADDRESS2\t0.10000000\tnew\t\t\n' 'm/0 \tDUMMYADDRESS3\t0.20000000\tnew\t\t\n' 'm/0 \tDUMMYADDRESS4\t0.30000000\tnew\t\t\n' 'Balance:\t0.60000000\n' 'Balance for mixdepth 1:\t1.20000000\n' 'mixdepth\t2\n' 'external addresses\tm/0\txpubDUMMYXPUB2\n' 'm/0 \tDUMMYADDRESS2\t0.00000000\tnew\t\t\n' 'm/0 \tDUMMYADDRESS3\t0.10000000\tnew\t\t\n' 'm/0 \tDUMMYADDRESS4\t0.20000000\tnew\t\t\n' 'm/0 \tDUMMYADDRESS5\t0.30000000\tnew\t\t\n' 'Balance:\t0.60000000\n' 'internal addresses\tm/0\txpubDUMMYXPUB3\n' 'm/0 \tDUMMYADDRESS2\t0.00000000\tnew\t\t\n' 'm/0 \tDUMMYADDRESS3\t0.10000000\tnew\t\t\n' 'm/0 \tDUMMYADDRESS4\t0.20000000\tnew\t\t\n' 'm/0 \tDUMMYADDRESS5\t0.30000000\tnew\t\t\n' 'Balance:\t0.60000000\n' 'Balance for mixdepth 2:\t1.20000000\n' 'Total balance:\t3.60000000'))