None of these reach a published package (their dependencies are tslib,
@noble/hashes and our own packages); they are build and test tooling.
tar, ip-address, fast-uri, minimatch, brace-expansion, rollup, ws,
form-data, picomatch, serialize-javascript, ajv, bn.js and others move
to fixed versions, fflate to 0.8.3, and braces resolves to
@pezkuwi/braces as in the other repositories. OSV: 21 packages with
advisories before, 0 after.
Panic messages carry source paths, so the 7.5.20 wasm names the home
directory it was built in 54 times. Remap the sysroot, the cargo home
and the checkout to /rustc, /cargo and /build.
curve25519-dalek 2/3 -> 4.1.3 (timing variability in Scalar52::sub, on
every signature), ed25519-dalek 1 -> 2, schnorrkel 0.9 -> 0.11, merlin
2 -> 3, secp256k1 0.21 -> 0.29, tiny-bip39 0.7 -> 1.0 (drops failure),
keccak 0.1.6, rand 0.8. wee_alloc is unmaintained and is no longer the
global allocator. OSV: 9 crates with advisories before, 0 after.
secp256k1 is built with lowmemory: newer libsecp256k1 embeds about 1 MB
of precomputed tables, which would have quadrupled the wasm. The
signatures are the same; recovery uses a smaller window.
getrandom 0.2 is used with a custom backend that calls one fixed
import, wbg.ext_fill_random, which the bridge fills from
@pezkuwi/x-randomvalues. The getrandom "js" backend would have needed a
dozen new hashed wasm-bindgen imports in the bridge; the wasm now has
one import instead of 18.
The recorded known answers still hold, and signatures made by either
build verify in the other.
kat.txt holds 166 deterministic outputs (hashes, pbkdf2, scrypt, bip39,
sr25519 keys, hard and soft derivation, agreement, VRF outputs, ed25519
and secp256k1 keys and signatures, recovery) and 24 sr25519/VRF
signatures, all produced by the 7.5.20 crate set. A later crate set has
to reproduce the first byte for byte and verify the second.
What the new toolchain asked for here:
- test/deno.ts: the import/* rules are import-x/* now, so the file-wide
disable for .ts imports names import-x/extensions. The test runner's `it`
was typed by redeclaring the global globalThis, which eslint 10 reports as
shadowing a restricted name; it is read through a typed alias instead,
the same object at runtime. A note duplicated in that file is gone.
- Two disable comments that no longer suppress anything were removed by the
linter (camelcase in wasm-crypto-init types, ban-ts-comment above a
described @ts-ignore, which typescript-eslint 8 allows).
Nothing proposes updates to the workflow actions: several still declare
the Node 20 runtime, which runners already force to Node 24 with a warning
on every run. Dependabot now checks them monthly and groups all action
updates into one pull request.
The six wasm packages carried the build's rewritten package.json as their
source: exports, browser and react-native pointing at ./build/cjs/*, main at
./build/cjs/index.js. The build rewrote them again, so the published 7.5.17
and 7.5.19 had exports naming files that are not in the package (init's
"." resolved to ./build/cjs/wasm.js) and './package.json' spread into an
object of characters. This is the January 2026 ./cjs/cjs/ fault in another
form; its cause was committing built manifests, not the build script.
main, module, types, exports, browser, react-native and sideEffects are back
to the form of the upstream sources they were renamed from; the build
generates the rest. scure-sr25519 has no upstream counterpart and a
consistent hand-written manifest, so it is left as it is.
CI now checks every build/package.json: each entry point must name a file
that is there, with no ./build/ or ./cjs/cjs/ path, no numeric keys in
exports and no workspace/portal ranges. Red on the 7.5.19 build, green on
this one.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Lint never ran here: the build step stopped first on @pezkuwi/dev 0.85.7.
With it running:
- .prettierrc.cjs loaded @polkadot/dev; it is @pezkuwi/dev
- license headers on .prettierrc.cjs and scripts/pack-wasm-base.mjs
- packages/scure-sr25519/lib holds compiled files only; it is ignored
- the wasm-crypto test entries take upstream's form: one @ts-ignore, for
the build output that may not exist, with the reason; test globals by
reference
- three ad-hoc scripts from the 7.5.17 release, referenced nowhere, removed
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
0.85.12 reads the repository address from package.json, so the build no
longer stops on the Gitea URL, and keeps import() of an ES module in the
CommonJS output.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
dtolnay/rust-action does not exist, so the test job failed at setup
("Unable to resolve action dtolnay/rust-action, repository not found")
before running a single Rust test.
7.5.15-7.5.18 shipped a wasm built from a separate sr25519-only module
(4 exports) and replaced every other function in bundle.ts with a stub
that throws "not yet implemented": ed25519 pair/sign/verify, sr25519
agree and hard/soft derivation, VRF, and all of secp256k1. Because the
wasm still initialised, isReady() was true and @pezkuwi/util-crypto
called those stubs instead of falling back to JS, so ed25519 and
ethereum accounts and any // derivation failed at runtime wherever the
package is used. bip39Generate threw as well, and bip39ToSeed hashed with
SHA-256 where BIP39 specifies SHA-512.
The Rust in packages/wasm-crypto/src/rs already implemented all of it,
with sr25519 under the "bizinikiwi" context. This builds that crate and
binds it again:
- bundle.ts: the withWasm bindings for every ext_* export, as in
b61206c; getSigningContext() kept, returning "bizinikiwi".
- wasm-bridge: wasm-bindgen 0.2.90 passes an alignment to
__wbindgen_malloc/__wbindgen_free (without it Rust aborts with
`unreachable`); __wbindgen_memory returns a heap index; the two-argument
getRandomValues import takes the crypto object and a Uint8Array by heap
index, not a pointer and length.
- build-wasm.sh: source rust-version.sh relative to the script; strip the
`import * as wbg` line newer wasm2js emits and call asmFunc({ wbg }),
which is the shape its output expects.
- pack-wasm-base.mjs: also write build/bytes.js. The package exports
./bytes from there for ESM, and it was still the old sr25519-only wasm.
The committed src copies are now empty placeholders, so a build that
skips the wasm step fails instead of shipping a stale binary.
- Tests: the sr25519 known-signature vectors were substrate-context
vectors; they are replaced by vectors signed by 7.5.18, plus a test that
the same seed yields the same public key. A rename had changed the
substrate-bip39 vector's password to "Bizinikiwi"; it is "Substrate".
Compatibility with 7.5.18, measured in separate processes:
mnemonic -> mini secret -> public key is identical for every phrase with
an empty or ASCII password (12/12). It differs when the BIP39 password has
characters NFKD changes: 7.5.18 normalised it, while the Rust crate and
util-crypto's JS path do not, so this returns to the canonical result.
Rust 43/43, JS 55/55, wasm and asm.js runners pass. With this build in
place, pezkuwi-extension's suite goes from 19 failing to 3 (the 3 left
are unrelated sorting tests).
All wasm packages move to 7.5.19 and pin each other at 7.5.19.
- Remove workflows requiring unavailable secrets
- Add simple CI workflow for build and test
- Write clean README with usage examples
- Prepare for dev branch
- Fixed scrypt function that was throwing 'not yet implemented' error
- Uses @noble/hashes/scrypt for proper scrypt KDF
- Fixes account creation/import in pezkuwi-extension
- Version bump to 7.5.18