npm package: @stableyard/mppx-stableyard
Description: Stableyard payment method for the Machine Payments Protocol (MPP). Any chain in, any chain out, fiat settlement.
Latest version: 0.1.0

# mppx-stableyard

A new payment method for [MPP](https://mpp.dev) that lets any agent pay from any chain, and any merchant receive on any chain — powered by [Stableyard](https://stableyard.fi).

```
tempo()      → Tempo chain only
stripe()     → cards only
stableyard() → Base, Polygon, Arbitrum, Ethereum, Solana (+ Tempo, Movement soon) + fiat to bank
```

## The Problem

MPP launched with two payment methods:
- `tempo()` — works only on Tempo chain
- `stripe()` — 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.

## The Solution

`stableyard()` — a new payment method that plugs into mppx:

```typescript
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.

## Supported Chains

| Chain | Chain ID | sourceChain value | Provider | Settlement Time | Status |
|-------|----------|-------------------|----------|-----------------|--------|
| Base | 8453 | `base` | direct_transfer | ~1s | Live |
| Polygon | 137 | `polygon` | gasyard | ~15s | Live |
| Arbitrum | 42161 | `arbitrum` | gasyard | ~15s | Live |
| Ethereum | 1 | `ethereum` | gasyard | ~15s | Live |
| Solana | 103 | `solana` | near_intents | ~22s | Live |
| Tempo | 4217 | `tempo` | relay | ~15s | Coming soon |
| Movement | 2 | `movement` | gasyard_v2 | ~3s | Coming soon |

Agent specifies the chain when creating the client:

```typescript
stableyard({ apiKey: '...', chain: 'base' })     // pay from Base
stableyard({ apiKey: '...', chain: 'polygon' })   // pay from Polygon
stableyard({ apiKey: '...', chain: 'solana' })     // pay from Solana
stableyard({ apiKey: '...', chain: 'tempo' })      // pay from Tempo (coming soon)
stableyard({ apiKey: '...', chain: 'movement' })   // pay from Movement (coming soon)
```

Merchant receives on their preferred chain regardless of where the agent paid from. Configure once in the Stableyard dashboard.

## How It Works

```
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 API call)
  2. Sends 0.10 USDC to deposit address
  3. POST /submit-tx { txHash }
     → Stableyard detects payment
  4. Polls → settled
  ↓
Agent retries with credential { sessionId }
  ↓
Server calls POST /v2/sessions/:id/verify
  → { verified: true }
  ↓
200 OK + data + Payment-Receipt
```

### Cross-Chain Example (Polygon → Base)

Agent has USDC on Polygon. Merchant wants settlement on Base.

```
Agent: POST /v2/sessions { destination: "merchant@stableyard", sourceChain: "polygon" }
  → Returns gasyard gateway calldata (approve + deposit txs)
  → Agent executes gateway transactions on Polygon
  → Stableyard routes Polygon → Base via solver network
  → Merchant receives USDC on Base in ~15 seconds
```

### Same-Chain Example (Base → Base)

```
Agent: POST /v2/sessions { destination: "merchant@stableyard", sourceChain: "base" }
  → Returns direct_transfer deposit address
  → Agent sends USDC to address on Base
  → Settled in ~1 second
```

## Proved with Real Money

```
Session:   ses_b6afc57b153e2ae1f8fb1025
Tx:        0xbeaf32d41f8f7573e02653a79e02bf56a73ae667dca203acb9e5c181116914a9
Chain:     Base (mainnet)
Amount:    0.10 USDC
Submit tx: → status: pending
Poll:      → settled in 9 seconds
Verify:    → { verified: true }
Basescan:  https://basescan.org/tx/0xbeaf32d41f8f7573e02653a79e02bf56a73ae667dca203acb9e5c181116914a9
```

## Install

```bash
npm i mppx-stableyard mppx
```

## Server

Accept MPP payments via Stableyard. Settle to any chain or fiat.

```typescript
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.

## Client

Agent automatically handles 402 → pay via Stableyard → retry.

```typescript
import { Mppx } from 'mppx/client'
import { stableyard } from 'mppx-stableyard/client'

Mppx.create({
  methods: [
    stableyard({
      apiKey: 'sy_secret_...',
      chain: 'base',        // or 'polygon', 'arbitrum', 'ethereum', 'solana'
      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')
```

## What stableyard() Adds to MPP

| Feature | tempo() | stableyard() |
|---------|---------|-------------|
| Tempo chain | Yes | Coming soon |
| Base | | Yes |
| Polygon | | Yes |
| Arbitrum | | Yes |
| 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 |

## Architecture

```
                     MPP Protocol
                         |
           +-------------+-------------+
           |             |             |
       tempo()      stripe()    stableyard()
       Tempo chain   Cards      Any chain -> Any chain
                                Powered by Stableyard
                                    |
                                    |-- Base (direct_transfer, ~1s)
                                    |-- Polygon (gasyard, ~15s)
                                    |-- Arbitrum (gasyard, ~15s)
                                    |-- Ethereum (gasyard, ~15s)
                                    |-- Solana (near_intents, ~22s)
                                    |-- Tempo (relay, coming soon)
                                    |-- Movement (gasyard_v2, coming soon)
                                    |
                                    |-- Gasless vault payments (EIP-712)
                                    |-- Fiat settlement (KYC)
                                    +-- x402+ backward compatible
```

Stableyard sits alongside Tempo and Stripe as a payment rail in MPP. Not competing — extending.

## What's Inside

```
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)
  specs/                 — draft-stableyard-charge-00.md (IETF-style protocol spec)
  demo/server.ts         — Working MPP server with tempo() + stableyard() methods
  demo/agent.ts          — Agent that auto-pays via Stableyard
```

## Configuration

### Server

```typescript
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
})
```

### Client

```typescript
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
  },
})
```

## Try It

```bash
git clone https://github.com/stableyardfi/mppx-stableyard
cd mppx-stableyard
npm install

# Start server
cp demo/.env.example .env
npx tsx demo/server.ts

# Test 402 response
curl -D- http://localhost:3000/api/market-data

# See the MPP challenge with method="stableyard"
```

## Also Built

- **Protocol spec**: `draft-stableyard-charge-00.md` — IETF-style spec following Lightning/Tempo format
- **Service registry PR**: Adding Stableyard to [MPP service directory](https://github.com/tempoxyz/mpp) alongside Alchemy, OpenAI, fal.ai
- **x402+ compatibility**: Same Stableyard backend powers both [x402+](https://github.com/stableyardfi/x402plus) and mppx-stableyard

## Links

- [Stableyard](https://stableyard.fi) — Cross-chain stablecoin payments
- [MPP](https://mpp.dev) — Machine Payments Protocol
- [mppx](https://github.com/wevm/mppx) — TypeScript SDK for MPP
- [x402+](https://github.com/stableyardfi/x402plus) — Stableyard's x402 protocol
- [Stableyard API](https://api.stableyard.fi/sdk.json) — OpenAPI spec
- [Basescan proof](https://basescan.org/tx/0xbeaf32d41f8f7573e02653a79e02bf56a73ae667dca203acb9e5c181116914a9) — Real money settlement tx

## License

MIT