Sigil Protocoldocs
ExplorerSKILL.md
SDK Reference

sigil-protocol SDK

TypeScript SDK for registering agent identities and notarizing outputs on 0G. Works in Node.js ≥ 20. Browser-compatible for read-only operations.

Installation

bash
pnpm add sigil-protocol ethers
# or
npm install sigil-protocol ethers

The SDK requires ethers@^6 as a peer dependency. It does not bundle ethers — your project supplies it.

SigilClient

The main entry point. Wraps all three sub-clients (passport, provenance, compute) and manages the 0G connections.

typescript
import { SigilClient } from "sigil-protocol";
import { Wallet } from "ethers";

const sigil = new SigilClient({
  rpcUrl: "https://evmrpc-testnet.0g.ai",
  chainId: 16602,
  registryAddress: "0x2C0457F82B57148e8363b4589bb3294b23AE7625",
  notaryAddress: "0xA1103E6490ab174036392EbF5c798C9DaBAb24EE",
  signer: wallet,                             // ethers Wallet or JsonRpcSigner
  storageRpcUrl: "https://indexer-storage-testnet-turbo.0g.ai",
  computeRpcUrl: "https://...",               // 0G Compute endpoint (optional)
  computeDefaultModel: "qwen/qwen-2.5-7b-instruct",
});
ParameterTypeDescription
rpcUrlrequiredstring0G Chain JSON-RPC endpoint
chainIdrequirednumberEVM chain ID (16602 for Galileo testnet)
registryAddressrequiredstringSigilRegistry contract address
notaryAddressrequiredstringProvenanceNotary contract address
signerrequiredWallet | JsonRpcSignerPrincipal wallet for registration, or agent wallet for notarization
storageRpcUrlstring0G Storage indexer URL
computeRpcUrlstring0G Compute broker URL
computeDefaultModelstringDefault model ID for sealed inference (e.g. qwen/qwen-2.5-7b-instruct)

AgentPassport

register()

Mints a new AgentPassport. Generates a fresh agent keypair, encrypts the permission manifest with AES-256-GCM (key derived from the principal's EIP-712 signature), uploads ciphertext to 0G Storage, then calls SigilRegistry.register() on-chain.

IMPORTANTThe returned agentPrivateKey is delivered exactly once. Store it immediately in a secrets manager or env var. Sigil never persists it.
typescript
const result = await sigil.passport.register({
  agentDescription: "DeFi risk scoring agent",
  permissions: {
    whitelistedContracts: ["0x..."],
    maxTxValuePerWindow: { USDC: 5000, ETH: 2 },
    authorizedApis: ["0g.compute", "uniswap.api"],
    allowedTokens: ["USDC", "ETH"],
    timeWindowSeconds: 3600,
  },
  persistAs: "risk-agent",          // optional: saves public metadata to ~/.sigil/credentials/
  credentialContext: {
    notaryAddress: "0x...",
    chainId: 16602,
    rpcUrl: "https://evmrpc-testnet.0g.ai",
  },
});

// result.passportId       — bytes32 on-chain ID
// result.agentAddress     — fresh agent wallet address
// result.agentPrivateKey  — store this once, immediately
// result.manifestRootHash — 0G Storage root hash of encrypted manifest
// result.txHash           — registration transaction hash
ParameterTypeDescription
agentDescriptionrequiredstringFree-text description ≤ 280 chars. Encrypted in the permission manifest.
permissionsrequiredPermissionManifestPlainThe agent's scope of authorization. Encrypted before upload.
persistAsstringIf set, writes a discoverability credential to ~/.sigil/credentials/<name>.json (public metadata only — no private key).
credentialContextobjectMetadata added to the credential file: notaryAddress, chainId, rpcUrl.
noncebigintOptional passportId nonce override. Default: cryptographic random.

resolve()

Read a PassportRecord from on-chain. Anyone can call this — no authentication required.

typescript
const passport = await sigil.passport.resolve(passportId);

passport.passportId             // bytes32
passport.principal              // principal wallet address
passport.agentAddress           // agent wallet address
passport.active                 // false after revokeAgent()
passport.reputationScore        // bigint, 0–1000
passport.taskCount              // number of keeper-attested tasks
passport.failureCount           // number of failed tasks
passport.provenanceRecordCount  // total notarized outputs
passport.executionFingerprintCount

getManifest()

Decrypt and return the permission manifest. Only succeeds if the configured signer is the principal that registered the passport — the AES-GCM key is derived from the principal's signature.

typescript
// signer must be the principal wallet
const manifest = await sigil.passport.getManifest(passportId);

manifest.agentDescription
manifest.permissions.whitelistedContracts
manifest.permissions.authorizedApis

ProvenanceNotary

notarize()

Notarize an AI-generated artifact on-chain. The signer must be the registered agent wallet for this passport. The method:

  1. Encrypts and uploads the input context to 0G Storage
  2. Builds a v2 provenance envelope wrapping the sealed receipt and raw output
  3. Uploads the envelope to 0G Storage
  4. Signs an EIP-712 typed-data payload
  5. Calls ProvenanceNotary.notarize() on-chain
  6. Optionally triggers the auto-attest sidecar (reputation update)
typescript
const result = await agentSigil.provenance.notarize({
  passportId,
  inferenceReceipt,       // SealedInferenceReceipt from 0G Compute
  inputContext: prompt,   // plaintext — encrypted before upload
  output: response,       // plaintext — hashed on-chain
  artifactType: ArtifactType.GENERIC_REPORT,
});

result.recordId             // bytes32 — permanent record identifier
result.txHash               // on-chain transaction hash
result.outputHash           // keccak256 of the output
result.inputContextHash     // keccak256 of the ciphertext
result.proofRootHash        // 0G Storage root hash of the proof envelope
result.attestation?.txHash  // auto-attest sidecar tx (if configured)
ParameterTypeDescription
passportIdrequiredPassportIdThe agent's passport identifier (bytes32)
inferenceReceiptrequiredSealedInferenceReceiptReceipt from ZeroGComputeAdapter.runSealedInference() or a manually constructed receipt
inputContextrequiredstringThe input prompt or context. Encrypted with HKDF-derived AES-256-GCM key before upload.
outputrequiredstringThe model output or artifact text. Hashed on-chain; also inlined in the proof envelope.
artifactTyperequiredArtifactTypeArtifact category enum (CODE_AUDIT, RISK_ASSESSMENT, GENERIC_REPORT, etc.)

resolve()

typescript
const record = await sigil.provenance.resolve(recordId);

record.recordId
record.passportId
record.principal    // principal at notarization time
record.agent        // agent wallet address
record.modelId      // e.g. "qwen/qwen-2.5-7b-instruct"
record.outputHash
record.artifactType
record.timestamp

resolveFull()

Resolve on-chain record + download proof envelope from 0G Storage + (optionally) decrypt input context.

typescript
const full = await agentSigil.provenance.resolveFull(recordId);

full.record           // on-chain ProvenanceRecord
full.proofEnvelope    // parsed JSON proof envelope from 0G Storage
full.output           // raw output text (v2 envelopes only)
full.envelopeSchema   // "sigil.provenance-envelope/2"
full.inputContext     // decrypted input context (only if signer is the agent)

verify()

typescript
const { valid, reason } = await sigil.provenance.verify(recordId);
// valid: boolean — signature + hash consistency check
// reason: string — explanation if invalid

ZeroGComputeAdapter

Runs sealed inference on 0G Compute and returns a cryptographic receipt binding the model, input, and output.

typescript
const { output, receipt } = await sigil.compute.runSealedInference({
  model: "qwen/qwen-2.5-7b-instruct",
  messages: [
    { role: "system", content: "You are a DeFi risk analyst." },
    { role: "user",   content: prompt },
  ],
  maxTokens: 2048,
});

// Pass receipt directly to notarize()
await agentSigil.provenance.notarize({ ..., inferenceReceipt: receipt, output });
TIPLive model IDs on 0G Galileo testnet: qwen/qwen-2.5-7b-instruct. The vendor prefix is required — passing qwen-2.5-7b-instruct without the prefix will not match the on-chain broker listing.

Credentials

The persistAs option in register() writes a discoverability file. Agent runtimes can later read it without re-scanning the chain.

typescript
import { readCredential, listCredentials } from "sigil-protocol";

// Read a specific credential
const me = readCredential("risk-agent");
console.log(me.passportId);
console.log(me.agentAddress);
console.log(me.principal);

// List all stored credentials
const all = listCredentials();

Credentials are stored at ~/.sigil/credentials/<name>.json. They contain only public metadata — never the agent private key.

Key Types

typescript
// From "sigil-protocol"

enum ArtifactType {
  CODE_AUDIT = 0,
  CONTRACT_CLAUSE = 1,
  RISK_ASSESSMENT = 2,
  FINANCIAL_MODEL = 3,
  DUE_DILIGENCE = 4,
  GOVERNANCE_ANALYSIS = 5,
  GENERIC_REPORT = 6,
}

enum AttestationType {
  DEFI_REBALANCE = 0,
  CODE_AUDIT = 1,
  RISK_ASSESSMENT = 2,
  DATA_ENRICHMENT = 3,
  GOVERNANCE_VOTE = 4,
  GENERIC_TASK = 5,
}

interface SealedInferenceReceipt {
  modelId: string;
  modelVersionHash: string;
  inputHash: string;
  outputHash: string;
  proof: string;   // JSON string — cryptographic binding
  timestamp: number;
}

interface PermissionManifestPlain {
  version: string;
  agentDescription: string;
  whitelistedContracts: string[];
  maxTxValuePerWindow: Record<string, number>;
  authorizedApis: string[];
  allowedTokens: string[];
  timeWindowSeconds: number;
}

Error Handling

typescript
import { SigilError, RegistryError, ProvenanceError } from "sigil-protocol";

try {
  await sigil.passport.resolve(passportId);
} catch (err) {
  if (err instanceof RegistryError) {
    // PassportNotFound, NotAuthorizedSigner, etc.
  }
  if (err instanceof SigilError) {
    // Base Sigil error
  }
}