@interest-protocol/vortex-sdk 2.0.0 → 3.0.1

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.
@@ -1,4 +1,4 @@
1
- import { MerkleTree } from '../entities/merkle-tree';
1
+ import { MerkleTree } from 'fixed-merkle-tree';
2
2
  import { Utxo } from '../entities/utxo';
3
3
  import { VortexKeypair } from '../entities/keypair';
4
4
  export declare const reverseBytes: (bytes: Uint8Array) => Uint8Array;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIpD,eAAO,MAAM,YAAY,GAAI,OAAO,UAAU,KAAG,UAMhD,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,OAAO,UAAU,KAAG,MAEjD,CAAC;AAEF,wBAAgB,aAAa,CAC3B,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,IAAI,GAAG,IAAI,GAChB,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAkEpB;AAED,UAAU,gBAAgB;IACxB,UAAU,EAAE,UAAU,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,aAAa,CAAC;IAC7B,UAAU,EAAE,IAAI,CAAC;IACjB,UAAU,EAAE,IAAI,CAAC;IACjB,WAAW,EAAE,IAAI,CAAC;IAClB,WAAW,EAAE,IAAI,CAAC;CACnB;AAED,eAAO,MAAM,YAAY,GAAI,+JAa1B,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;CA2BlB,CAAC;AAEF,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIpD,eAAO,MAAM,YAAY,GAAI,OAAO,UAAU,KAAG,UAMhD,CAAC;AAEF,eAAO,MAAM,aAAa,GAAI,OAAO,UAAU,KAAG,MAEjD,CAAC;AAEF,wBAAgB,aAAa,CAC3B,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,IAAI,GAAG,IAAI,GAChB,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAkEpB;AAED,UAAU,gBAAgB;IACxB,UAAU,EAAE,UAAU,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,aAAa,CAAC;IAC7B,UAAU,EAAE,IAAI,CAAC;IACjB,UAAU,EAAE,IAAI,CAAC;IACjB,WAAW,EAAE,IAAI,CAAC;IAClB,WAAW,EAAE,IAAI,CAAC;CACnB;AAED,eAAO,MAAM,YAAY,GAAI,+JAa1B,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;CA2BlB,CAAC;AAEF,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC"}
@@ -2,7 +2,7 @@ import { MaybeTx } from '@interest-protocol/sui-core-sdk';
2
2
  import { TransactionResult } from '@mysten/sui/transactions';
3
3
  import { Vortex } from './vortex';
4
4
  import { VortexKeypair } from './entities/keypair';
5
- import { MerkleTree } from './entities/merkle-tree';
5
+ import { MerkleTree } from 'fixed-merkle-tree';
6
6
  import { Utxo } from './entities/utxo';
7
7
  export declare enum Action {
8
8
  Deposit = 0,
@@ -1 +1 @@
1
- {"version":3,"file":"vortex.types.d.ts","sourceRoot":"","sources":["../src/vortex.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEvC,oBAAY,MAAM;IAChB,OAAO,IAAA;IACP,QAAQ,IAAA;CACT;AAED,MAAM,WAAW,YAAa,SAAQ,OAAO;IAC3C,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,MAAM,EAAE,gBAAgB,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,UAAU,CAAC;IAC7B,gBAAgB,EAAE,UAAU,CAAC;CAC9B;AAED,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACvE,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAe,SAAQ,OAAO;IAC7C,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,UAAU,CAAC;IAC7B,gBAAgB,EAAE,UAAU,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAa,SAAQ,OAAO;IAC3C,WAAW,EAAE,UAAU,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,UAAU,YAAY;IACpB,KAAK,EAAE,cAAc,CAAC;IACtB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,YAAa,SAAQ,OAAO;IAC3C,KAAK,EAAE,iBAAiB,CAAC;IACzB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,OAAO,EAAE,iBAAiB,GAAG,YAAY,CAAC;CAC3C;AAED,MAAM,WAAW,WAAY,SAAQ,OAAO;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,aAAa,CAAC;IAC7B,UAAU,EAAE,UAAU,CAAC;IACvB,YAAY,CAAC,EAAE,IAAI,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,YAAa,SAAQ,OAAO;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,IAAI,EAAE,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,aAAa,CAAC;IAC7B,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;CACzB"}
1
+ {"version":3,"file":"vortex.types.d.ts","sourceRoot":"","sources":["../src/vortex.types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@interest-protocol/vortex-sdk",
3
- "version": "2.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "module": "./dist/index.mjs",
@@ -23,6 +23,7 @@
23
23
  "@noble/hashes": "^2.0.1",
24
24
  "@polymedia/suitcase-core": "^0.0.67",
25
25
  "bn.js": "^5.2.2",
26
+ "fixed-merkle-tree": "^0.7.3",
26
27
  "ramda": "^0.30.1",
27
28
  "tiny-invariant": "^1.3.3",
28
29
  "@interest-protocol/sui-core-sdk": "1.0.0"
package/src/deposit.ts CHANGED
@@ -140,7 +140,7 @@ export const deposit = async ({
140
140
  const { proof: moveProof, tx: tx3 } = vortex.newProof({
141
141
  tx: tx2,
142
142
  proofPoints: fromHex('0x' + proof.proofSerializedHex),
143
- root: merkleTree.root(),
143
+ root: BigInt(merkleTree.root),
144
144
  publicValue: amountMinusFrontendFee,
145
145
  action: Action.Deposit,
146
146
  extDataHash: extDataHashBigInt,
@@ -1,256 +1,14 @@
1
1
  // packages/vortex/src/entities/merkle-tree.ts
2
2
 
3
- import {
4
- ZERO_VALUE,
5
- EMPTY_SUBTREE_HASHES,
6
- MERKLE_TREE_HEIGHT,
7
- } from '../constants';
3
+ import { ZERO_VALUE, MERKLE_TREE_HEIGHT } from '../constants';
8
4
  import { poseidon2 } from '../crypto';
5
+ import { Element, MerkleTree as FixedMerkleTree } from 'fixed-merkle-tree';
9
6
 
10
- /**
11
- * Sparse Merkle tree using Tornado Cash Nova's paired insertion strategy.
12
- * Inserts two leaves at once for better efficiency and privacy.
13
- */
14
- export class MerkleTree {
15
- levels: number;
16
- capacity: number;
17
- zeroElement: bigint;
7
+ export const buildMerkleTree = () =>
8
+ new FixedMerkleTree(MERKLE_TREE_HEIGHT, [], {
9
+ hashFunction: (left: Element, right: Element) =>
10
+ poseidon2(BigInt(left), BigInt(right)).toString(),
11
+ zeroElement: ZERO_VALUE.toString(),
12
+ });
18
13
 
19
- private zeros: bigint[];
20
- private subtrees: bigint[]; // filledSubtrees in Tornado Nova (indices 0..levels-1)
21
- private _nextIndex: number;
22
- private leaves: bigint[];
23
- private _root: bigint;
24
-
25
- constructor(levels: number) {
26
- this.levels = levels;
27
- this.capacity = 2 ** levels;
28
- this.zeroElement = ZERO_VALUE;
29
- this.zeros = [];
30
- this.subtrees = [];
31
- this._nextIndex = 0;
32
- this.leaves = [];
33
-
34
- // Initialize zero hashes (0 to levels, inclusive)
35
- // We need levels+1 elements: zeros[0] through zeros[levels]
36
- for (let i = 0; i <= levels; i++) {
37
- this.zeros[i] = EMPTY_SUBTREE_HASHES[i];
38
- }
39
-
40
- // Initialize subtrees[0..levels-1] (matching Nova's filledSubtrees)
41
- // subtrees[0] is initialized but never used (Nova quirk)
42
- for (let i = 0; i < levels; i++) {
43
- this.subtrees[i] = this.zeros[i];
44
- }
45
-
46
- // Empty root is zeros[levels]
47
- this._root = this.zeros[levels];
48
- }
49
-
50
- /**
51
- * Returns the current Merkle root
52
- */
53
- root(): bigint {
54
- return this._root;
55
- }
56
-
57
- /**
58
- * Insert elements in bulk (must be even number for pairing)
59
- */
60
- bulkInsert(elements: bigint[]) {
61
- if (elements.length % 2 !== 0) {
62
- throw new Error('Must insert even number of elements (pairs)');
63
- }
64
-
65
- for (let i = 0; i < elements.length; i += 2) {
66
- this.insertPair(elements[i], elements[i + 1]);
67
- }
68
- }
69
-
70
- /**
71
- * Insert a pair of leaves (Nova style)
72
- * This is the primary insertion method
73
- */
74
- insertPair(leaf1: bigint, leaf2: bigint) {
75
- if (this._nextIndex >= this.capacity) {
76
- throw new Error('Merkle tree is full. No more leaves can be added');
77
- }
78
-
79
- // Store both leaves
80
- this.leaves.push(leaf1, leaf2);
81
-
82
- // Start by hashing the pair (level 0)
83
- let currentIndex = Math.floor(this._nextIndex / 2);
84
- let currentLevelHash = poseidon2(leaf1, leaf2);
85
-
86
- // Increment by 2 since we're inserting a pair
87
- this._nextIndex += 2;
88
-
89
- // Process levels 1 to levels-1 (matching Nova: for i = 1; i < levels)
90
- for (let i = 1; i < this.levels; i++) {
91
- let left: bigint;
92
- let right: bigint;
93
-
94
- if (currentIndex % 2 === 0) {
95
- // Current is left child
96
- left = currentLevelHash;
97
- right = this.zeros[i];
98
- this.subtrees[i] = currentLevelHash; // Cache left subtree
99
- } else {
100
- // Current is right child
101
- left = this.subtrees[i]; // Get cached left subtree
102
- right = currentLevelHash;
103
- }
104
-
105
- currentLevelHash = poseidon2(left, right);
106
- currentIndex = Math.floor(currentIndex / 2);
107
- }
108
-
109
- // Update root
110
- this._root = currentLevelHash;
111
- }
112
-
113
- /**
114
- * Insert a single leaf (for backward compatibility)
115
- * Pairs it with a zero leaf
116
- */
117
- insert(leaf: bigint) {
118
- this.insertPair(leaf, this.zeros[0]);
119
- }
120
-
121
- /**
122
- * Generate Merkle path for a leaf at given index
123
- * Returns sibling hashes and indices for verification
124
- */
125
- path(index: number): { pathElements: bigint[]; pathIndices: number[] } {
126
- if (index < 0 || index >= this._nextIndex) {
127
- throw new Error(
128
- `Index out of bounds: ${index} (tree has ${this._nextIndex} leaves)`
129
- );
130
- }
131
-
132
- const pathElements: bigint[] = [];
133
- const pathIndices: number[] = [];
134
-
135
- // Level 0: Get sibling leaf
136
- const isLeftAtLevel0 = index % 2 === 0;
137
- pathIndices.push(isLeftAtLevel0 ? 0 : 1);
138
-
139
- const siblingIndex = isLeftAtLevel0 ? index + 1 : index - 1;
140
- const sibling =
141
- siblingIndex < this._nextIndex
142
- ? this.leaves[siblingIndex]
143
- : this.zeros[0];
144
- pathElements.push(sibling);
145
-
146
- // Levels 1 to levels-1 (matching Nova's loop structure)
147
- let currentIndex = Math.floor(index / 2);
148
- for (let i = 1; i < this.levels; i++) {
149
- const isLeft = currentIndex % 2 === 0;
150
- pathIndices.push(isLeft ? 0 : 1);
151
-
152
- if (isLeft) {
153
- // We're left child, sibling is right (zero hash)
154
- pathElements.push(this.zeros[i]);
155
- } else {
156
- // We're right child, sibling is the cached left subtree
157
- pathElements.push(this.subtrees[i]);
158
- }
159
-
160
- currentIndex = Math.floor(currentIndex / 2);
161
- }
162
-
163
- return { pathElements, pathIndices };
164
- }
165
-
166
- /**
167
- * Get all leaves in the tree
168
- */
169
- elements(): bigint[] {
170
- return this.leaves;
171
- }
172
-
173
- /**
174
- * Find the index of a specific leaf
175
- */
176
- indexOf(element: bigint, comparator: Function | null = null): number {
177
- if (comparator) {
178
- return this.leaves.findIndex((leaf) => comparator(element, leaf));
179
- }
180
- return this.leaves.findIndex((leaf) => leaf === element);
181
- }
182
-
183
- /**
184
- * Serialize tree state
185
- */
186
- serialize() {
187
- return {
188
- levels: this.levels,
189
- zeros: this.zeros,
190
- subtrees: this.subtrees,
191
- nextIndex: this._nextIndex,
192
- leaves: this.leaves,
193
- root: this._root,
194
- };
195
- }
196
-
197
- /**
198
- * Verify a Merkle path is valid for a given leaf and root
199
- */
200
- verify(
201
- leaf: bigint,
202
- pathElements: bigint[],
203
- pathIndices: number[],
204
- root: bigint
205
- ): boolean {
206
- if (
207
- pathElements.length !== this.levels ||
208
- pathIndices.length !== this.levels
209
- ) {
210
- return false;
211
- }
212
-
213
- let currentHash = leaf;
214
-
215
- for (let i = 0; i < this.levels; i++) {
216
- const sibling = pathElements[i];
217
- const isLeft = pathIndices[i] === 0;
218
-
219
- if (isLeft) {
220
- currentHash = poseidon2(currentHash, sibling);
221
- } else {
222
- currentHash = poseidon2(sibling, currentHash);
223
- }
224
- }
225
-
226
- return currentHash === root;
227
- }
228
-
229
- /**
230
- * Get the current number of leaves in the tree
231
- */
232
- get nextIndex(): number {
233
- return this._nextIndex;
234
- }
235
-
236
- /**
237
- * Check if the tree is full
238
- */
239
- isFull(): boolean {
240
- return this._nextIndex >= this.capacity;
241
- }
242
-
243
- /**
244
- * Get the maximum capacity of the tree
245
- */
246
- getCapacity(): number {
247
- return this.capacity;
248
- }
249
-
250
- /**
251
- * Get the current fill percentage
252
- */
253
- getFillPercentage(): number {
254
- return (this._nextIndex / this.capacity) * 100;
255
- }
256
- }
14
+ export type MerkleTree = FixedMerkleTree;
@@ -1,6 +1,6 @@
1
1
  import { toHex } from '@mysten/sui/utils';
2
2
  import invariant from 'tiny-invariant';
3
- import { MerkleTree } from '../entities/merkle-tree';
3
+ import { MerkleTree } from 'fixed-merkle-tree';
4
4
  import { Utxo } from '../entities/utxo';
5
5
  import { VortexKeypair } from '../entities/keypair';
6
6
  import { ZERO_VALUE, MERKLE_TREE_HEIGHT } from '../constants';
@@ -30,7 +30,7 @@ export function getMerklePath(
30
30
  }
31
31
 
32
32
  const utxoIndex = Number(utxo.index);
33
- const treeSize = merkleTree.elements().length;
33
+ const treeSize = merkleTree.elements.length;
34
34
 
35
35
  // For deposits, input UTXOs don't exist yet
36
36
  if (utxoIndex < 0 || utxoIndex >= treeSize) {
@@ -44,7 +44,7 @@ export function getMerklePath(
44
44
  const commitment = utxo.commitment();
45
45
 
46
46
  // Verify commitment matches what's in the tree
47
- const storedCommitment = merkleTree.elements()[utxoIndex]!;
47
+ const storedCommitment = BigInt(merkleTree.elements[utxoIndex]!);
48
48
 
49
49
  invariant(
50
50
  storedCommitment === commitment,
@@ -56,7 +56,7 @@ export function getMerklePath(
56
56
  let currentHash = commitment;
57
57
 
58
58
  for (let i = 0; i < MERKLE_TREE_HEIGHT; i++) {
59
- const sibling = pathElements[i];
59
+ const sibling = BigInt(pathElements[i]!);
60
60
  const isLeft = pathIndices[i] === 0;
61
61
 
62
62
  invariant(sibling !== undefined, `Sibling undefined at level ${i}`);
@@ -79,7 +79,7 @@ export function getMerklePath(
79
79
  }
80
80
 
81
81
  const calculatedRoot = currentHash;
82
- const expectedRoot = merkleTree.root();
82
+ const expectedRoot = BigInt(merkleTree.root);
83
83
 
84
84
  invariant(
85
85
  calculatedRoot === expectedRoot,
@@ -119,7 +119,7 @@ export const toProveInput = ({
119
119
  outputUtxo1,
120
120
  }: ToProveInputArgs) => {
121
121
  return {
122
- root: merkleTree.root(),
122
+ root: BigInt(merkleTree.root),
123
123
  publicAmount,
124
124
  extDataHash,
125
125
  inputNullifier0: nullifier0,
@@ -2,7 +2,7 @@ import { MaybeTx } from '@interest-protocol/sui-core-sdk';
2
2
  import { TransactionResult } from '@mysten/sui/transactions';
3
3
  import { Vortex } from './vortex';
4
4
  import { VortexKeypair } from './entities/keypair';
5
- import { MerkleTree } from './entities/merkle-tree';
5
+ import { MerkleTree } from 'fixed-merkle-tree';
6
6
  import { Utxo } from './entities/utxo';
7
7
 
8
8
  export enum Action {
package/src/withdraw.ts CHANGED
@@ -136,7 +136,7 @@ export const withdraw = async ({
136
136
  const { proof: moveProof, tx: tx3 } = vortex.newProof({
137
137
  tx: tx2,
138
138
  proofPoints: fromHex('0x' + proof.proofSerializedHex),
139
- root: merkleTree.root(),
139
+ root: BigInt(merkleTree.root),
140
140
  publicValue: amount + relayerFee,
141
141
  action: Action.Withdraw,
142
142
  extDataHash: extDataHashBigInt,
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=vortex.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"vortex.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/vortex.test.ts"],"names":[],"mappings":""}
@@ -1,25 +0,0 @@
1
- import { testVortex } from './test-utils';
2
- import { MERKLE_TREE_HEIGHT, EMPTY_SUBTREE_HASHES } from '../constants';
3
-
4
- describe('Vortex', () => {
5
- it('should get the TVL', async () => {
6
- const tvl = await testVortex.tvl();
7
- expect(tvl).toBe(0n);
8
- });
9
-
10
- it('should get the root', async () => {
11
- const root = await testVortex.root();
12
- expect(root).toBe(String(EMPTY_SUBTREE_HASHES[MERKLE_TREE_HEIGHT]));
13
- });
14
-
15
- it('should get the next index', async () => {
16
- const nextIndex = await testVortex.nextIndex();
17
- expect(nextIndex).toBe('0');
18
- });
19
-
20
- it('should check if a nullifier is spent', async () => {
21
- const nullifier = 12345n;
22
- const isNullifierSpent = await testVortex.isNullifierSpent(nullifier);
23
- expect(isNullifierSpent).toBe(false);
24
- });
25
- });