About WorkGrid
WorkGrid is a routing layer for verifiable AI work, built for Robinhood Chain, a permissionless, Ethereum-compatible Layer-2. Structured AI jobs are routed to distributed worker nodes, executed offchain with open-weight models, and every completed job produces a hash-linked work receipt designed to anchor onchain.
Execution happens where the compute is: worker hardware. Verification happens where the trust is: Robinhood Chain. Wallet connection and balances are read live from the chain. Receipts, reputation checkpoints, and payment state form a public proof trail for every unit of AI work, built against the same schemas the deployed contracts will use.
These docs cover the full surface: the job lifecycle, the receipt and reputation model, the session and chain REST API the dashboard itself calls, the worker CLI, the ledger event vocabulary, and the receipt contract. Use search (press /) to jump straight to a term.
Start building
Connect to the network
Point your tooling at Robinhood Chain and load the WorkGrid config.
Submit your first job
Create a structured job with the SDK and await its receipt.
Run a worker node
Serve open-weight models and earn reputation for verified work.
Architecture
WorkGrid splits cleanly into an offchain execution layer and an onchain verification layer. The four building blocks below map directly onto that split, from job intake to reputation:
WorkGridJobRegistry
OffchainTracks job creation, claiming, status transitions, and metadata hashes.
WorkGridReceipts
Contract-readyStores job hash, result hash, worker identity, model metadata, payment state, and completion timestamp.
WorkGridEscrow
PlannedHolds user payment until a job is completed, accepted, disputed, or refunded.
WorkerReputation
Future mainnetTracks worker completions, failures, latency, specialties, and reputation deltas.
WorkGridJobRegistry and WorkerReputation track state that changes on every job; WorkGridReceipts is the minimal, contract-ready anchor for the proof itself; and WorkGridEscrow is the planned payment layer that will hold funds until a job settles. Only hashes, identities, and payment metadata are meant to touch the chain, never raw prompts or model output.
Connecting to Robinhood Chain
All chain values live in one config, src/lib/chains.ts, and are never hardcoded in components. Use these parameters to add the network to your tooling:
export const ROBINHOOD_CHAIN = {
id: 4663,
name: "Robinhood Chain",
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
rpcUrl: "https://rpc.mainnet.chain.robinhood.com",
explorerUrl: "https://robinhoodchain.blockscout.com",
} as const;To add the network directly to a browser wallet, use the standard wallet_addEthereumChain payload:
{
"chainId": "0x1237",
"chainName": "Robinhood Chain",
"nativeCurrency": { "name": "Ether", "symbol": "ETH", "decimals": 18 },
"rpcUrls": ["https://rpc.mainnet.chain.robinhood.com"],
"blockExplorerUrls": ["https://robinhoodchain.blockscout.com"]
}Balance and block-height reads in the dashboard go through viem's createPublicClient against this exact RPC URL, no proxy or fallback endpoint in between. See src/lib/chain-client.ts or the Chain API reference.
Quickstart
The fastest way to see the full loop, no setup required:
Submit a job
Jobs are structured: a type, a model target, typed inputs, and a credit budget. The SDK resolves the job through routing, execution, and receipt anchoring, then returns the receipt.
import { WorkGridClient } from "@workgrid/sdk";
const grid = new WorkGridClient({
chainId: 4663,
});
const job = await grid.jobs.create({
type: "rwa.oracle_report",
model: "qwen2.5-coder",
input: {
asset: "tokenized-stock",
checks: ["spread", "latency", "liquidity"],
},
});
const receipt = await grid.receipts.waitFor(job.id);The dashboard itself uses the equivalent REST call under the hood, POST /api/session/jobs, documented in full under Jobs API. Either path deducts the job's credits from your balance the moment it's accepted, before any work runs.
Job lifecycle
Every job moves through seven stages. Each transition emits a ledger event, so the full path from prompt to payment is observable.
In the console's data model these seven stages collapse to four persisted AppJob statuses, Queued, Running, Completed, and Failed, while the finer-grained stages (Claimed, Generating, Hashing, Anchoring) are represented as ledger events rather than job states. See Status & errors.
Job templates
Purpose-built templates for RWA intelligence and developer workflows. Each pins a recommended model and a credit estimate.
| Template | Model | Credits | Output |
|---|---|---|---|
| Tokenized Stock Activity Summary | Llama 3.1 | 12 | Market memo |
| Oracle Deviation Report | Qwen2.5-Coder | 18 | Risk report |
| Liquidity Risk Scan | Mistral | 15 | Liquidity memo |
| Smart Contract Review | DeepSeek Coder | 22 | Review report |
| Portfolio Explanation | Llama 3.1 | 10 | Summary |
| Worker Node Audit | Qwen2.5-Coder | 14 | Audit card |
Status & errors
A job's status field is one of four values. Only Completed jobs produce a work receipt.
| Field | Type | Description |
|---|---|---|
| Queued | status | Accepted into the routing queue, credits already deducted. |
| Running | status | Claimed by a worker and executing offchain. |
| Completed | status | Result hashed and a WorkReceipt generated; reputation and jobs24h update. |
| Failed | status | Execution did not produce a valid result; no receipt is created. |
Session and job API errors are plain JSON with an error string and a matching HTTP status:
| Field | Type | Description |
|---|---|---|
| 400 | Bad Request | Missing or invalid address on the Chain API. |
| 403 | Forbidden | POST /api/session/jobs called before a wallet is connected. |
| 404 | Not Found | No session, or no job matching the given id. |
| 502 | Bad Gateway | The live Robinhood Chain RPC read failed. |
Offchain execution
WorkGrid does not run AI inference onchain. Worker nodes execute jobs locally with open-weight models (Llama 3.1, Qwen2.5-Coder, Mistral, DeepSeek Coder, Phi-4, Mixtral) loaded from HuggingFace or Ollama. Only hashes and metadata are designed to touch the chain: execution stays fast and cheap, verification stays public.
This split is the core architecture: offchain execution, onchain verification. A worker only ever needs to declare which models it serves and which specialties it targets (see Worker node CLI); the router matches jobs to capable nodes automatically.
Work receipts
Every completed job produces a WorkReceipt, the atomic proof unit tying prompt hash, result hash, worker identity, model, and payment together. Hashes are bytes32 (0x + 64 hex).
interface WorkReceipt {
receiptId: string; // WGR-8F2A41
jobId: string; // WG-1408
jobType: string; // rwa.oracle_report
promptHash: string; // 0x… (bytes32)
resultHash: string; // 0x… (bytes32)
workerAddress: string; // worker identity
workerName: string;
model: string; // qwen2.5-coder
paymentAsset: string; // ETH
paymentAmount: number; // credits
chainId: number; // 4663
chainName: string; // "Robinhood Chain"
txHash: string;
status: "Pending" | "Anchoring" | "Anchored" | "Failed";
timestamp: number;
reputationDelta: number;
executionTimeMs: number;
}statustracks the receipt's own anchoring progress independently of the job's status: Pending (created, not yet submitted), Anchoring (transaction in flight), Anchored (confirmed onchain), or Failed. reputationDeltais the amount this specific receipt contributes to the worker's score.
Reputation
Workers earn reputation for verified completions, uptime, and low latency. Each anchored receipt carries a reputationDelta; checkpoints accumulate into a score that gates priority routing and higher-value jobs. Failed or disputed work reduces it.
Reputation is surfaced in three places: a worker's reputation score (0-100) on its profile, a slashingRisk rating (Low or Medium) derived from its completion history, and a set of earned badges (for example Verified Worker, Low Latency, or a domain specialty like RWA Specialist).
Credits & escrow
Jobs are priced in credits, a number between 5 and 50 attached to the job at submission time and deducted from the session's kpis.creditsbalance immediately, before the job runs. There's no separate “charge on completion” step today.
WorkGridEscrow (see Architecture) is the planned contract that will hold a user's payment until a job is completed, accepted, disputed, or refunded, replacing today's immediate-deduction credit model with an onchain hold-and-release flow.
Session API
Every visitor gets a server-side SessionState, keyed by an httpOnly wg_sessioncookie minted on first request. There's no separate auth header for these endpoints, they're same-origin calls the dashboard itself makes; the apiKey field they return is for SDK/ programmatic use, documented under SDK reference.
/api/sessionReads (and lazily creates) the current session. A brand-new session comes back completely empty, no fabricated balances or jobs.
GET /api/session
// A brand-new visitor gets an empty session, not fabricated numbers:
{
"walletConnected": false,
"walletAddress": null,
"jobs": [],
"kpis": { "credits": 0, "jobs24h": 0, "successRate": 0, "avgExecS": 0 },
"weekly": [{ "day": "Mon", "value": 0 }, "…"],
"events": [],
"receipts": [],
"apiKey": "wg_sk_live_…",
"blockHeight": 8431920,
"createdAt": 1751500000000
}/api/session/connect-walletSeeds network activity into the session: jobs, KPIs, ledger events, receipts, a fresh API key, and a block height. Idempotent once connected.
| Field | Type | Description |
|---|---|---|
| address | string (optional) | Wallet address to attach; a placeholder identity is generated if omitted. |
curl -X POST https://workgrid.network/api/session/connect-wallet \
-H "Content-Type: application/json" \
-d '{ "address": "0xA91C...F22b" }'
# Idempotent: if the session is already connected, the existing
# state is returned unchanged instead of re-seeding.Jobs API
Job creation and updates operate on the connected session's job list; the id path segment is the job's WG-#### identifier.
/api/session/jobsCreates a job on the current session and deducts its credits.
| Field | Type | Description |
|---|---|---|
| type | string (optional) | Must match a known job category; falls back to the first category otherwise. |
| model | string (optional) | Must match a supported model; falls back to the first model otherwise. |
| prompt | string (optional) | Trimmed and capped at 500 characters; defaults to "Untitled job". |
| credits | number (optional) | Clamped between 5 and 50; defaults to 18. |
curl -X POST https://workgrid.network/api/session/jobs \
-H "Content-Type: application/json" \
-d '{
"type": "Oracle Check",
"model": "Qwen2.5-Coder",
"prompt": "Flag oracle spread deviation beyond 40bps",
"credits": 18
}'
# 403 { "error": "Wallet not connected" } if the session has no wallet yet/api/session/jobs/:idFetches a single job, its receipt (if any), and every ledger event recorded against it.
curl https://workgrid.network/api/session/jobs/WG-1408
# { "job": { … }, "receipt": null | WorkReceipt, "events": LedgerEvent[] }/api/session/jobs/:idUpdates a job's status and/or appends a ledger event for it. Completing a job mints its WorkReceipt if one doesn't exist yet.
| Field | Type | Description |
|---|---|---|
| status | AppJobStatus (optional) | One of Queued, Running, Completed, Failed. |
| stageEvent | LedgerEventName (optional) | Any of the seven ledger event names; prepended to the event log. |
curl -X PATCH https://workgrid.network/api/session/jobs/WG-1408 \
-H "Content-Type: application/json" \
-d '{ "status": "Completed" }'
# Completing a job with no existing receipt mints one and bumps kpis.jobs24hChain API
Thin server-side wrappers around a real viem createPublicClientpointed at Robinhood Chain's live RPC, so wallet balance and block height in the dashboard are never mocked.
/api/chain/balanceReturns a wallet's live native ETH balance on Robinhood Chain.
| Field | Type | Description |
|---|---|---|
| address | string (query, required) | Any address; validated with viem's non-strict isAddress, so unchecksummed input is accepted. |
/api/chain/blockReturns the current block number on Robinhood Chain.
curl "https://workgrid.network/api/chain/balance?address=0xA91C...F22b"
# { "formatted": "1.204981", "symbol": "ETH" }
curl "https://workgrid.network/api/chain/block"
# { "blockNumber": "8431920" }Worker node CLI
Operators join with one command, declaring served models, chain target, and specialty. The router only offers jobs the node's hardware and model profile can complete.
workgrid node start \ --models qwen2.5-coder,llama3.1,mistral \ --chain robinhood \ --receipts onchain \ --specialty rwa-research
| Field | Type | Description |
|---|---|---|
| --models | comma-separated list | Which open-weight models this node serves, e.g. qwen2.5-coder,llama3.1,mistral. |
| --chain | string | Target network; robinhood resolves to chain id 4663. |
| --receipts | onchain | simulated | Whether generated receipts are submitted for anchoring. |
| --specialty | string | Preferred job category for routing priority, e.g. rwa-research. |
Ledger events
The event vocabulary of the protocol. Every lifecycle transition maps to one of these signatures, each carrying a job id and tx hash.
event JobCreated(uint256 indexed jobId, bytes32 jobHash); event JobClaimed(uint256 indexed jobId, address indexed worker); event ModelExecutionStarted(uint256 indexed jobId); event ResultHashed(uint256 indexed jobId, bytes32 resultHash); event ReceiptAnchored(uint256 indexed receiptId, bytes32 resultHash); event ReputationUpdated(address indexed worker, int256 delta); event PaymentReleased(uint256 indexed jobId, uint256 amount);
| Field | Type | Description |
|---|---|---|
| JobCreated | → Queued | Job accepted into the routing queue. |
| JobClaimed | → Claimed | A worker node has claimed the job. |
| ModelExecutionStarted | → Running | Model loaded and inference started on worker hardware. |
| ResultHashed | → Hashing | Prompt/result hash pair computed. |
| ReceiptAnchored | → Anchoring | WorkGridReceipt submitted for onchain anchoring. |
| ReputationUpdated | → Completed | Worker reputation checkpoint applied. |
| PaymentReleased | → Completed | Payment state settled for the job. |
Contracts
WorkGridReceipts.sol is the minimal receipt anchor: a struct, a mapping, and one event. Full source lives in contracts/, with a matching ABI in src/lib/abi/workgridReceipts.ts.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract WorkGridReceipts {
struct Receipt {
bytes32 jobHash;
bytes32 resultHash;
address worker;
string model;
uint256 paymentAmount;
uint256 timestamp;
}
mapping(uint256 => Receipt) public receipts;
uint256 public nextReceiptId;
event ReceiptCreated(
uint256 indexed receiptId,
address indexed worker,
bytes32 jobHash,
bytes32 resultHash
);
function createReceipt(...) external returns (uint256);
}createReceipt is the only state-changing function: it stores the receipt struct at an auto-incrementing receiptId and emits ReceiptCreated. Everything else (job routing, escrow, reputation) is designed as a separate contract layered on top of this anchor, per the Architecture overview.
SDK reference
@workgrid/sdk mirrors the Session and Jobs REST API one-to-one, so teams not ready to adopt the SDK can call the same endpoints directly.
import { WorkGridClient } from "@workgrid/sdk";
const grid = new WorkGridClient({ chainId: 4663 });
// create a job
const job = await grid.jobs.create({
type: "rwa.oracle_report",
model: "qwen2.5-coder",
input: { asset: "tokenized-stock", checks: ["spread", "latency", "liquidity"] },
});
// resolves once the job is anchored, or throws on "Failed"
const receipt = await grid.receipts.waitFor(job.id);
// fetch a job or a past receipt directly by id
const current = await grid.jobs.get(job.id);
const past = await grid.receipts.get(receipt.receiptId);| Field | Type | Description |
|---|---|---|
| jobs.create(input) | → Job | Equivalent to POST /api/session/jobs. |
| jobs.get(id) | → Job | Equivalent to GET /api/session/jobs/:id. |
| receipts.waitFor(jobId) | → WorkReceipt | Polls until the job's receipt is anchored, or throws on Failed. |
| receipts.get(receiptId) | → WorkReceipt | Fetches a previously anchored receipt by id. |
Glossary
Terms used throughout these docs and the console UI.
- Job
- A structured unit of AI work: a type (e.g. Oracle Check), a target model, a prompt, and a credit budget. Represented as an AppJob with an id like WG-1408.
- Worker node
- An operator running open-weight models on its own hardware, joined to the network with the workgrid node CLI. Workers claim jobs matching their served models and specialties.
- Work receipt
- The atomic proof unit produced by a completed job: prompt hash, result hash, worker identity, model, and payment, designed to anchor onchain via WorkGridReceipts.
- Reputation
- A worker's running score, built from reputationDelta checkpoints on each anchored receipt. Higher reputation gates priority routing and higher-value jobs.
- Credits
- The unit jobs are budgeted and paid in. Submitting a job deducts its credits from the session's kpis.credits balance immediately.
- Ledger event
- One of seven onchain-shaped event signatures (JobCreated, JobClaimed, ModelExecutionStarted, ResultHashed, ReceiptAnchored, ReputationUpdated, PaymentReleased) emitted at each lifecycle transition.
- Chain ID
- Robinhood Chain's EVM chain id: 4663 (0x1237 in hex).
- Anchoring
- Writing a work receipt's hashes to Robinhood Chain so the proof trail is public and independently verifiable.
- Session
- A per-visitor server-side state object (SessionState) keyed by an httpOnly wg_session cookie, holding jobs, receipts, events, kpis, and an API key.
- Demo mode
- A client-side preview state (sample jobs, receipts, and events) toggled from the dashboard navbar, kept in sessionStorage and never written to the real session.