Follows quantus/common#6, which removed ed25519, sr25519, ecdsa and ethereum
from the keyring (forks at 14.0.3-quantus.3).
- restoreAccount now goes through keyring.createFromJson instead of building
the pair itself. A restored backup therefore gets the same refusal as every
other entry point: a polkadot{.js} export of an sr25519 or ed25519 account is
told "<type> keys are not quantum-safe and cannot be held here", not decoded.
- Version-0 JSON, which does not record its key type and so cannot be ML-DSA,
is refused. Upstream guessed ed25519.
- isEthereum is always false; it's kept so callers written against upstream
still read a boolean.
- loadAll already skips, with a warning, any stored account the keyring
refuses, so a profile holding an old classical account still starts.
The spec that pinned sr25519 restore as unchanged is replaced by the two
refusals. ui-keyring 3.16.7-quantus.3, on the quantus.3 forks. yarn test 47
passing; lint clean.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012uDUodEcRbBwNRi3UCmw8f
Follows the rename in quantus/common. The point is not tidiness: with the forks
numbered 14.0.3, a missing resolution here would have been satisfied from npm by
the unforked upstream package, installing cleanly and silently dropping Quantus
support. Now it fails with "No candidates found" — verified by removing the
@polkadot/networks resolution and running an install.
Refs quantus/extension#2
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012uDUodEcRbBwNRi3UCmw8f
Removes every workaround the symlink approach needed, and reverts tsconfig to
upstream's exactly.
The three forked packages — @polkadot/{networks,util-crypto,keyring} — are now
pinned to Gitea tarball URLs in resolutions. @polkadot/util is not, because this
fork does not modify it; it comes from npm like the rest of the scope.
Tarball URLs rather than routing the @polkadot scope to Gitea, because the scope
is mostly *not* forked: routing it would send yarn looking for dozens of packages
that are not there. @quantus is routed as a whole scope in .yarnrc.yml, which is
safe because we own every name in it.
Four things go away, all of which existed for one reason — node resolves a portal
or link symlink to its realpath, after which @polkadot/util-crypto resolved inside
*common's* tree, where it is a workspace source directory with no exports map:
- resolutions pointing four packages at ../common/packages/*/build
- tsconfig.base.json `*.d.ts` path mappings, needed because NodeNext will not
infer an extension for a bare path and looked for a `types` directory
- tsconfig.json overriding those with a runtime `.js` view, because
@polkadot/dev-ts reads that file and tried to import a declaration file as a
module
- --preserve-symlinks in the test scripts
Also drops fflate and @quantus/crypto from ui-keyring's devDependencies; they were
there only because `link:` does not install its target's dependencies.
`yarn lint` now reports 0 errors, down from 25 on pristine upstream. Those were
no-unsafe-assignment and no-unsafe-argument on values that were `any` purely
because the types did not resolve.
Refs quantus/extension#2, quantus/ui#1
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012uDUodEcRbBwNRi3UCmw8f
The mirror of the same mistake in keyring.createFromJson, fixed the same way.
restoreAccount passed `decodeAddress(json.address)` as the public key. For the
curve schemes that is correct — the address *is* the public key. An ML-DSA
account id is a one-way Poseidon2 hash, so this constructed a pair whose "public
key" was a hash of the public key. It did not throw; it produced a pair that was
simply wrong.
The public key is in `json.encoded`, still encrypted, and the pair is returned
*locked* with callers reading `pair.address` off it long before a password
appears. So it now passes an accountId — carried as data, used for the address
while locked, and checked against the real key once decodePkcs8 supplies one.
That check matters here as much as in the keyring: the address field sits outside
the encrypted blob, so a tampered one decodes cleanly and yields an account
displaying an address its key cannot sign for.
The 'ed25519' fallback for version-0 JSON is left alone. Those files predate the
crypto type being recorded and are by definition not Quantus, so the guess is
safe — but it is commented, because quantus/common#6 removes ed25519 from
KeypairType and this becomes a refusal.
Build plumbing, all of it dev-time only and all replaced by publishing these
packages to a registry (quantus/extension#2):
Resolutions point @polkadot/{keyring,util-crypto,networks,util} at the sibling
`common` checkout's build output, and @quantus/crypto at `wasm`.
tsconfig.base.json gains `*.d.ts` path mappings for them. Without these, node
resolves the portal symlink to its realpath and `@polkadot/util-crypto` then
resolves inside *common's* tree, where it is the workspace source directory with
no exports map — so EncryptedJson silently fails to resolve and KeyringPair$Json
loses `encoded` and `encoding`. The `*.d.ts` substitution has to come first
because NodeNext will not infer an extension for a bare path, and looks for a
`types` directory instead of `types.d.ts`.
tsconfig.json overrides those with the runtime `.js` view, because
@polkadot/dev-ts reads that file and would otherwise import a declaration file as
a module ("Debug Failure. Output generation failed"). tsc reads
tsconfig.build.json, which extends the base directly, so each gets the view it
needs.
The test script sets --preserve-symlinks, which yarn itself warns is required for
portals: without it the realpath problem above recurs at runtime.
Incidentally, `yarn lint` errors drop from 25 to 8 — resolving those types
removed a pile of `any`. The remaining 8 are upstream's own, in loadContract and
allowGenesis, and are left alone.
Refs quantus/ui#1
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012uDUodEcRbBwNRi3UCmw8f