Skip to content

[#1289] feat(sdk): add OpenTelemetry traceparent header propagation in BridgeWatch SDK queries Repo Avatar - #1385

Merged
Mosas2000 merged 1 commit into
StellaBridge:mainfrom
ToryMic:fix/1289-feat-sdk-add-opentelemetry-traceparent-header-propagation-in-bridgewatch-sdk-queries-repo-avatar
Sep 29, 2026
Merged

Mosas2000 merged 1 commit into
StellaBridge:mainfrom
ToryMic:fix/1289-feat-sdk-add-opentelemetry-traceparent-header-propagation-in-bridgewatch-sdk-queries-repo-avatar

Conversation

@ToryMic

@ToryMic ToryMic commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds W3C Trace Context propagation to the SDK's HTTP queries. Previously, requests made through the SDK carried no traceparent, so an integrating application could not correlate an SDK call with the backend's database spans.

sdk/src/tracecontext.ts

A self-contained implementation of the traceparent / tracestate formats:

  • parseTraceparent / formatTraceparent — rejects all-zero trace/span ids, malformed lengths, non-hex characters, and (per the spec) uppercase hex.
  • resolveTraceContext — with an inbound traceparent, it keeps the trace id and mints a fresh span id per request. That new span is what appears in the backend's trace and links back to the caller. Without one it starts a new root trace.
  • injectTraceHeaders — applies headers without clobbering a traceparent the caller already set, and never forwards tracestate alone (it is meaningless without its traceparent).

Wiring

BridgeWatchSdkConfig.tracing accepts the inbound traceparent/tracestate plus optional startNewTrace and sampled overrides, and fetchCompatibility injects the headers into its request. The existing X-API-Version / Accept headers are preserved. The config field is deliberately excluded from Required<> — propagation is opt-in, and a forced default would misrepresent the no-tracing case.

No backend change is needed for this to take effect end-to-end; the header is additive and ignored by anything that doesn't read it.

Testing

  • 37 new tests: 29 unit (tracecontext.test.ts) + 8 integration (tracePropagation.test.ts)
  • Integration tests assert the header reaches the outgoing request, that two requests in the same trace share a trace id but get distinct span ids, and that a malformed inbound traceparent is replaced rather than propagated.
  • All 37 pass.

Pre-existing failures (not touched here): sdk on main already has 2 type errors in src/contract.ts (result.status === "SUCCESS" where the status union has no SUCCESS, and val.bool() which does not exist on ScVal) and 4 failing tests in client.test.ts / contract.test.ts. Those counts are identical before and after this branch, so this adds no new failures. They look like genuine bugs — status === "SUCCESS" can never be true on a sendTransaction response, and val.bool() would throw at runtime — and I'm happy to fix them in a separate PR so they don't muddy this diff.

Reviewer notes

  • The issue title ends with "Repo Avatar", which looks like an artefact of how the issue was generated; I've preserved it verbatim in the branch name and PR title as required, but it's not reflected in the change.
  • Span/trace ids use crypto.getRandomValues when available with a Math.random fallback so the SDK still works on runtimes without Web Crypto.

Closes #1289

…ropagation in BridgeWatch SDK queries

HTTP requests made by the SDK carried no distributed-tracing headers, so
integrators could not correlate an SDK call with the backend's database spans.

Adds W3C Trace Context propagation to the SDK's HTTP queries.

### `sdk/src/tracecontext.ts`

A self-contained implementation of the `traceparent` / `tracestate` formats:

- `parseTraceparent` / `formatTraceparent` for the header, rejecting the
  all-zero trace/span ids, malformed lengths, non-hex characters, and (per the
  spec) uppercase hex.
- `resolveTraceContext` decides the outgoing context. With an inbound
  `traceparent` it **keeps the trace id and mints a fresh span id per request**
  — that new span is what shows up in the backend's trace and links back to the
  caller. Without one it starts a new root trace.
- `injectTraceHeaders` applies the headers to a `Headers` object without
  clobbering a `traceparent` a caller already set, and never forwards
  `tracestate` on its own since it is meaningless without its traceparent.

### Wiring

`BridgeWatchSdkConfig.tracing` takes the inbound `traceparent` / `tracestate`
(plus optional `startNewTrace` and `sampled` overrides), and
`fetchCompatibility` injects the headers into its request. The existing
`X-API-Version` / `Accept` headers are preserved. The config field is
intentionally left out of `Required<>` — propagation is opt-in, and a forced
default would misrepresent the no-tracing case.

### Tests

37 new tests: 29 unit tests over parsing, validation, id generation, and
context resolution, plus 8 integration tests asserting the header actually
reaches the outgoing request — including that two requests in the same trace
share a trace id but get distinct span ids, and that a malformed inbound
`traceparent` is replaced rather than propagated.
@drips-wave

drips-wave Bot commented Sep 29, 2026

Copy link
Copy Markdown

@ToryMic Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Mosas2000
Mosas2000 merged commit 3240ad6 into StellaBridge:main Sep 29, 2026
8 checks passed
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.

feat(sdk): add OpenTelemetry traceparent header propagation in BridgeWatch SDK queries

2 participants