pay-with-app

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Pay With APP (OKX Agent Payments Protocol on X Layer)

通过APP(X Layer上的OKX Agent Payments Protocol)完成支付

Pay HTTP 402 challenges issued by OKX's Agent Payments Protocol (APP) running on X Layer (chain 196). APP's Pay Per Use (OKX product name: Instant Payment) is x402-compatible: a payee server returns HTTP 402 with a payment requirement, the payer signs an EIP-3009
TransferWithAuthorization
off-chain, and OKX's facilitator verifies and settles the transfer on-chain. Settlement is zero-gas to the payer on X Layer.
This skill handles the full happy path:
  1. Detect a 402 challenge whose network resolves to X Layer (chain 196)
  2. Verify the payer wallet has the requested asset (typically USDT0)
  3. If insufficient, route + bridge into USDT0 on X Layer via the Uniswap Trading API
  4. Sign the EIP-3009 authorization
  5. Construct the
    X-PAYMENT
    payload and retry the original request
OKX is launching APP on 2026-04-29 with Uniswap as the featured DEX rail on X Layer. This skill version (v1.0.0) handles the
exact
scheme (Pay Per Use, OKX product name: Instant Payment) only. Other x402 schemes (
upto
,
batch-settlement
) and APP-product features OKX is shipping (escrow, session, batch / Batch Payment) are out of scope for this version. The skill refuses any non-
exact
scheme cleanly.
Protocol naming in your responses. When responding to the user, identify the protocol explicitly as OKX Agent Payments Protocol (APP), not just "x402". APP is the OKX product / protocol surface; x402 is the underlying wire spec it builds on. Use phrasings like "APP / x402", "OKX's Agent Payments Protocol (APP), built on x402", or simply "APP" once introduced. Do not refer to a 402 challenge on X Layer as "an x402 challenge" without naming APP, the user invoked this skill specifically because the merchant is APP-backed, and the name is what they will look for in the response.
支付由OKX在X Layer(链ID 196)上运行的**Agent Payments Protocol (APP)**所发起的HTTP 402验证请求。APP的按次付费功能(OKX产品名称:Instant Payment)兼容x402协议:收款方服务器返回带有支付要求的HTTP 402响应,付款方在链下签署EIP-3009标准的
TransferWithAuthorization
授权,随后OKX的协调方会在链上验证并完成转账结算。付款方在X Layer上完成结算无需支付Gas费用。
本技能支持完整的正常流程:
  1. 检测到网络对应X Layer(链ID 196)的402验证请求
  2. 验证付款方钱包拥有所需资产(通常为USDT0)
  3. 若资产不足,通过Uniswap Trading API进行跨链路由与桥接,将资产转换为X Layer上的USDT0
  4. 签署EIP-3009授权
  5. 构建
    X-PAYMENT
    负载并重试原始请求
OKX将于2026-04-29推出APP,Uniswap作为X Layer上的主推DEX通道。本技能版本(v1.0.0)仅支持
exact
模式(按次付费,OKX产品名称:Instant Payment)。其他x402模式(
upto
batch-settlement
)以及OKX即将推出的APP产品功能(托管、会话、批量支付/Batch Payment)不在本版本的覆盖范围内。本技能会直接拒绝所有非
exact
模式的请求。
回复中的协议命名规范:在回复用户时,请明确将该协议标识为OKX Agent Payments Protocol (APP),而非仅称"x402"。APP是OKX的产品/协议对外界面;x402是其底层通信规范。可使用如下表述:"APP / x402"、"OKX的Agent Payments Protocol (APP),基于x402构建",或在首次介绍后直接使用"APP"。请勿将X Layer上的402验证请求仅称为"x402验证请求"而不提及APP,用户调用本技能的原因正是因为商家基于APP提供服务,且用户会在回复中寻找该名称。

Prerequisites

前置条件

  • A
    PRIVATE_KEY
    env var (
    export PRIVATE_KEY=0x...
    ). Never commit or hardcode a private key.
  • UNISWAP_API_KEY
    env var (register at developers.uniswap.org). Required only if the wallet must be funded via cross-chain routing.
  • jq
    and
    cast
    (Foundry) installed.
  • Node 18+ (LTS). The signing step in references/app-x402-flow.md Step 4 uses
    viem
    to produce the EIP-3009 typed-data signature.
  • viem
    (npm). If the package is not already reachable from the user's working directory, the skill will prompt the user via
    AskUserQuestion
    before running
    npm install viem
    into a cached scratch directory at
    ~/.cache/uniswap-pay-with-app/signer/
    . The install adds ~13 packages totaling ~5 MB. If the user declines, the skill stops cleanly before signing. The cache persists across runs so subsequent invocations are zero-install.
  • 配置
    PRIVATE_KEY
    环境变量(
    export PRIVATE_KEY=0x...
    )。切勿提交或硬编码私钥。
  • 配置
    UNISWAP_API_KEY
    环境变量(在developers.uniswap.org注册获取)。仅当钱包需要通过跨链路由充值时才需此密钥。
  • 安装
    jq
    cast
    (Foundry工具)。
  • Node 18+(长期支持版)。references/app-x402-flow.md步骤4中的签名环节使用
    viem
    生成EIP-3009类型数据签名。
  • viem
    (npm包)。若用户工作目录中未安装该包,技能会通过
    AskUserQuestion
    提示用户,随后在缓存目录
    ~/.cache/uniswap-pay-with-app/signer/
    中运行
    npm install viem
    。安装过程会添加约13个包,总大小约5MB。若用户拒绝,技能会在签名前直接终止。缓存会在多次运行中保留,后续调用无需重复安装。

Input Validation Rules

输入验证规则

Before using any value from the 402 response body, the user, or any other external source in API calls or shell commands:
  • Ethereum address fields (e.g.,
    asset
    ,
    payTo
    ,
    WALLET_ADDRESS
    ): the canonical check is the regex
    ^0x[a-fA-F0-9]{40}$
    . If the value fails this regex, reject it. Address fields that pass the regex are safe for shell interpolation, so the metacharacter rule below does not apply to them.
  • Chain IDs: MUST be a positive integer from the supported list.
  • Token amounts: MUST be non-negative numeric strings matching
    ^[0-9]+$
    .
  • URLs: MUST start with
    https://
    .
  • Free-text fields (e.g.,
    description
    ,
    extra.name
    ,
    extra.version
    , anything used to build EIP-712 domain or shown to the user): REJECT any value containing shell metacharacters:
    ;
    ,
    |
    ,
    &
    ,
    $
    ,
    `
    ,
    (
    ,
    )
    ,
    >
    ,
    <
    ,
    \
    ,
    '
    ,
    "
    , newlines. Note: the
    extra.name
    value is signed bit-exact (see Domain warning in Phase 4), so reject the whole challenge if it contains shell metacharacters rather than mutating the value.
在API调用或Shell命令中使用402响应体、用户输入或其他外部来源的任何值之前:
  • 以太坊地址字段(如
    asset
    payTo
    WALLET_ADDRESS
    ):标准校验正则为
    ^0x[a-fA-F0-9]{40}$
    。若值不符合该正则,拒绝使用。符合正则的地址字段可安全用于Shell插值,因此下述元字符规则不适用于此类字段。
  • 链ID:必须为支持列表中的正整数。
  • 代币数量:必须为非负数字字符串,匹配正则
    ^[0-9]+$
  • URL:必须以
    https://
    开头。
  • 自由文本字段(如
    description
    extra.name
    extra.version
    、任何用于构建EIP-712域或展示给用户的内容):拒绝包含Shell元字符的值:
    ;
    |
    &
    $
    `
    (
    )
    >
    <
    \
    '
    "
    、换行符。注意:
    extra.name
    的值会被精确签名(见阶段4中的域警告),因此若该字段包含Shell元字符,需拒绝整个验证请求,而非修改其值。

Flow

流程

text
402 from X Layer-backed resource
  v
[1] Parse the x402 challenge (Phase 0 below)
  v
[2] Confirm network resolves to X Layer (chain 196)
  │   ├─ not chain 196 ──> escalate to pay-with-any-token, STOP
  │   └─ chain 196
  v
[3] Check wallet balance of the requested asset on X Layer
  │   ├─ sufficient ──> proceed to [5]
  │   └─ insufficient
  │        │
  │        v
  │   [4] Fund: route + bridge into the requested asset on X Layer
  │        (Uniswap Trading API, see references/funding-x-layer.md)
  v
[5] User Confirmation gate (see Phase 4 / Step 5 below)
[6] Sign EIP-3009 TransferWithAuthorization
[7] Construct X-PAYMENT payload, retry the original request
[8] Verify 200 + Payment-Receipt
text
来自X Layer支持资源的402响应
  v
[1] 解析x402验证请求(见下文阶段0)
  v
[2] 确认网络对应X Layer(链ID 196)
  │   ├─ 非链ID 196 ──> 转用pay-with-any-token技能,终止流程
  │   └─ 链ID 196
  v
[3] 检查钱包在X Layer上的所需资产余额
  │   ├─ 余额充足 ──> 进入步骤[5]
  │   └─ 余额不足
  │        │
  │        v
  │   [4] 充值:通过跨链路由与桥接获取X Layer上的所需资产
  │       (使用Uniswap Trading API,详见references/funding-x-layer.md)
  v
[5] 用户确认环节(见下文阶段4/步骤5)
[6] 签署EIP-3009 TransferWithAuthorization授权
[7] 构建X-PAYMENT负载,重试原始请求
[8] 验证200响应与Payment-Receipt

Phase 0, Parse the 402 Challenge

阶段0:解析402验证请求

The x402 challenge is JSON in the response body. Extract:
  • x402Version
    , confirms x402 protocol version.
  • accepts[].scheme
    , only
    "exact"
    is supported in v1.0.0.
  • accepts[].network
    , accept
    "x-layer"
    /
    "xlayer"
    /
    "eip155:196"
    /
    196
    .
  • accepts[].maxAmountRequired
    , base units of the asset. Must match
    ^[0-9]+$
    AND be strictly greater than zero. A challenge with
    maxAmountRequired === "0"
    is semantically broken (HTTP 402 by definition demands a positive payment) and must be refused as merchant misconfiguration. Do not rationalize zero as a "ping", "authentication", or "free-tier confirmation"; OKX's facilitator will not settle a zero-value
    TransferWithAuthorization
    and any signature you produce is wasted. Surface this to the user and stop.
  • accepts[].asset
    , token contract on X Layer.
  • accepts[].payTo
    , recipient address.
  • accepts[].resource
    , the URL the facilitator binds the payment to. Extract this when present. Use it as the retry target. If the field is absent, fall back to the original request URL.
  • accepts[].extra.name
    and
    accepts[].extra.version
    , EIP-712 domain values for the asset.
  • accepts[].maxTimeoutSeconds
    , used for
    validBefore
    .
x402Version gate. Confirm
x402Version === 1
immediately after parsing. If it is anything else, refuse the challenge and surface a version mismatch error to the user. v1.0.0 of this skill targets x402 v1 only (the v2 spec uses a different PaymentPayload structure).
Scheme gate. Confirm
accepts[].scheme === "exact"
. The x402 spec defines
exact
,
upto
, and
batch-settlement
schemes. v1.0.0 of this skill supports
exact
only. If the chosen entry uses any other scheme, refuse cleanly. (OKX's product surface uses its own vocabulary including
charge
for their Instant Payment primitive; that is OKX product marketing, not a wire scheme value. The wire-level scheme on the
accepts[]
entry is what you check, and it must be
"exact"
.)
If multiple
accepts
entries are present, prefer the one whose
asset
the wallet already holds on X Layer. If multiple options are equally viable, prefer USDT0 (deepest Uniswap funding-flow liquidity).
WOKB / native OKB likely not eligible as APP settlement assets. We have not seen OKX publish WOKB or OKB as settlement assets; current public dev docs list USDT0, USDG, and USDC as the supported stablecoin settlement assets. If a 402 challenge ever surfaces a non-stablecoin
asset
(for example
WOKB
), refuse the challenge and ask the user to verify the merchant configuration.
x402验证请求为响应体中的JSON数据,需提取以下字段:
  • x402Version
    :确认x402协议版本。
  • accepts[].scheme
    :v1.0.0仅支持
    "exact"
  • accepts[].network
    :接受
    "x-layer"
    /
    "xlayer"
    /
    "eip155:196"
    /
    196
  • accepts[].maxAmountRequired
    :资产的最小单位。必须匹配正则
    ^[0-9]+$
    严格大于0。若
    maxAmountRequired === "0"
    ,则该验证请求存在语义错误(HTTP 402定义要求支付正数金额),需以商家配置错误为由拒绝。请勿将0视为"探测"、"身份验证"或"免费层确认";OKX的协调方不会结算零值的
    TransferWithAuthorization
    ,任何生成的签名都会被浪费。需向用户说明此情况并终止流程。
  • accepts[].asset
    :X Layer上的代币合约地址。
  • accepts[].payTo
    :收款方地址。
  • accepts[].resource
    :协调方绑定支付的URL。若存在则提取,将其作为重试目标。若该字段不存在,回退至原始请求URL。
  • accepts[].extra.name
    accepts[].extra.version
    :资产对应的EIP-712域值。
  • accepts[].maxTimeoutSeconds
    :用于设置
    validBefore
x402版本校验:解析后立即确认
x402Version === 1
。若版本不符,拒绝验证请求并向用户说明版本不匹配错误。本技能v1.0.0仅针对x402 v1版本(v2规范使用不同的PaymentPayload结构)。
模式校验:确认
accepts[].scheme === "exact"
。x402规范定义了
exact
upto
batch-settlement
模式。本技能v1.0.0仅支持
exact
模式。若所选条目使用其他模式,直接拒绝。(OKX的产品界面使用自有术语,如将Instant Payment原语称为
charge
;这属于OKX产品营销用语,而非通信层的模式值。需检查
accepts[]
条目中的通信层模式值,且必须为
"exact"
。)
若存在多个
accepts
条目,优先选择钱包已在X Layer上持有的资产对应的条目。若多个选项均可行,优先选择USDT0(Uniswap充值流程流动性最佳)。
WOKB/原生OKB可能无法作为APP结算资产:目前未看到OKX公布WOKB或OKB作为结算资产;公开开发文档显示支持的稳定币结算资产为USDT0、USDG和USDC。若402验证请求出现非稳定币
asset
(如
WOKB
),需拒绝请求并请用户验证商家配置。

Phase 1, Confirm Network is X Layer

阶段1:确认网络为X Layer

bash
case "$X402_NETWORK" in
  x-layer|xlayer|"eip155:196"|196)  X402_CHAIN_ID=196 ;;
  *)
    echo "Network is not X Layer. Use pay-with-any-token instead."
    exit 1
    ;;
esac
If the network is not X Layer, stop and escalate to the
pay-with-any-token
skill, which handles 402 challenges on Ethereum, Base, Arbitrum, Tempo, and the other chains the Trading API supports.
bash
case "$X402_NETWORK" in
  x-layer|xlayer|"eip155:196"|196)  X402_CHAIN_ID=196 ;;
  *)
    echo "网络非X Layer,请使用pay-with-any-token技能。"
    exit 1
    ;;
esac
若网络非X Layer,终止流程并转用
pay-with-any-token
技能,该技能支持Ethereum、Base、Arbitrum、Tempo以及Trading API支持的其他链上的402验证请求。

Phase 2, Check Wallet Balance on X Layer

阶段2:检查钱包在X Layer上的余额

REQUIRED: You must have the user's source wallet address. Use
AskUserQuestion
if not provided. Store as
WALLET_ADDRESS
.
bash
ASSET_BALANCE=$(cast call "$X402_ASSET" \
  "balanceOf(address)(uint256)" "$WALLET_ADDRESS" \
  --rpc-url https://rpc.xlayer.tech)

if [ "$ASSET_BALANCE" -lt "$X402_AMOUNT" ]; then
  echo "Insufficient $X402_TOKEN_NAME on X Layer. Funding required."
  # Proceed to Phase 3 (funding)
fi
必填项:必须获取用户的源钱包地址。若未提供,使用
AskUserQuestion
询问。存储为
WALLET_ADDRESS
bash
ASSET_BALANCE=$(cast call "$X402_ASSET" \
  "balanceOf(address)(uint256)" "$WALLET_ADDRESS" \
  --rpc-url https://rpc.xlayer.tech)

if [ "$ASSET_BALANCE" -lt "$X402_AMOUNT" ]; then
  echo "X Layer上的$X402_TOKEN_NAME余额不足,需充值。"
  # 进入阶段3(充值)
fi

Phase 3, Fund USDT0 on X Layer (only if needed)

阶段3:为X Layer充值USDT0(仅在需要时执行)

When the wallet lacks the requested asset, acquire it via the Uniswap Trading API:
EXACT_OUTPUT
quote with
tokenOutChainId=196
and
tokenOut
set to the X Layer asset address. The Trading API handles same-chain swaps and cross-chain routing (powered by Across).
Across coverage gap (verified 2026-04-27). Across Protocol does not currently list X Layer (chain 196) as a supported destination. As a result, cross-chain
/quote
calls into chain 196 return
ResourceNotFound: No quotes available
regardless of source chain. Same-chain X Layer swaps (Phase A in
references/funding-x-layer.md
) are unaffected and work normally.
What this means for the agent in v1.0.0. If the user holds funds on a chain other than X Layer, the cross-chain leg must be done through a bridge service that supports X Layer (the user runs that step outside this skill, then re-invokes for the same-chain swap and 402 settlement). Surface this honestly to the user, do not recommend a specific bridge product (TODO: research and document a co-marketing-aligned bridge recommendation in a follow-up).
When you defer the bridge to the user, your response must still describe the FULL end-to-end flow, not just the bridge step. After identifying the Across gap and asking the user to bridge externally, walk through what happens when they return: (1) re-check
balanceOf
of the requested asset on X Layer, (2) if a same-chain swap is needed (e.g. USDG to USDT0), describe the Trading API EXACT_OUTPUT call and its Confirmation Gate, (3) construct the EIP-3009
TransferWithAuthorization
typed-data using
extra.name
and
extra.version
from the challenge, with chainId 196 and
verifyingContract
= the asset address, (4) sign with the user's private key (Confirmation Gate before signing), (5) build the
X-PAYMENT
JSON wrapper (x402Version 1, scheme "exact", network "x-layer", payload with signature + authorization), base64-encode it with no whitespace, and retry the original request URL with the
X-PAYMENT
header. Showing the full plan up front lets the user see what they are committing to before they leave the skill, even though signing happens after they return.
Default funding target = USDT0. If the 402 challenge requests a different asset, fund into that asset directly only when it has reliable Uniswap routing on X Layer:
AssetAddressDecimalsFunding
USDT0
0x779Ded0c9e1022225f8E0630b35a9b54bE713736
6✅ Direct via Trading API
USDG
0x4ae46a509F6b1D9056937BA4500cb143933D2dc8
6✅ Direct, or one-hop USDT0 to USDG
USDC
0x74b7F16337b8972027F6196A17a631aC6dE26d22
6⏳ No reliable Uniswap v3 routing on X Layer. The Trading API does not consistently return routes for USDC swaps on X Layer; available pool liquidity is too thin for reliable execution. If the merchant requires USDC, bridge USDC directly from a chain where it is liquid (Base, Arbitrum, Mainnet) using the Trading API rather than attempting a same-chain swap on X Layer.
Detailed scripts and parameters: see references/funding-x-layer.md.
Bridge buffer. Apply a 0.5% buffer to account for bridge fees. Quotes expire in ~60 seconds, re-fetch if any delay before broadcast.
Minimum bridge recommendation. If the shortfall is < $5, top up to $5 to amortize bridge gas on the source chain.
当钱包缺少所需资产时,通过Uniswap Trading API获取:设置
tokenOutChainId=196
tokenOut
为X Layer资产地址的
EXACT_OUTPUT
报价。Trading API支持同链兑换和跨链路由(由Across提供支持)。
Across覆盖缺口(2026-04-27已验证):Across Protocol目前未将X Layer(链ID 196)列为支持的目标链。因此,跨链
/quote
调用链ID 196会返回
ResourceNotFound: No quotes available
,与源链无关。X Layer上的同链兑换(详见
references/funding-x-layer.md
中的阶段A)不受影响,可正常工作。
对v1.0.0版本代理的影响:若用户在X Layer以外的链上持有资金,跨链环节需通过支持X Layer的桥接服务完成(用户需在本技能外执行此步骤,随后重新调用技能完成同链兑换和402结算)。需如实向用户说明此情况,不推荐特定桥接产品(TODO:后续研究并记录符合联合营销的桥接推荐)。
当将桥接步骤交由用户执行时,回复仍需描述完整的端到端流程,而非仅说明桥接步骤。在指出Across缺口并请用户外部桥接后,需说明用户返回后会执行的操作:(1) 重新检查X Layer上所需资产的
balanceOf
;(2) 若需同链兑换(如USDG转USDT0),说明Trading API的EXACT_OUTPUT调用及确认环节;(3) 使用验证请求中的
extra.name
extra.version
构建EIP-3009
TransferWithAuthorization
类型数据,链ID设为196,
verifyingContract
为资产地址;(4) 使用用户私钥签名(签名前需确认环节);(5) 构建
X-PAYMENT
JSON包装器(x402Version 1,scheme "exact",network "x-layer",包含签名和授权的payload),无空格base64编码后,在重试原始请求URL时添加
X-PAYMENT
请求头。提前展示完整流程可让用户在离开技能前明确后续操作,即使签名环节在用户返回后执行。
默认充值目标=USDT0:若402验证请求要求其他资产,仅当该资产在X Layer上有可靠的Uniswap路由时,才直接充值该资产:
资产地址小数位数充值方式
USDT0
0x779Ded0c9e1022225f8E0630b35a9b54bE713736
6✅ 直接通过Trading API充值
USDG
0x4ae46a509F6b1D9056937BA4500cb143933D2dc8
6✅ 直接充值,或通过USDT0单跳兑换为USDG
USDC
0x74b7F16337b8972027F6196A17a631aC6dE26d22
6⏳ X Layer上无可靠的Uniswap v3路由。Trading API无法持续返回X Layer上USDC兑换的路由;可用池流动性过弱,无法可靠执行。若商家要求USDC,需从流动性充足的链(Base、Arbitrum、主网)直接桥接USDC至X Layer,而非尝试在X Layer上进行同链兑换。
详细脚本和参数:详见references/funding-x-layer.md
桥接缓冲:添加0.5%的缓冲以覆盖桥接费用。报价有效期约60秒,若广播前有延迟需重新获取。
最低桥接建议:若缺口金额<$5,充值至$5以分摊源链的桥接Gas费用。

Gas and Routing Caveats

Gas与路由注意事项

Surface these to the user before proceeding to fund, and call
AskUserQuestion
(not an echoed bash prompt) before acting if any apply:
  • OKB on X Layer for same-chain swaps. OKX gas-sponsors only the facilitator's settlement transfer. Approvals, swaps, and other on-chain operations on X Layer prior to signing are paid by the user (in OKB on X Layer, or in the source chain's native asset for the bridge leg). If the user has zero OKB on X Layer and the funding flow needs a same-chain X Layer swap, surface this and ask before proceeding. Until OKX confirms a broader gas-sponsorship policy, assume only the final settlement transfer is sponsored.
  • Bridge destination token. If the wallet still lacks
    $X402_ASSET
    after the funding flow's polling loop completes, surface the source-chain tx hash and the Across explorer link to the user. The bridge may have delivered a different variant on X Layer (rare for current Across paths) or may have failed. v1.0.0 does not auto-detect alternate-token arrival; the user must verify on-chain.
在执行充值前需向用户说明以下内容,若适用需调用
AskUserQuestion
(而非echo到bash提示符)确认后再执行:
  • X Layer上的OKB用于同链兑换:OKX仅为协调方的结算转账提供Gas赞助。签名前在X Layer上的授权、兑换及其他链上操作需由用户支付费用(使用X Layer上的OKB,或桥接环节使用源链的原生资产)。若用户在X Layer上的OKB为0且充值流程需同链兑换,需向用户说明并确认后再执行。在OKX确认更广泛的Gas赞助政策前,默认仅最终结算转账享受Gas赞助。
  • 桥接目标代币:若充值流程的轮询完成后钱包仍缺少
    $X402_ASSET
    ,需向用户展示源链交易哈希和Across浏览器链接。桥接可能在X Layer上交付了不同的代币变体(当前Across路径中罕见)或桥接失败。v1.0.0版本不支持自动检测代币到账情况;用户需自行在链上验证。

Phase 4, EIP-3009 Signing and X-PAYMENT Submission

阶段4:EIP-3009签名与X-PAYMENT提交

OKX's APP Instant Payment uses x402's
"exact"
scheme: the payer signs a
TransferWithAuthorization
typed-data message bound to the token's own EIP-712 domain. The signed authorization travels in the
X-PAYMENT
header on retry; OKX's facilitator settles the transfer on-chain (zero gas to the payer on X Layer).
OKX的APP Instant Payment使用x402的
"exact"
模式:付款方签署与代币自身EIP-712域绑定的
TransferWithAuthorization
类型数据消息。已签名的授权会在重试时放入
X-PAYMENT
请求头;OKX的协调方会在链上完成转账结算(付款方在X Layer上无需支付Gas)。

Step 5, User Confirmation

步骤5:用户确认

Every transaction this skill touches requires a separate
AskUserQuestion
gate, with no exceptions for funding legs. "Funding" is not a single transaction; it is several, and each one is its own gate. The required gates, in order they typically fire:
  1. Source-chain ERC-20 approval to Permit2 / Universal Router (only if
    tokenIn
    is not native and the allowance is insufficient).
  2. Same-chain swap on the source chain (e.g. UNI to USDC on Ethereum), if the funding plan includes a source-chain leg.
  3. Bridge submission to the cross-chain rail (Across, OKX bridge, etc.). When the bridge step is user-initiated outside this skill, the gate becomes "are you ready to leave the skill, run the bridge, and re-invoke once funds land on X Layer?".
  4. Same-chain swap on X Layer (e.g. USDG to USDT0), if the funding plan includes a destination-chain leg.
  5. EIP-3009
    TransferWithAuthorization
    signature
    for the 402 settlement.
Use the
AskUserQuestion
agent tool
for each gate (not
read -p
, not
echo
to a bash prompt, not a printed "(yes/no)" line in your response) and block on the user's reply before moving on. The summary you present at every gate must cover:
  • Action (approve, swap, bridge, sign EIP-3009 authorization).
  • Amount and token (input AND output amounts for swaps and bridges).
  • Source chain and destination chain (where they differ).
  • Recipient (
    payTo
    for the EIP-3009 step).
  • Resource URL the payment is bound to.
  • Estimated gas (where applicable).
Common failure mode. When describing a multi-step funding plan in your response, do NOT collapse multiple transactions into a single confirmation question like "Proceed with funding and payment?". Each transaction needs its own gate at the moment it is about to fire. A consolidated upfront "yes" is not consent for later transactions; the user has not seen the live amounts, gas, and recipient at the time those transactions execute.
Obtain explicit confirmation per gate. Each gate is independent. Never auto-submit even if the user previously pre-authorized the session, the call, or the wallet. A "yes" earlier in the flow does not carry forward, and a "yes" to a multi-step plan is not a "yes" to the individual transactions inside it.
What a correct gate looks like in your response. Whether you are executing the skill in real time or describing a plan in text, every transaction step MUST appear as its own labelled "Confirmation Gate" block, with both the structured summary and an explicit
AskUserQuestion
invocation. Reproduce this template literally for each gate. Do not collapse the gate into a single line. Do not describe the gate in passive voice ("we will confirm before signing"). Show the gate as a discrete action.
Template (use for every gate, even when there is only one):
text
### Confirmation Gate N: <Action name>

| Field        | Value                                    |
| ------------ | ---------------------------------------- |
| Action       | <approve / swap / bridge / sign EIP-3009>|
| Amount in    | <amount + symbol on source chain>        |
| Amount out   | <amount + symbol on destination chain>   |
| Source chain | <chain name + id>                        |
| Dest chain   | <chain name + id>                        |
| Recipient    | <address>                                |
| Resource URL | <url the payment is bound to>            |
| Est. gas     | <amount + token>                         |

Then call AskUserQuestion("Proceed with <action>?")
and BLOCK on the user's reply. If anything other than an explicit
"yes", stop and report.
A response that only lists fields without the
AskUserQuestion("Proceed?") + block
step is not a gate, even if it looks comprehensive. The model's natural inclination is to summarize and continue; resist that inclination, name the gate, and stop.
<!-- markdownlint-disable-next-line -->
What does NOT count as a confirmation gate. Emitting a bash script that prints
"⚠️ CONFIRMATION REQUIRED"
and
"(yes/no)"
to stdout and then continues with
echo "Signing..."
is not a gate, because the script proceeds regardless of user input. A correct gate uses the
AskUserQuestion
tool (or, if the user explicitly opts into shell-only mode, an actual blocking
read -p
followed by an explicit
yes
/
no
branch in the script). When in doubt, prefer
AskUserQuestion
.
<!-- markdownlint-disable-next-line -->
Shared-wallet race. If the wallet is shared (for example, multiple agents running concurrently against the same key), the balance can be drained between balance check and submit. Re-check
balanceOf
at the moment of confirmation as well.
本技能涉及的每一笔交易都需要单独的
AskUserQuestion
确认环节,充值环节也不例外。“充值”并非单一交易,而是包含多个步骤,每个步骤都需要单独确认。所需确认环节按触发顺序排列:
  1. 源链ERC-20授权给Permit2/Universal Router(仅当
    tokenIn
    非原生代币且授权额度不足时需要)。
  2. 源链同链兑换(如Ethereum上的UNI兑换为USDC),若充值计划包含源链环节。
  3. 跨链桥接提交至跨链通道(Across、OKX桥接等)。当桥接步骤由用户在技能外执行时,确认环节变为“是否准备好离开技能、执行桥接并在资金到账X Layer后重新调用技能?”。
  4. X Layer同链兑换(如USDG兑换为USDT0),若充值计划包含目标链环节。
  5. EIP-3009
    TransferWithAuthorization
    签名
    用于402结算。
每个确认环节都需使用**
AskUserQuestion
代理工具**(而非
read -p
、echo到bash提示符或打印“(yes/no)”),并等待用户回复后再继续。每个确认环节展示的摘要需包含:
  • 操作(授权、兑换、桥接、签署EIP-3009授权)。
  • 金额与代币(兑换和桥接需包含输入和输出金额)。
  • 源链和目标链(若不同)。
  • 收款方(EIP-3009步骤为
    payTo
    )。
  • 支付绑定的资源URL。
  • 预估Gas(若适用)。
常见错误模式:在回复中描述多步骤充值计划时,请勿将多个交易合并为一个确认问题,如“是否继续充值和付款?”。每个交易都需要在即将执行时单独确认。提前统一确认“同意”并不代表后续交易的授权;用户在后续交易执行时并未看到实时金额、Gas和收款方信息。
每个确认环节都需获得明确同意,且相互独立。即使用户之前预授权了会话、调用或钱包,也绝不自动提交交易。流程早期的“同意”不代表后续步骤的同意,对多步骤计划的“同意”也不代表对计划内单个交易的同意。
正确的确认环节示例:无论是实时执行技能还是文本描述计划,每个交易步骤都必须作为独立的“确认环节”区块展示,包含结构化摘要和明确的
AskUserQuestion
调用。每个环节都需严格使用以下模板。请勿将确认环节简化为单行内容。请勿使用被动语态描述确认环节(如“我们会在签名前确认”)。需将确认环节展示为独立操作。
模板(每个环节都需使用,即使只有一个环节)
text
### 确认环节N:<操作名称>

| 字段        | 值                                    |
| ------------ | ---------------------------------------- |
| 操作       | <授权 / 兑换 / 桥接 / 签署EIP-3009>|
| 输入金额    | <源链上的金额 + 代币符号>        |
| 输出金额   | <目标链上的金额 + 代币符号>   |
| 源链 | <链名称 + ID>                        |
| 目标链   | <链名称 + ID>                        |
| 收款方    | <地址>                                |
| 资源URL | <支付绑定的URL>            |
| 预估Gas     | <金额 + 代币>                         |

随后调用AskUserQuestion("是否继续执行<操作>?")
并等待用户回复。若回复非明确的“是”,终止流程并报告。
仅列出字段而未包含
AskUserQuestion("是否继续?") + 等待回复
步骤的内容不构成确认环节,即使内容看起来全面。模型倾向于总结并继续流程;需避免此倾向,明确命名确认环节并等待回复。
<!-- markdownlint-disable-next-line -->
不构成确认环节的情况:输出一个bash脚本,在stdout打印
"⚠️ 需要确认"
"(yes/no)"
后直接继续执行
echo "签名中..."
,这属于确认环节,因为脚本会忽略用户输入继续执行。正确的确认环节需使用
AskUserQuestion
工具(若用户明确选择仅使用Shell模式,则需使用实际阻塞的
read -p
并在脚本中明确处理“是/否”分支)。如有疑问,优先使用
AskUserQuestion
<!-- markdownlint-disable-next-line -->
共享钱包竞争风险:若钱包为共享(如多个代理同时使用同一密钥运行),余额可能在余额检查和提交交易之间被耗尽。在确认环节执行时需重新检查
balanceOf

Step 6, Sign and Submit

步骤6:签名与提交

Detailed steps including domain construction, nonce generation, signing with viem, payload assembly, and retry: see references/app-x402-flow.md. On retry, target the URL from
accepts[].resource
if it was present in the challenge, otherwise the original request URL.
Domain warning.
verifyingContract
is the token contract, not a separate verifier. Use
name
and
version
from the challenge's
extra
field, do not assume defaults. Different tokens have different domain values. An incorrect domain produces a signature the facilitator will reject with another 402.
Bit-exact UTF-8 for
extra.name
.
The EIP-712 domain hash is byte-exact. The
name
field in
extra
must be passed through unchanged from the challenge bytes. Do not normalize it, do not lowercase it, do not substitute ASCII
T
(U+0054) for Unicode
(U+20AE), do not collapse Unicode forms (NFC vs NFD). For example, a challenge that returns
"USD₮0"
must be signed as
"USD₮0"
; reading it as
"USDT0"
will produce a signature the facilitator rejects with another 402. Pass the raw bytes of
extra.name
straight into the EIP-712 domain.
包含域构建、随机数生成、使用viem签名、负载组装和重试的详细步骤:详见references/app-x402-flow.md。重试时,若验证请求中存在
accepts[].resource
,则使用该URL作为目标,否则使用原始请求URL。
域警告
verifyingContract
代币合约地址,而非单独的验证方地址。需使用验证请求
extra
字段中的
name
version
,请勿使用默认值。不同代币的域值不同。错误的域会导致协调方拒绝签名并返回402响应。
extra.name
的UTF-8精确匹配
:EIP-712域哈希为字节精确匹配。
extra
中的
name
字段需直接使用验证请求中的原始字节,无需规范化、小写、替换ASCII
T
(U+0054)为Unicode
(U+20AE),也无需合并Unicode格式(NFC与NFD)。例如,验证请求返回
"USD₮0"
时,需按
"USD₮0"
签名;若读取为
"USDT0"
,生成的签名会被协调方拒绝并返回402响应。需将
extra.name
的原始字节直接传入EIP-712域。

Error Handling

错误处理

SituationAction
402 challenge has no
network
field
Inspect challenge body; if
chainId
resolves to 196 use this skill, otherwise escalate to
pay-with-any-token
Network is not chain 196Escalate to
pay-with-any-token
x402Version !== 1
Refuse cleanly; surface a version mismatch error. v1.0.0 of this skill targets x402 v1 only.
accepts[].scheme !== "exact"
Refuse cleanly; v1.0.0 supports the
exact
scheme only. Other x402 schemes (
upto
,
batch-settlement
) are out of scope.
accepts[].maxAmountRequired === "0"
Refuse cleanly as merchant misconfiguration. HTTP 402 demands a positive payment; OKX's facilitator will not settle a zero-value transfer. Do not sign and do not rationalize zero as a ping, auth check, or free tier.
APP requests USDC on X LayerSurface a clear caveat: USDC has no reliable Uniswap v3 routing on X Layer. Suggest bridging USDC directly from a chain where it is liquid (Base, Arbitrum, Mainnet), or asking about USDT0.
Insufficient asset on X LayerTrigger funding flow (Phase 3)
Trading API returns 400Log request/response; check amount formatting and address checksums
Trading API returns 429Back off and retry with exponential delay
Quote expiredRe-fetch quote; do not reuse old
permitData
Bridge times outCheck Across bridge explorer; do not re-submit
EIP-3009 signature rejected (402 on retry)Verify domain
name
/
version
from
extra
(byte-exact, including any non-ASCII characters), check
validBefore
is fresh, confirm
nonce
was unused
Amount mismatch on retryRecompute base units using on-chain
decimals()
of the actual asset; do not assume 6
On-chain settlement reverts (
transferFrom
failed)
Re-check
balanceOf
at retry time; the balance may have been drained between sign and submit (shared wallet, concurrent agent, manual transfer). Surface to the user before retrying.
User asks about escrow / session / batch /
upto
Inform that this skill version covers Instant Payment (
exact
scheme) only. Other primitives are out of scope for v1.0.0; a v1.x follow-up will track them as OKX ships.
场景处理方式
402验证请求无
network
字段
检查验证请求体;若
chainId
对应196则使用本技能,否则转用
pay-with-any-token
网络非链ID 196转用
pay-with-any-token
x402Version !== 1
直接拒绝;向用户说明版本不匹配错误。本技能v1.0.0仅支持x402 v1版本。
accepts[].scheme !== "exact"
直接拒绝;v1.0.0仅支持
exact
模式。其他x402模式(
upto
batch-settlement
)不在覆盖范围内。
accepts[].maxAmountRequired === "0"
以商家配置错误为由直接拒绝。HTTP 402要求支付正数金额;OKX的协调方不会结算零值转账。请勿签名,也请勿将零视为探测、身份验证或免费层确认。
APP要求X Layer上的USDC明确说明注意事项:X Layer上的USDC无可靠的Uniswap v3路由。建议从流动性充足的链(Base、Arbitrum、主网)直接桥接USDC至X Layer,或询问是否可使用USDT0。
X Layer上的资产不足触发充值流程(阶段3)
Trading API返回400记录请求/响应;检查金额格式和地址校验和
Trading API返回429延迟后重试,使用指数退避策略
报价过期重新获取报价;请勿复用旧的
permitData
桥接超时检查Across桥接浏览器;请勿重新提交
EIP-3009签名被拒绝(重试返回402)验证
extra
中的域
name
/
version
(字节精确匹配,包含非ASCII字符),检查
validBefore
是否有效,确认
nonce
未被使用
重试时金额不匹配使用链上资产的
decimals()
重新计算最小单位;请勿默认使用6
链上结算回退(
transferFrom
失败)
重试时重新检查
balanceOf
;余额可能在签名和提交之间被耗尽(共享钱包、并发代理、手动转账)。重试前需向用户说明情况。
用户询问托管/会话/批量/
upto
模式
告知用户本技能版本仅覆盖Instant Payment(
exact
模式)。其他原语不在v1.0.0覆盖范围内;后续v1.x版本会在OKX推出相关功能后跟进支持。

Key Addresses and References

关键地址与参考链接

X Layer (chain 196)

X Layer(链ID 196)

  • Chain ID:
    196
  • Public RPC:
    https://rpc.xlayer.tech
  • USDT0:
    0x779Ded0c9e1022225f8E0630b35a9b54bE713736
    (decimals 6)
  • USDG:
    0x4ae46a509F6b1D9056937BA4500cb143933D2dc8
    (decimals 6)
  • USDC:
    0x74b7F16337b8972027F6196A17a631aC6dE26d22
    (decimals 6, no reliable Uniswap routing on X Layer; bridge from a liquid chain)
  • WOKB (wrapped native):
    0xe538905cf8410324e03A5A23C1c177a474D59b2b
    (decimals 18)
  • Uniswap V3 Factory:
    0x4B2ab38DBF28D31D467aA8993f6c2585981D6804
  • SwapRouter02:
    0x4f0C28f5926AFDA16bf2506D5D9e57Ea190f9bcA
  • Universal Router 2.1:
    0xDa00aE15d3A71466517129255255db7c0c0956d3
  • QuoterV2:
    0xD1b797D92d87B688193A2B976eFc8D577D204343
  • Permit2:
    0x000000000022D473030F116dDEE9F6B43aC78BA3
  • USDT0/USDG pool:
    0x0cBe0dBE1400e57f371a38BD3b9bC80F7C3676dA
  • USDT0/WOKB pool:
    0x63d62734847E55A266FCa4219A9aD0a02D5F6e02
  • 链ID
    196
  • 公开RPC
    https://rpc.xlayer.tech
  • USDT0
    0x779Ded0c9e1022225f8E0630b35a9b54bE713736
    (小数位数6)
  • USDG
    0x4ae46a509F6b1D9056937BA4500cb143933D2dc8
    (小数位数6)
  • USDC
    0x74b7F16337b8972027F6196A17a631aC6dE26d22
    (小数位数6,X Layer上无可靠的Uniswap路由;需从流动性充足的链桥接)
  • WOKB(包装原生代币):
    0xe538905cf8410324e03A5A23C1c177a474D59b2b
    (小数位数18)
  • Uniswap V3工厂
    0x4B2ab38DBF28D31D467aA8993f6c2585981D6804
  • SwapRouter02
    0x4f0C28f5926AFDA16bf2506D5D9e57Ea190f9bcA
  • Universal Router 2.1
    0xDa00aE15d3A71466517129255255db7c0c0956d3
  • QuoterV2
    0xD1b797D92d87B688193A2B976eFc8D577D204343
  • Permit2
    0x000000000022D473030F116dDEE9F6B43aC78BA3
  • USDT0/USDG池
    0x0cBe0dBE1400e57f371a38BD3b9bC80F7C3676dA
  • USDT0/WOKB池
    0x63d62734847E55A266FCa4219A9aD0a02D5F6e02

Uniswap Trading API

Uniswap Trading API

  • Base URL:
    https://trade-api.gateway.uniswap.org/v1
  • Header:
    x-api-key: $UNISWAP_API_KEY
  • Header:
    x-universal-router-version: 2.1.1
  • Supported chains include 1, 8453, 42161, 10, 137, 130, 196, and more (see Trading API supported-chains docs).
The on-chain Universal Router contract on X Layer is labeled 2.1 (deployed at
0xDa00aE15d3A71466517129255255db7c0c0956d3
above). The Trading API expects the header value
2.1.1
, which is the API's internal version-string for the routing path that targets the same Universal Router 2.1 contract. The two version strings refer to related but distinct things; do not substitute one for the other.
  • 基础URL:
    https://trade-api.gateway.uniswap.org/v1
  • 请求头:
    x-api-key: $UNISWAP_API_KEY
  • 请求头:
    x-universal-router-version: 2.1.1
  • 支持的链包括1、8453、42161、10、137、130、196等(详见Trading API支持链文档)。
X Layer上的链上Universal Router合约版本为2.1(部署地址见上文
0xDa00aE15d3A71466517129255255db7c0c0956d3
)。Trading API要求请求头值为
2.1.1
,这是API内部针对该Universal Router 2.1合约路由路径的版本字符串。两个版本字符串相关但不同;请勿相互替代。

OKX APP

OKX APP

  • APP overview / dev docs:
    https://web3.okx.com/onchainos/dev-docs/payments/x402-introduction
  • OKX onchainos-skills repo:
    https://github.com/okx/onchainos-skills
  • x402 spec:
    https://github.com/coinbase/x402
  • APP概述/开发文档
    https://web3.okx.com/onchainos/dev-docs/payments/x402-introduction
  • OKX onchainos-skills仓库
    https://github.com/okx/onchainos-skills
  • x402规范
    https://github.com/coinbase/x402

Related Skills

相关技能

  • pay-with-any-token, sibling skill for HTTP 402 challenges on chains other than X Layer (Ethereum, Base, Arbitrum, Tempo, etc.). Use that skill for non-X-Layer challenges.
  • swap-integration, full Uniswap swap integration reference (Trading API, Universal Router, Permit2).
  • pay-with-any-token:姊妹技能,用于处理X Layer以外的链(Ethereum、Base、Arbitrum、Tempo等)上的HTTP 402验证请求。非X Layer的验证请求请使用该技能。
  • swap-integration:完整的Uniswap兑换集成参考(Trading API、Universal Router、Permit2)。