@interop/wallet-core 0.23.0 → 0.24.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 (94) hide show
  1. package/README.md +33 -18
  2. package/dist/clients/revocation.d.ts +3 -6
  3. package/dist/clients/revocation.d.ts.map +1 -1
  4. package/dist/clients/revocation.js +5 -9
  5. package/dist/clients/revocation.js.map +1 -1
  6. package/dist/clients/rosterPolicy.d.ts +11 -17
  7. package/dist/clients/rosterPolicy.d.ts.map +1 -1
  8. package/dist/clients/rosterPolicy.js +22 -27
  9. package/dist/clients/rosterPolicy.js.map +1 -1
  10. package/dist/enrollment/enrollment.d.ts +2 -2
  11. package/dist/enrollment/enrollment.d.ts.map +1 -1
  12. package/dist/enrollment/enrollment.js +15 -10
  13. package/dist/enrollment/enrollment.js.map +1 -1
  14. package/dist/index.d.ts +1 -1
  15. package/dist/index.js +1 -1
  16. package/dist/keys/index.d.ts +11 -8
  17. package/dist/keys/index.d.ts.map +1 -1
  18. package/dist/keys/index.js +11 -8
  19. package/dist/keys/index.js.map +1 -1
  20. package/dist/keys/rosterLogStore.d.ts +34 -0
  21. package/dist/keys/rosterLogStore.d.ts.map +1 -0
  22. package/dist/keys/rosterLogStore.js +110 -0
  23. package/dist/keys/rosterLogStore.js.map +1 -0
  24. package/dist/keys/rosterStore.d.ts +18 -4
  25. package/dist/keys/rosterStore.d.ts.map +1 -1
  26. package/dist/keys/rosterStore.js +35 -16
  27. package/dist/keys/rosterStore.js.map +1 -1
  28. package/dist/keys/userKeyCascade.d.ts +1 -1
  29. package/dist/keys/userKeyCascade.js +1 -1
  30. package/dist/keys/userKeyRoster.d.ts +50 -97
  31. package/dist/keys/userKeyRoster.d.ts.map +1 -1
  32. package/dist/keys/userKeyRoster.js +44 -145
  33. package/dist/keys/userKeyRoster.js.map +1 -1
  34. package/dist/request/appKey.d.ts +254 -0
  35. package/dist/request/appKey.d.ts.map +1 -0
  36. package/dist/request/appKey.js +498 -0
  37. package/dist/request/appKey.js.map +1 -0
  38. package/dist/request/classify.d.ts +54 -3
  39. package/dist/request/classify.d.ts.map +1 -1
  40. package/dist/request/classify.js +106 -0
  41. package/dist/request/classify.js.map +1 -1
  42. package/dist/request/index.d.ts +4 -0
  43. package/dist/request/index.d.ts.map +1 -1
  44. package/dist/request/index.js +4 -0
  45. package/dist/request/index.js.map +1 -1
  46. package/dist/request/processRequest.d.ts.map +1 -1
  47. package/dist/request/processRequest.js +15 -6
  48. package/dist/request/processRequest.js.map +1 -1
  49. package/dist/request/types.d.ts +45 -2
  50. package/dist/request/types.d.ts.map +1 -1
  51. package/dist/resourceLog/append.d.ts +103 -0
  52. package/dist/resourceLog/append.d.ts.map +1 -0
  53. package/dist/resourceLog/append.js +190 -0
  54. package/dist/resourceLog/append.js.map +1 -0
  55. package/dist/resourceLog/controller.d.ts +57 -0
  56. package/dist/resourceLog/controller.d.ts.map +1 -0
  57. package/dist/resourceLog/controller.js +81 -0
  58. package/dist/resourceLog/controller.js.map +1 -0
  59. package/dist/resourceLog/entry.d.ts +68 -0
  60. package/dist/resourceLog/entry.d.ts.map +1 -0
  61. package/dist/resourceLog/entry.js +167 -0
  62. package/dist/resourceLog/entry.js.map +1 -0
  63. package/dist/resourceLog/errors.d.ts +75 -0
  64. package/dist/resourceLog/errors.d.ts.map +1 -0
  65. package/dist/resourceLog/errors.js +76 -0
  66. package/dist/resourceLog/errors.js.map +1 -0
  67. package/dist/resourceLog/index.d.ts +23 -0
  68. package/dist/resourceLog/index.d.ts.map +1 -0
  69. package/dist/resourceLog/index.js +23 -0
  70. package/dist/resourceLog/index.js.map +1 -0
  71. package/dist/resourceLog/pin.d.ts +44 -0
  72. package/dist/resourceLog/pin.d.ts.map +1 -0
  73. package/dist/resourceLog/pin.js +32 -0
  74. package/dist/resourceLog/pin.js.map +1 -0
  75. package/dist/resourceLog/verify.d.ts +89 -0
  76. package/dist/resourceLog/verify.d.ts.map +1 -0
  77. package/dist/resourceLog/verify.js +434 -0
  78. package/dist/resourceLog/verify.js.map +1 -0
  79. package/dist/space/collections.d.ts +14 -11
  80. package/dist/space/collections.d.ts.map +1 -1
  81. package/dist/space/collections.js +14 -11
  82. package/dist/space/collections.js.map +1 -1
  83. package/dist/space/index.d.ts +2 -2
  84. package/dist/space/index.d.ts.map +1 -1
  85. package/dist/space/index.js +2 -2
  86. package/dist/space/index.js.map +1 -1
  87. package/dist/webvh/didWeb.d.ts +4 -6
  88. package/dist/webvh/didWeb.d.ts.map +1 -1
  89. package/dist/webvh/didWeb.js.map +1 -1
  90. package/dist/webvh/didWebvh.d.ts +1 -2
  91. package/dist/webvh/didWebvh.d.ts.map +1 -1
  92. package/dist/webvh/didWebvh.js +1 -6
  93. package/dist/webvh/didWebvh.js.map +1 -1
  94. package/package.json +10 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pin.d.ts","sourceRoot":"","sources":["../../src/resourceLog/pin.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;GAUG;AAEH;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,IAAI,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAA;IAC1C,KAAK,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC9C;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,IAAI,mBAAmB,CAU/D"}
@@ -0,0 +1,32 @@
1
+ /*!
2
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
3
+ */
4
+ /**
5
+ * The chain-head pin: the client-local durable record of a resource log's
6
+ * verified identity and latest verified head, kept per log beside the app's
7
+ * other continuity pins (the account pointer, the roster epoch pin). The pin
8
+ * is what turns one-shot verification into continuity: a served log whose
9
+ * SCID or method differs from the pin outside a verified handover, or whose
10
+ * history is not a descendant of the pinned head, is refused instead of
11
+ * adopted. Storage is the app's concern (freewallet: beside its other pins in
12
+ * localStorage; DCW: a table row), so only the seam lives here, plus an
13
+ * in-memory implementation for tests and single-session use.
14
+ */
15
+ /**
16
+ * An in-memory pin store: continuity within one session only. Tests use it
17
+ * as the seam's reference implementation; apps persist for real.
18
+ *
19
+ * @returns {ResourceLogPinStore}
20
+ */
21
+ export function memoryResourceLogPinStore() {
22
+ let pin = null;
23
+ return {
24
+ async read() {
25
+ return pin;
26
+ },
27
+ async write(next) {
28
+ pin = next;
29
+ }
30
+ };
31
+ }
32
+ //# sourceMappingURL=pin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pin.js","sourceRoot":"","sources":["../../src/resourceLog/pin.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH;;;;;;;;;;GAUG;AA0BH;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB;IACvC,IAAI,GAAG,GAA8B,IAAI,CAAA;IACzC,OAAO;QACL,KAAK,CAAC,IAAI;YACR,OAAO,GAAG,CAAA;QACZ,CAAC;QACD,KAAK,CAAC,KAAK,CAAC,IAAwB;YAClC,GAAG,GAAG,IAAI,CAAA;QACZ,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,89 @@
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.
11
+ */
12
+ export interface VerifiedResourceLog {
13
+ entries: ResourceLogEntry[];
14
+ method: string;
15
+ scid: string;
16
+ head: ResourceLogEntry;
17
+ state: ResourceLogEntry['state'];
18
+ pin: ResourceLogHeadPin;
19
+ terminal: {
20
+ method: string;
21
+ scid: string;
22
+ } | null;
23
+ previousLog: {
24
+ scid: string;
25
+ head: string;
26
+ } | null;
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 declare function isTerminalResourceLogEntry(entry: ResourceLogEntry): boolean;
37
+ /**
38
+ * Runs the profile's full verification over a parsed log, in order: parse
39
+ * shape, genesis (SCID recomputation, format identifier), chain-hash
40
+ * recomputation, per-entry proofs, the external-authorization rule with
41
+ * anchor monotonicity, termination, and continuity against the chain-head
42
+ * pin. Throws {@link ResourceLogIntegrityError} on fabrication-class
43
+ * failures, {@link ResourceLogContinuityError} on pin conflicts; any failure
44
+ * rejects the whole log.
45
+ *
46
+ * The controller view is the independently verified controller document --
47
+ * never material served beside the log. An unversioned controller (empty
48
+ * `versionIds`) degrades every anchor rule to current-document verification
49
+ * and requires anchorless proofs.
50
+ *
51
+ * @param options {object}
52
+ * @param options.entries {ResourceLogEntry[]} the parsed served log
53
+ * @param options.controller {ResourceLogController} the verified controller
54
+ * view ({@link webvhResourceLogController})
55
+ * @param options.expectedMethod {string} the format identifier this caller
56
+ * expects (`WAS_RESOURCE_LOG_METHOD`; also confirmed against any `history`
57
+ * dispatch hint the caller followed)
58
+ * @param [options.pin] {ResourceLogHeadPin} the held chain-head pin, when
59
+ * this client has verified the log before
60
+ * @returns {Promise<VerifiedResourceLog>}
61
+ */
62
+ export declare function verifyResourceLog({ entries, controller, expectedMethod, pin }: {
63
+ entries: ResourceLogEntry[];
64
+ controller: ResourceLogController;
65
+ expectedMethod: string;
66
+ pin?: ResourceLogHeadPin | null;
67
+ }): Promise<VerifiedResourceLog>;
68
+ /**
69
+ * Verifies a handover link from both sides: the prior log's terminal entry
70
+ * and the successor log's genesis back-reference. Both logs must already have
71
+ * passed {@link verifyResourceLog}. Checks: the terminal `nextLog` names the
72
+ * successor's SCID and method; the successor's `previousLog` names the prior
73
+ * log's SCID; and the successor's `previousLog.head` is the `versionId` of
74
+ * the terminal entry's immediate predecessor -- the terminal entry chains
75
+ * directly off the head the successor references. A verified handover is the
76
+ * one transition that replaces a chain-head pin wholesale (the caller stores
77
+ * `successor.pin`).
78
+ *
79
+ * @param options {object}
80
+ * @param options.prior {VerifiedResourceLog} the closed log
81
+ * @param options.successor {VerifiedResourceLog} the log its terminal entry
82
+ * names
83
+ * @returns {void}
84
+ */
85
+ export declare function verifyResourceLogHandover({ prior, successor }: {
86
+ prior: VerifiedResourceLog;
87
+ successor: VerifiedResourceLog;
88
+ }): void;
89
+ //# 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;;;;;;;GAOG;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,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,CA+M/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,434 @@
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
+ terminal,
394
+ previousLog: genesisParameters.previousLog ?? null
395
+ };
396
+ }
397
+ /**
398
+ * Verifies a handover link from both sides: the prior log's terminal entry
399
+ * and the successor log's genesis back-reference. Both logs must already have
400
+ * passed {@link verifyResourceLog}. Checks: the terminal `nextLog` names the
401
+ * successor's SCID and method; the successor's `previousLog` names the prior
402
+ * log's SCID; and the successor's `previousLog.head` is the `versionId` of
403
+ * the terminal entry's immediate predecessor -- the terminal entry chains
404
+ * directly off the head the successor references. A verified handover is the
405
+ * one transition that replaces a chain-head pin wholesale (the caller stores
406
+ * `successor.pin`).
407
+ *
408
+ * @param options {object}
409
+ * @param options.prior {VerifiedResourceLog} the closed log
410
+ * @param options.successor {VerifiedResourceLog} the log its terminal entry
411
+ * names
412
+ * @returns {void}
413
+ */
414
+ export function verifyResourceLogHandover({ prior, successor }) {
415
+ if (!prior.terminal) {
416
+ throw new ResourceLogContinuityError({
417
+ reason: 'scid-switch',
418
+ pinnedHead: prior.pin.head
419
+ });
420
+ }
421
+ const predecessor = prior.entries[prior.entries.length - 2];
422
+ if (prior.terminal.scid !== successor.scid ||
423
+ prior.terminal.method !== successor.method ||
424
+ successor.previousLog?.scid !== prior.scid ||
425
+ predecessor === undefined ||
426
+ successor.previousLog.head !== predecessor.versionId) {
427
+ throw new ResourceLogContinuityError({
428
+ reason: 'scid-switch',
429
+ pinnedHead: prior.pin.head,
430
+ servedEntries: successor.entries
431
+ });
432
+ }
433
+ }
434
+ //# 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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"}
@@ -91,8 +91,9 @@ export declare const CONTACTS_HISTORY_SPACE_COLLECTION_SPEC: SpaceCollectionSpec
91
91
  * document, so the did:web id is `did:web:<host>:space:<spaceId>:id` and
92
92
  * resolves to `https://<host>/space/<spaceId>/id/did.json`.
93
93
  * - `key-map` -- private and capability-gated: the key-id map (`keys.json`)
94
- * and the user key wrap-set roster (`user-key.json`). Kept separate from `id` exactly
95
- * so `id` can be made world-readable without ever exposing key material.
94
+ * and the user key wrap-set roster log (`user-key.jsonl`). Kept separate from
95
+ * `id` exactly so `id` can be made world-readable without ever exposing key
96
+ * material.
96
97
  * - `keyring` -- the unlock Space's single collection, holding the one
97
98
  * keyring record (`keyring.json`). It lives in the minimal unlock Space
98
99
  * controlled by an unlock identity, never in the wallet data Space.
@@ -129,7 +130,7 @@ export declare const WALLET_SPACE_SYNCED_SPECS: SpaceCollectionSpec[];
129
130
  /**
130
131
  * The provisioned-but-not-synced system collections: part of every wallet
131
132
  * Space's layout, but no wallet mints a replication feed for them -- their
132
- * resources (`did.json`, `keys.json`, `user-key.json`, ...) are read and
133
+ * resources (`did.json`, `keys.json`, `user-key.jsonl`, ...) are read and
133
134
  * written directly. `keyring` is deliberately absent: it lives in the separate
134
135
  * unlock Space, never in the wallet data Space this roster lays out.
135
136
  */
@@ -159,17 +160,19 @@ export declare const DID_LOG_RESOURCE = "did.jsonl";
159
160
  */
160
161
  export declare const DID_KEYS_RESOURCE = "keys.json";
161
162
  /**
162
- * The per-user-key (user key) wrap-set roster, sibling of `keys.json` in the
163
- * same private `key-map` collection: a `CollectionEncryption` descriptor stored
164
- * verbatim as the resource body, whose current epoch IS the current user key
165
- * (the epoch id is the user key's did:key; the wrapped secret is the user key's
166
- * raw key, wrapped to each enrolled client's key-agreement key). Read directly
167
- * with a compare-and-swap etag -- never replicated.
163
+ * The resource log governing the user key wrap-set roster, sibling of
164
+ * `keys.json` in the same private `key-map` collection: the hash-linked
165
+ * history of the roster descriptor (the Resource Log Profile), JSON Lines,
166
+ * one signed entry per line. The verified head entry's state is the roster --
167
+ * a `CollectionEncryption` descriptor whose current epoch IS the current user
168
+ * key (the epoch id is the user key's did:key; the wrapped secret is the user
169
+ * key's raw key, wrapped to each enrolled client's key-agreement key). Read
170
+ * directly with a compare-and-swap etag -- never replicated.
168
171
  */
169
- export declare const USER_KEY_ROSTER_RESOURCE = "user-key.json";
172
+ export declare const USER_KEY_ROSTER_LOG_RESOURCE = "user-key.jsonl";
170
173
  /**
171
174
  * The enrolled-client display labels, sibling of `keys.json` and
172
- * `user-key.json` in the same private `key-map` collection: a plain-JSON map
175
+ * `user-key.jsonl` in the same private `key-map` collection: a plain-JSON map
173
176
  * from a client's signing-key multibase to its human-chosen label. Display
174
177
  * metadata only -- the did:webvh document carries key material, never labels --
175
178
  * and plaintext by the collection's convention: the storage host can read the
@@ -1 +1 @@
1
- {"version":3,"file":"collections.d.ts","sourceRoot":"","sources":["../../src/space/collections.ts"],"names":[],"mappings":"AAyBA;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,iBAAiB,CAAA;AAE/C;;GAEG;AACH,eAAO,MAAM,8BAA8B,wBAAwB,CAAA;AACnE;;GAEG;AACH,eAAO,MAAM,6BAA6B,uBAAuB,CAAA;AACjE;;GAEG;AACH,eAAO,MAAM,0BAA0B,oBAAoB,CAAA;AAE3D;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,KAAK,GAAG,WAAW,CAAA;IAC/B,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,mBAAoB,SAAQ,kBAAkB;IAC7D,YAAY,EAAE,SAAS,GAAG,QAAQ,CAAA;IAClC,OAAO,EAAE,OAAO,CAAA;CACjB;AAED;;;GAGG;AACH,eAAO,MAAM,mCAAmC,EAAE,mBAOjD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,kCAAkC,EAAE,mBAOhD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,+BAA+B,EAAE,mBAO7C,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,8BAA8B,EAAE,mBAK5C,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,sCAAsC,EAAE,mBAKpD,CAAA;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,aAAa;;;CAAiC,CAAA;AAC3D,eAAO,MAAM,kBAAkB;;;CAAqC,CAAA;AACpE,eAAO,MAAM,kBAAkB;;;CAAqC,CAAA;AAEpE;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,kBAKhC,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,kBAKrC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,mBAAmB,EAM1D,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,EAAE,kBAAkB,EAGzD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,EAAE,kBAAkB,EAG7D,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,qBAAqB,aAAa,CAAA;AAC/C;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,cAAc,CAAA;AAC3C;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,cAAc,CAAA;AAC5C;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB,kBAAkB,CAAA;AACvD;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,uBAAuB,CAAA;AAC1D;;GAEG;AACH,eAAO,MAAM,gBAAgB,iBAAiB,CAAA"}
1
+ {"version":3,"file":"collections.d.ts","sourceRoot":"","sources":["../../src/space/collections.ts"],"names":[],"mappings":"AAyBA;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,iBAAiB,CAAA;AAE/C;;GAEG;AACH,eAAO,MAAM,8BAA8B,wBAAwB,CAAA;AACnE;;GAEG;AACH,eAAO,MAAM,6BAA6B,uBAAuB,CAAA;AACjE;;GAEG;AACH,eAAO,MAAM,0BAA0B,oBAAoB,CAAA;AAE3D;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,KAAK,GAAG,WAAW,CAAA;IAC/B,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,mBAAoB,SAAQ,kBAAkB;IAC7D,YAAY,EAAE,SAAS,GAAG,QAAQ,CAAA;IAClC,OAAO,EAAE,OAAO,CAAA;CACjB;AAED;;;GAGG;AACH,eAAO,MAAM,mCAAmC,EAAE,mBAOjD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,kCAAkC,EAAE,mBAOhD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,+BAA+B,EAAE,mBAO7C,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,8BAA8B,EAAE,mBAK5C,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,sCAAsC,EAAE,mBAKpD,CAAA;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,aAAa;;;CAAiC,CAAA;AAC3D,eAAO,MAAM,kBAAkB;;;CAAqC,CAAA;AACpE,eAAO,MAAM,kBAAkB;;;CAAqC,CAAA;AAEpE;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,kBAKhC,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,kBAKrC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,mBAAmB,EAM1D,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,EAAE,kBAAkB,EAGzD,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,EAAE,kBAAkB,EAG7D,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,qBAAqB,aAAa,CAAA;AAC/C;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,cAAc,CAAA;AAC3C;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,cAAc,CAAA;AAC5C;;;;;;;;;GASG;AACH,eAAO,MAAM,4BAA4B,mBAAmB,CAAA;AAC5D;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,uBAAuB,CAAA;AAC1D;;GAEG;AACH,eAAO,MAAM,gBAAgB,iBAAiB,CAAA"}