v0.1 — Beta

Stack

LayerTechnology
Payment ProtocolMachine Payments Protocol (MPP) — HTTP 402-based, open standard
BlockchainSolana Mainnet
Smart ContractAnchor (Rust) — Policy Program + Settlement Program
StablecoinUSDC (SPL Token, native Solana mint)
API BackendNode.js / TypeScript, Fastify
DatabasePostgreSQL — wallets, policies, audit log, session state
QueueBullMQ + Redis — async settlement processing and webhook fan-out
FrontendNext.js + TypeScript — operator dashboard
AuthHMAC-signed API keys + operator OAuth2
MonitoringDatadog + custom Solana RPC health checks
SDK (TypeScript)@mpppal/sdk
SDK (Python)mpppal

MPP payment flow (Charge intent)

A single agent request to a paid service:

text
Agent (SDK HTTP client)
  │
  ▼  GET https://api.provider.xyz/data
MPP Service
  │  HTTP 402 + WWW-Authenticate: Payment challenge
  ▼
MPPPal SDK (in-process)
  │  1. Parse payment challenge
  │  2. Check wallet balance and spending policy
  │  3. Sign payment credential
  ▼
Agent retries with Authorization: Payment header
  │
MPP Service
  │  HTTP 200 + Payment-Receipt header
  ▼
MPPPal API (async)
  │  4. Record receipt in PostgreSQL
  │  5. Enqueue settlement job
  ▼
Settlement Worker (BullMQ)
  │  6. Build Solana SPL transfer instruction
  │  7. Sign with PDA authority (Policy Program enforces limits)
  │  8. Submit to Solana RPC
  │  9. Poll for finality (~400ms)
  ▼
Solana Mainnet
  │  10. On-chain settlement confirmed
  ▼
Post-processing
  │  11. Write settled transfer to PostgreSQL audit log
  │  12. Update daily spend counter
  │  13. Fire webhooks (transfer.settled)
  ▼
Response / Webhook to Operator

Session settlement flow

For high-frequency agents using the Session intent, the on-chain footprint is radically smaller:

text
Agent opens session
  │  → On-chain: lock funds in escrow PDA (1 Solana tx)
  ▼
Agent makes N requests to same provider
  │  → Off-chain: micropayment receipts streamed to MPPPal
  │  → No on-chain transactions during session
  ▼
Session closes (timeout or explicit close)
  │  → On-chain: batch-settle net amount (1 Solana tx)
  │  → On-chain: release unused locked USDC to wallet
  ▼
N micropayments → 2 Solana transactions total

On-chain program structure

MPPPal deploys two Solana programs, both written in Rust using the Anchor framework:

Policy Program

Stores and enforces spending policy for each agent wallet. Policy rules live in a PDA derived from the wallet's public key. The program validates every transfer instruction against this policy before allowing execution.

text
Policy Program
└── Wallet PDA (one per agent wallet)
    ├── USDC SPL token account
    ├── Spending policy state
    │   ├── max_single_transfer
    │   ├── max_daily_spend
    │   ├── allowed_counterparties[]
    │   ├── categories[]
    │   ├── require_memo
    │   ├── escalation_threshold
    │   └── paused
    └── Transaction nonce (replay protection)

Settlement Program

Handles the movement of USDC between wallets, batch settlement of sessions, and escrow management for session locks.

text
Settlement Program
├── settle_batch(receipts[])   — batch-settle signed micropayment receipts
├── open_session(cap)          — lock funds in session escrow PDA
├── close_session(session_id)  — settle net amount, release remainder
└── transfer(from, to, amount) — direct wallet-to-wallet transfer
Both programs are open-source. The on-chain programs are publicly verifiable. Anyone can read what they do and confirm the deployed bytecode matches the source. MPPPal's off-chain API layer is trusted for convenience; the on-chain programs are trusted by math.

Database schema (simplified)

accounts

ColumnTypeNotes
account_idvarcharPrimary key. Format: acct_*
operator_iduuidFK to operators table
namevarcharDisplay name
handlevarcharHuman-readable handle e.g. @research-agent.mpppal
solana_addressvarchar(44)Base58 PDA address
usdc_token_accountvarchar(44)Base58 SPL token account
custody_modeenumcustodial | non_custodial
statusenumactive | paused
created_attimestamptz

transfers

ColumnTypeNotes
transfer_idvarcharPrimary key. Format: txn_*
account_idvarcharFK to accounts
to_addressvarchar(44)Recipient SPL address
amount_usdcnumeric(20,6)
memovarchar(200)Nullable
mpp_session_idvarcharNullable — set if settled as part of a session
idempotency_keyvarchar(128)Unique per account
tx_signaturevarchar(88)Nullable until settled
statusenumpending | settled | rejected | failed
rejection_reasonvarcharNullable
settled_attimestamptzNullable

mpp_sessions

ColumnTypeNotes
session_idvarcharPrimary key. Format: sess_*
account_idvarcharFK to accounts
provider_endpointvarcharMPP service URL
cap_usdcnumeric(20,6)Pre-authorized spending cap
running_total_usdcnumeric(20,6)Off-chain running tally
statusenumopen | settling | settled
settlement_tx_signaturevarchar(88)Nullable until settled
opened_attimestamptz
settled_attimestamptzNullable