Skip to main content
This guide walks you through registering a wallet in AgentBook, signing proof headers, and creating a premium x402 browser session with a Verified browser.

Prerequisites

  • An EVM wallet (any wallet that can sign messages)
  • World App with Orb verification completed
  • USDC on Base network (for x402 session payments)
  • Node.js 18+

Setup

1. Install dependencies

npm install @worldcoin/agentkit viem x402-fetch

2. Register your wallet in AgentBook

AgentBook is a smart contract on World Chain that links wallet addresses to verified humans. Registration is a one-time on-chain transaction.
npx @worldcoin/agentkit-cli register <your-wallet-address>
Registration requires the wallet holder to be Orb-verified through World App. This is what makes the proof meaningful — it’s not just a wallet, it’s a wallet linked to a unique human.

3. Set your environment variables

# Your wallet private key (used for both x402 payments and AgentKit signing)
PRIVATE_KEY=0x...

# Or use separate keys for payment and identity
X402_PRIVATE_KEY=0x...        # USDC on Base — pays for sessions
AGENTKIT_PRIVATE_KEY=0x...    # Registered in AgentBook — proves humanity
The same wallet can handle both x402 payments (USDC on Base) and AgentKit signing (identity on World Chain). They serve different purposes — payment vs. identity — but can share a key pair for convenience.

Create a verified session

Sign the AgentKit header

Your agent signs a SIWE-formatted message before each request:
import { privateKeyToAccount } from "viem/accounts";
import { formatSIWEMessage } from "@worldcoin/agentkit";
import { randomBytes } from "crypto";

const account = privateKeyToAccount(
  process.env.AGENTKIT_PRIVATE_KEY as `0x${string}`
);

async function signAgentkitHeader(url: string): Promise<string> {
  const parsed = new URL(url);
  const now = new Date();
  const expiry = new Date(now.getTime() + 5 * 60 * 1000); // 5-minute TTL

  const info = {
    domain: parsed.host,
    uri: url,
    version: "1" as const,
    nonce: randomBytes(16).toString("hex"),
    issuedAt: now.toISOString(),
    expirationTime: expiry.toISOString(),
    chainId: "eip155:480", // World Chain
    type: "eip191" as const,
    statement: "Verify your agent is backed by a real human",
  };

  const message = formatSIWEMessage(info, account.address);
  const signature = await account.signMessage({ message });

  const payload = { ...info, address: account.address, signature };
  return Buffer.from(JSON.stringify(payload)).toString("base64");
}

Send the request

Combine the agentkit header with your x402 payment using x402-fetch:
import { wrapFetchWithPayment } from "x402-fetch";
import { privateKeyToAccount } from "viem/accounts";

const walletAccount = privateKeyToAccount(
  process.env.PRIVATE_KEY as `0x${string}`
);
const x402Fetch = wrapFetchWithPayment(fetch, walletAccount);

const url = "https://x402.browserbase.com/browser/session/create";
const agentkitHeader = await signAgentkitHeader(url);

const session = await x402Fetch(url, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    agentkit: agentkitHeader,
  },
  body: JSON.stringify({ estimatedMinutes: 30 }),
}).then((r) => r.json());

console.log(session.connectUrl);
// → wss://connect.browserbase.com/... (Verified browser)

Connect with Playwright

import { chromium } from "playwright";

const browser = await chromium.connectOverCDP(session.connectUrl);
const page = browser.contexts()[0].pages()[0];

await page.goto("https://example.com");
console.log(await page.title());

await browser.close();

How verification works server-side

The x402 gateway verifies AgentKit proofs in four steps:
  1. Decode — Base64-decode the agentkit header and parse the JSON payload
  2. Validate — Check the SIWE message fields and TTL (must not be expired)
  3. Recover — ECRECOVER the signer’s address from the EIP-191 signature
  4. Lookup — Query AgentBook on World Chain (eip155:480) to confirm the address belongs to a registered human
If any step fails, the gateway logs the reason and falls back to a standard browser. No error is returned to the client.

FAQ

Yes. AgentBook registration requires the wallet holder to be verified through World App’s Orb verification. This is what makes the proof meaningful — it’s not just a wallet, it’s a wallet linked to a unique human.
Yes. The x402 payment wallet (USDC on Base) and the AgentKit signing wallet (registered on World Chain) are independent. You can use the same wallet for both or separate them.
Nothing. The AgentKit proof is only checked at session creation time. Once your session is created as Verified, it stays that way for the session’s lifetime.
No. The AgentKit proof is between your agent and the x402 gateway. Websites see a Verified Browserbase browser — they don’t see your wallet address or World ID.
You still get a working browser session (you paid for it via x402). It just won’t have Verified browser fingerprints. The gateway never rejects a paid request over a missing proof.

Next steps

x402 deep dive

Detailed x402 payment flow with AgentKit premium unlock

Agent Identity

All identity layers available to agents