@uvrn/core 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/core/engine.d.ts +3 -0
- package/dist/core/engine.d.ts.map +1 -0
- package/dist/core/engine.js +119 -0
- package/dist/core/engine.js.map +1 -0
- package/dist/core/serialization.d.ts +17 -0
- package/dist/core/serialization.d.ts.map +1 -0
- package/dist/core/serialization.js +40 -0
- package/dist/core/serialization.js.map +1 -0
- package/dist/core/validation.d.ts +7 -0
- package/dist/core/validation.d.ts.map +1 -0
- package/dist/core/validation.js +51 -0
- package/dist/core/validation.js.map +1 -0
- package/dist/core/verification.d.ts +7 -0
- package/dist/core/verification.d.ts.map +1 -0
- package/dist/core/verification.js +31 -0
- package/dist/core/verification.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/types/index.d.ts +55 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +36 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/core/engine.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,YAAY,EAEZ,UAAU,EAEX,MAAM,UAAU,CAAC;AA8BlB,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,YAAY,CAyGnF"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runDeltaEngine = runDeltaEngine;
|
|
4
|
+
const validation_1 = require("./validation");
|
|
5
|
+
const serialization_1 = require("./serialization");
|
|
6
|
+
/**
|
|
7
|
+
* Rounds a number to a fixed precision (8 decimal places) to mitigate FP hazards.
|
|
8
|
+
*/
|
|
9
|
+
function roundDet(num) {
|
|
10
|
+
return Math.round(num * 100000000) / 100000000;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Computes Delta between two numbers.
|
|
14
|
+
* Formula: |a - b| / ((a + b)/2)
|
|
15
|
+
*
|
|
16
|
+
* Rules:
|
|
17
|
+
* - If both 0 -> 0
|
|
18
|
+
* - If one 0, other != 0 -> 1.0 (Max Variance for this context)
|
|
19
|
+
*/
|
|
20
|
+
function computeDelta(a, b) {
|
|
21
|
+
if (a === 0 && b === 0)
|
|
22
|
+
return 0;
|
|
23
|
+
if (a === 0 || b === 0)
|
|
24
|
+
return 1.0;
|
|
25
|
+
const numerator = Math.abs(a - b);
|
|
26
|
+
const denominator = (a + b) / 2;
|
|
27
|
+
// Determine absolute delta
|
|
28
|
+
const rawDelta = numerator / denominator;
|
|
29
|
+
return roundDet(rawDelta);
|
|
30
|
+
}
|
|
31
|
+
function runDeltaEngine(bundle, opts) {
|
|
32
|
+
// 1. Validate
|
|
33
|
+
const validation = (0, validation_1.validateBundle)(bundle);
|
|
34
|
+
if (!validation.valid) {
|
|
35
|
+
throw new Error(`Invalid DeltaBundle: ${validation.error}`);
|
|
36
|
+
}
|
|
37
|
+
// 2. Sort DataSpecs (Stable Ordering)
|
|
38
|
+
const sortedSpecs = [...bundle.dataSpecs].sort((a, b) => a.id.localeCompare(b.id));
|
|
39
|
+
const sourceLabels = sortedSpecs.map(s => s.label);
|
|
40
|
+
// 3. Extract Comparable Metrics
|
|
41
|
+
const allKeys = new Set();
|
|
42
|
+
sortedSpecs.forEach(spec => {
|
|
43
|
+
spec.metrics.forEach(m => allKeys.add(m.key));
|
|
44
|
+
});
|
|
45
|
+
const sortedKeys = Array.from(allKeys).sort(); // Lexicographical sort
|
|
46
|
+
const comparableKeys = [];
|
|
47
|
+
for (const key of sortedKeys) {
|
|
48
|
+
let count = 0;
|
|
49
|
+
for (const spec of sortedSpecs) {
|
|
50
|
+
if (spec.metrics.some(m => m.key === key))
|
|
51
|
+
count++;
|
|
52
|
+
}
|
|
53
|
+
if (count >= 2) {
|
|
54
|
+
comparableKeys.push(key);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const maxRounds = bundle.maxRounds || 5;
|
|
58
|
+
const rounds = [];
|
|
59
|
+
let outcome = 'indeterminate';
|
|
60
|
+
// 4. Run Cycles
|
|
61
|
+
let currentRound = 0;
|
|
62
|
+
let finalDelta = 0;
|
|
63
|
+
while (currentRound < maxRounds) {
|
|
64
|
+
currentRound++;
|
|
65
|
+
const deltasByMetric = {};
|
|
66
|
+
let maxDeltaInRound = 0;
|
|
67
|
+
for (const key of comparableKeys) {
|
|
68
|
+
const values = [];
|
|
69
|
+
for (const spec of sortedSpecs) {
|
|
70
|
+
const m = spec.metrics.find(x => x.key === key);
|
|
71
|
+
if (m)
|
|
72
|
+
values.push(m.value);
|
|
73
|
+
}
|
|
74
|
+
const min = Math.min(...values);
|
|
75
|
+
const max = Math.max(...values);
|
|
76
|
+
const d = computeDelta(max, min);
|
|
77
|
+
deltasByMetric[key] = d;
|
|
78
|
+
if (d > maxDeltaInRound) {
|
|
79
|
+
maxDeltaInRound = d;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
finalDelta = maxDeltaInRound;
|
|
83
|
+
const within = maxDeltaInRound <= bundle.thresholdPct;
|
|
84
|
+
const roundData = {
|
|
85
|
+
round: currentRound,
|
|
86
|
+
deltasByMetric,
|
|
87
|
+
withinThreshold: within,
|
|
88
|
+
witnessRequired: !within && currentRound === maxRounds,
|
|
89
|
+
};
|
|
90
|
+
rounds.push(roundData);
|
|
91
|
+
if (within) {
|
|
92
|
+
outcome = 'consensus';
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
// Continue loop if not within threshold
|
|
96
|
+
}
|
|
97
|
+
if (outcome !== 'consensus') {
|
|
98
|
+
outcome = 'indeterminate';
|
|
99
|
+
}
|
|
100
|
+
// 5. Construct Receipt (excluding hash)
|
|
101
|
+
const receiptPayload = {
|
|
102
|
+
bundleId: bundle.bundleId,
|
|
103
|
+
deltaFinal: finalDelta,
|
|
104
|
+
sources: sourceLabels,
|
|
105
|
+
rounds,
|
|
106
|
+
suggestedFixes: [],
|
|
107
|
+
outcome,
|
|
108
|
+
};
|
|
109
|
+
if (opts?.timestamp) {
|
|
110
|
+
receiptPayload.ts = opts.timestamp;
|
|
111
|
+
}
|
|
112
|
+
// 6. Canonical Serialize & Hash
|
|
113
|
+
const hash = (0, serialization_1.hashReceipt)(receiptPayload);
|
|
114
|
+
return {
|
|
115
|
+
...receiptPayload,
|
|
116
|
+
hash
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/core/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delta Engine Core - Serialization & Hashing
|
|
3
|
+
* Implements canonical JSON serialization and SHA-256 hashing.
|
|
4
|
+
*/
|
|
5
|
+
import { DeltaReceipt } from '../types';
|
|
6
|
+
/**
|
|
7
|
+
* Canonically serializes an object (RFC 8785 style).
|
|
8
|
+
* - Object keys sorted lexicographically.
|
|
9
|
+
* - No whitespace.
|
|
10
|
+
*/
|
|
11
|
+
export declare function canonicalSerialize(obj: any): string;
|
|
12
|
+
/**
|
|
13
|
+
* Computes SHA-256 hash of the canonical serialization of the receipt payload.
|
|
14
|
+
* IMPORTANT: The hash matches the `canonicalSerialize` output.
|
|
15
|
+
*/
|
|
16
|
+
export declare function hashReceipt(receiptPayload: Omit<DeltaReceipt, 'hash'>): string;
|
|
17
|
+
//# sourceMappingURL=serialization.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialization.d.ts","sourceRoot":"","sources":["../../src/core/serialization.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,GAAG,GAAG,MAAM,CAkBnD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,cAAc,EAAE,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,GAAG,MAAM,CAG9E"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Delta Engine Core - Serialization & Hashing
|
|
4
|
+
* Implements canonical JSON serialization and SHA-256 hashing.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.canonicalSerialize = canonicalSerialize;
|
|
8
|
+
exports.hashReceipt = hashReceipt;
|
|
9
|
+
const crypto_1 = require("crypto");
|
|
10
|
+
/**
|
|
11
|
+
* Canonically serializes an object (RFC 8785 style).
|
|
12
|
+
* - Object keys sorted lexicographically.
|
|
13
|
+
* - No whitespace.
|
|
14
|
+
*/
|
|
15
|
+
function canonicalSerialize(obj) {
|
|
16
|
+
if (obj === undefined) {
|
|
17
|
+
return '';
|
|
18
|
+
}
|
|
19
|
+
if (obj === null || typeof obj !== 'object') {
|
|
20
|
+
return JSON.stringify(obj);
|
|
21
|
+
}
|
|
22
|
+
if (Array.isArray(obj)) {
|
|
23
|
+
return '[' + obj.map((item) => canonicalSerialize(item)).join(',') + ']';
|
|
24
|
+
}
|
|
25
|
+
const keys = Object.keys(obj).sort();
|
|
26
|
+
const acc = [];
|
|
27
|
+
for (const key of keys) {
|
|
28
|
+
acc.push(JSON.stringify(key) + ':' + canonicalSerialize(obj[key]));
|
|
29
|
+
}
|
|
30
|
+
return '{' + acc.join(',') + '}';
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Computes SHA-256 hash of the canonical serialization of the receipt payload.
|
|
34
|
+
* IMPORTANT: The hash matches the `canonicalSerialize` output.
|
|
35
|
+
*/
|
|
36
|
+
function hashReceipt(receiptPayload) {
|
|
37
|
+
const canonical = canonicalSerialize(receiptPayload);
|
|
38
|
+
return (0, crypto_1.createHash)('sha256').update(canonical).digest('hex');
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=serialization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serialization.js","sourceRoot":"","sources":["../../src/core/serialization.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAUH,gDAkBC;AAMD,kCAGC;AAnCD,mCAAoC;AAGpC;;;;GAIG;AACH,SAAgB,kBAAkB,CAAC,GAAQ;IACzC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IAC3E,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACrC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;AACnC,CAAC;AAED;;;GAGG;AACH,SAAgB,WAAW,CAAC,cAA0C;IACpE,MAAM,SAAS,GAAG,kBAAkB,CAAC,cAAc,CAAC,CAAC;IACrD,OAAO,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delta Engine Core - Validation Logic
|
|
3
|
+
* Structural validation only. No inference or enrichment.
|
|
4
|
+
*/
|
|
5
|
+
import { DeltaBundle, ValidationResult } from '../types';
|
|
6
|
+
export declare function validateBundle(bundle: DeltaBundle): ValidationResult;
|
|
7
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/core/validation.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEzD,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,gBAAgB,CAiDpE"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Delta Engine Core - Validation Logic
|
|
4
|
+
* Structural validation only. No inference or enrichment.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.validateBundle = validateBundle;
|
|
8
|
+
function validateBundle(bundle) {
|
|
9
|
+
if (!bundle) {
|
|
10
|
+
return { valid: false, error: 'Bundle is undefined or null' };
|
|
11
|
+
}
|
|
12
|
+
if (typeof bundle.bundleId !== 'string' || !bundle.bundleId) {
|
|
13
|
+
return { valid: false, error: 'Missing or invalid bundleId' };
|
|
14
|
+
}
|
|
15
|
+
if (typeof bundle.claim !== 'string' || !bundle.claim) {
|
|
16
|
+
return { valid: false, error: 'Missing or invalid claim' };
|
|
17
|
+
}
|
|
18
|
+
if (!Array.isArray(bundle.dataSpecs) || bundle.dataSpecs.length < 2) {
|
|
19
|
+
return { valid: false, error: 'dataSpecs must be an array with at least 2 items' };
|
|
20
|
+
}
|
|
21
|
+
// Validate thresholdPct
|
|
22
|
+
if (typeof bundle.thresholdPct !== 'number' || isNaN(bundle.thresholdPct)) {
|
|
23
|
+
return { valid: false, error: 'thresholdPct must be a valid number' };
|
|
24
|
+
}
|
|
25
|
+
if (bundle.thresholdPct <= 0 || bundle.thresholdPct > 1) {
|
|
26
|
+
return { valid: false, error: 'thresholdPct must be > 0 and <= 1' };
|
|
27
|
+
}
|
|
28
|
+
// Validate internals of dataSpecs
|
|
29
|
+
for (let i = 0; i < bundle.dataSpecs.length; i++) {
|
|
30
|
+
const spec = bundle.dataSpecs[i];
|
|
31
|
+
if (!spec.id || typeof spec.id !== 'string') {
|
|
32
|
+
return { valid: false, error: `DataSpec at index ${i} missing id` };
|
|
33
|
+
}
|
|
34
|
+
if (!spec.label || typeof spec.label !== 'string') {
|
|
35
|
+
return { valid: false, error: `DataSpec at index ${i} missing label` };
|
|
36
|
+
}
|
|
37
|
+
if (!Array.isArray(spec.metrics)) {
|
|
38
|
+
return { valid: false, error: `DataSpec at index ${i} metrics must be an array` };
|
|
39
|
+
}
|
|
40
|
+
for (const metric of spec.metrics) {
|
|
41
|
+
if (!metric.key || typeof metric.key !== 'string') {
|
|
42
|
+
return { valid: false, error: `DataSpec[${i}] has metric without key` };
|
|
43
|
+
}
|
|
44
|
+
if (typeof metric.value !== 'number' || isNaN(metric.value)) {
|
|
45
|
+
return { valid: false, error: `DataSpec[${i}] metric '${metric.key}' has invalid value` };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return { valid: true };
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/core/validation.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAIH,wCAiDC;AAjDD,SAAgB,cAAc,CAAC,MAAmB;IAChD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC;IAChE,CAAC;IAED,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC5D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC;IAChE,CAAC;IAED,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACtD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,0BAA0B,EAAE,CAAC;IAC7D,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,kDAAkD,EAAE,CAAC;IACrF,CAAC;IAED,wBAAwB;IACxB,IAAI,OAAO,MAAM,CAAC,YAAY,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;QAC1E,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,qCAAqC,EAAE,CAAC;IACxE,CAAC;IACD,IAAI,MAAM,CAAC,YAAY,IAAI,CAAC,IAAI,MAAM,CAAC,YAAY,GAAG,CAAC,EAAE,CAAC;QACxD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,mCAAmC,EAAE,CAAC;IACtE,CAAC;IAED,kCAAkC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACjD,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;YAC5C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,qBAAqB,CAAC,aAAa,EAAE,CAAC;QACtE,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YAClD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,qBAAqB,CAAC,gBAAgB,EAAE,CAAC;QACzE,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACjC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,qBAAqB,CAAC,2BAA2B,EAAE,CAAC;QACpF,CAAC;QAED,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,OAAO,MAAM,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAClD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC,0BAA0B,EAAE,CAAC;YAC1E,CAAC;YACD,IAAI,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC5D,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC,aAAa,MAAM,CAAC,GAAG,qBAAqB,EAAE,CAAC;YAC5F,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Delta Engine Core - Verification Logic
|
|
3
|
+
* Verify receipt integrity locally.
|
|
4
|
+
*/
|
|
5
|
+
import { DeltaReceipt, VerifyResult } from '../types';
|
|
6
|
+
export declare function verifyReceipt(receipt: DeltaReceipt): VerifyResult;
|
|
7
|
+
//# sourceMappingURL=verification.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification.d.ts","sourceRoot":"","sources":["../../src/core/verification.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAGtD,wBAAgB,aAAa,CAAC,OAAO,EAAE,YAAY,GAAG,YAAY,CAuBjE"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Delta Engine Core - Verification Logic
|
|
4
|
+
* Verify receipt integrity locally.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.verifyReceipt = verifyReceipt;
|
|
8
|
+
const serialization_1 = require("./serialization");
|
|
9
|
+
function verifyReceipt(receipt) {
|
|
10
|
+
if (!receipt) {
|
|
11
|
+
return { verified: false, error: 'Receipt is null or undefined' };
|
|
12
|
+
}
|
|
13
|
+
if (!receipt.hash) {
|
|
14
|
+
return { verified: false, error: 'Receipt missing hash' };
|
|
15
|
+
}
|
|
16
|
+
// extract hash and the rest
|
|
17
|
+
const { hash, ...payload } = receipt;
|
|
18
|
+
// Recompute hash
|
|
19
|
+
const computedHash = (0, serialization_1.hashReceipt)(payload);
|
|
20
|
+
if (computedHash === hash) {
|
|
21
|
+
return { verified: true, recomputedHash: computedHash };
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
return {
|
|
25
|
+
verified: false,
|
|
26
|
+
recomputedHash: computedHash,
|
|
27
|
+
error: `Hash mismatch. Provided: ${hash}, Computed: ${computedHash}`
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=verification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification.js","sourceRoot":"","sources":["../../src/core/verification.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAKH,sCAuBC;AAzBD,mDAA8C;AAE9C,SAAgB,aAAa,CAAC,OAAqB;IACjD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC;IACpE,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAC5D,CAAC;IAED,4BAA4B;IAC5B,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,GAAG,OAAO,CAAC;IAErC,iBAAiB;IACjB,MAAM,YAAY,GAAG,IAAA,2BAAW,EAAC,OAAO,CAAC,CAAC;IAE1C,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QAC1B,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,cAAc,EAAE,YAAY,EAAE,CAAC;IAC1D,CAAC;SAAM,CAAC;QACN,OAAO;YACL,QAAQ,EAAE,KAAK;YACf,cAAc,EAAE,YAAY;YAC5B,KAAK,EAAE,4BAA4B,IAAI,eAAe,YAAY,EAAE;SACrE,CAAC;IACJ,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loosechain Delta Engine Core
|
|
3
|
+
* Layer 1 Protocol Infrastructure
|
|
4
|
+
*/
|
|
5
|
+
export * from './types';
|
|
6
|
+
export * from './core/validation';
|
|
7
|
+
export * from './core/engine';
|
|
8
|
+
export * from './core/serialization';
|
|
9
|
+
export * from './core/verification';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,SAAS,CAAC;AACxB,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Loosechain Delta Engine Core
|
|
4
|
+
* Layer 1 Protocol Infrastructure
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
18
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
__exportStar(require("./types"), exports);
|
|
22
|
+
__exportStar(require("./core/validation"), exports);
|
|
23
|
+
__exportStar(require("./core/engine"), exports);
|
|
24
|
+
__exportStar(require("./core/serialization"), exports);
|
|
25
|
+
__exportStar(require("./core/verification"), exports);
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;;;;;;;;;;;;AAEH,0CAAwB;AACxB,oDAAkC;AAClC,gDAA8B;AAC9B,uDAAqC;AACrC,sDAAoC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loosechain Layer 1: Delta Engine Core - Types
|
|
3
|
+
* These types constitute the "Protocol Law" and must remain stable.
|
|
4
|
+
*/
|
|
5
|
+
export interface MetricPoint {
|
|
6
|
+
key: string;
|
|
7
|
+
value: number;
|
|
8
|
+
unit?: string;
|
|
9
|
+
ts?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface DataSpec {
|
|
12
|
+
id: string;
|
|
13
|
+
label: string;
|
|
14
|
+
sourceKind: 'report' | 'metric' | 'chart' | 'meta';
|
|
15
|
+
originDocIds: string[];
|
|
16
|
+
metrics: MetricPoint[];
|
|
17
|
+
}
|
|
18
|
+
export interface DeltaBundle {
|
|
19
|
+
bundleId: string;
|
|
20
|
+
claim: string;
|
|
21
|
+
dataSpecs: DataSpec[];
|
|
22
|
+
thresholdPct: number;
|
|
23
|
+
maxRounds?: number;
|
|
24
|
+
}
|
|
25
|
+
export interface DeltaRound {
|
|
26
|
+
round: number;
|
|
27
|
+
deltasByMetric: Record<string, number>;
|
|
28
|
+
withinThreshold: boolean;
|
|
29
|
+
witnessRequired: boolean;
|
|
30
|
+
notes?: string[];
|
|
31
|
+
}
|
|
32
|
+
export type Outcome = 'consensus' | 'indeterminate';
|
|
33
|
+
export interface DeltaReceipt {
|
|
34
|
+
bundleId: string;
|
|
35
|
+
deltaFinal: number;
|
|
36
|
+
sources: string[];
|
|
37
|
+
rounds: DeltaRound[];
|
|
38
|
+
suggestedFixes: [];
|
|
39
|
+
outcome: Outcome;
|
|
40
|
+
ts?: string;
|
|
41
|
+
hash: string;
|
|
42
|
+
}
|
|
43
|
+
export interface ValidationResult {
|
|
44
|
+
valid: boolean;
|
|
45
|
+
error?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface VerifyResult {
|
|
48
|
+
verified: boolean;
|
|
49
|
+
recomputedHash?: string;
|
|
50
|
+
error?: string;
|
|
51
|
+
}
|
|
52
|
+
export interface EngineOpts {
|
|
53
|
+
timestamp?: string;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;IACnD,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,MAAM,OAAO,GAAG,WAAW,GAAG,eAAe,CAAC;AAEpD,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,cAAc,EAAE,EAAE,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IAEzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":";AAAA;;;GAGG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@uvrn/core",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "UVRN engine core — deterministic protocol infrastructure",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"uvrn",
|
|
9
|
+
"deterministic",
|
|
10
|
+
"protocol",
|
|
11
|
+
"consensus"
|
|
12
|
+
],
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@types/jest": "^29.5.0",
|
|
16
|
+
"@types/node": "^20.0.0",
|
|
17
|
+
"@typescript-eslint/eslint-plugin": "^6.0.0",
|
|
18
|
+
"@typescript-eslint/parser": "^6.0.0",
|
|
19
|
+
"eslint": "^8.0.0",
|
|
20
|
+
"jest": "^29.5.0",
|
|
21
|
+
"ts-jest": "^29.1.0",
|
|
22
|
+
"typescript": "^5.3.0"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {},
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=18.0.0"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsc",
|
|
30
|
+
"test": "jest",
|
|
31
|
+
"test:watch": "jest --watch",
|
|
32
|
+
"test:coverage": "jest --coverage",
|
|
33
|
+
"lint": "eslint src/**/*.ts",
|
|
34
|
+
"clean": "rm -rf dist"
|
|
35
|
+
}
|
|
36
|
+
}
|