Skip to content

Architecture

Singula has two layers. The chain holds what everybody has to agree on: who is who, who paid, and who served how long. Everything else is software that runs all the time and talks over gRPC.

sequenceDiagram
    autonumber
    participant C as Client
    participant CP as Control Plane
    participant N as Node
    participant B as Chain

    C->>CP: SessionRequest with a wallet signature<br/>or an AccessProof
    CP->>N: PrepareSession
    Note over N: credentials sealed by ECDH<br/>to the client's key
    N-->>CP: SessionReady
    CP-->>C: SessionCredentials<br/>(which the CP cannot read)
    C->>N: VLESS over REALITY<br/>(raw TCP with Vision, or xHTTP)
    loop every 30 seconds
        C->>CP: checkpoint signed by the session key
    end
    CP->>N: sign this interval
    N-->>CP: node signature
    CP->>B: EpochAttestations.push
ContractWhat it does
SingulaProtocolThe directory. The one address you need to know; every other address and the epoch parameters are read from it
StarRegistryWho is who: owner, signer, role. Also the epoch clock
CPEndpointRegistryEach Control Plane’s host and port, and its front’s key
SubscriptionNFTThe Orbit: price, duration, how the money is split
SubscriberRegistryThe anonymity set — an ordered list of commitments
VoucherKeyRegistryCommitments to the keys Control Planes blind-sign permissions with, one per window
EpochAttestationsSeconds served, with the node’s signature on every interval
RewardDistributorThe pools and the payouts, in USDC
GasStationPays gas for operations nobody should need ETH for

Each one is described in the on-chain layer.

Control Planes and clients alike read these addresses from SingulaProtocol when they start.

The Control Plane issues sessions, checks entitlement, collects reports and publishes the time served. No traffic passes through it. It keeps its state locally in BadgerDB.

Next to its gRPC endpoint, every Control Plane runs a front: a REALITY entrance on port 443 that leads to the same endpoint and nowhere else. It is there for clients on networks that block the Control Plane’s address. The front’s settings are the same on every Control Plane; only the key differs, and each publishes its own in CPEndpointRegistry. See reaching a Control Plane through its front.

The node is the same program. It runs Xray with four REALITY inbounds, serves sessions, and sends its Control Plane a heartbeat every 30 seconds.

One program for both roles. At start the program reads its role from the chain and turns on what that role needs.

Stargate is the operators’ dashboard. It reads fixed facts straight from the chain and live data from a Control Plane. The two do not depend on each other: when no Control Plane answers, you can still manage your Stars; only the live statistics go missing.

Wanderer is a client for Windows, Linux and Android, built on the same open API as anyone else’s.

  1. The client reads the list of Control Planes from CPEndpointRegistry, calls GetHealth on each and sorts them by response time. Nobody assigns a client a Control Plane.
  2. The client shows it is entitled to a session: with a wallet signature naming that Control Plane, checked against SubscriptionNFT, or with a proof of membership in SubscriberRegistry, which names no wallet at all.
  3. The Control Plane picks a node by load, heartbeat freshness and a random term. Not by where the client is: it does not know and never asks. A country is used only when the client asks for one, and then it is a requirement: if there is no node there, the request is refused rather than served from elsewhere. A client can also name the node itself.
  4. The node creates the VLESS account and seals the credentials by ECDH to the client’s key. The Control Plane passes them along but cannot read them.
  5. The client connects straight to the node. From now on the Control Plane sees no traffic.
  6. The client sends a checkpoint signed by the session key regularly, usually every 30 seconds. Time is credited once 64 KiB has moved since the last credited checkpoint, and if that does not happen within 10 minutes, the time is dropped.
  7. Before the session expires, the client renews it with RenewSession, signed by the session key. The Control Plane checks entitlement again, so a lapsed Orbit stops at the next renewal.
  8. Every four hours — and again five minutes before an epoch ends — the Control Plane merges neighbouring intervals, asks each node to sign its own, and pushes them to EpochAttestations. Without the node’s signature the contract refuses the item.
  9. When the epoch closes, claimNode and claimCp pay USDC to the Stars’ owner wallets.

A node’s second is paid at a fixed rate, RewardDistributor.nodeRate(), and a Control Plane is paid a fixed amount for each epoch of its seat; see economics.

A Star has a cold owner, where the money goes, and a hot signer on the server. Whoever takes over the server gets the signer, not the money. The details, including how to replace the key after a break-in, are in Stars and roles.