Skip to content

Run a full / RPC node ​

A full node stores the entire chain state and validates every block, but does not sign blocks. It can serve eth_* JSON-RPC and Cosmos RPC/REST publicly. Anyone can run one — no permission needed.

This page covers two paths:

  1. One-click Railway deploy — production-style, public HTTPS in minutes.
  2. Local devnet on your laptop — for iteration and contract dev.

Prefer your own server? See Run a node on a VPS / dedicated server for a full Ubuntu + Docker guide (firewall, join config, health checks, TLS, updates).

Option 1 — Deploy on Railway ​

The repo's docker/ contains everything needed.

  1. Fork or use the repo.
  2. In Railway → New service → GitHub repo → this repo.
  3. Railway auto-detects railway.json at the repo root and builds docker/Dockerfile. For mainnet add the build variable TARGET_EVM_CHAIN_ID=7628 (the image defaults to the testnet ID 76287; with the wrong value eth_chainId is wrong and wallets reject the node).
  4. Attach a Volume mounted at /data. Without this, every redeploy wipes the chain (genesis regenerated, height resets to 0).
  5. Settings → Networking → Generate Domain.

That generated domain serves four things behind one HTTPS port (via Caddy):

PathBackendUse
/EVM JSON-RPC :8545MetaMask / ethers / web3
/wsEVM WebSocket :8546subscriptions, hardhat-network
/rpc/*CometBFT RPC :26657Cosmos clients / explorer
/rest/*Cosmos REST :1317LCD / explorer

Joining the existing network ​

The default entrypoint generates a fresh single-node chain if the volume is empty. To join the existing public sanect network instead, set JOIN_NETWORK=true and the entrypoint handles everything automatically: fetching genesis, configuring peers, and state-syncing to the chain tip.

Join mainnet ​

SEED_NODE_ID and SEED_PEER_HOST are required — the node refuses to start without them. Read the current values from the public RPC:

bash
curl -s https://rpc.sanect.com/rpc/status | jq -r '.result.node_info.id, .result.node_info.listen_addr'
# 3446053b0b871ce94199a312f87ccdd17db22953   <- SEED_NODE_ID
# p2p.sanect.com:35998                       <- SEED_PEER_HOST
env
JOIN_NETWORK=true
CHAIN_ID=sanect_7628-1
EVM_CHAIN_ID=7628
SEED_NODE_URL=https://rpc.sanect.com
SEED_NODE_ID=3446053b0b871ce94199a312f87ccdd17db22953
SEED_PEER_HOST=p2p.sanect.com:35998
MONIKER=my-sanect-node
HOMEDIR=/data/.sanectd

The id is stable for the life of the primary's key, but the public P2P port belongs to a Railway TCP proxy and can change if that proxy is recreated — always take SEED_PEER_HOST from the listen_addr command above.

Join testnet ​

env
JOIN_NETWORK=true
CHAIN_ID=sanect_76287-1
EVM_CHAIN_ID=76287
SEED_NODE_URL=https://rpc.testnet.sanect.com
SEED_NODE_ID=<curl -s https://rpc.testnet.sanect.com/rpc/status | jq -r .result.node_info.id>
SEED_PEER_HOST=<curl -s https://rpc.testnet.sanect.com/rpc/status | jq -r .result.node_info.listen_addr>
MONIKER=my-sanect-testnet-node
HOMEDIR=/data/.sanectd

On first boot with JOIN_NETWORK=true, the entrypoint:

  1. Generates a fresh validator key (unique per service).
  2. Fetches genesis from $SEED_NODE_URL/rpc/genesis.
  3. Wires persistent_peers to point at the seed.
  4. Configures state sync from the seed (trust height = current - 2000).
  5. Starts the node and syncs to tip.

Snapshot fast-start ​

For large chains (>100k blocks), you can speed up the initial sync by downloading a tarball snapshot. Set one of:

env
SNAPSHOT_MANIFEST_URL=https://snapshots.sanect.com/LATEST.json
# or an explicit URL:
# SNAPSHOT_URL=https://snapshots.sanect.com/sanect-<height>.tar.lz4

This is optional. The entrypoint tries the snapshot first; if the manifest is unreachable or the download fails it falls back to state sync, and ultimately to block sync from genesis. Leave it unset to use state sync directly.

Verify it's working ​

Once Railway shows the service "Active", check the logs for:

>>> Node up at block <N>. Running REST gateway self-test...
>>> REST SELF-TEST: OK (gRPC gateway serving — explorer will work)
>>> sanect | block=<N> | txs_in_block=0 | mempool_pending=0

Then from anywhere:

bash
curl https://<your-domain>/rpc/status | jq .result.sync_info.latest_block_height

Option 2 — Local devnet ​

Single command for laptop development:

bash
# Prerequisites: Go 1.25+, jq, a C toolchain (CGO).
git clone https://github.com/cosmos/evm && cd evm && make install
export PATH=$PATH:$(go env GOPATH)/bin

git clone https://github.com/sanect/sanect-node
cd sanect-node
./scripts/localnet.sh

This wipes ~/.sanectd and starts a single-validator chain at:

EndpointURL
EVM JSON-RPChttp://localhost:8545
Cosmos RPChttp://localhost:26657
Cosmos RESThttp://localhost:1317

Env overrides: CHAIN_ID, MONIKER, HOMEDIR, BASEFEE, LOGLEVEL, DENOM, DISPLAY. Set SETUP_ONLY=true to build genesis without starting.

Public RPC node = full node + a public domain ​

There's no separate "RPC node" mode — a full node already serves the JSON-RPC. Once it's reachable on the internet (Railway domain or your own DNS), it's a public RPC node. You can run many for load: see 1 → 50 validators on Railway §"RPC replicas".

Next step ​

→ Run a validator to also sign blocks and earn stake rewards.