Skip to content

chore: version packages#265

Merged
brendanjryan merged 1 commit intomainfrom
changeset-release/main
Mar 31, 2026
Merged

chore: version packages#265
brendanjryan merged 1 commit intomainfrom
changeset-release/main

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

mppx@0.5.0

Minor Changes

  • 5e7750b: Added a proof credential type for zero-amount Tempo charge requests. Clients now sign an EIP-712 proof over the challenge ID instead of creating a broadcastable transaction, and servers verify the proof against the credential source DID before accepting the request. This prevents zero-dollar auth flows from burning gas when the payer would otherwise have been the fee payer.

@brendanjryan brendanjryan merged commit 6f2682a into main Mar 31, 2026
2 checks passed
@brendanjryan brendanjryan deleted the changeset-release/main branch March 31, 2026 04:00
brendanjryan added a commit that referenced this pull request Apr 10, 2026
* feat: add OpenAPI-first discovery tooling (#235)

* feat: add openapi-first discovery tooling

* test: use inline snapshots as golden output for OpenApi.generate

* feat: accept custom intents and forward extra params in x-payment-info

* refactor: remove back-compat shims and make schemas extension-permissive

- Remove /discover* → 410 Gone shim from proxy (dead paths now 404)
- Remove dead serialize(), toServicesMarkdown(), toMarkdown(), pushRoutes()
- Use z.looseObject() throughout Discovery schemas so x-* extensions and
  extra OpenAPI fields (parameters, tags, operationId, etc.) pass through

* perf: generate discovery documents once at startup, serve cached JSON

Proxy pre-generates openapi.json and llms.txt at create() time.
Framework helpers (Express, Hono, Next.js) cache after first request
via lazy init (preserves dynamic import for code-splitting).
Switched docs.llms to relative path so the document is fully static.

* refactor: cleanup pass — passthrough payments, collapse docsLlmsUrl, static imports, typed handlers, elysia discovery

1. Proxy buildDiscoveryRoutes() passes through full paymentOf() output
   instead of hand-picking fields (preserves unitType, recipient, etc.)
2. Collapsed docsLlmsUrl callback to docs.llms string — removed
   resolveLlmsUrl/resolveLlmsLink dead code, kept input compat
3. Replaced dynamic await import() with static imports in Express/Hono/
   Next.js helpers; Express + Next.js precompute at registration time
4. Exported DiscoverableHandler type, updated Wrap to expose _internal
   metadata — removed as any casts from tests
5. Added Elysia discovery() helper for framework parity

* fix: allow relative doc URIs and model path items with explicit HTTP method keys

1. docs.llms (and all ServiceDocs links) now accept relative paths
   like /llms.txt — fixes validator rejecting proxy-generated docs
2. Paths modeled as PathItem with explicit get/post/put/etc keys
   instead of record<string, operation> — path-item-level fields
   like summary, parameters, x-extensions no longer cause errors
3. Validator iterates only HTTP method keys, skipping path-item fields

* refactor: simplify validator to skip non-object path-item entries

* style: fix oxfmt formatting

* fix: align Wrap _internal type with DiscoveryHandler for exactOptionalPropertyTypes

* fix: exit code 1 for missing file in discover validate

The IIFE pattern swallowed c.error() exit codes because the
return value was checked as typeof !== 'string' instead of
propagating the error. Refactored to flat if/else.

* fix: use global test imports instead of vitest

* feat(cli): add `mppx discover generate` command

* test(cli): add discover generate tests

* style: format cli files

* fix: remove vitest import from Discovery.test.ts

* fix: review feedback — paymentOf null, basePath boundary, validate guardrails, hono auto docs

- paymentOf() returns null instead of {} for paid endpoints missing _internal
- basePath matching uses boundary-aware check to prevent /proxy vs /proxy2 collision
- discover validate adds 30s timeout and 10MB size limit for remote fetches
- Hono auto discovery documented as best-effort/experimental
- tests for all changes

* style: fix formatting in cli.test.ts and Route.test.ts

* chore: changeset tweaks

* chore: version packages (#237)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* chore: format

* Merge commit from fork

* fix: reject close voucher equal to on-chain settled amount

* chore: version 0.4.11

* Revert "chore: version 0.4.11"

This reverts commit 8465ddeecc738aeef689b2d772096647c39ec0aa.

* Merge commit from fork

* chore: bump version

* chore: lint

* chore: viem version

* chore: up

* ci: speed up workflows with caching and dedup (#250)

- Deduplicate Prerelease runs: was triggering on both push and
  pull_request, causing 2 runs per PR push. Now only runs once.
- Cache pnpm store via setup-node cache option (~5-10s saved)
- Cache Playwright Chromium browser (~25s saved on cache hit)
- Cache Tempo Docker image via docker save/load (~10s saved on cache hit)

* ci: shard test suite across 3 parallel runners (#251)

Use Vitest's --shard flag with a GitHub Actions matrix to split the
~67 test files across 3 runners. Vitest automatically balances file
distribution — no manual maintenance needed.

This should reduce the Test Runtime wall clock from ~2.5 min to ~50s
at the cost of 3x compute (3 parallel runners).

* ci: add Cyclops PR audit workflow (#238)

* ci: add Cyclops PR audit workflow

* chore: replace pr-audit workflow with reth-style inline curl

* fix: log HTTP status code on pr-audit failure for debugging (#253)

* ci: add 10s test timeout to prevent hanging CI runs (#254)

* fix: return 410 ChannelClosed for zero-deposit settled channels (#243)

* fix: return 410 ChannelClosed for zero-deposit settled channels

During settlement the escrow contract may zero the deposit before
setting the finalized flag. This creates a window where finalized=false
but deposit=0. Without this guard, vouchers against such channels
return 402 AmountExceedsDepositError instead of 410 ChannelClosedError.

The 410 response tells clients to clear their local channel state and
open a fresh channel on the next request, which is the correct recovery
path.

* refactor: use zeroAddress from viem, add zero-deposit race window test

* changeset: zero-deposit channel closed guard

---------

Co-authored-by: Brendan Ryan <brendan@brendanjryan.com>

* ci: remove test sharding (shard 1/3 hangs consistently) (#255)

* feat: auto-detect realm from request Host header (#249)

* feat: auto-detect realm from request Host header

3-tier realm resolution: explicit > env var > request hostname.
Removes hardcoded 'MPP Payment' fallback. When no realm is configured,
derives it from the incoming request's URL hostname at charge-time.
Throws if realm cannot be determined (no URL or non-HTTP URL).

This enables Cloudflare Workers (and any runtime) to automatically
use the correct domain as the realm without explicit configuration.

Also fixes env var precedence: MPP_REALM is now checked first.
Removes HOST/HOSTNAME from realm detection (unsafe in containers).
Warns once at Mppx.create() time when realm is not explicitly set.

* fix: only warn when realm auto-detection fails, not at create time

* ci: disable ryuk on github actions

* changeset: realm auto-detection

* changeset: patch, fix wording per review

* ci: remove test sharding (shard 1/3 hangs consistently)

* Revert "ci: remove test sharding (shard 1/3 hangs consistently)"

This reverts commit e9062bc.

* fix: reject unknown properties on session() and charge() at compile time (#203)

* fix: reject unknown properties on session() and charge() at compile time

Add NoExtraKeys utility type and apply it via overload signatures to
tempo.session() and tempo.charge(). This catches typos like
`stream: { poll: true }` instead of `sse: { poll: true }` that
previously slipped through because generic `extends` constraints
bypass excess property checking.

Fixes the class of bug from PR #159.

* fix: remove overloads in favor of inline NoExtraKeys, update changeset wording

---------

Co-authored-by: Brendan Ryan <1572504+brendanjryan@users.noreply.github.com>

* fix: override path-to-regexp and tar to resolve audit vulnerabilities (#257)

* fix(session): separate sender from fee payer in settle and close (#247)

* fix(session): separate sender from fee payer in settle and close

The escrow contract requires msg.sender == payee for settle() and
close(). The sendFeePayerTx helper used the fee payer as both sender
and gas sponsor, causing every fee-sponsored settlement/close to
revert with NotPayee().

Fix sendFeePayerTx to accept a separate account (logical sender)
and feePayer (gas sponsor). Update settleOnChain and closeOnChain
to resolve and pass the correct account. Add account option to
the top-level tempo.settle() API.

Also fix feeToken resolution to use resolveCurrency() which falls
back to pathUsd for unknown chain IDs (e.g. localnet).

* fix: address review - test.todo, runtime guard for feePayer without account

* test: add 70% coverage threshold ratchet (#227)

Co-authored-by: Brendan Ryan <1572504+brendanjryan@users.noreply.github.com>

* refactor: move pnpm overrides from package.json to pnpm-workspace.yaml (#258)

* feat(tempo): add split payments for charge (#231)

* feat(tempo): add split payments for charge

* fix: align split payment verification with spec

- order-insensitive matching for both calldata and logs
- hash path uses log-only verification (spec conformance)
- bind validBefore to min(now+25s, challenge.expires)
- add expectedRecipients allowlist for client-side split validation
- allow transferWithMemo on memo-less split entries
- enforce exact call count only for fee-payer transactions
- sort by specificity (memo-required first) to prevent greedy matching
- try/catch in decodeTransferCall for malformed calldata resilience
- remove dead assertTransferLog and unused imports

* fix: resolve tsgo type errors for Call and Address types

* fix: coerce isFeePayerTx to boolean for tsgo

* fix: use pull mode for split payment tests (sendCallsSync doesn't batch on localnet)

* style: apply formatter

* fix(tempo): align charge flow with split payment spec

* chore(tempo): keep split payment PR narrowly scoped

* fix: add memo and splits to challenge scope binding

Prevents cross-route credential replay where a credential issued for a
no-splits (or no-memo) route is accepted on a route that requires splits
or a specific memo. The methodDetails fields memo and splits now participate
in the scope comparison alongside amount, currency, and recipient.

* fix: address review - patch changeset, use Address type for split recipients

* chore: version packages (#256)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix: format CHANGELOG.md (#261)

* fix: format CHANGELOG.md

* fix: auto-format after changeset version

* Increase coverage on session flows and edge cases (#230)

* Add multi-top-up and repeated exhaustion session coverage tests

* test(session): add guard, sse, fee-payer, and race coverage

* test(session): fold coverage cases into session tests

* test: align session coverage with current session APIs

* fix: defense in depth -- fail-closed expiry enforcement in credential verification (#262)

* fix: fail-closed expiry enforcement in credential verification

Previously, credentials with no expires field were silently accepted
because the check used `if (expires && ...)` which skips when
expires is undefined.

Now the handler rejects credentials missing expires with an
InvalidChallengeError before checking the timestamp. Method-specific
verify functions (Stripe, Tempo) also enforce fail-closed.

Adds test for missing-expires rejection.

MPP-F4

* test: add malformed expires guard and test

- Reject credentials with unparseable expires (NaN date) as InvalidChallengeError
- Guards added to core handler, Stripe verify, and Tempo verify
- Test: 'returns 402 when credential challenge has malformed expires'

* style: fix formatter nit in Stripe Charge.ts

* refactor: unify expiry checks into Expires.assert helper

* fix: align Expires.assert types with InvalidChallengeError.Options

* test: widen fee-payer server coverage (#252)

* feat: add proof credential type for zero-dollar auth (#263)

Adds a new 'proof' credential payload type that uses EIP-191 signed
messages instead of real transactions for zero-amount identity flows.

This prevents a grief attack where a server could broadcast a $0
transaction on-chain, burning ~0.001 USD in gas fees from the user.

Changes:
- Methods.ts: add 'proof' to charge credential discriminated union
- client/Charge.ts: when amount=0, sign a domain-separated message
  (mpp:proof:<challengeId>) instead of building a transaction
- server/Charge.ts: verify proof via recoverMessageAddress, reject
  hash/transaction payloads for zero-amount challenges, validate
  full DID source including chain ID

* test: zero-dollar auth regression tests for CLI and SDK (#264)

* test: repro zero-amount charge behavior on main

* test: validate zero-dollar auth against live servers

* fix: format nextjs zero-dollar auth tests

* chore: add missing changeset for zero-dollar proof auth

* chore: version packages (#265)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix: add configurable zero-dollar proof replay protection (#268)

* fix: add configurable zero-dollar proof replay protection

* docs: move zero-dollar replay docs to mpp site

* test: cover proof replay store boundaries

* fix: validate proof source DID chain id (#267)

* fix: validate proof source DID chain id

* fix: simplify proof source validation

* docs: use changeset for proof source validation

* docs: format proof source changeset

* ci: allow manual runs for pr-audit workflow (#270)

* chore: version packages (#269)

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* fix(cli): fail fast on hanging keychain commands (#272)

* fix(cli): fail fast on hanging keychain commands

* test: harden runtime server teardown

* style: format teardown hardening changes

* ci: resolve pr-audit manual sha from pull request (#271)

* ci: cap test runtime job at 10 minutes (#273)

---------

Co-authored-by: tmm <tmm@tmm.dev>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: grandizzy <38490174+grandizzy@users.noreply.github.com>
Co-authored-by: Brendan Ryan <1572504+brendanjryan@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant