Local Development
Requirements
- Node.js 22 or newer
- Circle test API key and registered entity secret
- Two funded developer-controlled wallet IDs and addresses on
ARC-TESTNET
Install
git clone https://github.com/OutstandingVick/setula.git cd setula npm install
Configure
Copy .env.example to .env and populate:
CIRCLE_API_KEY= CIRCLE_ENTITY_SECRET= CIRCLE_WALLET_A_ID= CIRCLE_WALLET_A_ADDRESS= CIRCLE_WALLET_B_ID= CIRCLE_WALLET_B_ADDRESS= CIRCLE_BLOCKCHAIN=ARC-TESTNET CIRCLE_USDC_TOKEN_ID= PAYOUT_CALLBACK_SECRET=
Optional runtime controls:
HOST=0.0.0.0 PORT=4000 DATA_FILE=.setula-data.json POLL_INTERVAL_MS=2000 POLL_TIMEOUT_MS=180000
Never commit .env. It is listed in .gitignore and must never be tracked.
Backend development server
npm run dev
Opens http://localhost:4000/pay. The server binds to 0.0.0.0:4000 by default. Runtime data is persisted atomically to .setula-data.json.
Open http://localhost:4000/pay to run the backend-served browser journey:
Invoice details → Quote review → Arc settlement progress → Payout confirmation → Receipt
Frontend development server
Keep the backend running on port 4000, then in a second terminal:
npm run dev:landing
Opens http://localhost:3001. The landing page shows a static preview of the contractor payment screen. The demo link opens http://localhost:3001/pay with the sandbox quote pre-loaded.
Set DEMO_BACKEND_ORIGIN if the backend proxy is hosted somewhere other than http://127.0.0.1:4000.
Tests
npm test
16 tests covering the backend state machine, HTTP API, idempotency, failure paths, reference integrity, and landing-page quote utilities. Tests inject a settlement gateway and never spend real USDC.
Test breakdown
| Suite | Tests | Coverage |
|---|---|---|
tests/service.test.ts | 9 | State machine, idempotency, failure paths, reference integrity |
tests/http.test.ts | 2 | HTTP server integration |
landing/tests/quote.test.ts | 5 | Landing-page quote calculator |
TypeScript checks
npm run typecheck # backend and shared types npm run typecheck:landing # landing page
Production build
npm run build:landing # Next.js landing page npm run build:web # browser bundle (esbuild)
Golden-path verification
Runs a full end-to-end payment against a real Arc Testnet settlement:
npm run verify:golden-path
To target a deployed backend instead of a local server:
VERIFY_BASE_URL="https://ideal-alignment-production-912d.up.railway.app" npm run verify:golden-path
This creates a real 0.01 USDC transfer on Arc Testnet, confirms the ArcScan link returns HTTP 200, validates duplicate prevention (recipient delta 0), and verifies the insufficient-balance failure path (SETTLEMENT_FAILED with no ArcScan link).
This spends real Arc Testnet USDC. Ensure your sender wallet is funded and the .env is configured correctly before running.
Repository structure
setula/ ├── src/ # Backend source │ ├── server.ts # Entry point │ ├── http.ts # HTTP server with all API routes │ ├── service.ts # Core business logic (SetulaService) │ ├── domain.ts # TypeScript types │ ├── state-machine.ts # Payment status transition rules │ ├── store.ts # In-memory and JSON-file persistence │ └── arc/ # Circle + Arc integration ├── web/app.ts # Payment demo client (vanilla TS) ├── public/ # Built browser assets ├── landing/ # Next.js landing page │ ├── app/ # App Router pages and layout │ ├── components/ # React components + docs │ └── lib/ # Quote calculator utilities ├── tests/ # Backend test suites ├── scripts/ │ └── run-golden-path.ts # Arc Testnet E2E verification ├── docs/ # Architecture diagrams ├── package.json ├── .env.example └── .gitignore