@uvrn/adapter 1.0.2 → 1.0.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/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  UVRN DRVC3 envelope adapter — wraps Delta Engine receipts in DRVC3 envelopes with EIP-191 signatures. Use this when you need to attach issuer identity and signing to core receipts without changing their deterministic hash.
4
4
 
5
+ **Disclaimer:** UVRN is in Alpha testing. The engine measures whether your sources agree with each other — not whether they’re correct. Final trust of output rests with the user. Use at your own risk. Have fun.
6
+
5
7
  ## Install
6
8
 
7
9
  ```bash
@@ -5,4 +5,4 @@
5
5
  export * from './types';
6
6
  export { wrapInDRVC3, extractDeltaReceipt } from './wrapper';
7
7
  export { signHash, recoverSigner, verifySignature } from './signer';
8
- export { validateDRVC3, isDRVC3Receipt } from './validator';
8
+ export { validateDRVC3, isDRVC3Receipt, verifyDRVC3Integrity } from './validator';
package/dist/src/index.js CHANGED
@@ -18,7 +18,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
18
18
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
19
19
  };
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.isDRVC3Receipt = exports.validateDRVC3 = exports.verifySignature = exports.recoverSigner = exports.signHash = exports.extractDeltaReceipt = exports.wrapInDRVC3 = void 0;
21
+ exports.verifyDRVC3Integrity = exports.isDRVC3Receipt = exports.validateDRVC3 = exports.verifySignature = exports.recoverSigner = exports.signHash = exports.extractDeltaReceipt = exports.wrapInDRVC3 = void 0;
22
22
  // Types
23
23
  __exportStar(require("./types"), exports);
24
24
  // Core wrapper
@@ -30,7 +30,8 @@ var signer_1 = require("./signer");
30
30
  Object.defineProperty(exports, "signHash", { enumerable: true, get: function () { return signer_1.signHash; } });
31
31
  Object.defineProperty(exports, "recoverSigner", { enumerable: true, get: function () { return signer_1.recoverSigner; } });
32
32
  Object.defineProperty(exports, "verifySignature", { enumerable: true, get: function () { return signer_1.verifySignature; } });
33
- // Validation
33
+ // Validation (validateDRVC3 is schema-only; use verifyDRVC3Integrity for full integrity)
34
34
  var validator_1 = require("./validator");
35
35
  Object.defineProperty(exports, "validateDRVC3", { enumerable: true, get: function () { return validator_1.validateDRVC3; } });
36
36
  Object.defineProperty(exports, "isDRVC3Receipt", { enumerable: true, get: function () { return validator_1.isDRVC3Receipt; } });
37
+ Object.defineProperty(exports, "verifyDRVC3Integrity", { enumerable: true, get: function () { return validator_1.verifyDRVC3Integrity; } });
@@ -1,17 +1,34 @@
1
1
  /**
2
- * DRVC3 Schema Validator
3
- * Uses ajv to validate DRVC3 receipts against the official schema
2
+ * DRVC3 Schema Validator and Integrity Verification
3
+ * - validateDRVC3: schema-only (structure); does not verify signatures or embedded receipt hash.
4
+ * - verifyDRVC3Integrity: full integrity check (schema + signature + core receipt hash).
4
5
  */
5
6
  import { DRVC3ValidationResult } from './types';
6
7
  /**
7
- * Validates a DRVC3 receipt against the official schema
8
+ * Validates a DRVC3 receipt against the official schema only.
9
+ * Does not verify cryptographic signature or embedded receipt hash.
10
+ * For full integrity check, use verifyDRVC3Integrity().
11
+ *
8
12
  * @param receipt - The receipt object to validate
9
13
  * @returns Validation result with errors if invalid
10
14
  */
11
15
  export declare function validateDRVC3(receipt: unknown): DRVC3ValidationResult;
12
16
  /**
13
- * Type guard to check if an object is a valid DRVC3 receipt
17
+ * Type guard to check if an object is a valid DRVC3 receipt (schema-only).
14
18
  * @param obj - Object to check
15
19
  * @returns True if the object is a valid DRVC3 receipt
16
20
  */
17
21
  export declare function isDRVC3Receipt(obj: unknown): boolean;
22
+ /**
23
+ * Full integrity verification: schema, EIP-191 signature, and embedded receipt hash.
24
+ * Use this before trusting envelope contents; extractDeltaReceipt is safe after this passes.
25
+ *
26
+ * @param drvc3 - DRVC3 envelope to verify
27
+ * @returns Object with verified: true, or verified: false and error message
28
+ */
29
+ export declare function verifyDRVC3Integrity(drvc3: unknown): {
30
+ verified: true;
31
+ } | {
32
+ verified: false;
33
+ error: string;
34
+ };
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  /**
3
- * DRVC3 Schema Validator
4
- * Uses ajv to validate DRVC3 receipts against the official schema
3
+ * DRVC3 Schema Validator and Integrity Verification
4
+ * - validateDRVC3: schema-only (structure); does not verify signatures or embedded receipt hash.
5
+ * - verifyDRVC3Integrity: full integrity check (schema + signature + core receipt hash).
5
6
  */
6
7
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
8
  if (k2 === undefined) k2 = k;
@@ -42,9 +43,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
42
43
  Object.defineProperty(exports, "__esModule", { value: true });
43
44
  exports.validateDRVC3 = validateDRVC3;
44
45
  exports.isDRVC3Receipt = isDRVC3Receipt;
46
+ exports.verifyDRVC3Integrity = verifyDRVC3Integrity;
47
+ const core_1 = require("@uvrn/core");
45
48
  const ajv_1 = __importDefault(require("ajv"));
46
49
  const path = __importStar(require("path"));
47
50
  const fs = __importStar(require("fs"));
51
+ const signer_1 = require("./signer");
52
+ const wrapper_1 = require("./wrapper");
48
53
  // Load schema from file
49
54
  const schemaPath = path.join(__dirname, '../schemas/drvc3.schema.json');
50
55
  const drvc3Schema = JSON.parse(fs.readFileSync(schemaPath, 'utf-8'));
@@ -57,7 +62,10 @@ addFormats(ajv);
57
62
  // Compile the schema once
58
63
  const validateSchema = ajv.compile(drvc3Schema);
59
64
  /**
60
- * Validates a DRVC3 receipt against the official schema
65
+ * Validates a DRVC3 receipt against the official schema only.
66
+ * Does not verify cryptographic signature or embedded receipt hash.
67
+ * For full integrity check, use verifyDRVC3Integrity().
68
+ *
61
69
  * @param receipt - The receipt object to validate
62
70
  * @returns Validation result with errors if invalid
63
71
  */
@@ -73,10 +81,38 @@ function validateDRVC3(receipt) {
73
81
  return { valid: false, errors };
74
82
  }
75
83
  /**
76
- * Type guard to check if an object is a valid DRVC3 receipt
84
+ * Type guard to check if an object is a valid DRVC3 receipt (schema-only).
77
85
  * @param obj - Object to check
78
86
  * @returns True if the object is a valid DRVC3 receipt
79
87
  */
80
88
  function isDRVC3Receipt(obj) {
81
89
  return validateDRVC3(obj).valid;
82
90
  }
91
+ /**
92
+ * Full integrity verification: schema, EIP-191 signature, and embedded receipt hash.
93
+ * Use this before trusting envelope contents; extractDeltaReceipt is safe after this passes.
94
+ *
95
+ * @param drvc3 - DRVC3 envelope to verify
96
+ * @returns Object with verified: true, or verified: false and error message
97
+ */
98
+ function verifyDRVC3Integrity(drvc3) {
99
+ const schemaResult = validateDRVC3(drvc3);
100
+ if (!schemaResult.valid) {
101
+ return { verified: false, error: schemaResult.errors?.join('; ') ?? 'Schema validation failed' };
102
+ }
103
+ const envelope = drvc3;
104
+ const { integrity, validation } = envelope;
105
+ if (!validation?.checks?.delta_receipt) {
106
+ return { verified: false, error: 'Missing validation.checks.delta_receipt' };
107
+ }
108
+ const receipt = (0, wrapper_1.extractDeltaReceipt)(envelope);
109
+ const coreResult = (0, core_1.verifyReceipt)(receipt);
110
+ if (!coreResult.verified) {
111
+ return { verified: false, error: `Embedded receipt: ${coreResult.error}` };
112
+ }
113
+ const sigOk = (0, signer_1.verifySignature)(integrity.hash, integrity.signature, integrity.signer_address);
114
+ if (!sigOk) {
115
+ return { verified: false, error: 'Signature verification failed' };
116
+ }
117
+ return { verified: true };
118
+ }
@@ -33,9 +33,10 @@ import { DRVC3Receipt, WrapOptions } from './types';
33
33
  */
34
34
  export declare function wrapInDRVC3(deltaReceipt: DeltaReceipt, signer: Wallet | HDNodeWallet, options: WrapOptions): Promise<DRVC3Receipt>;
35
35
  /**
36
- * Extracts the original DeltaReceipt from a DRVC3 envelope
36
+ * Extracts the original DeltaReceipt from a DRVC3 envelope.
37
+ * Does not verify signature or receipt hash; for untrusted input use verifyDRVC3Integrity() first, then extract.
37
38
  *
38
- * @param drvc3 - DRVC3 receipt envelope
39
+ * @param drvc3 - DRVC3 receipt envelope (must have validation.checks.delta_receipt)
39
40
  * @returns The embedded DeltaReceipt
40
41
  */
41
42
  export declare function extractDeltaReceipt(drvc3: DRVC3Receipt): DeltaReceipt;
@@ -10,6 +10,7 @@
10
10
  Object.defineProperty(exports, "__esModule", { value: true });
11
11
  exports.wrapInDRVC3 = wrapInDRVC3;
12
12
  exports.extractDeltaReceipt = extractDeltaReceipt;
13
+ const core_1 = require("@uvrn/core");
13
14
  const signer_1 = require("./signer");
14
15
  /**
15
16
  * Wraps a DeltaReceipt in a DRVC3 envelope
@@ -34,14 +35,19 @@ const signer_1 = require("./signer");
34
35
  * ```
35
36
  */
36
37
  async function wrapInDRVC3(deltaReceipt, signer, options) {
37
- // 1. Generate receipt_id (ENVELOPE METADATA - non-deterministic, intentional)
38
+ // 1. Verify receipt integrity before attesting (do not sign tampered payloads)
39
+ const coreVerify = (0, core_1.verifyReceipt)(deltaReceipt);
40
+ if (!coreVerify.verified) {
41
+ throw new Error(`Cannot wrap invalid receipt: ${coreVerify.error}`);
42
+ }
43
+ // 2. Generate receipt_id (ENVELOPE METADATA - non-deterministic, intentional)
38
44
  const timestamp = new Date().toISOString();
39
45
  const receipt_id = `drvc3-${deltaReceipt.bundleId}-${Date.now()}`;
40
- // 2. Read hash from DeltaReceipt (HASH DOMAIN - read-only from Layer 1)
46
+ // 3. Read hash from DeltaReceipt (HASH DOMAIN - read-only from Layer 1)
41
47
  const hash = deltaReceipt.hash;
42
- // 3. Sign hash with EIP-191 (ENVELOPE METADATA - certifies "who" and "when")
48
+ // 4. Sign hash with EIP-191 (ENVELOPE METADATA - certifies "who" and "when")
43
49
  const signature = await (0, signer_1.signHash)(hash, signer);
44
- // 4. Construct DRVC3 envelope
50
+ // 5. Construct DRVC3 envelope
45
51
  const drvc3 = {
46
52
  receipt_id,
47
53
  issuer: options.issuer,
@@ -82,9 +88,10 @@ async function wrapInDRVC3(deltaReceipt, signer, options) {
82
88
  return drvc3;
83
89
  }
84
90
  /**
85
- * Extracts the original DeltaReceipt from a DRVC3 envelope
91
+ * Extracts the original DeltaReceipt from a DRVC3 envelope.
92
+ * Does not verify signature or receipt hash; for untrusted input use verifyDRVC3Integrity() first, then extract.
86
93
  *
87
- * @param drvc3 - DRVC3 receipt envelope
94
+ * @param drvc3 - DRVC3 receipt envelope (must have validation.checks.delta_receipt)
88
95
  * @returns The embedded DeltaReceipt
89
96
  */
90
97
  function extractDeltaReceipt(drvc3) {
@@ -5,31 +5,25 @@
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  const ethers_1 = require("ethers");
8
+ const core_1 = require("@uvrn/core");
8
9
  const wrapper_1 = require("../src/wrapper");
9
10
  const validator_1 = require("../src/validator");
10
11
  const signer_1 = require("../src/signer");
11
12
  describe('DRVC3 Wrapper', () => {
12
- // Mock DeltaReceipt (as would come from Layer 1)
13
- const mockDeltaReceipt = {
14
- bundleId: 'test-bundle-001',
15
- deltaFinal: 0.05,
16
- sources: ['Source A', 'Source B'],
17
- rounds: [
18
- {
19
- round: 1,
20
- deltasByMetric: { revenue: 0.05, users: 0.0 },
21
- withinThreshold: true,
22
- witnessRequired: false
23
- }
24
- ],
25
- suggestedFixes: [],
26
- outcome: 'consensus',
27
- hash: 'a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2'
28
- };
13
+ let mockDeltaReceipt;
29
14
  let testWallet;
30
15
  beforeAll(() => {
31
- // Create a deterministic wallet for testing
32
16
  testWallet = ethers_1.Wallet.createRandom();
17
+ const bundle = {
18
+ bundleId: 'test-bundle-001',
19
+ claim: 'Test claim',
20
+ dataSpecs: [
21
+ { id: 's1', label: 'Source A', sourceKind: 'report', originDocIds: [], metrics: [{ key: 'k', value: 10 }] },
22
+ { id: 's2', label: 'Source B', sourceKind: 'report', originDocIds: [], metrics: [{ key: 'k', value: 10.5 }] }
23
+ ],
24
+ thresholdPct: 0.1
25
+ };
26
+ mockDeltaReceipt = (0, core_1.runDeltaEngine)(bundle);
33
27
  });
34
28
  it('should wrap DeltaReceipt in valid DRVC3 envelope', async () => {
35
29
  const drvc3 = await (0, wrapper_1.wrapInDRVC3)(mockDeltaReceipt, testWallet, {
@@ -42,7 +36,7 @@ describe('DRVC3 Wrapper', () => {
42
36
  expect(drvc3.event).toBe('delta-reconciliation');
43
37
  expect(drvc3.timestamp).toBeDefined();
44
38
  expect(drvc3.block_state).toBe('loose');
45
- expect(drvc3.certificate).toBe('DRVC3 v1.0');
39
+ expect(drvc3.certificate).toBe('DRVC3 v1.01');
46
40
  // Check integrity block
47
41
  expect(drvc3.integrity.hash_algorithm).toBe('sha256');
48
42
  expect(drvc3.integrity.hash).toBe(mockDeltaReceipt.hash);
@@ -91,6 +85,8 @@ describe('DRVC3 Wrapper', () => {
91
85
  event: 'test'
92
86
  });
93
87
  const extracted = (0, wrapper_1.extractDeltaReceipt)(drvc3);
94
- expect(extracted).toEqual(mockDeltaReceipt);
88
+ expect(extracted.bundleId).toBe(mockDeltaReceipt.bundleId);
89
+ expect(extracted.hash).toBe(mockDeltaReceipt.hash);
90
+ expect(extracted.outcome).toBe(mockDeltaReceipt.outcome);
95
91
  });
96
92
  });
package/package.json CHANGED
@@ -1,6 +1,9 @@
1
1
  {
2
2
  "name": "@uvrn/adapter",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
4
7
  "description": "UVRN DRVC3 envelope adapter — wraps core receipts with EIP-191 signatures",
5
8
  "main": "dist/index.js",
6
9
  "types": "dist/index.d.ts",
@@ -21,7 +24,7 @@
21
24
  "ethers": "^6.0.0",
22
25
  "ajv": "^8.12.0",
23
26
  "ajv-formats": "^2.1.1",
24
- "@uvrn/core": "1.0.2"
27
+ "@uvrn/core": "^1.0.3"
25
28
  },
26
29
  "devDependencies": {
27
30
  "@types/jest": "^29.5.0",
@@ -33,6 +36,10 @@
33
36
  "engines": {
34
37
  "node": ">=18.0.0"
35
38
  },
39
+ "files": [
40
+ "dist",
41
+ "README.md"
42
+ ],
36
43
  "scripts": {
37
44
  "build": "tsc",
38
45
  "test": "jest",
package/jest.config.js DELETED
@@ -1,12 +0,0 @@
1
- /** @type {import('ts-jest').JestConfigWithTsJest} */
2
- module.exports = {
3
- preset: 'ts-jest',
4
- testEnvironment: 'node',
5
- testMatch: ['**/tests/**/*.test.ts'],
6
- moduleFileExtensions: ['ts', 'js', 'json'],
7
- collectCoverageFrom: ['src/**/*.ts'],
8
- moduleNameMapper: {
9
- '^@uvrn/core$': '<rootDir>/../uvrn-core/src'
10
- }
11
- };
12
-
@@ -1,115 +0,0 @@
1
- {
2
- "$schema": "http://json-schema.org/draft-07/schema#",
3
- "$id": "https://uvrn.org/schemas/drvc3.v1.01.json",
4
- "title": "DRVC3 Receipt v1.01",
5
- "description": "DRVC3 envelope with Layer 2 extensions support. Backward-compatible with v1.0.",
6
- "type": "object",
7
- "required": [
8
- "receipt_id",
9
- "issuer",
10
- "event",
11
- "timestamp",
12
- "integrity",
13
- "block_state",
14
- "certificate"
15
- ],
16
- "properties": {
17
- "receipt_id": {
18
- "type": "string"
19
- },
20
- "issuer": {
21
- "type": "string"
22
- },
23
- "event": {
24
- "type": "string"
25
- },
26
- "timestamp": {
27
- "type": "string",
28
- "format": "date-time"
29
- },
30
- "description": {
31
- "type": "string"
32
- },
33
- "resource": {
34
- "type": "object",
35
- "properties": {
36
- "type": {
37
- "type": "string"
38
- },
39
- "url": {
40
- "type": "string"
41
- },
42
- "branch": {
43
- "type": "string"
44
- },
45
- "commit_hash": {
46
- "type": "string"
47
- }
48
- }
49
- },
50
- "integrity": {
51
- "type": "object",
52
- "required": [
53
- "hash_algorithm",
54
- "hash",
55
- "signature_method",
56
- "signature",
57
- "signer_address"
58
- ],
59
- "properties": {
60
- "hash_algorithm": {
61
- "enum": [
62
- "sha256"
63
- ]
64
- },
65
- "hash": {
66
- "type": "string"
67
- },
68
- "signature_method": {
69
- "enum": [
70
- "eip191"
71
- ]
72
- },
73
- "signature": {
74
- "type": "string"
75
- },
76
- "signer_address": {
77
- "type": "string"
78
- }
79
- }
80
- },
81
- "validation": {
82
- "type": "object",
83
- "properties": {
84
- "v_score": {
85
- "type": "number"
86
- },
87
- "checks": {
88
- "type": "object"
89
- }
90
- }
91
- },
92
- "block_state": {
93
- "enum": [
94
- "loose",
95
- "blocked"
96
- ]
97
- },
98
- "certificate": {
99
- "type": "string"
100
- },
101
- "replay_instructions": {
102
- "type": "object"
103
- },
104
- "tags": {
105
- "type": "array",
106
- "items": {
107
- "type": "string"
108
- }
109
- },
110
- "extensions": {
111
- "type": "object",
112
- "description": "Layer 2 provenance data — source URLs, timestamps, evidence links, domain metadata. Not covered by L1 integrity hash."
113
- }
114
- }
115
- }
package/src/index.ts DELETED
@@ -1,16 +0,0 @@
1
- /**
2
- * Loosechain UVRN Adapter
3
- * Layer 2 - Wraps Delta Engine Core receipts in DRVC3 envelopes
4
- */
5
-
6
- // Types
7
- export * from './types';
8
-
9
- // Core wrapper
10
- export { wrapInDRVC3, extractDeltaReceipt } from './wrapper';
11
-
12
- // Signing utilities
13
- export { signHash, recoverSigner, verifySignature } from './signer';
14
-
15
- // Validation
16
- export { validateDRVC3, isDRVC3Receipt } from './validator';
package/src/signer.ts DELETED
@@ -1,47 +0,0 @@
1
- /**
2
- * EIP-191 Signing Utilities
3
- * Provides Ethereum personal message signing for DRVC3 receipts
4
- */
5
-
6
- import { Wallet, HDNodeWallet, verifyMessage } from 'ethers';
7
-
8
- /**
9
- * Signs a hash using EIP-191 (Ethereum Signed Message)
10
- * @param hash - The hex string hash to sign
11
- * @param wallet - ethers Wallet instance with private key
12
- * @returns Promise resolving to the signature hex string
13
- */
14
- export async function signHash(hash: string, wallet: Wallet | HDNodeWallet): Promise<string> {
15
- // signMessage automatically prefixes with "\x19Ethereum Signed Message:\n" + message length
16
- return wallet.signMessage(hash);
17
- }
18
-
19
- /**
20
- * Recovers the signer address from a hash and signature
21
- * @param hash - The original hash that was signed
22
- * @param signature - The EIP-191 signature
23
- * @returns The signer's Ethereum address
24
- */
25
- export function recoverSigner(hash: string, signature: string): string {
26
- return verifyMessage(hash, signature);
27
- }
28
-
29
- /**
30
- * Verifies that a signature was created by the expected signer
31
- * @param hash - The original hash that was signed
32
- * @param signature - The EIP-191 signature
33
- * @param expectedAddress - The expected signer address
34
- * @returns True if the signature is valid and matches the expected address
35
- */
36
- export function verifySignature(
37
- hash: string,
38
- signature: string,
39
- expectedAddress: string
40
- ): boolean {
41
- try {
42
- const recoveredAddress = recoverSigner(hash, signature);
43
- return recoveredAddress.toLowerCase() === expectedAddress.toLowerCase();
44
- } catch {
45
- return false;
46
- }
47
- }
package/src/types.ts DELETED
@@ -1,102 +0,0 @@
1
- /**
2
- * DRVC3 Types for UVRN Adapter (v1.01)
3
- * Layer 2 envelope types that wrap Layer 1 DeltaReceipt
4
- *
5
- * v1.01 adds the `extensions` field for Layer 2 provenance data.
6
- */
7
-
8
- import { DeltaReceipt } from '@uvrn/core';
9
-
10
- /**
11
- * DRVC3 Integrity block - contains hash and signature data
12
- */
13
- export interface DRVC3Integrity {
14
- hash_algorithm: 'sha256';
15
- hash: string;
16
- signature_method: 'eip191';
17
- signature: string;
18
- signer_address: string;
19
- }
20
-
21
- /**
22
- * DRVC3 Validation block - contains score and embedded checks
23
- */
24
- export interface DRVC3Validation {
25
- v_score: number;
26
- checks: {
27
- delta_receipt: DeltaReceipt;
28
- [key: string]: unknown;
29
- };
30
- }
31
-
32
- /**
33
- * DRVC3 Resource block (optional) - describes the verified resource
34
- */
35
- export interface DRVC3Resource {
36
- type?: string;
37
- url?: string;
38
- branch?: string;
39
- commit_hash?: string;
40
- }
41
-
42
- /**
43
- * Block state - "loose" means mutable/portable, "blocked" means canonized/permanent
44
- */
45
- export type BlockState = 'loose' | 'blocked';
46
-
47
- /**
48
- * Full DRVC3 Receipt Envelope
49
- * Wraps Layer 1 DeltaReceipt with protocol metadata and signatures
50
- */
51
- export interface DRVC3Receipt {
52
- receipt_id: string;
53
- issuer: string;
54
- event: string;
55
- timestamp: string;
56
- description?: string;
57
- resource?: DRVC3Resource;
58
- integrity: DRVC3Integrity;
59
- validation: DRVC3Validation;
60
- block_state: BlockState;
61
- certificate: string;
62
- replay_instructions?: Record<string, unknown>;
63
- tags?: string[];
64
- /**
65
- * Layer 2 extension data — provenance, evidence, domain-specific metadata.
66
- * This field is NOT covered by the L1 integrity hash. It is envelope metadata
67
- * owned by the consumer chain (e.g., MarketChain source URLs, evidence links).
68
- */
69
- extensions?: Record<string, unknown>;
70
- }
71
-
72
- /**
73
- * Options for wrapping a DeltaReceipt in DRVC3 envelope
74
- */
75
- export interface WrapOptions {
76
- /** Issuer identifier (e.g., "uvrn", "app.example.com") */
77
- issuer: string;
78
- /** Event type (e.g., "delta-reconciliation") */
79
- event: string;
80
- /** Block state - defaults to "loose" */
81
- blockState?: BlockState;
82
- /** DRVC3 certificate version - defaults to "DRVC3 v1.0" */
83
- certificate?: string;
84
- /** Optional description */
85
- description?: string;
86
- /** Optional resource metadata */
87
- resource?: DRVC3Resource;
88
- /** Optional replay instructions */
89
- replayInstructions?: Record<string, unknown>;
90
- /** Optional tags (e.g., ["#uvrn", "#receipt"]) */
91
- tags?: string[];
92
- /** Optional Layer 2 extension data (provenance, evidence, domain metadata) */
93
- extensions?: Record<string, unknown>;
94
- }
95
-
96
- /**
97
- * Validation result from schema validation
98
- */
99
- export interface DRVC3ValidationResult {
100
- valid: boolean;
101
- errors?: string[];
102
- }
package/src/validator.ts DELETED
@@ -1,53 +0,0 @@
1
- /**
2
- * DRVC3 Schema Validator
3
- * Uses ajv to validate DRVC3 receipts against the official schema
4
- */
5
-
6
- import Ajv from 'ajv';
7
- import * as path from 'path';
8
- import * as fs from 'fs';
9
- import { DRVC3ValidationResult } from './types';
10
-
11
- // Load schema from file
12
- const schemaPath = path.join(__dirname, '../schemas/drvc3.schema.json');
13
- const drvc3Schema = JSON.parse(fs.readFileSync(schemaPath, 'utf-8'));
14
-
15
- // Initialize Ajv with JSON Schema 2020-12 support
16
- const ajv = new Ajv({ strict: false });
17
-
18
- // Add formats support (date-time, etc.)
19
- // eslint-disable-next-line @typescript-eslint/no-var-requires
20
- const addFormats = require('ajv-formats');
21
- addFormats(ajv);
22
-
23
- // Compile the schema once
24
- const validateSchema = ajv.compile(drvc3Schema);
25
-
26
- /**
27
- * Validates a DRVC3 receipt against the official schema
28
- * @param receipt - The receipt object to validate
29
- * @returns Validation result with errors if invalid
30
- */
31
- export function validateDRVC3(receipt: unknown): DRVC3ValidationResult {
32
- const valid = validateSchema(receipt);
33
-
34
- if (valid) {
35
- return { valid: true };
36
- }
37
-
38
- const errors = validateSchema.errors?.map(err => {
39
- const path = err.instancePath || '/';
40
- return `${path}: ${err.message}`;
41
- }) || ['Unknown validation error'];
42
-
43
- return { valid: false, errors };
44
- }
45
-
46
- /**
47
- * Type guard to check if an object is a valid DRVC3 receipt
48
- * @param obj - Object to check
49
- * @returns True if the object is a valid DRVC3 receipt
50
- */
51
- export function isDRVC3Receipt(obj: unknown): boolean {
52
- return validateDRVC3(obj).valid;
53
- }
package/src/wrapper.ts DELETED
@@ -1,103 +0,0 @@
1
- /**
2
- * DRVC3 Wrapper
3
- * Wraps Layer 1 DeltaReceipt in a DRVC3 envelope with EIP-191 signatures
4
- *
5
- * Key Principle: The DeltaReceipt hash is READ-ONLY from Layer 1.
6
- * DRVC3 envelope fields (receipt_id, timestamp, signature) are envelope metadata
7
- * and do NOT affect determinism or replay.
8
- */
9
-
10
- import { DeltaReceipt } from '@uvrn/core';
11
- import { Wallet, HDNodeWallet, Signer } from 'ethers';
12
- import { DRVC3Receipt, WrapOptions } from './types';
13
- import { signHash } from './signer';
14
-
15
- /**
16
- * Wraps a DeltaReceipt in a DRVC3 envelope
17
- *
18
- * @param deltaReceipt - Layer 1 DeltaReceipt (deterministic, hash-covered)
19
- * @param signer - ethers Wallet for EIP-191 signing
20
- * @param options - Envelope options (issuer, event, etc.)
21
- * @returns Promise resolving to complete DRVC3 receipt
22
- *
23
- * @example
24
- * ```typescript
25
- * import { runDeltaEngine } from '@uvrn/core';
26
- * import { wrapInDRVC3 } from '@uvrn/adapter';
27
- * import { Wallet } from 'ethers';
28
- *
29
- * const deltaReceipt = runDeltaEngine(bundle);
30
- * const wallet = new Wallet(privateKey);
31
- * const drvc3 = await wrapInDRVC3(deltaReceipt, wallet, {
32
- * issuer: 'uvrn',
33
- * event: 'delta-reconciliation'
34
- * });
35
- * ```
36
- */
37
- export async function wrapInDRVC3(
38
- deltaReceipt: DeltaReceipt,
39
- signer: Wallet | HDNodeWallet,
40
- options: WrapOptions
41
- ): Promise<DRVC3Receipt> {
42
- // 1. Generate receipt_id (ENVELOPE METADATA - non-deterministic, intentional)
43
- const timestamp = new Date().toISOString();
44
- const receipt_id = `drvc3-${deltaReceipt.bundleId}-${Date.now()}`;
45
-
46
- // 2. Read hash from DeltaReceipt (HASH DOMAIN - read-only from Layer 1)
47
- const hash = deltaReceipt.hash;
48
-
49
- // 3. Sign hash with EIP-191 (ENVELOPE METADATA - certifies "who" and "when")
50
- const signature = await signHash(hash, signer);
51
-
52
- // 4. Construct DRVC3 envelope
53
- const drvc3: DRVC3Receipt = {
54
- receipt_id,
55
- issuer: options.issuer,
56
- event: options.event,
57
- timestamp,
58
- integrity: {
59
- hash_algorithm: 'sha256',
60
- hash,
61
- signature_method: 'eip191',
62
- signature,
63
- signer_address: signer.address
64
- },
65
- validation: {
66
- v_score: deltaReceipt.deltaFinal,
67
- checks: {
68
- delta_receipt: deltaReceipt
69
- }
70
- },
71
- block_state: options.blockState || 'loose',
72
- certificate: options.certificate || 'DRVC3 v1.01'
73
- };
74
-
75
- // Add optional fields if provided
76
- if (options.description) {
77
- drvc3.description = options.description;
78
- }
79
- if (options.resource) {
80
- drvc3.resource = options.resource;
81
- }
82
- if (options.replayInstructions) {
83
- drvc3.replay_instructions = options.replayInstructions;
84
- }
85
- if (options.extensions) {
86
- drvc3.extensions = options.extensions;
87
- }
88
- if (options.tags) {
89
- drvc3.tags = options.tags;
90
- }
91
-
92
- return drvc3;
93
- }
94
-
95
- /**
96
- * Extracts the original DeltaReceipt from a DRVC3 envelope
97
- *
98
- * @param drvc3 - DRVC3 receipt envelope
99
- * @returns The embedded DeltaReceipt
100
- */
101
- export function extractDeltaReceipt(drvc3: DRVC3Receipt): DeltaReceipt {
102
- return drvc3.validation.checks.delta_receipt;
103
- }
@@ -1,123 +0,0 @@
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
- });
@@ -1,115 +0,0 @@
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 DELETED
@@ -1,21 +0,0 @@
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
- }