Skip to content

refactor(metrics): slim ops telemetry API#2913

Open
alex-connolly wants to merge 2 commits into
mainfrom
refactor/metrics-slim-ops-telemetry
Open

refactor(metrics): slim ops telemetry API#2913
alex-connolly wants to merge 2 commits into
mainfrom
refactor/metrics-slim-ops-telemetry

Conversation

@alex-connolly

@alex-connolly alex-connolly commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Slims the TypeScript client API of @imtbl/metrics for GDPR-safer ops telemetry, while keeping the existing /v1/sdk/metrics (sdk-analytics v1) backend contract unchanged.

TypeScript interface (breaking)

Before (broad analytics-style surface):

track(module, name, properties?: Record<string, string | number | boolean>)
trackError(module, name, error, properties?)
trackFlow(module, flowName)  Flow { addEvent, addFlowProperties,  }
trackDuration(module, name, duration, properties?)
identify({ passportId | ethAddress, traits? })
setEnvironment / setPassportClientId / setPublishableApiKey
utils.localStorage 

After (ops-only):

configure({ clientId?: string })
track(module, name, options?: { durationMs?: number; error?: Error })

Call sites that used free-form property bags, flow step chains, or identity must migrate to the slim track shape (or stop tracking).

Backend interface (unchanged)

Clients still POST https://api.immutable.com/v1/sdk/metrics with a base64-encoded v1 envelope:

{
  version: 1,
  data: {
    details: { rid, sdkVersion, passportClientId? },
    events: [{ event: "module.name", time, properties?: [[k, v], ] }]
  }
}

The new client maps slim events into that shape:

Client call Wire event name Wire properties
track('passport', 'login') passport.login (none)
track(…, { durationMs }) module.name durationMs
track(…, { error }) module.trackError_name isTrackError, optional errorName / errorCode

rid is still required by the backend hash check; the client now generates an opaque per-session id locally (no init/fingerprint round-trip). New Relic / sdk-analytics consumers that key on module.name / module.trackError_* keep working.

Data we keep / gain / lose

Keep (ops signal)

  • SDK version (sdkVersion in details)
  • Method / operation name (module.name)
  • Optional duration (durationMs)
  • Redacted failure signal: error name + optional code/type (no message/stack)
  • Optional Passport clientId via configurepassportClientId on the wire
  • Session rid (opaque; not user identity)

Lose (intentionally dropped for privacy / scope)

  • Identity: identify, passport id / eth address, traits
  • Error message and stack (and chained cause stacks)
  • Free-form property bags (walletType, makerAddress, anonymousId, flow step labels, etc.)
  • Flow graph: flowId, flowName, multi-step addEvent timelines
  • Environment / publishable API key details previously set via config helpers
  • Init / device context previously collected at initialise (browser, host/frame domain, clock skew dance, fingerprints)
  • Persistent localStorage queue / polling flush; replaced by fire-and-forget microtask batches that disable for the page session after the first failed or 204 response

Gain

  • Clear, typed ops API that is hard to accidentally send PII through
  • Fail-closed transport (one bad response → stop sending) instead of a durable retry queue
  • Same backend path for old and new SDK clients without dual v1/v2 support

Methods / areas still tracked

Area Module Events (success / error via { error })
Passport / Auth passport initialise, login, loginCallback, logout, getIdToken, getAccessToken, loginWithPKCEFlow, loginWithPKCEFlowCallback, storeTokens, getLogoutUrl, logoutSilentCallback, standalone login/logout helpers, connectEvm, getUserInfo, getLinkedAddresses, linkExternalWallet
Wallet / zkEVM passport / wallet ethRequestAccounts, ethSendTransaction (+ error name eth_sendTransaction), personalSign / personal_sign, ethSignTypedDataV4 / eth_signTypedData, imSignEjectionTransaction, Magic TEE create/sign, session activity (sendSessionActivity, sessionActivityError), confirmationPopupDenied, linkExternalWallet
Audience audience transport_send (errors), transport_send_failed, transport_partial_rejected, gpc_consent_overridden
Game bridge game-bridge module Method wrappers with durationMs (init/login/token/zkEVM helpers), plus failure tracks (failedCallFunction, per-fn errors)

Methods / areas no longer tracked via @imtbl/metrics

Area What was removed
Checkout SDK e.g. checkout_sdk.buy_initiated / sell equivalents
Checkout widgets Entire commerce trackFlow / trackError wrappers (approvals, Squid execute, bridge/sale/add-tokens flows, anonymousId attachment). Host widget events are unchanged; Segment product analytics is out of scope here (see #2914)
Orderbook orderbookmr.bulkListings (+ wallet address / listing count props)
Config config.created_imtbl_config; no longer sets metrics env / publishable key
Minting backend Persistence init, submit/process/record mint, and error/uncaught tracks

Test plan

  • pnpm --filter @imtbl/metrics test && pnpm --filter @imtbl/metrics typecheck && pnpm --filter @imtbl/metrics lint
  • pnpm --filter @imtbl/audience-core test
  • Spot-check Passport login still posts passport.login (failures as passport.trackError_login) to /v1/sdk/metrics in the v1 envelope
  • Confirm removed packages no longer import @imtbl/metrics (trackError / trackFlow / identify / configure({ env }))
  • CI pnpm install --frozen-lockfile succeeds

Replace the GDPR-heavy metrics client with configure + track only,
map to the existing sdk-analytics v1 wire format, and remove metrics
from checkout, orderbook, config, and minting-backend.

Co-authored-by: Cursor <cursoragent@cursor.com>
@alex-connolly
alex-connolly requested review from a team and shineli1984 as code owners July 25, 2026 11:12
Regenerate the lockfile so frozen CI installs match package.json
after dropping @imtbl/metrics from config, checkout, orderbook, and
minting-backend.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

Copy link
Copy Markdown

✅ Audience Bundle Size — @imtbl/audience

Metric Size Delta vs main (f8ac366)
Gzipped 17810 bytes (17.39 KB) -3873 bytes
Raw (minified) 53837 bytes -9360 bytes

Budget: 24.00 KB gzipped (warn at 20.00 KB)

@github-actions

Copy link
Copy Markdown

✅ Pixel Bundle Size — @imtbl/pixel

Metric Size Delta vs main
Gzipped 6965 bytes (6.80 KB) -100 bytes
Raw (minified) 18701 bytes -371 bytes

Budget: 10.00 KB gzipped (warn at 8.00 KB)

@nx-cloud

nx-cloud Bot commented Jul 25, 2026

Copy link
Copy Markdown

View your CI Pipeline Execution ↗ for commit cf53571

Command Status Duration Result
nx affected -t build,lint,test ✅ Succeeded 2m 36s View ↗
nx run-many -p @imtbl/sdk,@imtbl/checkout-widge... ✅ Succeeded 1m 3s View ↗

💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗


☁️ Nx Cloud last updated this comment at 2026-07-25 20:40:30 UTC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant