A new payment method for MPP that lets any agent pay from any chain, and any merchant receive on any chain — powered by Stableyard.
tempo() → Tempo chain only
stripe() → cards only
stableyard() → 5 chains live (+ Tempo, Movement soon) + fiat to bank
MPP launched with two payment methods:
tempo()— works only on Tempo chainstripe()— works only with cards
If an agent has USDC on Base and the server only accepts tempo(), the agent can't pay. Wrong chain. Stuck.
stableyard() — a third payment method that plugs into mppx:
import { stableyard } from 'mppx-stableyard/server'
const mppx = Mppx.create({
methods: [
tempo.charge({ ... }), // Tempo chain
stableyard({ // ANY chain
apiKey: 'sy_secret_...',
destination: 'merchant@stableyard',
}),
],
})One line added. The server now accepts payments from Base, Arbitrum, Polygon, Ethereum, and Solana — with Tempo and Movement coming soon.
Agent calls API
↓
402 Payment Required
WWW-Authenticate: Payment method="stableyard"
{ amount: "100000", currency: "USDC", destination: "merchant@stableyard" }
↓
Agent (mppx-stableyard client):
1. POST /v2/sessions { amount, destination, sourceChain: "base" }
→ Gets deposit address on Base (inline, one call)
2. Sends 0.10 USDC to deposit address
3. POST /submit-tx { txHash }
→ Stableyard detects payment
4. Polls → settled (9 seconds)
↓
Agent retries with credential { sessionId }
↓
Server calls POST /v2/sessions/:id/verify
→ { verified: true }
↓
200 OK + data + Payment-Receipt
Session: ses_b6afc57b153e2ae1f8fb1025
Tx: 0xbeaf32d41f8f7573e02653a79e02bf56a73ae667dca203acb9e5c181116914a9
Amount: 0.10 USDC on Base
Submit tx: → status: pending
Poll: → settled in 9 seconds
Verify: → { verified: true }
npm i mppx-stableyard mppxAccept MPP payments via Stableyard. Settle to any chain or fiat.
import { Mppx, tempo } from 'mppx/server'
import { stableyard } from 'mppx-stableyard/server'
const mppx = Mppx.create({
methods: [
tempo.charge({ currency: USDC, recipient: '0x...' }),
stableyard({
apiKey: 'sy_secret_...',
destination: 'merchant@stableyard',
}),
],
})
app.get('/api/data', async (req) => {
const result = await mppx['stableyard/charge']({
amount: '100000',
description: 'Premium data',
})(req)
if (result.status === 402) return result.challenge
return result.withReceipt(Response.json({ data: '...' }))
})The 402 response includes a WWW-Authenticate: Payment method="stableyard" challenge. The server verifies payment via Stableyard's /v2/sessions/:id/verify endpoint.
Agent automatically handles 402 → pay via Stableyard → retry.
import { Mppx } from 'mppx/client'
import { stableyard } from 'mppx-stableyard/client'
Mppx.create({
methods: [
stableyard({
apiKey: 'sy_secret_...',
chain: 'base',
sendPayment: async (deposit) => {
// Send USDC to deposit address
return await sendERC20(deposit.address, deposit.amount.raw)
},
}),
],
})
// fetch auto-handles 402 → pay via Stableyard → retry
const res = await fetch('https://api.example.com/data')| Feature | tempo() | stableyard() |
|---|---|---|
| Tempo chain | Yes | Yes (coming soon) |
| Base, Arbitrum, Polygon, Ethereum | Yes | |
| Solana | Yes | |
| Movement | Coming soon | |
| Fiat settlement (bank) | Yes | |
| Named identity (@stableyard) | Yes | |
| Gasless payments (vault) | Yes | |
| Merchant dashboard | Yes | |
| Cross-chain routing | Yes |
| Chain | Settlement Time |
|---|---|
| Base | ~1s (same-chain) |
| Arbitrum | ~15s |
| Polygon | ~15s |
| Ethereum | ~15s |
| Solana | ~22s |
| Tempo | Coming soon |
| Movement | Coming soon |
MPP Protocol
|
+-------------+-------------+
| | |
tempo() stripe() stableyard()
Tempo chain Cards Any chain -> Any chain
Powered by Stableyard
|
|-- 5 chains live (+ Tempo, Movement soon)
|-- Gasyard cross-chain routing
|-- Gasless vault payments
|-- Fiat settlement (KYC)
+-- x402+ backward compatible
Stableyard sits alongside Tempo and Stripe as a payment rail in MPP. Not competing — extending.
mppx-stableyard/
src/method.ts — Method.from() definition (stableyard/charge)
src/server.ts — Method.toServer() — generates 402 challenges, verifies via Stableyard API
src/client.ts — Method.toClient() — creates session, gets deposit addr, pays, polls
src/stableyard-api.ts — Stableyard API client (sessions, quote, verify, submit-tx, poll)
demo/server.ts — Working MPP server with tempo() + stableyard() methods
demo/agent.ts — Agent that auto-pays via Stableyard
stableyard({
apiKey: 'sy_secret_...', // Stableyard API key
destination: 'merchant@stableyard', // Where payments settle
currency: 'USDC', // Default: 'USDC'
decimals: 6, // Default: 6
verifyTimeoutMs: 30000, // Default: 30s
})stableyard({
apiKey: 'sy_secret_...', // Stableyard API key
chain: 'base', // Agent's payment chain
settlementTimeoutMs: 60000, // Default: 60s
sendPayment: async (deposit) => { // Your wallet logic
return txHash
},
})git clone https://github.com/stableyardfi/mppx-stableyard
cd mppx-stableyard
npm install
# Start server
cp demo/.env.example .env
# Edit .env with your Stableyard keys
npx tsx demo/server.ts
# Test 402 response
curl -D- http://localhost:3000/api/market-data
# Run agent
npx tsx demo/agent.tsPR ready to add Stableyard as a service in the MPP service directory (alongside Alchemy, OpenAI, fal.ai). 9 endpoints covering sessions, network, accounts, and deposits.
- Stableyard — Cross-chain stablecoin payments
- MPP — Machine Payments Protocol
- mppx — TypeScript SDK for MPP
- x402+ — Stableyard's x402 protocol implementation
- Stableyard API — OpenAPI spec
MIT