Quick Start
Hosts turn raw blockchain data into structured Views and produce Attestation Records that help secure the network. This guide covers installing, configuring, and running the Shinzo Host Client.
Hardware Recommendations
| Component | Minimum | Recommended |
|---|---|---|
| CPU | 8 vCPUs | 16 vCPUs |
| Memory (RAM) | 16 GB | 32–64 GB |
| Storage | 3 TB NVMe | 4+ TB NVMe |
| OS | Ubuntu 24.04 | Ubuntu 24.04 |
Local Deployment
Run the Shinzo Host Client directly on your local machine for development and testing.
Prerequisites
- Go 1.25
- Metamask with a wallet setup. This wallet does not need to hold any funds.
Clone the Repository
git clone https://github.com/shinzonetwork/shinzo-host-client.git
cd shinzo-host-client
Configuration
The Host Client reads from config.yaml, which comes with working defaults. The only field you need to set is defradb.keyring_secret. Alternatively, you can also set the password as an environment variable to avoid storing it in plaintext:
export DEFRA_KEYRING_SECRET=<make_a_password>
Key Fields
defradb.url: API endpoint of your local DefraDB node. Defaults work for most setups.defradb.keyring_secret: Requires a secret to generate your private keys.p2p.bootstrap_peers: Indexer peers for receiving indexed data. Defaults include a reliable bootstrap peer.p2p.listen_addr: Default is suitable for local runs. Override when containerizing.store.path: Directory where local DefraDB data is stored.shinzo.web_socket_url: Defaults to a hosted ShinzoHub node. Only change if connecting to a different node.logger.development: Set tofalsefor production.host.lens_registry_path: Where received WASM lens files are stored.
The included config.yaml works for most local development. You typically only need to change peer settings or storage paths for advanced setups.
Running Indexer and Host on the Same Machine
If you are running your own indexer, you can connect your Host to this indexer by configuring p2p.bootstrap_peers. To get the required Peer ID, query the registration endpoint:
curl http://localhost:8080/registration
From this information, assemble your peer connection info: /ip4/<your-ip-here>/tcp/9171/p2p/<your-PeerID-here>. Now replace the default peer in p2p.bootstrap_peers with your indexer peer.
If you are running both Indexer and Host on the same machine, apply the following changes to the Host's config.yaml to avoid port collisions.
The Indexer is likely already using port 9181, so update the defradb.url field:
url: "localhost:9182"
Also update the P2P settings to use localhost and a different port so the Host doesn't clash with the Indexer:
bootstrap_peers:
- '/ip4/127.0.0.1/tcp/9171/p2p/<PeerID>'
listen_addr: "/ip4/0.0.0.0/tcp/9172"
Build and Run
Option A: Run directly (no build step):
go run cmd/main.go
Option B: Build then run:
make build
make start
(Optional) Enable the GraphQL Playground
The host ships with an optional web-based GraphQL Playground for querying the embedded DefraDB instance.
make build-playground
make start
This runs the Host and exposes a Playground GUI. Check the output logs for the address:
🧪 GraphQL Playground available at ...
The playground lets you run GraphQL queries against primitive data and any Views your Host is serving. Try this query:
query GetLatestLogs {
Ethereum__Mainnet__Log(
order: { blockNumber: DESC }
limit: 10
) {
address
topics
data
blockNumber
blockHash
transactionHash
transactionIndex
logIndex
removed
}
}
More query examples are available here.
VM Deployment
This is the recommended approach for production and devnet participation. It uses Docker, docker-compose, and Nginx on a virtual machine.
Prerequisites
- Port
444open in your firewall/security group.
Install System Dependencies
sudo apt-get update
sudo apt-get install -y docker.io docker-compose nginx
Create the Data Directory
sudo mkdir -p ~/data/defradb ~/data/lens
sudo chown -R 1001:1001 ~/data/defradb ~/data/lens
Generate SSL Certificates
# Generate private key, certificate signing request, and self-signed certificate
set -e &&
sudo mkdir -p ~/ssl &&
sudo openssl genrsa -out ~/ssl/nginx.key 2048 &&
sudo openssl req -new -key ~/ssl/nginx.key -out /tmp/nginx.csr -subj "/C=US/ST=State/L=City/O=Shinzo/OU=Host Client/CN=shinzo.network" &&
sudo openssl x509 -req -days 365 -in /tmp/nginx.csr -signkey ~/ssl/nginx.key -out ~/ssl/nginx.crt &&
sudo rm /tmp/nginx.csr
Write the Configuration File
Create ~/config.yaml. The production config enables performance tuning, peer reconnection, pruning, and optional event filtering. Key values to set:
defradb:
url: "localhost:9181"
keyring_secret: "<YOUR_SECRET>" # Required, change this
p2p:
enabled: true
bootstrap_peers:
- '/ip4/34.63.13.57/tcp/9171/p2p/12D3KooWMYhYNBo4zAi9j7TpyGQJBSvbwSSNkgsMrLs6vHUnFUzY'
listen_addr: "/ip4/0.0.0.0/tcp/9171"
enable_auto_reconnect: true
store:
path: "./.defra"
shinzo:
hub_base_url: rpc.devnet.shinzo.network:26657
minimum_attestations: 1
logger:
development: false
level: "error"
host:
lens_registry_path: "./.defra/lens"
health_server_port: 8080
The full production config is generated automatically by host-prod-setup.sh. See below.
Write the Nginx Config
Create ~/nginx.conf:
events { worker_connections 1024; }
http {
map $http_origin $cors_origin {
default "";
"https://explorer.shinzo.network" $http_origin;
}
server {
listen 8080;
server_name _;
add_header 'Access-Control-Allow-Origin' $cors_origin always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Accept, Origin' always;
add_header 'Access-Control-Max-Age' 3600 always;
add_header 'Vary' 'Origin' always;
location / {
if ($request_method = OPTIONS) { return 204; }
proxy_pass http://shinzo-host:9181;
proxy_set_header Host $host;
}
location = /metrics {
if ($request_method = OPTIONS) { return 204; }
proxy_pass http://shinzo-host:8080/metrics;
proxy_set_header Host $host;
}
location = /api/v0/graphql {
if ($request_method = OPTIONS) { return 204; }
proxy_pass http://shinzo-host:9181/api/v0/graphql;
proxy_set_header Host $host;
}
}
}
Write the docker-compose File
Create ~/docker-compose.yml:
networks:
shinzo-net:
driver: bridge
services:
shinzo-host:
image: ghcr.io/shinzonetwork/shinzo-host-client:standard
user: "1001:1001"
mem_limit: 16g
mem_reservation: 13g
restart: unless-stopped
container_name: shinzo-host
networks:
- shinzo-net
ports:
- "9181:9181" # DefraDB API
- "444:9182" # GraphQL Playground
- "9171:9171" # P2P networking
volumes:
- ~/data/defradb:/app/.defra/data
- ~/data/lens:/app/.lens
- ~/config.yaml:/app/config.yaml:ro
environment:
- DEFRA_URL=0.0.0.0:9181
- GOMEMLIMIT=14GiB
- LOG_LEVEL=error
- LOG_SOURCE=false
- LOG_STACKTRACE=false
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:8080/metrics"]
interval: 15s
timeout: 30s
retries: 10
start_period: 120s
nginx:
image: nginx:alpine
ports:
- "8080:8080"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- shinzo-host
networks:
- shinzo-net
restart: unless-stopped
Start the Host
docker-compose up -d
Monitoring
The health check endpoint is available at:
http://<VM_IP>:8080/metrics
The container health check polls this every 15 seconds. To check container status:
docker ps
docker logs shinzo-host
Docker Image
The multi-stage Dockerfile builds the host binary (Go 1.25) along with the Wasmtime and Wasmer WASM runtimes. The production image is based on Ubuntu 24.04 and runs as a non-root shinzo user. Pre-built images are published to:
ghcr.io/shinzonetwork/shinzo-host-client:standard
ShinzoHub Registration
To participate in the Shinzo Network, you must register your host. Registration identifies your node so it can replicate data and earn rewards. An unregistered host will not be recognized by the network. There are two ways to register:
Option A: Register with the GUI
- Start your Host.
- Add Shinzo Devnet to Metamask with the following values:
- Network name: Shinzo
- Default RPC URL: http://rpc.devnet.shinzo.network:8545
- Chain ID: 91273002
- Currency symbol: SHNZ
- Open the registration route and connect your wallet.
- On the registration page, click Register and select "Host" as your role to complete the process.
- Submit your registration, then confirm the transaction in MetaMask. You should see a successful registration notification.
Option B: Register with the CLI
You can also register your host by submitting the registration transaction directly with Foundry’s cast CLI.
cast send "0x0000000000000000000000000000000000000211" \
"register(bytes,bytes,bytes,bytes,bytes,uint8)" \
"<public_key>" \
"<public_key_signedMessage>" \
"<peer_id>" \
"<peer_id_signedMessage>" \
"<signed_message>" \
"1" \
--rpc-url "http://rpc.devnet.shinzo.network:8545" \
--from "<your_address>" \
--private-key "<your_private_key>" \
--gas-limit 100000
Replace each placeholder with your actual registration values.
Be careful with your private key. Do not commit it to source control, paste it in public channels, or store it in shell history on shared machines.
Your host is now registered and authorized to participate in the Shinzo Network.
Need Help
If you run into issues installing or running the Shinzo Host, open a GitHub issue here.
Next Steps
Your host can now receive and serve Views. Try running queries against it through the playground GUI.