Architecture
Everything GenKaKu runs in production is either a static site or a peer process. Nothing in the request path is a GenKaKu server.
Packages
| Package | Role |
|---|---|
@genkaku/protocol | Chain bindings, escrow billing, libp2p sidecar, Ollama bridge |
@genkaku/dsh-runtime | The adapter both plugins share |
@genkaku/dsh-worker-plugin | Serves local models |
@genkaku/dsh-user-plugin | Consumes network models |
@genkaku/seed | libp2p relay and peer discovery service |
@genkaku/admin | Operator console for the seed host |
The protocol core has no dependency on DeepSeek Harness. That is deliberate: another adapter should not require touching it.
On-chain
Base Sepolia, chain ID 84532:
| Contract | Address |
|---|---|
| WorkerRegistry | 0xFbE9FF497dC24bD69d13E4201418938Df7435Ff6 |
| JobEscrow | 0x8175df796A659681009BeDa4609a3cFe9d281D82 |
| MockUSDC (test only) | 0xEb33DFC0424810039337a38510ef522e9E7F9727 |
WorkerRegistry stores, per wallet: a peer ID digest, a bytes32 policy hash,
an optional locator and an active flag. JobEscrow holds per-session USDC,
verifies the worker's receipt signature, splits 99/1 and credits the worker's
claimable balance. The 1% fee is a contract constant.
Writes are testnet-only. Mainnet paths throw: canonical USDC and a multisig treasury are a separate launch, not a configuration flag.
Data plane
Workers serve these libp2p protocols:
/genkaku/open/0 session open
/genkaku/token/0 auth token
/genkaku/receipt/0 signed ledger increments
/genkaku/settle/0 co-sign a settlement
/genkaku/offers/0 offer board
/genkaku/policy/0 policy document
/genkaku/hello/0 identity, wallet proof, quote
Every handler accepts a relayed connection (runOnLimitedConnection). A
session is therefore either direct or relay-carried, and both are first-class.
libp2p encrypts the stream, so the relay forwards ciphertext and sees metadata
only.
There is no DCUtR / hole punching in this build. A peer behind symmetric NAT uses the relay or is not reachable.
Discovery
Two independent paths:
- On-chain directory —
WorkerRegistryevents give the wallet, peer ID digest and optional locator. Plugins read logs through a public RPC with afallbacklist (base-sepolia.gateway.tenderly.cofirst,sepolia.base.orglast because it capseth_getLogsat 200 blocks). - Seed relay —
https://staging.genkaku.app/seedanswersGET /peerswith the multiaddrs that are true right now, and provides a circuit relay for peers that cannot connect directly.
The seed address is baked into the protocol package but can be overridden with
GENKAKU_BOOTSTRAP_SEEDS (comma-separated multiaddrs).
Billing model
pricePerHour : 6-decimal USDC, set by the worker
unit : 1 minute (60 units per hour)
billed : ceil(elapsed / 1min) × ceil(pricePerHour / 60)
Rounding happens once per hour, never per tick, so the user never pays more than the quoted hourly price and the worker's unbilled exposure is at most one minute.
A paid session is two transactions:
openEscrow(worker, pricePerHour)— user → JobEscrow,settle(...)— JobEscrow → worker (99%) + treasury (1%), remainder refunded.
A quote of 0 is served without any escrow, which is why a free worker can run
on a machine with no ETH at all.
Operator surfaces
- Panel — the plugin's own UI in DeepSeek Harness: models, price, wallet, claim, payments, manual workers.
- Status server — a local HTTP surface on
127.0.0.1, first free port in 47821–47826, used by the panel and the client adapter. - Seed admin — a separate console on the seed VM behind Caddy at
/admin, reading seed statistics and chain logs. It holds no wallet keys and moves no money.
What is intentionally absent
- No token, no staking, no credit score token.
- No orchestration server, no database of prompts.
- No automatic content filter — the protocol has no hook that inspects a prompt before a worker sees it.
- No mainnet write path.