Skip to content

Commit 7cf81f5

Browse files
committed
fix: normalize hashInput to use resolved StrongRefs instead of raw params
- Use locationRef (resolved StrongRef) instead of params.location which may be Blob - Use contributorsData (processed canonical format) instead of params.contributions - Extract image CID string instead of full imageBlobRef object - Use canonical rights object with only {name, type, description} This ensures sha256Hash() receives only JSON-serializable values and produces deterministic rKeys regardless of input format (Blob vs URI vs StrongRef).
1 parent 6774f0c commit 7cf81f5

2 files changed

Lines changed: 26 additions & 10 deletions

File tree

.changeset/wise-papayas-sing.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@
33
---
44

55
feat: implement pre-generation of rKeys for activity claims using deterministic content hashing (SHA-256).
6+
7+
fix: normalize hashInput in `createHypercertRecord()` to use resolved StrongRefs (`locationRef`, `contributorsData`)
8+
instead of raw params which may contain non-serializable Blobs or inconsistent formats, ensuring stable rKey generation.

packages/sdk-core/src/repository/HypercertOperationsImpl.ts

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -315,23 +315,36 @@ export class HypercertOperationsImpl extends EventEmitter<HypercertEvents> imple
315315
}
316316

317317
// Generate rKey from stable content hash (idempotency)
318-
// Hash the complete claim record including all StrongRefs and embedded data
319-
// These define the claim's identity per the lexicon.
318+
// Use NORMALIZED values (already resolved StrongRefs and processed data)
319+
// to ensure JSON-serializability and deterministic hashing.
320+
// Raw params.location can contain non-serializable Blobs (GeoJSON),
321+
// and params.contributions can have arbitrary/inconsistent props.
320322
const hashInput = {
321323
title: params.title,
322324
description: params.description,
323325
shortDescription: params.shortDescription,
324326
workScope: params.workScope,
325327
startDate: params.startDate,
326328
endDate: params.endDate,
327-
// Image blob reference (CID-based, stable)
328-
imageRecord: imageBlobRef,
329-
// Rights definition (what the user specified, not the generated CID)
330-
rightsData: typeof params.rights === "object" ? params.rights : undefined,
331-
// Location StrongRef - part of claim identity per lexicon
332-
location: params.location,
333-
// Contributors - part of claim identity per lexicon
334-
contributors: params.contributions ? params.contributions : undefined,
329+
// Image: extract CID string from blob ref (stable content hash)
330+
// JsonBlobRef can have ref.$link (upload result) or cid (existing record)
331+
imageRef: imageBlobRef
332+
? "ref" in imageBlobRef && imageBlobRef.ref
333+
? imageBlobRef.ref.$link
334+
: "cid" in imageBlobRef
335+
? imageBlobRef.cid
336+
: undefined
337+
: undefined,
338+
// Rights: canonical object with only known fields
339+
rights: {
340+
name: params.rights.name,
341+
type: params.rights.type,
342+
description: params.rights.description,
343+
},
344+
// Location: use resolved StrongRef (uri+cid), not raw params which may be Blob
345+
locationRef: locationRef ? { uri: locationRef.uri, cid: locationRef.cid } : undefined,
346+
// Contributors: use already-processed canonical format from processContributors()
347+
contributors: contributorsData,
335348
};
336349

337350
const contentHash = await sha256Hash(hashInput);

0 commit comments

Comments
 (0)