Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
1e5f7d3
feat: add compact-deploy package and wire it into compact-cli
0xisk May 18, 2026
7e30fa8
refactor(deploy): convert config and loaders to material classes
0xisk May 18, 2026
bfeb490
feat(deploy): add Symbol.asyncDispose to ProofServer
0xisk May 19, 2026
54417d8
chore(deploy,cli): bump engines.node to >=24
0xisk May 19, 2026
78ecdcc
refactor(deploy): replace runPipeline with Deployer + WalletHandler c…
0xisk May 19, 2026
6ebce94
test(deploy): add unit tests for Deployer and WalletHandler
0xisk May 19, 2026
0a6499c
refactor(deploy): rename package to @openzeppelin/compact-deployer
0xisk May 19, 2026
b1cb4df
refactor(deployer): rename directory packages/deploy -> packages/depl…
0xisk May 19, 2026
74c73a4
test(deployer): reword every test description to should.../should not…
0xisk May 19, 2026
26aa42b
test(integration): group specs into deploy/, errors/, wallet/ subdirs
0xisk May 19, 2026
95f7029
style(deployer): apply biome auto-fixes; relocate runDeploy.ts biome-…
0xisk May 19, 2026
6c48757
chore(deps): force-upgrade vulnerable+EOL transitive deps via resolut…
0xisk May 19, 2026
43e578d
test(deployer): add unit tests for errors, schema, loaders, and provi…
0xisk May 20, 2026
5d9938b
feat(deployer): allow injecting PrivateStateProvider via DeployerOptions
0xisk May 20, 2026
fd10681
test(integration): expand suite with PrivateCounter, new specs, and r…
0xisk May 20, 2026
0cae16c
chore(deploy): scaffold root compact.toml for preprod + gitignore dep…
0xisk May 20, 2026
96caf90
feat(deployer): wallet-state cache + observable preprod sync
0xisk May 21, 2026
da588ec
feat(deployer): persist dust sub-wallet + checkpoint state every 5 min
0xisk May 21, 2026
8b2d0c8
feat(deployer): add --fast-deploy flag for NIGHT-only deploy attempts
0xisk May 21, 2026
629e871
feat(deployer): add DustBootstrap class + standalone runner
0xisk May 21, 2026
4f5731b
chore(gitignore): ignore vendor/ and target/ for local Rust experiments
0xisk May 21, 2026
2daab82
chore(gitignore): ignore .toolkit-cache/ for local Rust toolkit exper…
0xisk May 22, 2026
5e61e42
feat(deployer): add --dust-start-id flag to skip ahead in dust event …
0xisk May 22, 2026
b6e877d
chore(gitignore): ignore deployments/ (contains contract signing key)
0xisk May 22, 2026
db8b5e0
feat(deployer): add preview network + fix dust fee overhead for fauce…
0xisk May 22, 2026
6fa8b7b
refactor(deployer): drop dust workarounds + faucet handling; add expl…
0xisk May 24, 2026
b3e1e9f
chore(deps): bump midnight-js + wallet-sdk family to 4.1.0
0xisk May 24, 2026
1d22da8
docs(deployer): rewrite README — developer-preview status, preprod bl…
0xisk May 24, 2026
79aaf04
docs: trim TSDoc/JSDoc across deployer + cli
0xisk May 24, 2026
11be0f2
chore(deps): add @vitest/coverage-v8 for unit-test coverage
0xisk May 24, 2026
d323539
test(cli): add unit tests for logger / prompt / runBuilder / runDeploy
0xisk May 24, 2026
bf0b002
test(deployer): cover seeds / keystore / deployer error paths and edg…
0xisk May 24, 2026
4348a7c
test(deployer): close mid-coverage gaps in loaders / config / providers
0xisk May 24, 2026
0d4532e
test(deployer): close one-line coverage gaps in deployments / proof-s…
0xisk May 24, 2026
7208c8b
test: wire coverage thresholds + root yarn coverage script
0xisk May 24, 2026
acf0fe8
docs(deployer): apply writing-style rule across README + TS comments
0xisk May 25, 2026
15327b3
feat(examples): add fungible-token walkthrough for compact-deploy
0xisk May 25, 2026
cb34632
feat(deployer): allow inline args via DeployerOptions.args
0xisk May 25, 2026
89e96dc
chore(deps): drop midnight-js + testkit vendor tarballs (now on npm @…
0xisk May 25, 2026
42ce2b8
feat(examples): install deployer as real dep + switch to per-contract…
0xisk May 25, 2026
6ddd1a3
feat(deployer): add runDeploy() programmatic helper for deploy scripts
0xisk May 25, 2026
41135f9
feat(examples): make fungible-token a yarn workspace + demo both args…
0xisk May 25, 2026
729f6c9
chore(gitignore): drop module-only example artifacts
0xisk May 25, 2026
2f43647
feat(examples): pair node deploy script with compact-deploy CLI flow …
0xisk May 25, 2026
77f2d44
feat(deployer): typed constructor args (named-object + curried form)
0xisk May 26, 2026
0a33af4
docs(examples): switch fungible-token to curried runDeploy form
0xisk May 26, 2026
68960d7
feat(deployer,cli): import pre-warmed wallet state via --seed-cache-f…
0xisk May 26, 2026
6f1ce4b
feat(deployer): preserve previous cache as .bak + atomic-rename on --…
0xisk May 26, 2026
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
40 changes: 40 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,19 @@
*.local
package-lock.json
.pnp.*
**/.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
# Nested yarn state (e.g. `examples/<name>/.yarn/cache`) shouldn't ship.
# Examples install standalone; their cache regenerates from yarn.lock.
**/.yarn/cache
**/.yarn/install-state.gz
**/.yarn/build-state.yml
**/.yarn/unplugged

logs
log
Expand All @@ -23,9 +30,42 @@ dist/
gen/
managed/
artifacts/
# Examples ship their compiled artifacts committed so the deploy walkthrough
# works without the `compact` toolchain installed. Override the global rule
# above only for the example tree.
!examples/**/artifacts/
!examples/**/artifacts/**
# Module-only artifacts produced by `compact-compiler --hierarchical` for
# vendored library code (FungibleToken, Initializable, Utils, …). These have
# no keys/zkir and aren't deployable on their own — they regenerate on every
# `yarn compile` and otherwise just create diff noise.
examples/**/artifacts/security/
examples/**/artifacts/token/
examples/**/artifacts/utils/
midnight-level-db
compactc

# Deploy secrets — wallet seeds, signing keys, keystores. Match at any depth
# so nested deploy/ directories (e.g. under examples/) are covered too.
**/deploy/*.seed
**/deploy/*.signingkey
**/deploy/*.keystore.json

# Deployment records — the JSON the deployer writes after a successful
# deploy. Includes the contract signing key, so treat as a secret.
deployments/

# compact-deployer wallet-state cache (per-seed, per-network shielded snapshots).
.states/
**/.states/

# Third-party source pulled in for local experimentation (e.g. the
# midnight-node fork validation under vendor/midnight-node/ — see
# plans/tooling/compact-deploy-rust-fork.md). Never committed.
vendor/
target/
.toolkit-cache/

coverage
**/reports

Expand Down
111 changes: 111 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# compact-tools — top-level Makefile.
#
# Single entry point for build / lint / test pipelines and for the
# integration-test docker stack. Workspace tasks delegate to `yarn`
# (which delegates to turbo); docker + compactc orchestration lives
# here because Make's recipes run in /bin/sh and support `trap`,
# which yarn's built-in shell does not.

INTEGRATION_DIR := tests/integrations
COMPOSE_FILE := $(INTEGRATION_DIR)/local-env.yml
LOGS_DIR := $(INTEGRATION_DIR)/logs
SERVICES := proof-server indexer node

# One marker file per fixture: Make uses mtime against the .compact
# source to decide whether a re-compile is needed, so `make compile`
# is a no-op when nothing changed (poor man's build cache, free).
COUNTER_OUT := $(INTEGRATION_DIR)/fixtures/artifacts/Counter/contract/index.js
PRIVATE_OUT := $(INTEGRATION_DIR)/fixtures/artifacts/PrivateCounter/contract/index.js

.PHONY: help \
build test types lint lint-fix clean \
env-up env-down env-logs env-status \
compile test-integration

help: ## Show this help.
@echo "compact-tools — common targets"
@echo ""
@echo " Workspace tasks (delegate to yarn → turbo)"
@echo " make build Build all workspace packages"
@echo " make test Run unit tests"
@echo " make types Type-check all packages"
@echo " make lint Lint with biome"
@echo " make lint-fix Lint and auto-fix"
@echo " make clean Clean build artifacts"
@echo ""
@echo " Integration-test docker stack"
@echo " make env-up Start local Midnight stack (proof-server + indexer + node)"
@echo " make env-down Stop local stack and remove volumes"
@echo " make env-logs Tail all docker stack logs"
@echo " make env-status Show docker container status"
@echo ""
@echo " Integration-test fixtures + run"
@echo " make compile Compile fixture contracts (idempotent via mtime)"
@echo " make test-integration End-to-end: env-up → compile → vitest → env-down"

# ── Workspace tasks ────────────────────────────────────────────────────

build:
yarn build

test:
yarn test

types:
yarn types

lint:
yarn lint

lint-fix:
yarn lint:fix

clean:
yarn clean

# ── Integration-test docker stack ──────────────────────────────────────

env-up: env-down
docker compose -f $(COMPOSE_FILE) up -d
@mkdir -p $(LOGS_DIR)
@for svc in $(SERVICES); do \
docker compose -f $(COMPOSE_FILE) logs -f --no-log-prefix $$svc > $(LOGS_DIR)/$$svc.log 2>&1 & \
done
@echo "Logs streaming to $(LOGS_DIR)/"

env-down:
@-pkill -f "docker compose -f $(COMPOSE_FILE) logs" 2>/dev/null || true
docker compose -f $(COMPOSE_FILE) down -v

env-logs:
tail -f $(LOGS_DIR)/*.log

env-status:
docker compose -f $(COMPOSE_FILE) ps

# ── Integration-test fixtures ──────────────────────────────────────────
#
# Each fixture has an explicit file dep on its .compact source; Make
# only re-runs `compact compile` when the source is newer than the
# emitted index.js. Idempotent across repeated invocations.

compile: $(COUNTER_OUT) $(PRIVATE_OUT)

$(COUNTER_OUT): $(INTEGRATION_DIR)/fixtures/Counter.compact
compact compile $< $(INTEGRATION_DIR)/fixtures/artifacts/Counter

$(PRIVATE_OUT): $(INTEGRATION_DIR)/fixtures/PrivateCounter.compact
compact compile $< $(INTEGRATION_DIR)/fixtures/artifacts/PrivateCounter

# ── End-to-end integration test ────────────────────────────────────────
#
# Runs the whole pipeline in one /bin/sh invocation (note the `\`
# continuations) so the `trap` survives across the chain. Teardown
# fires on success, on any failure, and on Ctrl+C (INT / TERM).

test-integration:
@trap '$(MAKE) env-down' EXIT INT TERM; \
rm -rf midnight-level-db && \
$(MAKE) env-up && \
$(MAKE) compile && \
yarn vitest run --config $(INTEGRATION_DIR)/vitest.config.ts
34 changes: 34 additions & 0 deletions compact.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Root deployer config — used by `compact-deploy` for real-network deploys.
# Local-stack deploys still go through tests/integrations/compact.toml.

[profile]
artifacts_dir = "tests/integrations/fixtures/artifacts"
deployments_dir = "deployments/compact"

# URLs taken verbatim from @midnight-ntwrk/testkit-js PreprodTestEnvironment
# (node_modules/.../testkit-js/dist/index.mjs). Indexer is v4 — the README
# example showed v3, which is stale.
[networks.preprod]
network_id = "preprod"
indexer = "https://indexer.preprod.midnight.network/api/v4/graphql"
indexer_ws = "wss://indexer.preprod.midnight.network/api/v4/graphql/ws"
node = "https://rpc.preprod.midnight.network"
node_ws = "wss://rpc.preprod.midnight.network"
proof_server = "http://127.0.0.1:6300" # reuse the local-stack proof-server from `make env-up`
explorer = "https://preprod.midnightexplorer.com"

# URLs taken verbatim from @midnight-ntwrk/testkit-js PreviewTestEnvironment.
# Recommended by Midnight team while preprod is blocked on the
# `midnight:event[v9]` DustSpendProcessed deserialization bug.
[networks.preview]
network_id = "preview"
indexer = "https://indexer.preview.midnight.network/api/v4/graphql"
indexer_ws = "wss://indexer.preview.midnight.network/api/v4/graphql/ws"
node = "https://rpc.preview.midnight.network"
node_ws = "wss://rpc.preview.midnight.network"
proof_server = "http://127.0.0.1:6300" # reuse the local-stack proof-server from `make env-up`
explorer = "https://preview.midnightexplorer.com"

[contracts.Counter]
artifact = "Counter"
signing_key_file = "deploy/Counter.preprod.signingkey"
36 changes: 36 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# compact-tools examples

Runnable, copy-pasteable starting points for `compact-deployer`. Each example is self-contained: its own `compact.toml`, its own `package.json`, its own compiled artifact, and its own hand-written deploy script using the programmatic deployer API.

## Available examples

| Example | What it covers |
|---|---|
| [fungible-token/](./fungible-token/) | Deploys a small ERC20-flavoured contract wrapping OpenZeppelin Compact's `FungibleToken` module. Constructor exercises every common Compact primitive type: strings, `Uint<8/32/64/128>`, `Boolean`, `Bytes<8/32>`. |

More to come (private state + witnesses, multisig patterns, programmatic API).

## Conventions

- Each example builds and runs on Node 24+.
- Compiled artifacts ship committed so you can deploy without installing the `compact` toolchain.
- `deploy/*.signingkey` files are gitignored. Generate per the example README.
- `.states/` (wallet cache) and `deployments/` (deploy records) are gitignored.
- Compact-contracts modules (`FungibleToken`, `Initializable`, `Utils`) are vendored as copies of [openzeppelin/compact-contracts](https://github.com/openzeppelin/compact-contracts) source, not submodules. Refresh by recopying when the library publishes.

## Setup

Each example is a yarn workspace member, so a single root-level install wires every binary (`compact-compiler`, `compact-deploy`) into the example. From the repo root:

```bash
yarn install
yarn build
```

After that:

```bash
cd examples/<name>
yarn compile # rebuild the artifact if you edit a .compact file
yarn deploy:local # run the example
```
Loading