Overview
meridian_x402 is the Solana (SVM) port of the Meridian facilitator. It is the
equivalent of X402ProxyFacilitator.transferWithAuthorization
on EVM: it pulls USDC from a payer, subtracts platform and treasury fees, and
settles the remainder to the recipient — atomically, in a single transaction.
This first version is intentionally minimal. It settles same-chain USDC
payments on Solana and nothing else: no cross-chain (Across) routing, no MRDN
cashback, and no batched settlement (those live only on the EVM facilitator
today).
Integrations should read the program ID, facilitator pubkey, and on-chain
config from
GET /v1/solana/facilitator at runtime rather than hardcoding
them, so they keep working across any redeploys.Deployment
Built with Anchor 0.32.1. The config account is a PDA at seeds
["config"],
derived from the program ID.
USDC mints the program settles against:
Why it looks different from the EVM facilitator
On EVM, the payer cannot join the settlement transaction without paying gas, so x402 relies on EIP-3009: the payer signs an off-chain authorization, and the facilitator submits it on-chain where the token contract verifies the signature. Solana needs none of that machinery:- A transaction can have multiple signers, and any of them can pay the fee.
The payer (
from) signs the settlement transaction as the authority of their USDC token account. The backend signer co-signs aspayer(fee payer) and submits it. The payer’s transaction signature is the authorization — no in-program signature verification required. - Settlement is atomic within one transaction, so there is no escrow hop.
The EVM contract first pulls the full amount into itself and then distributes;
here the program splits funds directly from the payer’s token account via up
to three
transfer_checkedCPIs (platform fee, treasury fee, recipient net).
transferWithAuthorization:
valid_after/valid_beforesettlement window, checked against the on-chain clock- a 32-byte
noncefor x402 payment correlation and idempotency - identical fee economics (platform fee off gross, treasury fee off the remainder)
Architecture
Config account
A single global PDA (seeds = ["config"]) holds the program’s configuration:
Instructions
transfer_with_authorization account list:
Fee math
Identical to the EVM facilitator’s_settleAndDistribute:
MAX_FEE_BPS = 1000 (10%). Multiplication is widened to
u128 so it cannot overflow. Each settlement emits an InstantSettlement
event with the full breakdown:
Replay protection & the nonce
Replay protection is transaction-level, matching the reference x402 SVM scheme. The paying user signs the settlement transaction itself, which embeds a recent blockhash: the runtime rejects duplicate signatures, and the transaction expires with the blockhash. Settling the same payment again would require a fresh signature from the payer. No nonce account is created on-chain, so no rent is locked per payment. The 32-bytenonce argument is carried into the InstantSettlement event for x402
payment correlation, and the facilitator additionally refuses to co-sign a nonce
it has already settled (a settlement cache in the payments table).
Errors
(Treasury-token ownership is enforced by an Anchor account constraint, which
surfaces as a generic constraint error rather than a program-specific code.)
How settlement is validated
The client builds and payer-signs the settlement transaction; the facilitator’sPOST /v1/settle acts as the co-signing safety boundary. Before it adds the
backend signer’s signature and submits, it checks that the transaction does
exactly one thing the backend signer is willing to pay for:
- the fee payer is the backend signer, and the transaction contains exactly one
transfer_with_authorizationinstruction against the Meridian program payer(account 0) is the backend signer;from(account 1) is a different signerconfigis the expected Config PDA and the token program is the SPL Token program- the mint equals
paymentRequirements.asset, andvalueequalsmaxAmountRequired - the validity window is still open (
valid_after <= now,valid_before >= now + 6s) from_token,recipient_token, and anyplatform_tokenare the correct associated token accounts for the resolved recipient / platform, andplatform_fee_bpsmatches the organization’s configured fee- the payer’s wallet signature is present and valid, and the backend signer has not already signed
Deliberately omitted (vs. EVM V6)
Settlement is instant to every party, so there are no fee-accrual balances or withdraw functions. Also out of scope for this version, all of which remain EVM-only for now:- MRDN cashback
- Cross-chain (Across) settlement
- Batch payments
Building & running locally
The program lives incontracts-sol/ in the Meridian
monorepo. Requires the Solana CLI (Agave) and Anchor 0.32.1 (avm use 0.32.1).
contracts-sol/README.md and contracts-sol/SETUP.md for
deploying to devnet and running the facilitator + pay app against it.
References
- Solana payments (AI skill) — end-to-end integration guide
- Smart Contracts — the EVM facilitator
- Supported Networks
- Payment Types
- Settle x402 Payment