@monad-crypto/mpp
v0.0.1
Published
Monad payment method for the Machine Payments Protocol
Readme
@monad-crypto/mpp
Monad payment method for the Machine Payments Protocol.
Warning: This package is under active development.
Install
npm install @monad-crypto/mpp mppx viemFeatures
- Charge — One-time ERC-20 token transfers. Supports push mode (client broadcasts) and pull mode (server broadcasts).
Usage
Server
import { Mppx } from 'mppx/server'
import { monad } from '@monad-crypto/mpp/server'
const mppx = Mppx.create({
methods: [
monad.charge({
recipient: '0x...', // address that receives payments
currency: '0x...', // ERC-20 token contract address
}),
],
})Client
import { Mppx } from 'mppx/client'
import { monad } from '@monad-crypto/mpp/client'
import { privateKeyToAccount } from 'viem/accounts'
const mppx = Mppx.create({
methods: [
monad.charge({
account: privateKeyToAccount('0x...'),
}),
],
})Exports
| Path | Description |
|------|-------------|
| @monad-crypto/mpp | Base method definition (charge) |
| @monad-crypto/mpp/client | Client-side charge with createCredential |
| @monad-crypto/mpp/server | Server-side charge with verify |
Client Parameters
| Parameter | Type | Description |
|-----------|------|-------------|
| account | Account \| Address | Wallet account for signing transactions |
| getClient | (params) => Client | Custom viem client resolver by chain ID |
| mode | 'push' \| 'pull' | push: client broadcasts an ERC-20 transfer (default for JSON-RPC accounts). pull: client signs an ERC-3009 TransferWithAuthorization for the server to submit (default for local accounts) |
Server Parameters
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| recipient | string | — | Address that receives payments |
| currency | string | USDC | ERC-20 token contract address |
| decimals | number | 6 | Token decimals |
| amount | string | — | Default payment amount (human-readable, e.g. "1.50") |
| description | string | — | Human-readable description |
| externalId | string | — | External identifier to echo back in receipt |
| getClient | (params) => Client | Built-in | Custom viem client resolver by chain ID |
| testnet | boolean | false | Use testnet chain ID |
| waitForConfirmation | boolean | true | Wait for on-chain confirmation before returning receipt |
| account | Account \| Address | — | Server wallet for broadcasting receiveWithAuthorization transactions. Required when accepting authorization payloads (the server pays gas from this account) |
| store | Store | In-memory | Store for transaction hash replay protection. Use a shared store (e.g. Redis) in multi-instance deployments so consumed hashes are visible across all server instances |
Example
A complete Hono server and client demo is in example/.
# 1. Copy the env file and fill in your private keys
cp example/.env.example example/.env
# 2. Start the server
bun run example/server.ts
# 3. In another terminal, run the client
bun run example/client.tsThe server account receives payments and broadcasts receiveWithAuthorization transactions, so it must be funded with MON for gas. The client account must be funded with USDC.
Specification
The formal protocol specification is available at spec/draft-monad-charge-00.md.
How It Works
- Server issues a
402 Payment Requiredchallenge viamppxwith methodmonadand intentcharge. - Client creates a credential based on the mode:
- Push mode: Client broadcasts an ERC-20
transfer(to, amount)transaction and returns the tx hash. - Pull mode: Client signs an ERC-3009
TransferWithAuthorizationand returns the signature. Server callsreceiveWithAuthorizationto execute the transfer and pay gas.
- Push mode: Client broadcasts an ERC-20
- Server verifies the payment matches the challenge (amount, recipient, currency).
- Server returns a
Payment-Receiptheader on success.
License
MIT
