Install
$ agentstack add skill-uniswap-uniswap-ai-pay-with-app ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
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:
- 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
X-PAYMENTpayload 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_KEYenv var (export PRIVATE_KEY=0x...). Never commit or
hardcode a private key.
UNISWAP_API_KEYenv var (register at
developers.uniswap.org). Required only if the wallet must be funded via cross-chain routing.
jqandcast(Foundry) installed.- Node 18+ (LTS). The signing step in
[references/app-x402-flow.md](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: ;, |, &, $, ` `, (, ), >, 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
```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.
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" \
"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
Phase 3, Fund USDT0 on X Layer (only if needed)
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:
| Asset | Address | Decimals | Funding | | ----- | -------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 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](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 to amortize bridge gas on the source chain.
Gas and Routing Caveats
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.
Phase 4, EIP-3009 Signing and X-PAYMENT Submission
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).
Step 5, User Confirmation
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:
- Source-chain ERC-20 approval to Permit2 / Universal Router (only
if tokenIn is not native and the allowance is insufficient).
- 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
TransferWithAuthorizationsignature 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 (
payTofor 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
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Uniswap
- Source: Uniswap/uniswap-ai
- License: MIT
- Homepage: https://developers.uniswap.org
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.