@interest-protocol/vortex-sdk 0.0.1-alpha.0 → 1.1.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.
Files changed (121) hide show
  1. package/.eslingignore +1 -0
  2. package/dist/__tests__/entities/keypair.spec.d.ts +2 -0
  3. package/dist/__tests__/entities/keypair.spec.d.ts.map +1 -0
  4. package/dist/__tests__/test-utils.d.ts +25 -0
  5. package/dist/__tests__/test-utils.d.ts.map +1 -0
  6. package/dist/__tests__/types.d.ts +3 -0
  7. package/dist/__tests__/types.d.ts.map +1 -0
  8. package/dist/__tests__/vortex.test.d.ts +2 -0
  9. package/dist/__tests__/vortex.test.d.ts.map +1 -0
  10. package/dist/constants.d.ts +44 -0
  11. package/dist/constants.d.ts.map +1 -0
  12. package/dist/crypto/ff/f1field.d.ts +76 -0
  13. package/dist/crypto/ff/f1field.d.ts.map +1 -0
  14. package/dist/crypto/ff/index.d.ts +6 -0
  15. package/dist/crypto/ff/index.d.ts.map +1 -0
  16. package/dist/crypto/ff/random.d.ts +2 -0
  17. package/dist/crypto/ff/random.d.ts.map +1 -0
  18. package/dist/crypto/ff/scalar.d.ts +45 -0
  19. package/dist/crypto/ff/scalar.d.ts.map +1 -0
  20. package/dist/crypto/ff/utils.d.ts +6 -0
  21. package/dist/crypto/ff/utils.d.ts.map +1 -0
  22. package/dist/crypto/index.d.ts +6 -0
  23. package/dist/crypto/index.d.ts.map +1 -0
  24. package/dist/crypto/poseidon/index.d.ts +2 -0
  25. package/dist/crypto/poseidon/index.d.ts.map +1 -0
  26. package/dist/crypto/poseidon/poseidon-constants-opt.d.ts +7 -0
  27. package/dist/crypto/poseidon/poseidon-constants-opt.d.ts.map +1 -0
  28. package/dist/crypto/poseidon/poseidon-opt.d.ts +16 -0
  29. package/dist/crypto/poseidon/poseidon-opt.d.ts.map +1 -0
  30. package/dist/deposit.d.ts +4 -0
  31. package/dist/deposit.d.ts.map +1 -0
  32. package/dist/entities/index.d.ts +4 -0
  33. package/dist/entities/index.d.ts.map +1 -0
  34. package/dist/entities/keypair.d.ts +29 -0
  35. package/dist/entities/keypair.d.ts.map +1 -0
  36. package/dist/entities/merkle-tree.d.ts +81 -0
  37. package/dist/entities/merkle-tree.d.ts.map +1 -0
  38. package/dist/entities/utxo.d.ts +24 -0
  39. package/dist/entities/utxo.d.ts.map +1 -0
  40. package/dist/index.d.ts +6 -2
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +38280 -4459
  43. package/dist/index.js.map +1 -1
  44. package/dist/index.mjs +38244 -4453
  45. package/dist/index.mjs.map +1 -1
  46. package/dist/jest-setup.d.ts +2 -0
  47. package/dist/jest-setup.d.ts.map +1 -0
  48. package/dist/keys/index.d.ts +3 -0
  49. package/dist/keys/index.d.ts.map +1 -0
  50. package/dist/pkg/nodejs/vortex.d.ts +11 -0
  51. package/dist/pkg/nodejs/vortex.d.ts.map +1 -0
  52. package/dist/pkg/web/vortex.d.ts +44 -0
  53. package/dist/pkg/web/vortex.d.ts.map +1 -0
  54. package/dist/utils/decrypt.d.ts +12 -0
  55. package/dist/utils/decrypt.d.ts.map +1 -0
  56. package/dist/utils/env.d.ts +2 -0
  57. package/dist/utils/env.d.ts.map +1 -0
  58. package/dist/utils/events.d.ts +7 -0
  59. package/dist/utils/events.d.ts.map +1 -0
  60. package/dist/utils/ext-data.d.ts +3 -0
  61. package/dist/utils/ext-data.d.ts.map +1 -0
  62. package/dist/utils/index.d.ts +50 -0
  63. package/dist/utils/index.d.ts.map +1 -0
  64. package/dist/utils/prove.d.ts +3 -0
  65. package/dist/utils/prove.d.ts.map +1 -0
  66. package/dist/vortex.d.ts +51 -21
  67. package/dist/vortex.d.ts.map +1 -1
  68. package/dist/vortex.types.d.ts +74 -50
  69. package/dist/vortex.types.d.ts.map +1 -1
  70. package/dist/vortex_bg.wasm +0 -0
  71. package/dist/withdraw.d.ts +4 -0
  72. package/dist/withdraw.d.ts.map +1 -0
  73. package/jest.config.js +31 -0
  74. package/package.json +22 -7
  75. package/src/__tests__/entities/keypair.spec.ts +191 -0
  76. package/src/__tests__/test-utils.ts +76 -0
  77. package/src/__tests__/types.ts +3 -0
  78. package/src/__tests__/vortex.test.ts +25 -0
  79. package/src/constants.ts +104 -0
  80. package/src/crypto/ff/f1field.ts +464 -0
  81. package/src/crypto/ff/index.ts +6 -0
  82. package/src/crypto/ff/random.ts +32 -0
  83. package/src/crypto/ff/readme.md +8 -0
  84. package/src/crypto/ff/scalar.ts +264 -0
  85. package/src/crypto/ff/utils.ts +121 -0
  86. package/src/crypto/index.ts +8 -0
  87. package/src/crypto/poseidon/index.ts +1 -0
  88. package/src/crypto/poseidon/poseidon-constants-opt.ts +24806 -0
  89. package/src/crypto/poseidon/poseidon-opt.ts +184 -0
  90. package/src/deposit.ts +168 -0
  91. package/src/entities/index.ts +3 -0
  92. package/src/entities/keypair.ts +262 -0
  93. package/src/entities/merkle-tree.ts +256 -0
  94. package/src/entities/utxo.ts +52 -0
  95. package/src/index.ts +6 -2
  96. package/src/jest-setup.ts +2 -0
  97. package/src/keys/index.ts +5 -0
  98. package/src/pkg/nodejs/vortex.d.ts +36 -0
  99. package/src/pkg/nodejs/vortex.js +332 -0
  100. package/src/pkg/nodejs/vortex_bg.wasm +0 -0
  101. package/src/pkg/nodejs/vortex_bg.wasm.d.ts +12 -0
  102. package/src/pkg/web/vortex.d.ts +72 -0
  103. package/src/pkg/web/vortex.js +442 -0
  104. package/src/pkg/web/vortex_bg.wasm +0 -0
  105. package/src/pkg/web/vortex_bg.wasm.d.ts +12 -0
  106. package/src/utils/decrypt.ts +46 -0
  107. package/src/utils/env.ts +18 -0
  108. package/src/utils/events.ts +16 -0
  109. package/src/utils/ext-data.ts +43 -0
  110. package/src/utils/index.ts +152 -0
  111. package/src/utils/prove.ts +18 -0
  112. package/src/vortex.ts +235 -111
  113. package/src/vortex.types.ts +74 -54
  114. package/src/withdraw.ts +159 -0
  115. package/tsconfig.json +4 -2
  116. package/dist/admin.d.ts +0 -17
  117. package/dist/admin.d.ts.map +0 -1
  118. package/dist/utils.d.ts +0 -11
  119. package/dist/utils.d.ts.map +0 -1
  120. package/src/admin.ts +0 -124
  121. package/src/utils.ts +0 -66
@@ -0,0 +1,152 @@
1
+ import { toHex } from '@mysten/sui/utils';
2
+ import invariant from 'tiny-invariant';
3
+ import { MerkleTree } from '../entities/merkle-tree';
4
+ import { Utxo } from '../entities/utxo';
5
+ import { VortexKeypair } from '../entities/keypair';
6
+ import { ZERO_VALUE, MERKLE_TREE_HEIGHT } from '../constants';
7
+ import { poseidon2 } from '../crypto';
8
+
9
+ export const reverseBytes = (bytes: Uint8Array): Uint8Array => {
10
+ const reversed = new Uint8Array(bytes.length);
11
+ for (let i = 0; i < bytes.length; i++) {
12
+ reversed[i] = bytes[bytes.length - 1 - i]!;
13
+ }
14
+ return reversed;
15
+ };
16
+
17
+ export const bytesToBigInt = (bytes: Uint8Array): bigint => {
18
+ return BigInt('0x' + toHex(bytes));
19
+ };
20
+
21
+ export function getMerklePath(
22
+ merkleTree: MerkleTree,
23
+ utxo: Utxo | null
24
+ ): [string, string][] {
25
+ // Handle zero-amount UTXOs
26
+ if (!utxo || utxo.amount === 0n) {
27
+ return Array(MERKLE_TREE_HEIGHT)
28
+ .fill(null)
29
+ .map(() => [ZERO_VALUE.toString(), ZERO_VALUE.toString()]);
30
+ }
31
+
32
+ const utxoIndex = Number(utxo.index);
33
+ const treeSize = merkleTree.elements().length;
34
+
35
+ // For deposits, input UTXOs don't exist yet
36
+ if (utxoIndex < 0 || utxoIndex >= treeSize) {
37
+ return Array(MERKLE_TREE_HEIGHT)
38
+ .fill(null)
39
+ .map(() => [ZERO_VALUE.toString(), ZERO_VALUE.toString()]);
40
+ }
41
+
42
+ // Get Merkle path
43
+ const { pathElements, pathIndices } = merkleTree.path(utxoIndex);
44
+ const commitment = utxo.commitment();
45
+
46
+ // Verify commitment matches what's in the tree
47
+ const storedCommitment = merkleTree.elements()[utxoIndex]!;
48
+
49
+ invariant(
50
+ storedCommitment === commitment,
51
+ `Commitment mismatch at index ${utxoIndex}: expected ${commitment}, got ${storedCommitment}`
52
+ );
53
+
54
+ // Build WASM-compatible path (always [left, right] format)
55
+ const wasmPath: [string, string][] = [];
56
+ let currentHash = commitment;
57
+
58
+ for (let i = 0; i < MERKLE_TREE_HEIGHT; i++) {
59
+ const sibling = pathElements[i];
60
+ const isLeft = pathIndices[i] === 0;
61
+
62
+ invariant(sibling !== undefined, `Sibling undefined at level ${i}`);
63
+
64
+ const leftHash = isLeft ? currentHash : sibling;
65
+ const rightHash = isLeft ? sibling : currentHash;
66
+
67
+ // Verify current hash appears in the pair (critical Rust check)
68
+ if (currentHash !== leftHash && currentHash !== rightHash) {
69
+ throw new Error(
70
+ `Invalid path at level ${i}: current hash must be either left or right`
71
+ );
72
+ }
73
+
74
+ wasmPath.push([leftHash.toString(), rightHash.toString()]);
75
+
76
+ const nextHash = poseidon2(leftHash, rightHash);
77
+
78
+ currentHash = nextHash;
79
+ }
80
+
81
+ const calculatedRoot = currentHash;
82
+ const expectedRoot = merkleTree.root();
83
+
84
+ invariant(
85
+ calculatedRoot === expectedRoot,
86
+ `Root mismatch: calculated ${calculatedRoot}, expected ${expectedRoot}`
87
+ );
88
+
89
+ return wasmPath;
90
+ }
91
+
92
+ interface ToProveInputArgs {
93
+ merkleTree: MerkleTree;
94
+ publicAmount: bigint;
95
+ extDataHash: bigint;
96
+ nullifier0: bigint;
97
+ nullifier1: bigint;
98
+ commitment0: bigint;
99
+ commitment1: bigint;
100
+ vortexKeypair: VortexKeypair;
101
+ inputUtxo0: Utxo;
102
+ inputUtxo1: Utxo;
103
+ outputUtxo0: Utxo;
104
+ outputUtxo1: Utxo;
105
+ }
106
+
107
+ export const toProveInput = ({
108
+ merkleTree,
109
+ publicAmount,
110
+ extDataHash,
111
+ nullifier0,
112
+ nullifier1,
113
+ commitment0,
114
+ commitment1,
115
+ vortexKeypair,
116
+ inputUtxo0,
117
+ inputUtxo1,
118
+ outputUtxo0,
119
+ outputUtxo1,
120
+ }: ToProveInputArgs) => {
121
+ return {
122
+ root: merkleTree.root(),
123
+ publicAmount,
124
+ extDataHash,
125
+ inputNullifier0: nullifier0,
126
+ inputNullifier1: nullifier1,
127
+ outputCommitment0: commitment0,
128
+ outputCommitment1: commitment1,
129
+ inPrivateKey0: vortexKeypair.privateKey,
130
+ inPrivateKey1: vortexKeypair.privateKey,
131
+ inAmount0: inputUtxo0.amount,
132
+ inAmount1: inputUtxo1.amount,
133
+ inBlinding0: inputUtxo0.blinding,
134
+ inBlinding1: inputUtxo1.blinding,
135
+ inPathIndex0: inputUtxo0.index,
136
+ inPathIndex1: inputUtxo1.index,
137
+ merklePath0: getMerklePath(merkleTree, inputUtxo0),
138
+ merklePath1: getMerklePath(merkleTree, inputUtxo1),
139
+
140
+ outPublicKey0: vortexKeypair.publicKey,
141
+ outPublicKey1: vortexKeypair.publicKey,
142
+ outAmount0: outputUtxo0.amount,
143
+ outAmount1: outputUtxo1.amount,
144
+ outBlinding0: outputUtxo0.blinding,
145
+ outBlinding1: outputUtxo1.blinding,
146
+ };
147
+ };
148
+
149
+ export * from './ext-data';
150
+ export * from './events';
151
+ export * from './prove';
152
+ export * from './decrypt';
@@ -0,0 +1,18 @@
1
+ import { prove as proveNode, verify as verifyNode } from '../pkg/nodejs/vortex';
2
+ import { prove as proveWeb, verify as verifyWeb } from '../pkg/web/vortex';
3
+ import { getEnv } from './env';
4
+ import { VERIFYING_KEY, PROVING_KEY } from '../keys';
5
+
6
+ export const prove = (input: string) => {
7
+ const env = getEnv();
8
+ if (env === 'node') return proveNode(input, PROVING_KEY);
9
+ if (env === 'web') return proveWeb(input, PROVING_KEY);
10
+ throw new Error('Unsupported environment');
11
+ };
12
+
13
+ export const verify = (proof: string) => {
14
+ const env = getEnv();
15
+ if (env === 'node') return verifyNode(proof, VERIFYING_KEY);
16
+ if (env === 'web') return verifyWeb(proof, VERIFYING_KEY);
17
+ throw new Error('Unsupported environment');
18
+ };
package/src/vortex.ts CHANGED
@@ -1,162 +1,286 @@
1
+ import { SuiClient, getFullnodeUrl } from '@mysten/sui/client';
2
+ import { Transaction } from '@mysten/sui/transactions';
1
3
  import {
2
- SdkConstructorArgs,
3
- VortexPools,
4
- DepositArgs,
5
- Modules,
6
- Pool,
7
- WithdrawArgs,
4
+ ConstructorArgs,
5
+ RegisterArgs,
6
+ SharedObjectData,
7
+ NewExtDataArgs,
8
+ Action,
9
+ NewProofArgs,
10
+ TransactArgs,
8
11
  } from './vortex.types';
9
- import { SuiClient } from '@mysten/sui/client';
10
- import {
11
- generateRandomNote,
12
- zeros,
13
- BN254_FIELD_MODULUS,
14
- addressToFieldElement,
15
- bigIntToFieldElement,
16
- } from './utils';
17
- import { poseidon2, poseidon1 } from 'poseidon-lite';
18
12
  import { devInspectAndGetReturnValues } from '@polymedia/suitcase-core';
19
- import { Transaction, coinWithBalance } from '@mysten/sui/transactions';
20
- import { fromHex, SUI_TYPE_ARG } from '@mysten/sui/utils';
21
13
  import { bcs } from '@mysten/sui/bcs';
22
14
  import invariant from 'tiny-invariant';
15
+ import { pathOr } from 'ramda';
16
+ import {
17
+ BN254_FIELD_MODULUS,
18
+ VORTEX_PACKAGE_ID,
19
+ REGISTRY_OBJECT_ID,
20
+ INITIAL_SHARED_VERSION,
21
+ VORTEX_POOL_OBJECT_ID,
22
+ } from './constants';
23
23
 
24
- export class VortexSdk {
25
- private client: SuiClient;
26
- private packageId: string;
27
- private pools: VortexPools;
24
+ export class Vortex {
25
+ #suiClient: SuiClient;
28
26
 
29
- public TREE_HEIGHT = 26;
30
- public BN254_FIELD_MODULUS = BN254_FIELD_MODULUS;
27
+ packageId: string;
28
+ registry: SharedObjectData;
29
+ vortex: SharedObjectData;
31
30
 
32
- constructor(args: SdkConstructorArgs) {
33
- this.client = args.client;
34
- this.packageId = args.packageId;
35
- this.pools = args.pools;
36
- }
31
+ newCommitmentEventType: string;
32
+ nullifierSpentEventType: string;
33
+ newEncryptionKeyEventType: string;
37
34
 
38
- generateRandomNote() {
39
- return generateRandomNote();
40
- }
35
+ constructor({
36
+ registry,
37
+ packageId,
38
+ vortex,
39
+ fullNodeUrl = getFullnodeUrl('devnet'),
40
+ }: ConstructorArgs) {
41
+ this.#suiClient = new SuiClient({
42
+ url: fullNodeUrl,
43
+ });
41
44
 
42
- poseidon1(a: bigint | number | string) {
43
- return poseidon1([a]);
44
- }
45
+ this.newCommitmentEventType = `${packageId}::vortex::NewCommitment`;
46
+ this.nullifierSpentEventType = `${packageId}::vortex::NullifierSpent`;
47
+ this.newEncryptionKeyEventType = `${packageId}::vortex::NewEncryptionKey`;
45
48
 
46
- poseidon2(a: bigint | number | string, b: bigint | number | string) {
47
- return poseidon2([a, b]);
49
+ this.packageId = packageId;
50
+ this.registry = registry;
51
+ this.vortex = vortex;
48
52
  }
49
53
 
50
- addressToFieldElement(address: string) {
51
- return addressToFieldElement(address);
52
- }
53
-
54
- bigIntToFieldElement(value: bigint) {
55
- return bigIntToFieldElement(value);
56
- }
54
+ register({ tx = new Transaction(), encryptionKey }: RegisterArgs) {
55
+ tx.moveCall({
56
+ target: `${this.packageId}::vortex::register`,
57
+ arguments: [this.mutableRegistryRef(tx), tx.pure.string(encryptionKey)],
58
+ });
57
59
 
58
- zeros() {
59
- return zeros(this.TREE_HEIGHT);
60
+ return { tx };
60
61
  }
61
62
 
62
- deposit({ commitment, pool, tx = new Transaction() }: DepositArgs) {
63
- const poolObject = this.pools[pool];
64
-
65
- const suiCoin = coinWithBalance({
66
- type: SUI_TYPE_ARG,
67
- balance: pool,
68
- })(tx);
63
+ async encryptionKey(user: string) {
64
+ const tx = new Transaction();
69
65
 
70
66
  tx.moveCall({
71
- package: this.packageId,
72
- module: Modules.vortex,
73
- function: 'deposit',
74
- arguments: [
75
- tx.sharedObjectRef({
76
- objectId: poolObject.objectId,
77
- mutable: true,
78
- initialSharedVersion: poolObject.initialSharedVersion,
79
- }),
80
- suiCoin,
81
- tx.pure.u256(commitment),
82
- ],
67
+ target: `${this.packageId}::vortex::encryption_key`,
68
+ arguments: [this.immutableRegistryRef(tx), tx.pure.address(user)],
83
69
  });
84
70
 
85
- return tx;
71
+ const result = await devInspectAndGetReturnValues(this.#suiClient, tx, [
72
+ [bcs.String],
73
+ ]);
74
+
75
+ invariant(result[0], 'Encryption key devInspectAndGetReturnValues failed');
76
+
77
+ return result[0][0] as string;
86
78
  }
87
79
 
88
- withdraw({
89
- proofPointsHex,
90
- root,
91
- nullifier,
80
+ newExtData({
81
+ tx = new Transaction(),
92
82
  recipient,
83
+ value,
84
+ action,
93
85
  relayer,
94
86
  relayerFee,
95
- pool,
96
- tx = new Transaction(),
97
- }: WithdrawArgs) {
98
- const poolObject = this.pools[pool];
99
-
100
- const proof = tx.moveCall({
101
- package: this.packageId,
102
- module: Modules.proof,
103
- function: 'new',
87
+ encryptedOutput1,
88
+ encryptedOutput0,
89
+ }: NewExtDataArgs) {
90
+ const extData = tx.moveCall({
91
+ target: `${this.packageId}::vortex_ext_data::new`,
104
92
  arguments: [
105
- tx.pure.vector('u8', fromHex(proofPointsHex)),
106
- tx.pure.vector('u8', []),
107
- tx.pure.vector('u8', []),
108
- tx.pure.u256(root),
109
- tx.pure.u256(nullifier),
110
93
  tx.pure.address(recipient),
111
- tx.pure.u64(pool),
94
+ tx.pure.u64(value),
95
+ tx.pure.bool(action === Action.Deposit), // true for deposit, false for withdraw
112
96
  tx.pure.address(relayer),
113
97
  tx.pure.u64(relayerFee),
98
+ tx.pure.vector('u8', encryptedOutput0),
99
+ tx.pure.vector('u8', encryptedOutput1),
114
100
  ],
115
101
  });
116
102
 
117
- tx.moveCall({
118
- package: this.packageId,
119
- module: Modules.vortex,
120
- function: 'withdraw',
103
+ return { tx, extData };
104
+ }
105
+
106
+ newProof({
107
+ tx = new Transaction(),
108
+ proofPoints,
109
+ root,
110
+ publicValue,
111
+ action,
112
+ extDataHash,
113
+ inputNullifier0,
114
+ inputNullifier1,
115
+ outputCommitment0,
116
+ outputCommitment1,
117
+ }: NewProofArgs) {
118
+ const value =
119
+ action === Action.Deposit
120
+ ? publicValue
121
+ : BN254_FIELD_MODULUS - publicValue;
122
+
123
+ const proof = tx.moveCall({
124
+ target: `${this.packageId}::vortex_proof::new`,
121
125
  arguments: [
122
- tx.sharedObjectRef({
123
- objectId: poolObject.objectId,
124
- mutable: true,
125
- initialSharedVersion: poolObject.initialSharedVersion,
126
- }),
127
- proof,
126
+ tx.pure.vector('u8', proofPoints),
127
+ tx.pure.u256(root),
128
+ tx.pure.u256(value),
129
+ tx.pure.u256(extDataHash),
130
+ tx.pure.u256(inputNullifier0),
131
+ tx.pure.u256(inputNullifier1),
132
+ tx.pure.u256(outputCommitment0),
133
+ tx.pure.u256(outputCommitment1),
128
134
  ],
129
135
  });
130
136
 
131
- return tx;
137
+ return { tx, proof };
132
138
  }
133
139
 
134
- async root(pool: Pool) {
135
- const tx = new Transaction();
140
+ transact({ tx = new Transaction(), proof, extData, deposit }: TransactArgs) {
141
+ tx.moveCall({
142
+ target: `${this.packageId}::vortex::transact`,
143
+ arguments: [this.mutableVortexRef(tx), proof, extData, deposit],
144
+ });
145
+
146
+ return { tx };
147
+ }
148
+
149
+ async tvl() {
150
+ const object = await this.#suiClient.getObject({
151
+ id: this.vortex.objectId,
152
+ options: {
153
+ showContent: true,
154
+ },
155
+ });
156
+
157
+ invariant(object.data, 'Vortex object data not found');
158
+
159
+ const content = object.data.content;
160
+
161
+ return BigInt(pathOr(0, ['fields', 'balance'], content));
162
+ }
136
163
 
137
- const poolObject = this.pools[pool];
164
+ async root() {
165
+ const tx = new Transaction();
138
166
 
139
167
  tx.moveCall({
140
- package: this.packageId,
141
- module: Modules.merkleTree,
142
- function: 'root',
143
- arguments: [
144
- tx.sharedObjectRef({
145
- objectId: poolObject.objectId,
146
- mutable: false,
147
- initialSharedVersion: poolObject.initialSharedVersion,
148
- }),
149
- ],
168
+ target: `${this.packageId}::vortex::root`,
169
+ arguments: [this.immutableVortexRef(tx)],
150
170
  });
151
171
 
152
- const result = await devInspectAndGetReturnValues(this.client, tx, [
172
+ const result = await devInspectAndGetReturnValues(this.#suiClient, tx, [
153
173
  [bcs.u256()],
154
174
  ]);
155
175
 
156
176
  invariant(result[0], 'Root devInspectAndGetReturnValues failed');
157
177
 
158
- const [root] = result[0][0].map((value: string) => BigInt(value));
178
+ return BigInt(result[0][0] as string);
179
+ }
180
+
181
+ async nextIndex() {
182
+ const tx = new Transaction();
183
+
184
+ tx.moveCall({
185
+ target: `${this.packageId}::vortex::next_index`,
186
+ arguments: [this.immutableVortexRef(tx)],
187
+ });
188
+
189
+ const result = await devInspectAndGetReturnValues(this.#suiClient, tx, [
190
+ [bcs.u64()],
191
+ ]);
192
+
193
+ invariant(result[0], 'Next index devInspectAndGetReturnValues failed');
194
+
195
+ return BigInt(result[0][0] as string);
196
+ }
197
+
198
+ async isNullifierSpent(nullifier: bigint) {
199
+ const tx = new Transaction();
200
+
201
+ tx.moveCall({
202
+ target: `${this.packageId}::vortex::is_nullifier_spent`,
203
+ arguments: [this.immutableVortexRef(tx), tx.pure.u256(nullifier)],
204
+ });
205
+
206
+ const result = await devInspectAndGetReturnValues(this.#suiClient, tx, [
207
+ [bcs.Bool],
208
+ ]);
209
+
210
+ invariant(
211
+ result[0],
212
+ 'Is nullifier spent devInspectAndGetReturnValues failed'
213
+ );
214
+
215
+ return result[0][0] as boolean;
216
+ }
217
+
218
+ async areNullifiersSpent(nullifiers: bigint[]) {
219
+ const tx = new Transaction();
220
+
221
+ nullifiers.forEach((nullifier) => {
222
+ tx.moveCall({
223
+ target: `${this.packageId}::vortex::is_nullifier_spent`,
224
+ arguments: [this.immutableVortexRef(tx), tx.pure.u256(nullifier)],
225
+ });
226
+ });
227
+
228
+ const result = await devInspectAndGetReturnValues(
229
+ this.#suiClient,
230
+ tx,
231
+ nullifiers.map(() => [bcs.Bool])
232
+ );
233
+
234
+ invariant(
235
+ result[0],
236
+ 'Is nullifier spent devInspectAndGetReturnValues failed'
237
+ );
238
+
239
+ return result.flat() as boolean[];
240
+ }
241
+
242
+ immutableVortexRef(tx: Transaction) {
243
+ return tx.sharedObjectRef({
244
+ objectId: this.vortex.objectId,
245
+ initialSharedVersion: this.vortex.initialSharedVersion,
246
+ mutable: false,
247
+ });
248
+ }
159
249
 
160
- return root;
250
+ immutableRegistryRef(tx: Transaction) {
251
+ return tx.sharedObjectRef({
252
+ objectId: this.registry.objectId,
253
+ initialSharedVersion: this.registry.initialSharedVersion,
254
+ mutable: false,
255
+ });
256
+ }
257
+
258
+ mutableVortexRef(tx: Transaction) {
259
+ return tx.sharedObjectRef({
260
+ objectId: this.vortex.objectId,
261
+ initialSharedVersion: this.vortex.initialSharedVersion,
262
+ mutable: true,
263
+ });
264
+ }
265
+
266
+ mutableRegistryRef(tx: Transaction) {
267
+ return tx.sharedObjectRef({
268
+ objectId: this.registry.objectId,
269
+ initialSharedVersion: this.registry.initialSharedVersion,
270
+ mutable: true,
271
+ });
161
272
  }
162
273
  }
274
+
275
+ export const vortexSDK = new Vortex({
276
+ packageId: VORTEX_PACKAGE_ID,
277
+ registry: {
278
+ objectId: REGISTRY_OBJECT_ID,
279
+ initialSharedVersion: INITIAL_SHARED_VERSION,
280
+ },
281
+ vortex: {
282
+ objectId: VORTEX_POOL_OBJECT_ID,
283
+ initialSharedVersion: INITIAL_SHARED_VERSION,
284
+ },
285
+ fullNodeUrl: getFullnodeUrl('devnet'),
286
+ });