UNPKG

@provablehq/sdk

Version:

A Software Development Kit (SDK) for Zero-Knowledge Transactions

193 lines (191 loc) 8.68 kB
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 };