Skip to main content

Installation

Choose your setup

ApproachWhen to use
API onlyYou just want to call endpoints. Use the hosted backend.
Frontend onlyYou want to run the web app locally against the hosted API.
Full stackYou want everything running on your machine.

Prerequisites

  • Rust 1.88+ (for backend)
  • Node.js 18+ (for frontend)
  • Docker (optional, for containerized backend)

Backend setup

# Clone the repo
git clone https://github.com/pranshurastogi/SPECTER.git
cd SPECTER/specter

# Copy environment config
cp .env.example .env
# Edit .env with your values (Pinata, Turso, etc.)

# Build and run
cargo build --release
cargo run --release --bin specter -- serve

The API server starts on http://localhost:3001.

Using Docker

cd SPECTER/specter
docker build -t specter .
docker run -p 3001:8080 --env-file .env specter

Frontend setup

cd SPECTER/SPECTER-web
npm install
npm run dev

The frontend starts on http://localhost:5173 and connects to the configured backend URL.

CLI usage

The specter binary supports standalone operations:

# Generate keys
cargo run --bin specter -- generate

# Create a stealth payment
cargo run --bin specter -- create --meta-address <META_ADDRESS>

# Scan for payments
cargo run --bin specter -- scan --viewing-sk <HEX> --spending-pk <HEX> --spending-sk <HEX>

# Run benchmarks
cargo run --bin specter -- bench

# Start API server
cargo run --bin specter -- serve

Environment variables

VariableRequiredDescription
REGISTRY_BACKENDNomemory (default) or turso
TURSO_DATABASE_URLFor tursolibSQL connection string
TURSO_AUTH_TOKENFor tursoAuth token
SPECTER_DB_ENC_KEYFor hardened tursoBase64 32-byte DB master key for pending-secret wrapping, dedup MACs, and telemetry hashing
RELAYER_PRIVATE_KEYFor relayerEnables server-side Monad announcement relay
MONAD_RPC_URLFor relayer/chainMonad RPC endpoint
SPECTER_ANNOUNCER_ADDRESSFor relayer/chainSPECTERAnnouncer contract address
SPECTER_ANNOUNCER_DEPLOY_BLOCKFor chain indexingDeployment block when ANNOUNCEMENT_SOURCE=chain
ANNOUNCEMENT_SOURCENoSet chain to enable chain indexer config
PINATA_JWTFor IPFS uploadPinata upload credentials
PINATA_GATEWAY_URLFor IPFS retrieveDedicated Pinata gateway
PINATA_GATEWAY_TOKENFor IPFS retrieveGateway access token
ENS_RPC_URLNoEthereum mainnet RPC endpoint for ENS (default: https://ethereum.publicnode.com)
SUI_RPC_URLNoSui RPC endpoint (defaults by USE_SUI_TESTNET)
USE_TESTNETNoGeneral EVM/Monad testnet flag (default: false)
USE_SUI_TESTNETNoSuiNS testnet flag; defaults to USE_TESTNET
ENABLE_CACHENoIPFS cache toggle (default: enabled; set false or 0 to disable)
CHAIN_RPC_ETHEREUMFor payment verificationSource-chain RPC for chain: "ethereum"
CHAIN_RPC_ARBITRUMFor payment verificationSource-chain RPC for chain: "arbitrum"
CHAIN_RPC_BASEFor payment verificationSource-chain RPC for chain: "base"
CHAIN_RPC_OPTIMISMFor payment verificationSource-chain RPC for chain: "optimism"
CHAIN_RPC_POLYGONFor payment verificationSource-chain RPC for chain: "polygon"
CHAIN_RPC_MONAD_TESTNETFor payment verificationSource-chain RPC for chain: "monad-testnet"
CHAIN_RPC_SEPOLIAFor payment verificationSource-chain RPC for chain: "sepolia"
API_KEYNoEnables auth for write endpoints
ALLOWED_ORIGINSNoCORS origins (default: *)
RATE_LIMIT_RPSNoRequests per second (default: 10)
RATE_LIMIT_BURSTNoBurst size (default: 30)
MAX_BODY_SIZENoRequest body limit in bytes (default: 1048576)

Verify it's working

curl -s http://localhost:3001/health | jq .
# Should return: {"status":"ok","version":"..."}

Then run the quickstart flow against http://localhost:3001 instead of the hosted backend.