Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@meshgateway/mpp-client

Pay machine-payable endpoints from any agent. This client speaks the x402 "exact" scheme over Permit2 witness transfers: it catches an HTTP 402 challenge, signs a stablecoin authorization, and retries the request. Built for tokens without EIP-3009 support, starting with USDG on Robinhood Chain (eip155:4663).

The buyer wallet only ever needs the stablecoin. Payments are signatures (the merchant's relayer pays settlement gas), and the one-time Permit2 approval can be gas-sponsored by a gateway.

Install

npm install @meshgateway/mpp-client viem

Pay an endpoint

import { createClient, getSettlement } from '@meshgateway/mpp-client';
import { privateKeyToAccount } from 'viem/accounts';

const client = createClient({
  signer: privateKeyToAccount(process.env.BUYER_PRIVATE_KEY),
  maxAmount: '0.05', // spend cap per request, display units
});

const res = await client.fetch(
  'https://api.meshgateway.com/m/acme-signals/v1/quote',
);
console.log(await res.json());
console.log(getSettlement(res)); // { transaction, network, payer }

client.fetch is a drop-in fetch: responses that are not a 402 pass through untouched. When the response is a 402 with a permit2 offer at or below your maxAmount, the client signs and retries once. Anything else throws a MppClientError with a code explaining why (no-permit2-offer, over-max-amount, payment-rejected).

One-time setup per wallet

Permit2 needs a single on-chain approval per token. Wallets holding only the stablecoin can have the gas sponsored:

import { ensurePermit2Approval } from '@meshgateway/mpp-client';
import { privateKeyToAccount } from 'viem/accounts';

await ensurePermit2Approval({
  account: privateKeyToAccount(process.env.BUYER_PRIVATE_KEY),
  token: '0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168', // USDG
  chainId: 4663,
  rpcUrl: 'https://your-robinhood-rpc',
  sponsorUrl: 'https://meshgateway.com', // POST /api/gas/sponsor
});

Lower-level API

For custom flows, the building blocks are exported directly:

  • parseChallenge(response) decodes the payment-required header of a 402
  • selectPermit2Offer(challenge) picks the permit2 offer from accepts[]
  • signPermit2Payment(signer, offer) returns the payment-signature header
  • getSettlement(response) decodes the payment-response settlement proof

How a payment works

  1. GET the resource. The server answers 402 Payment Required with a base64 JSON payment-required header listing offers (token, atomic amount, recipient, spender).
  2. The client signs an EIP-712 PermitWitnessTransferFrom against the canonical Permit2 contract. The spender is pinned to the x402ExactPermit2Proxy (0x402085...20001) and the witness pins the recipient, so the signature cannot be redirected.
  3. The client retries with the signed payload in the payment-signature header. The server verifies, a relayer broadcasts settle, and the token moves straight from payer to merchant. The response carries a payment-response header with the settlement transaction hash.

Security model

  • The signature authorizes one exact transfer to one recipient with a short deadline and a random nonce. It cannot be replayed or redirected.
  • maxAmount is enforced client-side before anything is signed.
  • The client never holds keys beyond the viem account you pass in.

Scope and roadmap

  • v0 supports the permit2 transfer method only. For EIP-3009 networks (USDC on Base) use the upstream mppx client.
  • Planned: browser wallet signers, EIP-3009 support, batch payments.

Server counterpart: meshgateway/mpp-server. Hosted gateway and marketplace: MeshGateway.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages