Integration

Integrating TrustGate

Two ways to consume TrustGate. Read trust scores from the public oracle to gate agent-to-agent commerce in your own protocol, or call the contracts directly from another contract or backend.

Pattern 1 — Oracle-as-a-service

Hit the public oracle, settle 0.001 USDC per query, get a typed score back. Best for off-chain agents and backend services that need to gate behaviour on counterparty trust.

TypeScript / Node

import { fetch } from "undici";

const ORACLE = process.env.NEXT_PUBLIC_ORACLE_URL!;

async function getTrust(address: string) {
  // Step 1 — challenge
  const challenge = await fetch(`${ORACLE}/trust/${address}`);
  if (challenge.status === 200) return challenge.json();

  if (challenge.status !== 402) {
    throw new Error(`Oracle error ${challenge.status}`);
  }

  const requirement = await challenge.json();

  // Step 2 — settle the 0.001 USDC payment on Arc
  const txHash = await sendUsdcToOracle({
    to: requirement.recipient,
    amount: requirement.amount,
    memo: requirement.memo,
  });

  // Step 3 — replay with X-Payment proof
  const paid = await fetch(`${ORACLE}/trust/${address}`, {
    headers: {
      "X-Payment": Buffer.from(JSON.stringify({ txHash })).toString("base64"),
    },
  });

  return paid.json();
}

const trust = await getTrust("0x60C05e2d820CE989E944ED4e7bb33bAEB8705c62");
if (trust.tier === "HIGH" || trust.tier === "HIGH_ELITE") {
  // proceed instantly
} else if (trust.tier === "MEDIUM") {
  // proceed but expect a 24h hold on settlement
} else {
  // require manual review
}

See API Reference for the full request and response shapes, including batch scoring up to ten addresses in a single payment.

Pattern 2 — Contract integration

Call AgentRegistry and TrustScoring directly from your own contract. Suitable for protocols that want to gate access at the contract level without depending on an offchain oracle.

Reading a tier from another contract

interface ITrustScoring {
  function getTrustTierPlaintext(address account) external view returns (uint8);
  function hasScore(address account) external view returns (bool);
}

contract MyProtocol {
  ITrustScoring public immutable trust;

  constructor(address trustAddr) { trust = ITrustScoring(trustAddr); }

  modifier onlyHighTrust(address agent) {
    require(trust.hasScore(agent), "unscored");
    require(trust.getTrustTierPlaintext(agent) >= 2, "not high trust");
    _;
  }
}

Tier values are 0 = LOW, 1 = MEDIUM, 2 = HIGH. HIGH_ELITE shares the on-chain tier with HIGH — the elite distinction is only relevant in UI surfaces.

Registering agents programmatically

Any wallet or contract can register agents by calling AgentRegistry.registerAgent(agent, metadataURI). The msg.sender becomes the agent owner and gains lifecycle control:

import { writeContract } from "@wagmi/core";
import { agentRegistryAbi } from "./abi/AgentRegistry";

await writeContract({
  address: "0x73d3cf7f2734C334927f991fe87D06d595d398b4",
  abi: agentRegistryAbi,
  functionName: "registerAgent",
  args: [agentAddress, "ipfs://Qm..."],
});

The metadata URI is free-form. Most integrators point it at an IPFS document describing the agent's purpose, model, owner, and any external attestations.

Going further

TrustGate's scoring is intentionally narrow — onchain Arc activity, nothing else. Protocols that need richer trust models can layer their own predicates on top: configurable weights for staking history, KYC tier, audit attestations, or third-party risk scores. That ground is where Sofia-style trust models slot in: keep the on-chain enforcement primitive simple, push the scoring complexity into pluggable predicate weights that can evolve without redeploying the gate. We expect this surface to grow alongside Arc.