@originals/sdk 1.4.2 → 1.4.3

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 (212) hide show
  1. package/package.json +4 -1
  2. package/.eslintrc.json +0 -33
  3. package/src/adapters/FeeOracleMock.ts +0 -9
  4. package/src/adapters/index.ts +0 -5
  5. package/src/adapters/providers/OrdHttpProvider.ts +0 -126
  6. package/src/adapters/providers/OrdMockProvider.ts +0 -101
  7. package/src/adapters/types.ts +0 -66
  8. package/src/bitcoin/BitcoinManager.ts +0 -330
  9. package/src/bitcoin/BroadcastClient.ts +0 -54
  10. package/src/bitcoin/OrdinalsClient.ts +0 -119
  11. package/src/bitcoin/PSBTBuilder.ts +0 -106
  12. package/src/bitcoin/fee-calculation.ts +0 -38
  13. package/src/bitcoin/providers/OrdNodeProvider.ts +0 -92
  14. package/src/bitcoin/providers/OrdinalsProvider.ts +0 -56
  15. package/src/bitcoin/providers/types.ts +0 -59
  16. package/src/bitcoin/transactions/commit.ts +0 -465
  17. package/src/bitcoin/transactions/index.ts +0 -13
  18. package/src/bitcoin/transfer.ts +0 -43
  19. package/src/bitcoin/utxo-selection.ts +0 -322
  20. package/src/bitcoin/utxo.ts +0 -113
  21. package/src/contexts/credentials-v1.json +0 -237
  22. package/src/contexts/credentials-v2-examples.json +0 -5
  23. package/src/contexts/credentials-v2.json +0 -340
  24. package/src/contexts/credentials.json +0 -237
  25. package/src/contexts/data-integrity-v2.json +0 -81
  26. package/src/contexts/dids.json +0 -58
  27. package/src/contexts/ed255192020.json +0 -93
  28. package/src/contexts/ordinals-plus.json +0 -23
  29. package/src/contexts/originals.json +0 -22
  30. package/src/core/OriginalsSDK.ts +0 -416
  31. package/src/crypto/Multikey.ts +0 -194
  32. package/src/crypto/Signer.ts +0 -254
  33. package/src/crypto/noble-init.ts +0 -121
  34. package/src/did/BtcoDidResolver.ts +0 -227
  35. package/src/did/DIDManager.ts +0 -694
  36. package/src/did/Ed25519Verifier.ts +0 -68
  37. package/src/did/KeyManager.ts +0 -236
  38. package/src/did/WebVHManager.ts +0 -498
  39. package/src/did/createBtcoDidDocument.ts +0 -59
  40. package/src/did/providers/OrdinalsClientProviderAdapter.ts +0 -68
  41. package/src/events/EventEmitter.ts +0 -222
  42. package/src/events/index.ts +0 -19
  43. package/src/events/types.ts +0 -331
  44. package/src/examples/basic-usage.ts +0 -78
  45. package/src/examples/create-module-original.ts +0 -435
  46. package/src/examples/full-lifecycle-flow.ts +0 -514
  47. package/src/examples/run.ts +0 -60
  48. package/src/index.ts +0 -150
  49. package/src/kinds/KindRegistry.ts +0 -290
  50. package/src/kinds/index.ts +0 -74
  51. package/src/kinds/types.ts +0 -470
  52. package/src/kinds/validators/AgentValidator.ts +0 -257
  53. package/src/kinds/validators/AppValidator.ts +0 -211
  54. package/src/kinds/validators/DatasetValidator.ts +0 -242
  55. package/src/kinds/validators/DocumentValidator.ts +0 -311
  56. package/src/kinds/validators/MediaValidator.ts +0 -269
  57. package/src/kinds/validators/ModuleValidator.ts +0 -225
  58. package/src/kinds/validators/base.ts +0 -276
  59. package/src/kinds/validators/index.ts +0 -12
  60. package/src/lifecycle/BatchOperations.ts +0 -373
  61. package/src/lifecycle/LifecycleManager.ts +0 -2126
  62. package/src/lifecycle/OriginalsAsset.ts +0 -524
  63. package/src/lifecycle/ProvenanceQuery.ts +0 -280
  64. package/src/lifecycle/ResourceVersioning.ts +0 -163
  65. package/src/migration/MigrationManager.ts +0 -527
  66. package/src/migration/audit/AuditLogger.ts +0 -176
  67. package/src/migration/checkpoint/CheckpointManager.ts +0 -112
  68. package/src/migration/checkpoint/CheckpointStorage.ts +0 -101
  69. package/src/migration/index.ts +0 -33
  70. package/src/migration/operations/BaseMigration.ts +0 -126
  71. package/src/migration/operations/PeerToBtcoMigration.ts +0 -105
  72. package/src/migration/operations/PeerToWebvhMigration.ts +0 -62
  73. package/src/migration/operations/WebvhToBtcoMigration.ts +0 -105
  74. package/src/migration/rollback/RollbackManager.ts +0 -170
  75. package/src/migration/state/StateMachine.ts +0 -92
  76. package/src/migration/state/StateTracker.ts +0 -156
  77. package/src/migration/types.ts +0 -344
  78. package/src/migration/validation/BitcoinValidator.ts +0 -107
  79. package/src/migration/validation/CredentialValidator.ts +0 -62
  80. package/src/migration/validation/DIDCompatibilityValidator.ts +0 -151
  81. package/src/migration/validation/LifecycleValidator.ts +0 -64
  82. package/src/migration/validation/StorageValidator.ts +0 -79
  83. package/src/migration/validation/ValidationPipeline.ts +0 -213
  84. package/src/resources/ResourceManager.ts +0 -655
  85. package/src/resources/index.ts +0 -21
  86. package/src/resources/types.ts +0 -202
  87. package/src/storage/LocalStorageAdapter.ts +0 -61
  88. package/src/storage/MemoryStorageAdapter.ts +0 -29
  89. package/src/storage/StorageAdapter.ts +0 -25
  90. package/src/storage/index.ts +0 -3
  91. package/src/types/bitcoin.ts +0 -98
  92. package/src/types/common.ts +0 -92
  93. package/src/types/credentials.ts +0 -88
  94. package/src/types/did.ts +0 -31
  95. package/src/types/external-shims.d.ts +0 -53
  96. package/src/types/index.ts +0 -7
  97. package/src/types/network.ts +0 -175
  98. package/src/utils/EventLogger.ts +0 -298
  99. package/src/utils/Logger.ts +0 -322
  100. package/src/utils/MetricsCollector.ts +0 -358
  101. package/src/utils/bitcoin-address.ts +0 -130
  102. package/src/utils/cbor.ts +0 -12
  103. package/src/utils/encoding.ts +0 -127
  104. package/src/utils/hash.ts +0 -6
  105. package/src/utils/retry.ts +0 -46
  106. package/src/utils/satoshi-validation.ts +0 -196
  107. package/src/utils/serialization.ts +0 -96
  108. package/src/utils/telemetry.ts +0 -40
  109. package/src/utils/validation.ts +0 -119
  110. package/src/vc/CredentialManager.ts +0 -918
  111. package/src/vc/Issuer.ts +0 -100
  112. package/src/vc/Verifier.ts +0 -47
  113. package/src/vc/cryptosuites/bbs.ts +0 -253
  114. package/src/vc/cryptosuites/bbsSimple.ts +0 -21
  115. package/src/vc/cryptosuites/eddsa.ts +0 -99
  116. package/src/vc/documentLoader.ts +0 -67
  117. package/src/vc/proofs/data-integrity.ts +0 -33
  118. package/src/vc/utils/jsonld.ts +0 -18
  119. package/tests/__mocks__/bbs-signatures.js +0 -17
  120. package/tests/__mocks__/mf-base58.js +0 -24
  121. package/tests/fixtures/did-documents.ts +0 -247
  122. package/tests/index.test.ts +0 -21
  123. package/tests/integration/BatchOperations.test.ts +0 -531
  124. package/tests/integration/CompleteLifecycle.e2e.test.ts +0 -735
  125. package/tests/integration/CredentialManager.test.ts +0 -42
  126. package/tests/integration/DIDManager.test.ts +0 -41
  127. package/tests/integration/DidPeerToWebVhFlow.test.ts +0 -351
  128. package/tests/integration/Events.test.ts +0 -435
  129. package/tests/integration/Lifecycle.transfer.btco.integration.test.ts +0 -25
  130. package/tests/integration/LifecycleManager.test.ts +0 -21
  131. package/tests/integration/MultikeyFlow.test.ts +0 -52
  132. package/tests/integration/TelemetryIntegration.test.ts +0 -395
  133. package/tests/integration/WebVhPublish.test.ts +0 -48
  134. package/tests/integration/createTypedOriginal.test.ts +0 -379
  135. package/tests/integration/migration/peer-to-webvh.test.ts +0 -172
  136. package/tests/manual/test-commit-creation.ts +0 -323
  137. package/tests/mocks/MockKeyStore.ts +0 -38
  138. package/tests/mocks/adapters/MemoryStorageAdapter.ts +0 -24
  139. package/tests/mocks/adapters/MockFeeOracle.ts +0 -11
  140. package/tests/mocks/adapters/MockOrdinalsProvider.ts +0 -76
  141. package/tests/mocks/adapters/OrdMockProvider.test.ts +0 -176
  142. package/tests/mocks/adapters/index.ts +0 -6
  143. package/tests/performance/BatchOperations.perf.test.ts +0 -403
  144. package/tests/performance/logging.perf.test.ts +0 -336
  145. package/tests/sdk.test.ts +0 -43
  146. package/tests/security/bitcoin-penetration-tests.test.ts +0 -622
  147. package/tests/setup.bun.ts +0 -69
  148. package/tests/setup.jest.ts +0 -23
  149. package/tests/stress/batch-operations-stress.test.ts +0 -571
  150. package/tests/unit/adapters/FeeOracleMock.test.ts +0 -40
  151. package/tests/unit/bitcoin/BitcoinManager.test.ts +0 -293
  152. package/tests/unit/bitcoin/BroadcastClient.test.ts +0 -52
  153. package/tests/unit/bitcoin/OrdNodeProvider.test.ts +0 -53
  154. package/tests/unit/bitcoin/OrdinalsClient.test.ts +0 -381
  155. package/tests/unit/bitcoin/OrdinalsClientProvider.test.ts +0 -102
  156. package/tests/unit/bitcoin/PSBTBuilder.test.ts +0 -84
  157. package/tests/unit/bitcoin/fee-calculation.test.ts +0 -261
  158. package/tests/unit/bitcoin/transactions/commit.test.ts +0 -649
  159. package/tests/unit/bitcoin/transfer.test.ts +0 -31
  160. package/tests/unit/bitcoin/utxo-selection-new.test.ts +0 -502
  161. package/tests/unit/bitcoin/utxo.more.test.ts +0 -39
  162. package/tests/unit/bitcoin/utxo.selection.test.ts +0 -38
  163. package/tests/unit/core/OriginalsSDK.test.ts +0 -152
  164. package/tests/unit/crypto/Multikey.test.ts +0 -206
  165. package/tests/unit/crypto/Signer.test.ts +0 -408
  166. package/tests/unit/did/BtcoDidResolver.test.ts +0 -611
  167. package/tests/unit/did/DIDManager.more.test.ts +0 -43
  168. package/tests/unit/did/DIDManager.test.ts +0 -185
  169. package/tests/unit/did/Ed25519Verifier.test.ts +0 -160
  170. package/tests/unit/did/KeyManager.test.ts +0 -452
  171. package/tests/unit/did/OrdinalsClientProviderAdapter.test.ts +0 -45
  172. package/tests/unit/did/WebVHManager.test.ts +0 -435
  173. package/tests/unit/did/createBtcoDidDocument.test.ts +0 -67
  174. package/tests/unit/did/providers/OrdinalsClientProviderAdapter.test.ts +0 -159
  175. package/tests/unit/events/EventEmitter.test.ts +0 -407
  176. package/tests/unit/kinds/KindRegistry.test.ts +0 -329
  177. package/tests/unit/kinds/types.test.ts +0 -409
  178. package/tests/unit/kinds/validators.test.ts +0 -651
  179. package/tests/unit/lifecycle/BatchOperations.test.ts +0 -527
  180. package/tests/unit/lifecycle/LifecycleManager.cleanapi.test.ts +0 -441
  181. package/tests/unit/lifecycle/LifecycleManager.keymanagement.test.ts +0 -312
  182. package/tests/unit/lifecycle/LifecycleManager.prov.test.ts +0 -18
  183. package/tests/unit/lifecycle/LifecycleManager.test.ts +0 -213
  184. package/tests/unit/lifecycle/LifecycleManager.transfer.unit.test.ts +0 -30
  185. package/tests/unit/lifecycle/OriginalsAsset.test.ts +0 -176
  186. package/tests/unit/lifecycle/ProvenanceQuery.test.ts +0 -577
  187. package/tests/unit/lifecycle/ResourceVersioning.test.ts +0 -651
  188. package/tests/unit/resources/ResourceManager.test.ts +0 -740
  189. package/tests/unit/storage/MemoryStorageAdapter.test.ts +0 -93
  190. package/tests/unit/types/network.test.ts +0 -255
  191. package/tests/unit/utils/EventIntegration.test.ts +0 -384
  192. package/tests/unit/utils/Logger.test.ts +0 -473
  193. package/tests/unit/utils/MetricsCollector.test.ts +0 -358
  194. package/tests/unit/utils/bitcoin-address.test.ts +0 -250
  195. package/tests/unit/utils/cbor.test.ts +0 -35
  196. package/tests/unit/utils/encoding.test.ts +0 -318
  197. package/tests/unit/utils/hash.test.ts +0 -12
  198. package/tests/unit/utils/retry.test.ts +0 -100
  199. package/tests/unit/utils/satoshi-validation.test.ts +0 -354
  200. package/tests/unit/utils/serialization.test.ts +0 -124
  201. package/tests/unit/utils/telemetry.test.ts +0 -52
  202. package/tests/unit/utils/validation.test.ts +0 -141
  203. package/tests/unit/vc/CredentialManager.helpers.test.ts +0 -527
  204. package/tests/unit/vc/CredentialManager.test.ts +0 -487
  205. package/tests/unit/vc/Issuer.test.ts +0 -107
  206. package/tests/unit/vc/Verifier.test.ts +0 -525
  207. package/tests/unit/vc/bbs.test.ts +0 -282
  208. package/tests/unit/vc/cryptosuites/eddsa.test.ts +0 -398
  209. package/tests/unit/vc/documentLoader.test.ts +0 -121
  210. package/tests/unit/vc/proofs/data-integrity.test.ts +0 -24
  211. package/tsconfig.json +0 -31
  212. package/tsconfig.test.json +0 -15
@@ -1,531 +0,0 @@
1
- /**
2
- * Integration tests for Batch Operations
3
- *
4
- * Tests the complete integration of batch operations with LifecycleManager,
5
- * including event emission, cost savings, and end-to-end workflows
6
- */
7
-
8
- import { describe, test, expect, beforeEach } from 'bun:test';
9
- import { OriginalsSDK } from '../../src/core/OriginalsSDK';
10
- import { OriginalsAsset } from '../../src/lifecycle/OriginalsAsset';
11
- import { AssetResource, OriginalsConfig } from '../../src/types';
12
- import { MemoryStorageAdapter } from '../../src/storage/MemoryStorageAdapter';
13
- import { FeeOracleMock } from '../../src/adapters/FeeOracleMock';
14
- import { OrdMockProvider } from '../../src/adapters/providers/OrdMockProvider';
15
- import { StorageAdapter as ConfigStorageAdapter } from '../../src/adapters/types';
16
- import { MockKeyStore } from '../mocks/MockKeyStore';
17
- import type { BatchResult } from '../../src/lifecycle/BatchOperations';
18
- import { KeyManager } from '../../src/did/KeyManager';
19
-
20
- function makeHash(prefix: string): string {
21
- const hexOnly = prefix.split('').map(c => {
22
- if (/[0-9a-f]/i.test(c)) return c;
23
- return c.charCodeAt(0).toString(16).slice(-1);
24
- }).join('');
25
- return hexOnly.padEnd(64, '0');
26
- }
27
-
28
- class StorageAdapterBridge implements ConfigStorageAdapter {
29
- constructor(private memoryAdapter: MemoryStorageAdapter) {}
30
-
31
- async put(objectKey: string, data: Buffer | string, options?: { contentType?: string }): Promise<string> {
32
- const firstSlash = objectKey.indexOf('/');
33
- const domain = firstSlash >= 0 ? objectKey.substring(0, firstSlash) : objectKey;
34
- const path = firstSlash >= 0 ? objectKey.substring(firstSlash + 1) : '';
35
- const content = typeof data === 'string' ? Buffer.from(data) : data;
36
- return await this.memoryAdapter.putObject(domain, path, new Uint8Array(content));
37
- }
38
-
39
- async get(objectKey: string): Promise<{ content: Buffer; contentType: string } | null> {
40
- const firstSlash = objectKey.indexOf('/');
41
- const domain = firstSlash >= 0 ? objectKey.substring(0, firstSlash) : objectKey;
42
- const path = firstSlash >= 0 ? objectKey.substring(firstSlash + 1) : '';
43
- const result = await this.memoryAdapter.getObject(domain, path);
44
- if (!result) return null;
45
- return {
46
- content: Buffer.from(result.content),
47
- contentType: result.contentType || 'application/octet-stream'
48
- };
49
- }
50
-
51
- async delete(objectKey: string): Promise<boolean> {
52
- return false;
53
- }
54
- }
55
-
56
- describe('Batch Operations Integration', () => {
57
- let sdk: OriginalsSDK;
58
- let memoryStorage: MemoryStorageAdapter;
59
- let feeOracle: FeeOracleMock;
60
- let ordinalsProvider: OrdMockProvider;
61
- let keyStore: MockKeyStore;
62
-
63
- beforeEach(async () => {
64
- memoryStorage = new MemoryStorageAdapter();
65
- const storageAdapter = new StorageAdapterBridge(memoryStorage);
66
- feeOracle = new FeeOracleMock(7);
67
- ordinalsProvider = new OrdMockProvider();
68
- keyStore = new MockKeyStore();
69
-
70
- const config: OriginalsConfig = {
71
- network: 'regtest',
72
- defaultKeyType: 'Ed25519', // Use Ed25519 for did:webvh compatibility
73
- enableLogging: false,
74
- storageAdapter,
75
- feeOracle,
76
- ordinalsProvider
77
- };
78
-
79
- sdk = new OriginalsSDK(config, keyStore);
80
-
81
- // Set up publisher DID keys for batch operation tests
82
- const keyManager = new KeyManager();
83
- const domains = ['example.com', 'test.com', 'batch.test'];
84
- for (const domain of domains) {
85
- const publisherKey = await keyManager.generateKeyPair('Ed25519');
86
- await keyStore.setPrivateKey(`did:webvh:${domain}:user#key-0`, publisherKey.privateKey);
87
- }
88
- });
89
-
90
- describe('batchCreateAssets', () => {
91
- test('should create multiple assets successfully', async () => {
92
- const resourcesList = [
93
- [
94
- { id: 'res1', type: 'image', contentType: 'image/png', hash: makeHash('img1'), content: 'image1' }
95
- ],
96
- [
97
- { id: 'res2', type: 'text', contentType: 'text/plain', hash: makeHash('txt1'), content: 'text1' }
98
- ],
99
- [
100
- { id: 'res3', type: 'data', contentType: 'application/json', hash: makeHash('json1'), content: '{"key":"value"}' }
101
- ]
102
- ];
103
-
104
- const result = await sdk.lifecycle.batchCreateAssets(resourcesList);
105
-
106
- expect(result.successful).toHaveLength(3);
107
- expect(result.failed).toHaveLength(0);
108
- expect(result.totalProcessed).toBe(3);
109
- expect(result.batchId).toBeDefined();
110
- expect(result.totalDuration).toBeGreaterThanOrEqual(0);
111
-
112
- // Verify each asset
113
- for (const item of result.successful) {
114
- expect(item.result).toBeInstanceOf(OriginalsAsset);
115
- expect(item.result.currentLayer).toBe('did:peer');
116
- expect(item.result.id).toMatch(/^did:peer:/);
117
- }
118
- });
119
-
120
- test('should handle validation errors', async () => {
121
- const invalidResourcesList = [
122
- [], // Empty resources
123
- [{ id: 'res1' }] // Missing required fields
124
- ];
125
-
126
- await expect(
127
- sdk.lifecycle.batchCreateAssets(invalidResourcesList as any)
128
- ).rejects.toThrow('Batch validation failed');
129
- });
130
-
131
- test('should continue on error when specified', async () => {
132
- const resourcesList = [
133
- [
134
- { id: 'res1', type: 'image', contentType: 'image/png', hash: makeHash('img1'), content: 'image1' }
135
- ],
136
- [], // This will fail validation at runtime
137
- [
138
- { id: 'res3', type: 'text', contentType: 'text/plain', hash: makeHash('txt1'), content: 'text1' }
139
- ]
140
- ];
141
-
142
- // Disable pre-validation to test runtime errors
143
- const result = await sdk.lifecycle.batchCreateAssets(resourcesList, {
144
- validateFirst: false,
145
- continueOnError: true
146
- });
147
-
148
- expect(result.successful.length).toBeGreaterThan(0);
149
- expect(result.failed.length).toBeGreaterThan(0);
150
- });
151
-
152
- test('should emit batch events', async () => {
153
- const events: any[] = [];
154
- const unsubscribe = sdk.lifecycle.on('batch:started', (event) => {
155
- events.push({ type: 'started', event });
156
- });
157
- sdk.lifecycle.on('batch:completed', (event) => {
158
- events.push({ type: 'completed', event });
159
- });
160
-
161
- const resourcesList = [
162
- [{ id: 'res1', type: 'image', contentType: 'image/png', hash: makeHash('img1'), content: 'image1' }]
163
- ];
164
-
165
- await sdk.lifecycle.batchCreateAssets(resourcesList);
166
-
167
- expect(events.length).toBeGreaterThanOrEqual(2);
168
- expect(events.find(e => e.type === 'started')).toBeDefined();
169
- expect(events.find(e => e.type === 'completed')).toBeDefined();
170
-
171
- const startedEvent = events.find(e => e.type === 'started').event;
172
- expect(startedEvent.operation).toBe('create');
173
- expect(startedEvent.itemCount).toBe(1);
174
-
175
- unsubscribe();
176
- });
177
- });
178
-
179
- describe('batchPublishToWeb', () => {
180
- test('should publish multiple assets successfully', async () => {
181
- // Create assets first
182
- const assets: OriginalsAsset[] = [];
183
- for (let i = 0; i < 3; i++) {
184
- const asset = await sdk.lifecycle.createAsset([
185
- { id: `res${i}`, type: 'text', contentType: 'text/plain', hash: makeHash(`txt${i}`), content: `text${i}` }
186
- ]);
187
- assets.push(asset);
188
- }
189
-
190
- const result = await sdk.lifecycle.batchPublishToWeb(assets, 'example.com');
191
-
192
- expect(result.successful).toHaveLength(3);
193
- expect(result.failed).toHaveLength(0);
194
-
195
- // Verify all assets are published
196
- for (const item of result.successful) {
197
- expect(item.result.currentLayer).toBe('did:webvh');
198
- expect(item.result.resources[0].url).toBeDefined();
199
- expect(item.result.resources[0].url).toMatch(/^did:webvh:/);
200
- }
201
- });
202
-
203
- test('should validate domain format', async () => {
204
- const asset = await sdk.lifecycle.createAsset([
205
- { id: 'res1', type: 'text', contentType: 'text/plain', hash: makeHash('txt1'), content: 'text1' }
206
- ]);
207
-
208
- await expect(
209
- sdk.lifecycle.batchPublishToWeb([asset], 'invalid domain!')
210
- ).rejects.toThrow('Invalid domain format');
211
- });
212
-
213
- test('should emit batch events for publishing', async () => {
214
- const events: any[] = [];
215
- sdk.lifecycle.on('batch:started', (event) => {
216
- events.push({ type: 'started', event });
217
- });
218
- sdk.lifecycle.on('batch:completed', (event) => {
219
- events.push({ type: 'completed', event });
220
- });
221
-
222
- const asset = await sdk.lifecycle.createAsset([
223
- { id: 'res1', type: 'text', contentType: 'text/plain', hash: makeHash('txt1'), content: 'text1' }
224
- ]);
225
-
226
- await sdk.lifecycle.batchPublishToWeb([asset], 'example.com');
227
-
228
- const startedEvent = events.find(e => e.type === 'started')?.event;
229
- expect(startedEvent.operation).toBe('publish');
230
- });
231
- });
232
-
233
- describe('batchInscribeOnBitcoin - Individual Transactions', () => {
234
- test('should inscribe multiple assets individually', async () => {
235
- const assets: OriginalsAsset[] = [];
236
- for (let i = 0; i < 3; i++) {
237
- const asset = await sdk.lifecycle.createAsset([
238
- { id: `res${i}`, type: 'text', contentType: 'text/plain', hash: makeHash(`txt${i}`), content: `text${i}` }
239
- ]);
240
- assets.push(asset);
241
- }
242
-
243
- const result = await sdk.lifecycle.batchInscribeOnBitcoin(assets, {
244
- singleTransaction: false,
245
- feeRate: 5
246
- });
247
-
248
- expect(result.successful).toHaveLength(3);
249
- expect(result.failed).toHaveLength(0);
250
-
251
- // Verify all assets are inscribed
252
- for (const item of result.successful) {
253
- expect(item.result.currentLayer).toBe('did:btco');
254
- const provenance = item.result.getProvenance();
255
- const latestMigration = provenance.migrations[provenance.migrations.length - 1];
256
- expect(latestMigration.transactionId).toBeDefined();
257
- expect(latestMigration.inscriptionId).toBeDefined();
258
- }
259
- });
260
- });
261
-
262
- describe('batchInscribeOnBitcoin - Single Transaction (Cost Savings)', () => {
263
- test('should inscribe multiple assets in single transaction', async () => {
264
- const assets: OriginalsAsset[] = [];
265
- for (let i = 0; i < 5; i++) {
266
- const asset = await sdk.lifecycle.createAsset([
267
- { id: `res${i}`, type: 'text', contentType: 'text/plain', hash: makeHash(`txt${i}`), content: `text${i}` }
268
- ]);
269
- assets.push(asset);
270
- }
271
-
272
- const result = await sdk.lifecycle.batchInscribeOnBitcoin(assets, {
273
- singleTransaction: true,
274
- feeRate: 10
275
- });
276
-
277
- expect(result.successful).toHaveLength(5);
278
- expect(result.failed).toHaveLength(0);
279
-
280
- // Verify all assets share the same batch transaction
281
- const batchIds = new Set<string>();
282
- const transactionIds = new Set<string>();
283
-
284
- for (const item of result.successful) {
285
- expect(item.result.currentLayer).toBe('did:btco');
286
- const provenance = item.result.getProvenance();
287
- const latestMigration = provenance.migrations[provenance.migrations.length - 1];
288
-
289
- expect((latestMigration as any).batchId).toBeDefined();
290
- expect((latestMigration as any).batchInscription).toBe(true);
291
- expect((latestMigration as any).feePaid).toBeDefined();
292
-
293
- batchIds.add((latestMigration as any).batchId);
294
- transactionIds.add(latestMigration.transactionId!);
295
- }
296
-
297
- // All assets should share the same batch ID and transaction ID
298
- expect(batchIds.size).toBe(1);
299
- expect(transactionIds.size).toBe(1);
300
- });
301
-
302
- test('should calculate cost savings correctly', async () => {
303
- const assets: OriginalsAsset[] = [];
304
- for (let i = 0; i < 10; i++) {
305
- const asset = await sdk.lifecycle.createAsset([
306
- { id: `res${i}`, type: 'text', contentType: 'text/plain', hash: makeHash(`txt${i}`), content: `text${i}` }
307
- ]);
308
- assets.push(asset);
309
- }
310
-
311
- // Track batch events to capture cost savings
312
- let costSavings: any = null;
313
- sdk.lifecycle.on('batch:completed', (event) => {
314
- if (event.results.costSavings) {
315
- costSavings = event.results.costSavings;
316
- }
317
- });
318
-
319
- await sdk.lifecycle.batchInscribeOnBitcoin(assets, {
320
- singleTransaction: true,
321
- feeRate: 10
322
- });
323
-
324
- expect(costSavings).toBeDefined();
325
- expect(costSavings.amount).toBeGreaterThan(0);
326
- expect(costSavings.percentage).toBeGreaterThan(0);
327
- // Should save at least 30% as per requirements
328
- expect(costSavings.percentage).toBeGreaterThanOrEqual(30);
329
- });
330
-
331
- test('should split fees proportionally by data size', async () => {
332
- // Create assets of different sizes
333
- const assets: OriginalsAsset[] = [];
334
-
335
- // Small asset
336
- assets.push(await sdk.lifecycle.createAsset([
337
- { id: 'small', type: 'text', contentType: 'text/plain', hash: makeHash('small'), content: 'x' }
338
- ]));
339
-
340
- // Large asset
341
- assets.push(await sdk.lifecycle.createAsset([
342
- { id: 'large', type: 'text', contentType: 'text/plain', hash: makeHash('large'), content: 'x'.repeat(1000) }
343
- ]));
344
-
345
- const result = await sdk.lifecycle.batchInscribeOnBitcoin(assets, {
346
- singleTransaction: true,
347
- feeRate: 10
348
- });
349
-
350
- const smallAssetFee = (result.successful[0].result.getProvenance().migrations[0] as any).feePaid;
351
- const largeAssetFee = (result.successful[1].result.getProvenance().migrations[0] as any).feePaid;
352
-
353
- // Large asset should pay more fees
354
- expect(largeAssetFee).toBeGreaterThan(smallAssetFee);
355
- });
356
-
357
- test('should handle atomic failure in single transaction mode', async () => {
358
- const assets: OriginalsAsset[] = [];
359
- for (let i = 0; i < 3; i++) {
360
- const asset = await sdk.lifecycle.createAsset([
361
- { id: `res${i}`, type: 'text', contentType: 'text/plain', hash: makeHash(`txt${i}`), content: `text${i}` }
362
- ]);
363
- assets.push(asset);
364
- }
365
-
366
- // Mock a failure scenario by using an invalid configuration
367
- // In single transaction mode, if the transaction fails, ALL assets should fail
368
- try {
369
- const result = await sdk.lifecycle.batchInscribeOnBitcoin(assets, {
370
- singleTransaction: true,
371
- feeRate: 10
372
- });
373
-
374
- // If it succeeds, all should succeed
375
- expect(result.failed).toHaveLength(0);
376
- } catch (error) {
377
- // If it fails, it should be a BatchError
378
- expect(error).toBeDefined();
379
- }
380
- });
381
- });
382
-
383
- describe('batchTransferOwnership', () => {
384
- test('should transfer multiple assets successfully', async () => {
385
- // Create and inscribe assets
386
- const assets: OriginalsAsset[] = [];
387
- for (let i = 0; i < 3; i++) {
388
- const asset = await sdk.lifecycle.createAsset([
389
- { id: `res${i}`, type: 'text', contentType: 'text/plain', hash: makeHash(`txt${i}`), content: `text${i}` }
390
- ]);
391
- const inscribed = await sdk.lifecycle.inscribeOnBitcoin(asset, 5);
392
- assets.push(inscribed);
393
- }
394
-
395
- const transfers = assets.map(asset => ({
396
- asset,
397
- to: 'tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx'
398
- }));
399
-
400
- const result = await sdk.lifecycle.batchTransferOwnership(transfers);
401
-
402
- expect(result.successful).toHaveLength(3);
403
- expect(result.failed).toHaveLength(0);
404
-
405
- // Verify all transfers
406
- for (let i = 0; i < assets.length; i++) {
407
- const provenance = assets[i].getProvenance();
408
- expect(provenance.transfers).toHaveLength(1);
409
- expect(provenance.transfers[0].to).toBe('tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx');
410
- }
411
- });
412
-
413
- test('should validate Bitcoin addresses', async () => {
414
- const asset = await sdk.lifecycle.createAsset([
415
- { id: 'res1', type: 'text', contentType: 'text/plain', hash: makeHash('txt1'), content: 'text1' }
416
- ]);
417
- const inscribed = await sdk.lifecycle.inscribeOnBitcoin(asset, 5);
418
-
419
- const transfers = [
420
- { asset: inscribed, to: 'invalid-address' }
421
- ];
422
-
423
- await expect(
424
- sdk.lifecycle.batchTransferOwnership(transfers)
425
- ).rejects.toThrow();
426
- });
427
-
428
- test('should validate assets are inscribed', async () => {
429
- const asset = await sdk.lifecycle.createAsset([
430
- { id: 'res1', type: 'text', contentType: 'text/plain', hash: makeHash('txt1'), content: 'text1' }
431
- ]);
432
-
433
- const transfers = [
434
- { asset, to: 'tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx' }
435
- ];
436
-
437
- await expect(
438
- sdk.lifecycle.batchTransferOwnership(transfers)
439
- ).rejects.toThrow('Batch validation failed');
440
- });
441
- });
442
-
443
- describe('Complete Batch Lifecycle', () => {
444
- test('should execute full lifecycle with batch operations', async () => {
445
- // Phase 1: Batch create
446
- const resourcesList = Array.from({ length: 5 }, (_, i) => [
447
- { id: `res${i}`, type: 'text', contentType: 'text/plain', hash: makeHash(`txt${i}`), content: `text${i}` }
448
- ]);
449
-
450
- const createResult = await sdk.lifecycle.batchCreateAssets(resourcesList);
451
- expect(createResult.successful).toHaveLength(5);
452
-
453
- const assets = createResult.successful.map(s => s.result);
454
-
455
- // Phase 2: Batch publish
456
- const publishResult = await sdk.lifecycle.batchPublishToWeb(assets, 'batch.test');
457
- expect(publishResult.successful).toHaveLength(5);
458
-
459
- const publishedAssets = publishResult.successful.map(s => s.result);
460
-
461
- // Phase 3: Batch inscribe with cost savings
462
- const inscribeResult = await sdk.lifecycle.batchInscribeOnBitcoin(publishedAssets, {
463
- singleTransaction: true,
464
- feeRate: 10
465
- });
466
- expect(inscribeResult.successful).toHaveLength(5);
467
-
468
- const inscribedAssets = inscribeResult.successful.map(s => s.result);
469
-
470
- // Phase 4: Batch transfer
471
- const transfers = inscribedAssets.map(asset => ({
472
- asset,
473
- to: 'tb1qw508d6qejxtdg4y5r3zarvary0c5xw7kxpjzsx'
474
- }));
475
-
476
- const transferResult = await sdk.lifecycle.batchTransferOwnership(transfers);
477
- expect(transferResult.successful).toHaveLength(5);
478
-
479
- // Verify complete provenance chain
480
- for (const asset of inscribedAssets) {
481
- const provenance = asset.getProvenance();
482
- expect(provenance.migrations).toHaveLength(2); // peer -> webvh -> btco
483
- expect(provenance.transfers).toHaveLength(1);
484
- expect(provenance.migrations[0].from).toBe('did:peer');
485
- expect(provenance.migrations[0].to).toBe('did:webvh');
486
- expect(provenance.migrations[1].from).toBe('did:webvh');
487
- expect(provenance.migrations[1].to).toBe('did:btco');
488
- }
489
- });
490
- });
491
-
492
- describe('Performance and Scalability', () => {
493
- test('should handle large batches efficiently', async () => {
494
- const resourcesList = Array.from({ length: 50 }, (_, i) => [
495
- { id: `res${i}`, type: 'text', contentType: 'text/plain', hash: makeHash(`txt${i}`), content: `text${i}` }
496
- ]);
497
-
498
- const startTime = Date.now();
499
- const result = await sdk.lifecycle.batchCreateAssets(resourcesList, {
500
- maxConcurrent: 5
501
- });
502
- const duration = Date.now() - startTime;
503
-
504
- expect(result.successful).toHaveLength(50);
505
- expect(result.totalDuration).toBeGreaterThanOrEqual(0);
506
-
507
- // With concurrency, should complete in reasonable time
508
- expect(duration).toBeLessThan(30000); // 30 seconds
509
- });
510
-
511
- test('should handle batch inscription of many assets', async () => {
512
- const assets: OriginalsAsset[] = [];
513
- for (let i = 0; i < 20; i++) {
514
- const asset = await sdk.lifecycle.createAsset([
515
- { id: `res${i}`, type: 'text', contentType: 'text/plain', hash: makeHash(`txt${i}`), content: `text${i}` }
516
- ]);
517
- assets.push(asset);
518
- }
519
-
520
- const startTime = Date.now();
521
- const result = await sdk.lifecycle.batchInscribeOnBitcoin(assets, {
522
- singleTransaction: true,
523
- feeRate: 10
524
- });
525
- const duration = Date.now() - startTime;
526
-
527
- expect(result.successful).toHaveLength(20);
528
- expect(duration).toBeLessThan(10000); // Should be fast with single transaction
529
- });
530
- });
531
- });