Documentation Index
Fetch the complete documentation index at: https://tfh-murph-idkit-intro.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Use this page when you need the full AgentKit surface area. For the shortest path to a working setup, start with Integrate AgentKit.
Access modes
Usage counters are tracked per human per endpoint. Two agents backed by the same human share the same counter.
| Mode | Fields | Behavior |
|---|
free | { type: "free" } | Registered human-backed agents always bypass payment. |
free-trial | { type: "free-trial"; uses?: number } | Registered human-backed agents bypass payment the first N times. Default uses is 1. |
discount | { type: "discount"; percent: number; uses?: number } | Registered human-backed agents can underpay by the configured percentage for the first N times. |
discount mode requires verifyFailureHook to be registered on the facilitator. Without it, discounted underpayments fail settlement verification.
Agent client APIs
createAgentkitClient(options)
Use this client in agents that call paid x402 APIs. agentkit.fetch inspects 402 Payment Required responses and retries once with a signed agentkit header when the response advertises extensions.agentkit.
import { createAgentkitClient } from '@worldcoin/agentkit'
const agentkit = createAgentkitClient({
signer: {
address: agentWallet.address,
chainId: 'eip155:8453',
type: 'eip191',
signMessage: message => agentWallet.signMessage(message),
},
})
| Option | Type | Description |
|---|
signer | AgentkitSigner | Agent wallet identity and SIWE signing function. Required. |
fetch | typeof fetch | Optional base fetch implementation. Defaults to globalThis.fetch. |
onEvent | (event: AgentkitFetchEvent) => void | Optional callback for logging and debugging. |
The client does not create x402 payments. It returns the original response unchanged when AgentKit is unavailable or cannot be used, so your existing x402 payment client can handle fallback.
AgentkitSigner
type AgentkitSigner = {
address: string
chainId: string
type: 'eip191' | 'eip1271'
signMessage(message: string): Promise<string>
}
Use eip191 for EOAs and eip1271 for smart contract wallets.
The returned client exposes:
| Field | Type | Description |
|---|
fetch | typeof fetch | Fetch-compatible function that retries AgentKit-enabled 402 responses once. |
createHeader | (extension: AgentkitExtension) => Promise<string> | Creates the base64 agentkit HTTP header for custom HTTP clients. |
Core server APIs
declareAgentkitExtension(options?)
Use this helper in your x402 route config to declare the agentkit extension that should be returned in a 402 Payment Required response.
| Parameter | Type | Description |
|---|
domain | string | Server hostname. Usually auto-derived from the request URL. |
resourceUri | string | Full protected resource URI. Usually auto-derived from the request URL. |
network | string | string[] | CAIP-2 network or list of networks. If omitted, the extension derives them from accepts[].network. |
statement | string | Human-readable signing purpose. |
version | string | CAIP-122 version. Defaults to "1". |
expirationSeconds | number | Challenge lifetime in seconds. |
mode | AgentkitMode | Access mode clients should expect after verification. |
Returns a record keyed by agentkit that can be attached directly to an x402 route declaration.
agentkitResourceServerExtension
Register this extension once on your x402 resource server. It turns the declaration returned by declareAgentkitExtension(...) into a full 402 challenge by:
- generating the nonce and timestamps
- inferring
domain and resourceUri from the incoming request when you omit them
- expanding each supported EVM network into
eip191 and eip1271 signature types
createAgentkitHooks(options)
Creates the request-time verification hooks used by the golden path integration.
| Option | Type | Description |
|---|
agentBook | AgentBookVerifier | Verifier used to resolve the agent wallet to a human identifier. Required. |
mode | AgentkitMode | Access mode. Defaults to { type: "free" }. |
storage | AgentKitStorage | Required for free-trial and discount. Optional for free. |
rpcUrl | string | Custom EVM RPC used during signature verification. |
onEvent | (event: AgentkitHookEvent) => void | Optional logging/debug callback. |
Returns:
| Field | Type | Description |
|---|
requestHook | function | Runs before payment settlement and can grant access for free or free-trial. |
verifyFailureHook | function | undefined | Present only for discount mode. Register it on the facilitator so discounted underpayments can be recovered. |
requestHook expects a context shaped like:
{
adapter: {
getHeader(name: string): string | undefined
getUrl(): string
}
path: string
}
That is why Express and Next.js are compatible even though the docs use Hono for the concrete example: you can adapt any server framework to this minimal contract.
AgentkitHookEvent
onEvent receives one of these event shapes:
| Event type | Fields |
|---|
agent_verified | resource, address, humanId |
agent_not_verified | resource, address |
validation_failed | resource, error? |
discount_applied | resource, address, humanId |
discount_exhausted | resource, address, humanId |
AgentBook lookup
createAgentBookVerifier(options?)
Creates the verifier used to resolve a wallet address to an anonymous human identifier. Lookup always resolves against the canonical AgentBook deployment on World Chain (eip155:480).
Canonical deployment:
- World Chain mainnet:
0xA23aB2712eA7BBa896930544C7d6636a96b944dA
| Option | Type | Description |
|---|
rpcUrl | string | Custom World Chain RPC URL. Defaults to the chain’s default public RPC. Ignored if client is provided. |
contractAddress | `0x${string}` | Custom AgentBook contract address on World Chain. Defaults to the canonical deployment. |
client | PublicClient | Advanced override. Inject a fully custom viem public client (useful for tests or non-standard deployments). |
In the common case call it with no arguments:
const agentBook = createAgentBookVerifier()
The returned object exposes:
lookupHuman(address: string): Promise<string | null>
Storage and replay protection
AgentKitStorage
AgentKitStorage is the persistence interface used for free-trial counters, discount counters, and optional nonce replay protection.
| Method | Description |
|---|
tryIncrementUsage(endpoint, humanId, limit) | Atomically increment usage if below the limit. Returns true when the use is recorded. |
hasUsedNonce?(nonce) | Optional replay check. Return true if the nonce has already been seen. |
recordNonce?(nonce) | Optional replay recorder. Persist the nonce after validation succeeds. |
InMemoryAgentKitStorage
InMemoryAgentKitStorage is the reference implementation exported by the package.
- Good for local development, demos, and tests
- Not appropriate for production because usage counters and nonce history disappear on restart
Validation and verification helpers
Parses the base64-encoded agentkit header into a structured payload. It throws if the header is not valid base64, is not valid JSON, or does not match the expected schema.
validateAgentkitMessage(payload, resourceUri, options?)
Validates message binding, freshness, and optional replay checks.
| Option | Type | Description |
|---|
maxAge | number | Maximum age for issuedAt in milliseconds. Defaults to 5 minutes. |
checkNonce | (nonce: string) => boolean | Promise<boolean> | Optional replay validation hook. |
Returns:
{ valid: boolean; error?: string }
verifyAgentkitSignature(payload, rpcUrl?)
Verifies the cryptographic signature and returns the recovered address on success.
| Option | Type | Description |
|---|
rpcUrl | string | Optional custom RPC endpoint for EVM verification. |
Behavior:
eip155:* payloads are reconstructed into a SIWE message and verified with viem
- unsupported chain namespaces return
{ valid: false, error: ... }
Returns:
{ valid: boolean; address?: string; error?: string }
buildAgentkitSchema()
Returns the JSON schema used in 402 challenge payloads.
Chain utilities
EVM
| Export | Description |
|---|
formatSIWEMessage | Reconstruct the SIWE message used for EVM signing and verification. |
verifyEVMSignature | Verify an EVM signature for the reconstructed SIWE message. |
extractEVMChainId | Convert a CAIP-2 eip155:* chain ID to its numeric chain ID. |
EVM verification uses viem’s verifyMessage, which covers EOAs and ERC-1271 smart wallets. Counterfactual wallets can still represent their signature scheme with signatureScheme: "eip6492" in the payload schema.
Supported chains and signature behavior
- Chain namespace:
eip155:*
- Payload
type: eip191 or eip1271
- Optional
signatureScheme: eip191, eip1271, or eip6492
- Message format: SIWE
Manual usage example
Use the low-level helpers directly when you are not using the x402 Hono wrapper or when you want full control over request handling:
import {
AGENTKIT,
createAgentBookVerifier,
declareAgentkitExtension,
parseAgentkitHeader,
validateAgentkitMessage,
verifyAgentkitSignature,
} from '@worldcoin/agentkit'
const extensions = declareAgentkitExtension({
domain: 'api.example.com',
resourceUri: 'https://api.example.com/data',
network: 'eip155:480',
statement: 'Verify your agent is backed by a real human',
})
const agentBook = createAgentBookVerifier()
async function handleRequest(request: Request) {
const header = request.headers.get(AGENTKIT)
if (!header) return
const payload = parseAgentkitHeader(header)
const validation = await validateAgentkitMessage(payload, 'https://api.example.com/data')
if (!validation.valid) {
return { error: validation.error }
}
const verification = await verifyAgentkitSignature(payload)
if (!verification.valid || !verification.address) {
return { error: verification.error }
}
const humanId = await agentBook.lookupHuman(verification.address)
if (!humanId) {
return { error: 'Agent is not registered in the AgentBook' }
}
return { humanId }
}
Production notes
- Treat
InMemoryAgentKitStorage as a demo-only implementation.
- If you need limited free uses, persistent storage is part of the integration, not an optional enhancement.
- If you need
discount mode, wire verifyFailureHook into the facilitator before you ship.
- Use Hono as a reference example, not as a framework restriction. The package surface is generic enough to be adapted to Express or Next.js handlers.