@glowlabs-org/utils 0.2.140 → 0.2.142
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/dist/cjs/browser.d.ts +1 -0
- package/dist/cjs/browser.js +5 -1
- package/dist/cjs/browser.js.map +1 -1
- package/dist/cjs/{farms-router-Darq9ZsF.js → farms-router-CCva--xp.js} +205 -60
- package/dist/cjs/farms-router-CCva--xp.js.map +1 -0
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/lib/types/index.d.ts +2 -1
- package/dist/cjs/utils/transaction-utils.d.ts +23 -0
- package/dist/esm/browser.d.ts +1 -0
- package/dist/esm/browser.js +2 -2
- package/dist/esm/{farms-router-B5g58fsT.js → farms-router-Cxbn5Hap.js} +202 -61
- package/dist/esm/farms-router-Cxbn5Hap.js.map +1 -0
- package/dist/esm/index.js +2 -2
- package/dist/esm/lib/types/index.d.ts +2 -1
- package/dist/esm/utils/transaction-utils.d.ts +23 -0
- package/package.json +1 -1
- package/src/browser.ts +1 -0
- package/src/lib/hooks/use-forwarder.ts +8 -30
- package/src/lib/hooks/use-offchain-fractions.ts +12 -49
- package/src/lib/types/index.ts +2 -1
- package/src/utils/transaction-utils.ts +285 -0
- package/dist/cjs/farms-router-Darq9ZsF.js.map +0 -1
- package/dist/esm/farms-router-B5g58fsT.js.map +0 -1
|
@@ -303,15 +303,27 @@ const DECIMALS_BY_TOKEN = {
|
|
|
303
303
|
GLW: 18,
|
|
304
304
|
};
|
|
305
305
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
306
|
+
// Error parsing utilities
|
|
307
|
+
function parseViemError(error) {
|
|
308
|
+
if (!error)
|
|
309
|
+
return "Unknown error";
|
|
310
|
+
// Check if it's a viem BaseError
|
|
311
|
+
if (error instanceof Error) {
|
|
312
|
+
// For contract revert errors
|
|
313
|
+
if (error.cause?.reason) {
|
|
314
|
+
return error.cause.reason;
|
|
315
|
+
}
|
|
316
|
+
// For viem's shortMessage
|
|
317
|
+
if (error.shortMessage) {
|
|
318
|
+
return error.shortMessage;
|
|
319
|
+
}
|
|
320
|
+
// Fallback to regular message
|
|
321
|
+
if (error.message) {
|
|
322
|
+
return error.message;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
return "Unknown error";
|
|
326
|
+
}
|
|
315
327
|
function parseEthersError(error) {
|
|
316
328
|
if (!error)
|
|
317
329
|
return "Unknown error";
|
|
@@ -336,8 +348,174 @@ function parseEthersError(error) {
|
|
|
336
348
|
return possibleError.reason;
|
|
337
349
|
if (possibleError?.message)
|
|
338
350
|
return possibleError.message;
|
|
339
|
-
return
|
|
351
|
+
return "Unknown error";
|
|
352
|
+
}
|
|
353
|
+
const DEFAULT_OPTIONS = {
|
|
354
|
+
maxRetries: 3,
|
|
355
|
+
timeoutMs: 60000,
|
|
356
|
+
enableLogging: true,
|
|
357
|
+
};
|
|
358
|
+
/**
|
|
359
|
+
* Enhanced transaction receipt handler with retry logic for viem
|
|
360
|
+
* @param publicClient The viem public client
|
|
361
|
+
* @param hash The transaction hash
|
|
362
|
+
* @param options Retry configuration options
|
|
363
|
+
*/
|
|
364
|
+
async function waitForViemTransactionWithRetry(publicClient, hash, options = {}) {
|
|
365
|
+
const { maxRetries, timeoutMs, enableLogging } = {
|
|
366
|
+
...DEFAULT_OPTIONS,
|
|
367
|
+
...options,
|
|
368
|
+
};
|
|
369
|
+
let lastError = null;
|
|
370
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
371
|
+
try {
|
|
372
|
+
// Wait for transaction receipt with timeout
|
|
373
|
+
const receipt = await publicClient.waitForTransactionReceipt({
|
|
374
|
+
hash,
|
|
375
|
+
timeout: timeoutMs,
|
|
376
|
+
});
|
|
377
|
+
// Check transaction status
|
|
378
|
+
if (receipt.status === "reverted") {
|
|
379
|
+
throw new Error(`Transaction ${hash} was reverted on-chain`);
|
|
380
|
+
}
|
|
381
|
+
if (enableLogging) {
|
|
382
|
+
console.log(`Transaction ${hash} confirmed successfully in block ${receipt.blockNumber}`);
|
|
383
|
+
}
|
|
384
|
+
return; // Success, exit the function
|
|
385
|
+
}
|
|
386
|
+
catch (error) {
|
|
387
|
+
lastError = error;
|
|
388
|
+
// Check if it's a timeout or not found error
|
|
389
|
+
const errorMessage = parseViemError(error);
|
|
390
|
+
const isRetryableError = errorMessage.includes("could not be found") ||
|
|
391
|
+
errorMessage.includes("timeout") ||
|
|
392
|
+
errorMessage.includes("timed out") ||
|
|
393
|
+
errorMessage.includes("receipt") ||
|
|
394
|
+
errorMessage.includes("not be processed");
|
|
395
|
+
if (!isRetryableError || attempt === maxRetries) {
|
|
396
|
+
// If it's not a retryable error or we've exhausted retries, throw
|
|
397
|
+
throw new Error(`Transaction failed after ${attempt} attempts: ${errorMessage}`);
|
|
398
|
+
}
|
|
399
|
+
// Wait before retrying (exponential backoff)
|
|
400
|
+
const delay = Math.min(2000 * Math.pow(2, attempt - 1), 10000);
|
|
401
|
+
if (enableLogging) {
|
|
402
|
+
console.warn(`Transaction receipt not found (attempt ${attempt}/${maxRetries}), retrying in ${delay}ms...`);
|
|
403
|
+
}
|
|
404
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
405
|
+
// Check transaction status before retrying
|
|
406
|
+
try {
|
|
407
|
+
const transaction = await publicClient.getTransaction({ hash });
|
|
408
|
+
if (!transaction) {
|
|
409
|
+
throw new Error("Transaction not found in mempool or blockchain");
|
|
410
|
+
}
|
|
411
|
+
if (enableLogging) {
|
|
412
|
+
console.log(`Transaction ${hash} found in ${transaction.blockNumber ? "block" : "mempool"}, waiting for confirmation...`);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
catch (txError) {
|
|
416
|
+
if (enableLogging) {
|
|
417
|
+
console.warn(`Could not fetch transaction ${hash}: ${parseViemError(txError)}`);
|
|
418
|
+
}
|
|
419
|
+
// Continue with retry anyway in case it's just an RPC issue
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
// This should never be reached, but just in case
|
|
424
|
+
throw new Error(`Transaction failed after ${maxRetries} attempts: ${parseViemError(lastError)}`);
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Enhanced transaction receipt handler with retry logic for ethers.js
|
|
428
|
+
* @param signer The ethers signer
|
|
429
|
+
* @param txHash The transaction hash
|
|
430
|
+
* @param options Retry configuration options
|
|
431
|
+
*/
|
|
432
|
+
async function waitForEthersTransactionWithRetry(signer, txHash, options = {}) {
|
|
433
|
+
const { maxRetries, timeoutMs, enableLogging } = {
|
|
434
|
+
...DEFAULT_OPTIONS,
|
|
435
|
+
...options,
|
|
436
|
+
};
|
|
437
|
+
let lastError = null;
|
|
438
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
439
|
+
try {
|
|
440
|
+
// Wait for transaction receipt with timeout
|
|
441
|
+
const provider = signer.provider;
|
|
442
|
+
if (!provider) {
|
|
443
|
+
throw new Error("Provider not available");
|
|
444
|
+
}
|
|
445
|
+
// Create a timeout promise
|
|
446
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
447
|
+
setTimeout(() => reject(new Error("Transaction receipt timeout")), timeoutMs);
|
|
448
|
+
});
|
|
449
|
+
// Race between waiting for receipt and timeout
|
|
450
|
+
const receipt = await Promise.race([
|
|
451
|
+
provider.waitForTransaction(txHash, 1, timeoutMs),
|
|
452
|
+
timeoutPromise,
|
|
453
|
+
]);
|
|
454
|
+
if (!receipt) {
|
|
455
|
+
throw new Error("Transaction receipt not found");
|
|
456
|
+
}
|
|
457
|
+
// Check transaction status (ethers.js uses status: 0 for failed, 1 for success)
|
|
458
|
+
if (receipt.status === 0) {
|
|
459
|
+
throw new Error(`Transaction ${txHash} was reverted on-chain`);
|
|
460
|
+
}
|
|
461
|
+
if (enableLogging) {
|
|
462
|
+
console.log(`Transaction ${txHash} confirmed successfully in block ${receipt.blockNumber}`);
|
|
463
|
+
}
|
|
464
|
+
return; // Success, exit the function
|
|
465
|
+
}
|
|
466
|
+
catch (error) {
|
|
467
|
+
lastError = error;
|
|
468
|
+
// Check if it's a timeout or not found error
|
|
469
|
+
const errorMessage = parseEthersError(error);
|
|
470
|
+
const isRetryableError = errorMessage.includes("could not be found") ||
|
|
471
|
+
errorMessage.includes("timeout") ||
|
|
472
|
+
errorMessage.includes("timed out") ||
|
|
473
|
+
errorMessage.includes("receipt") ||
|
|
474
|
+
errorMessage.includes("not be processed") ||
|
|
475
|
+
errorMessage.includes("Transaction receipt timeout");
|
|
476
|
+
if (!isRetryableError || attempt === maxRetries) {
|
|
477
|
+
// If it's not a retryable error or we've exhausted retries, throw
|
|
478
|
+
throw new Error(`Transaction failed after ${attempt} attempts: ${errorMessage}`);
|
|
479
|
+
}
|
|
480
|
+
// Wait before retrying (exponential backoff)
|
|
481
|
+
const delay = Math.min(2000 * Math.pow(2, attempt - 1), 10000);
|
|
482
|
+
if (enableLogging) {
|
|
483
|
+
console.warn(`Transaction receipt not found (attempt ${attempt}/${maxRetries}), retrying in ${delay}ms...`);
|
|
484
|
+
}
|
|
485
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
486
|
+
// Check transaction status before retrying
|
|
487
|
+
try {
|
|
488
|
+
const provider = signer.provider;
|
|
489
|
+
if (provider) {
|
|
490
|
+
const transaction = await provider.getTransaction(txHash);
|
|
491
|
+
if (!transaction) {
|
|
492
|
+
throw new Error("Transaction not found in mempool or blockchain");
|
|
493
|
+
}
|
|
494
|
+
if (enableLogging) {
|
|
495
|
+
console.log(`Transaction ${txHash} found in ${transaction.blockNumber ? "block" : "mempool"}, waiting for confirmation...`);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
catch (txError) {
|
|
500
|
+
if (enableLogging) {
|
|
501
|
+
console.warn(`Could not fetch transaction ${txHash}: ${parseEthersError(txError)}`);
|
|
502
|
+
}
|
|
503
|
+
// Continue with retry anyway in case it's just an RPC issue
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
// This should never be reached, but just in case
|
|
508
|
+
throw new Error(`Transaction failed after ${maxRetries} attempts: ${parseEthersError(lastError)}`);
|
|
340
509
|
}
|
|
510
|
+
|
|
511
|
+
exports.ForwarderError = void 0;
|
|
512
|
+
(function (ForwarderError) {
|
|
513
|
+
ForwarderError["CONTRACT_NOT_AVAILABLE"] = "Contract not available";
|
|
514
|
+
ForwarderError["SIGNER_NOT_AVAILABLE"] = "Signer not available";
|
|
515
|
+
ForwarderError["UNKNOWN_ERROR"] = "Unknown error";
|
|
516
|
+
ForwarderError["INVALID_FORWARD_TYPE"] = "Invalid forward type";
|
|
517
|
+
ForwarderError["MISSING_REQUIRED_PARAMS"] = "Missing required parameters";
|
|
518
|
+
})(exports.ForwarderError || (exports.ForwarderError = {}));
|
|
341
519
|
// Type-guard style helper to ensure a signer exists throughout the rest of the function.
|
|
342
520
|
function assertSigner(maybeSigner) {
|
|
343
521
|
if (!maybeSigner) {
|
|
@@ -483,7 +661,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
483
661
|
setIsProcessing(true);
|
|
484
662
|
// Approve only the specific amount needed
|
|
485
663
|
const approveTx = await tokenContract.approve(ADDRESSES.FORWARDER, amount);
|
|
486
|
-
await approveTx.
|
|
664
|
+
await waitForEthersTransactionWithRetry(signer, approveTx.hash);
|
|
487
665
|
return true;
|
|
488
666
|
}
|
|
489
667
|
catch (error) {
|
|
@@ -527,7 +705,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
527
705
|
if (allowance < amount) {
|
|
528
706
|
try {
|
|
529
707
|
const approveTx = await tokenContract.approve(ADDRESSES.FORWARDER, ethers.MaxUint256);
|
|
530
|
-
await approveTx.
|
|
708
|
+
await waitForEthersTransactionWithRetry(signer, approveTx.hash);
|
|
531
709
|
}
|
|
532
710
|
catch (approveError) {
|
|
533
711
|
throw new Error(parseEthersError(approveError) || "Token approval failed");
|
|
@@ -580,7 +758,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
580
758
|
? ADDRESSES.AUDIT_FEE_WALLET
|
|
581
759
|
: ADDRESSES.FOUNDATION_WALLET, amount, sendToCounterfactualWallet, message);
|
|
582
760
|
}
|
|
583
|
-
await tx.
|
|
761
|
+
await waitForEthersTransactionWithRetry(signer, tx.hash);
|
|
584
762
|
return tx.hash;
|
|
585
763
|
}
|
|
586
764
|
catch (txError) {
|
|
@@ -803,7 +981,7 @@ function useForwarder(signer, CHAIN_ID) {
|
|
|
803
981
|
setIsProcessing(true);
|
|
804
982
|
// Try to call mint function (common for test tokens)
|
|
805
983
|
const tx = await usdcContract.mint(recipient, amount);
|
|
806
|
-
await tx.
|
|
984
|
+
await waitForEthersTransactionWithRetry(signer, tx.hash);
|
|
807
985
|
return tx.hash;
|
|
808
986
|
}
|
|
809
987
|
catch (error) {
|
|
@@ -1320,27 +1498,6 @@ exports.OffchainFractionsError = void 0;
|
|
|
1320
1498
|
OffchainFractionsError["INSUFFICIENT_BALANCE"] = "Insufficient balance";
|
|
1321
1499
|
OffchainFractionsError["INSUFFICIENT_ALLOWANCE"] = "Insufficient allowance";
|
|
1322
1500
|
})(exports.OffchainFractionsError || (exports.OffchainFractionsError = {}));
|
|
1323
|
-
// Utility to extract the most useful revert reason from a viem error object
|
|
1324
|
-
function parseViemError(error) {
|
|
1325
|
-
if (!error)
|
|
1326
|
-
return "Unknown error";
|
|
1327
|
-
// Check if it's a viem BaseError
|
|
1328
|
-
if (error instanceof Error) {
|
|
1329
|
-
// For contract revert errors
|
|
1330
|
-
if (error.cause?.reason) {
|
|
1331
|
-
return error.cause.reason;
|
|
1332
|
-
}
|
|
1333
|
-
// For viem's shortMessage
|
|
1334
|
-
if (error.shortMessage) {
|
|
1335
|
-
return error.shortMessage;
|
|
1336
|
-
}
|
|
1337
|
-
// Fallback to regular message
|
|
1338
|
-
if (error.message) {
|
|
1339
|
-
return error.message;
|
|
1340
|
-
}
|
|
1341
|
-
}
|
|
1342
|
-
return exports.OffchainFractionsError.UNKNOWN_ERROR;
|
|
1343
|
-
}
|
|
1344
1501
|
// Type-guard style helper to ensure a wallet client exists throughout the rest of the function.
|
|
1345
1502
|
function assertWalletClient(maybeWalletClient) {
|
|
1346
1503
|
if (!maybeWalletClient) {
|
|
@@ -1422,9 +1579,7 @@ function useOffchainFractions(walletClient, publicClient, CHAIN_ID) {
|
|
|
1422
1579
|
chain: walletClient.chain,
|
|
1423
1580
|
account: walletClient.account,
|
|
1424
1581
|
});
|
|
1425
|
-
await publicClient
|
|
1426
|
-
hash,
|
|
1427
|
-
});
|
|
1582
|
+
await waitForViemTransactionWithRetry(publicClient, hash);
|
|
1428
1583
|
return true;
|
|
1429
1584
|
}
|
|
1430
1585
|
catch (error) {
|
|
@@ -1496,9 +1651,7 @@ function useOffchainFractions(walletClient, publicClient, CHAIN_ID) {
|
|
|
1496
1651
|
chain: walletClient.chain,
|
|
1497
1652
|
account: walletClient.account,
|
|
1498
1653
|
});
|
|
1499
|
-
await publicClient
|
|
1500
|
-
hash,
|
|
1501
|
-
});
|
|
1654
|
+
await waitForViemTransactionWithRetry(publicClient, hash);
|
|
1502
1655
|
return hash;
|
|
1503
1656
|
}
|
|
1504
1657
|
catch (error) {
|
|
@@ -1551,9 +1704,7 @@ function useOffchainFractions(walletClient, publicClient, CHAIN_ID) {
|
|
|
1551
1704
|
chain: walletClient.chain,
|
|
1552
1705
|
account: walletClient.account,
|
|
1553
1706
|
});
|
|
1554
|
-
await publicClient
|
|
1555
|
-
hash: approveHash,
|
|
1556
|
-
});
|
|
1707
|
+
await waitForViemTransactionWithRetry(publicClient, approveHash);
|
|
1557
1708
|
}
|
|
1558
1709
|
// Run a simulation first to surface any revert reason
|
|
1559
1710
|
try {
|
|
@@ -1593,9 +1744,7 @@ function useOffchainFractions(walletClient, publicClient, CHAIN_ID) {
|
|
|
1593
1744
|
chain: walletClient.chain,
|
|
1594
1745
|
account: walletClient.account,
|
|
1595
1746
|
});
|
|
1596
|
-
await publicClient
|
|
1597
|
-
hash,
|
|
1598
|
-
});
|
|
1747
|
+
await waitForViemTransactionWithRetry(publicClient, hash);
|
|
1599
1748
|
return hash;
|
|
1600
1749
|
}
|
|
1601
1750
|
catch (error) {
|
|
@@ -1673,9 +1822,7 @@ function useOffchainFractions(walletClient, publicClient, CHAIN_ID) {
|
|
|
1673
1822
|
chain: walletClient.chain,
|
|
1674
1823
|
account: walletClient.account,
|
|
1675
1824
|
});
|
|
1676
|
-
await publicClient
|
|
1677
|
-
hash,
|
|
1678
|
-
});
|
|
1825
|
+
await waitForViemTransactionWithRetry(publicClient, hash);
|
|
1679
1826
|
return hash;
|
|
1680
1827
|
}
|
|
1681
1828
|
catch (error) {
|
|
@@ -1725,9 +1872,7 @@ function useOffchainFractions(walletClient, publicClient, CHAIN_ID) {
|
|
|
1725
1872
|
chain: walletClient.chain,
|
|
1726
1873
|
account: walletClient.account,
|
|
1727
1874
|
});
|
|
1728
|
-
await publicClient
|
|
1729
|
-
hash,
|
|
1730
|
-
});
|
|
1875
|
+
await waitForViemTransactionWithRetry(publicClient, hash);
|
|
1731
1876
|
return hash;
|
|
1732
1877
|
}
|
|
1733
1878
|
catch (error) {
|
|
@@ -1893,9 +2038,7 @@ function useOffchainFractions(walletClient, publicClient, CHAIN_ID) {
|
|
|
1893
2038
|
chain: walletClient.chain,
|
|
1894
2039
|
account: walletClient.account,
|
|
1895
2040
|
});
|
|
1896
|
-
await publicClient
|
|
1897
|
-
hash,
|
|
1898
|
-
});
|
|
2041
|
+
await waitForViemTransactionWithRetry(publicClient, hash);
|
|
1899
2042
|
return hash;
|
|
1900
2043
|
}
|
|
1901
2044
|
catch (error) {
|
|
@@ -1945,9 +2088,7 @@ function useOffchainFractions(walletClient, publicClient, CHAIN_ID) {
|
|
|
1945
2088
|
chain: walletClient.chain,
|
|
1946
2089
|
account: walletClient.account,
|
|
1947
2090
|
});
|
|
1948
|
-
await publicClient
|
|
1949
|
-
hash,
|
|
1950
|
-
});
|
|
2091
|
+
await waitForViemTransactionWithRetry(publicClient, hash);
|
|
1951
2092
|
return hash;
|
|
1952
2093
|
}
|
|
1953
2094
|
catch (error) {
|
|
@@ -3715,8 +3856,12 @@ exports.WalletsRouter = WalletsRouter;
|
|
|
3715
3856
|
exports.allRegions = allRegions;
|
|
3716
3857
|
exports.countries = countries;
|
|
3717
3858
|
exports.getAddresses = getAddresses;
|
|
3859
|
+
exports.parseEthersError = parseEthersError;
|
|
3860
|
+
exports.parseViemError = parseViemError;
|
|
3718
3861
|
exports.regionMetadata = regionMetadata;
|
|
3719
3862
|
exports.usStates = usStates;
|
|
3720
3863
|
exports.useForwarder = useForwarder;
|
|
3721
3864
|
exports.useOffchainFractions = useOffchainFractions;
|
|
3722
|
-
|
|
3865
|
+
exports.waitForEthersTransactionWithRetry = waitForEthersTransactionWithRetry;
|
|
3866
|
+
exports.waitForViemTransactionWithRetry = waitForViemTransactionWithRetry;
|
|
3867
|
+
//# sourceMappingURL=farms-router-CCva--xp.js.map
|