본문으로 건너뛰기
cccskills
무료GitHub에 공개한국어 소개

agent-payment-x402

x402로 AI 에이전트의 유료 API 및 서비스 결제를 연동하고, 작업별·세션별 예산과 수신자 제한, 개인 키를 직접 관리하는 지갑을 설정합니다.

원문원문 설명 보기

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.

연동 도구X (Twitter)
AI 평가90점/ 100설치 방법 보기

이럴 때 유용합니다

  • 에이전트의 유료 API 이용에 활용합니다
  • 작업별·세션별 지출 한도를 설정합니다
  • 수신자·네트워크·자산을 제한합니다
  • API에 x402 과금을 연동합니다

한국어 소개

할 수 있는 일

AI 에이전트가 유료 API나 외부 서비스에 결제하는 기능을 연동합니다. HTTP에서 요금 요청과 결제를 처리하는 x402로 작업별 예산, 세션 전체 한도, 허용할 수신자와 거래 빈도를 설정합니다. Base에서는 agentwallet-sdk, X Layer에서는 OKX Agent Payments Protocol, Solana와 EVM 네트워크에서는 공식 x402 패키지를 쓰는 구성을 안내합니다. API에서 결제를 받는 구현도 다룹니다.

이럴 때 유용합니다

에이전트가 유료 API를 사용하거나 다른 에이전트에 지급하는 금액을 제한할 때 활용합니다. 개인 키를 직접 관리하면서 결제 허용 범위를 미리 정하려는 개발자에게도 유용합니다.

사용 예시

  • “유료 API를 호출하는 에이전트에 작업별 예산과 수신자 제한을 설정해 주세요.”
  • “Solana와 Base에서 결제를 받는 API 구성을 설계해 주세요.”

주의 사항

선택한 구성에 맞는 SDK, 개인 키, 네트워크 설정이 필요합니다. 지출 규칙은 에이전트 실행을 관리하는 쪽에서 설정합니다. 결제 전 승인과 패키지 버전 고정을 요구합니다. 운영 환경에서는 최신 지원 현황을 확인하고 결제 검증과 정산을 맡을 facilitator를 선택합니다. 기본 x402.org는 테스트 환경용입니다.

이 소개문은 공개된 SKILL.md를 바탕으로 AI(OpenAI Codex)가 작성했습니다. 정확한 사양은 아래 원문을 확인하세요.

객관 평가

AI가 SKILL.md의 내용만을 근거로 4가지 관점에서 판정했습니다. 스타 수나 인기도는 판정에 넣지 않았습니다.

지시의 명확성언제 쓰고 무엇을 하는지 알 수 있는가
A양호유료 API 이용과 API 과금을 구분하고 네트워크별 연동 선택표를 제시합니다.
절차의 구체성절차·입출력·예시가 구체적으로 적혀 있는가
A양호MCP 설정 예시, 지출 정책 항목, 구성별 도입 절차를 제시합니다.
안전성전송·삭제·명령 실행 등을 명시하고 있는가
A양호결제 전 명시적 확인, 패키지 버전 고정, 실행 관리 측의 지출 제한을 요구합니다.
도입의 용이성필요한 도구나 API 키가 적고 적혀 있는가
B일부 부족SDK, 개인 키, 네트워크가 필요하며 일부 도입 세부 사항은 외부 문서를 참조합니다.

총점은 각 항목을 A=25점, B=15점, C=5점으로 더한 값입니다. 2026년 10월 19일 기준으로 AI(OpenAI Codex)가 판정했습니다. 참고용이므로 설치 전에 원문도 확인해 주세요.

평가가 다르다고 생각되면 재검토를 요청하기

어느 항목이 왜 다르다고 생각하는지 적어 주세요. 로그인은 필요 없습니다. SKILL.md와 대조해 평가를 다시 만들고 이곳에 반영합니다.

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

포함된 파일(1)

  • SKILL.md26.8 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Agent Payment Execution (x402)

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.

When to Use

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.

Decision Tree

Choose the integration path based on whether your agent is buying access to a paid API or charging others for one:

NeedRecommended path
Agent pays a 402-gated API on Base or another agentwallet-supported chainUse agentwallet-sdk as an MCP payment server with strict spending policy
Agent pays a 402-gated API on X LayerUse 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 networkWrap 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 agentsUse OKX Payments TypeScript seller SDK docs for Express, Hono, Fastify, or Next.js
Go API charges agentsUse OKX Payments Go seller SDK docs for Gin, Echo, or net/http
Rust API charges agentsUse OKX Payments Rust seller SDK docs for Axum
Java API charges agentsUse OKX Payments Java seller SDK docs for Spring Boot 2/3, Java EE, or Jakarta
Python API charges agentsCheck the current OKX Payments repository before implementation; a Python seller guide may not be available

Supported Networks

  • 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.
  • OKX Payments / X Layer: current seller docs target X Layer (eip155:196) and USDT0 settlement. Fetch current SDK docs before generating production code because payment packages and facilitator behavior can change quickly.
  • Upstream x402 packages: multi-network by design — one route can advertise Base and Solana simultaneously and let the buyer pick. The packages default to the 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.

How It Works

x402 Protocol

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.

Spending Controls

Every payment tool call enforces a SpendingPolicy:

  • Per-task budget — max spend for a single agent action
  • Per-session budget — cumulative limit across an entire session
  • Allowlisted recipients — restrict which addresses/services the agent can pay
  • Rate limits — max transactions per minute/hour

Non-Custodial Wallets

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.

MCP Integration

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 npx installs introduce supply-chain risk.

Option A: agentwallet-sdk (Base / multi-chain)

{
  "mcpServers": {
    "agentpay": {
      "command": "npx",
      "args": ["agentwallet-sdk@6.0.0"]
    }
  }
}

Available Tools (agent-callable)

ToolPurpose
get_balanceCheck agent wallet balance
send_paymentSend payment to address or ENS
check_spendingQuery remaining budget
list_transactionsAudit 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_policy in your orchestration layer or pre-task hook, never as an agent-callable tool.

Option B: OKX Agent Payments Protocol (X Layer)

Use this path for X Layer x402, Multi-Party Payment (MPP), session payment, charge, and A2A charge flows.

For buyer-side agent flows:

  1. Install or reference the current okx/onchainos-skills repository.
  2. Use skills/okx-agent-payments-protocol/SKILL.md as the dispatcher.
  3. Treat skills/okx-x402-payment/SKILL.md as a deprecated compatibility alias, not as the canonical skill.
  4. Require explicit user confirmation before wallet status checks or payment actions. Do not hide payment execution behind a generic tool call.

For seller-side API flows, fetch the latest language-specific guide before generating code:

RuntimeCurrent guide
TypeScripthttps://raw.githubusercontent.com/okx/payments/main/typescript/SELLER.md
Gohttps://raw.githubusercontent.com/okx/payments/main/go/x402/SELLER.md
Rusthttps://raw.githubusercontent.com/okx/payments/main/rust/x402/SELLER.md
Javahttps://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.

Option C: Upstream x402 packages (Solana + Base/EVM)

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:

  1. Start from the maintained examples in examples/typescript/clients (fetch, axios, MCP) rather than copying snippets from older docs.

  2. 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.

  3. Pin package versions (for example @x402/fetch@2.22.0); all upstream packages version in lockstep.

  4. 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.

  5. 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:

OptionWhen it fits
Self-facilitate in-processYou want no third party in the settlement path and can hold keys and RPC access yourself
Run your own facilitatorYou want that same control but shared across several services
x402.org facilitatorDevelopment and testnets — it is the package default, requires no setup, and upstream documents it as not intended for mainnet routes
A hosted production facilitatorYou 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):

RuntimePackage
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):

  • In code, add 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.
  • A transfer of that token to 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.

Examples

Budget enforcement in an MCP client

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 — npx without -y will 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;
});

Best Practices

  • Set budgets before delegation: When spawning sub-agents, attach a SpendingPolicy via your orchestration layer. Never give an agent unlimited spend.
  • Pin your dependencies: Always specify an exact version in your MCP config (e.g., agentwallet-sdk@6.0.0). Verify package integrity before deploying to production.
  • Audit trails: Use list_transactions in post-task hooks to log what was spent and why.
  • Fail closed: If the payment tool is unreachable, block the paid action — don't fall back to unmetered access.
  • Pair with security-review: Payment tools are high-privilege. Apply the same scrutiny as shell access.
  • Test with testnets first: Use Base Sepolia for development; switch to Base mainnet for production. On Solana, develop against Solana devnet (solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1) and the free x402.org facilitator before moving to a production facilitator on mainnet.
  • On Solana, fund USDC not SOL: The exact-SVM scheme makes the facilitator the transaction fee payer, so a SOL-less wallet still pays. Verify each challenge's 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.

Production Reference

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

accessibility

무료요약 있음AI 평가 100점

Web·iOS·Android 화면을 WCAG 2.2에 맞춰 설계하고 점검합니다. 화면 읽기와 키보드 조작, 레이블, 대비, 조작 대상 크기를 확인합니다.

  • 아이콘 버튼에 설명 추가
  • 키보드 조작과 모달 초점 점검
  • 대비와 조작 대상 크기 확인
affaan-m/ECC28.4만2026년 10월 16일 업데이트

agent-architecture-audit

무료요약 있음AI 평가 80점

인공지능 에이전트의 문제를 지시, 기억, 도구 실행, 화면 표시 등 12개 계층에서 조사합니다. 코드와 로그를 근거로 원인을 정리하고 심각도에 따른 지적 사항과 수정안을 제시합니다.

  • 앱 안에서만 발생하는 문제 조사
  • 이전 대화가 섞이는 원인 확인
  • 도구 실행 누락과 허위 실행 보고 확인
affaan-m/ECC28.4만2026년 10월 16일 업데이트

agent-eval

무료요약 있음AI 평가 80점

실제 개발 과제로 여러 코딩 에이전트를 비교합니다. 성공률, 확인 가능한 API 비용, 소요 시간과 반복 실행의 안정성을 측정해 도입 결정과 업데이트 후 평가에 활용합니다.

  • 실제 개발 과제로 에이전트를 비교합니다
  • 새 도구나 모델을 도입하기 전에 평가합니다
  • 에이전트 업데이트 후 성능을 확인합니다
affaan-m/ECC28.4만2026년 10월 16일 업데이트

agent-harness-construction

무료요약 있음AI 평가 100점

AI 에이전트의 도구 구성, 입력과 출력 형식, 오류 복구 절차를 설계합니다. 문맥 정보량을 관리하고 완료율, 재시도 횟수, 성공한 작업당 비용으로 개선을 평가합니다.

  • 에이전트 도구와 입력 형식을 설계합니다
  • 도구 결과와 다음 행동을 명확히 합니다
  • 안전한 재시도와 중단 조건을 정합니다
affaan-m/ECC28.4만2026년 10월 16일 업데이트

agent-introspection-debugging

무료요약 있음AI 평가 100점

오류와 실행 환경을 바탕으로 AI 에이전트가 실패하거나 같은 작업을 반복하는 원인을 조사합니다. 작은 복구 작업을 시험하고 결과와 근거를 인계용 보고서로 정리합니다.

  • 에이전트의 연속 실패 진단
  • 동일한 도구 작업의 반복 조사
  • 정보 누적으로 인한 출력 품질 저하 점검
affaan-m/ECC28.4만2026년 10월 5일 업데이트

agent-introspection-debugging

무료요약 있음AI 평가 100점

AI 에이전트의 반복 실패와 도구 사용을 기록하고 원인을 좁힙니다. 영향이 제한된 복구 작업과 결과 보고를 통해 근거 있는 재시도를 돕습니다.

  • 같은 도구 작업을 반복하는 원인 조사
  • 대화 증가에 따른 출력 품질 저하 조사
  • 파일 경로와 환경 불일치 확인
affaan-m/ECC28.4만2026년 10월 16일 업데이트

affaan-m의 스킬 모두 보기

이 스킬의 문제 신고