Skip to content

feat(telemetry): add anonymous usage tracking across W3C and OpenAttestation flows#136

Closed
ffeew-dex wants to merge 5 commits into
mainfrom
feat/add-telemetry-data-collection
Closed

feat(telemetry): add anonymous usage tracking across W3C and OpenAttestation flows#136
ffeew-dex wants to merge 5 commits into
mainfrom
feat/add-telemetry-data-collection

Conversation

@ffeew-dex

@ffeew-dex ffeew-dex commented Apr 13, 2026

Copy link
Copy Markdown

Summary

Add anonymous SDK telemetry for TrustVC issuance and verification flows so the team can understand which document formats, DID methods, and cryptographic suites are being used in practice. This PR also documents the telemetry behavior and opt-out controls.

Changes

  • add a new telemetry utility that emits non-blocking anonymous events with action type, document format, SDK version, DID method, cryptosuite, and a persistent hashed instance identifier
  • expose telemetry controls through the public API with disableTelemetry(), enableTelemetry(), emitTelemetry(), and extractDidMethod(), plus environment-based opt-out via TRUSTVC_TELEMETRY_DISABLED
  • emit telemetry from W3C sign, verify, and derive flows and OpenAttestation sign and verify flows, including the follow-up fix to extract the correct DID method / identity proof type
  • document telemetry collection and opt-out behavior in the README, and disable telemetry by default in the general Vitest environment while keeping dedicated telemetry coverage enabled
  • add focused telemetry tests for the core utility, W3C flows, and OpenAttestation flows; targeted verification passed with npx vitest --run src/utils/telemetry/telemetry.test.ts src/__tests__/w3c/telemetry.test.ts src/__tests__/open-attestation/telemetry.test.ts (31 tests)

Issues

N/A

Summary by CodeRabbit

  • New Features

    • Anonymous telemetry: collects operation, document format, DID method, cryptosuite, SDK version, and a privacy-preserving instance ID; emitted from sign/derive/verify flows (W3C and OpenAttestation).
    • Runtime and env controls to enable/disable telemetry exposed by the SDK.
  • Documentation

    • Added detailed repository guidance and a README Telemetry section describing data, storage, and opt-out instructions.
  • Tests

    • Added comprehensive telemetry tests for extraction, persistence, enable/disable behavior, and network emission.

- Capture anonymous issuance and verification events for credential and
  document flows so SDK usage can be measured without collecting PII
- Persist a hashed random instance identifier and add opt-out controls
  for users who want telemetry disabled
- Document the behavior, export the telemetry helpers, and disable
  telemetry during tests to keep runs deterministic
- Derive OpenAttestation telemetry from issuer identity proof so
  V2 and V3 documents report the expected DID method consistently
- Derive W3C telemetry from the credential issuer instead of proof
  or key data so signing and verification emit the same method
- Add coverage for issuance and verification telemetry across OA
  and W3C document variants
@coderabbitai

coderabbitai Bot commented Apr 13, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds an opt-in anonymous telemetry subsystem, with env and runtime opt-out, persistent per-install instance ID, non‑blocking timed POSTs to a configurable endpoint, type definitions and tests; integrates telemetry emissions into W3C and OpenAttestation sign/verify/derive flows and documents the feature.

Changes

Cohort / File(s) Summary
Documentation
CLAUDE.md, README.md
Add CLAUDE.md; README: new "Telemetry" section documenting collected fields, storage locations, and opt-out via TRUSTVC_TELEMETRY_DISABLED and programmatic disableTelemetry()/enableTelemetry().
Telemetry Core
src/utils/telemetry/telemetry.ts, src/utils/telemetry/index.ts, src/utils/telemetry/types.ts
New telemetry subsystem: enable/disable APIs, emitTelemetry, extractDidMethod, typed payloads, persistent 64‑hex instance ID (Node fs or browser localStorage), env gating, configurable endpoint, 5s request timeout, error swallowing, and a testing reset hook.
W3C Integration
src/w3c/sign.ts, src/w3c/verify.ts, src/w3c/derive.ts, src/w3c/telemetry.ts
Sign/verify/derive now await results, call emitW3CTelemetry (computes cryptosuite and did_method) before returning; add W3C telemetry helpers including getProofCryptosuite and emitW3CTelemetry.
OpenAttestation Integration
src/open-attestation/sign.ts, src/open-attestation/verify.ts, src/open-attestation/telemetry.ts
Sign/verify now emit OA telemetry after operations; new OA telemetry helper extracts identityProof and cryptosuite and forwards to core emitTelemetry.
Exports / Barrel
src/utils/index.ts, src/utils/telemetry/index.ts
Re-export telemetry from utils barrel to expose emitTelemetry, disableTelemetry, enableTelemetry, and types.
Tests & Test Helpers
src/utils/telemetry/telemetry.test.ts, src/__tests__/w3c/telemetry.test.ts, src/__tests__/open-attestation/telemetry.test.ts, src/__tests__/utils/telemetry.ts, src/__tests__/fixtures/keys.ts, other test updates...`
Comprehensive telemetry tests and a test harness: did extraction, enable/disable precedence (env vs runtime), instance ID stability, SDK_VERSION format, emission behavior and resilience to fetch absence/failures; added test fixtures for BBS keys and updated related tests.
Config
tsconfig.json, vitest.config.ts
Add node types to tsconfig; vitest config now injects TRUSTVC_TELEMETRY_DISABLED='1' into test.env.
Minor
src/open-attestation/sign.ts, src/open-attestation/verify.ts, src/w3c/*
Sign/verify/derive functions changed to await results and emit telemetry before returning (no signature changes).

Sequence Diagram

sequenceDiagram
    participant App as Application
    participant Func as Sign/Verify/Derive
    participant Tel as Telemetry Module
    participant Persist as Persist (fs / localStorage)
    participant Remote as Telemetry Endpoint

    App->>Func: invoke signW3C / signOA / verify / derive
    Func->>Func: perform core operation
    Func->>Tel: compute did_method & cryptosuite
    Tel-->>Func: did_method
    Func->>Tel: emitTelemetry({action_type, document_format, did_method, cryptosuite})
    Tel->>Tel: isTelemetryEnabled()?
    alt enabled
        Tel->>Persist: getInstanceId()
        Persist-->>Tel: instance_id
        Tel->>Remote: POST /api/v1/telemetry (JSON, timeout 5s)
        Remote-->>Tel: response / error
        Tel-->>Tel: swallow errors
    else disabled
        Tel-->>Tel: skip emission
    end
    Func-->>App: return original result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • rongquan1
  • RishabhS7
  • Moiz47

Poem

🐰
I hopped through modules, light and spry,
Counting DIDs beneath the sky,
A hashed little id I tuck away,
Quiet pings that vanish at play,
Metrics whispered, then I hop away.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding anonymous usage tracking/telemetry across both W3C and OpenAttestation document signing and verification flows.
Description check ✅ Passed The description follows the required template with clear Summary, Changes, and Issues sections. It comprehensively details the telemetry implementation, public API exports, affected flows, documentation updates, and test coverage.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/add-telemetry-data-collection

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (7)
CLAUDE.md (1)

59-59: Consider documenting telemetry behavior and opt-out controls.

Line 59 mentions "analytics" under the utils module, which refers to the telemetry feature added in this PR. Since this file guides Claude Code on working with the repository, it would be helpful to document:

  • What telemetry tracks (anonymous usage metrics)
  • How to disable it (TRUSTVC_TELEMETRY_DISABLED=1 environment variable or disableTelemetry() API)
  • That it's documented in the README

This would help developers quickly understand telemetry behavior when working with the codebase.

📝 Suggested addition

Consider adding a "Telemetry" section after the "Testing" section:

 ## Code Style
+
+## Telemetry
+
+The SDK includes optional anonymous usage tracking that emits non-blocking events for issuance and verification operations. Telemetry can be disabled via:
+- Environment variable: `TRUSTVC_TELEMETRY_DISABLED=1`
+- Programmatic API: `disableTelemetry()` / `enableTelemetry()`
+
+See README for full details on telemetry behavior and opt-out.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CLAUDE.md` at line 59, Add a short "Telemetry" note to the docs near the
utils/ analytics entry describing that telemetry collects anonymous usage
metrics, how to opt out via the TRUSTVC_TELEMETRY_DISABLED=1 environment
variable or by calling the disableTelemetry() API, and point readers to the
README for full details; mention that telemetry is anonymous and configurable
and reference the utils/ analytics module and the disableTelemetry() function so
developers can find the implementation.
vitest.config.ts (1)

28-28: Drop the as any cast on test env object.

Line 28 masks type issues and is flagged by static analysis as unnecessary. Prefer a typed object (or a narrow cast like Record<string, string | undefined>) instead of any.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@vitest.config.ts` at line 28, The env object in vitest config uses an
unnecessary `as any` cast; replace it with a properly typed object such as
Record<string, string | undefined>. For example, construct a typed variable
(e.g., `const testEnv: Record<string, string | undefined> = { ...process.env,
TRUSTVC_TELEMETRY_DISABLED: '1' }`) and use `env: testEnv`, or cast process.env
narrowly (`...(process.env as Record<string,string|undefined>)`) and remove the
`as any` to satisfy static analysis while preserving the
TRUSTVC_TELEMETRY_DISABLED entry.
README.md (1)

1191-1195: Add language specifier to fenced code block.

The .env example code block is missing a language specifier, which triggers a markdownlint warning.

📝 Suggested fix
 Or in a `.env` file:
 
-```
+```env
 TRUSTVC_TELEMETRY_DISABLED=1
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @README.md around lines 1191 - 1195, The fenced code block showing the .env
example (the block containing TRUSTVC_TELEMETRY_DISABLED=1) lacks a language
specifier and triggers markdownlint; update that fenced block to include the env
language specifier (use ```env) so the block becomes a proper env-highlighted
code fence in README.md.


</details>

</blockquote></details>
<details>
<summary>src/utils/telemetry/telemetry.ts (3)</summary><blockquote>

`92-96`: **Consider using optional chaining for cleaner code.**

SonarCloud suggests using optional chaining for the nested property check.


<details>
<summary>📝 Suggested fix</summary>

```diff
 function isNodeEnvironment(): boolean {
   return (
-    typeof process !== 'undefined' && process.versions != null && process.versions.node != null
+    typeof process !== 'undefined' && process.versions?.node != null
   );
 }
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against the current code and only fix it if needed.

In `@src/utils/telemetry/telemetry.ts` around lines 92 - 96, The isNodeEnvironment
function uses explicit nested null checks for process.versions.node; replace the
nested check with optional chaining to simplify the expression while keeping the
typeof process !== 'undefined' guard: update the return expression in
isNodeEnvironment to use process?.versions?.node != null so the logic is
identical but cleaner and less error-prone.
```

</details>

---

`98-100`: **Consider using `globalThis.window` for consistency.**

SonarCloud suggests preferring `globalThis.window` over `window` for consistency with other global references in this file (e.g., `globalThis.crypto`, `globalThis.fetch`).


<details>
<summary>📝 Suggested fix</summary>

```diff
 function isBrowserEnvironment(): boolean {
-  return typeof window !== 'undefined' && typeof localStorage !== 'undefined';
+  return typeof globalThis.window !== 'undefined' && typeof localStorage !== 'undefined';
 }
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against the current code and only fix it if needed.

In `@src/utils/telemetry/telemetry.ts` around lines 98 - 100, The
isBrowserEnvironment function currently uses raw globals; update it to check
globalThis for consistency with other checks (e.g., globalThis.crypto,
globalThis.fetch) by replacing references to window and localStorage with
globalThis.window and globalThis.localStorage so the function uses typeof
globalThis.window !== 'undefined' && typeof globalThis.localStorage !==
'undefined' (refer to the isBrowserEnvironment function to locate the change).
```

</details>

---

`157-162`: **Consider using `export ... from` syntax for re-exports.**

SonarCloud suggests using the `export ... from` syntax for cleaner re-exports. However, since `isTelemetryEnabled` and `getInstanceId` are defined as regular functions (not exported inline), this would require restructuring. The current approach is functional.

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against the current code and only fix it if needed.

In `@src/utils/telemetry/telemetry.ts` around lines 157 - 162, Change the module
to use inline exports instead of a trailing re-export: mark the functions
isTelemetryEnabled and getInstanceId with the export keyword at their
declarations and export SDK_VERSION where it is defined, then remove the final
"export { isTelemetryEnabled, getInstanceId, SDK_VERSION };" line; keep
_resetForTesting and the internal symbols (_telemetryOverride, _instanceId)
unchanged so tests still call _resetForTesting().
```

</details>

</blockquote></details>
<details>
<summary>src/utils/telemetry/telemetry.test.ts (1)</summary><blockquote>

`1-2`: **Consolidate imports from the same module.**

SonarCloud correctly flags that `'./telemetry'` is imported twice. Consolidating into a single import improves readability.


<details>
<summary>📝 Suggested fix</summary>

```diff
-import { emitTelemetry, disableTelemetry, enableTelemetry, extractDidMethod } from './telemetry';
-import { _resetForTesting, isTelemetryEnabled, getInstanceId, SDK_VERSION } from './telemetry';
+import {
+  emitTelemetry,
+  disableTelemetry,
+  enableTelemetry,
+  extractDidMethod,
+  _resetForTesting,
+  isTelemetryEnabled,
+  getInstanceId,
+  SDK_VERSION,
+} from './telemetry';
```
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

```
Verify each finding against the current code and only fix it if needed.

In `@src/utils/telemetry/telemetry.test.ts` around lines 1 - 2, Consolidate the
two imports from './telemetry' into a single import statement that includes all
referenced symbols (emitTelemetry, disableTelemetry, enableTelemetry,
extractDidMethod, _resetForTesting, isTelemetryEnabled, getInstanceId,
SDK_VERSION); update the import lines so there is only one import from
'./telemetry' that lists these named exports to remove the duplicate import and
improve readability.
```

</details>

</blockquote></details>

</blockquote></details>

<details>
<summary>🤖 Prompt for all review comments with AI agents</summary>

Verify each finding against the current code and only fix it if needed.

Inline comments:
In @src/w3c/derive.ts:

  • Around line 21-24: The did_method fallback currently only checks string
    credential.issuer and thus misses object-form issuers; update the call site
    using extractDidMethod (the expression starting with
    credential.proof?.verificationMethod ?? ...) to also support credential.issuer
    as an object by extracting credential.issuer.id when issuer is an object
    (mirroring the behavior in signW3C/verifyW3CSignature), so that extractDidMethod
    receives the verificationMethod or the issuer id string before defaulting to
    ''/unknown.

Nitpick comments:
In @CLAUDE.md:

  • Line 59: Add a short "Telemetry" note to the docs near the utils/ analytics
    entry describing that telemetry collects anonymous usage metrics, how to opt out
    via the TRUSTVC_TELEMETRY_DISABLED=1 environment variable or by calling the
    disableTelemetry() API, and point readers to the README for full details;
    mention that telemetry is anonymous and configurable and reference the utils/
    analytics module and the disableTelemetry() function so developers can find the
    implementation.

In @README.md:

  • Around line 1191-1195: The fenced code block showing the .env example (the
    block containing TRUSTVC_TELEMETRY_DISABLED=1) lacks a language specifier and
    triggers markdownlint; update that fenced block to include the env language
    specifier (use ```env) so the block becomes a proper env-highlighted code fence
    in README.md.

In @src/utils/telemetry/telemetry.test.ts:

  • Around line 1-2: Consolidate the two imports from './telemetry' into a single
    import statement that includes all referenced symbols (emitTelemetry,
    disableTelemetry, enableTelemetry, extractDidMethod, _resetForTesting,
    isTelemetryEnabled, getInstanceId, SDK_VERSION); update the import lines so
    there is only one import from './telemetry' that lists these named exports to
    remove the duplicate import and improve readability.

In @src/utils/telemetry/telemetry.ts:

  • Around line 92-96: The isNodeEnvironment function uses explicit nested null
    checks for process.versions.node; replace the nested check with optional
    chaining to simplify the expression while keeping the typeof process !==
    'undefined' guard: update the return expression in isNodeEnvironment to use
    process?.versions?.node != null so the logic is identical but cleaner and less
    error-prone.
  • Around line 98-100: The isBrowserEnvironment function currently uses raw
    globals; update it to check globalThis for consistency with other checks (e.g.,
    globalThis.crypto, globalThis.fetch) by replacing references to window and
    localStorage with globalThis.window and globalThis.localStorage so the function
    uses typeof globalThis.window !== 'undefined' && typeof globalThis.localStorage
    !== 'undefined' (refer to the isBrowserEnvironment function to locate the
    change).
  • Around line 157-162: Change the module to use inline exports instead of a
    trailing re-export: mark the functions isTelemetryEnabled and getInstanceId with
    the export keyword at their declarations and export SDK_VERSION where it is
    defined, then remove the final "export { isTelemetryEnabled, getInstanceId,
    SDK_VERSION };" line; keep _resetForTesting and the internal symbols
    (_telemetryOverride, _instanceId) unchanged so tests still call
    _resetForTesting().

In @vitest.config.ts:

  • Line 28: The env object in vitest config uses an unnecessary as any cast;
    replace it with a properly typed object such as Record<string, string |
    undefined>. For example, construct a typed variable (e.g., const testEnv: Record<string, string | undefined> = { ...process.env, TRUSTVC_TELEMETRY_DISABLED: '1' }) and use env: testEnv, or cast process.env
    narrowly (...(process.env as Record<string,string|undefined>)) and remove the
    as any to satisfy static analysis while preserving the
    TRUSTVC_TELEMETRY_DISABLED entry.

</details>

<details>
<summary>🪄 Autofix (Beta)</summary>

Fix all unresolved CodeRabbit comments on this PR:

- [ ] <!-- {"checkboxId": "4b0d0e0a-96d7-4f10-b296-3a18ea78f0b9"} --> Push a commit to this branch (recommended)
- [ ] <!-- {"checkboxId": "ff5b1114-7d8c-49e6-8ac1-43f82af23a33"} --> Create a new PR with the fixes

</details>

---

<details>
<summary>ℹ️ Review info</summary>

<details>
<summary>⚙️ Run configuration</summary>

**Configuration used**: defaults

**Review profile**: CHILL

**Plan**: Pro

**Run ID**: `844ba480-554f-4885-9a3e-5a4c4c65be5c`

</details>

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 9233a6dced81a241aa2de72be7e52401506e004f and 09c4544ba9e16de822e78ffb03e1a084ce3ea5fa.

</details>

<details>
<summary>⛔ Files ignored due to path filters (1)</summary>

* `package-lock.json` is excluded by `!**/package-lock.json`

</details>

<details>
<summary>📒 Files selected for processing (16)</summary>

* `CLAUDE.md`
* `README.md`
* `src/__tests__/open-attestation/telemetry.test.ts`
* `src/__tests__/w3c/telemetry.test.ts`
* `src/open-attestation/sign.ts`
* `src/open-attestation/verify.ts`
* `src/utils/index.ts`
* `src/utils/telemetry/index.ts`
* `src/utils/telemetry/telemetry.test.ts`
* `src/utils/telemetry/telemetry.ts`
* `src/utils/telemetry/types.ts`
* `src/w3c/derive.ts`
* `src/w3c/sign.ts`
* `src/w3c/verify.ts`
* `tsconfig.json`
* `vitest.config.ts`

</details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Comment thread src/w3c/derive.ts Outdated
- move credential and document telemetry mapping into shared helpers so
  signing, verifying, and deriving report methods and cryptosuites
  consistently
- replace repeated async setup in tests with a shared harness and
  table-driven cases to reduce duplication and make telemetry assertions
  more reliable

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
src/utils/telemetry/telemetry.test.ts (1)

1-3: Consolidate imports from ./telemetry and drop redundant Vitest symbol imports.

On Lines 2-3, merge duplicated ./telemetry imports into one statement. Also, in practice with globals-enabled Vitest, explicit describe/it/expect imports are redundant.

Proposed cleanup
-import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
-import { emitTelemetry, disableTelemetry, enableTelemetry, extractDidMethod } from './telemetry';
-import { _resetForTesting, isTelemetryEnabled, getInstanceId, SDK_VERSION } from './telemetry';
+import { afterEach, beforeEach, vi } from 'vitest';
+import {
+  emitTelemetry,
+  disableTelemetry,
+  enableTelemetry,
+  extractDidMethod,
+  _resetForTesting,
+  isTelemetryEnabled,
+  getInstanceId,
+  SDK_VERSION,
+} from './telemetry';
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/utils/telemetry/telemetry.test.ts` around lines 1 - 3, Replace the two
separate imports so that all symbols exported from ./telemetry are imported in
one consolidated statement (include emitTelemetry, disableTelemetry,
enableTelemetry, extractDidMethod, _resetForTesting, isTelemetryEnabled,
getInstanceId, SDK_VERSION) and drop redundant vitest globals (remove explicit
describe/it/expect from the vitest import), keeping only the needed vitest
symbols (e.g., beforeEach, afterEach, vi) in the vitest import; update the
import lines to a single import from './telemetry' and a minimal import from
'vitest'.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/__tests__/w3c/telemetry.test.ts`:
- Line 1: The test file currently imports Vitest globals explicitly; remove the
import statement that imports describe and it from 'vitest' so the file relies
on the configured Vitest globals instead (locate and delete the import line that
references describe and it). Ensure no other references to that import remain
and run tests to confirm globals are used correctly.

In `@src/open-attestation/telemetry.ts`:
- Around line 20-25: emitOATelemetry currently hardcodes cryptosuite to
SUPPORTED_SIGNING_ALGORITHM.Secp256k1VerificationKey2018 which is incorrect;
update emitOATelemetry to derive the cryptosuite from the OA document structure
by checking V3-style proof.type and V2-style signature.type (handle array or
nested objects and fall back to 'unknown'), then pass that extracted string as
cryptosuite; reference the emitOATelemetry function and use the same
getIdentityProofType helper pattern for locating the proof/signature fields and
defaulting to 'unknown'.

---

Nitpick comments:
In `@src/utils/telemetry/telemetry.test.ts`:
- Around line 1-3: Replace the two separate imports so that all symbols exported
from ./telemetry are imported in one consolidated statement (include
emitTelemetry, disableTelemetry, enableTelemetry, extractDidMethod,
_resetForTesting, isTelemetryEnabled, getInstanceId, SDK_VERSION) and drop
redundant vitest globals (remove explicit describe/it/expect from the vitest
import), keeping only the needed vitest symbols (e.g., beforeEach, afterEach,
vi) in the vitest import; update the import lines to a single import from
'./telemetry' and a minimal import from 'vitest'.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cdf95d1e-5af6-4a61-a907-3acf99c7a9ce

📥 Commits

Reviewing files that changed from the base of the PR and between 09c4544 and e1355e0.

📒 Files selected for processing (11)
  • src/__tests__/open-attestation/telemetry.test.ts
  • src/__tests__/utils/telemetry.ts
  • src/__tests__/w3c/telemetry.test.ts
  • src/open-attestation/sign.ts
  • src/open-attestation/telemetry.ts
  • src/open-attestation/verify.ts
  • src/utils/telemetry/telemetry.test.ts
  • src/w3c/derive.ts
  • src/w3c/sign.ts
  • src/w3c/telemetry.ts
  • src/w3c/verify.ts
✅ Files skipped from review due to trivial changes (2)
  • src/open-attestation/sign.ts
  • src/tests/open-attestation/telemetry.test.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/open-attestation/verify.ts
  • src/w3c/sign.ts
  • src/w3c/verify.ts
  • src/w3c/derive.ts

Comment thread src/__tests__/w3c/telemetry.test.ts Outdated
Comment thread src/open-attestation/telemetry.ts
- replace the hardcoded OA cryptosuite value so telemetry reports the
  actual proof or signature type for v2 and v3 documents
- fall back to `unknown` for unsupported documents to keep emitted
  telemetry consistent instead of sending misleading defaults
- extend telemetry tests and helpers to assert cryptosuite extraction
  alongside DID method reporting

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/utils/telemetry/telemetry.test.ts (2)

77-79: Consider using a clearly synthetic did:key sample to avoid secret-scan noise.

The current value is valid-looking enough to trigger generic key detectors in some scanners. A clearly fake placeholder keeps intent while reducing false positives in CI/security tooling.

Suggested tweak
- input: 'did:key:z6MkrHKzgsahxBLyNAbLQyB1pcWNYC9GmywiWPgkrvntAZcj',
+ input: 'did:key:z6MkExampleDidKeyForTestsOnly000000000000000000',
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/utils/telemetry/telemetry.test.ts` around lines 77 - 79, Replace the
realistic-looking DID in the test case named "extracts did:key" in
telemetry.test.ts with a clearly synthetic placeholder (for example use an
obviously fake fragment like 'did:key:fake' or 'did:key:xxxxxxxx') so CI secret
scanners won't flag it; keep the test's expected value ('did:key') and the test
logic in the same function unchanged (refer to the test case name "extracts
did:key" and the input/expected fields to locate the change).

109-111: Test name is slightly inaccurate vs setup state.

beforeEach sets TRUSTVC_TELEMETRY_DISABLED to '', so this case is “empty env value” rather than “not set”. Please rename the test to match what it actually verifies.

Suggested tweak
- it('should return true by default when env var is not set', () => {
+ it('should return true when TRUSTVC_TELEMETRY_DISABLED is empty', () => {
   expect(isTelemetryEnabled()).toBe(true);
 });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/utils/telemetry/telemetry.test.ts` around lines 109 - 111, Rename the
test that currently reads "should return true by default when env var is not
set" to accurately reflect the setup where beforeEach sets
TRUSTVC_TELEMETRY_DISABLED = '' (empty string); update the test description to
something like "should return true when TRUSTVC_TELEMETRY_DISABLED is empty" and
keep the assertion calling isTelemetryEnabled() unchanged so the test still
verifies behavior for an empty env value.
src/__tests__/w3c/telemetry.test.ts (1)

9-51: Add W3C cryptosuite assertions to this telemetry matrix.

These tests currently validate only did_method; a regression in W3C cryptosuite extraction would still pass. Consider asserting telemetry.getLastCryptosuite() per case, similar to OA telemetry tests.

♻️ Suggested update
   [
     {
       name: 'emits did:web when signing with a string issuer',
       runOperation: async () => {
@@
       },
       expectedDidMethod: 'did:web',
+      expectedCryptosuite: 'BbsBlsSignature2020',
     },
     {
       name: 'emits did:web when verifying with a string issuer',
       runOperation: () => verifyW3CSignature(W3C_VERIFIABLE_DOCUMENT),
       expectedDidMethod: 'did:web',
+      expectedCryptosuite: 'BbsBlsSignature2020',
     },
@@
       runOperation: () =>
         verifyW3CSignature({
@@
         }),
       expectedDidMethod: 'did:key',
+      expectedCryptosuite: 'BbsBlsSignature2020',
     },
-  ].forEach(({ name, runOperation, expectedDidMethod }) => {
+  ].forEach(({ name, runOperation, expectedDidMethod, expectedCryptosuite }) => {
     it(name, async () => {
       await telemetry.assertDidMethod(runOperation, expectedDidMethod);
+      expect(telemetry.getLastCryptosuite()).toBe(expectedCryptosuite);
     });
   });
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/__tests__/w3c/telemetry.test.ts` around lines 9 - 51, The tests only
assert did method but not the W3C cryptosuite; update the test matrix entries to
include an expectedCryptosuite value for each case and after calling
telemetry.assertDidMethod(runOperation, expectedDidMethod) also assert the
cryptosuite by calling telemetry.getLastCryptosuite() (or a helper like
telemetry.assertCryptosuite if available) and compare it to expectedCryptosuite;
modify the objects in the array (and the forEach callback signature) to accept
expectedCryptosuite and perform that extra assertion for functions
runOperation/verifyW3CSignature so each case verifies both did method and
cryptosuite extraction.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/__tests__/w3c/telemetry.test.ts`:
- Around line 17-24: This test includes an inline privateKeyBase58 literal—move
it into a non-sensitive test fixture and reference it from the test instead:
create a fixture (e.g., export TEST_PRIVATE_KEY_BASE58) under
src/__tests__/fixtures, replace the inline privateKeyBase58 value in the object
(the entry with id 'did:web:trustvc.github.io:did:1#keys-1' and type
VerificationType.Bls12381G2Key2020) with the imported constant, and update the
test imports accordingly to centralize and reuse the test key material.

---

Nitpick comments:
In `@src/__tests__/w3c/telemetry.test.ts`:
- Around line 9-51: The tests only assert did method but not the W3C
cryptosuite; update the test matrix entries to include an expectedCryptosuite
value for each case and after calling telemetry.assertDidMethod(runOperation,
expectedDidMethod) also assert the cryptosuite by calling
telemetry.getLastCryptosuite() (or a helper like telemetry.assertCryptosuite if
available) and compare it to expectedCryptosuite; modify the objects in the
array (and the forEach callback signature) to accept expectedCryptosuite and
perform that extra assertion for functions runOperation/verifyW3CSignature so
each case verifies both did method and cryptosuite extraction.

In `@src/utils/telemetry/telemetry.test.ts`:
- Around line 77-79: Replace the realistic-looking DID in the test case named
"extracts did:key" in telemetry.test.ts with a clearly synthetic placeholder
(for example use an obviously fake fragment like 'did:key:fake' or
'did:key:xxxxxxxx') so CI secret scanners won't flag it; keep the test's
expected value ('did:key') and the test logic in the same function unchanged
(refer to the test case name "extracts did:key" and the input/expected fields to
locate the change).
- Around line 109-111: Rename the test that currently reads "should return true
by default when env var is not set" to accurately reflect the setup where
beforeEach sets TRUSTVC_TELEMETRY_DISABLED = '' (empty string); update the test
description to something like "should return true when
TRUSTVC_TELEMETRY_DISABLED is empty" and keep the assertion calling
isTelemetryEnabled() unchanged so the test still verifies behavior for an empty
env value.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 8061f3fd-14eb-4f91-9c0a-825ad8c1e801

📥 Commits

Reviewing files that changed from the base of the PR and between e1355e0 and ec9773d.

📒 Files selected for processing (5)
  • src/__tests__/open-attestation/telemetry.test.ts
  • src/__tests__/utils/telemetry.ts
  • src/__tests__/w3c/telemetry.test.ts
  • src/open-attestation/telemetry.ts
  • src/utils/telemetry/telemetry.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/open-attestation/telemetry.ts
  • src/tests/utils/telemetry.ts

Comment thread src/__tests__/w3c/telemetry.test.ts Outdated
- move the shared test signing key into a fixture to reduce duplication
  and keep test setup consistent across suites
- extend telemetry coverage to verify cryptosuite reporting alongside
  did method extraction
- simplify placeholder did:key inputs and clarify a telemetry
  environment test description
@sonarqubecloud

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/__tests__/fixtures/keys.ts`:
- Around line 4-12: The committed raw private key in the TEST_BBS2020_KEY_PAIR
fixture (privateKeyBase58 field) triggers secret scanners; either remove the
hard-coded secret and instead generate the key at test setup (e.g., replace
export TEST_BBS2020_KEY_PAIR with a factory like createTestBbs2020KeyPair() that
derives/loads the key from a test-only generator or env) or add an explicit
scanner allowlist marker scoped to this fixture (e.g., a single-line
scanner-allow comment immediately above TEST_BBS2020_KEY_PAIR referencing the
scanner’s rule/id) so the intent is machine-verifiable; update references to use
the factory or keep the allowlist comment next to the privateKeyBase58 symbol.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2e1611c9-84a0-4832-af2d-81fbba200ac3

📥 Commits

Reviewing files that changed from the base of the PR and between ec9773d and c1161d3.

📒 Files selected for processing (5)
  • src/__tests__/core/documentBuilder.test.ts
  • src/__tests__/fixtures/keys.ts
  • src/__tests__/w3c/sign.test.ts
  • src/__tests__/w3c/telemetry.test.ts
  • src/utils/telemetry/telemetry.test.ts
✅ Files skipped from review due to trivial changes (3)
  • src/tests/core/documentBuilder.test.ts
  • src/tests/w3c/telemetry.test.ts
  • src/utils/telemetry/telemetry.test.ts

Comment on lines +4 to +12
// Dummy/test cryptographic BBS 2020 key pair for local development and CI only.
export const TEST_BBS2020_KEY_PAIR: PrivateKeyPair = {
id: 'did:web:trustvc.github.io:did:1#keys-1',
controller: 'did:web:trustvc.github.io:did:1',
type: VerificationType.Bls12381G2Key2020,
publicKeyBase58:
'oRfEeWFresvhRtXCkihZbxyoi2JER7gHTJ5psXhHsdCoU1MttRMi3Yp9b9fpjmKh7bMgfWKLESiK2YovRd8KGzJsGuamoAXfqDDVhckxuc9nmsJ84skCSTijKeU4pfAcxeJ',
privateKeyBase58: '4LDU56PUhA9ZEutnR1qCWQnUhtLtpLu2EHSq4h1o7vtF',
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Secret-scanner false-positive risk on committed private key fixture.

Line 11 contains raw key material and is already flagged by static analysis. Even for test-only keys, this can create CI/security-noise churn. Please add an explicit scanner allowlist entry scoped to this fixture (or generate key material during test setup) to make intent machine-verifiable.

🧰 Tools
🪛 Betterleaks (1.1.1)

[high] 11-11: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/__tests__/fixtures/keys.ts` around lines 4 - 12, The committed raw
private key in the TEST_BBS2020_KEY_PAIR fixture (privateKeyBase58 field)
triggers secret scanners; either remove the hard-coded secret and instead
generate the key at test setup (e.g., replace export TEST_BBS2020_KEY_PAIR with
a factory like createTestBbs2020KeyPair() that derives/loads the key from a
test-only generator or env) or add an explicit scanner allowlist marker scoped
to this fixture (e.g., a single-line scanner-allow comment immediately above
TEST_BBS2020_KEY_PAIR referencing the scanner’s rule/id) so the intent is
machine-verifiable; update references to use the factory or keep the allowlist
comment next to the privateKeyBase58 symbol.

@ffeew-dex ffeew-dex closed this Apr 13, 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