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

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 (40) 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-QueRiudB.d.cts → index-B5OC9_8B.d.cts} +155 -4
  13. package/dist/index-Bu-xxcv9.d.ts +407 -0
  14. package/dist/{index-C2w5EvFH.d.ts → index-C6WNgPRx.d.ts} +155 -4
  15. package/dist/index-C7odEbp6.d.cts +407 -0
  16. package/dist/index.cjs +1000 -185
  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 +981 -185
  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 +477 -140
  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 +475 -141
  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-R78TpAhN.d.ts +0 -235
package/dist/index.cjs CHANGED
@@ -3,12 +3,36 @@
3
3
  var ethers = require('ethers');
4
4
  var jose = require('jose');
5
5
  var canonicalize = require('canonicalize');
6
+ var cid = require('multiformats/cid');
7
+ var sha2 = require('multiformats/hashes/sha2');
8
+ var raw = require('multiformats/codecs/raw');
9
+ var base32 = require('multiformats/bases/base32');
10
+ var base58 = require('multiformats/bases/base58');
6
11
  var easSdk = require('@ethereum-attestation-service/eas-sdk');
7
12
  var promises = require('dns/promises');
8
13
 
9
14
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
10
15
 
16
+ function _interopNamespace(e) {
17
+ if (e && e.__esModule) return e;
18
+ var n = Object.create(null);
19
+ if (e) {
20
+ Object.keys(e).forEach(function (k) {
21
+ if (k !== 'default') {
22
+ var d = Object.getOwnPropertyDescriptor(e, k);
23
+ Object.defineProperty(n, k, d.get ? d : {
24
+ enumerable: true,
25
+ get: function () { return e[k]; }
26
+ });
27
+ }
28
+ });
29
+ }
30
+ n.default = e;
31
+ return Object.freeze(n);
32
+ }
33
+
11
34
  var canonicalize__default = /*#__PURE__*/_interopDefault(canonicalize);
35
+ var raw__namespace = /*#__PURE__*/_interopNamespace(raw);
12
36
 
13
37
  var __defProp = Object.defineProperty;
14
38
  var __export = (target, all) => {
@@ -20,31 +44,31 @@ var __export = (target, all) => {
20
44
  var OmaTrustError = class extends Error {
21
45
  code;
22
46
  details;
23
- constructor(code, message, details) {
47
+ constructor(code2, message, details) {
24
48
  super(message);
25
49
  this.name = "OmaTrustError";
26
- this.code = code;
50
+ this.code = code2;
27
51
  this.details = details;
28
52
  }
29
53
  };
30
- function toOmaTrustError(code, message, details) {
31
- return new OmaTrustError(code, message, details);
54
+ function toOmaTrustError(code2, message, details) {
55
+ return new OmaTrustError(code2, message, details);
32
56
  }
33
57
 
34
58
  // src/shared/assert.ts
35
- function assertString(value, name, code = "INVALID_INPUT") {
59
+ function assertString(value, name, code2 = "INVALID_INPUT") {
36
60
  if (typeof value !== "string" || value.trim().length === 0) {
37
- throw new OmaTrustError(code, `${name} must be a non-empty string`, { value });
61
+ throw new OmaTrustError(code2, `${name} must be a non-empty string`, { value });
38
62
  }
39
63
  }
40
- function assertNumber(value, name, code = "INVALID_INPUT") {
64
+ function assertNumber(value, name, code2 = "INVALID_INPUT") {
41
65
  if (typeof value !== "number" || Number.isNaN(value)) {
42
- throw new OmaTrustError(code, `${name} must be a valid number`, { value });
66
+ throw new OmaTrustError(code2, `${name} must be a valid number`, { value });
43
67
  }
44
68
  }
45
- function assertObject(value, name, code = "INVALID_INPUT") {
69
+ function assertObject(value, name, code2 = "INVALID_INPUT") {
46
70
  if (!value || typeof value !== "object" || Array.isArray(value)) {
47
- throw new OmaTrustError(code, `${name} must be an object`, { value });
71
+ throw new OmaTrustError(code2, `${name} must be an object`, { value });
48
72
  }
49
73
  }
50
74
  function asError(err) {
@@ -57,19 +81,25 @@ function asError(err) {
57
81
  // src/identity/index.ts
58
82
  var identity_exports = {};
59
83
  __export(identity_exports, {
84
+ artifactDidFromBytes: () => artifactDidFromBytes,
85
+ artifactDidFromJson: () => artifactDidFromJson,
60
86
  assertBareDid: () => assertBareDid,
87
+ assertJsonSafe: () => assertJsonSafe,
61
88
  buildCaip10: () => buildCaip10,
62
89
  buildCaip2: () => buildCaip2,
63
90
  buildDidPkh: () => buildDidPkh,
64
91
  buildDidPkhFromCaip10: () => buildDidPkhFromCaip10,
65
92
  buildDidWeb: () => buildDidWeb,
66
93
  buildEvmDidPkh: () => buildEvmDidPkh,
94
+ canonicalizeAndKeccak256: () => canonicalizeAndKeccak256,
67
95
  canonicalizeForHash: () => canonicalizeForHash,
68
96
  canonicalizeJson: () => canonicalizeJson,
69
97
  computeDidAddress: () => computeDidAddress,
70
98
  computeDidHash: () => computeDidHash,
71
99
  computeJwkThumbprint: () => computeJwkThumbprint,
100
+ didEthrToDidPkh: () => didEthrToDidPkh,
72
101
  didJwkToJwk: () => didJwkToJwk,
102
+ didKeyToDidJwk: () => didKeyToDidJwk,
73
103
  didToAddress: () => didToAddress,
74
104
  extractAddressFromDid: () => extractAddressFromDid,
75
105
  extractAuthorizationMetadata: () => extractAuthorizationMetadata,
@@ -96,15 +126,18 @@ __export(identity_exports, {
96
126
  normalizeDidPkh: () => normalizeDidPkh,
97
127
  normalizeDidWeb: () => normalizeDidWeb,
98
128
  normalizeDomain: () => normalizeDomain,
129
+ parseArtifactDid: () => parseArtifactDid,
99
130
  parseCaip10: () => parseCaip10,
100
131
  parseCaip2: () => parseCaip2,
101
132
  parseDidUrl: () => parseDidUrl,
133
+ parseJsonStrict: () => parseJsonStrict,
102
134
  publicJwkEquals: () => publicJwkEquals,
103
135
  resolveDidUrlToControllerDid: () => resolveDidUrlToControllerDid,
104
136
  resolveDidUrlToPublicKey: () => resolveDidUrlToPublicKey,
105
137
  validateDidAddress: () => validateDidAddress,
106
138
  validatePrivateKeyDid: () => validatePrivateKeyDid,
107
- validatePublicJwk: () => validatePublicJwk
139
+ validatePublicJwk: () => validatePublicJwk,
140
+ verifyDidArtifact: () => verifyDidArtifact
108
141
  });
109
142
 
110
143
  // src/identity/caip.ts
@@ -160,6 +193,158 @@ function parseCaip2(caip2) {
160
193
  }
161
194
  return { namespace, reference };
162
195
  }
196
+ var VALID_KTY = /* @__PURE__ */ new Set(["EC", "OKP", "RSA"]);
197
+ var PRIVATE_KEY_FIELDS = /* @__PURE__ */ new Set(["d", "p", "q", "dp", "dq", "qi", "oth"]);
198
+ var REQUIRED_PUBLIC_FIELDS = {
199
+ EC: ["crv", "x", "y"],
200
+ OKP: ["crv", "x"],
201
+ RSA: ["n", "e"]
202
+ };
203
+ function validatePublicJwk(jwk) {
204
+ if (!jwk || typeof jwk !== "object" || Array.isArray(jwk)) {
205
+ return { valid: false, error: "JWK must be a non-null object" };
206
+ }
207
+ const obj = jwk;
208
+ const kty = obj.kty;
209
+ if (typeof kty !== "string" || !VALID_KTY.has(kty)) {
210
+ return {
211
+ valid: false,
212
+ error: `Invalid or missing kty (must be one of: ${[...VALID_KTY].join(", ")})`
213
+ };
214
+ }
215
+ for (const field of PRIVATE_KEY_FIELDS) {
216
+ if (field in obj) {
217
+ return {
218
+ valid: false,
219
+ error: `JWK contains private key field "${field}" \u2014 only public keys are allowed`
220
+ };
221
+ }
222
+ }
223
+ const required = REQUIRED_PUBLIC_FIELDS[kty];
224
+ if (required) {
225
+ for (const field of required) {
226
+ if (!(field in obj) || obj[field] === void 0 || obj[field] === null || obj[field] === "") {
227
+ return {
228
+ valid: false,
229
+ error: `Missing required public key field "${field}" for kty="${kty}"`
230
+ };
231
+ }
232
+ }
233
+ }
234
+ return { valid: true };
235
+ }
236
+ function canonicalizeJwkJson(jwk) {
237
+ const sorted = Object.keys(jwk).sort();
238
+ const obj = {};
239
+ for (const key of sorted) {
240
+ obj[key] = jwk[key];
241
+ }
242
+ return JSON.stringify(obj);
243
+ }
244
+ function jwkToDidJwk(jwk) {
245
+ assertObject(jwk, "jwk", "INVALID_JWK");
246
+ const validation = validatePublicJwk(jwk);
247
+ if (!validation.valid) {
248
+ throw new OmaTrustError("INVALID_JWK", validation.error ?? "Invalid public JWK", { jwk });
249
+ }
250
+ const canonical = canonicalizeJwkJson(jwk);
251
+ const encoded = jose.base64url.encode(new TextEncoder().encode(canonical));
252
+ return `did:jwk:${encoded}`;
253
+ }
254
+ function didJwkToJwk(didJwk) {
255
+ if (typeof didJwk !== "string" || !didJwk.startsWith("did:jwk:")) {
256
+ throw new OmaTrustError("INVALID_DID", "Expected a did:jwk DID", { input: didJwk });
257
+ }
258
+ const parts = didJwk.split(":");
259
+ if (parts.length !== 3) {
260
+ throw new OmaTrustError("INVALID_DID", "did:jwk must have exactly 3 colon-separated parts", {
261
+ input: didJwk
262
+ });
263
+ }
264
+ const encoded = parts[2];
265
+ if (!encoded || encoded.length === 0) {
266
+ throw new OmaTrustError("INVALID_DID", "Missing base64url-encoded JWK identifier", {
267
+ input: didJwk
268
+ });
269
+ }
270
+ let decoded;
271
+ try {
272
+ const bytes = jose.base64url.decode(encoded);
273
+ decoded = new TextDecoder().decode(bytes);
274
+ } catch {
275
+ throw new OmaTrustError("INVALID_DID", "Failed to base64url-decode did:jwk identifier", {
276
+ input: didJwk
277
+ });
278
+ }
279
+ let jwk;
280
+ try {
281
+ jwk = JSON.parse(decoded);
282
+ } catch {
283
+ throw new OmaTrustError("INVALID_DID", "Decoded did:jwk identifier is not valid JSON", {
284
+ input: didJwk
285
+ });
286
+ }
287
+ if (!jwk || typeof jwk !== "object" || Array.isArray(jwk)) {
288
+ throw new OmaTrustError("INVALID_DID", "Decoded did:jwk must be a JSON object", {
289
+ input: didJwk
290
+ });
291
+ }
292
+ const validation = validatePublicJwk(jwk);
293
+ if (!validation.valid) {
294
+ throw new OmaTrustError("INVALID_DID", validation.error ?? "Invalid public JWK in did:jwk", {
295
+ input: didJwk
296
+ });
297
+ }
298
+ return jwk;
299
+ }
300
+ function extractPublicKeyFields(jwk) {
301
+ const result = {};
302
+ const metadataFields = /* @__PURE__ */ new Set(["kid", "use", "key_ops", "alg", "ext"]);
303
+ for (const [key, value] of Object.entries(jwk)) {
304
+ if (PRIVATE_KEY_FIELDS.has(key)) continue;
305
+ if (metadataFields.has(key)) continue;
306
+ result[key] = value;
307
+ }
308
+ return result;
309
+ }
310
+ function publicJwkEquals(a, b) {
311
+ assertObject(a, "a", "INVALID_JWK");
312
+ assertObject(b, "b", "INVALID_JWK");
313
+ const aObj = a;
314
+ const bObj = b;
315
+ for (const field of PRIVATE_KEY_FIELDS) {
316
+ if (field in aObj) {
317
+ throw new OmaTrustError(
318
+ "INVALID_JWK",
319
+ `First JWK contains private key field "${field}"`,
320
+ { field }
321
+ );
322
+ }
323
+ if (field in bObj) {
324
+ throw new OmaTrustError(
325
+ "INVALID_JWK",
326
+ `Second JWK contains private key field "${field}"`,
327
+ { field }
328
+ );
329
+ }
330
+ }
331
+ const aPublic = extractPublicKeyFields(aObj);
332
+ const bPublic = extractPublicKeyFields(bObj);
333
+ return canonicalizeJwkJson(aPublic) === canonicalizeJwkJson(bPublic);
334
+ }
335
+ async function computeJwkThumbprint(jwk, digestAlgorithm = "sha256") {
336
+ assertObject(jwk, "jwk", "INVALID_JWK");
337
+ const validation = validatePublicJwk(jwk);
338
+ if (!validation.valid) {
339
+ throw new OmaTrustError("INVALID_JWK", validation.error ?? "Invalid public JWK", { jwk });
340
+ }
341
+ const alg = digestAlgorithm === "sha256" ? "sha256" : digestAlgorithm === "sha384" ? "sha384" : "sha512";
342
+ return jose.calculateJwkThumbprint(jwk, alg);
343
+ }
344
+ async function formatJktValue(jwk) {
345
+ const thumbprint = await computeJwkThumbprint(jwk, "sha256");
346
+ return `jkt=S256:${thumbprint}`;
347
+ }
163
348
 
164
349
  // src/identity/did.ts
165
350
  var DID_REGEX = /^did:[a-z0-9]+:.+$/i;
@@ -235,7 +420,7 @@ function normalizeDidKey(input) {
235
420
  }
236
421
  function normalizeDid(input) {
237
422
  assertString(input, "input", "INVALID_DID");
238
- const trimmed = input.trim();
423
+ const trimmed = input.trim().split("#")[0];
239
424
  if (!trimmed.startsWith("did:")) {
240
425
  return normalizeDidWeb(trimmed);
241
426
  }
@@ -424,6 +609,15 @@ function validateDidPkh(did) {
424
609
  };
425
610
  }
426
611
  }
612
+ if (namespace === "solana") {
613
+ if (!/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(address)) {
614
+ return {
615
+ valid: false,
616
+ method: "pkh",
617
+ error: `Invalid Solana address "${address}" (must be 32-44 base58 characters)`
618
+ };
619
+ }
620
+ }
427
621
  return { valid: true, method: "pkh" };
428
622
  }
429
623
  function validateDidJwk(did) {
@@ -477,6 +671,10 @@ function validateDidJwk(did) {
477
671
  error: "DID must reference a public key \u2014 private key component (d) is not allowed"
478
672
  };
479
673
  }
674
+ const jwkValidation = validatePublicJwk(jwk);
675
+ if (!jwkValidation.valid) {
676
+ return { valid: false, method: "jwk", error: jwkValidation.error };
677
+ }
480
678
  return { valid: true, method: "jwk" };
481
679
  }
482
680
  function normalizeDidJwk(input) {
@@ -543,158 +741,6 @@ function assertBareDid(input, paramName = "did") {
543
741
  );
544
742
  }
545
743
  }
546
- var VALID_KTY = /* @__PURE__ */ new Set(["EC", "OKP", "RSA"]);
547
- var PRIVATE_KEY_FIELDS = /* @__PURE__ */ new Set(["d", "p", "q", "dp", "dq", "qi", "oth"]);
548
- var REQUIRED_PUBLIC_FIELDS = {
549
- EC: ["crv", "x", "y"],
550
- OKP: ["crv", "x"],
551
- RSA: ["n", "e"]
552
- };
553
- function validatePublicJwk(jwk) {
554
- if (!jwk || typeof jwk !== "object" || Array.isArray(jwk)) {
555
- return { valid: false, error: "JWK must be a non-null object" };
556
- }
557
- const obj = jwk;
558
- const kty = obj.kty;
559
- if (typeof kty !== "string" || !VALID_KTY.has(kty)) {
560
- return {
561
- valid: false,
562
- error: `Invalid or missing kty (must be one of: ${[...VALID_KTY].join(", ")})`
563
- };
564
- }
565
- for (const field of PRIVATE_KEY_FIELDS) {
566
- if (field in obj) {
567
- return {
568
- valid: false,
569
- error: `JWK contains private key field "${field}" \u2014 only public keys are allowed`
570
- };
571
- }
572
- }
573
- const required = REQUIRED_PUBLIC_FIELDS[kty];
574
- if (required) {
575
- for (const field of required) {
576
- if (!(field in obj) || obj[field] === void 0 || obj[field] === null || obj[field] === "") {
577
- return {
578
- valid: false,
579
- error: `Missing required public key field "${field}" for kty="${kty}"`
580
- };
581
- }
582
- }
583
- }
584
- return { valid: true };
585
- }
586
- function canonicalizeJwkJson(jwk) {
587
- const sorted = Object.keys(jwk).sort();
588
- const obj = {};
589
- for (const key of sorted) {
590
- obj[key] = jwk[key];
591
- }
592
- return JSON.stringify(obj);
593
- }
594
- function jwkToDidJwk(jwk) {
595
- assertObject(jwk, "jwk", "INVALID_JWK");
596
- const validation = validatePublicJwk(jwk);
597
- if (!validation.valid) {
598
- throw new OmaTrustError("INVALID_JWK", validation.error ?? "Invalid public JWK", { jwk });
599
- }
600
- const canonical = canonicalizeJwkJson(jwk);
601
- const encoded = jose.base64url.encode(new TextEncoder().encode(canonical));
602
- return `did:jwk:${encoded}`;
603
- }
604
- function didJwkToJwk(didJwk) {
605
- if (typeof didJwk !== "string" || !didJwk.startsWith("did:jwk:")) {
606
- throw new OmaTrustError("INVALID_DID", "Expected a did:jwk DID", { input: didJwk });
607
- }
608
- const parts = didJwk.split(":");
609
- if (parts.length !== 3) {
610
- throw new OmaTrustError("INVALID_DID", "did:jwk must have exactly 3 colon-separated parts", {
611
- input: didJwk
612
- });
613
- }
614
- const encoded = parts[2];
615
- if (!encoded || encoded.length === 0) {
616
- throw new OmaTrustError("INVALID_DID", "Missing base64url-encoded JWK identifier", {
617
- input: didJwk
618
- });
619
- }
620
- let decoded;
621
- try {
622
- const bytes = jose.base64url.decode(encoded);
623
- decoded = new TextDecoder().decode(bytes);
624
- } catch {
625
- throw new OmaTrustError("INVALID_DID", "Failed to base64url-decode did:jwk identifier", {
626
- input: didJwk
627
- });
628
- }
629
- let jwk;
630
- try {
631
- jwk = JSON.parse(decoded);
632
- } catch {
633
- throw new OmaTrustError("INVALID_DID", "Decoded did:jwk identifier is not valid JSON", {
634
- input: didJwk
635
- });
636
- }
637
- if (!jwk || typeof jwk !== "object" || Array.isArray(jwk)) {
638
- throw new OmaTrustError("INVALID_DID", "Decoded did:jwk must be a JSON object", {
639
- input: didJwk
640
- });
641
- }
642
- const validation = validatePublicJwk(jwk);
643
- if (!validation.valid) {
644
- throw new OmaTrustError("INVALID_DID", validation.error ?? "Invalid public JWK in did:jwk", {
645
- input: didJwk
646
- });
647
- }
648
- return jwk;
649
- }
650
- function extractPublicKeyFields(jwk) {
651
- const result = {};
652
- const metadataFields = /* @__PURE__ */ new Set(["kid", "use", "key_ops", "alg", "ext"]);
653
- for (const [key, value] of Object.entries(jwk)) {
654
- if (PRIVATE_KEY_FIELDS.has(key)) continue;
655
- if (metadataFields.has(key)) continue;
656
- result[key] = value;
657
- }
658
- return result;
659
- }
660
- function publicJwkEquals(a, b) {
661
- assertObject(a, "a", "INVALID_JWK");
662
- assertObject(b, "b", "INVALID_JWK");
663
- const aObj = a;
664
- const bObj = b;
665
- for (const field of PRIVATE_KEY_FIELDS) {
666
- if (field in aObj) {
667
- throw new OmaTrustError(
668
- "INVALID_JWK",
669
- `First JWK contains private key field "${field}"`,
670
- { field }
671
- );
672
- }
673
- if (field in bObj) {
674
- throw new OmaTrustError(
675
- "INVALID_JWK",
676
- `Second JWK contains private key field "${field}"`,
677
- { field }
678
- );
679
- }
680
- }
681
- const aPublic = extractPublicKeyFields(aObj);
682
- const bPublic = extractPublicKeyFields(bObj);
683
- return canonicalizeJwkJson(aPublic) === canonicalizeJwkJson(bPublic);
684
- }
685
- async function computeJwkThumbprint(jwk, digestAlgorithm = "sha256") {
686
- assertObject(jwk, "jwk", "INVALID_JWK");
687
- const validation = validatePublicJwk(jwk);
688
- if (!validation.valid) {
689
- throw new OmaTrustError("INVALID_JWK", validation.error ?? "Invalid public JWK", { jwk });
690
- }
691
- const alg = digestAlgorithm === "sha256" ? "sha256" : digestAlgorithm === "sha384" ? "sha384" : "sha512";
692
- return jose.calculateJwkThumbprint(jwk, alg);
693
- }
694
- async function formatJktValue(jwk) {
695
- const thumbprint = await computeJwkThumbprint(jwk, "sha256");
696
- return `jkt=S256:${thumbprint}`;
697
- }
698
744
 
699
745
  // src/shared/did-document.ts
700
746
  async function fetchDidDocument(domain) {
@@ -857,7 +903,7 @@ function extractControllerEvmAddress(controllerDid) {
857
903
  function extractAuthorizationMetadata(result) {
858
904
  const payload = result.payload;
859
905
  const resourceUrl = typeof payload.resourceUrl === "string" ? payload.resourceUrl : null;
860
- const issuedAt = typeof payload.issuedAt === "string" ? payload.issuedAt : null;
906
+ const issuedAt = typeof payload.issuedAt === "string" ? payload.issuedAt : typeof payload.issuedAt === "number" ? payload.issuedAt : null;
861
907
  let subjectDid = null;
862
908
  if (resourceUrl) {
863
909
  try {
@@ -866,34 +912,467 @@ function extractAuthorizationMetadata(result) {
866
912
  } catch {
867
913
  }
868
914
  }
869
- return {
870
- controllerDid: result.publicKeyDid,
871
- subjectDid,
872
- resourceUrl,
873
- issuedAt,
874
- kid: result.kid,
875
- publicKeyJwk: result.publicKeyJwk
876
- };
915
+ if ("publicKeyDid" in result) {
916
+ const jwsResult = result;
917
+ return {
918
+ controllerDid: jwsResult.publicKeyDid,
919
+ subjectDid,
920
+ resourceUrl,
921
+ issuedAt,
922
+ kid: jwsResult.kid,
923
+ publicKeyJwk: jwsResult.publicKeyJwk,
924
+ signer: null
925
+ };
926
+ }
927
+ const eip712Result = result;
928
+ const signerAddress = eip712Result.signer.toLowerCase();
929
+ return {
930
+ controllerDid: `did:pkh:eip155:1:${signerAddress}`,
931
+ subjectDid,
932
+ resourceUrl,
933
+ issuedAt,
934
+ kid: null,
935
+ publicKeyJwk: null,
936
+ signer: eip712Result.signer
937
+ };
938
+ }
939
+ var VALID_ALGORITHMS = /* @__PURE__ */ new Set(["keccak256", "sha256"]);
940
+ var MAX_JSON_DEPTH = 32;
941
+ function assertDepthLimit(depth, context) {
942
+ if (depth > MAX_JSON_DEPTH) {
943
+ const msg = context ? `JSON nesting depth exceeds maximum of ${MAX_JSON_DEPTH} at ${context}` : `JSON nesting depth exceeds maximum of ${MAX_JSON_DEPTH}`;
944
+ throw new OmaTrustError("INVALID_INPUT", msg);
945
+ }
946
+ }
947
+ function parseJsonStrict(input) {
948
+ if (typeof input !== "string") {
949
+ throw new OmaTrustError("INVALID_INPUT", "Input must be a string");
950
+ }
951
+ const duplicateKeys = detectDuplicateKeys(input);
952
+ if (duplicateKeys.length > 0) {
953
+ throw new OmaTrustError(
954
+ "INVALID_INPUT",
955
+ `Duplicate JSON key${duplicateKeys.length > 1 ? "s" : ""} detected: ${duplicateKeys.map((k) => `"${k}"`).join(", ")}`,
956
+ { duplicateKeys }
957
+ );
958
+ }
959
+ try {
960
+ return JSON.parse(input);
961
+ } catch {
962
+ throw new OmaTrustError("INVALID_INPUT", "Input is not valid JSON");
963
+ }
964
+ }
965
+ function detectDuplicateKeys(input) {
966
+ const duplicates = [];
967
+ const objectKeyStack = [];
968
+ let inString = false;
969
+ let escaped = false;
970
+ let currentKey = "";
971
+ let collectingKey = false;
972
+ let afterColon = false;
973
+ let i = 0;
974
+ while (i < input.length) {
975
+ const ch = input[i];
976
+ if (escaped) {
977
+ if (collectingKey) currentKey += ch;
978
+ escaped = false;
979
+ i++;
980
+ continue;
981
+ }
982
+ if (ch === "\\") {
983
+ escaped = true;
984
+ if (collectingKey) currentKey += ch;
985
+ i++;
986
+ continue;
987
+ }
988
+ if (ch === '"') {
989
+ if (!inString) {
990
+ inString = true;
991
+ if (objectKeyStack.length > 0 && !afterColon) {
992
+ collectingKey = true;
993
+ currentKey = "";
994
+ }
995
+ } else {
996
+ inString = false;
997
+ if (collectingKey) {
998
+ collectingKey = false;
999
+ const keySet = objectKeyStack[objectKeyStack.length - 1];
1000
+ if (keySet.has(currentKey)) {
1001
+ if (!duplicates.includes(currentKey)) {
1002
+ duplicates.push(currentKey);
1003
+ }
1004
+ } else {
1005
+ keySet.add(currentKey);
1006
+ }
1007
+ }
1008
+ }
1009
+ i++;
1010
+ continue;
1011
+ }
1012
+ if (inString) {
1013
+ if (collectingKey) currentKey += ch;
1014
+ i++;
1015
+ continue;
1016
+ }
1017
+ if (ch === "{") {
1018
+ objectKeyStack.push(/* @__PURE__ */ new Set());
1019
+ assertDepthLimit(objectKeyStack.length);
1020
+ afterColon = false;
1021
+ } else if (ch === "}") {
1022
+ objectKeyStack.pop();
1023
+ afterColon = objectKeyStack.length > 0;
1024
+ } else if (ch === "[") {
1025
+ objectKeyStack.push(/* @__PURE__ */ new Set(["__array__"]));
1026
+ assertDepthLimit(objectKeyStack.length);
1027
+ afterColon = false;
1028
+ } else if (ch === "]") {
1029
+ objectKeyStack.pop();
1030
+ afterColon = objectKeyStack.length > 0;
1031
+ } else if (ch === ":") {
1032
+ afterColon = true;
1033
+ } else if (ch === ",") {
1034
+ afterColon = false;
1035
+ }
1036
+ i++;
1037
+ }
1038
+ return duplicates;
1039
+ }
1040
+ function assertJsonSafe(value, path = "$", depth = 0) {
1041
+ assertDepthLimit(depth, path);
1042
+ if (value === void 0) {
1043
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: undefined`);
1044
+ }
1045
+ if (value === null) return;
1046
+ switch (typeof value) {
1047
+ case "string":
1048
+ case "boolean":
1049
+ return;
1050
+ case "number":
1051
+ if (!Number.isFinite(value)) {
1052
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: ${value} (must be finite number)`);
1053
+ }
1054
+ return;
1055
+ case "bigint":
1056
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: BigInt (use number or string)`);
1057
+ case "function":
1058
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: function`);
1059
+ case "symbol":
1060
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: Symbol`);
1061
+ case "object":
1062
+ if (value instanceof Date) {
1063
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: Date (use ISO string or timestamp)`);
1064
+ }
1065
+ if (value instanceof RegExp) {
1066
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: RegExp`);
1067
+ }
1068
+ if (Array.isArray(value)) {
1069
+ for (let i = 0; i < value.length; i++) {
1070
+ assertJsonSafe(value[i], `${path}[${i}]`, depth + 1);
1071
+ }
1072
+ return;
1073
+ }
1074
+ for (const [key, val] of Object.entries(value)) {
1075
+ assertJsonSafe(val, `${path}.${key}`, depth + 1);
1076
+ }
1077
+ return;
1078
+ default:
1079
+ throw new OmaTrustError("INVALID_INPUT", `Non-JSON-safe value at ${path}: unknown type "${typeof value}"`);
1080
+ }
877
1081
  }
878
1082
  function canonicalizeJson(obj) {
1083
+ assertJsonSafe(obj);
879
1084
  const jcs = canonicalize__default.default(obj);
880
1085
  if (!jcs) {
881
1086
  throw new OmaTrustError("INVALID_INPUT", "Object cannot be canonicalized", { obj });
882
1087
  }
883
1088
  return jcs;
884
1089
  }
885
- function canonicalizeForHash(obj) {
1090
+ function canonicalizeAndKeccak256(obj) {
886
1091
  const jcsJson = canonicalizeJson(obj);
887
1092
  return {
888
1093
  jcsJson,
889
1094
  hash: ethers.keccak256(ethers.toUtf8Bytes(jcsJson))
890
1095
  };
891
1096
  }
1097
+ function canonicalizeForHash(obj) {
1098
+ return canonicalizeAndKeccak256(obj);
1099
+ }
892
1100
  function hashCanonicalizedJson(obj, algorithm) {
1101
+ if (!VALID_ALGORITHMS.has(algorithm)) {
1102
+ throw new OmaTrustError("INVALID_INPUT", `Unsupported hash algorithm: "${algorithm}". Must be "keccak256" or "sha256".`, { algorithm });
1103
+ }
893
1104
  const jcs = canonicalizeJson(obj);
894
1105
  const bytes = ethers.toUtf8Bytes(jcs);
895
1106
  return algorithm === "keccak256" ? ethers.keccak256(bytes) : ethers.sha256(bytes);
896
1107
  }
1108
+ var DID_ARTIFACT_PREFIX = "did:artifact:";
1109
+ var CID_VERSION = 1;
1110
+ var RAW_CODEC = raw__namespace.code;
1111
+ var SHA2_256_CODE = 18;
1112
+ var SHA2_256_DIGEST_LENGTH = 32;
1113
+ async function artifactDidFromBytes(bytes) {
1114
+ if (!(bytes instanceof Uint8Array) || bytes.length === 0) {
1115
+ throw new OmaTrustError(
1116
+ "INVALID_INPUT",
1117
+ "bytes must be a non-empty Uint8Array"
1118
+ );
1119
+ }
1120
+ const digest = await sha2.sha256.digest(bytes);
1121
+ const cid$1 = cid.CID.createV1(RAW_CODEC, digest);
1122
+ return `${DID_ARTIFACT_PREFIX}${cid$1.toString(base32.base32)}`;
1123
+ }
1124
+ async function artifactDidFromJson(input) {
1125
+ const value = typeof input === "string" ? parseJsonStrict(input) : input;
1126
+ const jcs = canonicalizeJson(value);
1127
+ const bytes = new TextEncoder().encode(jcs);
1128
+ const digest = await sha2.sha256.digest(bytes);
1129
+ const cid$1 = cid.CID.createV1(RAW_CODEC, digest);
1130
+ return `${DID_ARTIFACT_PREFIX}${cid$1.toString(base32.base32)}`;
1131
+ }
1132
+ function parseArtifactDid(did) {
1133
+ if (typeof did !== "string" || !did.startsWith(DID_ARTIFACT_PREFIX)) {
1134
+ throw new OmaTrustError("INVALID_DID", "Expected a did:artifact DID", { did });
1135
+ }
1136
+ const identifier = did.slice(DID_ARTIFACT_PREFIX.length);
1137
+ if (!identifier || identifier.length === 0) {
1138
+ throw new OmaTrustError("INVALID_DID", "Missing method-specific identifier", { did });
1139
+ }
1140
+ if (identifier[0] !== "b") {
1141
+ throw new OmaTrustError(
1142
+ "INVALID_DID",
1143
+ `Invalid multibase prefix "${identifier[0]}", expected "b" (base32lower)`,
1144
+ { did }
1145
+ );
1146
+ }
1147
+ let cid$1;
1148
+ try {
1149
+ cid$1 = cid.CID.parse(identifier, base32.base32);
1150
+ } catch (err) {
1151
+ throw new OmaTrustError(
1152
+ "INVALID_DID",
1153
+ "Failed to decode base32 CID from did:artifact identifier",
1154
+ { did, cause: err }
1155
+ );
1156
+ }
1157
+ if (cid$1.version !== CID_VERSION) {
1158
+ throw new OmaTrustError(
1159
+ "INVALID_DID",
1160
+ `CID version must be 1, got ${cid$1.version}`,
1161
+ { did }
1162
+ );
1163
+ }
1164
+ if (cid$1.code !== RAW_CODEC) {
1165
+ throw new OmaTrustError(
1166
+ "INVALID_DID",
1167
+ `Multicodec must be raw (0x55), got 0x${cid$1.code.toString(16)}`,
1168
+ { did }
1169
+ );
1170
+ }
1171
+ if (cid$1.multihash.code !== SHA2_256_CODE) {
1172
+ throw new OmaTrustError(
1173
+ "INVALID_DID",
1174
+ `Multihash function must be sha2-256 (0x12), got 0x${cid$1.multihash.code.toString(16)}`,
1175
+ { did }
1176
+ );
1177
+ }
1178
+ if (cid$1.multihash.digest.length !== SHA2_256_DIGEST_LENGTH) {
1179
+ throw new OmaTrustError(
1180
+ "INVALID_DID",
1181
+ `SHA-256 digest must be 32 bytes, got ${cid$1.multihash.digest.length}`,
1182
+ { did }
1183
+ );
1184
+ }
1185
+ const digest = cid$1.multihash.digest;
1186
+ const digestHex = Array.from(digest).map((b) => b.toString(16).padStart(2, "0")).join("");
1187
+ return { did, identifier, digest, digestHex };
1188
+ }
1189
+ async function verifyDidArtifact(did, content) {
1190
+ let parsed;
1191
+ try {
1192
+ parsed = parseArtifactDid(did);
1193
+ } catch (err) {
1194
+ return {
1195
+ valid: false,
1196
+ reason: err instanceof OmaTrustError ? err.message : "Invalid did:artifact DID"
1197
+ };
1198
+ }
1199
+ const expectedHex = parsed.digestHex;
1200
+ if (typeof content === "string" || typeof content === "object" && content !== null && !(content instanceof Uint8Array)) {
1201
+ try {
1202
+ const value = typeof content === "string" ? parseJsonStrict(content) : content;
1203
+ const jcs = canonicalizeJson(value);
1204
+ const jcsBytes = new TextEncoder().encode(jcs);
1205
+ const digest2 = await sha2.sha256.digest(jcsBytes);
1206
+ const digestHex2 = Array.from(digest2.digest).map((b) => b.toString(16).padStart(2, "0")).join("");
1207
+ if (digestHex2 === expectedHex) {
1208
+ return { valid: true, matchedAs: "json" };
1209
+ }
1210
+ } catch {
1211
+ }
1212
+ }
1213
+ let rawBytes;
1214
+ if (content instanceof Uint8Array) {
1215
+ rawBytes = content;
1216
+ } else if (typeof content === "string") {
1217
+ rawBytes = new TextEncoder().encode(content);
1218
+ } else {
1219
+ return {
1220
+ valid: false,
1221
+ reason: "Content did not match as canonical JSON and is not raw bytes"
1222
+ };
1223
+ }
1224
+ const digest = await sha2.sha256.digest(rawBytes);
1225
+ const digestHex = Array.from(digest.digest).map((b) => b.toString(16).padStart(2, "0")).join("");
1226
+ if (digestHex === expectedHex) {
1227
+ return { valid: true, matchedAs: "binary" };
1228
+ }
1229
+ return {
1230
+ valid: false,
1231
+ reason: "Content does not match the did:artifact identifier (neither as canonical JSON nor as raw bytes)"
1232
+ };
1233
+ }
1234
+ function didEthrToDidPkh(did) {
1235
+ if (typeof did !== "string" || !did.startsWith("did:ethr:")) {
1236
+ throw new OmaTrustError("INVALID_DID", "Expected a did:ethr DID", { did });
1237
+ }
1238
+ const remainder = did.slice("did:ethr:".length);
1239
+ if (!remainder) {
1240
+ throw new OmaTrustError("INVALID_DID", "Missing identifier in did:ethr DID", { did });
1241
+ }
1242
+ let chainId;
1243
+ let address;
1244
+ const parts = remainder.split(":");
1245
+ if (parts.length === 1) {
1246
+ chainId = "1";
1247
+ address = parts[0];
1248
+ } else if (parts.length === 2) {
1249
+ const rawChainId = parts[0];
1250
+ address = parts[1];
1251
+ if (rawChainId.startsWith("0x")) {
1252
+ chainId = String(parseInt(rawChainId, 16));
1253
+ } else if (/^\d+$/.test(rawChainId)) {
1254
+ chainId = rawChainId;
1255
+ } else {
1256
+ const networkMap = {
1257
+ mainnet: "1",
1258
+ goerli: "5",
1259
+ sepolia: "11155111",
1260
+ polygon: "137",
1261
+ arbitrum: "42161",
1262
+ optimism: "10",
1263
+ base: "8453"
1264
+ };
1265
+ const mapped = networkMap[rawChainId.toLowerCase()];
1266
+ if (!mapped) {
1267
+ throw new OmaTrustError(
1268
+ "INVALID_DID",
1269
+ `Unknown did:ethr network "${rawChainId}"`,
1270
+ { did, network: rawChainId }
1271
+ );
1272
+ }
1273
+ chainId = mapped;
1274
+ }
1275
+ } else {
1276
+ throw new OmaTrustError("INVALID_DID", "Invalid did:ethr format", { did });
1277
+ }
1278
+ if (!ethers.isAddress(address)) {
1279
+ throw new OmaTrustError("INVALID_DID", "Invalid Ethereum address in did:ethr DID", {
1280
+ did,
1281
+ address
1282
+ });
1283
+ }
1284
+ const checksummed = ethers.getAddress(address);
1285
+ return `did:pkh:eip155:${chainId}:${checksummed.toLowerCase()}`;
1286
+ }
1287
+ var MULTICODEC_KEY_TYPES = {
1288
+ // Ed25519 public key: 0xed (varint encoded as [0xed, 0x01])
1289
+ 237: { kty: "OKP", crv: "Ed25519" },
1290
+ // X25519 public key: 0xec (varint encoded as [0xec, 0x01])
1291
+ 236: { kty: "OKP", crv: "X25519" },
1292
+ // secp256k1 public key (compressed): 0xe7 (varint encoded as [0xe7, 0x01])
1293
+ 231: { kty: "EC", crv: "secp256k1", coordSize: 33 },
1294
+ // P-256 public key (compressed): 0x80 0x24 (varint 0x1200)
1295
+ 4608: { kty: "EC", crv: "P-256", coordSize: 33 },
1296
+ // P-384 public key (compressed): 0x81 0x24 (varint 0x1201)
1297
+ 4609: { kty: "EC", crv: "P-384", coordSize: 49 }
1298
+ };
1299
+ function readVarint(bytes, offset) {
1300
+ let value = 0;
1301
+ let shift = 0;
1302
+ let bytesRead = 0;
1303
+ while (offset + bytesRead < bytes.length) {
1304
+ const byte = bytes[offset + bytesRead];
1305
+ value |= (byte & 127) << shift;
1306
+ bytesRead++;
1307
+ if ((byte & 128) === 0) {
1308
+ return { value, bytesRead };
1309
+ }
1310
+ shift += 7;
1311
+ if (shift > 28) {
1312
+ throw new OmaTrustError("INVALID_DID", "Varint too long in did:key multicodec prefix");
1313
+ }
1314
+ }
1315
+ throw new OmaTrustError("INVALID_DID", "Truncated varint in did:key multicodec prefix");
1316
+ }
1317
+ function decompressEcKey(compressedKey, crv) {
1318
+ throw new OmaTrustError(
1319
+ "UNSUPPORTED_KEY_TYPE",
1320
+ `Cannot convert compressed EC key (${crv}) from did:key to did:jwk. Decompressing EC points requires elliptic curve arithmetic. For EVM keys, use didEthrToDidPkh() instead.`,
1321
+ { crv, keyLength: compressedKey.length }
1322
+ );
1323
+ }
1324
+ function didKeyToDidJwk(did) {
1325
+ if (typeof did !== "string" || !did.startsWith("did:key:")) {
1326
+ throw new OmaTrustError("INVALID_DID", "Expected a did:key DID", { did });
1327
+ }
1328
+ const identifier = did.slice("did:key:".length);
1329
+ if (!identifier || !identifier.startsWith("z")) {
1330
+ throw new OmaTrustError(
1331
+ "INVALID_DID",
1332
+ "did:key identifier must start with 'z' (base58btc multibase prefix)",
1333
+ { did }
1334
+ );
1335
+ }
1336
+ let decoded;
1337
+ try {
1338
+ decoded = base58.base58btc.decode(identifier);
1339
+ } catch (err) {
1340
+ throw new OmaTrustError(
1341
+ "INVALID_DID",
1342
+ "Failed to decode base58btc from did:key identifier",
1343
+ { did, cause: err }
1344
+ );
1345
+ }
1346
+ if (decoded.length < 3) {
1347
+ throw new OmaTrustError("INVALID_DID", "did:key decoded bytes too short", { did });
1348
+ }
1349
+ const { value: codecValue, bytesRead } = readVarint(decoded, 0);
1350
+ const keyType = MULTICODEC_KEY_TYPES[codecValue];
1351
+ if (!keyType) {
1352
+ throw new OmaTrustError(
1353
+ "UNSUPPORTED_KEY_TYPE",
1354
+ `Unsupported multicodec key type 0x${codecValue.toString(16)} in did:key`,
1355
+ { did, codec: `0x${codecValue.toString(16)}` }
1356
+ );
1357
+ }
1358
+ const keyBytes = decoded.slice(bytesRead);
1359
+ if (keyType.kty === "OKP") {
1360
+ if (keyBytes.length !== 32) {
1361
+ throw new OmaTrustError(
1362
+ "INVALID_DID",
1363
+ `Expected 32-byte ${keyType.crv} key, got ${keyBytes.length} bytes`,
1364
+ { did, crv: keyType.crv }
1365
+ );
1366
+ }
1367
+ const jwk = {
1368
+ kty: keyType.kty,
1369
+ crv: keyType.crv,
1370
+ x: jose.base64url.encode(keyBytes)
1371
+ };
1372
+ return jwkToDidJwk(jwk);
1373
+ }
1374
+ return decompressEcKey(keyBytes, keyType.crv).x.toString();
1375
+ }
897
1376
 
898
1377
  // src/reputation/index.ts
899
1378
  var reputation_exports = {};
@@ -960,10 +1439,13 @@ __export(reputation_exports, {
960
1439
  verifyDidWebOwnership: () => verifyDidWebOwnership,
961
1440
  verifyDnsTxtControllerDid: () => verifyDnsTxtControllerDid2,
962
1441
  verifyEip712Signature: () => verifyEip712Signature,
1442
+ verifyKeyBindingProofs: () => verifyKeyBindingProofs,
1443
+ verifyLinkedIdentifierProofs: () => verifyLinkedIdentifierProofs,
963
1444
  verifyProof: () => verifyProof,
964
1445
  verifySchemaExists: () => verifySchemaExists,
965
1446
  verifySubjectOwnership: () => verifySubjectOwnership,
966
1447
  verifyTransferProof: () => verifyTransferProof,
1448
+ verifyX402Artifact: () => verifyX402Artifact,
967
1449
  verifyX402Eip712Artifact: () => verifyX402Eip712Artifact,
968
1450
  verifyX402Eip712Offer: () => verifyX402Eip712Offer,
969
1451
  verifyX402Eip712Receipt: () => verifyX402Eip712Receipt,
@@ -1976,10 +2458,10 @@ function validateReceiptPayload(payload) {
1976
2458
  }
1977
2459
  return { valid: true };
1978
2460
  }
1979
- function failure(code, message, partial) {
2461
+ function failure(code2, message, partial) {
1980
2462
  return {
1981
2463
  valid: false,
1982
- error: { code, message },
2464
+ error: { code: code2, message },
1983
2465
  ...partial
1984
2466
  };
1985
2467
  }
@@ -2177,10 +2659,10 @@ function validateReceiptPayload2(payload) {
2177
2659
  }
2178
2660
  return { valid: true };
2179
2661
  }
2180
- function failure2(code, message, partial) {
2662
+ function failure2(code2, message, partial) {
2181
2663
  return {
2182
2664
  valid: false,
2183
- error: { code, message },
2665
+ error: { code: code2, message },
2184
2666
  ...partial
2185
2667
  };
2186
2668
  }
@@ -2698,8 +3180,8 @@ async function readOwnerFromContract(provider, contractAddress, signature, metho
2698
3180
  }
2699
3181
  async function discoverContractOwner(provider, contractAddress) {
2700
3182
  try {
2701
- const code = await provider.getCode(contractAddress);
2702
- if (code === "0x" || code === "0x0") {
3183
+ const code2 = await provider.getCode(contractAddress);
3184
+ if (code2 === "0x" || code2 === "0x0") {
2703
3185
  return null;
2704
3186
  }
2705
3187
  } catch {
@@ -3207,6 +3689,42 @@ function createX402OfferProof(offer) {
3207
3689
  };
3208
3690
  }
3209
3691
 
3692
+ // src/reputation/proof/x402-verify.ts
3693
+ async function verifyX402Artifact(artifact, options) {
3694
+ if (!artifact || typeof artifact !== "object") {
3695
+ return {
3696
+ valid: false,
3697
+ error: { code: "INVALID_ARTIFACT", message: "Artifact must be a non-null object" }
3698
+ };
3699
+ }
3700
+ const format = artifact.format;
3701
+ switch (format) {
3702
+ case "jws": {
3703
+ const jwsArtifact = artifact;
3704
+ const jwsOptions = options.resolveOptions ? { resolveOptions: options.resolveOptions } : void 0;
3705
+ if (options.artifactType === "offer") {
3706
+ return verifyX402JwsOffer(jwsArtifact, jwsOptions);
3707
+ }
3708
+ return verifyX402JwsReceipt(jwsArtifact, jwsOptions);
3709
+ }
3710
+ case "eip712": {
3711
+ const eip712Artifact = artifact;
3712
+ if (options.artifactType === "offer") {
3713
+ return verifyX402Eip712Offer(eip712Artifact);
3714
+ }
3715
+ return verifyX402Eip712Receipt(eip712Artifact);
3716
+ }
3717
+ default:
3718
+ return {
3719
+ valid: false,
3720
+ error: {
3721
+ code: "UNSUPPORTED_FORMAT",
3722
+ message: `Unsupported x402 artifact format: "${format}"`
3723
+ }
3724
+ };
3725
+ }
3726
+ }
3727
+
3210
3728
  // src/reputation/proof/evidence-pointer.ts
3211
3729
  function createEvidencePointerProof(url) {
3212
3730
  if (!url || typeof url !== "string") {
@@ -3315,8 +3833,8 @@ async function verifyDidPkhOwnership(params) {
3315
3833
  subjectDid: params.subjectDid
3316
3834
  });
3317
3835
  }
3318
- const code = await params.provider.getCode(subjectAddress);
3319
- const isContract = code !== "0x" && code !== "0x0";
3836
+ const code2 = await params.provider.getCode(subjectAddress);
3837
+ const isContract = code2 !== "0x" && code2 !== "0x0";
3320
3838
  if (!isContract) {
3321
3839
  if (ethers.getAddress(subjectAddress) === ethers.getAddress(connectedWalletAddress)) {
3322
3840
  return {
@@ -3492,6 +4010,300 @@ async function verifySubjectOwnership(params) {
3492
4010
  subjectDid
3493
4011
  });
3494
4012
  }
4013
+ function extractEip712Signer(proof) {
4014
+ const { domain, message, signature } = proof.proofObject;
4015
+ const typedData = {
4016
+ domain,
4017
+ types: {
4018
+ OmaTrustProof: [
4019
+ { name: "signer", type: "address" },
4020
+ { name: "authorizedEntity", type: "string" },
4021
+ { name: "signingPurpose", type: "string" },
4022
+ { name: "creationTimestamp", type: "uint256" },
4023
+ { name: "expirationTimestamp", type: "uint256" },
4024
+ { name: "randomValue", type: "bytes32" },
4025
+ { name: "statement", type: "string" }
4026
+ ]
4027
+ },
4028
+ message
4029
+ };
4030
+ try {
4031
+ const result = verifyEip712Signature(typedData, signature);
4032
+ return result.valid && result.signer ? result.signer : null;
4033
+ } catch (err) {
4034
+ console.warn("[omatrust] EIP-712 signer extraction failed:", err);
4035
+ return null;
4036
+ }
4037
+ }
4038
+ function extractJwsHeaderJwk(proof) {
4039
+ const jws = proof.proofObject;
4040
+ if (typeof jws !== "string") return null;
4041
+ const parts = jws.split(".");
4042
+ if (parts.length !== 3) return null;
4043
+ try {
4044
+ const headerB64 = parts[0].replace(/-/g, "+").replace(/_/g, "/");
4045
+ const padded = headerB64.padEnd(
4046
+ headerB64.length + (4 - headerB64.length % 4) % 4,
4047
+ "="
4048
+ );
4049
+ let headerJson;
4050
+ if (typeof atob === "function") {
4051
+ headerJson = decodeURIComponent(
4052
+ Array.from(atob(padded)).map((char) => `%${char.charCodeAt(0).toString(16).padStart(2, "0")}`).join("")
4053
+ );
4054
+ } else {
4055
+ headerJson = Buffer.from(padded, "base64").toString("utf8");
4056
+ }
4057
+ const header = JSON.parse(headerJson);
4058
+ return header.jwk ?? null;
4059
+ } catch {
4060
+ return null;
4061
+ }
4062
+ }
4063
+ function extractJwsPayload(proof) {
4064
+ const jws = proof.proofObject;
4065
+ if (typeof jws !== "string") return null;
4066
+ const parts = jws.split(".");
4067
+ if (parts.length !== 3) return null;
4068
+ try {
4069
+ const payloadB64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
4070
+ const padded = payloadB64.padEnd(
4071
+ payloadB64.length + (4 - payloadB64.length % 4) % 4,
4072
+ "="
4073
+ );
4074
+ let payloadJson;
4075
+ if (typeof atob === "function") {
4076
+ payloadJson = decodeURIComponent(
4077
+ Array.from(atob(padded)).map((char) => `%${char.charCodeAt(0).toString(16).padStart(2, "0")}`).join("")
4078
+ );
4079
+ } else {
4080
+ payloadJson = Buffer.from(padded, "base64").toString("utf8");
4081
+ }
4082
+ return JSON.parse(payloadJson);
4083
+ } catch {
4084
+ return null;
4085
+ }
4086
+ }
4087
+ function signerMatchesDid(signerAddress, did) {
4088
+ try {
4089
+ const didAddress = extractAddressFromDid(did);
4090
+ return ethers.getAddress(signerAddress).toLowerCase() === ethers.getAddress(didAddress).toLowerCase();
4091
+ } catch {
4092
+ return false;
4093
+ }
4094
+ }
4095
+ function jwkMatchesDid(jwk, did) {
4096
+ const method = extractDidMethod(did);
4097
+ if (method === "jwk") {
4098
+ try {
4099
+ const didJwk = didJwkToJwk(did);
4100
+ return publicJwkEquals(jwk, didJwk);
4101
+ } catch {
4102
+ return false;
4103
+ }
4104
+ }
4105
+ return false;
4106
+ }
4107
+ function proofSignerMatchesDid(proof, did) {
4108
+ switch (proof.proofType) {
4109
+ case "pop-eip712": {
4110
+ const signer = extractEip712Signer(proof);
4111
+ if (!signer) return false;
4112
+ return signerMatchesDid(signer, did);
4113
+ }
4114
+ case "pop-jws": {
4115
+ const jwsProof = proof;
4116
+ const jwk = extractJwsHeaderJwk(jwsProof);
4117
+ if (jwk && jwkMatchesDid(jwk, did)) return true;
4118
+ const payload = extractJwsPayload(jwsProof);
4119
+ if (payload && typeof payload.iss === "string") {
4120
+ if (payload.iss === did) return true;
4121
+ }
4122
+ return false;
4123
+ }
4124
+ case "tx-encoded-value":
4125
+ case "tx-interaction":
4126
+ return false;
4127
+ case "evidence-pointer":
4128
+ return false;
4129
+ default:
4130
+ return false;
4131
+ }
4132
+ }
4133
+ function proofAuthorizedEntityMatchesDid(proof, did) {
4134
+ switch (proof.proofType) {
4135
+ case "pop-eip712": {
4136
+ const eip712 = proof;
4137
+ const authorizedEntity = eip712.proofObject.message.authorizedEntity;
4138
+ return typeof authorizedEntity === "string" && authorizedEntity === did;
4139
+ }
4140
+ case "pop-jws": {
4141
+ const payload = extractJwsPayload(proof);
4142
+ if (!payload) return false;
4143
+ return typeof payload.aud === "string" && payload.aud === did;
4144
+ }
4145
+ default:
4146
+ return false;
4147
+ }
4148
+ }
4149
+ function verifyLinkedIdentifierProofs(data) {
4150
+ if (!data.subject || !data.linkedId) {
4151
+ return {
4152
+ valid: false,
4153
+ checks: [],
4154
+ reasons: ["subject and linkedId are required"]
4155
+ };
4156
+ }
4157
+ if (!Array.isArray(data.proofs) || data.proofs.length === 0) {
4158
+ return {
4159
+ valid: false,
4160
+ checks: [],
4161
+ reasons: ["At least one proof is required"]
4162
+ };
4163
+ }
4164
+ const checks = [];
4165
+ let subjectProved = false;
4166
+ let linkedIdProved = false;
4167
+ for (let i = 0; i < data.proofs.length; i++) {
4168
+ const proof = data.proofs[i];
4169
+ if (proofSignerMatchesDid(proof, data.subject)) {
4170
+ checks.push({
4171
+ proofIndex: i,
4172
+ proofType: proof.proofType,
4173
+ checkType: "signer-is-subject",
4174
+ valid: true
4175
+ });
4176
+ subjectProved = true;
4177
+ if (!proofAuthorizedEntityMatchesDid(proof, data.linkedId)) {
4178
+ checks.push({
4179
+ proofIndex: i,
4180
+ proofType: proof.proofType,
4181
+ checkType: "signer-is-subject",
4182
+ valid: false,
4183
+ reason: "Proof from subject does not authorize linkedId (aud mismatch)"
4184
+ });
4185
+ }
4186
+ }
4187
+ if (proofSignerMatchesDid(proof, data.linkedId)) {
4188
+ checks.push({
4189
+ proofIndex: i,
4190
+ proofType: proof.proofType,
4191
+ checkType: "signer-is-linkedId",
4192
+ valid: true
4193
+ });
4194
+ linkedIdProved = true;
4195
+ if (!proofAuthorizedEntityMatchesDid(proof, data.subject)) {
4196
+ checks.push({
4197
+ proofIndex: i,
4198
+ proofType: proof.proofType,
4199
+ checkType: "signer-is-linkedId",
4200
+ valid: false,
4201
+ reason: "Proof from linkedId does not authorize subject (aud mismatch)"
4202
+ });
4203
+ }
4204
+ }
4205
+ if (proof.proofType === "evidence-pointer") {
4206
+ checks.push({
4207
+ proofIndex: i,
4208
+ proofType: proof.proofType,
4209
+ checkType: "signer-is-subject",
4210
+ valid: true,
4211
+ reason: "Evidence pointer accepted (requires URL fetch for full verification)"
4212
+ });
4213
+ subjectProved = true;
4214
+ }
4215
+ }
4216
+ const reasons = [];
4217
+ if (!subjectProved) {
4218
+ reasons.push("No proof demonstrates control by subject");
4219
+ }
4220
+ if (!linkedIdProved) {
4221
+ reasons.push("No proof demonstrates control by linkedId");
4222
+ }
4223
+ return {
4224
+ valid: reasons.length === 0,
4225
+ checks,
4226
+ reasons
4227
+ };
4228
+ }
4229
+ function verifyKeyBindingProofs(data) {
4230
+ if (!data.subject || !data.keyId) {
4231
+ return {
4232
+ valid: false,
4233
+ checks: [],
4234
+ reasons: ["subject and keyId are required"]
4235
+ };
4236
+ }
4237
+ if (!Array.isArray(data.proofs) || data.proofs.length === 0) {
4238
+ return {
4239
+ valid: false,
4240
+ checks: [],
4241
+ reasons: ["At least one proof is required"]
4242
+ };
4243
+ }
4244
+ const checks = [];
4245
+ let subjectAuthorizedKey = false;
4246
+ for (let i = 0; i < data.proofs.length; i++) {
4247
+ const proof = data.proofs[i];
4248
+ if (proofSignerMatchesDid(proof, data.subject)) {
4249
+ const authorizesKey = proofAuthorizedEntityMatchesDid(proof, data.keyId);
4250
+ checks.push({
4251
+ proofIndex: i,
4252
+ proofType: proof.proofType,
4253
+ checkType: "signer-is-subject-for-key",
4254
+ valid: authorizesKey,
4255
+ reason: authorizesKey ? void 0 : "Proof signed by subject but does not authorize the keyId"
4256
+ });
4257
+ if (authorizesKey) {
4258
+ subjectAuthorizedKey = true;
4259
+ }
4260
+ }
4261
+ if (proofSignerMatchesDid(proof, data.keyId)) {
4262
+ checks.push({
4263
+ proofIndex: i,
4264
+ proofType: proof.proofType,
4265
+ checkType: "signer-is-keyId",
4266
+ valid: true,
4267
+ reason: "Key proved possession (supplementary, not sufficient alone)"
4268
+ });
4269
+ }
4270
+ if (proof.proofType === "evidence-pointer") {
4271
+ checks.push({
4272
+ proofIndex: i,
4273
+ proofType: proof.proofType,
4274
+ checkType: "signer-is-subject-for-key",
4275
+ valid: true,
4276
+ reason: "Evidence pointer accepted (requires URL fetch for full verification)"
4277
+ });
4278
+ subjectAuthorizedKey = true;
4279
+ }
4280
+ }
4281
+ if (data.publicKeyJwk && extractDidMethod(data.keyId) === "jwk") {
4282
+ try {
4283
+ const keyIdJwk = didJwkToJwk(data.keyId);
4284
+ const jwkConsistent = publicJwkEquals(data.publicKeyJwk, keyIdJwk);
4285
+ if (!jwkConsistent) {
4286
+ return {
4287
+ valid: false,
4288
+ checks,
4289
+ reasons: ["publicKeyJwk does not match the key material in keyId (did:jwk)"]
4290
+ };
4291
+ }
4292
+ } catch {
4293
+ }
4294
+ }
4295
+ const reasons = [];
4296
+ if (!subjectAuthorizedKey) {
4297
+ reasons.push(
4298
+ "No proof demonstrates that subject authorized the key binding"
4299
+ );
4300
+ }
4301
+ return {
4302
+ valid: reasons.length === 0,
4303
+ checks,
4304
+ reasons
4305
+ };
4306
+ }
3495
4307
 
3496
4308
  // src/app-registry/index.ts
3497
4309
  var app_registry_exports = {};
@@ -3579,8 +4391,8 @@ function getInterfaceTypes(bitmap) {
3579
4391
  }
3580
4392
 
3581
4393
  // src/app-registry/status.ts
3582
- function registryCodeToStatus(code) {
3583
- switch (code) {
4394
+ function registryCodeToStatus(code2) {
4395
+ switch (code2) {
3584
4396
  case 0:
3585
4397
  return "Active";
3586
4398
  case 1:
@@ -3588,7 +4400,7 @@ function registryCodeToStatus(code) {
3588
4400
  case 2:
3589
4401
  return "Replaced";
3590
4402
  default:
3591
- throw new OmaTrustError("INVALID_INPUT", "Invalid registry status code", { code });
4403
+ throw new OmaTrustError("INVALID_INPUT", "Invalid registry status code", { code: code2 });
3592
4404
  }
3593
4405
  }
3594
4406
  function registryStatusToCode(status) {
@@ -3690,6 +4502,9 @@ async function computeDataHashFromUrl(url, algorithm) {
3690
4502
  if (!url || typeof url !== "string") {
3691
4503
  throw new OmaTrustError("INVALID_INPUT", "url must be a non-empty string", { url });
3692
4504
  }
4505
+ if (algorithm !== "keccak256" && algorithm !== "sha256") {
4506
+ throw new OmaTrustError("INVALID_INPUT", `Unsupported hash algorithm: "${algorithm}". Must be "keccak256" or "sha256".`, { algorithm });
4507
+ }
3693
4508
  const json = await fetchJson(url);
3694
4509
  const jcsJson = canonicalizeJson(json);
3695
4510
  return hashJcs(jcsJson, algorithm);