@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.
- package/package.json +4 -1
- package/.eslintrc.json +0 -33
- package/src/adapters/FeeOracleMock.ts +0 -9
- package/src/adapters/index.ts +0 -5
- package/src/adapters/providers/OrdHttpProvider.ts +0 -126
- package/src/adapters/providers/OrdMockProvider.ts +0 -101
- package/src/adapters/types.ts +0 -66
- package/src/bitcoin/BitcoinManager.ts +0 -330
- package/src/bitcoin/BroadcastClient.ts +0 -54
- package/src/bitcoin/OrdinalsClient.ts +0 -119
- package/src/bitcoin/PSBTBuilder.ts +0 -106
- package/src/bitcoin/fee-calculation.ts +0 -38
- package/src/bitcoin/providers/OrdNodeProvider.ts +0 -92
- package/src/bitcoin/providers/OrdinalsProvider.ts +0 -56
- package/src/bitcoin/providers/types.ts +0 -59
- package/src/bitcoin/transactions/commit.ts +0 -465
- package/src/bitcoin/transactions/index.ts +0 -13
- package/src/bitcoin/transfer.ts +0 -43
- package/src/bitcoin/utxo-selection.ts +0 -322
- package/src/bitcoin/utxo.ts +0 -113
- package/src/contexts/credentials-v1.json +0 -237
- package/src/contexts/credentials-v2-examples.json +0 -5
- package/src/contexts/credentials-v2.json +0 -340
- package/src/contexts/credentials.json +0 -237
- package/src/contexts/data-integrity-v2.json +0 -81
- package/src/contexts/dids.json +0 -58
- package/src/contexts/ed255192020.json +0 -93
- package/src/contexts/ordinals-plus.json +0 -23
- package/src/contexts/originals.json +0 -22
- package/src/core/OriginalsSDK.ts +0 -416
- package/src/crypto/Multikey.ts +0 -194
- package/src/crypto/Signer.ts +0 -254
- package/src/crypto/noble-init.ts +0 -121
- package/src/did/BtcoDidResolver.ts +0 -227
- package/src/did/DIDManager.ts +0 -694
- package/src/did/Ed25519Verifier.ts +0 -68
- package/src/did/KeyManager.ts +0 -236
- package/src/did/WebVHManager.ts +0 -498
- package/src/did/createBtcoDidDocument.ts +0 -59
- package/src/did/providers/OrdinalsClientProviderAdapter.ts +0 -68
- package/src/events/EventEmitter.ts +0 -222
- package/src/events/index.ts +0 -19
- package/src/events/types.ts +0 -331
- package/src/examples/basic-usage.ts +0 -78
- package/src/examples/create-module-original.ts +0 -435
- package/src/examples/full-lifecycle-flow.ts +0 -514
- package/src/examples/run.ts +0 -60
- package/src/index.ts +0 -150
- package/src/kinds/KindRegistry.ts +0 -290
- package/src/kinds/index.ts +0 -74
- package/src/kinds/types.ts +0 -470
- package/src/kinds/validators/AgentValidator.ts +0 -257
- package/src/kinds/validators/AppValidator.ts +0 -211
- package/src/kinds/validators/DatasetValidator.ts +0 -242
- package/src/kinds/validators/DocumentValidator.ts +0 -311
- package/src/kinds/validators/MediaValidator.ts +0 -269
- package/src/kinds/validators/ModuleValidator.ts +0 -225
- package/src/kinds/validators/base.ts +0 -276
- package/src/kinds/validators/index.ts +0 -12
- package/src/lifecycle/BatchOperations.ts +0 -373
- package/src/lifecycle/LifecycleManager.ts +0 -2126
- package/src/lifecycle/OriginalsAsset.ts +0 -524
- package/src/lifecycle/ProvenanceQuery.ts +0 -280
- package/src/lifecycle/ResourceVersioning.ts +0 -163
- package/src/migration/MigrationManager.ts +0 -527
- package/src/migration/audit/AuditLogger.ts +0 -176
- package/src/migration/checkpoint/CheckpointManager.ts +0 -112
- package/src/migration/checkpoint/CheckpointStorage.ts +0 -101
- package/src/migration/index.ts +0 -33
- package/src/migration/operations/BaseMigration.ts +0 -126
- package/src/migration/operations/PeerToBtcoMigration.ts +0 -105
- package/src/migration/operations/PeerToWebvhMigration.ts +0 -62
- package/src/migration/operations/WebvhToBtcoMigration.ts +0 -105
- package/src/migration/rollback/RollbackManager.ts +0 -170
- package/src/migration/state/StateMachine.ts +0 -92
- package/src/migration/state/StateTracker.ts +0 -156
- package/src/migration/types.ts +0 -344
- package/src/migration/validation/BitcoinValidator.ts +0 -107
- package/src/migration/validation/CredentialValidator.ts +0 -62
- package/src/migration/validation/DIDCompatibilityValidator.ts +0 -151
- package/src/migration/validation/LifecycleValidator.ts +0 -64
- package/src/migration/validation/StorageValidator.ts +0 -79
- package/src/migration/validation/ValidationPipeline.ts +0 -213
- package/src/resources/ResourceManager.ts +0 -655
- package/src/resources/index.ts +0 -21
- package/src/resources/types.ts +0 -202
- package/src/storage/LocalStorageAdapter.ts +0 -61
- package/src/storage/MemoryStorageAdapter.ts +0 -29
- package/src/storage/StorageAdapter.ts +0 -25
- package/src/storage/index.ts +0 -3
- package/src/types/bitcoin.ts +0 -98
- package/src/types/common.ts +0 -92
- package/src/types/credentials.ts +0 -88
- package/src/types/did.ts +0 -31
- package/src/types/external-shims.d.ts +0 -53
- package/src/types/index.ts +0 -7
- package/src/types/network.ts +0 -175
- package/src/utils/EventLogger.ts +0 -298
- package/src/utils/Logger.ts +0 -322
- package/src/utils/MetricsCollector.ts +0 -358
- package/src/utils/bitcoin-address.ts +0 -130
- package/src/utils/cbor.ts +0 -12
- package/src/utils/encoding.ts +0 -127
- package/src/utils/hash.ts +0 -6
- package/src/utils/retry.ts +0 -46
- package/src/utils/satoshi-validation.ts +0 -196
- package/src/utils/serialization.ts +0 -96
- package/src/utils/telemetry.ts +0 -40
- package/src/utils/validation.ts +0 -119
- package/src/vc/CredentialManager.ts +0 -918
- package/src/vc/Issuer.ts +0 -100
- package/src/vc/Verifier.ts +0 -47
- package/src/vc/cryptosuites/bbs.ts +0 -253
- package/src/vc/cryptosuites/bbsSimple.ts +0 -21
- package/src/vc/cryptosuites/eddsa.ts +0 -99
- package/src/vc/documentLoader.ts +0 -67
- package/src/vc/proofs/data-integrity.ts +0 -33
- package/src/vc/utils/jsonld.ts +0 -18
- package/tests/__mocks__/bbs-signatures.js +0 -17
- package/tests/__mocks__/mf-base58.js +0 -24
- package/tests/fixtures/did-documents.ts +0 -247
- package/tests/index.test.ts +0 -21
- package/tests/integration/BatchOperations.test.ts +0 -531
- package/tests/integration/CompleteLifecycle.e2e.test.ts +0 -735
- package/tests/integration/CredentialManager.test.ts +0 -42
- package/tests/integration/DIDManager.test.ts +0 -41
- package/tests/integration/DidPeerToWebVhFlow.test.ts +0 -351
- package/tests/integration/Events.test.ts +0 -435
- package/tests/integration/Lifecycle.transfer.btco.integration.test.ts +0 -25
- package/tests/integration/LifecycleManager.test.ts +0 -21
- package/tests/integration/MultikeyFlow.test.ts +0 -52
- package/tests/integration/TelemetryIntegration.test.ts +0 -395
- package/tests/integration/WebVhPublish.test.ts +0 -48
- package/tests/integration/createTypedOriginal.test.ts +0 -379
- package/tests/integration/migration/peer-to-webvh.test.ts +0 -172
- package/tests/manual/test-commit-creation.ts +0 -323
- package/tests/mocks/MockKeyStore.ts +0 -38
- package/tests/mocks/adapters/MemoryStorageAdapter.ts +0 -24
- package/tests/mocks/adapters/MockFeeOracle.ts +0 -11
- package/tests/mocks/adapters/MockOrdinalsProvider.ts +0 -76
- package/tests/mocks/adapters/OrdMockProvider.test.ts +0 -176
- package/tests/mocks/adapters/index.ts +0 -6
- package/tests/performance/BatchOperations.perf.test.ts +0 -403
- package/tests/performance/logging.perf.test.ts +0 -336
- package/tests/sdk.test.ts +0 -43
- package/tests/security/bitcoin-penetration-tests.test.ts +0 -622
- package/tests/setup.bun.ts +0 -69
- package/tests/setup.jest.ts +0 -23
- package/tests/stress/batch-operations-stress.test.ts +0 -571
- package/tests/unit/adapters/FeeOracleMock.test.ts +0 -40
- package/tests/unit/bitcoin/BitcoinManager.test.ts +0 -293
- package/tests/unit/bitcoin/BroadcastClient.test.ts +0 -52
- package/tests/unit/bitcoin/OrdNodeProvider.test.ts +0 -53
- package/tests/unit/bitcoin/OrdinalsClient.test.ts +0 -381
- package/tests/unit/bitcoin/OrdinalsClientProvider.test.ts +0 -102
- package/tests/unit/bitcoin/PSBTBuilder.test.ts +0 -84
- package/tests/unit/bitcoin/fee-calculation.test.ts +0 -261
- package/tests/unit/bitcoin/transactions/commit.test.ts +0 -649
- package/tests/unit/bitcoin/transfer.test.ts +0 -31
- package/tests/unit/bitcoin/utxo-selection-new.test.ts +0 -502
- package/tests/unit/bitcoin/utxo.more.test.ts +0 -39
- package/tests/unit/bitcoin/utxo.selection.test.ts +0 -38
- package/tests/unit/core/OriginalsSDK.test.ts +0 -152
- package/tests/unit/crypto/Multikey.test.ts +0 -206
- package/tests/unit/crypto/Signer.test.ts +0 -408
- package/tests/unit/did/BtcoDidResolver.test.ts +0 -611
- package/tests/unit/did/DIDManager.more.test.ts +0 -43
- package/tests/unit/did/DIDManager.test.ts +0 -185
- package/tests/unit/did/Ed25519Verifier.test.ts +0 -160
- package/tests/unit/did/KeyManager.test.ts +0 -452
- package/tests/unit/did/OrdinalsClientProviderAdapter.test.ts +0 -45
- package/tests/unit/did/WebVHManager.test.ts +0 -435
- package/tests/unit/did/createBtcoDidDocument.test.ts +0 -67
- package/tests/unit/did/providers/OrdinalsClientProviderAdapter.test.ts +0 -159
- package/tests/unit/events/EventEmitter.test.ts +0 -407
- package/tests/unit/kinds/KindRegistry.test.ts +0 -329
- package/tests/unit/kinds/types.test.ts +0 -409
- package/tests/unit/kinds/validators.test.ts +0 -651
- package/tests/unit/lifecycle/BatchOperations.test.ts +0 -527
- package/tests/unit/lifecycle/LifecycleManager.cleanapi.test.ts +0 -441
- package/tests/unit/lifecycle/LifecycleManager.keymanagement.test.ts +0 -312
- package/tests/unit/lifecycle/LifecycleManager.prov.test.ts +0 -18
- package/tests/unit/lifecycle/LifecycleManager.test.ts +0 -213
- package/tests/unit/lifecycle/LifecycleManager.transfer.unit.test.ts +0 -30
- package/tests/unit/lifecycle/OriginalsAsset.test.ts +0 -176
- package/tests/unit/lifecycle/ProvenanceQuery.test.ts +0 -577
- package/tests/unit/lifecycle/ResourceVersioning.test.ts +0 -651
- package/tests/unit/resources/ResourceManager.test.ts +0 -740
- package/tests/unit/storage/MemoryStorageAdapter.test.ts +0 -93
- package/tests/unit/types/network.test.ts +0 -255
- package/tests/unit/utils/EventIntegration.test.ts +0 -384
- package/tests/unit/utils/Logger.test.ts +0 -473
- package/tests/unit/utils/MetricsCollector.test.ts +0 -358
- package/tests/unit/utils/bitcoin-address.test.ts +0 -250
- package/tests/unit/utils/cbor.test.ts +0 -35
- package/tests/unit/utils/encoding.test.ts +0 -318
- package/tests/unit/utils/hash.test.ts +0 -12
- package/tests/unit/utils/retry.test.ts +0 -100
- package/tests/unit/utils/satoshi-validation.test.ts +0 -354
- package/tests/unit/utils/serialization.test.ts +0 -124
- package/tests/unit/utils/telemetry.test.ts +0 -52
- package/tests/unit/utils/validation.test.ts +0 -141
- package/tests/unit/vc/CredentialManager.helpers.test.ts +0 -527
- package/tests/unit/vc/CredentialManager.test.ts +0 -487
- package/tests/unit/vc/Issuer.test.ts +0 -107
- package/tests/unit/vc/Verifier.test.ts +0 -525
- package/tests/unit/vc/bbs.test.ts +0 -282
- package/tests/unit/vc/cryptosuites/eddsa.test.ts +0 -398
- package/tests/unit/vc/documentLoader.test.ts +0 -121
- package/tests/unit/vc/proofs/data-integrity.test.ts +0 -24
- package/tsconfig.json +0 -31
- package/tsconfig.test.json +0 -15
|
@@ -1,527 +0,0 @@
|
|
|
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
|
-
|