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

# x402x-detector

> Detect whether an ERC-20 supports EIP-3009 / Permit / Permit2

## Overview

`x402x-detector` automatically identifies an ERC-20 token’s “gasless payment capability” — covering EIP-2612 Permit, EIP-3009, and Permit2 — and handles common proxy patterns (EIP-1967 / UUPS). Results are cached for millisecond-level access.

### Key features

* Full detection: Permit / EIP-3009 / Permit2
* Proxy handling: EIP-1967 / UUPS / custom implementation
* High performance: 2–5s on first run, `<1ms` with cache hits
* Simple API: `detect` / `getRecommendedMethod` / `initialize`

## Install

```bash theme={null}
npm i x402x-detector@beta viem
```

## Quick start

```ts theme={null}
import { TokenDetector } from "x402x-detector";
const detector = new TokenDetector(publicClient);
const info = await detector.detect("0xUSDC"); // { supportedMethods: ["permit", ...], name, version }
```

## Examples

<Tabs>
  <Tab title="Functional API (no cache)">
    Create `detect.ts`, core logic:

    ```ts theme={null}
    import { detectTokenPaymentMethods, getRecommendedPaymentMethod, getTokenInfo } from "x402x-detector";
    import { createPublicClient, http } from "viem";
    import { bsc } from "viem/chains";

    const client = createPublicClient({ chain: bsc, transport: http() });
    const token = "0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d"; // USD1 (BSC)

    // 1) Detect capabilities
    const capabilities = await detectTokenPaymentMethods(token, client);

    // 2) Recommend payment method (eip3009 > permit > permit2)
    const recommended = await getRecommendedPaymentMethod(token, client);

    // 3) Read token info (name/version)
    const info = await getTokenInfo(token, client);
    ```

    <AccordionGroup>
      <Accordion title="Full example (functional API)">
        ```ts theme={null}
        import { detectTokenPaymentMethods, getRecommendedPaymentMethod, getTokenInfo } from "x402x-detector";
        import { createPublicClient, http } from "viem";
        import { bsc } from "viem/chains";

        async function main() {
          const client = createPublicClient({ chain: bsc, transport: http() });
          const token = "0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d"; // USD1 (BSC)

          const capabilities = await detectTokenPaymentMethods(token, client);
          console.log("capabilities:", capabilities);

          const recommended = await getRecommendedPaymentMethod(token, client);
          console.log("recommended:", recommended);

          const info = await getTokenInfo(token, client);
          console.log("token info:", info);
        }

        main();
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>

  <Tab title="TokenDetector class (with cache)">
    Create `detector.ts`, core logic:

    ```ts theme={null}
    import { TokenDetector } from "x402x-detector";
    import { createPublicClient, http } from "viem";
    import { bsc } from "viem/chains";

    const client = createPublicClient({ chain: bsc, transport: http() });
    const detector = new TokenDetector(client);

    // Warm up cache (can be done at service startup)
    await detector.initialize([
      "0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d", // USD1
    ]);

    // Millisecond response on cache hit
    const result = await detector.detect("0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d");
    const method = await detector.getRecommendedMethod("0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d");
    ```

    <AccordionGroup>
      <Accordion title="Full example (class with cache)">
        ```ts theme={null}
        import { TokenDetector } from "x402x-detector";
        import { createPublicClient, http } from "viem";
        import { bsc } from "viem/chains";

        async function main() {
          const client = createPublicClient({ chain: bsc, transport: http() });
          const detector = new TokenDetector(client);

          // Warm up common tokens at startup
          const tokens = [
            "0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d", // USD1
          ];
          await detector.initialize(tokens);

          // Detection (super fast on cache hits)
          const result = await detector.detect(tokens[0]);
          console.log(result);

          // Recommended payment method
          const method = await detector.getRecommendedMethod(tokens[0]);
          console.log("recommended:", method);

          // Cache stats
          console.log(detector.getCacheStats());
        }

        main();
        ```
      </Accordion>
    </AccordionGroup>
  </Tab>

  <Tab title="Server integration (Express)">
    ```ts theme={null}
    import express from "express";
    import { createPublicClient, http } from "viem";
    import { bsc } from "viem/chains";
    import { TokenDetector } from "x402x-detector";

    const app = express();
    const client = createPublicClient({ chain: bsc, transport: http() });
    const detector = new TokenDetector(client);

    // Warm up (recommended)
    detector.initialize([
      "0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d", // USD1
    ]);

    app.get("/api/token/:address/capabilities", async (req, res) => {
      const data = await detector.detect(req.params.address);
      res.json(data);
    });

    app.get("/api/token/:address/recommended", async (req, res) => {
      const method = await detector.getRecommendedMethod(req.params.address);
      res.json({ recommendedMethod: method });
    });
    ```
  </Tab>

  <Tab title="Detect recipient (EIP-7702 + settle)">
    Detect whether a seller recipient address (recommended: EIP-7702 deployed wallet/contract) implements x402x settlement extension methods. Can be used for pre-launch checks, health checks, and canary rollouts.

    ```ts theme={null}
    import { detectSettleMethods } from "x402x-detector";
    import { createPublicClient, http } from "viem";
    import { bsc } from "viem/chains";

    const client = createPublicClient({ chain: bsc, transport: http() });
    const recipient = "0xSellerEIP7702RecipientAddress";

    const settle = await detectSettleMethods(client, recipient);
    // {
    //   supportsSettleWithPermit: boolean;    // 0x02ccc23e
    //   supportsSettleWithERC3009: boolean;   // 0x1fe200d9
    //   supportsSettleWithPermit2: boolean;   // 0xa7fcafbb
    // }

    if (!settle.supportsSettleWithPermit && !settle.supportsSettleWithERC3009 && !settle.supportsSettleWithPermit2) {
      throw new Error("Recipient does not implement any x402x settlement method. Please confirm EIP-7702 integration.");
    }
    ```

    <AccordionGroup>
      <Accordion title="How to understand settle detection (implementation highlights)">
        * Settle methods are recognized by function selectors (via ERC-165 capability exposure or static bytecode analysis):
          * `settleWithPermit` → `0x02ccc23e`
          * `settleWithERC3009` → `0x1fe200d9`
          * `settleWithPermit2` → `0xa7fcafbb`
        * We recommend using the EIP-7702 account model to deploy an extension contract for the recipient address, so settlement can be performed across authorization methods.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

## Detection details

* Permit: `permit() / DOMAIN_SEPARATOR() / nonces(owner)`
* EIP-3009: `transferWithAuthorization()` / `authorizationState()`
* Permit2: `allowance(user, token, spender)`

Proxy contracts: automatically read the implementation address (EIP-1967 storage slot / UUPS `proxiableUUID()`, etc.)

## Recommended usage

* Warm up on startup: `detector.initialize([USDC, DAI, ...])`
* Choose a recommended type: `detector.getRecommendedMethod(token)`
* For non-standard proxies, manually verify implementation address

## API reference (condensed)

```ts theme={null}
class TokenDetector {
  constructor(client: PublicClient);
  detect(tokenAddress: string): Promise<{
    address: string;
    supportedMethods: ("eip3009" | "permit" | "permit2" | "permit2-witness")[];
    details: { hasEIP3009: boolean; hasPermit: boolean; hasPermit2Approval: boolean };
    name: string;
    version: string;
  }>;
  getRecommendedMethod(tokenAddress: string): Promise<"eip3009" | "permit" | "permit2" | null>;
  initialize(tokenAddresses: string[]): Promise<any[]>;
  clearCache(tokenAddress?: string): Promise<void>;
  getCacheStats(): { size: number; keys: string[] };
}
```

For more types and return structures, see:

* Parameters: `/en/parameters-responses/detector/parameters`
* Responses: `/en/parameters-responses/detector/responses`

## Performance and optimization

* Warm up hot tokens: `initialize([tokens])` on service startup
* Parallel detection: prefer `initialize` for batch parallel detection
* Detect on demand: slow the first time, fast afterwards (cache hits)
* Periodic refresh: re-detect popular tokens on a schedule

## Resources

* Source: `https://github.com/WTFLabs-WTF/x402x/tree/main/typescript/packages/x402x-detector`
* Issues: `https://github.com/WTFLabs-WTF/x402x/issues`
