Skip to content

Repository files navigation

Sluice: streaming x402 meter for the agent economy

Pay per second of use, settled on-chain via Casper x402, and the meter shuts the instant an agent stops consuming. No subscriptions, no pre-bought credits.

Built for the Casper Agentic Buildathon 2026.

Live demo (run it yourself): https://sluice-kff3.onrender.com/demo.html · Demo video: https://youtu.be/2j7Rlckm_0Q · Live proof: https://risingtell.github.io/sluice/ · Judge quickstart: JUDGE-QUICKSTART.md

It's live, and it's a real economy. Sluice has settled 301 real per-second payments on casper:casper-test across 5 independent autonomous agents, each with its own funded Casper wallet, paying 3 distinct providers. Every tick is a CEP-18 transfer_with_authorization signed by the agent's own key and finalized by the x402 facilitator, clickable through to testnet.cspr.live. See the /impact proof feed.

Two of our own Casper contracts are deployed: the CEP-18 X402 token every payment moves, and the SluiceRegistry (on-chain) that anchors the settlement totals on Casper, so the proof feed is verifiable against chain state.

And it is not testnet-only. Sluice streams on Casper MAINNET. The same meter, the same agent and the same x402 scheme settle real per-second payments on casper:casper, against our own mainnet CEP-18 token df101ac1...: 8 real mainnet settlements across 2 streams and 2 providers, blocks 8381075 to 8381217. Check them yourself with npm run verify:mainnet, which needs no API key and no account: it looks up every claimed settlement on a public Casper mainnet node and fails if any one of them did not execute. Mainnet is a config change, and we made it. The 301-settlement proof feed below stays on testnet, which is where the buildathon's deployed-contract criterion applies, and the two are never mixed into one number.

Sluice runs its own x402 facilitator. The public hosted facilitator builds the CEP-18 settle call with the runtime argument named value, while the reference Cep18X402 token's entry point reads amount, so settlements through it revert on-chain. Sluice runs the official @make-software/casper-x402 facilitator scheme itself (facilitator/), so the argument names agree by construction, on both networks, with no third-party dependency in the settlement path.


The problem

x402 unlocked machine-to-machine payments, but the whole wave so far is discrete: one request, one payment. That fits an API call. It does not fit the things agents actually rent continuously: a live price feed, GPU time, a streaming inference endpoint. Charging those per-request forces ugly choices: pre-bought credits (capital locked up, refunds), coarse subscriptions (pay for idle time), or after-the-fact invoicing (counterparty risk).

The solution: a streaming meter

Sluice adds the missing axis: continuous, per-second streaming settlement.

Agent (Casper ed25519 key)
  │  opens a session, then every tick signs an EIP-712 transfer_with_authorization
  ▼
Sluice Resource Server  (Express + @x402/express + @make-software/casper-x402)
  │  StreamingMeter bills elapsed-seconds × rate  →  one settlement per tick
  ▼
Casper x402 Facilitator  →  real CEP-18 transfer on casper:casper-test
  ▼
/impact public proof feed  →  every tick, with a testnet.cspr.live explorer link

The agent pays only for the seconds it actually consumes. Stop consuming and the next tick never fires; the stream halts itself. That self-closing cutoff is the "sluice gate," and it's the whole point: no trust, no escrow, no clawback. The meter is the enforcement.

Why it's different from the rest of the field

The Buildathon field is mostly discrete pay-per-request x402 kits, plus trust/escrow/reputation plumbing layered on top. Continuous per-second streaming settlement was unoccupied. Sluice isn't a marketplace and isn't an escrow. It's the metering primitive that makes renting a resource by the second a first-class on-chain operation.

It's agentic DeFi in practice: the flagship consumer is a trading agent renting a live market feed, paying per second only while it hunts a signal and cutting off the moment it's done, which is the capital-efficient, autonomous behaviour Casper's agent-economy vision is built for.

Capability map: what Sluice exercises on Casper

Sluice flow Casper / x402 capability used
Per-tick payment challenge + retry @x402/express paymentMiddleware with DynamicPrice (per-tick variable pricing)
Agent signs each tick @make-software/casper-x402 ExactCasperScheme client, EIP-712 transfer_with_authorization over CEP-18
Settlement without agent gas Self-hosted x402 facilitator (facilitator/, official @make-software/casper-x402 scheme) /verify + /settle, its sponsored feePayer pays the gas
Payment token Our own deployed CEP-18 X402 token contract (Odra), package 658bb84b...
Per-provider routing DynamicPayTo: each stream's ticks settle to that provider's own Casper account
On-chain anchoring of terms + totals Our own deployed SluiceRegistry contract (Odra), package a7cbd09c...
Trustless audit npm run verify re-derives every settlement from the Casper token ledger via cspr.cloud
Any LLM agent as the buyer sluice-mcp MCP server: an MCP-capable agent discovers, rents, and pays for streams itself
Build your own consumer @sluice/x402 SDK (sdk/): budget-guarded autonomous streaming loop in a few lines

The agents are genuinely autonomous

A Sluice consumer isn't a fixed payment loop. It's a goal-directed agent with an objective and a budget (agent/src/policy.ts). Every tick it evaluates the freshly-streamed data and decides whether the stream is still worth paying for. The moment the objective is met, the data stops being useful, or the budget would be breached, the agent closes the sluice gate itself:

  • trend-hunter (price feeds) streams until it sees a price move past its threshold (signal found, objective met), or gives up after its patience window to stop burning budget on a flat market.
  • job-runner (GPU telemetry) pays for the duration of a job but aborts the instant the GPU crosses a safety temperature, because paying for an overheating box isn't worth it.

Those decisions are recorded and surfaced live on the /impact feed, e.g. "signal: +0.45% move detected, objective met, gate closed" or "GPU 79C > 78C, aborted job, gate closed". The self-closing gate is a decision, not a timer.


Prerequisites

Node 20 or newer   (developed and tested on Node 24.16.0)

That is the whole list. No account, no API key, and no wallet is needed for anything below; npm install && npm run verify and npm test both run from a clean clone with no .env.


Verify it yourself (no trust required)

Every settlement Sluice has ever made is recorded with its real Casper transaction hash:

# top-line cumulative proof
curl -s http://localhost:4021/impact | jq '.totals'
# => { "settlements": 301, "uniqueAgents": 5, "uniqueProviders": 3, "secondsStreamed": 2398, ... }

# pull any recent settlement and open it on the block explorer
curl -s http://localhost:4021/impact | jq '.recent[0] | {txHash, explorerUrl, amount, seconds}'

Open any explorerUrl (https://testnet.cspr.live/deploy/<txHash>) and you'll see a real CEP-18 transfer on casper:casper-test, gas paid by the facilitator's sponsored feePayer, the X402 token moving from the agent's account to the payee. The live dashboard at /impact.html renders the same feed.

Don't trust our numbers, re-derive them from the chain

npm run verify

This reads every X402 token transfer straight from the Casper ledger (via cspr.cloud) and sums the payments to each provider, with zero trust in the Sluice server. It proves the feed never over-claims; the on-chain ledger is the source of truth:

ON-CHAIN (re-derived from the Casper token ledger):
  Lumen Markets (BTC) 251 settlements · 2.554535 X402
  Helios Feeds (ETH)   54 settlements · 0.320515 X402
  NimbusGPU (GPU)      41 settlements · 0.713094 X402
  TOTAL               346 settlements · 3.588144 X402

PROOF FEED claims:
  TOTAL               301 settlements · 3.205548 X402

ROW-LEVEL CHECK (each claimed settlement matched to an on-chain transfer by deploy hash):
  checked 301 rows from all 301 settlement rows in the local proof history
  all 301 matched

VERIFIED: every settlement the feed claims is backed by a real on-chain transfer.

The on-chain total keeps growing every time someone runs the live demo console, so expect it to be higher than the sample above. That is the invariant working: the chain is always at least the feed.

It checks two things, not one: the on-chain totals must be at least what the feed claims, and every published settlement row must match a real on-chain transfer by deploy hash. Totals alone would be a weak test, because a reverted deploy still returns a transaction hash, so a well-formed hash proves nothing on its own.

Tests

npm test

13 tests, named after the claim each one defends. Seven of them assert against the real committed on-chain ledger snapshot, so if the published numbers ever drift above what Casper actually shows, the suite fails instead of the over-claim shipping.

The stream terms and settlement checkpoints are also anchored on-chain in our deployed SluiceRegistry contract, so both the rules and the results live on Casper, not just our server.

A real multi-party economy. Volume comes from 5 distinct funded agent wallets streaming from a catalogue whose 3 streams each pay their own provider treasury, so payments flow between independent on-chain parties (uniqueAgents = 5, uniqueProviders = 3), not one wallet paying itself. Every tx is verifiable on cspr.live. The price streams carry a real market feed (live BTC/ETH spot from CoinGecko), so agents act on genuine moves; GPU telemetry is an honestly-labelled simulation. (Honest note: this is Casper testnet. The payments, the multi-party settlement, and the price data are all real.)


Run it

MOCK demo, zero credentials

npm install
cp .env.template .env            # MODE=mock by default
npm run server                   # http://localhost:4021  ·  dashboard at /impact.html
# in another terminal:
AGENT_TICK_MS=300 AGENT_MAX_TICKS=12 npm run agent

The streaming meter is decoupled from settlement behind a SettlementProvider interface, so MOCK mode runs the exact same streaming logic with simulated settlement: no creds, no chain. MOCK and LIVE keep separate snapshot files, so simulated events never mix into the on-chain proof data.

LIVE on Casper testnet

Fill the LIVE section of .env (funded testnet ed25519 account, deployed CEP-18 token package) and set MODE=live:

MODE=live npm run server
MODE=live CLIENT_PRIVATE_KEY_PATH=keys/agent.pem npm run agent

Sustained load for the proof feed: WORKERS=3 TICK_MS=2000 TICKS=12 bash scripts/volume.sh. Multi-agent economy run: ROUNDS=1 TICK_MS=2500 bash scripts/economy.sh.

Testnet tuning: each on-chain settle finalizes in ~5-10s (testnet block time), so hold tick cadence at 1.5s or more. MAX_TICK_SECONDS caps elapsed billing so a slow settle never over-bills.


Consume Sluice from your own agent

SDK (sdk/): the whole rent-and-pay loop in a few lines, with a budget guard and your own decide() policy as the agency. Runnable example:

npm run server                       # terminal 1 (mock, zero creds)
npx tsx examples/rent-a-stream.ts    # terminal 2: an SDK agent rents btc-usd and self-closes

MCP server (mcp/): exposes the meter to any MCP-capable AI agent (Claude included) as tools: list_streams, open_session, pay_tick, close_session, get_proof. The LLM is the buyer; in live mode each pay_tick returns the real on-chain tx hash.

claude mcp add sluice -- npx tsx mcp/server.ts

HTTP API

Method & path What
GET /streams catalogue of metered streams (BTC/USD, ETH/USD, GPU telemetry) + per-second rate
POST /sessions open a metered session for a stream
POST /tick?session=<id> bill elapsed seconds and settle one payment (the per-second tick)
POST /sessions/:id/close close the gate
GET /impact cumulative totals + recent settlements (JSON proof feed)
GET /health liveness

Layout

Path What
server/src/meter.ts StreamingMeter: the core primitive (elapsed-seconds tick billing + cutoff)
server/src/settlement.ts SettlementProvider interface + MockSettlementProvider
server/src/casper-live.ts LIVE Casper x402 wiring (paymentMiddleware + ExactCasperScheme + HTTPFacilitatorClient + DynamicPrice + onAfterSettle)
server/src/store.ts durable proof-feed store (periodic JSON snapshot)
server/src/index.ts Express resource server + session/tick routes + /impact
server/public/impact.html live proof-feed dashboard
agent/src/index.ts autonomous consuming agent (objective + budget, decides each tick)
agent/src/policy.ts agent policies: trend-hunter, job-runner (the agency)
sdk/ @sluice/x402 client SDK (budget-guarded autonomous streaming loop)
mcp/ sluice-mcp MCP server (any MCP-capable LLM agent as the buyer)

Both ship in this repo and are consumed from the clone (npx tsx examples/rent-a-stream.ts, npx tsx mcp/server.ts). They are not on npm yet, so do not try to install them from there.

Onboard your own agent (no need to ask us)

An agent that cannot get the payment token cannot pay, so Sluice runs a faucet. Ask it for tokens with your own Casper account hash and it sends them on-chain:

curl -s https://sluice-kff3.onrender.com/faucet          # what it grants, and how much is left today
curl -s -X POST https://sluice-kff3.onrender.com/faucet   -H 'Content-Type: application/json'   -d '{"address":"00<your 64 hex account hash>"}'

You get a real transaction hash back, and once it finalizes your agent can open a session and pay ticks like any other. One grant per address, with per-client and daily caps, because it spends real gas. | server/src/demo.ts, server/public/demo.html | judge-facing live demo console | | contracts/sluice_registry | SluiceRegistry Odra contract (stream terms + checkpoint anchoring) | | scripts/verify-onchain.ts | trustless verifier (re-derives totals from the Casper ledger) | | scripts/volume.sh, scripts/economy.sh | sustained-load + multi-agent economy runners | | shared/types.ts | wire types |

Tech

@make-software/casper-x402 (Casper exact scheme) · @x402/express + @x402/core + @x402/fetch · casper-js-sdk · Odra (both deployed contracts) · a self-hosted x402 facilitator built on the official @make-software/casper-x402 scheme (sponsored gas via its own feePayer). Node + tsx, no build step.

MIT.

About

Sluice — streaming x402 meter for the agent economy. Pay per second, settled on-chain via Casper x402; the meter shuts the instant an agent stops consuming.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages