@foundryprotocol/0gkit-compute
Neutral 0G Compute: model-first routing, explicit-provider inference, provider discovery, and an OpenAI-compatible shim.
What it does
Wraps the 0G compute broker SDK behind one class. router() picks a
provider for you — the managed 0G Router endpoint when you supply a
routerApiKey, otherwise honest client-side selection over the provider list
with retry/fallback. direct()/inference() call a provider you name.
Either returns the result plus an on-chain fee Receipt. A drop-in OpenAI-style
shim is included so existing OpenAI code works unchanged. See the concept guide
router() vs direct().
When to use it
- Running LLM inference paid for on 0G, against a registered provider.
- Migrating OpenAI code to 0G with minimal changes (the
openai()shim). - Listing available providers / models programmatically.
Where to use it
Node only for live inference — the broker SDK
(@0gfoundation/0g-compute-ts-sdk, fallback @0glabs/0g-serving-broker) and
ethers are dynamically imported. The broker import is intentionally
non-analyzable + ignore-commented so it never breaks a bundler — but the SDK
itself is Node-only, so run inference on a server / script / via the CLI.
Install
npm install @foundryprotocol/0gkit-compute @foundryprotocol/0gkit-core viem
npm install @0gfoundation/0g-compute-ts-sdk ethers
API reference
class Compute
interface ChatMessage {
role: "system" | "user" | "assistant";
content: string;
}
interface ComputeConfig {
network?: "aristotle" | "galileo";
brokerRpc?: string; // default https://evmrpc.0g.ai
signer?: Signer; // preferred — use fromEnv() / fromPrivateKey() / etc.
brokerKey?: string; // legacy — deprecated, use signer instead
provider?: string; // on-chain inference provider address (default prefer for router())
model?: string; // default model id
routerApiKey?: string; // 0G Router API key (pc.0g.ai) — enables the managed Router
routerUrl?: string; // override the Router base URL (default by network)
fetch?: typeof fetch; // inject fetch (testing)
loadBroker?: (name: string) => Promise<unknown>; // inject the broker SDK
loadEthers?: () => Promise<typeof import("ethers")>;
}
interface InferenceResult {
output: string; // the assistant message content
receipt: Receipt; // { txHash?, latencyMs } — the on-chain fee receipt
raw: unknown; // the raw provider JSON
}
new Compute(config: ComputeConfig);
Pass a Signer (from @foundryprotocol/0gkit-wallet) to Compute so key
management is independent of the inference client. The legacy brokerKey
string continues to work but emits a deprecation warning — see
Legacy (deprecated) below.
compute.router(args) — model-first (recommended)
router(args: {
model?: string; // required for the managed Router; optional client-side
messages: ChatMessage[];
temperature?: number;
prefer?: string; // pin a provider (defaults to config.provider)
sort?: "price"; // managed-Router routing knob
maxAttempts?: number; // client-side retry cap
}): Promise<InferenceResult>;
Picks a provider for you. With routerApiKey set, calls the real 0G Router
endpoint (router-api.0g.ai/v1, server-side selection + failover). Without one,
selects client-side over listProviders() and retries the next candidate on
failure (logged once). Throws a typed NetworkError when no provider is
reachable, and ConfigError if the managed Router is used without a model. See
router() vs direct().
compute.direct(args) / compute.inference(args)
inference(args: {
provider?: string; // per-call provider (overrides config.provider)
model?: string;
messages: ChatMessage[];
temperature?: number;
}): Promise<InferenceResult>;
direct: typeof inference; // explicit-provider alias (no behaviour change)
The explicit-provider path: acknowledges the provider signer (non-fatal if
already done), fetches service metadata, signs request headers, POSTs to
<endpoint>/v1/chat/completions, and best-effort settles the fee (non-fatal).
direct() is a thin alias; the optional per-call { provider } is additive.
Throws ConfigError for a missing brokerKey/provider or unloadable
SDK/ethers; throws NetworkError for metadata/header/HTTP failures.
compute.listProviders()
listProviders(): Promise<unknown[]>;
Lists registered providers via the broker. Throws ConfigError if
brokerKey is missing, NetworkError if the listing fails.
compute.openai()
openai(): {
chat: {
completions: {
create(params: {
model?: string;
messages: ChatMessage[];
temperature?: number;
}): Promise<{
id: string;
object: "chat.completion";
model: string;
choices: Array<{
index: number;
message: { role: "assistant"; content: string };
finish_reason: "stop";
}>;
_0gReceipt: Receipt; // the 0G fee receipt, attached for you
}>;
};
};
};
An OpenAI-shaped chat.completions.create. The 0G fee Receipt is attached
as _0gReceipt on the response.
compute.raw()
raw(): Promise<{ inference: BrokerInference }>; // the underlying broker
The escape hatch — the underlying broker object.
Examples
Route by model — no provider address (recommended)
import { Compute } from "@foundryprotocol/0gkit-compute";
// Managed 0G Router: server-side selection + failover, single balance.
const compute = new Compute({
network: "galileo",
routerApiKey: process.env.ROUTER_API_KEY!, // from pc.0g.ai
});
const { output } = await compute.router({
model: "llama-3.1-8b",
messages: [{ role: "user", content: "Say hello to 0G in five words." }],
});
console.log(output);
Drop routerApiKey and pass a wallet signer/brokerKey instead to get the
same router() call backed by client-side selection over the on-chain
provider list — no dashboard key required.
With signer — recommended
import { Compute } from "@foundryprotocol/0gkit-compute";
import { fromEnv } from "@foundryprotocol/0gkit-wallet";
const signer = await fromEnv(); // KMS_KEY_ID > KEY_FILE > PRIVATE_KEY
const compute = new Compute({
network: "galileo",
signer,
provider: process.env.ZEROG_PROVIDER!,
});
const { output, receipt } = await compute.inference({
messages: [{ role: "user", content: "Say hello to 0G in five words." }],
});
console.log(output);
Minimal — one completion
import { Compute } from "@foundryprotocol/0gkit-compute";
import { fromPrivateKey } from "@foundryprotocol/0gkit-wallet";
const signer = await fromPrivateKey(process.env.ZEROG_BROKER_KEY!);
const compute = new Compute({
network: "galileo",
signer,
provider: process.env.ZEROG_PROVIDER!, // on-chain provider address
});
const { output, receipt } = await compute.inference({
messages: [{ role: "user", content: "Say hello to 0G in five words." }],
});
console.log(output);
console.log(`fee tx ${receipt.txHash ?? "(none)"} — ${receipt.latencyMs} ms`);
Realistic — OpenAI drop-in with error handling
import { Compute } from "@foundryprotocol/0gkit-compute";
import { ZeroGError } from "@foundryprotocol/0gkit-core";
import { fromPrivateKey } from "@foundryprotocol/0gkit-wallet";
const signer = await fromPrivateKey(process.env.ZEROG_BROKER_KEY!);
const compute = new Compute({
network: "galileo",
signer,
provider: process.env.ZEROG_PROVIDER!,
model: "llama-3.3-70b-instruct",
});
const oa = compute.openai(); // existing OpenAI code path
try {
const res = await oa.chat.completions.create({
messages: [
{ role: "system", content: "You are terse." },
{ role: "user", content: "What is 0G Data Availability?" },
],
temperature: 0.2,
});
console.log(res.choices[0].message.content);
console.log("0G fee receipt:", res._0gReceipt); // attached by 0gkit
} catch (err) {
if (err instanceof ZeroGError) {
console.error(`[${err.code}] ${err.message}\n→ ${err.hint}`);
} else {
throw err;
}
}
Legacy (deprecated)
Passing brokerKey directly is still supported but deprecated. It emits a
DeprecationWarning and will be removed in v2.
// ⚠ deprecated — works today, removed in v2
const compute = new Compute({
network: "galileo",
brokerKey: process.env.ZEROG_BROKER_KEY,
provider: process.env.ZEROG_PROVIDER!,
});
Migrate by wrapping with fromPrivateKey:
import { fromPrivateKey } from "@foundryprotocol/0gkit-wallet";
const signer = await fromPrivateKey(process.env.ZEROG_BROKER_KEY!);
const compute = new Compute({ network: "galileo", signer, provider: "0x…" });
Common errors
| Symptom | Cause | Fix |
|---|---|---|
ConfigError: Compute requires a signer or brokerKey | No credentials in config. | Pass { signer } (from fromEnv()) to the Compute constructor. |
ConfigError: Compute requires a provider address | No provider in config. | Pass { provider }, or call router() to select one for you. |
ConfigError: 0G compute SDK not found… | Optional broker peer not installed. | npm install @0gfoundation/0g-compute-ts-sdk ethers. |
NetworkError: Failed to fetch service metadata… | Provider not registered / broker unfunded. | Verify the provider address and fund the broker ledger. |
NetworkError: 0G compute provider returned HTTP … | Provider rejected the request. | Verify the provider address and broker ledger balance. |
Related
core · wallet (loaders: fromEnv, fromKMS, …) ·
CLI: 0g infer · MCP: og_infer (MCP guide) ·
React: useInference. Template:
npx degit rajkaria/0gkit/templates/inference-app.
Exports
DEFAULT_FEE_WEI_PER_TOKENDEFAULT_MAX_OUTPUT_TOKENS__resetDeprecationWarningcountTokensmakeComputeEstimatepickProviderAddressselectProviderstoProviderInfotype ChatMessagetype ComputeConfigtype ComputeEstimatetype ComputeEstimateBreakdowntype InferenceArgstype InferenceResulttype ProviderInfotype RouterArgstype RouterResult