Files
wasm/scripts/build-quantus.sh
rob thijssen b882f914e7 build(quantus-crypto): buildable, installable and tested as a package
The JS build now runs end to end and the built package has been consumed the way
quantus/common will consume it. Four things had to be worked out.

polkadot-dev-build-ts will not build this package. It returns early for any name
not starting with @polkadot/, in both buildJs and when collecting locals for
import rewriting. Renaming into someone else's scope to satisfy a string check
would be worse than not using the tool, and nothing is lost: this package needs
no deno variant, no rollup bundle, no cross-package import rewriting. A plain tsc
build lives in scripts/build-quantus-js.sh, which also keeps `yarn build:js`
byte-identical to upstream's behaviour.

binaryen 105 silently breaks the wasm. Upstream pins version_105 (2021), which
predates the externref tables wasm-bindgen 0.2.128 emits; wasm-opt "optimises"
the table into something that fails at instantiation with `WebAssembly.Table.
grow(): failed to grow table by 4`. The wasm is valid before wasm-opt and broken
after, every cargo test still passes, and it only surfaces when a consumer tries
to init. install-build-deps.sh now fetches binaryen 123 alongside, exactly as it
does a second wasm-bindgen.

The wasm-util dependency is imported deeply. Its package index re-exports
packageDetect, whose only job is a side effect registering with @polkadot/util —
a peer dependency we would inherit for nothing. base64 and fflate are pure
functions with no dependencies, so the deep paths are both lighter and honest.

ESM only, and the CJS scaffolding is removed. The consumers are ESM and the
wasm-bindgen glue is ESM-only, so a CJS variant would mean a second generated
glue or hand-written marshalling. Revisit if quantus/common's CJS build needs it.

Also: the pack step must run after tsc, which clears build/; the checked-in
bindings are refreshed by the build so they cannot drift; and both test suites
are wired into the repo's test script, which previously ran wasm-crypto's only.

The consumer test stages a real node_modules layout rather than testing in place,
because in this repo node_modules/@polkadot/wasm-util symlinks to the package
source, which carries no exports map — so a deep import resolves for a real
consumer and fails here for reasons that have nothing to do with our package.
Staging tests module resolution too, which is half of what can break in a
published package. It is also what caught the binaryen fault.

Post-wasm-opt: 234,292 raw / 109,649 zlib / 146,200 base64 — smaller than
upstream's entire wasm-crypto blob (335,277 / 168,782 / 225,044).

Refs quantus/wasm#1

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012uDUodEcRbBwNRi3UCmw8f
2026-09-10 14:17:15 +03:00

56 lines
2.4 KiB
Bash
Executable File

#!/usr/bin/env bash
# Copyright 2026 @quantus/crypto authors & contributors
# SPDX-License-Identifier: Apache-2.0
# Builds packages/quantus-crypto. Deliberately NOT part of build-wasm.sh: that
# script drives the nightly-2022-06-24 + xargo build that `wasm-crypto` needs,
# and this crate needs a modern compiler (inline `const {}` blocks, Rust >= 1.79).
# Keeping the two builds separate is what lets wasm-crypto stay byte-identical to
# upstream. See quantus/wasm#1.
#
# There is no asm.js step here. wasm2js over ML-DSA would be enormous and slow,
# and every context we ship into sets 'wasm-unsafe-eval', so wasm is always
# available where this runs.
set -e
PKG=quantus-crypto
CRATE=quantus_crypto
BINDGEN_VER=0.2.128
WASM=packages/$PKG/build-wasm/${CRATE}_bg.wasm
OPT=packages/$PKG/build-wasm/${CRATE}_opt.wasm
echo "*** Building Rust sources"
# The toolchain comes from packages/quantus-crypto/rust-toolchain.toml, which
# pins the same channel the chain builds its runtime with.
(cd packages/$PKG && cargo build --target wasm32-unknown-unknown --release --locked)
echo "*** Converting to WASM"
./bindgen-quantus/wasm-bindgen \
packages/$PKG/target/wasm32-unknown-unknown/release/$CRATE.wasm \
--out-dir packages/$PKG/build-wasm \
--target web
# The glue is a build artifact but is checked in, so the package can be built
# without a Rust toolchain — the same reasoning as upstream checking in an empty
# bytes.js. Copy it back so the two never drift.
echo "*** Updating checked-in bindings"
cp packages/$PKG/build-wasm/$CRATE.js packages/$PKG/src/generated/$CRATE.js
cp packages/$PKG/build-wasm/$CRATE.d.ts packages/$PKG/src/generated/$CRATE.d.ts
# binaryen-quantus, not binaryen. Upstream pins version_105 (2021), which predates
# the externref tables wasm-bindgen 0.2.128 emits: it "optimises" the table into
# something that fails at instantiation with
# `WebAssembly.Table.grow(): failed to grow table by 4`. The wasm is valid before
# wasm-opt and broken after, and nothing in the build says so — it only surfaces
# when a consumer tries to init. Same shape of problem as the two bindgens.
echo "*** Optimising WASM output"
./binaryen-quantus/bin/wasm-opt $WASM -Oz -o $OPT
# Must come before packing: tsc clears build/, which is where bytes.js lands.
./scripts/build-quantus-js.sh
echo "*** Packing WASM into baseX"
PKG_NAME=$PKG CRATE_NAME=$CRATE node ./scripts/pack-quantus-base.mjs