@claviss/sdk 0.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.
Files changed (42) hide show
  1. package/README.md +33 -0
  2. package/dist/chain/abi.d.ts +1149 -0
  3. package/dist/chain/abi.js +5 -0
  4. package/dist/chain/chains.d.ts +106 -0
  5. package/dist/chain/chains.js +24 -0
  6. package/dist/chain/index.d.ts +2 -0
  7. package/dist/chain/index.js +2 -0
  8. package/dist/index.d.ts +22 -0
  9. package/dist/index.js +22 -0
  10. package/dist/pool/crypto.d.ts +17 -0
  11. package/dist/pool/crypto.js +79 -0
  12. package/dist/pool/index.d.ts +3 -0
  13. package/dist/pool/index.js +3 -0
  14. package/dist/pool/note.d.ts +22 -0
  15. package/dist/pool/note.js +66 -0
  16. package/dist/pool/prover.d.ts +35 -0
  17. package/dist/pool/prover.js +48 -0
  18. package/dist/shielded/index.d.ts +4 -0
  19. package/dist/shielded/index.js +4 -0
  20. package/dist/shielded/keypair.d.ts +23 -0
  21. package/dist/shielded/keypair.js +72 -0
  22. package/dist/shielded/note.d.ts +22 -0
  23. package/dist/shielded/note.js +32 -0
  24. package/dist/shielded/prover.d.ts +56 -0
  25. package/dist/shielded/prover.js +100 -0
  26. package/dist/shielded/scan.d.ts +21 -0
  27. package/dist/shielded/scan.js +28 -0
  28. package/dist/stealth/index.d.ts +2 -0
  29. package/dist/stealth/index.js +2 -0
  30. package/dist/stealth/scanner.d.ts +20 -0
  31. package/dist/stealth/scanner.js +31 -0
  32. package/dist/stealth/stealth.d.ts +41 -0
  33. package/dist/stealth/stealth.js +122 -0
  34. package/dist/zk/calldata.d.ts +21 -0
  35. package/dist/zk/calldata.js +11 -0
  36. package/dist/zk/index.d.ts +3 -0
  37. package/dist/zk/index.js +3 -0
  38. package/dist/zk/merkle.d.ts +36 -0
  39. package/dist/zk/merkle.js +92 -0
  40. package/dist/zk/prover.d.ts +20 -0
  41. package/dist/zk/prover.js +27 -0
  42. package/package.json +49 -0
@@ -0,0 +1,92 @@
1
+ import { buildPoseidon } from "circomlibjs";
2
+ /**
3
+ * Poseidon Merkle tree whose hashing matches circuits/credential.circom:
4
+ * parent = Poseidon(left, right)
5
+ * leaf = Poseidon(secret) // identity commitment
6
+ *
7
+ * Fixed depth; empty slots are filled with a zero subtree so the root is
8
+ * stable. Keep `depth` in sync with the circuit (default 20).
9
+ */
10
+ export class PoseidonMerkleTree {
11
+ constructor(poseidon, depth) {
12
+ this.zeros = [];
13
+ this.layers = [];
14
+ this.poseidon = poseidon;
15
+ this.F = poseidon.F;
16
+ this.depth = depth;
17
+ }
18
+ static async create(depth = 20) {
19
+ const poseidon = await buildPoseidon();
20
+ const t = new PoseidonMerkleTree(poseidon, depth);
21
+ // precompute zero subtree roots per level
22
+ let cur = 0n;
23
+ t.zeros.push(cur);
24
+ for (let i = 0; i < depth; i++) {
25
+ cur = t.hash2(cur, cur);
26
+ t.zeros.push(cur);
27
+ }
28
+ t.layers = [[]];
29
+ return t;
30
+ }
31
+ toBig(x) {
32
+ return BigInt(this.F.toString(x));
33
+ }
34
+ hash1(a) {
35
+ return this.toBig(this.poseidon([a]));
36
+ }
37
+ hash2(a, b) {
38
+ return this.toBig(this.poseidon([a, b]));
39
+ }
40
+ /** identity commitment for a secret */
41
+ commitment(secret) {
42
+ return this.hash1(secret);
43
+ }
44
+ /** insert a leaf (already a commitment) and return its index */
45
+ insert(leaf) {
46
+ const index = this.layers[0].length;
47
+ this.layers[0].push(leaf);
48
+ this.rebuild();
49
+ return index;
50
+ }
51
+ /**
52
+ * Insert many leaves and rebuild once — O(n) total instead of O(n²) from
53
+ * calling insert() in a loop. Use this to load a tree from a commitment list.
54
+ */
55
+ insertMany(leaves) {
56
+ for (const leaf of leaves)
57
+ this.layers[0].push(leaf);
58
+ this.rebuild();
59
+ }
60
+ rebuild() {
61
+ for (let level = 0; level < this.depth; level++) {
62
+ const cur = this.layers[level];
63
+ const next = [];
64
+ for (let i = 0; i < cur.length; i += 2) {
65
+ const left = cur[i];
66
+ const right = i + 1 < cur.length ? cur[i + 1] : this.zeros[level];
67
+ next.push(this.hash2(left, right));
68
+ }
69
+ this.layers[level + 1] = next;
70
+ }
71
+ }
72
+ root() {
73
+ const top = this.layers[this.depth];
74
+ return top && top.length ? top[0] : this.zeros[this.depth];
75
+ }
76
+ /** Merkle proof for the leaf at `index`, formatted for the circuit. */
77
+ proof(index) {
78
+ const pathElements = [];
79
+ const pathIndices = [];
80
+ let idx = index;
81
+ for (let level = 0; level < this.depth; level++) {
82
+ const cur = this.layers[level] ?? [];
83
+ const isRight = idx % 2;
84
+ const siblingIdx = isRight ? idx - 1 : idx + 1;
85
+ const sibling = siblingIdx < cur.length ? cur[siblingIdx] : this.zeros[level];
86
+ pathElements.push(sibling);
87
+ pathIndices.push(isRight);
88
+ idx = Math.floor(idx / 2);
89
+ }
90
+ return { pathElements, pathIndices };
91
+ }
92
+ }
@@ -0,0 +1,20 @@
1
+ import { PoseidonMerkleTree } from "./merkle.js";
2
+ import { type ProofCalldata, type RawProof } from "./calldata.js";
3
+ export interface CredentialInputs {
4
+ secret: bigint;
5
+ tree: PoseidonMerkleTree;
6
+ leafIndex: number;
7
+ externalNullifier: bigint;
8
+ signalHash: bigint;
9
+ }
10
+ export type { ProofCalldata, RawProof };
11
+ /**
12
+ * Generate the raw snarkjs proof + public signals. Use this when submitting via
13
+ * the relay, which formats calldata server-side.
14
+ */
15
+ export declare function proveCredentialRaw(inputs: CredentialInputs, wasmPath: string, zkeyPath: string): Promise<RawProof>;
16
+ /**
17
+ * Selective-disclosure proof as CredentialGroups.verify calldata.
18
+ * signals = [nullifierHash, merkleRoot, externalNullifier, signalHash].
19
+ */
20
+ export declare function proveCredential(inputs: CredentialInputs, wasmPath: string, zkeyPath: string): Promise<ProofCalldata>;
@@ -0,0 +1,27 @@
1
+ import { groth16 } from "snarkjs";
2
+ import { toCalldata } from "./calldata.js";
3
+ /**
4
+ * Generate the raw snarkjs proof + public signals. Use this when submitting via
5
+ * the relay, which formats calldata server-side.
6
+ */
7
+ export async function proveCredentialRaw(inputs, wasmPath, zkeyPath) {
8
+ const { secret, tree, leafIndex, externalNullifier, signalHash } = inputs;
9
+ const { pathElements, pathIndices } = tree.proof(leafIndex);
10
+ const witness = {
11
+ secret: secret.toString(),
12
+ pathElements: pathElements.map((x) => x.toString()),
13
+ pathIndices: pathIndices.map((x) => x.toString()),
14
+ merkleRoot: tree.root().toString(),
15
+ externalNullifier: externalNullifier.toString(),
16
+ signalHash: signalHash.toString(),
17
+ };
18
+ const { proof, publicSignals } = await groth16.fullProve(witness, wasmPath, zkeyPath);
19
+ return { proof, publicSignals };
20
+ }
21
+ /**
22
+ * Selective-disclosure proof as CredentialGroups.verify calldata.
23
+ * signals = [nullifierHash, merkleRoot, externalNullifier, signalHash].
24
+ */
25
+ export async function proveCredential(inputs, wasmPath, zkeyPath) {
26
+ return toCalldata(await proveCredentialRaw(inputs, wasmPath, zkeyPath));
27
+ }
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@claviss/sdk",
3
+ "version": "0.1.0",
4
+ "description": "Clavis privacy SDK for Robinhood Chain (EVM): hidden-amount shielded payments, ZK selective disclosure, stealth addresses, compliant privacy pool.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/romeoscript/clavis.git",
9
+ "directory": "packages/sdk"
10
+ },
11
+ "homepage": "https://clavisrobinhood.com",
12
+ "keywords": [
13
+ "privacy",
14
+ "zero-knowledge",
15
+ "zk",
16
+ "stealth-address",
17
+ "privacy-pool",
18
+ "robinhood-chain",
19
+ "evm",
20
+ "ethereum"
21
+ ],
22
+ "type": "module",
23
+ "main": "dist/index.js",
24
+ "types": "dist/index.d.ts",
25
+ "exports": {
26
+ ".": {
27
+ "types": "./dist/index.d.ts",
28
+ "import": "./dist/index.js"
29
+ }
30
+ },
31
+ "files": [
32
+ "dist",
33
+ "README.md"
34
+ ],
35
+ "sideEffects": false,
36
+ "scripts": {
37
+ "build": "tsc -p tsconfig.json"
38
+ },
39
+ "dependencies": {
40
+ "@noble/curves": "^1.6.0",
41
+ "@noble/hashes": "^1.5.0",
42
+ "circomlibjs": "^0.1.7",
43
+ "snarkjs": "^0.7.5",
44
+ "viem": "^2.21.0"
45
+ },
46
+ "devDependencies": {
47
+ "typescript": "^5.6.3"
48
+ }
49
+ }