> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/magicblock-labs/magicblock-engine-examples/llms.txt
> Use this file to discover all available pages before exploring further.

# Local Development Setup

> Set up a local Ephemeral Rollup validator for development and testing

## Overview

Running a local Ephemeral Rollup validator allows you to develop and test your programs without relying on remote endpoints. This guide covers installing the validator, configuring your environment, and running tests locally.

<Info>
  For comprehensive local development guidance, see the [MagicBlock Local Development Guide](https://docs.magicblock.gg/pages/ephemeral-rollups-ers/how-to-guide/local-development).
</Info>

## Prerequisites

Before setting up your local environment, ensure you have:

* **Node.js** v24.10.0 or later
* **Solana CLI** v2.3.13 or later
* **Anchor Framework** v0.32.1 or later
* **Rust** v1.85.0 or later

## Installation

<Steps>
  <Step title="Install the Ephemeral Validator">
    Install the `@magicblock-labs/ephemeral-validator` package globally:

    ```bash theme={null}
    npm install -g @magicblock-labs/ephemeral-validator
    ```

    Verify the installation:

    ```bash theme={null}
    ephemeral-validator --version
    ```
  </Step>

  <Step title="Install mb-test-validator">
    The `mb-test-validator` is a wrapper around Solana's test validator that pre-configures required accounts for MagicBlock.

    ```bash theme={null}
    npm install -g @magicblock-labs/solana-test-validator
    ```

    <Note>
      The test scripts in the examples use `mb-test-validator` which clones necessary MagicBlock program accounts automatically.
    </Note>
  </Step>

  <Step title="Configure Solana CLI">
    Set your Solana CLI to use localhost:

    ```bash theme={null}
    solana config set --url localhost
    ```

    Create a keypair if you don't have one:

    ```bash theme={null}
    solana-keygen new --no-bip39-passphrase --outfile ~/.config/solana/id.json
    ```
  </Step>
</Steps>

## Starting Local Validators

### Starting mb-test-validator

The `mb-test-validator` runs on port 8899 and provides the base layer:

```bash theme={null}
mb-test-validator --reset
```

This command:

* Resets the ledger state
* Clones required MagicBlock program accounts from devnet
* Starts listening on `http://localhost:8899`

<Tip>
  Logs are written to `/tmp/mb-test-validator.log` when using the automated test scripts.
</Tip>

### Starting ephemeral-validator

The ephemeral validator runs on port 7799 and connects to your local base layer:

```bash theme={null}
RUST_LOG=info ephemeral-validator \
  --remotes "http://127.0.0.1:8899" \
  --remotes "ws://127.0.0.1:8900" \
  -l "127.0.0.1:7799" \
  --reset
```

<CodeGroup>
  ```bash Local Development theme={null}
  RUST_LOG=info ephemeral-validator \
    --remotes "http://127.0.0.1:8899" \
    --remotes "ws://127.0.0.1:8900" \
    -l "127.0.0.1:7799" \
    --reset
  ```

  ```bash Devnet Connection theme={null}
  ACCOUNTS_REMOTE=https://rpc.magicblock.app/devnet \
  ACCOUNTS_LIFECYCLE=ephemeral \
  ephemeral-validator
  ```
</CodeGroup>

The ephemeral validator:

* Listens on `http://localhost:7799` (RPC)
* Provides WebSocket on `ws://localhost:7800`
* Connects to the base layer at `http://127.0.0.1:8899`

## Environment Variables

Configure your environment for local testing:

```bash theme={null}
export EPHEMERAL_PROVIDER_ENDPOINT=http://localhost:7799
export EPHEMERAL_WS_ENDPOINT=ws://localhost:7800
export ANCHOR_PROVIDER_URL=http://127.0.0.1:8899
export ANCHOR_WALLET="${HOME}/.config/solana/id.json"
```

<Tabs>
  <Tab title="Localnet">
    ```bash .env theme={null}
    EPHEMERAL_PROVIDER_ENDPOINT=http://localhost:7799
    EPHEMERAL_WS_ENDPOINT=ws://localhost:7800
    PROVIDER_ENDPOINT=http://localhost:8899
    WS_ENDPOINT=ws://localhost:8900
    ANCHOR_PROVIDER_URL=http://127.0.0.1:8899
    ANCHOR_WALLET=~/.config/solana/id.json
    ```
  </Tab>

  <Tab title="Devnet">
    ```bash .env theme={null}
    EPHEMERAL_PROVIDER_ENDPOINT=https://devnet-as.magicblock.app/
    EPHEMERAL_WS_ENDPOINT=wss://devnet-as.magicblock.app/
    PROVIDER_ENDPOINT=https://api.devnet.solana.com
    ANCHOR_PROVIDER_URL=https://api.devnet.solana.com
    ANCHOR_WALLET=~/.config/solana/id.json
    ```
  </Tab>
</Tabs>

## Anchor.toml Configuration

Configure your `Anchor.toml` to support multiple clusters:

```toml Anchor.toml theme={null}
[toolchain]
anchor_version = "0.32.1"

[programs.localnet]
your_program = "YourProgramID111111111111111111111111111"

[programs.devnet]
your_program = "YourProgramID111111111111111111111111111"

[provider]
cluster = "localnet"  # Change to "devnet" for devnet testing
wallet = "~/.config/solana/id.json"

[scripts]
test = "./fullstack-test.sh"
```

<Note>
  The `fullstack-test.sh` script automatically detects the cluster from `Anchor.toml` and configures validators accordingly.
</Note>

## Automated Local Testing

The examples include a `fullstack-test.sh` script that automates the entire local testing process:

<Steps>
  <Step title="Script automatically starts validators">
    The script checks if validators are already running on ports 8899 and 7799. If not, it starts them:

    ```bash theme={null}
    # Auto-detected from Anchor.toml
    anchor test
    ```
  </Step>

  <Step title="Builds and deploys programs">
    ```bash theme={null}
    anchor build
    anchor deploy --provider.cluster localnet
    ```
  </Step>

  <Step title="Runs tests with proper configuration">
    ```bash theme={null}
    yarn ts-mocha --colors -p ./tsconfig.json -t 1000000 --exit tests/**/*.ts \
      --provider.cluster localnet \
      --skip-local-validator \
      --skip-build \
      --skip-deploy
    ```
  </Step>

  <Step title="Cleans up after tests">
    The script automatically stops validators and cleans up test ledgers when tests complete.
  </Step>
</Steps>

## Manual Testing Workflow

For manual control over the testing process:

<Steps>
  <Step title="Start validators in separate terminals">
    **Terminal 1 - Base Layer:**

    ```bash theme={null}
    mb-test-validator --reset
    ```

    **Terminal 2 - Ephemeral Rollup:**

    ```bash theme={null}
    RUST_LOG=info ephemeral-validator \
      --remotes "http://127.0.0.1:8899" \
      --remotes "ws://127.0.0.1:8900" \
      -l "127.0.0.1:7799" \
      --reset
    ```
  </Step>

  <Step title="Set environment variables">
    ```bash theme={null}
    export EPHEMERAL_PROVIDER_ENDPOINT=http://localhost:7799
    export EPHEMERAL_WS_ENDPOINT=ws://localhost:7800
    export PROVIDER_ENDPOINT=http://localhost:8899
    export WS_ENDPOINT=ws://localhost:8900
    ```
  </Step>

  <Step title="Build and deploy">
    ```bash theme={null}
    anchor build
    anchor deploy --provider.cluster localnet
    ```
  </Step>

  <Step title="Run tests">
    ```bash theme={null}
    anchor test --skip-local-validator --skip-build --skip-deploy
    ```
  </Step>
</Steps>

## Using --skip-local-validator

When you have validators already running, use the `--skip-local-validator` flag to avoid starting new instances:

```bash theme={null}
anchor test --skip-local-validator --skip-build --skip-deploy
```

This is useful when:

* You want to keep validators running between test runs
* You're manually managing validator lifecycles
* You're debugging and need to inspect validator logs

<Warning>
  Make sure validators are actually running before using `--skip-local-validator`, or tests will fail with connection errors.
</Warning>

## Airdropping SOL

For local testing, airdrop SOL to your wallet:

```bash theme={null}
solana airdrop 100 --url http://localhost:8899
```

The automated test script does this automatically:

```bash theme={null}
solana airdrop 100 $(solana address) --url http://127.0.0.1:8899
```

## Checking Validator Health

<Tabs>
  <Tab title="Base Layer (8899)">
    ```bash theme={null}
    curl http://127.0.0.1:8899/health
    ```

    ```bash theme={null}
    solana cluster-version --url http://localhost:8899
    ```
  </Tab>

  <Tab title="Ephemeral Rollup (7799)">
    ```bash theme={null}
    curl http://127.0.0.1:7799/health
    ```
  </Tab>
</Tabs>

## Troubleshooting

### Validators won't start

Check if ports are already in use:

```bash theme={null}
lsof -i :8899
lsof -i :7799
```

Kill existing processes:

```bash theme={null}
pkill -f "solana-test-validator"
pkill -f "mb-test-validator"
pkill -f "ephemeral-validator"
```

### Clean ledger state

```bash theme={null}
rm -rf test-ledger test-ledger-magicblock magicblock-test-storage
```

### Check logs

View validator logs:

```bash theme={null}
tail -f /tmp/mb-test-validator.log
tail -f /tmp/ephemeral-validator.log
```

## Next Steps

* Learn about [Testing Patterns](/development/testing)
* Explore [Troubleshooting Common Issues](/development/troubleshooting)
* Try running the [Anchor Counter Example](/examples/anchor-counter)
