Identity and provenance infrastructure for autonomous AI agents on 0G. Two permanent on-chain primitives — AgentPassport and ProvenanceRecord — that answer two questions any verifier needs: who produced this, and who authorized them.
Sigil separates two concerns that are always conflated in AI agent deployments: identity (who is this agent, who authorized it) and provenance (what did it produce, using which model, from which input).
AgentPassport
ERC-7857 iNFT
Minted once per agent. Binds a principal wallet to an agent wallet. Stores an encrypted permission manifest in 0G Storage. Tracks reputation, task count, and execution fingerprints on-chain.
ProvenanceRecord
On-chain notarization
Created on every consequential output. Stores output hash, input context hash (encrypted in 0G Storage), sealed inference receipt hash, EIP-712 agent signature, and a reverse lookup from output hash → record.
The two primitives are permanently linked. Every ProvenanceRecord references a passportId. Every AgentPassport maintains a count of its provenance records and execution fingerprints. Resolution works in both directions.
Dual Wallet Model
Sigil separates control from execution with two distinct wallets per agent.
Wallet
Role
Signs
Principal
Owns the iNFT, controls permissions
register() once at setup
Agent
Fresh keypair per passport, autonomous signer
Every notarize() call, autonomously
NOTEThe principal authorizes the agent exactly once at registration. After that, every notarization is signed by the agent autonomously — no per-output principal interaction. The principal can rotate or revoke the agent at any time via SigilRegistry.rotateAgentAddress() or revokeAgent().
Quick Start
Install
bash
pnpm add sigil-protocol ethers
Register an Agent (principal side)
register-agent.ts
import { Wallet } from "ethers";
import { SigilClient } from "sigil-protocol";
const principal = new Wallet(process.env.ZERO_G_PRIVATE_KEY!);
const sigil = new SigilClient({
rpcUrl: "https://evmrpc-testnet.0g.ai",
chainId: 16602,
registryAddress: "0x2C0457F82B57148e8363b4589bb3294b23AE7625",
notaryAddress: "0xA1103E6490ab174036392EbF5c798C9DaBAb24EE",
signer: principal,
});
const { passportId, agentAddress, agentPrivateKey } = await sigil.passport.register({
agentDescription: "Risk scoring agent for DeFi protocols",
permissions: {
whitelistedContracts: [],
maxTxValuePerWindow: { OG: 0 },
authorizedApis: ["0g.compute"],
allowedTokens: ["OG"],
timeWindowSeconds: 3600,
},
persistAs: "risk-agent", // writes public metadata to ~/.sigil/credentials/
});
// Store passportId and agentPrivateKey securely — key is returned once only
console.log("passportId:", passportId);
console.log("agentAddress:", agentAddress);
Notarize an Output (agent side)
notarize.ts
import { Wallet } from "ethers";
import { ArtifactType, SigilClient } from "sigil-protocol";
const agentWallet = new Wallet(process.env.SIGIL_AGENT_PRIVATE_KEY!);
const sigil = new SigilClient({ ...config, signer: agentWallet });
const record = await sigil.provenance.notarize({
passportId: process.env.SIGIL_PASSPORT_ID!,
inferenceReceipt, // from ZeroGComputeAdapter.runSealedInference()
inputContext: prompt, // encrypted before 0G Storage upload
output: response,
artifactType: ArtifactType.GENERIC_REPORT,
});
console.log("recordId:", record.recordId);
console.log("txHash: ", record.txHash);