zkProofer Node - NaaS Provider Integration Guide
Instructions for Node-as-a-Service (NaaS) providers integrating Humanity Verification Nodes into their platform.
The node Plug-in is open source here
Step 1 — Prerequisites
The owner's wallet address (License NFT holder)
Native $H tokens for gas funding
Hardware requirements
Container-Level Resource Limits
CPU
0.5 vCPU (or shared/burstable)
RAM
256 MB
Storage
500 MB
Network
10 Mbps
These limits apply to each container running a zk proofer node.
Minimum Machine Specs (Self-Host)
CPU
1 vCPU
RAM
512 MB
Storage
5 GB
Network
10 Mbps
OS
Linux (Ubuntu 22.04+), macOS, Windows (WSL2)
Runtime
Docker 24+
Arch
x86_64 (amd64) or ARM64
Step 2 — Pull the Image
Step 3 — Configure & Start the Node
Environment variables
OWNERS_ALLOWLIST
Yes
The owner's wallet address (License NFT holder)
ETH_PRIVATE_KEY
No
Burner wallet private key (hex, no 0x prefix). If omitted, auto-generated on first launch.
LOG_LEVEL
No
info (default) or debug
Volume
/app/cache
Stores burner wallet data. Must be persisted — losing this volume means losing the burner wallet and requiring re-delegation.
Single node — docker run
Multiple nodes — Docker Compose
Step 4 — Retrieve the Burner Wallet Address
On first launch the container generates a burner wallet and writes it to /app/cache/flohive-cache.json:
Read the address from the cache file:
Or read it directly from the startup logs — the node prints it on every start:
[WARN] no delegations, skipping heartbeat is expected at this stage — the node is running but nothing is delegated yet.
If ETH_PRIVATE_KEY is set, the container skips key generation and uses that key instead. Useful when redeploying a node that already has an active delegation.
Step 5 — Fund the Burner Wallet
Send native $H tokens to the burner wallet address. The node uses this balance to pay gas for on-chain verification proofs.
Minimum recommended balance: ~0.1 $H (roughly 1 week of operations)
Estimated $H per node per year: ~5 $H/year
Key Rules
One container = one License owner. Each node instance maps to one owner wallet address. One owner can delegate up to 20 License NFTs to the same node.
Heartbeat requirement. The node sends a heartbeat every hour (
heartbeatPeriodSeconds: 3600). A minimum of 22 successful heartbeats per day — out of 24 possible — is required to qualify for daily rewards. Keep containers running continuously.Gas. A node costs roughly 5 $H per year to run. Keep the burner wallet above 0.1 $H — a node without gas can't submit proofs.
Step 6 — Delegate the License NFT
The owner delegates their License NFT(s) to the burner wallet address. Rewards only start accruing once delegation is active.
Delegation can be done via the Node Dashboard or programmatically via on-chain contract calls.
Contracts
DelegationHub — manages delegation between owners and nodes
Testnet:
0x1aEbB36b9A6B33E377319a7E2d928BE54d0cB68e
License NFT — ERC-721 contract for node License NFTs
Testnet:
0xF04f1062D70432d167EB9f342b98063228c6b496
Check pending delegation offers
Parameters:
to— the node's burner wallet addressoffset— pagination offset (start at 0)limit— max results (e.g. 100)
Returns DelegationOffer[], each containing:
hash(bytes32)to(address) — burner addressfrom(address) — owner addresstokenId(uint256) — License NFT IDcommissionPercentage(uint32)enabled(bool)
A valid pending offer has enabled == true and from matching the expected owner address.
Step 7 — Verify Delegation is Active
Call getIncomingDelegations on the DelegationHub to confirm a License is actively delegated to the burner address.
Parameters:
to— the node's burner wallet addressoffset— pagination offset (start at 0)limit— max results (e.g. 100)
Returns Delegation[], each containing:
hash(bytes32)to(address) — burner addresstokenId(uint256) — License NFT IDcommissionPercentage(uint32)enabled(bool)
For each entry where enabled == true, call ownerOf(tokenId) on the License NFT contract and confirm the returned address matches the expected owner.
Verify License NFT ownership
Returns the current owner address of the given License NFT.
Once delegation is confirmed, the logs should show:
Step 8 — Monitor
Use whichever monitoring stack your platform already runs. Here's what to watch for.
Container health
The node produces two layers of logs: base node logs ([INFO], [DEBUG], [WARN]) and verification plugin logs ([VerificationPlugin]). The plugin layer confirms that actual verification jobs are running — separate from the node's own startup and delegation activity.
Container exits or restarts unexpectedly
Check logs for [ERROR] entries
[INFO] Using burner wallet on startup
Node started correctly
[INFO] delegation offer accepted
Delegation confirmed, node is active
[WARN] no delegations, skipping heartbeat
No delegation yet — expected before the owner delegates
[VerificationPlugin] SUCCESS: Verification completed
Node is actively completing verification jobs
[VerificationPlugin] ERROR:
Verification job failed — check for API errors or auth issues
SKIPPED: Node version too old
Image is outdated — pull the latest version
Any [ERROR] line
Investigate — API errors, auth issues, or connectivity problems
Gas balance
Monitor the burner wallet's native $H balance on-chain. When it drops below your threshold, auto-fund from your platform treasury wallet.
Alert threshold: 0.1 $H (roughly 1 week of operations at ~5 $H/year).
Heartbeat
A healthy node produces 22+ heartbeats per day. If logs show no heartbeat activity for an extended period, check container health and network connectivity.
Support & Contact
For image access, integration issues, or production credentials, contact the Humanity Protocol team at support@humanity.org.
Last updated