@originals/sdk 1.8.1 → 1.8.2
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.
- package/dist/utils/hash.js +1 -0
- package/package.json +6 -5
- package/src/adapters/FeeOracleMock.ts +9 -0
- package/src/adapters/index.ts +5 -0
- package/src/adapters/providers/OrdHttpProvider.ts +126 -0
- package/src/adapters/providers/OrdMockProvider.ts +101 -0
- package/src/adapters/types.ts +66 -0
- package/src/bitcoin/BitcoinManager.ts +329 -0
- package/src/bitcoin/BroadcastClient.ts +54 -0
- package/src/bitcoin/OrdinalsClient.ts +120 -0
- package/src/bitcoin/PSBTBuilder.ts +106 -0
- package/src/bitcoin/fee-calculation.ts +38 -0
- package/src/bitcoin/providers/OrdNodeProvider.ts +92 -0
- package/src/bitcoin/providers/OrdinalsProvider.ts +56 -0
- package/src/bitcoin/providers/types.ts +59 -0
- package/src/bitcoin/transactions/commit.ts +465 -0
- package/src/bitcoin/transactions/index.ts +13 -0
- package/src/bitcoin/transfer.ts +43 -0
- package/src/bitcoin/utxo-selection.ts +322 -0
- package/src/bitcoin/utxo.ts +113 -0
- package/src/cel/ExternalReferenceManager.ts +87 -0
- package/src/cel/OriginalsCel.ts +460 -0
- package/src/cel/algorithms/createEventLog.ts +68 -0
- package/src/cel/algorithms/deactivateEventLog.ts +109 -0
- package/src/cel/algorithms/index.ts +11 -0
- package/src/cel/algorithms/updateEventLog.ts +99 -0
- package/src/cel/algorithms/verifyEventLog.ts +306 -0
- package/src/cel/algorithms/witnessEvent.ts +87 -0
- package/src/cel/cli/create.ts +330 -0
- package/src/cel/cli/index.ts +383 -0
- package/src/cel/cli/inspect.ts +549 -0
- package/src/cel/cli/migrate.ts +473 -0
- package/src/cel/cli/verify.ts +249 -0
- package/src/cel/hash.ts +71 -0
- package/src/cel/index.ts +16 -0
- package/src/cel/layers/BtcoCelManager.ts +408 -0
- package/src/cel/layers/PeerCelManager.ts +371 -0
- package/src/cel/layers/WebVHCelManager.ts +361 -0
- package/src/cel/layers/index.ts +27 -0
- package/src/cel/serialization/cbor.ts +189 -0
- package/src/cel/serialization/index.ts +10 -0
- package/src/cel/serialization/json.ts +209 -0
- package/src/cel/types.ts +160 -0
- package/src/cel/witnesses/BitcoinWitness.ts +184 -0
- package/src/cel/witnesses/HttpWitness.ts +241 -0
- package/src/cel/witnesses/WitnessService.ts +51 -0
- package/src/cel/witnesses/index.ts +11 -0
- package/src/contexts/credentials-v1.json +237 -0
- package/src/contexts/credentials-v2-examples.json +5 -0
- package/src/contexts/credentials-v2.json +340 -0
- package/src/contexts/credentials.json +237 -0
- package/src/contexts/data-integrity-v2.json +81 -0
- package/src/contexts/dids.json +58 -0
- package/src/contexts/ed255192020.json +93 -0
- package/src/contexts/ordinals-plus.json +23 -0
- package/src/contexts/originals.json +22 -0
- package/src/core/OriginalsSDK.ts +420 -0
- package/src/crypto/Multikey.ts +194 -0
- package/src/crypto/Signer.ts +262 -0
- package/src/crypto/noble-init.ts +138 -0
- package/src/did/BtcoDidResolver.ts +231 -0
- package/src/did/DIDManager.ts +705 -0
- package/src/did/Ed25519Verifier.ts +68 -0
- package/src/did/KeyManager.ts +239 -0
- package/src/did/WebVHManager.ts +499 -0
- package/src/did/createBtcoDidDocument.ts +60 -0
- package/src/did/providers/OrdinalsClientProviderAdapter.ts +68 -0
- package/src/events/EventEmitter.ts +222 -0
- package/src/events/index.ts +19 -0
- package/src/events/types.ts +331 -0
- package/src/examples/basic-usage.ts +78 -0
- package/src/examples/create-module-original.ts +435 -0
- package/src/examples/full-lifecycle-flow.ts +514 -0
- package/src/examples/run.ts +60 -0
- package/src/index.ts +204 -0
- package/src/kinds/KindRegistry.ts +320 -0
- package/src/kinds/index.ts +74 -0
- package/src/kinds/types.ts +470 -0
- package/src/kinds/validators/AgentValidator.ts +257 -0
- package/src/kinds/validators/AppValidator.ts +211 -0
- package/src/kinds/validators/DatasetValidator.ts +242 -0
- package/src/kinds/validators/DocumentValidator.ts +311 -0
- package/src/kinds/validators/MediaValidator.ts +269 -0
- package/src/kinds/validators/ModuleValidator.ts +225 -0
- package/src/kinds/validators/base.ts +276 -0
- package/src/kinds/validators/index.ts +12 -0
- package/src/lifecycle/BatchOperations.ts +381 -0
- package/src/lifecycle/LifecycleManager.ts +2156 -0
- package/src/lifecycle/OriginalsAsset.ts +524 -0
- package/src/lifecycle/ProvenanceQuery.ts +280 -0
- package/src/lifecycle/ResourceVersioning.ts +163 -0
- package/src/migration/MigrationManager.ts +587 -0
- package/src/migration/audit/AuditLogger.ts +176 -0
- package/src/migration/checkpoint/CheckpointManager.ts +112 -0
- package/src/migration/checkpoint/CheckpointStorage.ts +101 -0
- package/src/migration/index.ts +33 -0
- package/src/migration/operations/BaseMigration.ts +126 -0
- package/src/migration/operations/PeerToBtcoMigration.ts +105 -0
- package/src/migration/operations/PeerToWebvhMigration.ts +62 -0
- package/src/migration/operations/WebvhToBtcoMigration.ts +105 -0
- package/src/migration/rollback/RollbackManager.ts +170 -0
- package/src/migration/state/StateMachine.ts +92 -0
- package/src/migration/state/StateTracker.ts +156 -0
- package/src/migration/types.ts +356 -0
- package/src/migration/validation/BitcoinValidator.ts +107 -0
- package/src/migration/validation/CredentialValidator.ts +62 -0
- package/src/migration/validation/DIDCompatibilityValidator.ts +151 -0
- package/src/migration/validation/LifecycleValidator.ts +64 -0
- package/src/migration/validation/StorageValidator.ts +79 -0
- package/src/migration/validation/ValidationPipeline.ts +213 -0
- package/src/resources/ResourceManager.ts +655 -0
- package/src/resources/index.ts +21 -0
- package/src/resources/types.ts +202 -0
- package/src/storage/LocalStorageAdapter.ts +64 -0
- package/src/storage/MemoryStorageAdapter.ts +29 -0
- package/src/storage/StorageAdapter.ts +25 -0
- package/src/storage/index.ts +3 -0
- package/src/types/bitcoin.ts +98 -0
- package/src/types/common.ts +92 -0
- package/src/types/credentials.ts +89 -0
- package/src/types/did.ts +31 -0
- package/src/types/external-shims.d.ts +53 -0
- package/src/types/index.ts +7 -0
- package/src/types/network.ts +178 -0
- package/src/utils/EventLogger.ts +298 -0
- package/src/utils/Logger.ts +324 -0
- package/src/utils/MetricsCollector.ts +358 -0
- package/src/utils/bitcoin-address.ts +132 -0
- package/src/utils/cbor.ts +31 -0
- package/src/utils/encoding.ts +135 -0
- package/src/utils/hash.ts +12 -0
- package/src/utils/retry.ts +46 -0
- package/src/utils/satoshi-validation.ts +196 -0
- package/src/utils/serialization.ts +102 -0
- package/src/utils/telemetry.ts +44 -0
- package/src/utils/validation.ts +123 -0
- package/src/vc/CredentialManager.ts +955 -0
- package/src/vc/Issuer.ts +105 -0
- package/src/vc/Verifier.ts +54 -0
- package/src/vc/cryptosuites/bbs.ts +253 -0
- package/src/vc/cryptosuites/bbsSimple.ts +21 -0
- package/src/vc/cryptosuites/eddsa.ts +99 -0
- package/src/vc/documentLoader.ts +81 -0
- package/src/vc/proofs/data-integrity.ts +33 -0
- package/src/vc/utils/jsonld.ts +18 -0
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PeerCelManager - CEL Manager for did:peer Layer
|
|
3
|
+
*
|
|
4
|
+
* Creates and manages Originals assets in the did:peer layer (Layer 0).
|
|
5
|
+
* This is the initial layer for creating new assets with local control.
|
|
6
|
+
* No witnesses are required at this layer.
|
|
7
|
+
*
|
|
8
|
+
* @see https://identity.foundation/peer-did-method-spec/
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { EventLog, ExternalReference, DataIntegrityProof, CreateOptions, UpdateOptions, AssetState } from '../types';
|
|
12
|
+
import { createEventLog } from '../algorithms/createEventLog';
|
|
13
|
+
import { updateEventLog } from '../algorithms/updateEventLog';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Configuration options for PeerCelManager
|
|
17
|
+
*/
|
|
18
|
+
export interface PeerCelConfig {
|
|
19
|
+
/** The DID URL of the verification method for signing */
|
|
20
|
+
verificationMethod?: string;
|
|
21
|
+
/** The purpose of proofs (defaults to 'assertionMethod') */
|
|
22
|
+
proofPurpose?: string;
|
|
23
|
+
/** Key type to use for DID generation (defaults to 'Ed25519') */
|
|
24
|
+
keyType?: 'Ed25519' | 'ES256K' | 'ES256';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Asset data stored in the create event
|
|
29
|
+
*/
|
|
30
|
+
export interface PeerAssetData {
|
|
31
|
+
/** Asset name */
|
|
32
|
+
name: string;
|
|
33
|
+
/** Asset DID (did:peer) */
|
|
34
|
+
did: string;
|
|
35
|
+
/** Current layer */
|
|
36
|
+
layer: 'peer';
|
|
37
|
+
/** External resources associated with the asset */
|
|
38
|
+
resources: ExternalReference[];
|
|
39
|
+
/** Creator DID (same as asset DID for peer layer) */
|
|
40
|
+
creator: string;
|
|
41
|
+
/** ISO 8601 creation timestamp */
|
|
42
|
+
createdAt: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Signer function type that produces a DataIntegrityProof
|
|
47
|
+
*/
|
|
48
|
+
export type CelSigner = (data: unknown) => Promise<DataIntegrityProof>;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* PeerCelManager - Manages CEL-based assets in the did:peer layer
|
|
52
|
+
*
|
|
53
|
+
* The peer layer is the initial layer for creating new Originals assets.
|
|
54
|
+
* Assets at this layer:
|
|
55
|
+
* - Have a did:peer identifier
|
|
56
|
+
* - Are controlled by the creator's key pair
|
|
57
|
+
* - Do not require witnesses (empty witness array)
|
|
58
|
+
* - Can be migrated to did:webvh or did:btco layers
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* ```typescript
|
|
62
|
+
* const manager = new PeerCelManager(async (data) => {
|
|
63
|
+
* // Sign with your private key
|
|
64
|
+
* return createEdDsaProof(data, privateKey);
|
|
65
|
+
* });
|
|
66
|
+
*
|
|
67
|
+
* const log = await manager.create('My Asset', [
|
|
68
|
+
* { digestMultibase: 'uXYZ...', mediaType: 'image/png' }
|
|
69
|
+
* ]);
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export class PeerCelManager {
|
|
73
|
+
private signer: CelSigner;
|
|
74
|
+
private config: PeerCelConfig;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Creates a new PeerCelManager instance
|
|
78
|
+
*
|
|
79
|
+
* @param signer - Function that signs data and returns a DataIntegrityProof
|
|
80
|
+
* @param config - Optional configuration options
|
|
81
|
+
*/
|
|
82
|
+
constructor(signer: CelSigner, config: PeerCelConfig = {}) {
|
|
83
|
+
if (typeof signer !== 'function') {
|
|
84
|
+
throw new Error('PeerCelManager requires a signer function');
|
|
85
|
+
}
|
|
86
|
+
this.signer = signer;
|
|
87
|
+
this.config = {
|
|
88
|
+
proofPurpose: 'assertionMethod',
|
|
89
|
+
keyType: 'Ed25519',
|
|
90
|
+
...config,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Creates a new asset with a did:peer identifier and CEL event log
|
|
96
|
+
*
|
|
97
|
+
* This method:
|
|
98
|
+
* 1. Generates a new did:peer DID using the verification method from config
|
|
99
|
+
* 2. Creates a "create" event with the asset data
|
|
100
|
+
* 3. Signs the event using the provided signer
|
|
101
|
+
* 4. Returns an EventLog containing the initial create event
|
|
102
|
+
*
|
|
103
|
+
* @param name - Human-readable name for the asset
|
|
104
|
+
* @param resources - External resources associated with the asset
|
|
105
|
+
* @returns Promise resolving to an EventLog with the create event
|
|
106
|
+
*
|
|
107
|
+
* @throws Error if signer produces invalid proof
|
|
108
|
+
* @throws Error if DID generation fails
|
|
109
|
+
*/
|
|
110
|
+
async create(name: string, resources: ExternalReference[]): Promise<EventLog> {
|
|
111
|
+
// Validate inputs
|
|
112
|
+
if (!name || typeof name !== 'string') {
|
|
113
|
+
throw new Error('Asset name is required and must be a string');
|
|
114
|
+
}
|
|
115
|
+
if (!Array.isArray(resources)) {
|
|
116
|
+
throw new Error('Resources must be an array');
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Generate did:peer DID for this asset
|
|
120
|
+
const did = await this.generatePeerDid();
|
|
121
|
+
|
|
122
|
+
// Prepare asset data for the create event
|
|
123
|
+
const assetData: PeerAssetData = {
|
|
124
|
+
name,
|
|
125
|
+
did,
|
|
126
|
+
layer: 'peer',
|
|
127
|
+
resources,
|
|
128
|
+
creator: did, // Creator is the same as asset DID for peer layer
|
|
129
|
+
createdAt: new Date().toISOString(),
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
// Build create options
|
|
133
|
+
const createOptions: CreateOptions = {
|
|
134
|
+
signer: this.signer,
|
|
135
|
+
verificationMethod: this.config.verificationMethod || `${did}#key-0`,
|
|
136
|
+
proofPurpose: this.config.proofPurpose,
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
// Create the event log with a create event
|
|
140
|
+
const eventLog = await createEventLog(assetData, createOptions);
|
|
141
|
+
|
|
142
|
+
return eventLog;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Generates a new did:peer DID (numalgo 4 - long form)
|
|
147
|
+
*
|
|
148
|
+
* Uses @aviarytech/did-peer library to create a numalgo 4 DID
|
|
149
|
+
* which embeds the full DID document for self-contained resolution.
|
|
150
|
+
*
|
|
151
|
+
* @returns Promise resolving to a did:peer string
|
|
152
|
+
*/
|
|
153
|
+
private async generatePeerDid(): Promise<string> {
|
|
154
|
+
// Dynamically import did-peer library
|
|
155
|
+
let didPeerMod: any;
|
|
156
|
+
try {
|
|
157
|
+
didPeerMod = await import('@aviarytech/did-peer');
|
|
158
|
+
} catch (err) {
|
|
159
|
+
throw new Error(
|
|
160
|
+
'Failed to import @aviarytech/did-peer. Make sure it is installed: npm install @aviarytech/did-peer'
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// If we have a verification method with a public key, use it
|
|
165
|
+
// Otherwise, generate a placeholder DID using a random key
|
|
166
|
+
// In production, the signer's verification method should be used
|
|
167
|
+
|
|
168
|
+
// For did:peer numalgo 4, we need a verification method
|
|
169
|
+
// The verification method should come from the config or be derived from the signer
|
|
170
|
+
|
|
171
|
+
// Generate a DID using numalgo 4 (long-form with embedded DID document)
|
|
172
|
+
// We'll use a simple verification method structure
|
|
173
|
+
let publicKeyMultibase: string;
|
|
174
|
+
|
|
175
|
+
// If verificationMethod is provided and contains a key reference, extract it
|
|
176
|
+
if (this.config.verificationMethod && this.config.verificationMethod.includes('did:key:')) {
|
|
177
|
+
// Extract the public key from did:key format
|
|
178
|
+
const keyMatch = this.config.verificationMethod.match(/did:key:(z[a-zA-Z0-9]+)/);
|
|
179
|
+
publicKeyMultibase = keyMatch ? keyMatch[1] : await this.generateRandomPublicKey();
|
|
180
|
+
} else if (this.config.verificationMethod && this.config.verificationMethod.includes('#')) {
|
|
181
|
+
// If it's a fragment reference, we need to generate a key
|
|
182
|
+
publicKeyMultibase = await this.generateRandomPublicKey();
|
|
183
|
+
} else {
|
|
184
|
+
// Generate a random public key for the DID
|
|
185
|
+
publicKeyMultibase = await this.generateRandomPublicKey();
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Create did:peer using numalgo 4
|
|
189
|
+
const did: string = await didPeerMod.createNumAlgo4(
|
|
190
|
+
[
|
|
191
|
+
{
|
|
192
|
+
type: 'Multikey',
|
|
193
|
+
publicKeyMultibase,
|
|
194
|
+
}
|
|
195
|
+
],
|
|
196
|
+
undefined, // services
|
|
197
|
+
undefined // alsoKnownAs
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
return did;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Generates a random Ed25519 public key for DID creation
|
|
205
|
+
*
|
|
206
|
+
* @returns Promise resolving to a multibase-encoded public key
|
|
207
|
+
*/
|
|
208
|
+
private async generateRandomPublicKey(): Promise<string> {
|
|
209
|
+
// Use @noble/ed25519 for key generation
|
|
210
|
+
const ed25519 = await import('@noble/ed25519');
|
|
211
|
+
const privateKeyBytes = ed25519.utils.randomPrivateKey();
|
|
212
|
+
const publicKeyBytes = await (ed25519 as any).getPublicKeyAsync(privateKeyBytes);
|
|
213
|
+
|
|
214
|
+
// Import multikey encoder
|
|
215
|
+
const { multikey } = await import('../../crypto/Multikey');
|
|
216
|
+
return multikey.encodePublicKey(publicKeyBytes as Uint8Array, 'Ed25519');
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Updates an existing event log by appending an update event.
|
|
221
|
+
*
|
|
222
|
+
* The new event is cryptographically linked to the previous event
|
|
223
|
+
* via a hash chain (previousEvent field).
|
|
224
|
+
*
|
|
225
|
+
* @param log - The existing event log to update
|
|
226
|
+
* @param data - The update data (new metadata, resources, etc.)
|
|
227
|
+
* @returns Promise resolving to a new EventLog with the update event appended
|
|
228
|
+
*
|
|
229
|
+
* @throws Error if the log is empty or deactivated
|
|
230
|
+
* @throws Error if signer produces invalid proof
|
|
231
|
+
*
|
|
232
|
+
* @example
|
|
233
|
+
* ```typescript
|
|
234
|
+
* const updatedLog = await manager.update(log, {
|
|
235
|
+
* name: 'Renamed Asset',
|
|
236
|
+
* description: 'Updated description'
|
|
237
|
+
* });
|
|
238
|
+
* ```
|
|
239
|
+
*/
|
|
240
|
+
async update(log: EventLog, data: unknown): Promise<EventLog> {
|
|
241
|
+
// Validate input log
|
|
242
|
+
if (!log || !log.events || log.events.length === 0) {
|
|
243
|
+
throw new Error('Cannot update an empty event log');
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Check if log is already deactivated
|
|
247
|
+
const lastEvent = log.events[log.events.length - 1];
|
|
248
|
+
if (lastEvent.type === 'deactivate') {
|
|
249
|
+
throw new Error('Cannot update a deactivated event log');
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Get the DID from the create event for verification method construction
|
|
253
|
+
const createData = log.events[0].data as PeerAssetData;
|
|
254
|
+
const did = createData.did;
|
|
255
|
+
|
|
256
|
+
// Build update options using the same signer
|
|
257
|
+
const updateOptions: UpdateOptions = {
|
|
258
|
+
signer: this.signer,
|
|
259
|
+
verificationMethod: this.config.verificationMethod || `${did}#key-0`,
|
|
260
|
+
proofPurpose: this.config.proofPurpose,
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
// Add timestamp to update data
|
|
264
|
+
const updateData = {
|
|
265
|
+
...((typeof data === 'object' && data !== null) ? data : { value: data }),
|
|
266
|
+
updatedAt: new Date().toISOString(),
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
// Delegate to updateEventLog algorithm
|
|
270
|
+
return updateEventLog(log, updateData, updateOptions);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Derives the current asset state by replaying all events in the log.
|
|
275
|
+
*
|
|
276
|
+
* This method:
|
|
277
|
+
* 1. Starts with the initial state from the create event
|
|
278
|
+
* 2. Applies each update event sequentially
|
|
279
|
+
* 3. Marks as deactivated if a deactivate event is present
|
|
280
|
+
*
|
|
281
|
+
* @param log - The event log to derive state from
|
|
282
|
+
* @returns The current AssetState derived from replaying events
|
|
283
|
+
*
|
|
284
|
+
* @throws Error if the log is empty
|
|
285
|
+
* @throws Error if the first event is not a create event
|
|
286
|
+
*
|
|
287
|
+
* @example
|
|
288
|
+
* ```typescript
|
|
289
|
+
* const state = manager.getCurrentState(log);
|
|
290
|
+
* console.log(state.name); // Current asset name
|
|
291
|
+
* console.log(state.deactivated); // Whether asset is deactivated
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
getCurrentState(log: EventLog): AssetState {
|
|
295
|
+
// Validate input log
|
|
296
|
+
if (!log || !log.events || log.events.length === 0) {
|
|
297
|
+
throw new Error('Cannot get state from an empty event log');
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// First event must be a create event
|
|
301
|
+
const createEvent = log.events[0];
|
|
302
|
+
if (createEvent.type !== 'create') {
|
|
303
|
+
throw new Error('First event must be a create event');
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Extract initial state from create event
|
|
307
|
+
const createData = createEvent.data as PeerAssetData;
|
|
308
|
+
|
|
309
|
+
// Initialize state from create event
|
|
310
|
+
const state: AssetState = {
|
|
311
|
+
did: createData.did,
|
|
312
|
+
name: createData.name,
|
|
313
|
+
layer: createData.layer,
|
|
314
|
+
resources: [...createData.resources],
|
|
315
|
+
creator: createData.creator,
|
|
316
|
+
createdAt: createData.createdAt,
|
|
317
|
+
updatedAt: undefined,
|
|
318
|
+
deactivated: false,
|
|
319
|
+
metadata: {},
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
// Apply subsequent events
|
|
323
|
+
for (let i = 1; i < log.events.length; i++) {
|
|
324
|
+
const event = log.events[i];
|
|
325
|
+
|
|
326
|
+
if (event.type === 'update') {
|
|
327
|
+
// Merge update data into state
|
|
328
|
+
const updateData = event.data as Record<string, unknown>;
|
|
329
|
+
|
|
330
|
+
// Update specific known fields
|
|
331
|
+
if (updateData.name !== undefined) {
|
|
332
|
+
state.name = updateData.name as string;
|
|
333
|
+
}
|
|
334
|
+
if (updateData.resources !== undefined) {
|
|
335
|
+
state.resources = updateData.resources as ExternalReference[];
|
|
336
|
+
}
|
|
337
|
+
if (updateData.updatedAt !== undefined) {
|
|
338
|
+
state.updatedAt = updateData.updatedAt as string;
|
|
339
|
+
}
|
|
340
|
+
if (updateData.did !== undefined) {
|
|
341
|
+
state.did = updateData.did as string;
|
|
342
|
+
}
|
|
343
|
+
if (updateData.layer !== undefined) {
|
|
344
|
+
state.layer = updateData.layer as 'peer' | 'webvh' | 'btco';
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Store other fields in metadata
|
|
348
|
+
for (const [key, value] of Object.entries(updateData)) {
|
|
349
|
+
if (!['name', 'resources', 'updatedAt', 'did', 'layer', 'creator', 'createdAt'].includes(key)) {
|
|
350
|
+
state.metadata = state.metadata || {};
|
|
351
|
+
state.metadata[key] = value;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
} else if (event.type === 'deactivate') {
|
|
355
|
+
state.deactivated = true;
|
|
356
|
+
|
|
357
|
+
// Extract deactivation details
|
|
358
|
+
const deactivateData = event.data as Record<string, unknown>;
|
|
359
|
+
if (deactivateData.deactivatedAt !== undefined) {
|
|
360
|
+
state.updatedAt = deactivateData.deactivatedAt as string;
|
|
361
|
+
}
|
|
362
|
+
if (deactivateData.reason !== undefined) {
|
|
363
|
+
state.metadata = state.metadata || {};
|
|
364
|
+
state.metadata.deactivationReason = deactivateData.reason;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return state;
|
|
370
|
+
}
|
|
371
|
+
}
|