@unlink-xyz/core 0.1.0 → 0.1.3-canary.01ac52d
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 +9 -0
- package/dist/account/{zkAccount.d.ts → account.d.ts} +36 -5
- package/dist/account/account.d.ts.map +1 -0
- package/dist/account/accounts.d.ts +42 -0
- package/dist/account/accounts.d.ts.map +1 -0
- package/dist/account/seed.d.ts +45 -0
- package/dist/account/seed.d.ts.map +1 -0
- package/dist/account/serialization.d.ts +6 -0
- package/dist/account/serialization.d.ts.map +1 -0
- package/dist/browser/index.js +56253 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/wallet/index.js +55974 -0
- package/dist/browser/wallet/index.js.map +1 -0
- package/dist/clients/broadcaster.d.ts +8 -2
- package/dist/clients/broadcaster.d.ts.map +1 -1
- package/dist/clients/http.d.ts +6 -0
- package/dist/clients/http.d.ts.map +1 -1
- package/dist/clients/indexer.d.ts +16 -0
- package/dist/clients/indexer.d.ts.map +1 -1
- package/dist/config.d.ts +35 -9
- package/dist/config.d.ts.map +1 -1
- package/dist/constants.d.ts +6 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/core.d.ts.map +1 -1
- package/dist/crypto/adapters/index.d.ts +17 -0
- package/dist/crypto/adapters/index.d.ts.map +1 -0
- package/dist/crypto/adapters/polyfills.d.ts +5 -0
- package/dist/crypto/adapters/polyfills.d.ts.map +1 -0
- package/dist/crypto/encrypt.d.ts +33 -0
- package/dist/crypto/encrypt.d.ts.map +1 -0
- package/dist/crypto/secure-memory.d.ts +25 -0
- package/dist/crypto/secure-memory.d.ts.map +1 -0
- package/dist/errors.d.ts +17 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/history/index.d.ts +3 -0
- package/dist/history/index.d.ts.map +1 -0
- package/dist/history/service.d.ts +46 -0
- package/dist/history/service.d.ts.map +1 -0
- package/dist/history/types.d.ts +21 -0
- package/dist/history/types.d.ts.map +1 -0
- package/dist/index.d.ts +16 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9969 -16
- package/dist/index.js.map +1 -0
- package/dist/keys/address.d.ts +13 -0
- package/dist/keys/address.d.ts.map +1 -0
- package/dist/keys/derive.d.ts +37 -0
- package/dist/keys/derive.d.ts.map +1 -0
- package/dist/keys/hex.d.ts +14 -0
- package/dist/keys/hex.d.ts.map +1 -0
- package/dist/keys/index.d.ts +5 -0
- package/dist/keys/index.d.ts.map +1 -0
- package/dist/keys/mnemonic.d.ts +6 -0
- package/dist/keys/mnemonic.d.ts.map +1 -0
- package/dist/keys.d.ts +5 -1
- package/dist/keys.d.ts.map +1 -1
- package/dist/prover/config.d.ts +53 -22
- package/dist/prover/config.d.ts.map +1 -1
- package/dist/prover/integrity.d.ts +20 -0
- package/dist/prover/integrity.d.ts.map +1 -0
- package/dist/prover/prover.d.ts +16 -20
- package/dist/prover/prover.d.ts.map +1 -1
- package/dist/prover/registry.d.ts +3 -30
- package/dist/prover/registry.d.ts.map +1 -1
- package/dist/state/merkle/hydrator.d.ts +21 -19
- package/dist/state/merkle/hydrator.d.ts.map +1 -1
- package/dist/state/merkle/index.d.ts +2 -2
- package/dist/state/merkle/index.d.ts.map +1 -1
- package/dist/state/merkle/merkle-tree.d.ts +8 -0
- package/dist/state/merkle/merkle-tree.d.ts.map +1 -1
- package/dist/state/store/ciphertext-store.d.ts +11 -0
- package/dist/state/store/ciphertext-store.d.ts.map +1 -1
- package/dist/state/store/history-store.d.ts +24 -0
- package/dist/state/store/history-store.d.ts.map +1 -0
- package/dist/state/store/index.d.ts +3 -2
- package/dist/state/store/index.d.ts.map +1 -1
- package/dist/state/store/job-store.d.ts +7 -7
- package/dist/state/store/job-store.d.ts.map +1 -1
- package/dist/state/store/jobs.d.ts +70 -25
- package/dist/state/store/jobs.d.ts.map +1 -1
- package/dist/state/store/leaf-store.d.ts +4 -0
- package/dist/state/store/leaf-store.d.ts.map +1 -1
- package/dist/state/store/note-store.d.ts +7 -7
- package/dist/state/store/note-store.d.ts.map +1 -1
- package/dist/state/store/nullifier-store.d.ts +9 -0
- package/dist/state/store/nullifier-store.d.ts.map +1 -1
- package/dist/state/store/records.d.ts +39 -2
- package/dist/state/store/records.d.ts.map +1 -1
- package/dist/state/store/root-store.d.ts.map +1 -1
- package/dist/state/store/store.d.ts +79 -27
- package/dist/state/store/store.d.ts.map +1 -1
- package/dist/storage/indexeddb.d.ts.map +1 -1
- package/dist/storage/memory.d.ts.map +1 -1
- package/dist/transactions/adapter.d.ts +31 -0
- package/dist/transactions/adapter.d.ts.map +1 -0
- package/dist/transactions/deposit.d.ts +12 -17
- package/dist/transactions/deposit.d.ts.map +1 -1
- package/dist/transactions/index.d.ts +9 -4
- package/dist/transactions/index.d.ts.map +1 -1
- package/dist/transactions/note-selection.d.ts +17 -0
- package/dist/transactions/note-selection.d.ts.map +1 -0
- package/dist/transactions/note-sync.d.ts +5 -33
- package/dist/transactions/note-sync.d.ts.map +1 -1
- package/dist/transactions/reconcile.d.ts +9 -11
- package/dist/transactions/reconcile.d.ts.map +1 -1
- package/dist/transactions/transact.d.ts +30 -27
- package/dist/transactions/transact.d.ts.map +1 -1
- package/dist/transactions/transaction-planner.d.ts +34 -0
- package/dist/transactions/transaction-planner.d.ts.map +1 -0
- package/dist/transactions/transfer-planner.d.ts +37 -0
- package/dist/transactions/transfer-planner.d.ts.map +1 -0
- package/dist/transactions/types/deposit.d.ts +67 -0
- package/dist/transactions/types/deposit.d.ts.map +1 -0
- package/dist/transactions/types/domain.d.ts +70 -0
- package/dist/transactions/types/domain.d.ts.map +1 -0
- package/dist/transactions/types/index.d.ts +18 -0
- package/dist/transactions/types/index.d.ts.map +1 -0
- package/dist/transactions/types/options.d.ts +54 -0
- package/dist/transactions/types/options.d.ts.map +1 -0
- package/dist/transactions/types/planning.d.ts +82 -0
- package/dist/transactions/types/planning.d.ts.map +1 -0
- package/dist/transactions/types/state-stores.d.ts +151 -0
- package/dist/transactions/types/state-stores.d.ts.map +1 -0
- package/dist/transactions/types/transact.d.ts +83 -0
- package/dist/transactions/types/transact.d.ts.map +1 -0
- package/dist/transactions/withdrawal-planner.d.ts +58 -0
- package/dist/transactions/withdrawal-planner.d.ts.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/tsup.browser.config.d.ts +7 -0
- package/dist/tsup.browser.config.d.ts.map +1 -0
- package/dist/tsup.config.d.ts +8 -0
- package/dist/tsup.config.d.ts.map +1 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/amounts.d.ts +26 -0
- package/dist/utils/amounts.d.ts.map +1 -0
- package/dist/utils/async.d.ts +9 -0
- package/dist/utils/async.d.ts.map +1 -1
- package/dist/utils/async.js +38 -11
- package/dist/utils/async.js.map +1 -0
- package/dist/utils/bigint.d.ts +0 -2
- package/dist/utils/bigint.d.ts.map +1 -1
- package/dist/utils/format.d.ts +25 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/notes.d.ts +15 -0
- package/dist/utils/notes.d.ts.map +1 -0
- package/dist/utils/polling.d.ts +5 -0
- package/dist/utils/polling.d.ts.map +1 -1
- package/dist/utils/random.d.ts +18 -0
- package/dist/utils/random.d.ts.map +1 -0
- package/dist/utils/signature.d.ts +6 -0
- package/dist/utils/signature.d.ts.map +1 -1
- package/dist/utils/validators.d.ts +21 -10
- package/dist/utils/validators.d.ts.map +1 -1
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/wallet/adapter.d.ts +21 -0
- package/dist/wallet/adapter.d.ts.map +1 -0
- package/dist/wallet/burner/service.d.ts +32 -0
- package/dist/wallet/burner/service.d.ts.map +1 -0
- package/dist/wallet/burner/types.d.ts +47 -0
- package/dist/wallet/burner/types.d.ts.map +1 -0
- package/dist/wallet/index.d.ts +20 -0
- package/dist/wallet/index.d.ts.map +1 -0
- package/dist/wallet/index.js +9712 -0
- package/dist/wallet/index.js.map +1 -0
- package/dist/wallet/sdk.d.ts +47 -0
- package/dist/wallet/sdk.d.ts.map +1 -0
- package/dist/wallet/types.d.ts +455 -0
- package/dist/wallet/types.d.ts.map +1 -0
- package/dist/wallet/unlink-wallet.d.ts +186 -0
- package/dist/wallet/unlink-wallet.d.ts.map +1 -0
- package/package.json +40 -14
- package/dist/account/zkAccount.d.ts.map +0 -1
- package/dist/account/zkAccount.js +0 -128
- package/dist/clients/broadcaster.js +0 -23
- package/dist/clients/http.js +0 -57
- package/dist/clients/indexer.js +0 -67
- package/dist/config.js +0 -29
- package/dist/core.js +0 -12
- package/dist/errors.js +0 -18
- package/dist/key-derivation/babyjubjub.d.ts +0 -9
- package/dist/key-derivation/babyjubjub.d.ts.map +0 -1
- package/dist/key-derivation/babyjubjub.js +0 -9
- package/dist/key-derivation/bech32.d.ts +0 -22
- package/dist/key-derivation/bech32.d.ts.map +0 -1
- package/dist/key-derivation/bech32.js +0 -86
- package/dist/key-derivation/bip32.d.ts +0 -17
- package/dist/key-derivation/bip32.d.ts.map +0 -1
- package/dist/key-derivation/bip32.js +0 -41
- package/dist/key-derivation/bip39.d.ts +0 -22
- package/dist/key-derivation/bip39.d.ts.map +0 -1
- package/dist/key-derivation/bip39.js +0 -56
- package/dist/key-derivation/bytes.d.ts +0 -19
- package/dist/key-derivation/bytes.d.ts.map +0 -1
- package/dist/key-derivation/bytes.js +0 -92
- package/dist/key-derivation/hash.d.ts +0 -3
- package/dist/key-derivation/hash.d.ts.map +0 -1
- package/dist/key-derivation/hash.js +0 -10
- package/dist/key-derivation/index.d.ts +0 -8
- package/dist/key-derivation/index.d.ts.map +0 -1
- package/dist/key-derivation/index.js +0 -7
- package/dist/key-derivation/wallet-node.d.ts +0 -45
- package/dist/key-derivation/wallet-node.d.ts.map +0 -1
- package/dist/key-derivation/wallet-node.js +0 -109
- package/dist/keys.js +0 -41
- package/dist/prover/config.js +0 -80
- package/dist/prover/index.js +0 -1
- package/dist/prover/prover.js +0 -274
- package/dist/prover/registry.js +0 -57
- package/dist/schema.js +0 -14
- package/dist/state/ciphertext-store.d.ts +0 -12
- package/dist/state/ciphertext-store.d.ts.map +0 -1
- package/dist/state/ciphertext-store.js +0 -25
- package/dist/state/index.js +0 -2
- package/dist/state/leaf-store.d.ts +0 -17
- package/dist/state/leaf-store.d.ts.map +0 -1
- package/dist/state/leaf-store.js +0 -35
- package/dist/state/merkle/hydrator.js +0 -36
- package/dist/state/merkle/index.js +0 -2
- package/dist/state/merkle/merkle-tree.js +0 -104
- package/dist/state/merkle-tree.d.ts +0 -34
- package/dist/state/merkle-tree.d.ts.map +0 -1
- package/dist/state/merkle-tree.js +0 -104
- package/dist/state/note-store.d.ts +0 -37
- package/dist/state/note-store.d.ts.map +0 -1
- package/dist/state/note-store.js +0 -133
- package/dist/state/nullifier-store.d.ts +0 -13
- package/dist/state/nullifier-store.d.ts.map +0 -1
- package/dist/state/nullifier-store.js +0 -21
- package/dist/state/records.d.ts +0 -57
- package/dist/state/records.d.ts.map +0 -1
- package/dist/state/records.js +0 -1
- package/dist/state/root-store.d.ts +0 -13
- package/dist/state/root-store.d.ts.map +0 -1
- package/dist/state/root-store.js +0 -30
- package/dist/state/store/ciphertext-store.js +0 -25
- package/dist/state/store/index.js +0 -8
- package/dist/state/store/job-store.js +0 -118
- package/dist/state/store/jobs.js +0 -1
- package/dist/state/store/leaf-store.js +0 -35
- package/dist/state/store/note-store.js +0 -142
- package/dist/state/store/nullifier-store.js +0 -30
- package/dist/state/store/records.js +0 -1
- package/dist/state/store/root-store.js +0 -30
- package/dist/state/store/store.js +0 -22
- package/dist/state/store.d.ts +0 -26
- package/dist/state/store.d.ts.map +0 -1
- package/dist/state/store.js +0 -19
- package/dist/storage/index.js +0 -2
- package/dist/storage/indexeddb.js +0 -205
- package/dist/storage/memory.js +0 -87
- package/dist/transactions/deposit.js +0 -173
- package/dist/transactions/index.js +0 -4
- package/dist/transactions/note-sync.js +0 -320
- package/dist/transactions/reconcile.js +0 -39
- package/dist/transactions/transact.js +0 -561
- package/dist/transactions/types.d.ts +0 -114
- package/dist/transactions/types.d.ts.map +0 -1
- package/dist/transactions/types.js +0 -1
- package/dist/types.js +0 -1
- package/dist/utils/bigint.js +0 -29
- package/dist/utils/crypto.d.ts +0 -12
- package/dist/utils/crypto.d.ts.map +0 -1
- package/dist/utils/crypto.js +0 -39
- package/dist/utils/json-codec.js +0 -25
- package/dist/utils/polling.js +0 -6
- package/dist/utils/signature.js +0 -12
- package/dist/utils/validators.js +0 -70
package/dist/prover/config.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Configuration for the prover system
|
|
3
|
-
* Handles artifact loading from local files or remote artifact server
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* Default configuration
|
|
7
|
-
* Can be overridden via environment variables
|
|
8
|
-
*/
|
|
9
|
-
export const DEFAULT_CONFIG = {
|
|
10
|
-
rpcUrl: typeof process !== "undefined" && process.env?.UNLINK_RPC_URL
|
|
11
|
-
? process.env.UNLINK_RPC_URL
|
|
12
|
-
: "http://localhost:3000",
|
|
13
|
-
enableCache: true,
|
|
14
|
-
};
|
|
15
|
-
/**
|
|
16
|
-
* Artifact file types
|
|
17
|
-
*/
|
|
18
|
-
export var ArtifactType;
|
|
19
|
-
(function (ArtifactType) {
|
|
20
|
-
ArtifactType["WASM"] = "joinsplit.wasm";
|
|
21
|
-
ArtifactType["ZKEY"] = "joinsplit.zkey";
|
|
22
|
-
ArtifactType["VKEY"] = "joinsplit.vkey.json";
|
|
23
|
-
})(ArtifactType || (ArtifactType = {}));
|
|
24
|
-
/**
|
|
25
|
-
* Build artifact URL for a given circuit and artifact type
|
|
26
|
-
* @param circuitName Full circuit name (e.g., "joinsplit_2x3_16")
|
|
27
|
-
* @param artifactType Type of artifact to fetch
|
|
28
|
-
* @param baseUrl Base URL of the artifact server
|
|
29
|
-
* @returns Full URL to the artifact
|
|
30
|
-
*/
|
|
31
|
-
export function buildArtifactUrl(circuitName, artifactType, baseUrl = DEFAULT_CONFIG.rpcUrl) {
|
|
32
|
-
// Remove trailing slash from baseUrl
|
|
33
|
-
const cleanBaseUrl = baseUrl.replace(/\/$/, "");
|
|
34
|
-
return `${cleanBaseUrl}/artifacts/${circuitName}/${artifactType}`;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Get relative path for local artifact loading
|
|
38
|
-
* Used in Node.js environment when artifacts are bundled
|
|
39
|
-
* @param circuitName Full circuit name (e.g., "joinsplit_2x3_16")
|
|
40
|
-
* @param artifactType Type of artifact
|
|
41
|
-
* @returns Relative path to artifact
|
|
42
|
-
*/
|
|
43
|
-
export function getLocalArtifactPath(circuitName, artifactType) {
|
|
44
|
-
// Return multiple candidate paths for different build scenarios
|
|
45
|
-
return [
|
|
46
|
-
// When compiled: dist/prover/ -> ../../artifacts/circuits/{circuit}/
|
|
47
|
-
`../../artifacts/circuits/${circuitName}/${artifactType}`,
|
|
48
|
-
// When in source: prover/ -> ../artifacts/circuits/{circuit}/
|
|
49
|
-
`../artifacts/circuits/${circuitName}/${artifactType}`,
|
|
50
|
-
];
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Runtime detection utilities
|
|
54
|
-
*/
|
|
55
|
-
export const Runtime = {
|
|
56
|
-
/**
|
|
57
|
-
* Check if running in browser environment
|
|
58
|
-
*/
|
|
59
|
-
isBrowser() {
|
|
60
|
-
return typeof window !== "undefined" && typeof document !== "undefined";
|
|
61
|
-
},
|
|
62
|
-
/**
|
|
63
|
-
* Check if running in Node.js environment
|
|
64
|
-
*/
|
|
65
|
-
isNode() {
|
|
66
|
-
return (typeof process !== "undefined" &&
|
|
67
|
-
process.versions != null &&
|
|
68
|
-
process.versions.node != null);
|
|
69
|
-
},
|
|
70
|
-
/**
|
|
71
|
-
* Get environment description for debugging
|
|
72
|
-
*/
|
|
73
|
-
getEnvironment() {
|
|
74
|
-
if (this.isBrowser())
|
|
75
|
-
return "browser";
|
|
76
|
-
if (this.isNode())
|
|
77
|
-
return "node";
|
|
78
|
-
return "unknown";
|
|
79
|
-
},
|
|
80
|
-
};
|
package/dist/prover/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./prover.js";
|
package/dist/prover/prover.js
DELETED
|
@@ -1,274 +0,0 @@
|
|
|
1
|
-
import * as snarkjs from "snarkjs";
|
|
2
|
-
import { CoreError } from "../errors.js";
|
|
3
|
-
import { ArtifactType, buildArtifactUrl, DEFAULT_CONFIG, getLocalArtifactPath, Runtime, } from "./config.js";
|
|
4
|
-
import { getCircuitConfig, SUPPORTED_CIRCUITS, } from "./registry.js";
|
|
5
|
-
// Cache for loaded artifacts to avoid reloading 18MB of files on every call
|
|
6
|
-
// Now keyed by circuit name to support multiple circuits
|
|
7
|
-
const artifactCache = {};
|
|
8
|
-
/**
|
|
9
|
-
* Select the appropriate circuit based on input/output dimensions
|
|
10
|
-
* @param inputs Number of inputs (nullifiers)
|
|
11
|
-
* @param outputs Number of outputs (commitments)
|
|
12
|
-
* @returns Circuit configuration
|
|
13
|
-
* @throws CoreError if no matching circuit is found
|
|
14
|
-
*/
|
|
15
|
-
function selectCircuit(inputs, outputs) {
|
|
16
|
-
const config = getCircuitConfig(inputs, outputs);
|
|
17
|
-
if (!config) {
|
|
18
|
-
throw new CoreError(`No circuit available for ${inputs} inputs and ${outputs} outputs. ` +
|
|
19
|
-
`Supported circuits: ${SUPPORTED_CIRCUITS.join(", ")}`);
|
|
20
|
-
}
|
|
21
|
-
return config;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Fetch circuit artifacts for a specific circuit
|
|
25
|
-
* Supports both browser (remote) and Node.js (local) environments
|
|
26
|
-
* @param circuitName Full circuit name (e.g., "joinsplit_2x3_16")
|
|
27
|
-
* @returns Artifacts object with wasm, zkey, and vkey
|
|
28
|
-
*/
|
|
29
|
-
async function fetchCircuitArtifacts(circuitName) {
|
|
30
|
-
// Check cache first
|
|
31
|
-
if (artifactCache[circuitName]) {
|
|
32
|
-
return artifactCache[circuitName];
|
|
33
|
-
}
|
|
34
|
-
let wasm;
|
|
35
|
-
let zkey;
|
|
36
|
-
let vkey;
|
|
37
|
-
// Browser environment: fetch from artifact server
|
|
38
|
-
if (Runtime.isBrowser()) {
|
|
39
|
-
try {
|
|
40
|
-
const baseUrl = DEFAULT_CONFIG.rpcUrl;
|
|
41
|
-
const wasmUrl = buildArtifactUrl(circuitName, ArtifactType.WASM, baseUrl);
|
|
42
|
-
const zkeyUrl = buildArtifactUrl(circuitName, ArtifactType.ZKEY, baseUrl);
|
|
43
|
-
const vkeyUrl = buildArtifactUrl(circuitName, ArtifactType.VKEY, baseUrl);
|
|
44
|
-
const [wasmRes, zkeyRes, vkeyRes] = await Promise.all([
|
|
45
|
-
fetch(wasmUrl),
|
|
46
|
-
fetch(zkeyUrl),
|
|
47
|
-
fetch(vkeyUrl),
|
|
48
|
-
]);
|
|
49
|
-
if (!wasmRes.ok || !zkeyRes.ok || !vkeyRes.ok) {
|
|
50
|
-
throw new CoreError(`Failed to fetch artifacts for ${circuitName} from ${baseUrl}. ` +
|
|
51
|
-
`Status: wasm=${wasmRes.status}, zkey=${zkeyRes.status}, vkey=${vkeyRes.status}`);
|
|
52
|
-
}
|
|
53
|
-
wasm = new Uint8Array(await wasmRes.arrayBuffer());
|
|
54
|
-
zkey = new Uint8Array(await zkeyRes.arrayBuffer());
|
|
55
|
-
vkey = await vkeyRes.json();
|
|
56
|
-
}
|
|
57
|
-
catch (error) {
|
|
58
|
-
throw new CoreError(`Failed to fetch artifacts from server for ${circuitName}: ${error.message}`);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
// Node.js environment: try local file paths
|
|
62
|
-
else {
|
|
63
|
-
const wasmCandidates = getLocalArtifactPath(circuitName, ArtifactType.WASM);
|
|
64
|
-
const zkeyCandidates = getLocalArtifactPath(circuitName, ArtifactType.ZKEY);
|
|
65
|
-
const vkeyCandidates = getLocalArtifactPath(circuitName, ArtifactType.VKEY);
|
|
66
|
-
let wasmLoaded = false;
|
|
67
|
-
for (const candidate of wasmCandidates) {
|
|
68
|
-
try {
|
|
69
|
-
wasm = await readBinaryResource(candidate);
|
|
70
|
-
wasmLoaded = true;
|
|
71
|
-
break;
|
|
72
|
-
}
|
|
73
|
-
catch {
|
|
74
|
-
// Try next candidate
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
if (!wasmLoaded) {
|
|
78
|
-
throw new CoreError(`Could not find WASM artifact for ${circuitName}. ` +
|
|
79
|
-
`Please run 'pnpm run build:all' in the circuits package.`);
|
|
80
|
-
}
|
|
81
|
-
// Load zkey
|
|
82
|
-
let zkeyLoaded = false;
|
|
83
|
-
for (const candidate of zkeyCandidates) {
|
|
84
|
-
try {
|
|
85
|
-
zkey = await readBinaryResource(candidate);
|
|
86
|
-
zkeyLoaded = true;
|
|
87
|
-
break;
|
|
88
|
-
}
|
|
89
|
-
catch {
|
|
90
|
-
// Try next candidate
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
if (!zkeyLoaded) {
|
|
94
|
-
throw new CoreError(`Could not find zkey artifact for ${circuitName}. ` +
|
|
95
|
-
`Please run 'pnpm run build:all' in the circuits package.`);
|
|
96
|
-
}
|
|
97
|
-
// Load vkey
|
|
98
|
-
let vkeyLoaded = false;
|
|
99
|
-
for (const candidate of vkeyCandidates) {
|
|
100
|
-
try {
|
|
101
|
-
const vkeyText = await readTextResource(candidate);
|
|
102
|
-
vkey = JSON.parse(vkeyText);
|
|
103
|
-
vkeyLoaded = true;
|
|
104
|
-
break;
|
|
105
|
-
}
|
|
106
|
-
catch {
|
|
107
|
-
// Try next candidate
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
if (!vkeyLoaded) {
|
|
111
|
-
throw new CoreError(`Could not find verification key for ${circuitName}. ` +
|
|
112
|
-
`Please run 'pnpm run build:all' in the circuits package.`);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
// Verify all artifacts were loaded
|
|
116
|
-
if (!wasm || !zkey || !vkey) {
|
|
117
|
-
throw new CoreError(`Failed to load all artifacts for ${circuitName}. ` +
|
|
118
|
-
`Missing: ${!wasm ? "wasm " : ""}${!zkey ? "zkey " : ""}${!vkey ? "vkey" : ""}`);
|
|
119
|
-
}
|
|
120
|
-
// Cache the artifacts for future calls
|
|
121
|
-
// TypeScript now knows these are defined after the check above
|
|
122
|
-
const artifacts = { wasm, zkey, vkey };
|
|
123
|
-
artifactCache[circuitName] = artifacts;
|
|
124
|
-
return artifacts;
|
|
125
|
-
}
|
|
126
|
-
async function readBinaryResource(relativePath) {
|
|
127
|
-
const url = new URL(relativePath, import.meta.url);
|
|
128
|
-
try {
|
|
129
|
-
if (url.protocol === "file:") {
|
|
130
|
-
const fs = (await import("fs")).default;
|
|
131
|
-
const readPromise = new Promise((resolve, reject) => {
|
|
132
|
-
fs.readFile(url.pathname, (err, data) => {
|
|
133
|
-
if (err) {
|
|
134
|
-
reject(err);
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
resolve(data);
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
});
|
|
141
|
-
const buf = await readPromise;
|
|
142
|
-
return new Uint8Array(buf);
|
|
143
|
-
}
|
|
144
|
-
const response = await fetch(url);
|
|
145
|
-
if (!response.ok) {
|
|
146
|
-
throw new CoreError(`failed to fetch ${relativePath}: ${response.statusText}`);
|
|
147
|
-
}
|
|
148
|
-
return new Uint8Array(await response.arrayBuffer());
|
|
149
|
-
}
|
|
150
|
-
catch (error) {
|
|
151
|
-
throw new CoreError(`failed to read binary resource ${relativePath}: ${error.message}`);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
async function readTextResource(relativePath) {
|
|
155
|
-
const url = new URL(relativePath, import.meta.url);
|
|
156
|
-
if (url.protocol === "file:") {
|
|
157
|
-
const fs = (await import("fs")).default;
|
|
158
|
-
const readPromise = new Promise((resolve, reject) => {
|
|
159
|
-
fs.readFile(url.pathname, (err, data) => {
|
|
160
|
-
if (err) {
|
|
161
|
-
reject(err);
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
resolve(data);
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
|
-
});
|
|
168
|
-
const buf = await readPromise;
|
|
169
|
-
return buf.toString("utf-8");
|
|
170
|
-
}
|
|
171
|
-
const response = await fetch(url);
|
|
172
|
-
if (!response.ok) {
|
|
173
|
-
throw new CoreError(`failed to fetch ${relativePath}: ${response.statusText}`);
|
|
174
|
-
}
|
|
175
|
-
return response.text();
|
|
176
|
-
}
|
|
177
|
-
export async function proveTransaction(input) {
|
|
178
|
-
try {
|
|
179
|
-
// Auto-detect circuit based on input dimensions
|
|
180
|
-
const nInputs = input.nullifiers.length;
|
|
181
|
-
const nOutputs = input.commitmentsOut.length;
|
|
182
|
-
const circuit = selectCircuit(nInputs, nOutputs);
|
|
183
|
-
// Fetch circuit artifacts (wasm and zkey)
|
|
184
|
-
const { wasm, vkey, zkey } = await fetchCircuitArtifacts(circuit.name);
|
|
185
|
-
const inputSignals = input;
|
|
186
|
-
const { proof, publicSignals } = await snarkjs.groth16.fullProve(inputSignals, wasm, zkey);
|
|
187
|
-
// Additional verification step (optional)
|
|
188
|
-
const isValid = await snarkjs.groth16.verify(vkey, publicSignals, proof);
|
|
189
|
-
if (!isValid) {
|
|
190
|
-
throw new CoreError("generated proof is invalid");
|
|
191
|
-
}
|
|
192
|
-
return {
|
|
193
|
-
proof,
|
|
194
|
-
publicSignals,
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
catch (error) {
|
|
198
|
-
throw new CoreError("proof generation failed: " + error.message);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
/**
|
|
202
|
-
* Get verification key for a specific circuit configuration
|
|
203
|
-
* @param inputs Number of inputs (nullifiers)
|
|
204
|
-
* @param outputs Number of outputs (commitments)
|
|
205
|
-
* @returns Verification key for the circuit
|
|
206
|
-
*/
|
|
207
|
-
export async function getVerificationKey(inputs, outputs) {
|
|
208
|
-
try {
|
|
209
|
-
const circuit = selectCircuit(inputs, outputs);
|
|
210
|
-
const { vkey } = await fetchCircuitArtifacts(circuit.name);
|
|
211
|
-
return vkey;
|
|
212
|
-
}
|
|
213
|
-
catch (error) {
|
|
214
|
-
throw new CoreError("failed to load verification key: " + error.message);
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
/**
|
|
218
|
-
* Verify a proof with public signals
|
|
219
|
-
* Auto-detects the circuit from the public signals structure
|
|
220
|
-
* @param proof Groth16 proof
|
|
221
|
-
* @param publicSignals Public signals array
|
|
222
|
-
* @returns True if proof is valid
|
|
223
|
-
*/
|
|
224
|
-
export async function verifyProof(proof, publicSignals) {
|
|
225
|
-
try {
|
|
226
|
-
// Public signals structure: [merkleRoot, boundParamsHash, ...nullifiers, ...commitments]
|
|
227
|
-
// We need to determine the circuit from the length
|
|
228
|
-
// This is tricky without additional context, so we'll need to try to infer
|
|
229
|
-
// or require explicit circuit specification
|
|
230
|
-
// For now, extract nullifier and commitment counts from the public signals
|
|
231
|
-
// The caller should know this information, but we can make an educated guess
|
|
232
|
-
// based on the total length and circuit registry
|
|
233
|
-
// Length = 2 (root + hash) + nInputs + nOutputs
|
|
234
|
-
const totalLength = publicSignals.length;
|
|
235
|
-
const variableCount = totalLength - 2; // Remove merkleRoot and boundParamsHash
|
|
236
|
-
// Try to find a matching circuit
|
|
237
|
-
let vkey = null;
|
|
238
|
-
for (const circuitKey of SUPPORTED_CIRCUITS) {
|
|
239
|
-
const parts = circuitKey.split("x");
|
|
240
|
-
const config = getCircuitConfig(parseInt(parts[0]), parseInt(parts[1]));
|
|
241
|
-
if (config && config.inputs + config.outputs === variableCount) {
|
|
242
|
-
const artifacts = await fetchCircuitArtifacts(config.name);
|
|
243
|
-
vkey = artifacts.vkey;
|
|
244
|
-
break;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
if (!vkey) {
|
|
248
|
-
throw new CoreError(`Could not determine circuit from ${totalLength} public signals`);
|
|
249
|
-
}
|
|
250
|
-
return await snarkjs.groth16.verify(vkey, publicSignals, proof);
|
|
251
|
-
}
|
|
252
|
-
catch (error) {
|
|
253
|
-
throw new CoreError("proof verification failed: " + error.message);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
/**
|
|
257
|
-
* Verify a proof with explicit circuit specification
|
|
258
|
-
* Preferred method when you know the circuit dimensions
|
|
259
|
-
* @param proof Groth16 proof
|
|
260
|
-
* @param publicSignals Public signals array
|
|
261
|
-
* @param inputs Number of inputs (nullifiers)
|
|
262
|
-
* @param outputs Number of outputs (commitments)
|
|
263
|
-
* @returns True if proof is valid
|
|
264
|
-
*/
|
|
265
|
-
export async function verifyProofWithCircuit(proof, publicSignals, inputs, outputs) {
|
|
266
|
-
try {
|
|
267
|
-
const circuit = selectCircuit(inputs, outputs);
|
|
268
|
-
const { vkey } = await fetchCircuitArtifacts(circuit.name);
|
|
269
|
-
return await snarkjs.groth16.verify(vkey, publicSignals, proof);
|
|
270
|
-
}
|
|
271
|
-
catch (error) {
|
|
272
|
-
throw new CoreError("proof verification failed: " + error.message);
|
|
273
|
-
}
|
|
274
|
-
}
|
package/dist/prover/registry.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
// AUTO-GENERATED FILE - DO NOT EDIT MANUALLY
|
|
2
|
-
// Generated by scripts/generate-registry.ts
|
|
3
|
-
// Source: circuits/circuits.json
|
|
4
|
-
// Generated at: 2025-11-25T13:26:58.576Z
|
|
5
|
-
/**
|
|
6
|
-
* Registry of available circuits
|
|
7
|
-
* Auto-generated from circuits/circuits.json
|
|
8
|
-
*/
|
|
9
|
-
export const CIRCUIT_REGISTRY = {
|
|
10
|
-
"3x3": {
|
|
11
|
-
name: "joinsplit_3x3_16",
|
|
12
|
-
inputs: 3,
|
|
13
|
-
outputs: 3,
|
|
14
|
-
depth: 16,
|
|
15
|
-
},
|
|
16
|
-
"2x3": {
|
|
17
|
-
name: "joinsplit_2x3_16",
|
|
18
|
-
inputs: 2,
|
|
19
|
-
outputs: 3,
|
|
20
|
-
depth: 16,
|
|
21
|
-
},
|
|
22
|
-
"1x2": {
|
|
23
|
-
name: "joinsplit_1x2_16",
|
|
24
|
-
inputs: 1,
|
|
25
|
-
outputs: 2,
|
|
26
|
-
depth: 16,
|
|
27
|
-
},
|
|
28
|
-
"1x1": {
|
|
29
|
-
name: "joinsplit_1x1_16",
|
|
30
|
-
inputs: 1,
|
|
31
|
-
outputs: 1,
|
|
32
|
-
depth: 16,
|
|
33
|
-
},
|
|
34
|
-
};
|
|
35
|
-
/**
|
|
36
|
-
* Get list of all supported circuit keys
|
|
37
|
-
*/
|
|
38
|
-
export const SUPPORTED_CIRCUITS = Object.keys(CIRCUIT_REGISTRY);
|
|
39
|
-
/**
|
|
40
|
-
* Get circuit configuration by dimensions
|
|
41
|
-
* @param inputs Number of inputs (nullifiers)
|
|
42
|
-
* @param outputs Number of outputs (commitments)
|
|
43
|
-
* @returns Circuit configuration or undefined if not supported
|
|
44
|
-
*/
|
|
45
|
-
export function getCircuitConfig(inputs, outputs) {
|
|
46
|
-
const key = `${inputs}x${outputs}`;
|
|
47
|
-
return CIRCUIT_REGISTRY[key];
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Check if a circuit configuration is supported
|
|
51
|
-
* @param inputs Number of inputs (nullifiers)
|
|
52
|
-
* @param outputs Number of outputs (commitments)
|
|
53
|
-
* @returns True if supported
|
|
54
|
-
*/
|
|
55
|
-
export function isCircuitSupported(inputs, outputs) {
|
|
56
|
-
return getCircuitConfig(inputs, outputs) !== undefined;
|
|
57
|
-
}
|
package/dist/schema.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { SchemaMismatchError } from "./errors.js";
|
|
2
|
-
export const CORE_SCHEMA_VERSION = 1;
|
|
3
|
-
export async function migrate(storage) {
|
|
4
|
-
await storage.open();
|
|
5
|
-
const current = await storage.getSchemaVersion();
|
|
6
|
-
if (current === 0) {
|
|
7
|
-
// seed structures if needed
|
|
8
|
-
await storage.setSchemaVersion(CORE_SCHEMA_VERSION);
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
if (current !== CORE_SCHEMA_VERSION) {
|
|
12
|
-
throw new SchemaMismatchError(current, CORE_SCHEMA_VERSION);
|
|
13
|
-
}
|
|
14
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { Storage } from "../types.js";
|
|
2
|
-
export declare function createCiphertextStore(storage: Storage): {
|
|
3
|
-
/**
|
|
4
|
-
* Store encrypted note payloads alongside their on-chain commitments.
|
|
5
|
-
*/
|
|
6
|
-
putCiphertext(chainId: number, index: number, payload: Uint8Array): Promise<void>;
|
|
7
|
-
/**
|
|
8
|
-
* Retrieve encrypted note payloads; returns null when the ciphertext is missing.
|
|
9
|
-
*/
|
|
10
|
-
getCiphertext(chainId: number, index: number): Promise<Uint8Array<ArrayBuffer> | null>;
|
|
11
|
-
};
|
|
12
|
-
//# sourceMappingURL=ciphertext-store.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ciphertext-store.d.ts","sourceRoot":"","sources":["../../state/ciphertext-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAG3C,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO;IAElD;;OAEG;2BAC0B,MAAM,SAAS,MAAM,WAAW,UAAU;IAQvE;;OAEG;2BAC0B,MAAM,SAAS,MAAM;EAOrD"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { keys, validateKey } from "../keys.js";
|
|
2
|
-
import { ensureChainId, ensurePositiveInt } from "../utils/validators.js";
|
|
3
|
-
export function createCiphertextStore(storage) {
|
|
4
|
-
return {
|
|
5
|
-
/**
|
|
6
|
-
* Store encrypted note payloads alongside their on-chain commitments.
|
|
7
|
-
*/
|
|
8
|
-
async putCiphertext(chainId, index, payload) {
|
|
9
|
-
ensureChainId(chainId);
|
|
10
|
-
ensurePositiveInt("ciphertext index", index);
|
|
11
|
-
const key = keys.ciphertext(chainId, index);
|
|
12
|
-
validateKey(key);
|
|
13
|
-
await storage.put(key, new Uint8Array(payload));
|
|
14
|
-
},
|
|
15
|
-
/**
|
|
16
|
-
* Retrieve encrypted note payloads; returns null when the ciphertext is missing.
|
|
17
|
-
*/
|
|
18
|
-
async getCiphertext(chainId, index) {
|
|
19
|
-
ensureChainId(chainId);
|
|
20
|
-
ensurePositiveInt("ciphertext index", index);
|
|
21
|
-
const data = await storage.get(keys.ciphertext(chainId, index));
|
|
22
|
-
return data ? new Uint8Array(data) : null;
|
|
23
|
-
},
|
|
24
|
-
};
|
|
25
|
-
}
|
package/dist/state/index.js
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { Storage } from "../types.js";
|
|
2
|
-
import type { LeafRecord } from "./records.js";
|
|
3
|
-
export declare function createLeafStore(storage: Storage): {
|
|
4
|
-
/**
|
|
5
|
-
* Cache public leaf data pulled from the on-chain Merkle tree.
|
|
6
|
-
*/
|
|
7
|
-
putLeaf(leaf: LeafRecord): Promise<void>;
|
|
8
|
-
/**
|
|
9
|
-
* Load a leaf commitment by tree index.
|
|
10
|
-
*/
|
|
11
|
-
getLeaf(chainId: number, index: number): Promise<LeafRecord | null>;
|
|
12
|
-
/**
|
|
13
|
-
* Remove all cached leaves for a chain.
|
|
14
|
-
*/
|
|
15
|
-
clearLeaves(chainId: number): Promise<void>;
|
|
16
|
-
};
|
|
17
|
-
//# sourceMappingURL=leaf-store.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"leaf-store.d.ts","sourceRoot":"","sources":["../../state/leaf-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO;IAE5C;;OAEG;kBACiB,UAAU;IAM9B;;OAEG;qBACoB,MAAM,SAAS,MAAM;IAM5C;;OAEG;yBACwB,MAAM;EASpC"}
|
package/dist/state/leaf-store.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { keys } from "../keys.js";
|
|
2
|
-
import { getJson, putJson } from "../utils/json-codec.js";
|
|
3
|
-
import { ensureChainId, ensurePositiveInt } from "../utils/validators.js";
|
|
4
|
-
export function createLeafStore(storage) {
|
|
5
|
-
return {
|
|
6
|
-
/**
|
|
7
|
-
* Cache public leaf data pulled from the on-chain Merkle tree.
|
|
8
|
-
*/
|
|
9
|
-
async putLeaf(leaf) {
|
|
10
|
-
ensureChainId(leaf.chainId);
|
|
11
|
-
ensurePositiveInt("leaf index", leaf.index);
|
|
12
|
-
await putJson(storage, keys.leaf(leaf.chainId, leaf.index), leaf);
|
|
13
|
-
},
|
|
14
|
-
/**
|
|
15
|
-
* Load a leaf commitment by tree index.
|
|
16
|
-
*/
|
|
17
|
-
async getLeaf(chainId, index) {
|
|
18
|
-
ensureChainId(chainId);
|
|
19
|
-
ensurePositiveInt("leaf index", index);
|
|
20
|
-
return getJson(storage, keys.leaf(chainId, index));
|
|
21
|
-
},
|
|
22
|
-
/**
|
|
23
|
-
* Remove all cached leaves for a chain.
|
|
24
|
-
*/
|
|
25
|
-
async clearLeaves(chainId) {
|
|
26
|
-
ensureChainId(chainId);
|
|
27
|
-
const prefix = `leaves:${chainId}:`;
|
|
28
|
-
const entries = await storage.iter({ prefix });
|
|
29
|
-
if (entries.length === 0)
|
|
30
|
-
return;
|
|
31
|
-
const deletions = entries.map(({ key }) => ({ del: key }));
|
|
32
|
-
await storage.batch(deletions);
|
|
33
|
-
},
|
|
34
|
-
};
|
|
35
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { parseHexToBigInt } from "../../utils/bigint.js";
|
|
2
|
-
export async function rebuildTreeFromStore({ chainId, trees, loadLeaf, }) {
|
|
3
|
-
trees.reset(chainId);
|
|
4
|
-
let idx = 0;
|
|
5
|
-
for (;;) {
|
|
6
|
-
const leaf = await loadLeaf(chainId, idx);
|
|
7
|
-
if (!leaf)
|
|
8
|
-
break;
|
|
9
|
-
const { index } = trees.addLeaf(chainId, parseHexToBigInt(leaf.commitment));
|
|
10
|
-
if (index !== idx) {
|
|
11
|
-
throw new Error(`stored leaves are inconsistent with local tree, expected ${idx}, got ${index}`);
|
|
12
|
-
}
|
|
13
|
-
idx += 1;
|
|
14
|
-
}
|
|
15
|
-
return idx;
|
|
16
|
-
}
|
|
17
|
-
// TODO: Will be used for inmemory merkle tree handling for caching.
|
|
18
|
-
// Atm everytime we need to access the tree we have to rebuild it from the store.
|
|
19
|
-
// This function will help to avoid multiple rebuilds for the same chain
|
|
20
|
-
export async function hydrateChain({ chainId, trees, loadLeaf, hydrated, }) {
|
|
21
|
-
if (hydrated.has(chainId))
|
|
22
|
-
return;
|
|
23
|
-
trees.reset(chainId);
|
|
24
|
-
let idx = 0;
|
|
25
|
-
for (;;) {
|
|
26
|
-
const leaf = await loadLeaf(chainId, idx);
|
|
27
|
-
if (!leaf)
|
|
28
|
-
break;
|
|
29
|
-
const { index } = trees.addLeaf(chainId, parseHexToBigInt(leaf.commitment));
|
|
30
|
-
if (index !== idx) {
|
|
31
|
-
throw new Error("stored leaves are inconsistent with local tree");
|
|
32
|
-
}
|
|
33
|
-
idx += 1;
|
|
34
|
-
}
|
|
35
|
-
hydrated.add(chainId);
|
|
36
|
-
}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { poseidon } from "@railgun-community/circomlibjs";
|
|
2
|
-
import { IMT, } from "@zk-kit/imt";
|
|
3
|
-
import { ByteLength, ByteUtils } from "../../key-derivation/bytes.js";
|
|
4
|
-
import { ensureChainId } from "../../utils/validators.js";
|
|
5
|
-
const DEFAULT_DEPTH = 16;
|
|
6
|
-
const DEFAULT_ARITY = 2;
|
|
7
|
-
const ZERO_BYTE_LENGTH = ByteLength.UINT_256;
|
|
8
|
-
// Simple adapter: IMTNode[] -> poseidon(bigint[])
|
|
9
|
-
const hash = (values) => poseidon(values.map((v) => BigInt(v)));
|
|
10
|
-
const formatNode = (value) => ByteUtils.nToHex(value, ZERO_BYTE_LENGTH, true);
|
|
11
|
-
export function createLocalMerkleTree() {
|
|
12
|
-
const zeroLeaf = 0n;
|
|
13
|
-
const capacity = 2 ** DEFAULT_DEPTH;
|
|
14
|
-
const tree = new IMT(hash, DEFAULT_DEPTH, zeroLeaf, DEFAULT_ARITY);
|
|
15
|
-
function addLeaf(value) {
|
|
16
|
-
if (tree.leaves.length >= capacity) {
|
|
17
|
-
throw new Error("merkle tree is full");
|
|
18
|
-
}
|
|
19
|
-
const insertedIndex = tree.leaves.length;
|
|
20
|
-
tree.insert(value);
|
|
21
|
-
return {
|
|
22
|
-
index: insertedIndex,
|
|
23
|
-
root: formatNode(tree.root),
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
function getRoot() {
|
|
27
|
-
return formatNode(tree.root);
|
|
28
|
-
}
|
|
29
|
-
function getLeafCount() {
|
|
30
|
-
return tree.leaves.length;
|
|
31
|
-
}
|
|
32
|
-
function getLeaf(index) {
|
|
33
|
-
const leaf = tree.leaves[index];
|
|
34
|
-
if (leaf === undefined) {
|
|
35
|
-
throw new Error("leaf does not exist in this tree");
|
|
36
|
-
}
|
|
37
|
-
return formatNode(BigInt(leaf));
|
|
38
|
-
}
|
|
39
|
-
function createMerkleProof(index) {
|
|
40
|
-
return tree.createProof(index);
|
|
41
|
-
}
|
|
42
|
-
return {
|
|
43
|
-
addLeaf,
|
|
44
|
-
getRoot,
|
|
45
|
-
getLeafCount,
|
|
46
|
-
getLeaf,
|
|
47
|
-
createMerkleProof,
|
|
48
|
-
getZero(level) {
|
|
49
|
-
if (level === tree.depth) {
|
|
50
|
-
return getRoot();
|
|
51
|
-
}
|
|
52
|
-
const zero = tree.zeroes[level];
|
|
53
|
-
if (zero === undefined) {
|
|
54
|
-
throw new Error("invalid level");
|
|
55
|
-
}
|
|
56
|
-
return formatNode(zero);
|
|
57
|
-
},
|
|
58
|
-
get depth() {
|
|
59
|
-
return tree.depth;
|
|
60
|
-
},
|
|
61
|
-
get capacity() {
|
|
62
|
-
return capacity;
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
export function createMerkleTrees() {
|
|
67
|
-
const trees = new Map();
|
|
68
|
-
const resetTree = (chainId) => {
|
|
69
|
-
ensureChainId(chainId);
|
|
70
|
-
const tree = createLocalMerkleTree();
|
|
71
|
-
trees.set(chainId, tree);
|
|
72
|
-
return tree;
|
|
73
|
-
};
|
|
74
|
-
const getOrCreate = (chainId) => {
|
|
75
|
-
ensureChainId(chainId);
|
|
76
|
-
let tree = trees.get(chainId);
|
|
77
|
-
if (!tree) {
|
|
78
|
-
tree = resetTree(chainId);
|
|
79
|
-
}
|
|
80
|
-
return tree;
|
|
81
|
-
};
|
|
82
|
-
return {
|
|
83
|
-
get(chainId) {
|
|
84
|
-
ensureChainId(chainId);
|
|
85
|
-
return trees.get(chainId);
|
|
86
|
-
},
|
|
87
|
-
getOrCreate,
|
|
88
|
-
addLeaf(chainId, value) {
|
|
89
|
-
return getOrCreate(chainId).addLeaf(value);
|
|
90
|
-
},
|
|
91
|
-
createMerkleProof(chainId, index) {
|
|
92
|
-
return getOrCreate(chainId).createMerkleProof(index);
|
|
93
|
-
},
|
|
94
|
-
getRoot(chainId) {
|
|
95
|
-
return getOrCreate(chainId).getRoot();
|
|
96
|
-
},
|
|
97
|
-
getLeafCount(chainId) {
|
|
98
|
-
return getOrCreate(chainId).getLeafCount();
|
|
99
|
-
},
|
|
100
|
-
reset(chainId) {
|
|
101
|
-
resetTree(chainId);
|
|
102
|
-
},
|
|
103
|
-
};
|
|
104
|
-
}
|