@originals/sdk 1.4.5 → 1.6.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 (105) hide show
  1. package/dist/adapters/FeeOracleMock.js +2 -2
  2. package/dist/bitcoin/OrdinalsClient.d.ts +1 -1
  3. package/dist/bitcoin/OrdinalsClient.js +10 -8
  4. package/dist/bitcoin/PSBTBuilder.js +1 -1
  5. package/dist/bitcoin/utxo-selection.js +2 -2
  6. package/dist/cel/ExternalReferenceManager.d.ts +57 -0
  7. package/dist/cel/ExternalReferenceManager.js +73 -0
  8. package/dist/cel/OriginalsCel.d.ts +245 -0
  9. package/dist/cel/OriginalsCel.js +349 -0
  10. package/dist/cel/algorithms/createEventLog.d.ts +32 -0
  11. package/dist/cel/algorithms/createEventLog.js +56 -0
  12. package/dist/cel/algorithms/deactivateEventLog.d.ts +35 -0
  13. package/dist/cel/algorithms/deactivateEventLog.js +91 -0
  14. package/dist/cel/algorithms/index.d.ts +10 -0
  15. package/dist/cel/algorithms/index.js +10 -0
  16. package/dist/cel/algorithms/updateEventLog.d.ts +34 -0
  17. package/dist/cel/algorithms/updateEventLog.js +82 -0
  18. package/dist/cel/algorithms/verifyEventLog.d.ts +45 -0
  19. package/dist/cel/algorithms/verifyEventLog.js +255 -0
  20. package/dist/cel/algorithms/witnessEvent.d.ts +29 -0
  21. package/dist/cel/algorithms/witnessEvent.js +75 -0
  22. package/dist/cel/cli/create.d.ts +36 -0
  23. package/dist/cel/cli/create.js +282 -0
  24. package/dist/cel/cli/index.d.ts +11 -0
  25. package/dist/cel/cli/index.js +351 -0
  26. package/dist/cel/cli/inspect.d.ts +30 -0
  27. package/dist/cel/cli/inspect.js +475 -0
  28. package/dist/cel/cli/migrate.d.ts +41 -0
  29. package/dist/cel/cli/migrate.js +405 -0
  30. package/dist/cel/cli/verify.d.ts +31 -0
  31. package/dist/cel/cli/verify.js +205 -0
  32. package/dist/cel/hash.d.ts +46 -0
  33. package/dist/cel/hash.js +66 -0
  34. package/dist/cel/index.d.ts +15 -0
  35. package/dist/cel/index.js +15 -0
  36. package/dist/cel/layers/BtcoCelManager.d.ts +121 -0
  37. package/dist/cel/layers/BtcoCelManager.js +329 -0
  38. package/dist/cel/layers/PeerCelManager.d.ts +151 -0
  39. package/dist/cel/layers/PeerCelManager.js +299 -0
  40. package/dist/cel/layers/WebVHCelManager.d.ts +122 -0
  41. package/dist/cel/layers/WebVHCelManager.js +291 -0
  42. package/dist/cel/layers/index.d.ts +13 -0
  43. package/dist/cel/layers/index.js +16 -0
  44. package/dist/cel/serialization/cbor.d.ts +42 -0
  45. package/dist/cel/serialization/cbor.js +163 -0
  46. package/dist/cel/serialization/index.d.ts +9 -0
  47. package/dist/cel/serialization/index.js +9 -0
  48. package/dist/cel/serialization/json.d.ts +41 -0
  49. package/dist/cel/serialization/json.js +180 -0
  50. package/dist/cel/types.d.ts +149 -0
  51. package/dist/cel/types.js +7 -0
  52. package/dist/cel/witnesses/BitcoinWitness.d.ts +83 -0
  53. package/dist/cel/witnesses/BitcoinWitness.js +116 -0
  54. package/dist/cel/witnesses/HttpWitness.d.ts +79 -0
  55. package/dist/cel/witnesses/HttpWitness.js +163 -0
  56. package/dist/cel/witnesses/WitnessService.d.ts +49 -0
  57. package/dist/cel/witnesses/WitnessService.js +10 -0
  58. package/dist/cel/witnesses/index.d.ts +10 -0
  59. package/dist/cel/witnesses/index.js +7 -0
  60. package/dist/core/OriginalsSDK.js +5 -1
  61. package/dist/crypto/Signer.js +14 -6
  62. package/dist/crypto/noble-init.js +20 -1
  63. package/dist/did/BtcoDidResolver.d.ts +2 -2
  64. package/dist/did/BtcoDidResolver.js +12 -8
  65. package/dist/did/DIDManager.js +6 -4
  66. package/dist/did/KeyManager.d.ts +1 -1
  67. package/dist/did/KeyManager.js +7 -4
  68. package/dist/did/WebVHManager.js +1 -1
  69. package/dist/did/createBtcoDidDocument.js +2 -1
  70. package/dist/events/types.d.ts +4 -1
  71. package/dist/examples/create-module-original.js +1 -1
  72. package/dist/examples/full-lifecycle-flow.js +2 -2
  73. package/dist/index.d.ts +13 -0
  74. package/dist/index.js +12 -0
  75. package/dist/kinds/KindRegistry.js +59 -29
  76. package/dist/lifecycle/BatchOperations.d.ts +5 -3
  77. package/dist/lifecycle/BatchOperations.js +11 -5
  78. package/dist/lifecycle/LifecycleManager.d.ts +1 -1
  79. package/dist/lifecycle/LifecycleManager.js +42 -33
  80. package/dist/lifecycle/OriginalsAsset.js +2 -2
  81. package/dist/migration/MigrationManager.js +67 -3
  82. package/dist/storage/LocalStorageAdapter.js +4 -1
  83. package/dist/storage/MemoryStorageAdapter.js +7 -7
  84. package/dist/types/network.js +6 -3
  85. package/dist/utils/Logger.d.ts +6 -6
  86. package/dist/utils/Logger.js +5 -3
  87. package/dist/utils/MetricsCollector.js +1 -1
  88. package/dist/utils/bitcoin-address.js +4 -2
  89. package/dist/utils/cbor.js +16 -3
  90. package/dist/utils/encoding.d.ts +4 -4
  91. package/dist/utils/encoding.js +7 -6
  92. package/dist/utils/hash.js +6 -1
  93. package/dist/utils/serialization.d.ts +2 -2
  94. package/dist/utils/serialization.js +7 -5
  95. package/dist/utils/telemetry.js +6 -2
  96. package/dist/utils/validation.js +8 -4
  97. package/dist/vc/CredentialManager.d.ts +8 -8
  98. package/dist/vc/CredentialManager.js +46 -33
  99. package/dist/vc/Issuer.d.ts +2 -2
  100. package/dist/vc/Issuer.js +5 -1
  101. package/dist/vc/Verifier.d.ts +2 -2
  102. package/dist/vc/Verifier.js +12 -6
  103. package/dist/vc/documentLoader.d.ts +5 -3
  104. package/dist/vc/documentLoader.js +5 -4
  105. package/package.json +4 -1
@@ -0,0 +1,349 @@
1
+ /**
2
+ * OriginalsCel - Unified SDK Entry Point for CEL Operations
3
+ *
4
+ * Provides a single, simplified interface for all Cryptographic Event Log
5
+ * operations across all layers (peer, webvh, btco).
6
+ *
7
+ * This class delegates to the appropriate layer manager based on
8
+ * the configured layer and the current state of the event log.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * // Create a peer-layer asset
13
+ * const cel = new OriginalsCel({
14
+ * layer: 'peer',
15
+ * signer: async (data) => createEdDsaProof(data, privateKey),
16
+ * });
17
+ *
18
+ * const log = await cel.create('My Asset', [
19
+ * { digestMultibase: 'uXYZ...', mediaType: 'image/png' }
20
+ * ]);
21
+ *
22
+ * // Update the asset
23
+ * const updated = await cel.update(log, { description: 'Updated' });
24
+ *
25
+ * // Verify the log
26
+ * const result = await cel.verify(updated);
27
+ *
28
+ * // Migrate to webvh layer
29
+ * const migrated = await cel.migrate(updated, 'webvh');
30
+ * ```
31
+ */
32
+ import { PeerCelManager } from './layers/PeerCelManager';
33
+ import { WebVHCelManager } from './layers/WebVHCelManager';
34
+ import { BtcoCelManager } from './layers/BtcoCelManager';
35
+ import { verifyEventLog } from './algorithms/verifyEventLog';
36
+ /**
37
+ * OriginalsCel - Unified SDK for Cryptographic Event Log operations
38
+ *
39
+ * Provides a consistent API for creating, updating, verifying, and migrating
40
+ * assets across all supported layers (peer, webvh, btco).
41
+ */
42
+ export class OriginalsCel {
43
+ /**
44
+ * Creates a new OriginalsCel instance
45
+ *
46
+ * @param options - Configuration options
47
+ * @param options.layer - The target layer for operations (peer, webvh, btco)
48
+ * @param options.signer - Function that signs data and returns a DataIntegrityProof
49
+ * @param options.config - Optional layer-specific configuration
50
+ *
51
+ * @throws Error if signer is not a function
52
+ * @throws Error if layer is invalid
53
+ */
54
+ constructor(options) {
55
+ if (typeof options.signer !== 'function') {
56
+ throw new Error('OriginalsCel requires a signer function');
57
+ }
58
+ const validLayers = ['peer', 'webvh', 'btco'];
59
+ if (!validLayers.includes(options.layer)) {
60
+ throw new Error(`Invalid layer: ${options.layer}. Must be one of: ${validLayers.join(', ')}`);
61
+ }
62
+ this.layer = options.layer;
63
+ this.signer = options.signer;
64
+ this.config = options.config || {};
65
+ }
66
+ /**
67
+ * Gets or creates the PeerCelManager instance
68
+ */
69
+ get peerManager() {
70
+ if (!this._peerManager) {
71
+ this._peerManager = new PeerCelManager(this.signer, this.config.peer);
72
+ }
73
+ return this._peerManager;
74
+ }
75
+ /**
76
+ * Gets or creates the WebVHCelManager instance
77
+ *
78
+ * @throws Error if domain is not configured for webvh operations
79
+ */
80
+ getWebVHManager(domain) {
81
+ const webvhDomain = domain || this.config.webvh?.domain;
82
+ if (!webvhDomain) {
83
+ throw new Error('WebVH operations require a domain. Provide it in config.webvh.domain');
84
+ }
85
+ // Always create a new instance with the current domain to support different domains
86
+ return new WebVHCelManager(this.signer, webvhDomain, this.config.webvh?.witnesses || [], this.config.webvh);
87
+ }
88
+ /**
89
+ * Gets or creates the BtcoCelManager instance
90
+ *
91
+ * @throws Error if BitcoinManager is not configured for btco operations
92
+ */
93
+ get btcoManager() {
94
+ if (!this._btcoManager) {
95
+ const bitcoinManager = this.config.btco?.bitcoinManager;
96
+ if (!bitcoinManager) {
97
+ throw new Error('BTCO operations require a BitcoinManager. Provide it in config.btco.bitcoinManager');
98
+ }
99
+ this._btcoManager = new BtcoCelManager(this.signer, bitcoinManager, this.config.btco);
100
+ }
101
+ return this._btcoManager;
102
+ }
103
+ /**
104
+ * Creates a new asset with a CEL event log
105
+ *
106
+ * This method creates an asset at the configured layer. Note that
107
+ * new assets can only be created at the peer layer - for other layers,
108
+ * create at peer first and then migrate.
109
+ *
110
+ * @param name - Human-readable name for the asset
111
+ * @param resources - External resources associated with the asset
112
+ * @returns Promise resolving to an EventLog with the create event
113
+ *
114
+ * @throws Error if signer produces invalid proof
115
+ * @throws Error if trying to create at non-peer layer
116
+ *
117
+ * @example
118
+ * ```typescript
119
+ * const log = await cel.create('My Asset', [
120
+ * createExternalReference(imageData, 'image/png')
121
+ * ]);
122
+ * ```
123
+ */
124
+ async create(name, resources) {
125
+ // Assets can only be created at the peer layer
126
+ // Other layers require migration from peer
127
+ if (this.layer !== 'peer') {
128
+ throw new Error(`Cannot create assets at ${this.layer} layer directly. ` +
129
+ `Create at peer layer first, then use migrate() to move to ${this.layer}.`);
130
+ }
131
+ return this.peerManager.create(name, resources);
132
+ }
133
+ /**
134
+ * Updates an existing event log by appending an update event
135
+ *
136
+ * The new event is cryptographically linked to the previous event
137
+ * via a hash chain (previousEvent field).
138
+ *
139
+ * @param log - The existing event log to update
140
+ * @param data - The update data (new metadata, resources, etc.)
141
+ * @returns Promise resolving to a new EventLog with the update event appended
142
+ *
143
+ * @throws Error if the log is empty or deactivated
144
+ * @throws Error if signer produces invalid proof
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * const updated = await cel.update(log, {
149
+ * description: 'Updated description',
150
+ * tags: ['art', 'digital']
151
+ * });
152
+ * ```
153
+ */
154
+ async update(log, data) {
155
+ // Determine the current layer of the log
156
+ const currentLayer = this.getCurrentLayer(log);
157
+ // Use the appropriate manager based on current layer
158
+ switch (currentLayer) {
159
+ case 'peer':
160
+ return this.peerManager.update(log, data);
161
+ case 'webvh': {
162
+ // For webvh, we need to use the webvh manager
163
+ // Get domain from the log if possible
164
+ const webvhDomain = this.extractDomainFromLog(log);
165
+ return this.getWebVHManager(webvhDomain).migrate(log).then(
166
+ // webvh manager doesn't have update, use peer manager's algorithm
167
+ () => this.peerManager.update(log, data));
168
+ }
169
+ case 'btco':
170
+ // For btco, updates use the same underlying algorithm
171
+ return this.peerManager.update(log, data);
172
+ default: {
173
+ // TypeScript exhaustiveness check
174
+ const _exhaustive = currentLayer;
175
+ throw new Error(`Unknown layer: ${String(_exhaustive)}`);
176
+ }
177
+ }
178
+ }
179
+ /**
180
+ * Verifies all proofs and hash chain integrity in an event log
181
+ *
182
+ * This method verifies:
183
+ * - Each event has at least one proof
184
+ * - Each proof is structurally valid
185
+ * - The hash chain is intact (each event links to previous)
186
+ *
187
+ * @param log - The event log to verify
188
+ * @param options - Optional verification options
189
+ * @returns Promise resolving to VerificationResult with detailed status
190
+ *
191
+ * @example
192
+ * ```typescript
193
+ * const result = await cel.verify(log);
194
+ * if (result.verified) {
195
+ * console.log('Log is valid!');
196
+ * } else {
197
+ * console.error('Verification failed:', result.errors);
198
+ * }
199
+ * ```
200
+ */
201
+ async verify(log, options) {
202
+ return verifyEventLog(log, options);
203
+ }
204
+ /**
205
+ * Migrates an event log to a target layer
206
+ *
207
+ * Migration adds an update event with migration data and (optionally)
208
+ * witness proofs. The valid migration paths are:
209
+ * - peer → webvh
210
+ * - webvh → btco
211
+ * - peer → btco (requires intermediate webvh migration)
212
+ *
213
+ * @param log - The event log to migrate
214
+ * @param targetLayer - The layer to migrate to
215
+ * @param options - Optional migration options (e.g., domain for webvh)
216
+ * @returns Promise resolving to the migrated EventLog
217
+ *
218
+ * @throws Error if migration path is invalid
219
+ * @throws Error if required config is missing for target layer
220
+ *
221
+ * @example
222
+ * ```typescript
223
+ * // Migrate peer to webvh
224
+ * const webvhLog = await cel.migrate(peerLog, 'webvh', {
225
+ * domain: 'example.com'
226
+ * });
227
+ *
228
+ * // Migrate webvh to btco
229
+ * const btcoLog = await cel.migrate(webvhLog, 'btco');
230
+ * ```
231
+ */
232
+ async migrate(log, targetLayer, options) {
233
+ const currentLayer = this.getCurrentLayer(log);
234
+ // Validate migration path
235
+ if (currentLayer === targetLayer) {
236
+ throw new Error(`Log is already at ${targetLayer} layer`);
237
+ }
238
+ if (currentLayer === 'btco') {
239
+ throw new Error('Cannot migrate from btco layer - it is the final layer');
240
+ }
241
+ // Perform migration based on current and target layers
242
+ switch (targetLayer) {
243
+ case 'peer':
244
+ throw new Error('Cannot migrate to peer layer - it is the initial layer');
245
+ case 'webvh': {
246
+ if (currentLayer !== 'peer') {
247
+ throw new Error(`Invalid migration: ${currentLayer} → webvh. Can only migrate peer → webvh.`);
248
+ }
249
+ const domain = options?.domain || this.config.webvh?.domain;
250
+ return this.getWebVHManager(domain).migrate(log);
251
+ }
252
+ case 'btco': {
253
+ if (currentLayer === 'peer') {
254
+ // Need to do two-step migration: peer → webvh → btco
255
+ throw new Error('Cannot migrate directly from peer to btco. ' +
256
+ 'Migrate to webvh first, then to btco.');
257
+ }
258
+ if (currentLayer !== 'webvh') {
259
+ throw new Error(`Invalid migration: ${String(currentLayer)} → btco. Can only migrate webvh → btco.`);
260
+ }
261
+ return this.btcoManager.migrate(log);
262
+ }
263
+ default: {
264
+ // TypeScript exhaustiveness check
265
+ const _exhaustive = targetLayer;
266
+ throw new Error(`Unknown target layer: ${String(_exhaustive)}`);
267
+ }
268
+ }
269
+ }
270
+ /**
271
+ * Derives the current asset state by replaying all events in the log
272
+ *
273
+ * @param log - The event log to derive state from
274
+ * @returns The current AssetState
275
+ *
276
+ * @example
277
+ * ```typescript
278
+ * const state = cel.getCurrentState(log);
279
+ * console.log(state.name); // Asset name
280
+ * console.log(state.layer); // Current layer
281
+ * console.log(state.deactivated); // Whether deactivated
282
+ * ```
283
+ */
284
+ getCurrentState(log) {
285
+ // Determine current layer and use appropriate manager
286
+ const currentLayer = this.getCurrentLayer(log);
287
+ switch (currentLayer) {
288
+ case 'peer':
289
+ return this.peerManager.getCurrentState(log);
290
+ case 'webvh': {
291
+ // WebVH manager also handles state derivation correctly
292
+ const domain = this.extractDomainFromLog(log) || 'unknown.com';
293
+ return this.getWebVHManager(domain).getCurrentState(log);
294
+ }
295
+ case 'btco':
296
+ return this.btcoManager.getCurrentState(log);
297
+ default:
298
+ // Fallback to peer manager which handles all event types
299
+ return this.peerManager.getCurrentState(log);
300
+ }
301
+ }
302
+ /**
303
+ * Determines the current layer of an event log by examining its events
304
+ *
305
+ * @param log - The event log to examine
306
+ * @returns The current layer of the log
307
+ */
308
+ getCurrentLayer(log) {
309
+ if (!log || !log.events || log.events.length === 0) {
310
+ return 'peer'; // Default for empty logs
311
+ }
312
+ let currentLayer = 'peer';
313
+ for (const event of log.events) {
314
+ const eventData = event.data;
315
+ if (event.type === 'create') {
316
+ currentLayer = eventData.layer || 'peer';
317
+ }
318
+ else if (event.type === 'update' && eventData.targetDid && eventData.layer) {
319
+ // This is a migration event
320
+ currentLayer = eventData.layer;
321
+ }
322
+ }
323
+ return currentLayer;
324
+ }
325
+ /**
326
+ * Extracts the domain from a webvh log's migration event
327
+ *
328
+ * @param log - The event log to examine
329
+ * @returns The domain if found, undefined otherwise
330
+ */
331
+ extractDomainFromLog(log) {
332
+ if (!log || !log.events) {
333
+ return undefined;
334
+ }
335
+ for (const event of log.events) {
336
+ const eventData = event.data;
337
+ if (eventData.domain) {
338
+ return eventData.domain;
339
+ }
340
+ }
341
+ return undefined;
342
+ }
343
+ /**
344
+ * Gets the configured layer for this instance
345
+ */
346
+ get currentLayer() {
347
+ return this.layer;
348
+ }
349
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * createEventLog Algorithm
3
+ *
4
+ * Creates a new Cryptographic Event Log with an initial "create" event.
5
+ * The create event is the first event in a log and has no previousEvent reference.
6
+ *
7
+ * @see https://w3c-ccg.github.io/cel-spec/
8
+ */
9
+ import type { EventLog, CreateOptions } from '../types';
10
+ /**
11
+ * Creates a new event log with a single "create" event.
12
+ *
13
+ * This is the first step in creating a CEL-based provenance chain.
14
+ * The create event establishes the initial state of an asset.
15
+ *
16
+ * @param data - The initial data for the asset (e.g., name, resources, metadata)
17
+ * @param options - Signing options including signer function and verification method
18
+ * @returns A new EventLog containing a single create event
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const log = await createEventLog(
23
+ * { name: 'My Asset', resources: [...] },
24
+ * {
25
+ * signer: async (data) => createEdDsaProof(data, privateKey),
26
+ * verificationMethod: 'did:key:z6Mk...',
27
+ * proofPurpose: 'assertionMethod'
28
+ * }
29
+ * );
30
+ * ```
31
+ */
32
+ export declare function createEventLog(data: unknown, options: CreateOptions): Promise<EventLog>;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * createEventLog Algorithm
3
+ *
4
+ * Creates a new Cryptographic Event Log with an initial "create" event.
5
+ * The create event is the first event in a log and has no previousEvent reference.
6
+ *
7
+ * @see https://w3c-ccg.github.io/cel-spec/
8
+ */
9
+ /**
10
+ * Creates a new event log with a single "create" event.
11
+ *
12
+ * This is the first step in creating a CEL-based provenance chain.
13
+ * The create event establishes the initial state of an asset.
14
+ *
15
+ * @param data - The initial data for the asset (e.g., name, resources, metadata)
16
+ * @param options - Signing options including signer function and verification method
17
+ * @returns A new EventLog containing a single create event
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * const log = await createEventLog(
22
+ * { name: 'My Asset', resources: [...] },
23
+ * {
24
+ * signer: async (data) => createEdDsaProof(data, privateKey),
25
+ * verificationMethod: 'did:key:z6Mk...',
26
+ * proofPurpose: 'assertionMethod'
27
+ * }
28
+ * );
29
+ * ```
30
+ */
31
+ export async function createEventLog(data, options) {
32
+ const { signer, verificationMethod, proofPurpose = 'assertionMethod' } = options;
33
+ // Create the event structure without proof first
34
+ const eventBase = {
35
+ type: 'create',
36
+ data,
37
+ // Note: First event has no previousEvent
38
+ };
39
+ // Generate proof using the provided signer
40
+ const proof = await signer(eventBase);
41
+ // Validate the proof has required fields
42
+ if (!proof.type || !proof.cryptosuite || !proof.proofValue) {
43
+ throw new Error('Invalid proof: missing required fields (type, cryptosuite, proofValue)');
44
+ }
45
+ // Construct the complete log entry
46
+ const entry = {
47
+ type: 'create',
48
+ data,
49
+ proof: [proof],
50
+ };
51
+ // Return the new event log
52
+ const eventLog = {
53
+ events: [entry],
54
+ };
55
+ return eventLog;
56
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * deactivateEventLog Algorithm
3
+ *
4
+ * Seals an event log with a "deactivate" event. Once deactivated,
5
+ * no further events should be added to the log.
6
+ *
7
+ * @see https://w3c-ccg.github.io/cel-spec/
8
+ */
9
+ import type { EventLog, DeactivateOptions } from '../types';
10
+ /**
11
+ * Deactivates an event log by appending a final "deactivate" event.
12
+ *
13
+ * The deactivate event seals the log, indicating that no further
14
+ * events should be added. This is used to mark an asset as retired,
15
+ * revoked, or otherwise no longer active.
16
+ *
17
+ * @param log - The existing event log to deactivate
18
+ * @param reason - The reason for deactivation (e.g., "retired", "revoked", "superseded")
19
+ * @param options - Signing options including signer function and verification method
20
+ * @returns A new EventLog with the deactivate event appended (input is not mutated)
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * const deactivatedLog = await deactivateEventLog(
25
+ * existingLog,
26
+ * 'Asset has been superseded by a new version',
27
+ * {
28
+ * signer: async (data) => createEdDsaProof(data, privateKey),
29
+ * verificationMethod: 'did:key:z6Mk...',
30
+ * proofPurpose: 'assertionMethod'
31
+ * }
32
+ * );
33
+ * ```
34
+ */
35
+ export declare function deactivateEventLog(log: EventLog, reason: string, options: DeactivateOptions): Promise<EventLog>;
@@ -0,0 +1,91 @@
1
+ /**
2
+ * deactivateEventLog Algorithm
3
+ *
4
+ * Seals an event log with a "deactivate" event. Once deactivated,
5
+ * no further events should be added to the log.
6
+ *
7
+ * @see https://w3c-ccg.github.io/cel-spec/
8
+ */
9
+ import { computeDigestMultibase } from '../hash';
10
+ /**
11
+ * Serializes a LogEntry to a deterministic byte representation for hashing.
12
+ * Uses JSON with sorted keys for reproducibility.
13
+ *
14
+ * @param entry - The log entry to serialize
15
+ * @returns UTF-8 encoded bytes
16
+ */
17
+ function serializeEntry(entry) {
18
+ // Use JSON with sorted keys for deterministic serialization
19
+ const json = JSON.stringify(entry, Object.keys(entry).sort());
20
+ return new TextEncoder().encode(json);
21
+ }
22
+ /**
23
+ * Deactivates an event log by appending a final "deactivate" event.
24
+ *
25
+ * The deactivate event seals the log, indicating that no further
26
+ * events should be added. This is used to mark an asset as retired,
27
+ * revoked, or otherwise no longer active.
28
+ *
29
+ * @param log - The existing event log to deactivate
30
+ * @param reason - The reason for deactivation (e.g., "retired", "revoked", "superseded")
31
+ * @param options - Signing options including signer function and verification method
32
+ * @returns A new EventLog with the deactivate event appended (input is not mutated)
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * const deactivatedLog = await deactivateEventLog(
37
+ * existingLog,
38
+ * 'Asset has been superseded by a new version',
39
+ * {
40
+ * signer: async (data) => createEdDsaProof(data, privateKey),
41
+ * verificationMethod: 'did:key:z6Mk...',
42
+ * proofPurpose: 'assertionMethod'
43
+ * }
44
+ * );
45
+ * ```
46
+ */
47
+ export async function deactivateEventLog(log, reason, options) {
48
+ const { signer, verificationMethod, proofPurpose = 'assertionMethod' } = options;
49
+ // Validate input log
50
+ if (!log.events || log.events.length === 0) {
51
+ throw new Error('Cannot deactivate an empty event log');
52
+ }
53
+ // Check if log is already deactivated
54
+ const lastEvent = log.events[log.events.length - 1];
55
+ if (lastEvent.type === 'deactivate') {
56
+ throw new Error('Event log is already deactivated');
57
+ }
58
+ // Compute the digestMultibase of the last event
59
+ const previousEvent = computeDigestMultibase(serializeEntry(lastEvent));
60
+ // Deactivation data includes the reason
61
+ const deactivationData = {
62
+ reason,
63
+ deactivatedAt: new Date().toISOString(),
64
+ };
65
+ // Create the event structure without proof first
66
+ const eventBase = {
67
+ type: 'deactivate',
68
+ data: deactivationData,
69
+ previousEvent,
70
+ };
71
+ // Generate proof using the provided signer
72
+ const proof = await signer(eventBase);
73
+ // Validate the proof has required fields
74
+ if (!proof.type || !proof.cryptosuite || !proof.proofValue) {
75
+ throw new Error('Invalid proof: missing required fields (type, cryptosuite, proofValue)');
76
+ }
77
+ // Construct the complete log entry
78
+ const entry = {
79
+ type: 'deactivate',
80
+ data: deactivationData,
81
+ previousEvent,
82
+ proof: [proof],
83
+ };
84
+ // Return a new event log (immutable - does not mutate input)
85
+ const eventLog = {
86
+ events: [...log.events, entry],
87
+ // Preserve previousLog reference if it exists
88
+ ...(log.previousLog ? { previousLog: log.previousLog } : {}),
89
+ };
90
+ return eventLog;
91
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * CEL Algorithms
3
+ *
4
+ * Core algorithms for working with Cryptographic Event Logs.
5
+ */
6
+ export { createEventLog } from './createEventLog';
7
+ export { updateEventLog } from './updateEventLog';
8
+ export { deactivateEventLog } from './deactivateEventLog';
9
+ export { verifyEventLog } from './verifyEventLog';
10
+ export { witnessEvent } from './witnessEvent';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * CEL Algorithms
3
+ *
4
+ * Core algorithms for working with Cryptographic Event Logs.
5
+ */
6
+ export { createEventLog } from './createEventLog';
7
+ export { updateEventLog } from './updateEventLog';
8
+ export { deactivateEventLog } from './deactivateEventLog';
9
+ export { verifyEventLog } from './verifyEventLog';
10
+ export { witnessEvent } from './witnessEvent';
@@ -0,0 +1,34 @@
1
+ /**
2
+ * updateEventLog Algorithm
3
+ *
4
+ * Appends an update event to an existing Cryptographic Event Log.
5
+ * Each update event references the previous event via a hash chain.
6
+ *
7
+ * @see https://w3c-ccg.github.io/cel-spec/
8
+ */
9
+ import type { EventLog, UpdateOptions } from '../types';
10
+ /**
11
+ * Updates an event log by appending a new "update" event.
12
+ *
13
+ * The new event is cryptographically linked to the previous event
14
+ * via a hash of the last event (previousEvent field).
15
+ *
16
+ * @param log - The existing event log to update
17
+ * @param data - The update data (e.g., modified metadata, new resources)
18
+ * @param options - Signing options including signer function and verification method
19
+ * @returns A new EventLog with the update event appended (input is not mutated)
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * const updatedLog = await updateEventLog(
24
+ * existingLog,
25
+ * { name: 'Updated Asset Name', version: 2 },
26
+ * {
27
+ * signer: async (data) => createEdDsaProof(data, privateKey),
28
+ * verificationMethod: 'did:key:z6Mk...',
29
+ * proofPurpose: 'assertionMethod'
30
+ * }
31
+ * );
32
+ * ```
33
+ */
34
+ export declare function updateEventLog(log: EventLog, data: unknown, options: UpdateOptions): Promise<EventLog>;