@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
package/dist/index.d.ts
CHANGED
|
@@ -40,4 +40,17 @@ export { sha256Bytes } from './utils/hash.js';
|
|
|
40
40
|
export { OrdMockProvider } from './adapters/providers/OrdMockProvider.js';
|
|
41
41
|
export { FeeOracleMock } from './adapters/FeeOracleMock.js';
|
|
42
42
|
export type { OrdinalsProvider, FeeOracleAdapter, StorageAdapter } from './adapters/types.js';
|
|
43
|
+
export { OriginalsCel, type CelLayer, type CelSigner, type OriginalsCelConfig, type OriginalsCelOptions, } from './cel/OriginalsCel.js';
|
|
44
|
+
export type { EventLog, LogEntry, EventType, DataIntegrityProof, WitnessProof, ExternalReference, VerificationResult, EventVerification, AssetState, CreateOptions, UpdateOptions, DeactivateOptions, VerifyOptions, } from './cel/types.js';
|
|
45
|
+
export { createEventLog, updateEventLog, deactivateEventLog, verifyEventLog, witnessEvent, } from './cel/algorithms/index.js';
|
|
46
|
+
export { computeDigestMultibase, verifyDigestMultibase, decodeDigestMultibase, } from './cel/hash.js';
|
|
47
|
+
export { createExternalReference, verifyExternalReference, } from './cel/ExternalReferenceManager.js';
|
|
48
|
+
export { PeerCelManager } from './cel/layers/PeerCelManager.js';
|
|
49
|
+
export { WebVHCelManager } from './cel/layers/WebVHCelManager.js';
|
|
50
|
+
export { BtcoCelManager } from './cel/layers/BtcoCelManager.js';
|
|
51
|
+
export type { WitnessService } from './cel/witnesses/WitnessService.js';
|
|
52
|
+
export { HttpWitness, HttpWitnessError } from './cel/witnesses/HttpWitness.js';
|
|
53
|
+
export { BitcoinWitness, BitcoinWitnessError, type BitcoinWitnessProof } from './cel/witnesses/BitcoinWitness.js';
|
|
54
|
+
export { serializeEventLogJson, parseEventLogJson, } from './cel/serialization/json.js';
|
|
55
|
+
export { serializeEventLogCbor, parseEventLogCbor, } from './cel/serialization/cbor.js';
|
|
43
56
|
export default OriginalsSDK;
|
package/dist/index.js
CHANGED
|
@@ -48,5 +48,17 @@ export { sha256Bytes } from './utils/hash.js';
|
|
|
48
48
|
// Adapter exports (for testing and custom integrations)
|
|
49
49
|
export { OrdMockProvider } from './adapters/providers/OrdMockProvider.js';
|
|
50
50
|
export { FeeOracleMock } from './adapters/FeeOracleMock.js';
|
|
51
|
+
// CEL (Cryptographic Event Log) exports
|
|
52
|
+
export { OriginalsCel, } from './cel/OriginalsCel.js';
|
|
53
|
+
export { createEventLog, updateEventLog, deactivateEventLog, verifyEventLog, witnessEvent, } from './cel/algorithms/index.js';
|
|
54
|
+
export { computeDigestMultibase, verifyDigestMultibase, decodeDigestMultibase, } from './cel/hash.js';
|
|
55
|
+
export { createExternalReference, verifyExternalReference, } from './cel/ExternalReferenceManager.js';
|
|
56
|
+
export { PeerCelManager } from './cel/layers/PeerCelManager.js';
|
|
57
|
+
export { WebVHCelManager } from './cel/layers/WebVHCelManager.js';
|
|
58
|
+
export { BtcoCelManager } from './cel/layers/BtcoCelManager.js';
|
|
59
|
+
export { HttpWitness, HttpWitnessError } from './cel/witnesses/HttpWitness.js';
|
|
60
|
+
export { BitcoinWitness, BitcoinWitnessError } from './cel/witnesses/BitcoinWitness.js';
|
|
61
|
+
export { serializeEventLogJson, parseEventLogJson, } from './cel/serialization/json.js';
|
|
62
|
+
export { serializeEventLogCbor, parseEventLogCbor, } from './cel/serialization/cbor.js';
|
|
51
63
|
// Default export
|
|
52
64
|
export default OriginalsSDK;
|
|
@@ -162,53 +162,83 @@ export class KindRegistry {
|
|
|
162
162
|
};
|
|
163
163
|
// Add kind-specific metadata templates
|
|
164
164
|
switch (kind) {
|
|
165
|
-
case OriginalKind.App:
|
|
165
|
+
case OriginalKind.App: {
|
|
166
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
167
|
+
const appMetadata = {
|
|
168
|
+
runtime: 'node',
|
|
169
|
+
entrypoint: 'index.js',
|
|
170
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
171
|
+
};
|
|
166
172
|
return {
|
|
167
173
|
...base,
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
174
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
175
|
+
metadata: appMetadata,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
case OriginalKind.Agent: {
|
|
179
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
180
|
+
const agentMetadata = {
|
|
181
|
+
capabilities: [],
|
|
182
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
172
183
|
};
|
|
173
|
-
case OriginalKind.Agent:
|
|
174
184
|
return {
|
|
175
185
|
...base,
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
186
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
187
|
+
metadata: agentMetadata,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
case OriginalKind.Module: {
|
|
191
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
192
|
+
const moduleMetadata = {
|
|
193
|
+
format: 'esm',
|
|
194
|
+
main: 'index.js',
|
|
195
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
179
196
|
};
|
|
180
|
-
case OriginalKind.Module:
|
|
181
197
|
return {
|
|
182
198
|
...base,
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
199
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
200
|
+
metadata: moduleMetadata,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
case OriginalKind.Dataset: {
|
|
204
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
205
|
+
const datasetMetadata = {
|
|
206
|
+
format: 'json',
|
|
207
|
+
schema: {},
|
|
208
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
187
209
|
};
|
|
188
|
-
case OriginalKind.Dataset:
|
|
189
210
|
return {
|
|
190
211
|
...base,
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
212
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
213
|
+
metadata: datasetMetadata,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
case OriginalKind.Media: {
|
|
217
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
218
|
+
const mediaMetadata = {
|
|
219
|
+
mediaType: 'image',
|
|
220
|
+
mimeType: 'image/png',
|
|
221
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
195
222
|
};
|
|
196
|
-
case OriginalKind.Media:
|
|
197
223
|
return {
|
|
198
224
|
...base,
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
225
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
226
|
+
metadata: mediaMetadata,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
case OriginalKind.Document: {
|
|
230
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
231
|
+
const documentMetadata = {
|
|
232
|
+
format: 'markdown',
|
|
233
|
+
content: 'content',
|
|
234
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
203
235
|
};
|
|
204
|
-
case OriginalKind.Document:
|
|
205
236
|
return {
|
|
206
237
|
...base,
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
content: 'content',
|
|
210
|
-
},
|
|
238
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
239
|
+
metadata: documentMetadata,
|
|
211
240
|
};
|
|
241
|
+
}
|
|
212
242
|
default:
|
|
213
243
|
return base;
|
|
214
244
|
}
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
* - Pre-validation of all items
|
|
9
9
|
* - Detailed timing and error tracking
|
|
10
10
|
*/
|
|
11
|
+
import type { AssetResource } from '../types';
|
|
12
|
+
import type { OriginalsAsset } from './OriginalsAsset';
|
|
11
13
|
/**
|
|
12
14
|
* Result of a batch operation containing successful and failed items
|
|
13
15
|
*/
|
|
@@ -132,16 +134,16 @@ export declare class BatchValidator {
|
|
|
132
134
|
/**
|
|
133
135
|
* Validate batch of resources for asset creation
|
|
134
136
|
*/
|
|
135
|
-
validateBatchCreate(resourcesList:
|
|
137
|
+
validateBatchCreate(resourcesList: AssetResource[][]): ValidationResult[];
|
|
136
138
|
/**
|
|
137
139
|
* Validate batch of assets for inscription
|
|
138
140
|
*/
|
|
139
|
-
validateBatchInscription(assets:
|
|
141
|
+
validateBatchInscription(assets: OriginalsAsset[]): ValidationResult[];
|
|
140
142
|
/**
|
|
141
143
|
* Validate batch of transfer operations
|
|
142
144
|
*/
|
|
143
145
|
validateBatchTransfer(transfers: Array<{
|
|
144
|
-
asset:
|
|
146
|
+
asset: OriginalsAsset;
|
|
145
147
|
to: string;
|
|
146
148
|
}>): ValidationResult[];
|
|
147
149
|
}
|
|
@@ -185,6 +185,7 @@ export class BatchValidator {
|
|
|
185
185
|
errors.push(`Item ${index}, resource ${i}: Invalid resource object`);
|
|
186
186
|
continue;
|
|
187
187
|
}
|
|
188
|
+
// AssetResource is properly typed, so we can access properties directly
|
|
188
189
|
if (!resource.id || typeof resource.id !== 'string') {
|
|
189
190
|
errors.push(`Item ${index}, resource ${i}: Missing or invalid id`);
|
|
190
191
|
}
|
|
@@ -214,13 +215,15 @@ export class BatchValidator {
|
|
|
214
215
|
if (!asset.id || typeof asset.id !== 'string') {
|
|
215
216
|
errors.push(`Item ${index}: Missing or invalid asset id`);
|
|
216
217
|
}
|
|
217
|
-
|
|
218
|
+
const currentLayer = asset.currentLayer;
|
|
219
|
+
if (!currentLayer) {
|
|
218
220
|
errors.push(`Item ${index}: Missing currentLayer`);
|
|
219
221
|
}
|
|
220
|
-
else if (
|
|
222
|
+
else if (currentLayer === 'did:btco') {
|
|
221
223
|
errors.push(`Item ${index}: Asset already inscribed on Bitcoin`);
|
|
222
224
|
}
|
|
223
|
-
|
|
225
|
+
const resources = asset.resources;
|
|
226
|
+
if (!resources || !Array.isArray(resources) || resources.length === 0) {
|
|
224
227
|
errors.push(`Item ${index}: Asset must have at least one resource`);
|
|
225
228
|
}
|
|
226
229
|
return { isValid: errors.length === 0, errors };
|
|
@@ -239,8 +242,11 @@ export class BatchValidator {
|
|
|
239
242
|
if (!transfer.asset || typeof transfer.asset !== 'object') {
|
|
240
243
|
errors.push(`Item ${index}: Invalid asset`);
|
|
241
244
|
}
|
|
242
|
-
else
|
|
243
|
-
|
|
245
|
+
else {
|
|
246
|
+
const currentLayer = transfer.asset.currentLayer;
|
|
247
|
+
if (currentLayer !== 'did:btco') {
|
|
248
|
+
errors.push(`Item ${index}: Asset must be inscribed on Bitcoin before transfer`);
|
|
249
|
+
}
|
|
244
250
|
}
|
|
245
251
|
if (!transfer.to || typeof transfer.to !== 'string') {
|
|
246
252
|
errors.push(`Item ${index}: Invalid destination address`);
|
|
@@ -358,5 +358,5 @@ export declare class LifecycleManager {
|
|
|
358
358
|
* }
|
|
359
359
|
* ```
|
|
360
360
|
*/
|
|
361
|
-
validateMigration(asset: OriginalsAsset, targetLayer: LayerType):
|
|
361
|
+
validateMigration(asset: OriginalsAsset, targetLayer: LayerType): MigrationValidation;
|
|
362
362
|
}
|
|
@@ -131,8 +131,8 @@ export class LifecycleManager {
|
|
|
131
131
|
}
|
|
132
132
|
};
|
|
133
133
|
// Emit from both LifecycleManager and asset emitters
|
|
134
|
-
this.eventEmitter.emit(event);
|
|
135
|
-
asset.eventEmitter.emit(event);
|
|
134
|
+
void this.eventEmitter.emit(event);
|
|
135
|
+
void asset.eventEmitter.emit(event);
|
|
136
136
|
});
|
|
137
137
|
stopTimer();
|
|
138
138
|
this.logger.info('Asset created successfully', { assetId: asset.id });
|
|
@@ -156,8 +156,8 @@ export class LifecycleManager {
|
|
|
156
156
|
}
|
|
157
157
|
};
|
|
158
158
|
// Emit from both LifecycleManager and asset emitters
|
|
159
|
-
this.eventEmitter.emit(event);
|
|
160
|
-
asset.eventEmitter.emit(event);
|
|
159
|
+
void this.eventEmitter.emit(event);
|
|
160
|
+
void asset.eventEmitter.emit(event);
|
|
161
161
|
});
|
|
162
162
|
stopTimer();
|
|
163
163
|
this.logger.info('Asset created successfully', { assetId: asset.id });
|
|
@@ -249,7 +249,7 @@ export class LifecycleManager {
|
|
|
249
249
|
}
|
|
250
250
|
};
|
|
251
251
|
// Emit from LifecycleManager
|
|
252
|
-
this.eventEmitter.emit(event);
|
|
252
|
+
void this.eventEmitter.emit(event);
|
|
253
253
|
});
|
|
254
254
|
stopTimer();
|
|
255
255
|
this.logger.info('Typed Original created successfully', {
|
|
@@ -387,7 +387,7 @@ export class LifecycleManager {
|
|
|
387
387
|
if (asset.currentLayer !== 'did:peer') {
|
|
388
388
|
throw new Error('Asset must be in did:peer layer to publish to web');
|
|
389
389
|
}
|
|
390
|
-
const { publisherDid, signer } =
|
|
390
|
+
const { publisherDid, signer } = this.extractPublisherInfo(publisherDidOrSigner);
|
|
391
391
|
const { domain, userPath } = this.parseWebVHDid(publisherDid);
|
|
392
392
|
this.logger.info('Publishing asset to web', { assetId: asset.id, publisherDid });
|
|
393
393
|
// Publish resources to storage
|
|
@@ -396,7 +396,7 @@ export class LifecycleManager {
|
|
|
396
396
|
const originalPeerDid = asset.id;
|
|
397
397
|
// Migrate asset to did:webvh layer
|
|
398
398
|
await asset.migrate('did:webvh');
|
|
399
|
-
asset.bindings = { ...asset.bindings, 'did:peer': originalPeerDid, 'did:webvh': publisherDid };
|
|
399
|
+
asset.bindings = { ...(asset.bindings || {}), 'did:peer': originalPeerDid, 'did:webvh': publisherDid };
|
|
400
400
|
// Issue publication credential (best-effort)
|
|
401
401
|
await this.issuePublicationCredential(asset, publisherDid, signer);
|
|
402
402
|
stopTimer();
|
|
@@ -415,7 +415,7 @@ export class LifecycleManager {
|
|
|
415
415
|
throw error;
|
|
416
416
|
}
|
|
417
417
|
}
|
|
418
|
-
|
|
418
|
+
extractPublisherInfo(publisherDidOrSigner) {
|
|
419
419
|
if (typeof publisherDidOrSigner === 'string') {
|
|
420
420
|
// If it's already a did:webvh DID, use it as-is
|
|
421
421
|
if (publisherDidOrSigner.startsWith('did:webvh:')) {
|
|
@@ -430,8 +430,8 @@ export class LifecycleManager {
|
|
|
430
430
|
return { publisherDid };
|
|
431
431
|
}
|
|
432
432
|
const signer = publisherDidOrSigner;
|
|
433
|
-
const
|
|
434
|
-
const publisherDid =
|
|
433
|
+
const resolvedVmId = signer.getVerificationMethodId();
|
|
434
|
+
const publisherDid = resolvedVmId.includes('#') ? resolvedVmId.split('#')[0] : resolvedVmId;
|
|
435
435
|
if (!publisherDid.startsWith('did:webvh:')) {
|
|
436
436
|
throw new Error('Signer must be associated with a did:webvh identifier');
|
|
437
437
|
}
|
|
@@ -457,12 +457,14 @@ export class LifecycleManager {
|
|
|
457
457
|
const data = resource.content
|
|
458
458
|
? Buffer.from(resource.content)
|
|
459
459
|
: Buffer.from(resource.hash);
|
|
460
|
-
|
|
461
|
-
|
|
460
|
+
const storageWithPut = storage;
|
|
461
|
+
const storageWithPutObject = storage;
|
|
462
|
+
if (typeof storageWithPut.put === 'function') {
|
|
463
|
+
await storageWithPut.put(`${domain}/${relativePath}`, data, { contentType: resource.contentType });
|
|
462
464
|
}
|
|
463
|
-
else {
|
|
465
|
+
else if (typeof storageWithPutObject.putObject === 'function') {
|
|
464
466
|
const encoded = new TextEncoder().encode(resource.content || resource.hash);
|
|
465
|
-
await
|
|
467
|
+
await storageWithPutObject.putObject(domain, relativePath, encoded);
|
|
466
468
|
}
|
|
467
469
|
resource.url = resourceUrl;
|
|
468
470
|
await this.emitResourcePublishedEvent(asset, resource, resourceUrl, publisherDid, domain);
|
|
@@ -501,7 +503,7 @@ export class LifecycleManager {
|
|
|
501
503
|
toLayer: 'did:webvh',
|
|
502
504
|
migratedAt: new Date().toISOString()
|
|
503
505
|
};
|
|
504
|
-
const unsigned =
|
|
506
|
+
const unsigned = this.credentialManager.createResourceCredential('ResourceMigrated', subject, publisherDid);
|
|
505
507
|
const signed = signer
|
|
506
508
|
? await this.credentialManager.signCredentialWithExternalSigner(unsigned, signer)
|
|
507
509
|
: await this.signWithKeyStore(unsigned, publisherDid);
|
|
@@ -545,8 +547,9 @@ export class LifecycleManager {
|
|
|
545
547
|
}
|
|
546
548
|
}
|
|
547
549
|
// If not found, try to find ANY key that starts with the issuer DID
|
|
548
|
-
|
|
549
|
-
|
|
550
|
+
const keyStoreWithGetAll = this.keyStore;
|
|
551
|
+
if (!privateKey && typeof keyStoreWithGetAll.getAllVerificationMethodIds === 'function') {
|
|
552
|
+
const allVmIds = keyStoreWithGetAll.getAllVerificationMethodIds();
|
|
550
553
|
for (const testVmId of allVmIds) {
|
|
551
554
|
if (testVmId.startsWith(issuer)) {
|
|
552
555
|
const key = await this.keyStore.getPrivateKey(testVmId);
|
|
@@ -573,6 +576,9 @@ export class LifecycleManager {
|
|
|
573
576
|
throw new Error('Private key not found in keyStore');
|
|
574
577
|
}
|
|
575
578
|
}
|
|
579
|
+
if (!vmId) {
|
|
580
|
+
throw new Error('Verification method ID could not be determined');
|
|
581
|
+
}
|
|
576
582
|
return this.credentialManager.signCredential(credential, privateKey, vmId);
|
|
577
583
|
}
|
|
578
584
|
async inscribeOnBitcoin(asset, feeRate) {
|
|
@@ -621,7 +627,7 @@ export class LifecycleManager {
|
|
|
621
627
|
const bindingValue = inscription.satoshi
|
|
622
628
|
? `did:btco:${inscription.satoshi}`
|
|
623
629
|
: `did:btco:${inscription.inscriptionId}`;
|
|
624
|
-
asset.bindings = Object.assign({}, asset.bindings, { 'did:btco': bindingValue });
|
|
630
|
+
asset.bindings = Object.assign({}, asset.bindings || {}, { 'did:btco': bindingValue });
|
|
625
631
|
stopTimer();
|
|
626
632
|
this.logger.info('Asset inscribed on Bitcoin successfully', {
|
|
627
633
|
assetId: asset.id,
|
|
@@ -674,6 +680,7 @@ export class LifecycleManager {
|
|
|
674
680
|
txid: latestMigration?.transactionId ?? 'unknown-tx',
|
|
675
681
|
vout: 0
|
|
676
682
|
};
|
|
683
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
677
684
|
const tx = await bm.transferInscription(inscription, newOwner);
|
|
678
685
|
await asset.recordTransfer(asset.id, newOwner, tx.txid);
|
|
679
686
|
stopTimer();
|
|
@@ -720,7 +727,7 @@ export class LifecycleManager {
|
|
|
720
727
|
});
|
|
721
728
|
try {
|
|
722
729
|
// Use batch executor to process all asset creations
|
|
723
|
-
const result = await this.batchExecutor.execute(resourcesList, async (resources,
|
|
730
|
+
const result = await this.batchExecutor.execute(resourcesList, async (resources, _index) => {
|
|
724
731
|
const asset = await this.createAsset(resources);
|
|
725
732
|
return asset;
|
|
726
733
|
}, options, batchId // Pass the pre-generated batchId for event correlation
|
|
@@ -792,7 +799,7 @@ export class LifecycleManager {
|
|
|
792
799
|
itemCount: assets.length
|
|
793
800
|
});
|
|
794
801
|
try {
|
|
795
|
-
const result = await this.batchExecutor.execute(assets, async (asset,
|
|
802
|
+
const result = await this.batchExecutor.execute(assets, async (asset, _index) => {
|
|
796
803
|
return await this.publishToWeb(asset, domain);
|
|
797
804
|
}, options, batchId // Pass the pre-generated batchId for event correlation
|
|
798
805
|
);
|
|
@@ -871,7 +878,7 @@ export class LifecycleManager {
|
|
|
871
878
|
// Calculate total data size for all assets
|
|
872
879
|
const totalDataSize = this.calculateTotalDataSize(assets);
|
|
873
880
|
// Estimate savings from batch inscription
|
|
874
|
-
const estimatedSavings =
|
|
881
|
+
const estimatedSavings = this.estimateBatchSavings(assets, options?.feeRate);
|
|
875
882
|
// Create manifests for all assets
|
|
876
883
|
const manifests = assets.map(asset => ({
|
|
877
884
|
assetId: asset.id,
|
|
@@ -913,7 +920,8 @@ export class LifecycleManager {
|
|
|
913
920
|
const contentSize = asset.resources.reduce((sum, r) => {
|
|
914
921
|
const content = r.content;
|
|
915
922
|
if (content) {
|
|
916
|
-
|
|
923
|
+
const length = typeof content === 'string' ? Buffer.byteLength(content) : content.length;
|
|
924
|
+
return sum + (length || 0);
|
|
917
925
|
}
|
|
918
926
|
return sum;
|
|
919
927
|
}, 0);
|
|
@@ -947,14 +955,15 @@ export class LifecycleManager {
|
|
|
947
955
|
// Add batch metadata to provenance
|
|
948
956
|
const provenance = asset.getProvenance();
|
|
949
957
|
const latestMigration = provenance.migrations[provenance.migrations.length - 1];
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
958
|
+
const migrationWithBatchData = latestMigration;
|
|
959
|
+
migrationWithBatchData.batchId = batchId;
|
|
960
|
+
migrationWithBatchData.batchInscription = true;
|
|
961
|
+
migrationWithBatchData.batchIndex = i; // Store index as metadata
|
|
962
|
+
migrationWithBatchData.feePaid = feePerAsset[i];
|
|
954
963
|
const bindingValue = inscription.satoshi
|
|
955
964
|
? `did:btco:${inscription.satoshi}`
|
|
956
965
|
: `did:btco:${individualInscriptionId}`;
|
|
957
|
-
asset.bindings = Object.assign({}, asset.bindings, { 'did:btco': bindingValue });
|
|
966
|
+
asset.bindings = Object.assign({}, asset.bindings || {}, { 'did:btco': bindingValue });
|
|
958
967
|
successful.push({
|
|
959
968
|
index: i,
|
|
960
969
|
result: asset,
|
|
@@ -1020,7 +1029,7 @@ export class LifecycleManager {
|
|
|
1020
1029
|
itemCount: assets.length
|
|
1021
1030
|
});
|
|
1022
1031
|
try {
|
|
1023
|
-
const result = await this.batchExecutor.execute(assets, async (asset,
|
|
1032
|
+
const result = await this.batchExecutor.execute(assets, async (asset, _index) => {
|
|
1024
1033
|
return await this.inscribeOnBitcoin(asset, options?.feeRate);
|
|
1025
1034
|
}, options, batchId // Pass the pre-generated batchId for event correlation
|
|
1026
1035
|
);
|
|
@@ -1087,7 +1096,7 @@ export class LifecycleManager {
|
|
|
1087
1096
|
itemCount: transfers.length
|
|
1088
1097
|
});
|
|
1089
1098
|
try {
|
|
1090
|
-
const result = await this.batchExecutor.execute(transfers, async (transfer,
|
|
1099
|
+
const result = await this.batchExecutor.execute(transfers, async (transfer, _index) => {
|
|
1091
1100
|
return await this.transferOwnership(transfer.asset, transfer.to);
|
|
1092
1101
|
}, options, batchId // Pass the pre-generated batchId for event correlation
|
|
1093
1102
|
);
|
|
@@ -1138,7 +1147,7 @@ export class LifecycleManager {
|
|
|
1138
1147
|
/**
|
|
1139
1148
|
* Estimate cost savings from batch inscription vs individual inscriptions
|
|
1140
1149
|
*/
|
|
1141
|
-
|
|
1150
|
+
estimateBatchSavings(assets, feeRate) {
|
|
1142
1151
|
// Calculate total size for batch
|
|
1143
1152
|
const batchSize = this.calculateTotalDataSize(assets);
|
|
1144
1153
|
// Estimate individual sizes
|
|
@@ -1264,7 +1273,7 @@ export class LifecycleManager {
|
|
|
1264
1273
|
message: 'Validating migration...'
|
|
1265
1274
|
});
|
|
1266
1275
|
// Pre-flight validation
|
|
1267
|
-
const validation =
|
|
1276
|
+
const validation = this.validateMigration(asset, 'did:webvh');
|
|
1268
1277
|
if (!validation.valid) {
|
|
1269
1278
|
onProgress?.({
|
|
1270
1279
|
phase: 'failed',
|
|
@@ -1333,7 +1342,7 @@ export class LifecycleManager {
|
|
|
1333
1342
|
message: 'Validating migration...'
|
|
1334
1343
|
});
|
|
1335
1344
|
// Pre-flight validation
|
|
1336
|
-
const validation =
|
|
1345
|
+
const validation = this.validateMigration(asset, 'did:btco');
|
|
1337
1346
|
if (!validation.valid) {
|
|
1338
1347
|
onProgress?.({
|
|
1339
1348
|
phase: 'failed',
|
|
@@ -1598,7 +1607,7 @@ export class LifecycleManager {
|
|
|
1598
1607
|
* }
|
|
1599
1608
|
* ```
|
|
1600
1609
|
*/
|
|
1601
|
-
|
|
1610
|
+
validateMigration(asset, targetLayer) {
|
|
1602
1611
|
const errors = [];
|
|
1603
1612
|
const warnings = [];
|
|
1604
1613
|
const checks = {
|
|
@@ -28,7 +28,7 @@ export class OriginalsAsset {
|
|
|
28
28
|
resourcesByIdMap.set(resource.id, existing);
|
|
29
29
|
}
|
|
30
30
|
// Process each resource ID's versions in sorted order
|
|
31
|
-
for (const
|
|
31
|
+
for (const resourceVersions of resourcesByIdMap.values()) {
|
|
32
32
|
// Sort by version number (ascending)
|
|
33
33
|
const sorted = resourceVersions.sort((a, b) => {
|
|
34
34
|
const versionA = a.version || 1;
|
|
@@ -336,7 +336,7 @@ export class OriginalsAsset {
|
|
|
336
336
|
};
|
|
337
337
|
// Emit asynchronously (don't block)
|
|
338
338
|
queueMicrotask(() => {
|
|
339
|
-
this.eventEmitter.emit(event);
|
|
339
|
+
void this.eventEmitter.emit(event);
|
|
340
340
|
});
|
|
341
341
|
return newResource;
|
|
342
342
|
}
|