Skip to content

Protocol · v0.0.1

Detection, verification, settlement.

Three separate stages. A flush is physically detected, an oracle decides whether to believe it, and only then can it be settled, in batches, on Solana.

Architecture

The pipeline

  1. 1

    Device

    ShitNode detects a flush and signs it with its ed25519 key.

  2. 2

    Ingest

    POST /api/telemetry receives the signed payload.

  3. 3

    Oracle

    Identity, signature, replay, timestamp, cooldown, rate limit.

  4. 4

    Event store

    Append-only record of every accept and reject.

  5. 5

    Batcher

    Groups 64 verified events and builds a Merkle root.

  6. 6

    Solana

    Optionally anchors the root. One tx per batch, not per flush.

  7. 7

    Consumers

    Points, leaderboards, receipts, the Degen Engine.

Telemetry

What a device sends

{
  "v": 1,
  "deviceId": "SN-PRO-00F3A1",
  "counter": 18204,
  "ts": 1793001234,
  "event": {
    "kind": "FLUSH",
    "volumeL": 4.8,
    "durationMs": 3120,
    "flowProfile": "dual-low"
  },
  "fw": "0.0.1",
  "sig": "base58-ed25519-signature"
}

Each ShitNode has an ed25519 keypair generated inside a secure element. The private key never leaves the chip. The device signs the canonical JSON of everything except sig.

counter is a monotonic sequence held in the secure element. It only goes up, so a replayed payload is useless.

Try it locally: npm run device:sim signs fake events and posts them to /api/telemetry. That endpoint runs real signature, replay, cooldown and rate-limit checks.

Oracle

Trust, but verify the shit

Device authentication

The deviceId must be registered, with a known public key.

Signed payload

An ed25519 signature over the canonical JSON (everything except sig).

Replay detection

The counter must be strictly greater than the last one accepted for that device.

Timestamp check

The event time must be within ±120 s of server time.

Cooldown

At least 30 s between flushes per device, because tanks need time to refill.

Rate limit

No more than 10 flushes per device per hour, plus per-IP limits.

Idempotency

The same payload posted twice is a no-op and returns the original verdict.

Audit log

Every accept and reject is recorded with its reason.

Settlement

Why we batch

Writing every flush to Solana would be expensive and deeply unnecessary. Verified events are grouped into batches of 64, each event becomes a Merkle leaf, and only the root is anchored. Anyone holding a receipt can later prove their flush was in a batch. In simulation mode, nothing is sent and solanaTransaction stays null.

rootflush 1flush 2flush 3flush 4

Threat model

Ways to cheat, and why they don't work

AttackMitigation
Flushing an empty toilet over and over for pointsCooldown, hourly rate limit, a plausibility model on volume and duration, and shame.
Replaying a captured payloadMonotonic counter per device. Replays are rejected with REPLAY.
Forging events without hardwareNo registered key means no valid signature. Rejected with BAD_SIG.
Clock gamesA ±120 s skew window, rejected with CLOCK_SKEW.
Extracting the device keyThe key lives in a secure element, can be revoked, and its oracle score drops.
Spamming the chainThere is no tx per event. Batches anchor a Merkle root, or anchoring is turned off entirely.