🌍 Build Agent Payment Rails on Stellar with MoneyGram
How to give your AI agent the ability to move USDC across borders, cash out to physical retail locations in 174 countries, pay other agents’ fiat accounts directly, and stream sub-cent micropayments — in one install, backed by
payment-skill+n-paymentSDK v0.30 on Stellar.Try Here = https://www.npmjs.com/package/n-payment
🎯 TL;DR — What you’ll ship
🤖 An agent that pays for HTTP APIs on Stellar in < 5 seconds with native USDC at fractions of a cent in gas.
🏪 The same agent cashes USDC out to MoneyGram retail pickup across ~500 000 agent locations in 174 countries via Stellar SEP-24.
💵 The same agent pays another agent’s fiat account directly via SEP-31 (agent-to-agent B2B rail).
🍻 The same agent opens off-chain payment channels (MPP) — deposit once, sign N commitments off-chain, close with one on-chain settlement.
One command bootstraps everything on Stellar testnet — zero MoneyGram allowlisting required for development.
🧭 Why Stellar for agent payments
Stellar solves specific problems that generic EVM rails do not:
🌐 Native cross-border DNA. The network was built for remittances. Every anchor speaks the same SEP standards, so an agent talks to MoneyGram the same way it talks to any other anchor.
⚡ Sub-5-second finality at fractions of a cent. Fast enough for 402-style request-response loops. Cheap enough for micropayments.
💵 USDC issued natively by Circle. No bridged wrappers, no peg risk.
🤖 Two agentic-payment protocols live on mainnet since May 2026.
x402— programmable HTTP 402 paywall (co-governed by Coinbase / Cloudflare / Google / Visa).MPP— Machine Payments Protocol (Stripe + Tempo, submitted to IETF).
🤝 MoneyGram × Stellar Development Foundation multi-year partnership since 2021 — the physical off-ramp for the whole ecosystem.
🪪 Six wallet integrations out of the box — Freighter, Albedo, Hana, HOT, Klever, OneKey. All support Soroban auth-entry signing.
🧩 What payment-skill + n-payment give you
The concept split:
🛠️
payment-skill— the agent-facing surface. A one-line install wires 42 tools into your AI host (Claude Code, Kiro, Cursor, Windsurf, Continue, Gemini CLI, Copilot). The agent asks in plain English; the skill picks the tool.🔧
n-paymentSDK — the payment engine. TypeScript library, 19 chains, all the SEPs, all the facilitators.payment-skillis a thin transport over it.
For Stellar + MoneyGram specifically, the skill exposes three tools:
💸
pay— pay any URL. Auto-detects x402 or MPP from the 402 response. Signs Soroban auth entries. Settles via the right facilitator (Coinbase testnet, OpenZeppelin Relayer mainnet).🌍
stellar_off_ramp— MoneyGram cash-out surface. Actions:corridors·quote·cash_out·b2b_payout·status. Testnet talks to SDF’s public reference anchor with zero config. Mainnet talks to MoneyGram Preview via one env var.🍻
stellar_session— MPP off-chain payment channels (”bar tab” mode). Actions:open·commit·close·status. Deposit once, spend at high frequency off-chain, close with a single on-chain settlement.
Plus supporting tools the agent gets for free:
💰
check_balance— reads native XLM + USDC via Horizon.🧾
generate_qr— emits SEP-7web+stellar:pay?…URIs scannable by any Stellar wallet.🛡️
policy_check— chain-agnostic policy gate; always run before mainnet sends.🪪
agent_card— publish an A2A Agent Card so other agents can discover your paid endpoints.
🏗️ The stack under the hood
🧠 AI host — Claude Code / Kiro / Cursor / Windsurf / Continue / Gemini CLI / GitHub Copilot.
🛠️ Skill —
n-payment-skill(npm / GitHub). MCP-native, single binary, one-line install.🔧 SDK —
n-payment@^0.30.0. ExposesstellarAgentKit(),createStellarSession(),DefaultAnchorRegistry,StellarWallet.🔌 Protocols — x402 (Coinbase spec) · MPP (
mpp.dev, submitted to IETF) · SEP-10 (auth) · SEP-24 (interactive withdraw) · SEP-31 (direct payment) · SEP-38 (quote) · SEP-7 (payment URI) · SEP-41 (token interface).⚡ Facilitators — auto-picked. Testnet: Coinbase free facilitator (no API key). Mainnet: OpenZeppelin Relayer x402 Plugin (API key required).
🏪 Anchor (testnet) — SDF’s public reference at
testanchor.stellar.org. Implements every SEP we need.🏪 Anchor (mainnet) — MoneyGram Access Preview Environment. Allowlisted host per operator.
💵 Token — USDC (SEP-41 Soroban SAC, issued natively by Circle on Stellar).
🪪 Wallet — Ed25519 keypair derived from the shared skill wallet seed. Same on-disk keyfile serves EVM, XRPL, Stellar, Solana, Cosmos.
🚀 Three-minute quickstart
Three steps to a working Stellar-testnet agent that can pay, cash out, and open a channel.
1️⃣ Install the skill
npx -y github:phamdat721101/payment-skill
What happens:
🔍 The installer detects your AI host (Claude Code / Kiro / Cursor / …).
🔐 It creates an encrypted local wallet at
~/.n-payment/wallets/default.json(chmod 0600, Web3 Secret Storage v3).🪪 Your Stellar
G…address is auto-derived from the same seed — no separate keystore.💧 Testnet USDC is dripped so you can try flows without spending real money.
🩺 A doctor check confirms everything reachable.
2️⃣ Fund the account on Stellar testnet (30 seconds, no creds)
n-payment-skill check_balance --chain stellar-testnet # prints your G-addressThen either:
🌐 Visit
https://laboratory.stellar.org/#account-creator
and fund the address you just derived.
💵 Add a USDC trustline (auto-handled by the SDK on first pay) and drip test USDC from
https://faucet.circle.com
.
3️⃣ Ask your agent
Open your host of choice, paste a prompt. Some to try:
“Check my Stellar testnet balance.” →
check_balance“List Stellar off-ramp corridors on testnet.” →
stellar_off_ramp action=corridors“Quote 10 USDC to USD for country US on Stellar testnet.” →
stellar_off_ramp action=quote“Cash out 10 USDC through MoneyGram on Stellar testnet.” →
stellar_off_ramp action=cash_out“Open a Stellar payment session with 1 USDC to GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN.” →
stellar_session action=open“Pay for https://x402-demo.stellar.org/data on stellar-testnet.” →
pay
The skill picks the tool. The tool picks the SEP. The SEP picks the anchor. You never touch the transport.
🧪 Testnet path — hermetic development
Zero MoneyGram allowlisting required. The skill auto-registers SDF’s public reference anchor at testanchor.stellar.org in the anchor registry when you target stellar-testnet. This anchor implements the full SEP surface (SEP-6 / 10 / 12 / 24 / 31 / 38) and loops deposits and withdrawals back within Stellar testnet — no real cash moves.
Flow inside the skill:
🧭
pickStellarAnchorRegistry({ chain: 'stellar-testnet' })creates aDefaultAnchorRegistryand registers the SDF test anchor entry.🔑
pickStellarConfig(env, walletPrivateKey, 'stellar-testnet')returns yourS…secret key (derived from the shared skill seed) with no facilitator API key needed.🏪
stellarAgentKit(signer, { registry, isMainnet: false })returns a five-method façade:quote,cashOut,b2bPayout,corridors,status.
Zero env vars required for testnet. n-payment-skill doctor --chain stellar-testnet will report “SDF test anchor reachable — off-ramp demo ready.”
🚦 Mainnet path — real fiat
Two env vars flip the mainnet switch:
🔑
STELLAR_OZ_API_KEY— OpenZeppelin Relayer x402 facilitator key. Free-tier generator at https://channels.openzeppelin.com/gen.🏪
STELLAR_ANCHOR_MONEYGRAM_COM_TOML_URL— your allowlisted MoneyGram Preview host, e.g.https://previewstellar.moneygram.com/.well-known/stellar.toml.
To get the MoneyGram allowlist:
🌐 Fill the self-onboarding form at https://developer.moneygram.com/moneygram-developer/docs/access-to-moneygram-ramps.
🪪 Provide the Stellar public keys the skill derived (
check_balance --chain stellar-testnetprints yourG…address; the same seed produces the mainnetG…address).📩 MoneyGram returns your allowlisted TOML URL (Preview host).
🔐
export STELLAR_ANCHOR_MONEYGRAM_COM_TOML_URL="https://<your-preview-host>/.well-known/stellar.toml".
Then opt into mainnet:
n-payment-skill config set testnetMode false
export STELLAR_OZ_API_KEY=oz_…
export STELLAR_ANCHOR_MONEYGRAM_COM_TOML_URL=https://previewstellar.moneygram.com/.well-known/stellar.toml
n-payment-skill doctor --chain stellar-mainnetDoctor prints “MoneyGram anchor reachable: “ — you’re ready to stellar_off_ramp action=cash_out for real fiat.
MoneyGram Preview Environment limits: 5 USDC min, 2 500 USDC max per transaction. Corridor coverage: 174 countries.
🧾 Off-ramp — the three flows in detail
💱 SEP-38 quote (pre-flight, no funds move)
Use before every cash-out to lock rate + fee:
{ action: 'quote', amount: '20', asset: 'USDC', fiat: 'USD', country: 'US', chain: 'stellar-mainnet' }Returns:
🎯
quoteId— bind this to a subsequentcash_outorb2b_payoutto lock the fee.💰
rate— USD per USDC.⏰
expiresAt— quote validity window (seconds).💸
feeFixed— fixed fee in USDC.
Fully headless. Does not block on human.
🏪 SEP-24 cash_out (retail cash pickup)
For agent-owned funds → physical MoneyGram cash pickup:
{ action: 'cash_out', amount: '20', asset: 'USDC', fiat: 'USD', chain: 'stellar-mainnet' }
Returns:
🔗
moreInfoUrl— open in a browser once to complete KYC and receive the payout instructions.🆔
id— transaction id to poll viaaction: 'status', handle_id: <id>.
Blocks on human: recipient must complete KYC + visit a MoneyGram retail location.
🤝 SEP-31 b2b_payout (agent-to-agent direct payment)
For agent A → agent B’s fiat account (or a merchant’s) — one-shot, no interactive UI:
{
action: 'b2b_payout',
amount: '100',
asset: 'USDC',
fiat: 'USD',
country: 'US',
receiver_fields: { first_name: 'Alice', last_name: 'Anchor', email_address: 'alice@example.com' },
chain: 'stellar-mainnet'
}First call per receiver returns receiverInfoUrl — the receiver operator visits it once, completes SEP-12 KYC, receives a receiver_id. Subsequent calls skip the URL:
{ action: 'b2b_payout', amount: '50', receiver_id: 'alice-receiver-id-from-anchor', quote_id: 'q-abc123', chain: 'stellar-mainnet' }Blocks on human only on the first call. After that, fully headless.
🍻 MPP off-chain channels — the “bar tab” pattern
For high-frequency micropayments (per-token, per-tick, per-second), the charge mode of MPP becomes expensive. Open a session channel instead:
1️⃣
open— one on-chain deposit tx locks the budget. Returnssession_id+receipt.2️⃣
commit(many times) — sign one off-chain commitment per micropayment. Zero on-chain traffic. Returnscommitment+cumulative.3️⃣
close— one on-chain settlement tx spends the cumulative amount. ReturnstxHash+settledMicros.
Example agent flow:
// 1. open
{ action: 'open', provider: 'GA5Z…', budget_micros: 1_000_000, chain: 'stellar-testnet' }
// → { sessionId: 'sess-abc', receipt: '…', budgetMicros: 1_000_000 }
// 2. commit 999 times off-chain (each is one micropayment)
{ action: 'commit', session_id: 'sess-abc', amount_micros: 1_000, prev_commitment: '0xbeef…' }
// → { commitment: '0xdead…', cumulative: 1000 }
// … repeat with the returned commitment as prev_commitment …
// 3. close
{ action: 'close', session_id: 'sess-abc' }
// → { txHash: 'stellar-tx-…', settledMicros: 999_000 }The critical design property: the tool is stateless. session_id and prev_commitment travel with the caller. No module-level map in the skill. Restarts, forks, and multi-tenant MCP HTTP hosts all work by construction.
When to use which mode:
✅
chargemode (via thepaytool withstellar-*chain) — occasional one-off paid API calls.✅
sessionmode (viastellar_session) — bursty / per-token / per-tick / per-second workloads.❌ If neither fits, you probably don’t need MPP at all.
🛡️ Security posture (why this is safe to run)
🔒 Encrypted at rest — the shared wallet is Web3 Secret Storage v3 (scrypt + AES-128-CTR + Keccak MAC). Interop with viem, ethers, geth, hardware imports.
🔓 Session unlock —
n-payment-skill unlockdecrypts once; auto-evicts after 30 min. Private key never touches disk after that.🛂 Policy-gated dispatcher — every signing path passes through unlock → denylist → allowlist → per-tx cap → per-day cap → rate limit.
🚫 Mainnet guard —
testnetMode=truerefuses any*-mainnetsend. Flip explicitly per rail.🩹 Env-var fail-closed — mainnet cash-out without
STELLAR_OZ_API_KEYreturnsSTELLAR_OZ_KEY_MISSINGbefore the SDK is even loaded; same forSTELLAR_ANCHOR_MONEYGRAM_COM_TOML_URL.📜 Audit log — append-only JSONL at
~/.n-payment/audit.log(0600, rotated at 5 MiB). Secret-shaped keys are redacted before write.
🛠️ Errors → fixes
Common codes when building against Stellar + MoneyGram:
🌐
OFFRAMP_NO_ANCHOR— no anchor supports the (asset, fiat, country) tuple. Testnet: SDF’stestanchor.stellar.orgauto-registers USDC/USD. Mainnet: setSTELLAR_ANCHOR_MONEYGRAM_COM_TOML_URLor pick another corridor.🔑
STELLAR_OZ_KEY_MISSING— Stellar mainnet requires the OpenZeppelin Relayer x402 API key. Generate at https://channels.openzeppelin.com/gen and export.📄
ANCHOR_TOML_FETCH_FAILED— the anchor’s.well-known/stellar.tomlis unreachable. Check the env var host, or wait for anchor health.❓
ANCHOR_QUOTE_NOT_SUPPORTED— anchor doesn’t offer SEP-38. Fall back tocash_out(SEP-24) without a pre-flight quote.❓
ANCHOR_B2B_NOT_SUPPORTED— anchor doesn’t offer SEP-31. Fall back tocash_outinteractive path.🔐
ANCHOR_AUTH_FAILED— SEP-10 challenge / token exchange rejected. Verify the anchor allowlisted yourG…andisMainnetmatches the anchor’s network.⏱️
OFFRAMP_TIMEOUT— a request exceededtimeout_ms(default 12 000). Raise viatimeout_msarg or check network.🚫
MAINNET_GUARD— mainnet send blocked whiletestnetMode=true. Runn-payment-skill config set testnetMode false.🔒
LOCKED— unlock cache is cold. Runn-payment-skill unlock.
🧠 What makes this SOLID (and reusable in your own agent)
SRP — one tool per rail.
stellar_off_rampowns MoneyGram-via-Stellar.stellar_sessionowns MPP channels. The existingoff_ramp(MoonPay / Transak) is untouched.OCP — anchor registry is extension-only.
registry.add({...})registers a new anchor without touching the façade.DIP — handlers depend on
stellarAgentKitandcreateStellarSessionabstractions, never on concrete anchor URLs or SEP transport.DRY — one
pickStellarConfiggives you the signer + mainnet gate for every Stellar tool. Onewrap/ok/failgives you the result shape.Immutability — no module-level mutable state in
stellar_session. Session id and cumulative commitment travel with the caller.
If you’re building your own agent-skill, this pattern is directly copyable: one declarative tool registry, one lazy-loaded SDK, one shared wallet, one policy engine.
📚 Resources
Stellar
📖 Developer Docs — https://developers.stellar.org
🤖 Agentic Payments — https://developers.stellar.org/docs/build/agentic-payments
💱 x402 on Stellar — https://developers.stellar.org/docs/build/agentic-payments/x402
🍻 MPP on Stellar — https://developers.stellar.org/docs/build/agentic-payments/mpp
SEPs (the standards that make it work)
🌐 SEP-1 — asset publishing (
stellar.toml)🔐 SEP-10 — wallet authentication (JWT via signed challenge)
🪪 SEP-12 — KYC info exchange
🏪 SEP-24 — hosted interactive deposit / withdrawal
🤝 SEP-31 — cross-border direct payment (agent-to-agent, agent-to-merchant)
💱 SEP-38 — anchor RFQ (quotes)
🧾 SEP-7 — payment URI
🪙 SEP-41 — token interface (Soroban)
MoneyGram
📖 Access Integration Guide — https://developers.stellar.org/docs/building-apps/moneygram-access-integration-guide
🪪 Developer Portal — https://developer.moneygram.com/moneygram-developer/docs/access-to-moneygram-ramps
Facilitators & infra
⚡ OpenZeppelin Relayer x402 Plugin — https://github.com/OpenZeppelin/relayer-plugin-x402-facilitator
🔑 OZ Mainnet API Key — https://channels.openzeppelin.com/gen
🔑 OZ Testnet API Key — https://channels.openzeppelin.com/testnet/gen
Skill + SDK
🛠️
n-payment-skill— https://github.com/phamdat721101/payment-skill🔧
n-paymentSDK — https://www.npmjs.com/package/n-payment🤖 Stellar Dev Skill (Claude Code / OpenCode / Codex) — https://github.com/stellar/stellar-dev-skill
📄
llms.txtfor LLM context — https://developers.stellar.org/llms.txt🧠 Stella AI assistant — https://developers.stellar.org/docs/tools/ai
🎬 Ship it
npx -y github:phamdat721101/payment-skillThen paste in your agent:
“Cash out 5 USDC to USD through MoneyGram on Stellar testnet, then open a payment session with 1 USDC for micropayments.”
You’ll have a working moreInfoUrl from SDF’s test anchor and an open MPP session before you finish reading the next paragraph.
The whole thing runs on your laptop. One wallet. One config. One policy engine. Every rail the SDK speaks.
That’s the shape of an agent-skill for payment.

