uniswap/uniswap-aiMIT3 files

Pay With App

>

Specification
Skill ID
uniswap/uniswap-ai/pay-with-app
Publisher
uniswap
Repository
uniswap-ai
Installs
0
Files
3
License
MIT
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

uniswap/uniswap-ai/pay-with-appInstalls these files
  • SKILL.md
  • references/app-x402-flow.md
  • references/funding-x-layer.md

What this skill tells the agent

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

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.

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.

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.

Flow

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

Phase 0, Parse the 402 Challenge

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.

Phase 1, Confirm Network is X Layer

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.

Phase 2, Check Wallet Balance on X Layer

REQUIRED: You must have the user's source wallet address. Use AskUserQuestion if not provided. Store as WALLET_ADDRESS.
ASSET_BALANCE=$(cast call "$X402_ASSET" \

Use this skill in a project

Open any RiverX project, search the Skills panel for uniswap/uniswap-ai/pay-with-app, and install it in one click.

Use this skill