privacycash 1.0.21 → 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.
@@ -14,3 +14,37 @@ export const SIGN_MESSAGE = `Privacy Money account sign in`;
14
14
  export const LSK_FETCH_OFFSET = 'fetch_offset';
15
15
  export const LSK_ENCRYPTED_OUTPUTS = 'encrypted_outputs';
16
16
  export const USDC_MINT = process.env.NEXT_PUBLIC_USDC_MINT ? new PublicKey(process.env.NEXT_PUBLIC_USDC_MINT) : new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v');
17
+ const tokenList = ['sol', 'usdc', 'usdt', 'zec', 'ore'];
18
+ const splList = ['usdc', 'usdt', 'ore'];
19
+ export const tokens = [
20
+ {
21
+ name: 'sol',
22
+ pubkey: new PublicKey('So11111111111111111111111111111111111111112'),
23
+ prefix: '',
24
+ units_per_token: 1e9
25
+ },
26
+ {
27
+ name: 'usdc',
28
+ pubkey: process.env.NEXT_PUBLIC_USDC_MINT ? new PublicKey(process.env.NEXT_PUBLIC_USDC_MINT) : new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'),
29
+ prefix: 'usdc_',
30
+ units_per_token: 1e6
31
+ },
32
+ {
33
+ name: 'usdt',
34
+ pubkey: process.env.NEXT_PUBLIC_USDT_MINT ? new PublicKey(process.env.NEXT_PUBLIC_USDT_MINT) : new PublicKey('Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB'),
35
+ prefix: 'usdt_',
36
+ units_per_token: 1e6
37
+ },
38
+ {
39
+ name: 'zec',
40
+ pubkey: process.env.NEXT_PUBLIC_ZEC_MINT ? new PublicKey(process.env.NEXT_PUBLIC_ZEC_MINT) : new PublicKey('A7bdiYdS5GjqGFtxf17ppRHtDKPkkRqbKtR27dxvQXaS'),
41
+ prefix: 'zec_',
42
+ units_per_token: 1e8
43
+ },
44
+ {
45
+ name: 'ore',
46
+ pubkey: process.env.NEXT_PUBLIC_ORE_MINT ? new PublicKey(process.env.NEXT_PUBLIC_ORE_MINT) : new PublicKey('oreoU2P8bN6jkk3jbaiVxYnG1dCXcYxwhwyK9jSybcp'),
47
+ prefix: 'ore_',
48
+ units_per_token: 1e11
49
+ }
50
+ ];
@@ -4,15 +4,16 @@ import { EncryptionService } from './utils/encryption.js';
4
4
  type WithdrawParams = {
5
5
  publicKey: PublicKey;
6
6
  connection: Connection;
7
- base_units: number;
7
+ base_units?: number;
8
+ amount?: number;
8
9
  keyBasePath: string;
9
10
  encryptionService: EncryptionService;
10
11
  lightWasm: hasher.LightWasm;
11
12
  recipient: PublicKey;
12
- mintAddress: PublicKey;
13
+ mintAddress: PublicKey | string;
13
14
  storage: Storage;
14
15
  };
15
- export declare function withdrawSPL({ recipient, lightWasm, storage, publicKey, connection, base_units, encryptionService, keyBasePath, mintAddress }: WithdrawParams): Promise<{
16
+ export declare function withdrawSPL({ recipient, lightWasm, storage, publicKey, connection, base_units, amount, encryptionService, keyBasePath, mintAddress }: WithdrawParams): Promise<{
16
17
  isPartial: boolean;
17
18
  tx: string;
18
19
  recipient: string;
@@ -4,7 +4,7 @@ import { Buffer } from 'buffer';
4
4
  import { Keypair as UtxoKeypair } from './models/keypair.js';
5
5
  import { Utxo } from './models/utxo.js';
6
6
  import { parseProofToBytesArray, parseToBytesArray, prove } from './utils/prover.js';
7
- import { ALT_ADDRESS, FEE_RECIPIENT, FIELD_SIZE, RELAYER_API_URL, MERKLE_TREE_DEPTH, PROGRAM_ID } from './utils/constants.js';
7
+ import { ALT_ADDRESS, FEE_RECIPIENT, FIELD_SIZE, RELAYER_API_URL, MERKLE_TREE_DEPTH, PROGRAM_ID, tokens } from './utils/constants.js';
8
8
  import { serializeProofAndExtData } from './utils/encryption.js';
9
9
  import { fetchMerkleProof, findNullifierPDAs, getProgramAccounts, queryRemoteTreeState, findCrossCheckNullifierPDAs, getMintAddressField, getExtDataHash } from './utils/utils.js';
10
10
  import { getUtxosSPL } from './getUtxosSPL.js';
@@ -36,26 +36,43 @@ async function submitWithdrawToIndexer(params) {
36
36
  throw error;
37
37
  }
38
38
  }
39
- export async function withdrawSPL({ recipient, lightWasm, storage, publicKey, connection, base_units, encryptionService, keyBasePath, mintAddress }) {
40
- let mintInfo = await getMint(connection, mintAddress);
39
+ export async function withdrawSPL({ recipient, lightWasm, storage, publicKey, connection, base_units, amount, encryptionService, keyBasePath, mintAddress }) {
40
+ if (typeof mintAddress == 'string') {
41
+ mintAddress = new PublicKey(mintAddress);
42
+ }
43
+ let token = tokens.find(t => t.pubkey.toString() == mintAddress.toString());
44
+ if (!token) {
45
+ throw new Error('token not found: ' + mintAddress.toString());
46
+ }
47
+ if (amount) {
48
+ base_units = amount * token.units_per_token;
49
+ }
50
+ if (!base_units) {
51
+ throw new Error('You must input at leaset one of "base_units" or "amount"');
52
+ }
53
+ let mintInfo = await getMint(connection, token.pubkey);
41
54
  let units_per_token = 10 ** mintInfo.decimals;
42
55
  let withdraw_fee_rate = await getConfig('withdraw_fee_rate');
43
- let withdraw_rent_fee = await getConfig('usdc_withdraw_rent_fee');
44
- let fee_base_units = Math.floor(base_units * withdraw_fee_rate + units_per_token * withdraw_rent_fee);
56
+ let withdraw_rent_fees = await getConfig('rent_fees');
57
+ let token_rent_fee = withdraw_rent_fees[token.name];
58
+ if (!token_rent_fee) {
59
+ throw new Error('can not find token_rent_fee for ' + token.name);
60
+ }
61
+ let fee_base_units = Math.floor(base_units * withdraw_fee_rate + units_per_token * token_rent_fee);
45
62
  base_units -= fee_base_units;
46
63
  if (base_units <= 0) {
47
- throw new Error('withdraw amount too low');
64
+ throw new Error('withdraw amount too low, at least ' + fee_base_units / token_rent_fee);
48
65
  }
49
66
  let isPartial = false;
50
- let recipient_ata = getAssociatedTokenAddressSync(mintAddress, recipient, true);
51
- let feeRecipientTokenAccount = getAssociatedTokenAddressSync(mintAddress, FEE_RECIPIENT, true);
52
- let signerTokenAccount = getAssociatedTokenAddressSync(mintAddress, publicKey);
67
+ let recipient_ata = getAssociatedTokenAddressSync(token.pubkey, recipient, true);
68
+ let feeRecipientTokenAccount = getAssociatedTokenAddressSync(token.pubkey, FEE_RECIPIENT, true);
69
+ let signerTokenAccount = getAssociatedTokenAddressSync(token.pubkey, publicKey);
53
70
  logger.debug('Encryption key generated from user keypair');
54
71
  // Derive tree account PDA with mint address for SPL (different from SOL version)
55
- const [treeAccount] = PublicKey.findProgramAddressSync([Buffer.from('merkle_tree'), mintAddress.toBuffer()], PROGRAM_ID);
72
+ const [treeAccount] = PublicKey.findProgramAddressSync([Buffer.from('merkle_tree'), token.pubkey.toBuffer()], PROGRAM_ID);
56
73
  const { globalConfigAccount, treeTokenAccount } = getProgramAccounts();
57
74
  // Get current tree state
58
- const { root, nextIndex: currentNextIndex } = await queryRemoteTreeState('usdc');
75
+ const { root, nextIndex: currentNextIndex } = await queryRemoteTreeState(token.name);
59
76
  logger.debug(`Using tree root: ${root}`);
60
77
  logger.debug(`New UTXOs will be inserted at indices: ${currentNextIndex} and ${currentNextIndex + 1}`);
61
78
  // Generate a deterministic private key derived from the wallet keypair
@@ -69,7 +86,7 @@ export async function withdrawSPL({ recipient, lightWasm, storage, publicKey, co
69
86
  // Fetch existing UTXOs for this user
70
87
  logger.debug('\nFetching existing UTXOs...');
71
88
  const mintUtxos = await getUtxosSPL({ connection, publicKey, encryptionService, storage, mintAddress });
72
- logger.debug(`Found ${mintUtxos.length} total UTXOs`);
89
+ logger.debug(`Found ${mintUtxos.length} total UTXOs for ${token.name}`);
73
90
  // Calculate and log total unspent UTXO balance
74
91
  const totalUnspentBalance = mintUtxos.reduce((sum, utxo) => sum.add(utxo.amount), new BN(0));
75
92
  logger.debug(`Total unspent UTXO balance before: ${totalUnspentBalance.toString()} lamports (${totalUnspentBalance.toNumber() / 1e9} SOL)`);
@@ -84,7 +101,7 @@ export async function withdrawSPL({ recipient, lightWasm, storage, publicKey, co
84
101
  lightWasm,
85
102
  keypair: utxoKeypair,
86
103
  amount: '0',
87
- mintAddress: mintAddress.toString()
104
+ mintAddress: token.pubkey.toString()
88
105
  });
89
106
  const inputs = [firstInput, secondInput];
90
107
  logger.debug(`firstInput index: ${firstInput.index}, commitment: ${firstInput.getCommitment()}`);
@@ -113,7 +130,7 @@ export async function withdrawSPL({ recipient, lightWasm, storage, publicKey, co
113
130
  }
114
131
  // For real UTXOs, fetch the proof from API
115
132
  const commitment = await utxo.getCommitment();
116
- return fetchMerkleProof(commitment, 'usdc');
133
+ return fetchMerkleProof(commitment, token.name);
117
134
  }));
118
135
  // Extract path elements and indices
119
136
  const inputMerklePathElements = inputMerkleProofs.map(proof => proof.pathElements);
@@ -125,14 +142,14 @@ export async function withdrawSPL({ recipient, lightWasm, storage, publicKey, co
125
142
  amount: changeAmount.toString(),
126
143
  keypair: utxoKeypairV2,
127
144
  index: currentNextIndex,
128
- mintAddress: mintAddress.toString()
145
+ mintAddress: token.pubkey.toString()
129
146
  }), // Change output
130
147
  new Utxo({
131
148
  lightWasm,
132
149
  amount: '0',
133
150
  keypair: utxoKeypairV2,
134
151
  index: currentNextIndex + 1,
135
- mintAddress: mintAddress.toString()
152
+ mintAddress: token.pubkey.toString()
136
153
  }) // Empty UTXO
137
154
  ];
138
155
  // For withdrawals, extAmount is negative (funds leaving the system)
@@ -185,7 +202,7 @@ export async function withdrawSPL({ recipient, lightWasm, storage, publicKey, co
185
202
  encryptedOutput2: encryptedOutput2,
186
203
  fee: new BN(fee_base_units),
187
204
  feeRecipient: feeRecipientTokenAccount,
188
- mintAddress: mintAddress.toString()
205
+ mintAddress: token.pubkey.toString()
189
206
  };
190
207
  // Calculate the extDataHash with the encrypted outputs
191
208
  const calculatedExtDataHash = getExtDataHash(extData);
@@ -193,7 +210,7 @@ export async function withdrawSPL({ recipient, lightWasm, storage, publicKey, co
193
210
  const input = {
194
211
  // Common transaction data
195
212
  root: root,
196
- mintAddress: getMintAddressField(mintAddress), // new mint address
213
+ mintAddress: getMintAddressField(token.pubkey), // new mint address
197
214
  publicAmount: publicAmountForCircuit.toString(), // Use proper field arithmetic result
198
215
  extDataHash: calculatedExtDataHash,
199
216
  // Input UTXO data (UTXOs being spent) - ensure all values are in decimal format
@@ -239,7 +256,7 @@ export async function withdrawSPL({ recipient, lightWasm, storage, publicKey, co
239
256
  const serializedProof = serializeProofAndExtData(proofToSubmit, extData, true);
240
257
  logger.debug(`Total instruction data size: ${serializedProof.length} bytes`);
241
258
  const [globalConfigPda, globalConfigPdaBump] = await PublicKey.findProgramAddressSync([Buffer.from("global_config")], PROGRAM_ID);
242
- const treeAta = getAssociatedTokenAddressSync(mintAddress, globalConfigPda, true);
259
+ const treeAta = getAssociatedTokenAddressSync(token.pubkey, globalConfigPda, true);
243
260
  // Prepare withdraw parameters for indexer backend
244
261
  const withdrawParams = {
245
262
  serializedProof: serializedProof.toString('base64'),
@@ -258,7 +275,7 @@ export async function withdrawSPL({ recipient, lightWasm, storage, publicKey, co
258
275
  senderAddress: publicKey.toString(),
259
276
  treeAta: treeAta.toString(),
260
277
  recipientAta: recipient_ata.toString(),
261
- mintAddress: mintAddress.toString(),
278
+ mintAddress: token.pubkey.toString(),
262
279
  feeRecipientTokenAccount: feeRecipientTokenAccount.toString()
263
280
  };
264
281
  logger.debug('Prepared withdraw parameters for indexer backend');
@@ -275,7 +292,7 @@ export async function withdrawSPL({ recipient, lightWasm, storage, publicKey, co
275
292
  console.log(`retryTimes: ${retryTimes}`);
276
293
  await new Promise(resolve => setTimeout(resolve, itv * 1000));
277
294
  console.log('Fetching updated tree state...');
278
- let res = await fetch(RELAYER_API_URL + '/utxos/check/' + encryptedOutputStr + '?token=usdc');
295
+ let res = await fetch(RELAYER_API_URL + '/utxos/check/' + encryptedOutputStr + '?token=' + token.name);
279
296
  let resJson = await res.json();
280
297
  console.log('resJson:', resJson);
281
298
  if (resJson.exists) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "privacycash",
3
- "version": "1.0.21",
3
+ "version": "1.1.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "repository": "https://github.com/Privacy-Cash/privacy-cash-sdk",
package/src/config.ts CHANGED
@@ -5,6 +5,7 @@ type Config = {
5
5
  withdraw_rent_fee: number
6
6
  deposit_fee_rate: number
7
7
  usdc_withdraw_rent_fee: number
8
+ rent_fees: any
8
9
  }
9
10
 
10
11
  let config: Config | undefined
@@ -14,7 +15,7 @@ export async function getConfig<K extends keyof Config>(key: K): Promise<Config[
14
15
  const res = await fetch(RELAYER_API_URL + '/config')
15
16
  config = await res.json()
16
17
  }
17
- if (typeof config![key] != 'number') {
18
+ if (typeof config![key] == 'undefined') {
18
19
  throw new Error(`can not get ${key} from ${RELAYER_API_URL}/config`)
19
20
  }
20
21
  return config![key]
package/src/deposit.ts CHANGED
@@ -67,6 +67,7 @@ type DepositParams = {
67
67
  export async function deposit({ lightWasm, storage, keyBasePath, publicKey, connection, amount_in_lamports, encryptionService, transactionSigner, referrer }: DepositParams) {
68
68
  // check limit
69
69
  let limitAmount = await checkDepositLimit(connection)
70
+
70
71
  if (limitAmount && amount_in_lamports > limitAmount * LAMPORTS_PER_SOL) {
71
72
  throw new Error(`Don't deposit more than ${limitAmount} SOL`)
72
73
  }
@@ -451,7 +452,7 @@ async function checkDepositLimit(connection: Connection) {
451
452
  const accountInfo = await connection.getAccountInfo(treeAccount);
452
453
 
453
454
  if (!accountInfo) {
454
- console.error('❌ Tree account not found. Make sure the program is initialized.');
455
+ console.error('❌ Tree account not found. Make sure the program is initialized.' + PROGRAM_ID);
455
456
  return;
456
457
  }
457
458
 
package/src/depositSPL.ts CHANGED
@@ -8,7 +8,7 @@ import { MerkleTree } from './utils/merkle_tree.js';
8
8
  import { EncryptionService, serializeProofAndExtData } from './utils/encryption.js';
9
9
  import { Keypair as UtxoKeypair } from './models/keypair.js';
10
10
  import { getUtxosSPL, isUtxoSpent } from './getUtxosSPL.js';
11
- import { FIELD_SIZE, FEE_RECIPIENT, MERKLE_TREE_DEPTH, RELAYER_API_URL, PROGRAM_ID, ALT_ADDRESS } from './utils/constants.js';
11
+ import { FIELD_SIZE, FEE_RECIPIENT, MERKLE_TREE_DEPTH, RELAYER_API_URL, PROGRAM_ID, ALT_ADDRESS, tokens, SplList, Token } from './utils/constants.js';
12
12
  import { getProtocolAddressesWithMint, useExistingALT } from './utils/address_lookup_table.js';
13
13
  import { logger } from './utils/logger.js';
14
14
  import { getAssociatedTokenAddress, ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID, getAssociatedTokenAddressSync, getMint, getAccount } from '@solana/spl-token';
@@ -34,7 +34,7 @@ async function relayDepositToIndexer({ signedTransaction, publicKey, referrer, m
34
34
  if (referrer) {
35
35
  params.referralWalletAddress = referrer
36
36
  }
37
- params.mintAddress = mintAddress.toString()
37
+ params.mintAddress = mintAddress
38
38
 
39
39
  const response = await fetch(`${RELAYER_API_URL}/deposit/spl`, {
40
40
  method: 'POST',
@@ -63,10 +63,11 @@ async function relayDepositToIndexer({ signedTransaction, publicKey, referrer, m
63
63
  }
64
64
 
65
65
  type DepositParams = {
66
- mintAddress: PublicKey,
66
+ mintAddress: PublicKey | string,
67
67
  publicKey: PublicKey,
68
68
  connection: Connection,
69
- base_units: number,
69
+ base_units?: number,
70
+ amount?: number,
70
71
  storage: Storage,
71
72
  encryptionService: EncryptionService,
72
73
  keyBasePath: string,
@@ -74,61 +75,70 @@ type DepositParams = {
74
75
  referrer?: string,
75
76
  transactionSigner: (tx: VersionedTransaction) => Promise<VersionedTransaction>
76
77
  }
77
- export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, connection, base_units, encryptionService, transactionSigner, referrer, mintAddress }: DepositParams) {
78
- let mintInfo = await getMint(connection, mintAddress)
79
- let units_per_token = 10 ** mintInfo.decimals
78
+ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, connection, base_units, amount, encryptionService, transactionSigner, referrer, mintAddress }: DepositParams) {
79
+ if (typeof mintAddress == 'string') {
80
+ mintAddress = new PublicKey(mintAddress)
81
+ }
82
+ let token = tokens.find(t => t.pubkey.toString() == mintAddress.toString())
83
+ if (!token) {
84
+ throw new Error('token not found: ' + mintAddress.toString())
85
+ }
86
+
87
+ if (amount) {
88
+ base_units = amount * token.units_per_token
89
+ }
90
+
91
+ if (!base_units) {
92
+ throw new Error('You must input at least one of "base_units" or "amount"')
93
+ }
94
+
95
+
96
+ // let mintInfo = await getMint(connection, token.pubkey)
97
+ // let units_per_token = 10 ** mintInfo.decimals
80
98
 
81
99
  let recipient = new PublicKey('AWexibGxNFKTa1b5R5MN4PJr9HWnWRwf8EW9g8cLx3dM')
82
100
  let recipient_ata = getAssociatedTokenAddressSync(
83
- mintAddress,
101
+ token.pubkey,
84
102
  recipient,
85
103
  true
86
104
  );
87
105
  let feeRecipientTokenAccount = getAssociatedTokenAddressSync(
88
- mintAddress,
106
+ token.pubkey,
89
107
  FEE_RECIPIENT,
90
108
  true
91
109
  );
92
110
  let signerTokenAccount = getAssociatedTokenAddressSync(
93
- mintAddress,
111
+ token.pubkey,
94
112
  publicKey
95
113
  );
96
114
 
97
- // Derive tree account PDA with mint address for SPL (different from SOL version)
115
+ // Derive tree account PDA with mint address for SPL
98
116
  const [treeAccount] = PublicKey.findProgramAddressSync(
99
- [Buffer.from('merkle_tree'), mintAddress.toBuffer()],
117
+ [Buffer.from('merkle_tree'), token.pubkey.toBuffer()],
100
118
  PROGRAM_ID
101
119
  );
102
120
 
103
- let limitAmount = await checkDepositLimit(connection, treeAccount)
104
- if (limitAmount && base_units > limitAmount * 1e6) {
105
- throw new Error(`Don't deposit more than ${limitAmount} USDC`)
121
+ let limitAmount = await checkDepositLimit(connection, treeAccount, token)
122
+ if (limitAmount && base_units > limitAmount * token.units_per_token) {
123
+ throw new Error(`Don't deposit more than ${limitAmount} ${token.name.toUpperCase()}`)
106
124
  }
107
125
 
108
-
109
-
110
- // check limit
111
- // let limitAmount = await checkDepositLimit(connection)
112
- // if (limitAmount && base_units > limitAmount * units_per_token) {
113
- // throw new Error(`Don't deposit more than ${limitAmount} SOL`)
114
- // }
115
-
116
126
  // const base_units = amount_in_sol * units_per_token
117
127
  const fee_base_units = 0
118
128
  logger.debug('Encryption key generated from user keypair');
119
129
  logger.debug(`User wallet: ${publicKey.toString()}`);
120
- logger.debug(`Deposit amount: ${base_units} base_units (${base_units / units_per_token} USDC)`);
121
- logger.debug(`Calculated fee: ${fee_base_units} base_units (${fee_base_units / units_per_token} USDC)`);
130
+ logger.debug(`Deposit amount: ${base_units} base_units (${base_units / token.units_per_token} ${token.name.toUpperCase()})`);
131
+ logger.debug(`Calculated fee: ${fee_base_units} base_units (${fee_base_units / token.units_per_token} ${token.name.toUpperCase()})`);
122
132
 
123
133
  // Check SPL balance
124
134
  const accountInfo = await getAccount(connection, signerTokenAccount)
125
135
  let balance = Number(accountInfo.amount)
126
- logger.debug(`USDC wallet balance: ${balance / units_per_token} USDC`);
136
+ logger.debug(`wallet balance: ${balance / token.units_per_token} ${token.name.toUpperCase()}`);
127
137
  console.log('balance', balance)
128
138
  console.log('base_units + fee_base_units', base_units + fee_base_units)
129
139
 
130
140
  if (balance < (base_units + fee_base_units)) {
131
- throw new Error(`Insufficient balance. Need at least ${(base_units + fee_base_units) / units_per_token} USDC.`);
141
+ throw new Error(`Insufficient balance. Need at least ${(base_units + fee_base_units) / token.units_per_token} ${token.name.toUpperCase()}.`);
132
142
  }
133
143
 
134
144
  // Check SOL balance
@@ -145,7 +155,7 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
145
155
  const tree = new MerkleTree(MERKLE_TREE_DEPTH, lightWasm);
146
156
 
147
157
  // Initialize root and nextIndex variables
148
- const { root, nextIndex: currentNextIndex } = await queryRemoteTreeState('usdc');
158
+ const { root, nextIndex: currentNextIndex } = await queryRemoteTreeState(token.name);
149
159
 
150
160
  logger.debug(`Using tree root: ${root}`);
151
161
  logger.debug(`New UTXOs will be inserted at indices: ${currentNextIndex} and ${currentNextIndex + 1}`);
@@ -185,12 +195,12 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
185
195
  new Utxo({
186
196
  lightWasm,
187
197
  keypair: utxoKeypair,
188
- mintAddress: mintAddress.toString()
198
+ mintAddress: token.pubkey.toString()
189
199
  }),
190
200
  new Utxo({
191
201
  lightWasm,
192
202
  keypair: utxoKeypair,
193
- mintAddress: mintAddress.toString()
203
+ mintAddress: token.pubkey.toString()
194
204
  })
195
205
  ];
196
206
 
@@ -227,7 +237,7 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
227
237
  lightWasm,
228
238
  keypair: utxoKeypair,
229
239
  amount: '0', // This UTXO will be inserted at currentNextIndex
230
- mintAddress: mintAddress.toString()
240
+ mintAddress: token.pubkey.toString()
231
241
  });
232
242
 
233
243
  inputs = [
@@ -237,13 +247,13 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
237
247
 
238
248
  // Fetch Merkle proofs for real UTXOs
239
249
  const firstUtxoCommitment = await firstUtxo.getCommitment();
240
- const firstUtxoMerkleProof = await fetchMerkleProof(firstUtxoCommitment, 'usdc');
250
+ const firstUtxoMerkleProof = await fetchMerkleProof(firstUtxoCommitment, token.name);
241
251
 
242
252
  let secondUtxoMerkleProof;
243
253
  if (secondUtxo.amount.gt(new BN(0))) {
244
254
  // Second UTXO is real, fetch its proof
245
255
  const secondUtxoCommitment = await secondUtxo.getCommitment();
246
- secondUtxoMerkleProof = await fetchMerkleProof(secondUtxoCommitment, 'usdc');
256
+ secondUtxoMerkleProof = await fetchMerkleProof(secondUtxoCommitment, token.name);
247
257
  logger.debug('\nSecond UTXO to be consolidated:');
248
258
  await secondUtxo.log();
249
259
  }
@@ -278,14 +288,14 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
278
288
  amount: outputAmount,
279
289
  keypair: utxoKeypair,
280
290
  index: currentNextIndex, // This UTXO will be inserted at currentNextIndex
281
- mintAddress: mintAddress.toString()
291
+ mintAddress: token.pubkey.toString()
282
292
  }), // Output with value (either deposit amount minus fee, or input amount minus fee)
283
293
  new Utxo({
284
294
  lightWasm,
285
295
  amount: '0',
286
296
  keypair: utxoKeypair,
287
297
  index: currentNextIndex + 1, // This UTXO will be inserted at currentNextIndex
288
- mintAddress: mintAddress.toString()
298
+ mintAddress: token.pubkey.toString()
289
299
  }) // Empty UTXO
290
300
  ];
291
301
 
@@ -341,7 +351,7 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
341
351
  encryptedOutput2: encryptedOutput2,
342
352
  fee: new BN(fee_base_units),
343
353
  feeRecipient: feeRecipientTokenAccount,
344
- mintAddress: mintAddress.toString()
354
+ mintAddress: token.pubkey.toString()
345
355
  };
346
356
  // Calculate the extDataHash with the encrypted outputs (now includes mintAddress for security)
347
357
  const calculatedExtDataHash = getExtDataHash(extData);
@@ -350,7 +360,7 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
350
360
  const input = {
351
361
  // Common transaction data
352
362
  root: root,
353
- mintAddress: getMintAddressField(mintAddress),// new mint address
363
+ mintAddress: getMintAddressField(token.pubkey),// new mint address
354
364
  publicAmount: publicAmountForCircuit.toString(), // Use proper field arithmetic result
355
365
  extDataHash: calculatedExtDataHash,
356
366
 
@@ -403,7 +413,7 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
403
413
  [Buffer.from("global_config")],
404
414
  PROGRAM_ID
405
415
  );
406
- const treeAta = getAssociatedTokenAddressSync(mintAddress, globalConfigPda, true);
416
+ const treeAta = getAssociatedTokenAddressSync(token.pubkey, globalConfigPda, true);
407
417
 
408
418
  const lookupTableAccount = await useExistingALT(connection, ALT_ADDRESS);
409
419
 
@@ -428,7 +438,7 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
428
438
  // signer
429
439
  { pubkey: publicKey, isSigner: true, isWritable: true },
430
440
  // SPL token mint
431
- { pubkey: mintAddress, isSigner: false, isWritable: false },
441
+ { pubkey: token.pubkey, isSigner: false, isWritable: false },
432
442
  // signer's token account
433
443
  { pubkey: signerTokenAccount, isSigner: false, isWritable: true },
434
444
  // recipient (placeholder)
@@ -482,7 +492,7 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
482
492
  // Relay the pre-signed transaction to indexer backend
483
493
  logger.info('submitting transaction to relayer...')
484
494
  const signature = await relayDepositToIndexer({
485
- mintAddress: mintAddress.toString(),
495
+ mintAddress: token.pubkey.toString(),
486
496
  publicKey,
487
497
  signedTransaction: serializedTransaction,
488
498
  referrer
@@ -500,7 +510,7 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
500
510
  logger.debug(`retryTimes: ${retryTimes}`)
501
511
  await new Promise(resolve => setTimeout(resolve, itv * 1000));
502
512
  logger.debug('Fetching updated tree state...');
503
- let url = RELAYER_API_URL + '/utxos/check/' + encryptedOutputStr + '?token=usdc'
513
+ let url = RELAYER_API_URL + '/utxos/check/' + encryptedOutputStr + '?token=' + token.name
504
514
  let res = await fetch(url)
505
515
  let resJson = await res.json()
506
516
  if (resJson.exists) {
@@ -516,7 +526,7 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
516
526
  }
517
527
 
518
528
 
519
- async function checkDepositLimit(connection: Connection, treeAccount: PublicKey) {
529
+ async function checkDepositLimit(connection: Connection, treeAccount: PublicKey, token: Token) {
520
530
  try {
521
531
 
522
532
  // Fetch the account data
@@ -533,21 +543,21 @@ async function checkDepositLimit(connection: Connection, treeAccount: PublicKey)
533
543
  const maxDepositAmount = new BN(accountInfo.data.slice(4120, 4128), 'le');
534
544
  const bump = accountInfo.data[4128];
535
545
 
536
- // Convert to SOL using BN division to handle large numbers
537
- const lamportsPerSol = new BN(1e6);
538
- const maxDepositSol = maxDepositAmount.div(lamportsPerSol);
539
- const remainder = maxDepositAmount.mod(lamportsPerSol);
546
+ // Convert to SPL using BN division to handle large numbers
547
+ const unitesPerToken = new BN(token.units_per_token);
548
+ const maxDepositSpl = maxDepositAmount.div(unitesPerToken);
549
+ const remainder = maxDepositAmount.mod(unitesPerToken);
540
550
 
541
- // Format the SOL amount with decimals
542
- let solFormatted = '1';
551
+ // Format the SPL amount with decimals
552
+ let amountFormatted = '1';
543
553
  if (remainder.eq(new BN(0))) {
544
- solFormatted = maxDepositSol.toString();
554
+ amountFormatted = maxDepositSpl.toString();
545
555
  } else {
546
- // Handle fractional SOL by converting remainder to decimal
547
- const fractional = remainder.toNumber() / 1e6;
548
- solFormatted = `${maxDepositSol.toString()}${fractional.toFixed(9).substring(1)}`;
556
+ // Handle fractional SPL by converting remainder to decimal
557
+ const fractional = remainder.toNumber() / token.units_per_token;
558
+ amountFormatted = `${maxDepositSpl.toString()}${fractional.toFixed(Math.log10(token.units_per_token)).substring(1)}`;
549
559
  }
550
- return Number(solFormatted)
560
+ return Number(amountFormatted)
551
561
 
552
562
  } catch (error) {
553
563
  console.log('❌ Error reading deposit limit:', error);
@@ -7,4 +7,6 @@ export { getBalanceFromUtxos, getUtxos, localstorageKey } from './getUtxos.js'
7
7
 
8
8
  export { depositSPL } from './depositSPL.js'
9
9
  export { withdrawSPL } from './withdrawSPL.js'
10
- export { getBalanceFromUtxosSPL, getUtxosSPL } from './getUtxosSPL.js'
10
+ export { getBalanceFromUtxosSPL, getUtxosSPL } from './getUtxosSPL.js'
11
+
12
+ export { type TokenList, type SplList, tokens } from './utils/constants.js'