Releases: lambdasistemi/plutus
Release list
1.67.0.0-wasm32.1
Plutus 1.67.0.0-wasm32.1
Recommended wasm32 release based exactly on upstream
IntersectMBO/plutus 1.67.0.0
at 48e9bf08f439e7223de713b5b71696fcd81cffc3.
Combined upstream changes since 1.65.0.0
The current browser consumer moves directly from 1.65.0.0-wasm32.1, so this summary compresses both
intervening upstream releases. See the official 1.66.0.0
and 1.67.0.0 release notes, or the
1.65.0.0...1.67.0.0 combined comparison.
- Compiler and evaluator: added RecInline and CollapseCase optimization passes; fixed an unsound
FloatDelaytransformation; improvedasDatalist-casing code generation. - Builtins and future protocol work: added
multiIndexArray(CIP-0156, behindfuturePV) and
policies(CIP-0168, expected for PV12); aligned host-language builtin definitions with on-chain
bounds and failure semantics. - Value and ledger APIs: exported inclusive interval-bound helpers; optimized
valueOfand
unionWith; addedunsafeLovelaceValueOf, broaderValuere-exports/comparisons, and draft Plutus
V4 script-context types. - CLI and serialization: made textual
Valueparsing enforce canonical keys, non-zero quantities,
and 128-bit bounds; added extension-based format inference, shell completion, worked help examples,
and early rejection of unsupported PLC formats. - Maintenance: replaced
deriving-aesoncost-model instances without changing their JSON format,
removed the obsoleteBuiltinCasingplugin option, and improved metatheory certifier performance.
What changed in the wasm32 fork since .0
- Rebuilt the fork as six dependency-ordered patches: evaluator semantics, WASI tests, reproducible build
outputs, automation, documentation, and repository governance. - Bound every GitHub release operation explicitly to
lambdasistemi/plutus; the tagged workflow no longer
depends on persistent-runner Git remote state. - Updated the artifact guide for this release, including direct download/checksum commands and the browser
WASI hosting contract. - Added a repository-local
maintain-wasm32-forkagent skill plus a mechanical stack validator for future
upstream bumps and same-base revisions.
The evaluator behavior is unchanged from .0; this revision repairs maintainability, tagged publication,
and consumer documentation.
Verification
plutus-core-test: 2350 passeduntyped-plutus-core-test: 883 passedplutus-ir-test: 363 passedindex-envs-test: 36 passedsatint-test: 17 test groups passed, including 10,000-case arithmetic propertiesflat-test: 1689 passedhaskell-conformance: 2008 passed- standalone
uplc.wasm: evaluates the smoke program to(con integer 42)and reports itsExBudget
Usage: WASM32.md.
Assets
0847734eadb767b8ac6a8e0803db78db0fae2374d823335629818ff172c5b249 uplc.wasm
1.67.0.0-wasm32.0
wasm32-correct Plutus evaluator, rebased onto upstream 1.67.0.0.
Every behavioural change is gated behind #if WORD_SIZE_IN_BITS == 64, so the source a 64-bit node compiles is byte-identical to upstream. What changed and how to use it: WASM32.md.
Changes
Initial wasm32 release for 1.67.0.0.
Assets
0847734eadb767b8ac6a8e0803db78db0fae2374d823335629818ff172c5b249 uplc.wasm
1.65.0.0-wasm32.1
wasm32-correct Plutus evaluator, rebased onto upstream 1.65.0.0.
Recommended build for 1.65.0.0. This is a bugfix over 1.65.0.0-wasm32 and supersedes it. Same upstream base, no API changes.
Bugfix — 64-bit neutrality of the platform-Int lift/unlift
1.65.0.0-wasm32 un-poisoned the Int/Word KnownType instances on wasm32 and unlifted them through a platform-Int bounds check. On a 32-bit target that bounds at 2³¹, while the chain (64-bit) bounds at 2⁶³ — i.e. the unlift direction was not 64-bit-neutral. No default builtin exercises it, so it was latent, but it's exactly the silent-narrowing class this fork exists to prevent.
The fix splits the two directions (see Note [Platform Int on non-64-bit targets] in PlutusCore.Default.Universe):
makeKnown(lift) kept — upcasting anInttoIntegeris lossless on any word size, and it is used on wasm32 (lengthOfByteString,countSetBits,findFirstSetBitreturn a bareInt). Identical result on 32- and 64-bit.readKnown(unlift) poisoned — a 32-bitIntcannot represent the chain's fullInt64range, so rather than ship a non-neutral instance we fail loudly. Any future builtin (or user extension) that unlifts a platformInton a 32-bit target now errors instead of silently diverging.
Verification
Full upstream suite re-run at WORD_SIZE_IN_BITS == 32 under wasmtime, green:
plutus-core-test— 2294untyped-plutus-core-test— 870
64-bit codegen is unchanged: the fix and its helper are gated #if WORD_SIZE_IN_BITS != 64, so the source a 64-bit node compiles is byte-identical to upstream.
What changed across the fork and how to use the artifacts: WASM32.md.
Assets
9d11ad68a5e511197df72438c9885b72f7d81914095105bb7b870ce47b39b715 uplc.wasm
plutus-wasm 1.65.0.0 — 32-bit-correct Plutus evaluator
plutus 1.65.0.0, made correct and tested on wasm32 (WORD_SIZE_IN_BITS == 32).
Upstream Plutus assumes a 64-bit machine word; on wasm32 several default builtins silently diverge from
the on-chain (64-bit) evaluator. This release tracks upstream 1.65.0.0 with a small, CPP-gated stack
that makes wasm32 evaluation byte-identical to the chain — and proves it by running upstream's own
test suite under wasmtime.
What's verified
- Full upstream suite green on wasm32 under wasmtime:
plutus-core-test2294,untyped-plutus-core-test
870,plutus-ir-test332,index-envs-test36,satint-test17,flat-test1491. (flat-big-test
is a multi-GB memory stress test, gated — incompatible with wasm32's address space.) - 64-bit neutrality: all changes are gated behind
#if WORD_SIZE_IN_BITS == 64, so the source the
node compiles is byte-identical to upstream. Verified: the affected suites pass on x86_64 unchanged. - UPLC deserialization is platform-independent (flat
Word64codec), so a script decodes identically on
wasm32 and on-chain.
How to use it
1. As a source dependency (wallets, verifiers, anyone embedding the evaluator in their own wasm).
Pin this rev and cross-compile your own wasm with the corrected plutus linked in:
source-repository-package
type: git
location: https://github.com/lambdasistemi/plutus.git
tag: d6b0a1988 # or: 1.65.0.0-wasm32
subdir: plutus-core plutus-ledger-api plutus-tx
Builds are cached in the paolino cachix cache, so you pull the prebuilt wasm dep closure instead of
recompiling. This is how cardano-ledger-wasi and cardano-mpfs-offchain consume it.
Verified end-to-end: repinning cardano-ledger-wasi to this rev builds wasm-tx-inspector.wasm with
no API changes, and its tx.evaluate.scripts smoke evaluates real Plutus scripts on wasm32 →
ExUnits memory=376813, steps=369294715 (within budget).
2. As a standalone evaluator (no Haskell toolchain) — verified.
Download uplc.wasm from the assets and run the real CEK + cost model on a UPLC program:
printf '(program 1.0.0 [ [ (builtin addInteger) (con integer 40) ] (con integer 2) ])' > add.uplc
wasmtime run --dir . --dir /tmp uplc.wasm -- evaluate -i add.uplc # -> (con integer 42)
wasmtime run --dir . --dir /tmp uplc.wasm -- evaluate -i add.uplc -c # adds CPU budget: 181308 / Memory budget: 602Runs the same under a browser WASI shim — the "real CEK in the browser" use case.
3. Reproduce the proof (verified end-to-end). Needs a checkout — the goldens / test/data live in
the source, not the .wasm:
git clone -b 1.65.0.0-wasm32 https://github.com/lambdasistemi/plutus && cd plutus
nix build .#wasm-plutus-core-test
WASMTIME=$(nix build --no-link --print-out-paths .#wasm-toolchain)/bin/wasmtime
( cd plutus-core && "$WASMTIME" run --dir . --dir /tmp \
../result/plutus-core-test.wasm --hedgehog-tests 1000 --no-create )
# -> All 2294 tests passedTo just build the artifact without cloning: nix build github:lambdasistemi/plutus/1.65.0.0-wasm32#wasm-plutus-core-test
— the ref is required (bare github:lambdasistemi/plutus resolves to the default branch, which has
no wasm targets). The 🕸️ Wasm32 Testsuite workflow (runs-on: nixos, cachix-cached) runs the full
matrix on every push.
Assets
uplc.wasm(24.6 MB) — the UPLC evaluator (real CEK + cost model) compiled to wasm32-wasi. Verified under wasmtime:evaluate -i <prog>→ result;-c→ result +ExBudget.SHA256SUMS.