Build against the Quantus forks instead of the published @polkadot packages #2
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Part of #1. Nothing else in this repo can be tested until this lands.
What
The root
package.jsonalready pins the whole@polkadotsurface throughresolutions:Point the ones we fork at quantus/common, quantus/ui, quantus/wasm and — only if quantus/api#1 concludes it is needed — quantus/api. Everything else keeps coming from npm.
Decide how the forks are consumed
Three options, and this issue should settle it rather than leave each developer to guess:
polkadot-devworkspaces that need building.@quantus/keyringetc. and depend on versions. Most conventional, needs auth in CI.portal:/workspace links for local dev, published artifacts for CI — probably where this ends up, but say so explicitly.Whatever is chosen,
yarn build:chromeandyarn build:ffmust work from a clean checkout, and the extension's own release build must not require a developer to have the fork repos checked out beside it.Also
script-src 'self' 'wasm-unsafe-eval', so the wasm from quantus/wasm#1 needs no manifest change — confirm this rather than assuming it, since the background context is an MV3 service worker, not a page.polkadot{.js}strings inmanifest_chrome.json/manifest_firefox.json. Cosmetic, but it decides whether a user can tell this apart from the upstream extension when both are installed, which they will be.git remotefor upstream polkadot-js/extension. The rebasability convention in #1 applies here too.grenade referenced this issue2026-09-10 10:15:38 +00:00
The "how are the forks consumed" question is answered and in place. Option 2 — a private registry.
Published
Gitea's npm registry at
https://git.lair.cafe/api/packages/quantus/npm/:@quantus/crypto@polkadot/keyring@polkadot/util-crypto@polkadot/networksReads are anonymous — verified — so a consumer needs no credential to install. Publishing uses
pass gitea/package-publisher-token, which is now in the agent credential store with its blast radius documented.@polkadot/utilis deliberately not published: this fork does not modify it, so it comes from npm like the rest of the scope.Two different mechanisms, for a reason
@quantusis routed as a whole scope in.yarnrc.yml:Safe, because we own every name in that scope.
@polkadotis not, and must not be. Most of that scope is unforked —util,dev,dev-ts,ui-settings,x-*,wasm-cryptoand more — so routing it would send yarn looking for dozens of packages that are not there. The three forks are pinned individually to tarball URLs inresolutions:Worth knowing when this repo is wired up: the extension will need the same split. It depends on far more of the
@polkadotscope thanuidoes.What came out
quantus/uicarried four workarounds, all for one cause — node resolves a portal or link symlink to its realpath, after which@polkadot/util-cryptoresolved inside common's tree, where it is a workspace source directory with noexportsmap. All four are gone:../common/packages/*/buildtsconfig.base.json*.d.tspath mappingstsconfig.jsonruntime.jsoverrides for@polkadot/dev-ts--preserve-symlinksin the test scriptstsconfig.base.jsonandtsconfig.jsonare now byte-identical to upstream again, which is the rebasability convention honoured rather than merely stated.Verified
common: build clean, 3084 tests passui: build clean, 46 tests pass including the 5 ML-DSA ones, and the installed@polkadot/util-cryptois confirmed to be the fork (hasdilithium/, not a symlink)uilint: 0 errors, down from 25 on pristine upstream — those wereno-unsafe-assignment/no-unsafe-argumenton values that wereanyonly because the types never resolvedOne operational note
A version cannot be overwritten in place — npm refuses with "You cannot publish over the previously published versions". Republishing during development is delete-then-publish:
The token can do this (
write:packagecovers delete, returns204). Worth deciding before long whether fork builds get a distinguishing version —14.0.3-quantus.1or similar — rather than shadowing upstream's number. Publishing under upstream's exact version is unambiguous in a lockfile because the URL is recorded, but it reads confusingly inyarn why.Done. Branch
quantus-registry(bff8eec1).yarn build:chromecompletes with post-quantum crypto in the bundle, and 65 tests pass.Registry contents
@quantus/crypto@polkadot/keyring@polkadot/util-crypto@polkadot/networks@polkadot/ui-keyringEverything else —
api,types,rpc-provider,util,dev,x-*,hw-ledger— still comes from npm, which is why@polkadotis pinned per-package rather than scope-routed.The bundler bug none of our tests could have caught
The first
build:chromefailed:wasm-bindgen's async
__wbg_initcontainsnew URL('quantus_crypto_bg.wasm', import.meta.url), and webpack resolves that statically at build time whether or not the branch can run. The file isn't in the package — the wasm ships base64'd inbytes.js, which is the package's whole purpose.Ten Rust tests, twelve consumer assertions and a browser probe all passed while the package was unusable in a bundler. Fixed in quantus/wasm (
e8bf9e20) by stripping the dead init after bindgen, with assertions so a wasm-bindgen upgrade fails the build rather than silently shipping it again.The lesson worth keeping: this package's consumers bundle, and nothing in its own test suite does.
One upstream test rewritten
buildHierarchy.spec.tsfailed on account ordering.compareByNetworkresolves a genesis hash throughgetNetworkMap()→selectableNetworks, which this fork narrowed to post-quantum chains — so Polkadot and Kusama both resolved to''and compared equal. The network-ordering tests were passing without ordering anything.Rewritten with Quantus and Heisenberg, whose display names sort in the same direction the originals did, so the fixtures keep their shape. (I got the direction wrong on the first attempt and had to redo it —
'Quantus' < 'Quantus Heisenberg'matches'Kusama' < 'Polkadot', not the reverse.)Verified in the artifacts, not assumed
background.js(1.1 MB) —QUANTUS_EXTRINSIC, the dilithium keypair types,ext_poseidon_hash,ext_mldsa_sign, and the base64 wasm payloadextension.js(3.5 MB) — the Quantus network entry,QTC, the mainnet genesis hashThe split is correct: signing lives in the service worker, the UI only renders addresses.
Still open on this issue
The branding item from the original body — name, description, icons, and the
polkadot{.js}strings in both manifests. Untouched. It decides whether a user can tell this apart from the upstream extension when both are installed, which they will be.Also still true: no CI publishes these packages. Today it is a manual
npm publish --tag quantusper package againstpass gitea/package-publisher-token. Fine while one person is building; worth a Gitea Actions workflow before a second.Verified against
main, closing..yarnrc.ymlroutes the@quantusscope, andpackage.jsonpins keyring, networks, ui-keyring and util-crypto to the-quantus.2tarballs (bff8eec1). Nothing points at local fork checkouts.'wasm-unsafe-eval'.@quantus/cryptoruns in the Firefox background page and in the Chrome MV3 service worker, since wallets were created and used in both browsers.e0aa7836);851500a5fixed the manifestauthorandhomepage_urlit left behind.package.jsonauthorship stays upstream's, as credit for the code.