Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PASS1-128: Add support back for Bitcoin testnet #29

Merged
merged 23 commits into from
Aug 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e08c3ff
Fixes part of PASS-91
FoundationKen Jul 23, 2021
956ce83
Second half of fix for ENV1-91
FoundationKen Jul 23, 2021
b8e3c74
Fixes PASS1-122
FoundationKen Jul 27, 2021
e337847
Fix comment punctuation
FoundationKen Jul 28, 2021
1d25875
Show backup filename to user after successful backup (#18)
FoundationKen Jul 28, 2021
53c7221
Auto-truncate multisig config names (#19)
FoundationKen Jul 28, 2021
45716b1
PASS1-101: Auto-truncate multisig config names (#19)
FoundationKen Jul 28, 2021
3966545
Merge remote-tracking branch 'origin/dev-v1.0.6' into dev-v1.0.6
FoundationKen Jul 28, 2021
1b04ea4
Remove unnecessary comments
FoundationKen Jul 29, 2021
f860dd8
PASS1-92 (#20)
FoundationKen Jul 29, 2021
4790981
PASS1-102: Fix backwards microSD issue
FoundationKen Jul 29, 2021
8a3da23
PASS1-102: Fix backwards microSD issue (#21)
FoundationKen Jul 29, 2021
f5b23f7
Merge remote-tracking branch 'origin/dev-v1.0.6' into dev-v1.0.6
FoundationKen Jul 29, 2021
1cc5282
PASS1-102_b (#22)
FoundationKen Jul 29, 2021
915e413
Merge remote-tracking branch 'origin/dev-v1.0.6' into dev-v1.0.6
FoundationKen Jul 29, 2021
c8fbd9d
PASS1-122_b (#23)
FoundationKen Jul 29, 2021
09f2c90
PASS1-125: Add Git commit-msg hook to check for Linear ID (#24)
FoundationKen Jul 30, 2021
c7ca908
PASS1-122: Minor updates to text (#27)
coreylakey Aug 2, 2021
cf6e244
PASS1-127: Fix `reuse lint` issues in the repo (#26)
coreylakey Aug 2, 2021
5ee103a
PASS1-113: Give the user a way to clear the developer pubkey slot (#25)
coreylakey Aug 2, 2021
25ae8d1
PASS1-122: Added "Address Verified" text to new wallet pairing (#28)
coreylakey Aug 3, 2021
ea5c8bb
PASS1-128: Add support back for Bitcoin testnet
coreylakey Aug 4, 2021
29fe3f5
Merge branch 'dev-v1.0.7' into PASS1-128
FoundationKen Aug 10, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ports/stm32/boards/Passport/modules/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion ports/stm32/boards/Passport/modules/chains.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'),
Expand All @@ -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'),
Expand Down
30 changes: 30 additions & 0 deletions ports/stm32/boards/Passport/modules/choosers.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,34 @@ def set_enable_passphrase(idx, text):
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 change: 1 addition & 0 deletions ports/stm32/boards/Passport/modules/flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def has_pubkey():
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)
]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 5 additions & 3 deletions ports/stm32/boards/Passport/modules/wallets/multisig_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
# multisig_json.py - Multisig export format
#

import chains
import stash
import uio
from utils import xfp2str
Expand All @@ -20,18 +21,19 @@

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 = []
with stash.SensitiveValues() as sv:

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)
Expand Down
27 changes: 15 additions & 12 deletions ports/stm32/boards/Passport/modules/wallets/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand All @@ -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

Expand Down
5 changes: 4 additions & 1 deletion ports/stm32/boards/Passport/modules/wallets/vault.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# vault.py - Export format used by some wallets
#

import chains
import stash
import ujson
from utils import xfp2str, to_str
Expand All @@ -14,8 +15,10 @@
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:
Expand Down
7 changes: 3 additions & 4 deletions ports/stm32/boards/Passport/modules/wallets/wasabi.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,14 @@
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()
Expand Down