Skip to content
Draft
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
31 changes: 31 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 @@ -22,10 +29,34 @@ result
dist/
gen/
managed/
# Compiler output. Regenerated by `compact-compiler` on every build, so it
# never gets committed — including under examples/, where the walkthrough
# expects you to compile the contract yourself before deploying.
artifacts/
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
Loading