Skip to content

feat(x402): add optional tracing hooks for payment flow observability - #372

Closed
odarome132 wants to merge 1 commit into
Vellar-Wallet:devfrom
odarome132:feat/250-add-tracing-hooks-x402-payment-flow
Closed

feat(x402): add optional tracing hooks for payment flow observability#372
odarome132 wants to merge 1 commit into
Vellar-Wallet:devfrom
odarome132:feat/250-add-tracing-hooks-x402-payment-flow

Conversation

@odarome132

Copy link
Copy Markdown

Closes #250

Summary

Adds optional span start/end hooks at each internal boundary of the x402 payment flow, giving consumers end-to-end visibility into the full lifecycle of a payment (request → decode → select → build → sign → retry → settle) without importing a specific tracing library. Hooks are zero-cost when unconfigured.

What Changed

File Change
src/x402-tracing.ts (new) X402TracingHooks (onSpanStart/onSpanEnd), X402TraceContext (traceId + optional attributes), SpanName (7 phases), tracedSpan() helper, generateTraceId()
src/x402-types.ts X402FetchInit.trace per-request context; X402Client.tracingHooks surface
src/x402-client.ts Wires tracedSpan at all 7 boundaries; threads the same trace context through the flow
src/x402-facade.ts Accepts and forwards tracingHooks to the client
src/index.ts Re-exports the tracing module
src/x402-tracing.test.ts (new) 14 tests: no-op path, success, error (ok=false + error), non-Error wrapping, duration, meta, trace propagation, full-flow capture
src/x402-client.test.ts 5 tracing-integration tests at the client level (passthrough, hooks exposed, start/end on success and on throw, trace context from init.trace)
README.md New Observability — tracing hooks section (span table + usage example)

Key Design Decisions

  • Plain callback hooks, not a vendor SDK — hooks receive SpanStartEvent/SpanEndEvent plain objects (span name, trace context, duration, error); consumers map them into OpenTelemetry, Datadog, or their own logger. No tracing dependency added.
  • Zero-cost when unconfigured — when no hooks are passed, every tracedSpan short-circuits to the raw fn(): no timing, no event allocation.
  • Trace context is a plain object threaded by reference through the flow; consumers own propagation (e.g. map traceId into OTel span context).
  • Error spans still fireonSpanEnd is always called, with ok:false plus the error, and the original error is re-thrown unchanged (non-Error throws are wrapped for the event only).

Acceptance Criteria

  • Optional span start and end hooks at each internal boundaryonSpanStart/onSpanEnd fire at all 7 boundaries (x402.request, x402.decode-requirements, x402.select-requirements, x402.build-payment, x402.sign-auth-entry, x402.paid-retry, x402.read-settlement); covered by x402-tracing.test.ts and the x402-client.test.ts tracing-integration suite.
  • Trace context propagated through the payment flow — the same X402TraceContext (per-request init.trace) is threaded through every span; covered by the propagation tests in both test files.
  • Test verifying a full trace is captured for a sample payment — the "full x402 flow trace capture" suite asserts all 7 phases start/end in order, the error path still records ends, and one context reaches all spans.
  • Documented in the observability section of the README — "Observability — tracing hooks" section with the span table, zero-cost note, and a usage example.

Test Output

 Test Files  31 passed (31)
      Tests  533 passed (533)

Focused suites: src/x402-tracing.test.ts (14 tests) and src/x402-client.test.ts (22 tests incl. 5 tracing-integration) all pass. npm run typecheck and npm run check:docs pass. Note: this repo does not configure a coverage provider or threshold (no @vitest/coverage-* installed, no coverage block in vitest.config.ts, none stated in the issue), so no coverage number is reported — adding @vitest/coverage-v8 + a threshold for the x402 modules would be a separate change.

Honest Follow-ups

  • No CI coverage threshold exists today; wiring one for the x402 modules is a sensible follow-up.
  • tracedSpan uses performance.now() (fine for browsers and Node ≥ 8.5); no shim is included for exotic runtimes.

Security Note

No new permissions, network calls, or secrets are introduced. Hooks receive only span metadata (names, durations, errors, and the consumer-supplied trace context) — never key material or the signed payment payload. When unconfigured, the feature is a strict no-op.

⚠️ Repo-policy note (please read)

This repo's .github/workflows/close-prs-outside-contrib.yml auto-closes external PRs that touch files outside contrib/. Issue #250's acceptance criteria require SDK-source changes (src/, README.md), so this PR necessarily touches files outside contrib/. Two earlier attempts at this issue (PRs #315 and #316) were auto-closed by that guard for exactly this reason — not by a maintainer. Per contrib/README.md, contributors whose assigned issue genuinely requires changes outside contrib/ are directed to say so on the issue; maintainers may need to exempt this PR or review it manually. Happy to move/scope the work however the maintainers prefer.

Add span start/end hooks at each internal boundary of the x402 payment flow,
allowing consumers to get end-to-end visibility without importing a specific
tracing library. The trace context is threaded through the flow and consumers
decide how to propagate it.

New module: x402-tracing.ts (zero-cost when unconfigured). Spans: request,
decode-requirements, select-requirements, build-payment, sign-auth-entry,
paid-retry, read-settlement. Tests cover success, error, and full-flow
capture paths. README updated with observability section.
@vercel

vercel Bot commented Aug 31, 2026

Copy link
Copy Markdown

@odarome132 is attempting to deploy a commit to the david's projects Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions

Copy link
Copy Markdown

Thanks for the contribution — but contributor PRs may only change files inside contrib/.

This PR touches file(s) outside that folder:

  • README.md
  • src/index.ts
  • src/x402-client.test.ts
  • src/x402-client.ts
  • src/x402-facade.ts
  • src/x402-tracing.test.ts
  • src/x402-tracing.ts
  • src/x402-types.ts

Please open a new PR with your changes scoped to contrib/ only, targeting dev. See CONTRIBUTING.md and contrib/README.md. If your assigned issue genuinely needs changes elsewhere, say so on the issue first — don't open a PR outside contrib/.

Questions? Ask in the Telegram group.

@github-actions github-actions Bot closed this Aug 31, 2026
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