Operations service (API + worker) for a Rayls privacy chain — token management, wallet balances, access-manager indexing, and custody-backed signing.
Quick start | Running | Auth | API docs
The Rayls Ops API is the operations service for a Rayls privacy chain. It exposes an HTTP API (Gin) and a background worker, both built from the same DI container:
- Tokens — deploy, list, mint/burn, and stream (SSE) tokens on the chain.
- Wallet balances — per-wallet balances synced from Blockscout, with live SSE updates.
- Access Manager — indexes on-chain roles/permissions and derives each wallet's callable functions.
- Auth — Google / Microsoft OAuth and SIWE (Sign-In with Ethereum), issuing JWTs.
- Custody — all signing is delegated to the Rayls HSM (keys never leave custody).
On-chain signing goes through the custody (HSM) service; the API resolves contracts via a DeploymentProxyRegistry.
- Go 1.24.2+
- PostgreSQL
- Docker (for the containerized dev stack)
cp config/.env.example config/.env
# fill in database connection, OAuth credentials, JWT secret, etc.See config/.env.example for all available settings.
Uses Dockerfile.dev with Air for hot reload and Delve for remote debugging:
docker compose -f docker-compose.dev.yml up --buildThis starts ops-api on http://localhost:8080, PostgreSQL on localhost:5432, and the Delve debugger on localhost:2345. Set GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET / MICROSOFT_CLIENT_ID / MICROSOFT_CLIENT_SECRET in docker-compose.dev.yml (or as environment variables) to enable OAuth.
For the full local stack against a RayUp-provisioned chain (ops-api + worker + custody + playground), see docs/flows.md and run ./start_dev.sh (needs a local RayUp control plane on k3d). Note that this dev stack also depends on components that are not open-sourced yet (RayUp, the playground, and the Blockscout fork), so it cannot be brought up from the public repositories alone.
To reuse Blockscout's shared postgres instead of a separate one, the docker-compose.blockscout.yml override swaps the local postgres for Blockscout's shared-db. Bring up the shared stack first, then:
docker compose -f docker-compose.blockscout.yml up --buildBuild and run the minimal (scratch-based) production image:
docker build -t rayls-ops-api .
docker run -p 8080:8080 \
-e DATABASE_CONNECTIONSTRING="host=<host> port=5432 user=<user> password=<pass> dbname=<db> sslmode=disable" \
-e JWT_SECRET="<secret>" \
-e BASE_URL="https://your-domain.com" \
-e CORSURLS="https://your-frontend.com" \
rayls-ops-apiThe entrypoint is /app/rayls-ops-api run; pass --config to use a mounted .env file.
make build # Build the API binary
make run # Build and run the API
make lint # Run golangci-lint
make swagger # Regenerate OpenAPI docs
make test # Run all testsThe binary uses Cobra subcommands (two processes, one DI container):
./build/rayls-ops-api run --config config/.env # HTTP API (port 8080) + SSE
./build/rayls-ops-api worker --config config/.env # background indexers (tokens, AccessManager)After first start, create the initial admin user:
curl -X POST http://localhost:8080/admin/bootstrap \
-H "Content-Type: application/json" \
-d '{"email": "admin@example.com"}'On success the API returns 201 Created with the provisioned HSM wallet address.
Note: This endpoint can be called only once — if any user exists it returns
409 Conflict(BOOTSTRAP_ALREADY_COMPLETED). It requires no authentication and should be protected at the network/infrastructure level in production.
Swagger UI is at http://localhost:8080/swagger/index.html while the server is running.
Three methods are supported:
- Google OAuth —
/auth/google/login - Microsoft OAuth —
/auth/microsoft/login - SIWE (Sign-In with Ethereum) —
/auth/siwe/login
See docs/architecture.md and docs/frontend-auth-guide.md for details.
- Go to the Google Cloud Console and create/select a project.
- Under APIs & Services > OAuth consent screen, choose the user type, fill in the app details, and add the
userinfo.profileanduserinfo.emailscopes (plus test users while in "Testing"). - Under APIs & Services > Credentials, create an OAuth client ID (Web application) and add
http://localhost:8080/auth/google/callbackto the Authorized redirect URIs (use your production callback in production). - Copy the Client ID and Client Secret into your
.env:GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com GOOGLE_CLIENT_SECRET=your-client-secret
- Architecture — services, DI, on-chain integration
- Flows — local dev flow (RayUp) and provisioning
- Frontend: Auth · Tokens · Balances
We are not accepting external contributions at this time — see CONTRIBUTING.md. Please also read our Code of Conduct.
To report a security vulnerability, see SECURITY.md — please do not open a public issue.
Licensed under the Apache License, Version 2.0 — see LICENSE.
This project links third-party libraries that remain under their own licenses; notably go-ethereum under the LGPL-3.0 (library packages only) and the HashiCorp errwrap / go-multierror libraries under the MPL-2.0. See NOTICE.
Copyright 2026 Rayls Core Ltd.