You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
HWIBridge.extract_xpub, sign_tx, and display_address all default chain="". For Jade specifically, this raises BadArgumentError: Unhandled network:during client construction — before any of the affected methods get a chance to apply their post-init chain override.
hwi_rpc.py:240 enters _get_client(chain=chain) with chain="". That string is passed through Chain.argparse(""), which falls through Chain[""].upper() → KeyError → returns the input string unchanged. So JadeClient(chain="") is constructed.
devices/hwi/jade.py:186 is __init__ calling self.jade.auth_user(self._network()) — and _network() (line 104) requires self.chain to be a Chain enum value present in NETWORKS. Empty string is neither, so BadArgumentError is raised before the constructor returns.
extract_xpub's logic at hwi_rpc.py:251-253would set client.chain from the derivation path, but execution never reaches that block.
Where it bites
Any direct caller of HWIBridge.extract_xpub / sign_tx / display_address that doesn't pass chain= explicitly. Most of Specter's UI flow does pass it; this hurts mostly programmatic / test consumers.
Derive chain from the derivation path inside _get_client (same heuristic that already exists in extract_xpub) when the caller passes chain="". Pre-init Jade gets a real chain.
Default chain="main" in _get_client and the public bridge methods. Caller can still override.
Option 2 is the smaller change and matches what most callers already pass.
Other HWWClient subclasses don't validate chain in __init__ so they don't fail loudly — but they may also produce subtly wrong results on testnet derivations. Option 1 is the more correct fix.
Summary
HWIBridge.extract_xpub,sign_tx, anddisplay_addressall defaultchain="". For Jade specifically, this raisesBadArgumentError: Unhandled network:during client construction — before any of the affected methods get a chance to apply their post-init chain override.Repro
Workaround:
Why it happens
hwi_rpc.py:240enters_get_client(chain=chain)withchain="". That string is passed throughChain.argparse(""), which falls throughChain[""].upper()→KeyError→ returns the input string unchanged. SoJadeClient(chain="")is constructed.devices/hwi/jade.py:186is__init__callingself.jade.auth_user(self._network())— and_network()(line 104) requiresself.chainto be aChainenum value present inNETWORKS. Empty string is neither, soBadArgumentErroris raised before the constructor returns.extract_xpub's logic athwi_rpc.py:251-253would setclient.chainfrom the derivation path, but execution never reaches that block.Where it bites
HWIBridge.extract_xpub/sign_tx/display_addressthat doesn't passchain=explicitly. Most of Specter's UI flow does pass it; this hurts mostly programmatic / test consumers.tests/test_jade_hardware.pysuite (PR deps: bump hwi 2.4.0 -> 3.1.0 (drops Python 3.7/3.8) #2616); tests had to passchain="main"/chain="test"explicitly as a workaround.Fix sketch
Two reasonable options:
_get_client(same heuristic that already exists inextract_xpub) when the caller passeschain="". Pre-init Jade gets a real chain.chain="main"in_get_clientand the public bridge methods. Caller can still override.Option 2 is the smaller change and matches what most callers already pass.
Other HWWClient subclasses don't validate chain in
__init__so they don't fail loudly — but they may also produce subtly wrong results on testnet derivations. Option 1 is the more correct fix.Refs
kn/bump-hwi-3.1) so the new Jade hardware tests can run.