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

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

Offchain

Tracks job creation, claiming, status transitions, and metadata hashes.

WorkGridReceipts

Contract-ready

Stores job hash, result hash, worker identity, model metadata, payment state, and completion timestamp.

WorkGridEscrow

Planned

Holds user payment until a job is completed, accepted, disputed, or refunded.

WorkerReputation

Future mainnet

Tracks 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:

Network nameRobinhood Chain
Chain ID4663
CurrencyETH (18 decimals)
RPC URLhttps://rpc.mainnet.chain.robinhood.com
src/lib/chains.ts
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:

wallet_addEthereumChain params
{
  "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:

1
Open the consoleVisit /dashboard. A first-time session is empty: zeroed balances, no jobs, nothing fabricated.
2
Connect a walletSign in with Privy (email, Google, or wallet). This calls Connect Wallet, seeding real activity into your session.
3
Or preview with DemoClick Demo in the dashboard navbar for sample jobs, receipts, and events, no wallet required, kept out of your real session.
4
Submit a jobUse the New Job flow, the SDK, or POST /api/session/jobs directly with a type, model, prompt, and credit budget.
5
Watch it settleLedger events stream in as the job moves through the lifecycle; a WorkReceipt appears once it completes.

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.

submit-job.ts
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.

01
QueuedStructured job accepted into the routing queue.
02
ClaimedA matched worker node claims the job.
03
Running modelOpen-weight model loads on operator hardware.
04
GeneratingThe model produces a structured result offchain.
05
HashingPrompt and result are hashed into a bytes32 proof pair.
06
AnchoringA WorkGridReceipt is anchored on Robinhood Chain.
07
CompletedPayment state and reputation checkpoints update.

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.

TemplateModelCreditsOutput
Tokenized Stock Activity SummaryLlama 3.112Market memo
Oracle Deviation ReportQwen2.5-Coder18Risk report
Liquidity Risk ScanMistral15Liquidity memo
Smart Contract ReviewDeepSeek Coder22Review report
Portfolio ExplanationLlama 3.110Summary
Worker Node AuditQwen2.5-Coder14Audit card

Status & errors

A job's status field is one of four values. Only Completed jobs produce a work receipt.

FieldTypeDescription
QueuedstatusAccepted into the routing queue, credits already deducted.
RunningstatusClaimed by a worker and executing offchain.
CompletedstatusResult hashed and a WorkReceipt generated; reputation and jobs24h update.
FailedstatusExecution 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:

FieldTypeDescription
400Bad RequestMissing or invalid address on the Chain API.
403ForbiddenPOST /api/session/jobs called before a wallet is connected.
404Not FoundNo session, or no job matching the given id.
502Bad GatewayThe 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).

WorkReceipt
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.

GET/api/session

Reads (and lazily creates) the current session. A brand-new session comes back completely empty, no fabricated balances or jobs.

Response
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
}
POST/api/session/connect-wallet

Seeds network activity into the session: jobs, KPIs, ledger events, receipts, a fresh API key, and a block height. Idempotent once connected.

FieldTypeDescription
addressstring (optional)Wallet address to attach; a placeholder identity is generated if omitted.
cURL
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.

POST/api/session/jobs

Creates a job on the current session and deducts its credits.

FieldTypeDescription
typestring (optional)Must match a known job category; falls back to the first category otherwise.
modelstring (optional)Must match a supported model; falls back to the first model otherwise.
promptstring (optional)Trimmed and capped at 500 characters; defaults to "Untitled job".
creditsnumber (optional)Clamped between 5 and 50; defaults to 18.
cURL
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
GET/api/session/jobs/:id

Fetches a single job, its receipt (if any), and every ledger event recorded against it.

cURL
curl https://workgrid.network/api/session/jobs/WG-1408

# { "job": { … }, "receipt": null | WorkReceipt, "events": LedgerEvent[] }
PATCH/api/session/jobs/:id

Updates a job's status and/or appends a ledger event for it. Completing a job mints its WorkReceipt if one doesn't exist yet.

FieldTypeDescription
statusAppJobStatus (optional)One of Queued, Running, Completed, Failed.
stageEventLedgerEventName (optional)Any of the seven ledger event names; prepended to the event log.
cURL
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.jobs24h

Chain 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.

GET/api/chain/balance

Returns a wallet's live native ETH balance on Robinhood Chain.

FieldTypeDescription
addressstring (query, required)Any address; validated with viem's non-strict isAddress, so unchecksummed input is accepted.
GET/api/chain/block

Returns the current block number on Robinhood Chain.

cURL
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
workgrid node start \
  --models qwen2.5-coder,llama3.1,mistral \
  --chain robinhood \
  --receipts onchain \
  --specialty rwa-research
FieldTypeDescription
--modelscomma-separated listWhich open-weight models this node serves, e.g. qwen2.5-coder,llama3.1,mistral.
--chainstringTarget network; robinhood resolves to chain id 4663.
--receiptsonchain | simulatedWhether generated receipts are submitted for anchoring.
--specialtystringPreferred 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.

Events
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);
FieldTypeDescription
JobCreated→ QueuedJob accepted into the routing queue.
JobClaimed→ ClaimedA worker node has claimed the job.
ModelExecutionStarted→ RunningModel loaded and inference started on worker hardware.
ResultHashed→ HashingPrompt/result hash pair computed.
ReceiptAnchored→ AnchoringWorkGridReceipt submitted for onchain anchoring.
ReputationUpdated→ CompletedWorker reputation checkpoint applied.
PaymentReleased→ CompletedPayment 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.

contracts/WorkGridReceipts.sol
// 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.

workgrid-client.ts
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);
FieldTypeDescription
jobs.create(input)→ JobEquivalent to POST /api/session/jobs.
jobs.get(id)→ JobEquivalent to GET /api/session/jobs/:id.
receipts.waitFor(jobId)→ WorkReceiptPolls until the job's receipt is anchored, or throws on Failed.
receipts.get(receiptId)→ WorkReceiptFetches 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.

FAQ

A session with no connected wallet is empty by design: zeroed KPIs, no jobs, no receipts. Nothing is fabricated and shown as though it were yours. Connecting a wallet (or opening Demo mode) is what seeds visible activity.