@interop/wallet-core 0.23.1 → 0.25.0

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 (125) hide show
  1. package/README.md +41 -22
  2. package/dist/clients/index.d.ts +6 -4
  3. package/dist/clients/index.d.ts.map +1 -1
  4. package/dist/clients/index.js +5 -3
  5. package/dist/clients/index.js.map +1 -1
  6. package/dist/clients/policy.d.ts +11 -3
  7. package/dist/clients/policy.d.ts.map +1 -1
  8. package/dist/clients/policy.js +12 -4
  9. package/dist/clients/policy.js.map +1 -1
  10. package/dist/clients/revocation.d.ts +24 -9
  11. package/dist/clients/revocation.d.ts.map +1 -1
  12. package/dist/clients/revocation.js +23 -10
  13. package/dist/clients/revocation.js.map +1 -1
  14. package/dist/clients/rosterPolicy.d.ts +23 -22
  15. package/dist/clients/rosterPolicy.d.ts.map +1 -1
  16. package/dist/clients/rosterPolicy.js +50 -31
  17. package/dist/clients/rosterPolicy.js.map +1 -1
  18. package/dist/descriptors/acquire.d.ts +4 -1
  19. package/dist/descriptors/acquire.d.ts.map +1 -1
  20. package/dist/descriptors/acquire.js +29 -1
  21. package/dist/descriptors/acquire.js.map +1 -1
  22. package/dist/descriptors/index.d.ts +9 -1
  23. package/dist/descriptors/index.d.ts.map +1 -1
  24. package/dist/descriptors/index.js +9 -1
  25. package/dist/descriptors/index.js.map +1 -1
  26. package/dist/descriptors/logSource.d.ts +33 -0
  27. package/dist/descriptors/logSource.d.ts.map +1 -0
  28. package/dist/descriptors/logSource.js +49 -0
  29. package/dist/descriptors/logSource.js.map +1 -0
  30. package/dist/enrollment/enrollment.d.ts +2 -2
  31. package/dist/enrollment/enrollment.d.ts.map +1 -1
  32. package/dist/enrollment/enrollment.js +15 -10
  33. package/dist/enrollment/enrollment.js.map +1 -1
  34. package/dist/index.d.ts +1 -1
  35. package/dist/index.js +1 -1
  36. package/dist/keys/index.d.ts +15 -8
  37. package/dist/keys/index.d.ts.map +1 -1
  38. package/dist/keys/index.js +14 -8
  39. package/dist/keys/index.js.map +1 -1
  40. package/dist/keys/rosterLogStore.d.ts +53 -0
  41. package/dist/keys/rosterLogStore.d.ts.map +1 -0
  42. package/dist/keys/rosterLogStore.js +134 -0
  43. package/dist/keys/rosterLogStore.js.map +1 -0
  44. package/dist/keys/rosterStore.d.ts +20 -6
  45. package/dist/keys/rosterStore.d.ts.map +1 -1
  46. package/dist/keys/rosterStore.js +36 -17
  47. package/dist/keys/rosterStore.js.map +1 -1
  48. package/dist/keys/userKeyCascade.d.ts +14 -7
  49. package/dist/keys/userKeyCascade.d.ts.map +1 -1
  50. package/dist/keys/userKeyCascade.js +12 -3
  51. package/dist/keys/userKeyCascade.js.map +1 -1
  52. package/dist/keys/userKeyRoster.d.ts +50 -97
  53. package/dist/keys/userKeyRoster.d.ts.map +1 -1
  54. package/dist/keys/userKeyRoster.js +44 -145
  55. package/dist/keys/userKeyRoster.js.map +1 -1
  56. package/dist/request/appKey.d.ts +255 -0
  57. package/dist/request/appKey.d.ts.map +1 -0
  58. package/dist/request/appKey.js +492 -0
  59. package/dist/request/appKey.js.map +1 -0
  60. package/dist/request/classify.d.ts +54 -3
  61. package/dist/request/classify.d.ts.map +1 -1
  62. package/dist/request/classify.js +106 -0
  63. package/dist/request/classify.js.map +1 -1
  64. package/dist/request/composeVp.d.ts +6 -7
  65. package/dist/request/composeVp.d.ts.map +1 -1
  66. package/dist/request/composeVp.js +44 -55
  67. package/dist/request/composeVp.js.map +1 -1
  68. package/dist/request/index.d.ts +4 -0
  69. package/dist/request/index.d.ts.map +1 -1
  70. package/dist/request/index.js +4 -0
  71. package/dist/request/index.js.map +1 -1
  72. package/dist/request/processRequest.d.ts +1 -4
  73. package/dist/request/processRequest.d.ts.map +1 -1
  74. package/dist/request/processRequest.js +17 -11
  75. package/dist/request/processRequest.js.map +1 -1
  76. package/dist/request/types.d.ts +45 -2
  77. package/dist/request/types.d.ts.map +1 -1
  78. package/dist/resourceLog/append.d.ts +103 -0
  79. package/dist/resourceLog/append.d.ts.map +1 -0
  80. package/dist/resourceLog/append.js +190 -0
  81. package/dist/resourceLog/append.js.map +1 -0
  82. package/dist/resourceLog/controller.d.ts +57 -0
  83. package/dist/resourceLog/controller.d.ts.map +1 -0
  84. package/dist/resourceLog/controller.js +81 -0
  85. package/dist/resourceLog/controller.js.map +1 -0
  86. package/dist/resourceLog/entry.d.ts +68 -0
  87. package/dist/resourceLog/entry.d.ts.map +1 -0
  88. package/dist/resourceLog/entry.js +167 -0
  89. package/dist/resourceLog/entry.js.map +1 -0
  90. package/dist/resourceLog/errors.d.ts +75 -0
  91. package/dist/resourceLog/errors.d.ts.map +1 -0
  92. package/dist/resourceLog/errors.js +76 -0
  93. package/dist/resourceLog/errors.js.map +1 -0
  94. package/dist/resourceLog/index.d.ts +26 -0
  95. package/dist/resourceLog/index.d.ts.map +1 -0
  96. package/dist/resourceLog/index.js +26 -0
  97. package/dist/resourceLog/index.js.map +1 -0
  98. package/dist/resourceLog/pin.d.ts +44 -0
  99. package/dist/resourceLog/pin.d.ts.map +1 -0
  100. package/dist/resourceLog/pin.js +32 -0
  101. package/dist/resourceLog/pin.js.map +1 -0
  102. package/dist/resourceLog/seal.d.ts +86 -0
  103. package/dist/resourceLog/seal.d.ts.map +1 -0
  104. package/dist/resourceLog/seal.js +99 -0
  105. package/dist/resourceLog/seal.js.map +1 -0
  106. package/dist/resourceLog/verify.d.ts +95 -0
  107. package/dist/resourceLog/verify.d.ts.map +1 -0
  108. package/dist/resourceLog/verify.js +435 -0
  109. package/dist/resourceLog/verify.js.map +1 -0
  110. package/dist/space/collections.d.ts +14 -11
  111. package/dist/space/collections.d.ts.map +1 -1
  112. package/dist/space/collections.js +14 -11
  113. package/dist/space/collections.js.map +1 -1
  114. package/dist/space/index.d.ts +2 -2
  115. package/dist/space/index.d.ts.map +1 -1
  116. package/dist/space/index.js +2 -2
  117. package/dist/space/index.js.map +1 -1
  118. package/dist/webvh/didWeb.d.ts +4 -6
  119. package/dist/webvh/didWeb.d.ts.map +1 -1
  120. package/dist/webvh/didWeb.js.map +1 -1
  121. package/dist/webvh/didWebvh.d.ts +1 -2
  122. package/dist/webvh/didWebvh.d.ts.map +1 -1
  123. package/dist/webvh/didWebvh.js +1 -6
  124. package/dist/webvh/didWebvh.js.map +1 -1
  125. package/package.json +11 -4
@@ -0,0 +1,99 @@
1
+ import { appendResourceLog, readResourceLog } from './append.js';
2
+ /**
3
+ * The controller's latest membership change: the largest index into
4
+ * `controller.versionIds` whose `assertionMethod` key set LOST a member
5
+ * against its predecessor's, or `0` when no version ever removed one (the
6
+ * genesis version has no predecessor and can never register as a removal, so
7
+ * `0` doubles as "nothing to seal against" -- every anchor satisfies it). An
8
+ * unversioned controller resolves `0` for the same reason: with no version
9
+ * history there is no removal to locate.
10
+ *
11
+ * @param options {object}
12
+ * @param options.controller {ResourceLogController} the verified controller
13
+ * view
14
+ * @returns {Promise<number>}
15
+ */
16
+ export async function latestAssertionRemovalIndex({ controller }) {
17
+ let removalIndex = 0;
18
+ let previous = null;
19
+ for (const [index, versionId] of controller.versionIds.entries()) {
20
+ const keys = await controller.assertionKeysAt(versionId);
21
+ if (previous !== null) {
22
+ for (const key of previous) {
23
+ if (!keys.has(key)) {
24
+ removalIndex = index;
25
+ break;
26
+ }
27
+ }
28
+ }
29
+ previous = keys;
30
+ }
31
+ return removalIndex;
32
+ }
33
+ /**
34
+ * Seals one resource log against the controller's latest membership change,
35
+ * idempotently: when the verified head already anchors at or past the latest
36
+ * `assertionMethod` removal (or the controller never removed one, or the log
37
+ * does not exist yet, or the controller is unversioned) nothing is written;
38
+ * otherwise the head state is re-appended VERBATIM as a no-op entry whose
39
+ * only job is its post-removal anchor -- ordinary entries may repeat state
40
+ * (only terminal entries are state-constrained), so the resource itself is
41
+ * untouched. A closed log that needs sealing propagates the append path's
42
+ * `ResourceLogClosedError`.
43
+ *
44
+ * `sealed` reports whether this call found the log unsealed (and it now is,
45
+ * by this call's append or a concurrent writer's -- the rebase hook converges
46
+ * rather than duplicating); `verified` is the log as last verified, `null`
47
+ * when it was never read (absent, or nothing to seal against).
48
+ *
49
+ * @param options {object}
50
+ * @param options.store {ResourceLogStore} the log's transport seam
51
+ * @param options.controller {ResourceLogController} the verified controller
52
+ * view
53
+ * @param options.expectedMethod {string} the format identifier expected
54
+ * @param options.pinStore {ResourceLogPinStore} this client's chain-head
55
+ * pin for this log
56
+ * @param options.signer {ResourceLogSigner} this client's enrolled signing
57
+ * key
58
+ * @param [options.versionTime] {string} RFC3339 UTC; defaults to now
59
+ * @returns {Promise<{ sealed: boolean, verified: VerifiedResourceLog | null }>}
60
+ */
61
+ export async function sealResourceLog({ store, controller, expectedMethod, pinStore, signer, versionTime }) {
62
+ if (controller.versionIds.length === 0) {
63
+ return { sealed: false, verified: null };
64
+ }
65
+ const removalIndex = await latestAssertionRemovalIndex({ controller });
66
+ if (removalIndex === 0) {
67
+ return { sealed: false, verified: null };
68
+ }
69
+ const current = await readResourceLog({
70
+ store,
71
+ controller,
72
+ expectedMethod,
73
+ pinStore
74
+ });
75
+ if (current === null) {
76
+ return { sealed: false, verified: null };
77
+ }
78
+ const { verified } = current;
79
+ if (verified.headAnchorIndex !== null &&
80
+ verified.headAnchorIndex >= removalIndex) {
81
+ return { sealed: false, verified };
82
+ }
83
+ const confirmed = await appendResourceLog({
84
+ store,
85
+ controller,
86
+ expectedMethod,
87
+ pinStore,
88
+ signer,
89
+ // The rebase hook doubles as the convergence check: a concurrent writer
90
+ // whose entry already anchors past the removal sealed the log for us.
91
+ buildState: rebased => rebased.headAnchorIndex !== null &&
92
+ rebased.headAnchorIndex >= removalIndex
93
+ ? null
94
+ : rebased.head.state,
95
+ ...(versionTime === undefined ? {} : { versionTime })
96
+ });
97
+ return { sealed: true, verified: confirmed };
98
+ }
99
+ //# sourceMappingURL=seal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seal.js","sourceRoot":"","sources":["../../src/resourceLog/seal.ts"],"names":[],"mappings":"AAyBA,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAMhE;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,EAChD,UAAU,EAGX;IACC,IAAI,YAAY,GAAG,CAAC,CAAA;IACpB,IAAI,QAAQ,GAAuB,IAAI,CAAA;IACvC,KAAK,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC;QACjE,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,eAAe,CAAC,SAAS,CAAC,CAAA;QACxD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtB,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;gBAC3B,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;oBACnB,YAAY,GAAG,KAAK,CAAA;oBACpB,MAAK;gBACP,CAAC;YACH,CAAC;QACH,CAAC;QACD,QAAQ,GAAG,IAAI,CAAA;IACjB,CAAC;IACD,OAAO,YAAY,CAAA;AACrB,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EACpC,KAAK,EACL,UAAU,EACV,cAAc,EACd,QAAQ,EACR,MAAM,EACN,WAAW,EAQZ;IACC,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAA;IAC1C,CAAC;IACD,MAAM,YAAY,GAAG,MAAM,2BAA2B,CAAC,EAAE,UAAU,EAAE,CAAC,CAAA;IACtE,IAAI,YAAY,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAA;IAC1C,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC;QACpC,KAAK;QACL,UAAU;QACV,cAAc;QACd,QAAQ;KACT,CAAC,CAAA;IACF,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAA;IAC1C,CAAC;IACD,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAA;IAC5B,IACE,QAAQ,CAAC,eAAe,KAAK,IAAI;QACjC,QAAQ,CAAC,eAAe,IAAI,YAAY,EACxC,CAAC;QACD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAA;IACpC,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,iBAAiB,CAAC;QACxC,KAAK;QACL,UAAU;QACV,cAAc;QACd,QAAQ;QACR,MAAM;QACN,wEAAwE;QACxE,sEAAsE;QACtE,UAAU,EAAE,OAAO,CAAC,EAAE,CACpB,OAAO,CAAC,eAAe,KAAK,IAAI;YAChC,OAAO,CAAC,eAAe,IAAI,YAAY;YACrC,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK;QACxB,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;KACtD,CAAC,CAAA;IACF,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAA;AAC9C,CAAC"}
@@ -0,0 +1,95 @@
1
+ import type { ResourceLogEntry } from '@interop/was-client/log';
2
+ import type { ResourceLogController } from './controller.js';
3
+ import type { ResourceLogHeadPin } from './pin.js';
4
+ /**
5
+ * What full verification resolves to. `state` is the profile's definition of
6
+ * the resource's current state -- the verified head entry's `state` -- and
7
+ * `pin` is the record the caller must store as its new chain-head pin.
8
+ * `terminal` is the head's `nextLog` when the log is closed by a handover
9
+ * entry (appends must be refused), `previousLog` the genesis back-reference
10
+ * when this log is a handover successor. `headAnchorIndex` is the head's
11
+ * effective anchor -- the verifier's anchor floor after the whole loop, which
12
+ * monotonicity makes the head entry's own anchor -- as an index into the
13
+ * controller's `versionIds` (`null` on an unversioned controller, whose
14
+ * entries carry no anchors); the sealing sweep compares it against the
15
+ * controller's latest membership change.
16
+ */
17
+ export interface VerifiedResourceLog {
18
+ entries: ResourceLogEntry[];
19
+ method: string;
20
+ scid: string;
21
+ head: ResourceLogEntry;
22
+ state: ResourceLogEntry['state'];
23
+ pin: ResourceLogHeadPin;
24
+ headAnchorIndex: number | null;
25
+ terminal: {
26
+ method: string;
27
+ scid: string;
28
+ } | null;
29
+ previousLog: {
30
+ scid: string;
31
+ head: string;
32
+ } | null;
33
+ }
34
+ /**
35
+ * Whether an entry is a terminal handover entry: its `parameters` carry a
36
+ * `nextLog` member. Position, exact member set, and state equality are the
37
+ * verifier's checks; this is only the discriminant.
38
+ *
39
+ * @param entry {ResourceLogEntry}
40
+ * @returns {boolean}
41
+ */
42
+ export declare function isTerminalResourceLogEntry(entry: ResourceLogEntry): boolean;
43
+ /**
44
+ * Runs the profile's full verification over a parsed log, in order: parse
45
+ * shape, genesis (SCID recomputation, format identifier), chain-hash
46
+ * recomputation, per-entry proofs, the external-authorization rule with
47
+ * anchor monotonicity, termination, and continuity against the chain-head
48
+ * pin. Throws {@link ResourceLogIntegrityError} on fabrication-class
49
+ * failures, {@link ResourceLogContinuityError} on pin conflicts; any failure
50
+ * rejects the whole log.
51
+ *
52
+ * The controller view is the independently verified controller document --
53
+ * never material served beside the log. An unversioned controller (empty
54
+ * `versionIds`) degrades every anchor rule to current-document verification
55
+ * and requires anchorless proofs.
56
+ *
57
+ * @param options {object}
58
+ * @param options.entries {ResourceLogEntry[]} the parsed served log
59
+ * @param options.controller {ResourceLogController} the verified controller
60
+ * view ({@link webvhResourceLogController})
61
+ * @param options.expectedMethod {string} the format identifier this caller
62
+ * expects (`WAS_RESOURCE_LOG_METHOD`; also confirmed against any `history`
63
+ * dispatch hint the caller followed)
64
+ * @param [options.pin] {ResourceLogHeadPin} the held chain-head pin, when
65
+ * this client has verified the log before
66
+ * @returns {Promise<VerifiedResourceLog>}
67
+ */
68
+ export declare function verifyResourceLog({ entries, controller, expectedMethod, pin }: {
69
+ entries: ResourceLogEntry[];
70
+ controller: ResourceLogController;
71
+ expectedMethod: string;
72
+ pin?: ResourceLogHeadPin | null;
73
+ }): Promise<VerifiedResourceLog>;
74
+ /**
75
+ * Verifies a handover link from both sides: the prior log's terminal entry
76
+ * and the successor log's genesis back-reference. Both logs must already have
77
+ * passed {@link verifyResourceLog}. Checks: the terminal `nextLog` names the
78
+ * successor's SCID and method; the successor's `previousLog` names the prior
79
+ * log's SCID; and the successor's `previousLog.head` is the `versionId` of
80
+ * the terminal entry's immediate predecessor -- the terminal entry chains
81
+ * directly off the head the successor references. A verified handover is the
82
+ * one transition that replaces a chain-head pin wholesale (the caller stores
83
+ * `successor.pin`).
84
+ *
85
+ * @param options {object}
86
+ * @param options.prior {VerifiedResourceLog} the closed log
87
+ * @param options.successor {VerifiedResourceLog} the log its terminal entry
88
+ * names
89
+ * @returns {void}
90
+ */
91
+ export declare function verifyResourceLogHandover({ prior, successor }: {
92
+ prior: VerifiedResourceLog;
93
+ successor: VerifiedResourceLog;
94
+ }): void;
95
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/resourceLog/verify.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EACV,gBAAgB,EAEjB,MAAM,yBAAyB,CAAA;AAChC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAK5D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAalD;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,gBAAgB,EAAE,CAAA;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,gBAAgB,CAAA;IACtB,KAAK,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAA;IAChC,GAAG,EAAE,kBAAkB,CAAA;IACvB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,QAAQ,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IACjD,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CACnD;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAM3E;AAwOD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,iBAAiB,CAAC,EACtC,OAAO,EACP,UAAU,EACV,cAAc,EACd,GAAG,EACJ,EAAE;IACD,OAAO,EAAE,gBAAgB,EAAE,CAAA;IAC3B,UAAU,EAAE,qBAAqB,CAAA;IACjC,cAAc,EAAE,MAAM,CAAA;IACtB,GAAG,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAA;CAChC,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAgN/B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,yBAAyB,CAAC,EACxC,KAAK,EACL,SAAS,EACV,EAAE;IACD,KAAK,EAAE,mBAAmB,CAAA;IAC1B,SAAS,EAAE,mBAAmB,CAAA;CAC/B,GAAG,IAAI,CAqBP"}
@@ -0,0 +1,435 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The Resource Log Profile's verification algorithm (App Connect spec,
6
+ * `#log-verification`), end-to-end and fail-closed: entry-shape parse checks,
7
+ * SCID recomputation, chain-hash recomputation (never a stated head), proof
8
+ * verification through the did:webvh log kernel, the external-authorization
9
+ * rule (anchor resolution against the independently verified controller
10
+ * document, `assertionMethod` membership at the anchored version, anchor
11
+ * monotonicity), terminal-entry recognition, and continuity against the
12
+ * chain-head pin. Any failure rejects the LOG, not just the failing entry,
13
+ * and nothing served -- a stated head, a digest, a count -- is ever accepted
14
+ * in place of recomputation.
15
+ */
16
+ import { buildVersionId, canonicalizeStrict, defaultWebvhLogVerifier, deriveHash, parseAndValidateVersionId, SCID_PLACEHOLDER, verifyEntryProofs } from '@interop/did-method-webvh';
17
+ import { ResourceLogContinuityError, ResourceLogIntegrityError } from './errors.js';
18
+ /**
19
+ * The five members a log entry carries, exactly.
20
+ */
21
+ const ENTRY_MEMBERS = [
22
+ 'versionId',
23
+ 'versionTime',
24
+ 'parameters',
25
+ 'state',
26
+ 'proof'
27
+ ];
28
+ /**
29
+ * Whether an entry is a terminal handover entry: its `parameters` carry a
30
+ * `nextLog` member. Position, exact member set, and state equality are the
31
+ * verifier's checks; this is only the discriminant.
32
+ *
33
+ * @param entry {ResourceLogEntry}
34
+ * @returns {boolean}
35
+ */
36
+ export function isTerminalResourceLogEntry(entry) {
37
+ return (typeof entry.parameters === 'object' &&
38
+ entry.parameters !== null &&
39
+ 'nextLog' in entry.parameters);
40
+ }
41
+ /**
42
+ * Structural check of one member of an entry's `proof` array against the
43
+ * profile's fixed shape, before any cryptography runs.
44
+ *
45
+ * @param proof {unknown}
46
+ * @param ordinal {number} the owning entry's 1-based position
47
+ * @returns {ResourceLogEntryProof}
48
+ */
49
+ function checkProofShape(proof, ordinal) {
50
+ const candidate = proof;
51
+ if (candidate === null ||
52
+ typeof candidate !== 'object' ||
53
+ candidate.type !== 'DataIntegrityProof' ||
54
+ candidate.cryptosuite !== 'eddsa-jcs-2022' ||
55
+ candidate.proofPurpose !== 'assertionMethod' ||
56
+ typeof candidate.verificationMethod !== 'string' ||
57
+ typeof candidate.proofValue !== 'string') {
58
+ throw new ResourceLogIntegrityError(`Resource log entry ${ordinal} carries a proof outside the profile's ` +
59
+ `fixed shape (DataIntegrityProof / eddsa-jcs-2022 / assertionMethod).`);
60
+ }
61
+ return candidate;
62
+ }
63
+ /**
64
+ * Shape-checks one entry (the profile's parse step): exactly the five
65
+ * members, `versionId` ordinal at its 1-based position, an RFC3339 UTC
66
+ * `versionTime` (format only -- temporal refusals are forbidden), the
67
+ * per-position `parameters` rules fail-closed, a `state` carrying `type` and
68
+ * no `history`, and a non-empty fixed-shape `proof` array.
69
+ *
70
+ * @param entry {ResourceLogEntry}
71
+ * @param index {number} the entry's 0-based position
72
+ */
73
+ function checkEntryShape(entry, index) {
74
+ const ordinal = index + 1;
75
+ const members = Object.keys(entry);
76
+ if (members.length !== ENTRY_MEMBERS.length ||
77
+ ENTRY_MEMBERS.some(member => !(member in entry))) {
78
+ throw new ResourceLogIntegrityError(`Resource log entry ${ordinal} does not carry exactly the profile's ` +
79
+ `five members (versionId, versionTime, parameters, state, proof).`);
80
+ }
81
+ try {
82
+ parseAndValidateVersionId(entry.versionId, ordinal);
83
+ }
84
+ catch (err) {
85
+ throw new ResourceLogIntegrityError(`Resource log entry ${ordinal} has a malformed or misplaced versionId.`, { cause: err });
86
+ }
87
+ if (typeof entry.versionTime !== 'string' ||
88
+ !entry.versionTime.endsWith('Z') ||
89
+ Number.isNaN(Date.parse(entry.versionTime))) {
90
+ throw new ResourceLogIntegrityError(`Resource log entry ${ordinal} has a malformed versionTime (RFC3339 ` +
91
+ `UTC required; the value itself is advisory).`);
92
+ }
93
+ const parameters = entry.parameters;
94
+ if (parameters === null || typeof parameters !== 'object') {
95
+ throw new ResourceLogIntegrityError(`Resource log entry ${ordinal} has a non-object parameters member.`);
96
+ }
97
+ const parameterMembers = Object.keys(parameters);
98
+ if (index === 0) {
99
+ const genesis = parameters;
100
+ const allowed = parameterMembers.every(member => ['method', 'scid', 'previousLog'].includes(member));
101
+ if (!allowed ||
102
+ typeof genesis.method !== 'string' ||
103
+ typeof genesis.scid !== 'string' ||
104
+ (genesis.previousLog !== undefined &&
105
+ (genesis.previousLog === null ||
106
+ typeof genesis.previousLog !== 'object' ||
107
+ typeof genesis.previousLog.scid !== 'string' ||
108
+ typeof genesis.previousLog.head !== 'string' ||
109
+ Object.keys(genesis.previousLog).length !== 2))) {
110
+ throw new ResourceLogIntegrityError('The resource log genesis parameters must carry method and scid ' +
111
+ '(plus, on a handover successor only, previousLog) and nothing else.');
112
+ }
113
+ }
114
+ else if (parameterMembers.length !== 0) {
115
+ // The only non-genesis entry with parameters is a terminal handover
116
+ // entry, exactly { nextLog: { method, scid } }. Anything else -- the
117
+ // deleted did:webvh key-management parameters in particular -- is refused
118
+ // fail-closed.
119
+ const terminal = parameters;
120
+ if (parameterMembers.length !== 1 ||
121
+ terminal.nextLog === undefined ||
122
+ terminal.nextLog === null ||
123
+ typeof terminal.nextLog !== 'object' ||
124
+ typeof terminal.nextLog.method !== 'string' ||
125
+ typeof terminal.nextLog.scid !== 'string' ||
126
+ Object.keys(terminal.nextLog).length !== 2) {
127
+ throw new ResourceLogIntegrityError(`Resource log entry ${ordinal} carries parameters this profile does ` +
128
+ `not define for its position (only a terminal entry's nextLog is ` +
129
+ `permitted past genesis).`);
130
+ }
131
+ }
132
+ const state = entry.state;
133
+ if (state === null ||
134
+ typeof state !== 'object' ||
135
+ typeof state.type !== 'string') {
136
+ throw new ResourceLogIntegrityError(`Resource log entry ${ordinal} has no state.type schema identifier.`);
137
+ }
138
+ if ('history' in state) {
139
+ throw new ResourceLogIntegrityError(`Resource log entry ${ordinal} carries a history member inside its ` +
140
+ `state (the profile reserves that member name).`);
141
+ }
142
+ if (!Array.isArray(entry.proof) || entry.proof.length === 0) {
143
+ throw new ResourceLogIntegrityError(`Resource log entry ${ordinal} carries no proof array.`);
144
+ }
145
+ for (const proof of entry.proof) {
146
+ checkProofShape(proof, ordinal);
147
+ }
148
+ }
149
+ /**
150
+ * Deep-clones a JSON value, replacing every string equal to the SCID with the
151
+ * `{SCID}` placeholder -- the inverse of genesis construction, used to
152
+ * recompute the SCID from a served genesis entry.
153
+ *
154
+ * @param value {unknown}
155
+ * @param scid {string}
156
+ * @returns {unknown}
157
+ */
158
+ function substituteScid(value, scid) {
159
+ if (typeof value === 'string') {
160
+ return value === scid ? SCID_PLACEHOLDER : value;
161
+ }
162
+ if (Array.isArray(value)) {
163
+ return value.map(item => substituteScid(item, scid));
164
+ }
165
+ if (value !== null && typeof value === 'object') {
166
+ const result = {};
167
+ for (const [key, member] of Object.entries(value)) {
168
+ result[key] = substituteScid(member, scid);
169
+ }
170
+ return result;
171
+ }
172
+ return value;
173
+ }
174
+ /**
175
+ * The hash input of entry `n`: the entry with `proof` removed and `versionId`
176
+ * replaced by the predecessor's `versionId` (the SCID for the genesis entry).
177
+ *
178
+ * @param entry {ResourceLogEntry}
179
+ * @param predecessorVersionId {string}
180
+ * @returns {object}
181
+ */
182
+ function hashInputOf(entry, predecessorVersionId) {
183
+ return {
184
+ versionId: predecessorVersionId,
185
+ versionTime: entry.versionTime,
186
+ parameters: entry.parameters,
187
+ state: entry.state
188
+ };
189
+ }
190
+ /**
191
+ * Splits a proof's `verificationMethod` DID URL into its base DID, its
192
+ * `versionId` DID parameter (the entry anchor), and its fragment (the signing
193
+ * key's multibase).
194
+ *
195
+ * @param verificationMethod {string}
196
+ * @param ordinal {number} the owning entry's 1-based position
197
+ * @returns {object}
198
+ */
199
+ function parseAnchoredVm(verificationMethod, ordinal) {
200
+ const hashIndex = verificationMethod.lastIndexOf('#');
201
+ if (hashIndex === -1 || hashIndex === verificationMethod.length - 1) {
202
+ throw new ResourceLogIntegrityError(`Resource log entry ${ordinal} has a proof verificationMethod without ` +
203
+ `a key fragment.`);
204
+ }
205
+ const keyMultibase = verificationMethod.slice(hashIndex + 1);
206
+ const didUrl = verificationMethod.slice(0, hashIndex);
207
+ const queryIndex = didUrl.indexOf('?');
208
+ if (queryIndex === -1) {
209
+ return { did: didUrl, keyMultibase };
210
+ }
211
+ const did = didUrl.slice(0, queryIndex);
212
+ const params = new URLSearchParams(didUrl.slice(queryIndex + 1));
213
+ const anchor = params.get('versionId') ?? undefined;
214
+ return { did, anchor, keyMultibase };
215
+ }
216
+ /**
217
+ * Runs the profile's full verification over a parsed log, in order: parse
218
+ * shape, genesis (SCID recomputation, format identifier), chain-hash
219
+ * recomputation, per-entry proofs, the external-authorization rule with
220
+ * anchor monotonicity, termination, and continuity against the chain-head
221
+ * pin. Throws {@link ResourceLogIntegrityError} on fabrication-class
222
+ * failures, {@link ResourceLogContinuityError} on pin conflicts; any failure
223
+ * rejects the whole log.
224
+ *
225
+ * The controller view is the independently verified controller document --
226
+ * never material served beside the log. An unversioned controller (empty
227
+ * `versionIds`) degrades every anchor rule to current-document verification
228
+ * and requires anchorless proofs.
229
+ *
230
+ * @param options {object}
231
+ * @param options.entries {ResourceLogEntry[]} the parsed served log
232
+ * @param options.controller {ResourceLogController} the verified controller
233
+ * view ({@link webvhResourceLogController})
234
+ * @param options.expectedMethod {string} the format identifier this caller
235
+ * expects (`WAS_RESOURCE_LOG_METHOD`; also confirmed against any `history`
236
+ * dispatch hint the caller followed)
237
+ * @param [options.pin] {ResourceLogHeadPin} the held chain-head pin, when
238
+ * this client has verified the log before
239
+ * @returns {Promise<VerifiedResourceLog>}
240
+ */
241
+ export async function verifyResourceLog({ entries, controller, expectedMethod, pin }) {
242
+ if (entries.length === 0) {
243
+ throw new ResourceLogIntegrityError('The resource log is empty (a log carries at least its genesis entry).');
244
+ }
245
+ // 1. Parse: per-entry shape, parameters rules, ordinal positions.
246
+ entries.forEach((entry, index) => {
247
+ checkEntryShape(entry, index);
248
+ });
249
+ // 2. Genesis: format identifier, then SCID recomputation.
250
+ const genesisParameters = entries[0].parameters;
251
+ const { method, scid } = genesisParameters;
252
+ if (method !== expectedMethod) {
253
+ throw new ResourceLogIntegrityError(`The resource log declares format "${method}", not the expected ` +
254
+ `"${expectedMethod}".`);
255
+ }
256
+ const preliminary = substituteScid(hashInputOf(entries[0], SCID_PLACEHOLDER), scid);
257
+ if ((await deriveHash(preliminary)) !== scid) {
258
+ throw new ResourceLogIntegrityError('The resource log SCID does not verify against its genesis content.');
259
+ }
260
+ // 3. Chain: recompute every entry hash from the predecessor-substituted
261
+ // input; never accept a stated head.
262
+ let predecessorVersionId = scid;
263
+ for (const [index, entry] of entries.entries()) {
264
+ const entryHash = await deriveHash(hashInputOf(entry, predecessorVersionId));
265
+ if (entry.versionId !== buildVersionId(index + 1, entryHash)) {
266
+ throw new ResourceLogIntegrityError(`Resource log entry ${index + 1} does not hash-chain to its ` +
267
+ `predecessor.`);
268
+ }
269
+ predecessorVersionId = entry.versionId;
270
+ }
271
+ // 4 + 5. Proofs and authorization, entry by entry, with anchor
272
+ // monotonicity carried along the log.
273
+ const versioned = controller.versionIds.length > 0;
274
+ let anchorFloor = 0;
275
+ for (const [index, entry] of entries.entries()) {
276
+ const ordinal = index + 1;
277
+ let entryAnchorIndex = anchorFloor;
278
+ const authorize = async (proof) => {
279
+ const { did, anchor, keyMultibase } = parseAnchoredVm(proof.verificationMethod ?? '', ordinal);
280
+ if (did !== controller.did) {
281
+ throw new ResourceLogIntegrityError(`Resource log entry ${ordinal} is signed under a different ` +
282
+ `controller than this log's account.`);
283
+ }
284
+ if (versioned && anchor === undefined) {
285
+ throw new ResourceLogIntegrityError(`Resource log entry ${ordinal} carries no entry anchor against a ` +
286
+ `version-resolvable controller.`);
287
+ }
288
+ if (!versioned && anchor !== undefined) {
289
+ throw new ResourceLogIntegrityError(`Resource log entry ${ordinal} anchors a version on an unversioned ` +
290
+ `controller.`);
291
+ }
292
+ let anchorIndex = 0;
293
+ if (anchor !== undefined) {
294
+ anchorIndex = controller.versionIds.indexOf(anchor);
295
+ if (anchorIndex === -1) {
296
+ throw new ResourceLogIntegrityError(`Resource log entry ${ordinal} anchors an unknown controller ` +
297
+ `document version.`);
298
+ }
299
+ if (anchorIndex < anchorFloor) {
300
+ throw new ResourceLogIntegrityError(`Resource log entry ${ordinal} anchors behind its predecessor ` +
301
+ `(anchors must be monotone along the log).`);
302
+ }
303
+ }
304
+ const assertionKeys = await controller.assertionKeysAt(anchor);
305
+ if (!assertionKeys.has(keyMultibase)) {
306
+ throw new ResourceLogIntegrityError(`Resource log entry ${ordinal} is signed by a key the controller ` +
307
+ `document does not list under assertionMethod at the anchored ` +
308
+ `version.`);
309
+ }
310
+ entryAnchorIndex = Math.max(entryAnchorIndex, anchorIndex);
311
+ };
312
+ try {
313
+ // The wire proof type narrows the kernel's (fixed purpose, optional
314
+ // created); the shape check above already enforced the profile form.
315
+ await verifyEntryProofs(entry, {
316
+ verifier: defaultWebvhLogVerifier,
317
+ authorize,
318
+ resolveVM: async (verificationMethod) => ({
319
+ publicKeyMultibase: parseAnchoredVm(verificationMethod, ordinal)
320
+ .keyMultibase
321
+ })
322
+ });
323
+ }
324
+ catch (err) {
325
+ if (err instanceof ResourceLogIntegrityError) {
326
+ throw err;
327
+ }
328
+ throw new ResourceLogIntegrityError(`Resource log entry ${ordinal} failed proof verification.`, { cause: err });
329
+ }
330
+ anchorFloor = entryAnchorIndex;
331
+ }
332
+ // 6. Termination: a terminal entry closes the log -- it must be last, must
333
+ // not be the genesis, and must change no state.
334
+ let terminal = null;
335
+ for (const [index, entry] of entries.entries()) {
336
+ if (!isTerminalResourceLogEntry(entry) || index === 0) {
337
+ continue;
338
+ }
339
+ if (index !== entries.length - 1) {
340
+ throw new ResourceLogIntegrityError('The resource log continues past a terminal handover entry.');
341
+ }
342
+ const predecessorState = entries[index - 1].state;
343
+ if (canonicalizeStrict(entry.state) !== canonicalizeStrict(predecessorState)) {
344
+ throw new ResourceLogIntegrityError("The terminal handover entry's state differs from its " +
345
+ "predecessor's (a handover changes no resource state).");
346
+ }
347
+ terminal = entry.parameters.nextLog;
348
+ }
349
+ // 7. Continuity against the chain-head pin, where one is held.
350
+ const head = entries[entries.length - 1];
351
+ if (pin) {
352
+ if (pin.method !== method) {
353
+ throw new ResourceLogContinuityError({
354
+ reason: 'method-switch',
355
+ pinnedHead: pin.head
356
+ });
357
+ }
358
+ if (pin.scid !== scid) {
359
+ throw new ResourceLogContinuityError({
360
+ reason: 'scid-switch',
361
+ pinnedHead: pin.head
362
+ });
363
+ }
364
+ const pinnedOrdinal = Number.parseInt(pin.head, 10);
365
+ if (!Number.isInteger(pinnedOrdinal) || pinnedOrdinal < 1) {
366
+ throw new ResourceLogContinuityError({
367
+ reason: 'fork',
368
+ pinnedHead: pin.head,
369
+ servedEntries: entries
370
+ });
371
+ }
372
+ if (entries.length < pinnedOrdinal) {
373
+ throw new ResourceLogContinuityError({
374
+ reason: 'rollback',
375
+ pinnedHead: pin.head
376
+ });
377
+ }
378
+ if (entries[pinnedOrdinal - 1].versionId !== pin.head) {
379
+ throw new ResourceLogContinuityError({
380
+ reason: 'fork',
381
+ pinnedHead: pin.head,
382
+ servedEntries: entries
383
+ });
384
+ }
385
+ }
386
+ return {
387
+ entries,
388
+ method,
389
+ scid,
390
+ head,
391
+ state: head.state,
392
+ pin: { method, scid, head: head.versionId },
393
+ headAnchorIndex: versioned ? anchorFloor : null,
394
+ terminal,
395
+ previousLog: genesisParameters.previousLog ?? null
396
+ };
397
+ }
398
+ /**
399
+ * Verifies a handover link from both sides: the prior log's terminal entry
400
+ * and the successor log's genesis back-reference. Both logs must already have
401
+ * passed {@link verifyResourceLog}. Checks: the terminal `nextLog` names the
402
+ * successor's SCID and method; the successor's `previousLog` names the prior
403
+ * log's SCID; and the successor's `previousLog.head` is the `versionId` of
404
+ * the terminal entry's immediate predecessor -- the terminal entry chains
405
+ * directly off the head the successor references. A verified handover is the
406
+ * one transition that replaces a chain-head pin wholesale (the caller stores
407
+ * `successor.pin`).
408
+ *
409
+ * @param options {object}
410
+ * @param options.prior {VerifiedResourceLog} the closed log
411
+ * @param options.successor {VerifiedResourceLog} the log its terminal entry
412
+ * names
413
+ * @returns {void}
414
+ */
415
+ export function verifyResourceLogHandover({ prior, successor }) {
416
+ if (!prior.terminal) {
417
+ throw new ResourceLogContinuityError({
418
+ reason: 'scid-switch',
419
+ pinnedHead: prior.pin.head
420
+ });
421
+ }
422
+ const predecessor = prior.entries[prior.entries.length - 2];
423
+ if (prior.terminal.scid !== successor.scid ||
424
+ prior.terminal.method !== successor.method ||
425
+ successor.previousLog?.scid !== prior.scid ||
426
+ predecessor === undefined ||
427
+ successor.previousLog.head !== predecessor.versionId) {
428
+ throw new ResourceLogContinuityError({
429
+ reason: 'scid-switch',
430
+ pinnedHead: prior.pin.head,
431
+ servedEntries: successor.entries
432
+ });
433
+ }
434
+ }
435
+ //# sourceMappingURL=verify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/resourceLog/verify.ts"],"names":[],"mappings":"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"}