Skip to main content

Quick Access

Explore private program and test scripts for Anchor, Native Rust, and Pinocchio:

Anchor Private Counter

Anchor implementation with permissions.

Pinocchio Private Counter

Pinocchio implementation with magic permission accounts.

Why a Local PER Setup Is Different

In production a Private Ephemeral Rollup runs the Ephemeral Rollup inside a Trusted Execution Environment (TEE) on Intel TDX. Clients don’t reach the ER directly — they connect through a token-gated TEE endpoint that enforces privacy and compliance (IP geofencing, OFAC screening, and per-account permission filtering) at ingress, before any transaction is accepted or executed. You can’t run real TDX hardware locally. Instead, the TEE ingress is emulated by a dedicated process — the Query Filtering Service (QFS) — which replicates the same token-auth and permission-filtering logic without hardware attestation, and fronts an ordinary local ephemeral validator. That is the only structural difference from a plain Ephemeral Rollup local setup: you run the QFS in front of the ER and point your client at the QFS instead of the ER directly.

Topology

Four processes, each fronting the next:
Point your client at the QFS (6699) to test privacy features. Point it at the ER (7799) directly when you don’t need the privacy layer.

Quickstart with mb-stack

mb-stack is a single CLI that wraps mb-test-validator, ephemeral-validator, and query-filtering-service, and handles the startup ordering between them for you, in a single command. It ships in the same package as ephemeral-validator.
1

Install

2

Bring up the full stack

This starts mb-test-validator (8899 / 8900), ephemeral-validator (7799 / 7800), and query-filtering-service (6699 / 6700) together, on the same default ports used throughout this guide.
3

Deploy your program

Once the stack is up, deploy against the base layer as usual:

Per-Service Setup

1

Install the binaries

mb-stack, ephemeral-validator, query-filtering-service, and mb-test-validator ship together:
2

Start the base validator (port 8899)

3

Deploy or preload your program

4

Start the ephemeral validator (port 7799)

5

Start the Query Filtering Service (port 6699)

This is the process that makes it a private rollup. It points upstream at the ER and exposes the client-facing endpoint:
--add-cors-headers is required if you test from a browser app. Wait for port 6699 to accept a connection before firing any request.
6

(Optional) Start the VRF oracle

If your program requests randomness, run one oracle against the base layer and one against the ER:

Connect Your Client Through the QFS

Your client treats the QFS endpoint as the TEE endpoint: point TEE_PROVIDER_ENDPOINT at http://localhost:6699 and reuse the same authorization flow from the quickstart — fetch a token by signing a challenge, then open the connection with ?token=... attached. When a PDA is set to private via its EphemeralPermission, the QFS blocks any wallet not in the member list — exactly as the TEE would on devnet.
verifyTeeRpcIntegrity checks a real TDX attestation and is meant for the devnet/mainnet TEE endpoints. The local QFS has no hardware attestation, so skip that check when running fully local.

Delegate to the Local Validator Identity

When delegating your PDA in a local test, delegate to the localnet ER identity — not a devnet/mainnet one — so commits and undelegations settle correctly:

These public validators are supported for development. Make sure to add the specific ER validator in your delegation instruction:

Mainnet
  • Asia (as.magicblock.app): MAS1Dt9qreoRMQ14YQuhg8UTZMMzDdKhmkZMECCzk57
  • EU (eu.magicblock.app): MEUGGrYPxKk17hCr7wpT6s8dtNokZj5U2L57vjYMS8e
  • US (us.magicblock.app): MUS3hc9TCw4cGC12vHNoYcCGzJG1txjgQLZWVoeNHNd
  • TEE (mainnet-tee.magicblock.app): MTEWGuqxUpYZGFJQcp8tLN7x5v9BSeoFHYWQQ3n3xzo
Devnet
  • Asia (devnet-as.magicblock.app): MAS1Dt9qreoRMQ14YQuhg8UTZMMzDdKhmkZMECCzk57
  • EU (devnet-eu.magicblock.app): MEUGGrYPxKk17hCr7wpT6s8dtNokZj5U2L57vjYMS8e
  • US (devnet-us.magicblock.app): MUS3hc9TCw4cGC12vHNoYcCGzJG1txjgQLZWVoeNHNd
  • TEE (devnet-tee.magicblock.app): MTEWGuqxUpYZGFJQcp8tLN7x5v9BSeoFHYWQQ3n3xzo
Localnet
  • Local ER (localhost:7799): mAGicPQYBMvcYveUZA5F5UNNwyHvfYh5xkLS2Fr1mev

Endpoint Environment Variables

Centralize the endpoints so tests hit the local cluster instead of silently falling back to devnet. The PER-relevant variables: