Retire the Ledger account path #5

Closed
opened 2026-09-10 10:15:04 +00:00 by grenade · 2 comments
Owner

Scoped down to Ledger only. This issue previously also called for removing QR, on reasoning that turned out to be wrong — see the correction below and #9 / #10.

Ledger cannot work

There is no Quantus app for any hardware wallet, and @polkadot/hw-ledger speaks ed25519 over the Ledger Substrate app. packages/extension-ui/src/Popup/ImportLedger.tsx, hooks/useLedger.ts and Popup/Signing/LedgerSign.tsx are all unreachable for a Quantus account.

useLedger.ts also makes its own setType('ed25519') / setType('ethereum') calls, which will fight whatever #3 does to the default type.

Once quantus/common#6 narrows KeypairType to the ML-DSA types this stops being a product decision and becomes a type error, so removing it now is bringing forward work that is coming regardless.

What to do

Remove rather than hide behind a flag. This fork is not trying to stay mergeable with upstream (see #1), so unreachable UI costs more than it saves. Make the absence legible — an extension that silently lacks a menu item reads as broken; one that says hardware wallets are not supported on Quantus reads as finished.

ALLOWED_PATH in packages/extension-base/src/defaults.ts gates which popup routes can open; prune the ones that no longer exist.

Correction: the QR claim in the original issue was wrong

The original text said a 5261/7219-byte signature "does not fit a QR flow at any sensible density". That is false. @polkadot/react-qr already splits payloads:

export const FRAME_SIZE = 1024;   // createFrames() → animated multipart frames

Size is handled. I asserted a limit without checking it.

The real obstacle is protocol, and it applies only to signing:

export const SUBSTRATE_ID = new Uint8Array([0x53]);
export const CRYPTO_SR25519 = new Uint8Array([0x01]);

That is the Parity Signer wire format, with the crypto type as a byte that has no ML-DSA value. Quantus's own air-gapped path uses multipart UR instead.

And "QR" was covering three unrelated things, only one of which is affected:

  • Address display — a plain SS58 string, no protocol involved, and useful for getting an address from the desktop extension onto a phone. Keep it Address QR: show and scan a plain SS58 string, not polkadot-js's payload (#9)
  • Address scanning — the same in reverse, for recipient entry → #9
  • Air-gapped signing — the Parity Signer round trip. Genuinely incompatible, but a port to UR, not an impossibility → #10
Scoped down to Ledger only. This issue previously also called for removing QR, on reasoning that turned out to be wrong — see the correction below and #9 / #10. ## Ledger cannot work There is no Quantus app for any hardware wallet, and `@polkadot/hw-ledger` speaks ed25519 over the Ledger Substrate app. `packages/extension-ui/src/Popup/ImportLedger.tsx`, `hooks/useLedger.ts` and `Popup/Signing/LedgerSign.tsx` are all unreachable for a Quantus account. `useLedger.ts` also makes its own `setType('ed25519')` / `setType('ethereum')` calls, which will fight whatever #3 does to the default type. Once quantus/common#6 narrows `KeypairType` to the ML-DSA types this stops being a product decision and becomes a type error, so removing it now is bringing forward work that is coming regardless. ## What to do Remove rather than hide behind a flag. This fork is not trying to stay mergeable with upstream (see #1), so unreachable UI costs more than it saves. Make the absence legible — an extension that silently lacks a menu item reads as broken; one that says hardware wallets are not supported on Quantus reads as finished. `ALLOWED_PATH` in `packages/extension-base/src/defaults.ts` gates which popup routes can open; prune the ones that no longer exist. ## Correction: the QR claim in the original issue was wrong The original text said a 5261/7219-byte signature "does not fit a QR flow at any sensible density". That is false. `@polkadot/react-qr` already splits payloads: ```js export const FRAME_SIZE = 1024; // createFrames() → animated multipart frames ``` Size is handled. I asserted a limit without checking it. The real obstacle is **protocol**, and it applies only to signing: ```js export const SUBSTRATE_ID = new Uint8Array([0x53]); export const CRYPTO_SR25519 = new Uint8Array([0x01]); ``` That is the Parity Signer wire format, with the crypto type as a byte that has no ML-DSA value. Quantus's own air-gapped path uses multipart **UR** instead. And "QR" was covering three unrelated things, only one of which is affected: - **Address display** — a plain SS58 string, no protocol involved, and useful for getting an address from the desktop extension onto a phone. **Keep it** → #9 - **Address scanning** — the same in reverse, for recipient entry → #9 - **Air-gapped signing** — the Parity Signer round trip. Genuinely incompatible, but a *port to UR*, not an impossibility → #10
grenade changed title from Retire the Ledger and QR account paths to Retire the Ledger account path 2026-09-15 08:22:37 +00:00
Author
Owner

Done. Branch quantus-remove-ledger (87a0b392). Typecheck clean, 65 tests pass, yarn build:chrome completes.

Removed

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. ~1250 lines.

Also the background handler: accountsCreateHardware, its message type and createAccountHardware in messaging were reachable only from ImportLedger. Dead code that mints accounts is worth deleting rather than leaving for someone to wire up again.

Two things deliberately kept

isHardware stays on AccountJson. Nothing creates such an account now, but a restored JSON can carry the flag, and the display branches reading it are correct for that case — an imported hardware account has no key here and cannot sign. Removing the flag would touch unrelated display code to delete 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 asserting the old behaviour are rewritten into one asserting the new rule.

One thing this issue asked for that I did not do

No "hardware wallets are not supported" note in the add menu.

The issue's reasoning 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 menu entry, needing translation into every locale, is a worse wart than its absence. It belongs in the README when branding lands (#2). Flagging it because I wrote the requirement and am now declining it, not because it slipped.

Where I stopped, and why

The QR-signer entry point is still there — "Attach external QR-signer account" in the add menu, /account/import-qr, ImportQr.tsx. It speaks the Parity Signer protocol and hardcodes sr25519, so an account created through it is unusable on Quantus.

I did not remove it, because doing so is larger than it looks and touches a question worth deciding deliberately — see the note I have added to #10.

Done. Branch `quantus-remove-ledger` (`87a0b392`). Typecheck clean, 65 tests pass, `yarn build:chrome` completes. ## Removed `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. ~1250 lines. Also the **background handler**: `accountsCreateHardware`, its message type and `createAccountHardware` in messaging were reachable only from `ImportLedger`. Dead code that mints accounts is worth deleting rather than leaving for someone to wire up again. ## Two things deliberately kept **`isHardware` stays on `AccountJson`.** Nothing creates such an account now, but a restored JSON can carry the flag, and the display branches reading it are *correct* for that case — an imported hardware account has no key here and cannot sign. Removing the flag would touch unrelated display code to delete 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 asserting the old behaviour are rewritten into one asserting the new rule. ## One thing this issue asked for that I did not do No "hardware wallets are not supported" note in the add menu. The issue's reasoning 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 menu entry, needing translation into every locale, is a worse wart than its absence. It belongs in the README when branding lands (#2). Flagging it because I wrote the requirement and am now declining it, not because it slipped. ## Where I stopped, and why The **QR-signer entry point is still there** — "Attach external QR-signer account" in the add menu, `/account/import-qr`, `ImportQr.tsx`. It speaks the Parity Signer protocol and hardcodes `sr25519`, so an account created through it is unusable on Quantus. I did not remove it, because doing so is larger than it looks and touches a question worth deciding deliberately — see the note I have added to #10.
Author
Owner

Verified against main, closing.

  • Removed: the Ledger UI, hook, signer and the hw-ledger dependency are gone from the tree, package.json and yarn.lock (87a0b392), and ALLOWED_PATH is pruned.
  • No notice: as agreed earlier on this issue, no "hardware wallets are not supported" notice was added. With the key type narrowed to ML-DSA (quantus/common#6), no Ledger device can hold these keys at all.
  • QR: split out to #9 and #10.
Verified against `main`, closing. - **Removed:** the Ledger UI, hook, signer and the `hw-ledger` dependency are gone from the tree, `package.json` and `yarn.lock` (`87a0b392`), and `ALLOWED_PATH` is pruned. - **No notice:** as agreed earlier on this issue, no "hardware wallets are not supported" notice was added. With the key type narrowed to ML-DSA (quantus/common#6), no Ledger device can hold these keys at all. - **QR:** split out to #9 and #10.
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: quantus/extension#5