@provablehq/sdk
Version:
A Software Development Kit (SDK) for Zero-Knowledge Transactions
193 lines (191 loc) • 8.68 kB
TypeScript
import { Field } from "../../wasm.js";
/**
* Client library that encapsulates methods for constructing Merkle exclusion proofs for compliant stablecoin programs following the Sealance architecture.
*
* @example
* Construct a Merkle exclusion proof.
* ```typescript
* const sealance = new SealanceMerkleTree();
* const leaves = [
* "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px",
* "aleo1s3ws5tra87fjycnjrwsjcrnw2qxr8jfqqdugnf0xzqqw29q9m5pqem2u4t",
* "aleo1s3ws5tra87fjycnjrwsjcrnw2qxr8jfqqdugnf0xzqqw29q9m5pqem2u4t",
* ];
* const result = sealance.generateLeaves(leaves);
* const tree = sealance.buildTree(result);
* const [leftIdx, rightIdx] = sealance.getLeafIndices(tree, "aleo1kypwp5m7qtk9mwazgcpg0tq8aal23mnrvwfvug65qgcg9xvsrqgspyjm6n");
* const proof_left = sealance.getSiblingPath(tree, leftIdx, 15);
* const proof_right = sealance.getSiblingPath(tree, rightIdx, 15);
* const exclusion_proof = [proof_left, proof_right];
* const formatted_proof = sealance.formatMerkleProof(exclusion_proof);
* ```
*/
declare class SealanceMerkleTree {
private static hasher;
/**
* Converts an Aleo blockchain address to a field element.
*
* This function decodes a bech32m-encoded Aleo address and converts it to a field element
* represented as a BigInt. The address format follows the Aleo protocol specification,
* starting with the prefix "aleo1" followed by encoded data.
*
* @param address - The Aleo blockchain address (e.g., "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px")
* @returns A BigInt representing the field element.
* @throws Error if the address is invalid or cannot be decoded.
*
* @example
* ```typescript
* const sealance = new SealanceMerkleTree();
* const address = "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px";
* const fieldValue = sealance.convertAddressToField(address);
* console.log(fieldValue); // 123456789...n
* ```
*/
convertAddressToField(address: string): bigint;
/**
* Hashes two elements using Poseidon4 hash function
* @param prefix - Prefix for the hash (e.g., "0field" for nodes, "1field" for leaves)
* @param el1 - First element to hash
* @param el2 - Second element to hash
* @returns The hash result as a Field
* @throws {Error} If inputs are empty or invalid
*/
hashTwoElements(prefix: string, el1: string, el2: string): Field;
/**
* Builds a Merkle tree from given leaves. The tree is built bottom-up, hashing pairs of elements at each level.
*
* @param leaves - Array of leaf elements (must have even number of elements).
* @returns Array representing the complete Merkle tree as BigInts.
* @throws {Error} If leaves array is empty or has odd number of elements.
*
* @example
* ```typescript
* const sealance = new SealanceMerkleTree();
* const leaves = ["0field", "1field", "2field", "3field"];
* const tree = sealance.buildTree(leaves);
* const root = tree[tree.length - 1]; // Get the Merkle root
* ```
*/
buildTree(leaves: string[]): bigint[];
/**
* Converts an array of decimal string representations of U256 numbers to an array of BigInts.
*
* @param tree - Array of decimal string representations of U256 numbers.
* @returns Array of BigInts.
*
* @example
* ```typescript
* const treeStrings = ["0","4328470178059738374782465505490977516512210899136548187530607227309847251692","1741259420362056497457198439964202806733137875365061915996980524089960046336"];
* const sealance = new SealanceMerkleTree();
* const treeBigInts = sealance.convertTreeToBigInt(treeStrings);
* console.log(treeBigInts); // [
* 0,
* 4328470178059738374782465505490977516512210899136548187530607227309847251692,
* 1741259420362056497457198439964202806733137875365061915996980524089960046336
* ]
* ```
*/
convertTreeToBigInt(tree: string[]): bigint[];
/**
* Converts Aleo addresses to field elements, sorts them, pads with zero fields, and returns an array. This prepares addresses for Merkle tree construction.
*
* @param addresses - Array of Aleo addresses.
* @param maxTreeDepth - Maximum depth of the Merkle tree (default: 15).
* @returns Array of field elements ready for Merkle tree construction.
* @throws {Error} If the number of addresses exceeds the maximum capacity.
*
* @example
* ```typescript
* const addresses = [
* "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px",
* "aleo1s3ws5tra87fjycnjrwsjcrnw2qxr8jfqqdugnf0xzqqw29q9m5pqem2u4t",
* "aleo1s3ws5tra87fjycnjrwsjcrnw2qxr8jfqqdugnf0xzqqw29q9m5pqem2u4t",
* ];
* const sealance = new SealanceMerkleTree();
* const leaves = sealance.generateLeaves(addresses, 15);
* console.log(leaves); // [
* "0field",
* "1295133970529764960316948294624974168921228814652993007266766481909235735940field",
* "1295133970529764960316948294624974168921228814652993007266766481909235735940field",
* "3501665755452795161867664882580888971213780722176652848275908626939553697821field"
* ]
* ```
*/
generateLeaves(addresses: string[], maxTreeDepth?: number): string[];
/**
* Finds the leaf indices for non-inclusion proof of an address and returns the indices of the two adjacent leaves that surround the target address.
*
* @param merkleTree - The complete Merkle tree as array of BigInts.
* @param address - The Aleo address for which to find indices.
* @returns Tuple of [leftLeafIndex, rightLeafIndex].
*
* @example
* ```typescript
* const addresses = [
* "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px",
* "aleo1s3ws5tra87fjycnjrwsjcrnw2qxr8jfqqdugnf0xzqqw29q9m5pqem2u4t",
* "aleo1s3ws5tra87fjycnjrwsjcrnw2qxr8jfqqdugnf0xzqqw29q9m5pqem2u4t",
* ];
* const sealance = new SealanceMerkleTree();
* const leaves = sealance.generateLeaves(addresses);
* const tree = sealance.buildTree(leaves);
* const [leftIdx, rightIdx] = sealance.getLeafIndices(tree, "aleo1...");
* ```
*/
getLeafIndices(merkleTree: bigint[], address: string): [number, number];
/**
* Generates the sibling path (Merkle proof) for a given leaf index
*
* @param tree - The complete Merkle tree.
* @param leafIndex - Index of the leaf for which to generate the proof.
* @param depth - Maximum depth of the tree.
* @returns Object containing siblings array and leaf_index.
*
* @example
* ```typescript
* const addresses = [
* "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px",
* "aleo1s3ws5tra87fjycnjrwsjcrnw2qxr8jfqqdugnf0xzqqw29q9m5pqem2u4t",
* "aleo1s3ws5tra87fjycnjrwsjcrnw2qxr8jfqqdugnf0xzqqw29q9m5pqem2u4t",
* ];
* const sealance = new SealanceMerkleTree();
* const leaves = sealance.generateLeaves(addresses);
* const tree = sealance.buildTree(leaves);
* const [leftIdx, rightIdx] = sealance.getLeafIndices(tree, "aleo1...");
* const proof = sealance.getSiblingPath(tree, leftIdx, 15);
* // proof = { siblings: [0n, 1n, ...], leaf_index: leftIdx }
* ```
*/
getSiblingPath(tree: bigint[], leafIndex: number, depth: number): {
siblings: bigint[];
leaf_index: number;
};
/**
* Generates a formatted exclusion proof suitable for Aleo transactions.
*
* @param proof - An array of two {sibling path, leafindex} objects.
* @returns String representation of the exclusion proof.
*
* @example
* ```typescript
* const addresses = [
* "aleo1rhgdu77hgyqd3xjj8ucu3jj9r2krwz6mnzyd80gncr5fxcwlh5rsvzp9px",
* "aleo1s3ws5tra87fjycnjrwsjcrnw2qxr8jfqqdugnf0xzqqw29q9m5pqem2u4t",
* "aleo1s3ws5tra87fjycnjrwsjcrnw2qxr8jfqqdugnf0xzqqw29q9m5pqem2u4t",
* ];
* const sealance = new SealanceMerkleTree();
* const leaves = sealance.generateLeaves(addresses);
* const tree = sealance.buildTree(leaves);
* const [leftIdx, rightIdx] = sealance.getLeafIndices(tree, "aleo1...");
* const proof1 = getSiblingPath(tree, leftIdx, 15);
* const proof2 = getSiblingPath(tree, rightIdx, 15);
* const formattedProof = formatMerkleProof([proof1, proof2]);
* // formattedProof = "[{ siblings: [0field, 1field, ...], leaf_index: 0u32 }, { siblings: [0field, 2field, ...], leaf_index: 1u32 }]"
* ```
*/
formatMerkleProof(proof: {
siblings: bigint[];
leaf_index: number;
}[]): string;
}
export { SealanceMerkleTree };