Skip to content

Getting started

This guide brings up a complete AttestMesh cluster on Base mainnet using the dstack (Phala) attestation method: the on-chain contracts, the gas-sponsorship webhook, the shared indexer, and two attested nodes that finish meshed, converged, and holding the Cluster Shared Key.

  • The AttestMesh monorepo checked out.
  • Foundry (forge, cast) and Rust (stable) installed.
  • A funded deployer key (cluster owner). Gas costs are small — the full on-chain deployment is well under 0.001 ETH on Base.
  • An Alchemy app for Base (RPC + EIP-4337 bundler + Gas Manager policy).
  • A Phala Cloud account with the phala CLI logged in (npx phala login) — nodes and the indexer run as dstack CVMs.
  • A Cloudflare account (the sponsorship webhook is a Worker).
  • A ghcr.io pull token if your sidecar/indexer images are private.

Credentials are loaded from the environment by deploy/env.sh; nothing secret is ever committed.

The entire bring-up is codified as a durable, resumable Smithers workflow:

Terminal window
source deploy/env.sh
bunx smithers-orchestrator up deploy/workflows/deploy.tsx

The attestmesh-deploy-full workflow runs 17 ordered tasks:

preflight → infra → cluster → pathaUpgrade → webhook → indexerEnsure
→ node-1 { env-file → deploy → prime → upgrade → verify }
→ node-2 { env-file → deploy → prime → upgrade → verify }
→ meshVerify

Every step is crash-recoverable: if a step fails (or a slow registration times out), fix the cause and resume with --run-id <id> --resume true — completed steps, deployed CVMs, and on-chain state are all reused, never redone.

Notable steps:

  • indexerEnsure is a no-op when the chain already has a registered indexer — the indexer is shared infrastructure, one instance for every cluster.
  • meshVerify polls both nodes’ health endpoints until they report phase: "healthy" — wireguard up, heartbeats converged, CSK held.

Each workflow task shells out to an idempotent, logged bash routine you can also run directly. Every step tees its output to deploy/logs/.

Terminal window
source deploy/env.sh
deploy/onchain.sh preflight # checks keys, chain id, balances
deploy/onchain.sh infra # facets, factories, IndexerRegistry (no-op if deployed)
deploy/onchain.sh cluster attestmesh-1
deploy/onchain.sh patha-upgrade <cluster-address>
Terminal window
deploy/webhook.sh deploy # wrangler deploy + asserts the custom-domain route

Then point your Alchemy Gas Manager policy’s webhook at the deployed URL.

Terminal window
deploy/indexer.sh attestmesh-indexer-1 ensure

ensure checks IndexerRegistry.current() first: if an indexer is already registered on this chain, it does nothing. Otherwise it deploys the indexer CVM, waits for boot, scrapes the TEE-derived signing pubkey from the logs, and registers (endpoint, codeId, pubKey) on chain.

Terminal window
CLUSTER=<cluster> MEMBER_IMPL=<impl> COMPOSE=deploy/compose/node-1.yaml \
deploy/node-pathA.sh attestmesh-node-1 all

The “Path A” routine (dstack base KMS) deploys a stock dstack app, allowlists its compose hash and app id on the cluster, upgrades the proxy to ClusterMember, and then polls the chain while the sidecar inside the CVM self-registers via a sponsored UserOperation. Repeat for attestmesh-node-2.

Terminal window
deploy/node-pathA.sh attestmesh-node-1 mesh-verify
deploy/node-pathA.sh attestmesh-node-2 mesh-verify

Success looks like:

{"csk_acquired":true,"first_converged":true,"live_peers":1,"phase":"healthy"}

From a cold start, both nodes typically reach healthy within a few minutes of their CVMs booting.

Each node, entirely on its own: derived its keys inside the TEE, proved its code identity to the cluster contract, found its peers from chain state, brought up an encrypted wireguard mesh through the dstack gateway, exchanged signed heartbeat keys via encrypted on-chain envelopes, and acquired the Cluster Shared Key — the first node by deriving it, every later node by pulling it over the mesh and verifying it against the on-chain commitment.

Next: Running a node for the node lifecycle in detail, and Day-2 operations for updates and rollouts.