Browse Source

PASS1-128: Add support back for Bitcoin testnet

PASS1-128
coreylakey 4 years ago
parent
commit
ea5c8bb0f0
  1. 4
      ports/stm32/boards/Passport/modules/actions.py
  2. 3
      ports/stm32/boards/Passport/modules/chains.py
  3. 30
      ports/stm32/boards/Passport/modules/choosers.py
  4. 1
      ports/stm32/boards/Passport/modules/flow.py
  5. 12
      ports/stm32/boards/Passport/modules/wallets/generic_json_wallet.py
  6. 8
      ports/stm32/boards/Passport/modules/wallets/multisig_json.py
  7. 27
      ports/stm32/boards/Passport/modules/wallets/utils.py
  8. 5
      ports/stm32/boards/Passport/modules/wallets/vault.py
  9. 7
      ports/stm32/boards/Passport/modules/wallets/wasabi.py

4
ports/stm32/boards/Passport/modules/actions.py

@ -1855,13 +1855,13 @@ async def test_derive_addresses(*a):
chain = chains.current_chain()
addrs = []
path = "m/84'/0'/{account}'/{change}/{idx}"
path = "m/84'/{coin_type}'/{account}'/{change}/{idx}"
system.turbo(True)
start_time = utime.ticks_ms()
with stash.SensitiveValues() as sv:
for idx in range(n):
subpath = path.format(account=0, change=0, idx=idx)
subpath = path.format(coin_type=chain.b44_cointype, account=0, change=0, idx=idx)
node = sv.derive_path(subpath, register=False)
addr = chain.address(node, AF_P2WPKH)
addrs.append(addr)

3
ports/stm32/boards/Passport/modules/chains.py

@ -195,6 +195,7 @@ class BitcoinMain(ChainsBase):
ctype = 'BTC'
name = 'Bitcoin'
core_name = 'Bitcoin Core'
menu_name = 'Bitcoin Mainnet'
slip132 = {
AF_CLASSIC: Slip132Version(0x0488B21E, 0x0488ADE4, 'x'),
@ -215,7 +216,7 @@ class BitcoinMain(ChainsBase):
class BitcoinTestnet(BitcoinMain):
ctype = 'TBTC'
name = 'Bitcoin Testnet'
menu_name = 'Testnet: BTC'
menu_name = 'Bitcoin Testnet'
slip132 = {
AF_CLASSIC: Slip132Version(0x043587cf, 0x04358394, 't'),

30
ports/stm32/boards/Passport/modules/choosers.py

@ -72,4 +72,34 @@ def enable_passphrase_chooser():
settings.set('enable_passphrase', va[idx])
return which, ch, set_enable_passphrase
def chain_chooser():
from chains import AllChains
chain = settings.get('chain', 'BTC')
ch = [(i.ctype, i.menu_name or i.name) for i in AllChains ]
# find index of current choice
try:
which = [n for n, (k,v) in enumerate(ch) if k == chain][0]
except IndexError:
which = 0
def set_chain(idx, text):
val = ch[idx][0]
assert ch[idx][1] == text
settings.set('chain', val)
try:
# update xpub stored in settings
import stash
with stash.SensitiveValues() as sv:
sv.capture_xpub()
except ValueError:
# no secrets yet, not an error
pass
return which, [t for _,t in ch], set_chain
# EOF

1
ports/stm32/boards/Passport/modules/flow.py

@ -65,6 +65,7 @@ AdvancedMenu = [
MenuItem('MicroSD Settings', menu=SDCardMenu),
MenuItem('View Seed Words', f=view_seed_words, predicate=lambda: settings.get('words', True)),
MenuItem('Developer PubKey', menu=DeveloperPubkeyMenu, menu_title='Developer'),
MenuItem('Testnet', chooser=chain_chooser),
MenuItem('Erase Passport', f=erase_wallet, arg=True)
]

12
ports/stm32/boards/Passport/modules/wallets/generic_json_wallet.py

@ -32,13 +32,13 @@ def create_generic_json_wallet(sw_wallet=None, addr_type=None, acct_num=0, multi
with stash.SensitiveValues() as sv:
# Each of these paths will have /{change}/{idx} in usage (not hardened)
for name, deriv, fmt, atype, is_multisig in [
( 'bip44', "m/44'/0'/{acct}'", AF_CLASSIC, 'p2pkh', False ),
( 'bip49', "m/49'/0'/{acct}'", AF_P2WPKH_P2SH, 'p2sh-p2wpkh', False ), # was "p2wpkh-p2sh"
( 'bip84', "m/84'/0'/{acct}'", AF_P2WPKH, 'p2wpkh', False ),
( 'bip48_1', "m/48'/0'/{acct}'/1'", AF_P2WSH_P2SH, 'p2sh-p2wsh', True ),
( 'bip48_2', "m/48'/0'/{acct}'/2'", AF_P2WSH, 'p2wsh', True ),
( 'bip44', "m/44'/{coin_type}'/{acct}'", AF_CLASSIC, 'p2pkh', False ),
( 'bip49', "m/49'/{coin_type}'/{acct}'", AF_P2WPKH_P2SH, 'p2sh-p2wpkh', False ), # was "p2wpkh-p2sh"
( 'bip84', "m/84'/{coin_type}'/{acct}'", AF_P2WPKH, 'p2wpkh', False ),
( 'bip48_1', "m/48'/{coin_type}'/{acct}'/1'", AF_P2WSH_P2SH, 'p2sh-p2wsh', True ),
( 'bip48_2', "m/48'/{coin_type}'/{acct}'/2'", AF_P2WSH, 'p2wsh', True ),
]:
dd = deriv.format(acct=acct_num)
dd = deriv.format(coin_type=chain.b44_cointype,acct=acct_num)
node = sv.derive_path(dd)
xfp = xfp2str(node.my_fingerprint())
xp = chain.serialize_public(node, AF_CLASSIC)

8
ports/stm32/boards/Passport/modules/wallets/multisig_json.py

@ -10,6 +10,7 @@
# multisig_json.py - Multisig export format
#
import chains
import stash
import uio
from utils import xfp2str
@ -20,6 +21,7 @@ from public_constants import AF_P2SH, AF_P2WSH, AF_P2WSH_P2SH
def create_multisig_json_wallet(sw_wallet=None, addr_type=None, acct_num=0, multisig=False, legacy=False):
fp = uio.StringIO()
chain = chains.current_chain()
fp.write('{\n')
accts = []
@ -27,11 +29,11 @@ def create_multisig_json_wallet(sw_wallet=None, addr_type=None, acct_num=0, mult
for deriv, name, fmt in [
("m/45'", 'p2sh', AF_P2SH),
("m/48'/0'/{acct}'/1'", 'p2wsh_p2sh', AF_P2WSH_P2SH),
("m/48'/0'/{acct}'/2'", 'p2wsh', AF_P2WSH)
("m/48'/{coin_type}'/{acct}'/1'", 'p2wsh_p2sh', AF_P2WSH_P2SH),
("m/48'/{coin_type}'/{acct}'/2'", 'p2wsh', AF_P2WSH)
]:
# Fill in the acct number
dd = deriv.format(acct=acct_num)
dd = deriv.format(coin_type=chain.b44_cointype,acct=acct_num)
node = sv.derive_path(dd)
xfp = xfp2str(node.my_fingerprint())
xpub = sv.chain.serialize_public(node, fmt)

27
ports/stm32/boards/Passport/modules/wallets/utils.py

@ -4,6 +4,7 @@
# utils.py - Wallet utils
#
import chains
import common
from common import settings
from public_constants import AF_CLASSIC, AF_P2SH, AF_P2WPKH_P2SH, AF_P2WSH_P2SH, AF_P2WPKH, AF_P2WSH
@ -94,16 +95,16 @@ def get_deriv_fmt_from_address(address, is_multisig):
# Map the address prefix to a standard derivation path and insert the account number
if is_multisig:
if address[0] == '3':
return "m/48'/0'/{acct}'/1'"
return "m/48'/{coin_type}'/{acct}'/1'"
elif address[0] == 'b' and address[1] == 'c' and address[2] == '1':
return "m/48'/0'/{acct}'/2'"
return "m/48'/{coin_type}'/{acct}'/2'"
else:
if address[0] == '1':
return "m/44'/0'/{acct}'"
return "m/44'/{coin_type}'/{acct}'"
elif address[0] == '3':
return "m/49'/0'/{acct}'"
return "m/49'/{coin_type}'/{acct}'"
elif address[0] == 'b' and address[1] == 'c' and address[2] == '1':
return "m/84'/0'/{acct}'"
return "m/84'/{coin_type}'/{acct}'"
return None
@ -113,33 +114,35 @@ def get_deriv_fmt_from_addr_type(addr_type, is_multisig):
# Map the address prefix to a standard derivation path and insert the account number
if is_multisig:
if addr_type == AF_P2WSH_P2SH:
return "m/48'/0'/{acct}'/1'"
return "m/48'/{coin_type}'/{acct}'/1'"
elif addr_type == AF_P2WSH:
return "m/48'/0'/{acct}'/2'"
return "m/48'/{coin_type}'/{acct}'/2'"
else:
if addr_type == AF_CLASSIC:
return "m/44'/0'/{acct}'"
return "m/44'/{coin_type}'/{acct}'"
elif addr_type == AF_P2WPKH_P2SH:
return "m/49'/0'/{acct}'"
return "m/49'/{coin_type}'/{acct}'"
elif addr_type == AF_P2WPKH:
return "m/84'/0'/{acct}'"
return "m/84'/{coin_type}'/{acct}'"
return None
def get_deriv_path_from_addr_type_and_acct(addr_type, acct_num, is_multisig):
chain = chains.current_chain()
# print('get_deriv_path_from_addr_type_and_acct(): addr_type={} acct={} is_multisig={}'.format(addr_type, acct_num, is_multisig))
fmt = get_deriv_fmt_from_addr_type(addr_type, is_multisig)
if fmt != None:
return fmt.format(acct=acct_num)
return fmt.format(coin_type=chain.b44_cointype,acct=acct_num)
return None
# For single sig only
def get_deriv_path_from_address_and_acct(address, acct, is_multisig):
chain = chains.current_chain()
# print('get_deriv_path_from_address_and_acct(): address={} acct={} is_multisig={}'.format(address, acct, is_multisig))
fmt = get_deriv_fmt_from_address(address, is_multisig)
if fmt != None:
return fmt.format(acct=acct)
return fmt.format(coin_type=chain.b44_cointype,acct=acct)
return None

5
ports/stm32/boards/Passport/modules/wallets/vault.py

@ -4,6 +4,7 @@
# vault.py - Export format used by some wallets
#
import chains
import stash
import ujson
from utils import xfp2str, to_str
@ -14,8 +15,10 @@ from public_constants import AF_CLASSIC, AF_P2WPKH, AF_P2WPKH_P2SH
def create_vault_export(sw_wallet=None, addr_type=None, acct_num=0, multisig=False, legacy=False):
from common import settings, system
chain = chains.current_chain()
(fw_version, _, _, _) = system.get_software_info()
acct_path = "84'/0'/{acct}'".format(acct=acct_num)
acct_path = "84'/{coin_type}'/{acct}'".format(coin_type=chain.b44_cointype,acct=acct_num)
master_xfp = xfp2str(settings.get('xfp'))
with stash.SensitiveValues() as sv:

7
ports/stm32/boards/Passport/modules/wallets/wasabi.py

@ -20,15 +20,14 @@ from common import settings, system
def create_wasabi_export(sw_wallet=None, addr_type=None, acct_num=0, multisig=False, legacy=False):
# Generate the data for a JSON file which Wasabi can open directly as a new wallet.
btc = chains.BitcoinMain
chain = chains.current_chain()
with stash.SensitiveValues() as sv:
acct_path = "m/84'/0'/{acct}'".format(acct=acct_num)
acct_path = "m/84'/{coin_type}'/{acct}'".format(coin_type=chain.b44_cointype,acct=acct_num)
node = sv.derive_path(acct_path)
xfp = xfp2str(settings.get('xfp'))
xpub = btc.serialize_public(node, AF_CLASSIC)
xpub = chain.serialize_public(node, AF_CLASSIC)
chain = chains.current_chain()
assert chain.ctype in {'BTC', 'TBTC'}, "Only Bitcoin supported"
(fw_version, _, _, _) = system.get_software_info()

Loading…
Cancel
Save