Provision and manage a local Rayls blockchain stack on a single host — a Rayls Sovereign bridged to a public chain by default, or the full multi-participant demo.
Features | Installation | Usage | Architecture | License
The Rayls CLI is a developer tool for provisioning and managing the Rayls blockchain stack.
Currently, this tool focuses on deploying a local demo environment on a single host, making it ideal for sales demonstrations, proof-of-concept exploration, and local development. It automates the generation of Docker Compose configurations and manages the lifecycle of the Rayls components.
What changed recently — the Rayls Sovereign is now the Axyl (
rayls-network) node, running gaslessly in its local dev-mode profile, and replacing the previous Geth-based ledger. The defaultrayls initnow spins up a single local Rayls Sovereign bridged to a public chain (the primary use case); the full multi-participant demo stack moved behind--full.
For a deeper understanding of the Rayls architecture and ecosystem, please visit the Official Rayls Documentation.
- Local Sovereign → public chain by default: A bare
rayls initruns a single Rayls Sovereign (Axyl) bridged to a public chain (Rayls testnet). - Gasless Axyl node: The Rayls Sovereign runs the Axyl
localhardfork profile (EIP-1559 active from block 0 with a zero base-fee floor), so relayer/pubrelayer transactions on the node need no gas funding. - Full demo stack on demand:
--fullbrings up the multi-participant stack with a local Private Network Hub (commit chain), governance, and proofs API — 2 to 6 participants. - Automated Setup: Generates a dynamic
docker-compose.yamltailored to your specifications. - Sequential Image Pulling: Automatically pulls container images one-by-one — in every mode,
--localincluded — to stay under ECR Public's per-IP pull rate limit, cooling off and retrying if a registry throttles anyway. - Lifecycle Management: Specialized commands to start, stop, and tear down the stack.
- Monitoring & Observability: Optional OpenTelemetry stack (a single
grafana/otel-lgtmcontainer: OTel collector, Grafana, Loki, Prometheus, Tempo, and Pyroscope). - Per-Node Block Explorers: Blockscout deployment per Sovereign (default-on).
- Version Management: Built-in version checking and update notifications.
- Environment Verification: Tools to verify the integrity of the setup, including an end-to-end public-chain bridge smoke test.
Before using the Rayls CLI, ensure you have the following installed on your system:
- Go (1.25.4+ recommended) - for building the CLI.
- Docker - The engine to run the containerized stack.
- Docker Compose (v2.24 or newer) - Required for orchestration. The generated stack uses
build: !overrideanddevelop.watch, which older versions cannot parse.
Stacks that bridge to the Rayls testnet (what a bare rayls init does) deploy the public-chain contracts and seed each participant's relayer wallets from your own deployer key. Funding happens outside the CLI:
- Create a fresh key with any wallet tool (e.g.
cast wallet new). - Request testnet USDr (the Rayls public chain's native gas token) for its address through the Rayls community. Budget roughly 5 USDr per participant (each participant's public-relayer wallets are seeded with 2.5 USDr in total, plus deploy gas).
- Run
./rayls init; it prompts for the key (input hidden,0xprefix optional) and stores it in the stack directory's.env(created with0600permissions), where every laterrayls/docker composerun picks it up automatically. For CI or scripting, setPUBLIC_CHAIN_PRIVATE_KEY=<hex>in the environment instead because it overrides.envand is never written to disk.
rayls init preflights the balance: it derives your key's address, queries the chain, and refuses immediately (naming the account, balance, and shortfall) if it can't cover a fresh deploy (~2 USDr gas + 2.5 USDr per participant). This replaces the opaque mid-deploy failures an underfunded key used to cause. Note that every fresh init (after rayls down -v) spends that amount again, and each restart of the contracts container re-seeds the relayer wallets with 2.5, so prefer rayls stop/start over wipe-and-redeploy while iterating.
Use a testnet-only key and never reuse a mainnet key: like any compose environment value it is visible in docker inspect on your machine. Fully local stacks (rayls init --local, --privacy-node-only, or --full without a public chain) need no funding at all since their chains run in-stack and are genesis-funded.
Download the latest binary for your platform:
macOS (Apple Silicon):
curl -fL https://cli.rayls.com/rayls-darwin-arm64 -o rayls
chmod +x rayls
sudo mv rayls /usr/local/bin/macOS (Intel):
curl -fL https://cli.rayls.com/rayls-darwin-amd64 -o rayls
chmod +x rayls
sudo mv rayls /usr/local/bin/Linux (x86_64):
curl -fL https://cli.rayls.com/rayls-linux-amd64 -o rayls
chmod +x rayls
sudo mv rayls /usr/local/bin/Linux (ARM64):
curl -fL https://cli.rayls.com/rayls-linux-arm64 -o rayls
chmod +x rayls
sudo mv rayls /usr/local/bin/1. Clone the Repository:
git clone <repository-url>
cd rayls-sovereign-cli2. Build the CLI:
go build -o rayls .Optionally, move the rayls binary to a directory in your system's $PATH for global access.
The CLI follows a standard verb-based command structure.
To set up a new environment, run the init command. This will:
- Generate the necessary
docker-compose.yamlfile - Pull all container images sequentially (to avoid registry rate limits)
- Start all Docker containers
./rayls initBy default this spins up Rayls Sovereign(s) bridged to a public chain, with hub-less as the default topology: the nodes intercommunicate via the public chain only, no Private Network Hub. With --local everything runs on your machine (source builds + an in-stack Axyl public chain). Pulled-image inits (no --local) bridge to the Rayls testnet, deploying from your own funded testnet key: rayls init prompts for it and saves it to the stack .env (see Funding). Every participant also gets a Blockscout explorer by default (--no-blockscout disables). --with-hub opts a lean stack into the minimal hub explicitly; --full brings the complete hub demo stack.
If a docker-compose.yaml already exists, you'll be prompted to overwrite or use the existing file. If you choose to keep the existing file, the CLI will proceed with pulling images and starting containers.
Options:
--full: Bring up the full multi-participant demo stack (local Private Network Hub / commit chain, governance, proofs API, multiple Sovereigns). Combine with--membersand/or--public-chain.--with-hub: Include the Private Network Hub in the default (lean) stack — a functional hub: PNH plus the private relayer and proofs-api, so Sovereign↔PNH messaging and Enygma work. Without it, hub-less is the default (both pulled-image and--localstacks): no PNH, no private relayer, no proofs API — the Rayls Sovereigns intercommunicate via the public chain only, and the contracts deploy runs withHUB_ENABLED=false. Every--localinit records its build sources in the stack.env— the local sibling checkouts (../rayls-sovereign-contracts,../rayls-sovereign-relayer, recorded as relative paths) viaCONTRACTS_SRC/RELAYER_SRCwhen present (whatever branch is checked out there is what builds), else themaingit contexts viaCONTRACTS_REF/RELAYER_REF.--fullalways includes the full hub.--members <int>: Number of Sovereign participants. With--full: 2–6 (default 2). For the hub-less default topology: 1–6 (default 1) — the nodes intercommunicate via the public chain, so any count is meaningful. Ignored on hub-carrying lean stacks (--with-hubruns a single participant; use--fullfor the multi-participant hub).--public-chain <preset>: Public chain preset to bridge to —local(an Axyl public chain running inside the stack: servicepublic-chain, RPClocalhost:8845, chain id7331, deployer genesis-funded, no external connectivity) orrayls-testnet(the external testnet). Applied by default for the default (lean) stack — in the hub-less default the public chain is the Rayls Sovereigns' only interconnection path:localwith--local,rayls-testnetotherwise.--full --localalso defaults tolocal(the 3.0.1 source deploy requires a public chain); only--fullwith pulled images runs without one. Adds per-participantpubrelayerservices.--privacy-node-only: Run just a single Rayls Sovereign (Axyl), with no bridge or surrounding services. Ignores all other flags.--monitoring: Enable the observability stack (Grafana, Loki, Prometheus, Tempo, Pyroscope, plus an OTLP collector on4317/4318). Default: off.--blockscout <list>: Comma-separated participant letters that should get a Blockscout explorer (e.g.a,b). Defaults to every participant; use this to narrow the set.--no-blockscout: Disable the per-node Blockscout explorers entirely (overrides--blockscout).--local: Dev mode. Build the Rayls app components (kos/CTS, pubrelayer, private relayer, contracts — plus governance, proofs-api and audit-explorer in hub topologies) from source (short names,pull_policy=build/never) instead of pulling them from ECR. Also defaults the topology to hub-less and--public-chaintolocal, so a--localinit runs everything on your machine with no hub — pair with--public-chain rayls-testnetto keep bridging to the testnet instead. The infra images (NATS, the Private Network Hub, Postgres, nginx, Blockscout) still come from their registries and are pre-pulled one at a time, same as the published stack.--no-pull: Skip the image-pull step;upthen fetches only the images missing locally, one at a time. Use to keep a locally-built image (e.g. a custom node/contracts build) instead of overwriting it from ECR.--lean: Deprecated — the lean Sovereign → public-chain bridge is now the default, so this flag is a no-op. Use--fullfor the multi-participant stack.
Example:
./rayls init # default: 1 Axyl node -> rayls-testnet + explorer (http://localhost:10004)
./rayls init --local # fully local: source builds + local Axyl public chain
./rayls init --local --public-chain rayls-testnet # source builds, but bridge to the testnet
./rayls init --local --members 3 # 3 hub-less Sovereigns, fully local
./rayls init --local --with-hub # keep the minimal PNH (lean hub stack)
./rayls init --full --members 3 --monitoring # full 3-participant demo stack + monitoringNote: The first init may take several minutes as Docker images are pulled sequentially from the registry. Subsequent runs will be faster as images are cached locally.
The init flags compose into several distinct stack flavors:
A minimal Sovereign → public-chain bridge for a single participant (a): the Rayls Sovereign (Axyl) plus the services needed to bridge to an external public chain, with no private relayer, gnark/proofs API, or governance. This is what a bare rayls init does.
./rayls init # bridge to rayls-testnet (default) + Sovereign ledger explorer
./rayls init --public-chain rayls-testnet # same; --public-chain overrides the targetHub-less (the default topology) the stack is 7 core services: postgres (shared Postgres — backs the pubrelayer + KOS databases), nats, privacy-node-a, public-chain (the in-stack Axyl public chain with --local; omitted when bridging to the testnet), contracts, kos-a, pubrelayer-a — plus the per-node Blockscout explorer services (default-on; --no-blockscout drops them). KOS is kept because the pubrelayer fetches its signing keys from it. With --with-hub the stack additionally runs private-network-hub (the Besu commit chain), relayer-a (the private relayer, Sovereign↔PNH message relaying) and proofs-api (Enygma proofs).
Bridging to the testnet deploys from your own funded key: rayls init prompts for it and saves it to the stack .env (see Funding). Non-interactive/CI runs pass it via the environment instead:
PUBLIC_CHAIN_PRIVATE_KEY=<hex> ./rayls init --public-chain rayls-testnet # 0x prefix optionalOnce the stack is healthy, bridge a token end-to-end (see Verifying the bridge).
This mode uses the
rayls-contracts:latestcontracts image (the 3.0.1HUB_ENABLED-aware deploy built fromrayls-sovereign-contractsmain; the older:lean-no-pnhtag points at the same digest and is kept only for backward compatibility) and therayls-privacy-axylnode image. Both are published to ECR, so the defaultinitworks out of the box.
The full Rayls stack with N participants, a local Besu commit chain (private-network-hub), proofs API, and governance services. Bridging happens between the Rayls Sovereigns and the local commit chain, plus a public chain: with --local the in-stack local preset is included by default (the 3.0.1 source deploy requires a public chain — its Sovereign deploy ABI-encodes PUBLIC_CHAIN_ID); with pulled images the public chain stays optional (the 3.0.0-era deploy supports the commit-chain-only demo).
./rayls init --full # 2 participants, local commit chain (pulled images)
./rayls init --full --members 4 # 4 participants
./rayls init --full --local # source builds + in-stack local public chain
./rayls init --full --public-chain rayls-testnet # full stack + external public chainThe deployer for the local Besu / Sovereigns can be overridden:
PRIVATE_KEY_SYSTEM=<0x-hex> ./rayls init --fullThe default topology runs the environment without the Private Network Hub, mirroring start_dev.sh --no-hub in the rayls-sovereign-relayer repo: no private-network-hub (Besu), no private relayers, no proofs API, no governance and no audit explorer (those belong to the hub topologies — use --with-hub or --full for them). The Rayls Sovereigns intercommunicate through the public chain only, so a public chain is always configured — with --local it defaults to the local preset (an Axyl public chain inside the stack), making the whole system fully self-contained on one host; pass --public-chain rayls-testnet to bridge to the external testnet instead. The contracts deploy runs with HUB_ENABLED=false, writes no PNH_* values into the per-participant env files, and the CTS detects hub-less mode from their absence.
./rayls init --local # single Sovereign <-> local public chain, fully isolated
./rayls init --local --members 3 # N Sovereigns interconnected via the local public chain
./rayls init --local --public-chain rayls-testnet # hub-less, bridged to the testnetHub-less needs the
HUB_ENABLED-aware contracts deploy and the hub-less-capable CTS, which ship in the 3.0.1rayls-sovereign-contracts/rayls-sovereign-relayercomponents — now published to ECR, so hub-less is the default for pulled-image inits too. For--local, the CLI records the build sources in the stack.env— preferring the local sibling checkouts (CONTRACTS_SRC/RELAYER_SRC, so in-flight hub-less branches build as checked out) and falling back to themaingit contexts (CONTRACTS_REF/RELAYER_REF). Override either in.envif needed.
Minimal stack: a single Axyl privacy-node-a, with no bridge or surrounding services. The EVM JSON-RPC is exposed on 127.0.0.1:8545 (gasless, chain id 12345). No contracts, relayer, KOS, governance, NATS, postgres, commit chain, or proofs API — Axyl self-stores in its datadir.
./rayls init --privacy-node-onlyUseful when external tooling only needs an EVM RPC endpoint. All other flags are ignored. The verify command is unavailable in this mode (no contracts container).
Adds a single grafana/otel-lgtm container: Grafana (:3300), Loki (:3100), Prometheus (:3090), Tempo (:3200), Pyroscope (:3040) and an OTLP collector (:4317 gRPC / :4318 HTTP). Services are not auto-instrumented; point them at the collector to ship telemetry. Combines with the default or --full modes.
./rayls init --monitoring
./rayls init --full --members 3 --monitoringRuns a Blockscout backend + frontend per participant (proxied behind nginx), by default in every mode. --blockscout <list> narrows the set; --no-blockscout disables them.
./rayls init # explorer for the default single node -> http://localhost:10004
./rayls init --full --blockscout a,b # only participants a and b get explorers
./rayls init --no-blockscout # no explorersBuilds the Rayls app components from source (pinned git refs, or your checkouts via rayls dev) instead of pulling their ECR images; infra images are still pulled. Combines with any of the above. Useful when iterating on Rayls source out-of-tree.
./rayls init --local
./rayls init --full --local
./rayls init --local --privacy-node-onlyOnce the default (or --public-chain) stack is healthy, bridge a token end-to-end:
./rayls verify public-chainThis creates a user, deploys a fresh DEMO_* ERC-20 on the Rayls Sovereign, waits for the pubrelayer to deploy the mirror token on the public chain, bridges 100 DEMO, and confirms the destination balance. It prints the token on the Sovereign ledger, the public-chain token, the recipient, and the public chain id; verify the public-chain token on the explorer (https://testnet-explorer.rayls.com/).
If a step (usually relayer authorization on the public chain) hasn't propagated yet, a clean ./rayls down -v and re-run typically clears it.
The rayls-privacy-axyl image is a multi-arch image published to ECR. To build it yourself from the sibling axyl repo (its dev single-node mode is behind a Cargo feature):
docker build -f etc/docker-network/Dockerfile \
--build-arg BUILD_FEATURES=dev-single-node-setup \
--build-arg VERGEN_GIT_SHA=$(git rev-parse HEAD) \
-t public.ecr.aws/w0k9o1t3/rayls-demo/rayls-privacy-axyl:latest .VERGEN_GIT_SHA must be set (reth's build script slices a short SHA and panics on an empty value). Run the CLI with --no-pull (or --local) to use a locally-built image instead of pulling from ECR.
- Start the environment:
./rayls start # Start all services ./rayls start privacy-node-a kos-a # Start specific services
- Stop the environment:
Pauses running containers without removing them.
./rayls stop # Stop all services ./rayls stop privacy-node-b # Stop specific services
- Tear down the environment:
Stops and removes containers and networks. By default, volumes are preserved (data is kept).
./rayls down # Remove containers/networks, keep volumes (data preserved) ./rayls down -v # Remove containers/networks AND volumes (destructive) ./rayls down -y # Skip the confirmation prompt (orphaned containers are always removed)
- Check status:
View the running status of all Rayls services.
./rayls ps # Show all services ./rayls ps -a # Show all containers (including stopped)
- View logs:
Stream logs from the services.
./rayls logs # Show logs from all services ./rayls logs privacy-node-a kos-a -f # Follow logs from specific services ./rayls logs contracts --tail=100 # Show last 100 lines ./rayls logs -f -t # Follow all logs with timestamps
- System Info:
Display information about Docker and Docker Compose versions.
./rayls info ./rayls stats # Show Docker daemon statistics
-
Check CLI version: Display the current version and build information.
./rayls version # Show version info ./rayls version --check # Check for available updates
-
Check for updates: Check if a newer version is available and get installation instructions.
./rayls update check # Check for updatesThe CLI caches update checks for 24 hours to avoid excessive network requests. Update information is stored in
~/.rayls/update-check.json.
After successful initialization, the exposed services depend on the mode.
Default (local Sovereign → public chain):
- Sovereign RPC:
http://localhost:8545— Axyl EVM JSON-RPC (chain id12345, gasless) - Private Network Hub:
http://localhost:3445— the minimal commit chain (only with--with-hubor--full; the hub-less default has none) - Pubrelayer:
http://localhost:9050— bridges to the public chain - KOS (Key Orchestration):
localhost:8080— the CTS gRPC endpoint (mTLS, not plain HTTP) - Blockscout explorer:
http://localhost:10004— Sovereign ledger explorer for nodea(default-on; per-node at10004 + 100·i)
Full stack (--full) — additional shared services:
- Block Explorer:
http://localhost:8181- View blockchain transactions and blocks - Private Network Hub:
http://localhost:3445- Commit chain coordination - Governance API:
http://localhost:9100- Governance management - Grafana (if
--monitoringenabled):http://localhost:3300- Observability dashboards
For each participant (A, B, C, …) in --full, services are exposed on incrementing ports:
| Service | Participant A | Participant B | Participant C |
|---|---|---|---|
| Sovereign | http://localhost:8545 |
http://localhost:8546 |
http://localhost:8547 |
| Relayer | http://localhost:9000 |
http://localhost:9001 |
http://localhost:9002 |
| KOS (Key Orchestration) | http://localhost:8080 |
http://localhost:8081 |
http://localhost:8082 |
Pattern continues for participants D, E, F with incrementing port numbers.
A bare rayls init pulls the published rayls-demo images from ECR. rayls init --local instead builds the Rayls app components from source (see Working on a component); infra images are still pulled.
| Image group | default rayls init (remote) |
rayls init --local (from source) |
|---|---|---|
| kos, pubrelayer, private relayer, contracts | published ECR rayls-demo images |
built by Docker from the pinned git refs (the rayls-sovereign-* repos on main), or your checkouts via rayls dev |
--full extras: governance-api/listener/flagger, proofs-api (gnark), audit-explorer |
ECR | built by Docker from their rayls-sovereign-* repos on main (see note on gnark's Git-LFS keys below) |
| Sovereign (Axyl) | pulled from ECR | pulled from ECR + retagged (a local rayls-privacy-axyl:latest you built yourself is left alone) |
| nats, Private Network Hub (Besu) | ECR | ECR (pulled — infra images aren't source-built) |
| Third-party (postgres, blockscout, nginx, grafana) | public registries | public registries |
The published rayls-demo service images are multi-arch (amd64 + arm64), so remote rayls init runs natively on both Intel/AMD and Apple Silicon. Use --local when you want to build from a specific ref or hack on a component — not as an architecture workaround.
⚠️ gnark (proofs-api) uses Git-LFS. Its proving keys are Git-LFS blobs, which a pinned git-context build can't fetch, so the default--localbuild ofproofs-apiwould ship pointer files. For a working Enygma stack, runrayls dev gnark(clones the repo and runsgit lfs pull) or use the pulled ECR image. The hub-less default stack never buildsproofs-api, so this only matters for--with-hub/--full.The
rayls-sovereign-ops-apiservice (the former backend) is intentionally not wired into the CLI.
In --local mode every app component builds from a pinned git ref. By default that ref is main of each component's public rayls-sovereign-* repo — the 3.0.1 code, which the repos currently carry as a single main branch (no version tags yet). Once the repos tag coordinated releases, one variable in .env (or the environment) selects the whole set:
RAYLS_VERSION=3.0.2 # all components build from tag v3.0.2 (once such tags exist)Any single component can deviate — point it at a tag, branch, or your own fork:
RELAYER_REF=fix/reorg-handling # branch on the canonical repo
CONTRACTS_REF=main # a specific ref
RELAYER_REPO=git@github.com:you/rayls-sovereign-relayer.git # your fork
CONTRACTS_SRC=../rayls-sovereign-contracts # a local checkout (what `rayls dev` sets)Re-run rayls init --local after changing RAYLS_VERSION / *_REF / *_REPO (they're baked into the generated compose file); *_SRC changes apply on the next docker compose up without regenerating.
The stack directory's .env file drives both the CLI and compose; the process environment always wins over the file. See .env.example for a commented template. The component prefixes are CONTRACTS, RELAYER (kos + pubrelayer + private relayer), GOVERNANCE, GNARK, and AUDITOR.
| Variable | Purpose | Applies |
|---|---|---|
PUBLIC_CHAIN_PRIVATE_KEY |
Your funded testnet deployer key (64 hex chars, 0x optional); required for rayls-testnet stacks, prompted by rayls init and saved here (see Funding) |
next up |
RAYLS_VERSION |
Coordinated release: all components build from tag v<version> |
re-run init --local |
<COMPONENT>_REF |
Per-component branch/tag/SHA; wins over RAYLS_VERSION |
re-run init --local |
<COMPONENT>_REPO |
Per-component git URL (e.g. a fork); cloned by BuildKit, so no ssh-config aliases | re-run init --local |
<COMPONENT>_SRC |
Local checkout path; replaces the git context (managed by rayls dev) |
next up / rebuild |
RAYLS_SRC_DIR |
Where rayls dev looks for / clones checkouts (default: parent of the stack dir) |
rayls dev |
RAYLS_AXYL_IMAGE |
Image to pull + retag as rayls-privacy-axyl:latest in --local |
next init --local |
Default refs (until the component repos tag coordinated
v<X.Y.Z>releases in lockstep): every component defaults tomain— therayls-sovereign-*repos' 3.0.1 code. SetRAYLS_VERSIONor a per-component*_REFto override.
rayls dev <component> switches a component from its pinned build to a local checkout you can edit, with hot reload via rayls watch. See DEV_MODE.md for the full guide. In short:
./rayls dev relayer # clone (if needed) + switch relayer to a local checkout you edit
./rayls watch # sync saves into the container; air rebuilds & restarts in ~seconds
./rayls dev --status # what's in dev mode?
./rayls dev --off relayer # back to the pinned build| Component | Repo | Services | Hot reload |
|---|---|---|---|
relayer |
rayls-sovereign-relayer | kos-*, pubrelayer-*, relayer-* |
yes |
governance |
rayls-sovereign-pnh-governance | governance-api, governance-listener, governance-flagger |
no — build from checkout, rebuild to apply (--full only) |
gnark |
rayls-sovereign-gnark-api | proofs-api |
no — Git-LFS keys; use rayls dev gnark (LFS-aware) or the pulled image |
auditor |
rayls-sovereign-pnh-auditor-ui | audit-explorer |
no — Angular→nginx build from checkout (--full only) |
contracts |
rayls-sovereign-contracts | contracts |
no — builds from your checkout, but deploys are explicit: re-run rayls init --local (or restart the contracts service) after contract changes |
| node | axyl | privacy-node-* |
no — pulled as a published image; build it yourself for node work |
Each Rayls Sovereign is an Axyl (rayls-network) node running in its single-validator dev mode. It exposes an Ethereum-compatible JSON-RPC (eth_*, net_*, web3_*, debug_*, trace_*) on 8545+i, keeps chain state in its own datadir (a named volume, no external database), and runs the local hardfork profile so it is gasless (EIP-1559 active from block 0 with a 0 base-fee floor). The genesis is generated externally at startup via a one-shot init container (keytool + genesis ceremony), keeping the node image config-free.
When running with --full, the CLI provisions the complete Rayls stack:
Infrastructure Layer
- Postgres - Relational database for relayer/KOS/governance data
- Commit Chain - Besu-based blockchain for cross-ledger coordination
- OpenTelemetry Stack - Optional (when
--monitoringis enabled): onegrafana/otel-lgtmcontainer bundling the OTel collector, Grafana, Loki, Tempo, Prometheus, and Pyroscope
Contract Deployment Layer
- Proofs API - Zero-knowledge proof generation service
- Contracts - Smart contract compilation and deployment service (deploys to all Sovereigns and the commit chain)
Governance Layer
- Governance API / Listener / Flagger - governance operations, event listening, and feature flags
Per-Participant Services For each participant (A, B, C, …):
- Sovereign - Axyl private blockchain node (e.g.
privacy-node-a, aliasespl-a/pn-a) - KOS (Key Orchestration Service) - Cryptographic key management (e.g.
kos-a) - Relayer - Cross-chain transaction relay service (e.g.
relayer-a)
A single shared NATS instance is deployed for all participants and the governance services.
The stack uses health checks and dependency ordering to ensure services start in the correct sequence:
- Infrastructure services (Postgres, NATS) start first
- Sovereigns (and, in
--full, the commit chain) start after their init/infrastructure is healthy - Contract deployment waits for the Rayls Sovereigns (and, in
--full, the proofs API and commit chain) - Application services (KOS, relayers, pubrelayer) wait for contracts to be deployed
- Governance services (in
--full) start after contracts and databases are ready
This orchestration ensures that all required dependencies are available before dependent services attempt to start.
invalid empty ssh agent socketduring a--localbuild: the default git build contexts are publichttps://URLs and need no agent; this appears when a*_REPOoverride uses agit@/ssh://URL (e.g. a private fork), which makes BuildKit request ssh forwarding — make sureSSH_AUTH_SOCKis set and your GitHub key is loaded (ssh-add -l).- BuildKit can't resolve a custom SSH host alias: git contexts are cloned by the Docker daemon, which doesn't read your
~/.ssh/config. Use the plaingithub.comhost in*_REPOURLs and select the right key via your agent, or fall back to a local checkout withrayls dev. docker-compose.override.yaml exists but was not generated by rayls dev: you have a hand-written override; move it aside (its job is likely covered byrayls devnow).
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.
This CLI tool is currently designed for local development and demonstration purposes. It deploys a simplified version of the Rayls stack on a single host. It is not intended for production deployments or multi-host environments at this stage.
Licensed under the Apache License, Version 2.0 — see LICENSE.
Copyright 2026 Rayls Core Ltd.