@vleap/warps-adapter-evm 0.2.0-alpha.21 → 0.2.0-alpha.23

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/index.mjs CHANGED
@@ -30,7 +30,7 @@ var FALLBACK_LOGOS = {
30
30
  "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913": "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png",
31
31
  "0x4200000000000000000000000000000000000006": "https://assets.coingecko.com/coins/images/2518/small/weth.png",
32
32
  "0x036CbD53842c5426634e7929541eC2318f3dCF7e": "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png",
33
- "0x808456652fdb597867f38412077A9182bf77359F": "https://assets.coingecko.com/coins/images/3318/small/euro-coin.png",
33
+ "0x808456652fdb597867f38412077A9182bf77359F": "https://assets.coingecko.com/coins/images/26045/standard/euro.png",
34
34
  "0xcbB7C0006F23900c38EB856149F799620fcb8A4a": "https://assets.coingecko.com/coins/images/7598/small/wrapped_bitcoin_wbtc.png"
35
35
  }
36
36
  };
@@ -172,6 +172,143 @@ var EvmLogoService = class {
172
172
  }
173
173
  };
174
174
 
175
+ // src/tokens.ts
176
+ var KnownTokens = {
177
+ ethereum: {
178
+ mainnet: [
179
+ {
180
+ id: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
181
+ name: "USD Coin",
182
+ symbol: "USDC",
183
+ decimals: 6,
184
+ logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
185
+ },
186
+ {
187
+ id: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
188
+ name: "Tether USD",
189
+ symbol: "USDT",
190
+ decimals: 6,
191
+ logoUrl: "https://assets.coingecko.com/coins/images/325/small/Tether.png"
192
+ },
193
+ {
194
+ id: "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
195
+ name: "Wrapped Bitcoin",
196
+ symbol: "WBTC",
197
+ decimals: 8,
198
+ logoUrl: "https://assets.coingecko.com/coins/images/7598/small/wrapped_bitcoin_wbtc.png"
199
+ },
200
+ {
201
+ id: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
202
+ name: "Wrapped Ether",
203
+ symbol: "WETH",
204
+ decimals: 18,
205
+ logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
206
+ },
207
+ {
208
+ id: "0x6B175474E89094C44Da98b954EedeAC495271d0F",
209
+ name: "Dai Stablecoin",
210
+ symbol: "DAI",
211
+ decimals: 18,
212
+ logoUrl: "https://assets.coingecko.com/coins/images/9956/small/4943.png"
213
+ }
214
+ ],
215
+ testnet: [
216
+ {
217
+ id: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
218
+ name: "USD Coin",
219
+ symbol: "USDC",
220
+ decimals: 6,
221
+ logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
222
+ },
223
+ {
224
+ id: "0x7169D38820dfd117C3FA1f22a697dBA58d90BA06",
225
+ name: "Tether USD",
226
+ symbol: "USDT",
227
+ decimals: 6,
228
+ logoUrl: "https://assets.coingecko.com/coins/images/325/small/Tether.png"
229
+ },
230
+ {
231
+ id: "0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9",
232
+ name: "Wrapped Ether",
233
+ symbol: "WETH",
234
+ decimals: 18,
235
+ logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
236
+ }
237
+ ]
238
+ },
239
+ arbitrum: {
240
+ mainnet: [
241
+ {
242
+ id: "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8",
243
+ name: "USD Coin",
244
+ symbol: "USDC",
245
+ decimals: 6,
246
+ logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
247
+ },
248
+ {
249
+ id: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
250
+ name: "Tether USD",
251
+ symbol: "USDT",
252
+ decimals: 6,
253
+ logoUrl: "https://assets.coingecko.com/coins/images/325/small/Tether.png"
254
+ },
255
+ {
256
+ id: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
257
+ name: "Wrapped Ether",
258
+ symbol: "WETH",
259
+ decimals: 18,
260
+ logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
261
+ }
262
+ ]
263
+ },
264
+ base: {
265
+ mainnet: [
266
+ {
267
+ id: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
268
+ name: "USD Coin",
269
+ symbol: "USDC",
270
+ decimals: 6,
271
+ logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
272
+ },
273
+ {
274
+ id: "0x4200000000000000000000000000000000000006",
275
+ name: "Wrapped Ether",
276
+ symbol: "WETH",
277
+ decimals: 18,
278
+ logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
279
+ },
280
+ {
281
+ id: "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
282
+ name: "USD Coin",
283
+ symbol: "USDC",
284
+ decimals: 6,
285
+ logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
286
+ },
287
+ {
288
+ id: "0x808456652fdb597867f38412077A9182bf77359F",
289
+ name: "Euro Coin",
290
+ symbol: "EURC",
291
+ decimals: 6,
292
+ logoUrl: "https://assets.coingecko.com/coins/images/26045/standard/euro.png"
293
+ },
294
+ {
295
+ id: "0xcbB7C0006F23900c38EB856149F799620fcb8A4a",
296
+ name: "Coinbase Wrapped BTC",
297
+ symbol: "CBETH",
298
+ decimals: 8,
299
+ logoUrl: "https://assets.coingecko.com/coins/images/7598/small/wrapped_bitcoin_wbtc.png"
300
+ }
301
+ ]
302
+ }
303
+ };
304
+ var findKnownTokenById = (chainName, id, env = "mainnet") => {
305
+ const chainTokens = KnownTokens[chainName]?.[env] || [];
306
+ return chainTokens.find((token) => token.id === id) || null;
307
+ };
308
+ var getKnownTokensForChain = (chainName, env = "mainnet") => {
309
+ return KnownTokens[chainName]?.[env] || [];
310
+ };
311
+
175
312
  // src/WarpEvmDataLoader.ts
176
313
  var ERC20_ABI = [
177
314
  "function balanceOf(address owner) view returns (uint256)",
@@ -180,111 +317,6 @@ var ERC20_ABI = [
180
317
  "function symbol() view returns (string)",
181
318
  "function totalSupply() view returns (uint256)"
182
319
  ];
183
- var KNOWN_TOKENS = {
184
- ethereum: {
185
- "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48": {
186
- name: "USD Coin",
187
- symbol: "USDC",
188
- decimals: 6,
189
- logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
190
- },
191
- "0xdAC17F958D2ee523a2206206994597C13D831ec7": {
192
- name: "Tether USD",
193
- symbol: "USDT",
194
- decimals: 6,
195
- logoUrl: "https://assets.coingecko.com/coins/images/325/small/Tether.png"
196
- },
197
- "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599": {
198
- name: "Wrapped Bitcoin",
199
- symbol: "WBTC",
200
- decimals: 8,
201
- logoUrl: "https://assets.coingecko.com/coins/images/7598/small/wrapped_bitcoin_wbtc.png"
202
- },
203
- "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2": {
204
- name: "Wrapped Ether",
205
- symbol: "WETH",
206
- decimals: 18,
207
- logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
208
- },
209
- "0x6B175474E89094C44Da98b954EedeAC495271d0F": {
210
- name: "Dai Stablecoin",
211
- symbol: "DAI",
212
- decimals: 18,
213
- logoUrl: "https://assets.coingecko.com/coins/images/9956/small/4943.png"
214
- },
215
- // Sepolia testnet tokens
216
- "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238": {
217
- name: "USD Coin",
218
- symbol: "USDC",
219
- decimals: 6,
220
- logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
221
- },
222
- "0x7169D38820dfd117C3FA1f22a697dBA58d90BA06": {
223
- name: "Tether USD",
224
- symbol: "USDT",
225
- decimals: 6,
226
- logoUrl: "https://assets.coingecko.com/coins/images/325/small/Tether.png"
227
- },
228
- "0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9": {
229
- name: "Wrapped Ether",
230
- symbol: "WETH",
231
- decimals: 18,
232
- logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
233
- }
234
- },
235
- arbitrum: {
236
- "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8": {
237
- name: "USD Coin",
238
- symbol: "USDC",
239
- decimals: 6,
240
- logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
241
- },
242
- "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9": {
243
- name: "Tether USD",
244
- symbol: "USDT",
245
- decimals: 6,
246
- logoUrl: "https://assets.coingecko.com/coins/images/325/small/Tether.png"
247
- },
248
- "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1": {
249
- name: "Wrapped Ether",
250
- symbol: "WETH",
251
- decimals: 18,
252
- logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
253
- }
254
- },
255
- base: {
256
- "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913": {
257
- name: "USD Coin",
258
- symbol: "USDC",
259
- decimals: 6,
260
- logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
261
- },
262
- "0x4200000000000000000000000000000000000006": {
263
- name: "Wrapped Ether",
264
- symbol: "WETH",
265
- decimals: 18,
266
- logoUrl: "https://assets.coingecko.com/coins/images/2518/small/weth.png"
267
- },
268
- "0x036CbD53842c5426634e7929541eC2318f3dCF7e": {
269
- name: "USD Coin",
270
- symbol: "USDC",
271
- decimals: 6,
272
- logoUrl: "https://assets.coingecko.com/coins/images/6319/small/USD_Coin_icon.png"
273
- },
274
- "0x808456652fdb597867f38412077A9182bf77359F": {
275
- name: "Euro Coin",
276
- symbol: "EURC",
277
- decimals: 6,
278
- logoUrl: "https://assets.coingecko.com/coins/images/3318/small/euro-coin.png"
279
- },
280
- "0xcbB7C0006F23900c38EB856149F799620fcb8A4a": {
281
- name: "Coinbase Wrapped BTC",
282
- symbol: "CBETH",
283
- decimals: 8,
284
- logoUrl: "https://assets.coingecko.com/coins/images/7598/small/wrapped_bitcoin_wbtc.png"
285
- }
286
- }
287
- };
288
320
  var WarpEvmDataLoader = class {
289
321
  constructor(config, chain) {
290
322
  this.config = config;
@@ -294,47 +326,79 @@ var WarpEvmDataLoader = class {
294
326
  this.provider = new ethers.JsonRpcProvider(apiUrl, network);
295
327
  }
296
328
  async getAccount(address) {
329
+ const balance = await this.provider.getBalance(address);
330
+ return {
331
+ chain: this.chain.name,
332
+ address,
333
+ balance
334
+ };
335
+ }
336
+ async getAccountAssets(address) {
337
+ const account = await this.getAccount(address);
338
+ const tokenBalances = await this.getERC20TokenBalances(address);
339
+ let assets = account.balance > 0 ? [{ ...this.chain.nativeToken, amount: account.balance }] : [];
340
+ for (const tokenBalance of tokenBalances) {
341
+ if (tokenBalance.balance > 0n) {
342
+ const logoUrl = tokenBalance.metadata.logoUrl || await this.getLogoUrl(tokenBalance);
343
+ assets.push({
344
+ chain: this.chain.name,
345
+ identifier: tokenBalance.tokenAddress,
346
+ name: tokenBalance.metadata.name,
347
+ amount: tokenBalance.balance,
348
+ decimals: tokenBalance.metadata.decimals,
349
+ logoUrl: logoUrl || ""
350
+ });
351
+ }
352
+ }
353
+ return assets;
354
+ }
355
+ async getAsset(identifier) {
297
356
  try {
298
- const balance = await this.provider.getBalance(address);
357
+ const metadata = await this.getTokenMetadata(identifier);
358
+ if (!metadata) return null;
299
359
  return {
300
360
  chain: this.chain.name,
301
- address,
302
- balance
361
+ identifier,
362
+ name: metadata.name,
363
+ amount: 0n,
364
+ decimals: metadata.decimals,
365
+ logoUrl: metadata.logoUrl || ""
303
366
  };
304
367
  } catch (error) {
305
- throw new Error(`Failed to get account balance for ${address}: ${error}`);
368
+ return null;
306
369
  }
307
370
  }
308
- async getAccountAssets(address) {
371
+ async getAction(identifier, awaitCompleted = false) {
309
372
  try {
310
- const accountReq = this.getAccount(address);
311
- const tokenBalancesReq = this.getERC20TokenBalances(address);
312
- const [account, tokenBalances] = await Promise.all([accountReq, tokenBalancesReq]);
313
- const assets = [];
314
- if (account.balance > 0n) {
315
- assets.push({ ...this.chain.nativeToken, amount: account.balance });
316
- }
317
- for (const tokenBalance of tokenBalances) {
318
- if (tokenBalance.balance > 0n) {
319
- const logoUrl = tokenBalance.metadata.logoUrl || await EvmLogoService.getLogoUrl(
320
- this.chain.name,
321
- tokenBalance.tokenAddress,
322
- tokenBalance.metadata.name,
323
- tokenBalance.metadata.symbol
324
- );
325
- assets.push({
326
- chain: this.chain.name,
327
- identifier: tokenBalance.tokenAddress,
328
- name: tokenBalance.metadata.name,
329
- amount: tokenBalance.balance,
330
- decimals: tokenBalance.metadata.decimals,
331
- logoUrl: logoUrl || ""
332
- });
373
+ const tx = await this.provider.getTransaction(identifier);
374
+ if (!tx) return null;
375
+ const receipt = await this.provider.getTransactionReceipt(identifier);
376
+ const block = await this.provider.getBlock(tx.blockNumber || "latest");
377
+ return {
378
+ chain: this.chain.name,
379
+ id: tx.hash || identifier,
380
+ receiver: tx.to || "",
381
+ sender: tx.from,
382
+ value: tx.value,
383
+ function: tx.data && tx.data !== "0x" ? "contract_call" : "",
384
+ status: receipt?.status === 1 ? "success" : receipt?.status === 0 ? "failed" : "pending",
385
+ createdAt: block?.timestamp ? new Date(Number(block.timestamp) * 1e3).toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
386
+ error: receipt?.status === 0 ? "Transaction failed" : null,
387
+ tx: {
388
+ hash: tx.hash || "",
389
+ from: tx.from,
390
+ to: tx.to || "",
391
+ value: tx.value.toString(),
392
+ data: tx.data || "0x",
393
+ gasLimit: tx.gasLimit?.toString() || "0",
394
+ gasPrice: tx.gasPrice?.toString() || "0",
395
+ blockNumber: tx.blockNumber || 0,
396
+ blockHash: tx.blockHash || "",
397
+ transactionIndex: tx.index || 0
333
398
  }
334
- }
335
- return assets;
399
+ };
336
400
  } catch (error) {
337
- throw new Error(`Failed to get account assets for ${address}: ${error}`);
401
+ return null;
338
402
  }
339
403
  }
340
404
  async getAccountActions(address, options) {
@@ -342,15 +406,16 @@ var WarpEvmDataLoader = class {
342
406
  }
343
407
  async getERC20TokenBalances(address) {
344
408
  const tokenBalances = [];
345
- const knownTokens = KNOWN_TOKENS[this.chain.name] || {};
346
- for (const [tokenAddress, metadata] of Object.entries(knownTokens)) {
409
+ const env = this.config.env === "devnet" ? "testnet" : this.config.env;
410
+ const knownTokens = getKnownTokensForChain(this.chain.name, env);
411
+ for (const token of knownTokens) {
347
412
  try {
348
- const balance = await this.getTokenBalance(address, tokenAddress);
413
+ const balance = await this.getTokenBalance(address, token.id);
349
414
  if (balance > 0n) {
350
415
  tokenBalances.push({
351
- tokenAddress,
416
+ tokenAddress: token.id,
352
417
  balance,
353
- metadata
418
+ metadata: token
354
419
  });
355
420
  }
356
421
  } catch (error) {
@@ -358,7 +423,7 @@ var WarpEvmDataLoader = class {
358
423
  }
359
424
  const additionalTokens = await this.detectTokensFromEvents(address);
360
425
  for (const tokenAddress of additionalTokens) {
361
- if (!knownTokens[tokenAddress]) {
426
+ if (!findKnownTokenById(this.chain.name, tokenAddress, env)) {
362
427
  try {
363
428
  const metadata = await this.getTokenMetadata(tokenAddress);
364
429
  const balance = await this.getTokenBalance(address, tokenAddress);
@@ -376,40 +441,32 @@ var WarpEvmDataLoader = class {
376
441
  return tokenBalances;
377
442
  }
378
443
  async getTokenBalance(address, tokenAddress) {
379
- try {
380
- const contract = new ethers.Contract(tokenAddress, ERC20_ABI, this.provider);
381
- const balance = await contract.balanceOf(address);
382
- return balance;
383
- } catch (error) {
384
- throw new Error(`Failed to get token balance: ${error}`);
385
- }
444
+ const contract = new ethers.Contract(tokenAddress, ERC20_ABI, this.provider);
445
+ const balance = await contract.balanceOf(address);
446
+ return balance;
386
447
  }
387
448
  async getTokenMetadata(tokenAddress) {
388
- try {
389
- const tokenInfo = await EvmLogoService.getTokenInfo(this.chain.name, tokenAddress);
390
- if (tokenInfo.name && tokenInfo.symbol && tokenInfo.decimals !== void 0) {
391
- return {
392
- name: tokenInfo.name,
393
- symbol: tokenInfo.symbol,
394
- decimals: tokenInfo.decimals,
395
- logoUrl: tokenInfo.logoURI
396
- };
397
- }
398
- const contract = new ethers.Contract(tokenAddress, ERC20_ABI, this.provider);
399
- const [name, symbol, decimals] = await Promise.all([
400
- contract.name().catch(() => tokenInfo.name || "Unknown Token"),
401
- contract.symbol().catch(() => tokenInfo.symbol || "UNKNOWN"),
402
- contract.decimals().catch(() => tokenInfo.decimals || 18)
403
- ]);
449
+ const tokenInfo = await EvmLogoService.getTokenInfo(this.chain.name, tokenAddress);
450
+ if (tokenInfo.name && tokenInfo.symbol && tokenInfo.decimals !== void 0) {
404
451
  return {
405
- name: name || tokenInfo.name || "Unknown Token",
406
- symbol: symbol || tokenInfo.symbol || "UNKNOWN",
407
- decimals: decimals || tokenInfo.decimals || 18,
452
+ name: tokenInfo.name,
453
+ symbol: tokenInfo.symbol,
454
+ decimals: tokenInfo.decimals,
408
455
  logoUrl: tokenInfo.logoURI
409
456
  };
410
- } catch (error) {
411
- throw new Error(`Failed to get token metadata: ${error}`);
412
457
  }
458
+ const contract = new ethers.Contract(tokenAddress, ERC20_ABI, this.provider);
459
+ const [name, symbol, decimals] = await Promise.all([
460
+ contract.name().catch(() => tokenInfo.name || "Unknown Token"),
461
+ contract.symbol().catch(() => tokenInfo.symbol || "UNKNOWN"),
462
+ contract.decimals().catch(() => tokenInfo.decimals || 18)
463
+ ]);
464
+ return {
465
+ name: name || tokenInfo.name || "Unknown Token",
466
+ symbol: symbol || tokenInfo.symbol || "UNKNOWN",
467
+ decimals: decimals || tokenInfo.decimals || 18,
468
+ logoUrl: tokenInfo.logoURI
469
+ };
413
470
  }
414
471
  async detectTokensFromEvents(address) {
415
472
  try {
@@ -418,13 +475,7 @@ var WarpEvmDataLoader = class {
418
475
  const filter = {
419
476
  fromBlock,
420
477
  toBlock: currentBlock,
421
- topics: [
422
- ethers.id("Transfer(address,address,uint256)"),
423
- null,
424
- // from address (any)
425
- ethers.zeroPadValue(address, 32)
426
- // to address (our target)
427
- ]
478
+ topics: [ethers.id("Transfer(address,address,uint256)"), null, ethers.zeroPadValue(address, 32)]
428
479
  };
429
480
  const logs = await this.provider.getLogs(filter);
430
481
  const tokenAddresses = /* @__PURE__ */ new Set();
@@ -436,56 +487,13 @@ var WarpEvmDataLoader = class {
436
487
  return [];
437
488
  }
438
489
  }
439
- // Additional utility methods for enhanced token support
440
- async getTokenInfo(tokenAddress) {
441
- try {
442
- return await this.getTokenMetadata(tokenAddress);
443
- } catch (error) {
444
- return null;
445
- }
446
- }
447
- async getTokenBalanceForAddress(address, tokenAddress) {
448
- try {
449
- return await this.getTokenBalance(address, tokenAddress);
450
- } catch (error) {
451
- throw new Error(`Failed to get token balance for ${tokenAddress}: ${error}`);
452
- }
453
- }
454
- async getMultipleTokenBalances(address, tokenAddresses) {
455
- const balances = /* @__PURE__ */ new Map();
456
- await Promise.all(
457
- tokenAddresses.map(async (tokenAddress) => {
458
- try {
459
- const balance = await this.getTokenBalance(address, tokenAddress);
460
- balances.set(tokenAddress, balance);
461
- } catch (error) {
462
- balances.set(tokenAddress, 0n);
463
- }
464
- })
490
+ async getLogoUrl(tokenBalance) {
491
+ return await EvmLogoService.getLogoUrl(
492
+ this.chain.name,
493
+ tokenBalance.tokenAddress,
494
+ tokenBalance.metadata.name,
495
+ tokenBalance.metadata.symbol
465
496
  );
466
- return balances;
467
- }
468
- async getAccountTokens(address) {
469
- return this.getAccountAssets(address);
470
- }
471
- async getTokenMetadataPublic(tokenAddress) {
472
- try {
473
- return await this.getTokenMetadata(tokenAddress);
474
- } catch (error) {
475
- return null;
476
- }
477
- }
478
- async getChainInfo() {
479
- try {
480
- const network = await this.provider.getNetwork();
481
- const latestBlock = await this.provider.getBlock("latest");
482
- return {
483
- chainId: network.chainId.toString(),
484
- blockTime: latestBlock?.timestamp ? Date.now() / 1e3 - latestBlock.timestamp : 12
485
- };
486
- } catch (error) {
487
- throw new Error(`Failed to get chain info: ${error}`);
488
- }
489
497
  }
490
498
  };
491
499