privacycash 1.1.0 → 1.1.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.
package/README.md CHANGED
@@ -9,11 +9,11 @@ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR I
9
9
  ### Usage
10
10
  This SDK provides APIs for developers to interact with Privacy Cash relayers easily. Developers can easily deposit/withdraw/query balances in Privacy Cash solana program.
11
11
 
12
- Main APIs for this SDK are:
13
- a. for SOL:
14
- deposit(), withdraw(), getPrivateBalance()
15
- b. for USDC:
16
- depositUSDC(), withdrawUSDC(), getPrivateBalanceUSDC()
12
+ Main APIs for this SDK are:
13
+ a. for SOL:
14
+ deposit(), withdraw(), getPrivateBalance()
15
+ b. for SPL (currently supporting USDC and USDT):
16
+ depositSPL(), withdrawSPL(), getPrivateBalanceSpl()
17
17
 
18
18
  Check the example project under /example folder. The code should be fairly self-explanatory.
19
19
 
package/dist/deposit.js CHANGED
@@ -363,7 +363,7 @@ async function checkDepositLimit(connection) {
363
363
  console.error('❌ Tree account not found. Make sure the program is initialized.' + PROGRAM_ID);
364
364
  return;
365
365
  }
366
- console.log(`Account data size: ${accountInfo.data.length} bytes`);
366
+ logger.debug(`Account data size: ${accountInfo.data.length} bytes`);
367
367
  const authority = new PublicKey(accountInfo.data.slice(8, 40));
368
368
  const nextIndex = new BN(accountInfo.data.slice(40, 48), 'le');
369
369
  const rootIndex = new BN(accountInfo.data.slice(4112, 4120), 'le');
@@ -31,18 +31,25 @@ async function relayDepositToIndexer({ signedTransaction, publicKey, referrer, m
31
31
  body: JSON.stringify(params)
32
32
  });
33
33
  if (!response.ok) {
34
- console.log('res text:', await response.json());
34
+ logger.debug('res text:', await response.text());
35
35
  throw new Error('response not ok');
36
36
  // const errorData = await response.json() as { error?: string };
37
37
  // throw new Error(`Deposit relay failed: ${response.status} ${response.statusText} - ${errorData.error || 'Unknown error'}`);
38
38
  }
39
- const result = await response.json();
40
- logger.debug('Pre-signed deposit transaction relayed successfully!');
41
- logger.debug('Response:', result);
39
+ let result;
40
+ try {
41
+ result = await response.json();
42
+ logger.debug('Pre-signed deposit transaction relayed successfully!');
43
+ logger.debug('Response:', result);
44
+ }
45
+ catch (e) {
46
+ console.log('response.text', await response.text());
47
+ throw new Error('failed to parse json');
48
+ }
42
49
  return result.signature;
43
50
  }
44
51
  catch (error) {
45
- console.error('Failed to relay deposit transaction to indexer:', error);
52
+ console.error('Failed to relay deposit transaction to indexer:', error.message);
46
53
  throw error;
47
54
  }
48
55
  }
@@ -82,8 +89,8 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
82
89
  const accountInfo = await getAccount(connection, signerTokenAccount);
83
90
  let balance = Number(accountInfo.amount);
84
91
  logger.debug(`wallet balance: ${balance / token.units_per_token} ${token.name.toUpperCase()}`);
85
- console.log('balance', balance);
86
- console.log('base_units + fee_base_units', base_units + fee_base_units);
92
+ logger.debug('balance', balance);
93
+ logger.debug('base_units + fee_base_units', base_units + fee_base_units);
87
94
  if (balance < (base_units + fee_base_units)) {
88
95
  throw new Error(`Insufficient balance. Need at least ${(base_units + fee_base_units) / token.units_per_token} ${token.name.toUpperCase()}.`);
89
96
  }
@@ -161,7 +168,6 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
161
168
  logger.debug(`Output amount (existing UTXOs + deposit - fee): ${outputAmount}`);
162
169
  logger.debug(`External amount (deposit): ${extAmount}`);
163
170
  logger.debug('\nFirst UTXO to be consolidated:');
164
- await firstUtxo.log();
165
171
  // Use first existing UTXO as first input, and either second UTXO or dummy UTXO as second input
166
172
  const secondUtxo = mintUtxos.length > 1 ? mintUtxos[1] : new Utxo({
167
173
  lightWasm,
@@ -240,10 +246,10 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
240
246
  logger.debug('\nEncrypting UTXOs with keypair data...');
241
247
  const encryptedOutput1 = encryptionService.encryptUtxo(outputs[0]);
242
248
  const encryptedOutput2 = encryptionService.encryptUtxo(outputs[1]);
243
- logger.debug(`\nOutput[0] (with value):`);
244
- await outputs[0].log();
245
- logger.debug(`\nOutput[1] (empty):`);
246
- await outputs[1].log();
249
+ // logger.debug(`\nOutput[0] (with value):`);
250
+ // await outputs[0].log();
251
+ // logger.debug(`\nOutput[1] (empty):`);
252
+ // await outputs[1].log();
247
253
  logger.debug(`\nEncrypted output 1 size: ${encryptedOutput1.length} bytes`);
248
254
  logger.debug(`Encrypted output 2 size: ${encryptedOutput2.length} bytes`);
249
255
  logger.debug(`Total encrypted outputs size: ${encryptedOutput1.length + encryptedOutput2.length} bytes`);
@@ -64,7 +64,7 @@ export async function getUtxosSPL({ publicKey, connection, encryptionService, st
64
64
  if (offset) {
65
65
  fetch_utxo_offset = Math.max(offset, fetch_utxo_offset);
66
66
  }
67
- console.log(' ####fetch_utxo_offset', fetch_utxo_offset);
67
+ logger.debug(' ####fetch_utxo_offset', fetch_utxo_offset);
68
68
  let fetch_utxo_end = fetch_utxo_offset + FETCH_UTXOS_GROUP_SIZE;
69
69
  let fetch_utxo_url = `${RELAYER_API_URL}/utxos/range?token=${token.name}&start=${fetch_utxo_offset}&end=${fetch_utxo_end}`;
70
70
  let fetched = await fetchUserUtxos({ url: fetch_utxo_url, encryptionService, storage, publicKey_ata, tokenName: token.name });
@@ -122,13 +122,7 @@ export async function getUtxosSPL({ publicKey, connection, encryptionService, st
122
122
  valid_strings = [...new Set(valid_strings)];
123
123
  logger.debug(`valid_strings len after set: ${valid_strings.length}`);
124
124
  storage.setItem(LSK_ENCRYPTED_OUTPUTS + localstorageKey(publicKey_ata), JSON.stringify(valid_strings));
125
- // reorgnize
126
- if (valid_utxos.length) {
127
- console.log('filter mint', valid_utxos[0].mintAddress, token.pubkey.toString());
128
- }
129
- let filtered_utxos = valid_utxos.filter(u => u.mintAddress == token.pubkey.toString());
130
- console.log('filtered_utxos.len', filtered_utxos.length);
131
- return filtered_utxos;
125
+ return valid_utxos.filter(u => u.mintAddress == token.pubkey.toString());
132
126
  }
133
127
  async function fetchUserUtxos({ url, storage, encryptionService, publicKey_ata, tokenName }) {
134
128
  const lightWasm = await WasmFactory.getInstance();
package/dist/index.js CHANGED
@@ -138,7 +138,7 @@ export class PrivacyCash {
138
138
  keyBasePath: path.join(import.meta.dirname, '..', 'circuit2', 'transaction2'),
139
139
  storage
140
140
  });
141
- console.log(`Withdraw successful. Recipient ${recipient} received ${res.amount_in_lamports / LAMPORTS_PER_SOL} SOL, with ${res.fee_in_lamports / LAMPORTS_PER_SOL} SOL relayers fees`);
141
+ logger.debug(`Withdraw successful. Recipient ${recipient} received ${res.amount_in_lamports / LAMPORTS_PER_SOL} SOL, with ${res.fee_in_lamports / LAMPORTS_PER_SOL} SOL relayers fees`);
142
142
  this.isRuning = false;
143
143
  return res;
144
144
  }
@@ -163,7 +163,7 @@ export class PrivacyCash {
163
163
  keyBasePath: path.join(import.meta.dirname, '..', 'circuit2', 'transaction2'),
164
164
  storage
165
165
  });
166
- console.log(`Withdraw successful. Recipient ${recipient} received ${base_units} USDC units`);
166
+ logger.debug(`Withdraw successful. Recipient ${recipient} received ${base_units} USDC units`);
167
167
  this.isRuning = false;
168
168
  return res;
169
169
  }
@@ -265,7 +265,7 @@ export class PrivacyCash {
265
265
  storage,
266
266
  mintAddress
267
267
  });
268
- console.log(`Withdraw successful. Recipient ${recipient} received ${base_units} USDC units`);
268
+ logger.debug(`Withdraw successful. Recipient ${recipient} received ${base_units} USDC units`);
269
269
  this.isRuning = false;
270
270
  return res;
271
271
  }
@@ -1,18 +1,19 @@
1
1
  import { PublicKey, SystemProgram, ComputeBudgetProgram } from '@solana/web3.js';
2
2
  import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from '@solana/spl-token';
3
+ import { logger } from './logger';
3
4
  /**
4
5
  * Helper function to use an existing ALT (recommended for production)
5
6
  * Use create_alt.ts to create the ALT once, then hardcode the address and use this function
6
7
  */
7
8
  export async function useExistingALT(connection, altAddress) {
8
9
  try {
9
- console.log(`Using existing ALT: ${altAddress.toString()}`);
10
+ logger.debug(`Using existing ALT: ${altAddress.toString()}`);
10
11
  const altAccount = await connection.getAddressLookupTable(altAddress);
11
12
  if (altAccount.value) {
12
- console.log(`✅ ALT found with ${altAccount.value.state.addresses.length} addresses`);
13
+ logger.debug(`✅ ALT found with ${altAccount.value.state.addresses.length} addresses`);
13
14
  }
14
15
  else {
15
- console.log('❌ ALT not found');
16
+ logger.error('❌ ALT not found');
16
17
  }
17
18
  return altAccount;
18
19
  }
package/dist/withdraw.js CHANGED
@@ -253,12 +253,12 @@ export async function withdraw({ recipient, lightWasm, storage, publicKey, conne
253
253
  const encryptedOutputStr = Buffer.from(encryptedOutput1).toString('hex');
254
254
  let start = Date.now();
255
255
  while (true) {
256
- console.log(`retryTimes: ${retryTimes}`);
256
+ logger.info(`retryTimes: ${retryTimes}`);
257
257
  await new Promise(resolve => setTimeout(resolve, itv * 1000));
258
- console.log('Fetching updated tree state...');
258
+ logger.info('Fetching updated tree state...');
259
259
  let res = await fetch(RELAYER_API_URL + '/utxos/check/' + encryptedOutputStr);
260
260
  let resJson = await res.json();
261
- console.log('resJson:', resJson);
261
+ logger.debug('resJson:', resJson);
262
262
  if (resJson.exists) {
263
263
  return { isPartial, tx: signature, recipient: recipient.toString(), amount_in_lamports, fee_in_lamports };
264
264
  }
@@ -289,12 +289,12 @@ export async function withdrawSPL({ recipient, lightWasm, storage, publicKey, co
289
289
  const encryptedOutputStr = Buffer.from(encryptedOutput1).toString('hex');
290
290
  let start = Date.now();
291
291
  while (true) {
292
- console.log(`retryTimes: ${retryTimes}`);
292
+ logger.info(`retryTimes: ${retryTimes}`);
293
293
  await new Promise(resolve => setTimeout(resolve, itv * 1000));
294
- console.log('Fetching updated tree state...');
294
+ logger.info('Fetching updated tree state...');
295
295
  let res = await fetch(RELAYER_API_URL + '/utxos/check/' + encryptedOutputStr + '?token=' + token.name);
296
296
  let resJson = await res.json();
297
- console.log('resJson:', resJson);
297
+ logger.debug('resJson:', resJson);
298
298
  if (resJson.exists) {
299
299
  return { isPartial, tx: signature, recipient: recipient.toString(), base_units, fee_base_units };
300
300
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "privacycash",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "repository": "https://github.com/Privacy-Cash/privacy-cash-sdk",
package/src/deposit.ts CHANGED
@@ -456,7 +456,7 @@ async function checkDepositLimit(connection: Connection) {
456
456
  return;
457
457
  }
458
458
 
459
- console.log(`Account data size: ${accountInfo.data.length} bytes`);
459
+ logger.debug(`Account data size: ${accountInfo.data.length} bytes`);
460
460
  const authority = new PublicKey(accountInfo.data.slice(8, 40));
461
461
  const nextIndex = new BN(accountInfo.data.slice(40, 48), 'le');
462
462
  const rootIndex = new BN(accountInfo.data.slice(4112, 4120), 'le');
package/src/depositSPL.ts CHANGED
@@ -45,19 +45,23 @@ async function relayDepositToIndexer({ signedTransaction, publicKey, referrer, m
45
45
  });
46
46
 
47
47
  if (!response.ok) {
48
- console.log('res text:', await response.json())
48
+ logger.debug('res text:', await response.text())
49
49
  throw new Error('response not ok')
50
50
  // const errorData = await response.json() as { error?: string };
51
51
  // throw new Error(`Deposit relay failed: ${response.status} ${response.statusText} - ${errorData.error || 'Unknown error'}`);
52
52
  }
53
-
54
- const result = await response.json() as { signature: string, success: boolean };
55
- logger.debug('Pre-signed deposit transaction relayed successfully!');
56
- logger.debug('Response:', result);
57
-
53
+ let result: { signature: string, success: boolean }
54
+ try {
55
+ result = await response.json()
56
+ logger.debug('Pre-signed deposit transaction relayed successfully!');
57
+ logger.debug('Response:', result);
58
+ } catch (e) {
59
+ console.log('response.text', await response.text())
60
+ throw new Error('failed to parse json')
61
+ }
58
62
  return result.signature;
59
- } catch (error) {
60
- console.error('Failed to relay deposit transaction to indexer:', error);
63
+ } catch (error: any) {
64
+ console.error('Failed to relay deposit transaction to indexer:', error.message);
61
65
  throw error;
62
66
  }
63
67
  }
@@ -134,8 +138,8 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
134
138
  const accountInfo = await getAccount(connection, signerTokenAccount)
135
139
  let balance = Number(accountInfo.amount)
136
140
  logger.debug(`wallet balance: ${balance / token.units_per_token} ${token.name.toUpperCase()}`);
137
- console.log('balance', balance)
138
- console.log('base_units + fee_base_units', base_units + fee_base_units)
141
+ logger.debug('balance', balance)
142
+ logger.debug('base_units + fee_base_units', base_units + fee_base_units)
139
143
 
140
144
  if (balance < (base_units + fee_base_units)) {
141
145
  throw new Error(`Insufficient balance. Need at least ${(base_units + fee_base_units) / token.units_per_token} ${token.name.toUpperCase()}.`);
@@ -171,6 +175,7 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
171
175
  // Fetch existing UTXOs for this user
172
176
  logger.debug('\nFetching existing UTXOs...');
173
177
  const mintUtxos = await getUtxosSPL({ connection, publicKey, encryptionService, storage, mintAddress });
178
+
174
179
  // Calculate output amounts and external amount based on scenario
175
180
  let extAmount: number;
176
181
  let outputAmount: string;
@@ -230,7 +235,6 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
230
235
  logger.debug(`External amount (deposit): ${extAmount}`);
231
236
 
232
237
  logger.debug('\nFirst UTXO to be consolidated:');
233
- await firstUtxo.log();
234
238
 
235
239
  // Use first existing UTXO as first input, and either second UTXO or dummy UTXO as second input
236
240
  const secondUtxo = mintUtxos.length > 1 ? mintUtxos[1] : new Utxo({
@@ -324,10 +328,10 @@ export async function depositSPL({ lightWasm, storage, keyBasePath, publicKey, c
324
328
  const encryptedOutput1 = encryptionService.encryptUtxo(outputs[0]);
325
329
  const encryptedOutput2 = encryptionService.encryptUtxo(outputs[1]);
326
330
 
327
- logger.debug(`\nOutput[0] (with value):`);
328
- await outputs[0].log();
329
- logger.debug(`\nOutput[1] (empty):`);
330
- await outputs[1].log();
331
+ // logger.debug(`\nOutput[0] (with value):`);
332
+ // await outputs[0].log();
333
+ // logger.debug(`\nOutput[1] (empty):`);
334
+ // await outputs[1].log();
331
335
 
332
336
  logger.debug(`\nEncrypted output 1 size: ${encryptedOutput1.length} bytes`);
333
337
  logger.debug(`Encrypted output 2 size: ${encryptedOutput2.length} bytes`);
@@ -105,7 +105,7 @@ export async function getUtxosSPL({ publicKey, connection, encryptionService, st
105
105
  if (offset) {
106
106
  fetch_utxo_offset = Math.max(offset, fetch_utxo_offset)
107
107
  }
108
- console.log(' ####fetch_utxo_offset', fetch_utxo_offset)
108
+ logger.debug(' ####fetch_utxo_offset', fetch_utxo_offset)
109
109
  let fetch_utxo_end = fetch_utxo_offset + FETCH_UTXOS_GROUP_SIZE
110
110
  let fetch_utxo_url = `${RELAYER_API_URL}/utxos/range?token=${token.name}&start=${fetch_utxo_offset}&end=${fetch_utxo_end}`
111
111
  let fetched = await fetchUserUtxos({ url: fetch_utxo_url, encryptionService, storage, publicKey_ata, tokenName: token.name })
@@ -162,13 +162,8 @@ export async function getUtxosSPL({ publicKey, connection, encryptionService, st
162
162
  valid_strings = [...new Set(valid_strings)];
163
163
  logger.debug(`valid_strings len after set: ${valid_strings.length}`)
164
164
  storage.setItem(LSK_ENCRYPTED_OUTPUTS + localstorageKey(publicKey_ata), JSON.stringify(valid_strings))
165
- // reorgnize
166
- if (valid_utxos.length) {
167
- console.log('filter mint', valid_utxos[0].mintAddress, token.pubkey.toString())
168
- }
169
- let filtered_utxos = valid_utxos.filter(u => u.mintAddress == token.pubkey.toString())
170
- console.log('filtered_utxos.len', filtered_utxos.length)
171
- return filtered_utxos
165
+ return valid_utxos.filter(u => u.mintAddress == token.pubkey.toString())
166
+
172
167
  }
173
168
 
174
169
  async function fetchUserUtxos({ url, storage, encryptionService, publicKey_ata, tokenName }: {
package/src/index.ts CHANGED
@@ -159,7 +159,7 @@ export class PrivacyCash {
159
159
  keyBasePath: path.join(import.meta.dirname, '..', 'circuit2', 'transaction2'),
160
160
  storage
161
161
  })
162
- console.log(`Withdraw successful. Recipient ${recipient} received ${res.amount_in_lamports / LAMPORTS_PER_SOL} SOL, with ${res.fee_in_lamports / LAMPORTS_PER_SOL} SOL relayers fees`)
162
+ logger.debug(`Withdraw successful. Recipient ${recipient} received ${res.amount_in_lamports / LAMPORTS_PER_SOL} SOL, with ${res.fee_in_lamports / LAMPORTS_PER_SOL} SOL relayers fees`)
163
163
  this.isRuning = false
164
164
  return res
165
165
  }
@@ -188,7 +188,7 @@ export class PrivacyCash {
188
188
  keyBasePath: path.join(import.meta.dirname, '..', 'circuit2', 'transaction2'),
189
189
  storage
190
190
  })
191
- console.log(`Withdraw successful. Recipient ${recipient} received ${base_units} USDC units`)
191
+ logger.debug(`Withdraw successful. Recipient ${recipient} received ${base_units} USDC units`)
192
192
  this.isRuning = false
193
193
  return res
194
194
  }
@@ -307,7 +307,7 @@ export class PrivacyCash {
307
307
  storage,
308
308
  mintAddress
309
309
  })
310
- console.log(`Withdraw successful. Recipient ${recipient} received ${base_units} USDC units`)
310
+ logger.debug(`Withdraw successful. Recipient ${recipient} received ${base_units} USDC units`)
311
311
  this.isRuning = false
312
312
  return res
313
313
  }
@@ -11,6 +11,7 @@ import {
11
11
  TransactionMessage
12
12
  } from '@solana/web3.js';
13
13
  import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from '@solana/spl-token';
14
+ import { logger } from './logger';
14
15
 
15
16
 
16
17
  /**
@@ -22,13 +23,13 @@ export async function useExistingALT(
22
23
  altAddress: PublicKey
23
24
  ): Promise<{ value: any } | null> {
24
25
  try {
25
- console.log(`Using existing ALT: ${altAddress.toString()}`);
26
+ logger.debug(`Using existing ALT: ${altAddress.toString()}`);
26
27
  const altAccount = await connection.getAddressLookupTable(altAddress);
27
28
 
28
29
  if (altAccount.value) {
29
- console.log(`✅ ALT found with ${altAccount.value.state.addresses.length} addresses`);
30
+ logger.debug(`✅ ALT found with ${altAccount.value.state.addresses.length} addresses`);
30
31
  } else {
31
- console.log('❌ ALT not found');
32
+ logger.error('❌ ALT not found');
32
33
  }
33
34
 
34
35
  return altAccount;
package/src/withdraw.ts CHANGED
@@ -314,12 +314,12 @@ export async function withdraw({ recipient, lightWasm, storage, publicKey, conne
314
314
  const encryptedOutputStr = Buffer.from(encryptedOutput1).toString('hex')
315
315
  let start = Date.now()
316
316
  while (true) {
317
- console.log(`retryTimes: ${retryTimes}`)
317
+ logger.info(`retryTimes: ${retryTimes}`)
318
318
  await new Promise(resolve => setTimeout(resolve, itv * 1000));
319
- console.log('Fetching updated tree state...');
319
+ logger.info('Fetching updated tree state...');
320
320
  let res = await fetch(RELAYER_API_URL + '/utxos/check/' + encryptedOutputStr)
321
321
  let resJson = await res.json()
322
- console.log('resJson:', resJson)
322
+ logger.debug('resJson:', resJson)
323
323
  if (resJson.exists) {
324
324
  return { isPartial, tx: signature, recipient: recipient.toString(), amount_in_lamports, fee_in_lamports }
325
325
  }
@@ -379,12 +379,12 @@ export async function withdrawSPL({ recipient, lightWasm, storage, publicKey, co
379
379
  const encryptedOutputStr = Buffer.from(encryptedOutput1).toString('hex')
380
380
  let start = Date.now()
381
381
  while (true) {
382
- console.log(`retryTimes: ${retryTimes}`)
382
+ logger.info(`retryTimes: ${retryTimes}`)
383
383
  await new Promise(resolve => setTimeout(resolve, itv * 1000));
384
- console.log('Fetching updated tree state...');
384
+ logger.info('Fetching updated tree state...');
385
385
  let res = await fetch(RELAYER_API_URL + '/utxos/check/' + encryptedOutputStr + '?token=' + token.name)
386
386
  let resJson = await res.json()
387
- console.log('resJson:', resJson)
387
+ logger.debug('resJson:', resJson)
388
388
  if (resJson.exists) {
389
389
  return { isPartial, tx: signature, recipient: recipient.toString(), base_units, fee_base_units }
390
390
  }