> For the complete documentation index, see [llms.txt](https://docs.astralbeam.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.astralbeam.io/for-developers/local-development.md).

# Local Development

This guide walks through setting up a complete local development environment for AstralBeam.

## Prerequisites

### Required Software

| Tool    | Version | Purpose                   |
| ------- | ------- | ------------------------- |
| Node.js | 18+     | CLI and workers           |
| Rust    | 1.70+   | Casper contracts          |
| Foundry | Latest  | EVM contracts             |
| Docker  | Latest  | Optional containerization |

> **Note**: Relayers use file-based JSON persistence. No database is required for relayer development.

### Installation

**Node.js:**

```bash
# Using nvm (recommended)
nvm install 18
nvm use 18
```

**Rust:**

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup target add wasm32-unknown-unknown
```

**Foundry:**

```bash
curl -L https://foundry.paradigm.xyz | bash
foundryup
```

***

## Repository Setup

### Clone and Install

```bash
# Clone repository
git clone https://github.com/make-software/cspr-bridge.git
cd bridge

# Install CLI dependencies
cd cli
npm install
npm run build

# Install EVM contract dependencies
cd ../contracts/eth
forge install

# Build Casper contracts
cd ../casper
cargo odra build
```

### Environment Configuration

Create `.env` file in `cli/` directory:

```bash
# EVM Networks
SEPOLIA_RPC_URL=https://sepolia.infura.io/v3/YOUR_KEY
BASE_SEPOLIA_RPC_URL=https://sepolia.base.org

# Casper Network
CASPER_NODE_URL=http://localhost:11101/rpc
CASPER_CHAIN_NAME=casper-net-1

# Keys (for local testing only)
EVM_PRIVATE_KEY=0x...
CASPER_SECRET_KEY_PATH=./keys/secret_key.pem

# Contract Addresses
SEPOLIA_LOCKER_ADDRESS=0x6aaea12cF566C9fddbC7082c15d38F1447a57D10
BASE_LOCKER_ADDRESS=0xB4Fcc5E0b3590272820b89aBfc55E8ceb7cFDabc
TOKEN_FACTORY_HASH=hash-bf16ba78a7ecfb0e64756aa8468251110f29639f38ccaf9bdb01b6f38a15c2f2
ETH_CLIENT_HASH=hash-fa183fe46e92b65da88265deb0d48c7ae44bf44d7917f19875f4457321497aa2

# P2P Configuration
P2P_PORT=9000
P2P_BOOTSTRAP_PEERS=

# Metrics
METRICS_ENABLED=true
METRICS_PORT=9090

# Logging
LOG_LEVEL=debug
```

***

## Local Networks

### EVM: Anvil

Start a local EVM chain using Anvil:

```bash
# Basic start
anvil

# With specific chain ID
anvil --chain-id 31337

# Fork Sepolia for testing
anvil --fork-url https://sepolia.infura.io/v3/YOUR_KEY
```

**Deploy contracts locally:**

```bash
cd contracts/eth

# Deploy to local Anvil
forge script script/DeployMultiSigLocker.s.sol \
  --rpc-url http://localhost:8545 \
  --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \
  --broadcast
```

### Casper: NCTL

NCTL provides a local Casper network for testing.

**Install NCTL:**

```bash
# Clone casper-node
git clone https://github.com/casper-network/casper-node.git
cd casper-node

# Build NCTL
make setup-rs
make build-system-contracts

# Add to PATH
export PATH=$PATH:$(pwd)/utils/nctl
```

**Start NCTL:**

```bash
# Start network with 5 validators
nctl-start

# Check status
nctl-status

# View node URLs
nctl-view-node-ports
# Node 1: http://localhost:11101/rpc
```

**Deploy Casper contracts:**

```bash
cd contracts/casper

# Deploy to NCTL
casper-client put-deploy \
  --node-address http://localhost:11101/rpc \
  --chain-name casper-net-1 \
  --secret-key ~/.nctl/assets/users/user-1/secret_key.pem \
  --payment-amount 200000000000 \
  --session-path target/wasm32-unknown-unknown/release/token_factory.wasm
```

***

## Development Workflow

### Project Structure

```
bridge/
├── cli/                    # TypeScript CLI and workers
│   ├── src/
│   │   ├── index.ts       # CLI entry point
│   │   ├── commands/      # CLI commands
│   │   ├── workers/       # Bridge workers
│   │   └── shared/        # Shared utilities
│   └── tests/
├── contracts/
│   ├── eth/               # EVM contracts (Foundry)
│   │   ├── erc20locker/
│   │   └── casperbridge/
│   └── casper/            # Casper contracts (Odra)
│       └── src/
├── api/                   # REST API server
└── monitoring/            # Grafana dashboards
```

### Running Components

**Start the CLI in development:**

```bash
cd cli
npm run dev
```

**Start a single worker:**

```bash
# EVM to Casper worker
npm run start -- --worker evm2casper

# Casper to EVM worker
npm run start -- --worker casper2evm
```

**Run API server:**

```bash
cd api
npm run dev
```

### Hot Reloading

For TypeScript development with hot reloading:

```bash
cd cli
npm run watch
```

In another terminal:

```bash
npm run dev
```

***

## Debugging

### Logging

Set log level in environment:

```bash
LOG_LEVEL=debug npm run start
```

Log levels: `error`, `warn`, `info`, `debug`, `trace`

### VS Code Debug Configuration

Add to `.vscode/launch.json`:

```json
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Debug CLI",
      "runtimeExecutable": "npm",
      "runtimeArgs": ["run", "dev"],
      "cwd": "${workspaceFolder}/cli",
      "env": {
        "LOG_LEVEL": "debug"
      }
    },
    {
      "type": "node",
      "request": "launch",
      "name": "Debug Tests",
      "runtimeExecutable": "npm",
      "runtimeArgs": ["test", "--", "--runInBand"],
      "cwd": "${workspaceFolder}/cli"
    }
  ]
}
```

### Contract Debugging

**EVM with Foundry:**

```bash
# Run with verbose output
forge test -vvvv

# Debug specific test
forge test --match-test testLockTokens -vvvv

# Gas report
forge test --gas-report
```

**Casper with Odra:**

```bash
# Run tests with output
cargo odra test -- --nocapture

# Specific test
cargo odra test test_mint_tokens
```

***

## Common Tasks

### Generate TypeScript Types from ABI

```bash
cd cli

# For EVM contracts
npx typechain --target ethers-v6 \
  --out-dir src/types \
  '../contracts/eth/out/**/*.json'
```

### Database Operations

```bash
cd cli

# Create new migration
npm run migrate:create -- add_new_table

# Run migrations
npm run migrate

# Rollback
npm run migrate:rollback

# Reset database
npm run migrate:reset
```

### Linting and Formatting

```bash
# TypeScript
cd cli
npm run lint
npm run format

# Rust
cd contracts/casper
cargo fmt
cargo clippy

# Solidity
cd contracts/eth
forge fmt
```

***

## Troubleshooting

### Common Issues

**"State file corrupted or missing"**

```bash
# Check data directory
ls -la data/

# Clear persistence and restart fresh
rm -rf data/*.json
npm run dev
```

**"NCTL not starting"**

```bash
# Clean and restart
nctl-stop
nctl-clean
nctl-start
```

**"Forge build fails"**

```bash
# Update dependencies
forge update

# Clean and rebuild
forge clean
forge build
```

**"Casper contract deployment fails"**

```bash
# Check payment amount
# Minimum is usually 100 CSPR for deployment
--payment-amount 200000000000  # 200 CSPR
```

### Getting Help

* GitHub Issues: [make-software/cspr-bridge/issues](https://github.com/make-software/cspr-bridge/issues)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.astralbeam.io/for-developers/local-development.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
