
Loading...

Loading...
Methods, networks, contract addresses, changelog, security model, ports.
Free, no key. Dashboards, leaderboards, eligibility checks, gating.
import { LightNode } from "lightnode-sdk";
const ln = new LightNode("mainnet");
const top = (await ln.getWorkerStats(1000, 5)).map((w) => ({
worker: w.address,
completionPct: w.completionRate * 100,
p95ms: w.p95LatencyMs,
}));
console.table(top);| Method | Returns | What it gives you |
|---|---|---|
getWorker(address) | Worker | null | Full record for one worker (stake, status, earnings, models served). |
getWorkers(first = 200) | Worker[] | Registered workers, busiest first. |
getWorkerJobs(address, first = 20) | Job[] | Recent jobs for one worker, newest first. |
getModels() | ModelInfo[] | Network's registered models: name, fee, max output tokens, whitelist flags. |
getNetworkStats() | NetworkStats | One-shot summary: totals, active count, jobs completed, earnings, model count. |
getModelStats(sample = 1000) | ModelStat[] | Per-model performance over the last N jobs: completion, p50/p95, incomplete, disputes, earnings. |
getNetworkAnalytics(sample = 1000) | NetworkAnalytics | Network-wide rollup across all models over the last N jobs. |
getWorkerStats(sample = 1000, limit = 25) | WorkerStat[] | Per-worker reliability over the last N jobs. Busiest first. |
isRegistered(address) | boolean | null | Authoritative on-chain registration. Beats the indexer on deregister + re-register cycles. |
getEarningsLcai(address) | number | Settled worker earnings in whole LCAI. |
modelId(tag) | 0x${string} | keccak256 of a model tag. Its on-chain + indexer id. |
estimateFee(modelTag) | number (LCAI) | On-chain inference fee. What submitJob will charge. |
gateway({ bearer }) | GatewayClient | Authenticated GatewayClient for this network. |
getJobStatus(jobId) | JobStatus | null | Job category (completed / stalled / disputed / ...) + refundable flag. |
getWorkerLiveness(address) | WorkerLivenessReport | Stuck-job + slash-risk diagnostic: flags a staked-but-offline worker not acknowledging assigned jobs, with slash exposure and suspension risk. |
getWorkerActions(address) | WorkerActionCenter | Action center: claimable earnings, worker-wallet gas (outOfGas), settle-now vs in-window jobs, liveness, and a prioritized to-do list. |
getWorkerModels(address) | WorkerModel[] | On-chain model whitelist for a worker (raw WorkerRegistry rows; can go stale after deregister). |
getServedModels(address) | ServedModel[] | Models a worker serves, reconciled against the chain (onchainEligible is the truth, indexedActive the subgraph). |
getJobOnchain(jobId) | OnchainJob | null | Authoritative on-chain job struct (state, deadlineAt, escrow) - ground truth the indexer may lag. |
getWorkersBatch(addresses, { parallel }) | (Worker | null)[] | Many workers at once, bounded concurrency, in input order. Null per missing slot, never throws. |
getJobStatusesBatch(jobIds, { parallel }) | (JobStatus | null)[] | Many job statuses at once, bounded concurrency, in input order. |
toWei(lcai) / fromWei(wei) → bigint / number - Exact LCAI<->wei conversions (toWei is precise; fromWei is Number-based).checksum(address) → string - EIP-55 checksum an address (input unchanged if invalid).isValidAddress(address) → boolean - Syntactic 0x-address check.truncateAddress(address, chars = 4) → string - 0x1234…abcd short form for UIs/logs.mapWithConcurrency(items, limit, fn) → Promise<R[]> - Bounded-concurrency map preserving input order - the basis for the batch reads.Same protocol, different chain IDs and addresses.
| testnet | mainnet | |
|---|---|---|
| Chain ID | 8200 | 9200 |
| RPC | rpc.testnet.lightchain.ai | rpc.mainnet.lightchain.ai |
| Explorer | testnet.lightscan.app | mainnet.lightscan.app |
| Faucet | lightfaucet.ai (~2 LCAI / IP / day) | n/a (bridge from Ethereum) |
| Worker min stake | 5,000 LCAI | 50,000 LCAI |
| Inference cost | free (testnet LCAI) | about 0.022 LCAI per call |
| Best for | Builder testing, examples, CI | Real users, paid traffic, on-chain proof |
Sourced from NETWORKS in lightnode-sdk. Edit the SDK, this page picks it up.
| Contract | Testnet (chain 8200) | Mainnet (chain 9200) | Purpose |
|---|---|---|---|
| WorkerRegistry | 0x0000000000000000000000000000000000001002 | 0x0000000000000000000000000000000000001002 | Genesis predeploy. Worker stake + ECDH key + supported models. |
| FeePool | 0x0000000000000000000000000000000000001004 | 0x0000000000000000000000000000000000001004 | Genesis predeploy. Where per-job fees accumulate before payout. |
| NativeVotes | 0x0000000000000000000000000000000000001001 | 0x0000000000000000000000000000000000001001 | Genesis predeploy. Voting weight backing LightChainGovernor (no wrapping). |
| AIConfig (proxy) | 0xeCF4Ca5Ba6D97ae586993e170764a1E92231b67e | 0x24D11533C354092ed6E18b964257819cE78Ce77D | Model whitelist + per-job fee + max output tokens. The model registry. |
| JobRegistry (proxy) | 0x531b3a87c5d785441b9cf55b98169f20fd9056a7 | 0xfB15F90298e4CcD7106E76fFB5e520315cC42B0b | createSession + submitJob + emits SessionCreated / JobSubmitted / JobCompleted. |
| Treasury (proxy) | not deployed | 0x786eDe8C42Ca54E54c9dCECa9b30052CF4743389 | DAO-controlled treasury holding protocol funds. |
| LightChainGovernor (proxy) | not deployed | 0xD216A0c0050EdC3a9E0449EcFDf178A1652b4b68 | On-chain DAO. Read + vote at dao.lightchain.ai. NativeVotes-backed. |
| TimelockController | not deployed | 0xc783376c8237E8f1ed17d825CE7CBB4c22e3cAE5 | Holds queue/execute delay for the LightChainGovernor. |
The SDK never holds your key. Here is exactly what touches what.
Three drop-in shapes. Open in StackBlitz, no install.
Standalone Node + tsx. ~30 lines using runInferenceWithKey.
Drop-in app/api/inference/route.ts. POST a prompt, get JSON back.
Tiny standalone microservice. Deploys to Bun, Cloudflare Workers, Railway, Fly, any Node host.
The project ships regularly. Pinned examples track the latest patch by default.
Security + attestation: openSession/runInference now bind the session key to the worker's CHAIN-REGISTERED encryption key (verifyWorkerKeyOnChain) instead of trusting the gateway's copy, closing a prompt/answer MITM where a hostile proxy substitutes its own key; the key-based auth challenge is validated (assertSafeChallenge) before signing so a proxy cannot harvest a SIWE signature for another account/site; and RunInferenceResult now exposes the worker's on-chain commitments responseHash + ciphertextHash for callers (e.g. a challenge protocol) that anchor the verdict on-chain.
Conversation reuses one on-chain session across turns (first send pays createSession, follow-ups submit straight onto it, transparent reopen + one retry on expiry or worker failure; currentSession() exposes the handle); new connectWithKey() returns the SIWE-authenticated gateway, viem clients, and WebSocket ctor for custom session flows; the Minimal* client interfaces are method-typed so real viem PublicClient/WalletClient instances pass into Bridge, DAO, WorkerOperator, and OnchainModelRegistry with zero casts; WorkerOperator.register(encryptionPubKey) completes the lifecycle; typescript added as a devDependency so a standalone sdk/ checkout builds.
Consistency + polish: LightNode { timeoutMs } now also applies to the viem transport behind the viem-backed reads (getJobOnchain, getWorkerLiveness, getWorkerActions), so the whole call honors one timeout instead of half of it; the CLI 'worker settle' JSON now uses the 'skipped' field name to match the exported BatchJobOpResult and the scaffolded worker-ops.ts; and the CLI help/usage text now lists 'add worker-operator' and the worker doctor/liveness/profitability diagnostics.
New scaffolder: npx lightnode add worker-operator writes a runnable Node console (worker-ops.ts + .env.example + README) over the WorkerOperator surface - status / settle / clearstuck / withdraw / deregister / profitability, no Docker or worker image. The status command prints JSON (a prioritized to-do list + an outOfGas flag) so an operator can cron it and never sit on stuck jobs or unclaimed earnings; the mainnet-slashing commands are gated behind --yes.
Cancellation + auth resilience: an AbortSignal on runInference / runInferenceWithKey is now honored at every await - including the mid-stream wait for JobCompleted and the relay-token poll - so a cancel stops the work promptly and closes the relay socket instead of running the poll loops to their deadlines; it rejects with InferenceAbortedError (name 'AbortError', detect via isAbortError). A function bearer on GatewayClient is re-invoked with { forceRefresh: true } on a 401 and the request is replayed once, so a server-side token revocation / clock-skew expiry self-heals (a static-string bearer still surfaces the 401).
Tuning + ergonomics: LightNode accepts { timeoutMs } to bound (or, with <= 0, unbound) every subgraph + raw on-chain read, so a slow indexer no longer dies on the built-in 12s/8s defaults (exported as DEFAULT_SUBGRAPH_TIMEOUT_MS / DEFAULT_ONCHAIN_TIMEOUT_MS). WorkerOperator.clearStuck and releaseAll now return one unified shape, BatchJobOpResult { done: [{jobId, tx}], skipped: [{jobId, reason}] } - skipped now explains WHY each job was left alone (not yet past deadline / still inside the dispute window) instead of a bare ID list.
Reliability: GatewayClient now auto-retries 429 (rate limit) for any method and 5xx for GETs with exponential backoff, honoring Retry-After (configurable via { retry: { maxRetries, baseDelayMs } }); GatewayHttpError gains isRateLimited / isAuthError / isServerError + retryAfterMs. LightNode accepts { cacheTtlMs } to TTL-memoize the network-wide reads (getModels / getNetworkStats / getModelStats / getNetworkAnalytics / getWorkerStats) with a clearCache() escape hatch - so a polling dashboard stops re-hitting the indexer every render.
Ecosystem polish: batch reads (getWorkersBatch, getJobStatusesBatch) with bounded concurrency in input order; getJobOnchain for the authoritative on-chain job struct; exported utility helpers (toWei/fromWei, checksum, isValidAddress, truncateAddress, mapWithConcurrency). CLI gains a --json mode on the read commands, per-command --help, and worker doctor / liveness / profitability diagnostics (the same rollups the dashboard shows, for scripting).
Worker activity signal: WorkerLivenessReport now carries activity (active | processing | stalled | idle | unknown) and lastCompletedAgoSec, derived from the on-chain job flow - an honest, gateway-free read of whether a worker is processing jobs (a recent completion = active; an acked job in flight = processing), useful for remote workers where there is no container status.
Worker action center: getWorkerActions(address) rolls up claimable earnings, the worker-wallet gas balance (an outOfGas flag that explains the silent settle/claim/deregister failures), settle-now vs still-in-dispute-window jobs, the liveness/stuck-job picture, and a prioritized to-do list. analyzeWorkerActions and analyzeSettlement are the pure analyzers behind it.
Worker liveness / stuck-job diagnostic: getWorkerLiveness(address) classifies a worker's recent jobs against the live protocol timeouts to flag a staked-but-offline worker that is no longer acknowledging assigned jobs (the silent pre-slash failure), including the Submitted-past-ack-deadline case the plain job buckets miss, with slash exposure and suspension risk. analyzeWorkerLiveness is the pure classifier behind it.
Web search inference (searchEnabled routes to a search-capable worker; the result carries a typed sources[] of citations), an onStage progress hook (Searching the web... / Uploading prompt to chain... / Thinking...), and session reuse so multi-turn chat pays one tx per turn instead of two. Faster relay-token polling and earlier stream completion.
One-command *-web3 scaffolders: npx lightnode add chat-web3 (and inference-web3 / judge-web3) scaffold a themed Next.js app end to end in an empty folder, bundling the wagmi config, providers, connect button, and deps.
Docker-free, gas-correct deregister: deregisterWorker() is sent directly with an estimated gas limit, so a stuck or half-finished worker can exit and recover its stake with no toolkit clone and no worker image. WorkerOperator.workerAddress is now optional on read-only paths.
Worker-operator README + CLI docs: full 17-method reference and the worker status / can-deregister / settle / clearstuck / withdraw / deregister commands.
WorkerOperator: the on-chain worker write surface. Register, stake (topUp / withdraw / reinstate), settle (releaseJob / releaseAll / withdraw), live AIConfig, and stuck-job recovery (claimTimeout / clearStuck / unstickAndDeregister) that clears acknowledged-but-unfinished jobs blocking deregister. decodeWorkerError turns the unverified custom reverts into plain English.
Higher-level inference: runInferenceBatch (parallel inference, capped concurrency, stable result order, per-slot errors), the Agent class (ReAct-style tool calling that works on llama3-8b without native function calling), and AbortSignal cancellation across runInference / runInferenceWithKey.
DAO covers both governors (Ethereum LCAIGovernor + LightChain LightChainGovernor with NativeVotes). All contract addresses now derived from NETWORKS. dao config CLI gets a friendlier RPC fallback.
Full SDK ecosystem release: Bridge SDK, DAO SDK, on-chain Model Registry reader, multi-turn Conversation, worker preflight + watch, job status reader.
lightnode chat + lightnode wallet CLI commands. runInferenceStream (AsyncIterable<string>). Auto-resolve `ws` in Node so no WebSocket import needed.
Crypto switched from Web Crypto to noble (P-256 + AES-GCM). Works in StackBlitz / Bolt WebContainer.
lightnode.app/api/gw CORS proxy. SDK auto-routes via the proxy in browser-like contexts.
JobCompleted grace fix: don't drop a delivered answer when the on-chain event is slow.
runInferenceWithKey: the real 5-line API. SDK builds viem + SIWE for you.
runInference orchestrator + four typed errors.
pip install lightnode-sdk for the read-only client + run_inference_with_key. Byte-perfect crypto vs the TS SDK.
LightChain's Remix-fork IDE loads JobRegistry / AIConfig, decodes tx payloads, lets you write Solidity callers.
Connect a wallet, type a prompt, run one real encrypted inference. Source you can copy.