@fairblock/stabletrust 1.0.11 → 1.0.13
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/package.json +1 -1
- package/src/client.js +36 -26
package/package.json
CHANGED
package/src/client.js
CHANGED
|
@@ -74,6 +74,9 @@ export class ConfidentialTransferClient {
|
|
|
74
74
|
// WASM will be auto-initialized on first use
|
|
75
75
|
this._wasmModule = null;
|
|
76
76
|
|
|
77
|
+
// Cache for derived keys — deterministic per wallet+chain+contract, safe to reuse
|
|
78
|
+
this._keyCache = new Map();
|
|
79
|
+
|
|
77
80
|
try {
|
|
78
81
|
this.provider = new ethers.JsonRpcProvider(this.config.rpcUrl);
|
|
79
82
|
this.contract = new ethers.Contract(
|
|
@@ -118,8 +121,12 @@ export class ConfidentialTransferClient {
|
|
|
118
121
|
if (!wallet) {
|
|
119
122
|
throw new Error("Wallet is required");
|
|
120
123
|
}
|
|
124
|
+
const address = await wallet.getAddress();
|
|
125
|
+
if (this._keyCache.has(address)) {
|
|
126
|
+
return this._keyCache.get(address);
|
|
127
|
+
}
|
|
121
128
|
const wasm = await this._getWasm();
|
|
122
|
-
|
|
129
|
+
const keys = await deriveKeys(
|
|
123
130
|
wallet,
|
|
124
131
|
{
|
|
125
132
|
chainId: this.config.chainId,
|
|
@@ -127,6 +134,8 @@ export class ConfidentialTransferClient {
|
|
|
127
134
|
},
|
|
128
135
|
wasm.generate_deterministic_keypair,
|
|
129
136
|
);
|
|
137
|
+
this._keyCache.set(address, keys);
|
|
138
|
+
return keys;
|
|
130
139
|
} catch (error) {
|
|
131
140
|
throw new Error(`Failed to derive keys: ${error.message}`);
|
|
132
141
|
}
|
|
@@ -155,11 +164,11 @@ export class ConfidentialTransferClient {
|
|
|
155
164
|
* @param {ethers.Wallet|ethers.Signer} wallet - The wallet to create account for
|
|
156
165
|
* @param {Object} [options] - Options
|
|
157
166
|
* @param {boolean} [options.waitForFinalization=true] - Wait for account finalization
|
|
158
|
-
* @param {number} [options.maxAttempts=
|
|
167
|
+
* @param {number} [options.maxAttempts=225] - Max attempts to wait for finalization
|
|
159
168
|
* @returns {Promise<{publicKey: string, privateKey: string}>} The derived keys
|
|
160
169
|
*/
|
|
161
170
|
async ensureAccount(wallet, options = {}) {
|
|
162
|
-
const { waitForFinalization = true, maxAttempts =
|
|
171
|
+
const { waitForFinalization = true, maxAttempts = 225 } = options;
|
|
163
172
|
|
|
164
173
|
try {
|
|
165
174
|
const address = await wallet.getAddress();
|
|
@@ -183,7 +192,7 @@ export class ConfidentialTransferClient {
|
|
|
183
192
|
if (waitForFinalization) {
|
|
184
193
|
let attempts = 0;
|
|
185
194
|
while (!accountInfo.finalized && attempts < maxAttempts) {
|
|
186
|
-
await sleep(
|
|
195
|
+
await sleep(400);
|
|
187
196
|
accountInfo = await this.getAccountInfo(address);
|
|
188
197
|
attempts++;
|
|
189
198
|
}
|
|
@@ -354,20 +363,17 @@ export class ConfidentialTransferClient {
|
|
|
354
363
|
const depositAmount = BigInt(amount);
|
|
355
364
|
const tokenContract = this._getTokenContract(tokenAddress);
|
|
356
365
|
|
|
357
|
-
// Check token balance
|
|
358
|
-
const tokenBalance = await
|
|
366
|
+
// Check token balance and allowance in parallel
|
|
367
|
+
const [tokenBalance, allowance] = await Promise.all([
|
|
368
|
+
tokenContract.balanceOf(address),
|
|
369
|
+
tokenContract.allowance(address, this.config.contractAddress),
|
|
370
|
+
]);
|
|
359
371
|
if (tokenBalance < depositAmount) {
|
|
360
372
|
throw new Error(
|
|
361
373
|
`Insufficient token balance. Required: ${depositAmount}, Available: ${tokenBalance}`,
|
|
362
374
|
);
|
|
363
375
|
}
|
|
364
376
|
|
|
365
|
-
// Check and approve if needed
|
|
366
|
-
const allowance = await tokenContract.allowance(
|
|
367
|
-
address,
|
|
368
|
-
this.config.contractAddress,
|
|
369
|
-
);
|
|
370
|
-
|
|
371
377
|
if (allowance < depositAmount) {
|
|
372
378
|
const approveTx = await tokenContract
|
|
373
379
|
.connect(wallet)
|
|
@@ -439,14 +445,15 @@ export class ConfidentialTransferClient {
|
|
|
439
445
|
|
|
440
446
|
const senderAddress = await senderWallet.getAddress();
|
|
441
447
|
|
|
442
|
-
//
|
|
443
|
-
const derivedSenderKeys = await
|
|
448
|
+
// Derive sender keys and fetch recipient account info in parallel
|
|
449
|
+
const [derivedSenderKeys, recipientAccountInfo] = await Promise.all([
|
|
450
|
+
this._deriveKeys(senderWallet),
|
|
451
|
+
this.getAccountInfo(recipientAddress),
|
|
452
|
+
]);
|
|
444
453
|
if (!derivedSenderKeys?.privateKey) {
|
|
445
454
|
throw new Error("Failed to derive sender keys");
|
|
446
455
|
}
|
|
447
456
|
|
|
448
|
-
// Auto-derive recipient public key
|
|
449
|
-
const recipientAccountInfo = await this.getAccountInfo(recipientAddress);
|
|
450
457
|
if (!recipientAccountInfo.exists) {
|
|
451
458
|
throw new Error(
|
|
452
459
|
`Recipient account does not exist. Address: ${recipientAddress}`,
|
|
@@ -474,12 +481,14 @@ export class ConfidentialTransferClient {
|
|
|
474
481
|
"transfer",
|
|
475
482
|
);
|
|
476
483
|
|
|
477
|
-
const balanceSummary = await
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
484
|
+
const [balanceSummary, fee] = await Promise.all([
|
|
485
|
+
this.getConfidentialBalance(
|
|
486
|
+
senderAddress,
|
|
487
|
+
derivedSenderKeys.privateKey,
|
|
488
|
+
tokenAddress,
|
|
489
|
+
),
|
|
490
|
+
this.getFeeAmount(),
|
|
491
|
+
]);
|
|
483
492
|
const derivedCurrentBalanceCiphertext =
|
|
484
493
|
balanceSummary.available.ciphertext;
|
|
485
494
|
const derivedCurrentBalance = balanceSummary.available.amount;
|
|
@@ -881,7 +890,8 @@ export class ConfidentialTransferClient {
|
|
|
881
890
|
*/
|
|
882
891
|
async _waitForGlobalState(address, actionLabel) {
|
|
883
892
|
let attempts = 0;
|
|
884
|
-
const maxAttempts =
|
|
893
|
+
const maxAttempts = 450; // 450 * 200ms = 90 seconds max wait
|
|
894
|
+
await sleep(2000);
|
|
885
895
|
|
|
886
896
|
while (attempts < maxAttempts) {
|
|
887
897
|
try {
|
|
@@ -912,8 +922,8 @@ export class ConfidentialTransferClient {
|
|
|
912
922
|
* @param {string} privateKey - Private key for decryption
|
|
913
923
|
* @param {string} tokenAddress - Token address
|
|
914
924
|
* @param {Object} [options] - Options
|
|
915
|
-
* @param {number} [options.maxAttempts=
|
|
916
|
-
* @param {number} [options.intervalMs=
|
|
925
|
+
* @param {number} [options.maxAttempts=225] - Maximum polling attempts
|
|
926
|
+
* @param {number} [options.intervalMs=400] - Polling interval in milliseconds
|
|
917
927
|
* @returns {Promise<{amount: number, ciphertext: string}>}
|
|
918
928
|
*/
|
|
919
929
|
async _waitForPendingBalance(
|
|
@@ -922,7 +932,7 @@ export class ConfidentialTransferClient {
|
|
|
922
932
|
tokenAddress,
|
|
923
933
|
options = {},
|
|
924
934
|
) {
|
|
925
|
-
const { maxAttempts =
|
|
935
|
+
const { maxAttempts = 225, intervalMs = 400 } = options;
|
|
926
936
|
|
|
927
937
|
try {
|
|
928
938
|
for (let i = 0; i < maxAttempts; i++) {
|