@originals/sdk 1.5.0 ā 1.6.1
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/adapters/FeeOracleMock.js +2 -2
- package/dist/bitcoin/OrdinalsClient.d.ts +1 -1
- package/dist/bitcoin/OrdinalsClient.js +10 -8
- package/dist/bitcoin/PSBTBuilder.js +1 -1
- package/dist/bitcoin/utxo-selection.js +2 -2
- package/dist/cel/ExternalReferenceManager.d.ts +57 -0
- package/dist/cel/ExternalReferenceManager.js +73 -0
- package/dist/cel/OriginalsCel.d.ts +245 -0
- package/dist/cel/OriginalsCel.js +349 -0
- package/dist/cel/algorithms/createEventLog.d.ts +32 -0
- package/dist/cel/algorithms/createEventLog.js +56 -0
- package/dist/cel/algorithms/deactivateEventLog.d.ts +35 -0
- package/dist/cel/algorithms/deactivateEventLog.js +91 -0
- package/dist/cel/algorithms/index.d.ts +10 -0
- package/dist/cel/algorithms/index.js +10 -0
- package/dist/cel/algorithms/updateEventLog.d.ts +34 -0
- package/dist/cel/algorithms/updateEventLog.js +82 -0
- package/dist/cel/algorithms/verifyEventLog.d.ts +45 -0
- package/dist/cel/algorithms/verifyEventLog.js +255 -0
- package/dist/cel/algorithms/witnessEvent.d.ts +29 -0
- package/dist/cel/algorithms/witnessEvent.js +75 -0
- package/dist/cel/cli/create.d.ts +36 -0
- package/dist/cel/cli/create.js +282 -0
- package/dist/cel/cli/index.d.ts +11 -0
- package/dist/cel/cli/index.js +351 -0
- package/dist/cel/cli/inspect.d.ts +30 -0
- package/dist/cel/cli/inspect.js +475 -0
- package/dist/cel/cli/migrate.d.ts +41 -0
- package/dist/cel/cli/migrate.js +405 -0
- package/dist/cel/cli/verify.d.ts +31 -0
- package/dist/cel/cli/verify.js +205 -0
- package/dist/cel/hash.d.ts +46 -0
- package/dist/cel/hash.js +66 -0
- package/dist/cel/index.d.ts +15 -0
- package/dist/cel/index.js +15 -0
- package/dist/cel/layers/BtcoCelManager.d.ts +121 -0
- package/dist/cel/layers/BtcoCelManager.js +329 -0
- package/dist/cel/layers/PeerCelManager.d.ts +151 -0
- package/dist/cel/layers/PeerCelManager.js +299 -0
- package/dist/cel/layers/WebVHCelManager.d.ts +122 -0
- package/dist/cel/layers/WebVHCelManager.js +291 -0
- package/dist/cel/layers/index.d.ts +13 -0
- package/dist/cel/layers/index.js +16 -0
- package/dist/cel/serialization/cbor.d.ts +42 -0
- package/dist/cel/serialization/cbor.js +163 -0
- package/dist/cel/serialization/index.d.ts +9 -0
- package/dist/cel/serialization/index.js +9 -0
- package/dist/cel/serialization/json.d.ts +41 -0
- package/dist/cel/serialization/json.js +180 -0
- package/dist/cel/types.d.ts +149 -0
- package/dist/cel/types.js +7 -0
- package/dist/cel/witnesses/BitcoinWitness.d.ts +83 -0
- package/dist/cel/witnesses/BitcoinWitness.js +116 -0
- package/dist/cel/witnesses/HttpWitness.d.ts +79 -0
- package/dist/cel/witnesses/HttpWitness.js +163 -0
- package/dist/cel/witnesses/WitnessService.d.ts +49 -0
- package/dist/cel/witnesses/WitnessService.js +10 -0
- package/dist/cel/witnesses/index.d.ts +10 -0
- package/dist/cel/witnesses/index.js +7 -0
- package/dist/core/OriginalsSDK.js +5 -1
- package/dist/crypto/Signer.js +14 -6
- package/dist/crypto/noble-init.js +20 -1
- package/dist/did/BtcoDidResolver.d.ts +2 -2
- package/dist/did/BtcoDidResolver.js +12 -8
- package/dist/did/DIDManager.js +6 -4
- package/dist/did/KeyManager.d.ts +1 -1
- package/dist/did/KeyManager.js +7 -4
- package/dist/did/WebVHManager.js +1 -1
- package/dist/did/createBtcoDidDocument.js +2 -1
- package/dist/events/types.d.ts +4 -1
- package/dist/examples/create-module-original.js +1 -1
- package/dist/examples/full-lifecycle-flow.js +2 -2
- package/dist/index.d.ts +13 -0
- package/dist/index.js +12 -0
- package/dist/kinds/KindRegistry.js +59 -29
- package/dist/lifecycle/BatchOperations.d.ts +5 -3
- package/dist/lifecycle/BatchOperations.js +11 -5
- package/dist/lifecycle/LifecycleManager.d.ts +1 -1
- package/dist/lifecycle/LifecycleManager.js +42 -33
- package/dist/lifecycle/OriginalsAsset.js +2 -2
- package/dist/migration/MigrationManager.js +67 -3
- package/dist/storage/LocalStorageAdapter.js +4 -1
- package/dist/storage/MemoryStorageAdapter.js +7 -7
- package/dist/types/network.js +6 -3
- package/dist/utils/Logger.d.ts +6 -6
- package/dist/utils/Logger.js +5 -3
- package/dist/utils/MetricsCollector.js +1 -1
- package/dist/utils/bitcoin-address.js +4 -2
- package/dist/utils/cbor.js +16 -3
- package/dist/utils/encoding.d.ts +4 -4
- package/dist/utils/encoding.js +7 -6
- package/dist/utils/hash.js +6 -1
- package/dist/utils/serialization.d.ts +2 -2
- package/dist/utils/serialization.js +7 -5
- package/dist/utils/telemetry.js +6 -2
- package/dist/utils/validation.js +8 -4
- package/dist/vc/CredentialManager.d.ts +8 -8
- package/dist/vc/CredentialManager.js +46 -33
- package/dist/vc/Issuer.d.ts +2 -2
- package/dist/vc/Issuer.js +5 -1
- package/dist/vc/Verifier.d.ts +2 -2
- package/dist/vc/Verifier.js +12 -6
- package/dist/vc/documentLoader.d.ts +5 -3
- package/dist/vc/documentLoader.js +5 -4
- package/package.json +4 -1
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CLI Inspect Command
|
|
4
|
+
*
|
|
5
|
+
* Inspects a CEL event log in human-readable format.
|
|
6
|
+
* Displays event timeline, current state, witness attestations, and layer history.
|
|
7
|
+
*
|
|
8
|
+
* Usage: originals-cel inspect --log <path> [options]
|
|
9
|
+
*/
|
|
10
|
+
import * as fs from 'fs';
|
|
11
|
+
import * as path from 'path';
|
|
12
|
+
import { parseEventLogJson } from '../serialization/json';
|
|
13
|
+
import { parseEventLogCbor } from '../serialization/cbor';
|
|
14
|
+
/**
|
|
15
|
+
* Check if a proof is a WitnessProof (has witnessedAt field)
|
|
16
|
+
*/
|
|
17
|
+
function isWitnessProof(proof) {
|
|
18
|
+
return 'witnessedAt' in proof && typeof proof.witnessedAt === 'string';
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Check if event data contains migration information
|
|
22
|
+
*/
|
|
23
|
+
function isMigrationEvent(data) {
|
|
24
|
+
if (typeof data !== 'object' || data === null)
|
|
25
|
+
return false;
|
|
26
|
+
const d = data;
|
|
27
|
+
return (('sourceDid' in d && 'targetDid' in d) ||
|
|
28
|
+
('layer' in d && typeof d.layer === 'string' && ['peer', 'webvh', 'btco'].includes(d.layer)));
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Loads and parses an event log from a file
|
|
32
|
+
* Supports both JSON (.json) and CBOR (.cbor) formats
|
|
33
|
+
*/
|
|
34
|
+
function loadEventLog(filePath) {
|
|
35
|
+
if (!fs.existsSync(filePath)) {
|
|
36
|
+
throw new Error(`File not found: ${filePath}`);
|
|
37
|
+
}
|
|
38
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
39
|
+
const content = fs.readFileSync(filePath);
|
|
40
|
+
if (ext === '.cbor') {
|
|
41
|
+
// Parse as CBOR binary
|
|
42
|
+
return parseEventLogCbor(new Uint8Array(content));
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
// Default to JSON parsing
|
|
46
|
+
return parseEventLogJson(content.toString('utf-8'));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Format a timestamp for display
|
|
51
|
+
*/
|
|
52
|
+
function formatTimestamp(timestamp) {
|
|
53
|
+
try {
|
|
54
|
+
const date = new Date(timestamp);
|
|
55
|
+
return date.toLocaleString('en-US', {
|
|
56
|
+
year: 'numeric',
|
|
57
|
+
month: 'short',
|
|
58
|
+
day: '2-digit',
|
|
59
|
+
hour: '2-digit',
|
|
60
|
+
minute: '2-digit',
|
|
61
|
+
second: '2-digit',
|
|
62
|
+
timeZoneName: 'short',
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return timestamp;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Format ISO timestamp to relative time
|
|
71
|
+
*/
|
|
72
|
+
function formatRelativeTime(timestamp) {
|
|
73
|
+
try {
|
|
74
|
+
const date = new Date(timestamp);
|
|
75
|
+
const now = new Date();
|
|
76
|
+
const diffMs = now.getTime() - date.getTime();
|
|
77
|
+
const diffMins = Math.floor(diffMs / 60000);
|
|
78
|
+
const diffHours = Math.floor(diffMs / 3600000);
|
|
79
|
+
const diffDays = Math.floor(diffMs / 86400000);
|
|
80
|
+
if (diffMins < 1)
|
|
81
|
+
return 'just now';
|
|
82
|
+
if (diffMins < 60)
|
|
83
|
+
return `${diffMins} minute${diffMins > 1 ? 's' : ''} ago`;
|
|
84
|
+
if (diffHours < 24)
|
|
85
|
+
return `${diffHours} hour${diffHours > 1 ? 's' : ''} ago`;
|
|
86
|
+
if (diffDays < 30)
|
|
87
|
+
return `${diffDays} day${diffDays > 1 ? 's' : ''} ago`;
|
|
88
|
+
return formatTimestamp(timestamp);
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return timestamp;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Truncate long strings for display
|
|
96
|
+
*/
|
|
97
|
+
function truncate(str, maxLen) {
|
|
98
|
+
if (str.length <= maxLen)
|
|
99
|
+
return str;
|
|
100
|
+
return str.substring(0, maxLen - 3) + '...';
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Format DID for display (truncate middle)
|
|
104
|
+
*/
|
|
105
|
+
function formatDid(did) {
|
|
106
|
+
if (did.length <= 50)
|
|
107
|
+
return did;
|
|
108
|
+
return did.substring(0, 25) + '...' + did.substring(did.length - 15);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get event type badge
|
|
112
|
+
*/
|
|
113
|
+
function getEventBadge(type) {
|
|
114
|
+
switch (type) {
|
|
115
|
+
case 'create': return 'š CREATE';
|
|
116
|
+
case 'update': return 'āļø UPDATE';
|
|
117
|
+
case 'deactivate': return 'š DEACTIVATE';
|
|
118
|
+
default: return `š ${type.toUpperCase()}`;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Get layer badge
|
|
123
|
+
*/
|
|
124
|
+
function getLayerBadge(layer) {
|
|
125
|
+
switch (layer) {
|
|
126
|
+
case 'peer': return 'š Peer (Layer 0)';
|
|
127
|
+
case 'webvh': return 'š WebVH (Layer 1)';
|
|
128
|
+
case 'btco': return 'āæ Bitcoin (Layer 2)';
|
|
129
|
+
default: return layer;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Derive current state from event log (simplified version)
|
|
134
|
+
*/
|
|
135
|
+
function deriveCurrentState(log) {
|
|
136
|
+
if (!log.events || log.events.length === 0) {
|
|
137
|
+
throw new Error('Cannot derive state from empty event log');
|
|
138
|
+
}
|
|
139
|
+
const createEvent = log.events[0];
|
|
140
|
+
if (createEvent.type !== 'create') {
|
|
141
|
+
throw new Error('First event must be a create event');
|
|
142
|
+
}
|
|
143
|
+
const createData = createEvent.data;
|
|
144
|
+
// Initialize state from create event
|
|
145
|
+
const state = {
|
|
146
|
+
did: createData.did || 'unknown',
|
|
147
|
+
name: createData.name,
|
|
148
|
+
layer: createData.layer || 'peer',
|
|
149
|
+
resources: createData.resources || [],
|
|
150
|
+
creator: createData.creator,
|
|
151
|
+
createdAt: createData.createdAt,
|
|
152
|
+
updatedAt: undefined,
|
|
153
|
+
deactivated: false,
|
|
154
|
+
metadata: {},
|
|
155
|
+
};
|
|
156
|
+
// Apply subsequent events
|
|
157
|
+
for (let i = 1; i < log.events.length; i++) {
|
|
158
|
+
const event = log.events[i];
|
|
159
|
+
if (event.type === 'update') {
|
|
160
|
+
const updateData = event.data;
|
|
161
|
+
// Update known fields
|
|
162
|
+
if (updateData.name !== undefined)
|
|
163
|
+
state.name = updateData.name;
|
|
164
|
+
if (updateData.resources !== undefined)
|
|
165
|
+
state.resources = updateData.resources;
|
|
166
|
+
if (updateData.updatedAt !== undefined)
|
|
167
|
+
state.updatedAt = updateData.updatedAt;
|
|
168
|
+
if (updateData.did !== undefined)
|
|
169
|
+
state.did = updateData.did;
|
|
170
|
+
if (updateData.targetDid !== undefined)
|
|
171
|
+
state.did = updateData.targetDid;
|
|
172
|
+
if (updateData.layer !== undefined)
|
|
173
|
+
state.layer = updateData.layer;
|
|
174
|
+
// Store migration data in metadata
|
|
175
|
+
if (isMigrationEvent(updateData)) {
|
|
176
|
+
state.metadata = state.metadata || {};
|
|
177
|
+
if (updateData.sourceDid)
|
|
178
|
+
state.metadata.sourceDid = updateData.sourceDid;
|
|
179
|
+
if (updateData.domain)
|
|
180
|
+
state.metadata.domain = updateData.domain;
|
|
181
|
+
if (updateData.txid)
|
|
182
|
+
state.metadata.txid = updateData.txid;
|
|
183
|
+
if (updateData.inscriptionId)
|
|
184
|
+
state.metadata.inscriptionId = updateData.inscriptionId;
|
|
185
|
+
}
|
|
186
|
+
// Store other fields in metadata
|
|
187
|
+
for (const [key, value] of Object.entries(updateData)) {
|
|
188
|
+
if (!['name', 'resources', 'updatedAt', 'did', 'targetDid', 'layer', 'creator', 'createdAt', 'sourceDid', 'domain', 'txid', 'inscriptionId'].includes(key)) {
|
|
189
|
+
state.metadata = state.metadata || {};
|
|
190
|
+
state.metadata[key] = value;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
else if (event.type === 'deactivate') {
|
|
195
|
+
state.deactivated = true;
|
|
196
|
+
const deactivateData = event.data;
|
|
197
|
+
if (deactivateData.deactivatedAt !== undefined) {
|
|
198
|
+
state.updatedAt = deactivateData.deactivatedAt;
|
|
199
|
+
}
|
|
200
|
+
if (deactivateData.reason !== undefined) {
|
|
201
|
+
state.metadata = state.metadata || {};
|
|
202
|
+
state.metadata.deactivationReason = deactivateData.reason;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return state;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Extract layer history from events
|
|
210
|
+
*/
|
|
211
|
+
function extractLayerHistory(log) {
|
|
212
|
+
const history = [];
|
|
213
|
+
for (const event of log.events) {
|
|
214
|
+
const data = event.data;
|
|
215
|
+
if (event.type === 'create' && data.layer) {
|
|
216
|
+
history.push({
|
|
217
|
+
layer: data.layer,
|
|
218
|
+
timestamp: data.createdAt || event.proof[0]?.created || 'unknown',
|
|
219
|
+
did: data.did,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
if (event.type === 'update' && isMigrationEvent(event.data)) {
|
|
223
|
+
const migrationData = event.data;
|
|
224
|
+
history.push({
|
|
225
|
+
layer: migrationData.layer ?? 'unknown',
|
|
226
|
+
timestamp: migrationData.migratedAt ?? event.proof[0]?.created ?? 'unknown',
|
|
227
|
+
did: migrationData.targetDid ?? 'unknown',
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return history;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Extract all witness attestations from the log
|
|
235
|
+
*/
|
|
236
|
+
function extractWitnesses(log) {
|
|
237
|
+
const witnesses = [];
|
|
238
|
+
for (let i = 0; i < log.events.length; i++) {
|
|
239
|
+
const event = log.events[i];
|
|
240
|
+
for (const proof of event.proof) {
|
|
241
|
+
if (isWitnessProof(proof)) {
|
|
242
|
+
witnesses.push({
|
|
243
|
+
eventIndex: i,
|
|
244
|
+
eventType: event.type,
|
|
245
|
+
witnessedAt: proof.witnessedAt,
|
|
246
|
+
cryptosuite: proof.cryptosuite,
|
|
247
|
+
verificationMethod: proof.verificationMethod,
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return witnesses;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Output the inspection result to stdout
|
|
256
|
+
*/
|
|
257
|
+
function outputInspection(log, state) {
|
|
258
|
+
console.log('\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
259
|
+
console.log(' CEL Event Log Inspector');
|
|
260
|
+
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n');
|
|
261
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
262
|
+
// Current State Section
|
|
263
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
264
|
+
console.log('š¦ CURRENT STATE');
|
|
265
|
+
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
266
|
+
// Status badge
|
|
267
|
+
if (state.deactivated) {
|
|
268
|
+
console.log(` Status: š DEACTIVATED`);
|
|
269
|
+
if (state.metadata?.deactivationReason) {
|
|
270
|
+
console.log(` Reason: ${state.metadata.deactivationReason}`);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
console.log(` Status: ā
ACTIVE`);
|
|
275
|
+
}
|
|
276
|
+
console.log(` Name: ${state.name || '(unnamed)'}`);
|
|
277
|
+
console.log(` Layer: ${getLayerBadge(state.layer)}`);
|
|
278
|
+
console.log(` DID: ${formatDid(state.did)}`);
|
|
279
|
+
if (state.creator) {
|
|
280
|
+
console.log(` Creator: ${formatDid(state.creator)}`);
|
|
281
|
+
}
|
|
282
|
+
if (state.createdAt) {
|
|
283
|
+
console.log(` Created: ${formatTimestamp(state.createdAt)} (${formatRelativeTime(state.createdAt)})`);
|
|
284
|
+
}
|
|
285
|
+
if (state.updatedAt) {
|
|
286
|
+
console.log(` Updated: ${formatTimestamp(state.updatedAt)} (${formatRelativeTime(state.updatedAt)})`);
|
|
287
|
+
}
|
|
288
|
+
// Resources
|
|
289
|
+
if (state.resources && state.resources.length > 0) {
|
|
290
|
+
console.log(`\n š Resources (${state.resources.length}):`);
|
|
291
|
+
for (let i = 0; i < state.resources.length; i++) {
|
|
292
|
+
const res = state.resources[i];
|
|
293
|
+
console.log(` [${i + 1}] ${res.mediaType || 'unknown'}`);
|
|
294
|
+
console.log(` Hash: ${truncate(res.digestMultibase, 50)}`);
|
|
295
|
+
if (res.url && res.url.length > 0) {
|
|
296
|
+
console.log(` URL: ${res.url[0]}`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
// Additional metadata
|
|
301
|
+
if (state.metadata && Object.keys(state.metadata).length > 0) {
|
|
302
|
+
const displayKeys = Object.keys(state.metadata).filter(k => !['deactivationReason'].includes(k));
|
|
303
|
+
if (displayKeys.length > 0) {
|
|
304
|
+
console.log(`\n š Metadata:`);
|
|
305
|
+
for (const key of displayKeys) {
|
|
306
|
+
const value = state.metadata[key];
|
|
307
|
+
const displayValue = typeof value === 'string'
|
|
308
|
+
? truncate(value, 50)
|
|
309
|
+
: JSON.stringify(value);
|
|
310
|
+
console.log(` ${key}: ${displayValue}`);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
315
|
+
// Layer History Section
|
|
316
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
317
|
+
const layerHistory = extractLayerHistory(log);
|
|
318
|
+
if (layerHistory.length > 1) {
|
|
319
|
+
console.log('\n\nšŗļø LAYER HISTORY');
|
|
320
|
+
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
321
|
+
for (let i = 0; i < layerHistory.length; i++) {
|
|
322
|
+
const entry = layerHistory[i];
|
|
323
|
+
const isLast = i === layerHistory.length - 1;
|
|
324
|
+
const prefix = isLast ? ' āā' : ' āā';
|
|
325
|
+
const arrow = i > 0 ? ' ā ' : '';
|
|
326
|
+
console.log(`${prefix} ${getLayerBadge(entry.layer)}`);
|
|
327
|
+
if (entry.timestamp) {
|
|
328
|
+
console.log(` ${isLast ? ' ' : 'ā'} ${formatTimestamp(entry.timestamp)}`);
|
|
329
|
+
}
|
|
330
|
+
if (entry.did) {
|
|
331
|
+
console.log(` ${isLast ? ' ' : 'ā'} ${formatDid(entry.did)}`);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
336
|
+
// Witness Attestations Section
|
|
337
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
338
|
+
const witnesses = extractWitnesses(log);
|
|
339
|
+
if (witnesses.length > 0) {
|
|
340
|
+
console.log('\n\nš WITNESS ATTESTATIONS');
|
|
341
|
+
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
342
|
+
for (let i = 0; i < witnesses.length; i++) {
|
|
343
|
+
const witness = witnesses[i];
|
|
344
|
+
console.log(`\n [${i + 1}] Event #${witness.eventIndex + 1} (${witness.eventType})`);
|
|
345
|
+
console.log(` Witnessed: ${formatTimestamp(witness.witnessedAt)}`);
|
|
346
|
+
console.log(` Cryptosuite: ${witness.cryptosuite}`);
|
|
347
|
+
console.log(` Witness: ${truncate(witness.verificationMethod, 50)}`);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
351
|
+
// Event Timeline Section
|
|
352
|
+
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
353
|
+
console.log('\n\nš EVENT TIMELINE');
|
|
354
|
+
console.log('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā');
|
|
355
|
+
for (let i = 0; i < log.events.length; i++) {
|
|
356
|
+
const event = log.events[i];
|
|
357
|
+
const data = event.data;
|
|
358
|
+
const isLast = i === log.events.length - 1;
|
|
359
|
+
const prefix = isLast ? 'āā' : 'āā';
|
|
360
|
+
const connector = isLast ? ' ' : 'ā ';
|
|
361
|
+
// Event header with type badge
|
|
362
|
+
console.log(`\n ${prefix} ${getEventBadge(event.type)}`);
|
|
363
|
+
// Timestamp from proof
|
|
364
|
+
const timestamp = event.proof[0]?.created || data.createdAt || data.updatedAt || data.migratedAt || data.deactivatedAt;
|
|
365
|
+
if (timestamp) {
|
|
366
|
+
console.log(` ${connector} š
${formatTimestamp(timestamp)}`);
|
|
367
|
+
}
|
|
368
|
+
// Event-specific details
|
|
369
|
+
if (event.type === 'create') {
|
|
370
|
+
if (data.name)
|
|
371
|
+
console.log(` ${connector} Name: ${data.name}`);
|
|
372
|
+
if (data.did)
|
|
373
|
+
console.log(` ${connector} DID: ${formatDid(data.did)}`);
|
|
374
|
+
if (data.layer)
|
|
375
|
+
console.log(` ${connector} Layer: ${data.layer}`);
|
|
376
|
+
if (data.resources && Array.isArray(data.resources)) {
|
|
377
|
+
console.log(` ${connector} Resources: ${data.resources.length} file(s)`);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
else if (event.type === 'update') {
|
|
381
|
+
// Show what changed
|
|
382
|
+
const changes = [];
|
|
383
|
+
if (data.name)
|
|
384
|
+
changes.push(`name ā "${data.name}"`);
|
|
385
|
+
if (data.resources)
|
|
386
|
+
changes.push(`resources updated`);
|
|
387
|
+
if (isMigrationEvent(event.data)) {
|
|
388
|
+
const migrationData = event.data;
|
|
389
|
+
changes.push(`migrated to ${migrationData.layer ?? 'unknown'}`);
|
|
390
|
+
if (migrationData.domain)
|
|
391
|
+
changes.push(`domain: ${migrationData.domain}`);
|
|
392
|
+
if (migrationData.txid)
|
|
393
|
+
changes.push(`txid: ${truncate(migrationData.txid, 20)}`);
|
|
394
|
+
}
|
|
395
|
+
if (changes.length > 0) {
|
|
396
|
+
console.log(` ${connector} Changes: ${changes.join(', ')}`);
|
|
397
|
+
}
|
|
398
|
+
else {
|
|
399
|
+
// Show raw data keys
|
|
400
|
+
const keys = Object.keys(data).filter(k => k !== 'updatedAt');
|
|
401
|
+
if (keys.length > 0) {
|
|
402
|
+
console.log(` ${connector} Fields: ${keys.join(', ')}`);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
else if (event.type === 'deactivate') {
|
|
407
|
+
if (data.reason)
|
|
408
|
+
console.log(` ${connector} Reason: ${data.reason}`);
|
|
409
|
+
}
|
|
410
|
+
// Proof summary
|
|
411
|
+
const controllerProofs = event.proof.filter(p => !isWitnessProof(p));
|
|
412
|
+
const witnessProofs = event.proof.filter(p => isWitnessProof(p));
|
|
413
|
+
const proofParts = [];
|
|
414
|
+
if (controllerProofs.length > 0) {
|
|
415
|
+
proofParts.push(`${controllerProofs.length} controller`);
|
|
416
|
+
}
|
|
417
|
+
if (witnessProofs.length > 0) {
|
|
418
|
+
proofParts.push(`${witnessProofs.length} witness`);
|
|
419
|
+
}
|
|
420
|
+
console.log(` ${connector} š Proofs: ${proofParts.join(', ')}`);
|
|
421
|
+
// Hash chain link
|
|
422
|
+
if (event.previousEvent) {
|
|
423
|
+
console.log(` ${connector} š Chain: ${truncate(event.previousEvent, 40)}`);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
console.log('\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n');
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Execute the inspect command
|
|
430
|
+
*/
|
|
431
|
+
export async function inspectCommand(flags) {
|
|
432
|
+
// Check for help flag
|
|
433
|
+
if (flags.help || flags.h) {
|
|
434
|
+
return {
|
|
435
|
+
success: true,
|
|
436
|
+
message: 'Use --help with the main CLI for full help text',
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
// Validate required arguments
|
|
440
|
+
if (!flags.log) {
|
|
441
|
+
return {
|
|
442
|
+
success: false,
|
|
443
|
+
message: 'Error: --log is required. Usage: originals-cel inspect --log <path>',
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
// Load the event log
|
|
447
|
+
let eventLog;
|
|
448
|
+
try {
|
|
449
|
+
eventLog = loadEventLog(flags.log);
|
|
450
|
+
}
|
|
451
|
+
catch (e) {
|
|
452
|
+
return {
|
|
453
|
+
success: false,
|
|
454
|
+
message: `Error: Failed to load event log: ${e.message}`,
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
// Derive current state
|
|
458
|
+
let state;
|
|
459
|
+
try {
|
|
460
|
+
state = deriveCurrentState(eventLog);
|
|
461
|
+
}
|
|
462
|
+
catch (e) {
|
|
463
|
+
return {
|
|
464
|
+
success: false,
|
|
465
|
+
message: `Error: Failed to derive state: ${e.message}`,
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
// Output the inspection
|
|
469
|
+
outputInspection(eventLog, state);
|
|
470
|
+
return {
|
|
471
|
+
success: true,
|
|
472
|
+
message: 'Inspection complete',
|
|
473
|
+
state,
|
|
474
|
+
};
|
|
475
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CLI Migrate Command
|
|
4
|
+
*
|
|
5
|
+
* Migrates a CEL asset between layers in the Originals Protocol.
|
|
6
|
+
*
|
|
7
|
+
* Migration paths:
|
|
8
|
+
* - peer ā webvh: Requires --domain
|
|
9
|
+
* - webvh ā btco: Requires --wallet
|
|
10
|
+
*
|
|
11
|
+
* Usage: originals-cel migrate --log <path> --to <layer> [options]
|
|
12
|
+
*/
|
|
13
|
+
import type { EventLog } from '../types';
|
|
14
|
+
/**
|
|
15
|
+
* Flags parsed from command line arguments
|
|
16
|
+
*/
|
|
17
|
+
export interface MigrateFlags {
|
|
18
|
+
log?: string;
|
|
19
|
+
to?: string;
|
|
20
|
+
domain?: string;
|
|
21
|
+
wallet?: string;
|
|
22
|
+
output?: string;
|
|
23
|
+
format?: string;
|
|
24
|
+
help?: boolean;
|
|
25
|
+
h?: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Result of the migrate command
|
|
29
|
+
*/
|
|
30
|
+
export interface MigrateResult {
|
|
31
|
+
success: boolean;
|
|
32
|
+
message: string;
|
|
33
|
+
log?: EventLog;
|
|
34
|
+
sourceDid?: string;
|
|
35
|
+
targetDid?: string;
|
|
36
|
+
targetLayer?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Execute the migrate command
|
|
40
|
+
*/
|
|
41
|
+
export declare function migrateCommand(flags: MigrateFlags): Promise<MigrateResult>;
|