chore(examples): simplify server examples#26
Merged
brendanjryan merged 1 commit intomainfrom Feb 9, 2026
Merged
Conversation
commit: |
53ea95b to
dc82854
Compare
- Move imports and client creation to the top - Pass `getClient` to reuse the same viem client instance - Remove the separate "Internal" section in basic example
dc82854 to
dee6536
Compare
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
getClientto reuse the same viem client instance