with one click
with one click
Write and run fast direct mode tests for GenLayer intelligent contracts.
Use the GenLayer CLI to deploy, interact with, and debug intelligent contracts.
Validate GenLayer intelligent contracts with the GenVM linter.
Write and run integration tests against a GenLayer environment.
Write production-quality GenLayer intelligent contracts. Always pins concrete GenVM runner version hashes and never uses local-only test/latest runner aliases. Covers equivalence principles, storage rules, LLM resilience, and cross-contract interaction.
Manage GenLayer validators across testnets using the genlayer CLI. Join, fund, set identity, list, and organize validators per network and owner.
| name | genlayernode |
| description | Interactive wizard to set up a GenLayer validator node on Linux. |
| allowed-tools | ["Bash","Read","Write","Edit","WebFetch","AskUserQuestion"] |
Interactive wizard to set up a GenLayer validator node from scratch on a Linux server.
CRITICAL REQUIREMENT: At the very beginning of ANY setup or upgrade operation, you MUST display a complete overview of ALL steps that will be performed. This is NON-NEGOTIABLE.
## GenLayer Validator Node Setup
I'll guide you through the complete validator node installation. Here's what we'll do:
**Step 1: Determine Server Location**
- Identify where the validator will run (local/GCP/AWS/SSH)
- Configure access method for commands
**Step 2: Verify Prerequisites**
- Check system architecture (must be x86_64)
- Verify RAM, CPU, and disk space
- Check Node.js, Docker, Python installations
**Step 3: New or Existing Validator**
- New: Run staking wizard (requires 42,000+ GEN)
- Existing: Provide validator wallet address
**Step 4: Download & Extract Node Software**
- Download GenLayer node tarball from official storage
- Extract to /opt/genlayer-node/${VERSION}/
- Set up directory structure and symlinks
- Run GenVM setup to download dependencies
**Step 5: Configure Environment (.env)**
- Create .env from example template
- Configure RPC and WebSocket URLs
- Set LLM provider (you'll add API key manually)
**Step 6: Configure Node (config.yaml)**
- Set validator wallet address
- Configure operator address
- Set network endpoints and ports
**Step 7: Set Up Operator Key**
- Import keystore from staking wizard, OR
- Copy from previous installation, OR
- Generate new operator key
**Step 8: Start WebDriver Container**
- Launch WebDriver via Docker Compose
- Wait for health check to pass
**Step 9: Run Doctor Check**
- Verify GenVM binaries are installed
- Verify WebDriver connectivity
**Step 10: Choose Deployment Method**
- Systemd service (recommended)
- Docker Compose
- Manual (screen/tmux)
**Step 11: Verify Node Running**
- Check health endpoint
- Verify sync status
**Estimated time: 20-45 minutes**
Ready to begin?
Always show a brief description of what will happen:
## Step 4: Download & Extract Node Software
This step will:
1. Download the GenLayer node v0.4.4 tarball (~XX MB)
2. Create directory /opt/genlayer-node/v0.4.4/
3. Extract binary, configs, and GenVM files
4. Set up symlinks for easy access
5. Run GenVM setup to download dependencies (~2 min)
Proceeding...
NEVER skip showing what a step will do before executing it.
This skill guides you through the complete validator node installation process. When you invoke this skill, it will:
Total time estimate: 20-45 minutes depending on your experience level and setup method.
If you are UPDATING an existing node, read this first:
NEVER stop your old node before preparing the new version!
Traditional update process (WRONG - causes 3-4 min downtime):
Stop node -> Download -> Extract -> GenVM setup (2 min) -> Start
Correct procedure (10-15 sec downtime):
Download -> Extract -> GenVM setup WHILE OLD NODE RUNS
THEN: Stop old -> Switch symlinks -> Start new
Impact of wrong procedure:
See update-procedure.md for detailed zero-downtime update steps.
For fresh installations, see install-procedure.md for the step-by-step installation guide.
For patch versions (v0.4.x), the database MUST be shared, not copied:
Correct structure:
/opt/genlayer-node/v0.4/data/node/genlayer.db <- Shared DB
/opt/genlayer-node/v0.4.3/data/node/genlayer.db -> symlink to shared
/opt/genlayer-node/v0.4.4/data/node/genlayer.db -> symlink to shared
Two LLM strategies are available:
OPENROUTERKEY)# 1. Apply release LLM config (has all backends)
cp third_party/genvm/config/genvm-modules-llm-release.yaml \
third_party/genvm/config/genvm-module-llm.yaml
# 2. For greybox strategy, switch lua script:
sed -i 's/genvm-llm-default\.lua/genvm-llm-greybox.lua/' \
third_party/genvm/config/genvm-module-llm.yaml
# 3. Enable your provider (replace <provider> with name from mapping):
# Provider mapping (env var -> config name):
# HEURISTKEY -> heurist
# COMPUT3KEY -> comput3
# IOINTELLIGENCEKEY -> ionet
# LIBERTAI_API_KEY -> libertai
# ANTHROPICKEY -> anthropic
# GEMINIKEY -> google
# OPENROUTERKEY -> openrouter
# MORPHEUS_API_KEY -> morpheus
sed -i '/^ <provider>:/,/^ [a-z]/ s/enabled: false/enabled: true/' \
third_party/genvm/config/genvm-module-llm.yaml
Symptom if not enabled: Node fails to start with "module_failed_to_start" error.
To update the Lua script or LLM YAML without a full redeploy, see
common-procedures.md -> "Update Greybox Config on Running Node".
Key points:
curl -X POST http://127.0.0.1:<port>/module/stop then /module/startBefore starting, ensure your setup meets these requirements:
flowchart TD
A[1. Environment Setup] --> B[2. Wallet & Staking]
B --> C[3. Software Download]
C --> D[4. Configuration]
D --> E[5. Operator Key Setup]
E --> F[6. LLM Configuration]
F --> G[7. Start Services]
G --> H[8. Verification & Cleanup]
When specifying a version:
v0.4.4latest to automatically download the most recent releaseThe skill automatically handles:
/opt/genlayer-node/v0.4.4/)Guide validators through complete GenLayer node installation including:
/opt/genlayer-node/
├── v0.4.4/ # Version-specific directory
│ ├── bin/genlayernode
│ ├── third_party/genvm/
│ ├── docker-compose.yaml
│ ├── .env
│ ├── data/node/
│ │ ├── genlayer.db
│ │ ├── keystore/
│ │ ├── logs/
│ │ └── merkle/
│ └── configs/node/config.yaml
├── bin -> v0.4.4/bin # Symlinks for easy access
├── third_party -> v0.4.4/third_party
├── data -> v0.4.4/data
├── configs -> v0.4.4/configs
├── docker-compose.yaml -> v0.4.4/docker-compose.yaml
├── .env -> v0.4.4/.env
├── alloy-config.river -> v0.4.4/alloy-config.river # Symlink (ships with tarball)
└── genvm-module-web-docker.yaml -> v0.4.4/genvm-module-web-docker.yaml
| Setting | Default Value |
|---|---|
| RPC URL | No default - user must provide |
| WebSocket | No default - user must provide |
| Consensus Address | 0xe66B434bc83805f380509642429eC8e43AE9874a |
| Genesis Block | 17326 |
| Install Path | /opt/genlayer-node |
| RPC Port | 9151 |
| Ops Port | 9153 |
| Admin Port | 9155 |
| Metrics Interval | 15s |
| Provider | Environment Variable |
|---|---|
| Heurist | HEURISTKEY |
| Comput3 | COMPUT3KEY |
| io.net | IOINTELLIGENCEKEY |
| LibertAI | LIBERTAI_API_KEY |
| Anthropic | ANTHROPICKEY |
GEMINIKEY | |
| xAI (Grok) | XAIKEY |
| Atoma | ATOMAKEY |
| OpenRouter | OPENROUTERKEY |
| Morpheus | MORPHEUS_API_KEY |
The skill guides through these steps interactively:
CRITICAL FIRST STEP: Before any installation begins, determine where the validator will run and how to access it.
Question: "Where will you run the validator node?"
Options:
Impact: This choice affects ALL subsequent steps:
Verify system meets requirements before starting:
# Check architecture (must be x86_64)
uname -m
# Check Node.js (v18+ required)
node --version
# Check Docker and Docker Compose
docker --version
docker compose version
# Check Python 3 with pip and venv
python3 --version
pip3 --version
python3 -m venv --help
Minimum requirements:
Note: The staking wizard runs on your local machine (not the server), since it manages wallet keys.
New: Run staking wizard (requires 42,000+ GEN)
npm install -g genlayer
genlayer staking wizard --network testnet-asimov
The wizard is fully interactive (requires TTY) and guides you through:
Three addresses are produced:
| Address | Purpose |
|---|---|
| Owner | Cold wallet that controls withdrawals (stays on local machine) |
| Operator | Hot wallet that signs blocks (goes on the server via keystore) |
| Validator Wallet | Smart contract deployed on-chain (used in config.yaml) |
After the wizard, save:
config.yamlconfig.yamlAfter the wizard, fund the operator: The operator account starts with 0 GEN and needs funds for gas fees to sign validation transactions.
# Check operator balance
genlayer account show --account "Operator Name"
# Send GEN from owner to operator (recommended: 10 GEN)
genlayer account send 0xOPERATOR_ADDRESS 10gen --account "Owner Name" --network testnet-asimov
See staking-wizard-procedure.md for the complete step-by-step wizard walkthrough, alternative CLI commands, and troubleshooting.
Existing: Skip to download (must have validator wallet address and operator keystore)
Note: For remote servers, download to the remote server, not your local machine.
List available versions:
curl -s "https://storage.googleapis.com/storage/v1/b/gh-af/o?prefix=genlayer-node/bin/amd64" | \
grep -o '"name": *"[^"]*"' | sed -n 's/.*\/\(v[^/]*\)\/.*/\1/p' | sort -ru | head -5
Download and extract (replace ${VERSION} with actual version, e.g., v0.4.4):
# Download to /tmp
wget https://storage.googleapis.com/gh-af/genlayer-node/bin/amd64/${VERSION}/genlayer-node-linux-amd64-${VERSION}.tar.gz \
-O /tmp/genlayer-node-${VERSION}.tar.gz
# Create versioned directory and extract
sudo mkdir -p /opt/genlayer-node/${VERSION}
sudo tar -xzvf /tmp/genlayer-node-${VERSION}.tar.gz \
-C /opt/genlayer-node/${VERSION} --strip-components=1
# Create data and config directories inside version folder
sudo mkdir -p /opt/genlayer-node/${VERSION}/{data/node,configs/node}
sudo chown -R $USER:$USER /opt/genlayer-node
# Setup symlinks for easy access
ln -sfn /opt/genlayer-node/${VERSION}/bin /opt/genlayer-node/bin
ln -sfn /opt/genlayer-node/${VERSION}/third_party /opt/genlayer-node/third_party
ln -sfn /opt/genlayer-node/${VERSION}/data /opt/genlayer-node/data
ln -sfn /opt/genlayer-node/${VERSION}/configs /opt/genlayer-node/configs
ln -sfn /opt/genlayer-node/${VERSION}/docker-compose.yaml /opt/genlayer-node/docker-compose.yaml
ln -sfn /opt/genlayer-node/${VERSION}/.env /opt/genlayer-node/.env
ln -sfn /opt/genlayer-node/${VERSION}/alloy-config.river /opt/genlayer-node/alloy-config.river
ln -sfn /opt/genlayer-node/${VERSION}/genvm-module-web-docker.yaml /opt/genlayer-node/genvm-module-web-docker.yaml
Run GenVM setup:
python3 /opt/genlayer-node/third_party/genvm/bin/setup.py
This downloads GenVM dependencies (genvm binary and genvm-modules).
IMPORTANT: Always start from the .env.example included in the downloaded artifact. This ensures all required variables are present.
First ask if user wants to copy existing .env or create from example:
.env.example, then customizeCreate .env from example:
cp /opt/genlayer-node/${VERSION}/.env.example /opt/genlayer-node/${VERSION}/.env
Key values to configure:
Rollup URLs - Add these lines (not in .env.example by default):
GENLAYERNODE_ROLLUP_GENLAYERCHAINRPCURL=<RPC_URL_FROM_USER>
GENLAYERNODE_ROLLUP_GENLAYERCHAINWEBSOCKETURL=<WSS_URL_FROM_USER>
LLM API Key - Set ONE of these (leave others empty):
HEURISTKEY=ANTHROPICKEY=GEMINIKEY=Node Password - Update NODE_PASSWORD= with a secure password
After creating .env, instruct user to:
gcloud compute ssh USER@VM --zone=ZONEnano /opt/genlayer-node/.envNODE_PASSWORDIMPORTANT: Always start from the example config included in the downloaded artifact (configs/node/config.yaml.example). This ensures the config format is compatible with the installed version.
First ask if user wants to copy existing config or use example:
After copying the base config, go through each configuration GROUP and ask whether to modify or keep defaults:
Group 1: Node Identity
Group 2: RPC Endpoints
Group 3: Ops Endpoints
Group 4: Admin Endpoints
Group 5: Metrics Configuration
Note: Rollup URLs (RPC, WebSocket) are configured in .env. Contract addresses and other settings remain in config.yaml with defaults.
First ask how user wants to provide the operator key:
Source options:
Upload flow:
Ask which type of file user has (keystore.json or keystore directory)
Create the keystore directory first (required before upload):
mkdir -p /opt/genlayer-node/${VERSION}/data/node/keystore
Provide upload instructions based on server location (from Step 0):
For local setup:
# Copy keystore.json
cp ./keystore.json /opt/genlayer-node/${VERSION}/data/node/keystore.json
# Or copy keystore directory
cp -r ./keystore/* /opt/genlayer-node/${VERSION}/data/node/keystore/
For remote SSH server:
# Upload keystore.json
scp ./keystore.json username@hostname:/opt/genlayer-node/${VERSION}/data/node/keystore.json
# Or upload keystore directory
scp -r ./keystore/* username@hostname:/opt/genlayer-node/${VERSION}/data/node/keystore/
For GCP VM:
# Upload keystore.json
gcloud compute scp ./keystore.json instance-name:/opt/genlayer-node/${VERSION}/data/node/keystore.json \
--project=project-id --zone=zone
# Or upload keystore directory
gcloud compute scp --recurse ./keystore/* instance-name:/opt/genlayer-node/${VERSION}/data/node/keystore/ \
--project=project-id --zone=zone
For AWS EC2:
# Upload keystore.json (assuming SSH access)
scp -i ~/.ssh/your-key.pem ./keystore.json ec2-user@instance-ip:/opt/genlayer-node/${VERSION}/data/node/keystore.json
# Or upload keystore directory
scp -i ~/.ssh/your-key.pem -r ./keystore/* ec2-user@instance-ip:/opt/genlayer-node/${VERSION}/data/node/keystore/
Wait for user confirmation
Verify upload:
ls -la /opt/genlayer-node/${VERSION}/data/node/keystore/
For keystore.json: Run import command (user provides passphrase manually on VM):
cd /opt/genlayer-node && source .env && ./bin/genlayernode account import \
--password "$NODE_PASSWORD" \
--path /opt/genlayer-node/${VERSION}/data/node/keystore.json
Note: User will be prompted for the export passphrase interactively
For keystore directory: Already in correct location, just verify contents show UTC--* file
Note: Always use the version-specific path (e.g., /opt/genlayer-node/v0.4.4/data/node/keystore/), not the symlink path.
WebDriver is required for web-based contract operations. Start it before running doctor check:
cd /opt/genlayer-node && docker compose up -d
Wait for WebDriver to be healthy:
until docker inspect --format='{{.State.Health.Status}}' genlayer-node-webdriver | grep -q 'healthy'; do
echo "Waiting for WebDriver to be healthy..."
sleep 2
done
echo "WebDriver is healthy!"
Verify WebDriver is running:
docker ps | grep webdriver
curl -s http://localhost:4444/status | jq '.value.ready'
Run the doctor command to verify all configuration is correct:
cd /opt/genlayer-node && source .env && ./bin/genlayernode doctor check
Expected output on success:
GenLayer Node Doctor
===================
✓ GenVM Binaries: Found at /opt/genlayer-node/third_party/genvm/bin
✓ WebDriver: Connected to http://localhost:4444 (ready: true)
✓ All checks passed!
If checks fail:
python3 /opt/genlayer-node/third_party/genvm/bin/setup.pydocker logs genlayer-node-webdriverAsk user which deployment method they prefer:
/etc/systemd/system/genlayer-node.service:[Unit]
Description=GenLayer Node
After=network.target docker.service
Requires=docker.service
[Service]
Type=simple
User=root
WorkingDirectory=/opt/genlayer-node
EnvironmentFile=/opt/genlayer-node/.env
ExecStart=/opt/genlayer-node/bin/genlayernode run --password ${NODE_PASSWORD}
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable genlayer-node
sudo systemctl start genlayer-node
sudo systemctl status genlayer-node
journalctl -u genlayer-node -f
cd /opt/genlayer-node && source .env && docker compose --profile node up -d
screen -S genlayer
cd /opt/genlayer-node && source .env && ./bin/genlayernode run --password "$NODE_PASSWORD"
# Detach: Ctrl+A, D
# Reattach: screen -r genlayer
After starting the node, verify it's running and syncing:
Health check:
curl -s http://localhost:9153/health | jq
Expected response:
{
"status": "up",
"checks": { ... }
}
Sync status:
curl -s http://localhost:9153/metrics | grep genlayer_node_synced
Expected output (1 = synced, 0 = syncing):
genlayer_node_synced{node="0x..."} 1
Check blocks behind:
curl -s http://localhost:9153/metrics | grep genlayer_node_blocks_behind
View logs (systemd):
journalctl -u genlayer-node -f --no-hostname
View logs (Docker):
docker logs -f genlayer-node
#testnet-asimov)monitoring-procedure.md for complete setup/etc/systemd/system/genlayer-node.serviceThis skill is defined by canonical YAML files:
Invoke this skill when:
The skill will guide through each step interactively, verifying prerequisites and configuration at each stage.
Basic invocation:
I want to set up a validator node
With specific version:
Install validator node version v0.4.4
With latest version:
Install validator node using the latest version
or simply:
Install validator node latest
When you use the word "latest", the skill will automatically fetch and install the most recent version from the official storage.
| Step | Description | Key Actions |
|---|---|---|
| 0 | Determine Server Location | Local vs Remote, SSH vs GCP vs AWS |
| 1 | Check Prerequisites | Architecture, Node.js, Docker, Python |
| 2 | New Validator or Existing? | Staking wizard or skip |
| 3 | Download & Setup | Download tarball, extract, create directories, symlinks, run GenVM setup |
| 4 | Environment (.env) | RPC URL, WebSocket URL, LLM key placeholder, password placeholder |
| 5 | Node Config (config.yaml) | Validator address, operator address, ports |
| 6 | Operator Key | Upload keystore (method depends on Step 0) or generate new |
| 7 | Start WebDriver | docker compose up -d, wait for healthy |
| 8 | Run Doctor Check | Verify all configuration |
| 9 | Deployment Method | Systemd (recommended), Docker, or manual |
| 10 | Verify Node Running | Health check, sync status |
| 11 | Monitoring (Optional) | Enable telemetry push |
IMPORTANT: When collecting user inputs, follow these rules:
Use AskUserQuestion with these options (tool requires minimum 2 options):
IMPORTANT: The "Other" text field in AskUserQuestion does not work reliably. When user selects "I'll enter my URL", follow up with a plain text question asking them to type the URL directly.
Example flow:
Step 1: AskUserQuestion
Question: "Do you have the GenLayer Chain RPC URL?"
Options:
- "Skip for now" (will need to configure manually later)
- "I'll enter my URL"
Step 2: If user selected "I'll enter my URL", ask:
"Please enter the RPC URL:"
[User types URL directly in chat]
These values are configured in config.yaml during the Node Identity group:
These values must NEVER be collected by Claude. Generate .env with placeholders, then ask user to update manually on the VM:
YOUR_API_KEY_HEREYOUR_PASSWORD_HEREAfter generating .env, instruct user to:
CRITICAL: When displaying any output that may contain secret values, they MUST be masked.
HEURISTKEY, COMPUT3KEY, IOINTELLIGENCEKEY, and other provider keysNODE_PASSWORD, export passphrasesNEVER execute these types of commands that expose secrets:
# FORBIDDEN - DO NOT USE
grep '<LLM_KEY>' /opt/genlayer-node/.env
cat /opt/genlayer-node/.env | grep KEY
gcloud compute ssh ... --command="grep '<LLM_KEY>' /opt/genlayer-node/.env"
ssh username@host "cat /opt/genlayer-node/.env"
Why this is forbidden:
Instead, instruct the user to check values themselves:
# CORRECT - Instruct user to run this on their VM
"To verify your API key is set, SSH to your VM and run:
grep '<YOUR_LLM_KEY>' /opt/genlayer-node/.env
This will show the key value on your secure terminal."
When displaying .env file contents:
HEURISTKEY=abc12345********...xyz9 instead of full keyWhen displaying command output:
export HEURISTKEY=abc12345********...xyz9When verifying configuration:
HEURISTKEY: Set (abc12345********...xyz9)In logs and error messages:
***MASKED***Remote command execution:
--command flag with SSH/gcloud to read secretsReading .env file:
# Before displaying, mask secrets using sed
cat /opt/genlayer-node/.env | sed -E 's/(KEY|PASSWORD|TOKEN)=([^[:space:]]{12}).*/\1=\2********.../'
Verifying environment variables:
# Show only that key is set, not the value
env | grep -E 'KEY|PASSWORD|TOKEN' | sed -E 's/=.*/=***MASKED***/'
Creating systemd service:
EnvironmentFile directive to load from .envExecStart=/opt/genlayer-node/bin/genlayernode run --password "${NODE_PASSWORD}"If user needs the actual secret value:
cat /opt/genlayer-node/.env | grep <YOUR_LLM_KEY>"These can be presented as multiple choice:
This skill includes focused step-by-step procedure guides:
| Document | Purpose |
|---|---|
install-procedure.md | Complete installation from scratch |
update-procedure.md | Zero-downtime update procedure |
staking-wizard-procedure.md | Running the staking wizard to create validator wallet |
monitoring-procedure.md | Enable centralized monitoring with Grafana/Alloy |
common-procedures.md | Shared commands used by install and update |
pre-update-checklist.md | Checklist before starting any update |
For the latest official setup guide, see: https://docs.genlayer.com/validators/setup-guide