- 2a0b88e: Fixed cooperative close to sign the server-reported spent amount instead of the high-water mark (
cumulativeAmount), preventing overcharging when actual usage was below the pre-authorized voucher amount.
- 281005c: Added support for
feePayeras a URL string ontempomethod.
- bbd4b3f: Updated Moderato (testnet) escrow contract address to
0xe1c4d3dce17bc111181ddf716f75bae49e61a336.
- b09a35a: fix: update getChannel ABI field order to match new escrow contract
- c520705: Fixed
Client.getResolverto inject Tempo serializers onto clients missing them, preventing the default serializer from rejecting Tempo-specific transaction fields. - b09a35a: chore: update mainnet escrow contract address
- 7f8d103: chore: update mainnet escrow contract address
- c089da5: Added CLI config via
mppx.config.(js|mjs|ts). Allows for extendingmppxCLI to support non-built-in methods.
- f2bc051: Support keychain V2 (
0x04) signatures via ox 0.14 upgrade
-
143ebc9: Support handler function refs in
compose().[mppx.tempo.charge, { amount: '1' }]syntax —compose()now accepts handler function references (e.g.mppx.tempo.charge) as the first element of entry tuples, in addition toMethod.AnyServerobjects and"name/intent"string keys._methodmetadata on nested handlers — nested handler functions are tagged with their sourceMethod.AnyServer, enablingcompose()to resolve the correct handler.
-
db2033c: Set
feeTokenduring server co-sign and simulation for fee-payer transactions.When the client sends a fee-payer (0x78) envelope,
feeTokenis intentionally omitted. The server must set it at co-sign time, but previously never did — causing "Fee token spending limit exceeded" errors. Now resolvesfeeTokenfrom the deserialized transaction or falls back to the chain's default currency.
- 79bbfc6: Added multi-challenge
mppx.challenge()combinator for presenting multiple payment methods in a single 402 response, nested accessors (mppx.tempo.charge(...)),Mppx.challenge()static,Challenge.fromResponseList(), and automatic client preference-based challenge selection. - b4f3c92: Migrated to use
callinstead of manualeth_estimateGas.
- cd42c28: Added
rawFetchproperty to the clientMppxinstance, exposing the original unwrapped fetch function for requests that should bypass 402 payment interception. - 230ef16: Moved CLI payment logs (Payment Required, Payment Receipt, channel open/close) behind
-vflag. Added-vvfor full HTTP headers.
- 345425f: Removed
expiresfrom charge request schemas (tempo, stripe). Expiry is now conveyed exclusively via theexpiresauth-param on the Challenge, not duplicated in the request body. Server handlers default toExpires.minutes(5)whenexpiresis not explicitly provided. - eb19f32: Added
modeparameter totempo.charge()client —'push'(client broadcasts tx, sends hash) and'pull'(client signs tx, server broadcasts). Defaults to'push'for JSON-RPC accounts,'pull'otherwise.
- 82206f5: Made
constantTimeEqualisomorphic by replacingnode:cryptowithoxsha256 and a custom constant-time comparison.
- c28944e: Added
autoSwapflag totempomethod. When enabled, the client automatically swaps from supported currencies via the DEX if the payer lacks the target token. - 9c23cb7: Fixed fetch polyfill to pass
initthrough unmodified for non-402 responses. Previously, every request eagerly destructuredinitto strip thecontextproperty, creating a new object that could break libraries relying on object identity (e.g. WebSocket upgrade handshakes).
- fd466c3: Added
waitForConfirmationoption tosession()andcharge()payment methods. Whenfalse, transactions are simulated viaeth_estimateGasand broadcast without waiting for on-chain confirmation, reducing latency. - ddb7057: Fixed
Handlerstype to omit shorthand intent keys when multiple methods share the same intent, matching runtime behavior and preventingTypeErroron collision.
- 558279e: Added
closeRequestedAtcheck in session voucher handler with configurablechannelStateTtl(default: 60s). Prevented payers from using a channel after initiating a forced close. - 558279e: Added expiration check on credentials in the core handler. Expired credentials are now rejected with
PaymentExpiredErrorinstead of being processed. - 558279e: Added token address validation in
broadcastTopUpTransactionfee-payer logic. Prevented approve calls to arbitrary contracts in fee-sponsored topUp transactions. - 558279e: Bound credential verification to the route's configured request. Prevented cross-route scope confusion where a credential issued for one route could be presented at another.
- 558279e: Removed insecure hardcoded
'tmp'fallback forsecretKey.Mppx.create()now throws a clear error if neitherMPP_SECRET_KEYenv var nor explicitsecretKeyis provided. - 5d4bb93: Removed
realmfromPaymentRequiredErrordetail message to avoid leaking deployment URLs and hostnames in error responses.
- a016e1f: Added fee payer support to
settleOnChainandcloseOnChainfor server-originated transactions on chains where the server EOA has no native tokens. Transactions are built usingprepareTransactionRequest→ dual-sign →sendRawTransactionSyncwith an explicitly resolved fee token.
- 7cb0d5f: Fixed CLI failing with "No account found" when
MPPX_PRIVATE_KEYis set to an empty string.
- e4f0138: Added
nonceKey: 'expiring'to tempo charge transactions to avoid nonce collisions on parallel requests.
- d2fb5e3: Fixed issue where mainnet would not default to USDC unless
testnet: falsewas explicitly passed.
-
6e2be11: Replaced
--channel <id>and--deposit <amount>CLI flags with-M/--method-optfor passing method-specific options.# Before - mppx example.com/content --channel 0x123 --deposit 1000000 # After + mppx example.com/content -M channel=0x123 -M deposit=1000000
-
6e2be11: Added Stripe payment method support to the CLI.
# Set your Stripe test-mode secret key export MPPX_STRIPE_SECRET_KEY=sk_test_... # Make a request to a Stripe-enabled endpoint mppx https://example.com/content
-
955deb2: Renamed USDC.e to USDC in account view token list.
- 9cf4943: Added USDC.e to account view mainnet token list and use
MPPX_RPC_URLfor default mainnet balance fetching. - 11c0422: Renamed internal
streamterminology tosessionto align with the MPP spec. This includes renaming thesrc/tempo/stream/directory tosrc/tempo/session/, updating all problem type URIs from…/problems/stream/…to…/problems/session/…, and renaming associated types (e.g.,StreamCredentialPayload→SessionCredentialPayload). No public API changes.
-
04b04c9: Added auto-detection of
realmandsecretKeyfrom environment variables inMppx.create().- Realm: checks
MPP_REALM,FLY_APP_NAME,HEROKU_APP_NAME,HOST,HOSTNAME,RAILWAY_PUBLIC_DOMAIN,RENDER_EXTERNAL_HOSTNAME,VERCEL_URL,WEBSITE_HOSTNAME - Secret key: checks
MPP_SECRET_KEY
- Realm: checks
- b927c06: -
mppx/proxy: Modified routes to show service in path for completeness (e.g.POST /openai/v1/chat/completionsinstead ofPOST /v1/chat/completions).
- e6c9f85: Fixed
/discover.mdroute returning 404.
- d60f623: -
mpp/proxy(Breaking): Renamed/services*discovery routes to/discover*.mpp/proxy: Simplifiedllms.txtto a brief service overview, linking each service to/discover/<id>.mpp/proxy: Added/discoverand/discover/<id>endpoints with content negotiation (JSON by default, markdown forAccept: text/markdown/text/plainor bot/CLI user agents).mpp/proxy: Added.mdextension variants (/discover.md,/discover/<id>.md) for explicit markdown.mpp/proxy: Added/discover/allfor full markdown listing with route details.
-
83c3bab: - Added
titleanddescriptionoptions toProxy.createconfig, used to populate thellms.txtheading and description.const proxy = Proxy.create({ title: 'My AI Gateway', description: 'A paid proxy for LLM and AI services.', services: [...] })
- Added
title,description, anddocsLlmsUrlproperties toServicetype andService.fromconfig.
Service.from('my-api', { baseUrl: 'https://api.example.com', title: 'My API', description: 'A custom API service.', docsLlmsUrl: 'https://example.com/llms.txt', routes: { ... }, }) // or with per-endpoint docs Service.from('my-api', { baseUrl: 'https://api.example.com', docsLlmsUrl: (endpoint) => endpoint ? `https://example.com/api/${encodeURIComponent(endpoint)}.md` : 'https://example.com/llms.txt', routes: { ... }, })
- Added
- 01fa8ba: Added fallback
authorizedSignertoaccount.accessKeyAddresswhen not explicitly provided.
- 83d0175: Bumped
viempeer dependency to>=2.46.2.
- c0aa6ad: Fixed Stripe
createWithClientto useshared_payment_granted_tokeninstead ofpayment_methodwhen creating a PaymentIntent with an SPT. This aligns the SDK client path with the raw fetch path and fixes 402 errors on credential retry. - e7f5985: Rejected keychain and non-secp256k1 signatures in
verifyVoucher.
- 360fc03: Added
Json.canonicalizefromox
- eb72c76: Breaking:
- Renamed
Challenge.fromIntenttoChallenge.fromMethod. - Renamed
PaymentRequest.fromIntenttoPaymentRequest.fromMethod.
- Renamed
-
627f5ec: Breaking:
- Renamed
IntentandMethodIntentmodules toMethod. - Removed
Intentexport frommppx. UseMethodinstead. - Removed
MethodIntentexport frommppx. UseMethodinstead. - Renamed
MethodIntentsexport toMethodsinmppx/tempoandmppx/stripe.
- Renamed
- 910102d: Fixed SSE streaming reliability: pass
signalthroughSessionManager.sse()so HTTP connections close on abort, snapshot challenge at SSE open time to prevent concurrent requests from corrupting voucher credentials, and forwardrequest.signaltoSse.serve()sochargeOrWaitbreaks on disconnect.
- badab1a: Initial release.