Keeps watch-only accounts, drops the protocol that cannot work.
ImportQr scanned a Parity Signer QR — SUBSTRATE_ID 0x53, CRYPTO_SR25519 0x01, a
crypto-type byte with no ML-DSA value — so no Quantus device could ever answer
it, and one branch hardcoded createAccountSuri(..., 'sr25519', ...). But it was
also the *only* caller of createAccountExternal, so deleting it would have taken
watch-only accounts with it. Those are wanted independently of how the address
arrives, and are what the account list is used for.
TrackAddress takes a pasted SS58 string instead, which for Quantus is the common
case anyway: the address is on screen in another wallet, not on a signing device.
It round-trips through decodeAddress/encodeAddress, which rejects a mistyped
address by its checksum rather than storing one that can never receive anything,
and normalises the prefix so an address pasted from a tool using a different one
displays the way the rest of the extension displays it.
The signing path had to change with it, and this is the part that would have been
a bug. `isExternal && !isHardware` previously rendered the QR signer — and a
tracked address satisfies exactly that condition, so leaving it would have shown
a Parity QR that nothing can scan, for an account that can never sign. External
accounts now show the decoded call and say plainly that the extension holds no
key for them.
That makes Signing/Qr.tsx unreachable, along with the CMD_MORTAL and
CMD_SIGN_MESSAGE Parity command bytes and the _onSignature callback, whose whole
job was accepting a signature produced outside the extension. All removed.
approveSignSignature in the background is deliberately left. Unlike Ledger, which
is gone for good, external signing returns when quantus/extension#10 ports the
flow to multipart UR — the message it carries is the right shape for that, and
deleting it would only mean writing it again.
Two specs rewritten rather than deleted: the one asserting a QR scanner appears
for external accounts now asserts the extrinsic and the cannot-sign warning
appear instead.
Typecheck, lint and 65 tests clean; build:chrome completes.
Refs quantus/extension#10, quantus/extension#5
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012uDUodEcRbBwNRi3UCmw8f
No hardware wallet speaks ML-DSA, and @polkadot/hw-ledger talks ed25519 over the
Ledger Substrate app, so every one of these screens was unreachable for a Quantus
account. Removed rather than hidden behind a flag: this fork is not trying to stay
mergeable with upstream, so unreachable UI costs more than it saves. It is also
work that quantus/common#6 turns into a type error regardless.
Gone: ImportLedger.tsx, useLedger.ts, LedgerSign.tsx, legerChains.ts (upstream's
typo), the route and its ALLOWED_PATH entry, the add-menu item, the Ledger App
setting, and the @polkadot/hw-ledger dependency.
Also gone is the background handler. accountsCreateHardware and its message type
were reachable only from ImportLedger, so they are now dead code — and dead code
that mints accounts is worth deleting rather than leaving for someone to wire up
again.
Two things deliberately stay:
isHardware remains on AccountJson. Nothing creates such an account any more, but
a restored JSON can still carry the flag, and the display branches that read it
are correct for that case — an imported hardware account has no key here and
cannot sign. Ripping the flag out would touch unrelated display code to remove a
branch that is right.
canEditGenesis becomes unconditional. It was `!isHardware || ledgerApp ===
'generic'`, because the chain-specific Ledger app could not sign for an arbitrary
genesis hash. With no hardware path and no such setting, nothing restricts it.
The two spec cases that asserted the old behaviour are rewritten into one that
asserts the new rule, rather than deleted.
Not done, contrary to what the issue asked for: no "hardware wallets are not
supported" note in the add menu. The reasoning there was that a missing item
reads as broken — but that only holds for someone looking for it, and in a
Quantus-only wallet nobody is. A permanent dead entry needing translation into
every locale is a worse wart than its absence. It belongs in the README when
branding lands (#2).
65 tests pass; typecheck clean.
Refs quantus/extension#5
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012uDUodEcRbBwNRi3UCmw8f
Wires this repo to the four forked @polkadot packages and @quantus/crypto, and
the extension now builds with post-quantum crypto in it.
Two mechanisms, for the reason established in quantus/ui: @quantus is routed as a
whole scope in .yarnrc.yml, which is safe because we own every name in it, while
the forked @polkadot packages are pinned individually to tarball URLs in
resolutions. Routing the @polkadot scope would send yarn hunting for the dozens
of packages in it that are not forked — api, types, rpc-provider, dev, x-*,
hw-ledger and more — all of which must keep coming from npm.
The forks carry -quantus.N versions, so a resolution left out fails with "No
candidates found" rather than being quietly satisfied from npm by the unforked
package.
buildHierarchy.spec.ts is rewritten rather than deleted. compareByNetwork
resolves a genesis hash through getNetworkMap(), which is built from
selectableNetworks — and this fork only offers chains whose accounts are
post-quantum, so Polkadot and Kusama are no longer in it. Both fixtures resolved
to '' and compared equal, meaning the network-ordering tests passed without
ordering anything. They now use Quantus and Heisenberg, whose display names sort
in the same direction the originals did, so the fixtures keep their shape.
Verified in the built artifacts rather than assumed: background.js carries
QUANTUS_EXTRINSIC, the dilithium keypair types, ext_poseidon_hash, ext_mldsa_sign
and the base64 wasm payload; extension.js carries the Quantus network entry, QTC
and the mainnet genesis hash. The split is right — signing lives in the service
worker, the UI only needs to render addresses.
65 tests pass; `yarn build:chrome` completes.
Refs quantus/extension#2
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012uDUodEcRbBwNRi3UCmw8f
The signing popup decided whether to show the message view or the
transaction view by inspecting fields on the payload (`data`,
`blockNumber`), while the background picks the signing behaviour from the
message channel the request arrived on. Those two are independent and the
payload comes from the dapp, so they can disagree.
`RequestSign` becomes a discriminated union on `channel`, set by the
background from the message type. Correlating the discriminant with the
payload type means consumers narrow through `isExtrinsicRequest` rather
than casting, so the display and the signing path can no longer drift
apart. `Tabs.extrinsicSign` also rejects a payload carrying a truthy
`data`, since that field has no meaning on that channel.
Also branches the signing render on the request rather than on decoded
state. Paging between two queued requests of different shapes could
otherwise commit one frame using the previous request's decoded payload.
Tests added under `signer channel` in `Extension.spec.ts`.
* feat(ui): allow generic Ledger app to derive from any chain via polkadot slip44
* feat: allow Ledger generic app accounts to sign on any chain
* fix(extension-ui): guard generic ledger init and stabilize i18n deps
* fix: prefer WebHID over WebUSB for Ledger transport to fix Flex/Nano X connectivity
* fix(ui): release Ledger transport with explicit disconnect lifecycle
* fix(ui): align Ledger app mode with reactive settings context
* refactor(ui): keep useLedger render phase pure for init errors
* fix(ui): apply popup-aware routing to Ledger connection links
* fix(ui): harden Ledger signing error handling and mismatch UX
- Remove chain.name being set as specName from merkleizeMetadata payload
- Use reactive SettingsContext ledgerApp instead of settings.get() snapshot
- Guard no-metadata signing path with setIsBusy(false) + early return
- Detect signer mismatch by normalizing addresses and block signing when mismatched