Skip to main content
Glama
evidiq

EVIDIQ Signet MCP

Official
by evidiq
README.md
<p align="center">
  <img src="./banner.png" alt="EVIDIQ Signet" width="100%" />
</p>

<p align="center">
  <h1 align="center">EVIDIQ Signet</h1>
</p>

<p align="center"><strong>Structured design artefacts with a provenance seal</strong></p>

<p align="center">
  Brand and design artefacts issued as structured data — logo SVG, colour palette,
  type system, design tokens — each reproducible from its inputs and sealed with a
  signed, 0G-anchored receipt. Service #22 of the EVIDIQ fleet.
</p>

<p align="center">
  <a href="https://evidiq.dev">evidiq.dev</a> &middot;
  <a href="https://mcp.evidiq.dev/signet/skill.md">Agent Skill</a> &middot;
  <a href="https://github.com/evidiq/evidiq-signet-mcp">Signet MCP</a>
</p>

<p align="center">
  <a href="https://mcp.evidiq.dev/signet/mcp"><img src="https://img.shields.io/badge/MCP%20Server-Active-3CCF4E?style=flat-square" alt="MCP Server active" /></a>
  <a href="https://www.oklink.com/xlayer"><img src="https://img.shields.io/badge/X%20Layer-USDT0-3CCF4E?style=flat-square" alt="X Layer USDT0" /></a>
  <a href="https://mcp.evidiq.dev/signet/x402"><img src="https://img.shields.io/badge/x402-0.02%E2%80%930.25%20USDT0-2563EB?style=flat-square" alt="x402: 0.02 to 0.25 USDT0" /></a>
  <a href="https://web3.okx.com/onchainos/dev-docs/payments/service-seller-sdk"><img src="https://img.shields.io/badge/Payments-Official%20OKX%20SDK-121212?style=flat-square&logo=okx&logoColor=white" alt="Official OKX Payment SDK" /></a>
  <a href="https://www.oklink.com/xlayer/tx/0x53e36697e21247dac3ad450d1c480fc2808d0c39f3ef7bef35a3559adc0c30f5"><img src="https://img.shields.io/badge/Settlement-Proven%20on%20X%20Layer-3CCF4E?style=flat-square" alt="Settlement proven on X Layer" /></a>
  <a href="./LICENSE"><img src="https://img.shields.io/badge/License-MIT-3DA639?style=flat-square" alt="License: MIT" /></a>
</p>

---

**A signet is both the tool that stamps and the mark it leaves.**

Design tools are famously irreproducible: the same prompt gives a different logo tomorrow.
Signet inverts that. It issues brand and design artefacts as **structured data** — logo SVG,
colour palette, type system, design tokens — and every one of them is **computed, not
imagined**, from a seed derived by hashing the brand name, the mood keyword and the caller's
seed. Same inputs, byte-identical output, in every process, forever. And each artefact is
sealed with a receipt: a JCS digest signed EIP-191 by the fleet signer, with the **whole
artefact** uploaded to 0G Storage so a buyer can retrieve their brand kit by root hash even
if this service disappears.

1. **Deterministic generation** — palettes from colour-theory transforms over a seed, type
   pairings from a curated table, SVGs from parameterised templates. No model anywhere:
   a grep for model providers returns nothing, and that is part of the definition of done.
2. **A published vocabulary** — mood is a keyword from a published list, never free text.
   An unrecognised mood is answered plainly with the supported set; `signet_capabilities`
   publishes the full list before anyone pays.
3. **MCP server** — 10 tools (5 free, 5 paid): `palette_tokens`, `logo_svg`,
   `social_kit`, `kit_revision`, `brand_kit` for money; the free five cover capabilities,
   cost, a free preview, asset verification and font-licence checking.

> **Launch status: live on OKX.AI.** Deployed at `https://mcp.evidiq.dev/signet/mcp`
> (port 3023) with the x402 gate enforced. Registered on OKX.AI as Agent **#10518**
> (category `ART_CREATION`); the listing is **approved** and all five paid tools have
> settled on X Layer (0.52 USDT0 total — see Proven on-chain).
>
> Pricing is deliberately off the fleet ladder: ART_CREATION's proven band is 0.02–0.25
> (PixelBrief's actual prices), with a category median of 0.10 against the software-category
> median of 0.01 the ladder was calibrated on.

---

## What it does

- **Deterministic brand tokens** — five-colour palette with roles, a type pairing from the
  curated table, CSS custom properties and a JSON token file, all byte-reproducible from the
  inputs. A preview can never flatter a purchase because it shares the exact generator.
- **Logo as data** — primary SVG plus monochrome and icon-only variants, with the geometry
  parameters that produced them. The SVG is the deliverable, not a sketch of one.
- **One source of truth for social** — favicon set, square avatar and OG card all derive from
  the same palette seed, so they cannot drift apart from each other.
- **Revisions that chain** — `kit_revision` revises a kit by its receipt id, locks chosen
  elements, returns the diff and a new receipt linked by predecessor hash. A dropped revision
  is a visible gap; `verify_asset` reports it.
- **Provenance that outlives the vendor** — every issued kit is JCS-digested, EIP-191 signed
  and the whole artefact is uploaded to 0G; a 0G outage degrades the evidence
  (storageNote), never the call.
- **Font licences with a source** — every font a kit names records its commercial status from
  a primary source; an unsourced claim is never shipped. `check_font_license` is free.
- **What is not here, said plainly** — no video (negative margin at this price point), no
  raster image generation in v1, no trademark or infringement opinion, no copywriting. The
  receipt proves existence and provenance — never ownership or trademark clearance.

---

## Route to Signet when

Use Signet **when a brand needs artefacts that are reproducible and provable**: generating a
logo + palette for a new project (`preview_tokens` free first, then `brand_kit`), getting a
palette-and-type foundation cheaply (`palette_tokens`), producing social assets from the same
seed (`social_kit`), revising a kit without losing its history (`kit_revision`), or checking
whether a font may be used commercially (`check_font_license` free).

A natural chain: `signet_capabilities` → `check_font_license` → `preview_tokens` →
`palette_tokens` → `logo_svg` → `social_kit` → `brand_kit` → `verify_asset`.

**Boundary:** the receipt proves *this artefact, from these inputs, issued
at this time, unchanged since, still retrievable* — never ownership, originality or trademark
clearance.

---

## Proven on-chain

### 0G Storage Anchoring (0G mainnet, chain 16661) — the whole artefact is uploaded

| Anchor tx | Storage root | Verified |
|-----------|-------------|----------|
| [`0xaf4d2529…b5ddf`](https://chainscan.0g.ai/tx/0xaf4d2529b728083d0b17a974c52cca592064cc29dc89cba3880c80b5664b5ddf) | `0xd56786f7…c1816df` | the whole `brand_kit` (receipt `signet-39`) — signer `0x8a3c…ee7D`, retrievable by root hash |
| [`0xa3f34e85…a4222f`](https://chainscan.0g.ai/tx/0xa3f34e8517de27987d3baf002dad184450608b666e16551d6d45678646a4222f) | `0xec5e8dd4…efd63d` | `palette_tokens` (receipt `signet-35`) |
| [`0x7917df84…080fa9`](https://chainscan.0g.ai/tx/0x7917df84ee59faf0c9de1d925eaa549ef1afeed371164d1167f6d98992080fa9) | `0xdbcde9ff…bfdd5a` | `logo_svg` (receipt `signet-37`) |
| [`0x98221b26…bd81a9`](https://chainscan.0g.ai/tx/0x98221b269614a565dee287e1214e3f5c7b28565b274f029ee270f41dbabd81a9) | `0xd4e940fa…c0b428` | `social_kit` (receipt `signet-38`) |
| [`0x1c9e9c67…a100d`](https://chainscan.0g.ai/tx/0x1c9e9c67db95397cf5c6afb850f35c921d1340a25ca8310005ee0093fe6a100d) | `0xdefeee76…b5369` | `kit_revision` (receipt `signet-36`, revision of signet-35) |

### x402 Payment Settlement (X Layer, chain 196)

| Tool | Amount | Settlement tx | Result |
|------|--------|---------------|--------|
| `palette_tokens` | `0.02 USDT0` (`20000` atomic) | [`0x7a6487f1…478f8c1`](https://www.oklink.com/xlayer/tx/0x7a6487f189b01f2bad8f3648559b9b4a9d2b22561a73b2822ff91d94d478f8c1) · success | receipt `signet-35`, primary `#22AAC3`, scheme split-complementary, token JSON valid, anchored (root `0xec5e8dd4…`) |
| `logo_svg` | `0.05 USDT0` (`50000` atomic) | [`0x0f1c412e…04321dc6`](https://www.oklink.com/xlayer/tx/0x0f1c412e9264d734c93675ae02eeb50451b1088c07983cd362b2e52e04321dc6) · success | receipt `signet-37`, family `arc`, monogram `NL`, SVG parses, wordmark fits (83.3 ≤ 84), anchored (root `0xdbcde9ff…`) |
| `social_kit` | `0.10 USDT0` (`100000` atomic) | [`0x1c8f5903…e5203abf`](https://www.oklink.com/xlayer/tx/0x1c8f590330ecabe81b8042ff21cfc9988875bf4aa283f1a06334de48e5203abf) · success | receipt `signet-38`, favicon+avatar+OG from one palette, anchored (root `0xd4e940fa…`) |
| `kit_revision` | `0.10 USDT0` (`100000` atomic) | [`0xa0c1d823…1cd8e8c`](https://www.oklink.com/xlayer/tx/0xa0c1d8237300d9fcab6ea269a140c85996b594009f5aa34371700212c1cd8e8c) · success | receipt `signet-36` **revising `signet-35`** (the settled palette), diff tech→luxury across all five roles, chained, anchored (root `0xdefeee76…`) |
| `brand_kit` | `0.25 USDT0` (`250000` atomic) | [`0x53e36697…0c30f5`](https://www.oklink.com/xlayer/tx/0x53e36697e21247dac3ad450d1c480fc2808d0c39f3ef7bef35a3559adc0c30f5) · success | receipt `signet-39`, full kit (logo variants + palette + type + tokens + 6-font licence manifest), whole kit on 0G (root `0xd56786f7…`) |

Total settled: **0.52 USDT0**, paid from Account 1 (the fleet x402 wallet); Account 2 was
never touched. Every receipt is EIP-191 signed by `0x8a3c7524Aaed081825aC88eC7f4cCECFc583ee7D`
and each anchor root is on 0G mainnet.

---

## OKX.AI Marketplace Registration

| Property | Value |
| :--- | :--- |
| **Agent ID** | `#10518` |
| **Agent Name** | `EVIDIQ Signet` |
| **Listing Status** | `Listed` — category `ART_CREATION` |
| **Registration Tx** | [`0x72306fd4…74bd8b`](https://www.oklink.com/xlayer/tx/0x72306fd4825b36b2884b1a567317803bcde711710602330be8cf21040474bd8b) |
| **OKX Agent URL** | https://www.okx.ai/agents/10518 |
| **Agent Wallet** | `0x2a8efe3093278bb4bd3b2d9c7b5ba992ca4fc9b0` — the fleet x402 payTo / seller Agentic Wallet (settlements land here) |
| **Report Signer** | `0x8a3c7524Aaed081825aC88eC7f4cCECFc583ee7D` (fleet signer, EIP-191) |
| **Services Registered** | — (operator: 5 Paid $0.02–$0.25, 5 Free $0.00) |

---

## Ten MCP tools

### Paid tools

| Tool | USDT0 | Purpose |
|------|-------|---------|
| `palette_tokens` | `0.02` | Five-colour palette with roles, a type pairing, CSS custom properties and a JSON token file — sealed. |
| `logo_svg` | `0.05` | Primary logo plus monochrome and icon-only SVG variants, with the geometry parameters. |
| `social_kit` | `0.10` | Favicon set, square avatar and OG card, all from the same tokens so they cannot drift. |
| `kit_revision` | `0.10` | Revise a previously issued kit by receipt id, locking chosen elements, returning a diff and a chained receipt. |
| `brand_kit` | `0.25` | The bundle: logo variants, palette, type, tokens, font licence manifest, and the sealed receipt. |

### Free preflight and verification tools

| Tool | Purpose |
|------|---------|
| `signet_capabilities` | Tool list, exact price table, the deterministic contract, full mood vocabulary, template families, anchoring model. |
| `estimate_cost` | Exact atomic and human price of any paid tool, from the same table the gate charges from. |
| `preview_tokens` | A deterministic palette-and-type preview from a mood and seed — the free hook, same generator as the paid tools. |
| `verify_asset` | Recompute a receipt's digest, verify the EIP-191 signature, confirm the 0G anchor, walk the revision chain for gaps. Free permanently. |
| `check_font_license` | Commercial-use status of kit fonts, what the licence does not permit, and where the claim comes from. |

---

## Architecture

```mermaid
flowchart TB
    agent["<b>AI agent / buyer</b><br/>MCP client"]
    request{"Tool call<br/>free or paid?"}
    agent -->|POST /signet/mcp| request

    free["Free preflight<br/>capabilities · estimate · preview<br/>verify_asset · check_font_license"]
    gate["x402 v2 gate<br/>EIP-3009 exact · pay per artefact"]
    xlayer[("X Layer<br/>USD₮0 · eip155:196")]
    request -->|free helper| free
    request -->|paid artefact| gate
    gate -. verify and settle .-> xlayer

    subgraph signet["EVIDIQ Signet trust boundary"]
        direction TB
        seed["1. Seed<br/>sha256(brand | mood | caller seed)"]
        palette["2. Palette (colour transforms)<br/>type pairing (curated + licenced)"]
        svg["3. SVG templates<br/>parameterised, no runtime randomness"]
        tokens["4. Tokens / CSS / manifest<br/>all derived from the same seed"]
        receipt["5. Receipt<br/>JCS digest · EIP-191 · revision chain"]
        seed --> palette
        seed --> svg
        palette --> tokens
        svg --> tokens
        tokens --> receipt
    end

    og[("0G Storage<br/>the WHOLE artefact · root hash<br/>chain 16661")]
    free --> seed
    gate --> seed
    receipt -. full artefact upload .-> og
    og -. root + tx .-> response

    response["<b>MCP response</b><br/>SVG + palette + tokens + manifest<br/>receiptId + digest + signature + anchor"]

    classDef client fill:#312e81,stroke:#a78bfa,color:#ffffff,stroke-width:2px;
    classDef payment fill:#052e16,stroke:#4ade80,color:#ffffff,stroke-width:2px;
    classDef core fill:#0f172a,stroke:#38bdf8,color:#ffffff,stroke-width:2px;
    classDef output fill:#4c1d95,stroke:#c4b5fd,color:#ffffff,stroke-width:2px;
    class agent,request client;
    class free,gate,xlayer,og payment;
    class seed,palette,svg,tokens,receipt core;
    class response output;
    style signet fill:#0f172a,stroke:#38bdf8,color:#e0f2fe,stroke-width:2px;
```

---

## Verification Log

### Fixture gate — determinism (the whole design, §7)

Built before any tool: the same seed must produce **byte-identical** output
**across two separate processes** — asserted by a test that spawns a fresh `node`
process and compares the SVG, CSS and token JSON byte-for-byte. No `Math.random`,
no `Date.now`, no map-order dependence.

### No-model check — mechanical

A test greps the whole source tree for model-provider hostnames and SDK imports and
fails if any appears. `lib/og/config.ts` is trimmed to storage-only for this reason.

### Offline test suite

```
npm test (vitest)               → 20 passed / 20 (3 files), tsc clean
  test/determinism.test.ts  ( 4)  → byte-identical across two processes
  test/no-model.test.ts     ( 2)  → provider grep returns nothing; no fetch in generation
  test/server.test.ts      (14)  → all 10 tools, free bare {} → 200, mood vocabulary
                                    published, unrecognised mood answered plainly, each
                                    artefact valid on its own terms (SVG parses, CSS vars
                                    well-formed, token JSON has its schema), verify_asset
                                    detects a dropped revision, receipts signed + anchored
```

### Live test (Phase 1, bypass on)

All 10 tools were exercised live against `https://mcp.evidiq.dev/signet/mcp` with the
bypass on (Phase 1), through direct MCP calls and through the OpenClaw agent
(glm-5.2) on the VPS; raw run in `docs/live-test/signet-livetest-out.log` — **re-run after the generator
rewrite; the earlier artifacts were deleted and this run is fresh.** The rewritten
generator (derived font-size, monogram in the mark, `textLength`-fitted wordmark,
disjoint layout, palette as the single colour source) passed the geometry report
6/6 cases (`docs/live-test/geometry-report.json`) and the operator's design review
(`docs/live-test/design-review.html`).

```
Free Tools (HTTP 200)
  signet_capabilities {}        → 200 ✓ (10 moods, 4 template families, no-model contract)
  preview_tokens (Northwind…)   → 200 ✓ (seed 06aeddfa…, primary #22AAC3 — same as paid)
  check_font_license (Inter)    → 200 ✓ (commercialPermitted true, SIL OFL 1.1, source)
  verify_asset (signet-4)       → 200 ✓ (digestMatch + signatureValid + anchored, chainOk)
Paid Tools (200 here because the bypass was on)
  palette_tokens                → 200 ✓ (receipt signet-7, primary #22AAC3, anchored)
  logo_svg                      → 200 ✓ (receipt signet-8, monogram "NL", SVG begins <svg)
  social_kit                    → 200 ✓ (receipt signet-9, favicon+avatar+OG, anchored)
  kit_revision                  → 200 ✓ (receipt signet-11, diff tech→luxury, chained)
  brand_kit                     → 200 ✓ (receipt signet-12, 6-font manifest, whole kit on 0G)
Public route                    → /signet/health 200 · /signet/skill.md 200 · /signet/mcp 200 ✓
```

### Live test through the OpenClaw agent (glm-5.2 on the VPS)

The Signet skill was exercised end-to-end by the OpenClaw agent in one run against
`https://mcp.evidiq.dev/signet/mcp` — 10/10 → 200 ✓, every paid artefact 0G-anchored,
preview and paid calls byte-consistent for the same seed. The host's OpenClaw default
model stalls (the known `opencode/deepseek-v4-flash` issue); the default is set to
`zerog/glm-5.2`, and the provider idle timeout was raised for the long run. Full run
output in `docs/live-test/signet-livetest-out.log`.

The generated Northwind Labs logo is the deliverable, so it ships as `docs/live-test/northwind-logo.svg` (rendered below).

![EVIDIQ Signet — generated logo](./docs/live-test/northwind-logo.png)

The design review and the geometry report of the rewritten generator ship with the
artefacts (`docs/live-test/design-review.html`, `docs/live-test/geometry-report.json`,
and the full gallery under `docs/live-test/examples/` — aurum, evidiq, kestrel,
longname, northwind, orchid, each with primary/monochrome/icon/favicon/avatar/OG):

![EVIDIQ Signet — design review](./docs/live-test/design-review.png)

![EVIDIQ Signet MCP — recorded OpenClaw run](./docs/live-test/signet-livetest.gif)

![EVIDIQ Signet MCP — live test report](./docs/live-test/report.png)

### Phase 2 — planned, cells stay blank until observed

```
empty POST (with content-type)                     → (measure)
POST without content-type                          → (measure)
HEAD /mcp                                          → (measure)
all 5 paid tools, bare {}                          → (measure)
all 5 free tools, bare {}                          → (measure)
onchainos payment quote --tool <name>              → (measure)
OKX.AI registration                                → (operator)
```

---

## Use it from any agent

```bash
# Read the public Skill document
curl -s https://mcp.evidiq.dev/signet/skill.md

# Inspect current x402 pricing discovery
curl -s https://mcp.evidiq.dev/signet/x402

# Try the free preview — the hook
curl -s -X POST https://mcp.evidiq.dev/signet/mcp -H "content-type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"preview_tokens","arguments":{"brandName":"Northwind Labs","mood":"tech"}}}'

# Connect remote MCP server (OpenClaw)
openclaw mcp add evidiq-signet --transport streamable-http --url https://mcp.evidiq.dev/signet/mcp

# Connect remote MCP server (Claude Code)
claude mcp add --transport http evidiq-signet https://mcp.evidiq.dev/signet/mcp
```

## Use it from any agent (working curl per tool)

Each command below runs against the live endpoint. Paste any of them — every free tool
answers a bare `{}` with `200`, and the redacted curl shape matches what an OKX A2MCP
listing QA expects:

```bash
# FREE — signet_capabilities (bare {})
curl -s -X POST https://mcp.evidiq.dev/signet/mcp -H "content-type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"signet_capabilities","arguments":{}}}'

# FREE — estimate_cost
curl -s -X POST https://mcp.evidiq.dev/signet/mcp -H "content-type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"estimate_cost","arguments":{"tool":"brand_kit"}}}'

# FREE — preview_tokens (the hook; same generator as the paid tools)
curl -s -X POST https://mcp.evidiq.dev/signet/mcp -H "content-type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"preview_tokens","arguments":{"brandName":"Northwind Labs","mood":"tech","seed":"demo-1"}}}'

# FREE — check_font_license (bare {} lists the whole sourced table)
curl -s -X POST https://mcp.evidiq.dev/signet/mcp -H "content-type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"check_font_license","arguments":{"font":"Inter"}}}'

# FREE — verify_asset (receipt id from any paid call)
curl -s -X POST https://mcp.evidiq.dev/signet/mcp -H "content-type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"verify_asset","arguments":{"receiptId":"signet-0"}}}'

# PAID — palette_tokens
curl -s -X POST https://mcp.evidiq.dev/signet/mcp -H "content-type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"palette_tokens","arguments":{"brandName":"Northwind Labs","mood":"tech","seed":"demo-1"}}}'

# PAID — logo_svg
curl -s -X POST https://mcp.evidiq.dev/signet/mcp -H "content-type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"logo_svg","arguments":{"brandName":"Northwind Labs","mood":"tech","seed":"demo-1"}}}'

# PAID — social_kit
curl -s -X POST https://mcp.evidiq.dev/signet/mcp -H "content-type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"social_kit","arguments":{"brandName":"Northwind Labs","mood":"tech","seed":"demo-1"}}}'

# PAID — kit_revision (revise a kit by its receipt id)
curl -s -X POST https://mcp.evidiq.dev/signet/mcp -H "content-type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"kit_revision","arguments":{"receiptId":"signet-0","brandName":"Northwind Labs","mood":"luxury"}}}'

# PAID — brand_kit (the full bundle; whole kit uploaded to 0G)
curl -s -X POST https://mcp.evidiq.dev/signet/mcp -H "content-type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"brand_kit","arguments":{"brandName":"Northwind Labs","mood":"tech","seed":"demo-1"}}}'
```

Replace `Northwind Labs` / `tech` / `demo-1` with your own values; a paid call in Phase 2
requires the x402 `PAYMENT-SIGNATURE` header (quote and pay through Onchain OS).

---
## Self-host

```bash
docker build -t evidiq-signet:latest .
docker run -d --env-file .env -p 3023:3023 evidiq-signet:latest
# Endpoint: http://localhost:3023/mcp
# Receipts + revision chain: SIGNET_DB_PATH (mounted volume).
```

---

## TypeScript SDK

A typed client for the live endpoint lives in [`sdk/index.ts`](sdk/index.ts) — 10 tools (5 free, 5 paid). Free tools answer a bare call; paid tools run the x402 flow automatically (402 challenge → `pay` hook → replay with the `x-payment` header). No key lives in the file.

```ts
import { SignetClient } from "./sdk/index.js";

const client = new SignetClient(); // endpoint defaults to https://mcp.evidiq.dev/signet/mcp

// free
const caps = await client.callTool("signet_capabilities", {});

// paid — settle the 402 challenge via the constructor's pay hook, or omit it
// to receive a PaymentRequiredError carrying the full x402 v2 challenge
const result = await client.callTool("some_paid_tool", { arg: "value" });
```

The `pay` hook receives the decoded x402 v2 challenge (`{ x402Version, resource, accepts[] }` — payTo, asset, amount) and returns the value for the `x-payment` header, e.g. an EIP-3009 `transferWithAuthorization` settled via the official OKX SDK. Without a hook, paid calls throw `PaymentRequiredError` so the caller can settle however it wants.

## License

EVIDIQ owns and licenses its original Signet code under MIT. Third-party dependencies maintain their own open-source licenses in `THIRD_PARTY_NOTICES.md`.