Conversation
📝 WalkthroughWalkthroughAdds an OpenCerts registry verifier, exposes the open-cert module via barrel exports, integrates the registry verifier into the verification pipeline, expands fixtures with Changes
Sequence Diagram(s)sequenceDiagram
participant Client as Client
participant Pipeline as Verification Pipeline
participant RegistryVerifier as OpencertsRegistryVerifier
participant Registry as External Registry (HTTP)
Client->>Pipeline: submit document (V2 / V3 / OpenCert)
Pipeline->>RegistryVerifier: test(document)
RegistryVerifier-->>Pipeline: return SKIPPED if issuer store info missing
alt registry applicable
RegistryVerifier->>Registry: fetch registry JSON (RPC/URL)
Registry-->>RegistryVerifier: registry data or error
RegistryVerifier-->>Pipeline: return fragment(s) (VALID / INVALID) with data/reason
end
Pipeline-->>Client: aggregated verification result
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Fix all issues with AI agents
In `@src/__tests__/core/verify.test.ts`:
- Around line 945-1153: The tests call out to the live registry and snapshot
volatile issuer payloads; update the two test cases that call verifyDocument
(using OPENCERT_VERIFIABLE_DOCUMENT_V2_0) to mock the network fetch for the
registry (e.g., vi.mock('node-fetch') to return a stable registry JSON) or stub
registryVerifier.verify to return a small deterministic issuer list, and then
change assertions to only check stable fields (name, status, type) and any
minimal required values instead of the full issuer payload / snapshot; reference
verifyDocument, OpencertsRegistryVerifier, registryVerifier.verify, node-fetch
and OPENCERT_VERIFIABLE_DOCUMENT_V2_0 when locating code to modify.
In `@src/__tests__/open-cert/verify.test.ts`:
- Around line 11-27: The test calls registryVerifier.verify (and
registryVerifier.test) which performs a live fetch of the OpenCert registry;
replace that network dependency by mocking node-fetch (or the fetch wrapper used
by src/open-cert/verify.ts) in this test: stub the fetch response to return a
local fixture JSON matching the expected registry format, ensure the mock is
applied before calling registryVerifier.verify and restored after the test, and
update the test to import/use the fixture so the assertions on
fragment.type/name/status remain the same.
In `@src/open-cert/verify.ts`:
- Around line 1-11: The Runtypes imports Boolean and String shadow JS globals
and must be aliased; change the imports to alias them (e.g., Boolean as RBoolean
and String as RString, similar to Array as RunTypesArray) and update every usage
in this module (types, Record/Union/Optional calls, Static<> references, etc.)
to use the new aliases (RBoolean, RString) so no global names are
shadowed—ensure RunTypesArray remains unchanged and only the Boolean and String
identifiers are renamed throughout verify.ts.
- Around line 154-158: Wrap the fetch/parse in the verify async function so
network or JSON errors are caught: use a try/catch around the
fetch('https://opencerts.io/static/registry.json') and await res.json(), check
res.ok before parsing, validate the parsed object conforms to the Registry shape
(e.g. ensure registry && Array.isArray(registry.issuers)), and on any failure
throw a CodedError constructed with OpencertsRegistryCode.UNEXPECTED_ERROR so
callers of OpencertsRegistryVerifierVerificationFragment receive a proper error
fragment; optionally use an AbortController with a short timeout to abort slow
requests.
| describe.concurrent('OpenCert registry verifier', () => { | ||
| it( | ||
| 'given an OpenCert document (with documentStore/certificateStore), should run verifier and return fragment as return value', | ||
| { timeout: 300000 }, | ||
| async () => { | ||
| expect(registryVerifier.test(OPENCERT_VERIFIABLE_DOCUMENT_V2_0 as any, {} as any)).toBe(true); | ||
| const fragment = await registryVerifier.verify( | ||
| OPENCERT_VERIFIABLE_DOCUMENT_V2_0 as any, | ||
| {} as any, | ||
| ); | ||
|
|
||
| // Uses real https://opencerts.io/static/registry.json | ||
| expect(fragment.type).toBe('ISSUER_IDENTITY'); | ||
| expect(fragment.name).toBe('OpencertsRegistryVerifier'); | ||
| expect(fragment.status).toBe('VALID'); | ||
| }, | ||
| ); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cd /tmp && find . -name "verify.test.ts" -o -name "*registry*verifier*" 2>/dev/null | head -20Repository: TrustVC/trustvc
Length of output: 41
🏁 Script executed:
git ls-files | grep -E "(verify\.test\.ts|registry.*verifier)" | head -20Repository: TrustVC/trustvc
Length of output: 210
🏁 Script executed:
fd "verify.test.ts"Repository: TrustVC/trustvc
Length of output: 210
🏁 Script executed:
cat -n src/__tests__/open-cert/verify.test.tsRepository: TrustVC/trustvc
Length of output: 11357
🏁 Script executed:
find . -name "*registryVerifier*" -o -name "*registry*" | grep -E "\.(ts|js)$" | head -20Repository: TrustVC/trustvc
Length of output: 41
🏁 Script executed:
rg "registryVerifier\s*=" --type ts --type js -A 5 | head -50Repository: TrustVC/trustvc
Length of output: 41
🏁 Script executed:
fd -e ts -e js | xargs grep -l "registryVerifier" | grep -v test | head -10Repository: TrustVC/trustvc
Length of output: 103
🏁 Script executed:
rg "export.*registryVerifier" --type ts --type jsRepository: TrustVC/trustvc
Length of output: 130
🏁 Script executed:
cat -n src/open-cert/verify.tsRepository: TrustVC/trustvc
Length of output: 9926
Mock the registry in this unit test to avoid live dependencies.
The test directly calls registryVerifier.verify(), which makes an HTTP request to https://opencerts.io/static/registry.json (line 155 in src/open-cert/verify.ts). This creates a flaky test that will fail if the registry is unreachable or changes, and the 300000ms timeout confirms network latency is expected. Mock node-fetch with a fixture so the test is deterministic and runs quickly.
🧪 Example: mock `node-fetch` with a local fixture
import { verifySignature } from '@tradetrust-tt/tradetrust';
import { cloneDeep } from 'lodash';
-import { describe, expect, it } from 'vitest';
+import { describe, expect, it, vi } from 'vitest';
import { isValidOpenCert, registryVerifier } from '../..';
import { OPENCERT_VERIFIABLE_DOCUMENT_V2_0 } from '../fixtures/fixtures';
+const REGISTRY_FIXTURE = {
+ issuers: {
+ '0xCFa2B7Fc3FdD5CA55715581e34420268CCcd3039': {
+ name: 'Singapore Management University',
+ displayCard: true,
+ },
+ },
+} as const;
+
+vi.mock('node-fetch', () => ({
+ default: vi.fn().mockResolvedValue({
+ ok: true,
+ json: async () => REGISTRY_FIXTURE,
+ }),
+}));🤖 Prompt for AI Agents
In `@src/__tests__/open-cert/verify.test.ts` around lines 11 - 27, The test calls
registryVerifier.verify (and registryVerifier.test) which performs a live fetch
of the OpenCert registry; replace that network dependency by mocking node-fetch
(or the fetch wrapper used by src/open-cert/verify.ts) in this test: stub the
fetch response to return a local fixture JSON matching the expected registry
format, ensure the mock is applied before calling registryVerifier.verify and
restored after the test, and update the test to import/use the fixture so the
assertions on fragment.type/name/status remain the same.
| import fetch from 'node-fetch'; | ||
| import { | ||
| Array as RunTypesArray, | ||
| Boolean, | ||
| Literal, | ||
| Optional, | ||
| Record, | ||
| Static, | ||
| String, | ||
| Union, | ||
| } from 'runtypes'; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
git ls-files src/open-cert/ | head -20Repository: TrustVC/trustvc
Length of output: 105
🏁 Script executed:
# Check if the file exists and read the imports
cat -n src/open-cert/verify.ts | head -50Repository: TrustVC/trustvc
Length of output: 1454
🏁 Script executed:
# Look for Biome configuration files
find . -name "biome.json" -o -name ".biomerc*" -o -name "biome.toml" | head -10Repository: TrustVC/trustvc
Length of output: 71
🏁 Script executed:
# Search for Biome configuration in common locations
ls -la | grep -E "biome|eslint"Repository: TrustVC/trustvc
Length of output: 190
🏁 Script executed:
cat biome.jsonRepository: TrustVC/trustvc
Length of output: 1834
🏁 Script executed:
# Read the complete verify.ts file to see all usages
cat -n src/open-cert/verify.tsRepository: TrustVC/trustvc
Length of output: 9926
🏁 Script executed:
# Check if index.ts or other files import from verify.ts
rg "from.*verify" src/open-cert/Repository: TrustVC/trustvc
Length of output: 166
🏁 Script executed:
# Also check if Boolean or String are re-exported from verify.ts
rg "export.*Boolean|export.*String" src/open-cert/verify.tsRepository: TrustVC/trustvc
Length of output: 41
Alias Runtypes Boolean and String imports to satisfy Biome's noShadowRestrictedNames rule.
These imports shadow JavaScript global built-ins and will trigger a lint error. Apply the following changes:
Fix aliasing and update all usages
import {
Array as RunTypesArray,
- Boolean,
+ Boolean as RtBoolean,
Literal,
Optional,
Record,
Static,
- String,
+ String as RtString,
Union,
} from 'runtypes';
export const RegistryEntry = Record({
- name: String,
- displayCard: Boolean,
- website: Optional(String),
- email: Optional(String),
- phone: Optional(String),
- logo: Optional(String),
- id: Optional(String),
+ name: RtString,
+ displayCard: RtBoolean,
+ website: Optional(RtString),
+ email: Optional(RtString),
+ phone: Optional(RtString),
+ logo: Optional(RtString),
+ id: Optional(RtString),
});
export const OpencertsRegistryVerificationValidData = RegistryEntry.And(
Record({
- value: String,
+ value: RtString,
status: Literal('VALID'),
}),
);
export const OpencertsRegistryVerificationInvalidData = Record({
- value: String,
+ value: RtString,
status: Literal('INVALID'),
reason: Reason,
});🧰 Tools
🪛 Biome (2.3.13)
[error] 4-4: Do not shadow the global "Boolean" property.
Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.
(lint/suspicious/noShadowRestrictedNames)
[error] 9-9: Do not shadow the global "String" property.
Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.
(lint/suspicious/noShadowRestrictedNames)
🤖 Prompt for AI Agents
In `@src/open-cert/verify.ts` around lines 1 - 11, The Runtypes imports Boolean
and String shadow JS globals and must be aliased; change the imports to alias
them (e.g., Boolean as RBoolean and String as RString, similar to Array as
RunTypesArray) and update every usage in this module (types,
Record/Union/Optional calls, Static<> references, etc.) to use the new aliases
(RBoolean, RString) so no global names are shadowed—ensure RunTypesArray remains
unchanged and only the Boolean and String identifiers are renamed throughout
verify.ts.
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Fix all issues with AI agents
In `@README.md`:
- Line 303: The README sentence about TrustVC's verification is grammatically
broken (missing a closing parenthesis) and awkwardly worded; update the
Verifying description to close the parenthesis and rephrase to clearly state
that TrustVC supports W3C Verifiable Credentials (VCs), OpenAttestation
Verifiable Documents (VDs) and OpenCert Verifiable Documents, and that for
ECDSA-SD-2023 and BBS-2023 signed documents the verifyDocument function will
automatically derive (if needed) and verify in a single step—refer to TrustVC
and verifyDocument when editing.
- Line 5: Replace the incorrect product name "OpenCert" with the official
branding "OpenCerts" in the README; search for occurrences of "OpenCert" (e.g.,
the sentence mentioning OpenCert for verification and any other mentions) and
update them to "OpenCerts" to match the project identifiers like
OpencertsRegistryVerifier and the upstream site opencerts.io.
| ## About | ||
|
|
||
| TrustVC is a comprehensive wrapper library designed to simplify the signing and verification processes for TrustVC W3C [Verifiable Credentials (VC)](https://github.com/TrustVC/w3c) and OpenAttestation Verifiable Documents (VD), adhering to the W3C [VC](https://www.w3.org/TR/vc-data-model/) Data Model v2.0 (W3C Standard). It ensures compatibility and interoperability for Verifiable Credentials while supporting OpenAttestation [Verifiable Documents (VD)](https://github.com/Open-Attestation/open-attestation) v6.9.5. TrustVC seamlessly integrates functionalities for handling W3C Verifiable Credentials and OpenAttestation Verifiable Documents, leveraging existing TradeTrust libraries and smart contracts for [Token Registry](https://github.com/TradeTrust/token-registry) (V4 and V5). Additionally, it includes essential utility functions for strings, networks, and chains, making it a versatile tool for developers working with decentralized identity and verifiable data solutions. | ||
| TrustVC is a comprehensive wrapper library designed to simplify the signing and verification processes for TrustVC W3C [Verifiable Credentials (VC)](https://github.com/TrustVC/w3c) and OpenAttestation Verifiable Documents (VD), including OpenCert for verification, adhering to the W3C [VC](https://www.w3.org/TR/vc-data-model/) Data Model v2.0 (W3C Standard). It ensures compatibility and interoperability for Verifiable Credentials while supporting OpenAttestation [Verifiable Documents (VD)](https://github.com/Open-Attestation/open-attestation) v6.9.5. TrustVC seamlessly integrates functionalities for handling W3C Verifiable Credentials and OpenAttestation Verifiable Documents, leveraging existing TradeTrust libraries and smart contracts for [Token Registry](https://github.com/TradeTrust/token-registry) (V4 and V5). Additionally, it includes essential utility functions for strings, networks, and chains, making it a versatile tool for developers working with decentralized identity and verifiable data solutions. |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's check the README.md file at the specified lines
head -20 README.md | tail -16Repository: TrustVC/trustvc
Length of output: 1664
🏁 Script executed:
# Check line 303 as well
sed -n '300,310p' README.mdRepository: TrustVC/trustvc
Length of output: 829
🏁 Script executed:
# Search for all occurrences of "OpenCert" (with or without 's')
rg "OpenCert" --ignore-caseRepository: TrustVC/trustvc
Length of output: 9106
🏁 Script executed:
# Check for references to OpenCerts GitHub or official sources
rg "github.com.*[Oo]pen[Cc]ert" -A 2 -B 2Repository: TrustVC/trustvc
Length of output: 1163
Use "OpenCerts" (with 's') instead of "OpenCert" to match official branding.
The official product name is "OpenCerts" (evidenced by https://opencerts.io and consistent code identifiers like OpencertsRegistryVerifier). Update lines 5 and 303 in README.md to use "OpenCerts" for consistency with the official branding and codebase.
🤖 Prompt for AI Agents
In `@README.md` at line 5, Replace the incorrect product name "OpenCert" with the
official branding "OpenCerts" in the README; search for occurrences of
"OpenCert" (e.g., the sentence mentioning OpenCert for verification and any
other mentions) and update them to "OpenCerts" to match the project identifiers
like OpencertsRegistryVerifier and the upstream site opencerts.io.
There was a problem hiding this comment.
@pennhan-dex, understood! I've noted your decision to keep the current naming convention.
|
## [2.6.0](v2.5.2...v2.6.0) (2026-02-06) ### Features * implement opencert verify ([#125](#125)) ([6885892](6885892))
|
🎉 This PR is included in version 2.6.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |


Summary
Implement support for openCert verification
Changes
Implemented registryVerifier from openCert
Added registryVerifier to list of verifiers for OpenAttestation
Unit Tests
Summary by CodeRabbit
New Features
Tests
Documentation