|
|
@ -1330,96 +1330,6 @@ async def ms_wallet_detail(menu, label, item): |
|
|
|
|
|
|
|
return await ms.show_detail() |
|
|
|
|
|
|
|
def generate_multisig_xpub_json(): |
|
|
|
from common import settings |
|
|
|
xfp = xfp2str(settings.get('xfp', 0)) |
|
|
|
chain = chains.current_chain() |
|
|
|
fp = uio.StringIO() |
|
|
|
|
|
|
|
fp.write('{\n') |
|
|
|
with stash.SensitiveValues() as sv: |
|
|
|
for deriv, name, fmt in [ |
|
|
|
("m/45'", 'p2sh', AF_P2SH), |
|
|
|
("m/48'/{coin}'/0'/1'", 'p2wsh_p2sh', AF_P2WSH_P2SH), |
|
|
|
("m/48'/{coin}'/0'/2'", 'p2wsh', AF_P2WSH) |
|
|
|
]: |
|
|
|
|
|
|
|
dd = deriv.format(coin=chain.b44_cointype) |
|
|
|
node = sv.derive_path(dd) |
|
|
|
xp = chain.serialize_public(node, fmt) |
|
|
|
fp.write(' "%s_deriv": "%s",\n' % (name, dd)) |
|
|
|
fp.write(' "%s": "%s",\n' % (name, xp)) |
|
|
|
|
|
|
|
fp.write(' "xfp": "%s"\n}\n' % xfp) |
|
|
|
result = fp.getvalue() |
|
|
|
# print('xpub json = {}'.format(result)) |
|
|
|
return result |
|
|
|
|
|
|
|
|
|
|
|
async def export_multisig_xpubs_to_sd(*a): |
|
|
|
# WAS: Create a single text file with lots of docs, and all possible useful xpub values. |
|
|
|
# THEN: Just create the one-liner xpub export value they need/want to support BIP45 |
|
|
|
# NOW: Export JSON with one xpub per useful address type and semi-standard derivation path |
|
|
|
# |
|
|
|
# Consumer for this file is supposed to be ourselves, when we build on-device multisig. |
|
|
|
# |
|
|
|
from common import settings |
|
|
|
xfp = xfp2str(settings.get('xfp', 0)) |
|
|
|
chain = chains.current_chain() |
|
|
|
|
|
|
|
fname_pattern = 'passport-%s.json' % xfp |
|
|
|
|
|
|
|
msg = '''\ |
|
|
|
This feature creates a small file containing \ |
|
|
|
the extended public keys (XPUB) you would need to join \ |
|
|
|
a multisig wallet using the 'Create Airgapped' feature. |
|
|
|
|
|
|
|
The public keys exported are: |
|
|
|
|
|
|
|
BIP45: |
|
|
|
m/45' |
|
|
|
P2SH-P2WSH: |
|
|
|
m/48'/{coin}'/0'/1' |
|
|
|
P2WSH: |
|
|
|
m/48'/{coin}'/0'/2' |
|
|
|
|
|
|
|
OK to continue. X to abort. |
|
|
|
'''.format(coin = chain.b44_cointype) |
|
|
|
|
|
|
|
resp = await ux_show_story(msg) |
|
|
|
if resp != 'y': return |
|
|
|
|
|
|
|
try: |
|
|
|
with CardSlot() as card: |
|
|
|
fname, nice = card.pick_filename(fname_pattern) |
|
|
|
# do actual write: manual JSON here so more human-readable. |
|
|
|
with open(fname, 'wt') as fp: |
|
|
|
fp.write('{\n') |
|
|
|
with stash.SensitiveValues() as sv: |
|
|
|
for deriv, name, fmt in [ |
|
|
|
( "m/45'", 'p2sh', AF_P2SH), |
|
|
|
( "m/48'/{coin}'/0'/1'", 'p2sh_p2wsh', AF_P2WSH_P2SH), |
|
|
|
( "m/48'/{coin}'/0'/2'", 'p2wsh', AF_P2WSH) |
|
|
|
]: |
|
|
|
|
|
|
|
dd = deriv.format(coin = chain.b44_cointype) |
|
|
|
node = sv.derive_path(dd) |
|
|
|
xp = chain.serialize_public(node, fmt) |
|
|
|
fp.write(' "%s_deriv": "%s",\n' % (name, dd)) |
|
|
|
fp.write(' "%s": "%s",\n' % (name, xp)) |
|
|
|
|
|
|
|
fp.write(' "xfp": "%s"\n}\n' % xfp) |
|
|
|
|
|
|
|
except CardMissingError: |
|
|
|
await needs_microsd() |
|
|
|
return |
|
|
|
except Exception as e: |
|
|
|
await ux_show_story('Unable to write!\n\n\n'+str(e)) |
|
|
|
return |
|
|
|
|
|
|
|
msg = '''BIP45 multisig xpub file written:\n\n%s''' % nice |
|
|
|
await ux_show_story(msg) |
|
|
|
|
|
|
|
def import_xpub(ln): |
|
|
|
# read an xpub/ypub/etc and return BIP32 node and what chain it's on. |
|
|
|
# - can handle any garbage line |
|
|
|