@keytrace/claims 0.0.10 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -92,7 +92,7 @@ interface ClaimVerificationResult {
92
92
  2. Fetches the user's PDS endpoint from their DID document
93
93
  3. Lists all `dev.keytrace.claim` records from their repo
94
94
  4. For each claim:
95
- - Fetches the signing key from the `sig.src` AT URI
95
+ - Fetches the signing key from the primary signature's `src` AT URI
96
96
  - Reconstructs the signed claim data
97
97
  - Verifies the ES256 signature using Web Crypto API
98
98
 
@@ -2,5 +2,6 @@ export declare const PUBLIC_API_URL = "https://public.api.bsky.app";
2
2
  export declare const PLC_DIRECTORY_URL = "https://plc.directory";
3
3
  export declare const COLLECTION_NSID = "dev.keytrace.claim";
4
4
  export declare const KEY_COLLECTION_NSID = "dev.keytrace.key";
5
+ export declare const SERVER_KEY_COLLECTION_NSID = "dev.keytrace.serverPublicKey";
5
6
  export declare const DEFAULT_TIMEOUT = 10000;
6
7
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,gCAAgC,CAAC;AAC5D,eAAO,MAAM,iBAAiB,0BAA0B,CAAC;AACzD,eAAO,MAAM,eAAe,uBAAuB,CAAC;AACpD,eAAO,MAAM,mBAAmB,qBAAqB,CAAC;AACtD,eAAO,MAAM,eAAe,QAAQ,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,cAAc,gCAAgC,CAAC;AAC5D,eAAO,MAAM,iBAAiB,0BAA0B,CAAC;AACzD,eAAO,MAAM,eAAe,uBAAuB,CAAC;AACpD,eAAO,MAAM,mBAAmB,qBAAqB,CAAC;AACtD,eAAO,MAAM,0BAA0B,iCAAiC,CAAC;AACzE,eAAO,MAAM,eAAe,QAAQ,CAAC"}
package/dist/constants.js CHANGED
@@ -2,5 +2,6 @@ export const PUBLIC_API_URL = "https://public.api.bsky.app";
2
2
  export const PLC_DIRECTORY_URL = "https://plc.directory";
3
3
  export const COLLECTION_NSID = "dev.keytrace.claim";
4
4
  export const KEY_COLLECTION_NSID = "dev.keytrace.key";
5
+ export const SERVER_KEY_COLLECTION_NSID = "dev.keytrace.serverPublicKey";
5
6
  export const DEFAULT_TIMEOUT = 10000;
6
7
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG,6BAA6B,CAAC;AAC5D,MAAM,CAAC,MAAM,iBAAiB,GAAG,uBAAuB,CAAC;AACzD,MAAM,CAAC,MAAM,eAAe,GAAG,oBAAoB,CAAC;AACpD,MAAM,CAAC,MAAM,mBAAmB,GAAG,kBAAkB,CAAC;AACtD,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC"}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG,6BAA6B,CAAC;AAC5D,MAAM,CAAC,MAAM,iBAAiB,GAAG,uBAAuB,CAAC;AACzD,MAAM,CAAC,MAAM,eAAe,GAAG,oBAAoB,CAAC;AACpD,MAAM,CAAC,MAAM,mBAAmB,GAAG,kBAAkB,CAAC;AACtD,MAAM,CAAC,MAAM,0BAA0B,GAAG,8BAA8B,CAAC;AACzE,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,CAAC"}
package/dist/types.d.ts CHANGED
@@ -19,25 +19,44 @@ export interface ClaimSignature {
19
19
  signedAt: string;
20
20
  /** JWS compact serialization */
21
21
  attestation: string;
22
+ /** Ordered list of field names included in the signed payload */
23
+ signedFields?: string[];
24
+ /** Datetime when this signature was retracted (ISO 8601) */
25
+ retractedAt?: string;
22
26
  }
23
27
  /**
24
- * Raw claim record from ATProto
28
+ * Raw claim record from ATProto.
29
+ * Supports both legacy format (sig: single object) and new format (sigs: array).
25
30
  */
26
31
  export interface ClaimRecord {
27
32
  $type: "dev.keytrace.claim";
28
33
  type: string;
29
34
  claimUri: string;
30
35
  identity: ClaimIdentity;
31
- sig: ClaimSignature;
36
+ /** @deprecated Use sigs array instead. Retained for backwards compatibility with old records. */
37
+ sig?: ClaimSignature;
38
+ /** One or more cryptographic attestation signatures from verification services */
39
+ sigs?: ClaimSignature[];
32
40
  comment?: string;
33
41
  createdAt: string;
34
42
  prerelease?: boolean;
43
+ nonce?: string;
44
+ retractedAt?: string;
35
45
  }
36
46
  /**
37
- * Public key record from keytrace service
47
+ * Get the attestation signature from a claim record.
48
+ * Looks for a sig with kid starting with "attest:", falls back to sigs[0] or legacy sig field.
49
+ */
50
+ export declare function getPrimarySig(record: {
51
+ sigs?: ClaimSignature[];
52
+ sig?: ClaimSignature;
53
+ }): ClaimSignature | undefined;
54
+ /**
55
+ * Public key record from keytrace service.
56
+ * Supports both old (dev.keytrace.key) and new (dev.keytrace.serverPublicKey) collection names.
38
57
  */
39
58
  export interface KeyRecord {
40
- $type: "dev.keytrace.key";
59
+ $type: "dev.keytrace.key" | "dev.keytrace.serverPublicKey";
41
60
  publicJwk: string;
42
61
  validFrom: string;
43
62
  validUntil: string;
@@ -52,14 +71,11 @@ export interface ES256PublicJwk {
52
71
  y: string;
53
72
  }
54
73
  /**
55
- * Claim data that is signed (canonical form)
74
+ * Claim data that is signed (canonical form).
75
+ * New format uses record field names: claimUri, did, identity.subject, type.
76
+ * Legacy format used: did, subject, type, verifiedAt.
56
77
  */
57
- export interface SignedClaimData {
58
- did: string;
59
- subject: string;
60
- type: string;
61
- verifiedAt: string;
62
- }
78
+ export type SignedClaimData = Record<string, string>;
63
79
  /**
64
80
  * Verification step detail for debugging/auditing
65
81
  */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js CHANGED
@@ -1,2 +1,9 @@
1
- export {};
1
+ /**
2
+ * Get the attestation signature from a claim record.
3
+ * Looks for a sig with kid starting with "attest:", falls back to sigs[0] or legacy sig field.
4
+ */
5
+ export function getPrimarySig(record) {
6
+ const attestSig = record.sigs?.find((s) => s.kid?.startsWith("attest:"));
7
+ return attestSig ?? record.sigs?.[0] ?? record.sig;
8
+ }
2
9
  //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAgDA;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,MAAyD;IACrF,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;IACzE,OAAO,SAAS,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC;AACrD,CAAC"}
package/dist/verify.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { VerificationResult, VerifyOptions } from "./types.js";
2
2
  export type { ClaimIdentity, ClaimRecord, ClaimSignature, ClaimVerificationResult, ES256PublicJwk, KeyRecord, SignedClaimData, VerificationResult, VerificationStep, VerifyOptions, } from "./types.js";
3
+ export { getPrimarySig } from "./types.js";
3
4
  /**
4
5
  * Verify all keytrace claims for a handle.
5
6
  *
@@ -1 +1 @@
1
- {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoF,kBAAkB,EAAoB,aAAa,EAAE,MAAM,YAAY,CAAC;AAQxK,YAAY,EACV,aAAa,EACb,WAAW,EACX,cAAc,EACd,uBAAuB,EACvB,cAAc,EACd,SAAS,EACT,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAQ7G;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAsCvG"}
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoF,kBAAkB,EAAoB,aAAa,EAAE,MAAM,YAAY,CAAC;AASxK,YAAY,EACV,aAAa,EACb,WAAW,EACX,cAAc,EACd,uBAAuB,EACvB,cAAc,EACd,SAAS,EACT,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAQ7G;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAsCvG"}
package/dist/verify.js CHANGED
@@ -1,7 +1,9 @@
1
+ import { getPrimarySig } from "./types.js";
1
2
  import { resolveHandle, resolvePds, listClaimRecords, getRecordByUri } from "./atproto.js";
2
3
  import { verifyES256Signature } from "./crypto/signature.js";
3
4
  /** Default trusted signer handles */
4
5
  const DEFAULT_TRUSTED_SIGNERS = ["keytrace.dev"];
6
+ export { getPrimarySig } from "./types.js";
5
7
  /**
6
8
  * Verify all keytrace claims for a handle.
7
9
  *
@@ -65,8 +67,10 @@ export async function getClaimsForDid(did, options) {
65
67
  async function verifySingleClaim(did, uri, rkey, claim, trustedDids, options) {
66
68
  const steps = [];
67
69
  try {
70
+ // Resolve the primary signature (supports both old `sig` and new `sigs` format)
71
+ const sig = getPrimarySig(claim);
68
72
  // Step 1: Validate claim structure
69
- if (!claim.sig?.src || !claim.sig?.attestation || !claim.sig?.signedAt) {
73
+ if (!sig?.src || !sig?.attestation || !sig?.signedAt) {
70
74
  steps.push({
71
75
  step: "validate_claim",
72
76
  success: false,
@@ -76,9 +80,9 @@ async function verifySingleClaim(did, uri, rkey, claim, trustedDids, options) {
76
80
  }
77
81
  steps.push({ step: "validate_claim", success: true, detail: "Claim structure valid" });
78
82
  // Step 2: Validate signing key is from a trusted signer
79
- const signerDid = extractDidFromAtUri(claim.sig.src);
83
+ const signerDid = extractDidFromAtUri(sig.src);
80
84
  if (!signerDid || !trustedDids.has(signerDid)) {
81
- const error = `Signing key is not from a trusted signer (source: ${claim.sig.src})`;
85
+ const error = `Signing key is not from a trusted signer (source: ${sig.src})`;
82
86
  steps.push({ step: "validate_signer", success: false, error });
83
87
  return buildResult(uri, rkey, claim, false, steps, error);
84
88
  }
@@ -86,8 +90,8 @@ async function verifySingleClaim(did, uri, rkey, claim, trustedDids, options) {
86
90
  // Step 3: Fetch the signing key
87
91
  let keyRecord;
88
92
  try {
89
- keyRecord = await getRecordByUri(claim.sig.src, options);
90
- steps.push({ step: "fetch_key", success: true, detail: `Fetched key from ${claim.sig.src}` });
93
+ keyRecord = await getRecordByUri(sig.src, options);
94
+ steps.push({ step: "fetch_key", success: true, detail: `Fetched key from ${sig.src}` });
91
95
  }
92
96
  catch (err) {
93
97
  const error = `Failed to fetch signing key: ${err instanceof Error ? err.message : String(err)}`;
@@ -108,20 +112,44 @@ async function verifySingleClaim(did, uri, rkey, claim, trustedDids, options) {
108
112
  steps.push({ step: "parse_key", success: false, error });
109
113
  return buildResult(uri, rkey, claim, false, steps, error);
110
114
  }
111
- // Step 5: Reconstruct the signed claim data
112
- const signedData = {
113
- did,
114
- subject: claim.identity.subject,
115
- type: claim.type,
116
- verifiedAt: claim.sig.signedAt,
117
- };
115
+ // Step 5: Reconstruct the signed claim data.
116
+ // Use signedFields to determine which fields were signed and reconstruct them.
117
+ const fields = sig.signedFields ?? [];
118
+ const isNewFormat = fields.includes("identity.subject");
119
+ let signedData;
120
+ if (isNewFormat) {
121
+ // New format: signedFields tells us exactly which fields to include.
122
+ // Map each field name to its value from the record.
123
+ const valueMap = {
124
+ claimUri: claim.claimUri,
125
+ createdAt: sig.signedAt, // createdAt was set to signedAt during attestation
126
+ did,
127
+ "identity.subject": claim.identity.subject,
128
+ type: claim.type,
129
+ };
130
+ signedData = {};
131
+ for (const field of fields) {
132
+ if (field in valueMap) {
133
+ signedData[field] = valueMap[field];
134
+ }
135
+ }
136
+ }
137
+ else {
138
+ // Legacy format: { did, subject, type, verifiedAt }
139
+ signedData = {
140
+ did,
141
+ subject: claim.identity.subject,
142
+ type: claim.type,
143
+ verifiedAt: sig.signedAt,
144
+ };
145
+ }
118
146
  steps.push({
119
147
  step: "reconstruct_data",
120
148
  success: true,
121
- detail: `Reconstructed signed data for ${claim.type}:${claim.identity.subject}`,
149
+ detail: `Reconstructed signed data for ${claim.type}:${claim.identity.subject} (${isNewFormat ? "new" : "legacy"} format)`,
122
150
  });
123
151
  // Step 6: Verify the signature
124
- const isValid = await verifyES256Signature(signedData, claim.sig.attestation, publicJwk);
152
+ const isValid = await verifyES256Signature(signedData, sig.attestation, publicJwk);
125
153
  if (isValid) {
126
154
  steps.push({ step: "verify_signature", success: true, detail: "Signature verified" });
127
155
  return buildResult(uri, rkey, claim, true, steps);
@@ -1 +1 @@
1
- {"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keytrace/claims",
3
- "version": "0.0.10",
3
+ "version": "0.0.11",
4
4
  "description": "Verify keytrace identity claims",
5
5
  "files": [
6
6
  "src",
package/src/constants.ts CHANGED
@@ -2,4 +2,5 @@ export const PUBLIC_API_URL = "https://public.api.bsky.app";
2
2
  export const PLC_DIRECTORY_URL = "https://plc.directory";
3
3
  export const COLLECTION_NSID = "dev.keytrace.claim";
4
4
  export const KEY_COLLECTION_NSID = "dev.keytrace.key";
5
+ export const SERVER_KEY_COLLECTION_NSID = "dev.keytrace.serverPublicKey";
5
6
  export const DEFAULT_TIMEOUT = 10000;
package/src/types.ts CHANGED
@@ -20,27 +20,47 @@ export interface ClaimSignature {
20
20
  signedAt: string;
21
21
  /** JWS compact serialization */
22
22
  attestation: string;
23
+ /** Ordered list of field names included in the signed payload */
24
+ signedFields?: string[];
25
+ /** Datetime when this signature was retracted (ISO 8601) */
26
+ retractedAt?: string;
23
27
  }
24
28
 
25
29
  /**
26
- * Raw claim record from ATProto
30
+ * Raw claim record from ATProto.
31
+ * Supports both legacy format (sig: single object) and new format (sigs: array).
27
32
  */
28
33
  export interface ClaimRecord {
29
34
  $type: "dev.keytrace.claim";
30
35
  type: string;
31
36
  claimUri: string;
32
37
  identity: ClaimIdentity;
33
- sig: ClaimSignature;
38
+ /** @deprecated Use sigs array instead. Retained for backwards compatibility with old records. */
39
+ sig?: ClaimSignature;
40
+ /** One or more cryptographic attestation signatures from verification services */
41
+ sigs?: ClaimSignature[];
34
42
  comment?: string;
35
43
  createdAt: string;
36
44
  prerelease?: boolean;
45
+ nonce?: string;
46
+ retractedAt?: string;
37
47
  }
38
48
 
39
49
  /**
40
- * Public key record from keytrace service
50
+ * Get the attestation signature from a claim record.
51
+ * Looks for a sig with kid starting with "attest:", falls back to sigs[0] or legacy sig field.
52
+ */
53
+ export function getPrimarySig(record: { sigs?: ClaimSignature[]; sig?: ClaimSignature }): ClaimSignature | undefined {
54
+ const attestSig = record.sigs?.find((s) => s.kid?.startsWith("attest:"));
55
+ return attestSig ?? record.sigs?.[0] ?? record.sig;
56
+ }
57
+
58
+ /**
59
+ * Public key record from keytrace service.
60
+ * Supports both old (dev.keytrace.key) and new (dev.keytrace.serverPublicKey) collection names.
41
61
  */
42
62
  export interface KeyRecord {
43
- $type: "dev.keytrace.key";
63
+ $type: "dev.keytrace.key" | "dev.keytrace.serverPublicKey";
44
64
  publicJwk: string;
45
65
  validFrom: string;
46
66
  validUntil: string;
@@ -57,14 +77,11 @@ export interface ES256PublicJwk {
57
77
  }
58
78
 
59
79
  /**
60
- * Claim data that is signed (canonical form)
80
+ * Claim data that is signed (canonical form).
81
+ * New format uses record field names: claimUri, did, identity.subject, type.
82
+ * Legacy format used: did, subject, type, verifiedAt.
61
83
  */
62
- export interface SignedClaimData {
63
- did: string;
64
- subject: string;
65
- type: string;
66
- verifiedAt: string;
67
- }
84
+ export type SignedClaimData = Record<string, string>;
68
85
 
69
86
  /**
70
87
  * Verification step detail for debugging/auditing
package/src/verify.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { ClaimRecord, ClaimVerificationResult, ES256PublicJwk, KeyRecord, SignedClaimData, VerificationResult, VerificationStep, VerifyOptions } from "./types.js";
2
+ import { getPrimarySig } from "./types.js";
2
3
  import { resolveHandle, resolvePds, listClaimRecords, getRecordByUri } from "./atproto.js";
3
4
  import { verifyES256Signature } from "./crypto/signature.js";
4
5
 
@@ -18,6 +19,7 @@ export type {
18
19
  VerificationStep,
19
20
  VerifyOptions,
20
21
  } from "./types.js";
22
+ export { getPrimarySig } from "./types.js";
21
23
 
22
24
  /**
23
25
  * Verify all keytrace claims for a handle.
@@ -90,8 +92,11 @@ async function verifySingleClaim(did: string, uri: string, rkey: string, claim:
90
92
  const steps: VerificationStep[] = [];
91
93
 
92
94
  try {
95
+ // Resolve the primary signature (supports both old `sig` and new `sigs` format)
96
+ const sig = getPrimarySig(claim);
97
+
93
98
  // Step 1: Validate claim structure
94
- if (!claim.sig?.src || !claim.sig?.attestation || !claim.sig?.signedAt) {
99
+ if (!sig?.src || !sig?.attestation || !sig?.signedAt) {
95
100
  steps.push({
96
101
  step: "validate_claim",
97
102
  success: false,
@@ -102,9 +107,9 @@ async function verifySingleClaim(did: string, uri: string, rkey: string, claim:
102
107
  steps.push({ step: "validate_claim", success: true, detail: "Claim structure valid" });
103
108
 
104
109
  // Step 2: Validate signing key is from a trusted signer
105
- const signerDid = extractDidFromAtUri(claim.sig.src);
110
+ const signerDid = extractDidFromAtUri(sig.src);
106
111
  if (!signerDid || !trustedDids.has(signerDid)) {
107
- const error = `Signing key is not from a trusted signer (source: ${claim.sig.src})`;
112
+ const error = `Signing key is not from a trusted signer (source: ${sig.src})`;
108
113
  steps.push({ step: "validate_signer", success: false, error });
109
114
  return buildResult(uri, rkey, claim, false, steps, error);
110
115
  }
@@ -113,8 +118,8 @@ async function verifySingleClaim(did: string, uri: string, rkey: string, claim:
113
118
  // Step 3: Fetch the signing key
114
119
  let keyRecord: KeyRecord;
115
120
  try {
116
- keyRecord = await getRecordByUri<KeyRecord>(claim.sig.src, options);
117
- steps.push({ step: "fetch_key", success: true, detail: `Fetched key from ${claim.sig.src}` });
121
+ keyRecord = await getRecordByUri<KeyRecord>(sig.src, options);
122
+ steps.push({ step: "fetch_key", success: true, detail: `Fetched key from ${sig.src}` });
118
123
  } catch (err) {
119
124
  const error = `Failed to fetch signing key: ${err instanceof Error ? err.message : String(err)}`;
120
125
  steps.push({ step: "fetch_key", success: false, error });
@@ -135,21 +140,44 @@ async function verifySingleClaim(did: string, uri: string, rkey: string, claim:
135
140
  return buildResult(uri, rkey, claim, false, steps, error);
136
141
  }
137
142
 
138
- // Step 5: Reconstruct the signed claim data
139
- const signedData: SignedClaimData = {
140
- did,
141
- subject: claim.identity.subject,
142
- type: claim.type,
143
- verifiedAt: claim.sig.signedAt,
144
- };
143
+ // Step 5: Reconstruct the signed claim data.
144
+ // Use signedFields to determine which fields were signed and reconstruct them.
145
+ const fields = sig.signedFields ?? [];
146
+ const isNewFormat = fields.includes("identity.subject");
147
+ let signedData: SignedClaimData;
148
+ if (isNewFormat) {
149
+ // New format: signedFields tells us exactly which fields to include.
150
+ // Map each field name to its value from the record.
151
+ const valueMap: Record<string, string> = {
152
+ claimUri: claim.claimUri,
153
+ createdAt: sig.signedAt, // createdAt was set to signedAt during attestation
154
+ did,
155
+ "identity.subject": claim.identity.subject,
156
+ type: claim.type,
157
+ };
158
+ signedData = {};
159
+ for (const field of fields) {
160
+ if (field in valueMap) {
161
+ signedData[field] = valueMap[field];
162
+ }
163
+ }
164
+ } else {
165
+ // Legacy format: { did, subject, type, verifiedAt }
166
+ signedData = {
167
+ did,
168
+ subject: claim.identity.subject,
169
+ type: claim.type,
170
+ verifiedAt: sig.signedAt,
171
+ };
172
+ }
145
173
  steps.push({
146
174
  step: "reconstruct_data",
147
175
  success: true,
148
- detail: `Reconstructed signed data for ${claim.type}:${claim.identity.subject}`,
176
+ detail: `Reconstructed signed data for ${claim.type}:${claim.identity.subject} (${isNewFormat ? "new" : "legacy"} format)`,
149
177
  });
150
178
 
151
179
  // Step 6: Verify the signature
152
- const isValid = await verifyES256Signature(signedData, claim.sig.attestation, publicJwk);
180
+ const isValid = await verifyES256Signature(signedData, sig.attestation, publicJwk);
153
181
 
154
182
  if (isValid) {
155
183
  steps.push({ step: "verify_signature", success: true, detail: "Signature verified" });