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

> 检测 ERC-20 是否支持 EIP-3009 / Permit / Permit2

## 概述

`x402x-detector` 用于自动识别 ERC-20 Token 的“免 Gas 支付能力”，覆盖 EIP-2612 Permit、EIP-3009、Permit2 等标准，并能处理常见代理模式（EIP-1967 / UUPS）。结果会永久缓存以获得毫秒级访问。

### 核心特性

* 🔍 全面检测：Permit / EIP-3009 / Permit2
* 🧭 代理处理：EIP-1967 / UUPS / 自定义 implementation
* ⚡ 高性能：首次 2-5s，命中缓存 `<1ms`
* 🧰 简洁 API：`detect` / `getRecommendedMethod` / `initialize`

## 安装

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

## 快速上手

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

## 示例

<Tabs>
  <Tab title="函数式 API（无缓存）">
    创建 `detect.ts`，核心逻辑如下：

    ```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) 检测支付能力
    const capabilities = await detectTokenPaymentMethods(token, client);

    // 2) 推荐支付方式（eip3009 > permit > permit2）
    const recommended = await getRecommendedPaymentMethod(token, client);

    // 3) 读取代币信息（name/version）
    const info = await getTokenInfo(token, client);
    ```

    <AccordionGroup>
      <Accordion title="查看完整示例代码（函数式 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 类（带缓存）">
    创建 `detector.ts`，核心逻辑如下：

    ```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);

    // 预热缓存（可在服务启动时执行）
    await detector.initialize([
      "0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d", // USD1
    ]);

    // 缓存命中时毫秒级返回
    const result = await detector.detect("0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d");
    const method = await detector.getRecommendedMethod("0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d");
    ```

    <AccordionGroup>
      <Accordion title="查看完整示例代码（带缓存类）">
        ```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);

          // 启动时预热常用 Token
          const tokens = [
            "0x8d0D000Ee44948FC98c9B98A4FA4921476f08B0d", // USD1
          ];
          await detector.initialize(tokens);

          // 检测（命中缓存速度极快）
          const result = await detector.detect(tokens[0]);
          console.log(result);

          // 推荐支付方式
          const method = await detector.getRecommendedMethod(tokens[0]);
          console.log("recommended:", method);

          // 缓存统计
          console.log(detector.getCacheStats());
        }

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

  <Tab title="服务端集成（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);

    // 推荐预热
    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="检测收款地址（EIP-7702 + settle）">
    用于检测卖家收款地址（建议使用 EIP-7702 部署的钱包/合约）是否实现 x402x 结算扩展方法。可在上线前自检，或做健康检查与灰度。

    ```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("收款地址未实现任一 x402x 结算方法，请确认已按 EIP-7702 集成扩展。");
    }
    ```

    <AccordionGroup>
      <Accordion title="如何理解 settle 检测（实现要点）">
        * settle 方法通过函数选择器进行识别（基于 ERC-165 能力暴露或静态字节码分析）：
          * `settleWithPermit` → `0x02ccc23e`
          * `settleWithERC3009` → `0x1fe200d9`
          * `settleWithPermit2` → `0xa7fcafbb`
        * 建议采用 EIP-7702 账户模型为收款地址部署扩展合约，以便在多种授权方式下完成结算。
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

## 检测细节

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

代理合约：自动读取实现地址（EIP-1967 存储槽 / UUPS `proxiableUUID()` 等）

## 建议用法

* 启动预热：`detector.initialize([USDC, DAI, ...])`
* 选择推荐类型：`detector.getRecommendedMethod(token)`
* 非标准代理合约需手动校验实现地址

## API 参考（精简）

```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[] };
}
```

更多类型与返回结构请参考：

* 参数说明：`/parameters-responses/detector/parameters`
* 返回结构：`/parameters-responses/detector/responses`

## 性能与优化

* 预热常用 Token：服务启动时 `initialize([tokens])`
* 并行检测：优先使用 `initialize` 批量并行
* 按需检测：首次慢、后续快（命中缓存）
* 定期刷新：周期性对热门 Token 重新检测

## 相关资源

* 源代码：`https://github.com/WTFLabs-WTF/x402x/tree/main/typescript/packages/x402x-detector`
* 问题反馈：`https://github.com/WTFLabs-WTF/x402x/issues`
