@glowlabs-org/utils 0.2.145 → 0.2.147

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/esm/index.js CHANGED
@@ -13,8 +13,8 @@ import { parseUnits, formatUnits } from 'viem';
13
13
  import { MerkleTree } from 'merkletreejs';
14
14
  import { solidityPackedKeccak256, keccak256 } from 'ethers';
15
15
  import Decimal from 'decimal.js';
16
- import { H as HUB_URL, U as USDG_WEIGHT_DECIMAL_PRECISION, G as GLOW_WEIGHT_DECIMAL_PRECISION, M as MAX_WEIGHT } from './farms-router-C_7Ys4An.js';
17
- export { C as ControlRouter, F as FarmsRouter, d as KICKSTARTER_STATUS, K as KickstarterRouter, O as OFF_CHAIN_PAYMENT_CURRENCIES, P as PAYMENT_CURRENCIES, b as REGIONS, R as RegionRouter, S as STAKING_DIRECTIONS, T as TRANSFER_TYPES, W as WalletsRouter, c as configureSentry, u as useForwarder, a as useOffchainFractions } from './farms-router-C_7Ys4An.js';
16
+ import { H as HUB_URL, U as USDG_WEIGHT_DECIMAL_PRECISION, G as GLOW_WEIGHT_DECIMAL_PRECISION, M as MAX_WEIGHT } from './farms-router-PZUo1LyW.js';
17
+ export { C as ControlRouter, F as FarmsRouter, d as KICKSTARTER_STATUS, K as KickstarterRouter, O as OFF_CHAIN_PAYMENT_CURRENCIES, P as PAYMENT_CURRENCIES, b as REGIONS, R as RegionRouter, S as STAKING_DIRECTIONS, T as TRANSFER_TYPES, W as WalletsRouter, c as configureSentry, u as useForwarder, a as useOffchainFractions } from './farms-router-PZUo1LyW.js';
18
18
 
19
19
  const GENESIS_TIMESTAMP = 1700352000;
20
20
 
@@ -6,6 +6,7 @@ export interface TransactionRetryOptions {
6
6
  maxRetries?: number;
7
7
  timeoutMs?: number;
8
8
  enableLogging?: boolean;
9
+ pollIntervalMs?: number;
9
10
  }
10
11
  /**
11
12
  * Enhanced transaction receipt handler with retry logic for viem
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@glowlabs-org/utils",
3
- "version": "0.2.145",
3
+ "version": "0.2.147",
4
4
  "description": "A library containing all typechain types and addresses relating to the glow guarded launch",
5
5
  "keywords": [],
6
6
  "author": "",
@@ -47,8 +47,8 @@ const sepoliaAddresses: Record<ContractKeys, `0x${string}`> = {
47
47
  USDC: "0x93c898be98cd2618ba84a6dccf5003d3bbe40356",
48
48
  USDG_UNISWAP: "0x2a085A3aEA8982396533327c854753Ce521B666d",
49
49
  GLW_UNISWAP: "0x8e27016D0B866a56CE74A1a280c749dD679bb0Fa",
50
- FORWARDER: "0xDaC24F18171224eeaf6a9B38f5C5081aDbDff969",
51
- OFFCHAIN_FRACTIONS: "0x7D97528eeF8B8D17AA1Ba3307Ed39b07b3A1b69B",
50
+ FORWARDER: "0xe7A366482899e2Ed29c9504F4792B8D1c67066ff",
51
+ OFFCHAIN_FRACTIONS: "0x5Ad30F90AFEf1279157A5055AAd2d8c1529a05D2",
52
52
  COUNTERFACTUAL_HOLDER_FACTORY: "0x2c3AB887746F6f4a8a4b9Db6aC800eb71945509A",
53
53
  FOUNDATION_WALLET: "0x5e230FED487c86B90f6508104149F087d9B1B0A7",
54
54
  FOUNDATION_HUB_MANAGER_WALLET: "0x5252FdA14A149c01EA5A1D6514a9c1369E4C70b4",
@@ -235,7 +235,10 @@ export function useForwarder(signer: Signer | undefined, CHAIN_ID: number) {
235
235
  ADDRESSES.FORWARDER,
236
236
  amount
237
237
  );
238
- await waitForEthersTransactionWithRetry(signer, approveTx.hash);
238
+ await waitForEthersTransactionWithRetry(signer, approveTx.hash, {
239
+ timeoutMs: 30000,
240
+ pollIntervalMs: 2000,
241
+ });
239
242
 
240
243
  return true;
241
244
  } catch (error) {
@@ -311,7 +314,10 @@ export function useForwarder(signer: Signer | undefined, CHAIN_ID: number) {
311
314
  ADDRESSES.FORWARDER,
312
315
  MaxUint256
313
316
  );
314
- await waitForEthersTransactionWithRetry(signer, approveTx.hash);
317
+ await waitForEthersTransactionWithRetry(signer, approveTx.hash, {
318
+ timeoutMs: 30000,
319
+ pollIntervalMs: 2000,
320
+ });
315
321
  } catch (approveError) {
316
322
  sentryCaptureException(approveError, {
317
323
  action: "forwardTokens.approve",
@@ -409,7 +415,10 @@ export function useForwarder(signer: Signer | undefined, CHAIN_ID: number) {
409
415
  message
410
416
  );
411
417
  }
412
- await waitForEthersTransactionWithRetry(signer, tx.hash);
418
+ await waitForEthersTransactionWithRetry(signer, tx.hash, {
419
+ timeoutMs: 30000,
420
+ pollIntervalMs: 2000,
421
+ });
413
422
 
414
423
  return tx.hash;
415
424
  } catch (txError: any) {
@@ -745,7 +754,10 @@ export function useForwarder(signer: Signer | undefined, CHAIN_ID: number) {
745
754
 
746
755
  // Try to call mint function (common for test tokens)
747
756
  const tx = await usdcContract.mint(recipient, amount);
748
- await waitForEthersTransactionWithRetry(signer, tx.hash);
757
+ await waitForEthersTransactionWithRetry(signer, tx.hash, {
758
+ timeoutMs: 30000,
759
+ pollIntervalMs: 2000,
760
+ });
749
761
 
750
762
  return tx.hash;
751
763
  } catch (error: any) {
@@ -56,12 +56,14 @@ export interface TransactionRetryOptions {
56
56
  maxRetries?: number;
57
57
  timeoutMs?: number;
58
58
  enableLogging?: boolean;
59
+ pollIntervalMs?: number;
59
60
  }
60
61
 
61
62
  const DEFAULT_OPTIONS: Required<TransactionRetryOptions> = {
62
63
  maxRetries: 3,
63
64
  timeoutMs: 60000,
64
65
  enableLogging: true,
66
+ pollIntervalMs: 2000,
65
67
  };
66
68
 
67
69
  /**
@@ -75,90 +77,57 @@ export async function waitForViemTransactionWithRetry(
75
77
  hash: `0x${string}`,
76
78
  options: TransactionRetryOptions = {}
77
79
  ): Promise<void> {
78
- const { maxRetries, timeoutMs, enableLogging } = {
80
+ const { maxRetries, timeoutMs, enableLogging, pollIntervalMs } = {
79
81
  ...DEFAULT_OPTIONS,
80
82
  ...options,
81
83
  };
82
84
 
83
- let lastError: Error | null = null;
85
+ const deadline = Date.now() + timeoutMs;
86
+ let consecutiveErrors = 0;
84
87
 
85
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
88
+ while (Date.now() < deadline) {
86
89
  try {
87
- // Wait for transaction receipt with timeout
88
- const receipt = await publicClient.waitForTransactionReceipt({
89
- hash,
90
- timeout: timeoutMs,
91
- });
92
-
93
- // Check transaction status
94
- if (receipt.status === "reverted") {
95
- throw new Error(`Transaction ${hash} was reverted on-chain`);
96
- }
97
-
98
- if (enableLogging) {
99
- console.log(
100
- `Transaction ${hash} confirmed successfully in block ${receipt.blockNumber}`
101
- );
90
+ const receipt = await publicClient.getTransactionReceipt({ hash });
91
+ if (receipt) {
92
+ if (receipt.status === "reverted") {
93
+ throw new Error(`Transaction ${hash} was reverted on-chain`);
94
+ }
95
+ if (enableLogging) {
96
+ console.log(
97
+ `Transaction ${hash} confirmed successfully in block ${receipt.blockNumber}`
98
+ );
99
+ }
100
+ return;
102
101
  }
103
- return; // Success, exit the function
104
102
  } catch (error) {
105
- lastError = error as Error;
106
-
107
- // Check if it's a timeout or not found error
108
103
  const errorMessage = parseViemError(error);
109
- const isRetryableError =
104
+ // Treat not found/receipt missing as retryable without counting towards errors
105
+ const isNotFound =
106
+ errorMessage.includes("not found") ||
110
107
  errorMessage.includes("could not be found") ||
111
- errorMessage.includes("timeout") ||
112
- errorMessage.includes("timed out") ||
113
108
  errorMessage.includes("receipt") ||
114
- errorMessage.includes("not be processed");
115
-
116
- if (!isRetryableError || attempt === maxRetries) {
117
- // If it's not a retryable error or we've exhausted retries, throw
118
- throw new Error(
119
- `Transaction failed after ${attempt} attempts: ${errorMessage}`
120
- );
121
- }
122
-
123
- // Wait before retrying (exponential backoff)
124
- const delay = Math.min(2000 * Math.pow(2, attempt - 1), 10000);
125
- if (enableLogging) {
126
- console.warn(
127
- `Transaction receipt not found (attempt ${attempt}/${maxRetries}), retrying in ${delay}ms...`
128
- );
129
- }
130
- await new Promise((resolve) => setTimeout(resolve, delay));
131
-
132
- // Check transaction status before retrying
133
- try {
134
- const transaction = await publicClient.getTransaction({ hash });
135
- if (!transaction) {
136
- throw new Error("Transaction not found in mempool or blockchain");
137
- }
138
- if (enableLogging) {
139
- console.log(
140
- `Transaction ${hash} found in ${
141
- transaction.blockNumber ? "block" : "mempool"
142
- }, waiting for confirmation...`
109
+ errorMessage.includes("not confirmed") ||
110
+ errorMessage.includes("TransactionReceiptNotFound");
111
+
112
+ if (!isNotFound) {
113
+ consecutiveErrors++;
114
+ if (consecutiveErrors >= maxRetries) {
115
+ throw new Error(
116
+ `Transaction failed after ${consecutiveErrors} attempts: ${errorMessage}`
143
117
  );
144
118
  }
145
- } catch (txError) {
146
119
  if (enableLogging) {
147
120
  console.warn(
148
- `Could not fetch transaction ${hash}: ${parseViemError(txError)}`
121
+ `Error fetching receipt (attempt ${consecutiveErrors}/${maxRetries}), retrying in ${pollIntervalMs}ms...`
149
122
  );
150
123
  }
151
- // Continue with retry anyway in case it's just an RPC issue
152
124
  }
153
125
  }
126
+
127
+ await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
154
128
  }
155
129
 
156
- // This should never be reached, but just in case
157
- throw new Error(
158
- `Transaction failed after ${maxRetries} attempts: ${parseViemError(
159
- lastError
160
- )}`
161
- );
130
+ throw new Error(`Transaction receipt not found within ${timeoutMs}ms`);
162
131
  }
163
132
 
164
133
  /**
@@ -172,114 +141,52 @@ export async function waitForEthersTransactionWithRetry(
172
141
  txHash: string,
173
142
  options: TransactionRetryOptions = {}
174
143
  ): Promise<void> {
175
- const { maxRetries, timeoutMs, enableLogging } = {
144
+ const { maxRetries, timeoutMs, enableLogging, pollIntervalMs } = {
176
145
  ...DEFAULT_OPTIONS,
177
146
  ...options,
178
147
  };
179
148
 
180
- let lastError: Error | null = null;
181
-
182
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
183
- try {
184
- // Wait for transaction receipt with timeout
185
- const provider = signer.provider;
186
- if (!provider) {
187
- throw new Error("Provider not available");
188
- }
189
-
190
- // Create a timeout promise
191
- const timeoutPromise = new Promise((_, reject) => {
192
- setTimeout(
193
- () => reject(new Error("Transaction receipt timeout")),
194
- timeoutMs
195
- );
196
- });
197
-
198
- // Race between waiting for receipt and timeout
199
- const receipt = await Promise.race([
200
- provider.waitForTransaction(txHash, 1, timeoutMs),
201
- timeoutPromise,
202
- ]);
203
-
204
- if (!receipt) {
205
- throw new Error("Transaction receipt not found");
206
- }
149
+ const provider = signer.provider;
150
+ if (!provider) {
151
+ throw new Error("Provider not available");
152
+ }
207
153
 
208
- // Check transaction status (ethers.js uses status: 0 for failed, 1 for success)
209
- if ((receipt as any).status === 0) {
210
- throw new Error(`Transaction ${txHash} was reverted on-chain`);
211
- }
154
+ const deadline = Date.now() + timeoutMs;
155
+ let consecutiveErrors = 0;
212
156
 
213
- if (enableLogging) {
214
- console.log(
215
- `Transaction ${txHash} confirmed successfully in block ${
216
- (receipt as any).blockNumber
217
- }`
218
- );
157
+ while (Date.now() < deadline) {
158
+ try {
159
+ const receipt = await provider.getTransactionReceipt(txHash);
160
+ if (receipt) {
161
+ if ((receipt as any).status === 0) {
162
+ throw new Error(`Transaction ${txHash} was reverted on-chain`);
163
+ }
164
+ if (enableLogging) {
165
+ console.log(
166
+ `Transaction ${txHash} confirmed successfully in block ${
167
+ (receipt as any).blockNumber
168
+ }`
169
+ );
170
+ }
171
+ return;
219
172
  }
220
- return; // Success, exit the function
221
173
  } catch (error) {
222
- lastError = error as Error;
223
-
224
- // Check if it's a timeout or not found error
225
174
  const errorMessage = parseEthersError(error);
226
- const isRetryableError =
227
- errorMessage.includes("could not be found") ||
228
- errorMessage.includes("timeout") ||
229
- errorMessage.includes("timed out") ||
230
- errorMessage.includes("receipt") ||
231
- errorMessage.includes("not be processed") ||
232
- errorMessage.includes("Transaction receipt timeout");
233
-
234
- if (!isRetryableError || attempt === maxRetries) {
235
- // If it's not a retryable error or we've exhausted retries, throw
175
+ consecutiveErrors++;
176
+ if (consecutiveErrors >= maxRetries) {
236
177
  throw new Error(
237
- `Transaction failed after ${attempt} attempts: ${errorMessage}`
178
+ `Transaction failed after ${consecutiveErrors} attempts: ${errorMessage}`
238
179
  );
239
180
  }
240
-
241
- // Wait before retrying (exponential backoff)
242
- const delay = Math.min(2000 * Math.pow(2, attempt - 1), 10000);
243
181
  if (enableLogging) {
244
182
  console.warn(
245
- `Transaction receipt not found (attempt ${attempt}/${maxRetries}), retrying in ${delay}ms...`
183
+ `Error fetching receipt (attempt ${consecutiveErrors}/${maxRetries}), retrying in ${pollIntervalMs}ms...`
246
184
  );
247
185
  }
248
- await new Promise((resolve) => setTimeout(resolve, delay));
249
-
250
- // Check transaction status before retrying
251
- try {
252
- const provider = signer.provider;
253
- if (provider) {
254
- const transaction = await provider.getTransaction(txHash);
255
- if (!transaction) {
256
- throw new Error("Transaction not found in mempool or blockchain");
257
- }
258
- if (enableLogging) {
259
- console.log(
260
- `Transaction ${txHash} found in ${
261
- transaction.blockNumber ? "block" : "mempool"
262
- }, waiting for confirmation...`
263
- );
264
- }
265
- }
266
- } catch (txError) {
267
- if (enableLogging) {
268
- console.warn(
269
- `Could not fetch transaction ${txHash}: ${parseEthersError(
270
- txError
271
- )}`
272
- );
273
- }
274
- // Continue with retry anyway in case it's just an RPC issue
275
- }
276
186
  }
187
+
188
+ await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
277
189
  }
278
190
 
279
- // This should never be reached, but just in case
280
- throw new Error(
281
- `Transaction failed after ${maxRetries} attempts: ${parseEthersError(
282
- lastError
283
- )}`
284
- );
191
+ throw new Error(`Transaction receipt not found within ${timeoutMs}ms`);
285
192
  }