@uvrn/adapter 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +4 -0
- package/dist/index.js +7 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.js +36 -0
- package/dist/src/signer.d.ts +27 -0
- package/dist/src/signer.js +45 -0
- package/dist/src/types.d.ts +94 -0
- package/dist/src/types.js +8 -0
- package/dist/src/validator.d.ts +17 -0
- package/dist/src/validator.js +82 -0
- package/dist/src/wrapper.d.ts +41 -0
- package/dist/src/wrapper.js +92 -0
- package/dist/tests/integration.test.d.ts +5 -0
- package/dist/tests/integration.test.js +105 -0
- package/dist/tests/wrapper.test.d.ts +5 -0
- package/dist/tests/wrapper.test.js +96 -0
- package/jest.config.js +12 -0
- package/package.json +36 -0
- package/schemas/drvc3.schema.json +115 -0
- package/src/index.ts +16 -0
- package/src/signer.ts +47 -0
- package/src/types.ts +102 -0
- package/src/validator.ts +53 -0
- package/src/wrapper.ts +103 -0
- package/tests/integration.test.ts +123 -0
- package/tests/wrapper.test.ts +115 -0
- package/tsconfig.json +21 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration Tests
|
|
3
|
+
* Tests the full flow from DeltaBundle → DeltaReceipt → DRVC3Receipt
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Wallet, HDNodeWallet } from 'ethers';
|
|
7
|
+
import {
|
|
8
|
+
runDeltaEngine,
|
|
9
|
+
verifyReceipt,
|
|
10
|
+
DeltaBundle
|
|
11
|
+
} from '@uvrn/core';
|
|
12
|
+
import { wrapInDRVC3, extractDeltaReceipt, validateDRVC3 } from '../src';
|
|
13
|
+
|
|
14
|
+
describe('Integration: Layer 1 → Layer 2', () => {
|
|
15
|
+
let testWallet: HDNodeWallet;
|
|
16
|
+
|
|
17
|
+
beforeAll(() => {
|
|
18
|
+
testWallet = Wallet.createRandom();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should complete full flow: bundle → receipt → DRVC3', async () => {
|
|
22
|
+
// 1. Create a DeltaBundle (input to Layer 1)
|
|
23
|
+
const bundle: DeltaBundle = {
|
|
24
|
+
bundleId: 'integration-test-001',
|
|
25
|
+
claim: 'Integration Test',
|
|
26
|
+
thresholdPct: 0.1,
|
|
27
|
+
dataSpecs: [
|
|
28
|
+
{
|
|
29
|
+
id: 'source-1',
|
|
30
|
+
label: 'Source 1',
|
|
31
|
+
sourceKind: 'metric',
|
|
32
|
+
originDocIds: ['doc-1'],
|
|
33
|
+
metrics: [
|
|
34
|
+
{ key: 'revenue', value: 1000 },
|
|
35
|
+
{ key: 'users', value: 500 }
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: 'source-2',
|
|
40
|
+
label: 'Source 2',
|
|
41
|
+
sourceKind: 'metric',
|
|
42
|
+
originDocIds: ['doc-2'],
|
|
43
|
+
metrics: [
|
|
44
|
+
{ key: 'revenue', value: 1050 },
|
|
45
|
+
{ key: 'users', value: 510 }
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// 2. Run Layer 1 Engine
|
|
52
|
+
const deltaReceipt = runDeltaEngine(bundle);
|
|
53
|
+
|
|
54
|
+
// Verify Layer 1 receipt
|
|
55
|
+
const verifyResult = verifyReceipt(deltaReceipt);
|
|
56
|
+
expect(verifyResult.verified).toBe(true);
|
|
57
|
+
|
|
58
|
+
// 3. Wrap in DRVC3 (Layer 2)
|
|
59
|
+
const drvc3 = await wrapInDRVC3(deltaReceipt, testWallet, {
|
|
60
|
+
issuer: 'uvrn-integration',
|
|
61
|
+
event: 'delta-reconciliation',
|
|
62
|
+
tags: ['#uvrn', '#integration-test']
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// 4. Validate DRVC3 schema
|
|
66
|
+
const schemaResult = validateDRVC3(drvc3);
|
|
67
|
+
expect(schemaResult.valid).toBe(true);
|
|
68
|
+
|
|
69
|
+
// 5. Verify hash chain integrity
|
|
70
|
+
expect(drvc3.integrity.hash).toBe(deltaReceipt.hash);
|
|
71
|
+
|
|
72
|
+
// 6. Extract and verify embedded receipt
|
|
73
|
+
const extracted = extractDeltaReceipt(drvc3);
|
|
74
|
+
expect(extracted.hash).toBe(deltaReceipt.hash);
|
|
75
|
+
expect(verifyReceipt(extracted).verified).toBe(true);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should maintain hash integrity through Layer 2 wrapping', async () => {
|
|
79
|
+
const bundle: DeltaBundle = {
|
|
80
|
+
bundleId: 'hash-integrity-test',
|
|
81
|
+
claim: 'Hash Test',
|
|
82
|
+
thresholdPct: 0.05,
|
|
83
|
+
dataSpecs: [
|
|
84
|
+
{
|
|
85
|
+
id: 'a',
|
|
86
|
+
label: 'A',
|
|
87
|
+
sourceKind: 'metric',
|
|
88
|
+
originDocIds: [],
|
|
89
|
+
metrics: [{ key: 'val', value: 100 }]
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
id: 'b',
|
|
93
|
+
label: 'B',
|
|
94
|
+
sourceKind: 'metric',
|
|
95
|
+
originDocIds: [],
|
|
96
|
+
metrics: [{ key: 'val', value: 100 }]
|
|
97
|
+
}
|
|
98
|
+
]
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
const receipt = runDeltaEngine(bundle);
|
|
102
|
+
const originalHash = receipt.hash;
|
|
103
|
+
|
|
104
|
+
// Wrap multiple times - hash should always match
|
|
105
|
+
const drvc3_1 = await wrapInDRVC3(receipt, testWallet, {
|
|
106
|
+
issuer: 'test',
|
|
107
|
+
event: 'test'
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
const drvc3_2 = await wrapInDRVC3(receipt, testWallet, {
|
|
111
|
+
issuer: 'test',
|
|
112
|
+
event: 'test'
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Envelope metadata differs (receipt_id, timestamp)
|
|
116
|
+
expect(drvc3_1.receipt_id).not.toBe(drvc3_2.receipt_id);
|
|
117
|
+
expect(drvc3_1.timestamp).not.toBe(drvc3_2.timestamp);
|
|
118
|
+
|
|
119
|
+
// But hash domain remains identical
|
|
120
|
+
expect(drvc3_1.integrity.hash).toBe(originalHash);
|
|
121
|
+
expect(drvc3_2.integrity.hash).toBe(originalHash);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DRVC3 Wrapper Tests
|
|
3
|
+
* Tests the wrapInDRVC3 function and schema validation
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Wallet, HDNodeWallet } from 'ethers';
|
|
7
|
+
import { wrapInDRVC3, extractDeltaReceipt } from '../src/wrapper';
|
|
8
|
+
import { validateDRVC3 } from '../src/validator';
|
|
9
|
+
import { recoverSigner } from '../src/signer';
|
|
10
|
+
import { DeltaReceipt } from '@uvrn/core';
|
|
11
|
+
|
|
12
|
+
describe('DRVC3 Wrapper', () => {
|
|
13
|
+
// Mock DeltaReceipt (as would come from Layer 1)
|
|
14
|
+
const mockDeltaReceipt: DeltaReceipt = {
|
|
15
|
+
bundleId: 'test-bundle-001',
|
|
16
|
+
deltaFinal: 0.05,
|
|
17
|
+
sources: ['Source A', 'Source B'],
|
|
18
|
+
rounds: [
|
|
19
|
+
{
|
|
20
|
+
round: 1,
|
|
21
|
+
deltasByMetric: { revenue: 0.05, users: 0.0 },
|
|
22
|
+
withinThreshold: true,
|
|
23
|
+
witnessRequired: false
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
suggestedFixes: [],
|
|
27
|
+
outcome: 'consensus',
|
|
28
|
+
hash: 'a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2'
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
let testWallet: HDNodeWallet;
|
|
32
|
+
|
|
33
|
+
beforeAll(() => {
|
|
34
|
+
// Create a deterministic wallet for testing
|
|
35
|
+
testWallet = Wallet.createRandom();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should wrap DeltaReceipt in valid DRVC3 envelope', async () => {
|
|
39
|
+
const drvc3 = await wrapInDRVC3(mockDeltaReceipt, testWallet, {
|
|
40
|
+
issuer: 'uvrn-test',
|
|
41
|
+
event: 'delta-reconciliation'
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Check required fields
|
|
45
|
+
expect(drvc3.receipt_id).toMatch(/^drvc3-test-bundle-001-\d+$/);
|
|
46
|
+
expect(drvc3.issuer).toBe('uvrn-test');
|
|
47
|
+
expect(drvc3.event).toBe('delta-reconciliation');
|
|
48
|
+
expect(drvc3.timestamp).toBeDefined();
|
|
49
|
+
expect(drvc3.block_state).toBe('loose');
|
|
50
|
+
expect(drvc3.certificate).toBe('DRVC3 v1.0');
|
|
51
|
+
|
|
52
|
+
// Check integrity block
|
|
53
|
+
expect(drvc3.integrity.hash_algorithm).toBe('sha256');
|
|
54
|
+
expect(drvc3.integrity.hash).toBe(mockDeltaReceipt.hash);
|
|
55
|
+
expect(drvc3.integrity.signature_method).toBe('eip191');
|
|
56
|
+
expect(drvc3.integrity.signature).toBeDefined();
|
|
57
|
+
expect(drvc3.integrity.signer_address).toBe(testWallet.address);
|
|
58
|
+
|
|
59
|
+
// Check validation block
|
|
60
|
+
expect(drvc3.validation.v_score).toBe(mockDeltaReceipt.deltaFinal);
|
|
61
|
+
expect(drvc3.validation.checks.delta_receipt).toEqual(mockDeltaReceipt);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('should produce schema-valid DRVC3 receipt', async () => {
|
|
65
|
+
const drvc3 = await wrapInDRVC3(mockDeltaReceipt, testWallet, {
|
|
66
|
+
issuer: 'uvrn',
|
|
67
|
+
event: 'test'
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const result = validateDRVC3(drvc3);
|
|
71
|
+
expect(result.valid).toBe(true);
|
|
72
|
+
expect(result.errors).toBeUndefined();
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('should include optional fields when provided', async () => {
|
|
76
|
+
const drvc3 = await wrapInDRVC3(mockDeltaReceipt, testWallet, {
|
|
77
|
+
issuer: 'uvrn',
|
|
78
|
+
event: 'delta-reconciliation',
|
|
79
|
+
blockState: 'blocked',
|
|
80
|
+
certificate: 'DRVC3 v1.1',
|
|
81
|
+
description: 'Test receipt',
|
|
82
|
+
tags: ['#uvrn', '#receipt', '#test']
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
expect(drvc3.block_state).toBe('blocked');
|
|
86
|
+
expect(drvc3.certificate).toBe('DRVC3 v1.1');
|
|
87
|
+
expect(drvc3.description).toBe('Test receipt');
|
|
88
|
+
expect(drvc3.tags).toEqual(['#uvrn', '#receipt', '#test']);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('should create verifiable signature', async () => {
|
|
92
|
+
const drvc3 = await wrapInDRVC3(mockDeltaReceipt, testWallet, {
|
|
93
|
+
issuer: 'uvrn',
|
|
94
|
+
event: 'test'
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Recover signer from signature
|
|
98
|
+
const recoveredAddress = recoverSigner(
|
|
99
|
+
drvc3.integrity.hash,
|
|
100
|
+
drvc3.integrity.signature
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
expect(recoveredAddress.toLowerCase()).toBe(testWallet.address.toLowerCase());
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('should extract original DeltaReceipt from envelope', async () => {
|
|
107
|
+
const drvc3 = await wrapInDRVC3(mockDeltaReceipt, testWallet, {
|
|
108
|
+
issuer: 'uvrn',
|
|
109
|
+
event: 'test'
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const extracted = extractDeltaReceipt(drvc3);
|
|
113
|
+
expect(extracted).toEqual(mockDeltaReceipt);
|
|
114
|
+
});
|
|
115
|
+
});
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"lib": ["ES2020"],
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noImplicitAny": true,
|
|
9
|
+
"strictNullChecks": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"skipLibCheck": true,
|
|
12
|
+
"forceConsistentCasingInFileNames": true,
|
|
13
|
+
"moduleResolution": "node",
|
|
14
|
+
"resolveJsonModule": true,
|
|
15
|
+
"outDir": "./dist",
|
|
16
|
+
"rootDir": ".",
|
|
17
|
+
"baseUrl": "."
|
|
18
|
+
},
|
|
19
|
+
"include": ["src/**/*", "tests/**/*"],
|
|
20
|
+
"exclude": ["node_modules", "dist"]
|
|
21
|
+
}
|