@interest-protocol/vortex-sdk 2.0.0 → 3.0.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.
package/dist/index.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import { devInspectAndGetReturnValues } from '@polymedia/suitcase-core';
2
2
  import invariant from 'tiny-invariant';
3
3
  import { pathOr } from 'ramda';
4
+ import { MerkleTree } from 'fixed-merkle-tree';
4
5
  import require$$0 from 'fs';
5
6
  import { BN } from 'bn.js';
6
7
 
@@ -38841,201 +38842,10 @@ _VortexKeypair_instances = new WeakSet(), _VortexKeypair_decrypt = function _Vor
38841
38842
  };
38842
38843
 
38843
38844
  // packages/vortex/src/entities/merkle-tree.ts
38844
- /**
38845
- * Sparse Merkle tree using Tornado Cash Nova's paired insertion strategy.
38846
- * Inserts two leaves at once for better efficiency and privacy.
38847
- */
38848
- class MerkleTree {
38849
- constructor(levels) {
38850
- this.levels = levels;
38851
- this.capacity = 2 ** levels;
38852
- this.zeroElement = ZERO_VALUE;
38853
- this.zeros = [];
38854
- this.subtrees = [];
38855
- this._nextIndex = 0;
38856
- this.leaves = [];
38857
- // Initialize zero hashes (0 to levels, inclusive)
38858
- // We need levels+1 elements: zeros[0] through zeros[levels]
38859
- for (let i = 0; i <= levels; i++) {
38860
- this.zeros[i] = EMPTY_SUBTREE_HASHES[i];
38861
- }
38862
- // Initialize subtrees[0..levels-1] (matching Nova's filledSubtrees)
38863
- // subtrees[0] is initialized but never used (Nova quirk)
38864
- for (let i = 0; i < levels; i++) {
38865
- this.subtrees[i] = this.zeros[i];
38866
- }
38867
- // Empty root is zeros[levels]
38868
- this._root = this.zeros[levels];
38869
- }
38870
- /**
38871
- * Returns the current Merkle root
38872
- */
38873
- root() {
38874
- return this._root;
38875
- }
38876
- /**
38877
- * Insert elements in bulk (must be even number for pairing)
38878
- */
38879
- bulkInsert(elements) {
38880
- if (elements.length % 2 !== 0) {
38881
- throw new Error('Must insert even number of elements (pairs)');
38882
- }
38883
- for (let i = 0; i < elements.length; i += 2) {
38884
- this.insertPair(elements[i], elements[i + 1]);
38885
- }
38886
- }
38887
- /**
38888
- * Insert a pair of leaves (Nova style)
38889
- * This is the primary insertion method
38890
- */
38891
- insertPair(leaf1, leaf2) {
38892
- if (this._nextIndex >= this.capacity) {
38893
- throw new Error('Merkle tree is full. No more leaves can be added');
38894
- }
38895
- // Store both leaves
38896
- this.leaves.push(leaf1, leaf2);
38897
- // Start by hashing the pair (level 0)
38898
- let currentIndex = Math.floor(this._nextIndex / 2);
38899
- let currentLevelHash = poseidon2(leaf1, leaf2);
38900
- // Increment by 2 since we're inserting a pair
38901
- this._nextIndex += 2;
38902
- // Process levels 1 to levels-1 (matching Nova: for i = 1; i < levels)
38903
- for (let i = 1; i < this.levels; i++) {
38904
- let left;
38905
- let right;
38906
- if (currentIndex % 2 === 0) {
38907
- // Current is left child
38908
- left = currentLevelHash;
38909
- right = this.zeros[i];
38910
- this.subtrees[i] = currentLevelHash; // Cache left subtree
38911
- }
38912
- else {
38913
- // Current is right child
38914
- left = this.subtrees[i]; // Get cached left subtree
38915
- right = currentLevelHash;
38916
- }
38917
- currentLevelHash = poseidon2(left, right);
38918
- currentIndex = Math.floor(currentIndex / 2);
38919
- }
38920
- // Update root
38921
- this._root = currentLevelHash;
38922
- }
38923
- /**
38924
- * Insert a single leaf (for backward compatibility)
38925
- * Pairs it with a zero leaf
38926
- */
38927
- insert(leaf) {
38928
- this.insertPair(leaf, this.zeros[0]);
38929
- }
38930
- /**
38931
- * Generate Merkle path for a leaf at given index
38932
- * Returns sibling hashes and indices for verification
38933
- */
38934
- path(index) {
38935
- if (index < 0 || index >= this._nextIndex) {
38936
- throw new Error(`Index out of bounds: ${index} (tree has ${this._nextIndex} leaves)`);
38937
- }
38938
- const pathElements = [];
38939
- const pathIndices = [];
38940
- // Level 0: Get sibling leaf
38941
- const isLeftAtLevel0 = index % 2 === 0;
38942
- pathIndices.push(isLeftAtLevel0 ? 0 : 1);
38943
- const siblingIndex = isLeftAtLevel0 ? index + 1 : index - 1;
38944
- const sibling = siblingIndex < this._nextIndex
38945
- ? this.leaves[siblingIndex]
38946
- : this.zeros[0];
38947
- pathElements.push(sibling);
38948
- // Levels 1 to levels-1 (matching Nova's loop structure)
38949
- let currentIndex = Math.floor(index / 2);
38950
- for (let i = 1; i < this.levels; i++) {
38951
- const isLeft = currentIndex % 2 === 0;
38952
- pathIndices.push(isLeft ? 0 : 1);
38953
- if (isLeft) {
38954
- // We're left child, sibling is right (zero hash)
38955
- pathElements.push(this.zeros[i]);
38956
- }
38957
- else {
38958
- // We're right child, sibling is the cached left subtree
38959
- pathElements.push(this.subtrees[i]);
38960
- }
38961
- currentIndex = Math.floor(currentIndex / 2);
38962
- }
38963
- return { pathElements, pathIndices };
38964
- }
38965
- /**
38966
- * Get all leaves in the tree
38967
- */
38968
- elements() {
38969
- return this.leaves;
38970
- }
38971
- /**
38972
- * Find the index of a specific leaf
38973
- */
38974
- indexOf(element, comparator = null) {
38975
- if (comparator) {
38976
- return this.leaves.findIndex((leaf) => comparator(element, leaf));
38977
- }
38978
- return this.leaves.findIndex((leaf) => leaf === element);
38979
- }
38980
- /**
38981
- * Serialize tree state
38982
- */
38983
- serialize() {
38984
- return {
38985
- levels: this.levels,
38986
- zeros: this.zeros,
38987
- subtrees: this.subtrees,
38988
- nextIndex: this._nextIndex,
38989
- leaves: this.leaves,
38990
- root: this._root,
38991
- };
38992
- }
38993
- /**
38994
- * Verify a Merkle path is valid for a given leaf and root
38995
- */
38996
- verify(leaf, pathElements, pathIndices, root) {
38997
- if (pathElements.length !== this.levels ||
38998
- pathIndices.length !== this.levels) {
38999
- return false;
39000
- }
39001
- let currentHash = leaf;
39002
- for (let i = 0; i < this.levels; i++) {
39003
- const sibling = pathElements[i];
39004
- const isLeft = pathIndices[i] === 0;
39005
- if (isLeft) {
39006
- currentHash = poseidon2(currentHash, sibling);
39007
- }
39008
- else {
39009
- currentHash = poseidon2(sibling, currentHash);
39010
- }
39011
- }
39012
- return currentHash === root;
39013
- }
39014
- /**
39015
- * Get the current number of leaves in the tree
39016
- */
39017
- get nextIndex() {
39018
- return this._nextIndex;
39019
- }
39020
- /**
39021
- * Check if the tree is full
39022
- */
39023
- isFull() {
39024
- return this._nextIndex >= this.capacity;
39025
- }
39026
- /**
39027
- * Get the maximum capacity of the tree
39028
- */
39029
- getCapacity() {
39030
- return this.capacity;
39031
- }
39032
- /**
39033
- * Get the current fill percentage
39034
- */
39035
- getFillPercentage() {
39036
- return (this._nextIndex / this.capacity) * 100;
39037
- }
39038
- }
38845
+ const buildMerkleTree = () => new MerkleTree(MERKLE_TREE_HEIGHT, [], {
38846
+ hashFunction: (left, right) => poseidon2(BigInt(left), BigInt(right)).toString(),
38847
+ zeroElement: ZERO_VALUE.toString(),
38848
+ });
39039
38849
 
39040
38850
  class Utxo {
39041
38851
  constructor({ amount, blinding, keypair, index }) {
@@ -39610,7 +39420,7 @@ function getMerklePath(merkleTree, utxo) {
39610
39420
  .map(() => [ZERO_VALUE.toString(), ZERO_VALUE.toString()]);
39611
39421
  }
39612
39422
  const utxoIndex = Number(utxo.index);
39613
- const treeSize = merkleTree.elements().length;
39423
+ const treeSize = merkleTree.elements.length;
39614
39424
  // For deposits, input UTXOs don't exist yet
39615
39425
  if (utxoIndex < 0 || utxoIndex >= treeSize) {
39616
39426
  return Array(MERKLE_TREE_HEIGHT)
@@ -39621,13 +39431,13 @@ function getMerklePath(merkleTree, utxo) {
39621
39431
  const { pathElements, pathIndices } = merkleTree.path(utxoIndex);
39622
39432
  const commitment = utxo.commitment();
39623
39433
  // Verify commitment matches what's in the tree
39624
- const storedCommitment = merkleTree.elements()[utxoIndex];
39434
+ const storedCommitment = BigInt(merkleTree.elements[utxoIndex]);
39625
39435
  invariant(storedCommitment === commitment, `Commitment mismatch at index ${utxoIndex}: expected ${commitment}, got ${storedCommitment}`);
39626
39436
  // Build WASM-compatible path (always [left, right] format)
39627
39437
  const wasmPath = [];
39628
39438
  let currentHash = commitment;
39629
39439
  for (let i = 0; i < MERKLE_TREE_HEIGHT; i++) {
39630
- const sibling = pathElements[i];
39440
+ const sibling = BigInt(pathElements[i]);
39631
39441
  const isLeft = pathIndices[i] === 0;
39632
39442
  invariant(sibling !== undefined, `Sibling undefined at level ${i}`);
39633
39443
  const leftHash = isLeft ? currentHash : sibling;
@@ -39641,13 +39451,13 @@ function getMerklePath(merkleTree, utxo) {
39641
39451
  currentHash = nextHash;
39642
39452
  }
39643
39453
  const calculatedRoot = currentHash;
39644
- const expectedRoot = merkleTree.root();
39454
+ const expectedRoot = BigInt(merkleTree.root);
39645
39455
  invariant(calculatedRoot === expectedRoot, `Root mismatch: calculated ${calculatedRoot}, expected ${expectedRoot}`);
39646
39456
  return wasmPath;
39647
39457
  }
39648
39458
  const toProveInput = ({ merkleTree, publicAmount, extDataHash, nullifier0, nullifier1, commitment0, commitment1, vortexKeypair, inputUtxo0, inputUtxo1, outputUtxo0, outputUtxo1, }) => {
39649
39459
  return {
39650
- root: merkleTree.root(),
39460
+ root: BigInt(merkleTree.root),
39651
39461
  publicAmount,
39652
39462
  extDataHash,
39653
39463
  inputNullifier0: nullifier0,
@@ -39759,7 +39569,7 @@ const deposit = async ({ tx = new Transaction(), amount, unspentUtxos = [], vort
39759
39569
  const { proof: moveProof, tx: tx3 } = vortex.newProof({
39760
39570
  tx: tx2,
39761
39571
  proofPoints: fromHex('0x' + proof.proofSerializedHex),
39762
- root: merkleTree.root(),
39572
+ root: BigInt(merkleTree.root),
39763
39573
  publicValue: amountMinusFrontendFee,
39764
39574
  action: Action.Deposit,
39765
39575
  extDataHash: extDataHashBigInt,
@@ -39860,7 +39670,7 @@ const withdraw = async ({ tx = new Transaction(), amount, unspentUtxos = [], vor
39860
39670
  const { proof: moveProof, tx: tx3 } = vortex.newProof({
39861
39671
  tx: tx2,
39862
39672
  proofPoints: fromHex('0x' + proof.proofSerializedHex),
39863
- root: merkleTree.root(),
39673
+ root: BigInt(merkleTree.root),
39864
39674
  publicValue: amount + relayerFee,
39865
39675
  action: Action.Withdraw,
39866
39676
  extDataHash: extDataHashBigInt,
@@ -39879,5 +39689,5 @@ const withdraw = async ({ tx = new Transaction(), amount, unspentUtxos = [], vor
39879
39689
  return tx4;
39880
39690
  };
39881
39691
 
39882
- export { Action, BASIS_POINTS, BN254_FIELD_MODULUS, DEPOSIT_FEE_IN_BASIS_POINTS, EMPTY_COMMITMENT, EMPTY_SUBTREE_HASHES, ERROR_CODES, INITIAL_SHARED_VERSION, LSK_ENCRYPTED_OUTPUTS, LSK_FETCH_OFFSET, MERKLE_TREE_HEIGHT, MerkleTree, Modules, OPT, Output, REGISTRY_OBJECT_ID, ROOT_HISTORY_SIZE, TREASURY_ADDRESS, UPGRADE_CAP, Utxo, VORTEX_PACKAGE_ID, VORTEX_POOL_OBJECT_ID, VORTEX_SIGNATURE_DOMAIN, Vortex, VortexKeypair, ZERO_VALUE, bytesToBigInt, computeExtDataHash, deposit, getMerklePath, getUnspentUtxos, parseNewCommitmentEvent, poseidon1, poseidon2, poseidon3, prove, reverseBytes, toProveInput, verify, vortexSDK, withdraw };
39692
+ export { Action, BASIS_POINTS, BN254_FIELD_MODULUS, DEPOSIT_FEE_IN_BASIS_POINTS, EMPTY_COMMITMENT, EMPTY_SUBTREE_HASHES, ERROR_CODES, INITIAL_SHARED_VERSION, LSK_ENCRYPTED_OUTPUTS, LSK_FETCH_OFFSET, MERKLE_TREE_HEIGHT, Modules, OPT, Output, REGISTRY_OBJECT_ID, ROOT_HISTORY_SIZE, TREASURY_ADDRESS, UPGRADE_CAP, Utxo, VORTEX_PACKAGE_ID, VORTEX_POOL_OBJECT_ID, VORTEX_SIGNATURE_DOMAIN, Vortex, VortexKeypair, ZERO_VALUE, buildMerkleTree, bytesToBigInt, computeExtDataHash, deposit, getMerklePath, getUnspentUtxos, parseNewCommitmentEvent, poseidon1, poseidon2, poseidon3, prove, reverseBytes, toProveInput, verify, vortexSDK, withdraw };
39883
39693
  //# sourceMappingURL=index.mjs.map