import { PublicClient, WalletClient, Chain, Hex } from 'viem'; import { ZodRawShape, z } from 'zod'; declare const ERROR_CODES: readonly ["CONFIG_MISSING_ENV", "CONFIG_INVALID_NETWORK", "CONFIG_INVALID_ADDRESS", "CONFIG_INVALID_ARGUMENT", "WALLET_NO_PRIVATE_KEY", "WALLET_KMS_SIGN_FAILED", "WALLET_KMS_PUBKEY_FAILED", "WALLET_BAD_DER_SIGNATURE", "WALLET_NO_CONNECTOR", "WALLET_CHAIN_MISMATCH", "CHAIN_RPC_UNREACHABLE", "CHAIN_RPC_TIMEOUT", "CHAIN_TX_REVERTED", "CHAIN_TX_TIMEOUT", "CHAIN_INSUFFICIENT_FUNDS", "CHAIN_NONCE_TOO_LOW", "STORAGE_QUOTA_EXCEEDED", "STORAGE_UPLOAD_FAILED", "STORAGE_DOWNLOAD_FAILED", "STORAGE_ROOT_NOT_FOUND", "STORAGE_ROOT_MISMATCH", "STORAGE_INVALID_BYTES", "COMPUTE_PROVIDER_UNREACHABLE", "COMPUTE_NO_PROVIDER", "COMPUTE_INFERENCE_FAILED", "COMPUTE_BAD_ATTESTATION", "COMPUTE_BUDGET_EXCEEDED", "DA_PUBLISH_FAILED", "DA_VERIFY_FAILED", "DA_INVALID_PAYLOAD", "ATTESTATION_BAD_SIGNATURE", "ATTESTATION_BAD_PAYLOAD", "ATTESTATION_EXPIRED", "CONTRACTS_REVERTED", "CONTRACTS_NO_ADDRESS", "CONTRACTS_ABI_MISMATCH", "CONTRACTS_CODEGEN_FAILED", "INDEXER_REORG_LIMIT_EXCEEDED", "INDEXER_CURSOR_BACKEND_UNREACHABLE", "INDEXER_EVENT_DECODE_FAILED", "JOBS_BACKEND_UNREACHABLE", "JOBS_JOB_NOT_FOUND", "JOBS_HANDLER_THREW", "JOBS_WEBHOOK_BAD_SIGNATURE", "OBSERVABILITY_EXPORTER_FAILED", "OBSERVABILITY_TRACE_DIR_NOT_SET", "OBSERVABILITY_TRACE_NOT_FOUND", "OBSERVABILITY_TRACE_READ_FAILED"]; type ErrorCode = (typeof ERROR_CODES)[number]; declare function isErrorCode(v: string): v is ErrorCode; declare function errorNamespace(code: ErrorCode): string; /** * The canonical base for every `ZeroGError.helpUrl`. Concatenated with the * error `code` to produce a stable, frozen-in-tarball remediation URL. * * See `docs/DECISIONS.md` D38. If this ever needs to move, only this * constant changes — the URL is derived, never hard-coded at throw sites. */ declare const ERROR_HELP_BASE = "https://0gkit.com/errors/"; declare function helpUrlFor(code: ErrorCode): string; /** * Base error for everything 0gkit throws. Every error carries: * - a canonical `code` from the {@link ErrorCode} enum * - an actionable `hint` (the exact remedy) * - a `helpUrl` pointing at the docs page for that code * * No 0gkit code path ever fails silently. */ declare class ZeroGError extends Error { readonly code: ErrorCode; readonly hint: string; readonly helpUrl: string; constructor(code: ErrorCode, message: string, hint: string); toJSON(): { name: string; code: "CONFIG_MISSING_ENV" | "CONFIG_INVALID_NETWORK" | "CONFIG_INVALID_ADDRESS" | "CONFIG_INVALID_ARGUMENT" | "WALLET_NO_PRIVATE_KEY" | "WALLET_KMS_SIGN_FAILED" | "WALLET_KMS_PUBKEY_FAILED" | "WALLET_BAD_DER_SIGNATURE" | "WALLET_NO_CONNECTOR" | "WALLET_CHAIN_MISMATCH" | "CHAIN_RPC_UNREACHABLE" | "CHAIN_RPC_TIMEOUT" | "CHAIN_TX_REVERTED" | "CHAIN_TX_TIMEOUT" | "CHAIN_INSUFFICIENT_FUNDS" | "CHAIN_NONCE_TOO_LOW" | "STORAGE_QUOTA_EXCEEDED" | "STORAGE_UPLOAD_FAILED" | "STORAGE_DOWNLOAD_FAILED" | "STORAGE_ROOT_NOT_FOUND" | "STORAGE_ROOT_MISMATCH" | "STORAGE_INVALID_BYTES" | "COMPUTE_PROVIDER_UNREACHABLE" | "COMPUTE_NO_PROVIDER" | "COMPUTE_INFERENCE_FAILED" | "COMPUTE_BAD_ATTESTATION" | "COMPUTE_BUDGET_EXCEEDED" | "DA_PUBLISH_FAILED" | "DA_VERIFY_FAILED" | "DA_INVALID_PAYLOAD" | "ATTESTATION_BAD_SIGNATURE" | "ATTESTATION_BAD_PAYLOAD" | "ATTESTATION_EXPIRED" | "CONTRACTS_REVERTED" | "CONTRACTS_NO_ADDRESS" | "CONTRACTS_ABI_MISMATCH" | "CONTRACTS_CODEGEN_FAILED" | "INDEXER_REORG_LIMIT_EXCEEDED" | "INDEXER_CURSOR_BACKEND_UNREACHABLE" | "INDEXER_EVENT_DECODE_FAILED" | "JOBS_BACKEND_UNREACHABLE" | "JOBS_JOB_NOT_FOUND" | "JOBS_HANDLER_THREW" | "JOBS_WEBHOOK_BAD_SIGNATURE" | "OBSERVABILITY_EXPORTER_FAILED" | "OBSERVABILITY_TRACE_DIR_NOT_SET" | "OBSERVABILITY_TRACE_NOT_FOUND" | "OBSERVABILITY_TRACE_READ_FAILED"; message: string; hint: string; helpUrl: string; }; } declare class ConfigError extends ZeroGError { constructor(message: string, hint: string, code?: ErrorCode); } declare class NetworkError extends ZeroGError { constructor(message: string, hint: string, code?: ErrorCode); } declare class ChainError extends ZeroGError { constructor(message: string, hint: string, code?: ErrorCode); } declare class AttestationError extends ZeroGError { constructor(message: string, hint: string, code?: ErrorCode); } type NetworkName = "aristotle" | "galileo" | "local"; interface NetworkPreset { /** Stable key. */ readonly name: NetworkName; /** EVM chain id. `undefined` ⇒ createClient throws ConfigError. */ readonly chainId?: number; /** EVM JSON-RPC URL. `undefined` ⇒ createClient throws ConfigError. */ readonly rpcUrl?: string; /** Block-explorer base, NO trailing slash. `undefined` ⇒ explorerUrl() throws. */ readonly explorer?: string; /** Programmatic faucet endpoint (testnet). `undefined` ⇒ faucet() throws. */ readonly faucetUrl?: string; /** Human faucet page, surfaced in faucet()'s error hint. */ readonly faucetWebUrl?: string; /** True for non-production networks. */ readonly testnet: boolean; } declare const aristotle: NetworkPreset; declare const galileo: NetworkPreset; declare const local: NetworkPreset; declare const networks: Record; declare function getNetwork(name: NetworkName): NetworkPreset; /** * Uniform result envelope returned by every 0gkit operation that touches * the chain. `explorerUrl` is only present when the active network preset * has a verified explorer base. `attestation` is opaque here; the * @foundryprotocol/0gkit-attestation package gives it a concrete type. */ interface Receipt { /** * Transaction hash. Typed as `\`0x${string}\` | string`: the template-literal * half documents the expected hex shape, while `| string` is a deliberate * escape hatch so untyped sources (e.g. a JSON/HTTP faucet response) can be * assigned without a cast. Not vacuous — intentional ergonomics. */ txHash?: `0x${string}` | string; explorerUrl?: string; blockNumber?: bigint; latencyMs: number; attestation?: unknown; } interface CreateClientOptions { network: NetworkName; /** Overrides the preset RPC. Required if the preset has no rpcUrl. */ rpcUrl?: string; /** Overrides the preset chain id. Required if the preset has no chainId. */ chainId?: number; /** * Private key for signing. The leading `0x` is optional — it is added * automatically. When set, a wallet client is also returned. */ privateKey?: string; } interface ZeroGClient { network: NetworkPreset; public: PublicClient; wallet?: WalletClient; } /** Build a viem Chain from a preset (+ optional overrides). */ declare function buildChain(preset: NetworkPreset, rpcUrl?: string, chainId?: number): Chain; declare function createClient(opts: CreateClientOptions): ZeroGClient; /** * Deterministic JSON: object keys sorted recursively, no whitespace. Two * logically-equal objects always produce the identical string (and digest), * regardless of key insertion order. Arrays keep their order. */ declare function canonicalJsonStringify(value: unknown): string; /** keccak256 of the canonical JSON encoding — the cross-package digest. */ declare function digestJson(value: unknown): Hex; /** * The neutral signer abstraction shared by every 0gkit primitive. * * Implementations live in `@foundryprotocol/0gkit-wallet` * (`fromPrivateKey` / `fromFile` / `fromEnv` / `fromKMS`) and * `@foundryprotocol/0gkit-wallet-react` (wagmi-backed). * * Primitives import only this type — they never depend on the wallet package * at build time, keeping the dependency graph acyclic. */ interface Signer { /** EIP-55 checksummed address (or lowercased 0x; both accepted by recipients). */ readonly address: `0x${string}`; /** * EIP-191 personal-sign over arbitrary bytes (or a pre-hashed `{raw}` * structure that matches viem's `SignableMessage` type). */ signMessage(bytes: string | Uint8Array | { raw: `0x${string}` | Uint8Array; }): Promise<`0x${string}`>; /** EIP-712 typed-data sign. */ signTypedData(args: SignTypedDataArgs): Promise<`0x${string}`>; /** Broadcast a transaction. Returns the tx hash. */ sendTransaction(tx: SignableTx): Promise<`0x${string}`>; /** * Optional: a raw private-key passthrough for legacy adapters (the existing * `0gkit-storage` / `0gkit-compute` paths that wrap ethers internally). * Loaders that hold the plaintext key (`fromPrivateKey`, `fromFile`, * `fromEnv` when reading PRIVATE_KEY) expose it; KMS-backed signers do not. */ readonly privateKey?: `0x${string}`; /** Loader provenance tag — useful for logging/observability. */ readonly source: "private-key" | "file" | "env" | "kms" | "wagmi" | "custom" | (string & {}); } interface SignTypedDataArgs { domain: { name?: string; version?: string; chainId?: number | bigint; verifyingContract?: `0x${string}`; salt?: `0x${string}`; }; types: Record>; primaryType: string; message: Record; } interface SignableTx { to?: `0x${string}`; value?: bigint; data?: `0x${string}`; gas?: bigint; gasPrice?: bigint; maxFeePerGas?: bigint; maxPriorityFeePerGas?: bigint; nonce?: number; chainId?: number; } /** * Common cost-estimate envelope used by every 0gkit primitive's `.estimate()`. * `kind` discriminates the breakdown shape; `gas` is units, `fee` is wei. * `expectedSeconds` is best-effort latency (e.g. block time or polling round-trip). */ interface Estimate { readonly kind: "storage" | "compute" | "da" | "contract"; readonly gas: bigint; readonly fee: bigint; readonly breakdown: Record; readonly expectedSeconds?: number; } /** * Returned by every write path when called with `{ dryRun: true }`. * The `result` field carries the same shape the success path would have * returned, but with no broadcast: `txHash` and any chain-side identifiers * are `undefined`. `estimate` is always populated. */ interface DryRunResult { readonly dryRun: true; readonly estimate: Estimate; readonly result: T; } /** * Human-readable wei → " 0G". * Picks 4/6/9 decimal places by magnitude; falls back to scientific notation * for sub-gwei values so the rendering never collapses to "0". */ declare function formatNative(wei: bigint): string; /** * Render an Estimate as an aligned key/value block. JSON callers should use * the structured Estimate directly; this is for human CLI output. */ declare function formatEstimate(est: Estimate): string; interface DefineConfigOptions { server?: ZodRawShape; client?: ZodRawShape; edge?: ZodRawShape; } interface DefinedConfig { server: (env?: Record) => SchemaOf; client: (env?: Record) => SchemaOf; edge: (env?: Record) => SchemaOf; envExample: () => string; } type SchemaOf = S extends ZodRawShape ? z.infer> : Record; declare function define0GConfig(opts: O): DefinedConfig; interface ProbeClient { getChainId: () => Promise; } interface DetectLocalDevnetOptions { rpcUrl?: string; timeoutMs?: number; probeClient?: (rpcUrl: string) => ProbeClient; } declare function detectLocalDevnet(opts?: DetectLocalDevnetOptions): Promise; declare const FIRST_SUCCESS_MARKER = "[0gkit:first-success]"; interface FirstSuccessArgs { op: string; id: string; note?: string; } declare function printFirstSuccess(args: FirstSuccessArgs, sink?: (line: string) => void): void; /** * Defect intelligence helpers — turn a {@link ZeroGError} into a ready-to-file * bug report in the shape the 0G ecosystem QA program expects. * * Background: the 0G APAC app-test effort (github.com/lvxuan149/0g-apac-app-test) * files reproducible defects against a fixed bilingual template and routes each * to an ownership bucket. Most of that template — environment, root-cause, * ownership, a starting severity — is already knowable from a 0gkit error. * {@link buildDefectReport} fills those fields so a tester (or a 0gkit-based * dApp itself) emits a half-complete, reproducible defect instead of prose. * * This lives in `0gkit-core` (not the CLI) on purpose: a browser dApp built on * a 0gkit template can call it from a global error handler exactly as the CLI * does on a thrown error. Framework-agnostic, zero deps. */ /** Routing bucket from the QA template. */ type DefectOwnership = "App Suite" | "0G Infra" | "生态 dApp" | "Hackathon项目"; /** Severity scale from the QA template. */ type DefectSeverity = "P1" | "P2" | "P3" | "P4"; /** * Suggest the ownership bucket for an error code. Infra-class failures * (chain/storage/compute/DA/attestation/indexer) → `0G Infra`; integration, * config, wallet, contracts, jobs and observability failures are the app's own * → `Hackathon项目`. `App Suite` / `生态 dApp` are never auto-suggested (they * describe 0G's own and third-party apps, not a 0gkit consumer) but remain * valid manual overrides. */ declare function suggestOwnership(code: ErrorCode): DefectOwnership; /** * Suggest a starting severity for an error code. This is a heuristic default — * the QA template requires a human to confirm severity against observed impact, * so {@link buildDefectReport} always labels the value as suggested. Anything * not classified as a blocker (P1) or caller-fixable (P3) defaults to P2; P4 is * reserved for manual downgrade of cosmetic issues. */ declare function suggestSeverity(code: ErrorCode): DefectSeverity; /** The error being reported. Accepts a {@link ZeroGError} or its `toJSON()` shape. */ interface DefectReportError { code: ErrorCode; message: string; hint?: string; helpUrl?: string; } /** Environment slots for the `环境` line. Render only the ones provided. */ interface DefectReportEnv { browser?: string; wallet?: string; chainId?: number | string; network?: string; /** Free-form runtime note for non-browser callers, e.g. `node v22 / darwin 25`. */ runtime?: string; } interface DefectReportInput { error: DefectReportError; /** Product / app name noted after the ownership bucket, e.g. `Foundry Protocol`. */ product?: string; /** Override the suggested ownership bucket. */ ownership?: DefectOwnership; /** Override the suggested severity. */ severity?: DefectSeverity; /** Environment context for the `环境` line. */ env?: DefectReportEnv; /** Override the title; defaults to the error message. */ title?: string; } /** * Render a defect report in the 0G QA template shape (bilingual field labels). * Auto-fills ownership, severity (suggested), environment, actual-result and * root-cause from the error; leaves the human-judgment fields (repro steps, * expected result, screenshot) as TODO placeholders. The output drops straight * into the QA program's defect log. */ declare function buildDefectReport(input: DefectReportInput): string; export { AttestationError, ChainError, ConfigError, type CreateClientOptions, type DefectOwnership, type DefectReportEnv, type DefectReportError, type DefectReportInput, type DefectSeverity, type DefineConfigOptions, type DefinedConfig, type DetectLocalDevnetOptions, type DryRunResult, ERROR_CODES, ERROR_HELP_BASE, type ErrorCode, type Estimate, FIRST_SUCCESS_MARKER, type FirstSuccessArgs, NetworkError, type NetworkName, type NetworkPreset, type Receipt, type SignTypedDataArgs, type SignableTx, type Signer, type ZeroGClient, ZeroGError, aristotle, buildChain, buildDefectReport, canonicalJsonStringify, createClient, define0GConfig, detectLocalDevnet, digestJson, errorNamespace, formatEstimate, formatNative, galileo, getNetwork, helpUrlFor, isErrorCode, local, networks, printFirstSuccess, suggestOwnership, suggestSeverity };