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

Resource
Single Node / Multi-Node (up to 20 licenses)

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)

Resource
Single Node / Multi-Node (up to 20 licenses)

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

Variable
Required
Description

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

Container path
Purpose

/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 address

  • offset — pagination offset (start at 0)

  • limit — max results (e.g. 100)

Returns DelegationOffer[], each containing:

  • hash (bytes32)

  • to (address) — burner address

  • from (address) — owner address

  • tokenId (uint256) — License NFT ID

  • commissionPercentage (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 address

  • offset — pagination offset (start at 0)

  • limit — max results (e.g. 100)

Returns Delegation[], each containing:

  • hash (bytes32)

  • to (address) — burner address

  • tokenId (uint256) — License NFT ID

  • commissionPercentage (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.

Signal
What it means

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 [email protected]envelope.

Last updated