x402

Metaplex x402 Payment Modes

Last updated September 8, 2026

Metaplex x402 supports three payment modes — a standard Solana wallet, a Core asset or agent paying directly, and a delegated agent paying without a per-request signature. Every mode produces the same artifact: a payment-aware fetch you hand to whatever HTTP client you already use.

Summary

Choosing a payment mode means deciding which account's USDC funds a request and how often its owner signs. The first two modes differ only in which payment scheme you register; a delegated agent also needs an auth token store and either the client extension or the fetch wrapper. Once fetchWithPayment exists, the request code that follows is identical across all three.

  • Standard wallet — vanilla x402 with ExactSvmScheme; the owner signs every payment, and no SOL is required
  • Core asset or agent (direct) — MetaplexSvmExactScheme with a coreExecute target; funds come from the asset's signer PDA and the owner still signs each payment
  • Delegated agent (instant) — a one-time onchain grant lets Mech approve payments from the agent's wallet; the client authenticates with a message signature instead
  • Revocable at any time — delegation is an onchain grant, so revoking it stops payments onchain rather than by policy

What you will build

By the end of this guide you will have a fetchWithPayment function that transparently pays for each request, wired to whichever account you want to spend from. Every recipe on this page produces that same function.

Prerequisites

Metaplex x402 needs a funded Solana account and a signer that can build payment transactions.

  • Node.js 20.18+ and an ESM project
  • A Solana signer — a Solana Kit keypair signer or a Umi signer
  • USDC in the paying account's classic SPL Token associated token account
  • For Core asset and agent modes, a Core asset owned by that signer, and SOL in its signer PDA
  • For delegated agent mode, a registered agent identity — mint a new agent or register an existing Core asset

Never embed a private key in browser code

The examples read a development keypair from an environment variable. In a browser, use a wallet adapter signer instead — a private key shipped to the client is a private key you have published.

Quick Start

Install the client, fund the paying account, then register the scheme for your chosen mode.

Install the client and its peers
pnpm add @metaplex-foundation/x402 \
@metaplex-foundation/umi \
@solana/kit \
@x402/core \
@x402/fetch \
@x402/svm

Then add the client you plan to use:

ClientInstall
OpenAI SDKpnpm add openai
Vercel AI SDKpnpm add ai @ai-sdk/openai-compatible
Solana web3.jspnpm add @solana/web3.js

Jump to your mode: standard wallet · Core asset or agent · delegated agent.

Funding Requirements by Payment Mode

Each mode draws USDC from a different account, and only the Core execute modes need SOL.

Payment modeUSDC sourceSOL requirement
Standard walletThe wallet's USDC token accountNone — the service's fee payer covers the network fee
Core asset or agent (direct or delegated)The asset signer PDA's USDC token accountRequired in the signer PDA for Core execute fees

The payment source is always a classic SPL Token associated token account. Token-2022 payment mints are not currently supported.

Pay with a Standard Solana Wallet

Register ExactSvmScheme from @x402/svm to pay from a wallet you control directly. This is vanilla x402 — the Metaplex client adds only endpoint constants and discovery helpers.

Standard wallet payment
import { createKeyPairSignerFromBytes, getBase58Encoder } from '@solana/kit';
import { x402Client } from '@x402/core/client';
import { wrapFetchWithPayment } from '@x402/fetch';
import { ExactSvmScheme } from '@x402/svm/exact/client';
const svmSigner = await createKeyPairSignerFromBytes(
getBase58Encoder().encode(process.env.SVM_PRIVATE_KEY!),
);
const paymentClient = new x402Client();
paymentClient.register('solana:*', new ExactSvmScheme(svmSigner));
const fetchWithPayment = wrapFetchWithPayment(fetch, paymentClient);

Pay Directly with a Core Asset or Agent

Register MetaplexSvmExactScheme with a coreExecute target to fund payments from a Core asset's own wallet while the owner still signs each one. Every Core asset has a built-in wallet — its Asset Signer PDA — so funding that wallet isolates spending from your main wallet, and the budget travels with the asset if ownership changes.

Core asset or agent direct payment
import { MetaplexSvmExactScheme } from '@metaplex-foundation/x402';
import { x402Client } from '@x402/core/client';
import { wrapFetchWithPayment } from '@x402/fetch';
const paymentClient = new x402Client();
paymentClient.register(
'solana:*',
new MetaplexSvmExactScheme(svmSigner, {
rpcUrl: svmRpcUrl,
coreExecute: {
asset: coreAssetAddress,
},
}),
);
const fetchWithPayment = wrapFetchWithPayment(fetch, paymentClient);

svmSigner controls the asset, svmRpcUrl is the Solana RPC endpoint used to build payment transactions, and coreAssetAddress is the Core asset or agent address.

Assets in a collection need the collection address

Pass coreExecute.collection when the asset belongs to a Core collection. The scheme options table lists every option.

Pay Instantly with a Delegated Agent

Delegate your agent to Mech once so the server can approve payments from the agent's wallet without an owner signature on every request. This is the mode for autonomous agents and high-frequency workloads.

The agent must be a registered agent identity owned by the approving signer. After delegation, the client authenticates with a Sign-In-With-X message signature and receives a 24-hour bearer token, and the server builds payments from the agent's wallet. The delegation is an onchain grant you can revoke at any time.

Approve the Delegation Once

Check the current status before approving so repeat runs do not resubmit the transaction.

One-time delegation approval
import {
approveMetaplexCoreExecuteDelegate,
fetchMetaplexCoreExecuteDelegateStatus,
} from '@metaplex-foundation/x402';
const status = await fetchMetaplexCoreExecuteDelegateStatus(coreAssetAddress);
if (!status.isDelegated) {
await approveMetaplexCoreExecuteDelegate(svmSigner, coreAssetAddress, {
rpcUrl: svmRpcUrl,
});
}

Choose a Reactive or Proactive Integration Style

Reactive and proactive integrations are alternatives — use one, never both.

StyleHow it authenticatesChoose it when
ReactiveA client extension; the initial 402 response drives authentication and preserves the server's dynamic payment requirementsYou already run an x402Client alongside other paid services, or want optional fallback to direct payment
ProactiveA fetch wrapper that authenticates before the resource request, so no 402 round trip is visibleYou want the simplest wiring against Metaplex endpoints only

In both snippets below, solanaSigner is a message-capable Solana signer used for authentication; a Solana Kit keypair signer works.

Reactive delegated agent payment
import {
createMetaplexCoreExecuteDelegateClientExtension,
InMemoryMetaplexCoreExecuteDelegateAuthTokenStore,
MetaplexSvmExactScheme,
} from '@metaplex-foundation/x402';
import { x402Client } from '@x402/core/client';
import { wrapFetchWithPayment } from '@x402/fetch';
const authTokenStore = new InMemoryMetaplexCoreExecuteDelegateAuthTokenStore();
const paymentClient = new x402Client();
paymentClient.register(
'solana:*',
new MetaplexSvmExactScheme(svmSigner, { rpcUrl: svmRpcUrl }),
);
paymentClient.registerExtension(
createMetaplexCoreExecuteDelegateClientExtension({
signer: solanaSigner,
asset: coreAssetAddress,
authTokenStore,
}),
);
const fetchWithPayment = wrapFetchWithPayment(fetch, paymentClient);
Proactive delegated agent payment
import {
InMemoryMetaplexCoreExecuteDelegateAuthTokenStore,
wrapFetchWithMetaplexCoreExecuteDelegate,
} from '@metaplex-foundation/x402';
const authTokenStore = new InMemoryMetaplexCoreExecuteDelegateAuthTokenStore();
const fetchWithPayment = wrapFetchWithMetaplexCoreExecuteDelegate(fetch, {
signer: solanaSigner,
asset: coreAssetAddress,
authTokenStore,
});

Delegation approval is still required for the proactive style, and requests to other origins pass through untouched.

Store Auth Tokens and Handle Expiry

Authorization JWTs expire after 24 hours, and the client replaces them automatically with a message signature — not another onchain approval.

  • Use InMemoryMetaplexCoreExecuteDelegateAuthTokenStore in Node.js and LocalStorageMetaplexCoreExecuteDelegateAuthTokenStore in browser-only code
  • Implement the MetaplexCoreExecuteDelegateAuthTokenStore interface for any other storage backend
  • Reactive direct-payment fallback is off by default; set fallback: true only when the registered payment scheme should handle delegation failures
  • Pass onEvent to observe authentication, cache, and fallback behavior

Authorization tokens are bearer credentials

LocalStorageMetaplexCoreExecuteDelegateAuthTokenStore keeps the JWT in browser-readable storage, so any XSS on your origin can read it and spend against the delegation until the token expires or the grant is revoked. Prefer InMemoryMetaplexCoreExecuteDelegateAuthTokenStore unless the token genuinely has to survive a page reload, keep the agent wallet funded with only what it needs, and call revokeMetaplexCoreExecuteDelegate as soon as the delegation is no longer required.

Revoke the Delegation

Call revokeMetaplexCoreExecuteDelegate with the same signer, asset, and RPC options used to approve it.

Revoke a delegation
import { revokeMetaplexCoreExecuteDelegate } from '@metaplex-foundation/x402';
await revokeMetaplexCoreExecuteDelegate(svmSigner, coreAssetAddress, {
rpcUrl: svmRpcUrl,
});

Because the grant lives onchain, revocation stops the server from building payments from the agent's wallet — it is not a policy the service chooses to honour.

Common Errors

Payment construction failures almost always trace back to funding, network mismatch, or delegation state.

SymptomCauseFix
Payment construction failsThe paying account has no USDC for the payment mintFund the wallet, Core asset, or agent signer PDA with USDC
Core execute payment failsThe asset signer PDA has no SOL for transaction feesSend SOL to the asset signer PDA
Payment rejected as wrong networkSVM_RPC_URL targets a different network than the 402 response declaresPoint the RPC URL at the network declared by the 402 response
Signature rejected for a Core assetThe asset is not controlled by the signer you passedPass the signer that owns the Core asset
Delegated payments fall back or failThe asset is not a registered agent identity, or delegation was never approvedConfirm fetchMetaplexCoreExecuteDelegateStatus() returns isDelegated: true
Authentication loops or double-paysThe reactive extension and proactive wrapper are composed togetherUse one integration style, never both

Tested Configuration

PackageVersion
@metaplex-foundation/x4020.1.0
Node.js20.18+ (ESM)
Payment mintUSDC (classic SPL Token)

Notes

  • MetaplexSvmExactScheme accepts Umi signers and Solana Kit partial transaction signers, but not sign-and-send signers. Kit signers are adapted internally.
  • Every service, client, and payment mode combination has a runnable example in the x402 repository, executable as pnpm example:<name>.
  • Delegated agent examples may submit an approval transaction the first time they run.
  • Delegation grants Mech authority to move USDC from the agent's wallet to pay for requests. Keep only a working balance in the signer PDA and revoke when the agent is idle.

Quick Reference

ItemValue
Standard wallet schemeExactSvmScheme (from @x402/svm)
Core asset and agent schemeMetaplexSvmExactScheme
Delegation helpersfetchMetaplexCoreExecuteDelegateStatus, approveMetaplexCoreExecuteDelegate, revokeMetaplexCoreExecuteDelegate
Delegated transportscreateMetaplexCoreExecuteDelegateClientExtension, wrapFetchWithMetaplexCoreExecuteDelegate
Auth token lifetime24 hours
Delegation endpoints/x402/core-execute-delegate/{status,approve,revoke,auth}

FAQ

Common questions about Metaplex x402 payment modes.

Which Metaplex x402 payment mode should I use?

Use a standard wallet when your app pays as itself, a Core asset or agent direct payment when you want an asset to hold its own budget under owner oversight, and a delegated agent when an autonomous agent must pay without a human signing each request.

Do I need SOL to pay for Metaplex x402 requests?

Only for Core asset and agent payment modes, where the asset signer PDA needs SOL to cover Core execute transaction fees. Standard wallet payments need no SOL because the service's fee payer covers the payment transaction's network fee.

How long does a delegated agent auth token last?

Authorization JWTs expire after 24 hours. Expired tokens are discarded and replaced automatically, and replacement requires only a message signature — not another onchain delegation approval.

Can I use the reactive extension and the proactive fetch wrapper together?

No. They are alternatives and composing them breaks the flow. Use the reactive client extension when you already run an x402Client or want optional fallback to direct payment; use the proactive fetch wrapper for the simplest wiring against Metaplex endpoints only.

How do I stop a delegated agent from paying?

Call revokeMetaplexCoreExecuteDelegate with the same signer, asset, and RPC options used to approve it. Delegation is an onchain grant, so revocation takes effect onchain and the server can no longer build payments from the agent's wallet.

Can I pay with Token-2022 USDC or another stablecoin?

No. The payment source is always a classic SPL Token associated token account, and Token-2022 payment mints are not currently supported.


Maintained by Metaplex Foundation. Last verified: 2026-09-08. Client version: @metaplex-foundation/x402 0.1.0. View source on GitHub.