Skip to main content

Running a Service Node

A service node is a neuraid instance that keeps the message pool for one DePIN token and its sections. It verifies holdings on the chain, authenticates readers, signs every reply with its pool key and stores ciphertext until it expires. It cannot read message content.

info

DePIN assets exist on testnet and regtest only for now, so a service node cannot be enabled on mainnet.

Requirements

RequirementWhyNote
assetindex=1Token ownership and holder listsFirst activation needs a full -reindex, which can take hours and adds roughly 20 to 30% disk usage
pubkeyindex=1Revealed public keys for encryption and signature verificationChanging it needs -reindex-chainstate
An existing DePIN tokenThe pool rootMust start with &. A section such as &NAME/SUB is also valid. Other asset kinds are rejected at startup
An unencrypted legacy BIP44 walletThe pool key is derived from itPass -depinwallet=<file> only when more than one wallet is loaded

Configuration

# neurai.conf

# Indexes (mandatory)
assetindex=1
pubkeyindex=1

# Pool
depinmsg=1 # enable DePIN messaging
depinmsgtoken=&NEWS # pool root: token or section

# Limits
depinmsgmaxusers=20 # max recipients per message (default 20, hard cap 50)
depinmsgsize=1024 # max content bytes (default 1024, max 10240)
depinmsgexpire=168 # expiry in hours (default 168, max 720)
depinpoolsize=100 # max pool size in MB (default 100, max 1000)
depinratelimit=20 # challenges + submissions per address and minute (default 20)
depinmsgcleanupinterval=300 # expiry sweep in seconds (default 300)

# Persistence
depinpoolpersist=0 # 1 saves the pool to depinpool.dat on shutdown

# Wallet (only with several wallets loaded)
# depinwallet=wallet.dat

Check the result:

neurai-cli depingetmsginfo

The reply is a signed plain body. Decoded, it reports enabled, token, cipher, the limits, protocol, depinpoolpkey and depinpoolkeyaddress.

The pool key

The pool key is a secp256k1 key derived deterministically from the service wallet. It does two things: it opens the envelope around every submitted message, and it signs every DePIN reply.

Publish depinpoolpkey and the pool root together with your service's address. Clients that ship or pin both are protected from a hostile proxy even on first contact. Keep the wallet backed up: a new wallet means a new pool key, and every pinned client will alert its user.

Exposing the service

Holderswallets and devicesown keyssign every requestpin the pool keyneurai-rpc-proxypublic endpointwhitelists depin* RPCsper-IP limit, HTTP 429never sees plaintextneuraidservice nodemessage pool, pool keyper-address quotasigns every replyChain indexesassetindex, pubkeyindexholdings and sectionsfreezes, self-revokesrevealed public keyshttpsrpcreads

Every DePIN operation is a regular JSON-RPC method on the node's RPC port (testnet 19101, regtest 19201). Do not expose the RPC port directly. Put an RPC proxy such as neurai-rpc-proxy in front of it, and whitelist only the public DePIN methods:

WhitelistNever whitelist
depingetmsginfo, depinpoolstats, depinmcpstatusdepinsendmsg, depingetmsg
depinchallenge, depinreceivemsg, depinlistsectionsdepinsignrequest, depinsignchallenge, depindecrypt
depinsubmitmsg, depinclearmsg, depingetancestorrecipientsdepinpoolpkey and any wallet RPC
checkdepinvalidity, listdepinholders, listdepinaddresses, getpubkey, getassetdata

The proxy applies per-IP limits on depin* calls (default 60 per minute, with a temporary block on excess) and answers HTTP 429 with Retry-After. The node applies its own per-address quota, so a flood from one IP cannot consume another holder's allowance.

Operating the pool

TaskCommand
Status and limitsneurai-cli depingetmsginfo
Aggregate countersneurai-cli depinpoolstats
Purge expired messages or the whole poolneurai-cli depinclearmsg with an admin challenge
Send from the node's own walletneurai-cli depinsendmsg "&NEWS/GENERAL" "text" "Nsender..."
Read with the node's own walletneurai-cli depingetmsg

Persistence

With depinpoolpersist=1 the pool is written to depinpool.dat on shutdown and loaded at startup. Expired messages are dropped during load and the file is compacted when needed. Without it, a restart empties the pool. Clients must treat the pool as transient either way.

Sizing

The total payload cap per message is depinmsgsize × depinmsgmaxusers. A leaf section can hit the recipient limit before the root does, because access is inherited and root holders are recipients of every section. Size the limits for the largest branch you serve.

Optional AI responder (MCP)

The node can run a background worker that answers messages through an MCP-compatible chat endpoint:

depinmcp=1
depinmcpaddress=Nbot... # address whose messages the worker decrypts and answers
depinmcpurl=http://localhost:1234 # MCP server (default)
depinmcpendpoint=/v1/chat/completions
depinmcpkey=/ai # command prefix that triggers a reply
depinmcpinterval=30 # poll interval in seconds
depinmcpmaxtokens=500
depinmcptemperature=0.7
depinmcpconcurrency=2 # parallel AI requests
depinmcpcontext=6 # history entries kept per sender, 0 disables
depinmcpratelimit=0 # per-address limit, 0 disables
depinmcpglobalratelimit=0
depinmcpfragsize=1500 # characters per response fragment
depinmcpmaxfragments=5

The worker polls the pool, decrypts messages addressed to depinmcpaddress, forwards the ones that start with depinmcpkey to the MCP server and posts the answers back into the pool as regular signed and encrypted messages. depinmcpstatus reports its state. See AI integration for the application side.

Troubleshooting

SymptomCauseFix
Invalid -depinmsgtoken at startupThe token is not a DePIN asset or does not existUse a name starting with & that is already issued on this network
Node refuses to start with index errorsassetindex or pubkeyindex was changedRun -reindex or -reindex-chainstate as indicated
A holder cannot authenticate or receiveIts address has never spent, so its public key is not revealedSpend once from the address
truncated: true in recipient discoveryThe active holder set exceeds depinmsgmaxusersRaise the limit (up to 50) or split the token into sections
Clients alert about a changed pool keyThe service wallet changedRestore the original wallet, or publish the new key and root out of band