Local development environment for the C-Address Onboarding Bridge — Soroban smart contract, TypeScript SDK, and off-chain relayer service.
| Tool | Version | Install |
|---|---|---|
| Docker + Docker Compose | 24+ | docs.docker.com |
| Node.js | 20 LTS | nodejs.org or nvm install 20 |
| Rust + wasm32 target | stable | curl https://sh.rustup.rs -sSf | sh |
| Stellar CLI | latest | cargo install --locked stellar-cli |
| Git | any | — |
Add the wasm32 target after installing Rust:
rustup target add wasm32-unknown-unknowngit clone https://github.com/chiboy948/C-Address-Onboarding-Bridge--Contract.git
cd C-Address-Onboarding-Bridge--Contract
cp .env.example .envEdit .env and fill in values. The minimum required for local dev:
DATABASE_URL=postgres://bridge:bridge@localhost:5432/bridge
REDIS_URL=redis://localhost:6379
STELLAR_RPC_URL=http://localhost:8000/soroban/rpc
NETWORK_PASSPHRASE=Standalone Network ; February 2017
Everything else can remain blank until you need it.
# TypeScript SDK
cd sdk && npm install && cd ..docker compose up -dThis starts four services:
| Service | Port | Description |
|---|---|---|
api |
3000 | Relayer service with ts-node-dev hot reload |
postgres |
5432 | Event store and reconciliation DB |
redis |
6379 | Nonce deduplication cache |
soroban |
8000 | Stellar + Soroban local sandbox |
Check all services are healthy:
docker compose psView logs (all services or a specific one):
docker compose logs -f
docker compose logs -f apiStop the stack:
docker compose down # keep volumes
docker compose down -v # also wipe DB and Redis datacargo build -p onboarding-bridge --release --target wasm32-unknown-unknownstellar keys generate admin --network local
stellar keys address admin # copy the G-address{
"rpcUrl": "http://localhost:8000/soroban/rpc",
"networkPassphrase": "Standalone Network ; February 2017",
"adminSecretKey": "<output of: stellar keys show admin>",
"feeCollectorPublicKey": "<another G-address>",
"feeBps": 50,
"wasmPath": "./target/wasm32-unknown-unknown/release/onboarding_bridge.wasm"
}npx ts-node scripts/deploy.ts allCopy the printed contract C-address into your .env:
CONTRACT_ID=C...
cargo test -p onboarding-bridge --features testutilscd sdk && npm testcargo test -p onboarding-bridge --features testutils && (cd sdk && npm test)Install husky so the pre-commit hook runs automatically:
npx husky installThe hook (.husky/pre-commit) runs on every git commit:
- TypeScript type-check —
tsc --noEmitacross the SDK - ESLint — on staged
.tsfiles only - Rust fmt check —
cargo fmt --checkon staged.rsfiles
To skip the hook in an emergency:
git commit --no-verify -m "..."Open the repo in VS Code and accept the prompt to install recommended extensions, or install them manually:
rust-lang.rust-analyzer — Rust IDE support
esbenp.prettier-vscode — TypeScript/JSON formatter
dbaeumer.vscode-eslint — ESLint integration
ms-azuretools.vscode-docker — Docker Compose UI
bierner.markdown-mermaid — Preview Mermaid diagrams
mikestead.dotenv — .env syntax highlighting
tamasfe.even-better-toml — Cargo.toml highlighting
eamodio.gitlens — Enhanced git blame/history
Workspace settings (.vscode/settings.json) are already configured for:
- Format on save (Prettier for TS, rustfmt for Rust)
- ESLint auto-fix on save
- rust-analyzer with
testutilsfeature and Clippy - Rulers at 100 characters
| Variable | Required | Description |
|---|---|---|
STELLAR_RPC_URL |
✅ | Soroban JSON-RPC endpoint |
NETWORK_PASSPHRASE |
✅ | Stellar network passphrase |
CONTRACT_ID |
✅ | Deployed bridge contract C-address |
ADMIN_SECRET_KEY |
✅ | Admin keypair secret (load from secrets manager in prod) |
FEE_COLLECTOR_SECRET_KEY |
✅ | Fee collector keypair secret |
RELAYER_SECRET_KEY |
✅ | Keypair that submits Soroban transactions |
RELAYER_PRIVATE_KEYS |
✅ | Comma-separated Ed25519 seeds (hex) for signing |
THRESHOLD |
✅ | Minimum signatures required (must match on-chain value) |
DATABASE_URL |
✅ | PostgreSQL connection string |
REDIS_URL |
✅ | Redis connection string |
ETH_RPC_URL |
optional | Ethereum JSON-RPC endpoint |
ETH_BRIDGE_CONTRACT |
optional | Ethereum bridge contract address |
ETH_EVENT_TOPIC |
optional | keccak256 of the BridgeFund event signature |
SOLANA_WS_URL |
optional | Solana WebSocket endpoint |
SOLANA_PROGRAM_ID |
optional | Solana bridge program id |
MOONPAY_API_KEY |
optional | Moonpay on-ramp API key |
TRANSAK_API_KEY |
optional | Transak on-ramp API key |
The quickstart image takes ~30 s to boot. Check its logs:
docker compose logs sorobanIf it keeps failing, pull the latest image:
docker compose pull soroban && docker compose up -d sorobanThe api container is Node-only. Run Rust commands on your host machine, not inside Docker.
Check what's using the port and stop it, or change the host-side port in docker-compose.yml:
lsof -i :5432 # example for PostgresRun it manually to see the full error:
cd sdk && npx tsc --noEmitThe key wasn't created or was created for a different network. Re-run:
stellar keys generate admin --network localYou need to deploy and initialize the contract first (see step 4), then set CONTRACT_ID in .env.
Wipe volumes and restart:
docker compose down -v && docker compose up -d.
├── contracts/
│ └── onboarding-bridge/
│ └── src/
│ ├── lib.rs # Contract implementation
│ └── tests.rs # Contract tests
├── sdk/
│ └── src/
│ ├── bridge.ts # OnboardingBridgeSDK
│ ├── offramp.ts # OffRampIntegration (Moonpay/Transak/CEX)
│ ├── types.ts # Shared TypeScript types
│ └── __tests__/ # SDK unit tests
├── relayer/
│ └── index.ts # Off-chain relayer service
├── scripts/
│ └── deploy.ts # Deploy + initialize script
├── .husky/
│ └── pre-commit # Git pre-commit hook
├── .vscode/
│ ├── settings.json # Workspace editor settings
│ └── extensions.json # Recommended extensions
├── docker-compose.yml # Local dev stack
├── Dockerfile.dev # API/relayer dev container
├── .env.example # Environment variable template
├── Cargo.toml # Rust workspace
└── DEVELOPER_SETUP.md # This file