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.
DePIN assets exist on testnet and regtest only for now, so a service node cannot be enabled on mainnet.
Requirements
| Requirement | Why | Note |
|---|---|---|
assetindex=1 | Token ownership and holder lists | First activation needs a full -reindex, which can take hours and adds roughly 20 to 30% disk usage |
pubkeyindex=1 | Revealed public keys for encryption and signature verification | Changing it needs -reindex-chainstate |
| An existing DePIN token | The pool root | Must start with &. A section such as &NAME/SUB is also valid. Other asset kinds are rejected at startup |
| An unencrypted legacy BIP44 wallet | The pool key is derived from it | Pass -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
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:
| Whitelist | Never whitelist |
|---|---|
depingetmsginfo, depinpoolstats, depinmcpstatus | depinsendmsg, depingetmsg |
depinchallenge, depinreceivemsg, depinlistsections | depinsignrequest, depinsignchallenge, depindecrypt |
depinsubmitmsg, depinclearmsg, depingetancestorrecipients | depinpoolpkey 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
| Task | Command |
|---|---|
| Status and limits | neurai-cli depingetmsginfo |
| Aggregate counters | neurai-cli depinpoolstats |
| Purge expired messages or the whole pool | neurai-cli depinclearmsg with an admin challenge |
| Send from the node's own wallet | neurai-cli depinsendmsg "&NEWS/GENERAL" "text" "Nsender..." |
| Read with the node's own wallet | neurai-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
| Symptom | Cause | Fix |
|---|---|---|
Invalid -depinmsgtoken at startup | The token is not a DePIN asset or does not exist | Use a name starting with & that is already issued on this network |
| Node refuses to start with index errors | assetindex or pubkeyindex was changed | Run -reindex or -reindex-chainstate as indicated |
| A holder cannot authenticate or receive | Its address has never spent, so its public key is not revealed | Spend once from the address |
truncated: true in recipient discovery | The active holder set exceeds depinmsgmaxusers | Raise the limit (up to 50) or split the token into sections |
| Clients alert about a changed pool key | The service wallet changed | Restore the original wallet, or publish the new key and root out of band |