SDK & agent plugins
@sigil/client — the typed client, plus drop-in guards for LangGraph/LangChain and ElizaOS.
@sigil/client
A zero-dependency typed client for the Sigil ASP. It speaks MCP streamable-HTTP,
surfaces x402 challenges as typed errors, and ships a one-line guard() for agents.
import { SigilClient } from "@sigil/client";
const sigil = new SigilClient(); // defaults to the live ASP on X Layer
const v = await sigil.screenTransaction({
chainId: 196,
from: "0x1111…",
to: "0x7777…",
data: "0xa22cb465…",
});
// v.verdict: 0 PASS · 1 WARN · 2 BLOCK — deterministic and sealed;
// the Merkle batch reference appears after anchoring
if (v.verdict === 2) throw new Error(`refusing to sign: ${v.reasons.join(", ")}`);The decision one-liner most agents want:
const g = await sigil.guard(tx); // PASS ⇒ allow
if (!g.allow) refuse(g.reason); // WARN/BLOCK ⇒ refuse
// policy: await sigil.guard(tx, { allowWarn: true })Payments (x402)
Unpaid priced calls throw SigilPaymentRequiredError carrying the full
challenge (exact + EIP‑3009 primary, Permit2 fallback, on X Layer USD₮0). Settle and retry in one hook:
const sigil = new SigilClient({
onPaymentRequired: async (challenge) => {
const proof = await payWithYourWallet(challenge); // e.g. OKX Payment SDK
return proof; // PAYMENT-SIGNATURE value (v2)
},
});sigil_verify_verdict is free forever — await sigil.verifyVerdict(receiptId)
works with no payment at all.
LangGraph / LangChain
Two integration styles from @sigil/client/langgraph:
As a tool the agent is prompted to call before signing:
import { tool } from "@langchain/core/tools";
import { sigilPreSignCheck } from "@sigil/client/langgraph";
const check = sigilPreSignCheck();
const sigilTool = tool(check.invoke, {
name: check.name,
description: check.description,
schema: check.schema,
});
// add sigilTool to your ToolNode / createReactAgent toolsAs a hard guard around the signer — the firewall path, no prompt needed:
import { guardSigner, SigilBlockedError } from "@sigil/client/langgraph";
const safeSign = guardSigner(wallet.sendTransaction);
await safeSign(tx); // throws SigilBlockedError instead of signing a drainerElizaOS
import { sigilPlugin } from "@sigil/client/eliza";
export const character = {
name: "Trader",
plugins: [sigilPlugin()],
// the agent gains SIGIL_SCREEN_TRANSACTION and is instructed
// to never sign when it returns BLOCK
};See it working
- The wallet pre-sign demo — a mock wallet whose sign button is controlled by real, live verdicts.
- Every verdict links to a public receipt (
/v/{id}) and an on-chain proof (/registry).
OKX rails
With OKX_API_KEY / OKX_API_SECRET / OKX_API_PASSPHRASE configured, the
intel layer enriches every token scan with OKX DEX's curated token list
(okx-dex-listed / okx-dex-unlisted in coverage/sources). Unconfigured,
the gap is recorded honestly as gap:okx-dex-unconfigured — never guessed.