@originals/sdk 1.2.0 → 1.4.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.
Files changed (244) hide show
  1. package/package.json +1 -1
  2. package/src/did/DIDManager.ts +1 -1
  3. package/src/did/WebVHManager.ts +11 -2
  4. package/src/examples/create-module-original.ts +435 -0
  5. package/src/examples/full-lifecycle-flow.ts +514 -0
  6. package/src/examples/run.ts +59 -4
  7. package/src/index.ts +69 -3
  8. package/src/kinds/KindRegistry.ts +290 -0
  9. package/src/kinds/index.ts +74 -0
  10. package/src/kinds/types.ts +470 -0
  11. package/src/kinds/validators/AgentValidator.ts +257 -0
  12. package/src/kinds/validators/AppValidator.ts +211 -0
  13. package/src/kinds/validators/DatasetValidator.ts +242 -0
  14. package/src/kinds/validators/DocumentValidator.ts +311 -0
  15. package/src/kinds/validators/MediaValidator.ts +269 -0
  16. package/src/kinds/validators/ModuleValidator.ts +225 -0
  17. package/src/kinds/validators/base.ts +276 -0
  18. package/src/kinds/validators/index.ts +12 -0
  19. package/src/lifecycle/LifecycleManager.ts +909 -1
  20. package/src/resources/ResourceManager.ts +655 -0
  21. package/src/resources/index.ts +21 -0
  22. package/src/resources/types.ts +202 -0
  23. package/src/types/common.ts +1 -1
  24. package/src/vc/CredentialManager.ts +647 -2
  25. package/tests/integration/createTypedOriginal.test.ts +379 -0
  26. package/tests/performance/BatchOperations.perf.test.ts +2 -2
  27. package/tests/unit/kinds/KindRegistry.test.ts +329 -0
  28. package/tests/unit/kinds/types.test.ts +409 -0
  29. package/tests/unit/kinds/validators.test.ts +651 -0
  30. package/tests/unit/lifecycle/LifecycleManager.cleanapi.test.ts +441 -0
  31. package/tests/unit/resources/ResourceManager.test.ts +740 -0
  32. package/tests/unit/vc/CredentialManager.helpers.test.ts +527 -0
  33. package/.turbo/turbo-build.log +0 -1
  34. package/dist/adapters/FeeOracleMock.d.ts +0 -6
  35. package/dist/adapters/FeeOracleMock.js +0 -8
  36. package/dist/adapters/index.d.ts +0 -4
  37. package/dist/adapters/index.js +0 -4
  38. package/dist/adapters/providers/OrdHttpProvider.d.ts +0 -56
  39. package/dist/adapters/providers/OrdHttpProvider.js +0 -110
  40. package/dist/adapters/providers/OrdMockProvider.d.ts +0 -70
  41. package/dist/adapters/providers/OrdMockProvider.js +0 -75
  42. package/dist/adapters/types.d.ts +0 -71
  43. package/dist/adapters/types.js +0 -1
  44. package/dist/bitcoin/BitcoinManager.d.ts +0 -15
  45. package/dist/bitcoin/BitcoinManager.js +0 -262
  46. package/dist/bitcoin/BroadcastClient.d.ts +0 -30
  47. package/dist/bitcoin/BroadcastClient.js +0 -35
  48. package/dist/bitcoin/OrdinalsClient.d.ts +0 -21
  49. package/dist/bitcoin/OrdinalsClient.js +0 -105
  50. package/dist/bitcoin/PSBTBuilder.d.ts +0 -24
  51. package/dist/bitcoin/PSBTBuilder.js +0 -80
  52. package/dist/bitcoin/fee-calculation.d.ts +0 -14
  53. package/dist/bitcoin/fee-calculation.js +0 -31
  54. package/dist/bitcoin/providers/OrdNodeProvider.d.ts +0 -38
  55. package/dist/bitcoin/providers/OrdNodeProvider.js +0 -67
  56. package/dist/bitcoin/providers/OrdinalsProvider.d.ts +0 -33
  57. package/dist/bitcoin/providers/OrdinalsProvider.js +0 -50
  58. package/dist/bitcoin/providers/types.d.ts +0 -63
  59. package/dist/bitcoin/providers/types.js +0 -1
  60. package/dist/bitcoin/transactions/commit.d.ts +0 -89
  61. package/dist/bitcoin/transactions/commit.js +0 -311
  62. package/dist/bitcoin/transactions/index.d.ts +0 -7
  63. package/dist/bitcoin/transactions/index.js +0 -8
  64. package/dist/bitcoin/transfer.d.ts +0 -9
  65. package/dist/bitcoin/transfer.js +0 -26
  66. package/dist/bitcoin/utxo-selection.d.ts +0 -78
  67. package/dist/bitcoin/utxo-selection.js +0 -237
  68. package/dist/bitcoin/utxo.d.ts +0 -26
  69. package/dist/bitcoin/utxo.js +0 -78
  70. package/dist/contexts/credentials-v1.json +0 -195
  71. package/dist/contexts/credentials-v2-examples.json +0 -5
  72. package/dist/contexts/credentials-v2.json +0 -301
  73. package/dist/contexts/credentials.json +0 -195
  74. package/dist/contexts/data-integrity-v2.json +0 -81
  75. package/dist/contexts/dids.json +0 -57
  76. package/dist/contexts/ed255192020.json +0 -93
  77. package/dist/contexts/ordinals-plus.json +0 -23
  78. package/dist/contexts/originals.json +0 -22
  79. package/dist/core/OriginalsSDK.d.ts +0 -158
  80. package/dist/core/OriginalsSDK.js +0 -274
  81. package/dist/crypto/Multikey.d.ts +0 -30
  82. package/dist/crypto/Multikey.js +0 -149
  83. package/dist/crypto/Signer.d.ts +0 -21
  84. package/dist/crypto/Signer.js +0 -196
  85. package/dist/crypto/noble-init.d.ts +0 -18
  86. package/dist/crypto/noble-init.js +0 -106
  87. package/dist/did/BtcoDidResolver.d.ts +0 -57
  88. package/dist/did/BtcoDidResolver.js +0 -166
  89. package/dist/did/DIDManager.d.ts +0 -101
  90. package/dist/did/DIDManager.js +0 -493
  91. package/dist/did/Ed25519Verifier.d.ts +0 -30
  92. package/dist/did/Ed25519Verifier.js +0 -59
  93. package/dist/did/KeyManager.d.ts +0 -17
  94. package/dist/did/KeyManager.js +0 -207
  95. package/dist/did/WebVHManager.d.ts +0 -100
  96. package/dist/did/WebVHManager.js +0 -304
  97. package/dist/did/createBtcoDidDocument.d.ts +0 -10
  98. package/dist/did/createBtcoDidDocument.js +0 -42
  99. package/dist/did/providers/OrdinalsClientProviderAdapter.d.ts +0 -23
  100. package/dist/did/providers/OrdinalsClientProviderAdapter.js +0 -51
  101. package/dist/events/EventEmitter.d.ts +0 -115
  102. package/dist/events/EventEmitter.js +0 -198
  103. package/dist/events/index.d.ts +0 -7
  104. package/dist/events/index.js +0 -6
  105. package/dist/events/types.d.ts +0 -286
  106. package/dist/events/types.js +0 -9
  107. package/dist/examples/basic-usage.d.ts +0 -3
  108. package/dist/examples/basic-usage.js +0 -62
  109. package/dist/examples/run.d.ts +0 -1
  110. package/dist/examples/run.js +0 -4
  111. package/dist/index.d.ts +0 -39
  112. package/dist/index.js +0 -47
  113. package/dist/lifecycle/BatchOperations.d.ts +0 -147
  114. package/dist/lifecycle/BatchOperations.js +0 -251
  115. package/dist/lifecycle/LifecycleManager.d.ts +0 -116
  116. package/dist/lifecycle/LifecycleManager.js +0 -971
  117. package/dist/lifecycle/OriginalsAsset.d.ts +0 -164
  118. package/dist/lifecycle/OriginalsAsset.js +0 -380
  119. package/dist/lifecycle/ProvenanceQuery.d.ts +0 -126
  120. package/dist/lifecycle/ProvenanceQuery.js +0 -220
  121. package/dist/lifecycle/ResourceVersioning.d.ts +0 -73
  122. package/dist/lifecycle/ResourceVersioning.js +0 -127
  123. package/dist/migration/MigrationManager.d.ts +0 -86
  124. package/dist/migration/MigrationManager.js +0 -412
  125. package/dist/migration/audit/AuditLogger.d.ts +0 -51
  126. package/dist/migration/audit/AuditLogger.js +0 -156
  127. package/dist/migration/checkpoint/CheckpointManager.d.ts +0 -31
  128. package/dist/migration/checkpoint/CheckpointManager.js +0 -96
  129. package/dist/migration/checkpoint/CheckpointStorage.d.ts +0 -26
  130. package/dist/migration/checkpoint/CheckpointStorage.js +0 -89
  131. package/dist/migration/index.d.ts +0 -22
  132. package/dist/migration/index.js +0 -27
  133. package/dist/migration/operations/BaseMigration.d.ts +0 -48
  134. package/dist/migration/operations/BaseMigration.js +0 -83
  135. package/dist/migration/operations/PeerToBtcoMigration.d.ts +0 -25
  136. package/dist/migration/operations/PeerToBtcoMigration.js +0 -67
  137. package/dist/migration/operations/PeerToWebvhMigration.d.ts +0 -19
  138. package/dist/migration/operations/PeerToWebvhMigration.js +0 -46
  139. package/dist/migration/operations/WebvhToBtcoMigration.d.ts +0 -25
  140. package/dist/migration/operations/WebvhToBtcoMigration.js +0 -67
  141. package/dist/migration/rollback/RollbackManager.d.ts +0 -29
  142. package/dist/migration/rollback/RollbackManager.js +0 -146
  143. package/dist/migration/state/StateMachine.d.ts +0 -25
  144. package/dist/migration/state/StateMachine.js +0 -76
  145. package/dist/migration/state/StateTracker.d.ts +0 -36
  146. package/dist/migration/state/StateTracker.js +0 -123
  147. package/dist/migration/types.d.ts +0 -306
  148. package/dist/migration/types.js +0 -33
  149. package/dist/migration/validation/BitcoinValidator.d.ts +0 -13
  150. package/dist/migration/validation/BitcoinValidator.js +0 -83
  151. package/dist/migration/validation/CredentialValidator.d.ts +0 -13
  152. package/dist/migration/validation/CredentialValidator.js +0 -46
  153. package/dist/migration/validation/DIDCompatibilityValidator.d.ts +0 -16
  154. package/dist/migration/validation/DIDCompatibilityValidator.js +0 -127
  155. package/dist/migration/validation/LifecycleValidator.d.ts +0 -10
  156. package/dist/migration/validation/LifecycleValidator.js +0 -52
  157. package/dist/migration/validation/StorageValidator.d.ts +0 -10
  158. package/dist/migration/validation/StorageValidator.js +0 -65
  159. package/dist/migration/validation/ValidationPipeline.d.ts +0 -29
  160. package/dist/migration/validation/ValidationPipeline.js +0 -180
  161. package/dist/storage/LocalStorageAdapter.d.ts +0 -11
  162. package/dist/storage/LocalStorageAdapter.js +0 -53
  163. package/dist/storage/MemoryStorageAdapter.d.ts +0 -6
  164. package/dist/storage/MemoryStorageAdapter.js +0 -21
  165. package/dist/storage/StorageAdapter.d.ts +0 -16
  166. package/dist/storage/StorageAdapter.js +0 -1
  167. package/dist/storage/index.d.ts +0 -2
  168. package/dist/storage/index.js +0 -2
  169. package/dist/types/bitcoin.d.ts +0 -84
  170. package/dist/types/bitcoin.js +0 -1
  171. package/dist/types/common.d.ts +0 -82
  172. package/dist/types/common.js +0 -1
  173. package/dist/types/credentials.d.ts +0 -75
  174. package/dist/types/credentials.js +0 -1
  175. package/dist/types/did.d.ts +0 -26
  176. package/dist/types/did.js +0 -1
  177. package/dist/types/index.d.ts +0 -5
  178. package/dist/types/index.js +0 -5
  179. package/dist/types/network.d.ts +0 -78
  180. package/dist/types/network.js +0 -145
  181. package/dist/utils/EventLogger.d.ts +0 -71
  182. package/dist/utils/EventLogger.js +0 -232
  183. package/dist/utils/Logger.d.ts +0 -106
  184. package/dist/utils/Logger.js +0 -257
  185. package/dist/utils/MetricsCollector.d.ts +0 -110
  186. package/dist/utils/MetricsCollector.js +0 -264
  187. package/dist/utils/bitcoin-address.d.ts +0 -38
  188. package/dist/utils/bitcoin-address.js +0 -113
  189. package/dist/utils/cbor.d.ts +0 -2
  190. package/dist/utils/cbor.js +0 -9
  191. package/dist/utils/encoding.d.ts +0 -37
  192. package/dist/utils/encoding.js +0 -120
  193. package/dist/utils/hash.d.ts +0 -1
  194. package/dist/utils/hash.js +0 -5
  195. package/dist/utils/retry.d.ts +0 -10
  196. package/dist/utils/retry.js +0 -35
  197. package/dist/utils/satoshi-validation.d.ts +0 -60
  198. package/dist/utils/satoshi-validation.js +0 -156
  199. package/dist/utils/serialization.d.ts +0 -14
  200. package/dist/utils/serialization.js +0 -76
  201. package/dist/utils/telemetry.d.ts +0 -17
  202. package/dist/utils/telemetry.js +0 -24
  203. package/dist/utils/validation.d.ts +0 -5
  204. package/dist/utils/validation.js +0 -98
  205. package/dist/vc/CredentialManager.d.ts +0 -22
  206. package/dist/vc/CredentialManager.js +0 -227
  207. package/dist/vc/Issuer.d.ts +0 -27
  208. package/dist/vc/Issuer.js +0 -70
  209. package/dist/vc/Verifier.d.ts +0 -16
  210. package/dist/vc/Verifier.js +0 -50
  211. package/dist/vc/cryptosuites/bbs.d.ts +0 -44
  212. package/dist/vc/cryptosuites/bbs.js +0 -213
  213. package/dist/vc/cryptosuites/bbsSimple.d.ts +0 -9
  214. package/dist/vc/cryptosuites/bbsSimple.js +0 -12
  215. package/dist/vc/cryptosuites/eddsa.d.ts +0 -30
  216. package/dist/vc/cryptosuites/eddsa.js +0 -81
  217. package/dist/vc/documentLoader.d.ts +0 -16
  218. package/dist/vc/documentLoader.js +0 -59
  219. package/dist/vc/proofs/data-integrity.d.ts +0 -21
  220. package/dist/vc/proofs/data-integrity.js +0 -15
  221. package/dist/vc/utils/jsonld.d.ts +0 -2
  222. package/dist/vc/utils/jsonld.js +0 -15
  223. package/test/logs/did_webvh_QmNTn9Kkp8dQ75WrF9xqJ2kuDp9QhKc3aPiERRMj8XoTBN_example_com.jsonl +0 -1
  224. package/test/logs/did_webvh_QmNu4MNr8Lr5txx5gYNhuhZDchXsZEu3hJXKYuphpWTPDp_example_com_users_etc_passwd.jsonl +0 -1
  225. package/test/logs/did_webvh_QmR9MrGZACzjKETA8SBRNCKG11HxU85c4bVR2qN5eDCfsD_example_com.jsonl +0 -1
  226. package/test/logs/did_webvh_QmUc5suaqRM2P4nrXxZwqYMfqzhdMqjuL7oJaJbEpCQVCd_example_com_users_etc_passwd.jsonl +0 -1
  227. package/test/logs/did_webvh_QmUkiB2RCV2VZ1RTXsCebWN25Eiy9TLvpzDWAJNjhgvB4X_example_com_etc_passwd.jsonl +0 -1
  228. package/test/logs/did_webvh_QmUoRTe8UMwpAQXZSAW7pjAgZK1tq2X3C6Kfxq3UXGcaGy_example_com_secret.jsonl +0 -1
  229. package/test/logs/did_webvh_QmWWot3chx1t6KwTmcE5i2FeDZ5JMkQw3qXycsKDVmJ9Be_example_com_users_alice.jsonl +0 -1
  230. package/test/logs/did_webvh_QmWvVgALL5kjZdpgR7KZay7J8UiiUr834kkRmWeFAxjAuC_example_com_users_etc_passwd.jsonl +0 -1
  231. package/test/logs/did_webvh_QmWwaRQHUZAFcKihFC6xR6tRTTrQhHPTku6azf1egWbpy1_example_com_users_alice.jsonl +0 -1
  232. package/test/logs/did_webvh_QmXJLtkz23r7AozbtXsZMKWnVU6rd38CkVtjdWuATU3Yp6_example_com_users_alice123_profile.jsonl +0 -1
  233. package/test/logs/did_webvh_QmYsce448po14oDE1wXbyaP6wY9HQgHSKLwdezn1k577SF_example_com_my_org_user_name_test_123.jsonl +0 -1
  234. package/test/logs/did_webvh_QmZBeNzzqajxdfwcDUPZ4P8C5YSXyRztrAwmPiKuKUxmAK_example_com.jsonl +0 -1
  235. package/test/logs/did_webvh_QmZhJsqxizwVbRtqCUkmE6XQunSxtxMt3gbTYadVBNAaEq_example_com.jsonl +0 -1
  236. package/test/logs/did_webvh_QmZk7NHU2D57RzzbMq4tWW9gBa9AqtVTWfiRM6RFdwGVj2_example_com.jsonl +0 -1
  237. package/test/logs/did_webvh_QmZshSXp9w8ovH62zGGBS1b5pGGPsuYiu1VQ935sga2hWF_example_com_level1_level2.jsonl +0 -1
  238. package/test/logs/did_webvh_QmbWAmw7HQL7vKJyCsctZihXf1rmT4sGvggKCPKWcUWjw1_example_com.jsonl +0 -1
  239. package/test/logs/did_webvh_QmbdLUMbYs3juR39TLB6hhrFWLcNg45ybUzeBJCS1MhCh1_example_com_C_Windows_System32.jsonl +0 -1
  240. package/test/logs/did_webvh_QmcaQ1Ma4gkSbae85aCm8Mv4rvdT2Sb2RR3JzYwrm5XBq8_example_com_etc_passwd.jsonl +0 -1
  241. package/test/logs/did_webvh_QmcbA7WQhsBqZSoDpKJHjV8Q5o53h8vmgJhQfo6rqTY5ho_example_com.jsonl +0 -1
  242. package/test/logs/did_webvh_Qmdy8uWr2gkUJrXsThynAug3DASTWwb3onEj89LKmMGZYB_example_com.jsonl +0 -1
  243. package/tests/e2e/README.md +0 -97
  244. package/tests/e2e/example.spec.ts +0 -78
@@ -0,0 +1,527 @@
1
+ import { describe, test, expect } from 'bun:test';
2
+ import {
3
+ CredentialManager,
4
+ type ResourceCreatedSubject,
5
+ type MigrationSubject,
6
+ type OwnershipSubject,
7
+ type AssetResource,
8
+ type VerifiableCredential
9
+ } from '../../../src';
10
+ import { DIDManager } from '../../../src/did/DIDManager';
11
+
12
+ const config: any = {
13
+ network: 'regtest',
14
+ defaultKeyType: 'Ed25519',
15
+ enableLogging: false
16
+ };
17
+
18
+ describe('CredentialManager - Factory Methods', () => {
19
+ const didManager = new DIDManager(config);
20
+ const credentialManager = new CredentialManager(config, didManager);
21
+
22
+ describe('issueResourceCredential', () => {
23
+ test('creates a ResourceCreated credential with all required fields', async () => {
24
+ const resource: AssetResource = {
25
+ id: 'main.js',
26
+ type: 'code',
27
+ contentType: 'text/javascript',
28
+ hash: 'abc123def456',
29
+ createdAt: '2024-01-15T10:00:00Z'
30
+ };
31
+
32
+ const credential = await credentialManager.issueResourceCredential(
33
+ resource,
34
+ 'did:peer:assetId',
35
+ 'did:peer:creator'
36
+ );
37
+
38
+ expect(credential.type).toContain('VerifiableCredential');
39
+ expect(credential.type).toContain('ResourceCreated');
40
+ expect(credential.issuer).toBe('did:peer:creator');
41
+ expect(credential.issuanceDate).toBeDefined();
42
+ expect(credential.id).toBeDefined();
43
+ expect(credential.id?.startsWith('urn:uuid:')).toBe(true);
44
+
45
+ const subject = credential.credentialSubject as ResourceCreatedSubject;
46
+ expect(subject.id).toBe('did:peer:assetId');
47
+ expect(subject.resourceId).toBe('main.js');
48
+ expect(subject.resourceType).toBe('code');
49
+ expect(subject.contentHash).toBe('abc123def456');
50
+ expect(subject.contentType).toBe('text/javascript');
51
+ expect(subject.creator).toBe('did:peer:creator');
52
+ expect(subject.createdAt).toBe('2024-01-15T10:00:00Z');
53
+ });
54
+
55
+ test('uses current timestamp when resource.createdAt is not provided', async () => {
56
+ const resource: AssetResource = {
57
+ id: 'readme.md',
58
+ type: 'text',
59
+ contentType: 'text/markdown',
60
+ hash: 'deadbeef'
61
+ };
62
+
63
+ const before = new Date().toISOString();
64
+ const credential = await credentialManager.issueResourceCredential(
65
+ resource,
66
+ 'did:peer:asset',
67
+ 'did:peer:creator'
68
+ );
69
+ const after = new Date().toISOString();
70
+
71
+ const subject = credential.credentialSubject as ResourceCreatedSubject;
72
+ expect(subject.createdAt >= before).toBe(true);
73
+ expect(subject.createdAt <= after).toBe(true);
74
+ });
75
+
76
+ test('supports credential chaining', async () => {
77
+ const resource: AssetResource = {
78
+ id: 'file.txt',
79
+ type: 'text',
80
+ contentType: 'text/plain',
81
+ hash: 'aabbccdd'
82
+ };
83
+
84
+ const credential = await credentialManager.issueResourceCredential(
85
+ resource,
86
+ 'did:peer:asset',
87
+ 'did:peer:creator',
88
+ {
89
+ previousCredentialId: 'urn:uuid:previous-credential',
90
+ previousCredentialHash: 'prevhash123'
91
+ }
92
+ );
93
+
94
+ const subject = credential.credentialSubject as any;
95
+ expect(subject.previousCredential).toBeDefined();
96
+ expect(subject.previousCredential.id).toBe('urn:uuid:previous-credential');
97
+ expect(subject.previousCredential.hash).toBe('prevhash123');
98
+ });
99
+ });
100
+
101
+ describe('issueResourceUpdateCredential', () => {
102
+ test('creates a ResourceUpdated credential', async () => {
103
+ const credential = await credentialManager.issueResourceUpdateCredential(
104
+ 'main.js',
105
+ 'did:webvh:example.com:asset',
106
+ 'oldhash',
107
+ 'newhash',
108
+ 1,
109
+ 2,
110
+ 'did:webvh:example.com:updater',
111
+ 'Bug fix'
112
+ );
113
+
114
+ expect(credential.type).toContain('ResourceUpdated');
115
+ expect(credential.issuer).toBe('did:webvh:example.com:updater');
116
+
117
+ const subject = credential.credentialSubject as any;
118
+ expect(subject.id).toBe('did:webvh:example.com:asset');
119
+ expect(subject.resourceId).toBe('main.js');
120
+ expect(subject.previousHash).toBe('oldhash');
121
+ expect(subject.newHash).toBe('newhash');
122
+ expect(subject.fromVersion).toBe(1);
123
+ expect(subject.toVersion).toBe(2);
124
+ expect(subject.updateReason).toBe('Bug fix');
125
+ expect(subject.updatedAt).toBeDefined();
126
+ });
127
+
128
+ test('works without update reason', async () => {
129
+ const credential = await credentialManager.issueResourceUpdateCredential(
130
+ 'file.txt',
131
+ 'did:peer:asset',
132
+ 'old',
133
+ 'new',
134
+ 1,
135
+ 2,
136
+ 'did:peer:user'
137
+ );
138
+
139
+ const subject = credential.credentialSubject as any;
140
+ expect(subject.updateReason).toBeUndefined();
141
+ });
142
+ });
143
+
144
+ describe('issueMigrationCredential', () => {
145
+ test('creates a MigrationCompleted credential for peer to webvh', async () => {
146
+ const credential = await credentialManager.issueMigrationCredential(
147
+ 'did:peer:source123',
148
+ 'did:webvh:example.com:target456',
149
+ 'did:peer',
150
+ 'did:webvh',
151
+ 'did:webvh:example.com:publisher'
152
+ );
153
+
154
+ expect(credential.type).toContain('MigrationCompleted');
155
+ expect(credential.issuer).toBe('did:webvh:example.com:publisher');
156
+
157
+ const subject = credential.credentialSubject as MigrationSubject;
158
+ expect(subject.id).toBe('did:webvh:example.com:target456');
159
+ expect(subject.sourceDid).toBe('did:peer:source123');
160
+ expect(subject.targetDid).toBe('did:webvh:example.com:target456');
161
+ expect(subject.fromLayer).toBe('did:peer');
162
+ expect(subject.toLayer).toBe('did:webvh');
163
+ expect(subject.migratedAt).toBeDefined();
164
+ });
165
+
166
+ test('creates a MigrationCompleted credential for webvh to btco', async () => {
167
+ const credential = await credentialManager.issueMigrationCredential(
168
+ 'did:webvh:example.com:asset',
169
+ 'did:btco:12345',
170
+ 'did:webvh',
171
+ 'did:btco',
172
+ 'did:btco:12345',
173
+ {
174
+ transactionId: 'tx123',
175
+ inscriptionId: 'insc456',
176
+ satoshi: '12345',
177
+ migrationReason: 'Permanent anchoring'
178
+ }
179
+ );
180
+
181
+ const subject = credential.credentialSubject as MigrationSubject;
182
+ expect(subject.fromLayer).toBe('did:webvh');
183
+ expect(subject.toLayer).toBe('did:btco');
184
+ expect(subject.transactionId).toBe('tx123');
185
+ expect(subject.inscriptionId).toBe('insc456');
186
+ expect(subject.satoshi).toBe('12345');
187
+ expect(subject.migrationReason).toBe('Permanent anchoring');
188
+ });
189
+
190
+ test('works without targetDid (same-layer operation)', async () => {
191
+ const credential = await credentialManager.issueMigrationCredential(
192
+ 'did:peer:asset',
193
+ undefined,
194
+ 'did:peer',
195
+ 'did:webvh',
196
+ 'did:peer:issuer'
197
+ );
198
+
199
+ const subject = credential.credentialSubject as MigrationSubject;
200
+ expect(subject.id).toBe('did:peer:asset');
201
+ expect(subject.targetDid).toBeUndefined();
202
+ });
203
+ });
204
+
205
+ describe('issueOwnershipCredential', () => {
206
+ test('creates an OwnershipTransferred credential', async () => {
207
+ const credential = await credentialManager.issueOwnershipCredential(
208
+ 'did:btco:12345',
209
+ 'bc1qoldowner...',
210
+ 'bc1qnewowner...',
211
+ 'txid123abc',
212
+ 'did:btco:12345',
213
+ {
214
+ satoshi: '12345',
215
+ transferReason: 'Sale'
216
+ }
217
+ );
218
+
219
+ expect(credential.type).toContain('OwnershipTransferred');
220
+ expect(credential.issuer).toBe('did:btco:12345');
221
+
222
+ const subject = credential.credentialSubject as OwnershipSubject;
223
+ expect(subject.id).toBe('did:btco:12345');
224
+ expect(subject.previousOwner).toBe('bc1qoldowner...');
225
+ expect(subject.newOwner).toBe('bc1qnewowner...');
226
+ expect(subject.transactionId).toBe('txid123abc');
227
+ expect(subject.transferredAt).toBeDefined();
228
+ expect(subject.satoshi).toBe('12345');
229
+ expect(subject.transferReason).toBe('Sale');
230
+ });
231
+
232
+ test('works without optional details', async () => {
233
+ const credential = await credentialManager.issueOwnershipCredential(
234
+ 'did:btco:67890',
235
+ 'bc1qold...',
236
+ 'bc1qnew...',
237
+ 'txid456',
238
+ 'did:btco:67890'
239
+ );
240
+
241
+ const subject = credential.credentialSubject as OwnershipSubject;
242
+ expect(subject.satoshi).toBeUndefined();
243
+ expect(subject.transferReason).toBeUndefined();
244
+ });
245
+ });
246
+ });
247
+
248
+ describe('CredentialManager - Credential Chaining', () => {
249
+ const credentialManager = new CredentialManager(config);
250
+
251
+ describe('computeCredentialHash', () => {
252
+ test('computes consistent hash for same credential', async () => {
253
+ const credential: VerifiableCredential = {
254
+ '@context': ['https://www.w3.org/2018/credentials/v1'],
255
+ type: ['VerifiableCredential', 'TestCredential'],
256
+ issuer: 'did:test:issuer',
257
+ issuanceDate: '2024-01-15T10:00:00Z',
258
+ credentialSubject: { id: 'did:test:subject', name: 'Test' }
259
+ };
260
+
261
+ const hash1 = await credentialManager.computeCredentialHash(credential);
262
+ const hash2 = await credentialManager.computeCredentialHash(credential);
263
+
264
+ expect(hash1).toBe(hash2);
265
+ expect(hash1.length).toBe(64); // SHA-256 hex string
266
+ });
267
+
268
+ test('computes different hash for different credentials', async () => {
269
+ const credential1: VerifiableCredential = {
270
+ '@context': ['https://www.w3.org/2018/credentials/v1'],
271
+ type: ['VerifiableCredential', 'TypeOne'],
272
+ issuer: 'did:test:issuer1',
273
+ issuanceDate: '2024-01-15T10:00:00Z',
274
+ credentialSubject: {
275
+ id: 'subject1',
276
+ name: 'Alice',
277
+ role: 'admin'
278
+ }
279
+ };
280
+
281
+ const credential2: VerifiableCredential = {
282
+ '@context': ['https://www.w3.org/2018/credentials/v1'],
283
+ type: ['VerifiableCredential', 'TypeTwo'],
284
+ issuer: 'did:test:issuer2',
285
+ issuanceDate: '2024-01-16T10:00:00Z',
286
+ credentialSubject: {
287
+ id: 'subject2',
288
+ name: 'Bob',
289
+ role: 'user'
290
+ }
291
+ };
292
+
293
+ const hash1 = await credentialManager.computeCredentialHash(credential1);
294
+ const hash2 = await credentialManager.computeCredentialHash(credential2);
295
+
296
+ expect(hash1).not.toBe(hash2);
297
+ });
298
+ });
299
+
300
+ describe('verifyCredentialChain', () => {
301
+ test('returns valid for empty chain', async () => {
302
+ const result = await credentialManager.verifyCredentialChain([]);
303
+
304
+ expect(result.valid).toBe(true);
305
+ expect(result.chainLength).toBe(0);
306
+ expect(result.errors).toHaveLength(0);
307
+ });
308
+
309
+ test('validates chain with linked credentials', async () => {
310
+ // Create first credential
311
+ const cred1: VerifiableCredential = {
312
+ '@context': ['https://www.w3.org/2018/credentials/v1'],
313
+ type: ['VerifiableCredential'],
314
+ id: 'urn:uuid:cred1',
315
+ issuer: 'did:test:issuer',
316
+ issuanceDate: '2024-01-01T00:00:00Z',
317
+ credentialSubject: { id: 'subject', value: 1 }
318
+ };
319
+
320
+ // Compute hash of first credential
321
+ const cred1Hash = await credentialManager.computeCredentialHash(cred1);
322
+
323
+ // Create second credential linked to first
324
+ const cred2: VerifiableCredential = {
325
+ '@context': ['https://www.w3.org/2018/credentials/v1'],
326
+ type: ['VerifiableCredential'],
327
+ id: 'urn:uuid:cred2',
328
+ issuer: 'did:test:issuer',
329
+ issuanceDate: '2024-01-02T00:00:00Z',
330
+ credentialSubject: {
331
+ id: 'subject',
332
+ value: 2,
333
+ previousCredential: { id: 'urn:uuid:cred1', hash: cred1Hash }
334
+ }
335
+ };
336
+
337
+ // Note: Without actual proofs, verifyCredential returns false
338
+ // The chain verification will report credential verification failures
339
+ // but the hash linking will be validated
340
+ const result = await credentialManager.verifyCredentialChain([cred1, cred2]);
341
+
342
+ // We expect credential verification failures (no proofs)
343
+ // but no chain integrity errors
344
+ expect(result.chainLength).toBe(2);
345
+ });
346
+ });
347
+ });
348
+
349
+ describe('CredentialManager - Selective Disclosure', () => {
350
+ const credentialManager = new CredentialManager(config);
351
+
352
+ describe('prepareSelectiveDisclosure', () => {
353
+ test('prepares credential with mandatory pointers', async () => {
354
+ const credential: VerifiableCredential = {
355
+ '@context': ['https://www.w3.org/2018/credentials/v1'],
356
+ type: ['VerifiableCredential'],
357
+ issuer: 'did:test:issuer',
358
+ issuanceDate: '2024-01-15T10:00:00Z',
359
+ credentialSubject: {
360
+ id: 'did:test:subject',
361
+ name: 'Alice',
362
+ email: 'alice@example.com',
363
+ age: 30
364
+ }
365
+ };
366
+
367
+ const result = await credentialManager.prepareSelectiveDisclosure(credential, {
368
+ mandatoryPointers: ['/issuer', '/issuanceDate', '/credentialSubject/id'],
369
+ selectivePointers: ['/credentialSubject/name', '/credentialSubject/age']
370
+ });
371
+
372
+ expect(result.credential).toBeDefined();
373
+ expect(result.mandatoryPointers).toContain('/issuer');
374
+ expect(result.mandatoryPointers).toContain('/issuanceDate');
375
+ expect(result.selectivePointers).toContain('/credentialSubject/name');
376
+ });
377
+
378
+ test('throws error for empty mandatory pointers', async () => {
379
+ const credential: VerifiableCredential = {
380
+ '@context': ['https://www.w3.org/2018/credentials/v1'],
381
+ type: ['VerifiableCredential'],
382
+ issuer: 'did:test:issuer',
383
+ issuanceDate: '2024-01-15T10:00:00Z',
384
+ credentialSubject: { id: 'subject' }
385
+ };
386
+
387
+ await expect(
388
+ credentialManager.prepareSelectiveDisclosure(credential, {
389
+ mandatoryPointers: []
390
+ })
391
+ ).rejects.toThrow('At least one mandatory pointer is required');
392
+ });
393
+
394
+ test('throws error for invalid JSON Pointer format', async () => {
395
+ const credential: VerifiableCredential = {
396
+ '@context': ['https://www.w3.org/2018/credentials/v1'],
397
+ type: ['VerifiableCredential'],
398
+ issuer: 'did:test:issuer',
399
+ issuanceDate: '2024-01-15T10:00:00Z',
400
+ credentialSubject: { id: 'subject' }
401
+ };
402
+
403
+ await expect(
404
+ credentialManager.prepareSelectiveDisclosure(credential, {
405
+ mandatoryPointers: ['issuer'] // Missing leading /
406
+ })
407
+ ).rejects.toThrow('Invalid JSON Pointer');
408
+ });
409
+ });
410
+
411
+ describe('deriveSelectiveProof', () => {
412
+ test('creates derived proof result with disclosed/hidden fields', async () => {
413
+ const credential: VerifiableCredential = {
414
+ '@context': ['https://www.w3.org/2018/credentials/v1'],
415
+ type: ['VerifiableCredential'],
416
+ issuer: 'did:test:issuer',
417
+ issuanceDate: '2024-01-15T10:00:00Z',
418
+ credentialSubject: {
419
+ id: 'did:test:subject',
420
+ name: 'Alice',
421
+ email: 'alice@example.com'
422
+ }
423
+ };
424
+
425
+ const result = await credentialManager.deriveSelectiveProof(
426
+ credential,
427
+ ['/issuer', '/credentialSubject/name']
428
+ );
429
+
430
+ expect(result.credential).toBeDefined();
431
+ expect(result.disclosedFields).toContain('/issuer');
432
+ expect(result.disclosedFields).toContain('/credentialSubject/name');
433
+ expect(result.hiddenFields).toContain('/credentialSubject/email');
434
+ });
435
+
436
+ test('throws error for invalid JSON Pointer in disclosure', async () => {
437
+ const credential: VerifiableCredential = {
438
+ '@context': ['https://www.w3.org/2018/credentials/v1'],
439
+ type: ['VerifiableCredential'],
440
+ issuer: 'did:test:issuer',
441
+ issuanceDate: '2024-01-15T10:00:00Z',
442
+ credentialSubject: { id: 'subject' }
443
+ };
444
+
445
+ await expect(
446
+ credentialManager.deriveSelectiveProof(credential, ['issuer'])
447
+ ).rejects.toThrow('Invalid JSON Pointer');
448
+ });
449
+ });
450
+
451
+ describe('getFieldByPointer', () => {
452
+ const credential: VerifiableCredential = {
453
+ '@context': ['https://www.w3.org/2018/credentials/v1'],
454
+ type: ['VerifiableCredential'],
455
+ issuer: 'did:test:issuer',
456
+ issuanceDate: '2024-01-15T10:00:00Z',
457
+ credentialSubject: {
458
+ id: 'did:test:subject',
459
+ name: 'Alice',
460
+ address: {
461
+ city: 'New York',
462
+ zip: '10001'
463
+ }
464
+ }
465
+ };
466
+
467
+ test('retrieves top-level field', () => {
468
+ const value = credentialManager.getFieldByPointer(credential, '/issuer');
469
+ expect(value).toBe('did:test:issuer');
470
+ });
471
+
472
+ test('retrieves nested field', () => {
473
+ const value = credentialManager.getFieldByPointer(credential, '/credentialSubject/name');
474
+ expect(value).toBe('Alice');
475
+ });
476
+
477
+ test('retrieves deeply nested field', () => {
478
+ const value = credentialManager.getFieldByPointer(credential, '/credentialSubject/address/city');
479
+ expect(value).toBe('New York');
480
+ });
481
+
482
+ test('returns undefined for non-existent path', () => {
483
+ const value = credentialManager.getFieldByPointer(credential, '/nonexistent');
484
+ expect(value).toBeUndefined();
485
+ });
486
+
487
+ test('throws error for invalid pointer format', () => {
488
+ expect(() => {
489
+ credentialManager.getFieldByPointer(credential, 'issuer');
490
+ }).toThrow('JSON Pointer must start with /');
491
+ });
492
+ });
493
+ });
494
+
495
+ describe('CredentialManager - Credential ID Generation', () => {
496
+ const credentialManager = new CredentialManager(config);
497
+
498
+ test('generates unique credential IDs', async () => {
499
+ const resource: AssetResource = {
500
+ id: 'test',
501
+ type: 'text',
502
+ contentType: 'text/plain',
503
+ hash: 'abc'
504
+ };
505
+
506
+ const cred1 = await credentialManager.issueResourceCredential(resource, 'did:a', 'did:b');
507
+ const cred2 = await credentialManager.issueResourceCredential(resource, 'did:a', 'did:b');
508
+
509
+ expect(cred1.id).toBeDefined();
510
+ expect(cred2.id).toBeDefined();
511
+ expect(cred1.id).not.toBe(cred2.id);
512
+ });
513
+
514
+ test('credential IDs follow URN format', async () => {
515
+ const resource: AssetResource = {
516
+ id: 'test',
517
+ type: 'text',
518
+ contentType: 'text/plain',
519
+ hash: 'abc'
520
+ };
521
+
522
+ const credential = await credentialManager.issueResourceCredential(resource, 'did:a', 'did:b');
523
+
524
+ expect(credential.id).toMatch(/^urn:uuid:\d+-[a-f0-9]+-[a-f0-9]+$/);
525
+ });
526
+ });
527
+
@@ -1 +0,0 @@
1
- $ tsc && tsc-alias
@@ -1,6 +0,0 @@
1
- import { FeeOracleAdapter } from './types';
2
- export declare class FeeOracleMock implements FeeOracleAdapter {
3
- private feeRate;
4
- constructor(feeRate?: number);
5
- estimateFeeRate(targetBlocks?: number): Promise<number>;
6
- }
@@ -1,8 +0,0 @@
1
- export class FeeOracleMock {
2
- constructor(feeRate = 7) {
3
- this.feeRate = feeRate;
4
- }
5
- async estimateFeeRate(targetBlocks = 1) {
6
- return Math.max(1, this.feeRate - (targetBlocks - 1));
7
- }
8
- }
@@ -1,4 +0,0 @@
1
- export * from './types';
2
- export * from './FeeOracleMock';
3
- export * from './providers/OrdMockProvider';
4
- export * from './providers/OrdHttpProvider';
@@ -1,4 +0,0 @@
1
- export * from './types';
2
- export * from './FeeOracleMock';
3
- export * from './providers/OrdMockProvider';
4
- export * from './providers/OrdHttpProvider';
@@ -1,56 +0,0 @@
1
- import type { OrdinalsProvider } from '../types';
2
- interface HttpProviderOptions {
3
- baseUrl: string;
4
- }
5
- export declare class OrdHttpProvider implements OrdinalsProvider {
6
- private readonly baseUrl;
7
- constructor(options: HttpProviderOptions);
8
- getInscriptionById(id: string): Promise<{
9
- inscriptionId: any;
10
- content: any;
11
- contentType: any;
12
- txid: any;
13
- vout: any;
14
- satoshi: string;
15
- blockHeight: any;
16
- } | null>;
17
- getInscriptionsBySatoshi(satoshi: string): Promise<{
18
- inscriptionId: string;
19
- }[]>;
20
- broadcastTransaction(_txHexOrObj: unknown): Promise<string>;
21
- getTransactionStatus(_txid: string): Promise<{
22
- confirmed: boolean;
23
- }>;
24
- estimateFee(blocks?: number): Promise<number>;
25
- createInscription(params: {
26
- data: any;
27
- contentType: string;
28
- feeRate?: number;
29
- }): Promise<{
30
- inscriptionId: string;
31
- revealTxId: string;
32
- txid: string;
33
- vout: number;
34
- blockHeight: undefined;
35
- content: any;
36
- contentType: string;
37
- feeRate: number | undefined;
38
- }>;
39
- transferInscription(inscriptionId: string, _toAddress: string, _options?: {
40
- feeRate?: number;
41
- }): Promise<{
42
- txid: string;
43
- vin: {
44
- txid: string;
45
- vout: number;
46
- }[];
47
- vout: {
48
- value: number;
49
- scriptPubKey: string;
50
- }[];
51
- fee: number;
52
- confirmations: number;
53
- }>;
54
- }
55
- export declare function createOrdinalsProviderFromEnv(): Promise<OrdinalsProvider>;
56
- export {};