@totemsdk/proofgraph 1.0.0 → 1.1.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/LICENSE +202 -21
- package/NOTICE +60 -0
- package/README.md +1 -1
- package/dist/canonical.js +11 -19
- package/dist/cjs/canonical.d.ts +22 -0
- package/dist/cjs/canonical.js +51 -0
- package/dist/cjs/durable-store.d.ts +50 -0
- package/dist/cjs/durable-store.js +178 -0
- package/dist/cjs/evidence.d.ts +89 -0
- package/dist/cjs/evidence.js +130 -0
- package/dist/cjs/graph.d.ts +103 -0
- package/dist/cjs/graph.js +298 -0
- package/dist/cjs/index.d.ts +26 -0
- package/dist/cjs/index.js +84 -0
- package/dist/cjs/io.d.ts +26 -0
- package/dist/cjs/io.js +173 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/query.d.ts +85 -0
- package/dist/cjs/query.js +189 -0
- package/dist/cjs/replicated-evidence.d.ts +42 -0
- package/dist/cjs/replicated-evidence.js +98 -0
- package/dist/cjs/types.d.ts +62 -0
- package/dist/cjs/types.js +7 -0
- package/dist/cjs/verify.d.ts +23 -0
- package/dist/cjs/verify.js +77 -0
- package/dist/durable-store.d.ts +50 -0
- package/dist/durable-store.js +175 -0
- package/dist/evidence.d.ts +89 -0
- package/dist/evidence.js +125 -0
- package/dist/graph.d.ts +11 -0
- package/dist/graph.js +49 -33
- package/dist/index.d.ts +7 -2
- package/dist/index.js +8 -46
- package/dist/io.js +4 -8
- package/dist/query.d.ts +4 -0
- package/dist/query.js +28 -36
- package/dist/replicated-evidence.d.ts +42 -0
- package/dist/replicated-evidence.js +95 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -2
- package/dist/verify.js +3 -40
- package/package.json +22 -14
- package/rust/pkg/package.json +2 -2
- package/rust/pkg/proofgraph_wasm_bg.wasm +0 -0
- package/rust/pkg-node/package.json +2 -2
- package/rust/pkg-node/proofgraph_wasm_bg.wasm +0 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC-057 Phase 4 — replicated proofgraph evidence adapter.
|
|
3
|
+
*
|
|
4
|
+
* Keeps the authoritative proofgraph evidence store local while allowing a
|
|
5
|
+
* replicated index to locate the same digest-verified artifacts on other
|
|
6
|
+
* peers. The replicated index is never trusted for bytes: every read
|
|
7
|
+
* re-verifies the artifact digest.
|
|
8
|
+
*/
|
|
9
|
+
import type { ArtifactRef, ArtifactStore } from '@totemsdk/storage/artifacts';
|
|
10
|
+
import type { ProofGraph } from './types.js';
|
|
11
|
+
export interface ReplicatedEvidenceIndexEntry {
|
|
12
|
+
readonly nodeId: string;
|
|
13
|
+
readonly ref: ArtifactRef;
|
|
14
|
+
readonly contentHash: string;
|
|
15
|
+
readonly storedAt: number;
|
|
16
|
+
}
|
|
17
|
+
export interface ReplicatedEvidenceIndexPort {
|
|
18
|
+
get(key: string): Promise<unknown | null>;
|
|
19
|
+
put(key: string, value: unknown): Promise<void>;
|
|
20
|
+
list?(prefix?: string): AsyncIterable<{
|
|
21
|
+
key: string;
|
|
22
|
+
value: unknown;
|
|
23
|
+
}>;
|
|
24
|
+
}
|
|
25
|
+
export interface ReplicatedEvidenceRead {
|
|
26
|
+
readonly nodeId: string;
|
|
27
|
+
readonly status: 'ok' | 'not-found' | 'corrupt' | 'unavailable';
|
|
28
|
+
readonly ref?: ArtifactRef;
|
|
29
|
+
readonly bytes?: Uint8Array;
|
|
30
|
+
readonly message?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface ReplicatedProofGraphEvidenceStore {
|
|
33
|
+
putEvidence(graph: ProofGraph, bytesFor: (nodeId: string) => Uint8Array | undefined): Promise<ArtifactRef[]>;
|
|
34
|
+
getEvidence(nodeId: string): Promise<ReplicatedEvidenceRead>;
|
|
35
|
+
verifyEvidence(nodeId: string): Promise<boolean>;
|
|
36
|
+
listEvidence(): AsyncIterable<ReplicatedEvidenceIndexEntry>;
|
|
37
|
+
}
|
|
38
|
+
export declare function createReplicatedProofGraphEvidenceStore(options: {
|
|
39
|
+
artifacts: ArtifactStore;
|
|
40
|
+
index: ReplicatedEvidenceIndexPort;
|
|
41
|
+
namespace?: string;
|
|
42
|
+
}): ReplicatedProofGraphEvidenceStore;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC-057 Phase 4 — replicated proofgraph evidence adapter.
|
|
3
|
+
*
|
|
4
|
+
* Keeps the authoritative proofgraph evidence store local while allowing a
|
|
5
|
+
* replicated index to locate the same digest-verified artifacts on other
|
|
6
|
+
* peers. The replicated index is never trusted for bytes: every read
|
|
7
|
+
* re-verifies the artifact digest.
|
|
8
|
+
*/
|
|
9
|
+
import { sha3_256, toHex } from '@totemsdk/core';
|
|
10
|
+
import { StorageError } from '@totemsdk/storage/errors';
|
|
11
|
+
const KEY_PREFIX = 'proofgraph:evidence:';
|
|
12
|
+
const DEFAULT_NAMESPACE = 'totem-proofgraph-evidence';
|
|
13
|
+
function normalizeHash(value) {
|
|
14
|
+
return value.replace(/^0x/i, '').toLowerCase();
|
|
15
|
+
}
|
|
16
|
+
function evidenceNodes(graph) {
|
|
17
|
+
return graph.nodes.filter((node) => node.type === 'evidence');
|
|
18
|
+
}
|
|
19
|
+
function contentHashOf(node) {
|
|
20
|
+
const value = node.data?.contentHash;
|
|
21
|
+
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
22
|
+
}
|
|
23
|
+
export function createReplicatedProofGraphEvidenceStore(options) {
|
|
24
|
+
if (!options.artifacts.capabilities.writable) {
|
|
25
|
+
throw new Error('replicated evidence store requires a writable artifact store');
|
|
26
|
+
}
|
|
27
|
+
const namespace = options.namespace ?? DEFAULT_NAMESPACE;
|
|
28
|
+
const key = (nodeId) => `${KEY_PREFIX}${nodeId}`;
|
|
29
|
+
return {
|
|
30
|
+
async putEvidence(graph, bytesFor) {
|
|
31
|
+
const refs = [];
|
|
32
|
+
for (const node of evidenceNodes(graph)) {
|
|
33
|
+
const bytes = bytesFor(node.id);
|
|
34
|
+
if (!bytes)
|
|
35
|
+
continue;
|
|
36
|
+
const digest = toHex(sha3_256(bytes));
|
|
37
|
+
const contentHash = contentHashOf(node);
|
|
38
|
+
if (contentHash && normalizeHash(contentHash) !== digest) {
|
|
39
|
+
throw new StorageError(`evidence commitment mismatch for node "${node.id}"`, 'corrupt', {
|
|
40
|
+
key: key(node.id),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
const receipt = await options.artifacts.put(namespace, bytes);
|
|
44
|
+
if (contentHash && normalizeHash(contentHash) !== receipt.ref.digest) {
|
|
45
|
+
throw new StorageError(`artifact digest mismatch for node "${node.id}"`, 'corrupt', {
|
|
46
|
+
key: key(node.id),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
await options.index.put(key(node.id), {
|
|
50
|
+
nodeId: node.id,
|
|
51
|
+
ref: receipt.ref,
|
|
52
|
+
contentHash: contentHash ?? receipt.ref.digest,
|
|
53
|
+
storedAt: Date.now(),
|
|
54
|
+
});
|
|
55
|
+
refs.push(receipt.ref);
|
|
56
|
+
}
|
|
57
|
+
return refs;
|
|
58
|
+
},
|
|
59
|
+
async getEvidence(nodeId) {
|
|
60
|
+
const raw = await options.index.get(key(nodeId));
|
|
61
|
+
if (!raw)
|
|
62
|
+
return { nodeId, status: 'not-found' };
|
|
63
|
+
const entry = raw;
|
|
64
|
+
const read = await options.artifacts.get(entry.ref);
|
|
65
|
+
if (read.status !== 'ok' || !read.bytes) {
|
|
66
|
+
return {
|
|
67
|
+
nodeId,
|
|
68
|
+
status: read.status,
|
|
69
|
+
ref: entry.ref,
|
|
70
|
+
...(read.message ? { message: read.message } : {}),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const digest = toHex(sha3_256(read.bytes));
|
|
74
|
+
if (normalizeHash(entry.contentHash) !== digest) {
|
|
75
|
+
return {
|
|
76
|
+
nodeId,
|
|
77
|
+
status: 'corrupt',
|
|
78
|
+
ref: entry.ref,
|
|
79
|
+
message: `evidence digest mismatch: ${digest} !== ${entry.contentHash}`,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return { nodeId, status: 'ok', ref: entry.ref, bytes: read.bytes };
|
|
83
|
+
},
|
|
84
|
+
async verifyEvidence(nodeId) {
|
|
85
|
+
return (await this.getEvidence(nodeId)).status === 'ok';
|
|
86
|
+
},
|
|
87
|
+
async *listEvidence() {
|
|
88
|
+
if (!options.index.list)
|
|
89
|
+
return;
|
|
90
|
+
for await (const entry of options.index.list(KEY_PREFIX)) {
|
|
91
|
+
yield entry.value;
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Pure schema — no network, no DHT, no blockchain submission, no crypto.
|
|
5
5
|
*/
|
|
6
6
|
export type ProofGraphNodeType = 'proof' | 'identity' | 'identity-claim' | 'manifest' | 'address' | 'subject' | 'evidence' | 'anchor' | 'receipt' | 'payment' | 'device' | 'service' | 'policy' | 'custom';
|
|
7
|
-
export type ProofGraphEdgeType = 'proves' | 'issued_by' | 'signed_by' | 'about' | 'references' | 'derived_from' | 'supports' | 'contradicts' | 'supersedes' | 'revokes' | 'anchored_to' | 'delegates_to' | 'controls' | 'depends_on' | 'manifests_as' | 'conflicts_with';
|
|
7
|
+
export type ProofGraphEdgeType = 'proves' | 'issued_by' | 'signed_by' | 'about' | 'references' | 'derived_from' | 'supports' | 'contradicts' | 'supersedes' | 'revokes' | 'anchored_to' | 'delegates_to' | 'controls' | 'depends_on' | 'manifests_as' | 'revision_of' | 'conflicts_with';
|
|
8
8
|
export interface ProofGraphNode {
|
|
9
9
|
id: string;
|
|
10
10
|
type: ProofGraphNodeType;
|
package/dist/types.js
CHANGED
package/dist/verify.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Graph-level verification.
|
|
4
3
|
*
|
|
@@ -8,43 +7,7 @@
|
|
|
8
7
|
*
|
|
9
8
|
* verifyGraphProofs: same logic, returns the list of invalid proof IDs (string[]).
|
|
10
9
|
*/
|
|
11
|
-
|
|
12
|
-
if (k2 === undefined) k2 = k;
|
|
13
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
-
}
|
|
17
|
-
Object.defineProperty(o, k2, desc);
|
|
18
|
-
}) : (function(o, m, k, k2) {
|
|
19
|
-
if (k2 === undefined) k2 = k;
|
|
20
|
-
o[k2] = m[k];
|
|
21
|
-
}));
|
|
22
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
-
}) : function(o, v) {
|
|
25
|
-
o["default"] = v;
|
|
26
|
-
});
|
|
27
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
28
|
-
var ownKeys = function(o) {
|
|
29
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30
|
-
var ar = [];
|
|
31
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
32
|
-
return ar;
|
|
33
|
-
};
|
|
34
|
-
return ownKeys(o);
|
|
35
|
-
};
|
|
36
|
-
return function (mod) {
|
|
37
|
-
if (mod && mod.__esModule) return mod;
|
|
38
|
-
var result = {};
|
|
39
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
40
|
-
__setModuleDefault(result, mod);
|
|
41
|
-
return result;
|
|
42
|
-
};
|
|
43
|
-
})();
|
|
44
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
-
exports.verifyProofGraph = verifyProofGraph;
|
|
46
|
-
exports.verifyGraphProofs = verifyGraphProofs;
|
|
47
|
-
const proofModule = __importStar(require("@totemsdk/proof"));
|
|
10
|
+
import * as proofModule from '@totemsdk/proof';
|
|
48
11
|
/**
|
|
49
12
|
* Verify every proof node stored in the graph.
|
|
50
13
|
*
|
|
@@ -52,7 +15,7 @@ const proofModule = __importStar(require("@totemsdk/proof"));
|
|
|
52
15
|
* and calls proofModule.verifyProof() from @totemsdk/proof.
|
|
53
16
|
* Returns { valid: true } if ALL proofs pass; otherwise lists the failing proofIds.
|
|
54
17
|
*/
|
|
55
|
-
function verifyProofGraph(graph, _options) {
|
|
18
|
+
export function verifyProofGraph(graph, _options) {
|
|
56
19
|
const invalidProofs = [];
|
|
57
20
|
for (const node of graph.nodes) {
|
|
58
21
|
if (node.type !== 'proof' || !node.data)
|
|
@@ -72,6 +35,6 @@ function verifyProofGraph(graph, _options) {
|
|
|
72
35
|
* Returns the list of invalid proof IDs in the graph.
|
|
73
36
|
* Equivalent to verifyProofGraph(graph).invalidProofs.
|
|
74
37
|
*/
|
|
75
|
-
function verifyGraphProofs(graph) {
|
|
38
|
+
export function verifyGraphProofs(graph) {
|
|
76
39
|
return verifyProofGraph(graph).invalidProofs;
|
|
77
40
|
}
|
package/package.json
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@totemsdk/proofgraph",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Local deterministic proof relationship graph for Totem Edge — indexes proofs, identities, manifests, and subjects into a queryable content-addressed DAG",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
5
|
+
"main": "dist/cjs/index.js",
|
|
6
|
+
"types": "dist/cjs/index.d.ts",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": {
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
"import": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"require": {
|
|
14
|
+
"types": "./dist/cjs/index.d.ts",
|
|
15
|
+
"default": "./dist/cjs/index.js"
|
|
16
|
+
}
|
|
12
17
|
}
|
|
13
18
|
},
|
|
14
19
|
"files": [
|
|
@@ -16,13 +21,15 @@
|
|
|
16
21
|
"rust/pkg/",
|
|
17
22
|
"rust/pkg-node/",
|
|
18
23
|
"README.md",
|
|
19
|
-
"LICENSE"
|
|
24
|
+
"LICENSE",
|
|
25
|
+
"NOTICE"
|
|
20
26
|
],
|
|
21
27
|
"dependencies": {
|
|
22
|
-
"@totemsdk/core": "^1.2
|
|
23
|
-
"@totemsdk/proof": "^1.0.
|
|
24
|
-
"@totemsdk/
|
|
25
|
-
"@totemsdk/identity": "^1.
|
|
28
|
+
"@totemsdk/core": "^1.4.2",
|
|
29
|
+
"@totemsdk/proof": "^1.0.2",
|
|
30
|
+
"@totemsdk/storage": "^0.2.2",
|
|
31
|
+
"@totemsdk/identity": "^1.1.0",
|
|
32
|
+
"@totemsdk/manifest": "^2.1.0"
|
|
26
33
|
},
|
|
27
34
|
"devDependencies": {
|
|
28
35
|
"@types/jest": "^30.0.0",
|
|
@@ -37,9 +44,9 @@
|
|
|
37
44
|
"publishConfig": {
|
|
38
45
|
"access": "public"
|
|
39
46
|
},
|
|
40
|
-
"license": "
|
|
47
|
+
"license": "Apache-2.0",
|
|
41
48
|
"author": "Totem SDK",
|
|
42
|
-
"homepage": "https://totem.ing",
|
|
49
|
+
"homepage": "https://docs.totem.ing",
|
|
43
50
|
"bugs": {
|
|
44
51
|
"url": "https://github.com/Totem-Edge/totem-sdk/issues"
|
|
45
52
|
},
|
|
@@ -64,8 +71,9 @@
|
|
|
64
71
|
"verification",
|
|
65
72
|
"content-addressed"
|
|
66
73
|
],
|
|
74
|
+
"type": "module",
|
|
67
75
|
"scripts": {
|
|
68
|
-
"build": "
|
|
76
|
+
"build": "tsc && tsc -p tsconfig.cjs.json && node -e \"require('fs').writeFileSync('dist/cjs/package.json', JSON.stringify({type:'commonjs'})+'\\n')\"",
|
|
69
77
|
"build:wasm": "cd rust && wasm-pack build --target bundler --out-dir pkg && wasm-pack build --target nodejs --out-dir pkg-node",
|
|
70
78
|
"clean": "rm -rf dist rust/pkg rust/pkg-node rust/target",
|
|
71
79
|
"test": "jest"
|
package/rust/pkg/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
],
|
|
7
7
|
"description": "Local deterministic proof relationship graph — content-addressed DAG, node/edge ID computation, graph ID hashing, import/export validation (Rust/WASM)",
|
|
8
8
|
"version": "0.1.0",
|
|
9
|
-
"license": "
|
|
9
|
+
"license": "Apache-2.0",
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
12
|
"url": "https://github.com/Totem-Edge/totem-sdk"
|
|
@@ -24,4 +24,4 @@
|
|
|
24
24
|
"./proofgraph_wasm.js",
|
|
25
25
|
"./snippets/*"
|
|
26
26
|
]
|
|
27
|
-
}
|
|
27
|
+
}
|
|
Binary file
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
],
|
|
6
6
|
"description": "Local deterministic proof relationship graph — content-addressed DAG, node/edge ID computation, graph ID hashing, import/export validation (Rust/WASM)",
|
|
7
7
|
"version": "0.1.0",
|
|
8
|
-
"license": "
|
|
8
|
+
"license": "Apache-2.0",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
11
11
|
"url": "https://github.com/Totem-Edge/totem-sdk"
|
|
@@ -18,4 +18,4 @@
|
|
|
18
18
|
"main": "proofgraph_wasm.js",
|
|
19
19
|
"homepage": "https://totem.ing",
|
|
20
20
|
"types": "proofgraph_wasm.d.ts"
|
|
21
|
-
}
|
|
21
|
+
}
|
|
Binary file
|