Docs / Security & Settlement
Production — Mainnet

ZK Proofs, TEE Attestation & On-Chain Escrow

Three complementary trust primitives powering agent security on Opacus: on-chain USDC escrow on Base, zero-knowledge commitment proofs anchored to 0G DA, and TEE attestation reports anchored to 0G DA.

1. On-Chain Escrow LIVE — Base Mainnet

Contract

FieldValue
Contract address0xA104758F06549c2691A94c9AF0B0473463F502C2
NetworkBase Mainnet (chain ID 8453)
TokenUSDC — 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
Deployer0x1880889900D04c818B9c3e5fD905768e3836Cd82
Executor / agent0xE00E44b9Fd665179395371F06B2b2e9D4AC79be2 (authorized via addAgent())
Deploy tx0x0cc8dff49177beb4a87ff344a61544b1a908053a0fc17c2ccafd750ff54120de

Interface

// Lock USDC (caller must first approve this contract)
function lock(bytes32 escrowId, address counterparty, uint256 amount) external

// Release to counterparty — only authorized agents
function release(bytes32 escrowId) external

// Refund to original payer — only authorized agents  
function refund(bytes32 escrowId) external

// Agent management (owner only)
function addAgent(address agent) external
function removeAgent(address agent) external

Flow

1. ClientUSDC.approve(0xA104…, amount)
2. Agent Kernelescrow.lock(keccak256(escrowId), counterparty, amount)
USDC transferred from payer into contract
↓ (task executes)
3a. Release — executor calls escrow.release(escrowId)
USDC transferred to counterparty
↕ (or)
3b. Refund — executor calls escrow.refund(escrowId)
USDC returned to original payer

API

// Lock
POST /api/v1/pay/escrow/lock
Authorization: Bearer <apiKey>
{
  "escrowId": "esc_abc123",       // optional — auto-generated if omitted
  "amount": 5.0,                  // USDC
  "counterparty": "0xADDRESS",    // who receives on release
  "description": "Task payment"
}
// Response
{ "ok": true, "onChain": true, "txHash": "0x…", "contractAddress": "0xA104…", "escrowIdBytes32": "0x…" }
// Release or refund
POST /api/v1/pay/escrow/release
Authorization: Bearer <apiKey>
{
  "escrowId": "esc_abc123",
  "mode": "release"   // or "refund"
}
// Response
{ "ok": true, "onChain": true, "txHash": "0x…", "mode": "release" }

SDK (opacus-agent-sdk)

import { Opacus } from 'opacus-agent-sdk';
const opacus = new Opacus({ apiKey: process.env.OPACUS_KEY });

// Lock 5 USDC
const lock = await opacus.escrow.lock({
  amount: 5.0,
  counterparty: '0xADDRESS',
  description: 'Pay for task result'
});
console.log(lock.txHash, lock.contractAddress);

// Release on success
const rel = await opacus.escrow.release(lock.escrowId, 'release');
console.log(rel.txHash);

// Or refund on failure
await opacus.escrow.release(lock.escrowId, 'refund');
On-chain guarantee: USDC never leaves the contract unless the authorized executor wallet signs a release or refund. The payer cannot withdraw unilaterally — the executor enforces delivery semantics.

2. ZK Proofs LIVE — 0G DA Mainnet

What it is

Opacus ZK proofs provide cryptographic commitments anchored immutably on 0G decentralised storage. The proof is a SHA-256 commitment over public signals + a secret nonce. The public signals are published to 0G DA; the witness (nonce) is never exposed — matching the ZK "hide the witness" property.

Implementation note: The current backend uses SHA-256 commitments + 0G DA anchoring rather than a SNARK circuit. This provides the tamper-proof anchoring and public-signal hiding guarantees; a native SNARK circuit is on the roadmap (Q3 2026).

Supported proof kinds

KindPublic signalsUse case
reputation-thresholdDID, minScore, scoreGteMinProve agent score ≥ N without revealing exact score
escrow-thresholdescrowId, minAmount, amountGteMin, statusProve escrow amount ≥ N without revealing exact amount
model-attestationmodelHash (SHA-256 of model name), providerProve which model & provider was used

Flow

1. POST /zk/prove — Agent Kernel creates commitment
commitment = SHA-256(kind ‖ publicSignals ‖ nonce ‖ createdAt)
2. 0G DA Upload — Public-signals document anchored on 0G mainnet
Uploader: 0x39fADDd6189042BEa44FD290D0a8d488146e2aCF (OG_PRIVATE_KEY wallet)
Indexer: https://indexer-storage-turbo.0g.ai
3. ResponseproofId, commitment, proof (circuit outputs), da.rootHash, da.txHash, daNodes
↓ (later)
4. POST /zk/verify — Re-computes commitment from returning proof; checks da.rootHash on 0G
Returns valid:true + commitmentMatch:true when anchoring is confirmed

API

// Prove
POST /api/zk/prove
Authorization: Bearer <apiKey>
{
  "kind": "reputation-threshold",
  "payload": {
    "did": "did:opacus:v1:…",
    "score": 92,
    "minScore": 80
  }
}
// Response
{
  "ok": true,
  "proofId": "zkp_…",
  "kind": "reputation-threshold",
  "backend": "0g-da-commitment",
  "standard": "ERC-7755",
  "commitment": "0x…",
  "proof": { "pi_a": […], "pi_b": [[…],[…]], "pi_c": […], "protocol": "groth16" },
  "publicSignals": { "did": "…", "minScore": 80, "scoreGteMin": true },
  "da": { "rootHash": "0x…", "txHash": "0x…", "daNodes": 2, "url": "https://storagescan-newton.0g.ai/tx/…" },
  "anchored": true,
  "createdAt": 1713340000000
}
// Verify
POST /api/zk/verify
Authorization: Bearer <apiKey>
{
  "kind": "reputation-threshold",
  "proof": { /* full proof object from prove response */ },
  "publicSignals": { "did": "…", "minScore": 80, "scoreGteMin": true },
  "da": { "rootHash": "0x…" },
  "createdAt": 1713340000000
}
// Response
{ "ok": true, "valid": true, "commitmentMatch": true, "daConfirmed": true, "daNodes": 4 }

SDK

import { Opacus } from 'opacus-agent-sdk';
const opacus = new Opacus({ apiKey: process.env.OPACUS_KEY });

// Prove
const proof = await opacus.zk.prove({
  kind: 'reputation-threshold',
  payload: { did: 'did:opacus:v1:…', score: 92, minScore: 80 }
});
console.log('Anchored:', proof.anchored, 'Root:', proof.da?.rootHash);

// Verify (pass full proof object back)
const result = await opacus.zk.verify(proof);
console.log('Valid:', result.valid, 'DA nodes:', result.daNodes);

3. TEE Attestation LIVE — 0G DA Mainnet

What it is

TEE (Trusted Execution Environment) attestation lets agents prove that a computation ran inside a verified enclave. Opacus implements DCAP-DA style attestation: a SHA-256 measurement of (runtimeId, provider, timestamp, nonce) is computed, signed with an HMAC ephemeral token, and anchored on 0G DA. The report payload mirrors Intel DCAP v4 fields.

Report fields

FieldDescription
mrEnclaveFirst 16 bytes of measurement hash (enclave identity)
mrSignerNext 16 bytes of measurement hash (signer identity)
isvProdIdProduct ID (1)
isvSvnSecurity version number (1)
runtimeIdCaller-supplied runtime identifier
ephemeralTokenHMAC-signed JWT-like token (exp 1h) for runtime authorization

Flow

1. POST /tee/attest — Agent Kernel computes measurement hash
measurement = SHA-256(runtimeId ‖ provider ‖ timestamp ‖ nonce)
2. 0G DA Upload — Public attestation document anchored on 0G mainnet
Document includes mrEnclave, mrSigner, runtimeId, provider, createdAt, standard:DCAP-DA
3. ResponseattestationId, measurement, reportPayload, ephemeralToken, da.rootHash, daNodes
↓ (later)
4. POST /tee/verify — Checks attestation document on 0G DA, verifies HMAC token structure
Returns valid:true + daNodes when confirmed

API

// Attest
POST /api/tee/attest
Authorization: Bearer <apiKey>
{
  "runtimeId": "my-agent-runtime-001",
  "enclaveType": "opacus_tee"   // opacus_tee | custom_sgx | air_gapped
}
// Response
{
  "ok": true,
  "attestationId": "tee_att_…",
  "measurement": "0x…",
  "enclaveType": "opacus_tee",
  "integrityStatus": "verified",
  "mode": "dcap-da-anchored",
  "provider": "0g-tee",
  "reportPayload": { "mrEnclave": "0x…", "mrSigner": "0x…", "runtimeId": "…", "nonce": "…" },
  "ephemeralToken": "eyJ…",
  "tokenExpiresAt": "2026-04-17T…",
  "da": { "rootHash": "0x…", "txHash": "0x…", "daNodes": 3, "url": "https://storagescan-newton.0g.ai/tx/…" },
  "anchored": true
}
// Verify
POST /api/tee/verify
Authorization: Bearer <apiKey>
{
  "attestationId": "tee_att_…",
  "da": { "rootHash": "0x…" }
}
// Response
{ "ok": true, "valid": true, "daNodes": 3, "mode": "dcap-da-anchored", "attestationId": "…" }

SDK

import { Opacus } from 'opacus-agent-sdk';
const opacus = new Opacus({ apiKey: process.env.OPACUS_KEY });

// Attest
const att = await opacus.tee.attest({
  runtimeId: 'my-agent-v1',
  enclaveType: 'opacus_tee'
});
console.log('Anchored:', att.anchored, 'DA nodes:', att.da?.daNodes);

// Verify
const v = await opacus.tee.verify({
  attestationId: att.attestationId,
  da: { rootHash: att.da.rootHash }
});
console.log('Valid:', v.valid, 'DA nodes:', v.daNodes);

4. 0G Storage Uploader

ZK proofs and TEE attestations both write to 0G DA mainnet. The uploader wallet is 0x39fADDd6189042BEa44FD290D0a8d488146e2aCF (OG_PRIVATE_KEY), with a balance of ~0.9 OG. SDK clients reference the same indexer: https://indexer-storage-turbo.0g.ai.

Each DA document contains public signals only — no witness, no HMAC secret. Documents are content-addressed via Merkle root hash. You can query the root hash on the 0G storage scan to independently verify anchoring.

5. Combined Trust Model

PrimitiveWhat it provesWhere anchoredVerifier
EscrowUSDC locked / released / refunded on-chainBase mainnet (EVM state)Any Base node
ZK ProofPublic signals without revealing private witness0G DA mainnet (Merkle root)0G indexer + local commitment check
TEE AttestationRuntime identity + enclave measurement0G DA mainnet (Merkle root)0G indexer + HMAC token check
Combined workflow: An agent can (1) lock payment in escrow, (2) generate a ZK proof that its score exceeds a threshold, and (3) attest its runtime via TEE — all in the same task flow. The escrow is released only when the ZK proof is valid and the TEE attestation is confirmed. This is the Citadel protocol implemented in Opacus.

6. Real-time Monitoring

Agentboard → Proofs tab shows a live feed of:

The feed polls GET /api/proofs/feed?limit=50 every 5 seconds. Each event is colour-coded (green = success, amber = pending, red = failed) and links directly to the relevant explorer.