@oma3/omatrust 0.1.0-alpha.11 → 0.1.0-alpha.13

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.
Files changed (42) hide show
  1. package/README.md +3 -0
  2. package/dist/app-registry/index.cjs +53 -0
  3. package/dist/app-registry/index.cjs.map +1 -1
  4. package/dist/app-registry/index.js +53 -0
  5. package/dist/app-registry/index.js.map +1 -1
  6. package/dist/identity/index.cjs +643 -164
  7. package/dist/identity/index.cjs.map +1 -1
  8. package/dist/identity/index.d.cts +2 -2
  9. package/dist/identity/index.d.ts +2 -2
  10. package/dist/identity/index.js +616 -165
  11. package/dist/identity/index.js.map +1 -1
  12. package/dist/index-Bu-xxcv9.d.ts +407 -0
  13. package/dist/index-C7odEbp6.d.cts +407 -0
  14. package/dist/index-CnWY9arI.d.cts +612 -0
  15. package/dist/index-DREQRFIE.d.ts +612 -0
  16. package/dist/index.cjs +1316 -202
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.d.cts +3 -3
  19. package/dist/index.d.ts +3 -3
  20. package/dist/index.js +1297 -202
  21. package/dist/index.js.map +1 -1
  22. package/dist/reputation/index.browser.cjs +153 -148
  23. package/dist/reputation/index.browser.cjs.map +1 -1
  24. package/dist/reputation/index.browser.js +153 -148
  25. package/dist/reputation/index.browser.js.map +1 -1
  26. package/dist/reputation/index.cjs +884 -163
  27. package/dist/reputation/index.cjs.map +1 -1
  28. package/dist/reputation/index.d.cts +2 -2
  29. package/dist/reputation/index.d.ts +2 -2
  30. package/dist/reputation/index.js +860 -164
  31. package/dist/reputation/index.js.map +1 -1
  32. package/dist/{types-dpYxRq8N.d.cts → types-Dn0OwaNj.d.cts} +37 -11
  33. package/dist/{types-dpYxRq8N.d.ts → types-Dn0OwaNj.d.ts} +37 -11
  34. package/dist/widgets/index.cjs.map +1 -1
  35. package/dist/widgets/index.d.cts +3 -0
  36. package/dist/widgets/index.d.ts +3 -0
  37. package/dist/widgets/index.js.map +1 -1
  38. package/package.json +4 -2
  39. package/dist/index-BOvk-7Ku.d.cts +0 -235
  40. package/dist/index-C2w5EvFH.d.ts +0 -329
  41. package/dist/index-QueRiudB.d.cts +0 -329
  42. package/dist/index-R78TpAhN.d.ts +0 -235
package/README.md CHANGED
@@ -41,10 +41,13 @@ npm install @ethereum-attestation-service/eas-sdk
41
41
  - DID address derivation
42
42
  - CAIP-10 / CAIP-2 helpers
43
43
  - JSON canonicalization helpers
44
+ - did:artifact construction and verification
45
+ - DID method migration (did:ethr → did:pkh, did:key → did:jwk)
44
46
  - `@oma3/omatrust/reputation`
45
47
  - attestation submit/delegated flows
46
48
  - attestation query + verification
47
49
  - proof creation/verification helpers
50
+ - schema-aware proof verification (linked identifier, key binding)
48
51
  - controller witness client
49
52
  - `@oma3/omatrust/app-registry`
50
53
  - ERC-8004 helpers
@@ -165,7 +165,57 @@ var METADATA_KEY_VERSION_MINOR = "omat.versionMinor";
165
165
  var METADATA_KEY_VERSION_PATCH = "omat.versionPatch";
166
166
  var METADATA_KEY_TRAIT_HASHES = "omat.traitHashes";
167
167
  var METADATA_KEY_METADATA_JSON = "omat.metadataJson";
168
+ var MAX_JSON_DEPTH = 32;
169
+ function assertDepthLimit(depth, context) {
170
+ if (depth > MAX_JSON_DEPTH) {
171
+ const msg = context ? `JSON nesting depth exceeds maximum of ${MAX_JSON_DEPTH} at ${context}` : `JSON nesting depth exceeds maximum of ${MAX_JSON_DEPTH}`;
172
+ throw new OmaTrustError("INVALID_INPUT", msg);
173
+ }
174
+ }
175
+ function assertJsonSafe(value, path = "$", depth = 0) {
176
+ assertDepthLimit(depth, path);
177
+ if (value === void 0) {
178
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: undefined`);
179
+ }
180
+ if (value === null) return;
181
+ switch (typeof value) {
182
+ case "string":
183
+ case "boolean":
184
+ return;
185
+ case "number":
186
+ if (!Number.isFinite(value)) {
187
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: ${value} (must be finite number)`);
188
+ }
189
+ return;
190
+ case "bigint":
191
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: BigInt (use number or string)`);
192
+ case "function":
193
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: function`);
194
+ case "symbol":
195
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: Symbol`);
196
+ case "object":
197
+ if (value instanceof Date) {
198
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: Date (use ISO string or timestamp)`);
199
+ }
200
+ if (value instanceof RegExp) {
201
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: RegExp`);
202
+ }
203
+ if (Array.isArray(value)) {
204
+ for (let i = 0; i < value.length; i++) {
205
+ assertJsonSafe(value[i], `${path}[${i}]`, depth + 1);
206
+ }
207
+ return;
208
+ }
209
+ for (const [key, val] of Object.entries(value)) {
210
+ assertJsonSafe(val, `${path}.${key}`, depth + 1);
211
+ }
212
+ return;
213
+ default:
214
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: unknown type "${typeof value}"`);
215
+ }
216
+ }
168
217
  function canonicalizeJson(obj) {
218
+ assertJsonSafe(obj);
169
219
  const jcs = canonicalize__default.default(obj);
170
220
  if (!jcs) {
171
221
  throw new OmaTrustError("INVALID_INPUT", "Object cannot be canonicalized", { obj });
@@ -201,6 +251,9 @@ async function computeDataHashFromUrl(url, algorithm) {
201
251
  if (!url || typeof url !== "string") {
202
252
  throw new OmaTrustError("INVALID_INPUT", "url must be a non-empty string", { url });
203
253
  }
254
+ if (algorithm !== "keccak256" && algorithm !== "sha256") {
255
+ throw new OmaTrustError("INVALID_INPUT", `Unsupported hash algorithm: "${algorithm}". Must be "keccak256" or "sha256".`, { algorithm });
256
+ }
204
257
  const json = await fetchJson(url);
205
258
  const jcsJson = canonicalizeJson(json);
206
259
  return hashJcs(jcsJson, algorithm);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/shared/errors.ts","../../src/shared/assert.ts","../../src/app-registry/traits.ts","../../src/app-registry/interfaces.ts","../../src/app-registry/status.ts","../../src/app-registry/version.ts","../../src/app-registry/metadata-keys.ts","../../src/identity/data.ts","../../src/app-registry/data-hash.ts"],"names":["id","canonicalize","toUtf8Bytes","keccak256","sha256"],"mappings":"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","file":"index.cjs","sourcesContent":["export class OmaTrustError extends Error {\n code: string;\n details?: unknown;\n\n constructor(code: string, message: string, details?: unknown) {\n super(message);\n this.name = \"OmaTrustError\";\n this.code = code;\n this.details = details;\n }\n}\n\nexport function toOmaTrustError(\n code: string,\n message: string,\n details?: unknown\n): OmaTrustError {\n return new OmaTrustError(code, message, details);\n}\n","import { OmaTrustError } from \"./errors\";\n\nexport function assertString(value: unknown, name: string, code = \"INVALID_INPUT\"): asserts value is string {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new OmaTrustError(code, `${name} must be a non-empty string`, { value });\n }\n}\n\nexport function assertNumber(value: unknown, name: string, code = \"INVALID_INPUT\"): asserts value is number {\n if (typeof value !== \"number\" || Number.isNaN(value)) {\n throw new OmaTrustError(code, `${name} must be a valid number`, { value });\n }\n}\n\nexport function assertObject(value: unknown, name: string, code = \"INVALID_INPUT\"): asserts value is Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new OmaTrustError(code, `${name} must be an object`, { value });\n }\n}\n\nexport function asError(err: unknown): Error {\n if (err instanceof Error) {\n return err;\n }\n return new Error(String(err));\n}\n","import { id } from \"ethers\";\nimport { assertString } from \"../shared/assert\";\n\ntype Hex = `0x${string}`;\n\nexport function hashTrait(trait: string): Hex {\n assertString(trait, \"trait\");\n return id(trait) as Hex;\n}\n\nexport function hashTraits(traits: string[]): Hex[] {\n if (!Array.isArray(traits)) {\n throw new TypeError(\"traits must be an array\");\n }\n return traits.map((trait) => hashTrait(trait));\n}\n","import type { InterfaceFlags, InterfaceType } from \"./types\";\nimport { OmaTrustError } from \"../shared/errors\";\n\nconst BIT_HUMAN = 1;\nconst BIT_API = 2;\nconst BIT_CONTRACT = 4;\n\nexport function computeInterfacesBitmap(flags: InterfaceFlags): number {\n return (flags.human ? BIT_HUMAN : 0) +\n (flags.api ? BIT_API : 0) +\n (flags.smartContract ? BIT_CONTRACT : 0);\n}\n\nexport function parseBitmapToFlags(bitmap: number): InterfaceFlags {\n return {\n human: (bitmap & BIT_HUMAN) !== 0,\n api: (bitmap & BIT_API) !== 0,\n smartContract: (bitmap & BIT_CONTRACT) !== 0\n };\n}\n\nexport function hasInterface(bitmap: number, type: InterfaceType): boolean {\n switch (type) {\n case \"human\":\n return (bitmap & BIT_HUMAN) !== 0;\n case \"api\":\n return (bitmap & BIT_API) !== 0;\n case \"contract\":\n return (bitmap & BIT_CONTRACT) !== 0;\n default:\n throw new OmaTrustError(\"INVALID_INPUT\", \"Unsupported interface type\", { type });\n }\n}\n\nexport function getInterfaceTypes(bitmap: number): InterfaceType[] {\n const results: InterfaceType[] = [];\n if (hasInterface(bitmap, \"human\")) {\n results.push(\"human\");\n }\n if (hasInterface(bitmap, \"api\")) {\n results.push(\"api\");\n }\n if (hasInterface(bitmap, \"contract\")) {\n results.push(\"contract\");\n }\n return results;\n}\n","import type { RegistryStatus } from \"./types\";\nimport { OmaTrustError } from \"../shared/errors\";\n\nexport function registryCodeToStatus(code: number): RegistryStatus {\n switch (code) {\n case 0:\n return \"Active\";\n case 1:\n return \"Deprecated\";\n case 2:\n return \"Replaced\";\n default:\n throw new OmaTrustError(\"INVALID_INPUT\", \"Invalid registry status code\", { code });\n }\n}\n\nexport function registryStatusToCode(status: RegistryStatus): number {\n switch (status) {\n case \"Active\":\n return 0;\n case \"Deprecated\":\n return 1;\n case \"Replaced\":\n return 2;\n default:\n throw new OmaTrustError(\"INVALID_INPUT\", \"Invalid registry status\", { status });\n }\n}\n\nexport function isValidRegistryStatus(status: string): status is RegistryStatus {\n return status === \"Active\" || status === \"Deprecated\" || status === \"Replaced\";\n}\n","import type { Version } from \"./types\";\nimport { OmaTrustError } from \"../shared/errors\";\n\nexport function parseVersion(input: string): Version {\n const match = input.match(/^(\\d+)\\.(\\d+)\\.(\\d+)$/);\n if (!match) {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Invalid semantic version\", { input });\n }\n\n return {\n major: Number(match[1]),\n minor: Number(match[2]),\n patch: Number(match[3])\n };\n}\n\nexport function formatVersion(version: Version): string {\n return `${version.major}.${version.minor}.${version.patch}`;\n}\n\nexport function compareVersions(a: Version, b: Version): -1 | 0 | 1 {\n if (a.major !== b.major) {\n return a.major < b.major ? -1 : 1;\n }\n if (a.minor !== b.minor) {\n return a.minor < b.minor ? -1 : 1;\n }\n if (a.patch !== b.patch) {\n return a.patch < b.patch ? -1 : 1;\n }\n return 0;\n}\n\nexport function isVersionGreater(a: Version, b: Version): boolean {\n return compareVersions(a, b) === 1;\n}\n\nexport function isVersionEqual(a: Version, b: Version): boolean {\n return compareVersions(a, b) === 0;\n}\n\nexport function getLatestVersion(history: Version[]): Version {\n if (history.length === 0) {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Version history cannot be empty\");\n }\n\n return history.reduce((current, candidate) => {\n return compareVersions(candidate, current) === 1 ? candidate : current;\n });\n}\n","export const METADATA_KEY_DID = \"omat.did\";\nexport const METADATA_KEY_DID_HASH = \"omat.didHash\";\nexport const METADATA_KEY_DATA_HASH = \"omat.dataHash\";\nexport const METADATA_KEY_DATA_HASH_ALGORITHM = \"omat.dataHashAlgorithm\";\nexport const METADATA_KEY_STATUS = \"omat.status\";\nexport const METADATA_KEY_INTERFACES = \"omat.interfaces\";\nexport const METADATA_KEY_FUNGIBLE_TOKEN_ID = \"omat.fungibleTokenId\";\nexport const METADATA_KEY_CONTRACT_ID = \"omat.contractId\";\nexport const METADATA_KEY_VERSION_MAJOR = \"omat.versionMajor\";\nexport const METADATA_KEY_VERSION_MINOR = \"omat.versionMinor\";\nexport const METADATA_KEY_VERSION_PATCH = \"omat.versionPatch\";\nexport const METADATA_KEY_TRAIT_HASHES = \"omat.traitHashes\";\nexport const METADATA_KEY_METADATA_JSON = \"omat.metadataJson\";\n","import canonicalize from \"canonicalize\";\nimport { keccak256, sha256, toUtf8Bytes } from \"ethers\";\nimport { OmaTrustError } from \"../shared/errors\";\n\ntype Hex = `0x${string}`;\n\nexport function canonicalizeJson(obj: unknown): string {\n const jcs = canonicalize(obj);\n if (!jcs) {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Object cannot be canonicalized\", { obj });\n }\n return jcs;\n}\n\nexport function canonicalizeForHash(obj: unknown): { jcsJson: string; hash: Hex } {\n const jcsJson = canonicalizeJson(obj);\n return {\n jcsJson,\n hash: keccak256(toUtf8Bytes(jcsJson)) as Hex\n };\n}\n\nexport function hashCanonicalizedJson(obj: unknown, algorithm: \"keccak256\" | \"sha256\"): Hex {\n const jcs = canonicalizeJson(obj);\n const bytes = toUtf8Bytes(jcs);\n return (algorithm === \"keccak256\" ? keccak256(bytes) : sha256(bytes)) as Hex;\n}\n","import { keccak256, sha256, toUtf8Bytes } from \"ethers\";\nimport { canonicalizeJson } from \"../identity/data\";\nimport { OmaTrustError } from \"../shared/errors\";\n\ntype Hex = `0x${string}`;\nexport type DataHashAlgorithm = \"keccak256\" | \"sha256\";\n\nasync function fetchJson(url: string): Promise<unknown> {\n let response: Response;\n try {\n response = await fetch(url, { headers: { Accept: \"application/json\" } });\n } catch (err) {\n throw new OmaTrustError(\"NETWORK_ERROR\", \"Failed to fetch data URL\", { url, err });\n }\n\n if (!response.ok) {\n throw new OmaTrustError(\"NETWORK_ERROR\", \"Failed to fetch data URL\", {\n url,\n status: response.status\n });\n }\n\n try {\n return await response.json();\n } catch (err) {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Response body is not valid JSON\", { url, err });\n }\n}\n\nfunction hashJcs(jcsJson: string, algorithm: DataHashAlgorithm): Hex {\n const bytes = toUtf8Bytes(jcsJson);\n return (algorithm === \"keccak256\" ? keccak256(bytes) : sha256(bytes)) as Hex;\n}\n\nexport async function computeDataHashFromUrl(\n url: string,\n algorithm: DataHashAlgorithm\n): Promise<Hex> {\n if (!url || typeof url !== \"string\") {\n throw new OmaTrustError(\"INVALID_INPUT\", \"url must be a non-empty string\", { url });\n }\n\n const json = await fetchJson(url);\n const jcsJson = canonicalizeJson(json);\n return hashJcs(jcsJson, algorithm);\n}\n\nexport async function verifyDataUrlHash(\n url: string,\n expectedHash: Hex,\n algorithm: DataHashAlgorithm\n): Promise<boolean> {\n const computedHash = await computeDataHashFromUrl(url, algorithm);\n return computedHash.toLowerCase() === expectedHash.toLowerCase();\n}\n"]}
1
+ {"version":3,"sources":["../../src/shared/errors.ts","../../src/shared/assert.ts","../../src/app-registry/traits.ts","../../src/app-registry/interfaces.ts","../../src/app-registry/status.ts","../../src/app-registry/version.ts","../../src/app-registry/metadata-keys.ts","../../src/identity/data.ts","../../src/app-registry/data-hash.ts"],"names":["id","canonicalize","toUtf8Bytes","keccak256","sha256"],"mappings":";;;;;;;;;;;;AAAO,IAAM,aAAA,GAAN,cAA4B,KAAA,CAAM;AAAA,EACvC,IAAA;AAAA,EACA,OAAA;AAAA,EAEA,WAAA,CAAY,IAAA,EAAc,OAAA,EAAiB,OAAA,EAAmB;AAC5D,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AACZ,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,OAAA,GAAU,OAAA;AAAA,EACjB;AACF,CAAA;;;ACRO,SAAS,YAAA,CAAa,KAAA,EAAgB,IAAA,EAAc,IAAA,GAAO,eAAA,EAA0C;AAC1G,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,MAAM,IAAA,EAAK,CAAE,WAAW,CAAA,EAAG;AAC1D,IAAA,MAAM,IAAI,cAAc,IAAA,EAAM,CAAA,EAAG,IAAI,CAAA,2BAAA,CAAA,EAA+B,EAAE,OAAO,CAAA;AAAA,EAC/E;AACF;;;ACDO,SAAS,UAAU,KAAA,EAAoB;AAC5C,EAAA,YAAA,CAAa,OAAO,OAAO,CAAA;AAC3B,EAAA,OAAOA,UAAG,KAAK,CAAA;AACjB;AAEO,SAAS,WAAW,MAAA,EAAyB;AAClD,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,MAAM,CAAA,EAAG;AAC1B,IAAA,MAAM,IAAI,UAAU,yBAAyB,CAAA;AAAA,EAC/C;AACA,EAAA,OAAO,OAAO,GAAA,CAAI,CAAC,KAAA,KAAU,SAAA,CAAU,KAAK,CAAC,CAAA;AAC/C;;;ACZA,IAAM,SAAA,GAAY,CAAA;AAClB,IAAM,OAAA,GAAU,CAAA;AAChB,IAAM,YAAA,GAAe,CAAA;AAEd,SAAS,wBAAwB,KAAA,EAA+B;AACrE,EAAA,OAAA,CAAQ,KAAA,CAAM,KAAA,GAAQ,SAAA,GAAY,CAAA,KAC/B,KAAA,CAAM,MAAM,OAAA,GAAU,CAAA,CAAA,IACtB,KAAA,CAAM,aAAA,GAAgB,YAAA,GAAe,CAAA,CAAA;AAC1C;AAEO,SAAS,mBAAmB,MAAA,EAAgC;AACjE,EAAA,OAAO;AAAA,IACL,KAAA,EAAA,CAAQ,SAAS,SAAA,MAAe,CAAA;AAAA,IAChC,GAAA,EAAA,CAAM,SAAS,OAAA,MAAa,CAAA;AAAA,IAC5B,aAAA,EAAA,CAAgB,SAAS,YAAA,MAAkB;AAAA,GAC7C;AACF;AAEO,SAAS,YAAA,CAAa,QAAgB,IAAA,EAA8B;AACzE,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,OAAA;AACH,MAAA,OAAA,CAAQ,SAAS,SAAA,MAAe,CAAA;AAAA,IAClC,KAAK,KAAA;AACH,MAAA,OAAA,CAAQ,SAAS,OAAA,MAAa,CAAA;AAAA,IAChC,KAAK,UAAA;AACH,MAAA,OAAA,CAAQ,SAAS,YAAA,MAAkB,CAAA;AAAA,IACrC;AACE,MAAA,MAAM,IAAI,aAAA,CAAc,eAAA,EAAiB,4BAAA,EAA8B,EAAE,MAAM,CAAA;AAAA;AAErF;AAEO,SAAS,kBAAkB,MAAA,EAAiC;AACjE,EAAA,MAAM,UAA2B,EAAC;AAClC,EAAA,IAAI,YAAA,CAAa,MAAA,EAAQ,OAAO,CAAA,EAAG;AACjC,IAAA,OAAA,CAAQ,KAAK,OAAO,CAAA;AAAA,EACtB;AACA,EAAA,IAAI,YAAA,CAAa,MAAA,EAAQ,KAAK,CAAA,EAAG;AAC/B,IAAA,OAAA,CAAQ,KAAK,KAAK,CAAA;AAAA,EACpB;AACA,EAAA,IAAI,YAAA,CAAa,MAAA,EAAQ,UAAU,CAAA,EAAG;AACpC,IAAA,OAAA,CAAQ,KAAK,UAAU,CAAA;AAAA,EACzB;AACA,EAAA,OAAO,OAAA;AACT;;;AC3CO,SAAS,qBAAqB,IAAA,EAA8B;AACjE,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,CAAA;AACH,MAAA,OAAO,QAAA;AAAA,IACT,KAAK,CAAA;AACH,MAAA,OAAO,YAAA;AAAA,IACT,KAAK,CAAA;AACH,MAAA,OAAO,UAAA;AAAA,IACT;AACE,MAAA,MAAM,IAAI,aAAA,CAAc,eAAA,EAAiB,8BAAA,EAAgC,EAAE,MAAM,CAAA;AAAA;AAEvF;AAEO,SAAS,qBAAqB,MAAA,EAAgC;AACnE,EAAA,QAAQ,MAAA;AAAQ,IACd,KAAK,QAAA;AACH,MAAA,OAAO,CAAA;AAAA,IACT,KAAK,YAAA;AACH,MAAA,OAAO,CAAA;AAAA,IACT,KAAK,UAAA;AACH,MAAA,OAAO,CAAA;AAAA,IACT;AACE,MAAA,MAAM,IAAI,aAAA,CAAc,eAAA,EAAiB,yBAAA,EAA2B,EAAE,QAAQ,CAAA;AAAA;AAEpF;AAEO,SAAS,sBAAsB,MAAA,EAA0C;AAC9E,EAAA,OAAO,MAAA,KAAW,QAAA,IAAY,MAAA,KAAW,YAAA,IAAgB,MAAA,KAAW,UAAA;AACtE;;;AC5BO,SAAS,aAAa,KAAA,EAAwB;AACnD,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,uBAAuB,CAAA;AACjD,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,MAAM,IAAI,aAAA,CAAc,eAAA,EAAiB,0BAAA,EAA4B,EAAE,OAAO,CAAA;AAAA,EAChF;AAEA,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,IACtB,KAAA,EAAO,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC,CAAA;AAAA,IACtB,KAAA,EAAO,MAAA,CAAO,KAAA,CAAM,CAAC,CAAC;AAAA,GACxB;AACF;AAEO,SAAS,cAAc,OAAA,EAA0B;AACtD,EAAA,OAAO,CAAA,EAAG,QAAQ,KAAK,CAAA,CAAA,EAAI,QAAQ,KAAK,CAAA,CAAA,EAAI,QAAQ,KAAK,CAAA,CAAA;AAC3D;AAEO,SAAS,eAAA,CAAgB,GAAY,CAAA,EAAwB;AAClE,EAAA,IAAI,CAAA,CAAE,KAAA,KAAU,CAAA,CAAE,KAAA,EAAO;AACvB,IAAA,OAAO,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAE,KAAA,GAAQ,EAAA,GAAK,CAAA;AAAA,EAClC;AACA,EAAA,IAAI,CAAA,CAAE,KAAA,KAAU,CAAA,CAAE,KAAA,EAAO;AACvB,IAAA,OAAO,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAE,KAAA,GAAQ,EAAA,GAAK,CAAA;AAAA,EAClC;AACA,EAAA,IAAI,CAAA,CAAE,KAAA,KAAU,CAAA,CAAE,KAAA,EAAO;AACvB,IAAA,OAAO,CAAA,CAAE,KAAA,GAAQ,CAAA,CAAE,KAAA,GAAQ,EAAA,GAAK,CAAA;AAAA,EAClC;AACA,EAAA,OAAO,CAAA;AACT;AAEO,SAAS,gBAAA,CAAiB,GAAY,CAAA,EAAqB;AAChE,EAAA,OAAO,eAAA,CAAgB,CAAA,EAAG,CAAC,CAAA,KAAM,CAAA;AACnC;AAEO,SAAS,cAAA,CAAe,GAAY,CAAA,EAAqB;AAC9D,EAAA,OAAO,eAAA,CAAgB,CAAA,EAAG,CAAC,CAAA,KAAM,CAAA;AACnC;AAEO,SAAS,iBAAiB,OAAA,EAA6B;AAC5D,EAAA,IAAI,OAAA,CAAQ,WAAW,CAAA,EAAG;AACxB,IAAA,MAAM,IAAI,aAAA,CAAc,eAAA,EAAiB,iCAAiC,CAAA;AAAA,EAC5E;AAEA,EAAA,OAAO,OAAA,CAAQ,MAAA,CAAO,CAAC,OAAA,EAAS,SAAA,KAAc;AAC5C,IAAA,OAAO,eAAA,CAAgB,SAAA,EAAW,OAAO,CAAA,KAAM,IAAI,SAAA,GAAY,OAAA;AAAA,EACjE,CAAC,CAAA;AACH;;;ACjDO,IAAM,gBAAA,GAAmB;AACzB,IAAM,qBAAA,GAAwB;AAC9B,IAAM,sBAAA,GAAyB;AAC/B,IAAM,gCAAA,GAAmC;AACzC,IAAM,mBAAA,GAAsB;AAC5B,IAAM,uBAAA,GAA0B;AAChC,IAAM,8BAAA,GAAiC;AACvC,IAAM,wBAAA,GAA2B;AACjC,IAAM,0BAAA,GAA6B;AACnC,IAAM,0BAAA,GAA6B;AACnC,IAAM,0BAAA,GAA6B;AACnC,IAAM,yBAAA,GAA4B;AAClC,IAAM,0BAAA,GAA6B;ACH1C,IAAM,cAAA,GAAiB,EAAA;AAEvB,SAAS,gBAAA,CAAiB,OAAe,OAAA,EAAwB;AAC/D,EAAA,IAAI,QAAQ,cAAA,EAAgB;AAC1B,IAAA,MAAM,GAAA,GAAM,UACR,CAAA,sCAAA,EAAyC,cAAc,OAAO,OAAO,CAAA,CAAA,GACrE,yCAAyC,cAAc,CAAA,CAAA;AAC3D,IAAA,MAAM,IAAI,aAAA,CAAc,eAAA,EAAiB,GAAG,CAAA;AAAA,EAC9C;AACF;AAwIO,SAAS,cAAA,CAAe,KAAA,EAAgB,IAAA,GAAe,GAAA,EAAK,QAAgB,CAAA,EAAS;AAC1F,EAAA,gBAAA,CAAiB,OAAO,IAAI,CAAA;AAE5B,EAAA,IAAI,UAAU,MAAA,EAAW;AACvB,IAAA,MAAM,IAAI,aAAA,CAAc,eAAA,EAAiB,CAAA,uBAAA,EAA0B,IAAI,CAAA,WAAA,CAAa,CAAA;AAAA,EACtF;AAEA,EAAA,IAAI,UAAU,IAAA,EAAM;AAEpB,EAAA,QAAQ,OAAO,KAAA;AAAO,IACpB,KAAK,QAAA;AAAA,IACL,KAAK,SAAA;AACH,MAAA;AAAA,IACF,KAAK,QAAA;AACH,MAAA,IAAI,CAAC,MAAA,CAAO,QAAA,CAAS,KAAK,CAAA,EAAG;AAC3B,QAAA,MAAM,IAAI,aAAA,CAAc,eAAA,EAAiB,0BAA0B,IAAI,CAAA,EAAA,EAAK,KAAK,CAAA,wBAAA,CAA0B,CAAA;AAAA,MAC7G;AACA,MAAA;AAAA,IACF,KAAK,QAAA;AACH,MAAA,MAAM,IAAI,aAAA,CAAc,eAAA,EAAiB,CAAA,uBAAA,EAA0B,IAAI,CAAA,+BAAA,CAAiC,CAAA;AAAA,IAC1G,KAAK,UAAA;AACH,MAAA,MAAM,IAAI,aAAA,CAAc,eAAA,EAAiB,CAAA,uBAAA,EAA0B,IAAI,CAAA,UAAA,CAAY,CAAA;AAAA,IACrF,KAAK,QAAA;AACH,MAAA,MAAM,IAAI,aAAA,CAAc,eAAA,EAAiB,CAAA,uBAAA,EAA0B,IAAI,CAAA,QAAA,CAAU,CAAA;AAAA,IACnF,KAAK,QAAA;AACH,MAAA,IAAI,iBAAiB,IAAA,EAAM;AACzB,QAAA,MAAM,IAAI,aAAA,CAAc,eAAA,EAAiB,CAAA,uBAAA,EAA0B,IAAI,CAAA,oCAAA,CAAsC,CAAA;AAAA,MAC/G;AACA,MAAA,IAAI,iBAAiB,MAAA,EAAQ;AAC3B,QAAA,MAAM,IAAI,aAAA,CAAc,eAAA,EAAiB,CAAA,uBAAA,EAA0B,IAAI,CAAA,QAAA,CAAU,CAAA;AAAA,MACnF;AACA,MAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,QAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,CAAM,QAAQ,CAAA,EAAA,EAAK;AACrC,UAAA,cAAA,CAAe,KAAA,CAAM,CAAC,CAAA,EAAG,CAAA,EAAG,IAAI,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA,CAAA,EAAK,KAAA,GAAQ,CAAC,CAAA;AAAA,QACrD;AACA,QAAA;AAAA,MACF;AAEA,MAAA,KAAA,MAAW,CAAC,GAAA,EAAK,GAAG,KAAK,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,EAAG;AAC9C,QAAA,cAAA,CAAe,KAAK,CAAA,EAAG,IAAI,IAAI,GAAG,CAAA,CAAA,EAAI,QAAQ,CAAC,CAAA;AAAA,MACjD;AACA,MAAA;AAAA,IACF;AACE,MAAA,MAAM,IAAI,cAAc,eAAA,EAAiB,CAAA,uBAAA,EAA0B,IAAI,CAAA,gBAAA,EAAmB,OAAO,KAAK,CAAA,CAAA,CAAG,CAAA;AAAA;AAE/G;AAEO,SAAS,iBAAiB,GAAA,EAAsB;AACrD,EAAA,cAAA,CAAe,GAAG,CAAA;AAClB,EAAA,MAAM,GAAA,GAAMC,8BAAa,GAAG,CAAA;AAC5B,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,MAAM,IAAI,aAAA,CAAc,eAAA,EAAiB,gCAAA,EAAkC,EAAE,KAAK,CAAA;AAAA,EACpF;AACA,EAAA,OAAO,GAAA;AACT;;;ACzMA,eAAe,UAAU,GAAA,EAA+B;AACtD,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI;AACF,IAAA,QAAA,GAAW,MAAM,MAAM,GAAA,EAAK,EAAE,SAAS,EAAE,MAAA,EAAQ,kBAAA,EAAmB,EAAG,CAAA;AAAA,EACzE,SAAS,GAAA,EAAK;AACZ,IAAA,MAAM,IAAI,aAAA,CAAc,eAAA,EAAiB,4BAA4B,EAAE,GAAA,EAAK,KAAK,CAAA;AAAA,EACnF;AAEA,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,IAAI,aAAA,CAAc,eAAA,EAAiB,0BAAA,EAA4B;AAAA,MACnE,GAAA;AAAA,MACA,QAAQ,QAAA,CAAS;AAAA,KAClB,CAAA;AAAA,EACH;AAEA,EAAA,IAAI;AACF,IAAA,OAAO,MAAM,SAAS,IAAA,EAAK;AAAA,EAC7B,SAAS,GAAA,EAAK;AACZ,IAAA,MAAM,IAAI,aAAA,CAAc,eAAA,EAAiB,mCAAmC,EAAE,GAAA,EAAK,KAAK,CAAA;AAAA,EAC1F;AACF;AAEA,SAAS,OAAA,CAAQ,SAAiB,SAAA,EAAmC;AACnE,EAAA,MAAM,KAAA,GAAQC,mBAAY,OAAO,CAAA;AACjC,EAAA,OAAQ,cAAc,WAAA,GAAcC,gBAAAA,CAAU,KAAK,CAAA,GAAIC,cAAO,KAAK,CAAA;AACrE;AAEA,eAAsB,sBAAA,CACpB,KACA,SAAA,EACc;AACd,EAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,QAAA,EAAU;AACnC,IAAA,MAAM,IAAI,aAAA,CAAc,eAAA,EAAiB,gCAAA,EAAkC,EAAE,KAAK,CAAA;AAAA,EACpF;AAEA,EAAA,IAAI,SAAA,KAAc,WAAA,IAAe,SAAA,KAAc,QAAA,EAAU;AACvD,IAAA,MAAM,IAAI,cAAc,eAAA,EAAiB,CAAA,6BAAA,EAAgC,SAAS,CAAA,mCAAA,CAAA,EAAuC,EAAE,WAAW,CAAA;AAAA,EACxI;AAEA,EAAA,MAAM,IAAA,GAAO,MAAM,SAAA,CAAU,GAAG,CAAA;AAChC,EAAA,MAAM,OAAA,GAAU,iBAAiB,IAAI,CAAA;AACrC,EAAA,OAAO,OAAA,CAAQ,SAAS,SAAS,CAAA;AACnC;AAEA,eAAsB,iBAAA,CACpB,GAAA,EACA,YAAA,EACA,SAAA,EACkB;AAClB,EAAA,MAAM,YAAA,GAAe,MAAM,sBAAA,CAAuB,GAAA,EAAK,SAAS,CAAA;AAChE,EAAA,OAAO,YAAA,CAAa,WAAA,EAAY,KAAM,YAAA,CAAa,WAAA,EAAY;AACjE","file":"index.cjs","sourcesContent":["export class OmaTrustError extends Error {\n code: string;\n details?: unknown;\n\n constructor(code: string, message: string, details?: unknown) {\n super(message);\n this.name = \"OmaTrustError\";\n this.code = code;\n this.details = details;\n }\n}\n\nexport function toOmaTrustError(\n code: string,\n message: string,\n details?: unknown\n): OmaTrustError {\n return new OmaTrustError(code, message, details);\n}\n","import { OmaTrustError } from \"./errors\";\n\nexport function assertString(value: unknown, name: string, code = \"INVALID_INPUT\"): asserts value is string {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new OmaTrustError(code, `${name} must be a non-empty string`, { value });\n }\n}\n\nexport function assertNumber(value: unknown, name: string, code = \"INVALID_INPUT\"): asserts value is number {\n if (typeof value !== \"number\" || Number.isNaN(value)) {\n throw new OmaTrustError(code, `${name} must be a valid number`, { value });\n }\n}\n\nexport function assertObject(value: unknown, name: string, code = \"INVALID_INPUT\"): asserts value is Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new OmaTrustError(code, `${name} must be an object`, { value });\n }\n}\n\nexport function asError(err: unknown): Error {\n if (err instanceof Error) {\n return err;\n }\n return new Error(String(err));\n}\n","import { id } from \"ethers\";\nimport { assertString } from \"../shared/assert\";\n\ntype Hex = `0x${string}`;\n\nexport function hashTrait(trait: string): Hex {\n assertString(trait, \"trait\");\n return id(trait) as Hex;\n}\n\nexport function hashTraits(traits: string[]): Hex[] {\n if (!Array.isArray(traits)) {\n throw new TypeError(\"traits must be an array\");\n }\n return traits.map((trait) => hashTrait(trait));\n}\n","import type { InterfaceFlags, InterfaceType } from \"./types\";\nimport { OmaTrustError } from \"../shared/errors\";\n\nconst BIT_HUMAN = 1;\nconst BIT_API = 2;\nconst BIT_CONTRACT = 4;\n\nexport function computeInterfacesBitmap(flags: InterfaceFlags): number {\n return (flags.human ? BIT_HUMAN : 0) +\n (flags.api ? BIT_API : 0) +\n (flags.smartContract ? BIT_CONTRACT : 0);\n}\n\nexport function parseBitmapToFlags(bitmap: number): InterfaceFlags {\n return {\n human: (bitmap & BIT_HUMAN) !== 0,\n api: (bitmap & BIT_API) !== 0,\n smartContract: (bitmap & BIT_CONTRACT) !== 0\n };\n}\n\nexport function hasInterface(bitmap: number, type: InterfaceType): boolean {\n switch (type) {\n case \"human\":\n return (bitmap & BIT_HUMAN) !== 0;\n case \"api\":\n return (bitmap & BIT_API) !== 0;\n case \"contract\":\n return (bitmap & BIT_CONTRACT) !== 0;\n default:\n throw new OmaTrustError(\"INVALID_INPUT\", \"Unsupported interface type\", { type });\n }\n}\n\nexport function getInterfaceTypes(bitmap: number): InterfaceType[] {\n const results: InterfaceType[] = [];\n if (hasInterface(bitmap, \"human\")) {\n results.push(\"human\");\n }\n if (hasInterface(bitmap, \"api\")) {\n results.push(\"api\");\n }\n if (hasInterface(bitmap, \"contract\")) {\n results.push(\"contract\");\n }\n return results;\n}\n","import type { RegistryStatus } from \"./types\";\nimport { OmaTrustError } from \"../shared/errors\";\n\nexport function registryCodeToStatus(code: number): RegistryStatus {\n switch (code) {\n case 0:\n return \"Active\";\n case 1:\n return \"Deprecated\";\n case 2:\n return \"Replaced\";\n default:\n throw new OmaTrustError(\"INVALID_INPUT\", \"Invalid registry status code\", { code });\n }\n}\n\nexport function registryStatusToCode(status: RegistryStatus): number {\n switch (status) {\n case \"Active\":\n return 0;\n case \"Deprecated\":\n return 1;\n case \"Replaced\":\n return 2;\n default:\n throw new OmaTrustError(\"INVALID_INPUT\", \"Invalid registry status\", { status });\n }\n}\n\nexport function isValidRegistryStatus(status: string): status is RegistryStatus {\n return status === \"Active\" || status === \"Deprecated\" || status === \"Replaced\";\n}\n","import type { Version } from \"./types\";\nimport { OmaTrustError } from \"../shared/errors\";\n\nexport function parseVersion(input: string): Version {\n const match = input.match(/^(\\d+)\\.(\\d+)\\.(\\d+)$/);\n if (!match) {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Invalid semantic version\", { input });\n }\n\n return {\n major: Number(match[1]),\n minor: Number(match[2]),\n patch: Number(match[3])\n };\n}\n\nexport function formatVersion(version: Version): string {\n return `${version.major}.${version.minor}.${version.patch}`;\n}\n\nexport function compareVersions(a: Version, b: Version): -1 | 0 | 1 {\n if (a.major !== b.major) {\n return a.major < b.major ? -1 : 1;\n }\n if (a.minor !== b.minor) {\n return a.minor < b.minor ? -1 : 1;\n }\n if (a.patch !== b.patch) {\n return a.patch < b.patch ? -1 : 1;\n }\n return 0;\n}\n\nexport function isVersionGreater(a: Version, b: Version): boolean {\n return compareVersions(a, b) === 1;\n}\n\nexport function isVersionEqual(a: Version, b: Version): boolean {\n return compareVersions(a, b) === 0;\n}\n\nexport function getLatestVersion(history: Version[]): Version {\n if (history.length === 0) {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Version history cannot be empty\");\n }\n\n return history.reduce((current, candidate) => {\n return compareVersions(candidate, current) === 1 ? candidate : current;\n });\n}\n","export const METADATA_KEY_DID = \"omat.did\";\nexport const METADATA_KEY_DID_HASH = \"omat.didHash\";\nexport const METADATA_KEY_DATA_HASH = \"omat.dataHash\";\nexport const METADATA_KEY_DATA_HASH_ALGORITHM = \"omat.dataHashAlgorithm\";\nexport const METADATA_KEY_STATUS = \"omat.status\";\nexport const METADATA_KEY_INTERFACES = \"omat.interfaces\";\nexport const METADATA_KEY_FUNGIBLE_TOKEN_ID = \"omat.fungibleTokenId\";\nexport const METADATA_KEY_CONTRACT_ID = \"omat.contractId\";\nexport const METADATA_KEY_VERSION_MAJOR = \"omat.versionMajor\";\nexport const METADATA_KEY_VERSION_MINOR = \"omat.versionMinor\";\nexport const METADATA_KEY_VERSION_PATCH = \"omat.versionPatch\";\nexport const METADATA_KEY_TRAIT_HASHES = \"omat.traitHashes\";\nexport const METADATA_KEY_METADATA_JSON = \"omat.metadataJson\";\n","import canonicalize from \"canonicalize\";\nimport { keccak256, sha256, toUtf8Bytes } from \"ethers\";\nimport { OmaTrustError } from \"../shared/errors\";\n\ntype Hex = `0x${string}`;\n\nconst VALID_ALGORITHMS = new Set([\"keccak256\", \"sha256\"]);\n\n/** Maximum JSON nesting depth allowed. */\nconst MAX_JSON_DEPTH = 32;\n\nfunction assertDepthLimit(depth: number, context?: string): void {\n if (depth > MAX_JSON_DEPTH) {\n const msg = context\n ? `JSON nesting depth exceeds maximum of ${MAX_JSON_DEPTH} at ${context}`\n : `JSON nesting depth exceeds maximum of ${MAX_JSON_DEPTH}`;\n throw new OmaTrustError(\"INVALID_INPUT\", msg);\n }\n}\n\n/**\n * Parse JSON strictly, rejecting duplicate keys.\n * Standard JSON.parse() silently accepts duplicates (last-wins).\n * This function detects duplicates at any nesting depth and throws.\n */\nexport function parseJsonStrict(input: string): unknown {\n if (typeof input !== \"string\") {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Input must be a string\");\n }\n\n // First pass: detect duplicate keys by scanning object literals\n const seen = new Map<string, Set<string>>();\n let pathStack: string[] = [];\n let depth = 0;\n\n // Use a reviver to track keys at each depth\n const keyTracker = new Map<number, Set<string>>();\n\n // Parse with a reviver that tracks keys per object depth\n // JSON.parse calls the reviver bottom-up, so we use a different approach:\n // scan the raw string for duplicate keys using a state machine.\n const duplicateKeys = detectDuplicateKeys(input);\n if (duplicateKeys.length > 0) {\n throw new OmaTrustError(\n \"INVALID_INPUT\",\n `Duplicate JSON key${duplicateKeys.length > 1 ? \"s\" : \"\"} detected: ${duplicateKeys.map(k => `\"${k}\"`).join(\", \")}`,\n { duplicateKeys }\n );\n }\n\n try {\n return JSON.parse(input);\n } catch {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Input is not valid JSON\");\n }\n}\n\n/**\n * Detect duplicate keys in a JSON string.\n * Returns an array of key names that appear more than once in any single object.\n */\nfunction detectDuplicateKeys(input: string): string[] {\n const duplicates: string[] = [];\n // Stack of sets — each set tracks keys for the current object nesting level\n const objectKeyStack: Set<string>[] = [];\n let inString = false;\n let escaped = false;\n let currentKey = \"\";\n let collectingKey = false;\n let afterColon = false;\n let i = 0;\n\n while (i < input.length) {\n const ch = input[i];\n\n if (escaped) {\n if (collectingKey) currentKey += ch;\n escaped = false;\n i++;\n continue;\n }\n\n if (ch === \"\\\\\") {\n escaped = true;\n if (collectingKey) currentKey += ch;\n i++;\n continue;\n }\n\n if (ch === '\"') {\n if (!inString) {\n inString = true;\n // If we're in an object context and not after a colon, this is a key\n if (objectKeyStack.length > 0 && !afterColon) {\n collectingKey = true;\n currentKey = \"\";\n }\n } else {\n inString = false;\n if (collectingKey) {\n collectingKey = false;\n const keySet = objectKeyStack[objectKeyStack.length - 1];\n if (keySet.has(currentKey)) {\n if (!duplicates.includes(currentKey)) {\n duplicates.push(currentKey);\n }\n } else {\n keySet.add(currentKey);\n }\n }\n }\n i++;\n continue;\n }\n\n if (inString) {\n if (collectingKey) currentKey += ch;\n i++;\n continue;\n }\n\n // Outside string\n if (ch === \"{\") {\n objectKeyStack.push(new Set());\n assertDepthLimit(objectKeyStack.length);\n afterColon = false;\n } else if (ch === \"}\") {\n objectKeyStack.pop();\n afterColon = objectKeyStack.length > 0; // restore parent context\n } else if (ch === \"[\") {\n // Arrays don't have keys — push a sentinel\n objectKeyStack.push(new Set([\"__array__\"]));\n assertDepthLimit(objectKeyStack.length);\n afterColon = false;\n } else if (ch === \"]\") {\n objectKeyStack.pop();\n afterColon = objectKeyStack.length > 0;\n } else if (ch === \":\") {\n afterColon = true;\n } else if (ch === \",\") {\n afterColon = false;\n }\n\n i++;\n }\n\n return duplicates;\n}\n\n/**\n * Assert that a value is JSON-safe (representable in JSON without lossy conversion).\n * Rejects: undefined, NaN, Infinity, -Infinity, BigInt, functions, symbols, Date objects.\n * These values would be silently coerced or dropped by JSON.stringify / canonicalize.\n */\nexport function assertJsonSafe(value: unknown, path: string = \"$\", depth: number = 0): void {\n assertDepthLimit(depth, path);\n\n if (value === undefined) {\n throw new OmaTrustError(\"INVALID_INPUT\", `Non-JSON-safe value at ${path}: undefined`);\n }\n\n if (value === null) return;\n\n switch (typeof value) {\n case \"string\":\n case \"boolean\":\n return;\n case \"number\":\n if (!Number.isFinite(value)) {\n throw new OmaTrustError(\"INVALID_INPUT\", `Non-JSON-safe value at ${path}: ${value} (must be finite number)`);\n }\n return;\n case \"bigint\":\n throw new OmaTrustError(\"INVALID_INPUT\", `Non-JSON-safe value at ${path}: BigInt (use number or string)`);\n case \"function\":\n throw new OmaTrustError(\"INVALID_INPUT\", `Non-JSON-safe value at ${path}: function`);\n case \"symbol\":\n throw new OmaTrustError(\"INVALID_INPUT\", `Non-JSON-safe value at ${path}: Symbol`);\n case \"object\":\n if (value instanceof Date) {\n throw new OmaTrustError(\"INVALID_INPUT\", `Non-JSON-safe value at ${path}: Date (use ISO string or timestamp)`);\n }\n if (value instanceof RegExp) {\n throw new OmaTrustError(\"INVALID_INPUT\", `Non-JSON-safe value at ${path}: RegExp`);\n }\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n assertJsonSafe(value[i], `${path}[${i}]`, depth + 1);\n }\n return;\n }\n // Plain object\n for (const [key, val] of Object.entries(value)) {\n assertJsonSafe(val, `${path}.${key}`, depth + 1);\n }\n return;\n default:\n throw new OmaTrustError(\"INVALID_INPUT\", `Non-JSON-safe value at ${path}: unknown type \"${typeof value}\"`);\n }\n}\n\nexport function canonicalizeJson(obj: unknown): string {\n assertJsonSafe(obj);\n const jcs = canonicalize(obj);\n if (!jcs) {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Object cannot be canonicalized\", { obj });\n }\n return jcs;\n}\n\n/**\n * Canonicalize a JSON object (JCS / RFC 8785) and compute its keccak256 hash.\n * Returns both the canonical JCS string and the 0x-prefixed hash.\n */\nexport function canonicalizeAndKeccak256(obj: unknown): { jcsJson: string; hash: Hex } {\n const jcsJson = canonicalizeJson(obj);\n return {\n jcsJson,\n hash: keccak256(toUtf8Bytes(jcsJson)) as Hex\n };\n}\n\n/** @deprecated Use canonicalizeAndKeccak256 instead. */\nexport function canonicalizeForHash(obj: unknown): { jcsJson: string; hash: Hex } {\n return canonicalizeAndKeccak256(obj);\n}\n\nexport function hashCanonicalizedJson(obj: unknown, algorithm: \"keccak256\" | \"sha256\"): Hex {\n if (!VALID_ALGORITHMS.has(algorithm)) {\n throw new OmaTrustError(\"INVALID_INPUT\", `Unsupported hash algorithm: \"${algorithm}\". Must be \"keccak256\" or \"sha256\".`, { algorithm });\n }\n const jcs = canonicalizeJson(obj);\n const bytes = toUtf8Bytes(jcs);\n return (algorithm === \"keccak256\" ? keccak256(bytes) : sha256(bytes)) as Hex;\n}\n","import { keccak256, sha256, toUtf8Bytes } from \"ethers\";\nimport { canonicalizeJson } from \"../identity/data\";\nimport { OmaTrustError } from \"../shared/errors\";\n\ntype Hex = `0x${string}`;\nexport type DataHashAlgorithm = \"keccak256\" | \"sha256\";\n\nasync function fetchJson(url: string): Promise<unknown> {\n let response: Response;\n try {\n response = await fetch(url, { headers: { Accept: \"application/json\" } });\n } catch (err) {\n throw new OmaTrustError(\"NETWORK_ERROR\", \"Failed to fetch data URL\", { url, err });\n }\n\n if (!response.ok) {\n throw new OmaTrustError(\"NETWORK_ERROR\", \"Failed to fetch data URL\", {\n url,\n status: response.status\n });\n }\n\n try {\n return await response.json();\n } catch (err) {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Response body is not valid JSON\", { url, err });\n }\n}\n\nfunction hashJcs(jcsJson: string, algorithm: DataHashAlgorithm): Hex {\n const bytes = toUtf8Bytes(jcsJson);\n return (algorithm === \"keccak256\" ? keccak256(bytes) : sha256(bytes)) as Hex;\n}\n\nexport async function computeDataHashFromUrl(\n url: string,\n algorithm: DataHashAlgorithm\n): Promise<Hex> {\n if (!url || typeof url !== \"string\") {\n throw new OmaTrustError(\"INVALID_INPUT\", \"url must be a non-empty string\", { url });\n }\n\n if (algorithm !== \"keccak256\" && algorithm !== \"sha256\") {\n throw new OmaTrustError(\"INVALID_INPUT\", `Unsupported hash algorithm: \"${algorithm}\". Must be \"keccak256\" or \"sha256\".`, { algorithm });\n }\n\n const json = await fetchJson(url);\n const jcsJson = canonicalizeJson(json);\n return hashJcs(jcsJson, algorithm);\n}\n\nexport async function verifyDataUrlHash(\n url: string,\n expectedHash: Hex,\n algorithm: DataHashAlgorithm\n): Promise<boolean> {\n const computedHash = await computeDataHashFromUrl(url, algorithm);\n return computedHash.toLowerCase() === expectedHash.toLowerCase();\n}\n"]}
@@ -159,7 +159,57 @@ var METADATA_KEY_VERSION_MINOR = "omat.versionMinor";
159
159
  var METADATA_KEY_VERSION_PATCH = "omat.versionPatch";
160
160
  var METADATA_KEY_TRAIT_HASHES = "omat.traitHashes";
161
161
  var METADATA_KEY_METADATA_JSON = "omat.metadataJson";
162
+ var MAX_JSON_DEPTH = 32;
163
+ function assertDepthLimit(depth, context) {
164
+ if (depth > MAX_JSON_DEPTH) {
165
+ const msg = context ? `JSON nesting depth exceeds maximum of ${MAX_JSON_DEPTH} at ${context}` : `JSON nesting depth exceeds maximum of ${MAX_JSON_DEPTH}`;
166
+ throw new OmaTrustError("INVALID_INPUT", msg);
167
+ }
168
+ }
169
+ function assertJsonSafe(value, path = "$", depth = 0) {
170
+ assertDepthLimit(depth, path);
171
+ if (value === void 0) {
172
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: undefined`);
173
+ }
174
+ if (value === null) return;
175
+ switch (typeof value) {
176
+ case "string":
177
+ case "boolean":
178
+ return;
179
+ case "number":
180
+ if (!Number.isFinite(value)) {
181
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: ${value} (must be finite number)`);
182
+ }
183
+ return;
184
+ case "bigint":
185
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: BigInt (use number or string)`);
186
+ case "function":
187
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: function`);
188
+ case "symbol":
189
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: Symbol`);
190
+ case "object":
191
+ if (value instanceof Date) {
192
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: Date (use ISO string or timestamp)`);
193
+ }
194
+ if (value instanceof RegExp) {
195
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: RegExp`);
196
+ }
197
+ if (Array.isArray(value)) {
198
+ for (let i = 0; i < value.length; i++) {
199
+ assertJsonSafe(value[i], `${path}[${i}]`, depth + 1);
200
+ }
201
+ return;
202
+ }
203
+ for (const [key, val] of Object.entries(value)) {
204
+ assertJsonSafe(val, `${path}.${key}`, depth + 1);
205
+ }
206
+ return;
207
+ default:
208
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: unknown type "${typeof value}"`);
209
+ }
210
+ }
162
211
  function canonicalizeJson(obj) {
212
+ assertJsonSafe(obj);
163
213
  const jcs = canonicalize(obj);
164
214
  if (!jcs) {
165
215
  throw new OmaTrustError("INVALID_INPUT", "Object cannot be canonicalized", { obj });
@@ -195,6 +245,9 @@ async function computeDataHashFromUrl(url, algorithm) {
195
245
  if (!url || typeof url !== "string") {
196
246
  throw new OmaTrustError("INVALID_INPUT", "url must be a non-empty string", { url });
197
247
  }
248
+ if (algorithm !== "keccak256" && algorithm !== "sha256") {
249
+ throw new OmaTrustError("INVALID_INPUT", `Unsupported hash algorithm: "${algorithm}". Must be "keccak256" or "sha256".`, { algorithm });
250
+ }
198
251
  const json = await fetchJson(url);
199
252
  const jcsJson = canonicalizeJson(json);
200
253
  return hashJcs(jcsJson, algorithm);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/shared/errors.ts","../../src/shared/assert.ts","../../src/app-registry/traits.ts","../../src/app-registry/interfaces.ts","../../src/app-registry/status.ts","../../src/app-registry/version.ts","../../src/app-registry/metadata-keys.ts","../../src/identity/data.ts","../../src/app-registry/data-hash.ts"],"names":["toUtf8Bytes","keccak256","sha256"],"mappings":"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","file":"index.js","sourcesContent":["export class OmaTrustError extends Error {\n code: string;\n details?: unknown;\n\n constructor(code: string, message: string, details?: unknown) {\n super(message);\n this.name = \"OmaTrustError\";\n this.code = code;\n this.details = details;\n }\n}\n\nexport function toOmaTrustError(\n code: string,\n message: string,\n details?: unknown\n): OmaTrustError {\n return new OmaTrustError(code, message, details);\n}\n","import { OmaTrustError } from \"./errors\";\n\nexport function assertString(value: unknown, name: string, code = \"INVALID_INPUT\"): asserts value is string {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new OmaTrustError(code, `${name} must be a non-empty string`, { value });\n }\n}\n\nexport function assertNumber(value: unknown, name: string, code = \"INVALID_INPUT\"): asserts value is number {\n if (typeof value !== \"number\" || Number.isNaN(value)) {\n throw new OmaTrustError(code, `${name} must be a valid number`, { value });\n }\n}\n\nexport function assertObject(value: unknown, name: string, code = \"INVALID_INPUT\"): asserts value is Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new OmaTrustError(code, `${name} must be an object`, { value });\n }\n}\n\nexport function asError(err: unknown): Error {\n if (err instanceof Error) {\n return err;\n }\n return new Error(String(err));\n}\n","import { id } from \"ethers\";\nimport { assertString } from \"../shared/assert\";\n\ntype Hex = `0x${string}`;\n\nexport function hashTrait(trait: string): Hex {\n assertString(trait, \"trait\");\n return id(trait) as Hex;\n}\n\nexport function hashTraits(traits: string[]): Hex[] {\n if (!Array.isArray(traits)) {\n throw new TypeError(\"traits must be an array\");\n }\n return traits.map((trait) => hashTrait(trait));\n}\n","import type { InterfaceFlags, InterfaceType } from \"./types\";\nimport { OmaTrustError } from \"../shared/errors\";\n\nconst BIT_HUMAN = 1;\nconst BIT_API = 2;\nconst BIT_CONTRACT = 4;\n\nexport function computeInterfacesBitmap(flags: InterfaceFlags): number {\n return (flags.human ? BIT_HUMAN : 0) +\n (flags.api ? BIT_API : 0) +\n (flags.smartContract ? BIT_CONTRACT : 0);\n}\n\nexport function parseBitmapToFlags(bitmap: number): InterfaceFlags {\n return {\n human: (bitmap & BIT_HUMAN) !== 0,\n api: (bitmap & BIT_API) !== 0,\n smartContract: (bitmap & BIT_CONTRACT) !== 0\n };\n}\n\nexport function hasInterface(bitmap: number, type: InterfaceType): boolean {\n switch (type) {\n case \"human\":\n return (bitmap & BIT_HUMAN) !== 0;\n case \"api\":\n return (bitmap & BIT_API) !== 0;\n case \"contract\":\n return (bitmap & BIT_CONTRACT) !== 0;\n default:\n throw new OmaTrustError(\"INVALID_INPUT\", \"Unsupported interface type\", { type });\n }\n}\n\nexport function getInterfaceTypes(bitmap: number): InterfaceType[] {\n const results: InterfaceType[] = [];\n if (hasInterface(bitmap, \"human\")) {\n results.push(\"human\");\n }\n if (hasInterface(bitmap, \"api\")) {\n results.push(\"api\");\n }\n if (hasInterface(bitmap, \"contract\")) {\n results.push(\"contract\");\n }\n return results;\n}\n","import type { RegistryStatus } from \"./types\";\nimport { OmaTrustError } from \"../shared/errors\";\n\nexport function registryCodeToStatus(code: number): RegistryStatus {\n switch (code) {\n case 0:\n return \"Active\";\n case 1:\n return \"Deprecated\";\n case 2:\n return \"Replaced\";\n default:\n throw new OmaTrustError(\"INVALID_INPUT\", \"Invalid registry status code\", { code });\n }\n}\n\nexport function registryStatusToCode(status: RegistryStatus): number {\n switch (status) {\n case \"Active\":\n return 0;\n case \"Deprecated\":\n return 1;\n case \"Replaced\":\n return 2;\n default:\n throw new OmaTrustError(\"INVALID_INPUT\", \"Invalid registry status\", { status });\n }\n}\n\nexport function isValidRegistryStatus(status: string): status is RegistryStatus {\n return status === \"Active\" || status === \"Deprecated\" || status === \"Replaced\";\n}\n","import type { Version } from \"./types\";\nimport { OmaTrustError } from \"../shared/errors\";\n\nexport function parseVersion(input: string): Version {\n const match = input.match(/^(\\d+)\\.(\\d+)\\.(\\d+)$/);\n if (!match) {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Invalid semantic version\", { input });\n }\n\n return {\n major: Number(match[1]),\n minor: Number(match[2]),\n patch: Number(match[3])\n };\n}\n\nexport function formatVersion(version: Version): string {\n return `${version.major}.${version.minor}.${version.patch}`;\n}\n\nexport function compareVersions(a: Version, b: Version): -1 | 0 | 1 {\n if (a.major !== b.major) {\n return a.major < b.major ? -1 : 1;\n }\n if (a.minor !== b.minor) {\n return a.minor < b.minor ? -1 : 1;\n }\n if (a.patch !== b.patch) {\n return a.patch < b.patch ? -1 : 1;\n }\n return 0;\n}\n\nexport function isVersionGreater(a: Version, b: Version): boolean {\n return compareVersions(a, b) === 1;\n}\n\nexport function isVersionEqual(a: Version, b: Version): boolean {\n return compareVersions(a, b) === 0;\n}\n\nexport function getLatestVersion(history: Version[]): Version {\n if (history.length === 0) {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Version history cannot be empty\");\n }\n\n return history.reduce((current, candidate) => {\n return compareVersions(candidate, current) === 1 ? candidate : current;\n });\n}\n","export const METADATA_KEY_DID = \"omat.did\";\nexport const METADATA_KEY_DID_HASH = \"omat.didHash\";\nexport const METADATA_KEY_DATA_HASH = \"omat.dataHash\";\nexport const METADATA_KEY_DATA_HASH_ALGORITHM = \"omat.dataHashAlgorithm\";\nexport const METADATA_KEY_STATUS = \"omat.status\";\nexport const METADATA_KEY_INTERFACES = \"omat.interfaces\";\nexport const METADATA_KEY_FUNGIBLE_TOKEN_ID = \"omat.fungibleTokenId\";\nexport const METADATA_KEY_CONTRACT_ID = \"omat.contractId\";\nexport const METADATA_KEY_VERSION_MAJOR = \"omat.versionMajor\";\nexport const METADATA_KEY_VERSION_MINOR = \"omat.versionMinor\";\nexport const METADATA_KEY_VERSION_PATCH = \"omat.versionPatch\";\nexport const METADATA_KEY_TRAIT_HASHES = \"omat.traitHashes\";\nexport const METADATA_KEY_METADATA_JSON = \"omat.metadataJson\";\n","import canonicalize from \"canonicalize\";\nimport { keccak256, sha256, toUtf8Bytes } from \"ethers\";\nimport { OmaTrustError } from \"../shared/errors\";\n\ntype Hex = `0x${string}`;\n\nexport function canonicalizeJson(obj: unknown): string {\n const jcs = canonicalize(obj);\n if (!jcs) {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Object cannot be canonicalized\", { obj });\n }\n return jcs;\n}\n\nexport function canonicalizeForHash(obj: unknown): { jcsJson: string; hash: Hex } {\n const jcsJson = canonicalizeJson(obj);\n return {\n jcsJson,\n hash: keccak256(toUtf8Bytes(jcsJson)) as Hex\n };\n}\n\nexport function hashCanonicalizedJson(obj: unknown, algorithm: \"keccak256\" | \"sha256\"): Hex {\n const jcs = canonicalizeJson(obj);\n const bytes = toUtf8Bytes(jcs);\n return (algorithm === \"keccak256\" ? keccak256(bytes) : sha256(bytes)) as Hex;\n}\n","import { keccak256, sha256, toUtf8Bytes } from \"ethers\";\nimport { canonicalizeJson } from \"../identity/data\";\nimport { OmaTrustError } from \"../shared/errors\";\n\ntype Hex = `0x${string}`;\nexport type DataHashAlgorithm = \"keccak256\" | \"sha256\";\n\nasync function fetchJson(url: string): Promise<unknown> {\n let response: Response;\n try {\n response = await fetch(url, { headers: { Accept: \"application/json\" } });\n } catch (err) {\n throw new OmaTrustError(\"NETWORK_ERROR\", \"Failed to fetch data URL\", { url, err });\n }\n\n if (!response.ok) {\n throw new OmaTrustError(\"NETWORK_ERROR\", \"Failed to fetch data URL\", {\n url,\n status: response.status\n });\n }\n\n try {\n return await response.json();\n } catch (err) {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Response body is not valid JSON\", { url, err });\n }\n}\n\nfunction hashJcs(jcsJson: string, algorithm: DataHashAlgorithm): Hex {\n const bytes = toUtf8Bytes(jcsJson);\n return (algorithm === \"keccak256\" ? keccak256(bytes) : sha256(bytes)) as Hex;\n}\n\nexport async function computeDataHashFromUrl(\n url: string,\n algorithm: DataHashAlgorithm\n): Promise<Hex> {\n if (!url || typeof url !== \"string\") {\n throw new OmaTrustError(\"INVALID_INPUT\", \"url must be a non-empty string\", { url });\n }\n\n const json = await fetchJson(url);\n const jcsJson = canonicalizeJson(json);\n return hashJcs(jcsJson, algorithm);\n}\n\nexport async function verifyDataUrlHash(\n url: string,\n expectedHash: Hex,\n algorithm: DataHashAlgorithm\n): Promise<boolean> {\n const computedHash = await computeDataHashFromUrl(url, algorithm);\n return computedHash.toLowerCase() === expectedHash.toLowerCase();\n}\n"]}
1
+ {"version":3,"sources":["../../src/shared/errors.ts","../../src/shared/assert.ts","../../src/app-registry/traits.ts","../../src/app-registry/interfaces.ts","../../src/app-registry/status.ts","../../src/app-registry/version.ts","../../src/app-registry/metadata-keys.ts","../../src/identity/data.ts","../../src/app-registry/data-hash.ts"],"names":["toUtf8Bytes","keccak256","sha256"],"mappings":"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","file":"index.js","sourcesContent":["export class OmaTrustError extends Error {\n code: string;\n details?: unknown;\n\n constructor(code: string, message: string, details?: unknown) {\n super(message);\n this.name = \"OmaTrustError\";\n this.code = code;\n this.details = details;\n }\n}\n\nexport function toOmaTrustError(\n code: string,\n message: string,\n details?: unknown\n): OmaTrustError {\n return new OmaTrustError(code, message, details);\n}\n","import { OmaTrustError } from \"./errors\";\n\nexport function assertString(value: unknown, name: string, code = \"INVALID_INPUT\"): asserts value is string {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n throw new OmaTrustError(code, `${name} must be a non-empty string`, { value });\n }\n}\n\nexport function assertNumber(value: unknown, name: string, code = \"INVALID_INPUT\"): asserts value is number {\n if (typeof value !== \"number\" || Number.isNaN(value)) {\n throw new OmaTrustError(code, `${name} must be a valid number`, { value });\n }\n}\n\nexport function assertObject(value: unknown, name: string, code = \"INVALID_INPUT\"): asserts value is Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n throw new OmaTrustError(code, `${name} must be an object`, { value });\n }\n}\n\nexport function asError(err: unknown): Error {\n if (err instanceof Error) {\n return err;\n }\n return new Error(String(err));\n}\n","import { id } from \"ethers\";\nimport { assertString } from \"../shared/assert\";\n\ntype Hex = `0x${string}`;\n\nexport function hashTrait(trait: string): Hex {\n assertString(trait, \"trait\");\n return id(trait) as Hex;\n}\n\nexport function hashTraits(traits: string[]): Hex[] {\n if (!Array.isArray(traits)) {\n throw new TypeError(\"traits must be an array\");\n }\n return traits.map((trait) => hashTrait(trait));\n}\n","import type { InterfaceFlags, InterfaceType } from \"./types\";\nimport { OmaTrustError } from \"../shared/errors\";\n\nconst BIT_HUMAN = 1;\nconst BIT_API = 2;\nconst BIT_CONTRACT = 4;\n\nexport function computeInterfacesBitmap(flags: InterfaceFlags): number {\n return (flags.human ? BIT_HUMAN : 0) +\n (flags.api ? BIT_API : 0) +\n (flags.smartContract ? BIT_CONTRACT : 0);\n}\n\nexport function parseBitmapToFlags(bitmap: number): InterfaceFlags {\n return {\n human: (bitmap & BIT_HUMAN) !== 0,\n api: (bitmap & BIT_API) !== 0,\n smartContract: (bitmap & BIT_CONTRACT) !== 0\n };\n}\n\nexport function hasInterface(bitmap: number, type: InterfaceType): boolean {\n switch (type) {\n case \"human\":\n return (bitmap & BIT_HUMAN) !== 0;\n case \"api\":\n return (bitmap & BIT_API) !== 0;\n case \"contract\":\n return (bitmap & BIT_CONTRACT) !== 0;\n default:\n throw new OmaTrustError(\"INVALID_INPUT\", \"Unsupported interface type\", { type });\n }\n}\n\nexport function getInterfaceTypes(bitmap: number): InterfaceType[] {\n const results: InterfaceType[] = [];\n if (hasInterface(bitmap, \"human\")) {\n results.push(\"human\");\n }\n if (hasInterface(bitmap, \"api\")) {\n results.push(\"api\");\n }\n if (hasInterface(bitmap, \"contract\")) {\n results.push(\"contract\");\n }\n return results;\n}\n","import type { RegistryStatus } from \"./types\";\nimport { OmaTrustError } from \"../shared/errors\";\n\nexport function registryCodeToStatus(code: number): RegistryStatus {\n switch (code) {\n case 0:\n return \"Active\";\n case 1:\n return \"Deprecated\";\n case 2:\n return \"Replaced\";\n default:\n throw new OmaTrustError(\"INVALID_INPUT\", \"Invalid registry status code\", { code });\n }\n}\n\nexport function registryStatusToCode(status: RegistryStatus): number {\n switch (status) {\n case \"Active\":\n return 0;\n case \"Deprecated\":\n return 1;\n case \"Replaced\":\n return 2;\n default:\n throw new OmaTrustError(\"INVALID_INPUT\", \"Invalid registry status\", { status });\n }\n}\n\nexport function isValidRegistryStatus(status: string): status is RegistryStatus {\n return status === \"Active\" || status === \"Deprecated\" || status === \"Replaced\";\n}\n","import type { Version } from \"./types\";\nimport { OmaTrustError } from \"../shared/errors\";\n\nexport function parseVersion(input: string): Version {\n const match = input.match(/^(\\d+)\\.(\\d+)\\.(\\d+)$/);\n if (!match) {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Invalid semantic version\", { input });\n }\n\n return {\n major: Number(match[1]),\n minor: Number(match[2]),\n patch: Number(match[3])\n };\n}\n\nexport function formatVersion(version: Version): string {\n return `${version.major}.${version.minor}.${version.patch}`;\n}\n\nexport function compareVersions(a: Version, b: Version): -1 | 0 | 1 {\n if (a.major !== b.major) {\n return a.major < b.major ? -1 : 1;\n }\n if (a.minor !== b.minor) {\n return a.minor < b.minor ? -1 : 1;\n }\n if (a.patch !== b.patch) {\n return a.patch < b.patch ? -1 : 1;\n }\n return 0;\n}\n\nexport function isVersionGreater(a: Version, b: Version): boolean {\n return compareVersions(a, b) === 1;\n}\n\nexport function isVersionEqual(a: Version, b: Version): boolean {\n return compareVersions(a, b) === 0;\n}\n\nexport function getLatestVersion(history: Version[]): Version {\n if (history.length === 0) {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Version history cannot be empty\");\n }\n\n return history.reduce((current, candidate) => {\n return compareVersions(candidate, current) === 1 ? candidate : current;\n });\n}\n","export const METADATA_KEY_DID = \"omat.did\";\nexport const METADATA_KEY_DID_HASH = \"omat.didHash\";\nexport const METADATA_KEY_DATA_HASH = \"omat.dataHash\";\nexport const METADATA_KEY_DATA_HASH_ALGORITHM = \"omat.dataHashAlgorithm\";\nexport const METADATA_KEY_STATUS = \"omat.status\";\nexport const METADATA_KEY_INTERFACES = \"omat.interfaces\";\nexport const METADATA_KEY_FUNGIBLE_TOKEN_ID = \"omat.fungibleTokenId\";\nexport const METADATA_KEY_CONTRACT_ID = \"omat.contractId\";\nexport const METADATA_KEY_VERSION_MAJOR = \"omat.versionMajor\";\nexport const METADATA_KEY_VERSION_MINOR = \"omat.versionMinor\";\nexport const METADATA_KEY_VERSION_PATCH = \"omat.versionPatch\";\nexport const METADATA_KEY_TRAIT_HASHES = \"omat.traitHashes\";\nexport const METADATA_KEY_METADATA_JSON = \"omat.metadataJson\";\n","import canonicalize from \"canonicalize\";\nimport { keccak256, sha256, toUtf8Bytes } from \"ethers\";\nimport { OmaTrustError } from \"../shared/errors\";\n\ntype Hex = `0x${string}`;\n\nconst VALID_ALGORITHMS = new Set([\"keccak256\", \"sha256\"]);\n\n/** Maximum JSON nesting depth allowed. */\nconst MAX_JSON_DEPTH = 32;\n\nfunction assertDepthLimit(depth: number, context?: string): void {\n if (depth > MAX_JSON_DEPTH) {\n const msg = context\n ? `JSON nesting depth exceeds maximum of ${MAX_JSON_DEPTH} at ${context}`\n : `JSON nesting depth exceeds maximum of ${MAX_JSON_DEPTH}`;\n throw new OmaTrustError(\"INVALID_INPUT\", msg);\n }\n}\n\n/**\n * Parse JSON strictly, rejecting duplicate keys.\n * Standard JSON.parse() silently accepts duplicates (last-wins).\n * This function detects duplicates at any nesting depth and throws.\n */\nexport function parseJsonStrict(input: string): unknown {\n if (typeof input !== \"string\") {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Input must be a string\");\n }\n\n // First pass: detect duplicate keys by scanning object literals\n const seen = new Map<string, Set<string>>();\n let pathStack: string[] = [];\n let depth = 0;\n\n // Use a reviver to track keys at each depth\n const keyTracker = new Map<number, Set<string>>();\n\n // Parse with a reviver that tracks keys per object depth\n // JSON.parse calls the reviver bottom-up, so we use a different approach:\n // scan the raw string for duplicate keys using a state machine.\n const duplicateKeys = detectDuplicateKeys(input);\n if (duplicateKeys.length > 0) {\n throw new OmaTrustError(\n \"INVALID_INPUT\",\n `Duplicate JSON key${duplicateKeys.length > 1 ? \"s\" : \"\"} detected: ${duplicateKeys.map(k => `\"${k}\"`).join(\", \")}`,\n { duplicateKeys }\n );\n }\n\n try {\n return JSON.parse(input);\n } catch {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Input is not valid JSON\");\n }\n}\n\n/**\n * Detect duplicate keys in a JSON string.\n * Returns an array of key names that appear more than once in any single object.\n */\nfunction detectDuplicateKeys(input: string): string[] {\n const duplicates: string[] = [];\n // Stack of sets — each set tracks keys for the current object nesting level\n const objectKeyStack: Set<string>[] = [];\n let inString = false;\n let escaped = false;\n let currentKey = \"\";\n let collectingKey = false;\n let afterColon = false;\n let i = 0;\n\n while (i < input.length) {\n const ch = input[i];\n\n if (escaped) {\n if (collectingKey) currentKey += ch;\n escaped = false;\n i++;\n continue;\n }\n\n if (ch === \"\\\\\") {\n escaped = true;\n if (collectingKey) currentKey += ch;\n i++;\n continue;\n }\n\n if (ch === '\"') {\n if (!inString) {\n inString = true;\n // If we're in an object context and not after a colon, this is a key\n if (objectKeyStack.length > 0 && !afterColon) {\n collectingKey = true;\n currentKey = \"\";\n }\n } else {\n inString = false;\n if (collectingKey) {\n collectingKey = false;\n const keySet = objectKeyStack[objectKeyStack.length - 1];\n if (keySet.has(currentKey)) {\n if (!duplicates.includes(currentKey)) {\n duplicates.push(currentKey);\n }\n } else {\n keySet.add(currentKey);\n }\n }\n }\n i++;\n continue;\n }\n\n if (inString) {\n if (collectingKey) currentKey += ch;\n i++;\n continue;\n }\n\n // Outside string\n if (ch === \"{\") {\n objectKeyStack.push(new Set());\n assertDepthLimit(objectKeyStack.length);\n afterColon = false;\n } else if (ch === \"}\") {\n objectKeyStack.pop();\n afterColon = objectKeyStack.length > 0; // restore parent context\n } else if (ch === \"[\") {\n // Arrays don't have keys — push a sentinel\n objectKeyStack.push(new Set([\"__array__\"]));\n assertDepthLimit(objectKeyStack.length);\n afterColon = false;\n } else if (ch === \"]\") {\n objectKeyStack.pop();\n afterColon = objectKeyStack.length > 0;\n } else if (ch === \":\") {\n afterColon = true;\n } else if (ch === \",\") {\n afterColon = false;\n }\n\n i++;\n }\n\n return duplicates;\n}\n\n/**\n * Assert that a value is JSON-safe (representable in JSON without lossy conversion).\n * Rejects: undefined, NaN, Infinity, -Infinity, BigInt, functions, symbols, Date objects.\n * These values would be silently coerced or dropped by JSON.stringify / canonicalize.\n */\nexport function assertJsonSafe(value: unknown, path: string = \"$\", depth: number = 0): void {\n assertDepthLimit(depth, path);\n\n if (value === undefined) {\n throw new OmaTrustError(\"INVALID_INPUT\", `Non-JSON-safe value at ${path}: undefined`);\n }\n\n if (value === null) return;\n\n switch (typeof value) {\n case \"string\":\n case \"boolean\":\n return;\n case \"number\":\n if (!Number.isFinite(value)) {\n throw new OmaTrustError(\"INVALID_INPUT\", `Non-JSON-safe value at ${path}: ${value} (must be finite number)`);\n }\n return;\n case \"bigint\":\n throw new OmaTrustError(\"INVALID_INPUT\", `Non-JSON-safe value at ${path}: BigInt (use number or string)`);\n case \"function\":\n throw new OmaTrustError(\"INVALID_INPUT\", `Non-JSON-safe value at ${path}: function`);\n case \"symbol\":\n throw new OmaTrustError(\"INVALID_INPUT\", `Non-JSON-safe value at ${path}: Symbol`);\n case \"object\":\n if (value instanceof Date) {\n throw new OmaTrustError(\"INVALID_INPUT\", `Non-JSON-safe value at ${path}: Date (use ISO string or timestamp)`);\n }\n if (value instanceof RegExp) {\n throw new OmaTrustError(\"INVALID_INPUT\", `Non-JSON-safe value at ${path}: RegExp`);\n }\n if (Array.isArray(value)) {\n for (let i = 0; i < value.length; i++) {\n assertJsonSafe(value[i], `${path}[${i}]`, depth + 1);\n }\n return;\n }\n // Plain object\n for (const [key, val] of Object.entries(value)) {\n assertJsonSafe(val, `${path}.${key}`, depth + 1);\n }\n return;\n default:\n throw new OmaTrustError(\"INVALID_INPUT\", `Non-JSON-safe value at ${path}: unknown type \"${typeof value}\"`);\n }\n}\n\nexport function canonicalizeJson(obj: unknown): string {\n assertJsonSafe(obj);\n const jcs = canonicalize(obj);\n if (!jcs) {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Object cannot be canonicalized\", { obj });\n }\n return jcs;\n}\n\n/**\n * Canonicalize a JSON object (JCS / RFC 8785) and compute its keccak256 hash.\n * Returns both the canonical JCS string and the 0x-prefixed hash.\n */\nexport function canonicalizeAndKeccak256(obj: unknown): { jcsJson: string; hash: Hex } {\n const jcsJson = canonicalizeJson(obj);\n return {\n jcsJson,\n hash: keccak256(toUtf8Bytes(jcsJson)) as Hex\n };\n}\n\n/** @deprecated Use canonicalizeAndKeccak256 instead. */\nexport function canonicalizeForHash(obj: unknown): { jcsJson: string; hash: Hex } {\n return canonicalizeAndKeccak256(obj);\n}\n\nexport function hashCanonicalizedJson(obj: unknown, algorithm: \"keccak256\" | \"sha256\"): Hex {\n if (!VALID_ALGORITHMS.has(algorithm)) {\n throw new OmaTrustError(\"INVALID_INPUT\", `Unsupported hash algorithm: \"${algorithm}\". Must be \"keccak256\" or \"sha256\".`, { algorithm });\n }\n const jcs = canonicalizeJson(obj);\n const bytes = toUtf8Bytes(jcs);\n return (algorithm === \"keccak256\" ? keccak256(bytes) : sha256(bytes)) as Hex;\n}\n","import { keccak256, sha256, toUtf8Bytes } from \"ethers\";\nimport { canonicalizeJson } from \"../identity/data\";\nimport { OmaTrustError } from \"../shared/errors\";\n\ntype Hex = `0x${string}`;\nexport type DataHashAlgorithm = \"keccak256\" | \"sha256\";\n\nasync function fetchJson(url: string): Promise<unknown> {\n let response: Response;\n try {\n response = await fetch(url, { headers: { Accept: \"application/json\" } });\n } catch (err) {\n throw new OmaTrustError(\"NETWORK_ERROR\", \"Failed to fetch data URL\", { url, err });\n }\n\n if (!response.ok) {\n throw new OmaTrustError(\"NETWORK_ERROR\", \"Failed to fetch data URL\", {\n url,\n status: response.status\n });\n }\n\n try {\n return await response.json();\n } catch (err) {\n throw new OmaTrustError(\"INVALID_INPUT\", \"Response body is not valid JSON\", { url, err });\n }\n}\n\nfunction hashJcs(jcsJson: string, algorithm: DataHashAlgorithm): Hex {\n const bytes = toUtf8Bytes(jcsJson);\n return (algorithm === \"keccak256\" ? keccak256(bytes) : sha256(bytes)) as Hex;\n}\n\nexport async function computeDataHashFromUrl(\n url: string,\n algorithm: DataHashAlgorithm\n): Promise<Hex> {\n if (!url || typeof url !== \"string\") {\n throw new OmaTrustError(\"INVALID_INPUT\", \"url must be a non-empty string\", { url });\n }\n\n if (algorithm !== \"keccak256\" && algorithm !== \"sha256\") {\n throw new OmaTrustError(\"INVALID_INPUT\", `Unsupported hash algorithm: \"${algorithm}\". Must be \"keccak256\" or \"sha256\".`, { algorithm });\n }\n\n const json = await fetchJson(url);\n const jcsJson = canonicalizeJson(json);\n return hashJcs(jcsJson, algorithm);\n}\n\nexport async function verifyDataUrlHash(\n url: string,\n expectedHash: Hex,\n algorithm: DataHashAlgorithm\n): Promise<boolean> {\n const computedHash = await computeDataHashFromUrl(url, algorithm);\n return computedHash.toLowerCase() === expectedHash.toLowerCase();\n}\n"]}