Skip to content

@mistcash/sdk

The core package provides all cryptographic primitives needed for private transactions: Poseidon hashing via Go WASM, Groth16 zero-knowledge proof generation, Merkle tree operations, and Chamber contract interaction utilities.

Terminal window
pnpm add @mistcash/sdk @mistcash/config

The SDK relies on a Go-compiled WASM module for cryptographic operations. Initialize before use:

import { initCore } from "@mistcash/sdk";
await initCore();

Or initialize modules independently:

import { initWasm, initGaraga } from "@mistcash/sdk";
await initWasm(); // Hashing + proof generation
await initGaraga(); // Proof calldata formatting for Starknet

The SDK uses Poseidon hashing — a ZK-friendly hash function. All hash functions are powered by the Go WASM module.

Two-input Poseidon hash. Returns a hex string.

const commitment = await hash2(claimingKey, ownerAddress);

Synchronous version. Use when you know WASM is already initialized.

const commitment = hash2Sync(claimingKey, ownerAddress);

Three-input Poseidon hash.

const hash = await hash3(secret, tokenAddress, amount);

Synchronous three-input hash.

const hash = hash3Sync(secret, tokenAddress, amount);

Derives a transaction secret from a claiming key and recipient address.

const secret = txSecret(claimingKey, recipientAddress);

Hashes a transaction secret with asset details to create a commitment leaf.

const leaf = hash_with_asset(secret, tokenAddress, amount);

Computes the full transaction hash used as a Merkle leaf. Returns a bigint.

const hash = txHash(claimingKey, ownerAddress, tokenAddress, amount);
// Returns: bigint

Generates a cryptographically random claiming key.

const key = generateClaimingKey();
// Returns: "0x..." (hex string)

Generates a Groth16 proof from a witness. The proof is computed entirely client-side in WASM.

import { prove_groth16 } from "@mistcash/sdk";
import type { Witness } from "@mistcash/sdk";
const witness: Witness = {
ClaimingKey: claimingKey,
Owner: recipientAddress,
TxAsset: tokenAddress,
Withdraw: {
Amount: amount,
},
MerkleRoot: root.toString(),
MerkleProof: proof.map(String),
Tx1Secret: txSecret(claimingKey, recipientAddress),
};
const result = await prove_groth16(witness);
if (result.status === "ok") {
console.log("Proof:", result.proof);
} else {
console.error("Proof failed:", result.error);
}

Generates a proof and formats it as Starknet calldata using Garaga. Returns an array of bigint values ready to submit on-chain.

import { full_prove } from "@mistcash/sdk";
const calldata = await full_prove(witness);
// Returns: bigint[] — ready for contract call

Pre-built test fixtures for development:

import { FIXTURES } from "@mistcash/sdk";
console.log(FIXTURES.witness); // Example witness
console.log(FIXTURES.proof); // Example proof
console.log(FIXTURES.verifyingKey); // Verification key

The SDK implements a binary Merkle tree using Poseidon hashing.

calculateMerkleRoot(leaves, hasher?, leafFilter?)

Section titled “calculateMerkleRoot(leaves, hasher?, leafFilter?)”

Compute the Merkle root from an array of leaves.

import { calculateMerkleRoot } from "@mistcash/sdk";
const leaves = [leaf1, leaf2, leaf3]; // bigint[]
const root = calculateMerkleRoot(leaves);
// Returns: bigint

calculateMerkleRootAndProof(leaves, index, hasher?, leafFilter?)

Section titled “calculateMerkleRootAndProof(leaves, index, hasher?, leafFilter?)”

Compute both the Merkle root and the proof path for a specific leaf index.

import { calculateMerkleRootAndProof } from "@mistcash/sdk";
const [root, ...proof] = calculateMerkleRootAndProof(leaves, targetIndex);

merkleRootFromPath(element, path, hasher?, leafFilter?)

Section titled “merkleRootFromPath(element, path, hasher?, leafFilter?)”

Verify a Merkle proof by recomputing the root from an element and its proof path.

import { merkleRootFromPath } from "@mistcash/sdk";
const computedRoot = merkleRootFromPath(leaf, proofPath);
const isValid = computedRoot === expectedRoot;

The default Poseidon-based hasher used in Merkle tree operations.

import { merkleHasher } from "@mistcash/sdk";
const parentHash = merkleHasher(leftChild, rightChild);

Returns a typed instance of the Chamber contract.

import { getChamber } from "@mistcash/sdk";
const chamber = getChamber(provider);

Fetches the assets associated with a transaction from the contract.

const asset = await fetchTxAssets(chamber, claimingKey, recipientAddress);
// Returns: { addr: string, amount: string | bigint }

checkTxExists(contract, valKey, valTo, tokenAddr, amount)

Section titled “checkTxExists(contract, valKey, valTo, tokenAddr, amount)”

Check whether a specific transaction exists in the contract.

const exists = await checkTxExists(chamber, key, to, tokenAddr, amount);
// Returns: boolean

getTxIndexInTree(leaves, valKey, valTo, tokenAddr, amount)

Section titled “getTxIndexInTree(leaves, valKey, valTo, tokenAddr, amount)”

Find the index of a transaction in the Merkle tree leaves.

const index = await getTxIndexInTree(leaves, key, to, tokenAddr, amount);
// Returns: number

Format a bigint amount with decimal places for display.

import { fmtAmount } from "@mistcash/sdk";
fmtAmount(1000000n, 6); // "1.0"

Parse a decimal string into a bigint with the given precision.

import { fmtAmtToBigInt } from "@mistcash/sdk";
fmtAmtToBigInt("1.5", 18); // 1500000000000000000n

Parse URL hash parameters (useful for sharing transaction links).

const params = getHashParams();
// Returns: Record<string, string>