@noirstack/hexarchproof-sdk 0.0.1
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 +50 -0
- package/out/canon.d.ts +12 -0
- package/out/canon.d.ts.map +1 -0
- package/out/canon.js +29 -0
- package/out/canon.js.map +1 -0
- package/out/hash.d.ts +8 -0
- package/out/hash.d.ts.map +1 -0
- package/out/hash.js +20 -0
- package/out/hash.js.map +1 -0
- package/out/index.d.ts +6 -0
- package/out/index.d.ts.map +1 -0
- package/out/index.js +16 -0
- package/out/index.js.map +1 -0
- package/out/proof.d.ts +6 -0
- package/out/proof.d.ts.map +1 -0
- package/out/proof.js +36 -0
- package/out/proof.js.map +1 -0
- package/out/types.d.ts +37 -0
- package/out/types.d.ts.map +1 -0
- package/out/types.js +3 -0
- package/out/types.js.map +1 -0
- package/out/verify.d.ts +4 -0
- package/out/verify.d.ts.map +1 -0
- package/out/verify.js +50 -0
- package/out/verify.js.map +1 -0
- package/package.json +56 -0
package/README.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# @hexarchproof/sdk
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for **Hexarch Deterministic Reproduction Proofs (DRP)**.
|
|
4
|
+
|
|
5
|
+
> Execution becomes a verifiable artifact. Same input → same hash → same proof — anchored for independent verification.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @hexarchproof/sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { buildProof, verifyProof, sha256HexString, sha256HexJson } from '@hexarchproof/sdk';
|
|
17
|
+
|
|
18
|
+
const hash = sha256HexString('my payload');
|
|
19
|
+
const jsonHash = sha256HexJson({ b: 2, a: 1 });
|
|
20
|
+
|
|
21
|
+
const proof = buildProof(
|
|
22
|
+
{ input: 'my deterministic payload' },
|
|
23
|
+
{ type: 'hexarch.text-proof', version: '1' },
|
|
24
|
+
{ output: 'my deterministic payload' }
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
const result = verifyProof(
|
|
28
|
+
proof,
|
|
29
|
+
{ input: 'my deterministic payload' },
|
|
30
|
+
{ type: 'hexarch.text-proof', version: '1' },
|
|
31
|
+
{ output: 'my deterministic payload' }
|
|
32
|
+
);
|
|
33
|
+
// result.valid === true
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## API
|
|
37
|
+
|
|
38
|
+
- `canonicalJsonString(value)` — RFC 8785 canonical JSON string
|
|
39
|
+
- `canonicalJsonBytes(value)` — UTF-8 Buffer of the above
|
|
40
|
+
- `sha256HexBytes(raw)` — SHA-256 hex of raw bytes
|
|
41
|
+
- `sha256HexString(input)` — SHA-256 hex of a UTF-8 string
|
|
42
|
+
- `sha256HexJson(value)` — SHA-256 hex of canonical JSON bytes
|
|
43
|
+
- `buildProof(input, spec, output)` — builds a full `DRPv1Proof`
|
|
44
|
+
- `recomputeProofHash(proof)` — re-derives `proof_hash` for tamper detection
|
|
45
|
+
- `verifyProof(proof, input, spec, output)` — fully verifies a proof document
|
|
46
|
+
|
|
47
|
+
## Links
|
|
48
|
+
|
|
49
|
+
- Hexarch Domain: https://hexarch.systems/
|
|
50
|
+
- Discord: https://discord.gg/DZysBQJQ
|
package/out/canon.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { JsonLike } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Produces a deterministic, compact canonical JSON string for `value`.
|
|
4
|
+
* Rules (matching Python canonicaljson / RFC 8785):
|
|
5
|
+
* - Object keys are sorted lexicographically.
|
|
6
|
+
* - No whitespace around separators.
|
|
7
|
+
* - Arrays are order-preserving.
|
|
8
|
+
*/
|
|
9
|
+
export declare function canonicalJsonString(value: JsonLike): string;
|
|
10
|
+
/** Returns UTF-8 bytes of the canonical JSON encoding of `value`. */
|
|
11
|
+
export declare function canonicalJsonBytes(value: JsonLike): Buffer;
|
|
12
|
+
//# sourceMappingURL=canon.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canon.d.ts","sourceRoot":"","sources":["../src/canon.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAU3D;AAED,qEAAqE;AACrE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAE1D"}
|
package/out/canon.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.canonicalJsonString = canonicalJsonString;
|
|
4
|
+
exports.canonicalJsonBytes = canonicalJsonBytes;
|
|
5
|
+
/**
|
|
6
|
+
* Produces a deterministic, compact canonical JSON string for `value`.
|
|
7
|
+
* Rules (matching Python canonicaljson / RFC 8785):
|
|
8
|
+
* - Object keys are sorted lexicographically.
|
|
9
|
+
* - No whitespace around separators.
|
|
10
|
+
* - Arrays are order-preserving.
|
|
11
|
+
*/
|
|
12
|
+
function canonicalJsonString(value) {
|
|
13
|
+
if (value === null)
|
|
14
|
+
return 'null';
|
|
15
|
+
if (typeof value !== 'object')
|
|
16
|
+
return JSON.stringify(value);
|
|
17
|
+
if (Array.isArray(value)) {
|
|
18
|
+
return '[' + value.map(canonicalJsonString).join(',') + ']';
|
|
19
|
+
}
|
|
20
|
+
const obj = value;
|
|
21
|
+
const keys = Object.keys(obj).sort();
|
|
22
|
+
const pairs = keys.map(k => JSON.stringify(k) + ':' + canonicalJsonString(obj[k]));
|
|
23
|
+
return '{' + pairs.join(',') + '}';
|
|
24
|
+
}
|
|
25
|
+
/** Returns UTF-8 bytes of the canonical JSON encoding of `value`. */
|
|
26
|
+
function canonicalJsonBytes(value) {
|
|
27
|
+
return Buffer.from(canonicalJsonString(value), 'utf8');
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=canon.js.map
|
package/out/canon.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canon.js","sourceRoot":"","sources":["../src/canon.ts"],"names":[],"mappings":";;AASA,kDAUC;AAGD,gDAEC;AAtBD;;;;;;GAMG;AACH,SAAgB,mBAAmB,CAAC,KAAe;IACjD,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IAClC,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC5D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,GAAG,GAAI,KAAoB,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IAC9E,CAAC;IACD,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAa,CAAC,CAAC,CAAC;IAC/F,OAAO,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;AACrC,CAAC;AAED,qEAAqE;AACrE,SAAgB,kBAAkB,CAAC,KAAe;IAChD,OAAO,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;AACzD,CAAC"}
|
package/out/hash.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { JsonLike } from './types';
|
|
2
|
+
/** SHA-256 hex digest of raw bytes. Matches Python hashlib.sha256(raw).hexdigest(). */
|
|
3
|
+
export declare function sha256HexBytes(raw: Buffer | Uint8Array): string;
|
|
4
|
+
/** SHA-256 hex digest of a UTF-8 string. */
|
|
5
|
+
export declare function sha256HexString(input: string, encoding?: BufferEncoding): string;
|
|
6
|
+
/** SHA-256 hex digest of canonical JSON bytes. Matches Python sha256_hex_json exactly. */
|
|
7
|
+
export declare function sha256HexJson(value: JsonLike): string;
|
|
8
|
+
//# sourceMappingURL=hash.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,uFAAuF;AACvF,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAE/D;AAED,4CAA4C;AAC5C,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,GAAE,cAAuB,GAAG,MAAM,CAExF;AAED,0FAA0F;AAC1F,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAErD"}
|
package/out/hash.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sha256HexBytes = sha256HexBytes;
|
|
4
|
+
exports.sha256HexString = sha256HexString;
|
|
5
|
+
exports.sha256HexJson = sha256HexJson;
|
|
6
|
+
const crypto_1 = require("crypto");
|
|
7
|
+
const canon_1 = require("./canon");
|
|
8
|
+
/** SHA-256 hex digest of raw bytes. Matches Python hashlib.sha256(raw).hexdigest(). */
|
|
9
|
+
function sha256HexBytes(raw) {
|
|
10
|
+
return (0, crypto_1.createHash)('sha256').update(raw).digest('hex');
|
|
11
|
+
}
|
|
12
|
+
/** SHA-256 hex digest of a UTF-8 string. */
|
|
13
|
+
function sha256HexString(input, encoding = 'utf8') {
|
|
14
|
+
return (0, crypto_1.createHash)('sha256').update(Buffer.from(input, encoding)).digest('hex');
|
|
15
|
+
}
|
|
16
|
+
/** SHA-256 hex digest of canonical JSON bytes. Matches Python sha256_hex_json exactly. */
|
|
17
|
+
function sha256HexJson(value) {
|
|
18
|
+
return sha256HexBytes((0, canon_1.canonicalJsonBytes)(value));
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=hash.js.map
|
package/out/hash.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hash.js","sourceRoot":"","sources":["../src/hash.ts"],"names":[],"mappings":";;AAKA,wCAEC;AAGD,0CAEC;AAGD,sCAEC;AAjBD,mCAAoC;AACpC,mCAA6C;AAG7C,uFAAuF;AACvF,SAAgB,cAAc,CAAC,GAAwB;IACrD,OAAO,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACxD,CAAC;AAED,4CAA4C;AAC5C,SAAgB,eAAe,CAAC,KAAa,EAAE,WAA2B,MAAM;IAC9E,OAAO,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACjF,CAAC;AAED,0FAA0F;AAC1F,SAAgB,aAAa,CAAC,KAAe;IAC3C,OAAO,cAAc,CAAC,IAAA,0BAAkB,EAAC,KAAK,CAAC,CAAC,CAAC;AACnD,CAAC"}
|
package/out/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type { DRPv1Proof, DRPv1Anchor, JsonLike, VerificationResult } from './types';
|
|
2
|
+
export { canonicalJsonString, canonicalJsonBytes } from './canon';
|
|
3
|
+
export { sha256HexBytes, sha256HexString, sha256HexJson } from './hash';
|
|
4
|
+
export { buildProof, recomputeProofHash } from './proof';
|
|
5
|
+
export { verifyProof } from './verify';
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AACrF,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC"}
|
package/out/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.verifyProof = exports.recomputeProofHash = exports.buildProof = exports.sha256HexJson = exports.sha256HexString = exports.sha256HexBytes = exports.canonicalJsonBytes = exports.canonicalJsonString = void 0;
|
|
4
|
+
var canon_1 = require("./canon");
|
|
5
|
+
Object.defineProperty(exports, "canonicalJsonString", { enumerable: true, get: function () { return canon_1.canonicalJsonString; } });
|
|
6
|
+
Object.defineProperty(exports, "canonicalJsonBytes", { enumerable: true, get: function () { return canon_1.canonicalJsonBytes; } });
|
|
7
|
+
var hash_1 = require("./hash");
|
|
8
|
+
Object.defineProperty(exports, "sha256HexBytes", { enumerable: true, get: function () { return hash_1.sha256HexBytes; } });
|
|
9
|
+
Object.defineProperty(exports, "sha256HexString", { enumerable: true, get: function () { return hash_1.sha256HexString; } });
|
|
10
|
+
Object.defineProperty(exports, "sha256HexJson", { enumerable: true, get: function () { return hash_1.sha256HexJson; } });
|
|
11
|
+
var proof_1 = require("./proof");
|
|
12
|
+
Object.defineProperty(exports, "buildProof", { enumerable: true, get: function () { return proof_1.buildProof; } });
|
|
13
|
+
Object.defineProperty(exports, "recomputeProofHash", { enumerable: true, get: function () { return proof_1.recomputeProofHash; } });
|
|
14
|
+
var verify_1 = require("./verify");
|
|
15
|
+
Object.defineProperty(exports, "verifyProof", { enumerable: true, get: function () { return verify_1.verifyProof; } });
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
package/out/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AACA,iCAAkE;AAAzD,4GAAA,mBAAmB,OAAA;AAAE,2GAAA,kBAAkB,OAAA;AAChD,+BAAwE;AAA/D,sGAAA,cAAc,OAAA;AAAE,uGAAA,eAAe,OAAA;AAAE,qGAAA,aAAa,OAAA;AACvD,iCAAyD;AAAhD,mGAAA,UAAU,OAAA;AAAE,2GAAA,kBAAkB,OAAA;AACvC,mCAAuC;AAA9B,qGAAA,WAAW,OAAA"}
|
package/out/proof.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { DRPv1Proof, JsonLike } from './types';
|
|
2
|
+
/** Re-derives proof_hash from canonical payload fields. */
|
|
3
|
+
export declare function recomputeProofHash(proof: DRPv1Proof): string;
|
|
4
|
+
/** Builds a fully formed DRPv1Proof. Mirrors build_proof in the Python engine. */
|
|
5
|
+
export declare function buildProof(inputPayload: JsonLike, specPayload: JsonLike, outputPayload: JsonLike, network?: 'sepolia'): DRPv1Proof;
|
|
6
|
+
//# sourceMappingURL=proof.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proof.d.ts","sourceRoot":"","sources":["../src/proof.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAapD,2DAA2D;AAC3D,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAE5D;AAED,kFAAkF;AAClF,wBAAgB,UAAU,CACxB,YAAY,EAAE,QAAQ,EACtB,WAAW,EAAE,QAAQ,EACrB,aAAa,EAAE,QAAQ,EACvB,OAAO,GAAE,SAAqB,GAC7B,UAAU,CAYZ"}
|
package/out/proof.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.recomputeProofHash = recomputeProofHash;
|
|
4
|
+
exports.buildProof = buildProof;
|
|
5
|
+
const crypto_1 = require("crypto");
|
|
6
|
+
const canon_1 = require("./canon");
|
|
7
|
+
const hash_1 = require("./hash");
|
|
8
|
+
function proofPayloadForHash(proof) {
|
|
9
|
+
return {
|
|
10
|
+
schema_version: proof.schema_version,
|
|
11
|
+
proof_id: proof.proof_id,
|
|
12
|
+
input_hash: proof.input_hash,
|
|
13
|
+
spec_hash: proof.spec_hash,
|
|
14
|
+
output_hash: proof.output_hash,
|
|
15
|
+
timestamp: proof.timestamp,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/** Re-derives proof_hash from canonical payload fields. */
|
|
19
|
+
function recomputeProofHash(proof) {
|
|
20
|
+
return (0, hash_1.sha256HexBytes)((0, canon_1.canonicalJsonBytes)(proofPayloadForHash(proof)));
|
|
21
|
+
}
|
|
22
|
+
/** Builds a fully formed DRPv1Proof. Mirrors build_proof in the Python engine. */
|
|
23
|
+
function buildProof(inputPayload, specPayload, outputPayload, network = 'sepolia') {
|
|
24
|
+
const timestamp = new Date().toISOString();
|
|
25
|
+
const partial = {
|
|
26
|
+
schema_version: 'drp.v1',
|
|
27
|
+
proof_id: (0, crypto_1.randomUUID)(),
|
|
28
|
+
input_hash: (0, hash_1.sha256HexJson)(inputPayload),
|
|
29
|
+
spec_hash: (0, hash_1.sha256HexJson)(specPayload),
|
|
30
|
+
output_hash: (0, hash_1.sha256HexJson)(outputPayload),
|
|
31
|
+
anchor: { network, tx_hash: null, block_number: null, anchored_at: null },
|
|
32
|
+
timestamp,
|
|
33
|
+
};
|
|
34
|
+
return { ...partial, proof_hash: (0, hash_1.sha256HexBytes)((0, canon_1.canonicalJsonBytes)(proofPayloadForHash(partial))) };
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=proof.js.map
|
package/out/proof.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proof.js","sourceRoot":"","sources":["../src/proof.ts"],"names":[],"mappings":";;AAiBA,gDAEC;AAGD,gCAiBC;AAvCD,mCAAoC;AACpC,mCAA6C;AAC7C,iCAAuD;AAGvD,SAAS,mBAAmB,CAAC,KAAkD;IAC7E,OAAO;QACL,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;KAC3B,CAAC;AACJ,CAAC;AAED,2DAA2D;AAC3D,SAAgB,kBAAkB,CAAC,KAAiB;IAClD,OAAO,IAAA,qBAAc,EAAC,IAAA,0BAAkB,EAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC;AAED,kFAAkF;AAClF,SAAgB,UAAU,CACxB,YAAsB,EACtB,WAAqB,EACrB,aAAuB,EACvB,UAAqB,SAAS;IAE9B,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,MAAM,OAAO,GAAG;QACd,cAAc,EAAE,QAAiB;QACjC,QAAQ,EAAE,IAAA,mBAAU,GAAE;QACtB,UAAU,EAAE,IAAA,oBAAa,EAAC,YAAY,CAAC;QACvC,SAAS,EAAE,IAAA,oBAAa,EAAC,WAAW,CAAC;QACrC,WAAW,EAAE,IAAA,oBAAa,EAAC,aAAa,CAAC;QACzC,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE;QACzE,SAAS;KAC+B,CAAC;IAC3C,OAAO,EAAE,GAAG,OAAO,EAAE,UAAU,EAAE,IAAA,qBAAc,EAAC,IAAA,0BAAkB,EAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;AACtG,CAAC"}
|
package/out/types.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** Any JSON-serialisable value (used as the canonical hash input). */
|
|
2
|
+
export type JsonLike = Record<string, unknown> | unknown[] | string | number | boolean | null;
|
|
3
|
+
/** Blockchain anchor for a proof. Currently scoped to Sepolia testnet. */
|
|
4
|
+
export interface DRPv1Anchor {
|
|
5
|
+
network: 'sepolia';
|
|
6
|
+
tx_hash: string | null;
|
|
7
|
+
block_number: number | null;
|
|
8
|
+
anchored_at: string | null;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A Hexarch Deterministic Reproduction Proof (DRP) document.
|
|
12
|
+
* All hash fields are lowercase hex-encoded SHA-256 digests of canonical JSON.
|
|
13
|
+
* The canonical form follows RFC 8785 key-sort ordering.
|
|
14
|
+
*/
|
|
15
|
+
export interface DRPv1Proof {
|
|
16
|
+
schema_version: 'drp.v1';
|
|
17
|
+
proof_id: string;
|
|
18
|
+
input_hash: string;
|
|
19
|
+
spec_hash: string;
|
|
20
|
+
output_hash: string;
|
|
21
|
+
proof_hash: string;
|
|
22
|
+
anchor: DRPv1Anchor;
|
|
23
|
+
timestamp: string;
|
|
24
|
+
}
|
|
25
|
+
/** Result of verifying a DRPv1Proof against its original payloads. */
|
|
26
|
+
export interface VerificationResult {
|
|
27
|
+
valid: boolean;
|
|
28
|
+
checks: {
|
|
29
|
+
schema_valid: boolean;
|
|
30
|
+
input_hash_matches: boolean;
|
|
31
|
+
spec_hash_matches: boolean;
|
|
32
|
+
output_hash_matches: boolean;
|
|
33
|
+
proof_hash_matches: boolean;
|
|
34
|
+
};
|
|
35
|
+
errors: string[];
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,MAAM,MAAM,QAAQ,GAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvB,OAAO,EAAE,GACT,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,CAAC;AAET,0EAA0E;AAC1E,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,SAAS,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,cAAc,EAAE,QAAQ,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,sEAAsE;AACtE,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE;QACN,YAAY,EAAE,OAAO,CAAC;QACtB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,iBAAiB,EAAE,OAAO,CAAC;QAC3B,mBAAmB,EAAE,OAAO,CAAC;QAC7B,kBAAkB,EAAE,OAAO,CAAC;KAC7B,CAAC;IACF,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB"}
|
package/out/types.js
ADDED
package/out/types.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/out/verify.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { JsonLike, VerificationResult } from './types';
|
|
2
|
+
/** Verifies a DRPv1Proof against original payloads. Mirrors verify_proof in the Python engine. */
|
|
3
|
+
export declare function verifyProof(proof: unknown, inputPayload: JsonLike, specPayload: JsonLike, outputPayload: JsonLike): VerificationResult;
|
|
4
|
+
//# sourceMappingURL=verify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAc,QAAQ,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAoBxE,kGAAkG;AAClG,wBAAgB,WAAW,CACzB,KAAK,EAAE,OAAO,EACd,YAAY,EAAE,QAAQ,EACtB,WAAW,EAAE,QAAQ,EACrB,aAAa,EAAE,QAAQ,GACtB,kBAAkB,CAuBpB"}
|
package/out/verify.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.verifyProof = verifyProof;
|
|
4
|
+
const proof_1 = require("./proof");
|
|
5
|
+
const hash_1 = require("./hash");
|
|
6
|
+
const HEX64_RE = /^[A-Fa-f0-9]{64}$/;
|
|
7
|
+
function isValidDRPShape(candidate) {
|
|
8
|
+
if (candidate === null || typeof candidate !== 'object' || Array.isArray(candidate))
|
|
9
|
+
return false;
|
|
10
|
+
const p = candidate;
|
|
11
|
+
const anchor = p['anchor'];
|
|
12
|
+
return (p['schema_version'] === 'drp.v1' &&
|
|
13
|
+
typeof p['proof_id'] === 'string' && p['proof_id'].length > 0 &&
|
|
14
|
+
typeof p['input_hash'] === 'string' && HEX64_RE.test(p['input_hash']) &&
|
|
15
|
+
typeof p['spec_hash'] === 'string' && HEX64_RE.test(p['spec_hash']) &&
|
|
16
|
+
typeof p['output_hash'] === 'string' && HEX64_RE.test(p['output_hash']) &&
|
|
17
|
+
typeof p['proof_hash'] === 'string' && HEX64_RE.test(p['proof_hash']) &&
|
|
18
|
+
typeof p['timestamp'] === 'string' && p['timestamp'].length > 0 &&
|
|
19
|
+
anchor !== null && typeof anchor === 'object' && !Array.isArray(anchor));
|
|
20
|
+
}
|
|
21
|
+
/** Verifies a DRPv1Proof against original payloads. Mirrors verify_proof in the Python engine. */
|
|
22
|
+
function verifyProof(proof, inputPayload, specPayload, outputPayload) {
|
|
23
|
+
const checks = {
|
|
24
|
+
schema_valid: false,
|
|
25
|
+
input_hash_matches: false,
|
|
26
|
+
spec_hash_matches: false,
|
|
27
|
+
output_hash_matches: false,
|
|
28
|
+
proof_hash_matches: false,
|
|
29
|
+
};
|
|
30
|
+
const errors = [];
|
|
31
|
+
if (!isValidDRPShape(proof)) {
|
|
32
|
+
errors.push('schema_invalid:proof does not match DRPv1Proof shape');
|
|
33
|
+
return { valid: false, checks, errors };
|
|
34
|
+
}
|
|
35
|
+
checks.schema_valid = true;
|
|
36
|
+
checks.input_hash_matches = proof.input_hash === (0, hash_1.sha256HexJson)(inputPayload);
|
|
37
|
+
if (!checks.input_hash_matches)
|
|
38
|
+
errors.push('input_hash_mismatch');
|
|
39
|
+
checks.spec_hash_matches = proof.spec_hash === (0, hash_1.sha256HexJson)(specPayload);
|
|
40
|
+
if (!checks.spec_hash_matches)
|
|
41
|
+
errors.push('spec_hash_mismatch');
|
|
42
|
+
checks.output_hash_matches = proof.output_hash === (0, hash_1.sha256HexJson)(outputPayload);
|
|
43
|
+
if (!checks.output_hash_matches)
|
|
44
|
+
errors.push('output_hash_mismatch');
|
|
45
|
+
checks.proof_hash_matches = proof.proof_hash === (0, proof_1.recomputeProofHash)(proof);
|
|
46
|
+
if (!checks.proof_hash_matches)
|
|
47
|
+
errors.push('proof_hash_mismatch');
|
|
48
|
+
return { valid: Object.values(checks).every(Boolean), checks, errors };
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../src/verify.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@noirstack/hexarchproof-sdk",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "TypeScript SDK for Hexarch Deterministic Reproduction Proofs (DRP). Same input → same hash → same proof, anchored for independent verification.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"hexarch",
|
|
7
|
+
"drp",
|
|
8
|
+
"deterministic",
|
|
9
|
+
"reproducibility",
|
|
10
|
+
"verifiable-compute",
|
|
11
|
+
"proof",
|
|
12
|
+
"auditability",
|
|
13
|
+
"noirstack",
|
|
14
|
+
"canonical-json",
|
|
15
|
+
"sha256"
|
|
16
|
+
],
|
|
17
|
+
"license": "BLI",
|
|
18
|
+
"author": {
|
|
19
|
+
"name": "Noir Stack LLC",
|
|
20
|
+
"url": "https://noirstack.com"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://hexarch.systems/",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "https://github.com/no1rstack/hexarchproof-sdk"
|
|
26
|
+
},
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://noirstack.com/support"
|
|
29
|
+
},
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
33
|
+
"main": "./out/index.js",
|
|
34
|
+
"types": "./out/index.d.ts",
|
|
35
|
+
"exports": {
|
|
36
|
+
".": {
|
|
37
|
+
"require": "./out/index.js",
|
|
38
|
+
"types": "./out/index.d.ts"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"files": [
|
|
42
|
+
"out/",
|
|
43
|
+
"LICENSE",
|
|
44
|
+
"README.md"
|
|
45
|
+
],
|
|
46
|
+
"scripts": {
|
|
47
|
+
"compile": "tsc -p ./",
|
|
48
|
+
"watch": "tsc -watch -p ./",
|
|
49
|
+
"test": "node --test out/test/",
|
|
50
|
+
"prepublishOnly": "npm run compile"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/node": "^20.16.5",
|
|
54
|
+
"typescript": "^5.6.3"
|
|
55
|
+
}
|
|
56
|
+
}
|