privacycash 1.1.24 → 1.2.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.
@@ -0,0 +1,67 @@
1
+ import { PublicKey } from '@solana/web3.js';
2
+ import { describe, expect, it } from 'vitest';
3
+ import { depositSPL } from '../src/depositSPL';
4
+ import {
5
+ getRelayerTokenName,
6
+ LEGACY_STORE_MINT,
7
+ normalizeRelayerTokenMap,
8
+ resolveToken,
9
+ resolveTokenName,
10
+ STORE_MINT,
11
+ tokens,
12
+ } from '../src/utils/constants';
13
+
14
+ describe('stORE token aliases', () => {
15
+ it('exports latest stORE as store and old stORE as legacyStore', () => {
16
+ const tokenNames = tokens.map(token => token.name);
17
+
18
+ expect(tokenNames).toContain('store');
19
+ expect(tokenNames).toContain('legacyStore');
20
+ expect(tokenNames).not.toContain('newstore' as any);
21
+
22
+ expect(tokens.find(token => token.name === 'store')?.pubkey.toString()).toBe(STORE_MINT.toString());
23
+ expect(tokens.find(token => token.name === 'legacyStore')?.pubkey.toString()).toBe(LEGACY_STORE_MINT.toString());
24
+ });
25
+
26
+ it('maps public stORE names to relayer token names', () => {
27
+ expect(getRelayerTokenName('store')).toBe('newstore');
28
+ expect(getRelayerTokenName('legacyStore')).toBe('store');
29
+ expect(getRelayerTokenName('usdc')).toBe('usdc');
30
+ });
31
+
32
+ it('resolves CLI token aliases without exposing newstore', () => {
33
+ expect(resolveTokenName('store')).toBe('store');
34
+ expect(resolveTokenName('newstore')).toBe('store');
35
+ expect(resolveTokenName('legacyStore')).toBe('legacyStore');
36
+ expect(resolveTokenName('legacystore')).toBe('legacyStore');
37
+
38
+ expect(resolveToken('newstore')?.pubkey.toString()).toBe(STORE_MINT.toString());
39
+ expect(resolveToken('legacyStore')?.pubkey.toString()).toBe(LEGACY_STORE_MINT.toString());
40
+ });
41
+
42
+ it('normalizes relayer config maps without exposing newstore', () => {
43
+ expect(normalizeRelayerTokenMap({
44
+ sol: 1,
45
+ store: 2,
46
+ newstore: 3,
47
+ })).toEqual({
48
+ sol: 1,
49
+ store: 3,
50
+ legacyStore: 2,
51
+ });
52
+ });
53
+
54
+ it('rejects legacy stORE deposits before transaction work starts', async () => {
55
+ await expect(depositSPL({
56
+ mintAddress: new PublicKey(LEGACY_STORE_MINT),
57
+ lightWasm: {} as any,
58
+ storage: {} as any,
59
+ keyBasePath: '',
60
+ publicKey: PublicKey.default,
61
+ connection: {} as any,
62
+ base_units: 1,
63
+ encryptionService: {} as any,
64
+ transactionSigner: async tx => tx,
65
+ })).rejects.toThrow('Legacy stORE deposit has been disabled. Please use the latest stORE.');
66
+ });
67
+ });
package/dist/config.d.ts CHANGED
@@ -3,7 +3,9 @@ type Config = {
3
3
  withdraw_rent_fee: number;
4
4
  deposit_fee_rate: number;
5
5
  usdc_withdraw_rent_fee: number;
6
- rent_fees: any;
6
+ rent_fees: Record<string, number>;
7
+ minimum_withdrawal: Record<string, number>;
8
+ prices: Record<string, number>;
7
9
  };
8
10
  export declare function getConfig<K extends keyof Config>(key: K): Promise<Config[K]>;
9
11
  export {};
package/dist/config.js CHANGED
@@ -1,12 +1,20 @@
1
- import { RELAYER_API_URL } from "./utils/constants.js";
1
+ import { normalizeRelayerTokenMap, RELAYER_API_URL } from "./utils/constants.js";
2
2
  let config;
3
3
  export async function getConfig(key) {
4
4
  if (!config) {
5
5
  const res = await fetch(RELAYER_API_URL + '/config');
6
- config = await res.json();
6
+ config = normalizeConfig(await res.json());
7
7
  }
8
8
  if (typeof config[key] == 'undefined') {
9
9
  throw new Error(`can not get ${key} from ${RELAYER_API_URL}/config`);
10
10
  }
11
11
  return config[key];
12
12
  }
13
+ function normalizeConfig(raw) {
14
+ return {
15
+ ...raw,
16
+ rent_fees: normalizeRelayerTokenMap(raw.rent_fees) ?? {},
17
+ minimum_withdrawal: normalizeRelayerTokenMap(raw.minimum_withdrawal) ?? {},
18
+ prices: normalizeRelayerTokenMap(raw.prices) ?? {},
19
+ };
20
+ }
@@ -5,7 +5,7 @@ import { getUtxosSPL } from './getUtxosSPL.js';
5
5
  import { Keypair as UtxoKeypair } from './models/keypair.js';
6
6
  import { Utxo } from './models/utxo.js';
7
7
  import { useExistingALT } from './utils/address_lookup_table.js';
8
- import { ALT_ADDRESS, FEE_RECIPIENT, FIELD_SIZE, MERKLE_TREE_DEPTH, PROGRAM_ID, RELAYER_API_URL, tokens } from './utils/constants.js';
8
+ import { ALT_ADDRESS, FEE_RECIPIENT, FIELD_SIZE, getRelayerTokenName, MERKLE_TREE_DEPTH, PROGRAM_ID, RELAYER_API_URL, tokens } from './utils/constants.js';
9
9
  import { serializeProofAndExtData } from './utils/encryption.js';
10
10
  import { logger } from './utils/logger.js';
11
11
  import { MerkleTree } from './utils/merkle_tree.js';
@@ -61,6 +61,10 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
61
61
  if (!token) {
62
62
  throw new Error('token not found: ' + mintAddress.toString());
63
63
  }
64
+ if (token.name === 'legacyStore') {
65
+ throw new Error('Legacy stORE deposit has been disabled. Please use the latest stORE.');
66
+ }
67
+ const relayerTokenName = getRelayerTokenName(token.name);
64
68
  if (amount) {
65
69
  base_units = amount * token.units_per_token;
66
70
  }
@@ -125,7 +129,7 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
125
129
  let root;
126
130
  let nextIndex;
127
131
  if (mintUtxos.length === 0) {
128
- const treeState = await queryRemoteTreeState(token.name);
132
+ const treeState = await queryRemoteTreeState(relayerTokenName);
129
133
  root = treeState.root;
130
134
  nextIndex = treeState.nextIndex;
131
135
  // Scenario 1: Fresh deposit with dummy inputs - add new funds to the system
@@ -193,7 +197,7 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
193
197
  logger.debug('\nSecond UTXO to be consolidated:');
194
198
  await secondUtxo.log();
195
199
  }
196
- let data = await fetchMerkleProof(commitmentsToFetch, token.name);
200
+ let data = await fetchMerkleProof(commitmentsToFetch, relayerTokenName);
197
201
  root = data.root;
198
202
  nextIndex = data.nextIndex;
199
203
  let [firstUtxoMerkleProof, secondUtxoMerkleProof] = data.proofs;
@@ -425,7 +429,7 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
425
429
  logger.debug(`retryTimes: ${retryTimes}`);
426
430
  await new Promise(resolve => setTimeout(resolve, itv * 1000));
427
431
  logger.debug('Fetching updated onchain state...');
428
- let url = RELAYER_API_URL + '/utxos/check/' + encryptedOutputStr + '?token=' + token.name;
432
+ let url = RELAYER_API_URL + '/utxos/check/' + encryptedOutputStr + '?token=' + relayerTokenName;
429
433
  let res = await fetch(url);
430
434
  let resJson = await res.json();
431
435
  if (resJson.exists) {
@@ -7,4 +7,4 @@ export { getBalanceFromUtxos, getUtxos, localstorageKey } from './getUtxos.js';
7
7
  export { depositSPL } from './depositSPL.js';
8
8
  export { withdrawSPL } from './withdrawSPL.js';
9
9
  export { getBalanceFromUtxosSPL, getUtxosSPL } from './getUtxosSPL.js';
10
- export { type TokenList, type SplList, tokens } from './utils/constants.js';
10
+ export { getRelayerTokenName, LEGACY_STORE_MINT, normalizeRelayerTokenMap, STORE_MINT, type TokenList, type SplList, tokens } from './utils/constants.js';
@@ -7,4 +7,4 @@ export { getBalanceFromUtxos, getUtxos, localstorageKey } from './getUtxos.js';
7
7
  export { depositSPL } from './depositSPL.js';
8
8
  export { withdrawSPL } from './withdrawSPL.js';
9
9
  export { getBalanceFromUtxosSPL, getUtxosSPL } from './getUtxosSPL.js';
10
- export { tokens } from './utils/constants.js';
10
+ export { getRelayerTokenName, LEGACY_STORE_MINT, normalizeRelayerTokenMap, STORE_MINT, tokens } from './utils/constants.js';
@@ -4,7 +4,7 @@ import { Keypair as UtxoKeypair } from './models/keypair.js';
4
4
  import { WasmFactory } from '@lightprotocol/hasher.rs';
5
5
  //@ts-ignore
6
6
  import * as ffjavascript from 'ffjavascript';
7
- import { FETCH_UTXOS_GROUP_SIZE, RELAYER_API_URL, LSK_ENCRYPTED_OUTPUTS, LSK_FETCH_OFFSET, PROGRAM_ID, tokens } from './utils/constants.js';
7
+ import { FETCH_UTXOS_GROUP_SIZE, getRelayerTokenName, RELAYER_API_URL, LSK_ENCRYPTED_OUTPUTS, LSK_FETCH_OFFSET, PROGRAM_ID, tokens } from './utils/constants.js';
8
8
  import { logger } from './utils/logger.js';
9
9
  import { getAssociatedTokenAddress } from '@solana/spl-token';
10
10
  // Use type assertion for the utility functions (same pattern as in get_verification_keys.ts)
@@ -40,6 +40,7 @@ export async function getUtxosSPL({ publicKey, connection, encryptionService, st
40
40
  if (!token) {
41
41
  throw new Error('token not found: ' + mintAddress.toString());
42
42
  }
43
+ const relayerTokenName = getRelayerTokenName(token.name);
43
44
  logger.debug('token name: ' + token.name + ', token address' + token.pubkey.toString());
44
45
  try {
45
46
  publicKey_ata = await getAssociatedTokenAddress(token.pubkey, publicKey);
@@ -66,8 +67,8 @@ export async function getUtxosSPL({ publicKey, connection, encryptionService, st
66
67
  }
67
68
  logger.debug(' ####fetch_utxo_offset', fetch_utxo_offset);
68
69
  let fetch_utxo_end = fetch_utxo_offset + FETCH_UTXOS_GROUP_SIZE;
69
- let fetch_utxo_url = `${RELAYER_API_URL}/utxos/range?token=${token.name}&start=${fetch_utxo_offset}&end=${fetch_utxo_end}`;
70
- let fetched = await fetchUserUtxos({ url: fetch_utxo_url, encryptionService, storage, publicKey_ata, tokenName: token.name });
70
+ let fetch_utxo_url = `${RELAYER_API_URL}/utxos/range?token=${relayerTokenName}&start=${fetch_utxo_offset}&end=${fetch_utxo_end}`;
71
+ let fetched = await fetchUserUtxos({ url: fetch_utxo_url, encryptionService, storage, publicKey_ata, tokenName: relayerTokenName });
71
72
  let am = 0;
72
73
  const nonZeroUtxos = [];
73
74
  const nonZeroEncrypted = [];
@@ -13,9 +13,11 @@ export declare const SIGN_MESSAGE = "Privacy Money account sign in";
13
13
  export declare const LSK_FETCH_OFFSET = "fetch_offset";
14
14
  export declare const LSK_ENCRYPTED_OUTPUTS = "encrypted_outputs";
15
15
  export declare const USDC_MINT: PublicKey;
16
- declare const tokenList: readonly ["sol", "usdc", "usdt", "zec", "ore", "store", "jlusdc", "jlwsol"];
16
+ export declare const STORE_MINT: PublicKey;
17
+ export declare const LEGACY_STORE_MINT: PublicKey;
18
+ declare const tokenList: readonly ["sol", "usdc", "usdt", "zec", "ore", "store", "legacyStore", "jlusdc", "jlwsol"];
17
19
  export type TokenList = typeof tokenList[number];
18
- declare const splList: readonly ["usdc", "usdt", "zec", "ore", "store", "jlusdc", "jlwsol"];
20
+ declare const splList: readonly ["usdc", "usdt", "zec", "ore", "store", "legacyStore", "jlusdc", "jlwsol"];
19
21
  export type SplList = typeof splList[number];
20
22
  export type Token = {
21
23
  name: TokenList;
@@ -24,4 +26,8 @@ export type Token = {
24
26
  pubkey: PublicKey;
25
27
  };
26
28
  export declare const tokens: Token[];
29
+ export declare function getRelayerTokenName(tokenName: string): string;
30
+ export declare function resolveTokenName(tokenName: string): TokenList | undefined;
31
+ export declare function resolveToken(tokenName: string): Token | undefined;
32
+ export declare function normalizeRelayerTokenMap(values?: Record<string, number>): Record<string, number> | undefined;
27
33
  export {};
@@ -14,8 +14,14 @@ 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', 'store', 'jlusdc', 'jlwsol'];
18
- const splList = ['usdc', 'usdt', 'zec', 'ore', 'store', 'jlusdc', 'jlwsol'];
17
+ export const STORE_MINT = process.env.NEXT_PUBLIC_NEWSTORE_MINT ? new PublicKey(process.env.NEXT_PUBLIC_NEWSTORE_MINT) : new PublicKey('storenSbvkfzircixnaosc5CbzNZVrHJ6S3EKrS1yqR');
18
+ export const LEGACY_STORE_MINT = process.env.NEXT_PUBLIC_LEGACY_STORE_MINT
19
+ ? new PublicKey(process.env.NEXT_PUBLIC_LEGACY_STORE_MINT)
20
+ : process.env.NEXT_PUBLIC_STORE_MINT
21
+ ? new PublicKey(process.env.NEXT_PUBLIC_STORE_MINT)
22
+ : new PublicKey('sTorERYB6xAZ1SSbwpK3zoK2EEwbBrc7TZAzg1uCGiH');
23
+ const tokenList = ['sol', 'usdc', 'usdt', 'zec', 'ore', 'store', 'legacyStore', 'jlusdc', 'jlwsol'];
24
+ const splList = ['usdc', 'usdt', 'zec', 'ore', 'store', 'legacyStore', 'jlusdc', 'jlwsol'];
19
25
  export const tokens = [
20
26
  {
21
27
  name: 'sol',
@@ -49,10 +55,16 @@ export const tokens = [
49
55
  },
50
56
  {
51
57
  name: 'store',
52
- pubkey: process.env.NEXT_PUBLIC_STORE_MINT ? new PublicKey(process.env.NEXT_PUBLIC_STORE_MINT) : new PublicKey('sTorERYB6xAZ1SSbwpK3zoK2EEwbBrc7TZAzg1uCGiH'),
58
+ pubkey: STORE_MINT,
53
59
  prefix: 'store_',
54
60
  units_per_token: 1e11
55
61
  },
62
+ {
63
+ name: 'legacyStore',
64
+ pubkey: LEGACY_STORE_MINT,
65
+ prefix: 'legacyStore_',
66
+ units_per_token: 1e11
67
+ },
56
68
  {
57
69
  name: 'jlusdc',
58
70
  pubkey: process.env.NEXT_PUBLIC_JLUSDC_MINT ? new PublicKey(process.env.NEXT_PUBLIC_JLUSDC_MINT) : new PublicKey('9BEcn9aPEmhSPbPQeFGjidRiEKki46fVQDyPpSQXPA2D'),
@@ -66,3 +78,40 @@ export const tokens = [
66
78
  units_per_token: 1e9
67
79
  }
68
80
  ];
81
+ export function getRelayerTokenName(tokenName) {
82
+ if (tokenName === 'store') {
83
+ return 'newstore';
84
+ }
85
+ if (tokenName === 'legacyStore') {
86
+ return 'store';
87
+ }
88
+ return tokenName;
89
+ }
90
+ export function resolveTokenName(tokenName) {
91
+ const normalized = tokenName.trim().toLowerCase();
92
+ if (normalized === 'newstore') {
93
+ return 'store';
94
+ }
95
+ if (normalized === 'legacystore') {
96
+ return 'legacyStore';
97
+ }
98
+ return tokens.find(token => token.name.toLowerCase() === normalized)?.name;
99
+ }
100
+ export function resolveToken(tokenName) {
101
+ const resolvedName = resolveTokenName(tokenName);
102
+ return resolvedName ? tokens.find(token => token.name === resolvedName) : undefined;
103
+ }
104
+ export function normalizeRelayerTokenMap(values) {
105
+ if (!values) {
106
+ return values;
107
+ }
108
+ const normalized = { ...values };
109
+ if (values.newstore !== undefined) {
110
+ normalized.store = values.newstore;
111
+ }
112
+ if (values.store !== undefined) {
113
+ normalized.legacyStore = values.store;
114
+ }
115
+ delete normalized.newstore;
116
+ return normalized;
117
+ }
@@ -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, PROGRAM_ID, RELAYER_API_URL, tokens } from './utils/constants.js';
7
+ import { ALT_ADDRESS, FEE_RECIPIENT, FIELD_SIZE, getRelayerTokenName, PROGRAM_ID, RELAYER_API_URL, tokens } from './utils/constants.js';
8
8
  import { serializeProofAndExtData } from './utils/encryption.js';
9
9
  import { fetchMerkleProof, findCrossCheckNullifierPDAs, findNullifierPDAs, getExtDataHash, getMintAddressField, getProgramAccounts } from './utils/utils.js';
10
10
  import { getAssociatedTokenAddressSync, getMint } from '@solana/spl-token';
@@ -44,6 +44,7 @@ export async function withdrawSPL({ recipient, lightWasm, storage, publicKey, co
44
44
  if (!token) {
45
45
  throw new Error('token not found: ' + mintAddress.toString());
46
46
  }
47
+ const relayerTokenName = getRelayerTokenName(token.name);
47
48
  if (amount) {
48
49
  base_units = amount * token.units_per_token;
49
50
  }
@@ -53,7 +54,7 @@ export async function withdrawSPL({ recipient, lightWasm, storage, publicKey, co
53
54
  let mintInfo = await getMint(connection, token.pubkey);
54
55
  let units_per_token = 10 ** mintInfo.decimals;
55
56
  let withdraw_fee_rate = await getConfig('withdraw_fee_rate');
56
- if (token.name === 'store') {
57
+ if (token.name === 'legacyStore') {
57
58
  withdraw_fee_rate = 0;
58
59
  }
59
60
  let withdraw_rent_fees = await getConfig('rent_fees');
@@ -119,7 +120,7 @@ export async function withdrawSPL({ recipient, lightWasm, storage, publicKey, co
119
120
  const changeAmount = totalInputAmount.sub(new BN(base_units)).sub(new BN(fee_base_units));
120
121
  logger.debug(`Withdrawing ${base_units} lamports with ${fee_base_units} fee, ${changeAmount.toString()} as change`);
121
122
  let commitmentsToFetch = inputs.map(utxo => utxo.getCommitment());
122
- const { root, nextIndex, proofs } = await fetchMerkleProof(commitmentsToFetch, token.name);
123
+ const { root, nextIndex, proofs } = await fetchMerkleProof(commitmentsToFetch, relayerTokenName);
123
124
  // Extract path elements and indices
124
125
  const inputMerklePathElements = proofs.map(proof => proof.pathElements);
125
126
  const inputMerklePathIndices = inputs.map(utxo => utxo.index || 0);
@@ -281,7 +282,7 @@ export async function withdrawSPL({ recipient, lightWasm, storage, publicKey, co
281
282
  logger.debug(`retryTimes: ${retryTimes}`);
282
283
  await new Promise(resolve => setTimeout(resolve, itv * 1000));
283
284
  logger.info('Fetching updated onchain state...');
284
- let res = await fetch(RELAYER_API_URL + '/utxos/check/' + encryptedOutputStr + '?token=' + token.name);
285
+ let res = await fetch(RELAYER_API_URL + '/utxos/check/' + encryptedOutputStr + '?token=' + relayerTokenName);
285
286
  let resJson = await res.json();
286
287
  logger.debug('resJson:', resJson);
287
288
  if (resJson.exists) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "privacycash",
3
- "version": "1.1.24",
3
+ "version": "1.2.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "repository": "https://github.com/Privacy-Cash/privacy-cash-sdk",
@@ -12,7 +12,9 @@
12
12
  "type": "module",
13
13
  "scripts": {
14
14
  "build": "tsc",
15
- "test": "vitest run --exclude \"**/__tests__/e2e.test.ts,**/__tests__/e2espl.test.ts\"",
15
+ "postinstall": "cp node_modules/@lightprotocol/hasher.rs/dist/hasher_wasm_simd_bg.wasm node_modules/@lightprotocol/hasher.rs/dist/browser-fat/es/ && cp node_modules/@lightprotocol/hasher.rs/dist/light_wasm_hasher_bg.wasm node_modules/@lightprotocol/hasher.rs/dist/browser-fat/es/",
16
+ "prepare": "npm run build",
17
+ "test": "vitest run --exclude \"**/__tests__/e2e.test.ts\" --exclude \"**/__tests__/e2espl.test.ts\"",
16
18
  "teste2e": "vitest run e2e.test.ts",
17
19
  "teste2espl": "vitest run e2espl.test.ts"
18
20
  },
package/src/config.ts CHANGED
@@ -1,11 +1,13 @@
1
- import { RELAYER_API_URL } from "./utils/constants.js";
1
+ import { normalizeRelayerTokenMap, RELAYER_API_URL } from "./utils/constants.js";
2
2
 
3
3
  type Config = {
4
4
  withdraw_fee_rate: number
5
5
  withdraw_rent_fee: number
6
6
  deposit_fee_rate: number
7
7
  usdc_withdraw_rent_fee: number
8
- rent_fees: any
8
+ rent_fees: Record<string, number>
9
+ minimum_withdrawal: Record<string, number>
10
+ prices: Record<string, number>
9
11
  }
10
12
 
11
13
  let config: Config | undefined
@@ -13,10 +15,19 @@ let config: Config | undefined
13
15
  export async function getConfig<K extends keyof Config>(key: K): Promise<Config[K]> {
14
16
  if (!config) {
15
17
  const res = await fetch(RELAYER_API_URL + '/config')
16
- config = await res.json()
18
+ config = normalizeConfig(await res.json())
17
19
  }
18
20
  if (typeof config![key] == 'undefined') {
19
21
  throw new Error(`can not get ${key} from ${RELAYER_API_URL}/config`)
20
22
  }
21
23
  return config![key]
22
- }
24
+ }
25
+
26
+ function normalizeConfig(raw: Config): Config {
27
+ return {
28
+ ...raw,
29
+ rent_fees: normalizeRelayerTokenMap(raw.rent_fees) ?? {},
30
+ minimum_withdrawal: normalizeRelayerTokenMap(raw.minimum_withdrawal) ?? {},
31
+ prices: normalizeRelayerTokenMap(raw.prices) ?? {},
32
+ }
33
+ }
package/src/depositSPL.ts CHANGED
@@ -6,7 +6,7 @@ import { getUtxosSPL } from './getUtxosSPL.js';
6
6
  import { Keypair as UtxoKeypair } from './models/keypair.js';
7
7
  import { Utxo } from './models/utxo.js';
8
8
  import { useExistingALT } from './utils/address_lookup_table.js';
9
- import { ALT_ADDRESS, FEE_RECIPIENT, FIELD_SIZE, MERKLE_TREE_DEPTH, PROGRAM_ID, RELAYER_API_URL, Token, tokens } from './utils/constants.js';
9
+ import { ALT_ADDRESS, FEE_RECIPIENT, FIELD_SIZE, getRelayerTokenName, MERKLE_TREE_DEPTH, PROGRAM_ID, RELAYER_API_URL, Token, tokens } from './utils/constants.js';
10
10
  import { EncryptionService, serializeProofAndExtData } from './utils/encryption.js';
11
11
  import { logger } from './utils/logger.js';
12
12
  import { MerkleTree } from './utils/merkle_tree.js';
@@ -88,6 +88,10 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
88
88
  if (!token) {
89
89
  throw new Error('token not found: ' + mintAddress.toString())
90
90
  }
91
+ if (token.name === 'legacyStore') {
92
+ throw new Error('Legacy stORE deposit has been disabled. Please use the latest stORE.')
93
+ }
94
+ const relayerTokenName = getRelayerTokenName(token.name)
91
95
 
92
96
  if (amount) {
93
97
  base_units = amount * token.units_per_token
@@ -185,7 +189,7 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
185
189
  let root: string;
186
190
  let nextIndex: number;
187
191
  if (mintUtxos.length === 0) {
188
- const treeState = await queryRemoteTreeState(token.name);
192
+ const treeState = await queryRemoteTreeState(relayerTokenName);
189
193
  root = treeState.root
190
194
  nextIndex = treeState.nextIndex
191
195
  // Scenario 1: Fresh deposit with dummy inputs - add new funds to the system
@@ -264,7 +268,7 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
264
268
  await secondUtxo.log();
265
269
  }
266
270
 
267
- let data = await fetchMerkleProof(commitmentsToFetch, token.name)
271
+ let data = await fetchMerkleProof(commitmentsToFetch, relayerTokenName)
268
272
  root = data.root
269
273
  nextIndex = data.nextIndex
270
274
  let [firstUtxoMerkleProof, secondUtxoMerkleProof] = data.proofs
@@ -542,7 +546,7 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
542
546
  logger.debug(`retryTimes: ${retryTimes}`)
543
547
  await new Promise(resolve => setTimeout(resolve, itv * 1000));
544
548
  logger.debug('Fetching updated onchain state...');
545
- let url = RELAYER_API_URL + '/utxos/check/' + encryptedOutputStr + '?token=' + token.name
549
+ let url = RELAYER_API_URL + '/utxos/check/' + encryptedOutputStr + '?token=' + relayerTokenName
546
550
  let res = await fetch(url)
547
551
  let resJson = await res.json()
548
552
  if (resJson.exists) {
@@ -595,4 +599,4 @@ async function checkDepositLimit(connection: Connection, treeAccount: PublicKey,
595
599
  console.log('❌ Error reading deposit limit:', error);
596
600
  throw error
597
601
  }
598
- }
602
+ }
@@ -9,4 +9,4 @@ export { depositSPL } from './depositSPL.js'
9
9
  export { withdrawSPL } from './withdrawSPL.js'
10
10
  export { getBalanceFromUtxosSPL, getUtxosSPL } from './getUtxosSPL.js'
11
11
 
12
- export { type TokenList, type SplList, tokens } from './utils/constants.js'
12
+ export { getRelayerTokenName, LEGACY_STORE_MINT, normalizeRelayerTokenMap, STORE_MINT, type TokenList, type SplList, tokens } from './utils/constants.js'
@@ -6,7 +6,7 @@ import { EncryptionService } from './utils/encryption.js';
6
6
  import { WasmFactory } from '@lightprotocol/hasher.rs';
7
7
  //@ts-ignore
8
8
  import * as ffjavascript from 'ffjavascript';
9
- import { FETCH_UTXOS_GROUP_SIZE, RELAYER_API_URL, LSK_ENCRYPTED_OUTPUTS, LSK_FETCH_OFFSET, PROGRAM_ID, SplList, tokens } from './utils/constants.js';
9
+ import { FETCH_UTXOS_GROUP_SIZE, getRelayerTokenName, RELAYER_API_URL, LSK_ENCRYPTED_OUTPUTS, LSK_FETCH_OFFSET, PROGRAM_ID, tokens } from './utils/constants.js';
10
10
  import { logger } from './utils/logger.js';
11
11
  import { getAssociatedTokenAddress } from '@solana/spl-token';
12
12
 
@@ -77,6 +77,7 @@ export async function getUtxosSPL({ publicKey, connection, encryptionService, st
77
77
  if (!token) {
78
78
  throw new Error('token not found: ' + mintAddress.toString())
79
79
  }
80
+ const relayerTokenName = getRelayerTokenName(token.name)
80
81
 
81
82
  logger.debug('token name: ' + token.name + ', token address' + token.pubkey.toString())
82
83
 
@@ -107,8 +108,8 @@ export async function getUtxosSPL({ publicKey, connection, encryptionService, st
107
108
  }
108
109
  logger.debug(' ####fetch_utxo_offset', fetch_utxo_offset)
109
110
  let fetch_utxo_end = fetch_utxo_offset + FETCH_UTXOS_GROUP_SIZE
110
- let fetch_utxo_url = `${RELAYER_API_URL}/utxos/range?token=${token.name}&start=${fetch_utxo_offset}&end=${fetch_utxo_end}`
111
- let fetched = await fetchUserUtxos({ url: fetch_utxo_url, encryptionService, storage, publicKey_ata, tokenName: token.name })
111
+ let fetch_utxo_url = `${RELAYER_API_URL}/utxos/range?token=${relayerTokenName}&start=${fetch_utxo_offset}&end=${fetch_utxo_end}`
112
+ let fetched = await fetchUserUtxos({ url: fetch_utxo_url, encryptionService, storage, publicKey_ata, tokenName: relayerTokenName })
112
113
  let am = 0
113
114
 
114
115
  const nonZeroUtxos: Utxo[] = [];
@@ -525,4 +526,4 @@ async function decrypt_outputs(
525
526
  }
526
527
 
527
528
  return results;
528
- }
529
+ }
@@ -26,10 +26,16 @@ export const LSK_FETCH_OFFSET = 'fetch_offset'
26
26
  export const LSK_ENCRYPTED_OUTPUTS = 'encrypted_outputs'
27
27
 
28
28
  export const USDC_MINT = process.env.NEXT_PUBLIC_USDC_MINT ? new PublicKey(process.env.NEXT_PUBLIC_USDC_MINT) : new PublicKey('EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v')
29
+ export const STORE_MINT = process.env.NEXT_PUBLIC_NEWSTORE_MINT ? new PublicKey(process.env.NEXT_PUBLIC_NEWSTORE_MINT) : new PublicKey('storenSbvkfzircixnaosc5CbzNZVrHJ6S3EKrS1yqR')
30
+ export const LEGACY_STORE_MINT = process.env.NEXT_PUBLIC_LEGACY_STORE_MINT
31
+ ? new PublicKey(process.env.NEXT_PUBLIC_LEGACY_STORE_MINT)
32
+ : process.env.NEXT_PUBLIC_STORE_MINT
33
+ ? new PublicKey(process.env.NEXT_PUBLIC_STORE_MINT)
34
+ : new PublicKey('sTorERYB6xAZ1SSbwpK3zoK2EEwbBrc7TZAzg1uCGiH')
29
35
 
30
- const tokenList = ['sol', 'usdc', 'usdt', 'zec', 'ore', 'store', 'jlusdc', 'jlwsol'] as const;
36
+ const tokenList = ['sol', 'usdc', 'usdt', 'zec', 'ore', 'store', 'legacyStore', 'jlusdc', 'jlwsol'] as const;
31
37
  export type TokenList = typeof tokenList[number];
32
- const splList = ['usdc', 'usdt', 'zec', 'ore', 'store', 'jlusdc', 'jlwsol'] as const;
38
+ const splList = ['usdc', 'usdt', 'zec', 'ore', 'store', 'legacyStore', 'jlusdc', 'jlwsol'] as const;
33
39
  export type SplList = typeof splList[number];
34
40
  export type Token = {
35
41
  name: TokenList
@@ -70,10 +76,16 @@ export const tokens: Token[] = [
70
76
  },
71
77
  {
72
78
  name: 'store',
73
- pubkey: process.env.NEXT_PUBLIC_STORE_MINT ? new PublicKey(process.env.NEXT_PUBLIC_STORE_MINT) : new PublicKey('sTorERYB6xAZ1SSbwpK3zoK2EEwbBrc7TZAzg1uCGiH'),
79
+ pubkey: STORE_MINT,
74
80
  prefix: 'store_',
75
81
  units_per_token: 1e11
76
82
  },
83
+ {
84
+ name: 'legacyStore',
85
+ pubkey: LEGACY_STORE_MINT,
86
+ prefix: 'legacyStore_',
87
+ units_per_token: 1e11
88
+ },
77
89
  {
78
90
  name: 'jlusdc',
79
91
  pubkey: process.env.NEXT_PUBLIC_JLUSDC_MINT ? new PublicKey(process.env.NEXT_PUBLIC_JLUSDC_MINT) : new PublicKey('9BEcn9aPEmhSPbPQeFGjidRiEKki46fVQDyPpSQXPA2D'),
@@ -86,4 +98,45 @@ export const tokens: Token[] = [
86
98
  prefix: 'jlwsol_',
87
99
  units_per_token: 1e9
88
100
  }
89
- ]
101
+ ]
102
+
103
+ export function getRelayerTokenName(tokenName: string) {
104
+ if (tokenName === 'store') {
105
+ return 'newstore'
106
+ }
107
+ if (tokenName === 'legacyStore') {
108
+ return 'store'
109
+ }
110
+ return tokenName
111
+ }
112
+
113
+ export function resolveTokenName(tokenName: string): TokenList | undefined {
114
+ const normalized = tokenName.trim().toLowerCase()
115
+ if (normalized === 'newstore') {
116
+ return 'store'
117
+ }
118
+ if (normalized === 'legacystore') {
119
+ return 'legacyStore'
120
+ }
121
+ return tokens.find(token => token.name.toLowerCase() === normalized)?.name
122
+ }
123
+
124
+ export function resolveToken(tokenName: string): Token | undefined {
125
+ const resolvedName = resolveTokenName(tokenName)
126
+ return resolvedName ? tokens.find(token => token.name === resolvedName) : undefined
127
+ }
128
+
129
+ export function normalizeRelayerTokenMap(values?: Record<string, number>): Record<string, number> | undefined {
130
+ if (!values) {
131
+ return values
132
+ }
133
+ const normalized = { ...values }
134
+ if (values.newstore !== undefined) {
135
+ normalized.store = values.newstore
136
+ }
137
+ if (values.store !== undefined) {
138
+ normalized.legacyStore = values.store
139
+ }
140
+ delete normalized.newstore
141
+ return normalized
142
+ }
@@ -6,7 +6,7 @@ import { Keypair as UtxoKeypair } from './models/keypair.js';
6
6
  import { Utxo } from './models/utxo.js';
7
7
  import { parseProofToBytesArray, parseToBytesArray, prove } from './utils/prover.js';
8
8
 
9
- import { ALT_ADDRESS, FEE_RECIPIENT, FIELD_SIZE, PROGRAM_ID, RELAYER_API_URL, tokens } from './utils/constants.js';
9
+ import { ALT_ADDRESS, FEE_RECIPIENT, FIELD_SIZE, getRelayerTokenName, PROGRAM_ID, RELAYER_API_URL, tokens } from './utils/constants.js';
10
10
  import { EncryptionService, serializeProofAndExtData } from './utils/encryption.js';
11
11
  import { fetchMerkleProof, findCrossCheckNullifierPDAs, findNullifierPDAs, getExtDataHash, getMintAddressField, getProgramAccounts } from './utils/utils.js';
12
12
 
@@ -66,6 +66,7 @@ export async function withdrawSPL({ recipient, lightWasm, storage, publicKey, co
66
66
  if (!token) {
67
67
  throw new Error('token not found: ' + mintAddress.toString())
68
68
  }
69
+ const relayerTokenName = getRelayerTokenName(token.name)
69
70
 
70
71
  if (amount) {
71
72
  base_units = amount * token.units_per_token
@@ -80,7 +81,7 @@ export async function withdrawSPL({ recipient, lightWasm, storage, publicKey, co
80
81
  let units_per_token = 10 ** mintInfo.decimals
81
82
 
82
83
  let withdraw_fee_rate = await getConfig('withdraw_fee_rate')
83
- if (token.name === 'store') {
84
+ if (token.name === 'legacyStore') {
84
85
  withdraw_fee_rate = 0
85
86
  }
86
87
  let withdraw_rent_fees = await getConfig('rent_fees')
@@ -179,7 +180,7 @@ export async function withdrawSPL({ recipient, lightWasm, storage, publicKey, co
179
180
  logger.debug(`Withdrawing ${base_units} lamports with ${fee_base_units} fee, ${changeAmount.toString()} as change`);
180
181
 
181
182
  let commitmentsToFetch = inputs.map(utxo => utxo.getCommitment());
182
- const { root, nextIndex, proofs } = await fetchMerkleProof(commitmentsToFetch, token.name);
183
+ const { root, nextIndex, proofs } = await fetchMerkleProof(commitmentsToFetch, relayerTokenName);
183
184
 
184
185
  // Extract path elements and indices
185
186
  const inputMerklePathElements = proofs.map(proof => proof.pathElements);
@@ -368,7 +369,7 @@ export async function withdrawSPL({ recipient, lightWasm, storage, publicKey, co
368
369
  logger.debug(`retryTimes: ${retryTimes}`)
369
370
  await new Promise(resolve => setTimeout(resolve, itv * 1000));
370
371
  logger.info('Fetching updated onchain state...');
371
- let res = await fetch(RELAYER_API_URL + '/utxos/check/' + encryptedOutputStr + '?token=' + token.name)
372
+ let res = await fetch(RELAYER_API_URL + '/utxos/check/' + encryptedOutputStr + '?token=' + relayerTokenName)
372
373
  let resJson = await res.json()
373
374
  logger.debug('resJson:', resJson)
374
375
  if (resJson.exists) {