Browse Source

chore: linting and typechecking yak shaving to the nth degree

benduran 3 weeks ago
parent
commit
a615b5a17f
100 changed files with 1274 additions and 1104 deletions
  1. 1 1
      apps/api-reference/package.json
  2. 2 7
      apps/api-reference/tsconfig.build.json
  3. 1 1
      apps/developer-hub/package.json
  4. 2 7
      apps/developer-hub/tsconfig.build.json
  5. 1 1
      apps/entropy-explorer/package.json
  6. 2 7
      apps/entropy-explorer/tsconfig.build.json
  7. 1 1
      apps/entropy-tester/package.json
  8. 2 7
      apps/entropy-tester/tsconfig.build.json
  9. 1 1
      apps/insights/package.json
  10. 2 7
      apps/insights/tsconfig.build.json
  11. 1 1
      apps/price_pusher/package.json
  12. 35 34
      apps/price_pusher/src/aptos/aptos.ts
  13. 11 10
      apps/price_pusher/src/aptos/balance-tracker.ts
  14. 15 8
      apps/price_pusher/src/aptos/command.ts
  15. 7 8
      apps/price_pusher/src/controller.ts
  16. 11 10
      apps/price_pusher/src/evm/balance-tracker.ts
  17. 15 8
      apps/price_pusher/src/evm/command.ts
  18. 11 10
      apps/price_pusher/src/evm/custom-gas-station.ts
  19. 60 63
      apps/price_pusher/src/evm/evm.ts
  20. 3 1
      apps/price_pusher/src/evm/pyth-contract.ts
  21. 13 9
      apps/price_pusher/src/evm/super-wallet.ts
  22. 11 5
      apps/price_pusher/src/fuel/command.ts
  23. 24 15
      apps/price_pusher/src/fuel/fuel.ts
  24. 11 8
      apps/price_pusher/src/index.ts
  25. 12 7
      apps/price_pusher/src/injective/command.ts
  26. 40 37
      apps/price_pusher/src/injective/injective.ts
  27. 13 12
      apps/price_pusher/src/interface.ts
  28. 14 11
      apps/price_pusher/src/metrics.ts
  29. 8 4
      apps/price_pusher/src/near/command.ts
  30. 45 40
      apps/price_pusher/src/near/near.ts
  31. 13 9
      apps/price_pusher/src/price-config.ts
  32. 34 31
      apps/price_pusher/src/pyth-price-listener.ts
  33. 12 11
      apps/price_pusher/src/solana/balance-tracker.ts
  34. 33 19
      apps/price_pusher/src/solana/command.ts
  35. 45 44
      apps/price_pusher/src/solana/solana.ts
  36. 12 11
      apps/price_pusher/src/sui/balance-tracker.ts
  37. 17 10
      apps/price_pusher/src/sui/command.ts
  38. 47 47
      apps/price_pusher/src/sui/sui.ts
  39. 10 5
      apps/price_pusher/src/ton/command.ts
  40. 23 26
      apps/price_pusher/src/ton/ton.ts
  41. 15 7
      apps/price_pusher/src/utils.ts
  42. 1 1
      apps/staking/package.json
  43. 2 7
      apps/staking/tsconfig.build.json
  44. 11 13
      contract_manager/scripts/batchDeployReceivers.ts
  45. 18 13
      contract_manager/scripts/check_proposal.ts
  46. 14 13
      contract_manager/scripts/common.ts
  47. 2 1
      contract_manager/scripts/deploy_cosmwasm.ts
  48. 7 6
      contract_manager/scripts/deploy_evm_contract.ts
  49. 16 15
      contract_manager/scripts/deploy_evm_entropy_contracts.ts
  50. 5 4
      contract_manager/scripts/deploy_evm_executor_contracts.ts
  51. 7 5
      contract_manager/scripts/deploy_evm_lazer_contracts.ts
  52. 6 5
      contract_manager/scripts/deploy_evm_pricefeed_contracts.ts
  53. 8 6
      contract_manager/scripts/deploy_evm_pulse_contracts.ts
  54. 3 2
      contract_manager/scripts/entropy-accept-admin-and-ownership.ts
  55. 9 8
      contract_manager/scripts/entropy_debug_reveal.ts
  56. 11 19
      contract_manager/scripts/execute_vaas.ts
  57. 3 2
      contract_manager/scripts/fetch_account_balance.ts
  58. 4 3
      contract_manager/scripts/fetch_accrued_entropy_dao_fees.ts
  59. 3 2
      contract_manager/scripts/fetch_fees.ts
  60. 3 2
      contract_manager/scripts/generate_evm_lazer_update_trusted_signer_proposal.ts
  61. 2 1
      contract_manager/scripts/generate_governance_set_fee_payload.ts
  62. 4 3
      contract_manager/scripts/generate_upgrade_near_contract_proposal.ts
  63. 8 6
      contract_manager/scripts/generate_upgrade_ton_contract_proposal.ts
  64. 3 2
      contract_manager/scripts/get_entropy_registration.ts
  65. 7 6
      contract_manager/scripts/latency_entropy.ts
  66. 4 3
      contract_manager/scripts/latency_entropy_with_callback.ts
  67. 6 5
      contract_manager/scripts/list_entropy_contracts.ts
  68. 4 3
      contract_manager/scripts/list_evm_contracts.ts
  69. 4 3
      contract_manager/scripts/list_wormhole_contracts.ts
  70. 5 4
      contract_manager/scripts/load_test_entropy.ts
  71. 1 0
      contract_manager/scripts/send_message_to_wormhole.ts
  72. 7 6
      contract_manager/scripts/sync_governance_vaas.ts
  73. 6 5
      contract_manager/scripts/sync_wormhole_guardian_set.ts
  74. 15 14
      contract_manager/scripts/transfer_balance_entropy_chains.ts
  75. 3 2
      contract_manager/scripts/update_all_pricefeeds.ts
  76. 3 2
      contract_manager/scripts/update_pricefeed.ts
  77. 11 10
      contract_manager/scripts/upgrade_evm_entropy_contracts.ts
  78. 8 7
      contract_manager/scripts/upgrade_evm_pricefeed_contracts.ts
  79. 8 5
      contract_manager/scripts/upgrade_ton_contract.ts
  80. 2 1
      contract_manager/scripts/upload_cosmwasm.ts
  81. 4 3
      contract_manager/src/core/base.ts
  82. 43 44
      contract_manager/src/core/chains.ts
  83. 12 10
      contract_manager/src/core/contracts/aptos.ts
  84. 31 29
      contract_manager/src/core/contracts/cosmwasm.ts
  85. 11 9
      contract_manager/src/core/contracts/evm.ts
  86. 2 1
      contract_manager/src/core/contracts/evm_abis.ts
  87. 21 20
      contract_manager/src/core/contracts/fuel.ts
  88. 37 37
      contract_manager/src/core/contracts/iota.ts
  89. 40 39
      contract_manager/src/core/contracts/near.ts
  90. 23 14
      contract_manager/src/core/contracts/starknet.ts
  91. 37 37
      contract_manager/src/core/contracts/sui.ts
  92. 6 4
      contract_manager/src/core/contracts/wormhole.ts
  93. 8 3
      contract_manager/src/core/token.ts
  94. 7 5
      contract_manager/src/node/utils/executor.ts
  95. 62 45
      contract_manager/src/node/utils/governance.ts
  96. 33 23
      contract_manager/src/node/utils/store.ts
  97. 5 3
      contract_manager/src/utils/utils.ts
  98. 4 0
      governance/pyth_staking_sdk/src/utils/transaction.ts
  99. 4 1
      governance/xc_admin/packages/xc_admin_common/src/message_buffer.ts
  100. 4 1
      governance/xc_admin/packages/xc_admin_common/src/multisig.ts

+ 1 - 1
apps/api-reference/package.json

@@ -66,4 +66,4 @@
     "vercel": "catalog:"
     "vercel": "catalog:"
   },
   },
   "packageManager": "pnpm@10.19.0"
   "packageManager": "pnpm@10.19.0"
-}
+}

+ 2 - 7
apps/api-reference/tsconfig.build.json

@@ -5,10 +5,5 @@
     "incremental": false,
     "incremental": false,
     "declaration": true
     "declaration": true
   },
   },
-  "exclude": [
-    "node_modules",
-    "dist",
-    "examples/",
-    "**/__tests__/*"
-  ]
-}
+  "exclude": ["node_modules", "dist", "examples/", "**/__tests__/*"]
+}

+ 1 - 1
apps/developer-hub/package.json

@@ -74,4 +74,4 @@
     "vercel": "catalog:"
     "vercel": "catalog:"
   },
   },
   "packageManager": "pnpm@10.19.0"
   "packageManager": "pnpm@10.19.0"
-}
+}

+ 2 - 7
apps/developer-hub/tsconfig.build.json

@@ -5,10 +5,5 @@
     "incremental": false,
     "incremental": false,
     "declaration": true
     "declaration": true
   },
   },
-  "exclude": [
-    "node_modules",
-    "dist",
-    "examples/",
-    "**/__tests__/*"
-  ]
-}
+  "exclude": ["node_modules", "dist", "examples/", "**/__tests__/*"]
+}

+ 1 - 1
apps/entropy-explorer/package.json

@@ -54,4 +54,4 @@
     "vercel": "catalog:"
     "vercel": "catalog:"
   },
   },
   "packageManager": "pnpm@10.19.0"
   "packageManager": "pnpm@10.19.0"
-}
+}

+ 2 - 7
apps/entropy-explorer/tsconfig.build.json

@@ -5,10 +5,5 @@
     "incremental": false,
     "incremental": false,
     "declaration": true
     "declaration": true
   },
   },
-  "exclude": [
-    "node_modules",
-    "dist",
-    "examples/",
-    "**/__tests__/*"
-  ]
-}
+  "exclude": ["node_modules", "dist", "examples/", "**/__tests__/*"]
+}

+ 1 - 1
apps/entropy-tester/package.json

@@ -67,4 +67,4 @@
     "pnpm": ">=10.19.0"
     "pnpm": ">=10.19.0"
   },
   },
   "packageManager": "pnpm@10.19.0"
   "packageManager": "pnpm@10.19.0"
-}
+}

+ 2 - 7
apps/entropy-tester/tsconfig.build.json

@@ -7,10 +7,5 @@
     "declaration": true,
     "declaration": true,
     "isolatedModules": false
     "isolatedModules": false
   },
   },
-  "exclude": [
-    "node_modules",
-    "dist",
-    "examples/",
-    "**/__tests__/*"
-  ]
-}
+  "exclude": ["node_modules", "dist", "examples/", "**/__tests__/*"]
+}

+ 1 - 1
apps/insights/package.json

@@ -75,4 +75,4 @@
     "vercel": "catalog:"
     "vercel": "catalog:"
   },
   },
   "packageManager": "pnpm@10.19.0"
   "packageManager": "pnpm@10.19.0"
-}
+}

+ 2 - 7
apps/insights/tsconfig.build.json

@@ -5,10 +5,5 @@
     "incremental": false,
     "incremental": false,
     "declaration": true
     "declaration": true
   },
   },
-  "exclude": [
-    "node_modules",
-    "dist",
-    "examples/",
-    "**/__tests__/*"
-  ]
-}
+  "exclude": ["node_modules", "dist", "examples/", "**/__tests__/*"]
+}

+ 1 - 1
apps/price_pusher/package.json

@@ -233,4 +233,4 @@
     "./package.json": "./package.json"
     "./package.json": "./package.json"
   },
   },
   "module": "./dist/esm/index.js"
   "module": "./dist/esm/index.js"
-}
+}

+ 35 - 34
apps/price_pusher/src/aptos/aptos.ts

@@ -1,14 +1,17 @@
-import {
-  ChainPriceListener,
-  type IPricePusher,
-  type PriceInfo,
-  type PriceItem,
-} from "../interface.js";
-import { AptosAccount, AptosClient } from "aptos";
-import type { DurationInSeconds } from "../utils.js";
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
+/* eslint-disable unicorn/no-await-expression-member */
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
+/* eslint-disable @typescript-eslint/no-explicit-any */
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
 import { HermesClient } from "@pythnetwork/hermes-client";
 import { HermesClient } from "@pythnetwork/hermes-client";
+import { AptosAccount, AptosClient } from "aptos";
 import type { Logger } from "pino";
 import type { Logger } from "pino";
 
 
+import type { IPricePusher, PriceInfo, PriceItem } from "../interface.js";
+import { ChainPriceListener } from "../interface.js";
+import type { DurationInSeconds } from "../utils.js";
+
 export class AptosPriceListener extends ChainPriceListener {
 export class AptosPriceListener extends ChainPriceListener {
   constructor(
   constructor(
     private pythModule: string,
     private pythModule: string,
@@ -49,9 +52,9 @@ export class AptosPriceListener extends ChainPriceListener {
         multiplier * Number(priceItemRes.price_feed.price.price.magnitude);
         multiplier * Number(priceItemRes.price_feed.price.price.magnitude);
 
 
       this.logger.debug(
       this.logger.debug(
-        `Polled an Aptos on-chain price for feed ${this.priceIdToAlias.get(
-          priceId,
-        )} (${priceId}).`,
+        `Polled an Aptos on-chain price for feed ${
+          this.priceIdToAlias.get(priceId) ?? ""
+        } (${priceId}).`,
       );
       );
 
 
       return {
       return {
@@ -59,9 +62,9 @@ export class AptosPriceListener extends ChainPriceListener {
         conf: priceItemRes.price_feed.price.conf,
         conf: priceItemRes.price_feed.price.conf,
         publishTime: Number(priceItemRes.price_feed.price.timestamp),
         publishTime: Number(priceItemRes.price_feed.price.timestamp),
       };
       };
-    } catch (err) {
+    } catch (error) {
       this.logger.error(
       this.logger.error(
-        err,
+        error,
         `Polling Aptos on-chain price for ${priceId} failed.`,
         `Polling Aptos on-chain price for ${priceId} failed.`,
       );
       );
       return undefined;
       return undefined;
@@ -104,7 +107,7 @@ export class AptosPricePusher implements IPricePusher {
    * Gets price update data which then can be submitted to the Pyth contract to update the prices.
    * Gets price update data which then can be submitted to the Pyth contract to update the prices.
    * This will throw an axios error if there is a network problem or the price service returns a non-ok response (e.g: Invalid price ids)
    * This will throw an axios error if there is a network problem or the price service returns a non-ok response (e.g: Invalid price ids)
    *
    *
-   * @param priceIds Array of hex-encoded price ids.
+   * @param priceIds - Array of hex-encoded price ids.
    * @returns Array of price update data.
    * @returns Array of price update data.
    */
    */
   async getPriceFeedsUpdateData(priceIds: string[]): Promise<number[][]> {
   async getPriceFeedsUpdateData(priceIds: string[]): Promise<number[][]> {
@@ -112,9 +115,7 @@ export class AptosPricePusher implements IPricePusher {
       encoding: "base64",
       encoding: "base64",
       ignoreInvalidPriceIds: true,
       ignoreInvalidPriceIds: true,
     });
     });
-    return response.binary.data.map((data) =>
-      Array.from(Buffer.from(data, "base64")),
-    );
+    return response.binary.data.map((data) => [...Buffer.from(data, "base64")]);
   }
   }
 
 
   async updatePriceFeed(
   async updatePriceFeed(
@@ -132,8 +133,8 @@ export class AptosPricePusher implements IPricePusher {
     try {
     try {
       // get the latest VAAs for updatePriceFeed and then push them
       // get the latest VAAs for updatePriceFeed and then push them
       priceFeedUpdateData = await this.getPriceFeedsUpdateData(priceIds);
       priceFeedUpdateData = await this.getPriceFeedsUpdateData(priceIds);
-    } catch (err) {
-      this.logger.error(err, "Error fetching the latest vaas to push.");
+    } catch (error) {
+      this.logger.error(error, "Error fetching the latest vaas to push.");
       return;
       return;
     }
     }
 
 
@@ -152,7 +153,7 @@ export class AptosPricePusher implements IPricePusher {
         arguments: [priceFeedUpdateData],
         arguments: [priceFeedUpdateData],
       },
       },
       {
       {
-        sequence_number: sequenceNumber.toFixed(),
+        sequence_number: sequenceNumber.toFixed(0),
       },
       },
     );
     );
 
 
@@ -169,11 +170,11 @@ export class AptosPricePusher implements IPricePusher {
       // to go out of sync. Missing transactions are rare and we don't want this check to block
       // to go out of sync. Missing transactions are rare and we don't want this check to block
       // the next price update. So we use spawn a promise without awaiting on it to wait for the
       // the next price update. So we use spawn a promise without awaiting on it to wait for the
       // transaction to be confirmed and if it fails, it resets the sequence number and return.
       // transaction to be confirmed and if it fails, it resets the sequence number and return.
-      this.waitForTransactionConfirmation(client, pendingTx.hash);
+      void this.waitForTransactionConfirmation(client, pendingTx.hash);
 
 
       return;
       return;
-    } catch (err: any) {
-      this.logger.error(err, "Error executing messages");
+    } catch (error: any) {
+      this.logger.error(error, "Error executing messages");
 
 
       // Reset the sequence number to re-sync it (in case that was the issue)
       // Reset the sequence number to re-sync it (in case that was the issue)
       this.lastSequenceNumber = undefined;
       this.lastSequenceNumber = undefined;
@@ -194,9 +195,9 @@ export class AptosPricePusher implements IPricePusher {
       });
       });
 
 
       this.logger.info({ hash: txHash }, `Transaction confirmed.`);
       this.logger.info({ hash: txHash }, `Transaction confirmed.`);
-    } catch (err) {
+    } catch (error) {
       this.logger.error(
       this.logger.error(
-        { err, hash: txHash },
+        { err: error, hash: txHash },
         `Transaction failed to confirm.`,
         `Transaction failed to confirm.`,
       );
       );
 
 
@@ -211,14 +212,13 @@ export class AptosPricePusher implements IPricePusher {
     client: AptosClient,
     client: AptosClient,
     account: AptosAccount,
     account: AptosAccount,
   ): Promise<number> {
   ): Promise<number> {
-    if (this.lastSequenceNumber !== undefined) {
-      this.lastSequenceNumber += 1;
-      return this.lastSequenceNumber;
-    } else {
+    if (this.lastSequenceNumber === undefined) {
       // Fetch from the blockchain if we don't have the local cache.
       // Fetch from the blockchain if we don't have the local cache.
       // Note that this is locked so that only 1 fetch occurs regardless of how many updates
       // Note that this is locked so that only 1 fetch occurs regardless of how many updates
       // happen during that fetch.
       // happen during that fetch.
-      if (!this.sequenceNumberLocked) {
+      if (this.sequenceNumberLocked) {
+        throw new Error("Waiting for sequence number in another thread.");
+      } else {
         try {
         try {
           this.sequenceNumberLocked = true;
           this.sequenceNumberLocked = true;
           this.lastSequenceNumber = Number(
           this.lastSequenceNumber = Number(
@@ -228,14 +228,15 @@ export class AptosPricePusher implements IPricePusher {
             `Fetched account sequence number: ${this.lastSequenceNumber}`,
             `Fetched account sequence number: ${this.lastSequenceNumber}`,
           );
           );
           return this.lastSequenceNumber;
           return this.lastSequenceNumber;
-        } catch (e: any) {
-          throw new Error("Failed to retrieve sequence number" + e);
+        } catch (error: any) {
+          throw new Error(`Failed to retrieve sequence number ${error}`);
         } finally {
         } finally {
           this.sequenceNumberLocked = false;
           this.sequenceNumberLocked = false;
         }
         }
-      } else {
-        throw new Error("Waiting for sequence number in another thread.");
       }
       }
+    } else {
+      this.lastSequenceNumber += 1;
+      return this.lastSequenceNumber;
     }
     }
   }
   }
 }
 }

+ 11 - 10
apps/price_pusher/src/aptos/balance-tracker.ts

@@ -1,24 +1,25 @@
 import { Aptos, AptosConfig, Network } from "@aptos-labs/ts-sdk";
 import { Aptos, AptosConfig, Network } from "@aptos-labs/ts-sdk";
-import {
-  BaseBalanceTracker,
-  type BaseBalanceTrackerConfig,
-  type IBalanceTracker,
+import type { Logger } from "pino";
+
+import type {
+  BaseBalanceTrackerConfig,
+  IBalanceTracker,
 } from "../interface.js";
 } from "../interface.js";
-import type { DurationInSeconds } from "../utils.js";
+import { BaseBalanceTracker } from "../interface.js";
 import { PricePusherMetrics } from "../metrics.js";
 import { PricePusherMetrics } from "../metrics.js";
-import type { Logger } from "pino";
+import type { DurationInSeconds } from "../utils.js";
 
 
 /**
 /**
  * Aptos-specific configuration for balance tracker
  * Aptos-specific configuration for balance tracker
  */
  */
-export interface AptosBalanceTrackerConfig extends BaseBalanceTrackerConfig {
+export type AptosBalanceTrackerConfig = {
   /** Aptos node endpoint URL */
   /** Aptos node endpoint URL */
   endpoint: string;
   endpoint: string;
   /** Aptos account address */
   /** Aptos account address */
   address: string;
   address: string;
   /** Optional decimal places for APT token (default: 8) */
   /** Optional decimal places for APT token (default: 8) */
   decimals?: number;
   decimals?: number;
-}
+} & BaseBalanceTrackerConfig;
 
 
 /**
 /**
  * Aptos-specific implementation of the balance tracker
  * Aptos-specific implementation of the balance tracker
@@ -80,7 +81,7 @@ export class AptosBalanceTracker extends BaseBalanceTracker {
 /**
 /**
  * Parameters for creating an Aptos balance tracker
  * Parameters for creating an Aptos balance tracker
  */
  */
-export interface CreateAptosBalanceTrackerParams {
+export type CreateAptosBalanceTrackerParams = {
   endpoint: string;
   endpoint: string;
   address: string;
   address: string;
   network: string;
   network: string;
@@ -88,7 +89,7 @@ export interface CreateAptosBalanceTrackerParams {
   metrics: PricePusherMetrics;
   metrics: PricePusherMetrics;
   logger: Logger;
   logger: Logger;
   decimals?: number;
   decimals?: number;
-}
+};
 
 
 /**
 /**
  * Factory function to create a balance tracker for Aptos chain
  * Factory function to create a balance tracker for Aptos chain

+ 15 - 8
apps/price_pusher/src/aptos/command.ts

@@ -1,19 +1,26 @@
+/* eslint-disable @typescript-eslint/no-non-null-assertion */
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import fs from "node:fs";
+
 import { HermesClient } from "@pythnetwork/hermes-client";
 import { HermesClient } from "@pythnetwork/hermes-client";
+import { AptosAccount } from "aptos";
+import pino from "pino";
+import type { Options } from "yargs";
+
+import { Controller } from "../controller.js";
+import { PricePusherMetrics } from "../metrics.js";
 import * as options from "../options.js";
 import * as options from "../options.js";
 import { readPriceConfigFile } from "../price-config.js";
 import { readPriceConfigFile } from "../price-config.js";
-import fs from "fs";
 import { PythPriceListener } from "../pyth-price-listener.js";
 import { PythPriceListener } from "../pyth-price-listener.js";
-import { Controller } from "../controller.js";
-import type { Options } from "yargs";
 import {
 import {
   AptosPriceListener,
   AptosPriceListener,
   AptosPricePusher,
   AptosPricePusher,
   APTOS_ACCOUNT_HD_PATH,
   APTOS_ACCOUNT_HD_PATH,
 } from "./aptos.js";
 } from "./aptos.js";
-import { AptosAccount } from "aptos";
-import pino from "pino";
 import { filterInvalidPriceItems } from "../utils.js";
 import { filterInvalidPriceItems } from "../utils.js";
-import { PricePusherMetrics } from "../metrics.js";
 import { createAptosBalanceTracker } from "./balance-tracker.js";
 import { createAptosBalanceTracker } from "./balance-tracker.js";
 
 
 export default {
 export default {
@@ -76,7 +83,7 @@ export default {
       logger.info(`Metrics server started on port ${metricsPort}`);
       logger.info(`Metrics server started on port ${metricsPort}`);
     }
     }
 
 
-    const mnemonic = fs.readFileSync(mnemonicFile, "utf-8").trim();
+    const mnemonic = fs.readFileSync(mnemonicFile, "utf8").trim();
     const account = AptosAccount.fromDerivePath(
     const account = AptosAccount.fromDerivePath(
       APTOS_ACCOUNT_HD_PATH,
       APTOS_ACCOUNT_HD_PATH,
       mnemonic,
       mnemonic,
@@ -149,6 +156,6 @@ export default {
       await balanceTracker.start();
       await balanceTracker.start();
     }
     }
 
 
-    controller.start();
+    void controller.start();
   },
   },
 };
 };

+ 7 - 8
apps/price_pusher/src/controller.ts

@@ -1,13 +1,12 @@
 import type { UnixTimestamp } from "@pythnetwork/hermes-client";
 import type { UnixTimestamp } from "@pythnetwork/hermes-client";
-import { type DurationInSeconds, sleep } from "./utils.js";
-import type { IPriceListener, IPricePusher } from "./interface.js";
-import {
-  type PriceConfig,
-  shouldUpdate,
-  UpdateCondition,
-} from "./price-config.js";
 import type { Logger } from "pino";
 import type { Logger } from "pino";
+
+import type { IPriceListener, IPricePusher } from "./interface.js";
 import { PricePusherMetrics } from "./metrics.js";
 import { PricePusherMetrics } from "./metrics.js";
+import type { PriceConfig } from "./price-config.js";
+import { shouldUpdate, UpdateCondition } from "./price-config.js";
+import type { DurationInSeconds } from "./utils.js";
+import { sleep } from "./utils.js";
 
 
 export class Controller {
 export class Controller {
   private pushingFrequency: DurationInSeconds;
   private pushingFrequency: DurationInSeconds;
@@ -94,7 +93,7 @@ export class Controller {
           priceShouldUpdate == UpdateCondition.EARLY
           priceShouldUpdate == UpdateCondition.EARLY
         ) {
         ) {
           pricesToPush.push(priceConfig);
           pricesToPush.push(priceConfig);
-          pubTimesToPush.push((targetLatestPrice?.publishTime || 0) + 1);
+          pubTimesToPush.push((targetLatestPrice?.publishTime ?? 0) + 1);
         }
         }
       }
       }
       if (pushThresholdMet) {
       if (pushThresholdMet) {

+ 11 - 10
apps/price_pusher/src/evm/balance-tracker.ts

@@ -1,22 +1,23 @@
+import type { Logger } from "pino";
+
 import type { SuperWalletClient } from "./super-wallet.js";
 import type { SuperWalletClient } from "./super-wallet.js";
-import {
-  BaseBalanceTracker,
-  type BaseBalanceTrackerConfig,
-  type IBalanceTracker,
+import type {
+  BaseBalanceTrackerConfig,
+  IBalanceTracker,
 } from "../interface.js";
 } from "../interface.js";
-import type { DurationInSeconds } from "../utils.js";
+import { BaseBalanceTracker } from "../interface.js";
 import { PricePusherMetrics } from "../metrics.js";
 import { PricePusherMetrics } from "../metrics.js";
-import type { Logger } from "pino";
+import type { DurationInSeconds } from "../utils.js";
 
 
 /**
 /**
  * EVM-specific configuration for balance tracker
  * EVM-specific configuration for balance tracker
  */
  */
-export interface EvmBalanceTrackerConfig extends BaseBalanceTrackerConfig {
+export type EvmBalanceTrackerConfig = {
   /** EVM wallet client */
   /** EVM wallet client */
   client: SuperWalletClient;
   client: SuperWalletClient;
   /** EVM address with 0x prefix */
   /** EVM address with 0x prefix */
   address: `0x${string}`;
   address: `0x${string}`;
-}
+} & BaseBalanceTrackerConfig;
 
 
 /**
 /**
  * EVM-specific implementation of the balance tracker
  * EVM-specific implementation of the balance tracker
@@ -60,14 +61,14 @@ export class EvmBalanceTracker extends BaseBalanceTracker {
 /**
 /**
  * Parameters for creating an EVM balance tracker
  * Parameters for creating an EVM balance tracker
  */
  */
-export interface CreateEvmBalanceTrackerParams {
+export type CreateEvmBalanceTrackerParams = {
   client: SuperWalletClient;
   client: SuperWalletClient;
   address: `0x${string}`;
   address: `0x${string}`;
   network: string;
   network: string;
   updateInterval: DurationInSeconds;
   updateInterval: DurationInSeconds;
   metrics: PricePusherMetrics;
   metrics: PricePusherMetrics;
   logger: Logger;
   logger: Logger;
-}
+};
 
 
 /**
 /**
  * Factory function to create a balance tracker for EVM chains
  * Factory function to create a balance tracker for EVM chains

+ 15 - 8
apps/price_pusher/src/evm/command.ts

@@ -1,17 +1,24 @@
+/* eslint-disable @typescript-eslint/no-non-null-assertion */
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import fs from "node:fs";
+
 import { HermesClient } from "@pythnetwork/hermes-client";
 import { HermesClient } from "@pythnetwork/hermes-client";
-import fs from "fs";
+import pino from "pino";
 import type { Options } from "yargs";
 import type { Options } from "yargs";
+
+import { Controller } from "../controller.js";
 import * as options from "../options.js";
 import * as options from "../options.js";
 import { readPriceConfigFile } from "../price-config.js";
 import { readPriceConfigFile } from "../price-config.js";
 import { PythPriceListener } from "../pyth-price-listener.js";
 import { PythPriceListener } from "../pyth-price-listener.js";
-import { Controller } from "../controller.js";
-import { EvmPriceListener, EvmPricePusher } from "./evm.js";
 import { getCustomGasStation } from "./custom-gas-station.js";
 import { getCustomGasStation } from "./custom-gas-station.js";
-import pino from "pino";
-import { createClient } from "./super-wallet.js";
+import { EvmPriceListener, EvmPricePusher } from "./evm.js";
 import { createPythContract } from "./pyth-contract.js";
 import { createPythContract } from "./pyth-contract.js";
-import { isWsEndpoint, filterInvalidPriceItems } from "../utils.js";
+import { createClient } from "./super-wallet.js";
 import { PricePusherMetrics } from "../metrics.js";
 import { PricePusherMetrics } from "../metrics.js";
+import { isWsEndpoint, filterInvalidPriceItems } from "../utils.js";
 import { createEvmBalanceTracker } from "./balance-tracker.js";
 import { createEvmBalanceTracker } from "./balance-tracker.js";
 
 
 export default {
 export default {
@@ -118,7 +125,7 @@ export default {
     const priceConfigs = readPriceConfigFile(priceConfigFile);
     const priceConfigs = readPriceConfigFile(priceConfigFile);
     const hermesClient = new HermesClient(priceServiceEndpoint);
     const hermesClient = new HermesClient(priceServiceEndpoint);
 
 
-    const mnemonic = fs.readFileSync(mnemonicFile, "utf-8").trim();
+    const mnemonic = fs.readFileSync(mnemonicFile, "utf8").trim();
 
 
     let priceItems = priceConfigs.map(({ id, alias }) => ({ id, alias }));
     let priceItems = priceConfigs.map(({ id, alias }) => ({ id, alias }));
 
 
@@ -217,6 +224,6 @@ export default {
       await balanceTracker.start();
       await balanceTracker.start();
     }
     }
 
 
-    await controller.start();
+    void controller.start();
   },
   },
 };
 };

+ 11 - 10
apps/price_pusher/src/evm/custom-gas-station.ts

@@ -1,13 +1,14 @@
-import {
-  type CustomGasChainId,
-  type TxSpeed,
-  verifyValidOption,
-  txSpeeds,
-  customGasChainIds,
-} from "../utils.js";
+/* eslint-disable @typescript-eslint/no-explicit-any */
+/* eslint-disable @typescript-eslint/no-unsafe-call */
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
 import type { Logger } from "pino";
 import type { Logger } from "pino";
 import { parseGwei } from "viem";
 import { parseGwei } from "viem";
 
 
+import type { CustomGasChainId, TxSpeed } from "../utils.js";
+import { verifyValidOption, txSpeeds, customGasChainIds } from "../utils.js";
+
 type chainMethods = Record<CustomGasChainId, () => Promise<bigint | undefined>>;
 type chainMethods = Record<CustomGasChainId, () => Promise<bigint | undefined>>;
 
 
 export class CustomGasStation {
 export class CustomGasStation {
@@ -34,12 +35,12 @@ export class CustomGasStation {
       const jsonRes = (await res.json()) as any;
       const jsonRes = (await res.json()) as any;
       const gasPrice = jsonRes[this.speed].maxFee;
       const gasPrice = jsonRes[this.speed].maxFee;
       return parseGwei(gasPrice.toFixed(2));
       return parseGwei(gasPrice.toFixed(2));
-    } catch (err) {
+    } catch (error) {
       this.logger.error(
       this.logger.error(
-        err,
+        error,
         "Failed to fetch gas price from Matic mainnet. Returning undefined",
         "Failed to fetch gas price from Matic mainnet. Returning undefined",
       );
       );
-      return undefined;
+      return;
     }
     }
   }
   }
 }
 }

+ 60 - 63
apps/price_pusher/src/evm/evm.ts

@@ -1,26 +1,13 @@
-import {
-  type IPricePusher,
-  type PriceInfo,
-  ChainPriceListener,
-  type PriceItem,
-} from "../interface.js";
-import {
-  addLeading0x,
-  assertDefined,
-  type DurationInSeconds,
-  removeLeading0x,
-} from "../utils.js";
-import { PythAbi } from "./pyth-abi.js";
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+/* eslint-disable @typescript-eslint/no-explicit-any */
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
+/* eslint-disable @typescript-eslint/require-await */
+import type { HexString, UnixTimestamp } from "@pythnetwork/hermes-client";
+import { HermesClient } from "@pythnetwork/hermes-client";
 import type { Logger } from "pino";
 import type { Logger } from "pino";
+import type { WatchContractEventOnLogsParameter } from "viem";
 import {
 import {
-  HermesClient,
-  type HexString,
-  type UnixTimestamp,
-} from "@pythnetwork/hermes-client";
-import { CustomGasStation } from "./custom-gas-station";
-import type { PushAttempt } from "../common.js";
-import {
-  type WatchContractEventOnLogsParameter,
   TransactionExecutionError,
   TransactionExecutionError,
   BaseError,
   BaseError,
   ContractFunctionRevertedError,
   ContractFunctionRevertedError,
@@ -30,8 +17,15 @@ import {
   ContractFunctionExecutionError,
   ContractFunctionExecutionError,
 } from "viem";
 } from "viem";
 
 
+import type { PushAttempt } from "../common.js";
+import type { IPricePusher, PriceInfo, PriceItem } from "../interface.js";
+import type { DurationInSeconds } from "../utils.js";
+import { CustomGasStation } from "./custom-gas-station";
 import type { PythContract } from "./pyth-contract.js";
 import type { PythContract } from "./pyth-contract.js";
+import { addLeading0x, assertDefined, removeLeading0x } from "../utils.js";
+import { PythAbi } from "./pyth-abi.js";
 import type { SuperWalletClient } from "./super-wallet.js";
 import type { SuperWalletClient } from "./super-wallet.js";
+import { ChainPriceListener } from "../interface.js";
 
 
 export class EvmPriceListener extends ChainPriceListener {
 export class EvmPriceListener extends ChainPriceListener {
   constructor(
   constructor(
@@ -54,7 +48,7 @@ export class EvmPriceListener extends ChainPriceListener {
   override async start() {
   override async start() {
     if (this.watchEvents) {
     if (this.watchEvents) {
       this.logger.info("Watching target network pyth contract events...");
       this.logger.info("Watching target network pyth contract events...");
-      this.startWatching();
+      void this.startWatching();
     } else {
     } else {
       this.logger.info(
       this.logger.info(
         "The target network RPC endpoint is not Websocket. " +
         "The target network RPC endpoint is not Websocket. " +
@@ -104,8 +98,8 @@ export class EvmPriceListener extends ChainPriceListener {
       priceRaw = await this.pythContract.read.getPriceUnsafe([
       priceRaw = await this.pythContract.read.getPriceUnsafe([
         addLeading0x(priceId),
         addLeading0x(priceId),
       ]);
       ]);
-    } catch (err) {
-      this.logger.error(err, `Polling on-chain price for ${priceId} failed.`);
+    } catch (error) {
+      this.logger.error(error, `Polling on-chain price for ${priceId} failed.`);
       return undefined;
       return undefined;
     }
     }
 
 
@@ -175,12 +169,12 @@ export class EvmPricePusher implements IPricePusher {
         Math.round(Number(updateFee) * (this.updateFeeMultiplier || 1)),
         Math.round(Number(updateFee) * (this.updateFeeMultiplier || 1)),
       );
       );
       this.logger.debug(`Update fee: ${updateFee}`);
       this.logger.debug(`Update fee: ${updateFee}`);
-    } catch (e: any) {
+    } catch (error: any) {
       this.logger.error(
       this.logger.error(
-        e,
+        error,
         "An unidentified error has occured when getting the update fee.",
         "An unidentified error has occured when getting the update fee.",
       );
       );
-      throw e;
+      throw error;
     }
     }
 
 
     // Gas price in networks with transaction type eip1559 represents the
     // Gas price in networks with transaction type eip1559 represents the
@@ -195,9 +189,7 @@ export class EvmPricePusher implements IPricePusher {
       );
       );
 
 
     // Try to re-use the same nonce and increase the gas if the last tx is not landed yet.
     // Try to re-use the same nonce and increase the gas if the last tx is not landed yet.
-    if (this.pusherAddress === undefined) {
-      this.pusherAddress = this.client.account.address;
-    }
+    this.pusherAddress ??= this.client.account.address;
 
 
     const lastExecutedNonce =
     const lastExecutedNonce =
       (await this.client.getTransactionCount({
       (await this.client.getTransactionCount({
@@ -229,9 +221,7 @@ export class EvmPricePusher implements IPricePusher {
 
 
     this.logger.debug(`Using gas price: ${gasPrice} and nonce: ${txNonce}`);
     this.logger.debug(`Using gas price: ${gasPrice} and nonce: ${txNonce}`);
 
 
-    const pubTimesToPushParam = pubTimesToPush.map((pubTime) =>
-      BigInt(pubTime),
-    );
+    const pubTimesToPushParam = pubTimesToPush.map(BigInt);
 
 
     const priceIdsWith0x = priceIds.map((priceId) => addLeading0x(priceId));
     const priceIdsWith0x = priceIds.map((priceId) => addLeading0x(priceId));
 
 
@@ -250,9 +240,9 @@ export class EvmPricePusher implements IPricePusher {
             gasPrice: BigInt(Math.ceil(gasPrice)),
             gasPrice: BigInt(Math.ceil(gasPrice)),
             nonce: txNonce,
             nonce: txNonce,
             gas:
             gas:
-              this.gasLimit !== undefined
-                ? BigInt(Math.ceil(this.gasLimit))
-                : undefined,
+              this.gasLimit === undefined
+                ? undefined
+                : BigInt(Math.ceil(this.gasLimit)),
           },
           },
         );
         );
 
 
@@ -262,13 +252,16 @@ export class EvmPricePusher implements IPricePusher {
 
 
       this.logger.info({ hash }, "Price update sent");
       this.logger.info({ hash }, "Price update sent");
 
 
-      this.waitForTransactionReceipt(hash);
-    } catch (err: any) {
-      this.logger.debug({ err }, "Simulating or sending transactions failed.");
+      void this.waitForTransactionReceipt(hash);
+    } catch (error: any) {
+      this.logger.debug(
+        { err: error },
+        "Simulating or sending transactions failed.",
+      );
 
 
-      if (err instanceof BaseError) {
+      if (error instanceof BaseError) {
         if (
         if (
-          err.walk(
+          error.walk(
             (e) =>
             (e) =>
               e instanceof ContractFunctionRevertedError &&
               e instanceof ContractFunctionRevertedError &&
               e.data?.errorName === "NoFreshUpdate",
               e.data?.errorName === "NoFreshUpdate",
@@ -280,18 +273,18 @@ export class EvmPricePusher implements IPricePusher {
           return;
           return;
         }
         }
 
 
-        if (err.walk((e) => e instanceof InsufficientFundsError)) {
+        if (error.walk((e) => e instanceof InsufficientFundsError)) {
           this.logger.error(
           this.logger.error(
-            { err },
+            { err: error },
             "Wallet doesn't have enough balance. In rare cases, there might be issues with gas price " +
             "Wallet doesn't have enough balance. In rare cases, there might be issues with gas price " +
               "calculation in the RPC.",
               "calculation in the RPC.",
           );
           );
-          throw err;
+          throw error;
         }
         }
 
 
         if (
         if (
-          err.walk((e) => e instanceof FeeCapTooLowError) ||
-          err.walk(
+          error.walk((e) => e instanceof FeeCapTooLowError) ||
+          error.walk(
             (e) =>
             (e) =>
               e instanceof InternalRpcError &&
               e instanceof InternalRpcError &&
               e.details.includes("replacement transaction underpriced"),
               e.details.includes("replacement transaction underpriced"),
@@ -307,7 +300,7 @@ export class EvmPricePusher implements IPricePusher {
         }
         }
 
 
         if (
         if (
-          err.walk(
+          error.walk(
             (e) =>
             (e) =>
               e instanceof TransactionExecutionError &&
               e instanceof TransactionExecutionError &&
               (e.details.includes("nonce too low") ||
               (e.details.includes("nonce too low") ||
@@ -321,9 +314,9 @@ export class EvmPricePusher implements IPricePusher {
         }
         }
 
 
         // Sometimes the contract function execution fails in simulation and this error is thrown.
         // Sometimes the contract function execution fails in simulation and this error is thrown.
-        if (err.walk((e) => e instanceof ContractFunctionExecutionError)) {
+        if (error.walk((e) => e instanceof ContractFunctionExecutionError)) {
           this.logger.warn(
           this.logger.warn(
-            { err },
+            { err: error },
             "The contract function execution failed in simulation. This is an expected behaviour in high frequency or multi-instance setup. " +
             "The contract function execution failed in simulation. This is an expected behaviour in high frequency or multi-instance setup. " +
               "Please review this error and file an issue if it is a bug. Skipping this push.",
               "Please review this error and file an issue if it is a bug. Skipping this push.",
           );
           );
@@ -332,9 +325,9 @@ export class EvmPricePusher implements IPricePusher {
 
 
         // We normally crash on unknown failures but we believe that this type of error is safe to skip. The other reason is that
         // We normally crash on unknown failures but we believe that this type of error is safe to skip. The other reason is that
         // wometimes we see a TransactionExecutionError because of the nonce without any details and it is not catchable.
         // wometimes we see a TransactionExecutionError because of the nonce without any details and it is not catchable.
-        if (err.walk((e) => e instanceof TransactionExecutionError)) {
+        if (error.walk((e) => e instanceof TransactionExecutionError)) {
           this.logger.error(
           this.logger.error(
-            { err },
+            { err: error },
             "Transaction execution failed. This is an expected behaviour in high frequency or multi-instance setup. " +
             "Transaction execution failed. This is an expected behaviour in high frequency or multi-instance setup. " +
               "Please review this error and file an issue if it is a bug. Skipping this push.",
               "Please review this error and file an issue if it is a bug. Skipping this push.",
           );
           );
@@ -344,9 +337,9 @@ export class EvmPricePusher implements IPricePusher {
         // The following errors are part of the legacy code and might not work as expected.
         // The following errors are part of the legacy code and might not work as expected.
         // We are keeping them in case they help with handling what is not covered above.
         // We are keeping them in case they help with handling what is not covered above.
         if (
         if (
-          err.message.includes("the tx doesn't have the correct nonce.") ||
-          err.message.includes("nonce too low") ||
-          err.message.includes("invalid nonce")
+          error.message.includes("the tx doesn't have the correct nonce.") ||
+          error.message.includes("nonce too low") ||
+          error.message.includes("invalid nonce")
         ) {
         ) {
           this.logger.info(
           this.logger.info(
             "The nonce is incorrect (are multiple users using this account?). Skipping this push.",
             "The nonce is incorrect (are multiple users using this account?). Skipping this push.",
@@ -354,7 +347,9 @@ export class EvmPricePusher implements IPricePusher {
           return;
           return;
         }
         }
 
 
-        if (err.message.includes("max fee per gas less than block base fee")) {
+        if (
+          error.message.includes("max fee per gas less than block base fee")
+        ) {
           // We just have to handle this error and return.
           // We just have to handle this error and return.
           // LastPushAttempt was stored with the class
           // LastPushAttempt was stored with the class
           // Next time the update will be executing, it will check the last attempt
           // Next time the update will be executing, it will check the last attempt
@@ -367,13 +362,13 @@ export class EvmPricePusher implements IPricePusher {
         }
         }
 
 
         if (
         if (
-          err.message.includes("sender doesn't have enough funds to send tx.")
+          error.message.includes("sender doesn't have enough funds to send tx.")
         ) {
         ) {
           this.logger.error("Payer is out of balance, please top it up.");
           this.logger.error("Payer is out of balance, please top it up.");
           throw new Error("Please top up the wallet");
           throw new Error("Please top up the wallet");
         }
         }
 
 
-        if (err.message.includes("could not replace existing tx")) {
+        if (error.message.includes("could not replace existing tx")) {
           this.logger.error(
           this.logger.error(
             "A transaction with the same nonce has been mined and this one is no longer needed. Skipping this push.",
             "A transaction with the same nonce has been mined and this one is no longer needed. Skipping this push.",
           );
           );
@@ -383,11 +378,11 @@ export class EvmPricePusher implements IPricePusher {
 
 
       // If the error is not handled, we will crash the process.
       // If the error is not handled, we will crash the process.
       this.logger.error(
       this.logger.error(
-        { err },
+        { err: error },
         "The transaction failed with an unhandled error. crashing the process. " +
         "The transaction failed with an unhandled error. crashing the process. " +
           "Please review this error and file an issue if it is a bug.",
           "Please review this error and file an issue if it is a bug.",
       );
       );
-      throw err;
+      throw error;
     }
     }
   }
   }
 
 
@@ -398,19 +393,21 @@ export class EvmPricePusher implements IPricePusher {
       });
       });
 
 
       switch (receipt.status) {
       switch (receipt.status) {
-        case "success":
+        case "success": {
           this.logger.debug({ hash, receipt }, "Price update successful");
           this.logger.debug({ hash, receipt }, "Price update successful");
           this.logger.info({ hash }, "Price update successful");
           this.logger.info({ hash }, "Price update successful");
           break;
           break;
-        default:
+        }
+        default: {
           this.logger.info(
           this.logger.info(
             { hash, receipt },
             { hash, receipt },
             "Price update did not succeed or its transaction did not land. " +
             "Price update did not succeed or its transaction did not land. " +
               "This is an expected behaviour in high frequency or multi-instance setup.",
               "This is an expected behaviour in high frequency or multi-instance setup.",
           );
           );
+        }
       }
       }
-    } catch (err: any) {
-      this.logger.warn({ err }, "Failed to get transaction receipt");
+    } catch (error: any) {
+      this.logger.warn({ err: error }, "Failed to get transaction receipt");
     }
     }
   }
   }
 
 

+ 3 - 1
apps/price_pusher/src/evm/pyth-contract.ts

@@ -1,4 +1,6 @@
-import { getContract, type Address, type GetContractReturnType } from "viem";
+import type { Address, GetContractReturnType } from "viem";
+import { getContract } from "viem";
+
 import { PythAbi } from "./pyth-abi.js";
 import { PythAbi } from "./pyth-abi.js";
 import type { SuperWalletClient } from "./super-wallet.js";
 import type { SuperWalletClient } from "./super-wallet.js";
 
 

+ 13 - 9
apps/price_pusher/src/evm/super-wallet.ts

@@ -1,22 +1,25 @@
+import type {
+  Account,
+  Chain,
+  Client,
+  RpcSchema,
+  WalletActions,
+  PublicActions,
+  WebSocketTransport,
+  HttpTransport,
+  Transport,
+} from "viem";
 import {
 import {
   createPublicClient,
   createPublicClient,
   createWalletClient,
   createWalletClient,
   defineChain,
   defineChain,
   http,
   http,
   webSocket,
   webSocket,
-  type Account,
-  type Chain,
   publicActions,
   publicActions,
-  type Client,
-  type RpcSchema,
-  type WalletActions,
-  type PublicActions,
-  type WebSocketTransport,
-  type HttpTransport,
-  type Transport,
 } from "viem";
 } from "viem";
 import { mnemonicToAccount } from "viem/accounts";
 import { mnemonicToAccount } from "viem/accounts";
 import * as chains from "viem/chains";
 import * as chains from "viem/chains";
+
 import { isWsEndpoint } from "../utils.js";
 import { isWsEndpoint } from "../utils.js";
 
 
 const UNKNOWN_CHAIN_CONFIG = {
 const UNKNOWN_CHAIN_CONFIG = {
@@ -50,6 +53,7 @@ const getTransport = (endpoint: string): WebSocketTransport | HttpTransport =>
 // the viem package to support new chains if they don't work as expected with the unknown
 // the viem package to support new chains if they don't work as expected with the unknown
 // chain.
 // chain.
 const getChainById = (chainId: number): Chain =>
 const getChainById = (chainId: number): Chain =>
+  // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
   Object.values(chains).find((chain) => chain.id === chainId) ||
   Object.values(chains).find((chain) => chain.id === chainId) ||
   defineChain({ id: chainId, ...UNKNOWN_CHAIN_CONFIG });
   defineChain({ id: chainId, ...UNKNOWN_CHAIN_CONFIG });
 
 

+ 11 - 5
apps/price_pusher/src/fuel/command.ts

@@ -1,13 +1,19 @@
+/* eslint-disable @typescript-eslint/no-unsafe-call */
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import fs from "node:fs";
+
+import { HermesClient } from "@pythnetwork/hermes-client";
+import { Provider, Wallet } from "fuels";
+import pino from "pino";
 import type { Options } from "yargs";
 import type { Options } from "yargs";
+
 import * as options from "../options.js";
 import * as options from "../options.js";
 import { readPriceConfigFile } from "../price-config.js";
 import { readPriceConfigFile } from "../price-config.js";
-import { HermesClient } from "@pythnetwork/hermes-client";
 import { PythPriceListener } from "../pyth-price-listener.js";
 import { PythPriceListener } from "../pyth-price-listener.js";
 import { FuelPriceListener, FuelPricePusher } from "./fuel.js";
 import { FuelPriceListener, FuelPricePusher } from "./fuel.js";
 import { Controller } from "../controller.js";
 import { Controller } from "../controller.js";
-import { Provider, Wallet } from "fuels";
-import fs from "fs";
-import pino from "pino";
 import { filterInvalidPriceItems } from "../utils.js";
 import { filterInvalidPriceItems } from "../utils.js";
 
 
 export default {
 export default {
@@ -107,6 +113,6 @@ export default {
       { pushingFrequency },
       { pushingFrequency },
     );
     );
 
 
-    await controller.start();
+    void controller.start();
   },
   },
 };
 };

+ 24 - 15
apps/price_pusher/src/fuel/fuel.ts

@@ -1,17 +1,22 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+/* eslint-disable @typescript-eslint/no-unsafe-call */
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+/* eslint-disable no-console */
 import { HermesClient } from "@pythnetwork/hermes-client";
 import { HermesClient } from "@pythnetwork/hermes-client";
-import {
-  ChainPriceListener,
-  type IPricePusher,
-  type PriceInfo,
-  type PriceItem,
-} from "../interface.js";
-import { addLeading0x, type DurationInSeconds } from "../utils.js";
-import type { Logger } from "pino";
-import { Provider, Contract, hexlify, arrayify, Wallet, BN } from "fuels";
 import {
 import {
   PYTH_CONTRACT_ABI,
   PYTH_CONTRACT_ABI,
   FUEL_ETH_ASSET_ID,
   FUEL_ETH_ASSET_ID,
 } from "@pythnetwork/pyth-fuel-js";
 } from "@pythnetwork/pyth-fuel-js";
+import { Provider, Contract, hexlify, arrayify, Wallet, BN } from "fuels";
+import type { Logger } from "pino";
+
+import type { IPricePusher, PriceInfo, PriceItem } from "../interface.js";
+import { ChainPriceListener } from "../interface.js";
+import type { DurationInSeconds } from "../utils.js";
+import { addLeading0x } from "../utils.js";
 
 
 // Convert TAI64 timestamp to Unix timestamp
 // Convert TAI64 timestamp to Unix timestamp
 function tai64ToUnix(tai64: BN): number {
 function tai64ToUnix(tai64: BN): number {
@@ -65,8 +70,11 @@ export class FuelPriceListener extends ChainPriceListener {
         price: priceInfo?.value.price.toString() ?? "",
         price: priceInfo?.value.price.toString() ?? "",
         publishTime: tai64ToUnix(priceInfo?.value.publish_time),
         publishTime: tai64ToUnix(priceInfo?.value.publish_time),
       };
       };
-    } catch (err) {
-      this.logger.error({ err, priceId }, `Polling on-chain price failed.`);
+    } catch (error) {
+      this.logger.error(
+        { err: error, priceId },
+        `Polling on-chain price failed.`,
+      );
       return undefined;
       return undefined;
     }
     }
   }
   }
@@ -88,6 +96,7 @@ export class FuelPricePusher implements IPricePusher {
     );
     );
   }
   }
 
 
+  // eslint-disable-next-line @typescript-eslint/no-unused-vars
   async updatePriceFeed(priceIds: string[], _: number[]): Promise<void> {
   async updatePriceFeed(priceIds: string[], _: number[]): Promise<void> {
     if (priceIds.length === 0) {
     if (priceIds.length === 0) {
       return;
       return;
@@ -100,8 +109,8 @@ export class FuelPricePusher implements IPricePusher {
         ignoreInvalidPriceIds: true,
         ignoreInvalidPriceIds: true,
       });
       });
       priceFeedUpdateData = response.binary.data;
       priceFeedUpdateData = response.binary.data;
-    } catch (err: any) {
-      this.logger.error(err, "getPriceFeedsUpdateData failed");
+    } catch (error: any) {
+      this.logger.error(error, "getPriceFeedsUpdateData failed");
       return;
       return;
     }
     }
 
 
@@ -123,8 +132,8 @@ export class FuelPricePusher implements IPricePusher {
         { transactionId: result?.transactionId },
         { transactionId: result?.transactionId },
         "updatePriceFeed successful",
         "updatePriceFeed successful",
       );
       );
-    } catch (err: any) {
-      this.logger.error(err, "updatePriceFeed failed");
+    } catch (error: any) {
+      this.logger.error(error, "updatePriceFeed failed");
     }
     }
   }
   }
 }
 }

+ 11 - 8
apps/price_pusher/src/index.ts

@@ -1,17 +1,20 @@
-#!/usr/bin/env node
-import yargs from "yargs";
+import createCLI from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
-import injective from "./injective/command.js";
-import evm from "./evm/command.js";
+
 import aptos from "./aptos/command.js";
 import aptos from "./aptos/command.js";
-import sui from "./sui/command.js";
+import evm from "./evm/command.js";
+import fuel from "./fuel/command.js";
+import injective from "./injective/command.js";
 import near from "./near/command.js";
 import near from "./near/command.js";
+import { enableMetrics, metricsPort } from "./options.js";
 import solana from "./solana/command.js";
 import solana from "./solana/command.js";
-import fuel from "./fuel/command.js";
+import sui from "./sui/command.js";
 import ton from "./ton/command.js";
 import ton from "./ton/command.js";
-import { enableMetrics, metricsPort } from "./options.js";
 
 
-yargs(hideBin(process.argv))
+const yargs = createCLI(hideBin(process.argv));
+
+// let the application run but don't await on the value here, per existing behavior
+void yargs
   .parserConfiguration({
   .parserConfiguration({
     "parse-numbers": false,
     "parse-numbers": false,
   })
   })

+ 12 - 7
apps/price_pusher/src/injective/command.ts

@@ -1,13 +1,18 @@
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import fs from "node:fs";
+
+import { getNetworkInfo } from "@injectivelabs/networks";
 import { HermesClient } from "@pythnetwork/hermes-client";
 import { HermesClient } from "@pythnetwork/hermes-client";
+import { pino } from "pino";
+import type { Options } from "yargs";
+
 import * as options from "../options.js";
 import * as options from "../options.js";
 import { readPriceConfigFile } from "../price-config.js";
 import { readPriceConfigFile } from "../price-config.js";
-import fs from "fs";
 import { InjectivePriceListener, InjectivePricePusher } from "./injective.js";
 import { InjectivePriceListener, InjectivePricePusher } from "./injective.js";
-import { PythPriceListener } from "../pyth-price-listener.js";
 import { Controller } from "../controller.js";
 import { Controller } from "../controller.js";
-import type { Options } from "yargs";
-import { getNetworkInfo } from "@injectivelabs/networks";
-import { pino } from "pino";
+import { PythPriceListener } from "../pyth-price-listener.js";
 import { filterInvalidPriceItems } from "../utils.js";
 import { filterInvalidPriceItems } from "../utils.js";
 export default {
 export default {
   command: "injective",
   command: "injective",
@@ -75,7 +80,7 @@ export default {
 
 
     const priceConfigs = readPriceConfigFile(priceConfigFile);
     const priceConfigs = readPriceConfigFile(priceConfigFile);
     const hermesClient = new HermesClient(priceServiceEndpoint);
     const hermesClient = new HermesClient(priceServiceEndpoint);
-    const mnemonic = fs.readFileSync(mnemonicFile, "utf-8").trim();
+    const mnemonic = fs.readFileSync(mnemonicFile, "utf8").trim();
 
 
     let priceItems = priceConfigs.map(({ id, alias }) => ({ id, alias }));
     let priceItems = priceConfigs.map(({ id, alias }) => ({ id, alias }));
 
 
@@ -131,6 +136,6 @@ export default {
       { pushingFrequency },
       { pushingFrequency },
     );
     );
 
 
-    controller.start();
+    void controller.start();
   },
   },
 };
 };

+ 40 - 37
apps/price_pusher/src/injective/injective.ts

@@ -1,15 +1,11 @@
-import { type HexString, HermesClient } from "@pythnetwork/hermes-client";
+/* eslint-disable @typescript-eslint/no-unsafe-call */
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+/* eslint-disable @typescript-eslint/no-explicit-any */
+/* eslint-disable @typescript-eslint/no-unnecessary-condition */
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+import type { Msgs, Account, TxResponse } from "@injectivelabs/sdk-ts";
 import {
 import {
-  type PriceItem,
-  type PriceInfo,
-  type IPricePusher,
-  ChainPriceListener,
-} from "../interface.js";
-import type { DurationInSeconds } from "../utils.js";
-import {
-  type Msgs,
-  type Account,
-  type TxResponse,
   PrivateKey,
   PrivateKey,
   TxGrpcApi,
   TxGrpcApi,
   ChainGrpcAuthApi,
   ChainGrpcAuthApi,
@@ -18,9 +14,15 @@ import {
   createTransactionFromMsg,
   createTransactionFromMsg,
 } from "@injectivelabs/sdk-ts";
 } from "@injectivelabs/sdk-ts";
 import { splitArrayToChunks } from "@injectivelabs/utils";
 import { splitArrayToChunks } from "@injectivelabs/utils";
+import type { HexString } from "@pythnetwork/hermes-client";
+import { HermesClient } from "@pythnetwork/hermes-client";
 import type { Logger } from "pino";
 import type { Logger } from "pino";
 
 
-const DEFAULT_GAS_PRICE = 160000000;
+import type { PriceItem, PriceInfo, IPricePusher } from "../interface.js";
+import { ChainPriceListener } from "../interface.js";
+import type { DurationInSeconds } from "../utils.js";
+
+const DEFAULT_GAS_PRICE = 160_000_000;
 const DEFAULT_GAS_MULTIPLIER = 1.05;
 const DEFAULT_GAS_MULTIPLIER = 1.05;
 const DEFAULT_PRICE_IDS_PROCESS_CHUNK_SIZE = -1;
 const DEFAULT_PRICE_IDS_PROCESS_CHUNK_SIZE = -1;
 const INJECTIVE_TESTNET_CHAIN_ID = "injective-888";
 const INJECTIVE_TESTNET_CHAIN_ID = "injective-888";
@@ -71,8 +73,8 @@ export class InjectivePriceListener extends ChainPriceListener {
 
 
       const json = Buffer.from(data).toString();
       const json = Buffer.from(data).toString();
       priceQueryResponse = JSON.parse(json);
       priceQueryResponse = JSON.parse(json);
-    } catch (err) {
-      this.logger.error(err, `Polling on-chain price for ${priceId} failed.`);
+    } catch (error) {
+      this.logger.error(error, `Polling on-chain price for ${priceId} failed.`);
       return undefined;
       return undefined;
     }
     }
 
 
@@ -93,8 +95,7 @@ export class InjectivePriceListener extends ChainPriceListener {
 export class InjectivePricePusher implements IPricePusher {
 export class InjectivePricePusher implements IPricePusher {
   private mnemonic: string;
   private mnemonic: string;
   private chainConfig: InjectiveConfig;
   private chainConfig: InjectiveConfig;
-  private accounts: Record<string, Account | undefined> =
-    {}; /** { address: Account } */
+  private accounts: Record<string, Account | undefined> = {};
 
 
   constructor(
   constructor(
     private hermesClient: HermesClient,
     private hermesClient: HermesClient,
@@ -150,6 +151,7 @@ export class InjectivePricePusher implements IPricePusher {
         pubKey: wallet.toPublicKey().toBase64(),
         pubKey: wallet.toPublicKey().toBase64(),
       });
       });
 
 
+      // eslint-disable-next-line @typescript-eslint/await-thenable
       const sig = await wallet.sign(Buffer.from(signBytes));
       const sig = await wallet.sign(Buffer.from(signBytes));
 
 
       /** Append Signatures */
       /** Append Signatures */
@@ -163,13 +165,13 @@ export class InjectivePricePusher implements IPricePusher {
       account.baseAccount.sequence++;
       account.baseAccount.sequence++;
 
 
       return txResponse;
       return txResponse;
-    } catch (e: any) {
+    } catch (error: any) {
       // The sequence number was invalid and hence we will have to fetch it again
       // The sequence number was invalid and hence we will have to fetch it again
-      if (JSON.stringify(e).match(/account sequence mismatch/) !== null) {
+      if (/account sequence mismatch/.exec(JSON.stringify(error)) !== null) {
         this.accounts[injectiveAddress] = undefined;
         this.accounts[injectiveAddress] = undefined;
       }
       }
 
 
-      throw e;
+      throw error;
     }
     }
   }
   }
 
 
@@ -224,23 +226,23 @@ export class InjectivePricePusher implements IPricePusher {
         { hash: rs.txHash },
         { hash: rs.txHash },
         `Successfully broadcasted txHash for chunk ${chunkIndex}`,
         `Successfully broadcasted txHash for chunk ${chunkIndex}`,
       );
       );
-    } catch (err: any) {
-      if (err.message.match(/account inj[a-zA-Z0-9]+ not found/) !== null) {
-        this.logger.error(err, `Account not found for chunk ${chunkIndex}`);
+    } catch (error: any) {
+      if (error.message.match(/account inj[a-zA-Z0-9]+ not found/) !== null) {
+        this.logger.error(error, `Account not found for chunk ${chunkIndex}`);
 
 
         throw new Error("Please check the mnemonic");
         throw new Error("Please check the mnemonic");
       }
       }
 
 
       if (
       if (
-        err.message.match(/insufficient/) !== null &&
-        err.message.match(/funds/) !== null
+        error.message.match(/insufficient/) !== null &&
+        error.message.match(/funds/) !== null
       ) {
       ) {
-        this.logger.error(err, `Insufficient funds for chunk ${chunkIndex}`);
+        this.logger.error(error, `Insufficient funds for chunk ${chunkIndex}`);
         throw new Error("Insufficient funds");
         throw new Error("Insufficient funds");
       }
       }
 
 
       this.logger.error(
       this.logger.error(
-        err,
+        error,
         `Error executing messages for chunk ${chunkIndex}`,
         `Error executing messages for chunk ${chunkIndex}`,
       );
       );
     }
     }
@@ -276,21 +278,21 @@ export class InjectivePricePusher implements IPricePusher {
 
 
       const gas = (
       const gas = (
         result.gasInfo.gasUsed * this.chainConfig.gasMultiplier
         result.gasInfo.gasUsed * this.chainConfig.gasMultiplier
-      ).toFixed();
+      ).toFixed(0);
       const fee = {
       const fee = {
         amount: [
         amount: [
           {
           {
             denom: "inj",
             denom: "inj",
-            amount: (Number(gas) * this.chainConfig.gasPrice).toFixed(),
+            amount: (Number(gas) * this.chainConfig.gasPrice).toFixed(0),
           },
           },
         ],
         ],
         gas,
         gas,
       };
       };
 
 
       return fee;
       return fee;
-    } catch (err) {
-      this.logger.error(err, `Error getting std fee`);
-      throw err;
+    } catch (error) {
+      this.logger.error(error, `Error getting std fee`);
+      throw error;
     }
     }
   }
   }
 
 
@@ -314,9 +316,9 @@ export class InjectivePricePusher implements IPricePusher {
           data: string[];
           data: string[];
         };
         };
       };
       };
-    } catch (err) {
-      this.logger.error(err, `Error fetching the latest vaas to push`);
-      throw err;
+    } catch (error) {
+      this.logger.error(error, `Error fetching the latest vaas to push`);
+      throw error;
     }
     }
   }
   }
 
 
@@ -339,12 +341,13 @@ export class InjectivePricePusher implements IPricePusher {
 
 
       const json = Buffer.from(data).toString();
       const json = Buffer.from(data).toString();
 
 
+      // eslint-disable-next-line @typescript-eslint/no-unsafe-return
       return JSON.parse(json);
       return JSON.parse(json);
-    } catch (err) {
-      this.logger.error(err, `Error fetching update fee.`);
+    } catch (error) {
+      this.logger.error(error, `Error fetching update fee.`);
 
 
       // Throwing an error because it is likely an RPC issue
       // Throwing an error because it is likely an RPC issue
-      throw err;
+      throw error;
     }
     }
   }
   }
 }
 }

+ 13 - 12
apps/price_pusher/src/interface.ts

@@ -1,7 +1,8 @@
 import type { HexString, UnixTimestamp } from "@pythnetwork/hermes-client";
 import type { HexString, UnixTimestamp } from "@pythnetwork/hermes-client";
-import type { DurationInSeconds } from "./utils.js";
 import type { Logger } from "pino";
 import type { Logger } from "pino";
+
 import { PricePusherMetrics } from "./metrics.js";
 import { PricePusherMetrics } from "./metrics.js";
+import type { DurationInSeconds } from "./utils.js";
 
 
 export type PriceItem = {
 export type PriceItem = {
   id: HexString;
   id: HexString;
@@ -14,11 +15,11 @@ export type PriceInfo = {
   publishTime: UnixTimestamp;
   publishTime: UnixTimestamp;
 };
 };
 
 
-export interface IPriceListener {
+export type IPriceListener = {
   // start fetches the latest price initially and then keep updating it
   // start fetches the latest price initially and then keep updating it
   start(): Promise<void>;
   start(): Promise<void>;
   getLatestPriceInfo(priceId: string): PriceInfo | undefined;
   getLatestPriceInfo(priceId: string): PriceInfo | undefined;
-}
+};
 
 
 export abstract class ChainPriceListener implements IPriceListener {
 export abstract class ChainPriceListener implements IPriceListener {
   private latestPriceInfo: Map<HexString, PriceInfo>;
   private latestPriceInfo: Map<HexString, PriceInfo>;
@@ -35,7 +36,7 @@ export abstract class ChainPriceListener implements IPriceListener {
   }
   }
 
 
   async start() {
   async start() {
-    setInterval(this.pollPrices.bind(this), this.pollingFrequency * 1000);
+    setInterval(() => void this.pollPrices(), this.pollingFrequency * 1000);
 
 
     await this.pollPrices();
     await this.pollPrices();
   }
   }
@@ -78,17 +79,17 @@ export abstract class ChainPriceListener implements IPriceListener {
   ): Promise<PriceInfo | undefined>;
   ): Promise<PriceInfo | undefined>;
 }
 }
 
 
-export interface IPricePusher {
+export type IPricePusher = {
   updatePriceFeed(
   updatePriceFeed(
     priceIds: string[],
     priceIds: string[],
     pubTimesToPush: UnixTimestamp[],
     pubTimesToPush: UnixTimestamp[],
   ): Promise<void>;
   ): Promise<void>;
-}
+};
 
 
 /**
 /**
  * Common configuration properties for all balance trackers
  * Common configuration properties for all balance trackers
  */
  */
-export interface BaseBalanceTrackerConfig {
+export type BaseBalanceTrackerConfig = {
   /** Address of the wallet to track */
   /** Address of the wallet to track */
   address: string;
   address: string;
   /** Name/ID of the network/chain */
   /** Name/ID of the network/chain */
@@ -99,13 +100,13 @@ export interface BaseBalanceTrackerConfig {
   metrics: PricePusherMetrics;
   metrics: PricePusherMetrics;
   /** Logger instance */
   /** Logger instance */
   logger: Logger;
   logger: Logger;
-}
+};
 
 
 /**
 /**
  * Interface for all balance trackers to implement
  * Interface for all balance trackers to implement
  * Each chain will have its own implementation of this interface
  * Each chain will have its own implementation of this interface
  */
  */
-export interface IBalanceTracker {
+export type IBalanceTracker = {
   /**
   /**
    * Start tracking the wallet balance
    * Start tracking the wallet balance
    */
    */
@@ -115,7 +116,7 @@ export interface IBalanceTracker {
    * Stop tracking the wallet balance
    * Stop tracking the wallet balance
    */
    */
   stop(): void;
   stop(): void;
-}
+};
 
 
 /**
 /**
  * Abstract base class that implements common functionality for all balance trackers
  * Abstract base class that implements common functionality for all balance trackers
@@ -126,7 +127,7 @@ export abstract class BaseBalanceTracker implements IBalanceTracker {
   protected updateInterval: DurationInSeconds;
   protected updateInterval: DurationInSeconds;
   protected metrics: PricePusherMetrics;
   protected metrics: PricePusherMetrics;
   protected logger: Logger;
   protected logger: Logger;
-  protected isRunning: boolean = false;
+  protected isRunning = false;
 
 
   constructor(config: BaseBalanceTrackerConfig) {
   constructor(config: BaseBalanceTrackerConfig) {
     this.address = config.address;
     this.address = config.address;
@@ -147,7 +148,7 @@ export abstract class BaseBalanceTracker implements IBalanceTracker {
     await this.updateBalance();
     await this.updateBalance();
 
 
     // Start the update loop
     // Start the update loop
-    this.startUpdateLoop();
+    void this.startUpdateLoop();
   }
   }
 
 
   private async startUpdateLoop(): Promise<void> {
   private async startUpdateLoop(): Promise<void> {

+ 14 - 11
apps/price_pusher/src/metrics.ts

@@ -1,6 +1,9 @@
-import { Registry, Counter, Gauge } from "prom-client";
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
+/* eslint-disable @typescript-eslint/no-misused-promises */
 import express from "express";
 import express from "express";
 import type { Logger } from "pino";
 import type { Logger } from "pino";
+import { Registry, Counter, Gauge } from "prom-client";
+
 import { UpdateCondition } from "./price-config.js";
 import { UpdateCondition } from "./price-config.js";
 
 
 // Define the metrics we want to track
 // Define the metrics we want to track
@@ -10,15 +13,15 @@ export class PricePusherMetrics {
   private logger: Logger;
   private logger: Logger;
 
 
   // Metrics for price feed updates
   // Metrics for price feed updates
-  public lastPublishedTime: Gauge<string>;
-  public priceUpdateAttempts: Counter<string>;
-  public priceFeedsTotal: Gauge<string>;
-  public sourceTimestamp: Gauge<string>;
-  public configuredTimeDifference: Gauge<string>;
-  public sourcePriceValue: Gauge<string>;
-  public targetPriceValue: Gauge<string>;
+  public lastPublishedTime: Gauge;
+  public priceUpdateAttempts: Counter;
+  public priceFeedsTotal: Gauge;
+  public sourceTimestamp: Gauge;
+  public configuredTimeDifference: Gauge;
+  public sourcePriceValue: Gauge;
+  public targetPriceValue: Gauge;
   // Wallet metrics
   // Wallet metrics
-  public walletBalance: Gauge<string>;
+  public walletBalance: Gauge;
 
 
   constructor(logger: Logger) {
   constructor(logger: Logger) {
     this.logger = logger;
     this.logger = logger;
@@ -103,7 +106,7 @@ export class PricePusherMetrics {
   public recordPriceUpdate(
   public recordPriceUpdate(
     priceId: string,
     priceId: string,
     alias: string,
     alias: string,
-    trigger: string = "yes",
+    trigger = "yes",
   ): void {
   ): void {
     this.priceUpdateAttempts.inc({
     this.priceUpdateAttempts.inc({
       price_id: priceId,
       price_id: priceId,
@@ -137,7 +140,7 @@ export class PricePusherMetrics {
   public recordPriceUpdateError(
   public recordPriceUpdateError(
     priceId: string,
     priceId: string,
     alias: string,
     alias: string,
-    trigger: string = "yes",
+    trigger = "yes",
   ): void {
   ): void {
     this.priceUpdateAttempts.inc({
     this.priceUpdateAttempts.inc({
       price_id: priceId,
       price_id: priceId,

+ 8 - 4
apps/price_pusher/src/near/command.ts

@@ -1,11 +1,15 @@
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+/* eslint-disable @typescript-eslint/no-explicit-any */
 import { HermesClient } from "@pythnetwork/hermes-client";
 import { HermesClient } from "@pythnetwork/hermes-client";
+import { pino } from "pino";
+import type { Options } from "yargs";
+
+import { Controller } from "../controller";
 import * as options from "../options";
 import * as options from "../options";
 import { readPriceConfigFile } from "../price-config";
 import { readPriceConfigFile } from "../price-config";
 import { PythPriceListener } from "../pyth-price-listener";
 import { PythPriceListener } from "../pyth-price-listener";
-import { Controller } from "../controller";
-import type { Options } from "yargs";
 import { NearAccount, NearPriceListener, NearPricePusher } from "./near";
 import { NearAccount, NearPriceListener, NearPricePusher } from "./near";
-import { pino } from "pino";
 import { filterInvalidPriceItems } from "../utils";
 import { filterInvalidPriceItems } from "../utils";
 
 
 export default {
 export default {
@@ -116,6 +120,6 @@ export default {
       { pushingFrequency },
       { pushingFrequency },
     );
     );
 
 
-    controller.start();
+    void controller.start();
   },
   },
 };
 };

+ 45 - 40
apps/price_pusher/src/near/near.ts

@@ -1,25 +1,28 @@
-import os from "os";
-import path from "path";
-import fs from "fs";
-
-import {
-  type IPricePusher,
-  type PriceInfo,
-  ChainPriceListener,
-  type PriceItem,
-} from "../interface.js";
-import { HermesClient, type HexString } from "@pythnetwork/hermes-client";
-import type { DurationInSeconds } from "../utils.js";
-
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
+/* eslint-disable unicorn/no-array-reduce */
+/* eslint-disable @typescript-eslint/no-explicit-any */
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+import fs from "node:fs";
+import os from "node:os";
+import path from "node:path";
+
+import type { HexString } from "@pythnetwork/hermes-client";
+import { HermesClient } from "@pythnetwork/hermes-client";
 import { Account, Connection, KeyPair } from "near-api-js";
 import { Account, Connection, KeyPair } from "near-api-js";
-import {
-  type ExecutionStatus,
-  ExecutionStatusBasic,
-  type FinalExecutionOutcome,
-} from "near-api-js/lib/providers/provider";
 import { InMemoryKeyStore } from "near-api-js/lib/key_stores";
 import { InMemoryKeyStore } from "near-api-js/lib/key_stores";
+import type {
+  ExecutionStatus,
+  FinalExecutionOutcome,
+} from "near-api-js/lib/providers/provider";
+import { ExecutionStatusBasic } from "near-api-js/lib/providers/provider";
 import type { Logger } from "pino";
 import type { Logger } from "pino";
 
 
+import type { IPricePusher, PriceInfo, PriceItem } from "../interface.js";
+import { ChainPriceListener } from "../interface.js";
+import type { DurationInSeconds } from "../utils.js";
+
 export class NearPriceListener extends ChainPriceListener {
 export class NearPriceListener extends ChainPriceListener {
   constructor(
   constructor(
     private account: NearAccount,
     private account: NearAccount,
@@ -42,17 +45,18 @@ export class NearPriceListener extends ChainPriceListener {
         )} (${priceId}) ${JSON.stringify(priceRaw)}.`,
         )} (${priceId}) ${JSON.stringify(priceRaw)}.`,
       );
       );
 
 
-      if (priceRaw) {
-        return {
-          conf: priceRaw.conf,
-          price: priceRaw.price,
-          publishTime: priceRaw.publish_time,
-        };
-      } else {
-        return undefined;
-      }
-    } catch (err) {
-      this.logger.error(err, `Polling on-chain price for ${priceId} failed.:`);
+      return priceRaw
+        ? {
+            conf: priceRaw.conf,
+            price: priceRaw.price,
+            publishTime: priceRaw.publish_time,
+          }
+        : undefined;
+    } catch (error) {
+      this.logger.error(
+        error,
+        `Polling on-chain price for ${priceId} failed.:`,
+      );
       return undefined;
       return undefined;
     }
     }
   }
   }
@@ -79,8 +83,8 @@ export class NearPricePusher implements IPricePusher {
     let priceFeedUpdateData;
     let priceFeedUpdateData;
     try {
     try {
       priceFeedUpdateData = await this.getPriceFeedsUpdateData(priceIds);
       priceFeedUpdateData = await this.getPriceFeedsUpdateData(priceIds);
-    } catch (err: any) {
-      this.logger.error(err, "getPriceFeedsUpdateData failed");
+    } catch (error: any) {
+      this.logger.error(error, "getPriceFeedsUpdateData failed");
       return;
       return;
     }
     }
 
 
@@ -89,23 +93,23 @@ export class NearPricePusher implements IPricePusher {
       try {
       try {
         updateFee = await this.account.getUpdateFeeEstimate(data);
         updateFee = await this.account.getUpdateFeeEstimate(data);
         this.logger.debug(`Update fee: ${updateFee}`);
         this.logger.debug(`Update fee: ${updateFee}`);
-      } catch (err: any) {
-        this.logger.error(err, "getUpdateFeeEstimate failed");
+      } catch (error: any) {
+        this.logger.error(error, "getUpdateFeeEstimate failed");
         continue;
         continue;
       }
       }
 
 
       try {
       try {
         const outcome = await this.account.updatePriceFeeds(data, updateFee);
         const outcome = await this.account.updatePriceFeeds(data, updateFee);
         const failureMessages: (ExecutionStatus | ExecutionStatusBasic)[] = [];
         const failureMessages: (ExecutionStatus | ExecutionStatusBasic)[] = [];
-        const is_success = Object.values(outcome["receipts_outcome"]).reduce(
+        const is_success = Object.values(outcome.receipts_outcome).reduce(
           (is_success, receipt) => {
           (is_success, receipt) => {
             if (
             if (
               Object.prototype.hasOwnProperty.call(
               Object.prototype.hasOwnProperty.call(
-                receipt["outcome"]["status"],
+                receipt.outcome.status,
                 "Failure",
                 "Failure",
               )
               )
             ) {
             ) {
-              failureMessages.push(receipt["outcome"]["status"]);
+              failureMessages.push(receipt.outcome.status);
               return false;
               return false;
             }
             }
             return is_success;
             return is_success;
@@ -114,14 +118,14 @@ export class NearPricePusher implements IPricePusher {
         );
         );
         if (is_success) {
         if (is_success) {
           this.logger.info(
           this.logger.info(
-            { hash: outcome["transaction"]["hash"] },
+            { hash: outcome.transaction.hash },
             "updatePriceFeeds successful.",
             "updatePriceFeeds successful.",
           );
           );
         } else {
         } else {
           this.logger.error({ failureMessages }, "updatePriceFeeds failed");
           this.logger.error({ failureMessages }, "updatePriceFeeds failed");
         }
         }
-      } catch (err: any) {
-        this.logger.error(err, "updatePriceFeeds failed");
+      } catch (error: any) {
+        this.logger.error(error, "updatePriceFeeds failed");
       }
       }
     }
     }
   }
   }
@@ -198,6 +202,7 @@ export class NearAccount {
     privateKeyPath: string | undefined,
     privateKeyPath: string | undefined,
   ): Connection {
   ): Connection {
     const content = fs.readFileSync(
     const content = fs.readFileSync(
+      // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
       privateKeyPath ||
       privateKeyPath ||
         path.join(
         path.join(
           os.homedir(),
           os.homedir(),
@@ -214,7 +219,7 @@ export class NearAccount {
     if (accountInfo.account_id && privateKey) {
     if (accountInfo.account_id && privateKey) {
       const keyPair = KeyPair.fromString(privateKey);
       const keyPair = KeyPair.fromString(privateKey);
       const keyStore = new InMemoryKeyStore();
       const keyStore = new InMemoryKeyStore();
-      keyStore.setKey(network, accountInfo.account_id, keyPair);
+      void keyStore.setKey(network, accountInfo.account_id, keyPair);
       return Connection.fromConfig({
       return Connection.fromConfig({
         networkId: network,
         networkId: network,
         provider: { type: "JsonRpcProvider", args: { url: nodeUrl } },
         provider: { type: "JsonRpcProvider", args: { url: nodeUrl } },

+ 13 - 9
apps/price_pusher/src/price-config.ts

@@ -1,14 +1,18 @@
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
+/* eslint-disable @typescript-eslint/no-explicit-any */
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+import fs from "node:fs";
+
 import type { HexString } from "@pythnetwork/hermes-client";
 import type { HexString } from "@pythnetwork/hermes-client";
 import Joi from "joi";
 import Joi from "joi";
-import YAML from "yaml";
-import fs from "fs";
 import type { Logger } from "pino";
 import type { Logger } from "pino";
-import {
-  type DurationInSeconds,
-  type PctNumber,
-  removeLeading0x,
-} from "./utils.js";
+import YAML from "yaml";
+
 import type { PriceInfo } from "./interface.js";
 import type { PriceInfo } from "./interface.js";
+import type { DurationInSeconds, PctNumber } from "./utils.js";
+import { removeLeading0x } from "./utils.js";
 
 
 const PriceConfigFileSchema: Joi.Schema = Joi.array()
 const PriceConfigFileSchema: Joi.Schema = Joi.array()
   .items(
   .items(
@@ -53,7 +57,7 @@ export type PriceConfig = {
 };
 };
 
 
 export function readPriceConfigFile(path: string): PriceConfig[] {
 export function readPriceConfigFile(path: string): PriceConfig[] {
-  const priceConfigs = YAML.parse(fs.readFileSync(path, "utf-8"));
+  const priceConfigs = YAML.parse(fs.readFileSync(path, "utf8"));
   const validationResult = PriceConfigFileSchema.validate(priceConfigs);
   const validationResult = PriceConfigFileSchema.validate(priceConfigs);
 
 
   if (validationResult.error !== undefined) {
   if (validationResult.error !== undefined) {
@@ -89,7 +93,7 @@ export enum UpdateCondition {
 /**
 /**
  * Checks whether on-chain price needs to be updated with the latest pyth price information.
  * Checks whether on-chain price needs to be updated with the latest pyth price information.
  *
  *
- * @param priceConfig Config of the price feed to check
+ * @param priceConfig - Config of the price feed to check
  * @returns True if the on-chain price needs to be updated.
  * @returns True if the on-chain price needs to be updated.
  */
  */
 export function shouldUpdate(
 export function shouldUpdate(

+ 34 - 31
apps/price_pusher/src/pyth-price-listener.ts

@@ -1,10 +1,12 @@
-import {
-  type HexString,
-  HermesClient,
-  type PriceUpdate,
-} from "@pythnetwork/hermes-client";
-import type { PriceInfo, IPriceListener, PriceItem } from "./interface.js";
+/* eslint-disable no-console */
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
+/* eslint-disable unicorn/prefer-add-event-listener */
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
+import type { HexString, PriceUpdate } from "@pythnetwork/hermes-client";
+import { HermesClient } from "@pythnetwork/hermes-client";
 import type { Logger } from "pino";
 import type { Logger } from "pino";
+
+import type { PriceInfo, IPriceListener, PriceItem } from "./interface.js";
 import { sleep } from "./utils.js";
 import { sleep } from "./utils.js";
 
 
 type TimestampInMs = number & { readonly _: unique symbol };
 type TimestampInMs = number & { readonly _: unique symbol };
@@ -35,7 +37,7 @@ export class PythPriceListener implements IPriceListener {
   // This method should be awaited on and once it finishes it has the latest value
   // This method should be awaited on and once it finishes it has the latest value
   // for the given price feeds (if they exist).
   // for the given price feeds (if they exist).
   async start() {
   async start() {
-    this.startListening();
+    await this.startListening();
 
 
     // Store health check interval reference
     // Store health check interval reference
     this.healthCheckInterval = setInterval(() => {
     this.healthCheckInterval = setInterval(() => {
@@ -62,39 +64,40 @@ export class PythPriceListener implements IPriceListener {
     );
     );
     eventSource.onmessage = (event: MessageEvent) => {
     eventSource.onmessage = (event: MessageEvent) => {
       const priceUpdates = JSON.parse(event.data) as PriceUpdate;
       const priceUpdates = JSON.parse(event.data) as PriceUpdate;
-      priceUpdates.parsed?.forEach((priceUpdate) => {
-        this.logger.debug(
-          `Received new price feed update from Pyth price service: ${this.priceIdToAlias.get(
-            priceUpdate.id,
-          )} ${priceUpdate.id}`,
-        );
+      if (priceUpdates.parsed)
+        for (const priceUpdate of priceUpdates.parsed) {
+          this.logger.debug(
+            `Received new price feed update from Pyth price service: ${this.priceIdToAlias.get(
+              priceUpdate.id,
+            )} ${priceUpdate.id}`,
+          );
 
 
-        // Consider price to be currently available if it is not older than 60s
-        const currentPrice =
-          Date.now() / 1000 - priceUpdate.price.publish_time > 60
-            ? undefined
-            : priceUpdate.price;
-        if (currentPrice === undefined) {
-          this.logger.debug("Price is older than 60s, skipping");
-          return;
-        }
+          // Consider price to be currently available if it is not older than 60s
+          const currentPrice =
+            Date.now() / 1000 - priceUpdate.price.publish_time > 60
+              ? undefined
+              : priceUpdate.price;
+          if (currentPrice === undefined) {
+            this.logger.debug("Price is older than 60s, skipping");
+            continue;
+          }
 
 
-        const priceInfo: PriceInfo = {
-          conf: currentPrice.conf,
-          price: currentPrice.price,
-          publishTime: currentPrice.publish_time,
-        };
+          const priceInfo: PriceInfo = {
+            conf: currentPrice.conf,
+            price: currentPrice.price,
+            publishTime: currentPrice.publish_time,
+          };
 
 
-        this.latestPriceInfo.set(priceUpdate.id, priceInfo);
-        this.lastUpdated = Date.now() as TimestampInMs;
-      });
+          this.latestPriceInfo.set(priceUpdate.id, priceInfo);
+          this.lastUpdated = Date.now() as TimestampInMs;
+        }
     };
     };
 
 
     eventSource.onerror = async (error: Event) => {
     eventSource.onerror = async (error: Event) => {
       console.error("Error receiving updates from Hermes:", error);
       console.error("Error receiving updates from Hermes:", error);
       eventSource.close();
       eventSource.close();
       await sleep(5000); // Wait a bit before trying to reconnect
       await sleep(5000); // Wait a bit before trying to reconnect
-      this.startListening(); // Attempt to restart the listener
+      void this.startListening(); // Attempt to restart the listener
     };
     };
   }
   }
 
 

+ 12 - 11
apps/price_pusher/src/solana/balance-tracker.ts

@@ -1,22 +1,23 @@
 import { Connection, PublicKey, LAMPORTS_PER_SOL } from "@solana/web3.js";
 import { Connection, PublicKey, LAMPORTS_PER_SOL } from "@solana/web3.js";
-import {
-  BaseBalanceTracker,
-  type BaseBalanceTrackerConfig,
-  type IBalanceTracker,
+import type { Logger } from "pino";
+
+import type {
+  BaseBalanceTrackerConfig,
+  IBalanceTracker,
 } from "../interface.js";
 } from "../interface.js";
-import type { DurationInSeconds } from "../utils.js";
+import { BaseBalanceTracker } from "../interface.js";
 import { PricePusherMetrics } from "../metrics.js";
 import { PricePusherMetrics } from "../metrics.js";
-import type { Logger } from "pino";
+import type { DurationInSeconds } from "../utils.js";
 
 
 /**
 /**
  * Solana-specific configuration for balance tracker
  * Solana-specific configuration for balance tracker
  */
  */
-export interface SolanaBalanceTrackerConfig extends BaseBalanceTrackerConfig {
+export type SolanaBalanceTrackerConfig = {
   /** Solana connection instance */
   /** Solana connection instance */
   connection: Connection;
   connection: Connection;
   /** Solana public key */
   /** Solana public key */
   publicKey: PublicKey;
   publicKey: PublicKey;
-}
+} & BaseBalanceTrackerConfig;
 
 
 /**
 /**
  * Solana-specific implementation of the balance tracker
  * Solana-specific implementation of the balance tracker
@@ -53,7 +54,7 @@ export class SolanaBalanceTracker extends BaseBalanceTracker {
         balanceInSol,
         balanceInSol,
       );
       );
       this.logger.debug(
       this.logger.debug(
-        `Updated Solana wallet balance: ${this.address} = ${balanceInSol.toString()} SOL (${balanceInLamports} lamports)`,
+        `Updated Solana wallet balance: ${this.address} = ${balanceInSol.toString()} SOL (${balanceInLamports.toString()} lamports)`,
       );
       );
     } catch (error) {
     } catch (error) {
       this.logger.error(
       this.logger.error(
@@ -67,14 +68,14 @@ export class SolanaBalanceTracker extends BaseBalanceTracker {
 /**
 /**
  * Parameters for creating a Solana balance tracker
  * Parameters for creating a Solana balance tracker
  */
  */
-export interface CreateSolanaBalanceTrackerParams {
+export type CreateSolanaBalanceTrackerParams = {
   connection: Connection;
   connection: Connection;
   publicKey: PublicKey;
   publicKey: PublicKey;
   network: string;
   network: string;
   updateInterval: DurationInSeconds;
   updateInterval: DurationInSeconds;
   metrics: PricePusherMetrics;
   metrics: PricePusherMetrics;
   logger: Logger;
   logger: Logger;
-}
+};
 
 
 /**
 /**
  * Factory function to create a balance tracker for Solana
  * Factory function to create a balance tracker for Solana

+ 33 - 19
apps/price_pusher/src/solana/command.ts

@@ -1,4 +1,29 @@
+/* eslint-disable @typescript-eslint/no-non-null-assertion */
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+/* eslint-disable @typescript-eslint/no-unsafe-call */
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import fs from "node:fs";
+
+import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet.js";
+import { HermesClient } from "@pythnetwork/hermes-client";
+import { PythSolanaReceiver } from "@pythnetwork/pyth-solana-receiver";
+import {
+  Keypair,
+  Connection,
+  LAMPORTS_PER_SOL,
+  PublicKey,
+} from "@solana/web3.js";
+import {
+  searcherClient,
+  SearcherClient,
+} from "jito-ts/dist/sdk/block-engine/searcher";
+import type { Logger } from "pino";
+import { pino } from "pino";
 import type { Options } from "yargs";
 import type { Options } from "yargs";
+
 import * as options from "../options.js";
 import * as options from "../options.js";
 import { readPriceConfigFile } from "../price-config.js";
 import { readPriceConfigFile } from "../price-config.js";
 import { PythPriceListener } from "../pyth-price-listener.js";
 import { PythPriceListener } from "../pyth-price-listener.js";
@@ -8,22 +33,10 @@ import {
   SolanaPricePusherJito,
   SolanaPricePusherJito,
 } from "./solana.js";
 } from "./solana.js";
 import { Controller } from "../controller.js";
 import { Controller } from "../controller.js";
-import { PythSolanaReceiver } from "@pythnetwork/pyth-solana-receiver";
-import { Keypair, Connection, LAMPORTS_PER_SOL } from "@solana/web3.js";
-import fs from "fs";
-import { PublicKey } from "@solana/web3.js";
-import { pino } from "pino";
-import type { Logger } from "pino";
-import { HermesClient } from "@pythnetwork/hermes-client";
-import {
-  searcherClient,
-  SearcherClient,
-} from "jito-ts/dist/sdk/block-engine/searcher";
-import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet.js";
-import { filterInvalidPriceItems } from "../utils.js";
+import type { IBalanceTracker } from "../interface.js";
 import { PricePusherMetrics } from "../metrics.js";
 import { PricePusherMetrics } from "../metrics.js";
+import { filterInvalidPriceItems } from "../utils.js";
 import { createSolanaBalanceTracker } from "./balance-tracker.js";
 import { createSolanaBalanceTracker } from "./balance-tracker.js";
-import type { IBalanceTracker } from "../interface.js";
 
 
 export default {
 export default {
   command: "solana",
   command: "solana",
@@ -47,7 +60,7 @@ export default {
     "compute-unit-price-micro-lamports": {
     "compute-unit-price-micro-lamports": {
       description: "Priority fee per compute unit",
       description: "Priority fee per compute unit",
       type: "number",
       type: "number",
-      default: 50000,
+      default: 50_000,
     } as Options,
     } as Options,
     "jito-endpoints": {
     "jito-endpoints": {
       description: "Jito endpoint(s) - comma-separated list of endpoints",
       description: "Jito endpoint(s) - comma-separated list of endpoints",
@@ -235,9 +248,9 @@ export default {
         lookupTableAccount,
         lookupTableAccount,
       );
       );
 
 
-      jitoClients.forEach((client, index) => {
+      for (const [index, client] of jitoClients.entries()) {
         onBundleResult(client, logger.child({ module: `JitoClient-${index}` }));
         onBundleResult(client, logger.child({ module: `JitoClient-${index}` }));
-      });
+      }
     } else {
     } else {
       solanaPricePusher = new SolanaPricePusher(
       solanaPricePusher = new SolanaPricePusher(
         pythSolanaReceiver,
         pythSolanaReceiver,
@@ -269,14 +282,15 @@ export default {
       },
       },
     );
     );
 
 
-    controller.start();
+    void controller.start();
   },
   },
 };
 };
 
 
 export const onBundleResult = (c: SearcherClient, logger: Logger) => {
 export const onBundleResult = (c: SearcherClient, logger: Logger) => {
   try {
   try {
     c.onBundleResult(
     c.onBundleResult(
-      () => undefined,
+      // eslint-disable-next-line @typescript-eslint/no-empty-function
+      () => {},
       (err) => {
       (err) => {
         logger.error(err, "Error in bundle result");
         logger.error(err, "Error in bundle result");
       },
       },

+ 45 - 44
apps/price_pusher/src/solana/solana.ts

@@ -1,20 +1,19 @@
-import { PythSolanaReceiver } from "@pythnetwork/pyth-solana-receiver";
-import {
-  ChainPriceListener,
-  type IPricePusher,
-  type PriceInfo,
-  type PriceItem,
-} from "../interface.js";
-import type { DurationInSeconds } from "../utils.js";
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+/* eslint-disable @typescript-eslint/no-explicit-any */
 import { HermesClient } from "@pythnetwork/hermes-client";
 import { HermesClient } from "@pythnetwork/hermes-client";
+import { sliceAccumulatorUpdateData } from "@pythnetwork/price-service-sdk";
+import { PythSolanaReceiver } from "@pythnetwork/pyth-solana-receiver";
 import {
 import {
   sendTransactions,
   sendTransactions,
   sendTransactionsJito,
   sendTransactionsJito,
 } from "@pythnetwork/solana-utils";
 } from "@pythnetwork/solana-utils";
+import { AddressLookupTableAccount, LAMPORTS_PER_SOL } from "@solana/web3.js";
 import { SearcherClient } from "jito-ts/dist/sdk/block-engine/searcher";
 import { SearcherClient } from "jito-ts/dist/sdk/block-engine/searcher";
-import { sliceAccumulatorUpdateData } from "@pythnetwork/price-service-sdk";
 import type { Logger } from "pino";
 import type { Logger } from "pino";
-import { AddressLookupTableAccount, LAMPORTS_PER_SOL } from "@solana/web3.js";
+
+import type { IPricePusher, PriceInfo, PriceItem } from "../interface.js";
+import { ChainPriceListener } from "../interface.js";
+import type { DurationInSeconds } from "../utils.js";
 
 
 const HEALTH_CHECK_TIMEOUT_SECONDS = 60;
 const HEALTH_CHECK_TIMEOUT_SECONDS = 60;
 
 
@@ -39,25 +38,25 @@ export class SolanaPriceListener extends ChainPriceListener {
       const blockTime =
       const blockTime =
         await this.pythSolanaReceiver.connection.getBlockTime(slot);
         await this.pythSolanaReceiver.connection.getBlockTime(slot);
       if (
       if (
-        blockTime === null ||
-        blockTime < Date.now() / 1000 - HEALTH_CHECK_TIMEOUT_SECONDS
+        (blockTime === null ||
+          blockTime < Date.now() / 1000 - HEALTH_CHECK_TIMEOUT_SECONDS) &&
+        blockTime !== null
       ) {
       ) {
-        if (blockTime !== null) {
-          this.logger.info(
-            `Solana connection is behind by ${
-              Date.now() / 1000 - blockTime
-            } seconds`,
-          );
-        }
+        this.logger.info(
+          `Solana connection is behind by ${(
+            Date.now() / 1000 -
+            blockTime
+          ).toString()} seconds`,
+        );
       }
       }
-    } catch (err) {
-      this.logger.error({ err }, "checkHealth failed");
+    } catch (error) {
+      this.logger.error({ err: error }, "checkHealth failed");
     }
     }
   }
   }
 
 
   override async start() {
   override async start() {
     // Frequently check the RPC connection to ensure it is healthy
     // Frequently check the RPC connection to ensure it is healthy
-    setInterval(this.checkHealth.bind(this), 5000);
+    setInterval(() => void this.checkHealth(), 5000);
 
 
     await super.start();
     await super.start();
   }
   }
@@ -70,21 +69,22 @@ export class SolanaPriceListener extends ChainPriceListener {
           Buffer.from(priceId, "hex"),
           Buffer.from(priceId, "hex"),
         );
         );
       this.logger.debug(
       this.logger.debug(
-        `Polled a Solana on chain price for feed ${this.priceIdToAlias.get(
-          priceId,
-        )} (${priceId}).`,
+        `Polled a Solana on chain price for feed ${
+          this.priceIdToAlias.get(priceId)?.toString() ?? ""
+        } (${priceId}).`,
+      );
+      return priceFeedAccount
+        ? {
+            conf: priceFeedAccount.priceMessage.conf.toString(),
+            price: priceFeedAccount.priceMessage.price.toString(),
+            publishTime: priceFeedAccount.priceMessage.publishTime.toNumber(),
+          }
+        : undefined;
+    } catch (error) {
+      this.logger.error(
+        { err: error, priceId },
+        `Polling on-chain price failed.`,
       );
       );
-      if (priceFeedAccount) {
-        return {
-          conf: priceFeedAccount.priceMessage.conf.toString(),
-          price: priceFeedAccount.priceMessage.price.toString(),
-          publishTime: priceFeedAccount.priceMessage.publishTime.toNumber(),
-        };
-      } else {
-        return undefined;
-      }
-    } catch (err) {
-      this.logger.error({ err, priceId }, `Polling on-chain price failed.`);
       return undefined;
       return undefined;
     }
     }
   }
   }
@@ -122,8 +122,8 @@ export class SolanaPricePusher implements IPricePusher {
         },
         },
       );
       );
       priceFeedUpdateData = response.binary.data;
       priceFeedUpdateData = response.binary.data;
-    } catch (err: any) {
-      this.logger.error(err, "getPriceFeedsUpdateData failed:");
+    } catch (error: any) {
+      this.logger.error(error, "getPriceFeedsUpdateData failed:");
       return;
       return;
     }
     }
 
 
@@ -150,8 +150,8 @@ export class SolanaPricePusher implements IPricePusher {
         this.pythSolanaReceiver.wallet,
         this.pythSolanaReceiver.wallet,
       );
       );
       this.logger.info({ signatures }, "updatePriceFeed successful");
       this.logger.info({ signatures }, "updatePriceFeed successful");
-    } catch (err: any) {
-      this.logger.error(err, "updatePriceFeed failed");
+    } catch (error: any) {
+      this.logger.error(error, "updatePriceFeed failed");
       return;
       return;
     }
     }
   }
   }
@@ -189,8 +189,9 @@ export class SolanaPricePusherJito implements IPricePusher {
       return Math.floor(
       return Math.floor(
         Number(data[0].landed_tips_50th_percentile) * LAMPORTS_PER_SOL,
         Number(data[0].landed_tips_50th_percentile) * LAMPORTS_PER_SOL,
       );
       );
-    } catch (err: any) {
-      this.logger.error({ err }, "getRecentJitoTips failed");
+    } catch (error: any) {
+      // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
+      this.logger.error({ err: error }, "getRecentJitoTips failed");
       return undefined;
       return undefined;
     }
     }
   }
   }
@@ -211,8 +212,8 @@ export class SolanaPricePusherJito implements IPricePusher {
         encoding: "base64",
         encoding: "base64",
       });
       });
       priceFeedUpdateData = response.binary.data;
       priceFeedUpdateData = response.binary.data;
-    } catch (err: any) {
-      this.logger.error(err, "getPriceFeedsUpdateData failed");
+    } catch (error: any) {
+      this.logger.error(error, "getPriceFeedsUpdateData failed");
       return;
       return;
     }
     }
 
 

+ 12 - 11
apps/price_pusher/src/sui/balance-tracker.ts

@@ -1,20 +1,21 @@
 import { SuiClient } from "@mysten/sui/client";
 import { SuiClient } from "@mysten/sui/client";
-import {
-  BaseBalanceTracker,
-  type BaseBalanceTrackerConfig,
-  type IBalanceTracker,
+import type { Logger } from "pino";
+
+import type {
+  BaseBalanceTrackerConfig,
+  IBalanceTracker,
 } from "../interface.js";
 } from "../interface.js";
-import type { DurationInSeconds } from "../utils.js";
+import { BaseBalanceTracker } from "../interface.js";
 import { PricePusherMetrics } from "../metrics.js";
 import { PricePusherMetrics } from "../metrics.js";
-import type { Logger } from "pino";
+import type { DurationInSeconds } from "../utils.js";
 
 
 /**
 /**
  * Sui-specific configuration for balance tracker
  * Sui-specific configuration for balance tracker
  */
  */
-export interface SuiBalanceTrackerConfig extends BaseBalanceTrackerConfig {
+export type SuiBalanceTrackerConfig = {
   /** Sui client instance */
   /** Sui client instance */
   client: SuiClient;
   client: SuiClient;
-}
+} & BaseBalanceTrackerConfig;
 
 
 /**
 /**
  * Sui-specific implementation of the balance tracker
  * Sui-specific implementation of the balance tracker
@@ -50,7 +51,7 @@ export class SuiBalanceTracker extends BaseBalanceTracker {
       );
       );
 
 
       this.logger.debug(
       this.logger.debug(
-        `Updated Sui wallet balance: ${this.address} = ${normalizedBalance} SUI`,
+        `Updated Sui wallet balance: ${this.address} = ${normalizedBalance.toString()} SUI`,
       );
       );
     } catch (error) {
     } catch (error) {
       this.logger.error(
       this.logger.error(
@@ -64,14 +65,14 @@ export class SuiBalanceTracker extends BaseBalanceTracker {
 /**
 /**
  * Parameters for creating a Sui balance tracker
  * Parameters for creating a Sui balance tracker
  */
  */
-export interface CreateSuiBalanceTrackerParams {
+export type CreateSuiBalanceTrackerParams = {
   client: SuiClient;
   client: SuiClient;
   address: string;
   address: string;
   network: string;
   network: string;
   updateInterval: DurationInSeconds;
   updateInterval: DurationInSeconds;
   metrics: PricePusherMetrics;
   metrics: PricePusherMetrics;
   logger: Logger;
   logger: Logger;
-}
+};
 
 
 /**
 /**
  * Factory function to create a balance tracker for Sui chain
  * Factory function to create a balance tracker for Sui chain

+ 17 - 10
apps/price_pusher/src/sui/command.ts

@@ -1,17 +1,24 @@
+/* eslint-disable @typescript-eslint/no-non-null-assertion */
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import fs from "node:fs";
+
+import { SuiClient } from "@mysten/sui/client";
+import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
 import { HermesClient } from "@pythnetwork/hermes-client";
 import { HermesClient } from "@pythnetwork/hermes-client";
+import pino from "pino";
+import type { Options } from "yargs";
+
+import { Controller } from "../controller.js";
+import { PricePusherMetrics } from "../metrics.js";
 import * as options from "../options.js";
 import * as options from "../options.js";
 import { readPriceConfigFile } from "../price-config";
 import { readPriceConfigFile } from "../price-config";
-import fs from "fs";
 import { PythPriceListener } from "../pyth-price-listener.js";
 import { PythPriceListener } from "../pyth-price-listener.js";
-import { Controller } from "../controller.js";
-import type { Options } from "yargs";
+import { createSuiBalanceTracker } from "./balance-tracker.js";
 import { SuiPriceListener, SuiPricePusher } from "./sui.js";
 import { SuiPriceListener, SuiPricePusher } from "./sui.js";
-import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
-import pino from "pino";
 import { filterInvalidPriceItems } from "../utils.js";
 import { filterInvalidPriceItems } from "../utils.js";
-import { PricePusherMetrics } from "../metrics.js";
-import { createSuiBalanceTracker } from "./balance-tracker.js";
-import { SuiClient } from "@mysten/sui/client";
 
 
 export default {
 export default {
   command: "sui",
   command: "sui",
@@ -103,7 +110,7 @@ export default {
     const priceConfigs = readPriceConfigFile(priceConfigFile);
     const priceConfigs = readPriceConfigFile(priceConfigFile);
     const hermesClient = new HermesClient(priceServiceEndpoint);
     const hermesClient = new HermesClient(priceServiceEndpoint);
 
 
-    const mnemonic = fs.readFileSync(mnemonicFile, "utf-8").trim();
+    const mnemonic = fs.readFileSync(mnemonicFile, "utf8").trim();
     const keypair = Ed25519Keypair.deriveKeypair(
     const keypair = Ed25519Keypair.deriveKeypair(
       mnemonic,
       mnemonic,
       `m/44'/784'/${accountIndex}'/0'/0'`,
       `m/44'/784'/${accountIndex}'/0'/0'`,
@@ -191,6 +198,6 @@ export default {
       await balanceTracker.start();
       await balanceTracker.start();
     }
     }
 
 
-    controller.start();
+    void controller.start();
   },
   },
 };
 };

+ 47 - 47
apps/price_pusher/src/sui/sui.ts

@@ -1,20 +1,21 @@
-import {
-  ChainPriceListener,
-  type IPricePusher,
-  type PriceInfo,
-  type PriceItem,
-} from "../interface.js";
-import type { DurationInSeconds } from "../utils.js";
-import { SuiPythClient } from "@pythnetwork/pyth-sui-js";
+/* eslint-disable @typescript-eslint/no-non-null-assertion */
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
+/* eslint-disable @typescript-eslint/no-explicit-any */
+/* eslint-disable @typescript-eslint/no-unsafe-return */
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+import type { SuiObjectRef, PaginatedCoins } from "@mysten/sui/client";
+import { SuiClient } from "@mysten/sui/client";
 import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
 import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
 import { Transaction } from "@mysten/sui/transactions";
 import { Transaction } from "@mysten/sui/transactions";
-import {
-  SuiClient,
-  type SuiObjectRef,
-  type PaginatedCoins,
-} from "@mysten/sui/client";
-import type { Logger } from "pino";
 import { HermesClient } from "@pythnetwork/hermes-client";
 import { HermesClient } from "@pythnetwork/hermes-client";
+import { SuiPythClient } from "@pythnetwork/pyth-sui-js";
+import type { Logger } from "pino";
+
+import type { IPricePusher, PriceInfo, PriceItem } from "../interface.js";
+import { ChainPriceListener } from "../interface.js";
+import type { DurationInSeconds } from "../utils.js";
 const GAS_FEE_FOR_SPLIT = 2_000_000_000;
 const GAS_FEE_FOR_SPLIT = 2_000_000_000;
 // TODO: read this from on chain config
 // TODO: read this from on chain config
 const MAX_NUM_GAS_OBJECTS_IN_PTB = 256;
 const MAX_NUM_GAS_OBJECTS_IN_PTB = 256;
@@ -62,7 +63,7 @@ export class SuiPriceListener extends ChainPriceListener {
         options: { showContent: true },
         options: { showContent: true },
       });
       });
 
 
-      if (!priceInfoObject.data || !priceInfoObject.data.content)
+      if (!priceInfoObject.data?.content)
         throw new Error("Price not found on chain for price id " + priceId);
         throw new Error("Price not found on chain for price id " + priceId);
 
 
       if (priceInfoObject.data.content.dataType !== "moveObject")
       if (priceInfoObject.data.content.dataType !== "moveObject")
@@ -80,13 +81,13 @@ export class SuiPriceListener extends ChainPriceListener {
       const timestamp = priceInfo.timestamp;
       const timestamp = priceInfo.timestamp;
 
 
       return {
       return {
-        price: negative ? "-" + magnitude : magnitude,
+        price: negative ? `-${magnitude}` : magnitude,
         conf,
         conf,
         publishTime: Number(timestamp),
         publishTime: Number(timestamp),
       };
       };
-    } catch (err) {
+    } catch (error) {
       this.logger.error(
       this.logger.error(
-        err,
+        error,
         `Polling Sui on-chain price for ${priceId} failed.`,
         `Polling Sui on-chain price for ${priceId} failed.`,
       );
       );
       return undefined;
       return undefined;
@@ -122,8 +123,6 @@ export class SuiPricePusher implements IPricePusher {
   /**
   /**
    * getPackageId returns the latest package id that the object belongs to. Use this to
    * getPackageId returns the latest package id that the object belongs to. Use this to
    * fetch the latest package id for a given object id and handle package upgrades automatically.
    * fetch the latest package id for a given object id and handle package upgrades automatically.
-   * @param provider
-   * @param objectId
    * @returns package id
    * @returns package id
    */
    */
   static async getPackageId(
   static async getPackageId(
@@ -252,7 +251,7 @@ export class SuiPricePusher implements IPricePusher {
   }
   }
 
 
   /** Send every transaction in txs in parallel, returning when all transactions have completed. */
   /** Send every transaction in txs in parallel, returning when all transactions have completed. */
-  private async sendTransactionBlocks(txs: Transaction[]): Promise<void[]> {
+  private async sendTransactionBlocks(txs: Transaction[]) {
     return Promise.all(txs.map((tx) => this.sendTransactionBlock(tx)));
     return Promise.all(txs.map((tx) => this.sendTransactionBlock(tx)));
   }
   }
 
 
@@ -284,17 +283,17 @@ export class SuiPricePusher implements IPricePusher {
         { hash: result.digest },
         { hash: result.digest },
         "Successfully updated price with transaction digest",
         "Successfully updated price with transaction digest",
       );
       );
-    } catch (err: any) {
+    } catch (error: any) {
       if (
       if (
-        String(err).includes("Balance of gas object") ||
-        String(err).includes("GasBalanceTooLow")
+        String(error).includes("Balance of gas object") ||
+        String(error).includes("GasBalanceTooLow")
       ) {
       ) {
-        this.logger.error(err, "Insufficient gas balance");
+        this.logger.error(error, "Insufficient gas balance");
         // If the error is caused by insufficient gas, we should panic
         // If the error is caused by insufficient gas, we should panic
-        throw err;
+        throw error;
       } else {
       } else {
         this.logger.error(
         this.logger.error(
-          err,
+          error,
           "Failed to update price. Trying to refresh gas object references.",
           "Failed to update price. Trying to refresh gas object references.",
         );
         );
         // Refresh the coin object here in case the error is caused by an object version mismatch.
         // Refresh the coin object here in case the error is caused by an object version mismatch.
@@ -343,8 +342,7 @@ export class SuiPricePusher implements IPricePusher {
     });
     });
     let balance;
     let balance;
     if (
     if (
-      coinResult.data &&
-      coinResult.data.content &&
+      coinResult.data?.content &&
       coinResult.data.content.dataType == "moveObject"
       coinResult.data.content.dataType == "moveObject"
     ) {
     ) {
       // eslint-disable-next-line @typescript-eslint/ban-ts-comment
       // eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -373,14 +371,14 @@ export class SuiPricePusher implements IPricePusher {
     ref: SuiObjectRef,
     ref: SuiObjectRef,
   ): Promise<SuiObjectRef> {
   ): Promise<SuiObjectRef> {
     const objectResponse = await provider.getObject({ id: ref.objectId });
     const objectResponse = await provider.getObject({ id: ref.objectId });
-    if (objectResponse.data !== undefined) {
+    if (objectResponse.data === undefined) {
+      throw new Error("Failed to refresh object reference");
+    } else {
       return {
       return {
         digest: objectResponse.data!.digest,
         digest: objectResponse.data!.digest,
         objectId: objectResponse.data!.objectId,
         objectId: objectResponse.data!.objectId,
         version: objectResponse.data!.version,
         version: objectResponse.data!.version,
       };
       };
-    } else {
-      throw new Error("Failed to refresh object reference");
     }
     }
   }
   }
 
 
@@ -398,15 +396,14 @@ export class SuiPricePusher implements IPricePusher {
         cursor,
         cursor,
       });
       });
       numCoins += paginatedCoins.data.length;
       numCoins += paginatedCoins.data.length;
-      paginatedCoins.data.forEach((c) =>
+      for (const c of paginatedCoins.data)
         coins.add(
         coins.add(
           JSON.stringify({
           JSON.stringify({
             objectId: c.coinObjectId,
             objectId: c.coinObjectId,
             version: c.version,
             version: c.version,
             digest: c.digest,
             digest: c.digest,
           }),
           }),
-        ),
-      );
+        );
       hasNextPage = paginatedCoins.hasNextPage;
       hasNextPage = paginatedCoins.hasNextPage;
       cursor = paginatedCoins.nextCursor;
       cursor = paginatedCoins.nextCursor;
     }
     }
@@ -442,7 +439,7 @@ export class SuiPricePusher implements IPricePusher {
       transaction: tx,
       transaction: tx,
       options: { showEffects: true },
       options: { showEffects: true },
     });
     });
-    const error = result?.effects?.status.error;
+    const error = result.effects?.status.error;
     if (error) {
     if (error) {
       throw new Error(
       throw new Error(
         `Failed to initialize gas pool: ${error}. Try re-running the script`,
         `Failed to initialize gas pool: ${error}. Try re-running the script`,
@@ -451,7 +448,7 @@ export class SuiPricePusher implements IPricePusher {
     const newCoins = result.effects!.created!.map((obj) => obj.reference);
     const newCoins = result.effects!.created!.map((obj) => obj.reference);
     if (newCoins.length !== numGasObjects) {
     if (newCoins.length !== numGasObjects) {
       throw new Error(
       throw new Error(
-        `Failed to initialize gas pool. Expected ${numGasObjects}, got: ${newCoins}`,
+        `Failed to initialize gas pool. Expected ${numGasObjects}, got: ${JSON.stringify(newCoins)}`,
       );
       );
     }
     }
     return newCoins;
     return newCoins;
@@ -475,8 +472,8 @@ export class SuiPricePusher implements IPricePusher {
       MAX_NUM_GAS_OBJECTS_IN_PTB - 2,
       MAX_NUM_GAS_OBJECTS_IN_PTB - 2,
     );
     );
     let finalCoin;
     let finalCoin;
-    const lockedAddresses: Set<string> = new Set();
-    initialLockedAddresses.forEach((value) => lockedAddresses.add(value));
+    const lockedAddresses = new Set<string>();
+    for (const value of initialLockedAddresses) lockedAddresses.add(value);
     for (let i = 0; i < gasCoinsChunks.length; i++) {
     for (let i = 0; i < gasCoinsChunks.length; i++) {
       const mergeTx = new Transaction();
       const mergeTx = new Transaction();
       let coins = gasCoinsChunks[i];
       let coins = gasCoinsChunks[i];
@@ -493,15 +490,17 @@ export class SuiPricePusher implements IPricePusher {
           transaction: mergeTx,
           transaction: mergeTx,
           options: { showEffects: true },
           options: { showEffects: true },
         });
         });
-      } catch (err) {
-        logger.error(err, "Merge transaction failed with error");
+      } catch (error_) {
+        logger.error(error_, "Merge transaction failed with error");
 
 
         if (
         if (
-          String(err).includes(
+          String(error_).includes(
             "quorum of validators because of locked objects. Retried a conflicting transaction",
             "quorum of validators because of locked objects. Retried a conflicting transaction",
           )
           )
         ) {
         ) {
-          Object.values((err as any).data).forEach((lockedObjects: any) => {
+          // eslint-disable-next-line unicorn/no-array-for-each
+          Object.values((error_ as any).data).forEach((lockedObjects: any) => {
+            // eslint-disable-next-line @typescript-eslint/no-unsafe-call, unicorn/no-array-for-each
             lockedObjects.forEach((lockedObject: [string, number, string]) => {
             lockedObjects.forEach((lockedObject: [string, number, string]) => {
               lockedAddresses.add(lockedObject[0]);
               lockedAddresses.add(lockedObject[0]);
             });
             });
@@ -510,9 +509,9 @@ export class SuiPricePusher implements IPricePusher {
           i--;
           i--;
           continue;
           continue;
         }
         }
-        throw err;
+        throw error_;
       }
       }
-      const error = mergeResult?.effects?.status.error;
+      const error = mergeResult.effects?.status.error;
       if (error) {
       if (error) {
         throw new Error(
         throw new Error(
           `Failed to merge coins when initializing gas pool: ${error}. Try re-running the script`,
           `Failed to merge coins when initializing gas pool: ${error}. Try re-running the script`,
@@ -521,11 +520,12 @@ export class SuiPricePusher implements IPricePusher {
       finalCoin = mergeResult.effects!.mutated!.map((obj) => obj.reference)[0];
       finalCoin = mergeResult.effects!.mutated!.map((obj) => obj.reference)[0];
     }
     }
 
 
-    return finalCoin as SuiObjectRef;
+    // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
+    return finalCoin!;
   }
   }
 }
 }
 
 
-function chunkArray<T>(array: Array<T>, size: number): Array<Array<T>> {
+function chunkArray<T>(array: T[], size: number): T[][] {
   const chunked = [];
   const chunked = [];
   let index = 0;
   let index = 0;
   while (index < array.length) {
   while (index < array.length) {

+ 10 - 5
apps/price_pusher/src/ton/command.ts

@@ -1,15 +1,20 @@
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import fs from "node:fs";
+
+import { HermesClient } from "@pythnetwork/hermes-client";
+import { Address, TonClient } from "@ton/ton";
 import { pino } from "pino";
 import { pino } from "pino";
 import type { Options } from "yargs";
 import type { Options } from "yargs";
+
+import type { IPriceListener } from "../interface.js";
 import * as options from "../options.js";
 import * as options from "../options.js";
 import { readPriceConfigFile } from "../price-config.js";
 import { readPriceConfigFile } from "../price-config.js";
 import { PythPriceListener } from "../pyth-price-listener.js";
 import { PythPriceListener } from "../pyth-price-listener.js";
 import { TonPriceListener, TonPricePusher } from "./ton.js";
 import { TonPriceListener, TonPricePusher } from "./ton.js";
 import { Controller } from "../controller.js";
 import { Controller } from "../controller.js";
-import { Address, TonClient } from "@ton/ton";
-import fs from "fs";
-import { HermesClient } from "@pythnetwork/hermes-client";
 import { filterInvalidPriceItems } from "../utils.js";
 import { filterInvalidPriceItems } from "../utils.js";
-import type { IPriceListener } from "../interface.js";
 
 
 export default {
 export default {
   command: "ton",
   command: "ton",
@@ -109,6 +114,6 @@ export default {
       { pushingFrequency },
       { pushingFrequency },
     );
     );
 
 
-    await controller.start();
+    void controller.start();
   },
   },
 };
 };

+ 23 - 26
apps/price_pusher/src/ton/ton.ts

@@ -1,25 +1,18 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
 import { HermesClient } from "@pythnetwork/hermes-client";
 import { HermesClient } from "@pythnetwork/hermes-client";
-import {
-  ChainPriceListener,
-  type IPricePusher,
-  type PriceInfo,
-  type PriceItem,
-} from "../interface.js";
-import { addLeading0x, type DurationInSeconds } from "../utils.js";
-import type { Logger } from "pino";
-import {
-  Address,
-  type ContractProvider,
-  type OpenedContract,
-  type Sender,
-  TonClient,
-  WalletContractV4,
-} from "@ton/ton";
-import { keyPairFromSeed } from "@ton/crypto";
 import {
 import {
   PythContract,
   PythContract,
   calculateUpdatePriceFeedsFee,
   calculateUpdatePriceFeedsFee,
 } from "@pythnetwork/pyth-ton-js";
 } from "@pythnetwork/pyth-ton-js";
+import { keyPairFromSeed } from "@ton/crypto";
+import type { ContractProvider, OpenedContract, Sender } from "@ton/ton";
+import { Address, TonClient, WalletContractV4 } from "@ton/ton";
+import type { Logger } from "pino";
+
+import type { IPricePusher, PriceInfo, PriceItem } from "../interface.js";
+import { ChainPriceListener } from "../interface.js";
+import type { DurationInSeconds } from "../utils.js";
+import { addLeading0x } from "../utils.js";
 
 
 export class TonPriceListener extends ChainPriceListener {
 export class TonPriceListener extends ChainPriceListener {
   private contract: OpenedContract<PythContract>;
   private contract: OpenedContract<PythContract>;
@@ -45,9 +38,9 @@ export class TonPriceListener extends ChainPriceListener {
       const priceInfo = await this.contract.getPriceUnsafe(formattedPriceId);
       const priceInfo = await this.contract.getPriceUnsafe(formattedPriceId);
 
 
       this.logger.debug(
       this.logger.debug(
-        `Polled a TON on chain price for feed ${this.priceIdToAlias.get(
-          priceId,
-        )} (${priceId}).`,
+        `Polled a TON on chain price for feed ${
+          this.priceIdToAlias.get(priceId) ?? ""
+        } (${priceId}).`,
       );
       );
 
 
       return {
       return {
@@ -55,8 +48,11 @@ export class TonPriceListener extends ChainPriceListener {
         price: priceInfo.price.toString(),
         price: priceInfo.price.toString(),
         publishTime: priceInfo.publishTime,
         publishTime: priceInfo.publishTime,
       };
       };
-    } catch (err) {
-      this.logger.error({ err, priceId }, `Polling on-chain price failed.`);
+    } catch (error) {
+      this.logger.error(
+        { err: error, priceId },
+        `Polling on-chain price failed.`,
+      );
       return undefined;
       return undefined;
     }
     }
   }
   }
@@ -85,6 +81,7 @@ export class TonPricePusher implements IPricePusher {
     this.sender = provider.sender(keyPair.secretKey);
     this.sender = provider.sender(keyPair.secretKey);
   }
   }
 
 
+  // eslint-disable-next-line @typescript-eslint/no-unused-vars
   async updatePriceFeed(priceIds: string[], _: number[]): Promise<void> {
   async updatePriceFeed(priceIds: string[], _: number[]): Promise<void> {
     if (priceIds.length === 0) {
     if (priceIds.length === 0) {
       return;
       return;
@@ -97,8 +94,8 @@ export class TonPricePusher implements IPricePusher {
         ignoreInvalidPriceIds: true,
         ignoreInvalidPriceIds: true,
       });
       });
       priceFeedUpdateData = response.binary.data;
       priceFeedUpdateData = response.binary.data;
-    } catch (err: any) {
-      this.logger.error(err, "getPriceFeedsUpdateData failed");
+    } catch (error: any) {
+      this.logger.error(error, "getPriceFeedsUpdateData failed");
       return;
       return;
     }
     }
 
 
@@ -118,8 +115,8 @@ export class TonPricePusher implements IPricePusher {
       }
       }
 
 
       this.logger.info("updatePriceFeed successful");
       this.logger.info("updatePriceFeed successful");
-    } catch (err: any) {
-      this.logger.error(err, "updatePriceFeed failed");
+    } catch (error: any) {
+      this.logger.error(error, "updatePriceFeed failed");
     }
     }
   }
   }
 }
 }

+ 15 - 7
apps/price_pusher/src/utils.ts

@@ -1,4 +1,9 @@
-import { HermesClient, type HexString } from "@pythnetwork/hermes-client";
+/* eslint-disable @typescript-eslint/no-unsafe-return */
+/* eslint-disable @typescript-eslint/no-unnecessary-type-parameters */
+/* eslint-disable @typescript-eslint/no-explicit-any */
+import type { HexString } from "@pythnetwork/hermes-client";
+import { HermesClient } from "@pythnetwork/hermes-client";
+
 import type { PriceItem } from "./interface.js";
 import type { PriceItem } from "./interface.js";
 
 
 export type PctNumber = number;
 export type PctNumber = number;
@@ -14,7 +19,7 @@ export async function sleep(ms: number): Promise<void> {
 
 
 export function removeLeading0x(id: HexString): HexString {
 export function removeLeading0x(id: HexString): HexString {
   if (id.startsWith("0x")) {
   if (id.startsWith("0x")) {
-    return id.substring(2);
+    return id.slice(2);
   }
   }
   return id;
   return id;
 }
 }
@@ -37,14 +42,14 @@ export function isWsEndpoint(endpoint: string): boolean {
 }
 }
 
 
 export function verifyValidOption<
 export function verifyValidOption<
-  options extends Readonly<Array<any>>,
+  options extends readonly any[],
   validOption extends options[number],
   validOption extends options[number],
 >(option: any, validOptions: options) {
 >(option: any, validOptions: options) {
   if (validOptions.includes(option)) {
   if (validOptions.includes(option)) {
     return option as validOption;
     return option as validOption;
   }
   }
-  const errorString =
-    option + " is not a valid option. Please choose between " + validOptions;
+  // eslint-disable-next-line @typescript-eslint/restrict-template-expressions
+  const errorString = `${option} is not a valid option. Please choose betweeen ${validOptions}`;
   throw new Error(errorString);
   throw new Error(errorString);
 }
 }
 
 
@@ -64,15 +69,18 @@ export async function filterInvalidPriceItems(
   invalidPriceItems: PriceItem[];
   invalidPriceItems: PriceItem[];
 }> {
 }> {
   const priceMetadata = await hermesClient.getPriceFeeds();
   const priceMetadata = await hermesClient.getPriceFeeds();
-  const allPriceIds = priceMetadata.map((priceMetadata) => priceMetadata.id);
+  const allPriceIds = new Set(
+    priceMetadata.map((priceMetadata) => priceMetadata.id),
+  );
 
 
   // Filter out invalid price ids
   // Filter out invalid price ids
+  // eslint-disable-next-line unicorn/no-array-reduce
   const { existingPriceItems, invalidPriceItems } = priceItems.reduce<{
   const { existingPriceItems, invalidPriceItems } = priceItems.reduce<{
     existingPriceItems: PriceItem[];
     existingPriceItems: PriceItem[];
     invalidPriceItems: PriceItem[];
     invalidPriceItems: PriceItem[];
   }>(
   }>(
     (acc, item) => {
     (acc, item) => {
-      if (allPriceIds.includes(item.id)) {
+      if (allPriceIds.has(item.id)) {
         acc.existingPriceItems.push(item);
         acc.existingPriceItems.push(item);
       } else {
       } else {
         acc.invalidPriceItems.push(item);
         acc.invalidPriceItems.push(item);

+ 1 - 1
apps/staking/package.json

@@ -75,4 +75,4 @@
     "vercel": "catalog:"
     "vercel": "catalog:"
   },
   },
   "packageManager": "pnpm@10.19.0"
   "packageManager": "pnpm@10.19.0"
-}
+}

+ 2 - 7
apps/staking/tsconfig.build.json

@@ -5,10 +5,5 @@
     "incremental": false,
     "incremental": false,
     "declaration": true
     "declaration": true
   },
   },
-  "exclude": [
-    "node_modules",
-    "dist",
-    "examples/",
-    "**/__tests__/*"
-  ]
-}
+  "exclude": ["node_modules", "dist", "examples/", "**/__tests__/*"]
+}

+ 11 - 13
contract_manager/scripts/batchDeployReceivers.ts

@@ -3,17 +3,19 @@
  * wormhole addresses to the deployed receiver contracts.
  * wormhole addresses to the deployed receiver contracts.
  */
  */
 
 
-import yargs from "yargs";
-import { hideBin } from "yargs/helpers";
+import * as fs from "node:fs";
+
 import {
 import {
   DefaultStore,
   DefaultStore,
   EvmChain,
   EvmChain,
   loadHotWallet,
   loadHotWallet,
   EvmWormholeContract,
   EvmWormholeContract,
 } from "@pythnetwork/contract-manager";
 } from "@pythnetwork/contract-manager";
-import Web3 from "web3";
 import { CHAINS } from "@pythnetwork/xc-admin-common";
 import { CHAINS } from "@pythnetwork/xc-admin-common";
-import * as fs from "fs";
+import Web3 from "web3";
+import yargs from "yargs";
+import { hideBin } from "yargs/helpers";
+
 
 
 import { getDefaultConfig } from "../../target_chains/ethereum/contracts/scripts/contractManagerConfig";
 import { getDefaultConfig } from "../../target_chains/ethereum/contracts/scripts/contractManagerConfig";
 
 
@@ -63,14 +65,14 @@ async function memoize(
 async function main() {
 async function main() {
   const argv = await parser.argv;
   const argv = await parser.argv;
   const privateKey = argv["private-key"];
   const privateKey = argv["private-key"];
-  const network = argv["network"];
+  const network = argv.network;
 
 
-  const setupInfo = await import(argv["contract"] + "/ReceiverSetup.json");
+  const setupInfo = await import(argv.contract + "/ReceiverSetup.json");
   const implementationInfo = await import(
   const implementationInfo = await import(
-    argv["contract"] + "/ReceiverImplementation.json"
+    argv.contract + "/ReceiverImplementation.json"
   );
   );
   const receiverInfo = await import(
   const receiverInfo = await import(
-    argv["contract"] + "/WormholeReceiver.json"
+    argv.contract + "/WormholeReceiver.json"
   );
   );
 
 
   const payloads: Buffer[] = [];
   const payloads: Buffer[] = [];
@@ -133,11 +135,7 @@ async function main() {
     }
     }
   }
   }
   let vaultName;
   let vaultName;
-  if (network === "mainnet") {
-    vaultName = "mainnet-beta_FVQyHcooAtThJ83XFrNnv74BcinbRH3bRmfFamAHBfuj";
-  } else {
-    vaultName = "devnet_6baWtW1zTUVMSJHJQVxDUXWzqrQeYBr6mu31j3bTKwY3";
-  }
+  vaultName = network === "mainnet" ? "mainnet-beta_FVQyHcooAtThJ83XFrNnv74BcinbRH3bRmfFamAHBfuj" : "devnet_6baWtW1zTUVMSJHJQVxDUXWzqrQeYBr6mu31j3bTKwY3";
   const vault = DefaultStore.vaults[vaultName];
   const vault = DefaultStore.vaults[vaultName];
   vault.connect(await loadHotWallet(argv["ops-wallet"]));
   vault.connect(await loadHotWallet(argv["ops-wallet"]));
   await vault.proposeWormholeMessage(payloads);
   await vault.proposeWormholeMessage(payloads);

+ 18 - 13
contract_manager/scripts/check_proposal.ts

@@ -1,8 +1,10 @@
-import yargs from "yargs";
-import { hideBin } from "yargs/helpers";
-import { CosmWasmChain, EvmChain } from "../src/core/chains";
-import { createHash } from "crypto";
-import { DefaultStore } from "../src/node/utils/store";
+import { createHash } from "node:crypto";
+
+import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet";
+import {
+  getPythClusterApiUrl,
+  PythCluster,
+} from "@pythnetwork/client/lib/cluster";
 import {
 import {
   CosmosUpgradeContract,
   CosmosUpgradeContract,
   EvmExecute,
   EvmExecute,
@@ -12,20 +14,23 @@ import {
   MultisigParser,
   MultisigParser,
   WormholeMultisigInstruction,
   WormholeMultisigInstruction,
 } from "@pythnetwork/xc-admin-common";
 } from "@pythnetwork/xc-admin-common";
-import SquadsMesh from "@sqds/mesh";
-import {
-  getPythClusterApiUrl,
-  PythCluster,
-} from "@pythnetwork/client/lib/cluster";
-import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet";
 import { AccountMeta, Keypair, PublicKey } from "@solana/web3.js";
 import { AccountMeta, Keypair, PublicKey } from "@solana/web3.js";
+import SquadsMesh from "@sqds/mesh";
+import Web3 from "web3";
+import yargs from "yargs";
+import { hideBin } from "yargs/helpers";
+
+import { CosmWasmChain, EvmChain } from "../src/core/chains";
 import {
 import {
   EvmEntropyContract,
   EvmEntropyContract,
   EvmPriceFeedContract,
   EvmPriceFeedContract,
   getCodeDigestWithoutAddress,
   getCodeDigestWithoutAddress,
   EvmWormholeContract,
   EvmWormholeContract,
 } from "../src/core/contracts/evm";
 } from "../src/core/contracts/evm";
-import Web3 from "web3";
+import { DefaultStore } from "../src/node/utils/store";
+
+
+
 
 
 const parser = yargs(hideBin(process.argv))
 const parser = yargs(hideBin(process.argv))
   .usage("Usage: $0 --cluster <cluster_id> --proposal <proposal_address>")
   .usage("Usage: $0 --cluster <cluster_id> --proposal <proposal_address>")
@@ -179,7 +184,7 @@ async function main() {
               .encodeFunctionSignature(invokedMethod)
               .encodeFunctionSignature(invokedMethod)
               .replace("0x", "");
               .replace("0x", "");
 
 
-            let newImplementationAddress: string | undefined = undefined;
+            let newImplementationAddress: string | undefined;
             if (calldataHex.startsWith(methodSignature)) {
             if (calldataHex.startsWith(methodSignature)) {
               newImplementationAddress = web3.eth.abi.decodeParameter(
               newImplementationAddress = web3.eth.abi.decodeParameter(
                 "address",
                 "address",

+ 14 - 13
contract_manager/scripts/common.ts

@@ -1,9 +1,10 @@
-import { DefaultStore } from "../src/node/utils/store";
-import { existsSync, readFileSync, writeFileSync } from "fs";
-import { join } from "path";
+import { existsSync, readFileSync, writeFileSync } from "node:fs";
+import { join } from "node:path";
+
 import Web3 from "web3";
 import Web3 from "web3";
 import { Contract } from "web3-eth-contract";
 import { Contract } from "web3-eth-contract";
 import { InferredOptionType } from "yargs";
 import { InferredOptionType } from "yargs";
+
 import { PrivateKey, getDefaultDeploymentConfig } from "../src/core/base";
 import { PrivateKey, getDefaultDeploymentConfig } from "../src/core/base";
 import { EvmChain } from "../src/core/chains";
 import { EvmChain } from "../src/core/chains";
 import {
 import {
@@ -11,8 +12,9 @@ import {
   EvmExecutorContract,
   EvmExecutorContract,
   EvmWormholeContract,
   EvmWormholeContract,
 } from "../src/core/contracts";
 } from "../src/core/contracts";
+import { DefaultStore } from "../src/node/utils/store";
 
 
-export interface BaseDeployConfig {
+export type BaseDeployConfig = {
   gasMultiplier: number;
   gasMultiplier: number;
   gasPriceMultiplier: number;
   gasPriceMultiplier: number;
   jsonOutputDir: string;
   jsonOutputDir: string;
@@ -46,7 +48,7 @@ export async function deployIfNotCached(
     );
     );
 
 
     // Handle bytecode which can be either a string or an object with an 'object' property
     // Handle bytecode which can be either a string or an object with an 'object' property
-    let bytecode = artifact["bytecode"];
+    let bytecode = artifact.bytecode;
     if (
     if (
       typeof bytecode === "object" &&
       typeof bytecode === "object" &&
       bytecode !== null &&
       bytecode !== null &&
@@ -63,7 +65,7 @@ export async function deployIfNotCached(
     console.log(`Deploying ${artifactName} on ${chain.getId()}...`);
     console.log(`Deploying ${artifactName} on ${chain.getId()}...`);
     const addr = await chain.deploy(
     const addr = await chain.deploy(
       config.privateKey,
       config.privateKey,
-      artifact["abi"],
+      artifact.abi,
       bytecode,
       bytecode,
       deployArgs,
       deployArgs,
       config.gasMultiplier,
       config.gasMultiplier,
@@ -87,7 +89,7 @@ export function getWeb3Contract(
     ),
     ),
   );
   );
   const web3 = new Web3();
   const web3 = new Web3();
-  return new web3.eth.Contract(artifact["abi"], address);
+  return new web3.eth.Contract(artifact.abi, address);
 }
 }
 
 
 export const COMMON_DEPLOY_OPTIONS = {
 export const COMMON_DEPLOY_OPTIONS = {
@@ -272,11 +274,10 @@ export function findExecutorContract(
   }
   }
 }
 }
 
 
-export interface DeployWormholeReceiverContractsConfig
-  extends BaseDeployConfig {
+export type DeployWormholeReceiverContractsConfig = {
   saveContract: boolean;
   saveContract: boolean;
   type: "stable" | "beta";
   type: "stable" | "beta";
-}
+} & BaseDeployConfig
 /**
 /**
  * Deploys the wormhole receiver contract for a given EVM chain.
  * Deploys the wormhole receiver contract for a given EVM chain.
  * @param {EvmChain} chain The EVM chain to find the wormhole receiver contract for.
  * @param {EvmChain} chain The EVM chain to find the wormhole receiver contract for.
@@ -369,7 +370,7 @@ export async function getOrDeployWormholeContract(
   );
   );
 }
 }
 
 
-export interface DefaultAddresses {
+export type DefaultAddresses = {
   mainnet: string;
   mainnet: string;
   testnet: string;
   testnet: string;
 }
 }
@@ -377,7 +378,7 @@ export interface DefaultAddresses {
 export async function topupAccountsIfNecessary(
 export async function topupAccountsIfNecessary(
   chain: EvmChain,
   chain: EvmChain,
   deploymentConfig: BaseDeployConfig,
   deploymentConfig: BaseDeployConfig,
-  accounts: Array<[string, DefaultAddresses]>,
+  accounts: [string, DefaultAddresses][],
   minBalance = 0.01,
   minBalance = 0.01,
 ) {
 ) {
   for (const [accountName, defaultAddresses] of accounts) {
   for (const [accountName, defaultAddresses] of accounts) {
@@ -411,7 +412,7 @@ export async function topupAccountsIfNecessary(
       });
       });
 
 
       console.log(
       console.log(
-        `Topped up the ${accountName} address. Tx: `,
+        `Topped up the ${accountName} address. Tx:`,
         tx.transactionHash,
         tx.transactionHash,
       );
       );
     }
     }

+ 2 - 1
contract_manager/scripts/deploy_cosmwasm.ts

@@ -1,10 +1,11 @@
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
+
+import { COMMON_DEPLOY_OPTIONS } from "./common";
 import { CosmWasmChain } from "../src/core/chains";
 import { CosmWasmChain } from "../src/core/chains";
 import { CosmWasmPriceFeedContract } from "../src/core/contracts/cosmwasm";
 import { CosmWasmPriceFeedContract } from "../src/core/contracts/cosmwasm";
 import { DefaultStore } from "../src/node/utils/store";
 import { DefaultStore } from "../src/node/utils/store";
 
 
-import { COMMON_DEPLOY_OPTIONS } from "./common";
 
 
 const parser = yargs(hideBin(process.argv))
 const parser = yargs(hideBin(process.argv))
   .scriptName("deploy_cosmwasm.ts")
   .scriptName("deploy_cosmwasm.ts")

+ 7 - 6
contract_manager/scripts/deploy_evm_contract.ts

@@ -1,11 +1,12 @@
+import { readFileSync } from "node:fs";
+
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
-import { EvmChain } from "../src/core/chains";
-import { DefaultStore } from "../src/node/utils/store";
-import { readFileSync } from "fs";
-import { toPrivateKey } from "../src/core/base";
 
 
 import { COMMON_DEPLOY_OPTIONS } from "./common";
 import { COMMON_DEPLOY_OPTIONS } from "./common";
+import { toPrivateKey } from "../src/core/base";
+import { EvmChain } from "../src/core/chains";
+import { DefaultStore } from "../src/node/utils/store";
 
 
 const parser = yargs(hideBin(process.argv))
 const parser = yargs(hideBin(process.argv))
   .scriptName("deploy_evm_contract.ts")
   .scriptName("deploy_evm_contract.ts")
@@ -37,8 +38,8 @@ async function main() {
   const artifact = JSON.parse(readFileSync(argv["std-output"], "utf8"));
   const artifact = JSON.parse(readFileSync(argv["std-output"], "utf8"));
   const address = await chain.deploy(
   const address = await chain.deploy(
     toPrivateKey(argv["private-key"]),
     toPrivateKey(argv["private-key"]),
-    artifact["abi"],
-    artifact["bytecode"].object, // As per the artifacts generated by forge, bytecode is an object with an 'object' property
+    artifact.abi,
+    artifact.bytecode.object, // As per the artifacts generated by forge, bytecode is an object with an 'object' property
     argv["deploy-args"] || [],
     argv["deploy-args"] || [],
   );
   );
 
 

+ 16 - 15
contract_manager/scripts/deploy_evm_entropy_contracts.ts

@@ -1,17 +1,6 @@
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
-import { EvmChain } from "../src/core/chains";
-import { DefaultStore } from "../src/node/utils/store";
-import {
-  ENTROPY_DEFAULT_KEEPER,
-  ENTROPY_DEFAULT_PROVIDER,
-  EvmEntropyContract,
-} from "../src/core/contracts/evm";
-import {
-  DeploymentType,
-  toDeploymentType,
-  toPrivateKey,
-} from "../src/core/base";
+
 import {
 import {
   COMMON_DEPLOY_OPTIONS,
   COMMON_DEPLOY_OPTIONS,
   deployIfNotCached,
   deployIfNotCached,
@@ -22,11 +11,23 @@ import {
   DefaultAddresses,
   DefaultAddresses,
 } from "./common";
 } from "./common";
 import { getOrDeployExecutorContract } from "./deploy_evm_executor_contracts";
 import { getOrDeployExecutorContract } from "./deploy_evm_executor_contracts";
+import {
+  DeploymentType,
+  toDeploymentType,
+  toPrivateKey,
+} from "../src/core/base";
+import { EvmChain } from "../src/core/chains";
+import {
+  ENTROPY_DEFAULT_KEEPER,
+  ENTROPY_DEFAULT_PROVIDER,
+  EvmEntropyContract,
+} from "../src/core/contracts/evm";
+import { DefaultStore } from "../src/node/utils/store";
 
 
-interface DeploymentConfig extends BaseDeployConfig {
+type DeploymentConfig = {
   type: DeploymentType;
   type: DeploymentType;
   saveContract: boolean;
   saveContract: boolean;
-}
+} & BaseDeployConfig
 
 
 const CACHE_FILE = ".cache-deploy-evm-entropy-contracts";
 const CACHE_FILE = ".cache-deploy-evm-entropy-contracts";
 
 
@@ -92,7 +93,7 @@ async function topupEntropyAccountsIfNecessary(
   chain: EvmChain,
   chain: EvmChain,
   deploymentConfig: DeploymentConfig,
   deploymentConfig: DeploymentConfig,
 ) {
 ) {
-  const accounts: Array<[string, DefaultAddresses]> = [
+  const accounts: [string, DefaultAddresses][] = [
     ["keeper", ENTROPY_DEFAULT_KEEPER],
     ["keeper", ENTROPY_DEFAULT_KEEPER],
     ["provider", ENTROPY_DEFAULT_PROVIDER],
     ["provider", ENTROPY_DEFAULT_PROVIDER],
   ];
   ];

+ 5 - 4
contract_manager/scripts/deploy_evm_executor_contracts.ts

@@ -1,6 +1,6 @@
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
-import { EvmChain } from "../src/core/chains";
+
 import {
 import {
   BaseDeployConfig,
   BaseDeployConfig,
   COMMON_DEPLOY_OPTIONS,
   COMMON_DEPLOY_OPTIONS,
@@ -15,8 +15,9 @@ import {
   toDeploymentType,
   toDeploymentType,
   toPrivateKey,
   toPrivateKey,
 } from "../src/core/base";
 } from "../src/core/base";
-import { DefaultStore } from "../src/node/utils/store";
+import { EvmChain } from "../src/core/chains";
 import { EvmExecutorContract } from "../src/core/contracts/evm";
 import { EvmExecutorContract } from "../src/core/contracts/evm";
+import { DefaultStore } from "../src/node/utils/store";
 
 
 const CACHE_FILE = ".cache-deploy-evm-executor";
 const CACHE_FILE = ".cache-deploy-evm-executor";
 
 
@@ -34,10 +35,10 @@ const parser = yargs(hideBin(process.argv))
     },
     },
   });
   });
 
 
-interface DeploymentConfig extends BaseDeployConfig {
+type DeploymentConfig = {
   type: DeploymentType;
   type: DeploymentType;
   saveContract: boolean;
   saveContract: boolean;
-}
+} & BaseDeployConfig
 
 
 export async function getOrDeployExecutorContract(
 export async function getOrDeployExecutorContract(
   chain: EvmChain,
   chain: EvmChain,

+ 7 - 5
contract_manager/scripts/deploy_evm_lazer_contracts.ts

@@ -38,14 +38,16 @@
  * - All operations use the chain's RPC URL from the DefaultStore
  * - All operations use the chain's RPC URL from the DefaultStore
  */
  */
 
 
+import { execSync } from "node:child_process";
+import { join } from "node:path";
+
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
-import { execSync } from "child_process";
-import { join } from "path";
-import { DefaultStore } from "../src/node/utils/store";
+
+import { toPrivateKey, PrivateKey } from "../src/core/base";
 import { EvmChain } from "../src/core/chains";
 import { EvmChain } from "../src/core/chains";
 import { EvmLazerContract } from "../src/core/contracts/evm";
 import { EvmLazerContract } from "../src/core/contracts/evm";
-import { toPrivateKey, PrivateKey } from "../src/core/base";
+import { DefaultStore } from "../src/node/utils/store";
 
 
 const parser = yargs(hideBin(process.argv))
 const parser = yargs(hideBin(process.argv))
   .usage(
   .usage(
@@ -153,7 +155,7 @@ async function deployPythLazerContract(
     console.log(output);
     console.log(output);
 
 
     // Extract proxy address from output
     // Extract proxy address from output
-    const proxyMatch = output.match(/Deployed proxy to: (0x[a-fA-F0-9]{40})/);
+    const proxyMatch = /Deployed proxy to: (0x[a-fA-F0-9]{40})/.exec(output);
     if (!proxyMatch) {
     if (!proxyMatch) {
       throw new Error("Could not extract proxy address from deployment output");
       throw new Error("Could not extract proxy address from deployment output");
     }
     }

+ 6 - 5
contract_manager/scripts/deploy_evm_pricefeed_contracts.ts

@@ -1,5 +1,7 @@
+import { HermesClient } from "@pythnetwork/hermes-client";
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
+
 import {
 import {
   COMMON_DEPLOY_OPTIONS,
   COMMON_DEPLOY_OPTIONS,
   deployIfNotCached,
   deployIfNotCached,
@@ -7,7 +9,6 @@ import {
   getOrDeployWormholeContract,
   getOrDeployWormholeContract,
   BaseDeployConfig,
   BaseDeployConfig,
 } from "./common";
 } from "./common";
-import { HermesClient } from "@pythnetwork/hermes-client";
 import {
 import {
   DeploymentType,
   DeploymentType,
   getDefaultDeploymentConfig,
   getDefaultDeploymentConfig,
@@ -18,12 +19,12 @@ import { EvmChain } from "../src/core/chains";
 import { EvmPriceFeedContract } from "../src/core/contracts";
 import { EvmPriceFeedContract } from "../src/core/contracts";
 import { DefaultStore } from "../src/node/utils/store";
 import { DefaultStore } from "../src/node/utils/store";
 
 
-interface DeploymentConfig extends BaseDeployConfig {
+type DeploymentConfig = {
   type: DeploymentType;
   type: DeploymentType;
   validTimePeriodSeconds: number;
   validTimePeriodSeconds: number;
   singleUpdateFeeInWei: number;
   singleUpdateFeeInWei: number;
   saveContract: boolean;
   saveContract: boolean;
-}
+} & BaseDeployConfig
 
 
 const CACHE_FILE = ".cache-deploy-evm";
 const CACHE_FILE = ".cache-deploy-evm";
 
 
@@ -115,7 +116,7 @@ async function main() {
   const nativeTokenDecimals = argv["native-token-decimals"];
   const nativeTokenDecimals = argv["native-token-decimals"];
   if (
   if (
     singleUpdateFeeInUsd &&
     singleUpdateFeeInUsd &&
-    (nativeTokenPriceFeedId == null || nativeTokenDecimals == null)
+    (nativeTokenPriceFeedId == undefined || nativeTokenDecimals == undefined)
   ) {
   ) {
     throw new Error(
     throw new Error(
       "native-token-price-feed-id and native-token-decimals are required when single-update-fee-in-usd is provided",
       "native-token-price-feed-id and native-token-decimals are required when single-update-fee-in-usd is provided",
@@ -132,7 +133,7 @@ async function main() {
     );
     );
 
 
     const price = priceObject.parsed?.[0].price;
     const price = priceObject.parsed?.[0].price;
-    if (price == null) {
+    if (price == undefined) {
       throw new Error("Failed to get price of the native token");
       throw new Error("Failed to get price of the native token");
     }
     }
     const priceInUsd = Number(price.price);
     const priceInUsd = Number(price.price);

+ 8 - 6
contract_manager/scripts/deploy_evm_pulse_contracts.ts

@@ -1,5 +1,9 @@
+import fs from "node:fs";
+import path from "node:path";
+
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
+
 import {
 import {
   COMMON_DEPLOY_OPTIONS,
   COMMON_DEPLOY_OPTIONS,
   deployIfNotCached,
   deployIfNotCached,
@@ -9,8 +13,6 @@ import {
   topupAccountsIfNecessary,
   topupAccountsIfNecessary,
   DefaultAddresses,
   DefaultAddresses,
 } from "./common";
 } from "./common";
-import fs from "fs";
-import path from "path";
 import {
 import {
   DeploymentType,
   DeploymentType,
   toDeploymentType,
   toDeploymentType,
@@ -24,10 +26,10 @@ import {
 } from "../src/core/contracts";
 } from "../src/core/contracts";
 import { DefaultStore } from "../src/node/utils/store";
 import { DefaultStore } from "../src/node/utils/store";
 
 
-interface DeploymentConfig extends BaseDeployConfig {
+type DeploymentConfig = {
   type: DeploymentType;
   type: DeploymentType;
   saveContract: boolean;
   saveContract: boolean;
-}
+} & BaseDeployConfig
 
 
 const CACHE_FILE = ".cache-deploy-evm-pulse-contracts";
 const CACHE_FILE = ".cache-deploy-evm-pulse-contracts";
 
 
@@ -112,7 +114,7 @@ async function topupPulseAccountsIfNecessary(
   chain: EvmChain,
   chain: EvmChain,
   deploymentConfig: DeploymentConfig,
   deploymentConfig: DeploymentConfig,
 ) {
 ) {
-  const accounts: Array<[string, DefaultAddresses]> = [
+  const accounts: [string, DefaultAddresses][] = [
     ["keeper", PULSE_DEFAULT_KEEPER],
     ["keeper", PULSE_DEFAULT_KEEPER],
     ["provider", PULSE_DEFAULT_PROVIDER],
     ["provider", PULSE_DEFAULT_PROVIDER],
   ];
   ];
@@ -128,7 +130,7 @@ async function main() {
   if (!chain) {
   if (!chain) {
     throw new Error(`Chain ${chainName} not found`);
     throw new Error(`Chain ${chainName} not found`);
   } else if (!(chain instanceof EvmChain)) {
   } else if (!(chain instanceof EvmChain)) {
-    throw new Error(`Chain ${chainName} is not an EVM chain`);
+    throw new TypeError(`Chain ${chainName} is not an EVM chain`);
   }
   }
 
 
   const deploymentConfig: DeploymentConfig = {
   const deploymentConfig: DeploymentConfig = {

+ 3 - 2
contract_manager/scripts/entropy-accept-admin-and-ownership.ts

@@ -1,5 +1,6 @@
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
+
 import { EvmChain } from "../src/core/chains";
 import { EvmChain } from "../src/core/chains";
 import { loadHotWallet } from "../src/node/utils/governance";
 import { loadHotWallet } from "../src/node/utils/governance";
 import { DefaultStore } from "../src/node/utils/store";
 import { DefaultStore } from "../src/node/utils/store";
@@ -67,7 +68,7 @@ async function main() {
   const payloads: Buffer[] = [];
   const payloads: Buffer[] = [];
   for (const contract of Object.values(DefaultStore.entropy_contracts)) {
   for (const contract of Object.values(DefaultStore.entropy_contracts)) {
     if (selectedChains.includes(contract.chain)) {
     if (selectedChains.includes(contract.chain)) {
-      console.log("Creating payload for chain: ", contract.chain.getId());
+      console.log("Creating payload for chain:", contract.chain.getId());
       const pendingOwner = await contract.getPendingOwner();
       const pendingOwner = await contract.getPendingOwner();
       const adminPayload = contract.generateAcceptAdminPayload(pendingOwner);
       const adminPayload = contract.generateAcceptAdminPayload(pendingOwner);
       const ownerPayload =
       const ownerPayload =
@@ -79,7 +80,7 @@ async function main() {
 
 
   console.log("Using vault at for proposal", vault.getId());
   console.log("Using vault at for proposal", vault.getId());
   const wallet = await loadHotWallet(argv["ops-key-path"]);
   const wallet = await loadHotWallet(argv["ops-key-path"]);
-  console.log("Using wallet ", wallet.publicKey.toBase58());
+  console.log("Using wallet", wallet.publicKey.toBase58());
   await vault.connect(wallet);
   await vault.connect(wallet);
   const proposal = await vault.proposeWormholeMessage(payloads);
   const proposal = await vault.proposeWormholeMessage(payloads);
   console.log("Proposal address", proposal.address.toBase58());
   console.log("Proposal address", proposal.address.toBase58());

+ 9 - 8
contract_manager/scripts/entropy_debug_reveal.ts

@@ -1,5 +1,6 @@
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
+
 import { COMMON_DEPLOY_OPTIONS, findEntropyContract } from "./common";
 import { COMMON_DEPLOY_OPTIONS, findEntropyContract } from "./common";
 import { toPrivateKey } from "../src/core/base";
 import { toPrivateKey } from "../src/core/base";
 import { EvmChain } from "../src/core/chains";
 import { EvmChain } from "../src/core/chains";
@@ -58,24 +59,24 @@ async function main() {
     sequenceNumber < endingSequenceNumber;
     sequenceNumber < endingSequenceNumber;
     sequenceNumber++
     sequenceNumber++
   ) {
   ) {
-    console.log("Revealing request for sequence number: ", sequenceNumber);
+    console.log("Revealing request for sequence number:", sequenceNumber);
     const request = await contract.getRequest(provider, sequenceNumber);
     const request = await contract.getRequest(provider, sequenceNumber);
     if (request.sequenceNumber === "0") {
     if (request.sequenceNumber === "0") {
       console.log("Request not found");
       console.log("Request not found");
       continue;
       continue;
     }
     }
-    console.log("Request block number: ", request.blockNumber);
+    console.log("Request block number:", request.blockNumber);
     const userRandomNumber = await contract.getUserRandomNumber(
     const userRandomNumber = await contract.getUserRandomNumber(
       provider,
       provider,
       sequenceNumber,
       sequenceNumber,
-      parseInt(request.blockNumber),
+      Number.parseInt(request.blockNumber),
     );
     );
-    console.log("User random number: ", userRandomNumber);
+    console.log("User random number:", userRandomNumber);
     const revealUrl = providerInfo.uri + `/revelations/${sequenceNumber}`;
     const revealUrl = providerInfo.uri + `/revelations/${sequenceNumber}`;
     const fortunaResponse = await fetch(revealUrl);
     const fortunaResponse = await fetch(revealUrl);
     if (fortunaResponse.status !== 200) {
     if (fortunaResponse.status !== 200) {
-      console.error("Fortuna response status: ", fortunaResponse.status);
-      console.error("Fortuna response body: ", await fortunaResponse.text());
+      console.error("Fortuna response status:", fortunaResponse.status);
+      console.error("Fortuna response body:", await fortunaResponse.text());
       console.error(
       console.error(
         "Refusing to continue the script, please check the Fortuna service first.",
         "Refusing to continue the script, please check the Fortuna service first.",
       );
       );
@@ -91,8 +92,8 @@ async function main() {
         sequenceNumber,
         sequenceNumber,
         privateKey,
         privateKey,
       );
       );
-    } catch (e) {
-      console.error("Error revealing request: ", e);
+    } catch (error) {
+      console.error("Error revealing request:", error);
       continue;
       continue;
     }
     }
   }
   }

+ 11 - 19
contract_manager/scripts/execute_vaas.ts

@@ -1,12 +1,12 @@
-import yargs from "yargs";
-import { hideBin } from "yargs/helpers";
 import { parseVaa } from "@certusone/wormhole-sdk";
 import { parseVaa } from "@certusone/wormhole-sdk";
 import { decodeGovernancePayload } from "@pythnetwork/xc-admin-common";
 import { decodeGovernancePayload } from "@pythnetwork/xc-admin-common";
+import yargs from "yargs";
+import { hideBin } from "yargs/helpers";
+
 import { COMMON_DEPLOY_OPTIONS } from "./common";
 import { COMMON_DEPLOY_OPTIONS } from "./common";
-import { Vault } from "../src/node/utils/governance";
 import { toPrivateKey } from "../src/core/base";
 import { toPrivateKey } from "../src/core/base";
-import { SubmittedWormholeMessage } from "../src/node/utils/governance";
 import { executeVaa } from "../src/node/utils/executor";
 import { executeVaa } from "../src/node/utils/executor";
+import { Vault , SubmittedWormholeMessage } from "../src/node/utils/governance";
 import { DefaultStore } from "../src/node/utils/store";
 import { DefaultStore } from "../src/node/utils/store";
 
 
 const parser = yargs(hideBin(process.argv))
 const parser = yargs(hideBin(process.argv))
@@ -49,17 +49,9 @@ const parser = yargs(hideBin(process.argv))
 async function main() {
 async function main() {
   const argv = await parser.argv;
   const argv = await parser.argv;
   let vault: Vault;
   let vault: Vault;
-  if (argv.vault === "mainnet") {
-    vault =
-      DefaultStore.vaults[
+  vault = argv.vault === "mainnet" ? DefaultStore.vaults[
         "mainnet-beta_FVQyHcooAtThJ83XFrNnv74BcinbRH3bRmfFamAHBfuj"
         "mainnet-beta_FVQyHcooAtThJ83XFrNnv74BcinbRH3bRmfFamAHBfuj"
-      ];
-  } else {
-    vault =
-      DefaultStore.vaults[
-        "devnet_6baWtW1zTUVMSJHJQVxDUXWzqrQeYBr6mu31j3bTKwY3"
-      ];
-  }
+      ] : DefaultStore.vaults.devnet_6baWtW1zTUVMSJHJQVxDUXWzqrQeYBr6mu31j3bTKwY3;
   console.log("Executing VAAs for vault", vault.getId());
   console.log("Executing VAAs for vault", vault.getId());
   console.log(
   console.log(
     "Executing VAAs for emitter",
     "Executing VAAs for emitter",
@@ -72,13 +64,13 @@ async function main() {
   if (argv.sequence !== undefined) {
   if (argv.sequence !== undefined) {
     startSequenceNumber = argv.sequence;
     startSequenceNumber = argv.sequence;
     endSequenceNumber = argv.sequence;
     endSequenceNumber = argv.sequence;
-  } else if (argv.offset !== undefined) {
+  } else if (argv.offset === undefined) {
+    // this is unreachable but it makes the typescript linter happy.
+    throw new Error("Either --offset or --sequence must be provided");
+  } else {
     const lastSequenceNumber = await vault.getLastSequenceNumber();
     const lastSequenceNumber = await vault.getLastSequenceNumber();
     startSequenceNumber = lastSequenceNumber - argv.offset;
     startSequenceNumber = lastSequenceNumber - argv.offset;
     endSequenceNumber = lastSequenceNumber;
     endSequenceNumber = lastSequenceNumber;
-  } else {
-    // this is unreachable but it makes the typescript linter happy.
-    throw new Error("Either --offset or --sequence must be provided");
   }
   }
 
 
   console.log(
   console.log(
@@ -98,7 +90,7 @@ async function main() {
     const vaa = await submittedWormholeMessage.fetchVaa();
     const vaa = await submittedWormholeMessage.fetchVaa();
     const decodedAction = decodeGovernancePayload(parseVaa(vaa).payload);
     const decodedAction = decodeGovernancePayload(parseVaa(vaa).payload);
     if (!decodedAction) {
     if (!decodedAction) {
-      console.log("Skipping unknown action for vaa ", seqNumber);
+      console.log("Skipping unknown action for vaa", seqNumber);
       continue;
       continue;
     }
     }
     console.log("Executing vaa", seqNumber);
     console.log("Executing vaa", seqNumber);

+ 3 - 2
contract_manager/scripts/fetch_account_balance.ts

@@ -1,5 +1,6 @@
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
+
 import { PrivateKey, toPrivateKey } from "../src/core/base";
 import { PrivateKey, toPrivateKey } from "../src/core/base";
 import { DefaultStore } from "../src/node/utils/store";
 import { DefaultStore } from "../src/node/utils/store";
 
 
@@ -35,8 +36,8 @@ async function getBalance(
     const balance =
     const balance =
       await DefaultStore.chains[chain].getAccountBalance(privateKey);
       await DefaultStore.chains[chain].getAccountBalance(privateKey);
     return { chain, address, balance };
     return { chain, address, balance };
-  } catch (e) {
-    console.error(`Error fetching balance for ${chain}`, e);
+  } catch (error) {
+    console.error(`Error fetching balance for ${chain}`, error);
   }
   }
   return { chain, address, balance: undefined };
   return { chain, address, balance: undefined };
 }
 }

+ 4 - 3
contract_manager/scripts/fetch_accrued_entropy_dao_fees.ts

@@ -1,9 +1,10 @@
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
-import { DefaultStore } from "../src/node/utils/store";
+
+import { findEntropyContract } from "./common";
 import { EvmChain } from "../src/core/chains";
 import { EvmChain } from "../src/core/chains";
 import { EvmEntropyContract } from "../src/core/contracts";
 import { EvmEntropyContract } from "../src/core/contracts";
-import { findEntropyContract } from "./common";
+import { DefaultStore } from "../src/node/utils/store";
 
 
 const parser = yargs(hideBin(process.argv))
 const parser = yargs(hideBin(process.argv))
   .usage(
   .usage(
@@ -35,7 +36,7 @@ const parser = yargs(hideBin(process.argv))
     return true;
     return true;
   });
   });
 
 
-interface FeeResult {
+type FeeResult = {
   chainId: string;
   chainId: string;
   contractAddress: string;
   contractAddress: string;
   accruedFees: string;
   accruedFees: string;

+ 3 - 2
contract_manager/scripts/fetch_fees.ts

@@ -1,5 +1,6 @@
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
+
 import {
 import {
   AptosPriceFeedContract,
   AptosPriceFeedContract,
   CosmWasmPriceFeedContract,
   CosmWasmPriceFeedContract,
@@ -54,8 +55,8 @@ async function main() {
             `${contract.getId()} ${fee.amount} ${fee.denom} ($ value unknown)`,
             `${contract.getId()} ${fee.amount} ${fee.denom} ($ value unknown)`,
           );
           );
         }
         }
-      } catch (e) {
-        console.error(`Error fetching fees for ${contract.getId()}`, e);
+      } catch (error) {
+        console.error(`Error fetching fees for ${contract.getId()}`, error);
       }
       }
     }
     }
   }
   }

+ 3 - 2
contract_manager/scripts/generate_evm_lazer_update_trusted_signer_proposal.ts

@@ -1,7 +1,8 @@
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
-import { DefaultStore } from "../src/node/utils/store";
+
 import { loadHotWallet } from "../src/node/utils/governance";
 import { loadHotWallet } from "../src/node/utils/governance";
+import { DefaultStore } from "../src/node/utils/store";
 
 
 const parser = yargs(hideBin(process.argv))
 const parser = yargs(hideBin(process.argv))
   .usage("Usage: $0 --config <path/to/config.json>")
   .usage("Usage: $0 --config <path/to/config.json>")
@@ -61,7 +62,7 @@ async function main() {
 
 
   console.log("Using vault at for proposal", vault.getId());
   console.log("Using vault at for proposal", vault.getId());
   const wallet = await loadHotWallet(argv["ops-key-path"]);
   const wallet = await loadHotWallet(argv["ops-key-path"]);
-  console.log("Using wallet ", wallet.publicKey.toBase58());
+  console.log("Using wallet", wallet.publicKey.toBase58());
   await vault.connect(wallet);
   await vault.connect(wallet);
   const proposal = await vault.proposeWormholeMessage(updatePayloads);
   const proposal = await vault.proposeWormholeMessage(updatePayloads);
   console.log("Proposal address", proposal.address.toBase58());
   console.log("Proposal address", proposal.address.toBase58());

+ 2 - 1
contract_manager/scripts/generate_governance_set_fee_payload.ts

@@ -1,7 +1,8 @@
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
-import { DefaultStore } from "../src/node/utils/store";
+
 import { loadHotWallet } from "../src/node/utils/governance";
 import { loadHotWallet } from "../src/node/utils/governance";
+import { DefaultStore } from "../src/node/utils/store";
 
 
 const parser = yargs(hideBin(process.argv))
 const parser = yargs(hideBin(process.argv))
   .usage("Usage: $0 --config <path/to/config.json>")
   .usage("Usage: $0 --config <path/to/config.json>")

+ 4 - 3
contract_manager/scripts/generate_upgrade_near_contract_proposal.ts

@@ -1,8 +1,9 @@
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
-import { DefaultStore } from "../src/node/utils/store";
-import { loadHotWallet } from "../src/node/utils/governance";
+
 import { NearChain } from "../src/core/chains";
 import { NearChain } from "../src/core/chains";
+import { loadHotWallet } from "../src/node/utils/governance";
+import { DefaultStore } from "../src/node/utils/store";
 
 
 const parser = yargs(hideBin(process.argv))
 const parser = yargs(hideBin(process.argv))
   .usage(
   .usage(
@@ -55,7 +56,7 @@ async function main() {
 
 
   // Create and submit governance proposal
   // Create and submit governance proposal
   console.log("Using vault for proposal:", vault.getId());
   console.log("Using vault for proposal:", vault.getId());
-  const keypair = await loadHotWallet(argv["ops-key-path"] as string);
+  const keypair = await loadHotWallet(argv["ops-key-path"]);
   console.log("Using wallet:", keypair.publicKey.toBase58());
   console.log("Using wallet:", keypair.publicKey.toBase58());
   vault.connect(keypair);
   vault.connect(keypair);
   const proposal = await vault.proposeWormholeMessage([payload]);
   const proposal = await vault.proposeWormholeMessage([payload]);

+ 8 - 6
contract_manager/scripts/generate_upgrade_ton_contract_proposal.ts

@@ -1,11 +1,13 @@
+import fs from "node:fs";
+import path from "node:path";
+
+import { CHAINS, toChainName } from "@pythnetwork/xc-admin-common";
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
-import { DefaultStore } from "../src/node/utils/store";
-import { loadHotWallet } from "../src/node/utils/governance";
+
 import { TonChain } from "../src/core/chains";
 import { TonChain } from "../src/core/chains";
-import { CHAINS, toChainName } from "@pythnetwork/xc-admin-common";
-import fs from "fs";
-import path from "path";
+import { loadHotWallet } from "../src/node/utils/governance";
+import { DefaultStore } from "../src/node/utils/store";
 
 
 const parser = yargs(hideBin(process.argv))
 const parser = yargs(hideBin(process.argv))
   .usage(
   .usage(
@@ -74,7 +76,7 @@ async function main() {
 
 
   // Create and submit governance proposal
   // Create and submit governance proposal
   console.log("Using vault for proposal:", vault.getId());
   console.log("Using vault for proposal:", vault.getId());
-  const keypair = await loadHotWallet(argv["ops-key-path"] as string);
+  const keypair = await loadHotWallet(argv["ops-key-path"]);
   console.log("Using wallet:", keypair.publicKey.toBase58());
   console.log("Using wallet:", keypair.publicKey.toBase58());
   vault.connect(keypair);
   vault.connect(keypair);
   const proposal = await vault.proposeWormholeMessage([payload]);
   const proposal = await vault.proposeWormholeMessage([payload]);

+ 3 - 2
contract_manager/scripts/get_entropy_registration.ts

@@ -1,5 +1,6 @@
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
+
 import { DefaultStore } from "../src/node/utils/store";
 import { DefaultStore } from "../src/node/utils/store";
 
 
 function deserializeCommitmentMetadata(data: Buffer) {
 function deserializeCommitmentMetadata(data: Buffer) {
@@ -32,8 +33,8 @@ async function main() {
     try {
     try {
       provider = await contract.getDefaultProvider();
       provider = await contract.getDefaultProvider();
       providerInfo = await contract.getProviderInfo(provider);
       providerInfo = await contract.getProviderInfo(provider);
-    } catch (e) {
-      console.error(`Error fetching info for ${contract.getId()}`, e);
+    } catch (error) {
+      console.error(`Error fetching info for ${contract.getId()}`, error);
       continue;
       continue;
     }
     }
 
 

+ 7 - 6
contract_manager/scripts/latency_entropy.ts

@@ -1,9 +1,10 @@
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
-import { DefaultStore } from "../src/node/utils/store";
-import { EvmChain } from "../src/core/chains";
-import { toPrivateKey } from "../src/core/base";
+
 import { COMMON_DEPLOY_OPTIONS, findEntropyContract } from "./common";
 import { COMMON_DEPLOY_OPTIONS, findEntropyContract } from "./common";
+import { toPrivateKey } from "../src/core/base";
+import { EvmChain } from "../src/core/chains";
+import { DefaultStore } from "../src/node/utils/store";
 
 
 const parser = yargs(hideBin(process.argv))
 const parser = yargs(hideBin(process.argv))
   .usage(
   .usage(
@@ -34,12 +35,12 @@ async function main() {
     provider,
     provider,
     privateKey,
     privateKey,
   );
   );
-  console.log("Request tx hash: ", requestResponse.transactionHash);
+  console.log("Request tx hash:", requestResponse.transactionHash);
   const startTime = Date.now();
   const startTime = Date.now();
   const sequenceNumber = providerInfo.sequenceNumber;
   const sequenceNumber = providerInfo.sequenceNumber;
   const revealUrl = providerInfo.uri + `/revelations/${sequenceNumber}`;
   const revealUrl = providerInfo.uri + `/revelations/${sequenceNumber}`;
   console.log("Checking this url for revelation:", revealUrl);
   console.log("Checking this url for revelation:", revealUrl);
-  // eslint-disable-next-line no-constant-condition
+   
   while (true) {
   while (true) {
     const fortunaResponse = await fetch(revealUrl);
     const fortunaResponse = await fetch(revealUrl);
     if (fortunaResponse.status === 200) {
     if (fortunaResponse.status === 200) {
@@ -54,7 +55,7 @@ async function main() {
         sequenceNumber,
         sequenceNumber,
         privateKey,
         privateKey,
       );
       );
-      console.log("Reveal tx hash: ", revealResponse.transactionHash);
+      console.log("Reveal tx hash:", revealResponse.transactionHash);
       break;
       break;
     }
     }
     await new Promise((resolve) => setTimeout(resolve, 300));
     await new Promise((resolve) => setTimeout(resolve, 300));

+ 4 - 3
contract_manager/scripts/latency_entropy_with_callback.ts

@@ -1,10 +1,11 @@
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
+
+import { COMMON_DEPLOY_OPTIONS, findEntropyContract } from "./common";
 import { PrivateKey, toPrivateKey } from "../src/core/base";
 import { PrivateKey, toPrivateKey } from "../src/core/base";
 import { EvmChain } from "../src/core/chains";
 import { EvmChain } from "../src/core/chains";
 import { EvmEntropyContract } from "../src/core/contracts";
 import { EvmEntropyContract } from "../src/core/contracts";
 import { DefaultStore } from "../src/node/utils/store";
 import { DefaultStore } from "../src/node/utils/store";
-import { COMMON_DEPLOY_OPTIONS, findEntropyContract } from "./common";
 
 
 const parser = yargs(hideBin(process.argv))
 const parser = yargs(hideBin(process.argv))
   .usage(
   .usage(
@@ -57,7 +58,7 @@ async function testLatency(
   const web3 = contract.chain.getWeb3();
   const web3 = contract.chain.getWeb3();
   const entropyContract = contract.getContract();
   const entropyContract = contract.getContract();
 
 
-  // eslint-disable-next-line no-constant-condition
+   
   while (true) {
   while (true) {
     await new Promise((resolve) => setTimeout(resolve, 1000));
     await new Promise((resolve) => setTimeout(resolve, 1000));
     const currentBlock = await web3.eth.getBlockNumber();
     const currentBlock = await web3.eth.getBlockNumber();
@@ -86,7 +87,7 @@ async function testLatency(
       );
       );
       break;
       break;
     }
     }
-    if (Date.now() - startTime > 60000) {
+    if (Date.now() - startTime > 60_000) {
       console.log("Timeout: 60s passed without the callback being called.");
       console.log("Timeout: 60s passed without the callback being called.");
       break;
       break;
     }
     }

+ 6 - 5
contract_manager/scripts/list_entropy_contracts.ts

@@ -1,8 +1,9 @@
+import Web3 from "web3";
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
-import { DefaultStore } from "../src/node/utils/store";
+
 import { ENTROPY_DEFAULT_KEEPER } from "../src/core/contracts";
 import { ENTROPY_DEFAULT_KEEPER } from "../src/core/contracts";
-import Web3 from "web3";
+import { DefaultStore } from "../src/node/utils/store";
 
 
 const parser = yargs(hideBin(process.argv))
 const parser = yargs(hideBin(process.argv))
   .usage("Usage: $0")
   .usage("Usage: $0")
@@ -40,7 +41,7 @@ async function main() {
       let version = "unknown";
       let version = "unknown";
       try {
       try {
         version = await contract.getVersion();
         version = await contract.getVersion();
-      } catch (e) {
+      } catch {
         /* old deployments did not have this method */
         /* old deployments did not have this method */
       }
       }
       const providerInfo = await contract.getProviderInfo(provider);
       const providerInfo = await contract.getProviderInfo(provider);
@@ -58,8 +59,8 @@ async function main() {
         version,
         version,
       });
       });
       console.log(`Fetched info for ${contract.getId()}`);
       console.log(`Fetched info for ${contract.getId()}`);
-    } catch (e) {
-      console.error(`Error fetching info for ${contract.getId()}`, e);
+    } catch (error) {
+      console.error(`Error fetching info for ${contract.getId()}`, error);
     }
     }
   }
   }
   console.table(entries);
   console.table(entries);

+ 4 - 3
contract_manager/scripts/list_evm_contracts.ts

@@ -1,7 +1,8 @@
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
-import { DefaultStore } from "../src/node/utils/store";
+
 import { EvmPriceFeedContract } from "../src/core/contracts";
 import { EvmPriceFeedContract } from "../src/core/contracts";
+import { DefaultStore } from "../src/node/utils/store";
 
 
 const parser = yargs(hideBin(process.argv))
 const parser = yargs(hideBin(process.argv))
   .usage("Usage: $0")
   .usage("Usage: $0")
@@ -31,8 +32,8 @@ async function main() {
           version: version,
           version: version,
         });
         });
         console.log(`Fetched version for ${contract.getId()}`);
         console.log(`Fetched version for ${contract.getId()}`);
-      } catch (e) {
-        console.error(`Error fetching version for ${contract.getId()}`, e);
+      } catch (error) {
+        console.error(`Error fetching version for ${contract.getId()}`, error);
       }
       }
     }
     }
   }
   }

+ 4 - 3
contract_manager/scripts/list_wormhole_contracts.ts

@@ -1,7 +1,8 @@
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
-import { DefaultStore } from "../src/node/utils/store";
+
 import { EvmWormholeContract } from "../src/core/contracts";
 import { EvmWormholeContract } from "../src/core/contracts";
+import { DefaultStore } from "../src/node/utils/store";
 
 
 const parser = yargs(hideBin(process.argv))
 const parser = yargs(hideBin(process.argv))
   .usage("Usage: $0")
   .usage("Usage: $0")
@@ -36,8 +37,8 @@ async function main() {
           chainId: chainId,
           chainId: chainId,
         });
         });
         console.log(`Fetched contract for ${contract.getId()}`);
         console.log(`Fetched contract for ${contract.getId()}`);
-      } catch (e) {
-        console.error(`Error fetching contract for ${contract.getId()}`, e);
+      } catch (error) {
+        console.error(`Error fetching contract for ${contract.getId()}`, error);
       }
       }
     }
     }
   }
   }

+ 5 - 4
contract_manager/scripts/load_test_entropy.ts

@@ -1,9 +1,10 @@
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
-import { DefaultStore } from "../src/node/utils/store";
-import { EvmChain } from "../src/core/chains";
-import { toPrivateKey } from "../src/core/base";
+
 import { COMMON_DEPLOY_OPTIONS, findEntropyContract } from "./common";
 import { COMMON_DEPLOY_OPTIONS, findEntropyContract } from "./common";
+import { toPrivateKey } from "../src/core/base";
+import { EvmChain } from "../src/core/chains";
+import { DefaultStore } from "../src/node/utils/store";
 
 
 const parser = yargs(hideBin(process.argv))
 const parser = yargs(hideBin(process.argv))
   .usage(
   .usage(
@@ -88,7 +89,7 @@ async function main() {
       value: (fee * totalCount).toString(),
       value: (fee * totalCount).toString(),
     },
     },
   );
   );
-  console.log("Submitted transaction ", result.transactionHash);
+  console.log("Submitted transaction", result.transactionHash);
 }
 }
 
 
 main();
 main();

+ 1 - 0
contract_manager/scripts/send_message_to_wormhole.ts

@@ -1,5 +1,6 @@
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
+
 import { WormholeEmitter, loadHotWallet } from "../src/node/utils/governance";
 import { WormholeEmitter, loadHotWallet } from "../src/node/utils/governance";
 
 
 const parser = yargs(hideBin(process.argv))
 const parser = yargs(hideBin(process.argv))

+ 7 - 6
contract_manager/scripts/sync_governance_vaas.ts

@@ -1,7 +1,8 @@
-import yargs from "yargs";
-import { hideBin } from "yargs/helpers";
 import { parseVaa } from "@certusone/wormhole-sdk";
 import { parseVaa } from "@certusone/wormhole-sdk";
 import { decodeGovernancePayload } from "@pythnetwork/xc-admin-common";
 import { decodeGovernancePayload } from "@pythnetwork/xc-admin-common";
+import yargs from "yargs";
+import { hideBin } from "yargs/helpers";
+
 import { toPrivateKey } from "../src/core/base";
 import { toPrivateKey } from "../src/core/base";
 import { SubmittedWormholeMessage, Vault } from "../src/node/utils/governance";
 import { SubmittedWormholeMessage, Vault } from "../src/node/utils/governance";
 import { DefaultStore } from "../src/node/utils/store";
 import { DefaultStore } from "../src/node/utils/store";
@@ -41,7 +42,7 @@ async function main() {
       "mainnet-beta_FVQyHcooAtThJ83XFrNnv74BcinbRH3bRmfFamAHBfuj"
       "mainnet-beta_FVQyHcooAtThJ83XFrNnv74BcinbRH3bRmfFamAHBfuj"
     ];
     ];
   const devnetVault =
   const devnetVault =
-    DefaultStore.vaults["devnet_6baWtW1zTUVMSJHJQVxDUXWzqrQeYBr6mu31j3bTKwY3"];
+    DefaultStore.vaults.devnet_6baWtW1zTUVMSJHJQVxDUXWzqrQeYBr6mu31j3bTKwY3;
   let matchedVault: Vault;
   let matchedVault: Vault;
   if (
   if (
     (await devnetVault.getEmitter()).toBuffer().toString("hex") ===
     (await devnetVault.getEmitter()).toBuffer().toString("hex") ===
@@ -67,7 +68,7 @@ async function main() {
     lastExecuted = argv.offset - 1;
     lastExecuted = argv.offset - 1;
   }
   }
   console.log("Starting from sequence number", lastExecuted);
   console.log("Starting from sequence number", lastExecuted);
-  // eslint-disable-next-line no-constant-condition
+   
   while (true) {
   while (true) {
     const submittedWormholeMessage = new SubmittedWormholeMessage(
     const submittedWormholeMessage = new SubmittedWormholeMessage(
       await matchedVault.getEmitter(),
       await matchedVault.getEmitter(),
@@ -77,8 +78,8 @@ async function main() {
     let vaa: Buffer;
     let vaa: Buffer;
     try {
     try {
       vaa = await submittedWormholeMessage.fetchVaa();
       vaa = await submittedWormholeMessage.fetchVaa();
-    } catch (e) {
-      console.log(e);
+    } catch (error) {
+      console.log(error);
       console.log("no vaa found for sequence", lastExecuted + 1);
       console.log("no vaa found for sequence", lastExecuted + 1);
       break;
       break;
     }
     }

+ 6 - 5
contract_manager/scripts/sync_wormhole_guardian_set.ts

@@ -1,5 +1,7 @@
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
+
+import { toPrivateKey } from "../src/core/base";
 import {
 import {
   AptosWormholeContract,
   AptosWormholeContract,
   CosmWasmPriceFeedContract,
   CosmWasmPriceFeedContract,
@@ -8,7 +10,6 @@ import {
   SuiWormholeContract,
   SuiWormholeContract,
 } from "../src/core/contracts";
 } from "../src/core/contracts";
 import { DefaultStore } from "../src/node/utils/store";
 import { DefaultStore } from "../src/node/utils/store";
-import { toPrivateKey } from "../src/core/base";
 
 
 const parser = yargs(hideBin(process.argv))
 const parser = yargs(hideBin(process.argv))
   .usage("Update the guardian set in stable networks. Usage: $0")
   .usage("Update the guardian set in stable networks. Usage: $0")
@@ -46,8 +47,8 @@ async function main() {
         await contract.syncMainnetGuardianSets(privateKey);
         await contract.syncMainnetGuardianSets(privateKey);
         index = await contract.getCurrentGuardianSetIndex();
         index = await contract.getCurrentGuardianSetIndex();
         console.log("Guardian Index at End:", index);
         console.log("Guardian Index at End:", index);
-      } catch (e) {
-        console.error(`Error updating Guardianset for ${contract.getId()}`, e);
+      } catch (error) {
+        console.error(`Error updating Guardianset for ${contract.getId()}`, error);
       }
       }
     }
     }
   }
   }
@@ -84,8 +85,8 @@ async function main() {
 
 
         await wormhole.syncMainnetGuardianSets(privateKey);
         await wormhole.syncMainnetGuardianSets(privateKey);
         console.log(`Updated Guardianset for ${contract.getId()}`);
         console.log(`Updated Guardianset for ${contract.getId()}`);
-      } catch (e) {
-        console.error(`Error updating Guardianset for ${contract.getId()}`, e);
+      } catch (error) {
+        console.error(`Error updating Guardianset for ${contract.getId()}`, error);
       }
       }
     }
     }
   }
   }

+ 15 - 14
contract_manager/scripts/transfer_balance_entropy_chains.ts

@@ -1,11 +1,12 @@
+import Web3 from "web3";
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
-import { DefaultStore } from "../src/node/utils/store";
+
 import { PrivateKey, toPrivateKey } from "../src/core/base";
 import { PrivateKey, toPrivateKey } from "../src/core/base";
 import { EvmChain } from "../src/core/chains";
 import { EvmChain } from "../src/core/chains";
-import Web3 from "web3";
+import { DefaultStore } from "../src/node/utils/store";
 
 
-interface TransferResult {
+type TransferResult = {
   chain: string;
   chain: string;
   success: boolean;
   success: boolean;
   sourceAddress: string;
   sourceAddress: string;
@@ -153,9 +154,7 @@ async function transferOnChain(
 
 
     // Calculate transfer amount
     // Calculate transfer amount
     let transferAmountEth: number;
     let transferAmountEth: number;
-    if (transferAmount !== undefined) {
-      transferAmountEth = transferAmount;
-    } else {
+    if (transferAmount === undefined) {
       // transferRatio is guaranteed to be defined at this point
       // transferRatio is guaranteed to be defined at this point
       if (transferRatio === undefined) {
       if (transferRatio === undefined) {
         throw new Error(
         throw new Error(
@@ -163,6 +162,8 @@ async function transferOnChain(
         );
         );
       }
       }
       transferAmountEth = (balanceEth - gasCostEth) * transferRatio;
       transferAmountEth = (balanceEth - gasCostEth) * transferRatio;
+    } else {
+      transferAmountEth = transferAmount;
     }
     }
 
 
     // Round to 10 decimal places to avoid Web3 conversion errors
     // Round to 10 decimal places to avoid Web3 conversion errors
@@ -317,7 +318,7 @@ function getSelectedChains(argv: {
       }
       }
       const chain = DefaultStore.chains[chainId];
       const chain = DefaultStore.chains[chainId];
       if (!(chain instanceof EvmChain)) {
       if (!(chain instanceof EvmChain)) {
-        throw new Error(`Chain ${chainId} is not an EVM chain`);
+        throw new TypeError(`Chain ${chainId} is not an EVM chain`);
       }
       }
       selectedChains.push(chain);
       selectedChains.push(chain);
     }
     }
@@ -326,9 +327,9 @@ function getSelectedChains(argv: {
   if (selectedChains.length === 0) {
   if (selectedChains.length === 0) {
     const mode = argv.testnets
     const mode = argv.testnets
       ? "testnet"
       ? "testnet"
-      : argv.mainnets
+      : (argv.mainnets
         ? "mainnet"
         ? "mainnet"
-        : "specified";
+        : "specified");
     throw new Error(`No valid ${mode} entropy chains found`);
     throw new Error(`No valid ${mode} entropy chains found`);
   }
   }
 
 
@@ -367,18 +368,18 @@ async function main() {
 
 
   // Determine transfer method for display
   // Determine transfer method for display
   let transferMethod: string;
   let transferMethod: string;
-  if (argv.amount !== undefined) {
-    transferMethod = `${argv.amount} ETH (fixed amount)`;
-  } else {
+  if (argv.amount === undefined) {
     if (argv.ratio === undefined) {
     if (argv.ratio === undefined) {
       throw new Error("Ratio must be defined when amount is not specified");
       throw new Error("Ratio must be defined when amount is not specified");
     }
     }
     transferMethod = `${(argv.ratio * 100).toFixed(1)}% of available balance`;
     transferMethod = `${(argv.ratio * 100).toFixed(1)}% of available balance`;
+  } else {
+    transferMethod = `${argv.amount} ETH (fixed amount)`;
   }
   }
 
 
   console.log(`\nConfiguration:`);
   console.log(`\nConfiguration:`);
   console.log(
   console.log(
-    `   Network: ${argv.testnets ? "Testnet" : argv.mainnets ? "Mainnet" : "Specific chains"}`,
+    `   Network: ${argv.testnets ? "Testnet" : (argv.mainnets ? "Mainnet" : "Specific chains")}`,
   );
   );
   console.log(`   Destination: ${argv.destinationAddress}`);
   console.log(`   Destination: ${argv.destinationAddress}`);
   console.log(`   Transfer method: ${transferMethod}`);
   console.log(`   Transfer method: ${transferMethod}`);
@@ -418,7 +419,7 @@ async function main() {
   console.log(`Successful transfers: ${successful.length}`);
   console.log(`Successful transfers: ${successful.length}`);
   console.log(`Failed transfers: ${failed.length}`);
   console.log(`Failed transfers: ${failed.length}`);
   console.log(
   console.log(
-    `Total transferred: ${successful.reduce((sum, r) => sum + parseFloat(r.transferAmount), 0).toFixed(6)} ETH`,
+    `Total transferred: ${successful.reduce((sum, r) => sum + Number.parseFloat(r.transferAmount), 0).toFixed(6)} ETH`,
   );
   );
 
 
   if (successful.length > 0) {
   if (successful.length > 0) {

+ 3 - 2
contract_manager/scripts/update_all_pricefeeds.ts

@@ -1,8 +1,9 @@
+import { HermesClient, PriceFeedMetadata } from "@pythnetwork/hermes-client";
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
-import { HermesClient, PriceFeedMetadata } from "@pythnetwork/hermes-client";
-import { DefaultStore } from "../src/node/utils/store";
+
 import { toPrivateKey } from "../src/core/base";
 import { toPrivateKey } from "../src/core/base";
+import { DefaultStore } from "../src/node/utils/store";
 
 
 const parser = yargs(hideBin(process.argv))
 const parser = yargs(hideBin(process.argv))
   .usage("Update the set of price feeds in a network. Usage: $0")
   .usage("Update the set of price feeds in a network. Usage: $0")

+ 3 - 2
contract_manager/scripts/update_pricefeed.ts

@@ -1,8 +1,9 @@
+import { PriceServiceConnection } from "@pythnetwork/price-service-client";
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
-import { DefaultStore } from "../src/node/utils/store";
+
 import { toPrivateKey } from "../src/core/base";
 import { toPrivateKey } from "../src/core/base";
-import { PriceServiceConnection } from "@pythnetwork/price-service-client";
+import { DefaultStore } from "../src/node/utils/store";
 
 
 const parser = yargs(hideBin(process.argv))
 const parser = yargs(hideBin(process.argv))
   .usage(
   .usage(

+ 11 - 10
contract_manager/scripts/upgrade_evm_entropy_contracts.ts

@@ -1,16 +1,17 @@
+import { readFileSync } from "node:fs";
+
+import { PythCluster } from "@pythnetwork/client/lib/cluster";
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
-import { DefaultStore } from "../src/node/utils/store";
-import { loadHotWallet } from "../src/node/utils/governance";
-import { toPrivateKey } from "../src/core/base";
-import { readFileSync } from "fs";
-import { PythCluster } from "@pythnetwork/client/lib/cluster";
 
 
 import {
 import {
   COMMON_UPGRADE_OPTIONS,
   COMMON_UPGRADE_OPTIONS,
   getSelectedChains,
   getSelectedChains,
   makeCacheFunction,
   makeCacheFunction,
 } from "./common";
 } from "./common";
+import { toPrivateKey } from "../src/core/base";
+import { loadHotWallet } from "../src/node/utils/governance";
+import { DefaultStore } from "../src/node/utils/store";
 
 
 const EXECUTOR_CACHE_FILE = ".cache-upgrade-evm-executor-contract";
 const EXECUTOR_CACHE_FILE = ".cache-upgrade-evm-executor-contract";
 const ENTROPY_CACHE_FILE = ".cache-upgrade-evm-entropy-contract";
 const ENTROPY_CACHE_FILE = ".cache-upgrade-evm-entropy-contract";
@@ -74,8 +75,8 @@ async function main() {
           () => {
           () => {
             return contract.chain.deploy(
             return contract.chain.deploy(
               toPrivateKey(argv["private-key"]),
               toPrivateKey(argv["private-key"]),
-              artifact["abi"],
-              artifact["bytecode"].object, // As per the artifacts generated by forge, bytecode is an object with an 'object' property
+              artifact.abi,
+              artifact.bytecode.object, // As per the artifacts generated by forge, bytecode is an object with an 'object' property
               [],
               [],
               2,
               2,
             );
             );
@@ -91,8 +92,8 @@ async function main() {
 
 
         console.log(payload.toString("hex"));
         console.log(payload.toString("hex"));
         payloads.push(payload);
         payloads.push(payload);
-      } catch (e) {
-        console.log(`error deploying: ${e}`);
+      } catch (error) {
+        console.log(`error deploying: ${error}`);
         failures.push(contract.chain.getId());
         failures.push(contract.chain.getId());
       }
       }
     }
     }
@@ -108,7 +109,7 @@ async function main() {
 
 
   console.log("Using vault at for proposal", vault.getId());
   console.log("Using vault at for proposal", vault.getId());
   const wallet = await loadHotWallet(argv["ops-key-path"]);
   const wallet = await loadHotWallet(argv["ops-key-path"]);
-  console.log("Using wallet ", wallet.publicKey.toBase58());
+  console.log("Using wallet", wallet.publicKey.toBase58());
   vault.connect(wallet, registry);
   vault.connect(wallet, registry);
   const proposal = await vault.proposeWormholeMessage(payloads);
   const proposal = await vault.proposeWormholeMessage(payloads);
   console.log("Proposal address", proposal.address.toBase58());
   console.log("Proposal address", proposal.address.toBase58());

+ 8 - 7
contract_manager/scripts/upgrade_evm_pricefeed_contracts.ts

@@ -1,15 +1,16 @@
+import { readFileSync } from "node:fs";
+
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
-import { DefaultStore } from "../src/node/utils/store";
-import { loadHotWallet } from "../src/node/utils/governance";
-import { toPrivateKey } from "../src/core/base";
-import { readFileSync } from "fs";
 
 
 import {
 import {
   COMMON_UPGRADE_OPTIONS,
   COMMON_UPGRADE_OPTIONS,
   getSelectedChains,
   getSelectedChains,
   makeCacheFunction,
   makeCacheFunction,
 } from "./common";
 } from "./common";
+import { toPrivateKey } from "../src/core/base";
+import { loadHotWallet } from "../src/node/utils/governance";
+import { DefaultStore } from "../src/node/utils/store";
 
 
 const CACHE_FILE = ".cache-upgrade-evm";
 const CACHE_FILE = ".cache-upgrade-evm";
 const runIfNotCached = makeCacheFunction(CACHE_FILE);
 const runIfNotCached = makeCacheFunction(CACHE_FILE);
@@ -44,8 +45,8 @@ async function main() {
     const address = await runIfNotCached(`deploy-${chain.getId()}`, () => {
     const address = await runIfNotCached(`deploy-${chain.getId()}`, () => {
       return chain.deploy(
       return chain.deploy(
         toPrivateKey(argv["private-key"]),
         toPrivateKey(argv["private-key"]),
-        artifact["abi"],
-        artifact["bytecode"].object, // As per the artifacts generated by forge, bytecode is an object with an 'object' property
+        artifact.abi,
+        artifact.bytecode.object, // As per the artifacts generated by forge, bytecode is an object with an 'object' property
         [],
         [],
       );
       );
     });
     });
@@ -57,7 +58,7 @@ async function main() {
 
 
   console.log("Using vault at for proposal", vault.getId());
   console.log("Using vault at for proposal", vault.getId());
   const wallet = await loadHotWallet(argv["ops-key-path"]);
   const wallet = await loadHotWallet(argv["ops-key-path"]);
-  console.log("Using wallet ", wallet.publicKey.toBase58());
+  console.log("Using wallet", wallet.publicKey.toBase58());
   await vault.connect(wallet);
   await vault.connect(wallet);
   const proposal = await vault.proposeWormholeMessage(payloads);
   const proposal = await vault.proposeWormholeMessage(payloads);
   console.log("Proposal address", proposal.address.toBase58());
   console.log("Proposal address", proposal.address.toBase58());

+ 8 - 5
contract_manager/scripts/upgrade_ton_contract.ts

@@ -1,11 +1,14 @@
+import fs from "node:fs";
+import path from "node:path";
+
+import { Cell } from "@ton/ton";
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
-import { DefaultStore } from "../src/node/utils/store";
-import { TonPriceFeedContract } from "../src/core/contracts";
+
 import { toPrivateKey } from "../src/core/base";
 import { toPrivateKey } from "../src/core/base";
-import fs from "fs";
-import path from "path";
-import { Cell } from "@ton/ton";
+import { TonPriceFeedContract } from "../src/core/contracts";
+import { DefaultStore } from "../src/node/utils/store";
+
 
 
 // This script upgrades the Pyth contract on TON after the governance has authorized the upgrade
 // This script upgrades the Pyth contract on TON after the governance has authorized the upgrade
 // If you are starting over, the process is like the following:
 // If you are starting over, the process is like the following:

+ 2 - 1
contract_manager/scripts/upload_cosmwasm.ts

@@ -1,9 +1,10 @@
 import yargs from "yargs";
 import yargs from "yargs";
 import { hideBin } from "yargs/helpers";
 import { hideBin } from "yargs/helpers";
+
+import { toPrivateKey } from "../src/core/base";
 import { CosmWasmChain } from "../src/core/chains";
 import { CosmWasmChain } from "../src/core/chains";
 import { CosmWasmPriceFeedContract } from "../src/core/contracts";
 import { CosmWasmPriceFeedContract } from "../src/core/contracts";
 import { DefaultStore } from "../src/node/utils/store";
 import { DefaultStore } from "../src/node/utils/store";
-import { toPrivateKey } from "../src/core/base";
 
 
 const parser = yargs(hideBin(process.argv))
 const parser = yargs(hideBin(process.argv))
   .usage(
   .usage(

+ 4 - 3
contract_manager/src/core/base.ts

@@ -1,7 +1,8 @@
 import type { DataSource } from "@pythnetwork/xc-admin-common";
 import type { DataSource } from "@pythnetwork/xc-admin-common";
+
 import { Chain } from "./chains";
 import { Chain } from "./chains";
 
 
-export interface TxResult {
+export type TxResult = {
   id: string;
   id: string;
   info: unknown; // chain specific info
   info: unknown; // chain specific info
 }
 }
@@ -45,14 +46,14 @@ export abstract class Storable {
   abstract toJson(): KeyValueConfig;
   abstract toJson(): KeyValueConfig;
 }
 }
 
 
-export interface Price {
+export type Price = {
   price: string;
   price: string;
   conf: string;
   conf: string;
   publishTime: string;
   publishTime: string;
   expo: string;
   expo: string;
 }
 }
 
 
-export interface PriceFeed {
+export type PriceFeed = {
   price: Price;
   price: Price;
   emaPrice: Price;
   emaPrice: Price;
 }
 }

+ 43 - 44
contract_manager/src/core/chains.ts

@@ -1,37 +1,6 @@
-import {
-  type KeyValueConfig,
-  type PrivateKey,
-  Storable,
-  type TxResult,
-} from "./base";
-import {
-  type ChainName,
-  SetFee,
-  CosmosUpgradeContract,
-  EvmUpgradeContract,
-  toChainId,
-  SetDataSources,
-  SetValidPeriod,
-  type DataSource,
-  EvmSetWormholeAddress,
-  UpgradeContract256Bit,
-  EvmExecute,
-} from "@pythnetwork/xc-admin-common";
-import { AptosClient, AptosAccount, CoinClient, TxnBuilderTypes } from "aptos";
-import Web3 from "web3";
-import {
-  CosmwasmExecutor,
-  CosmwasmQuerier,
-  InjectiveExecutor,
-} from "@pythnetwork/cosmwasm-deploy-tools";
 import { Network } from "@injectivelabs/networks";
 import { Network } from "@injectivelabs/networks";
 import { IotaClient } from "@iota/iota-sdk/client";
 import { IotaClient } from "@iota/iota-sdk/client";
-import { SuiClient } from "@mysten/sui/client";
 import { Ed25519Keypair as IotaEd25519Keypair } from "@iota/iota-sdk/keypairs/ed25519";
 import { Ed25519Keypair as IotaEd25519Keypair } from "@iota/iota-sdk/keypairs/ed25519";
-import { Ed25519Keypair as SuiEd25519Keypair } from "@mysten/sui/keypairs/ed25519";
-import type { TokenId } from "./token";
-import { BN, Provider, Wallet, WalletUnlocked } from "fuels";
-import { FUEL_ETH_ASSET_ID } from "@pythnetwork/pyth-fuel-js";
 import { Contract, RpcProvider, Signer, ec, shortString } from "starknet";
 import { Contract, RpcProvider, Signer, ec, shortString } from "starknet";
 import {
 import {
   TonClient,
   TonClient,
@@ -47,13 +16,47 @@ import * as nearAPI from "near-api-js";
 import * as bs58 from "bs58";
 import * as bs58 from "bs58";
 import { MIST_PER_SUI } from "@mysten/sui/utils";
 import { MIST_PER_SUI } from "@mysten/sui/utils";
 import { NANOS_PER_IOTA } from "@iota/iota-sdk/utils";
 import { NANOS_PER_IOTA } from "@iota/iota-sdk/utils";
+import { SuiClient } from "@mysten/sui/client";
+import { Ed25519Keypair as SuiEd25519Keypair } from "@mysten/sui/keypairs/ed25519";
+import {
+  CosmwasmExecutor,
+  CosmwasmQuerier,
+  InjectiveExecutor,
+} from "@pythnetwork/cosmwasm-deploy-tools";
+import { FUEL_ETH_ASSET_ID } from "@pythnetwork/pyth-fuel-js";
+import type {ChainName, DataSource} from "@pythnetwork/xc-admin-common";
+import {
+  
+  SetFee,
+  CosmosUpgradeContract,
+  EvmUpgradeContract,
+  toChainId,
+  SetDataSources,
+  SetValidPeriod,
+  
+  EvmSetWormholeAddress,
+  UpgradeContract256Bit,
+  EvmExecute
+} from "@pythnetwork/xc-admin-common";
+import { AptosClient, AptosAccount, CoinClient, TxnBuilderTypes } from "aptos";
+import { BN, Provider, Wallet, WalletUnlocked } from "fuels";
 import * as chains from "viem/chains";
 import * as chains from "viem/chains";
+import Web3 from "web3";
+
+import type {KeyValueConfig, PrivateKey, TxResult} from "./base";
+import {
+  
+  
+  Storable
+  
+} from "./base";
+import type { TokenId } from "./token";
 
 
 /**
 /**
  * Returns the chain rpc url with any environment variables replaced or throws an error if any are missing
  * Returns the chain rpc url with any environment variables replaced or throws an error if any are missing
  */
  */
 export function parseRpcUrl(rpcUrl: string): string {
 export function parseRpcUrl(rpcUrl: string): string {
-  const envMatches = rpcUrl.match(/\$ENV_\w+/);
+  const envMatches = /\$ENV_\w+/.exec(rpcUrl);
   if (envMatches) {
   if (envMatches) {
     for (const envMatch of envMatches) {
     for (const envMatch of envMatches) {
       const envName = envMatch.replace("$ENV_", "");
       const envName = envMatch.replace("$ENV_", "");
@@ -267,7 +270,7 @@ export class CosmWasmChain extends Chain {
   async getExecutor(
   async getExecutor(
     privateKey: PrivateKey,
     privateKey: PrivateKey,
   ): Promise<CosmwasmExecutor | InjectiveExecutor> {
   ): Promise<CosmwasmExecutor | InjectiveExecutor> {
-    if (this.getId().indexOf("injective") > -1) {
+    if (this.getId().includes("injective")) {
       return InjectiveExecutor.fromPrivateKey(
       return InjectiveExecutor.fromPrivateKey(
         this.isMainnet() ? Network.Mainnet : Network.Testnet,
         this.isMainnet() ? Network.Mainnet : Network.Testnet,
         privateKey,
         privateKey,
@@ -282,11 +285,7 @@ export class CosmWasmChain extends Chain {
 
 
   async getAccountAddress(privateKey: PrivateKey): Promise<string> {
   async getAccountAddress(privateKey: PrivateKey): Promise<string> {
     const executor = await this.getExecutor(privateKey);
     const executor = await this.getExecutor(privateKey);
-    if (executor instanceof InjectiveExecutor) {
-      return executor.getAddress();
-    } else {
-      return await executor.getAddress();
-    }
+    return executor instanceof InjectiveExecutor ? executor.getAddress() : (await executor.getAddress());
   }
   }
 
 
   async getAccountBalance(privateKey: PrivateKey): Promise<number> {
   async getAccountBalance(privateKey: PrivateKey): Promise<number> {
@@ -593,11 +592,11 @@ export class EvmChain extends Chain {
         gasPrice: gasPrice.toString(),
         gasPrice: gasPrice.toString(),
       });
       });
       return deployedContract.options.address;
       return deployedContract.options.address;
-    } catch (e) {
+    } catch (error) {
       // RPC errors often have useful information in the non-primary message field. Log the whole error
       // RPC errors often have useful information in the non-primary message field. Log the whole error
       // to simplify identifying the problem.
       // to simplify identifying the problem.
-      console.log(`Error deploying contract: ${JSON.stringify(e)}`);
-      throw e;
+      console.log(`Error deploying contract: ${JSON.stringify(error)}`);
+      throw error;
     }
     }
   }
   }
 
 
@@ -694,7 +693,7 @@ export class AptosChain extends Chain {
       sender,
       sender,
       txPayload,
       txPayload,
       {
       {
-        maxGasAmount: BigInt(30000),
+        maxGasAmount: BigInt(30_000),
       },
       },
     );
     );
     return { id: result.hash, info: result };
     return { id: result.hash, info: result };
@@ -818,7 +817,7 @@ export class StarknetChain extends Chain {
     const ARGENT_CLASS_HASH =
     const ARGENT_CLASS_HASH =
       "0x029927c8af6bccf3f6fda035981e765a7bdbf18a2dc0d630494f8758aa908e2b";
       "0x029927c8af6bccf3f6fda035981e765a7bdbf18a2dc0d630494f8758aa908e2b";
     const ADDR_BOUND =
     const ADDR_BOUND =
-      0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00n;
+      0x7_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_FF_00n;
 
 
     function computeHashOnElements(elements: string[]): string {
     function computeHashOnElements(elements: string[]): string {
       let hash = "0";
       let hash = "0";
@@ -1032,7 +1031,7 @@ export class NearChain extends Chain {
     senderPrivateKey?: PrivateKey,
     senderPrivateKey?: PrivateKey,
   ): Promise<nearAPI.Account> {
   ): Promise<nearAPI.Account> {
     const keyStore = new nearAPI.keyStores.InMemoryKeyStore();
     const keyStore = new nearAPI.keyStores.InMemoryKeyStore();
-    if (typeof senderPrivateKey !== "undefined") {
+    if (senderPrivateKey !== undefined) {
       const key = bs58.encode(
       const key = bs58.encode(
         new Uint8Array(Buffer.from(senderPrivateKey, "hex")),
         new Uint8Array(Buffer.from(senderPrivateKey, "hex")),
       );
       );

+ 12 - 10
contract_manager/src/core/contracts/aptos.ts

@@ -1,14 +1,16 @@
+import type { DataSource } from "@pythnetwork/xc-admin-common";
+import { ApiError, BCS, CoinClient, TxnBuilderTypes } from "aptos";
+
+import type {PriceFeed, PrivateKey, TxResult} from "../base";
 import {
 import {
-  PriceFeedContract,
-  type PriceFeed,
-  type PrivateKey,
-  type TxResult,
+  PriceFeedContract
+  
+  
+  
 } from "../base";
 } from "../base";
-import { ApiError, BCS, CoinClient, TxnBuilderTypes } from "aptos";
 import { AptosChain, Chain } from "../chains";
 import { AptosChain, Chain } from "../chains";
-import type { DataSource } from "@pythnetwork/xc-admin-common";
-import { WormholeContract } from "./wormhole";
 import type { TokenQty } from "../token";
 import type { TokenQty } from "../token";
+import { WormholeContract } from "./wormhole";
 
 
 type WormholeState = {
 type WormholeState = {
   chain_id: { number: string };
   chain_id: { number: string };
@@ -251,10 +253,10 @@ export class AptosPriceFeedContract extends PriceFeedContract {
         price: this.parsePrice(priceItemRes.price_feed.price),
         price: this.parsePrice(priceItemRes.price_feed.price),
         emaPrice: this.parsePrice(priceItemRes.price_feed.ema_price),
         emaPrice: this.parsePrice(priceItemRes.price_feed.ema_price),
       };
       };
-    } catch (e) {
-      if (e instanceof ApiError && e.errorCode === "table_item_not_found")
+    } catch (error) {
+      if (error instanceof ApiError && error.errorCode === "table_item_not_found")
         return undefined;
         return undefined;
-      throw e;
+      throw error;
     }
     }
   }
   }
 
 

+ 31 - 29
contract_manager/src/core/contracts/cosmwasm.ts

@@ -1,33 +1,37 @@
-import { Chain, CosmWasmChain } from "../chains";
-import { readFileSync } from "fs";
+import { readFileSync } from "node:fs";
+
+import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate";
+import type { Coin } from "@cosmjs/stargate";
+import type {ContractInfoResponse, Price} from "@pythnetwork/cosmwasm-deploy-tools";
 import {
 import {
-  type ContractInfoResponse,
+  
   CosmwasmQuerier,
   CosmwasmQuerier,
-  type Price,
+  
   PythWrapperExecutor,
   PythWrapperExecutor,
-  PythWrapperQuerier,
+  PythWrapperQuerier
 } from "@pythnetwork/cosmwasm-deploy-tools";
 } from "@pythnetwork/cosmwasm-deploy-tools";
-import type { Coin } from "@cosmjs/stargate";
 import type { DataSource } from "@pythnetwork/xc-admin-common";
 import type { DataSource } from "@pythnetwork/xc-admin-common";
-import { CosmWasmClient } from "@cosmjs/cosmwasm-stargate";
+
+import type {PrivateKey, TxResult} from "../base";
 import {
 import {
   PriceFeedContract,
   PriceFeedContract,
-  getDefaultDeploymentConfig,
-  type PrivateKey,
-  type TxResult,
+  getDefaultDeploymentConfig
+  
+  
 } from "../base";
 } from "../base";
-import { WormholeContract } from "./wormhole";
+import { Chain, CosmWasmChain } from "../chains";
 import type { TokenQty } from "../token";
 import type { TokenQty } from "../token";
+import { WormholeContract } from "./wormhole";
 
 
 /**
 /**
  * Variables here need to be snake case to match the on-chain contract configs
  * Variables here need to be snake case to match the on-chain contract configs
  */
  */
-export interface WormholeSource {
+export type WormholeSource = {
   emitter: string;
   emitter: string;
   chain_id: number;
   chain_id: number;
 }
 }
 
 
-export interface DeploymentConfig {
+export type DeploymentConfig = {
   data_sources: WormholeSource[];
   data_sources: WormholeSource[];
   governance_source: WormholeSource;
   governance_source: WormholeSource;
   wormhole_contract: string;
   wormhole_contract: string;
@@ -84,24 +88,22 @@ export class CosmWasmWormholeContract extends WormholeContract {
 
 
   async getCurrentGuardianSetIndex(): Promise<number> {
   async getCurrentGuardianSetIndex(): Promise<number> {
     const config = await this.getConfig();
     const config = await this.getConfig();
-    return JSON.parse(config["\x00\x06config"] ?? "{}")["guardian_set_index"];
+    return JSON.parse(config["\u0000\u0006config"] ?? "{}").guardian_set_index;
   }
   }
 
 
   async getChainId(): Promise<number> {
   async getChainId(): Promise<number> {
     const config = await this.getConfig();
     const config = await this.getConfig();
-    return JSON.parse(config["\x00\x06config"] ?? "{}")["chain_id"];
+    return JSON.parse(config["\u0000\u0006config"] ?? "{}").chain_id;
   }
   }
 
 
   async getGuardianSet(): Promise<string[]> {
   async getGuardianSet(): Promise<string[]> {
     const config = await this.getConfig();
     const config = await this.getConfig();
-    const guardianSetIndex = JSON.parse(config["\x00\x06config"] ?? "{}")[
-      "guardian_set_index"
-    ];
-    let key = "\x00\fguardian_set";
+    const guardianSetIndex = JSON.parse(config["\u0000\u0006config"] ?? "{}").guardian_set_index;
+    let key = "\u0000\fguardian_set";
     //append guardianSetIndex as 4 bytes to key string
     //append guardianSetIndex as 4 bytes to key string
     key += Buffer.from(guardianSetIndex.toString(16).padStart(8, "0"), "hex");
     key += Buffer.from(guardianSetIndex.toString(16).padStart(8, "0"), "hex");
 
 
-    const guardianSet = JSON.parse(config[key] ?? "{}")["addresses"];
+    const guardianSet = JSON.parse(config[key] ?? "{}").addresses;
     return guardianSet.map((entry: { bytes: string }) =>
     return guardianSet.map((entry: { bytes: string }) =>
       Buffer.from(entry.bytes, "base64").toString("hex"),
       Buffer.from(entry.bytes, "base64").toString("hex"),
     );
     );
@@ -245,9 +247,9 @@ export class CosmWasmPriceFeedContract extends PriceFeedContract {
       contractAddr: this.address,
       contractAddr: this.address,
     })) as Record<string, string>;
     })) as Record<string, string>;
     const config = {
     const config = {
-      config_v1: JSON.parse(allStates["\x00\tconfig_v1"] ?? "{}"),
-      contract_version: allStates["\x00\x10contract_version"]
-        ? JSON.parse(allStates["\x00\x10contract_version"])
+      config_v1: JSON.parse(allStates["\u0000\tconfig_v1"] ?? "{}"),
+      contract_version: allStates["\u0000\u0010contract_version"]
+        ? JSON.parse(allStates["\u0000\u0010contract_version"])
         : undefined,
         : undefined,
     };
     };
     return config;
     return config;
@@ -275,8 +277,8 @@ export class CosmWasmPriceFeedContract extends PriceFeedContract {
         price: this.parsePrice(response.price),
         price: this.parsePrice(response.price),
         emaPrice: this.parsePrice(response.ema_price),
         emaPrice: this.parsePrice(response.ema_price),
       };
       };
-    } catch (e) {
-      return undefined;
+    } catch {
+      return;
     }
     }
   }
   }
 
 
@@ -285,12 +287,12 @@ export class CosmWasmPriceFeedContract extends PriceFeedContract {
     dataSources2: WormholeSource[],
     dataSources2: WormholeSource[],
   ): boolean {
   ): boolean {
     if (dataSources1.length !== dataSources2.length) return false;
     if (dataSources1.length !== dataSources2.length) return false;
-    for (let i = 0; i < dataSources1.length; i++) {
+    for (const element of dataSources1) {
       let found = false;
       let found = false;
-      for (let j = 0; j < dataSources2.length; j++) {
+      for (const element_ of dataSources2) {
         if (
         if (
-          dataSources1[i]?.emitter === dataSources2[j]?.emitter &&
-          dataSources1[i]?.chain_id === dataSources2[j]?.chain_id
+          element.emitter === element_.emitter &&
+          element.chain_id === element_.chain_id
         ) {
         ) {
           found = true;
           found = true;
           break;
           break;

+ 11 - 9
contract_manager/src/core/contracts/evm.ts

@@ -1,9 +1,10 @@
+import type { DataSource } from "@pythnetwork/xc-admin-common";
 import Web3 from "web3";
 import Web3 from "web3";
 import type { Contract } from "web3-eth-contract";
 import type { Contract } from "web3-eth-contract";
-import { PriceFeedContract, type PrivateKey, Storable } from "../base";
+
+import type {PrivateKey} from "../base";
+import { PriceFeedContract,  Storable } from "../base";
 import { Chain, EvmChain } from "../chains";
 import { Chain, EvmChain } from "../chains";
-import type { DataSource } from "@pythnetwork/xc-admin-common";
-import { WormholeContract } from "./wormhole";
 import type { TokenQty } from "../token";
 import type { TokenQty } from "../token";
 import {
 import {
   EXECUTOR_ABI,
   EXECUTOR_ABI,
@@ -13,6 +14,7 @@ import {
   PULSE_UPGRADEABLE_ABI,
   PULSE_UPGRADEABLE_ABI,
   LAZER_ABI,
   LAZER_ABI,
 } from "./evm_abis";
 } from "./evm_abis";
+import { WormholeContract } from "./wormhole";
 
 
 /**
 /**
  * Returns the keccak256 digest of the contract bytecode at the given address after replacing
  * Returns the keccak256 digest of the contract bytecode at the given address after replacing
@@ -124,7 +126,7 @@ export class EvmWormholeContract extends WormholeContract {
   }
   }
 }
 }
 
 
-interface EntropyProviderInfo {
+type EntropyProviderInfo = {
   feeInWei: string;
   feeInWei: string;
   accruedFeesInWei: string;
   accruedFeesInWei: string;
   originalCommitment: string;
   originalCommitment: string;
@@ -138,7 +140,7 @@ interface EntropyProviderInfo {
   feeManager: string;
   feeManager: string;
 }
 }
 
 
-interface EntropyRequest {
+type EntropyRequest = {
   provider: string;
   provider: string;
   sequenceNumber: string;
   sequenceNumber: string;
   numHashes: string;
   numHashes: string;
@@ -586,7 +588,7 @@ export class EvmPriceFeedContract extends PriceFeedContract {
     try {
     try {
       web3 = this.chain.getWeb3();
       web3 = this.chain.getWeb3();
       amount = BigInt(await web3.eth.getBalance(this.address));
       amount = BigInt(await web3.eth.getBalance(this.address));
-    } catch (error) {
+    } catch {
       console.error(
       console.error(
         "Error getting balance with given RPC, moving to viem default RPC",
         "Error getting balance with given RPC, moving to viem default RPC",
       );
       );
@@ -611,7 +613,7 @@ export class EvmPriceFeedContract extends PriceFeedContract {
     const feed = "0x" + feedId;
     const feed = "0x" + feedId;
     const exists = await pythContract.methods.priceFeedExists(feed).call();
     const exists = await pythContract.methods.priceFeedExists(feed).call();
     if (!exists) {
     if (!exists) {
-      return undefined;
+      return;
     }
     }
     const [price, conf, expo, publishTime] = await pythContract.methods
     const [price, conf, expo, publishTime] = await pythContract.methods
       .getPriceUnsafe(feed)
       .getPriceUnsafe(feed)
@@ -837,13 +839,13 @@ export class EvmPulseContract extends Storable {
   }
   }
 
 
   async getFirstActiveRequests(count: number): Promise<{
   async getFirstActiveRequests(count: number): Promise<{
-    requests: Array<{
+    requests: {
       provider: string;
       provider: string;
       publishTime: string;
       publishTime: string;
       priceIds: string[];
       priceIds: string[];
       callbackGasLimit: string;
       callbackGasLimit: string;
       requester: string;
       requester: string;
-    }>;
+    }[];
     actualCount: number;
     actualCount: number;
   }> {
   }> {
     const contract = this.getContract();
     const contract = this.getContract();

+ 2 - 1
contract_manager/src/core/contracts/evm_abis.ts

@@ -1,5 +1,6 @@
-import PythInterfaceAbi from "@pythnetwork/pyth-sdk-solidity/abis/IPyth.json";
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
 import EntropyAbi from "@pythnetwork/entropy-sdk-solidity/abis/IEntropy.json";
 import EntropyAbi from "@pythnetwork/entropy-sdk-solidity/abis/IEntropy.json";
+import PythInterfaceAbi from "@pythnetwork/pyth-sdk-solidity/abis/IPyth.json";
 
 
 export const OWNABLE_ABI = [
 export const OWNABLE_ABI = [
   {
   {

+ 21 - 20
contract_manager/src/core/contracts/fuel.ts

@@ -1,29 +1,30 @@
-import { Chain, FuelChain } from "../chains";
-import { WormholeContract } from "./wormhole";
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+/* eslint-disable @typescript-eslint/no-unsafe-call */
+/* eslint-disable @typescript-eslint/require-await */
+/* eslint-disable @typescript-eslint/no-unnecessary-condition */
+/* eslint-disable @typescript-eslint/prefer-optional-chain */
+/* eslint-disable @typescript-eslint/no-unsafe-return */
+/* eslint-disable unicorn/no-await-expression-member */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
+/* eslint-disable @typescript-eslint/no-base-to-string */
+import type {
+  PriceFeedOutput,
+  DataSourceOutput,
+} from "@pythnetwork/pyth-fuel-js";
 import {
 import {
   PYTH_CONTRACT_ABI as FuelContractAbi,
   PYTH_CONTRACT_ABI as FuelContractAbi,
   FUEL_ETH_ASSET_ID,
   FUEL_ETH_ASSET_ID,
-  type PriceFeedOutput,
-  type DataSourceOutput,
 } from "@pythnetwork/pyth-fuel-js";
 } from "@pythnetwork/pyth-fuel-js";
+import type { DataSource } from "@pythnetwork/xc-admin-common";
+import type { DryRunResult } from "fuels";
+import { Account, Contract, Wallet, arrayify, hexlify } from "fuels";
 
 
-import {
-  Account,
-  Contract,
-  Wallet,
-  arrayify,
-  hexlify,
-  type DryRunResult,
-} from "fuels";
-import {
-  type PriceFeed,
-  PriceFeedContract,
-  type PrivateKey,
-  type TxResult,
-} from "../base";
-
+import type { PriceFeed, PrivateKey, TxResult } from "../base";
+import { Chain, FuelChain } from "../chains";
+import { WormholeContract } from "./wormhole";
+import { PriceFeedContract } from "../base";
 import type { TokenQty } from "../token";
 import type { TokenQty } from "../token";
-import type { DataSource } from "@pythnetwork/xc-admin-common";
 
 
 export class FuelWormholeContract extends WormholeContract {
 export class FuelWormholeContract extends WormholeContract {
   static type = "FuelWormholeContract";
   static type = "FuelWormholeContract";

+ 37 - 37
contract_manager/src/core/contracts/iota.ts

@@ -1,12 +1,23 @@
-import { Chain, IotaChain } from "../chains";
-import type { DataSource } from "@pythnetwork/xc-admin-common";
-import { WormholeContract } from "./wormhole";
-import { PriceFeedContract, type PrivateKey, type TxResult } from "../base";
-import { IotaPythClient } from "@pythnetwork/pyth-iota-js";
-import { IOTA_CLOCK_OBJECT_ID } from "@iota/iota-sdk/utils";
+/* eslint-disable @typescript-eslint/no-unsafe-return */
+/* eslint-disable @typescript-eslint/no-unsafe-call */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+/* eslint-disable @typescript-eslint/no-non-null-assertion */
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
+/* eslint-disable @typescript-eslint/require-await */
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
+/* eslint-disable @typescript-eslint/no-base-to-string */
+import { uint8ArrayToBCS } from "@certusone/wormhole-sdk/lib/cjs/sui";
 import { Ed25519Keypair } from "@iota/iota-sdk/keypairs/ed25519";
 import { Ed25519Keypair } from "@iota/iota-sdk/keypairs/ed25519";
 import { Transaction } from "@iota/iota-sdk/transactions";
 import { Transaction } from "@iota/iota-sdk/transactions";
-import { uint8ArrayToBCS } from "@certusone/wormhole-sdk/lib/cjs/sui";
+import { IOTA_CLOCK_OBJECT_ID } from "@iota/iota-sdk/utils";
+import { IotaPythClient } from "@pythnetwork/pyth-iota-js";
+import type { DataSource } from "@pythnetwork/xc-admin-common";
+
+import type { PrivateKey, TxResult } from "../base";
+import { Chain, IotaChain } from "../chains";
+import { WormholeContract } from "./wormhole";
+import { PriceFeedContract } from "../base";
 
 
 type ObjectId = string;
 type ObjectId = string;
 
 
@@ -18,9 +29,9 @@ export class IotaPriceFeedContract extends PriceFeedContract {
    * Given the ids of the pyth state and wormhole state, create a new IotaPriceFeedContract
    * Given the ids of the pyth state and wormhole state, create a new IotaPriceFeedContract
    * The package ids are derived based on the state ids
    * The package ids are derived based on the state ids
    *
    *
-   * @param chain the chain which this contract is deployed on
-   * @param stateId id of the pyth state for the deployed contract
-   * @param wormholeStateId id of the wormhole state for the wormhole contract that pyth binds to
+   * @param chain - the chain which this contract is deployed on
+   * @param stateId - id of the pyth state for the deployed contract
+   * @param wormholeStateId - id of the wormhole state for the wormhole contract that pyth binds to
    */
    */
   constructor(
   constructor(
     public chain: IotaChain,
     public chain: IotaChain,
@@ -69,7 +80,7 @@ export class IotaPriceFeedContract extends PriceFeedContract {
 
 
   /**
   /**
    * Given a objectId, returns the id for the package that the object belongs to.
    * Given a objectId, returns the id for the package that the object belongs to.
-   * @param objectId
+   * @param objectId - the object id to get
    */
    */
   async getPackageId(objectId: ObjectId): Promise<ObjectId> {
   async getPackageId(objectId: ObjectId): Promise<ObjectId> {
     return this.client.getPackageId(objectId);
     return this.client.getPackageId(objectId);
@@ -111,12 +122,12 @@ export class IotaPriceFeedContract extends PriceFeedContract {
   async getPriceFeed(feedId: string) {
   async getPriceFeed(feedId: string) {
     const provider = this.getProvider();
     const provider = this.getProvider();
     const priceInfoObjectId = await this.client.getPriceFeedObjectId(feedId);
     const priceInfoObjectId = await this.client.getPriceFeedObjectId(feedId);
-    if (!priceInfoObjectId) return undefined;
+    if (!priceInfoObjectId) return;
     const priceInfo = await provider.getObject({
     const priceInfo = await provider.getObject({
       id: priceInfoObjectId,
       id: priceInfoObjectId,
       options: { showContent: true },
       options: { showContent: true },
     });
     });
-    if (!priceInfo.data || !priceInfo.data.content) {
+    if (!priceInfo.data?.content) {
       throw new Error(
       throw new Error(
         `Price feed ID ${priceInfoObjectId} in price table but object not found!!`,
         `Price feed ID ${priceInfoObjectId} in price table but object not found!!`,
       );
       );
@@ -144,8 +155,8 @@ export class IotaPriceFeedContract extends PriceFeedContract {
   /**
   /**
    * Given a signed VAA, execute the migration instruction on the pyth contract.
    * Given a signed VAA, execute the migration instruction on the pyth contract.
    * The payload of the VAA can be obtained from the `getUpgradePackagePayload` method.
    * The payload of the VAA can be obtained from the `getUpgradePackagePayload` method.
-   * @param vaa
-   * @param keypair used to sign the transaction
+   * @param vaa - the vaa payload
+   * @param keypair - used to sign the transaction
    */
    */
   async executeMigrateInstruction(vaa: Buffer, keypair: Ed25519Keypair) {
   async executeMigrateInstruction(vaa: Buffer, keypair: Ed25519Keypair) {
     const tx = new Transaction();
     const tx = new Transaction();
@@ -260,10 +271,9 @@ export class IotaPriceFeedContract extends PriceFeedContract {
   /**
   /**
    * Utility function to get the verification receipt object for a VAA that can be
    * Utility function to get the verification receipt object for a VAA that can be
    * used to authorize a governance instruction.
    * used to authorize a governance instruction.
-   * @param tx
-   * @param packageId pyth package id
-   * @param vaa
-   * @private
+   * @param tx - the transaction
+   * @param packageId - pyth package id
+   * @param vaa - the vaa payload
    */
    */
   async getVaaVerificationReceipt(
   async getVaaVerificationReceipt(
     tx: Transaction,
     tx: Transaction,
@@ -276,7 +286,7 @@ export class IotaPriceFeedContract extends PriceFeedContract {
       target: `${wormholePackageId}::vaa::parse_and_verify`,
       target: `${wormholePackageId}::vaa::parse_and_verify`,
       arguments: [
       arguments: [
         tx.object(this.wormholeStateId),
         tx.object(this.wormholeStateId),
-        tx.pure.arguments(Array.from(vaa)),
+        tx.pure.arguments([...vaa]),
         tx.object(IOTA_CLOCK_OBJECT_ID),
         tx.object(IOTA_CLOCK_OBJECT_ID),
       ],
       ],
     });
     });
@@ -291,9 +301,8 @@ export class IotaPriceFeedContract extends PriceFeedContract {
   /**
   /**
    * Given a transaction block and a keypair, sign and execute it
    * Given a transaction block and a keypair, sign and execute it
    * Sets the gas budget to 2x the estimated gas cost
    * Sets the gas budget to 2x the estimated gas cost
-   * @param tx
-   * @param keypair
-   * @private
+   * @param tx - the transaction
+   * @param keypair - the keypair
    */
    */
   private async executeTransaction(tx: Transaction, keypair: Ed25519Keypair) {
   private async executeTransaction(tx: Transaction, keypair: Ed25519Keypair) {
     const provider = this.getProvider();
     const provider = this.getProvider();
@@ -328,7 +337,7 @@ export class IotaPriceFeedContract extends PriceFeedContract {
         value: "data_sources",
         value: "data_sources",
       },
       },
     });
     });
-    if (!result.data || !result.data.content) {
+    if (!result.data?.content) {
       throw new Error(
       throw new Error(
         "Data Sources not found, contract may not be initialized",
         "Data Sources not found, contract may not be initialized",
       );
       );
@@ -395,11 +404,7 @@ export class IotaPriceFeedContract extends PriceFeedContract {
       id: this.stateId,
       id: this.stateId,
       options: { showContent: true },
       options: { showContent: true },
     });
     });
-    if (
-      !result.data ||
-      !result.data.content ||
-      result.data.content.dataType !== "moveObject"
-    )
+    if (!result.data?.content || result.data.content.dataType !== "moveObject")
       throw new Error("Unable to fetch pyth state object");
       throw new Error("Unable to fetch pyth state object");
     return result.data.content.fields;
     return result.data.content.fields;
   }
   }
@@ -533,11 +538,7 @@ export class IotaWormholeContract extends WormholeContract {
       id: this.stateId,
       id: this.stateId,
       options: { showContent: true },
       options: { showContent: true },
     });
     });
-    if (
-      !result.data ||
-      !result.data.content ||
-      result.data.content.dataType !== "moveObject"
-    )
+    if (!result.data?.content || result.data.content.dataType !== "moveObject")
       throw new Error("Unable to fetch pyth state object");
       throw new Error("Unable to fetch pyth state object");
     return result.data.content.fields;
     return result.data.content.fields;
   }
   }
@@ -545,9 +546,8 @@ export class IotaWormholeContract extends WormholeContract {
   /**
   /**
    * Given a transaction block and a keypair, sign and execute it
    * Given a transaction block and a keypair, sign and execute it
    * Sets the gas budget to 2x the estimated gas cost
    * Sets the gas budget to 2x the estimated gas cost
-   * @param tx
-   * @param keypair
-   * @private
+   * @param tx - the transaction
+   * @param keypair - the keypair
    */
    */
   private async executeTransaction(tx: Transaction, keypair: Ed25519Keypair) {
   private async executeTransaction(tx: Transaction, keypair: Ed25519Keypair) {
     const provider = this.chain.getProvider();
     const provider = this.chain.getProvider();

+ 40 - 39
contract_manager/src/core/contracts/near.ts

@@ -1,14 +1,17 @@
+/* eslint-disable @typescript-eslint/require-await */
+/* eslint-disable @typescript-eslint/no-unsafe-return */
+/* eslint-disable @typescript-eslint/no-non-null-assertion */
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
+/* eslint-disable @typescript-eslint/no-base-to-string */
 import type { DataSource } from "@pythnetwork/xc-admin-common";
 import type { DataSource } from "@pythnetwork/xc-admin-common";
-import {
-  type KeyValueConfig,
-  type PriceFeed,
-  PriceFeedContract,
-  type PrivateKey,
-  type TxResult,
-} from "../base";
-import { Chain, NearChain } from "../chains";
-import * as nearAPI from "near-api-js";
 import { BN } from "fuels";
 import { BN } from "fuels";
+import * as nearAPI from "near-api-js";
+
+import type { KeyValueConfig, PriceFeed, PrivateKey, TxResult } from "../base";
+import { PriceFeedContract } from "../base";
+import { Chain, NearChain } from "../chains";
 import { WormholeContract } from "./wormhole";
 import { WormholeContract } from "./wormhole";
 
 
 export class NearWormholeContract extends WormholeContract {
 export class NearWormholeContract extends WormholeContract {
@@ -22,7 +25,7 @@ export class NearWormholeContract extends WormholeContract {
   }
   }
 
 
   getId(): string {
   getId(): string {
-    return `${this.chain.getId()}__${this.address.replace(/-|\./g, "_")}`;
+    return `${this.chain.getId()}__${this.address.replaceAll(/-|\./g, "_")}`;
   }
   }
 
 
   getChain(): NearChain {
   getChain(): NearChain {
@@ -101,7 +104,7 @@ export class NearPriceFeedContract extends PriceFeedContract {
   }
   }
 
 
   getId(): string {
   getId(): string {
-    return `${this.chain.getId()}__${this.address.replace(/-|\./g, "_")}`;
+    return `${this.chain.getId()}__${this.address.replaceAll(/-|\./g, "_")}`;
   }
   }
 
 
   getType(): string {
   getType(): string {
@@ -137,7 +140,7 @@ export class NearPriceFeedContract extends PriceFeedContract {
       throw new Error("Invalid type");
       throw new Error("Invalid type");
     }
     }
     if (!(chain instanceof NearChain)) {
     if (!(chain instanceof NearChain)) {
-      throw new Error(`Wrong chain type ${chain}`);
+      throw new TypeError(`Wrong chain type ${chain}`);
     }
     }
     return new NearPriceFeedContract(
     return new NearPriceFeedContract(
       chain,
       chain,
@@ -158,10 +161,12 @@ export class NearPriceFeedContract extends PriceFeedContract {
 
 
   async getValidTimePeriod(): Promise<number> {
   async getValidTimePeriod(): Promise<number> {
     const account = await this.getContractNearAccount();
     const account = await this.getContractNearAccount();
-    return account.viewFunction({
+    const result = await account.viewFunction({
       contractId: this.address,
       contractId: this.address,
       methodName: "get_stale_threshold",
       methodName: "get_stale_threshold",
     });
     });
+
+    return Number(result);
   }
   }
 
 
   async getDataSources(): Promise<DataSource[]> {
   async getDataSources(): Promise<DataSource[]> {
@@ -201,24 +206,22 @@ export class NearPriceFeedContract extends PriceFeedContract {
       methodName: "get_ema_price_unsafe",
       methodName: "get_ema_price_unsafe",
       args: { price_id: feedId },
       args: { price_id: feedId },
     });
     });
-    if (price === null || emaPrice === null) {
-      return undefined;
-    } else {
-      return {
-        price: {
-          price: price.price,
-          conf: price.conf,
-          expo: price.expo.toString(),
-          publishTime: price.publish_time.toString(),
-        },
-        emaPrice: {
-          price: emaPrice.price,
-          conf: emaPrice.conf,
-          expo: emaPrice.expo.toString(),
-          publishTime: emaPrice.publish_time.toString(),
-        },
-      };
-    }
+    return price === null || emaPrice === null
+      ? undefined
+      : {
+          price: {
+            price: price.price,
+            conf: price.conf,
+            expo: price.expo.toString(),
+            publishTime: price.publish_time.toString(),
+          },
+          emaPrice: {
+            price: emaPrice.price,
+            conf: emaPrice.conf,
+            expo: emaPrice.expo.toString(),
+            publishTime: emaPrice.publish_time.toString(),
+          },
+        };
   }
   }
 
 
   async executeUpdatePriceFeed(
   async executeUpdatePriceFeed(
@@ -244,14 +247,12 @@ export class NearPriceFeedContract extends PriceFeedContract {
       });
       });
       results.push({ id: outcome.transaction.hash, info: outcome });
       results.push({ id: outcome.transaction.hash, info: outcome });
     }
     }
-    if (results.length === 1) {
-      return results[0]!;
-    } else {
-      return {
-        id: results.map((x) => x.id).join(","),
-        info: results.map((x) => x.info),
-      };
-    }
+    return results.length === 1
+      ? results[0]!
+      : {
+          id: results.map((x) => x.id).join(","),
+          info: results.map((x) => x.info),
+        };
   }
   }
 
 
   async executeGovernanceInstruction(
   async executeGovernanceInstruction(

+ 23 - 14
contract_manager/src/core/contracts/starknet.ts

@@ -1,15 +1,24 @@
+/* eslint-disable unicorn/no-await-expression-member */
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+/* eslint-disable @typescript-eslint/no-unsafe-return */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+/* eslint-disable @typescript-eslint/no-unsafe-call */
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
+/* eslint-disable @typescript-eslint/no-base-to-string */
+import { ByteBuffer } from "@pythnetwork/pyth-starknet-js";
 import type { DataSource } from "@pythnetwork/xc-admin-common";
 import type { DataSource } from "@pythnetwork/xc-admin-common";
-import {
-  type KeyValueConfig,
-  type Price,
-  type PriceFeed,
-  PriceFeedContract,
-  type PrivateKey,
-  type TxResult,
+import { Account, Contract, shortString } from "starknet";
+
+import type {
+  KeyValueConfig,
+  Price,
+  PriceFeed,
+  PrivateKey,
+  TxResult,
 } from "../base";
 } from "../base";
+import { PriceFeedContract } from "../base";
 import { Chain, StarknetChain } from "../chains";
 import { Chain, StarknetChain } from "../chains";
-import { Account, Contract, shortString } from "starknet";
-import { ByteBuffer } from "@pythnetwork/pyth-starknet-js";
 import { WormholeContract } from "./wormhole";
 import { WormholeContract } from "./wormhole";
 
 
 export class StarknetWormholeContract extends WormholeContract {
 export class StarknetWormholeContract extends WormholeContract {
@@ -179,7 +188,7 @@ export class StarknetPriceFeedContract extends PriceFeedContract {
 
 
   /**
   /**
    * Returns the single update fee and symbol of the specified token.
    * Returns the single update fee and symbol of the specified token.
-   * @param token hex encoded token address without 0x prefix
+   * @param token - hex encoded token address without 0x prefix
    */
    */
   async getBaseUpdateFeeInToken(
   async getBaseUpdateFeeInToken(
     token: string,
     token: string,
@@ -203,13 +212,13 @@ export class StarknetPriceFeedContract extends PriceFeedContract {
   async getPriceFeed(feedId: string): Promise<PriceFeed | undefined> {
   async getPriceFeed(feedId: string): Promise<PriceFeed | undefined> {
     const contract = await this.getContractClient();
     const contract = await this.getContractClient();
     const result = await contract.query_price_feed_unsafe("0x" + feedId);
     const result = await contract.query_price_feed_unsafe("0x" + feedId);
-    if (result.Ok !== undefined) {
+    if (result.Ok === undefined) {
+      throw new Error(JSON.stringify(result.Err));
+    } else {
       return {
       return {
         price: convertPrice(result.Ok.price),
         price: convertPrice(result.Ok.price),
         emaPrice: convertPrice(result.Ok.ema_price),
         emaPrice: convertPrice(result.Ok.ema_price),
       };
       };
-    } else {
-      throw new Error(JSON.stringify(result.Err));
     }
     }
   }
   }
 
 
@@ -227,7 +236,7 @@ export class StarknetPriceFeedContract extends PriceFeedContract {
     );
     );
     contract.connect(account);
     contract.connect(account);
 
 
-    const feeToken = "0x" + (await this.getFeeTokenAddresses())[0];
+    const feeToken = `0x${(await this.getFeeTokenAddresses())[0]}`;
     const tokenClassData = await provider.getClassAt(feeToken);
     const tokenClassData = await provider.getClassAt(feeToken);
     const tokenContract = new Contract(tokenClassData.abi, feeToken, provider);
     const tokenContract = new Contract(tokenClassData.abi, feeToken, provider);
     tokenContract.connect(account);
     tokenContract.connect(account);

+ 37 - 37
contract_manager/src/core/contracts/sui.ts

@@ -1,12 +1,23 @@
-import { Chain, SuiChain } from "../chains";
-import type { DataSource } from "@pythnetwork/xc-admin-common";
-import { WormholeContract } from "./wormhole";
-import { PriceFeedContract, type PrivateKey, type TxResult } from "../base";
-import { SuiPythClient } from "@pythnetwork/pyth-sui-js";
-import { SUI_CLOCK_OBJECT_ID } from "@mysten/sui/utils";
+/* eslint-disable @typescript-eslint/no-unsafe-return */
+/* eslint-disable @typescript-eslint/no-unsafe-call */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+/* eslint-disable @typescript-eslint/no-non-null-assertion */
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
+/* eslint-disable @typescript-eslint/require-await */
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
+/* eslint-disable @typescript-eslint/no-base-to-string */
+import { uint8ArrayToBCS } from "@certusone/wormhole-sdk/lib/cjs/sui";
 import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
 import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
 import { Transaction } from "@mysten/sui/transactions";
 import { Transaction } from "@mysten/sui/transactions";
-import { uint8ArrayToBCS } from "@certusone/wormhole-sdk/lib/cjs/sui";
+import { SUI_CLOCK_OBJECT_ID } from "@mysten/sui/utils";
+import { SuiPythClient } from "@pythnetwork/pyth-sui-js";
+import type { DataSource } from "@pythnetwork/xc-admin-common";
+
+import type { PrivateKey, TxResult } from "../base";
+import { Chain, SuiChain } from "../chains";
+import { WormholeContract } from "./wormhole";
+import { PriceFeedContract } from "../base";
 
 
 type ObjectId = string;
 type ObjectId = string;
 
 
@@ -18,9 +29,9 @@ export class SuiPriceFeedContract extends PriceFeedContract {
    * Given the ids of the pyth state and wormhole state, create a new SuiPriceFeedContract
    * Given the ids of the pyth state and wormhole state, create a new SuiPriceFeedContract
    * The package ids are derived based on the state ids
    * The package ids are derived based on the state ids
    *
    *
-   * @param chain the chain which this contract is deployed on
-   * @param stateId id of the pyth state for the deployed contract
-   * @param wormholeStateId id of the wormhole state for the wormhole contract that pyth binds to
+   * @param chain - the chain which this contract is deployed on
+   * @param stateId - id of the pyth state for the deployed contract
+   * @param wormholeStateId - id of the wormhole state for the wormhole contract that pyth binds to
    */
    */
   constructor(
   constructor(
     public chain: SuiChain,
     public chain: SuiChain,
@@ -69,7 +80,7 @@ export class SuiPriceFeedContract extends PriceFeedContract {
 
 
   /**
   /**
    * Given a objectId, returns the id for the package that the object belongs to.
    * Given a objectId, returns the id for the package that the object belongs to.
-   * @param objectId
+   * @param objectId - the object id to get
    */
    */
   async getPackageId(objectId: ObjectId): Promise<ObjectId> {
   async getPackageId(objectId: ObjectId): Promise<ObjectId> {
     return this.client.getPackageId(objectId);
     return this.client.getPackageId(objectId);
@@ -111,12 +122,12 @@ export class SuiPriceFeedContract extends PriceFeedContract {
   async getPriceFeed(feedId: string) {
   async getPriceFeed(feedId: string) {
     const provider = this.getProvider();
     const provider = this.getProvider();
     const priceInfoObjectId = await this.client.getPriceFeedObjectId(feedId);
     const priceInfoObjectId = await this.client.getPriceFeedObjectId(feedId);
-    if (!priceInfoObjectId) return undefined;
+    if (!priceInfoObjectId) return;
     const priceInfo = await provider.getObject({
     const priceInfo = await provider.getObject({
       id: priceInfoObjectId,
       id: priceInfoObjectId,
       options: { showContent: true },
       options: { showContent: true },
     });
     });
-    if (!priceInfo.data || !priceInfo.data.content) {
+    if (!priceInfo.data?.content) {
       throw new Error(
       throw new Error(
         `Price feed ID ${priceInfoObjectId} in price table but object not found!!`,
         `Price feed ID ${priceInfoObjectId} in price table but object not found!!`,
       );
       );
@@ -144,8 +155,8 @@ export class SuiPriceFeedContract extends PriceFeedContract {
   /**
   /**
    * Given a signed VAA, execute the migration instruction on the pyth contract.
    * Given a signed VAA, execute the migration instruction on the pyth contract.
    * The payload of the VAA can be obtained from the `getUpgradePackagePayload` method.
    * The payload of the VAA can be obtained from the `getUpgradePackagePayload` method.
-   * @param vaa
-   * @param keypair used to sign the transaction
+   * @param vaa - the vaa payload
+   * @param keypair - used to sign the transaction
    */
    */
   async executeMigrateInstruction(vaa: Buffer, keypair: Ed25519Keypair) {
   async executeMigrateInstruction(vaa: Buffer, keypair: Ed25519Keypair) {
     const tx = new Transaction();
     const tx = new Transaction();
@@ -260,10 +271,9 @@ export class SuiPriceFeedContract extends PriceFeedContract {
   /**
   /**
    * Utility function to get the verification receipt object for a VAA that can be
    * Utility function to get the verification receipt object for a VAA that can be
    * used to authorize a governance instruction.
    * used to authorize a governance instruction.
-   * @param tx
-   * @param packageId pyth package id
-   * @param vaa
-   * @private
+   * @param tx - the transaction
+   * @param packageId - pyth package id
+   * @param vaa - the vaa payload
    */
    */
   async getVaaVerificationReceipt(
   async getVaaVerificationReceipt(
     tx: Transaction,
     tx: Transaction,
@@ -276,7 +286,7 @@ export class SuiPriceFeedContract extends PriceFeedContract {
       target: `${wormholePackageId}::vaa::parse_and_verify`,
       target: `${wormholePackageId}::vaa::parse_and_verify`,
       arguments: [
       arguments: [
         tx.object(this.wormholeStateId),
         tx.object(this.wormholeStateId),
-        tx.pure.arguments(Array.from(vaa)),
+        tx.pure.arguments([...vaa]),
         tx.object(SUI_CLOCK_OBJECT_ID),
         tx.object(SUI_CLOCK_OBJECT_ID),
       ],
       ],
     });
     });
@@ -291,9 +301,8 @@ export class SuiPriceFeedContract extends PriceFeedContract {
   /**
   /**
    * Given a transaction block and a keypair, sign and execute it
    * Given a transaction block and a keypair, sign and execute it
    * Sets the gas budget to 2x the estimated gas cost
    * Sets the gas budget to 2x the estimated gas cost
-   * @param tx
-   * @param keypair
-   * @private
+   * @param tx - the transaction
+   * @param keypair - the keypair
    */
    */
   private async executeTransaction(tx: Transaction, keypair: Ed25519Keypair) {
   private async executeTransaction(tx: Transaction, keypair: Ed25519Keypair) {
     const provider = this.getProvider();
     const provider = this.getProvider();
@@ -328,7 +337,7 @@ export class SuiPriceFeedContract extends PriceFeedContract {
         value: "data_sources",
         value: "data_sources",
       },
       },
     });
     });
-    if (!result.data || !result.data.content) {
+    if (!result.data?.content) {
       throw new Error(
       throw new Error(
         "Data Sources not found, contract may not be initialized",
         "Data Sources not found, contract may not be initialized",
       );
       );
@@ -395,11 +404,7 @@ export class SuiPriceFeedContract extends PriceFeedContract {
       id: this.stateId,
       id: this.stateId,
       options: { showContent: true },
       options: { showContent: true },
     });
     });
-    if (
-      !result.data ||
-      !result.data.content ||
-      result.data.content.dataType !== "moveObject"
-    )
+    if (!result.data?.content || result.data.content.dataType !== "moveObject")
       throw new Error("Unable to fetch pyth state object");
       throw new Error("Unable to fetch pyth state object");
     return result.data.content.fields;
     return result.data.content.fields;
   }
   }
@@ -532,11 +537,7 @@ export class SuiWormholeContract extends WormholeContract {
       id: this.stateId,
       id: this.stateId,
       options: { showContent: true },
       options: { showContent: true },
     });
     });
-    if (
-      !result.data ||
-      !result.data.content ||
-      result.data.content.dataType !== "moveObject"
-    )
+    if (!result.data?.content || result.data.content.dataType !== "moveObject")
       throw new Error("Unable to fetch pyth state object");
       throw new Error("Unable to fetch pyth state object");
     return result.data.content.fields;
     return result.data.content.fields;
   }
   }
@@ -544,9 +545,8 @@ export class SuiWormholeContract extends WormholeContract {
   /**
   /**
    * Given a transaction block and a keypair, sign and execute it
    * Given a transaction block and a keypair, sign and execute it
    * Sets the gas budget to 2x the estimated gas cost
    * Sets the gas budget to 2x the estimated gas cost
-   * @param tx
-   * @param keypair
-   * @private
+   * @param tx - the transaction
+   * @param keypair - the keypair
    */
    */
   private async executeTransaction(tx: Transaction, keypair: Ed25519Keypair) {
   private async executeTransaction(tx: Transaction, keypair: Ed25519Keypair) {
     const provider = this.chain.getProvider();
     const provider = this.chain.getProvider();

+ 6 - 4
contract_manager/src/core/contracts/wormhole.ts

@@ -1,4 +1,5 @@
-import { type PrivateKey, Storable, type TxResult } from "../base";
+import type { PrivateKey, TxResult } from "../base";
+import { Storable } from "../base";
 
 
 export abstract class WormholeContract extends Storable {
 export abstract class WormholeContract extends Storable {
   abstract getCurrentGuardianSetIndex(): Promise<number>;
   abstract getCurrentGuardianSetIndex(): Promise<number>;
@@ -16,8 +17,8 @@ export abstract class WormholeContract extends Storable {
 
 
   /**
   /**
    * Upgrades the guardian set of this contract using an upgrade VAA
    * Upgrades the guardian set of this contract using an upgrade VAA
-   * @param senderPrivateKey
-   * @param vaa
+   * @param senderPrivateKey - the sender private key
+   * @param vaa - the vaa payload
    */
    */
   abstract upgradeGuardianSets(
   abstract upgradeGuardianSets(
     senderPrivateKey: PrivateKey,
     senderPrivateKey: PrivateKey,
@@ -26,7 +27,7 @@ export abstract class WormholeContract extends Storable {
 
 
   /**
   /**
    * Upgrades the guardian set of this contract with the 3 pre-configured VAAs for mainnet assuming this is a mainnet contract
    * Upgrades the guardian set of this contract with the 3 pre-configured VAAs for mainnet assuming this is a mainnet contract
-   * @param senderPrivateKey
+   * @param senderPrivateKey - the sender private key
    */
    */
   async syncMainnetGuardianSets(senderPrivateKey: PrivateKey) {
   async syncMainnetGuardianSets(senderPrivateKey: PrivateKey) {
     const MAINNET_UPGRADE_VAAS = [
     const MAINNET_UPGRADE_VAAS = [
@@ -42,6 +43,7 @@ export abstract class WormholeContract extends Storable {
         senderPrivateKey,
         senderPrivateKey,
         Buffer.from(vaa, "hex"),
         Buffer.from(vaa, "hex"),
       );
       );
+      // eslint-disable-next-line no-console, @typescript-eslint/restrict-template-expressions
       console.log(`Submitted upgrade VAA ${i} with tx id ${result.id}`);
       console.log(`Submitted upgrade VAA ${i} with tx id ${result.id}`);
       // make sure the upgrade is complete before continuing
       // make sure the upgrade is complete before continuing
       while ((await this.getCurrentGuardianSetIndex()) <= i) {
       while ((await this.getCurrentGuardianSetIndex()) <= i) {

+ 8 - 3
contract_manager/src/core/token.ts

@@ -1,5 +1,10 @@
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
 import axios from "axios";
 import axios from "axios";
-import { type KeyValueConfig, Storable } from "./base";
+
+import type { KeyValueConfig } from "./base";
+import { Storable } from "./base";
 
 
 export type TokenId = string;
 export type TokenId = string;
 /**
 /**
@@ -48,7 +53,7 @@ export class Token extends Storable {
 
 
       // Note that this conversion can lose some precision.
       // Note that this conversion can lose some precision.
       // We don't really care about that in this application.
       // We don't really care about that in this application.
-      return parseInt(price.price) * Math.pow(10, price.expo);
+      return Number.parseInt(price.price) * Math.pow(10, price.expo);
     } else {
     } else {
       // We may support other pricing methodologies in the future but whatever.
       // We may support other pricing methodologies in the future but whatever.
       return undefined;
       return undefined;
@@ -67,7 +72,7 @@ export class Token extends Storable {
   toJson(): KeyValueConfig {
   toJson(): KeyValueConfig {
     return {
     return {
       id: this.id,
       id: this.id,
-      ...(this.pythId !== undefined ? { pythId: this.pythId } : {}),
+      ...(this.pythId === undefined ? {} : { pythId: this.pythId }),
     };
     };
   }
   }
 
 

+ 7 - 5
contract_manager/src/node/utils/executor.ts

@@ -1,9 +1,11 @@
+/* eslint-disable no-console */
 import { parseVaa } from "@certusone/wormhole-sdk";
 import { parseVaa } from "@certusone/wormhole-sdk";
+import type { DataSource } from "@pythnetwork/xc-admin-common";
 import {
 import {
-  type DataSource,
   EvmExecute,
   EvmExecute,
   decodeGovernancePayload,
   decodeGovernancePayload,
 } from "@pythnetwork/xc-admin-common";
 } from "@pythnetwork/xc-admin-common";
+
 import { DefaultStore } from "./store.js";
 import { DefaultStore } from "./store.js";
 import type { PrivateKey, TxResult } from "../../core/base.js";
 import type { PrivateKey, TxResult } from "../../core/base.js";
 import { EvmChain } from "../../core/chains.js";
 import { EvmChain } from "../../core/chains.js";
@@ -11,7 +13,7 @@ import { EvmExecutorContract } from "../../core/contracts/evm.js";
 
 
 // TODO: A better place for this would be `base.ts`. That will require
 // TODO: A better place for this would be `base.ts`. That will require
 // significant refactor. Todo in separate PR.
 // significant refactor. Todo in separate PR.
-interface GovernanceContract {
+type GovernanceContract = {
   getId(): string;
   getId(): string;
   getGovernanceDataSource(): Promise<DataSource>;
   getGovernanceDataSource(): Promise<DataSource>;
   getLastExecutedGovernanceSequence(): Promise<number>;
   getLastExecutedGovernanceSequence(): Promise<number>;
@@ -19,7 +21,7 @@ interface GovernanceContract {
     senderPrivateKey: PrivateKey,
     senderPrivateKey: PrivateKey,
     vaa: Buffer,
     vaa: Buffer,
   ): Promise<TxResult>;
   ): Promise<TxResult>;
-}
+};
 
 
 async function executeForGovernanceContract(
 async function executeForGovernanceContract(
   contract: GovernanceContract,
   contract: GovernanceContract,
@@ -51,8 +53,8 @@ async function executeForGovernanceContract(
 
 
 /**
 /**
  * A general executor that tries to find any contract that can execute a given VAA and executes it
  * A general executor that tries to find any contract that can execute a given VAA and executes it
- * @param senderPrivateKey the private key to execute the governance instruction with
- * @param vaa the VAA to execute
+ * @param senderPrivateKey - the private key to execute the governance instruction with
+ * @param vaa - src/node/utils/executor.tsthe VAA to execute
  */
  */
 export async function executeVaa(senderPrivateKey: PrivateKey, vaa: Buffer) {
 export async function executeVaa(senderPrivateKey: PrivateKey, vaa: Buffer) {
   const parsedVaa = parseVaa(vaa);
   const parsedVaa = parseVaa(vaa);

+ 62 - 45
contract_manager/src/node/utils/governance.ts

@@ -1,38 +1,49 @@
-import { readFileSync } from "fs";
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
+/* eslint-disable @typescript-eslint/no-explicit-any */
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+/* eslint-disable @typescript-eslint/no-unsafe-return */
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
+import { readFileSync } from "node:fs";
 
 
+import {
+  createWormholeProgramInterface,
+  deriveEmitterSequenceKey,
+  deriveFeeCollectorKey,
+  deriveWormholeBridgeDataKey,
+} from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole/index.js";
+import { AnchorProvider, Wallet } from "@coral-xyz/anchor";
+import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet.js";
+import type { PythCluster } from "@pythnetwork/client";
+import { getPythClusterApiUrl } from "@pythnetwork/client";
+import type { PriorityFeeConfig } from "@pythnetwork/solana-utils";
+import {
+  executeProposal,
+  MultisigVault,
+  WORMHOLE_ADDRESS,
+  WORMHOLE_API_ENDPOINT,
+} from "@pythnetwork/xc-admin-common";
+import type {
+  ParsedInstruction,
+  PartiallyDecodedInstruction,
+} from "@solana/web3.js";
 import {
 import {
   Connection,
   Connection,
   Keypair,
   Keypair,
-  type ParsedInstruction,
-  type PartiallyDecodedInstruction,
   PublicKey,
   PublicKey,
   SystemProgram,
   SystemProgram,
   SYSVAR_CLOCK_PUBKEY,
   SYSVAR_CLOCK_PUBKEY,
   SYSVAR_RENT_PUBKEY,
   SYSVAR_RENT_PUBKEY,
   Transaction,
   Transaction,
 } from "@solana/web3.js";
 } from "@solana/web3.js";
-import * as bs58 from "bs58";
-import { getPythClusterApiUrl, type PythCluster } from "@pythnetwork/client";
-import { AnchorProvider, Wallet } from "@coral-xyz/anchor";
-import {
-  executeProposal,
-  MultisigVault,
-  WORMHOLE_ADDRESS,
-  WORMHOLE_API_ENDPOINT,
-} from "@pythnetwork/xc-admin-common";
-import { type KeyValueConfig, Storable } from "../../core/base.js";
-import type { PriorityFeeConfig } from "@pythnetwork/solana-utils";
 import SquadsMesh from "@sqds/mesh";
 import SquadsMesh from "@sqds/mesh";
+import * as bs58 from "bs58";
+
+import type { KeyValueConfig } from "../../core/base.js";
+import { Storable } from "../../core/base.js";
+
 // TODO: this should be migrated to @wormhole-foundation/dsk
 // TODO: this should be migrated to @wormhole-foundation/dsk
 // as such, we cannot publish an ESM variant of the contract_manager
 // as such, we cannot publish an ESM variant of the contract_manager
 // until we upgrade
 // until we upgrade
-import {
-  createWormholeProgramInterface,
-  deriveEmitterSequenceKey,
-  deriveFeeCollectorKey,
-  deriveWormholeBridgeDataKey,
-} from "@certusone/wormhole-sdk/lib/cjs/solana/wormhole/index.js";
-import NodeWallet from "@coral-xyz/anchor/dist/cjs/nodewallet.js";
 
 
 class InvalidTransactionError extends Error {
 class InvalidTransactionError extends Error {
   constructor(message: string) {
   constructor(message: string) {
@@ -55,9 +66,9 @@ export class SubmittedWormholeMessage {
    * Attempts to find the emitter and sequence number of a wormhole message from a transaction
    * Attempts to find the emitter and sequence number of a wormhole message from a transaction
    * Parses the transaction and looks for the wormhole postMessage instruction to find the emitter
    * Parses the transaction and looks for the wormhole postMessage instruction to find the emitter
    * Inspects the transaction logs to find the sequence number
    * Inspects the transaction logs to find the sequence number
-   * @param signature signature of the transaction to inspect
-   * @param cluster the cluster the transaction was submitted to
-   * @param registry registry of RPC nodes to use for each solana network. Defaults to the Solana public RPCs if not provided.
+   * @param signature - signature of the transaction to inspect
+   * @param cluster - the cluster the transaction was submitted to
+   * @param registry - registry of RPC nodes to use for each solana network. Defaults to the Solana public RPCs if not provided.
    */
    */
   static async fromTransactionSignature(
   static async fromTransactionSignature(
     signature: string,
     signature: string,
@@ -73,8 +84,11 @@ export class SubmittedWormholeMessage {
     );
     );
 
 
     const sequenceNumber = Number(
     const sequenceNumber = Number(
-      txLog?.substring(
-        txLog.indexOf(sequenceLogPrefix) + sequenceLogPrefix.length,
+      txLog?.slice(
+        Math.max(
+          0,
+          txLog.indexOf(sequenceLogPrefix) + sequenceLogPrefix.length,
+        ),
       ),
       ),
     );
     );
 
 
@@ -83,17 +97,18 @@ export class SubmittedWormholeMessage {
     let emitter: PublicKey | undefined = undefined;
     let emitter: PublicKey | undefined = undefined;
 
 
     let allInstructions: (ParsedInstruction | PartiallyDecodedInstruction)[] =
     let allInstructions: (ParsedInstruction | PartiallyDecodedInstruction)[] =
-      txDetails?.transaction?.message?.instructions || [];
-    txDetails?.meta?.innerInstructions?.forEach((instruction) => {
-      allInstructions = allInstructions.concat(instruction.instructions);
-    });
-    allInstructions.forEach((instruction) => {
-      if (!instruction.programId.equals(wormholeAddress)) return;
+      txDetails?.transaction.message.instructions ?? [];
+    if (txDetails?.meta?.innerInstructions)
+      for (const instruction of txDetails.meta.innerInstructions) {
+        allInstructions = [...allInstructions, ...instruction.instructions];
+      }
+    for (const instruction of allInstructions) {
+      if (!instruction.programId.equals(wormholeAddress)) continue;
       // we assume RPC can not parse wormhole instructions and the type is not ParsedInstruction
       // we assume RPC can not parse wormhole instructions and the type is not ParsedInstruction
       const wormholeInstruction = instruction as PartiallyDecodedInstruction;
       const wormholeInstruction = instruction as PartiallyDecodedInstruction;
-      if (bs58.decode(wormholeInstruction.data)[0] !== 1) return; // 1 is wormhole postMessage Instruction discriminator
+      if (bs58.decode(wormholeInstruction.data)[0] !== 1) continue; // 1 is wormhole postMessage Instruction discriminator
       emitter = wormholeInstruction.accounts[2];
       emitter = wormholeInstruction.accounts[2];
-    });
+    }
     if (!emitter)
     if (!emitter)
       throw new InvalidTransactionError(
       throw new InvalidTransactionError(
         "Could not find wormhole postMessage instruction",
         "Could not find wormhole postMessage instruction",
@@ -104,7 +119,7 @@ export class SubmittedWormholeMessage {
   /**
   /**
    * Tries to fetch the VAA from the wormhole bridge API waiting for a certain amount of time
    * Tries to fetch the VAA from the wormhole bridge API waiting for a certain amount of time
    * before giving up and throwing an error
    * before giving up and throwing an error
-   * @param waitingSeconds how long to wait before giving up
+   * @param waitingSeconds - how long to wait before giving up
    */
    */
   async fetchVaa(waitingSeconds = 1): Promise<Buffer> {
   async fetchVaa(waitingSeconds = 1): Promise<Buffer> {
     const rpcUrl = WORMHOLE_API_ENDPOINT[this.cluster];
     const rpcUrl = WORMHOLE_API_ENDPOINT[this.cluster];
@@ -156,8 +171,8 @@ export class WormholeEmitter {
 
 
   /**
   /**
    * Send a wormhole message containing payload through wormhole.
    * Send a wormhole message containing payload through wormhole.
-   * @param payload the contents of the message
-   * @param registry registry of RPC nodes to use for each solana network. Defaults to the Solana public RPCs if not provided.
+   * @param payload - the contents of the message
+   * @param registry - registry of RPC nodes to use for each solana network. Defaults to the Solana public RPCs if not provided.
    */
    */
   async sendMessage(
   async sendMessage(
     payload: Buffer,
     payload: Buffer,
@@ -252,8 +267,8 @@ export class WormholeMultisigProposal {
             this.cluster,
             this.cluster,
           ),
           ),
         );
         );
-      } catch (e) {
-        if (!(e instanceof InvalidTransactionError)) throw e;
+      } catch (error) {
+        if (!(error instanceof InvalidTransactionError)) throw error;
       }
       }
     }
     }
     if (msgs.length > 0) return msgs;
     if (msgs.length > 0) return msgs;
@@ -305,8 +320,8 @@ export class Vault extends Storable {
   /**
   /**
    * Connects the vault to a wallet that can be used to submit proposals
    * Connects the vault to a wallet that can be used to submit proposals
    * The wallet should be a multisig signer of the vault
    * The wallet should be a multisig signer of the vault
-   * @param wallet
-   * @param registry registry of RPC nodes to use for each solana network. Defaults to the Solana public RPCs if not provided.
+   * @param wallet - the wallet
+   * @param registry - registry of RPC nodes to use for each solana network. Defaults to the Solana public RPCs if not provided.
    */
    */
   public connect(
   public connect(
     wallet: Wallet,
     wallet: Wallet,
@@ -322,8 +337,9 @@ export class Vault extends Storable {
 
 
   /**
   /**
    * Gets the emitter address of the vault
    * Gets the emitter address of the vault
-   * @param registry registry of RPC nodes to use for each solana network. Defaults to the Solana public RPCs if not provided.
+   * @param registry - registry of RPC nodes to use for each solana network. Defaults to the Solana public RPCs if not provided.
    */
    */
+  // eslint-disable-next-line @typescript-eslint/require-await
   public async getEmitter(registry: SolanaRpcRegistry = getPythClusterApiUrl) {
   public async getEmitter(registry: SolanaRpcRegistry = getPythClusterApiUrl) {
     const squad = SquadsMesh.endpoint(
     const squad = SquadsMesh.endpoint(
       registry(this.cluster),
       registry(this.cluster),
@@ -352,8 +368,8 @@ export class Vault extends Storable {
    * Proposes sending an array of wormhole messages to the wormhole bridge
    * Proposes sending an array of wormhole messages to the wormhole bridge
    * Requires a wallet to be connected to the vault
    * Requires a wallet to be connected to the vault
    *
    *
-   * @param payloads the payloads to send to the wormhole bridge
-   * @param proposalAddress if specified, will continue an existing proposal
+   * @param payloads - the payloads to send to the wormhole bridge
+   * @param proposalAddress - if specified, will continue an existing proposal
    */
    */
   public async proposeWormholeMessage(
   public async proposeWormholeMessage(
     payloads: Buffer[],
     payloads: Buffer[],
@@ -381,8 +397,9 @@ export class Vault extends Storable {
 /**
 /**
  * Loads a solana wallet from a file. The file should contain the secret key in array of integers format
  * Loads a solana wallet from a file. The file should contain the secret key in array of integers format
  * This wallet can be used to connect to a vault and submit proposals
  * This wallet can be used to connect to a vault and submit proposals
- * @param walletPath path to the wallet file
+ * @param walletPath - - path to the wallet file
  */
  */
+// eslint-disable-next-line @typescript-eslint/require-await
 export async function loadHotWallet(walletPath: string): Promise<Wallet> {
 export async function loadHotWallet(walletPath: string): Promise<Wallet> {
   return new NodeWallet(
   return new NodeWallet(
     Keypair.fromSecretKey(
     Keypair.fromSecretKey(

+ 33 - 23
contract_manager/src/node/utils/store.ts

@@ -1,3 +1,16 @@
+/* eslint-disable no-empty */
+/* eslint-disable tsdoc/syntax */
+/* eslint-disable unicorn/no-array-for-each */
+/* eslint-disable unicorn/no-array-push-push */
+/* eslint-disable @typescript-eslint/no-non-null-assertion */
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
+/* eslint-disable @typescript-eslint/restrict-template-expressions */
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+import { readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
+
+import { Vault } from "./governance";
+import { PriceFeedContract, Storable } from "../../core/base";
 import {
 import {
   AptosChain,
   AptosChain,
   Chain,
   Chain,
@@ -32,18 +45,15 @@ import {
   EvmExecutorContract,
   EvmExecutorContract,
   EvmLazerContract,
   EvmLazerContract,
 } from "../../core/contracts";
 } from "../../core/contracts";
-import { Token } from "../../core/token";
-import { PriceFeedContract, Storable } from "../../core/base";
-import { readdirSync, readFileSync, statSync, writeFileSync } from "fs";
-import { Vault } from "./governance";
-import {
-  StarknetPriceFeedContract,
-  StarknetWormholeContract,
-} from "../../core/contracts/starknet";
 import {
 import {
   NearPriceFeedContract,
   NearPriceFeedContract,
   NearWormholeContract,
   NearWormholeContract,
 } from "../../core/contracts/near";
 } from "../../core/contracts/near";
+import {
+  StarknetPriceFeedContract,
+  StarknetWormholeContract,
+} from "../../core/contracts/starknet";
+import { Token } from "../../core/token";
 
 
 export class Store {
 export class Store {
   public chains: Record<string, Chain> = { global: new GlobalChain() };
   public chains: Record<string, Chain> = { global: new GlobalChain() };
@@ -64,24 +74,24 @@ export class Store {
   }
   }
 
 
   static serialize(obj: Storable) {
   static serialize(obj: Storable) {
-    return JSON.stringify([obj.toJson()], null, 2);
+    return JSON.stringify([obj.toJson()], undefined, 2);
   }
   }
 
 
   getJsonFiles(path: string) {
   getJsonFiles(path: string) {
     const walk = function (dir: string) {
     const walk = function (dir: string) {
       let results: string[] = [];
       let results: string[] = [];
       const list = readdirSync(dir);
       const list = readdirSync(dir);
-      list.forEach(function (file) {
+      for (let file of list) {
         file = dir + "/" + file;
         file = dir + "/" + file;
         const stat = statSync(file);
         const stat = statSync(file);
-        if (stat && stat.isDirectory()) {
+        if (stat.isDirectory()) {
           // Recurse into a subdirectory
           // Recurse into a subdirectory
-          results = results.concat(walk(file));
+          results = [...results, ...walk(file)];
         } else {
         } else {
           // Is a file
           // Is a file
           results.push(file);
           results.push(file);
         }
         }
-      });
+      }
       return results;
       return results;
     };
     };
     return walk(path).filter((file) => file.endsWith(".json"));
     return walk(path).filter((file) => file.endsWith(".json"));
@@ -101,8 +111,8 @@ export class Store {
       [IotaChain.type]: IotaChain,
       [IotaChain.type]: IotaChain,
     };
     };
 
 
-    this.getJsonFiles(`${this.path}/chains/`).forEach((jsonFile) => {
-      const parsedArray = JSON.parse(readFileSync(jsonFile, "utf-8"));
+    for (const jsonFile of this.getJsonFiles(`${this.path}/chains/`)) {
+      const parsedArray = JSON.parse(readFileSync(jsonFile, "utf8"));
       for (const parsed of parsedArray) {
       for (const parsed of parsedArray) {
         if (allChainClasses[parsed.type] === undefined) {
         if (allChainClasses[parsed.type] === undefined) {
           throw new Error(
           throw new Error(
@@ -116,7 +126,7 @@ export class Store {
         }
         }
         this.chains[id] = chain!;
         this.chains[id] = chain!;
       }
       }
-    });
+    }
   }
   }
 
 
   saveAllContracts() {
   saveAllContracts() {
@@ -137,7 +147,7 @@ export class Store {
         `${this.path}/contracts/${type}s.json`,
         `${this.path}/contracts/${type}s.json`,
         JSON.stringify(
         JSON.stringify(
           contracts.map((c) => c.toJson()),
           contracts.map((c) => c.toJson()),
-          null,
+          undefined,
           2,
           2,
         ),
         ),
       );
       );
@@ -157,7 +167,7 @@ export class Store {
         `${this.path}/chains/${type}s.json`,
         `${this.path}/chains/${type}s.json`,
         JSON.stringify(
         JSON.stringify(
           chains.map((c) => c.toJson()),
           chains.map((c) => c.toJson()),
-          null,
+          undefined,
           2,
           2,
         ),
         ),
       );
       );
@@ -189,7 +199,7 @@ export class Store {
       [EvmLazerContract.type]: EvmLazerContract,
       [EvmLazerContract.type]: EvmLazerContract,
     };
     };
     this.getJsonFiles(`${this.path}/contracts/`).forEach((jsonFile) => {
     this.getJsonFiles(`${this.path}/contracts/`).forEach((jsonFile) => {
-      const parsedArray = JSON.parse(readFileSync(jsonFile, "utf-8"));
+      const parsedArray = JSON.parse(readFileSync(jsonFile, "utf8"));
       for (const parsed of parsedArray) {
       for (const parsed of parsedArray) {
         if (allContractClasses[parsed.type] === undefined) return;
         if (allContractClasses[parsed.type] === undefined) return;
         if (!this.chains[parsed.chain])
         if (!this.chains[parsed.chain])
@@ -226,7 +236,7 @@ export class Store {
 
 
   loadAllTokens() {
   loadAllTokens() {
     this.getJsonFiles(`${this.path}/tokens/`).forEach((jsonFile) => {
     this.getJsonFiles(`${this.path}/tokens/`).forEach((jsonFile) => {
-      const parsedArray = JSON.parse(readFileSync(jsonFile, "utf-8"));
+      const parsedArray = JSON.parse(readFileSync(jsonFile, "utf8"));
       for (const parsed of parsedArray) {
       for (const parsed of parsedArray) {
         if (parsed.type !== Token.type) return;
         if (parsed.type !== Token.type) return;
 
 
@@ -240,7 +250,7 @@ export class Store {
 
 
   loadAllVaults() {
   loadAllVaults() {
     this.getJsonFiles(`${this.path}/vaults/`).forEach((jsonFile) => {
     this.getJsonFiles(`${this.path}/vaults/`).forEach((jsonFile) => {
-      const parsedArray = JSON.parse(readFileSync(jsonFile, "utf-8"));
+      const parsedArray = JSON.parse(readFileSync(jsonFile, "utf8"));
       for (const parsed of parsedArray) {
       for (const parsed of parsedArray) {
         if (parsed.type !== Vault.type) return;
         if (parsed.type !== Vault.type) return;
 
 
@@ -254,8 +264,8 @@ export class Store {
 
 
   /**
   /**
    * Returns the chain with the given ID, or throws an error if it doesn't exist or is not of the specified type.
    * Returns the chain with the given ID, or throws an error if it doesn't exist or is not of the specified type.
-   * @param chainId The unique identifier of the chain to retrieve
-   * @param ChainClass Optional class to validate the chain type.
+   * @param chainId - The unique identifier of the chain to retrieve
+   * @param ChainClass - Optional class to validate the chain type.
    * @returns The chain instance of type T
    * @returns The chain instance of type T
    * @throws Error if chain doesn't exist or is not of the specified type
    * @throws Error if chain doesn't exist or is not of the specified type
    * @template T Type of chain to return, extends base Chain class
    * @template T Type of chain to return, extends base Chain class

+ 5 - 3
contract_manager/src/utils/utils.ts

@@ -1,7 +1,8 @@
+import * as chains from "viem/chains";
+
 import evmChainsData from "../store/chains/EvmChains.json" with { type: "json" };
 import evmChainsData from "../store/chains/EvmChains.json" with { type: "json" };
 import evmPriceFeedContractsData from "../store/contracts/EvmPriceFeedContracts.json" with { type: "json" };
 import evmPriceFeedContractsData from "../store/contracts/EvmPriceFeedContracts.json" with { type: "json" };
 import evmWormholeContractsData from "../store/contracts/EvmWormholeContracts.json" with { type: "json" };
 import evmWormholeContractsData from "../store/contracts/EvmWormholeContracts.json" with { type: "json" };
-import * as chains from "viem/chains";
 
 
 export const allEvmChainIds: number[] = evmChainsData.map((c) => c.networkId);
 export const allEvmChainIds: number[] = evmChainsData.map((c) => c.networkId);
 
 
@@ -29,7 +30,7 @@ const getContractAddress = (
     if (contract?.address === undefined) {
     if (contract?.address === undefined) {
       return undefined;
       return undefined;
     } else if (isZeroXString(contract.address)) {
     } else if (isZeroXString(contract.address)) {
-      return contract.address as `0x${string}`;
+      return contract.address;
     } else {
     } else {
       throw new Error(
       throw new Error(
         `Invariant failed: invalid contract address ${contract.address} for chain ${contract.chain}`,
         `Invariant failed: invalid contract address ${contract.address} for chain ${contract.chain}`,
@@ -50,7 +51,8 @@ export const getEvmChainRpcUrl = (chainId: number): string | undefined => {
       (c) => "id" in c && c.id === Number.parseInt(chain.id, 10),
       (c) => "id" in c && c.id === Number.parseInt(chain.id, 10),
     );
     );
     if (viemChain && "rpcUrls" in viemChain) {
     if (viemChain && "rpcUrls" in viemChain) {
-      return viemChain?.rpcUrls.default.http[0] ?? chain.rpcUrl;
+      // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+      return viemChain.rpcUrls.default.http[0] ?? chain.rpcUrl;
     }
     }
     return;
     return;
   }
   }

+ 4 - 0
governance/pyth_staking_sdk/src/utils/transaction.ts

@@ -1,3 +1,7 @@
+/* eslint-disable @typescript-eslint/no-unsafe-call */
+/* eslint-disable @typescript-eslint/no-unsafe-assignment */
+/* eslint-disable @typescript-eslint/no-unsafe-member-access */
+/* eslint-disable @typescript-eslint/no-unsafe-argument */
 import { TransactionBuilder } from "@pythnetwork/solana-utils";
 import { TransactionBuilder } from "@pythnetwork/solana-utils";
 import { Connection, TransactionInstruction } from "@solana/web3.js";
 import { Connection, TransactionInstruction } from "@solana/web3.js";
 
 

+ 4 - 1
governance/xc_admin/packages/xc_admin_common/src/message_buffer.ts

@@ -1,4 +1,7 @@
-import { getPythProgramKeyForCluster, type PythCluster } from "@pythnetwork/client";
+import {
+  getPythProgramKeyForCluster,
+  type PythCluster,
+} from "@pythnetwork/client";
 import { PublicKey } from "@solana/web3.js";
 import { PublicKey } from "@solana/web3.js";
 
 
 /**
 /**

+ 4 - 1
governance/xc_admin/packages/xc_admin_common/src/multisig.ts

@@ -4,7 +4,10 @@ import Squads, {
   getIxPDA,
   getIxPDA,
   getTxPDA,
   getTxPDA,
 } from "@sqds/mesh";
 } from "@sqds/mesh";
-import { type InstructionAccount, type TransactionAccount } from "@sqds/mesh/lib/types";
+import {
+  type InstructionAccount,
+  type TransactionAccount,
+} from "@sqds/mesh/lib/types";
 import BN from "bn.js";
 import BN from "bn.js";
 import lodash from "lodash";
 import lodash from "lodash";
 
 

Some files were not shown because too many files changed in this diff