@originals/sdk 1.1.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 (247) hide show
  1. package/package.json +3 -2
  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/tsconfig.json +0 -1
  34. package/.turbo/turbo-build.log +0 -1
  35. package/.turbo/turbo-test.log +0 -68353
  36. package/dist/adapters/FeeOracleMock.d.ts +0 -6
  37. package/dist/adapters/FeeOracleMock.js +0 -8
  38. package/dist/adapters/index.d.ts +0 -4
  39. package/dist/adapters/index.js +0 -4
  40. package/dist/adapters/providers/OrdHttpProvider.d.ts +0 -56
  41. package/dist/adapters/providers/OrdHttpProvider.js +0 -110
  42. package/dist/adapters/providers/OrdMockProvider.d.ts +0 -70
  43. package/dist/adapters/providers/OrdMockProvider.js +0 -75
  44. package/dist/adapters/types.d.ts +0 -71
  45. package/dist/adapters/types.js +0 -1
  46. package/dist/bitcoin/BitcoinManager.d.ts +0 -15
  47. package/dist/bitcoin/BitcoinManager.js +0 -262
  48. package/dist/bitcoin/BroadcastClient.d.ts +0 -30
  49. package/dist/bitcoin/BroadcastClient.js +0 -35
  50. package/dist/bitcoin/OrdinalsClient.d.ts +0 -21
  51. package/dist/bitcoin/OrdinalsClient.js +0 -105
  52. package/dist/bitcoin/PSBTBuilder.d.ts +0 -24
  53. package/dist/bitcoin/PSBTBuilder.js +0 -80
  54. package/dist/bitcoin/fee-calculation.d.ts +0 -14
  55. package/dist/bitcoin/fee-calculation.js +0 -31
  56. package/dist/bitcoin/providers/OrdNodeProvider.d.ts +0 -38
  57. package/dist/bitcoin/providers/OrdNodeProvider.js +0 -67
  58. package/dist/bitcoin/providers/OrdinalsProvider.d.ts +0 -33
  59. package/dist/bitcoin/providers/OrdinalsProvider.js +0 -50
  60. package/dist/bitcoin/providers/types.d.ts +0 -63
  61. package/dist/bitcoin/providers/types.js +0 -1
  62. package/dist/bitcoin/transactions/commit.d.ts +0 -89
  63. package/dist/bitcoin/transactions/commit.js +0 -311
  64. package/dist/bitcoin/transactions/index.d.ts +0 -7
  65. package/dist/bitcoin/transactions/index.js +0 -8
  66. package/dist/bitcoin/transfer.d.ts +0 -9
  67. package/dist/bitcoin/transfer.js +0 -26
  68. package/dist/bitcoin/utxo-selection.d.ts +0 -78
  69. package/dist/bitcoin/utxo-selection.js +0 -237
  70. package/dist/bitcoin/utxo.d.ts +0 -26
  71. package/dist/bitcoin/utxo.js +0 -78
  72. package/dist/contexts/credentials-v1.json +0 -195
  73. package/dist/contexts/credentials-v2-examples.json +0 -5
  74. package/dist/contexts/credentials-v2.json +0 -301
  75. package/dist/contexts/credentials.json +0 -195
  76. package/dist/contexts/data-integrity-v2.json +0 -81
  77. package/dist/contexts/dids.json +0 -57
  78. package/dist/contexts/ed255192020.json +0 -93
  79. package/dist/contexts/ordinals-plus.json +0 -23
  80. package/dist/contexts/originals.json +0 -22
  81. package/dist/core/OriginalsSDK.d.ts +0 -158
  82. package/dist/core/OriginalsSDK.js +0 -274
  83. package/dist/crypto/Multikey.d.ts +0 -30
  84. package/dist/crypto/Multikey.js +0 -149
  85. package/dist/crypto/Signer.d.ts +0 -21
  86. package/dist/crypto/Signer.js +0 -196
  87. package/dist/crypto/noble-init.d.ts +0 -18
  88. package/dist/crypto/noble-init.js +0 -106
  89. package/dist/did/BtcoDidResolver.d.ts +0 -57
  90. package/dist/did/BtcoDidResolver.js +0 -166
  91. package/dist/did/DIDManager.d.ts +0 -101
  92. package/dist/did/DIDManager.js +0 -493
  93. package/dist/did/Ed25519Verifier.d.ts +0 -30
  94. package/dist/did/Ed25519Verifier.js +0 -59
  95. package/dist/did/KeyManager.d.ts +0 -17
  96. package/dist/did/KeyManager.js +0 -207
  97. package/dist/did/WebVHManager.d.ts +0 -100
  98. package/dist/did/WebVHManager.js +0 -304
  99. package/dist/did/createBtcoDidDocument.d.ts +0 -10
  100. package/dist/did/createBtcoDidDocument.js +0 -42
  101. package/dist/did/providers/OrdinalsClientProviderAdapter.d.ts +0 -23
  102. package/dist/did/providers/OrdinalsClientProviderAdapter.js +0 -51
  103. package/dist/events/EventEmitter.d.ts +0 -115
  104. package/dist/events/EventEmitter.js +0 -198
  105. package/dist/events/index.d.ts +0 -7
  106. package/dist/events/index.js +0 -6
  107. package/dist/events/types.d.ts +0 -286
  108. package/dist/events/types.js +0 -9
  109. package/dist/examples/basic-usage.d.ts +0 -3
  110. package/dist/examples/basic-usage.js +0 -62
  111. package/dist/examples/run.d.ts +0 -1
  112. package/dist/examples/run.js +0 -4
  113. package/dist/index.d.ts +0 -39
  114. package/dist/index.js +0 -47
  115. package/dist/lifecycle/BatchOperations.d.ts +0 -147
  116. package/dist/lifecycle/BatchOperations.js +0 -251
  117. package/dist/lifecycle/LifecycleManager.d.ts +0 -116
  118. package/dist/lifecycle/LifecycleManager.js +0 -971
  119. package/dist/lifecycle/OriginalsAsset.d.ts +0 -164
  120. package/dist/lifecycle/OriginalsAsset.js +0 -380
  121. package/dist/lifecycle/ProvenanceQuery.d.ts +0 -126
  122. package/dist/lifecycle/ProvenanceQuery.js +0 -220
  123. package/dist/lifecycle/ResourceVersioning.d.ts +0 -73
  124. package/dist/lifecycle/ResourceVersioning.js +0 -127
  125. package/dist/migration/MigrationManager.d.ts +0 -86
  126. package/dist/migration/MigrationManager.js +0 -412
  127. package/dist/migration/audit/AuditLogger.d.ts +0 -51
  128. package/dist/migration/audit/AuditLogger.js +0 -156
  129. package/dist/migration/checkpoint/CheckpointManager.d.ts +0 -31
  130. package/dist/migration/checkpoint/CheckpointManager.js +0 -96
  131. package/dist/migration/checkpoint/CheckpointStorage.d.ts +0 -26
  132. package/dist/migration/checkpoint/CheckpointStorage.js +0 -89
  133. package/dist/migration/index.d.ts +0 -22
  134. package/dist/migration/index.js +0 -27
  135. package/dist/migration/operations/BaseMigration.d.ts +0 -48
  136. package/dist/migration/operations/BaseMigration.js +0 -83
  137. package/dist/migration/operations/PeerToBtcoMigration.d.ts +0 -25
  138. package/dist/migration/operations/PeerToBtcoMigration.js +0 -67
  139. package/dist/migration/operations/PeerToWebvhMigration.d.ts +0 -19
  140. package/dist/migration/operations/PeerToWebvhMigration.js +0 -46
  141. package/dist/migration/operations/WebvhToBtcoMigration.d.ts +0 -25
  142. package/dist/migration/operations/WebvhToBtcoMigration.js +0 -67
  143. package/dist/migration/rollback/RollbackManager.d.ts +0 -29
  144. package/dist/migration/rollback/RollbackManager.js +0 -146
  145. package/dist/migration/state/StateMachine.d.ts +0 -25
  146. package/dist/migration/state/StateMachine.js +0 -76
  147. package/dist/migration/state/StateTracker.d.ts +0 -36
  148. package/dist/migration/state/StateTracker.js +0 -123
  149. package/dist/migration/types.d.ts +0 -306
  150. package/dist/migration/types.js +0 -33
  151. package/dist/migration/validation/BitcoinValidator.d.ts +0 -13
  152. package/dist/migration/validation/BitcoinValidator.js +0 -83
  153. package/dist/migration/validation/CredentialValidator.d.ts +0 -13
  154. package/dist/migration/validation/CredentialValidator.js +0 -46
  155. package/dist/migration/validation/DIDCompatibilityValidator.d.ts +0 -16
  156. package/dist/migration/validation/DIDCompatibilityValidator.js +0 -127
  157. package/dist/migration/validation/LifecycleValidator.d.ts +0 -10
  158. package/dist/migration/validation/LifecycleValidator.js +0 -52
  159. package/dist/migration/validation/StorageValidator.d.ts +0 -10
  160. package/dist/migration/validation/StorageValidator.js +0 -65
  161. package/dist/migration/validation/ValidationPipeline.d.ts +0 -29
  162. package/dist/migration/validation/ValidationPipeline.js +0 -180
  163. package/dist/storage/LocalStorageAdapter.d.ts +0 -11
  164. package/dist/storage/LocalStorageAdapter.js +0 -53
  165. package/dist/storage/MemoryStorageAdapter.d.ts +0 -6
  166. package/dist/storage/MemoryStorageAdapter.js +0 -21
  167. package/dist/storage/StorageAdapter.d.ts +0 -16
  168. package/dist/storage/StorageAdapter.js +0 -1
  169. package/dist/storage/index.d.ts +0 -2
  170. package/dist/storage/index.js +0 -2
  171. package/dist/types/bitcoin.d.ts +0 -84
  172. package/dist/types/bitcoin.js +0 -1
  173. package/dist/types/common.d.ts +0 -82
  174. package/dist/types/common.js +0 -1
  175. package/dist/types/credentials.d.ts +0 -75
  176. package/dist/types/credentials.js +0 -1
  177. package/dist/types/did.d.ts +0 -26
  178. package/dist/types/did.js +0 -1
  179. package/dist/types/index.d.ts +0 -5
  180. package/dist/types/index.js +0 -5
  181. package/dist/types/network.d.ts +0 -78
  182. package/dist/types/network.js +0 -145
  183. package/dist/utils/EventLogger.d.ts +0 -71
  184. package/dist/utils/EventLogger.js +0 -232
  185. package/dist/utils/Logger.d.ts +0 -106
  186. package/dist/utils/Logger.js +0 -257
  187. package/dist/utils/MetricsCollector.d.ts +0 -110
  188. package/dist/utils/MetricsCollector.js +0 -264
  189. package/dist/utils/bitcoin-address.d.ts +0 -38
  190. package/dist/utils/bitcoin-address.js +0 -113
  191. package/dist/utils/cbor.d.ts +0 -2
  192. package/dist/utils/cbor.js +0 -9
  193. package/dist/utils/encoding.d.ts +0 -37
  194. package/dist/utils/encoding.js +0 -120
  195. package/dist/utils/hash.d.ts +0 -1
  196. package/dist/utils/hash.js +0 -5
  197. package/dist/utils/retry.d.ts +0 -10
  198. package/dist/utils/retry.js +0 -35
  199. package/dist/utils/satoshi-validation.d.ts +0 -60
  200. package/dist/utils/satoshi-validation.js +0 -156
  201. package/dist/utils/serialization.d.ts +0 -14
  202. package/dist/utils/serialization.js +0 -76
  203. package/dist/utils/telemetry.d.ts +0 -17
  204. package/dist/utils/telemetry.js +0 -24
  205. package/dist/utils/validation.d.ts +0 -5
  206. package/dist/utils/validation.js +0 -98
  207. package/dist/vc/CredentialManager.d.ts +0 -22
  208. package/dist/vc/CredentialManager.js +0 -227
  209. package/dist/vc/Issuer.d.ts +0 -27
  210. package/dist/vc/Issuer.js +0 -70
  211. package/dist/vc/Verifier.d.ts +0 -16
  212. package/dist/vc/Verifier.js +0 -50
  213. package/dist/vc/cryptosuites/bbs.d.ts +0 -44
  214. package/dist/vc/cryptosuites/bbs.js +0 -213
  215. package/dist/vc/cryptosuites/bbsSimple.d.ts +0 -9
  216. package/dist/vc/cryptosuites/bbsSimple.js +0 -12
  217. package/dist/vc/cryptosuites/eddsa.d.ts +0 -30
  218. package/dist/vc/cryptosuites/eddsa.js +0 -81
  219. package/dist/vc/documentLoader.d.ts +0 -16
  220. package/dist/vc/documentLoader.js +0 -59
  221. package/dist/vc/proofs/data-integrity.d.ts +0 -21
  222. package/dist/vc/proofs/data-integrity.js +0 -15
  223. package/dist/vc/utils/jsonld.d.ts +0 -2
  224. package/dist/vc/utils/jsonld.js +0 -15
  225. package/test/logs/did_webvh_QmQsRNhXxPSCSeLjpbKYcNMZj8b1kBQAoC6cZmkFAgmpHt_example_com.jsonl +0 -1
  226. package/test/logs/did_webvh_QmSQkpD58qxcqMWHYcEmDUn3wk7hHvJwzYTrZmhh6zjPQ8_example_com_users_alice123_profile.jsonl +0 -1
  227. package/test/logs/did_webvh_QmTMda6VW3cUPdKk5Yc3onnv1vdgEumvWWdP2noAYFSjeG_example_com.jsonl +0 -1
  228. package/test/logs/did_webvh_QmTkb8KnCYcsnKKDCY4eUQuKQdKJLrCinvhw13v3zETxpE_example_com_users_etc_passwd.jsonl +0 -1
  229. package/test/logs/did_webvh_QmTn9FdCfpXFDrxHH52pwB4iNrDFVvNDjJ5FQTcDbmM3Fg_example_com.jsonl +0 -1
  230. package/test/logs/did_webvh_QmUCQUi1xjtJjnSQ1XJZgKqcWgErx1v7E2dz4DAPraAyJP_example_com_etc_passwd.jsonl +0 -1
  231. package/test/logs/did_webvh_QmUENQJCDKBJVRS5BkL6zjaUvcRjkb9xHmy7foCgRjmv3W_example_com.jsonl +0 -1
  232. package/test/logs/did_webvh_QmUPdGyjYBEnQ3aQUkmqyyBKTyjvCP5RZQGiaEDeTtf6dc_example_com.jsonl +0 -1
  233. package/test/logs/did_webvh_QmUoHTuHMWzQM29ZFrE9VLtMxkZ5u869yqee8LwcCLN39M_example_com.jsonl +0 -1
  234. package/test/logs/did_webvh_QmUrnms8G65ggVKsr9oQeWrLUBuGChwQPPb2LCFvaoNxaw_example_com_users_alice.jsonl +0 -1
  235. package/test/logs/did_webvh_QmUwiw3eSXdHG1hPvoAGu3cuK5jF4aXRYDLBAjPXfv1qzb_example_com_level1_level2.jsonl +0 -1
  236. package/test/logs/did_webvh_QmW7bzKh6yFEKNAtmVsrPGvvsMHTUQdzJSNsTZkbuGFpbj_example_com_secret.jsonl +0 -1
  237. package/test/logs/did_webvh_QmXbFTFBBJ8zpjdz9WE1DNN44A2wprFmdvAubjSffeyoAG_example_com.jsonl +0 -1
  238. package/test/logs/did_webvh_QmXyVXFPCTffGb2mTUFDeMCsScjnpLWkyUkVkB6q6QoeBf_example_com_C_Windows_System32.jsonl +0 -1
  239. package/test/logs/did_webvh_QmZK9B81gxZtvo5fYHYKDtKt8zZfZZPhmCMhbujBJuRRzE_example_com_etc_passwd.jsonl +0 -1
  240. package/test/logs/did_webvh_QmbNLCVSdXSVLrwFBvCBQPAabjtRb1SGHjkGVyw3QUbfBL_example_com_users_etc_passwd.jsonl +0 -1
  241. package/test/logs/did_webvh_QmbeaicmGW3Q7Yzbqmftc8a9jLBngokveb5A2KVKfVGZRb_example_com_my_org_user_name_test_123.jsonl +0 -1
  242. package/test/logs/did_webvh_Qmdv7c7AjUreUfoKyvkN2UpAWTozxKsv99srQetPJMJEnp_example_com_users_etc_passwd.jsonl +0 -1
  243. package/test/logs/did_webvh_QmeioWY3uypYLkYpCXe9eCYnn4xBVruP9C1d79azMrTEHG_example_com.jsonl +0 -1
  244. package/test/logs/did_webvh_Qmf4QH5dsA6Ecr5HJ6KaJL9uJRyY8RxrQdqoRCM25DzvPi_example_com_users_alice.jsonl +0 -1
  245. package/tests/e2e/README.md +0 -97
  246. package/tests/e2e/example.spec.ts +0 -78
  247. package/tsconfig.tsbuildinfo +0 -1
@@ -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
+
package/tsconfig.json CHANGED
@@ -5,7 +5,6 @@
5
5
  "lib": ["ES2020"],
6
6
  "allowJs": true,
7
7
  "declaration": true,
8
- "composite": true,
9
8
  "outDir": "./dist",
10
9
  "rootDir": "./src",
11
10
  "strict": true,
@@ -1 +0,0 @@
1
- $ tsc