Physical devices stream signed telemetry anchored on BOT Chain every interval (blocks are ~0.74s). An autonomous Settlement Agent reads the on-chain anchors, evaluates each device's interval against its on-chain service contract, and pays or slashes the operator per interval in stablecoin, continuously and gaslessly for devices. On-chain policy, not the agent, is the authority. The guarantee now runs two layers deep: a device cannot be paid for data it did not deliver (liveness), and cannot be paid for data that is out of range (data quality), and the agent cannot stiff an honest operator. Settlement is also permissionless: anyone can run a keeper.
devices (EOAs) sponsor / relayer BOT Chain mainnet (677, ~0.74s)
+----------+ signed +---------------+ zero-gas +---------------------+
| device / |--telemetry-->| paymaster |--tx------>| TelemetryAnchor |
| devicesim| + int256 | (self-hosted | | anchorsInEpoch |
| (Go) | value + blob | MegaFuel- | | inRangeInEpoch |
+----------+ payload | shaped) | | DeviceRegistry |
+---------------+ | ServiceContract |
| SettlementVault |
+--------------+ reads anchors, drives settle | PolicyModule (auth) |
| Settlement |------------------------------------------------+-----------+
| Agent / any | settleEpoch(deviceId, epoch), verdict re-derived on-chain
| keeper (Go) | caller earns a tip from the keeper pool
+--------------+
|
v
+--------------+ wagmi/viem, explorer deep-links
| web (Next.js)| fleet grid, device detail, settlement ledger, proof panel
+--------------+
| Primitive | PulseGrid use | Status |
|---|---|---|
EOA Paymaster (pm_isSponsorable) |
gasless device telemetry | LIVE (self-hosted sponsor). A fleet anchors gaslessly, device balances flat at 0. There is no native paymaster on mainnet or testnet (probed and logged as BOUNTY_LOG B-008), so we run a MegaFuel-shaped self-hosted sponsor; that is the intended production path until BOT Chain ships a paymaster |
| Blob API (EIP-4844) | raw telemetry in blobs, KZG/hash anchor on-chain | LIVE. Devices post type-3 blob txs; blobhash(0) bound on-chain, payload recovered, keccak256 == payloadHash |
| Sub-second blocks (0.74s) | per-interval real-time settlement | LIVE. Per-epoch pay/slash settling on mainnet |
| Near-zero fees (base fee 0) | continuous micro-settlement economics | CONFIRMED. ~0.04 BOT/anchor, ~0.03 BOT/settlement at the mainnet gas floor; blob DA effectively free |
| Canonical stablecoin | settlement asset | LIVE. Mainnet settles in real bridge-backed USDT (0xaBabc7Ddc03e501d190C676BF3d92ef0e6e87a3C, 6 dp); the vault is asset-agnostic (token is a constructor arg) |
SettlementVault.settleEpoch(deviceId, epoch) is the only settlement entrypoint and its entire
caller surface is (deviceId, epoch). The verdict and amount are re-derived on-chain by the
PolicyModule pure library from device-signed facts and the stored SLA, so a malicious agent or
keeper cannot overpay, wrongly slash, pay an un-anchored or out-of-range epoch, or replay (proven by
test_Adversarial_*, part of 81 passing tests). Dual escrow: a funder-funded payEscrow pays the
operator on a good epoch; the operator-staked bond is slashed to the treasury on a bad or missing
one. Settlement keys off aggregate counts of signed anchors, never raw blob bytes.
Value-layer (data quality, not just liveness). The device signs its reading as a first-class
EIP-712 field, int256 value in milliunits (e.g. 40.55 kW is 40550), byte-identical across the
Solidity contract, the Go signer, and the browser signer. At anchor time TelemetryAnchor decides
in-range against the governing SLA's [minValue, maxValue] and keeps a separate inRangeInEpoch
count next to anchorsInEpoch. This is sound because ServiceContract.setSLA forces
activeFromEpoch > currentEpoch, so the SLA governing an in-progress epoch is frozen and the
anchor-time range equals what settlement re-derives. When an SLA has checkValue on, PolicyModule
pays only when at least minAnchors readings were both delivered and in range; otherwise it
slashes. A device that streams its full quota but out of range is slashed, proven on mainnet.
Versioned SLA. The ServiceContract SLA is append-only: slaOfAt(epoch) resolves the terms
in force when an interval was delivered, and new terms only take effect from a future epoch, so an
interval always settles at its delivered-time terms (pay/slash amounts and value bounds) and cannot be
repriced retroactively.
Permissionless keepers. settleEpoch pays an equal tip to whoever calls it, drawn from a
dedicated keeperPool that is funded separately and never skimmed from operator pay or the slash, so
PAY-to-operator and SLASH-to-treasury amounts are unchanged and the invariant is untouched. The single
Settlement Agent becomes an incentivized, permissionless keeper set: the Go settler runs as one keeper
of many (hash-partitioned device ownership, AlreadySettled treated as success), and the contract is
the safety net for any race.
The production value-layer + keeper stack is deployed and Blockscout-verified on scan.botchain.ai,
settling in real USDT. Deploy block 18822148, 600s epochs, keeper reward 0.1 USDT.
| Contract | Address |
|---|---|
| DeviceRegistry | 0x3697113dEe694BeEA5FD354384D03ec9198DE7aF |
| TelemetryAnchor | 0x6377BC3B08d81e33Fa91927D71CC7f806Fc45662 |
| ServiceContract | 0x908302Eb8810ef6E40f02dC5Dd63E62bc1cC00Eb |
| SettlementVault | 0x6380ebC2EbF72fC6deA07028e500943fb876C546 |
Proven live in real USDT under a [30, 55] kW value SLA: in-range PAY
0x6b70ff3cd3402ade72ef8701099c394fcdc7684a7484b806ced8c97ad22623a2, and a device that delivered its
full anchor quota but out of range was SLASHED
0xd3263742c27c83bec60f441199e7983e22ea077fd206ccd4cdc7003377f69c75.
Beyond the browser tab and the devicesim fleet, a real device runs agent/cmd/device: a standalone
single-device binary that holds its key in an encrypted keystore (not a shared plaintext
fleet.json), signs each reading, and streams it gaslessly. The signing lives in the importable
agent/device package, byte-identical to the on-chain typehash, so any device built on the SDK is a
first-class node. On-chain key rotation is supported via DeviceRegistry.rotateDeviceKey.
Alongside settlement, the agent maintains an explainable reputation snapshot (uptime, cadence
z-score, dropout/degraded flags) from the same on-chain anchor facts. It informs the dashboard
and future risk-priced bonding; it never feeds a settlement verdict.
For live tx hashes and the full reproduce steps, see the repository README.md.