> ## Documentation Index
> Fetch the complete documentation index at: https://docs.world.org/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK Reference

> Reference for AgentKit modes, APIs, EVM signatures, and low-level helpers.

Use this page when you need the full AgentKit surface area. For the shortest path to a working setup, start with [Integrate AgentKit](/agents/agent-kit/integrate).

## 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`.

```typescript theme={null}
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`

```ts theme={null}
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:

```ts theme={null}
{
  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:

```typescript theme={null}
const agentBook = createAgentBookVerifier()
```

The returned object exposes:

```ts theme={null}
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

### `parseAgentkitHeader(header)`

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:

```ts theme={null}
{ 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:

```ts theme={null}
{ 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:

```typescript theme={null}
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.
