Package Exports
- @totemsdk/proofgraph
Readme
@totemsdk/proofgraph
Local deterministic proof relationship graph for Totem Edge — indexes proofs, identities, manifests, anchors, and subjects into a queryable, content-addressed DAG.
No network. No storage. Pure in-memory immutable graph with SHA3-256 content addressing.
Installation
npm install @totemsdk/proofgraphOverview
@totemsdk/proofgraph takes SignedProof objects (from @totemsdk/proof) and builds a local relationship graph you can query and verify. Every mutation returns a new graph with a recomputed graphId — the ID is a deterministic SHA3-256 over node and edge content, so the same logical graph always produces the same ID regardless of when it was built.
Key properties:
- Immutable — every add/mutation returns a new
ProofGraph; originals are never modified - Idempotent — adding the same node or edge twice has no effect (deduplication by content ID)
- Content-deterministic —
graphIdexcludescreatedAttimestamps so identical content always hashes identically - Interface-only storage —
ProofGraphStoragePortis an interface; no concrete adapter ships in this package
All exports
Graph construction
| Export | Description |
|---|---|
createProofGraph() |
Create an empty graph |
setGraphMetadata(graph, metadata) |
Attach mutable metadata; recomputes graphId |
addProof(graph, signed) |
Add a SignedProof with all its linked nodes and edges |
addIdentityDocument(graph, doc) |
Add a TotemIdentityDocument node |
addIdentityClaim(graph, signed) |
Add a SignedIdentityClaim with its edge type |
addManifest(graph, signed) |
Add a SignedManifest with manifests_as address edges |
addReceiptLike(graph, receipt) |
Add a receipt node; optionally link to a proof |
addAnchor(graph, anchor) |
Add a standalone anchor node; optionally link to a proof |
addNode(graph, node) |
Low-level: add a pre-built ProofGraphNode |
addEdge(graph, edge) |
Low-level: add a pre-built ProofGraphEdge |
buildEdge(type, from, to, contextId?) |
Construct an edge without adding it |
Query
| Export | Description |
|---|---|
findNode(graph, refId) |
Find a node by its refId |
getProofNodes(graph) |
All nodes of type 'proof' |
findProofsBySubject(graph, subjectId) |
Proofs where the subject matches (via about or proves edges) |
findProofsByIssuer(graph, issuer) |
Proofs issued by a given address |
findAnchorsForProof(graph, proofId) |
Anchor nodes linked to a proof via anchored_to edges |
findRevocations(graph, proofId) |
Proofs that revoke a given proof |
findSupersessions(graph, proofId) |
Proofs that supersede a given proof |
findConflicts(graph) |
All subject nodes targeted by more than one proof |
getEvidenceTrail(graph, proofId) |
Evidence nodes linked to a proof, in insertion order |
getProofLineage(graph, proofId) |
Walk derived_from chain; returns ancestor nodes (cycle-safe) |
resolveCurrentProofSet(graph) |
Active proofs — revoked and superseded proofs are excluded |
getManifestsForAddress(graph, address) |
Manifest nodes linked to an address |
getEdgesFrom(graph, refId) |
All edges originating from a node |
getEdgesTo(graph, refId) |
All edges terminating at a node |
getEdgesByType(graph, type) |
All edges of a given type |
getEdgesBetween(graph, fromId, toId) |
All edges between two specific nodes |
reachableFrom(graph, startId, edgeTypes?) |
BFS reachability from a node, optionally filtered by edge type |
Verification
| Export | Description |
|---|---|
verifyProofGraph(graph) |
Verify all proof nodes; returns ProofGraphVerifyResult |
verifyGraphProofs(graph) |
Returns string[] — IDs of proofs that fail verification |
Import / Export
| Export | Description |
|---|---|
exportProofGraph(graph) |
Serialize to JSON string |
importProofGraph(json) |
Deserialize and verify graphId integrity — throws on tamper |
Canonical helpers
| Export | Description |
|---|---|
computeNodeId(type, refId, data?) |
Deterministic SHA3-256 node ID |
computeEdgeId(type, from, to) |
Deterministic SHA3-256 edge ID |
computeProofGraphId(graph) |
SHA3-256 of all node and edge IDs (excludes createdAt, metadata) |
recomputeGraphId(graph) |
Return a new graph with a freshly computed graphId |
toHex(bytes) |
Uint8Array → lowercase hex (no 0x prefix) |
canonicalJson(value) |
Deterministic JSON — sorted keys, no undefined |
Type reference
ProofGraph
interface ProofGraph {
graphId: string; // SHA3-256 over all node/edge content IDs
nodes: ProofGraphNode[];
edges: ProofGraphEdge[];
createdAt: number; // Unix ms — excluded from graphId
metadata?: Record<string, unknown>; // Also excluded from graphId
}ProofGraphNode
interface ProofGraphNode {
id: string; // computeNodeId(type, refId, data)
type: ProofGraphNodeType;
refId: string; // External ID (proofId, address, evidenceId, …)
createdAt: number; // Unix ms — excluded from graphId hash
data?: Record<string, unknown>;
}
type ProofGraphNodeType =
| 'proof' | 'subject' | 'issuer' | 'evidence'
| 'anchor' | 'manifest' | 'address' | 'identity'
| 'receipt';ProofGraphEdge
interface ProofGraphEdge {
id: string; // computeEdgeId(type, from, to)
type: ProofGraphEdgeType;
from: string; // source node refId
to: string; // target node refId
contextId?: string; // e.g. the proofId that caused this edge
}
type ProofGraphEdgeType =
| 'issued_by' | 'about' | 'proves' | 'has_evidence'
| 'anchored_to' | 'revokes' | 'supersedes' | 'delegates_to'
| 'derived_from' | 'manifests_as' | 'controls' | 'supports';ProofGraphVerifyResult
interface ProofGraphVerifyResult {
valid: boolean;
invalidProofs: string[]; // proofIds that failed verification
checkedCount: number;
}ReceiptLikeInput / AnchorInput
interface ReceiptLikeInput {
id: string;
data?: Record<string, unknown>;
proofId?: string; // If set, adds a 'supports' edge from receipt → proof
}
interface AnchorInput {
hash: string; // Used as the node's refId
proofId?: string; // If set, adds an 'anchored_to' edge from proof → anchor
[key: string]: unknown; // Additional fields stored as node data
}Usage
import {
createProofGraph,
addProof,
addAnchor,
verifyProofGraph,
findProofsBySubject,
resolveCurrentProofSet,
exportProofGraph,
importProofGraph,
} from '@totemsdk/proofgraph';
import { createProof, signProof, createAnchorCommitment } from '@totemsdk/proof';
// 1. Build a signed proof
const unsigned = createProof({
kind: 'ownership',
subject: { id: 'totem:subject:asset:nft-001', kind: 'nft' },
issuer: 'MxROOT...',
});
const signed = signProof(unsigned, seed, keyIndex);
// 2. Build the graph
let graph = createProofGraph();
graph = addProof(graph, signed);
// 3. Add an on-chain anchor
graph = addAnchor(graph, {
hash: createAnchorCommitment(signed),
proofId: signed.proofId,
txId: '0xabc...',
});
// 4. Query
const forAsset = findProofsBySubject(graph, 'totem:subject:asset:nft-001');
console.log('Proofs:', forAsset.length);
const active = resolveCurrentProofSet(graph);
console.log('Active proofs:', active.length);
// 5. Verify all signatures
const result = verifyProofGraph(graph);
console.assert(result.valid, result.invalidProofs);
// 6. Serialize / deserialize (graphId is verified on import)
const json = exportProofGraph(graph);
const restored = importProofGraph(json);
console.assert(restored.graphId === graph.graphId);Design notes
Content-deterministic graphId
computeProofGraphId excludes node.createdAt and graph.metadata from the hash. Two graphs built at different times from identical proofs will have the same graphId. This makes the ID suitable as a stable content address for caching and deduplication.
Immutable + idempotent mutations
Every function that modifies a graph (addProof, addEdge, etc.) returns a new ProofGraph with a recomputed graphId. Calling the same add function twice with the same arguments returns a graph identical to calling it once — duplicate nodes and edges are silently ignored.
ProofGraphStoragePort
This package exports a ProofGraphStoragePort interface only. If you need persistent storage, implement the interface in your own adapter:
import type { ProofGraphStoragePort, ProofGraph } from '@totemsdk/proofgraph';
class MyStorage implements ProofGraphStoragePort {
async save(graph: ProofGraph): Promise<void> { /* ... */ }
async load(graphId: string): Promise<ProofGraph | null> { /* ... */ }
}Related packages
@totemsdk/proof— signed proof creation and verification@totemsdk/proof-integritas— Integritas v2 on-chain anchoring@totemsdk/identity— identity documents and claims@totemsdk/core— WOTS signing primitives
License
MIT