Relayer API
Real Devnet health, config, readiness, relay and transaction-status endpoints with exact request and response shapes.
All routes are JSON, served over HTTPS by the hosted Devnet relayer. The service verifies the configured RPC is canonical Solana Devnet. No route accepts note secrets or witness material.
Endpoints
| Method | Path | Purpose |
|---|---|---|
GET | /api/v1/health | Configuration and Devnet-cluster health; does not check relayer balance. |
GET | /api/v1/config | Public network, program, versions, relayer key, limits and supported operations. |
GET | /api/v1/ready | Checks Devnet RPC, blockhash reachability and configured relayer reserve. |
POST | /api/v1/relay | Validates, signs, simulates and submits a prepared v0 transaction. |
GET | /api/v1/status/:signature | Polls processed, confirmed, finalized or failed status. |
Health, configuration and readiness responses
GET /api/v1/health:
{
"status": "ok",
"service": "lethenymous-relayer",
"network": "devnet",
"coreVersion": "0.1.0",
"sdkVersion": "0.1.1"
}GET /api/v1/config returns public values only. This reflects the hosted configuration verified for this documentation release; numeric limits are live-configurable:
{
"network": "devnet",
"programId": "ZkCP47fAJJREdXNKSBvTsgJAuLoTKepgk6opmqsHobm",
"relayerPublicKey": "RLY3eqaaAJaYutKs8NezvB2bevqhtssYqU1DjpBXtzW",
"sdkVersion": "0.1.1",
"coreVersion": "0.1.0",
"maxTransactionBytes": 1232,
"maxComputeUnitLimit": 1400000,
"maxComputeUnitPriceMicroLamports": "1000",
"maxRelayFeeLamports": "15000000",
"supportedOperations": ["private_swap", "unshield"]
}GET /api/v1/ready returns { "status": "ready", "network": "devnet" } only when the RPC and configured fee-payer reserve check pass. It does not relay a transaction.
Relay request
POST /api/v1/relay requires Content-Type: application/json and the strict body:
{
"transaction": "<base64 serialized Solana v0 VersionedTransaction>"
}The operation kind is inferred from its Core instruction discriminator; the client cannot nominate a different operation name. The transaction's message fee payer and the instruction's first payer account must both be the configured relayer key. The relayer is the only required signer.
The response is returned after submission, not finality:
{
"signature": "<base58 signature>",
"status": "submitted",
"operation": "private_swap"
}Errors use a stable wrapper such as { "error": { "code": "POLICY_REJECTED", "message": "...", "requestId": "..." } }. A submission error may include a signature for subsequent polling.
Relay flow
- Resolve every referenced v0 LUT through HTTPS RPC.
- Validate the fee payer, signer count, program, instruction, account order and privileges.
- Check pool/tree/page/nullifier accounts, root liveness and rent exposure.
- Enforce packet, compute, priority-price, fee and reserve bounds.
- Sign as the relayer, simulate the exact signed transaction and submit.
- Poll status separately; on-chain execution failure is reported as
failedwithONCHAIN_FAILED.
Errors
| Code | Meaning |
|---|---|
INVALID_REQUEST | Wrong content type/schema, malformed base64 or request body bound. |
POLICY_REJECTED | Unsupported instruction/account/signer/LUT/blockhash/compute/fee/size shape. |
REPLAY_DETECTED | Spent nullifier or conflicting short-lived replay claim. |
RATE_LIMITED / CONCURRENCY_LIMITED | Per-process request or active-relay limit reached. |
LOW_RELAYER_BALANCE | Required reserve plus estimated fee/rent is unavailable. |
SIMULATION_FAILED | Exact signed transaction simulation returned an error. |
RPC_UNAVAILABLE | Required HTTPS JSON-RPC operation failed. |
SUBMISSION_FAILED | RPC did not acknowledge submission; a signature can be included for polling. |
ONCHAIN_FAILED | Status query found an execution error. |
REQUEST_TIMEOUT | Relay deadline elapsed before a submission result. |
CONFIGURATION_ERROR | Required service configuration is invalid or incomplete. |
Response messages are safe summaries; provider text, proof bytes and keys are not returned. For fee-payer construction, see Policy validation.