Okx Dex Trenches
nirholas/three.ws
Read-only on-chain research for pump.fun and other meme-token launchpads (Solana / BSC / X Layer / TRON).
Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets.
$ npx skills add affaan-m/ECC --skill agent-payment-x402 -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install affaan-m/ECC agent-payment-x402 --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/affaan-m/ECC.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/agent-payment-x402 .claude/skills/agent-payment-x402 && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "agent-payment-x402" agent skill from https://github.com/affaan-m/ECC/tree/main/skills/agent-payment-x402 into .claude/skills/agent-payment-x402/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "agent-payment-x402", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/affaan-m/ECC/tree/main/skills/agent-payment-x402Type this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add affaan-m/ECC --skill agent-payment-x402 -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install affaan-m/ECC agent-payment-x402 --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/affaan-m/ECC.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/agent-payment-x402 .agents/skills/agent-payment-x402 && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "agent-payment-x402" agent skill from https://github.com/affaan-m/ECC/tree/main/skills/agent-payment-x402 into .agents/skills/agent-payment-x402/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "agent-payment-x402", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add affaan-m/ECC --skill agent-payment-x402 -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install affaan-m/ECC agent-payment-x402 --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/affaan-m/ECC.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/agent-payment-x402 .cursor/skills/agent-payment-x402 && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "agent-payment-x402" agent skill from https://github.com/affaan-m/ECC/tree/main/skills/agent-payment-x402 into .cursor/skills/agent-payment-x402/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "agent-payment-x402", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/affaan-m/ECC.git --path skills/agent-payment-x402--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add affaan-m/ECC --skill agent-payment-x402 -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install affaan-m/ECC agent-payment-x402 --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/affaan-m/ECC.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/agent-payment-x402 .gemini/skills/agent-payment-x402 && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "agent-payment-x402" agent skill from https://github.com/affaan-m/ECC/tree/main/skills/agent-payment-x402 into .gemini/skills/agent-payment-x402/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "agent-payment-x402", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install affaan-m/ECC agent-payment-x402Installs for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add affaan-m/ECC --skill agent-payment-x402 -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/affaan-m/ECC.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/agent-payment-x402 .github/skills/agent-payment-x402 && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "agent-payment-x402" agent skill from https://github.com/affaan-m/ECC/tree/main/skills/agent-payment-x402 into .github/skills/agent-payment-x402/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "agent-payment-x402", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add affaan-m/ECC --skill agent-payment-x402 -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install affaan-m/ECC agent-payment-x402 --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/affaan-m/ECC.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/agent-payment-x402 .opencode/skills/agent-payment-x402 && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "agent-payment-x402" agent skill from https://github.com/affaan-m/ECC/tree/main/skills/agent-payment-x402 into .opencode/skills/agent-payment-x402/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "agent-payment-x402", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
agent-payment-x402Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets.
Agent Payment X402 is an agent skill from affaan-m/ECC. Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk, X Layer through OKX Payments / OKX Agent Payments Protocol, and Solana plus multi-network EVM through the upstream x402 packages with facilitator-based settlement. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.
Its SKILL.md is about 6.8k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Backend & APIs, covering Smart contracts. It works with x402, OKX, Solana and Python. The repository describes itself as: The agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond. The licence is MIT.
4 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 4eb71d9. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
curljqnpmFrom the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
raw.githubusercontent.comapi.cdp.coinbase.comfacilitator.payai.networkapi.mainnet-beta.solana.comAlso links to:
github.comdocs.x402.orgx402.orgpay.shnpmjs.comweb3.okx.comFrom URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
WALLET_PRIVATE_KEYEVM_PRIVATE_KEYSVM_PRIVATE_KEYFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Agent Payment X402 loads about 6.8k tokens when it runs. Until then it costs about 113 tokens; SKILL.md has 1,985 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from affaan-m/ECC at commit 4eb71d9, republished under its MIT licence (© affaan-m). 1,985 words, ~6,849 tokens.
.claude/skills/agent-payment-x402/SKILL.md (or your agent's skills folder).Enable AI agents to make policy-gated payments with built-in spending controls. Uses the x402 HTTP payment protocol and MCP tools so agents can pay for external services, APIs, or other agents without custodial risk.
Use when: your agent needs to pay for an API call, purchase a service, settle with another agent, enforce per-task spending limits, or manage a non-custodial wallet. Pairs naturally with cost-aware-llm-pipeline and security-review skills.
Choose the integration path based on whether your agent is buying access to a paid API or charging others for one:
| Need | Recommended path |
|---|---|
| Agent pays a 402-gated API on Base or another agentwallet-supported chain | Use agentwallet-sdk as an MCP payment server with strict spending policy |
| Agent pays a 402-gated API on X Layer | Use OKX Agent Payments Protocol from okx/onchainos-skills; okx-x402-payment is a deprecated legacy alias |
| Agent pays a 402-gated API on Solana or another x402 v2 network | Wrap the agent's HTTP client with the upstream @x402/fetch or @x402/axios package and register the EVM/SVM schemes; the resource server's facilitator verifies and settles |
| API charges agents on Solana or multiple networks (TypeScript, Python, or Go) | Use the upstream x402 middleware from x402-foundation/x402 — @x402/express, @x402/hono, @x402/next, or @x402/fastify for TypeScript, x402 for Python, github.com/x402-foundation/x402/go/v2 for Go |
| TypeScript API charges agents | Use OKX Payments TypeScript seller SDK docs for Express, Hono, Fastify, or Next.js |
| Go API charges agents | Use OKX Payments Go seller SDK docs for Gin, Echo, or net/http |
| Rust API charges agents | Use OKX Payments Rust seller SDK docs for Axum |
| Java API charges agents | Use OKX Payments Java seller SDK docs for Spring Boot 2/3, Java EE, or Jakarta |
| Python API charges agents | Check the current OKX Payments repository before implementation; a Python seller guide may not be available |
agentwallet-sdk: use the package docs to confirm current network coverage before production. Base Sepolia is the safest development default; Base mainnet is the production path called out by the original skill.eip155:196) and USDT0 settlement. Fetch current SDK docs before generating production code because payment packages and facilitator behavior can change quickly.x402.org facilitator, which is testnet-only (Base Sepolia eip155:84532, Solana devnet solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1, plus Stellar, Aptos, Hedera, and XRPL testnets) and is not intended for mainnet routes. For mainnet (solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp for Solana), either self-facilitate, run your own facilitator, or pick a hosted one from the upstream facilitator list — see the facilitator comparison under Option C. Confirm live coverage at the facilitator's /supported endpoint before production rather than hardcoding it here.x402 extends HTTP 402 (Payment Required) into a machine-negotiable flow. When a server returns 402, the agent's payment tool negotiates price, checks budget, signs a transaction, and retries only inside the policy and confirmation boundary set by the orchestrator.
Every payment tool call enforces a SpendingPolicy:
Agents hold their own keys via ERC-4337 smart accounts. The orchestrator sets policy before delegation; the agent can only spend within bounds. No pooled funds, no custodial risk.
The payment layer exposes standard MCP tools that slot into any Claude Code or agent harness setup.
Security note: Always pin the package version. This tool manages private keys — unpinned
npxinstalls introduce supply-chain risk.
{
"mcpServers": {
"agentpay": {
"command": "npx",
"args": ["agentwallet-sdk@6.0.0"]
}
}
}| Tool | Purpose |
|---|---|
get_balance | Check agent wallet balance |
send_payment | Send payment to address or ENS |
check_spending | Query remaining budget |
list_transactions | Audit trail of all payments |
Note: Spending policy is set by the orchestrator before delegating to the agent — not by the agent itself. This prevents agents from escalating their own spending limits. Configure policy via
set_policyin your orchestration layer or pre-task hook, never as an agent-callable tool.
Use this path for X Layer x402, Multi-Party Payment (MPP), session payment, charge, and A2A charge flows.
For buyer-side agent flows:
okx/onchainos-skills repository.skills/okx-agent-payments-protocol/SKILL.md as the dispatcher.skills/okx-x402-payment/SKILL.md as a deprecated compatibility alias, not as the canonical skill.For seller-side API flows, fetch the latest language-specific guide before generating code:
| Runtime | Current guide |
|---|---|
| TypeScript | https://raw.githubusercontent.com/okx/payments/main/typescript/SELLER.md |
| Go | https://raw.githubusercontent.com/okx/payments/main/go/x402/SELLER.md |
| Rust | https://raw.githubusercontent.com/okx/payments/main/rust/x402/SELLER.md |
| Java | https://raw.githubusercontent.com/okx/payments/main/java/SELLER.md |
Do not copy examples from older docs without checking the current OKX repository. Current OKX guidance uses okx-agent-payments-protocol as the dispatcher, and Java seller docs are now available.
Use this path when the agent pays — or your API charges — on Solana, Base, or another network the upstream protocol implementation supports. The canonical x402 monorepo at x402-foundation/x402 is actively maintained and publishes the client and middleware packages directly. Unlike Options A and B this is not a separate MCP server — you wrap the agent's own HTTP client, and a facilitator chosen by the resource server verifies and settles.
For buyer-side agent flows:
Start from the maintained examples in examples/typescript/clients (fetch, axios, MCP) rather than copying snippets from older docs.
Require explicit user confirmation before signing or submitting the first paid request, exactly as Option B requires for OKX flows. Do not hide payment execution behind a generic tool call.
Pin package versions (for example @x402/fetch@2.22.0); all upstream packages version in lockstep.
Enforce your budget with a PaymentPolicy registered on the client, so the check runs against the server's actual challenge on every call. A budget compared against a number you passed in yourself proves nothing — the amount, asset, and network all come from the server, so all three must be validated before a signature exists.
Configure an exact resource-origin allowlist separately from recipient and budget policy. All payment-enabled fetches below refuse redirects. Session approval names the approved origins, networks, assets, recipients, and human-unit spending caps; concurrent calls share one decision. Keep this client and its policy private to the orchestrator.
import { x402Client, wrapFetchWithPayment } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm/exact/client";
import { ExactSvmScheme } from "@x402/svm/exact/client";
import { privateKeyToAccount } from "viem/accounts";
import { createKeyPairSignerFromBytes } from "@solana/kit";
import { base58 } from "@scure/base";
// Signer keys belong to the ORCHESTRATOR's env — never hardcoded, never agent-writable.
const evmKey = process.env.EVM_PRIVATE_KEY as `0x${string}`;
const svmKey = process.env.SVM_PRIVATE_KEY;
if (!evmKey || !svmKey) {
throw new Error("Signer keys are not set — refusing to start payment client");
}
// One client, both network families: the buyer pays whichever chain the 402 offers.
const client = new x402Client();
client.register("eip155:*", new ExactEvmScheme(privateKeyToAccount(evmKey)));
client.register("solana:*", new ExactSvmScheme(await createKeyPairSignerFromBytes(base58.decode(svmKey))));
// A PaymentPolicy filters the SERVER's payment requirements before any
// signature is created. Returning an empty array means "nothing here is
// acceptable" and the client refuses to pay rather than falling back.
const ALLOWED_NETWORKS = new Set([
"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", // Solana mainnet
"eip155:8453", // Base
]);
const MAX_AMOUNT = 10_000n; // atomic units, 6-decimal USDC: 0.01 USDC per call
const SESSION_CAP = 50_000n; // 0.05 USDC across the whole session
// EVM addresses are case-insensitive, so compare them lowercased. Solana
// addresses are base58 and ARE case-sensitive — never lowercase those, or a
// different account could slip through.
const normalizeAddress = (a: string) => (a.startsWith("0x") ? a.toLowerCase() : a);
const ALLOWED_ASSETS = new Set(
[
"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // USDC, Solana mainnet
"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC, Base
].map(normalizeAddress),
);
// Who you are willing to pay. Without this, any 402 an agent happens to hit
// can name its own recipient.
const ALLOWED_PAY_TO = new Set(
["7pr7NCaQRz5PEhPy7BAeB3Z72TVkiShhjRyVCN5DA6yC"].map(normalizeAddress),
);
client.registerPolicy((_x402Version, requirements) =>
requirements.filter(r => {
if (!ALLOWED_NETWORKS.has(r.network)) return false; // wrong chain
if (!ALLOWED_ASSETS.has(normalizeAddress(r.asset))) return false; // wrong token
if (!ALLOWED_PAY_TO.has(normalizeAddress(r.payTo))) return false; // wrong recipient
try {
const amount = BigInt(r.amount);
return amount >= 0n && amount <= MAX_AMOUNT; // over budget / negative
} catch {
return false; // unparseable amount
}
}),
);
// The policy sees one challenge at a time, so it cannot enforce a session
// total or ask a human anything. Keep the payment-enabled client private and
// route every paid call through the payOnce boundary below.
// Supply this from your harness — a real prompt, never a stub that returns true.
declare function confirmWithUser(prompt: string): Promise<boolean>;
// Resource authorization is independent of recipient and budget policy.
// The ORCHESTRATOR supplies exact approved HTTPS origins before delegation;
// never populate this set from a server challenge or agent-controlled input.
const ALLOWED_ORIGINS = new Set(["https://api.example.com"]);
function requireAllowedOrigin(url: string): void {
const parsed = new URL(url);
if (!ALLOWED_ORIGINS.has(parsed.origin) || parsed.username || parsed.password) {
throw new Error("Resource origin is not authorized");
}
}
// Both approved assets above are 6-decimal USDC. Update this trusted formatting
// policy along with the asset allowlist if you support other assets/decimals.
const USDC_SCALE = 1_000_000n;
const humanUSDC = (amount: bigint) =>
`${amount / USDC_SCALE}.${(amount % USDC_SCALE).toString().padStart(6, "0").replace(/0+$/, "") || "0"} USDC`;
let sessionSpent = 0n;
let sessionApproval: Promise<boolean> | undefined;
async function payOnce(url: string, init?: RequestInit): Promise<Response> {
requireAllowedOrigin(url); // Before reservation, prompt, fetch, or signature.
// Reserve the worst case the policy allows. Settlement responses do not
// carry an amount, so counting MAX_AMOUNT per call is a deliberate
// over-estimate — it can stop early, never late. Reserve before any await,
// so concurrent calls cannot all pass the check.
if (sessionSpent + MAX_AMOUNT > SESSION_CAP) {
throw new Error("Session budget exhausted — blocked");
}
sessionSpent += MAX_AMOUNT;
// Release the reservation only when no signed payment left this process:
// a declined or failed prompt, a challenge the policy rejected, or a free
// response. Once a signed request is sent it may settle, so keep it counted.
let signedRequestSent = false;
const trackingFetch: typeof fetch = async (input, reqInit) => {
// Override caller options on BOTH the challenge and signed retry. Native
// fetch refuses redirects, so an unauthorized host cannot return a 402
// or receive a payment header via an automatic redirect.
const req = new Request(input, { ...reqInit, redirect: "error" });
requireAllowedOrigin(req.url);
if (req.headers.has("PAYMENT-SIGNATURE") || req.headers.has("X-PAYMENT")) {
signedRequestSent = true;
}
const response = await fetch(req);
// Also fail closed for adapters that expose a redirect response instead.
if (response.redirected || (response.status >= 300 && response.status < 400)) {
throw new Error("Paid request redirects are blocked");
}
return response;
};
try {
// Install one promise before awaiting the prompt. Concurrent calls share
// the same decision, including a decline or failure; never auto-reprompt.
sessionApproval ??= Promise.resolve().then(() => confirmWithUser(
`Allow paid requests to origins: ${[...ALLOWED_ORIGINS].join(", ")}? ` +
`Networks: ${[...ALLOWED_NETWORKS].join(", ")}. ` +
`Assets: ${[...ALLOWED_ASSETS].join(", ")} (6-decimal USDC). ` +
`Recipients (payTo): ${[...ALLOWED_PAY_TO].join(", ")}. ` +
`Per-call cap: ${humanUSDC(MAX_AMOUNT)}; session cap: ${humanUSDC(SESSION_CAP)}.`,
));
if (!await sessionApproval) {
throw new Error("User declined: no payment attempted");
}
return await wrapFetchWithPayment(trackingFetch, client)(url, init);
} finally {
if (!signedRequestSent) sessionSpent -= MAX_AMOUNT;
}
}
const res = await payOnce("https://api.example.com/data", { method: "GET" });With the policy registered, an over-budget amount, an unexpected token, or an unregistered chain all fail closed — createPaymentPayload throws instead of signing, because every candidate was filtered out. Devnet USDC is 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU; add it to ALLOWED_ASSETS only for development. Test the policy adversarially — feed it a challenge demanding 5000000 atomic units, one quoting a different mint, and one on a chain you never registered, and assert that none of them produce a signature. In the exact-SVM scheme the facilitator is the transaction fee payer, so the buyer wallet holds USDC only — no SOL for gas.
Facilitator choice. A facilitator verifies and settles on the resource server's behalf, so this is the resource server's decision, not the buyer's. In rough order of least to most trust delegated:
| Option | When it fits |
|---|---|
| Self-facilitate in-process | You want no third party in the settlement path and can hold keys and RPC access yourself |
| Run your own facilitator | You want that same control but shared across several services |
x402.org facilitator | Development and testnets — it is the package default, requires no setup, and upstream documents it as not intended for mainnet routes |
| A hosted production facilitator | You want mainnet coverage without operating infrastructure |
For the hosted option, choose from the facilitator list in the upstream docs rather than a name copied from here — it is maintained, it is not exhaustive, and coverage changes. As of writing it includes Coinbase's CDP (KYT/OFAC screening on every transaction), PayAI, Corbits, Dexter, Solvador, and others; several cover Solana mainnet alongside EVM. Whichever you pick, confirm live coverage at its /supported endpoint before production and re-check when you add a network.
Disclosure: this section was contributed by someone who works on PayAI, one of the listed facilitators. It is included as one option among several, and the self-hosted and upstream-default paths above are deliberately listed first.
Seller side (API charges agents). Use the upstream middleware; one route can advertise Base and Solana simultaneously (see examples/typescript/servers for runnable versions):
| Runtime | Package |
|---|---|
| Express / Hono / Next.js / Fastify | @x402/express@2.22.0, @x402/hono@2.22.0, @x402/next@2.22.0, @x402/fastify@2.22.0 |
| Python (FastAPI, Flask) | x402 on PyPI |
Go (Gin, Echo, net/http) | github.com/x402-foundation/x402/go/v2 |
Solana sellers: the payTo address needs its canonical token account first. The exact-SVM client derives the associated token account (ATA) for payTo with findAssociatedTokenPda and transfers there; it never creates it. If that exact account is missing, settlement fails at simulation and the 402 comes back with transaction_simulation_failed, which reads like a client bug rather than a missing recipient account. Check the derived address itself — scanning the owner's token accounts is not equivalent, because a non-canonical auxiliary account for the same mint would pass while the ATA the client targets is still absent:
import { findAssociatedTokenPda, TOKEN_PROGRAM_ADDRESS } from "@solana-program/token";
const [ata] = await findAssociatedTokenPda({
mint: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // USDC mainnet
owner: payToAddress,
tokenProgram: TOKEN_PROGRAM_ADDRESS, // TOKEN_2022_PROGRAM_ADDRESS for Token-2022 mints
});Then confirm that exact address exists — value: null means it does not, and settlement to it will fail:
curl -s https://api.mainnet-beta.solana.com -X POST -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"getAccountInfo",
"params":["<DERIVED_ATA>",{"encoding":"base64"}]}' \
| jq '.result.value != null'To provision it (whoever creates it pays the small rent, not the payer):
getCreateAssociatedTokenIdempotentInstruction from @solana-program/token to your onboarding flow — the idempotent variant is safe to re-run and is the only option that is deterministic.spl-token create-account <MINT> --owner <PAYTO_ADDRESS> with the spl-token CLI.payTo also works, but only when the sender includes the create instruction — wallets and spl-token transfer --fund-recipient do; a bare transferChecked to a missing ATA fails the same way settlement does.This bites hardest when payouts go to freshly provisioned or custodial wallets, which often have no ATA for the asset yet.
Discovery. Facilitators that implement the x402 bazaar extension expose a /discovery/resources endpoint — query the CDP catalog at https://api.cdp.coinbase.com/platform/v2/x402/discovery/resources and the PayAI catalog at https://facilitator.payai.network/discovery/resources. For Solana-payable services there is also pay.sh, the Solana Foundation's curated catalog.
When building an orchestrator that calls the agentpay MCP server, enforce budgets before dispatching paid tool calls.
Prerequisites: Install the package before adding the MCP config —
npxwithout-ywill prompt for confirmation in non-interactive environments, causing the server to hang:npm install -g agentwallet-sdk@6.0.0
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
async function main() {
// 1. Validate credentials before constructing the transport.
// A missing key must fail immediately — never let the subprocess start without auth.
const walletKey = process.env.WALLET_PRIVATE_KEY;
if (!walletKey) {
throw new Error("WALLET_PRIVATE_KEY is not set — refusing to start payment server");
}
// Connect to the agentpay MCP server via stdio transport.
// Whitelist only the env vars the server needs — never forward all of process.env
// to a third-party subprocess that manages private keys.
const transport = new StdioClientTransport({
command: "npx",
args: ["agentwallet-sdk@6.0.0"],
env: {
PATH: process.env.PATH ?? "",
NODE_ENV: process.env.NODE_ENV ?? "production",
WALLET_PRIVATE_KEY: walletKey,
},
});
const agentpay = new Client({ name: "orchestrator", version: "1.0.0" });
await agentpay.connect(transport);
// 2. Set spending policy before delegating to the agent.
// Always verify success — a silent failure means no controls are active.
const policyResult = await agentpay.callTool({
name: "set_policy",
arguments: {
per_task_budget: 0.50,
per_session_budget: 5.00,
allowlisted_recipients: ["api.example.com"],
},
});
if (policyResult.isError) {
throw new Error(
`Failed to set spending policy — do not delegate: ${JSON.stringify(policyResult.content)}`
);
}
// 3. Use preToolCheck before any paid action
await preToolCheck(agentpay, 0.01);
}
// Pre-tool hook: fail-closed budget enforcement with four distinct error paths.
async function preToolCheck(agentpay: Client, apiCost: number): Promise<void> {
// Path 1: Reject invalid input (NaN/Infinity bypass the < comparison)
if (!Number.isFinite(apiCost) || apiCost < 0) {
throw new Error(`Invalid apiCost: ${apiCost} — action blocked`);
}
// Path 2: Transport/connectivity failure
let result;
try {
result = await agentpay.callTool({ name: "check_spending" });
} catch (err) {
throw new Error(`Payment service unreachable — action blocked: ${err}`);
}
// Path 3: Tool returned an error (e.g., auth failure, wallet not initialised)
if (result.isError) {
throw new Error(
`check_spending failed — action blocked: ${JSON.stringify(result.content)}`
);
}
// Path 4: Parse and validate the response shape
let remaining: number;
try {
const parsed = JSON.parse(
(result.content as Array<{ text: string }>)[0].text
);
if (!Number.isFinite(parsed?.remaining)) {
throw new TypeError("missing or non-finite 'remaining' field");
}
remaining = parsed.remaining;
} catch (err) {
throw new Error(
`check_spending returned unexpected format — action blocked: ${err}`
);
}
// Path 5: Budget exceeded
if (remaining < apiCost) {
throw new Error(
`Budget exceeded: need $${apiCost} but only $${remaining} remaining`
);
}
}
main().catch((err) => {
console.error(err);
process.exitCode = 1;
});agentwallet-sdk@6.0.0). Verify package integrity before deploying to production.list_transactions in post-task hooks to log what was spent and why.solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1) and the free x402.org facilitator before moving to a production facilitator on mainnet.asset against the expected USDC mint (mainnet EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v, devnet 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU) before signing — a wrapped client that pays any asset is a hole in your budget.agentwallet-sdkokx/payments — TypeScript, Go, Rust, and Java seller integrations for X Layer x402okx/onchainos-skillsx402-foundation/x402 — TypeScript, Python, and Go implementations plus maintained client and server examples@x402 packages: npmjs.com/org/x402 — @x402/fetch, @x402/axios, @x402/express, @x402/hono, @x402/next, @x402/fastify, @x402/evm, @x402/svm/discovery/resources; pay.sh for Solana-payable services© affaan-m, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in skills/agent-payment-x402 of affaan-m/ECC.
Open the folder on GitHubat commit 4eb71d9
Agent Payment X402 next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Agent Payment X402 this skillaffaan-m/ECC | 276k | — | ~6.8k | Automated safety check: Pass | MIT | |
| Okx Dex Trenchesnirholas/three.ws | 229 | — | ~2.6k | Automated safety check: Pass | MIT | |
| Temporal Developertemporalio/skill-temporal-developer | 230 | — | ~2.5k | Automated safety check: Pass | MIT | |
| Build X402 Clientcoinbase/cdp-sdk | 203 | — | ~3k | Automated safety check: Pass | MIT | |
| Build X402 Servercoinbase/cdp-sdk | 203 | — | ~3.7k | Automated safety check: Notes | MIT | |
| Alchemy Agentic Gatewaymoonpay/skills | 113 | — | ~2.1k | Automated safety check: Notes | MIT |
nirholas/three.ws
Read-only on-chain research for pump.fun and other meme-token launchpads (Solana / BSC / X Layer / TRON).
temporalio/skill-temporal-developer
Develop, debug, and manage Temporal applications across Python, TypeScript, Go, Java, .NET, Ruby, and Rust.
coinbase/cdp-sdk
Write code that pays for an HTTP API returning 402 Payment Required, using the x402 protocol and a CDP-managed wallet.
coinbase/cdp-sdk
Write code that charges for an HTTP route with the x402 protocol and receives USDC in a CDP-managed wallet.
moonpay/skills
A skill your agent uses when accessing Alchemy APIs for RPC calls, token balances, NFT metadata, asset transfers, transaction simulation, or Alchemy-specific features.
internet-court/internet-court-skill
Shows how to read Pyth oracle prices in Solana apps, off-chain through the Hermes client or on-chain from an Anchor program, including confidence and EMA values.
affaan-m/ECC
Audits your installed Claude skills and commands for quality, with a quick mode for recently changed skills and a full mode that evaluates all of them through subagents.
affaan-m/ECC
Ingests, indexes, searches, edits and monitors video, audio and live streams through the VideoDB Python SDK, returning stream links, clips and timestamps.
affaan-m/ECC
Route broad documentation-governance requests to existing ECC skills and run an opt-in, read-only audit of mapped documentation roles, links, ADR indexes, and evidence references.
affaan-m/ECC
Scans installed skills for principles that recur across them and proposes rule-file changes: append, revise, add a section, create a file or leave as covered.
affaan-m/ECC
Builds DRAFT counterparty agreements from one markdown template and a small JSON spec per party, with clauses picked by the party's role.
affaan-m/ECC
Set an ECC-specific frontend design direction for production UI work.
Categories
Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Agent Payment X402 is an agent skill from affaan-m/ECC. Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets.
Agent Payment X402 fits situations like: an agent must pay for something itself and needs per-task budgets; spending controls; A non-custodial wallet.
Run `npx skills add affaan-m/ECC --skill agent-payment-x402 -a claude-code`. Or copy the skill folder (skills/agent-payment-x402 in affaan-m/ECC) into .claude/skills/agent-payment-x402 in your project. Claude Code loads it when a task matches its description.
Run `npx skills add affaan-m/ECC --skill agent-payment-x402 -a codex`. Or copy the skill folder (skills/agent-payment-x402 in affaan-m/ECC) into .agents/skills/agent-payment-x402 in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add affaan-m/ECC --skill agent-payment-x402 -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/agent-payment-x402, .gemini/skills/agent-payment-x402, .github/skills/agent-payment-x402 and .opencode/skills/agent-payment-x402 in your project.
Going by SKILL.md and its folder, Agent Payment X402 needs the command-line tools its instructions call (curl, jq and npm) and credentials named WALLET_PRIVATE_KEY, EVM_PRIVATE_KEY and SVM_PRIVATE_KEY. Our summary lists: Python 3; A credential in EVM_PRIVATE_KEY; A credential in SVM_PRIVATE_KEY.
SKILL.md names 10 domains. In commands or code: raw.githubusercontent.com, api.cdp.coinbase.com, facilitator.payai.network and api.mainnet-beta.solana.com; the agent is likely to contact these when it follows the instructions. As links in the text: github.com, docs.x402.org, x402.org, pay.sh, npmjs.com and web3.okx.com. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Agent Payment X402 is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 6.8k tokens (SKILL.md is roughly 27k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Agent Payment X402: Okx Dex Trenches (nirholas/three.ws, 229 stars), Temporal Developer (temporalio/skill-temporal-developer, 230 stars), Build X402 Client (coinbase/cdp-sdk, 203 stars) and Build X402 Server (coinbase/cdp-sdk, 203 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
affaan-m (a GitHub user) maintains it in affaan-m/ECC, which has 276,111 GitHub stars. The repository holds 683 skills in this directory. The repository was last updated on October 10, 2026.
Source: affaan-m/ECC on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.