| name | private-zone-rpc |
| description | Interact with authenticated private Tempo Zone RPC endpoints, derive X-Authorization-Token zone auth tokens, identify zone IDs and chain IDs from ZoneFactory or repo metadata, and debug 401/403 auth failures. Use when calling rpc-zone-*-private endpoints, web3_clientVersion, eth_chainId, zone_getZoneInfo, or any private zone JSON-RPC method that needs a zone auth token. |
Private Zone RPC
Use this skill for private Tempo Zone JSON-RPC endpoints that require
X-Authorization-Token.
Auth Model
Private zone RPC authenticates every request before method dispatch, including
public methods like web3_clientVersion.
The token header is:
X-Authorization-Token: <hex token>
The token is:
<signature><version:1><zoneId:4><chainId:8><issuedAt:8><expiresAt:8>
Build the signing digest as:
keccak256("TempoZoneRPC" padded with zeros to 32 bytes || token fields)
Sign that digest with cast wallet sign --no-hash. Do not use Ethereum signed
message prefixing.
Quick Call
For zones created by the current repo tooling, prefer the built-in token helper
because it reads generated metadata:
export PRIVATE_KEY=<zone-wallet-private-key>
TOKEN=$(just zone-auth-token my-zone)
cast rpc web3_clientVersion \
--rpc-url https://private-zone-rpc.example.com \
--rpc-headers "X-Authorization-Token: $TOKEN"
When only the endpoint tuple is known, set PRIVATE_KEY in the environment and
use the helper script for one-off calls:
.codex/skills/private-zone-rpc/scripts/private_rpc_call.sh \
https://private-zone-rpc.example.com \
71 \
421700071 \
web3_clientVersion
The helper prints the JSON-RPC body on success and keeps the token out of logs.
Finding Zone ID And Chain ID
Prefer exact metadata:
- Read
generated/<name>/zone.json for zoneId.
- Read
generated/<name>/genesis.json for .config.chainId; zone.json may
also mirror the same value as chainId.
- Resolve the ZoneFactory address from
generated/<name>/zone.json,
ZONE_FACTORY, or the repo default. In this repo, the default lives
in xtask/src/zone_utils.rs as MODERATO_ZONE_FACTORY, and docs/ZONES.md
mirrors it.
- For this repo, derive missing chain IDs with
zone_primitives::constants::zone_chain_id:
chain_id = 421700000 + (zone_id % 1002610000)
xtask create-zone writes this value, and the node validates it at startup
when --zone.id is nonzero.
Query the factory counter:
cast call "$ZONE_FACTORY" \
'zoneCount()(uint32)' \
--rpc-url https://rpc.moderato.tempo.xyz
zoneCount() returns created zones. The internal next-zone counter is
zoneCount + 1.
Debugging Status Codes
401 with empty body usually means the auth header is missing or the header
name is wrong.
403 with empty body means a token was present but failed validation:
malformed signature, wrong zoneId, wrong chainId, expired token, or token
validity window too large.
- If
X-Authorization-Token gives 403 but zone-auth-token or
Authorization: Bearer gives 401, the endpoint is using the expected
header name and the tuple/signature is wrong.