0gkitdocsGitHub

@foundryprotocol/0gkit-da

Neutral 0G Data Availability: deterministic digest, encoder publish, and a local integrity verify.

What it does

Computes a deterministic keccak256 digest of a payload (objects via canonical JSON, strings and bytes raw), optionally publishes the bytes to a 0G DA encoder, and verifies a payload against an expected digest locally (no network). With no encoder configured it runs in "local" digest mode — useful offline and in tests.

When to use it

  • Anchoring a payload's digest on-chain (the digest matches @foundryprotocol/0gkit-core's digestJson and on-chain keccak).
  • Publishing a blob to the 0G DA layer for availability.
  • Tamper-checking a payload you received against a digest you trust — verify() is a pure local integrity check.

Where to use it

Anywhere — pure viem + fetch. digest()/verify() are fully local (browser-safe). publish() needs network access to the encoder (or runs in local mode with no encoder).

Install

npm install @foundryprotocol/0gkit-da @foundryprotocol/0gkit-core viem

API reference

class DA

interface DAConfig {
  network?: "aristotle" | "galileo"; // selects the preset encoder URL
  encoderUrl?: string; // overrides the preset encoder
  apiKey?: string; // Bearer token for the encoder
  signer?: Signer; // accepted for symmetry with other primitives (reserved)
  fetch?: typeof fetch; // inject fetch (testing)
}
interface DAPublishResult {
  digest: Hex; // 0x… keccak256
  daRef?: string; // encoder ref (live mode)
  blobId?: string; // encoder blob id (live mode)
  mode: "live" | "local"; // "local" when no encoder is configured
  latencyMs: number;
  raw?: unknown;
}
new DA(config: DAConfig);

With no network and no encoderUrl, publish runs in "local" mode (digest only, no network). With a network, the encoder defaults to https://da-encoder.0g.network (aristotle) or https://da-encoder-testnet.0g.ai (galileo).

signer is accepted but reserved. The current DA encoder API uses bearer apiKey authentication, not a wallet signature. The signer field is accepted for constructor symmetry with other primitives and will be wired when DA introduces on-chain fee settlement. Passing one today has no effect.

da.digest(payload)

digest(payload: unknown): Hex;

keccak256 of the exact wire bytes: an object → keccak of the canonical-JSON encoding (identical to core's digestJson); a string → keccak of raw UTF-8; a Uint8Array → keccak of the raw bytes. Pure, local, never throws.

da.publish(payload)

publish(payload: unknown): Promise<DAPublishResult>;

Computes the digest, then (if an encoder is configured) POSTs the bytes to <encoder>/blob. Returns mode: "local" with just the digest when no encoder is set. Throws NetworkError if the encoder request fails or returns non-2xx.

da.verify(payload, expectedDigest)

verify(payload: unknown, expectedDigest: string): boolean;

Recomputes the digest and compares (case-insensitive). A local integrity check — no network. Throws ConfigError if expectedDigest is not a 32-byte 0x hex string.

Examples

Minimal — local digest + verify (no network, no keys)

import { DA } from "@foundryprotocol/0gkit-da";

const da = new DA({}); // no network ⇒ local mode
const payload = { model: "m1", score: 0.92 };

const { digest, mode } = await da.publish(payload);
console.log(mode); // "local"
console.log(da.verify(payload, digest)); // true
console.log(da.verify({ model: "m1", score: 0.93 }, digest)); // false

Realistic — publish to the testnet encoder with error handling

import { DA } from "@foundryprotocol/0gkit-da";
import { ZeroGError } from "@foundryprotocol/0gkit-core";

const da = new DA({ network: "galileo" }); // ⇒ testnet encoder, live mode

try {
  const res = await da.publish({ event: "eval", at: Date.now() });
  console.log(`mode ${res.mode} — digest ${res.digest}`);
  if (res.daRef) console.log(`daRef ${res.daRef} (${res.latencyMs} ms)`);

  // Later, anywhere, verify a copy of the payload against the digest:
  const ok = da.verify({ event: "eval", at: res.raw }, res.digest);
  console.log("integrity:", ok);
} catch (err) {
  if (err instanceof ZeroGError) {
    // NetworkError ⇒ encoder unreachable; ConfigError ⇒ bad digest format
    console.error(`[${err.code}] ${err.message}\n→ ${err.hint}`);
  } else {
    throw err;
  }
}

Common errors

SymptomCauseFix
ConfigError: expectedDigest is not a 32-byte 0x hex…Bad value passed to verify.Pass the value returned by da.digest() / publish().digest.
NetworkError: DA encoder request failed…Encoder unreachable.Check the encoder URL, or omit it for local-digest mode.
NetworkError: DA encoder returned HTTP …Encoder rejected the request.Verify the encoder URL / API key, or use local mode.

Related

core (digestJson matches da.digest) · CLI: 0g da · MCP: og_da_publish / og_da_verify (MCP guide). Template: npx degit rajkaria/0g-ai-kit/templates/attestation-verify.

Exports

  • DEFAULT_DA_RATE_WEI_PER_BYTE
  • estimateBytes
  • type DAConfig
  • type DAEstimate
  • type DAEstimateBreakdown
  • type DAPublishResult