pay-with-app
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePay 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
off-chain, and OKX's facilitator verifies and
settles the transfer on-chain. Settlement is zero-gas to the payer on X
Layer.
TransferWithAuthorizationThis skill handles the full happy path:
- Detect a 402 challenge whose network resolves to X Layer (chain 196)
- Verify the payer wallet has the requested asset (typically USDT0)
- If insufficient, route + bridge into USDT0 on X Layer via the Uniswap Trading API
- Sign the EIP-3009 authorization
- Construct the payload and retry the original request
X-PAYMENT
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 scheme
(Pay Per Use, OKX product name: Instant Payment) only. Other x402 schemes
(, ) and APP-product features OKX is shipping
(escrow, session, batch / Batch Payment) are out of scope for this
version. The skill refuses any non- scheme cleanly.
exactuptobatch-settlementexactProtocol 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标准的授权,随后OKX的协调方会在链上验证并完成转账结算。付款方在X Layer上完成结算无需支付Gas费用。
TransferWithAuthorization本技能支持完整的正常流程:
- 检测到网络对应X Layer(链ID 196)的402验证请求
- 验证付款方钱包拥有所需资产(通常为USDT0)
- 若资产不足,通过Uniswap Trading API进行跨链路由与桥接,将资产转换为X Layer上的USDT0
- 签署EIP-3009授权
- 构建负载并重试原始请求
X-PAYMENT
OKX将于2026-04-29推出APP,Uniswap作为X Layer上的主推DEX通道。本技能版本(v1.0.0)仅支持模式(按次付费,OKX产品名称:Instant Payment)。其他x402模式(、)以及OKX即将推出的APP产品功能(托管、会话、批量支付/Batch Payment)不在本版本的覆盖范围内。本技能会直接拒绝所有非模式的请求。
exactuptobatch-settlementexact回复中的协议命名规范:在回复用户时,请明确将该协议标识为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 env var (
PRIVATE_KEY). Never commit or hardcode a private key.export PRIVATE_KEY=0x... - env var (register at developers.uniswap.org). Required only if the wallet must be funded via cross-chain routing.
UNISWAP_API_KEY - and
jq(Foundry) installed.cast - Node 18+ (LTS). The signing step in
references/app-x402-flow.md Step 4 uses
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
viembefore runningAskUserQuestioninto a cached scratch directory atnpm install viem. 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.~/.cache/uniswap-pay-with-app/signer/
- 配置环境变量(
PRIVATE_KEY)。切勿提交或硬编码私钥。export PRIVATE_KEY=0x... - 配置环境变量(在developers.uniswap.org注册获取)。仅当钱包需要通过跨链路由充值时才需此密钥。
UNISWAP_API_KEY - 安装和
jq(Foundry工具)。cast - Node 18+(长期支持版)。references/app-x402-flow.md步骤4中的签名环节使用生成EIP-3009类型数据签名。
viem - (npm包)。若用户工作目录中未安装该包,技能会通过
viem提示用户,随后在缓存目录AskUserQuestion中运行~/.cache/uniswap-pay-with-app/signer/。安装过程会添加约13个包,总大小约5MB。若用户拒绝,技能会在签名前直接终止。缓存会在多次运行中保留,后续调用无需重复安装。npm install viem
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): the canonical check is the regexWALLET_ADDRESS. 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.^0x[a-fA-F0-9]{40}$ - 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, anything used to build EIP-712 domain or shown to the user): REJECT any value containing shell metacharacters:extra.version,;,|,&,$,`,(,),>,<,\,', newlines. Note: the"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.extra.name
在API调用或Shell命令中使用402响应体、用户输入或其他外部来源的任何值之前:
- 以太坊地址字段(如、
asset、payTo):标准校验正则为WALLET_ADDRESS。若值不符合该正则,拒绝使用。符合正则的地址字段可安全用于Shell插值,因此下述元字符规则不适用于此类字段。^0x[a-fA-F0-9]{40}$ - 链ID:必须为支持列表中的正整数。
- 代币数量:必须为非负数字字符串,匹配正则。
^[0-9]+$ - URL:必须以开头。
https:// - 自由文本字段(如、
description、extra.name、任何用于构建EIP-712域或展示给用户的内容):拒绝包含Shell元字符的值:extra.version、;、|、&、$、`、(、)、>、<、\、'、换行符。注意:"的值会被精确签名(见阶段4中的域警告),因此若该字段包含Shell元字符,需拒绝整个验证请求,而非修改其值。extra.name
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-Receipttext
来自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-ReceiptPhase 0, Parse the 402 Challenge
阶段0:解析402验证请求
The x402 challenge is JSON in the response body. Extract:
- , confirms x402 protocol version.
x402Version - , only
accepts[].schemeis supported in v1.0.0."exact" - , accept
accepts[].network/"x-layer"/"xlayer"/"eip155:196".196 - , base units of the asset. Must match
accepts[].maxAmountRequiredAND be strictly greater than zero. A challenge with^[0-9]+$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-valuemaxAmountRequired === "0"and any signature you produce is wasted. Surface this to the user and stop.TransferWithAuthorization - , token contract on X Layer.
accepts[].asset - , recipient address.
accepts[].payTo - , 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[].resource - and
accepts[].extra.name, EIP-712 domain values for the asset.accepts[].extra.version - , used for
accepts[].maxTimeoutSeconds.validBefore
x402Version gate. Confirmimmediately 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).x402Version === 1Scheme gate. Confirm. The x402 spec definesaccepts[].scheme === "exact",exact, anduptoschemes. v1.0.0 of this skill supportsbatch-settlementonly. If the chosen entry uses any other scheme, refuse cleanly. (OKX's product surface uses its own vocabulary includingexactfor their Instant Payment primitive; that is OKX product marketing, not a wire scheme value. The wire-level scheme on thechargeentry is what you check, and it must beaccepts[].)"exact"
If multiple entries are present, prefer the one whose
the wallet already holds on X Layer. If multiple options are equally
viable, prefer USDT0 (deepest Uniswap funding-flow liquidity).
acceptsassetWOKB / 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
(for example ), refuse the challenge and ask the user to
verify the merchant configuration.
assetWOKBx402验证请求为响应体中的JSON数据,需提取以下字段:
- :确认x402协议版本。
x402Version - :v1.0.0仅支持
accepts[].scheme。"exact" - :接受
accepts[].network/"x-layer"/"xlayer"/"eip155:196"。196 - :资产的最小单位。必须匹配正则
accepts[].maxAmountRequired且严格大于0。若^[0-9]+$,则该验证请求存在语义错误(HTTP 402定义要求支付正数金额),需以商家配置错误为由拒绝。请勿将0视为"探测"、"身份验证"或"免费层确认";OKX的协调方不会结算零值的maxAmountRequired === "0",任何生成的签名都会被浪费。需向用户说明此情况并终止流程。TransferWithAuthorization - :X Layer上的代币合约地址。
accepts[].asset - :收款方地址。
accepts[].payTo - :协调方绑定支付的URL。若存在则提取,将其作为重试目标。若该字段不存在,回退至原始请求URL。
accepts[].resource - 和
accepts[].extra.name:资产对应的EIP-712域值。accepts[].extra.version - :用于设置
accepts[].maxTimeoutSeconds。validBefore
x402版本校验:解析后立即确认。若版本不符,拒绝验证请求并向用户说明版本不匹配错误。本技能v1.0.0仅针对x402 v1版本(v2规范使用不同的PaymentPayload结构)。x402Version === 1模式校验:确认。x402规范定义了accepts[].scheme === "exact"、exact和upto模式。本技能v1.0.0仅支持batch-settlement模式。若所选条目使用其他模式,直接拒绝。(OKX的产品界面使用自有术语,如将Instant Payment原语称为exact;这属于OKX产品营销用语,而非通信层的模式值。需检查charge条目中的通信层模式值,且必须为accepts[]。)"exact"
若存在多个条目,优先选择钱包已在X Layer上持有的资产对应的条目。若多个选项均可行,优先选择USDT0(Uniswap充值流程流动性最佳)。
acceptsWOKB/原生OKB可能无法作为APP结算资产:目前未看到OKX公布WOKB或OKB作为结算资产;公开开发文档显示支持的稳定币结算资产为USDT0、USDG和USDC。若402验证请求出现非稳定币(如),需拒绝请求并请用户验证商家配置。
assetWOKBPhase 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
;;
esacIf the network is not X Layer, stop and escalate to theskill, which handles 402 challenges on Ethereum, Base, Arbitrum, Tempo, and the other chains the Trading API supports.pay-with-any-token
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,终止流程并转用技能,该技能支持Ethereum、Base、Arbitrum、Tempo以及Trading API支持的其他链上的402验证请求。pay-with-any-token
Phase 2, Check Wallet Balance on X Layer
阶段2:检查钱包在X Layer上的余额
REQUIRED: You must have the user's source wallet address. Useif not provided. Store asAskUserQuestion.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(充值)
fiPhase 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: quote with and
set to the X Layer asset address. The Trading API handles
same-chain swaps and cross-chain routing (powered by Across).
EXACT_OUTPUTtokenOutChainId=196tokenOutAcross coverage gap (verified 2026-04-27). Across Protocol does not currently list X Layer (chain 196) as a supported destination. As a result, cross-chaincalls into chain 196 return/quoteregardless of source chain. Same-chain X Layer swaps (Phase A inResourceNotFound: No quotes available) are unaffected and work normally.references/funding-x-layer.mdWhat 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-checkof 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-3009balanceOftyped-data usingTransferWithAuthorizationandextra.namefrom the challenge, with chainId 196 andextra.version= the asset address, (4) sign with the user's private key (Confirmation Gate before signing), (5) build theverifyingContractJSON 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 theX-PAYMENTheader. 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.X-PAYMENT
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:
| Asset | Address | Decimals | Funding |
|---|---|---|---|
| USDT0 | | 6 | ✅ Direct via Trading API |
| USDG | | 6 | ✅ Direct, or one-hop USDT0 to USDG |
| USDC | | 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获取:设置和为X Layer资产地址的报价。Trading API支持同链兑换和跨链路由(由Across提供支持)。
tokenOutChainId=196tokenOutEXACT_OUTPUTAcross覆盖缺口(2026-04-27已验证):Across Protocol目前未将X Layer(链ID 196)列为支持的目标链。因此,跨链调用链ID 196会返回/quote,与源链无关。X Layer上的同链兑换(详见ResourceNotFound: No quotes available中的阶段A)不受影响,可正常工作。references/funding-x-layer.md对v1.0.0版本代理的影响:若用户在X Layer以外的链上持有资金,跨链环节需通过支持X Layer的桥接服务完成(用户需在本技能外执行此步骤,随后重新调用技能完成同链兑换和402结算)。需如实向用户说明此情况,不推荐特定桥接产品(TODO:后续研究并记录符合联合营销的桥接推荐)。当将桥接步骤交由用户执行时,回复仍需描述完整的端到端流程,而非仅说明桥接步骤。在指出Across缺口并请用户外部桥接后,需说明用户返回后会执行的操作:(1) 重新检查X Layer上所需资产的;(2) 若需同链兑换(如USDG转USDT0),说明Trading API的EXACT_OUTPUT调用及确认环节;(3) 使用验证请求中的balanceOf和extra.name构建EIP-3009extra.version类型数据,链ID设为196,TransferWithAuthorization为资产地址;(4) 使用用户私钥签名(签名前需确认环节);(5) 构建verifyingContractJSON包装器(x402Version 1,scheme "exact",network "x-layer",包含签名和授权的payload),无空格base64编码后,在重试原始请求URL时添加X-PAYMENT请求头。提前展示完整流程可让用户在离开技能前明确后续操作,即使签名环节在用户返回后执行。X-PAYMENT
默认充值目标=USDT0:若402验证请求要求其他资产,仅当该资产在X Layer上有可靠的Uniswap路由时,才直接充值该资产:
| 资产 | 地址 | 小数位数 | 充值方式 |
|---|---|---|---|
| USDT0 | | 6 | ✅ 直接通过Trading API充值 |
| USDG | | 6 | ✅ 直接充值,或通过USDT0单跳兑换为USDG |
| USDC | | 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
(not an echoed bash prompt) before acting if any
apply:
AskUserQuestion- 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
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.
$X402_ASSET
在执行充值前需向用户说明以下内容,若适用需调用(而非echo到bash提示符)确认后再执行:
AskUserQuestion- X Layer上的OKB用于同链兑换:OKX仅为协调方的结算转账提供Gas赞助。签名前在X Layer上的授权、兑换及其他链上操作需由用户支付费用(使用X Layer上的OKB,或桥接环节使用源链的原生资产)。若用户在X Layer上的OKB为0且充值流程需同链兑换,需向用户说明并确认后再执行。在OKX确认更广泛的Gas赞助政策前,默认仅最终结算转账享受Gas赞助。
- 桥接目标代币:若充值流程的轮询完成后钱包仍缺少,需向用户展示源链交易哈希和Across浏览器链接。桥接可能在X Layer上交付了不同的代币变体(当前Across路径中罕见)或桥接失败。v1.0.0版本不支持自动检测代币到账情况;用户需自行在链上验证。
$X402_ASSET
Phase 4, EIP-3009 Signing and X-PAYMENT Submission
阶段4:EIP-3009签名与X-PAYMENT提交
OKX's APP Instant Payment uses x402's scheme: the payer signs a
typed-data message bound to the token's
own EIP-712 domain. The signed authorization travels in the
header on retry; OKX's facilitator settles the transfer
on-chain (zero gas to the payer on X Layer).
"exact"TransferWithAuthorizationX-PAYMENTOKX的APP Instant Payment使用x402的模式:付款方签署与代币自身EIP-712域绑定的类型数据消息。已签名的授权会在重试时放入请求头;OKX的协调方会在链上完成转账结算(付款方在X Layer上无需支付Gas)。
"exact"TransferWithAuthorizationX-PAYMENTStep 5, User Confirmation
步骤5:用户确认
Every transaction this skill touches requires a separate
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:
AskUserQuestion- Source-chain ERC-20 approval to Permit2 / Universal Router (only
if is not native and the allowance is insufficient).
tokenIn - Same-chain swap on the source chain (e.g. UNI to USDC on Ethereum), if the funding plan includes a source-chain leg.
- 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?".
- Same-chain swap on X Layer (e.g. USDG to USDT0), if the funding plan includes a destination-chain leg.
- EIP-3009 signature for the 402 settlement.
TransferWithAuthorization
Use the agent tool for each gate (not ,
not 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:
AskUserQuestionread -pecho- 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 (for the EIP-3009 step).
payTo - 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.
<!-- markdownlint-disable-next-line -->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 explicitinvocation. 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.AskUserQuestionTemplate (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 thestep 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.AskUserQuestion("Proceed?") + block
<!-- markdownlint-disable-next-line -->What does NOT count as a confirmation gate. Emitting a bash script that printsand"⚠️ CONFIRMATION REQUIRED"to stdout and then continues with"(yes/no)"is not a gate, because the script proceeds regardless of user input. A correct gate uses theecho "Signing..."tool (or, if the user explicitly opts into shell-only mode, an actual blockingAskUserQuestionfollowed by an explicitread -p/yesbranch in the script). When in doubt, preferno.AskUserQuestion
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-checkat the moment of confirmation as well.balanceOf
本技能涉及的每一笔交易都需要单独的确认环节,充值环节也不例外。“充值”并非单一交易,而是包含多个步骤,每个步骤都需要单独确认。所需确认环节按触发顺序排列:
AskUserQuestion- 源链ERC-20授权给Permit2/Universal Router(仅当非原生代币且授权额度不足时需要)。
tokenIn - 源链同链兑换(如Ethereum上的UNI兑换为USDC),若充值计划包含源链环节。
- 跨链桥接提交至跨链通道(Across、OKX桥接等)。当桥接步骤由用户在技能外执行时,确认环节变为“是否准备好离开技能、执行桥接并在资金到账X Layer后重新调用技能?”。
- X Layer同链兑换(如USDG兑换为USDT0),若充值计划包含目标链环节。
- EIP-3009 签名用于402结算。
TransferWithAuthorization
每个确认环节都需使用**代理工具**(而非、echo到bash提示符或打印“(yes/no)”),并等待用户回复后再继续。每个确认环节展示的摘要需包含:
AskUserQuestionread -p- 操作(授权、兑换、桥接、签署EIP-3009授权)。
- 金额与代币(兑换和桥接需包含输入和输出金额)。
- 源链和目标链(若不同)。
- 收款方(EIP-3009步骤为)。
payTo - 支付绑定的资源URL。
- 预估Gas(若适用)。
常见错误模式:在回复中描述多步骤充值计划时,请勿将多个交易合并为一个确认问题,如“是否继续充值和付款?”。每个交易都需要在即将执行时单独确认。提前统一确认“同意”并不代表后续交易的授权;用户在后续交易执行时并未看到实时金额、Gas和收款方信息。
每个确认环节都需获得明确同意,且相互独立。即使用户之前预授权了会话、调用或钱包,也绝不自动提交交易。流程早期的“同意”不代表后续步骤的同意,对多步骤计划的“同意”也不代表对计划内单个交易的同意。
<!-- markdownlint-disable-next-line -->正确的确认环节示例:无论是实时执行技能还是文本描述计划,每个交易步骤都必须作为独立的“确认环节”区块展示,包含结构化摘要和明确的调用。每个环节都需严格使用以下模板。请勿将确认环节简化为单行内容。请勿使用被动语态描述确认环节(如“我们会在签名前确认”)。需将确认环节展示为独立操作。AskUserQuestion模板(每个环节都需使用,即使只有一个环节):text### 确认环节N:<操作名称> | 字段 | 值 | | ------------ | ---------------------------------------- | | 操作 | <授权 / 兑换 / 桥接 / 签署EIP-3009>| | 输入金额 | <源链上的金额 + 代币符号> | | 输出金额 | <目标链上的金额 + 代币符号> | | 源链 | <链名称 + ID> | | 目标链 | <链名称 + ID> | | 收款方 | <地址> | | 资源URL | <支付绑定的URL> | | 预估Gas | <金额 + 代币> | 随后调用AskUserQuestion("是否继续执行<操作>?") 并等待用户回复。若回复非明确的“是”,终止流程并报告。仅列出字段而未包含步骤的内容不构成确认环节,即使内容看起来全面。模型倾向于总结并继续流程;需避免此倾向,明确命名确认环节并等待回复。AskUserQuestion("是否继续?") + 等待回复
<!-- markdownlint-disable-next-line -->不构成确认环节的情况:输出一个bash脚本,在stdout打印和"⚠️ 需要确认"后直接继续执行"(yes/no)",这不属于确认环节,因为脚本会忽略用户输入继续执行。正确的确认环节需使用echo "签名中..."工具(若用户明确选择仅使用Shell模式,则需使用实际阻塞的AskUserQuestion并在脚本中明确处理“是/否”分支)。如有疑问,优先使用read -p。AskUserQuestion
共享钱包竞争风险:若钱包为共享(如多个代理同时使用同一密钥运行),余额可能在余额检查和提交交易之间被耗尽。在确认环节执行时需重新检查。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 if it was present in the
challenge, otherwise the original request URL.
accepts[].resourceDomain warning.is the token contract, not a separate verifier. UseverifyingContractandnamefrom the challenge'sversionfield, do not assume defaults. Different tokens have different domain values. An incorrect domain produces a signature the facilitator will reject with another 402.extraBit-exact UTF-8 for. The EIP-712 domain hash is byte-exact. Theextra.namefield innamemust be passed through unchanged from the challenge bytes. Do not normalize it, do not lowercase it, do not substitute ASCIIextra(U+0054) for UnicodeT(U+20AE), do not collapse Unicode forms (NFC vs NFD). For example, a challenge that returns₮must be signed as"USD₮0"; reading it as"USD₮0"will produce a signature the facilitator rejects with another 402. Pass the raw bytes of"USDT0"straight into the EIP-712 domain.extra.name
包含域构建、随机数生成、使用viem签名、负载组装和重试的详细步骤:详见references/app-x402-flow.md。重试时,若验证请求中存在,则使用该URL作为目标,否则使用原始请求URL。
accepts[].resource域警告:为代币合约地址,而非单独的验证方地址。需使用验证请求verifyingContract字段中的extra和name,请勿使用默认值。不同代币的域值不同。错误的域会导致协调方拒绝签名并返回402响应。version的UTF-8精确匹配:EIP-712域哈希为字节精确匹配。extra.name中的extra字段需直接使用验证请求中的原始字节,无需规范化、小写、替换ASCIIname(U+0054)为UnicodeT(U+20AE),也无需合并Unicode格式(NFC与NFD)。例如,验证请求返回₮时,需按"USD₮0"签名;若读取为"USD₮0",生成的签名会被协调方拒绝并返回402响应。需将"USDT0"的原始字节直接传入EIP-712域。extra.name
Error Handling
错误处理
| Situation | Action |
|---|---|
402 challenge has no | Inspect challenge body; if |
| Network is not chain 196 | Escalate to |
| Refuse cleanly; surface a version mismatch error. v1.0.0 of this skill targets x402 v1 only. |
| Refuse cleanly; v1.0.0 supports the |
| 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 Layer | Surface 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 Layer | Trigger funding flow (Phase 3) |
| Trading API returns 400 | Log request/response; check amount formatting and address checksums |
| Trading API returns 429 | Back off and retry with exponential delay |
| Quote expired | Re-fetch quote; do not reuse old |
| Bridge times out | Check Across bridge explorer; do not re-submit |
| EIP-3009 signature rejected (402 on retry) | Verify domain |
| Amount mismatch on retry | Recompute base units using on-chain |
On-chain settlement reverts ( | Re-check |
User asks about escrow / session / batch / | Inform that this skill version covers Instant Payment ( |
| 场景 | 处理方式 |
|---|---|
402验证请求无 | 检查验证请求体;若 |
| 网络非链ID 196 | 转用 |
| 直接拒绝;向用户说明版本不匹配错误。本技能v1.0.0仅支持x402 v1版本。 |
| 直接拒绝;v1.0.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 | 延迟后重试,使用指数退避策略 |
| 报价过期 | 重新获取报价;请勿复用旧的 |
| 桥接超时 | 检查Across桥接浏览器;请勿重新提交 |
| EIP-3009签名被拒绝(重试返回402) | 验证 |
| 重试时金额不匹配 | 使用链上资产的 |
链上结算回退( | 重试时重新检查 |
用户询问托管/会话/批量/ | 告知用户本技能版本仅覆盖Instant Payment( |
Key Addresses and References
关键地址与参考链接
X Layer (chain 196)
X Layer(链ID 196)
- Chain ID:
196 - Public RPC:
https://rpc.xlayer.tech - USDT0: (decimals 6)
0x779Ded0c9e1022225f8E0630b35a9b54bE713736 - USDG: (decimals 6)
0x4ae46a509F6b1D9056937BA4500cb143933D2dc8 - USDC: (decimals 6, no reliable Uniswap routing on X Layer; bridge from a liquid chain)
0x74b7F16337b8972027F6196A17a631aC6dE26d22 - WOKB (wrapped native): (decimals 18)
0xe538905cf8410324e03A5A23C1c177a474D59b2b - 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:(小数位数6)
0x779Ded0c9e1022225f8E0630b35a9b54bE713736 - USDG:(小数位数6)
0x4ae46a509F6b1D9056937BA4500cb143933D2dc8 - USDC:(小数位数6,X Layer上无可靠的Uniswap路由;需从流动性充足的链桥接)
0x74b7F16337b8972027F6196A17a631aC6dE26d22 - WOKB(包装原生代币):(小数位数18)
0xe538905cf8410324e03A5A23C1c177a474D59b2b - 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 atabove). The Trading API expects the header value0xDa00aE15d3A71466517129255255db7c0c0956d3, 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.2.1.1
- 基础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(部署地址见上文)。Trading API要求请求头值为0xDa00aE15d3A71466517129255255db7c0c0956d3,这是API内部针对该Universal Router 2.1合约路由路径的版本字符串。两个版本字符串相关但不同;请勿相互替代。2.1.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)。