privacycash 1.1.0 → 1.1.2
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 +5 -5
- package/dist/deposit.js +1 -1
- package/dist/depositSPL.js +18 -12
- package/dist/getUtxosSPL.js +2 -8
- package/dist/index.js +3 -3
- package/dist/utils/address_lookup_table.js +4 -3
- package/dist/utils/constants.d.ts +3 -3
- package/dist/utils/constants.js +2 -14
- package/dist/withdraw.js +3 -3
- package/dist/withdrawSPL.js +3 -3
- package/package.json +1 -1
- package/src/deposit.ts +1 -1
- package/src/depositSPL.ts +19 -15
- package/src/getUtxosSPL.ts +3 -8
- package/src/index.ts +3 -3
- package/src/utils/address_lookup_table.ts +4 -3
- package/src/utils/constants.ts +3 -16
- package/src/withdraw.ts +3 -3
- package/src/withdrawSPL.ts +3 -3
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
|
-
|
|
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
|
-
|
|
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');
|
package/dist/depositSPL.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
-
|
|
86
|
-
|
|
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`);
|
package/dist/getUtxosSPL.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
10
|
+
logger.debug(`Using existing ALT: ${altAddress.toString()}`);
|
|
10
11
|
const altAccount = await connection.getAddressLookupTable(altAddress);
|
|
11
12
|
if (altAccount.value) {
|
|
12
|
-
|
|
13
|
+
logger.debug(`✅ ALT found with ${altAccount.value.state.addresses.length} addresses`);
|
|
13
14
|
}
|
|
14
15
|
else {
|
|
15
|
-
|
|
16
|
+
logger.error('❌ ALT not found');
|
|
16
17
|
}
|
|
17
18
|
return altAccount;
|
|
18
19
|
}
|
|
@@ -13,12 +13,12 @@ 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"
|
|
16
|
+
declare const tokenList: readonly ["sol", "usdc", "usdt"];
|
|
17
17
|
export type TokenList = typeof tokenList[number];
|
|
18
|
-
declare const splList: readonly ["usdc", "usdt"
|
|
18
|
+
declare const splList: readonly ["usdc", "usdt"];
|
|
19
19
|
export type SplList = typeof splList[number];
|
|
20
20
|
export type Token = {
|
|
21
|
-
name:
|
|
21
|
+
name: TokenList;
|
|
22
22
|
prefix: string;
|
|
23
23
|
units_per_token: number;
|
|
24
24
|
pubkey: PublicKey;
|
package/dist/utils/constants.js
CHANGED
|
@@ -14,8 +14,8 @@ 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'
|
|
18
|
-
const splList = ['usdc', 'usdt'
|
|
17
|
+
const tokenList = ['sol', 'usdc', 'usdt'];
|
|
18
|
+
const splList = ['usdc', 'usdt'];
|
|
19
19
|
export const tokens = [
|
|
20
20
|
{
|
|
21
21
|
name: 'sol',
|
|
@@ -34,17 +34,5 @@ export const tokens = [
|
|
|
34
34
|
pubkey: process.env.NEXT_PUBLIC_USDT_MINT ? new PublicKey(process.env.NEXT_PUBLIC_USDT_MINT) : new PublicKey('Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB'),
|
|
35
35
|
prefix: 'usdt_',
|
|
36
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
37
|
}
|
|
50
38
|
];
|
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
|
-
|
|
256
|
+
logger.info(`retryTimes: ${retryTimes}`);
|
|
257
257
|
await new Promise(resolve => setTimeout(resolve, itv * 1000));
|
|
258
|
-
|
|
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
|
-
|
|
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
|
}
|
package/dist/withdrawSPL.js
CHANGED
|
@@ -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
|
-
|
|
292
|
+
logger.info(`retryTimes: ${retryTimes}`);
|
|
293
293
|
await new Promise(resolve => setTimeout(resolve, itv * 1000));
|
|
294
|
-
|
|
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
|
-
|
|
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
package/src/deposit.ts
CHANGED
|
@@ -456,7 +456,7 @@ async function checkDepositLimit(connection: Connection) {
|
|
|
456
456
|
return;
|
|
457
457
|
}
|
|
458
458
|
|
|
459
|
-
|
|
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
|
-
|
|
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
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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
|
-
|
|
138
|
-
|
|
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`);
|
package/src/getUtxosSPL.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
166
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
26
|
+
logger.debug(`Using existing ALT: ${altAddress.toString()}`);
|
|
26
27
|
const altAccount = await connection.getAddressLookupTable(altAddress);
|
|
27
28
|
|
|
28
29
|
if (altAccount.value) {
|
|
29
|
-
|
|
30
|
+
logger.debug(`✅ ALT found with ${altAccount.value.state.addresses.length} addresses`);
|
|
30
31
|
} else {
|
|
31
|
-
|
|
32
|
+
logger.error('❌ ALT not found');
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
return altAccount;
|
package/src/utils/constants.ts
CHANGED
|
@@ -27,12 +27,12 @@ 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
29
|
|
|
30
|
-
const tokenList = ['sol', 'usdc', 'usdt'
|
|
30
|
+
const tokenList = ['sol', 'usdc', 'usdt'] as const;
|
|
31
31
|
export type TokenList = typeof tokenList[number];
|
|
32
|
-
const splList = ['usdc', 'usdt'
|
|
32
|
+
const splList = ['usdc', 'usdt'] as const;
|
|
33
33
|
export type SplList = typeof splList[number];
|
|
34
34
|
export type Token = {
|
|
35
|
-
name:
|
|
35
|
+
name: TokenList
|
|
36
36
|
prefix: string
|
|
37
37
|
units_per_token: number
|
|
38
38
|
pubkey: PublicKey
|
|
@@ -55,18 +55,5 @@ export const tokens: Token[] = [
|
|
|
55
55
|
pubkey: process.env.NEXT_PUBLIC_USDT_MINT ? new PublicKey(process.env.NEXT_PUBLIC_USDT_MINT) : new PublicKey('Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB'),
|
|
56
56
|
prefix: 'usdt_',
|
|
57
57
|
units_per_token: 1e6
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
name: 'zec',
|
|
61
|
-
pubkey: process.env.NEXT_PUBLIC_ZEC_MINT ? new PublicKey(process.env.NEXT_PUBLIC_ZEC_MINT) : new PublicKey('A7bdiYdS5GjqGFtxf17ppRHtDKPkkRqbKtR27dxvQXaS'),
|
|
62
|
-
prefix: 'zec_',
|
|
63
|
-
units_per_token: 1e8
|
|
64
|
-
}
|
|
65
|
-
,
|
|
66
|
-
{
|
|
67
|
-
name: 'ore',
|
|
68
|
-
pubkey: process.env.NEXT_PUBLIC_ORE_MINT ? new PublicKey(process.env.NEXT_PUBLIC_ORE_MINT) : new PublicKey('oreoU2P8bN6jkk3jbaiVxYnG1dCXcYxwhwyK9jSybcp'),
|
|
69
|
-
prefix: 'ore_',
|
|
70
|
-
units_per_token: 1e11
|
|
71
58
|
}
|
|
72
59
|
]
|
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
|
-
|
|
317
|
+
logger.info(`retryTimes: ${retryTimes}`)
|
|
318
318
|
await new Promise(resolve => setTimeout(resolve, itv * 1000));
|
|
319
|
-
|
|
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
|
-
|
|
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
|
}
|
package/src/withdrawSPL.ts
CHANGED
|
@@ -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
|
-
|
|
382
|
+
logger.info(`retryTimes: ${retryTimes}`)
|
|
383
383
|
await new Promise(resolve => setTimeout(resolve, itv * 1000));
|
|
384
|
-
|
|
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
|
-
|
|
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
|
}
|