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

Feature: Add wallet export to Jade via QR #2370

Merged
57 changes: 56 additions & 1 deletion src/cryptoadvance/specter/devices/jade.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
from .hwi_device import HWIDevice
from .hwi.jade import JadeClient
from .hwi.jade import enumerate as jade_enumerate
from ..helpers import is_liquid
from ..helpers import is_liquid, to_ascii20
from ..util import bcur
from binascii import b2a_base64


class Jade(HWIDevice):
Expand All @@ -18,6 +20,8 @@ class Jade(HWIDevice):
supports_hwi_multisig_display_address = True
supports_multisig_registration = True
liquid_support = True
exportable_to_wallet = True
wallet_export_type = "qr"

@classmethod
def get_client(cls, *args, **kwargs):
Expand All @@ -43,3 +47,54 @@ def create_psbts(self, base64_psbt, wallet):
qr_psbt = wallet.fill_psbt(base64_psbt, non_witness=False, xpubs=False)
psbts["qrcode"] = f"{self.supported_qr_code_format}:{qr_psbt}"
return psbts

# Enables the export of a multisig wallet to a Jade via QR
def export_wallet(self, wallet):
if not wallet.is_multisig:
return None
# Jade uses ColdCard's style (assumes derivaion paths of the keys to be the same)
CC_TYPES = {"legacy": "BIP45", "p2sh-segwit": "P2WSH-P2SH", "bech32": "P2WSH"}
derivation = None
for k in wallet.keys:
if k in self.keys and k.derivation != "":
derivation = k.derivation.replace("h", "'")
break
if derivation is None:
return None
qr_string = """
Name: {}
Policy: {} of {}
Derivation: {}
Format: {}
Sorted: {}
""".format(
to_ascii20(wallet.name),
wallet.sigs_required,
len(wallet.keys),
derivation,
CC_TYPES[wallet.address_type],
not wallet.uses_multi,
)

for k in wallet.keys:
fingerprint = k.fingerprint
if fingerprint == "":
fingerprint = get_xpub_fingerprint(k.xpub).hex()
qr_string += "{}: {}\n".format(
fingerprint.upper(),
k.xpub,
)

qr_string = b2a_base64(qr_string.encode()).decode()
return f"ur-bytes:{qr_string}"

# Example output:
# """
# Name: MyWallet
# Policy: 2 of 3
# Derivation: m/48'/1'/0'/2'
# Format: P2WSH
# Sorted: False
# A1B2C3D4: tpubD6NzVbkrYhZ...
# F2E3D4C5: tpubE6NzVhkxF7Q...
# """
Loading