Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions .github/actions/build-smplx-wasm/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Build smplx_wasm
description: >-
Build the smplx_wasm WASM package from the vendored `smplx` git submodule so the
`file:smplx/crates/wasm/pkg` dependency resolves. Like `lwk_wasm/pkg`, it is a wasm-pack
build artifact that is not committed, so it must be produced in CI. The output is cached
by the pinned submodule commit, so the Rust build only runs when the submodule bumps.
Requires the repo to be checked out with `submodules: recursive`.

The fork's build script needs a C compiler with a WebAssembly backend — Apple's system
clang has none, and neither does a bare ubuntu runner without LLVM's clang on PATH, which
is why one is installed rather than assumed. Without it the build fails inside
`secp256k1-sys` and `simplicity-sys` with "unable to create target", which points at the
crates and misleads.

runs:
using: composite
steps:
- name: Resolve pinned smplx commit
id: smplx
shell: bash
run: echo "sha=$(git rev-parse HEAD:smplx)" >> "$GITHUB_OUTPUT"

- name: Restore built smplx pkg
id: pkg-cache
uses: actions/cache@v4
with:
path: smplx/crates/wasm/pkg
key: smplx-wasm-${{ runner.os }}-${{ steps.smplx.outputs.sha }}

# 1.91.0 because `crates/simplex` declares it as the workspace's minimum, and the
# build tree demands it independently: `ar_archive_writer` reached through wasm-pack
# requires 1.88.0. An earlier pin of 1.85.0 built locally on a newer toolchain and
# failed here on the runner's, which is the whole reason to pin rather than inherit.
- name: Install Rust toolchain (1.91.0 + wasm32)
if: steps.pkg-cache.outputs.cache-hit != 'true'
uses: dtolnay/rust-toolchain@master
with:
toolchain: "1.91.0"
targets: wasm32-unknown-unknown

- name: Cache cargo registry + build
if: steps.pkg-cache.outputs.cache-hit != 'true'
uses: actions/cache@v4
with:
path: |
~/.cargo/registry/index
~/.cargo/registry/cache
~/.cargo/git/db
smplx/target
key: cargo-smplx-${{ runner.os }}-${{ steps.smplx.outputs.sha }}
restore-keys: |
cargo-smplx-${{ runner.os }}-

- name: Install wasm-pack
if: steps.pkg-cache.outputs.cache-hit != 'true'
uses: jetli/wasm-pack-action@v0.4.0

# Installed rather than exported: the fork's build script already searches for a clang
# with a WebAssembly backend and fails with a clear message when there is none, so
# putting one on PATH keeps that guard rather than bypassing it.
- name: Install a C compiler with a WebAssembly backend
if: steps.pkg-cache.outputs.cache-hit != 'true'
shell: bash
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends -y clang llvm

- name: Build smplx_wasm
if: steps.pkg-cache.outputs.cache-hit != 'true'
shell: bash
run: smplx/crates/wasm/build.sh
7 changes: 6 additions & 1 deletion .github/workflows/build-extension.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout (with the lwk submodule)
- name: Checkout (with the lwk and smplx submodules)
uses: actions/checkout@v4
with:
submodules: recursive
Expand All @@ -38,6 +38,11 @@ jobs:
with:
profile: ${{ inputs.profile }}

# The manifest runtime compiles Simplicity covenants and assembles transactions with
# this module, so the extension does not build without the package either.
- name: Build smplx_wasm
uses: ./.github/actions/build-smplx-wasm

- name: Install dependencies
uses: ./.github/actions/install

Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/deploy-storybook.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ jobs:
restore-keys: |
${{ runner.os }}-bun-

# This checkout has no submodules and Storybook imports neither wasm package, so the
# two local `file:` dependencies are given a package at their path rather than built.
# Without one at `smplx/crates/wasm/pkg`, `bun install` cannot resolve the workspace.
- name: Prepare unused wasm dependencies
run: |
mkdir -p lwk/lwk_wasm/pkg smplx/crates/wasm/pkg
printf '{"name":"lwk_wasm","version":"0.0.0","type":"module"}\n' > lwk/lwk_wasm/pkg/package.json
printf '{"name":"smplx-wasm","version":"0.0.0","type":"module"}\n' > smplx/crates/wasm/pkg/package.json

- name: Install dependencies
run: bun install --frozen-lockfile

Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/deploy-web-netlify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ jobs:
mkdir -p lwk/lwk_wasm/pkg
printf '{"name":"lwk_wasm","version":"0.0.0","type":"module"}\n' > lwk/lwk_wasm/pkg/package.json

# Same again for `smplx-wasm`, added for the manifest runtime the extension ships and
# likewise not imported by the web app. This checkout has no submodules, so without a
# package at that path `bun install` cannot resolve the workspace and the deploy fails
# on a dependency nothing here builds with.
- name: Prepare unused smplx-wasm dependency
run: |
mkdir -p smplx/crates/wasm/pkg
printf '{"name":"smplx-wasm","version":"0.0.0","type":"module"}\n' > smplx/crates/wasm/pkg/package.json

- name: Install dependencies
uses: ./.github/actions/install

Expand Down
85 changes: 85 additions & 0 deletions .github/workflows/tx-manifest-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: tx-manifest / smplx check

# The gate for the tx-manifest package and the smplx adapter, and only for those.
#
# Deliberately not `bun run check`. On a clean frozen install against the pinned
# submodules, the repository-wide typecheck fails in existing UI code on duplicate React
# and Zod type families reached through separate dependency trees — a problem that predates
# this work and that is repaired later on this branch. Running the full gate here would
# report those failures against every change to the manifest runtime and say nothing about
# it. So this checks what this slice owns, in full, and the root gate is restored in the
# activation slice once the cumulative branch carries the dependency repairs.
on:
push:
branches: ["**"]
pull_request:

permissions:
contents: read

jobs:
check:
runs-on: ubuntu-latest
steps:
# Recursive, and both wasm packages are built before anything else runs. Neither is
# optional: `lwk_wasm` and `smplx-wasm` are local `file:` dependencies, so on a
# checkout without them the frozen install cannot resolve the workspace, the
# typechecks have no declarations to read, and the two test files that drive the real
# smplx module rather than a substitute fail on
# `Cannot find module 'smplx-wasm/smplx_wasm_bg.js'` — driving the real one is the
# point of them.
- name: Checkout (with the lwk and smplx submodules)
uses: actions/checkout@v4
with:
submodules: recursive

- name: Setup Bun
uses: ./.github/actions/setup-bun

# dev rather than release: this job checks code, and an unoptimised wasm builds
# faster. The release profile belongs to the build workflow, which ships the result.
- name: Build lwk_wasm
uses: ./.github/actions/build-lwk-wasm
with:
profile: dev

- name: Build smplx_wasm
uses: ./.github/actions/build-smplx-wasm

- name: Install dependencies
uses: ./.github/actions/install

- name: Typecheck packages
run: bun run typecheck:packages

# The extension half of this slice, typechecked by naming its files rather than by
# running the root project over `apps/extension/src`. `--ignoreConfig` is what makes
# that possible: the root `tsconfig.json` would pull in the whole app and with it the
# baseline failures above, so the flags this surface actually needs are stated here
# instead. The two ambient declaration files are named because nothing imports them —
# they are what make `smplx-wasm/smplx_wasm_bg.js` and `bun:test` resolvable.
- name: Typecheck the smplx adapter
run: |
bunx tsc --ignoreConfig --noEmit --strict \
--module ESNext --moduleResolution bundler --target ESNext \
--lib ESNext,DOM --types bun-types --skipLibCheck \
apps/extension/src/vite-env.d.ts \
apps/extension/src/bun-test-env.d.ts \
apps/extension/src/core/chains/liquid/adapters/smplx/loadSmplxWasm.ts \
apps/extension/src/core/chains/liquid/adapters/smplx/compileCovenantWithSmplx.ts \
apps/extension/src/core/chains/liquid/adapters/smplx/assembleReviewedTransaction.ts \
apps/extension/src/core/chains/liquid/adapters/smplx/smplxWasmForTests.ts \
apps/extension/src/core/chains/liquid/adapters/smplx/loadSmplxWasm.test.ts \
apps/extension/src/core/chains/liquid/adapters/smplx/compileCovenantWithSmplx.test.ts \
apps/extension/src/core/chains/liquid/adapters/smplx/assembleReviewedTransaction.test.ts

# Both are repository-wide and both pass on this branch, so they are run as they are
# rather than narrowed to these paths.
- name: Lint
run: bun run lint

- name: Check formatting
run: bun run format:check

- name: Test
run: bun test packages/tx-manifest apps/extension/src/core/chains/liquid/adapters/smplx
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
path = lwk
url = https://github.com/lukachi/lwk.git
branch = humid/esplora-backend-config
[submodule "smplx"]
path = smplx
url = https://github.com/lukachi/smplx.git
branch = dev
6 changes: 6 additions & 0 deletions .oxfmtrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,15 @@
"sortTailwindcss": true,
"ignorePatterns": [
"lwk/**",
"smplx/**",
"**/__fixtures__/**",
"AGENTS.md",
"CLAUDE.md",
"PROJECT_WORKFLOW.md",
"skills-lock.json",
".workflow/**",
".claude/**",
".agents/**",
"README.md",
"CHANGELOG.md",
"dist/**",
Expand Down
1 change: 1 addition & 0 deletions .oxlintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
},
"ignorePatterns": [
"lwk/**",
"smplx/**",
"dist/**",
"build/**",
"node_modules/**",
Expand Down
16 changes: 16 additions & 0 deletions apps/extension/src/bun-test-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/// <reference types="bun-types" />

// Makes `bun:test` resolvable to `tsc`, which the test files import from.
//
// `@types/bun` re-exports `bun-types` and is supposed to be picked up automatically,
// but it is not under this project's configuration, so the reference is stated once
// here rather than repeated at the top of every test file — the same arrangement
// `vite-env.d.ts` already uses for Vite's ambient types.
//
// No `export {}` below, deliberately: this file is a declaration script rather than a
// module, which is what a bare triple-slash reference wants to be. An empty export would
// make it a module whose only statement exports nothing.
//
// Side effect worth knowing: the reference makes Bun's globals visible to application
// code, which does not run under Bun. Reach for a browser or extension API there,
// not `Bun.*`.
Loading
Loading