@pythnetwork/price-pusher 8.3.3 → 9.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/README.md +1 -2
  2. package/lib/aptos/aptos.d.ts +3 -3
  3. package/lib/aptos/aptos.d.ts.map +1 -1
  4. package/lib/aptos/aptos.js +8 -7
  5. package/lib/aptos/command.d.ts +1 -2
  6. package/lib/aptos/command.d.ts.map +1 -1
  7. package/lib/aptos/command.js +16 -10
  8. package/lib/evm/command.d.ts +0 -1
  9. package/lib/evm/command.d.ts.map +1 -1
  10. package/lib/evm/command.js +18 -10
  11. package/lib/evm/evm.d.ts +3 -3
  12. package/lib/evm/evm.d.ts.map +1 -1
  13. package/lib/evm/evm.js +13 -9
  14. package/lib/fuel/command.d.ts +0 -1
  15. package/lib/fuel/command.d.ts.map +1 -1
  16. package/lib/fuel/command.js +15 -9
  17. package/lib/fuel/fuel.d.ts +3 -3
  18. package/lib/fuel/fuel.d.ts.map +1 -1
  19. package/lib/fuel/fuel.js +8 -5
  20. package/lib/injective/command.d.ts +1 -2
  21. package/lib/injective/command.d.ts.map +1 -1
  22. package/lib/injective/command.js +16 -10
  23. package/lib/injective/injective.d.ts +3 -3
  24. package/lib/injective/injective.d.ts.map +1 -1
  25. package/lib/injective/injective.js +7 -4
  26. package/lib/interface.d.ts +1 -1
  27. package/lib/interface.d.ts.map +1 -1
  28. package/lib/near/command.d.ts +1 -2
  29. package/lib/near/command.d.ts.map +1 -1
  30. package/lib/near/command.js +16 -10
  31. package/lib/near/near.d.ts +3 -3
  32. package/lib/near/near.d.ts.map +1 -1
  33. package/lib/near/near.js +7 -5
  34. package/lib/options.d.ts +0 -3
  35. package/lib/options.d.ts.map +1 -1
  36. package/lib/options.js +2 -11
  37. package/lib/price-config.d.ts +1 -1
  38. package/lib/price-config.d.ts.map +1 -1
  39. package/lib/pyth-price-listener.d.ts +4 -5
  40. package/lib/pyth-price-listener.d.ts.map +1 -1
  41. package/lib/pyth-price-listener.js +30 -85
  42. package/lib/solana/command.d.ts +3 -2
  43. package/lib/solana/command.d.ts.map +1 -1
  44. package/lib/solana/command.js +39 -15
  45. package/lib/solana/solana.d.ts +8 -5
  46. package/lib/solana/solana.d.ts.map +1 -1
  47. package/lib/solana/solana.js +20 -10
  48. package/lib/sui/command.d.ts +0 -1
  49. package/lib/sui/command.d.ts.map +1 -1
  50. package/lib/sui/command.js +16 -13
  51. package/lib/sui/sui.d.ts +4 -4
  52. package/lib/sui/sui.d.ts.map +1 -1
  53. package/lib/sui/sui.js +11 -9
  54. package/lib/ton/command.d.ts +0 -1
  55. package/lib/ton/command.d.ts.map +1 -1
  56. package/lib/ton/command.js +15 -9
  57. package/lib/ton/ton.d.ts +3 -3
  58. package/lib/ton/ton.d.ts.map +1 -1
  59. package/lib/ton/ton.js +7 -4
  60. package/lib/utils.d.ts +6 -1
  61. package/lib/utils.d.ts.map +1 -1
  62. package/lib/utils.js +16 -0
  63. package/package.json +5 -6
package/README.md CHANGED
@@ -203,8 +203,7 @@ human-readable logs, you can pipe the output of the program to `pino-pretty`. Se
203
203
 
204
204
  You can configure the log level of some of the modules of the price pusher as well. The available modules are PriceServiceConnection, which
205
205
  is responsible for connecting to the Hermes price service, and Controller, which is responsible for checking the prices from the Hermes
206
- and the on-chain Pyth contract and deciding whether to push a new price. You can configure the log level of these modules by passing the
207
- `--price-service-connection-log-level` and `--controller-log-level` arguments, respectively.
206
+ and the on-chain Pyth contract and deciding whether to push a new price. You can configure the log level of these modules by passing the `--controller-log-level` arguments, respectively.
208
207
 
209
208
  ### Example
210
209
 
@@ -1,6 +1,6 @@
1
1
  import { ChainPriceListener, IPricePusher, PriceInfo, PriceItem } from "../interface";
2
2
  import { DurationInSeconds } from "../utils";
3
- import { PriceServiceConnection } from "@pythnetwork/price-service-client";
3
+ import { HermesClient } from "@pythnetwork/hermes-client";
4
4
  import { Logger } from "pino";
5
5
  export declare class AptosPriceListener extends ChainPriceListener {
6
6
  private pythModule;
@@ -23,7 +23,7 @@ export declare const APTOS_ACCOUNT_HD_PATH = "m/44'/637'/0'/0'/0'";
23
23
  * land all of their pushed updates on-chain.
24
24
  */
25
25
  export declare class AptosPricePusher implements IPricePusher {
26
- private priceServiceConnection;
26
+ private hermesClient;
27
27
  private logger;
28
28
  private pythContractAddress;
29
29
  private endpoint;
@@ -31,7 +31,7 @@ export declare class AptosPricePusher implements IPricePusher {
31
31
  private overrideGasPriceMultiplier;
32
32
  private lastSequenceNumber;
33
33
  private sequenceNumberLocked;
34
- constructor(priceServiceConnection: PriceServiceConnection, logger: Logger, pythContractAddress: string, endpoint: string, mnemonic: string, overrideGasPriceMultiplier: number);
34
+ constructor(hermesClient: HermesClient, logger: Logger, pythContractAddress: string, endpoint: string, mnemonic: string, overrideGasPriceMultiplier: number);
35
35
  /**
36
36
  * Gets price update data which then can be submitted to the Pyth contract to update the prices.
37
37
  * 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)
@@ -1 +1 @@
1
- {"version":3,"file":"aptos.d.ts","sourceRoot":"","sources":["../../src/aptos/aptos.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACT,SAAS,EACV,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAE9B,qBAAa,kBAAmB,SAAQ,kBAAkB;IAEtD,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,QAAQ;IAEhB,OAAO,CAAC,MAAM;gBAHN,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EACxB,UAAU,EAAE,SAAS,EAAE,EACf,MAAM,EAAE,MAAM,EACtB,MAAM,EAAE;QACN,gBAAgB,EAAE,iBAAiB,CAAC;KACrC;IAKG,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;CA6C3E;AAGD,eAAO,MAAM,qBAAqB,wBAAwB,CAAC;AAE3D;;;;;;;;;GASG;AACH,qBAAa,gBAAiB,YAAW,YAAY;IAOjD,OAAO,CAAC,sBAAsB;IAC9B,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,0BAA0B;IAVpC,OAAO,CAAC,kBAAkB,CAAqB;IAE/C,OAAO,CAAC,oBAAoB,CAAU;gBAG5B,sBAAsB,EAAE,sBAAsB,EAC9C,MAAM,EAAE,MAAM,EACd,mBAAmB,EAAE,MAAM,EAC3B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,0BAA0B,EAAE,MAAM;IAK5C;;;;;;OAMG;IACG,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IAQhE,eAAe,CACnB,QAAQ,EAAE,MAAM,EAAE,EAClB,cAAc,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC;YA+DF,8BAA8B;YAwB9B,wBAAwB;CA+BvC"}
1
+ {"version":3,"file":"aptos.d.ts","sourceRoot":"","sources":["../../src/aptos/aptos.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACT,SAAS,EACV,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAE9B,qBAAa,kBAAmB,SAAQ,kBAAkB;IAEtD,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,QAAQ;IAEhB,OAAO,CAAC,MAAM;gBAHN,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EACxB,UAAU,EAAE,SAAS,EAAE,EACf,MAAM,EAAE,MAAM,EACtB,MAAM,EAAE;QACN,gBAAgB,EAAE,iBAAiB,CAAC;KACrC;IAKG,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;CA6C3E;AAGD,eAAO,MAAM,qBAAqB,wBAAwB,CAAC;AAE3D;;;;;;;;;GASG;AACH,qBAAa,gBAAiB,YAAW,YAAY;IAOjD,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,0BAA0B;IAVpC,OAAO,CAAC,kBAAkB,CAAqB;IAE/C,OAAO,CAAC,oBAAoB,CAAU;gBAG5B,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,MAAM,EACd,mBAAmB,EAAE,MAAM,EAC3B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,0BAA0B,EAAE,MAAM;IAK5C;;;;;;OAMG;IACG,uBAAuB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IAShE,eAAe,CACnB,QAAQ,EAAE,MAAM,EAAE,EAClB,cAAc,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC;YA+DF,8BAA8B;YAwB9B,wBAAwB;CA+BvC"}
@@ -56,7 +56,7 @@ exports.APTOS_ACCOUNT_HD_PATH = "m/44'/637'/0'/0'/0'";
56
56
  * land all of their pushed updates on-chain.
57
57
  */
58
58
  class AptosPricePusher {
59
- priceServiceConnection;
59
+ hermesClient;
60
60
  logger;
61
61
  pythContractAddress;
62
62
  endpoint;
@@ -66,8 +66,8 @@ class AptosPricePusher {
66
66
  lastSequenceNumber;
67
67
  // If true, we are trying to fetch the most recent sequence number from the blockchain.
68
68
  sequenceNumberLocked;
69
- constructor(priceServiceConnection, logger, pythContractAddress, endpoint, mnemonic, overrideGasPriceMultiplier) {
70
- this.priceServiceConnection = priceServiceConnection;
69
+ constructor(hermesClient, logger, pythContractAddress, endpoint, mnemonic, overrideGasPriceMultiplier) {
70
+ this.hermesClient = hermesClient;
71
71
  this.logger = logger;
72
72
  this.pythContractAddress = pythContractAddress;
73
73
  this.endpoint = endpoint;
@@ -83,9 +83,10 @@ class AptosPricePusher {
83
83
  * @returns Array of price update data.
84
84
  */
85
85
  async getPriceFeedsUpdateData(priceIds) {
86
- // Fetch the latest price feed update VAAs from the price service
87
- const latestVaas = await this.priceServiceConnection.getLatestVaas(priceIds);
88
- return latestVaas.map((vaa) => Array.from(Buffer.from(vaa, "base64")));
86
+ const response = await this.hermesClient.getLatestPriceUpdates(priceIds, {
87
+ encoding: "base64",
88
+ });
89
+ return response.binary.data.map((data) => Array.from(Buffer.from(data, "base64")));
89
90
  }
90
91
  async updatePriceFeed(priceIds, pubTimesToPush) {
91
92
  if (priceIds.length === 0) {
@@ -164,7 +165,7 @@ class AptosPricePusher {
164
165
  return this.lastSequenceNumber;
165
166
  }
166
167
  catch (e) {
167
- throw new Error("Failed to retrieve sequence number");
168
+ throw new Error("Failed to retrieve sequence number" + e);
168
169
  }
169
170
  finally {
170
171
  this.sequenceNumberLocked = false;
@@ -4,7 +4,6 @@ declare const _default: {
4
4
  describe: string;
5
5
  builder: {
6
6
  "controller-log-level": Options;
7
- "price-service-connection-log-level": Options;
8
7
  "log-level": Options;
9
8
  "pushing-frequency": Options;
10
9
  "polling-frequency": Options;
@@ -15,7 +14,7 @@ declare const _default: {
15
14
  endpoint: Options;
16
15
  "override-gas-price-multiplier": Options;
17
16
  };
18
- handler: (argv: any) => void;
17
+ handler: (argv: any) => Promise<void>;
19
18
  };
20
19
  export default _default;
21
20
  //# sourceMappingURL=command.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/aptos/command.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;;;;;;;;;;;;;;kBAoBvB,OAAO;yCAOP,OAAO;;oBAWW,GAAG;;AA7B9B,wBAqGE"}
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/aptos/command.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;;;;;;;;;;;;;kBAoBvB,OAAO;yCAOP,OAAO;;oBAUiB,GAAG;;AA5BpC,wBAyGE"}
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- const price_service_client_1 = require("@pythnetwork/price-service-client");
29
+ const hermes_client_1 = require("@pythnetwork/hermes-client");
30
30
  const options = __importStar(require("../options"));
31
31
  const price_config_1 = require("../price-config");
32
32
  const fs_1 = __importDefault(require("fs"));
@@ -35,6 +35,7 @@ const controller_1 = require("../controller");
35
35
  const aptos_1 = require("./aptos");
36
36
  const aptos_2 = require("aptos");
37
37
  const pino_1 = __importDefault(require("pino"));
38
+ const utils_1 = require("../utils");
38
39
  exports.default = {
39
40
  command: "aptos",
40
41
  describe: "run price pusher for aptos",
@@ -59,24 +60,29 @@ exports.default = {
59
60
  ...options.pollingFrequency,
60
61
  ...options.pushingFrequency,
61
62
  ...options.logLevel,
62
- ...options.priceServiceConnectionLogLevel,
63
63
  ...options.controllerLogLevel,
64
64
  },
65
- handler: function (argv) {
65
+ handler: async function (argv) {
66
66
  // FIXME: type checks for this
67
- const { endpoint, priceConfigFile, priceServiceEndpoint, mnemonicFile, pythContractAddress, pushingFrequency, pollingFrequency, overrideGasPriceMultiplier, logLevel, priceServiceConnectionLogLevel, controllerLogLevel, } = argv;
67
+ const { endpoint, priceConfigFile, priceServiceEndpoint, mnemonicFile, pythContractAddress, pushingFrequency, pollingFrequency, overrideGasPriceMultiplier, logLevel, controllerLogLevel, } = argv;
68
68
  const logger = (0, pino_1.default)({ level: logLevel });
69
69
  const priceConfigs = (0, price_config_1.readPriceConfigFile)(priceConfigFile);
70
- const priceServiceConnection = new price_service_client_1.PriceServiceConnection(priceServiceEndpoint, {
71
- logger: logger.child({ module: "PriceServiceConnection" }, { level: priceServiceConnectionLogLevel }),
72
- });
70
+ const hermesClient = new hermes_client_1.HermesClient(priceServiceEndpoint);
73
71
  const mnemonic = fs_1.default.readFileSync(mnemonicFile, "utf-8").trim();
74
72
  const account = aptos_2.AptosAccount.fromDerivePath(aptos_1.APTOS_ACCOUNT_HD_PATH, mnemonic);
75
73
  logger.info(`Pushing from account address: ${account.address()}`);
76
- const priceItems = priceConfigs.map(({ id, alias }) => ({ id, alias }));
77
- const pythListener = new pyth_price_listener_1.PythPriceListener(priceServiceConnection, priceItems, logger.child({ module: "PythPriceListener" }));
74
+ let priceItems = priceConfigs.map(({ id, alias }) => ({ id, alias }));
75
+ // Better to filter out invalid price items before creating the pyth listener
76
+ const { existingPriceItems, invalidPriceItems } = await (0, utils_1.filterInvalidPriceItems)(hermesClient, priceItems);
77
+ if (invalidPriceItems.length > 0) {
78
+ logger.error(`Invalid price id submitted for: ${invalidPriceItems
79
+ .map(({ alias }) => alias)
80
+ .join(", ")}`);
81
+ }
82
+ priceItems = existingPriceItems;
83
+ const pythListener = new pyth_price_listener_1.PythPriceListener(hermesClient, priceItems, logger.child({ module: "PythPriceListener" }));
78
84
  const aptosListener = new aptos_1.AptosPriceListener(pythContractAddress, endpoint, priceItems, logger.child({ module: "AptosPriceListener" }), { pollingFrequency });
79
- const aptosPusher = new aptos_1.AptosPricePusher(priceServiceConnection, logger.child({ module: "AptosPricePusher" }), pythContractAddress, endpoint, mnemonic, overrideGasPriceMultiplier);
85
+ const aptosPusher = new aptos_1.AptosPricePusher(hermesClient, logger.child({ module: "AptosPricePusher" }), pythContractAddress, endpoint, mnemonic, overrideGasPriceMultiplier);
80
86
  const controller = new controller_1.Controller(priceConfigs, pythListener, aptosListener, aptosPusher, logger.child({ module: "Controller" }, { level: controllerLogLevel }), { pushingFrequency });
81
87
  controller.start();
82
88
  },
@@ -4,7 +4,6 @@ declare const _default: {
4
4
  describe: string;
5
5
  builder: {
6
6
  "controller-log-level": Options;
7
- "price-service-connection-log-level": Options;
8
7
  "log-level": Options;
9
8
  "pushing-frequency": Options;
10
9
  "polling-frequency": Options;
@@ -1 +1 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/evm/command.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;;;;;;;;;;;;;;kBAyBvB,OAAO;8BAMP,OAAO;oBAMP,OAAO;yCAUP,OAAO;6CAQP,OAAO;qBAKP,OAAO;iCASP,OAAO;;oBAWiB,GAAG;;AApEpC,wBAkKE"}
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/evm/command.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;;;;;;;;;;;;;kBAyBvB,OAAO;8BAMP,OAAO;oBAMP,OAAO;yCAUP,OAAO;6CAQP,OAAO;qBAKP,OAAO;iCASP,OAAO;;oBAUiB,GAAG;;AAnEpC,wBAyKE"}
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- const price_service_client_1 = require("@pythnetwork/price-service-client");
29
+ const hermes_client_1 = require("@pythnetwork/hermes-client");
30
30
  const fs_1 = __importDefault(require("fs"));
31
31
  const options = __importStar(require("../options"));
32
32
  const price_config_1 = require("../price-config");
@@ -97,20 +97,28 @@ exports.default = {
97
97
  ...options.pollingFrequency,
98
98
  ...options.pushingFrequency,
99
99
  ...options.logLevel,
100
- ...options.priceServiceConnectionLogLevel,
101
100
  ...options.controllerLogLevel,
102
101
  },
103
102
  handler: async function (argv) {
104
103
  // FIXME: type checks for this
105
- const { endpoint, priceConfigFile, priceServiceEndpoint, mnemonicFile, pythContractAddress, pushingFrequency, pollingFrequency, customGasStation, txSpeed, overrideGasPriceMultiplier, overrideGasPriceMultiplierCap, gasLimit, updateFeeMultiplier, logLevel, priceServiceConnectionLogLevel, controllerLogLevel, } = argv;
106
- const logger = (0, pino_1.default)({ level: logLevel });
107
- const priceConfigs = (0, price_config_1.readPriceConfigFile)(priceConfigFile);
108
- const priceServiceConnection = new price_service_client_1.PriceServiceConnection(priceServiceEndpoint, {
109
- logger: logger.child({ module: "PriceServiceConnection" }, { level: priceServiceConnectionLogLevel }),
104
+ const { endpoint, priceConfigFile, priceServiceEndpoint, mnemonicFile, pythContractAddress, pushingFrequency, pollingFrequency, customGasStation, txSpeed, overrideGasPriceMultiplier, overrideGasPriceMultiplierCap, gasLimit, updateFeeMultiplier, logLevel, controllerLogLevel, } = argv;
105
+ console.log("***** priceServiceEndpoint *****", priceServiceEndpoint);
106
+ const logger = (0, pino_1.default)({
107
+ level: logLevel,
110
108
  });
109
+ const priceConfigs = (0, price_config_1.readPriceConfigFile)(priceConfigFile);
110
+ const hermesClient = new hermes_client_1.HermesClient(priceServiceEndpoint);
111
111
  const mnemonic = fs_1.default.readFileSync(mnemonicFile, "utf-8").trim();
112
- const priceItems = priceConfigs.map(({ id, alias }) => ({ id, alias }));
113
- const pythListener = new pyth_price_listener_1.PythPriceListener(priceServiceConnection, priceItems, logger.child({ module: "PythPriceListener" }));
112
+ let priceItems = priceConfigs.map(({ id, alias }) => ({ id, alias }));
113
+ // Better to filter out invalid price items before creating the pyth listener
114
+ const { existingPriceItems, invalidPriceItems } = await (0, utils_1.filterInvalidPriceItems)(hermesClient, priceItems);
115
+ if (invalidPriceItems.length > 0) {
116
+ logger.error(`Invalid price id submitted for: ${invalidPriceItems
117
+ .map(({ alias }) => alias)
118
+ .join(", ")}`);
119
+ }
120
+ priceItems = existingPriceItems;
121
+ const pythListener = new pyth_price_listener_1.PythPriceListener(hermesClient, priceItems, logger.child({ module: "PythPriceListener" }));
114
122
  const client = await (0, super_wallet_1.createClient)(endpoint, mnemonic);
115
123
  const pythContract = (0, pyth_contract_1.createPythContract)(client, pythContractAddress);
116
124
  logger.info(`Pushing updates from wallet address: ${client.account.address}`);
@@ -122,7 +130,7 @@ exports.default = {
122
130
  pollingFrequency,
123
131
  });
124
132
  const gasStation = (0, custom_gas_station_1.getCustomGasStation)(logger.child({ module: "CustomGasStation" }), customGasStation, txSpeed);
125
- const evmPusher = new evm_1.EvmPricePusher(priceServiceConnection, client, pythContract, logger.child({ module: "EvmPricePusher" }), overrideGasPriceMultiplier, overrideGasPriceMultiplierCap, updateFeeMultiplier, gasLimit, gasStation);
133
+ const evmPusher = new evm_1.EvmPricePusher(hermesClient, client, pythContract, logger.child({ module: "EvmPricePusher" }), overrideGasPriceMultiplier, overrideGasPriceMultiplierCap, updateFeeMultiplier, gasLimit, gasStation);
126
134
  const controller = new controller_1.Controller(priceConfigs, pythListener, evmListener, evmPusher, logger.child({ module: "Controller" }, { level: controllerLogLevel }), { pushingFrequency });
127
135
  controller.start();
128
136
  },
package/lib/evm/evm.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { IPricePusher, PriceInfo, ChainPriceListener, PriceItem } from "../interface";
2
2
  import { DurationInSeconds } from "../utils";
3
3
  import { Logger } from "pino";
4
- import { PriceServiceConnection, HexString, UnixTimestamp } from "@pythnetwork/price-service-client";
4
+ import { HermesClient, HexString, UnixTimestamp } from "@pythnetwork/hermes-client";
5
5
  import { CustomGasStation } from "./custom-gas-station";
6
6
  import { PythContract } from "./pyth-contract";
7
7
  import { SuperWalletClient } from "./super-wallet";
@@ -18,7 +18,7 @@ export declare class EvmPriceListener extends ChainPriceListener {
18
18
  getOnChainPriceInfo(priceId: HexString): Promise<PriceInfo | undefined>;
19
19
  }
20
20
  export declare class EvmPricePusher implements IPricePusher {
21
- private connection;
21
+ private hermesClient;
22
22
  private client;
23
23
  private pythContract;
24
24
  private logger;
@@ -29,7 +29,7 @@ export declare class EvmPricePusher implements IPricePusher {
29
29
  private customGasStation?;
30
30
  private pusherAddress;
31
31
  private lastPushAttempt;
32
- constructor(connection: PriceServiceConnection, client: SuperWalletClient, pythContract: PythContract, logger: Logger, overrideGasPriceMultiplier: number, overrideGasPriceMultiplierCap: number, updateFeeMultiplier: number, gasLimit?: number | undefined, customGasStation?: CustomGasStation | undefined);
32
+ constructor(hermesClient: HermesClient, client: SuperWalletClient, pythContract: PythContract, logger: Logger, overrideGasPriceMultiplier: number, overrideGasPriceMultiplierCap: number, updateFeeMultiplier: number, gasLimit?: number | undefined, customGasStation?: CustomGasStation | undefined);
33
33
  updatePriceFeed(priceIds: string[], pubTimesToPush: UnixTimestamp[]): Promise<void>;
34
34
  private waitForTransactionReceipt;
35
35
  private getPriceFeedsUpdateData;
@@ -1 +1 @@
1
- {"version":3,"file":"evm.d.ts","sourceRoot":"","sources":["../../src/evm/evm.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,SAAS,EACT,kBAAkB,EAClB,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAGL,iBAAiB,EAElB,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAC9B,OAAO,EACL,sBAAsB,EACtB,SAAS,EACT,aAAa,EACd,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAaxD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,qBAAa,gBAAiB,SAAQ,kBAAkB;IAEpD,OAAO,CAAC,YAAY;IAEpB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,MAAM;gBAHN,YAAY,EAAE,YAAY,EAClC,UAAU,EAAE,SAAS,EAAE,EACf,WAAW,EAAE,OAAO,EACpB,MAAM,EAAE,MAAM,EACtB,MAAM,EAAE;QACN,gBAAgB,EAAE,iBAAiB,CAAC;KACrC;IAUG,KAAK;YAeG,aAAa;IAO3B,OAAO,CAAC,iBAAiB;IAuBnB,mBAAmB,CACvB,OAAO,EAAE,SAAS,GACjB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;CAuBlC;AAED,qBAAa,cAAe,YAAW,YAAY;IAK/C,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,0BAA0B;IAClC,OAAO,CAAC,6BAA6B;IACrC,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,QAAQ,CAAC;IACjB,OAAO,CAAC,gBAAgB,CAAC;IAZ3B,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,eAAe,CAA0B;gBAGvC,UAAU,EAAE,sBAAsB,EAClC,MAAM,EAAE,iBAAiB,EACzB,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,MAAM,EACd,0BAA0B,EAAE,MAAM,EAClC,6BAA6B,EAAE,MAAM,EACrC,mBAAmB,EAAE,MAAM,EAC3B,QAAQ,CAAC,EAAE,MAAM,YAAA,EACjB,gBAAgB,CAAC,EAAE,gBAAgB,YAAA;IASvC,eAAe,CACnB,QAAQ,EAAE,MAAM,EAAE,EAClB,cAAc,EAAE,aAAa,EAAE,GAC9B,OAAO,CAAC,IAAI,CAAC;YA2OF,yBAAyB;YAuBzB,uBAAuB;CAQtC"}
1
+ {"version":3,"file":"evm.d.ts","sourceRoot":"","sources":["../../src/evm/evm.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,SAAS,EACT,kBAAkB,EAClB,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAGL,iBAAiB,EAElB,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAC9B,OAAO,EACL,YAAY,EACZ,SAAS,EACT,aAAa,EACd,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAaxD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,qBAAa,gBAAiB,SAAQ,kBAAkB;IAEpD,OAAO,CAAC,YAAY;IAEpB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,MAAM;gBAHN,YAAY,EAAE,YAAY,EAClC,UAAU,EAAE,SAAS,EAAE,EACf,WAAW,EAAE,OAAO,EACpB,MAAM,EAAE,MAAM,EACtB,MAAM,EAAE;QACN,gBAAgB,EAAE,iBAAiB,CAAC;KACrC;IAUG,KAAK;YAeG,aAAa;IAO3B,OAAO,CAAC,iBAAiB;IAuBnB,mBAAmB,CACvB,OAAO,EAAE,SAAS,GACjB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;CAuBlC;AAED,qBAAa,cAAe,YAAW,YAAY;IAK/C,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,0BAA0B;IAClC,OAAO,CAAC,6BAA6B;IACrC,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,QAAQ,CAAC;IACjB,OAAO,CAAC,gBAAgB,CAAC;IAZ3B,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,eAAe,CAA0B;gBAGvC,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,iBAAiB,EACzB,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,MAAM,EACd,0BAA0B,EAAE,MAAM,EAClC,6BAA6B,EAAE,MAAM,EACrC,mBAAmB,EAAE,MAAM,EAC3B,QAAQ,CAAC,EAAE,MAAM,YAAA,EACjB,gBAAgB,CAAC,EAAE,gBAAgB,YAAA;IASvC,eAAe,CACnB,QAAQ,EAAE,MAAM,EAAE,EAClB,cAAc,EAAE,aAAa,EAAE,GAC9B,OAAO,CAAC,IAAI,CAAC;YA+OF,yBAAyB;YAuBzB,uBAAuB;CAStC"}
package/lib/evm/evm.js CHANGED
@@ -66,7 +66,7 @@ class EvmPriceListener extends interface_1.ChainPriceListener {
66
66
  }
67
67
  exports.EvmPriceListener = EvmPriceListener;
68
68
  class EvmPricePusher {
69
- connection;
69
+ hermesClient;
70
70
  client;
71
71
  pythContract;
72
72
  logger;
@@ -77,8 +77,8 @@ class EvmPricePusher {
77
77
  customGasStation;
78
78
  pusherAddress;
79
79
  lastPushAttempt;
80
- constructor(connection, client, pythContract, logger, overrideGasPriceMultiplier, overrideGasPriceMultiplierCap, updateFeeMultiplier, gasLimit, customGasStation) {
81
- this.connection = connection;
80
+ constructor(hermesClient, client, pythContract, logger, overrideGasPriceMultiplier, overrideGasPriceMultiplierCap, updateFeeMultiplier, gasLimit, customGasStation) {
81
+ this.hermesClient = hermesClient;
82
82
  this.client = client;
83
83
  this.pythContract = pythContract;
84
84
  this.logger = logger;
@@ -100,12 +100,12 @@ class EvmPricePusher {
100
100
  }
101
101
  if (priceIds.length !== pubTimesToPush.length)
102
102
  throw new Error("Invalid arguments");
103
- const priceIdsWith0x = priceIds.map((priceId) => (0, utils_1.addLeading0x)(priceId));
104
- const priceFeedUpdateData = (await this.getPriceFeedsUpdateData(priceIdsWith0x));
103
+ const priceFeedUpdateData = (await this.getPriceFeedsUpdateData(priceIds));
104
+ const priceFeedUpdateDataWith0x = priceFeedUpdateData.map((data) => (0, utils_1.addLeading0x)(data));
105
105
  let updateFee;
106
106
  try {
107
107
  updateFee = await this.pythContract.read.getUpdateFee([
108
- priceFeedUpdateData,
108
+ priceFeedUpdateDataWith0x,
109
109
  ]);
110
110
  updateFee = BigInt(Math.round(Number(updateFee) * (this.updateFeeMultiplier || 1)));
111
111
  this.logger.debug(`Update fee: ${updateFee}`);
@@ -144,8 +144,9 @@ class EvmPricePusher {
144
144
  const txNonce = lastExecutedNonce + 1;
145
145
  this.logger.debug(`Using gas price: ${gasPrice} and nonce: ${txNonce}`);
146
146
  const pubTimesToPushParam = pubTimesToPush.map((pubTime) => BigInt(pubTime));
147
+ const priceIdsWith0x = priceIds.map((priceId) => (0, utils_1.addLeading0x)(priceId));
147
148
  try {
148
- const { request } = await this.pythContract.simulate.updatePriceFeedsIfNecessary([priceFeedUpdateData, priceIdsWith0x, pubTimesToPushParam], {
149
+ const { request } = await this.pythContract.simulate.updatePriceFeedsIfNecessary([priceFeedUpdateDataWith0x, priceIdsWith0x, pubTimesToPushParam], {
149
150
  value: updateFee,
150
151
  gasPrice: BigInt(Math.ceil(gasPrice)),
151
152
  nonce: txNonce,
@@ -256,8 +257,11 @@ class EvmPricePusher {
256
257
  }
257
258
  }
258
259
  async getPriceFeedsUpdateData(priceIds) {
259
- const latestVaas = await this.connection.getLatestVaas(priceIds);
260
- return latestVaas.map((vaa) => "0x" + Buffer.from(vaa, "base64").toString("hex"));
260
+ const response = await this.hermesClient.getLatestPriceUpdates(priceIds, {
261
+ encoding: "hex",
262
+ ignoreInvalidPriceIds: true,
263
+ });
264
+ return response.binary.data;
261
265
  }
262
266
  }
263
267
  exports.EvmPricePusher = EvmPricePusher;
@@ -4,7 +4,6 @@ declare const _default: {
4
4
  describe: string;
5
5
  builder: {
6
6
  "controller-log-level": Options;
7
- "price-service-connection-log-level": Options;
8
7
  "log-level": Options;
9
8
  "polling-frequency": Options;
10
9
  "pushing-frequency": Options;
@@ -1 +1 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/fuel/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;;;;;;;;;;;;kBAmBvB,OAAO;4BAKP,OAAO;iCAKP,OAAO;;oBASiB,GAAG;;AA3BpC,wBA6FE"}
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/fuel/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;;;;;;;;;;;kBAmBvB,OAAO;4BAKP,OAAO;iCAKP,OAAO;;oBAQiB,GAAG;;AA1BpC,wBAiGE"}
@@ -28,13 +28,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  const options = __importStar(require("../options"));
30
30
  const price_config_1 = require("../price-config");
31
- const price_service_client_1 = require("@pythnetwork/price-service-client");
31
+ const hermes_client_1 = require("@pythnetwork/hermes-client");
32
32
  const pyth_price_listener_1 = require("../pyth-price-listener");
33
33
  const fuel_1 = require("./fuel");
34
34
  const controller_1 = require("../controller");
35
35
  const fuels_1 = require("fuels");
36
36
  const fs_1 = __importDefault(require("fs"));
37
37
  const pino_1 = __importDefault(require("pino"));
38
+ const utils_1 = require("../utils");
38
39
  exports.default = {
39
40
  command: "fuel",
40
41
  describe: "run price pusher for Fuel",
@@ -59,23 +60,28 @@ exports.default = {
59
60
  ...options.pushingFrequency,
60
61
  ...options.pollingFrequency,
61
62
  ...options.logLevel,
62
- ...options.priceServiceConnectionLogLevel,
63
63
  ...options.controllerLogLevel,
64
64
  },
65
65
  handler: async function (argv) {
66
- const { endpoint, privateKeyFile, pythContractAddress, priceConfigFile, priceServiceEndpoint, pushingFrequency, pollingFrequency, logLevel, priceServiceConnectionLogLevel, controllerLogLevel, } = argv;
66
+ const { endpoint, privateKeyFile, pythContractAddress, priceConfigFile, priceServiceEndpoint, pushingFrequency, pollingFrequency, logLevel, controllerLogLevel, } = argv;
67
67
  const logger = (0, pino_1.default)({ level: logLevel });
68
68
  const priceConfigs = (0, price_config_1.readPriceConfigFile)(priceConfigFile);
69
- const priceServiceConnection = new price_service_client_1.PriceServiceConnection(priceServiceEndpoint, {
70
- logger: logger.child({ module: "PriceServiceConnection" }, { level: priceServiceConnectionLogLevel }),
71
- });
72
- const priceItems = priceConfigs.map(({ id, alias }) => ({ id, alias }));
73
- const pythListener = new pyth_price_listener_1.PythPriceListener(priceServiceConnection, priceItems, logger.child({ module: "PythPriceListener" }));
69
+ const hermesClient = new hermes_client_1.HermesClient(priceServiceEndpoint);
70
+ let priceItems = priceConfigs.map(({ id, alias }) => ({ id, alias }));
71
+ // Better to filter out invalid price items before creating the pyth listener
72
+ const { existingPriceItems, invalidPriceItems } = await (0, utils_1.filterInvalidPriceItems)(hermesClient, priceItems);
73
+ if (invalidPriceItems.length > 0) {
74
+ logger.error(`Invalid price id submitted for: ${invalidPriceItems
75
+ .map(({ alias }) => alias)
76
+ .join(", ")}`);
77
+ }
78
+ priceItems = existingPriceItems;
79
+ const pythListener = new pyth_price_listener_1.PythPriceListener(hermesClient, priceItems, logger.child({ module: "PythPriceListener" }));
74
80
  const provider = await fuels_1.Provider.create(endpoint);
75
81
  const privateKey = fs_1.default.readFileSync(privateKeyFile, "utf8").trim();
76
82
  const wallet = fuels_1.Wallet.fromPrivateKey(privateKey, provider);
77
83
  const fuelPriceListener = new fuel_1.FuelPriceListener(provider, pythContractAddress, priceItems, logger.child({ module: "FuelPriceListener" }), { pollingFrequency });
78
- const fuelPricePusher = new fuel_1.FuelPricePusher(wallet, pythContractAddress, priceServiceConnection, logger.child({ module: "FuelPricePusher" }));
84
+ const fuelPricePusher = new fuel_1.FuelPricePusher(wallet, pythContractAddress, hermesClient, logger.child({ module: "FuelPricePusher" }));
79
85
  const controller = new controller_1.Controller(priceConfigs, pythListener, fuelPriceListener, fuelPricePusher, logger.child({ module: "Controller" }, { level: controllerLogLevel }), { pushingFrequency });
80
86
  await controller.start();
81
87
  },
@@ -1,4 +1,4 @@
1
- import { PriceServiceConnection } from "@pythnetwork/price-service-client";
1
+ import { HermesClient } from "@pythnetwork/hermes-client";
2
2
  import { ChainPriceListener, IPricePusher, PriceInfo, PriceItem } from "../interface";
3
3
  import { DurationInSeconds } from "../utils";
4
4
  import { Logger } from "pino";
@@ -16,10 +16,10 @@ export declare class FuelPriceListener extends ChainPriceListener {
16
16
  export declare class FuelPricePusher implements IPricePusher {
17
17
  private wallet;
18
18
  private pythContractId;
19
- private priceServiceConnection;
19
+ private hermesClient;
20
20
  private logger;
21
21
  private contract;
22
- constructor(wallet: Wallet, pythContractId: string, priceServiceConnection: PriceServiceConnection, logger: Logger);
22
+ constructor(wallet: Wallet, pythContractId: string, hermesClient: HermesClient, logger: Logger);
23
23
  updatePriceFeed(priceIds: string[], pubTimesToPush: number[]): Promise<void>;
24
24
  }
25
25
  //# sourceMappingURL=fuel.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fuel.d.ts","sourceRoot":"","sources":["../../src/fuel/fuel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACT,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAgB,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAC9B,OAAO,EAAE,QAAQ,EAA+B,MAAM,EAAM,MAAM,OAAO,CAAC;AAc1E,qBAAa,iBAAkB,SAAQ,kBAAkB;IAIrD,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,cAAc;IAEtB,OAAO,CAAC,MAAM;IANhB,OAAO,CAAC,QAAQ,CAAW;gBAGjB,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAE,MAAM,EAC9B,UAAU,EAAE,SAAS,EAAE,EACf,MAAM,EAAE,MAAM,EACtB,MAAM,EAAE;QACN,gBAAgB,EAAE,iBAAiB,CAAC;KACrC;IAUG,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;CA6B3E;AAED,qBAAa,eAAgB,YAAW,YAAY;IAIhD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,sBAAsB;IAC9B,OAAO,CAAC,MAAM;IANhB,OAAO,CAAC,QAAQ,CAAW;gBAGjB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EACtB,sBAAsB,EAAE,sBAAsB,EAC9C,MAAM,EAAE,MAAM;IASlB,eAAe,CACnB,QAAQ,EAAE,MAAM,EAAE,EAElB,cAAc,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC;CAuCjB"}
1
+ {"version":3,"file":"fuel.d.ts","sourceRoot":"","sources":["../../src/fuel/fuel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,SAAS,EACT,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAgB,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAC9B,OAAO,EAAE,QAAQ,EAA+B,MAAM,EAAM,MAAM,OAAO,CAAC;AAc1E,qBAAa,iBAAkB,SAAQ,kBAAkB;IAIrD,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,cAAc;IAEtB,OAAO,CAAC,MAAM;IANhB,OAAO,CAAC,QAAQ,CAAW;gBAGjB,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAE,MAAM,EAC9B,UAAU,EAAE,SAAS,EAAE,EACf,MAAM,EAAE,MAAM,EACtB,MAAM,EAAE;QACN,gBAAgB,EAAE,iBAAiB,CAAC;KACrC;IAUG,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;CA6B3E;AAED,qBAAa,eAAgB,YAAW,YAAY;IAIhD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,cAAc;IACtB,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,MAAM;IANhB,OAAO,CAAC,QAAQ,CAAW;gBAGjB,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,MAAM;IASlB,eAAe,CACnB,QAAQ,EAAE,MAAM,EAAE,EAElB,cAAc,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC;CAsCjB"}
package/lib/fuel/fuel.js CHANGED
@@ -52,13 +52,13 @@ exports.FuelPriceListener = FuelPriceListener;
52
52
  class FuelPricePusher {
53
53
  wallet;
54
54
  pythContractId;
55
- priceServiceConnection;
55
+ hermesClient;
56
56
  logger;
57
57
  contract;
58
- constructor(wallet, pythContractId, priceServiceConnection, logger) {
58
+ constructor(wallet, pythContractId, hermesClient, logger) {
59
59
  this.wallet = wallet;
60
60
  this.pythContractId = pythContractId;
61
- this.priceServiceConnection = priceServiceConnection;
61
+ this.hermesClient = hermesClient;
62
62
  this.logger = logger;
63
63
  this.contract = new fuels_1.Contract(this.pythContractId, pyth_fuel_js_1.PYTH_CONTRACT_ABI, this.wallet);
64
64
  }
@@ -70,13 +70,16 @@ class FuelPricePusher {
70
70
  }
71
71
  let priceFeedUpdateData;
72
72
  try {
73
- priceFeedUpdateData = await this.priceServiceConnection.getLatestVaas(priceIds);
73
+ const response = await this.hermesClient.getLatestPriceUpdates(priceIds, {
74
+ encoding: "base64",
75
+ });
76
+ priceFeedUpdateData = response.binary.data;
74
77
  }
75
78
  catch (err) {
76
79
  this.logger.error(err, "getPriceFeedsUpdateData failed");
77
80
  return;
78
81
  }
79
- const updateData = priceFeedUpdateData.map((data) => (0, fuels_1.arrayify)(Buffer.from(data, "base64")));
82
+ const updateData = priceFeedUpdateData.map((data) => (0, fuels_1.arrayify)(data));
80
83
  try {
81
84
  const updateFee = await this.contract.functions
82
85
  .update_fee(updateData)
@@ -4,7 +4,6 @@ declare const _default: {
4
4
  describe: string;
5
5
  builder: {
6
6
  "controller-log-level": Options;
7
- "price-service-connection-log-level": Options;
8
7
  "log-level": Options;
9
8
  "pushing-frequency": Options;
10
9
  "polling-frequency": Options;
@@ -17,7 +16,7 @@ declare const _default: {
17
16
  "gas-price": Options;
18
17
  "gas-multiplier": Options;
19
18
  };
20
- handler: (argv: any) => void;
19
+ handler: (argv: any) => Promise<void>;
21
20
  };
22
21
  export default _default;
23
22
  //# sourceMappingURL=command.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/injective/command.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;;;;;;;;;;;;;;yBAevB,OAAO;iBAKP,OAAO;qBAIP,OAAO;0BAIP,OAAO;;oBAWW,GAAG;;AAnC9B,wBAgHE"}
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/injective/command.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;;;;;;;;;;;;;yBAevB,OAAO;iBAKP,OAAO;qBAIP,OAAO;0BAIP,OAAO;;oBAUiB,GAAG;;AAlCpC,wBAoHE"}
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- const price_service_client_1 = require("@pythnetwork/price-service-client");
29
+ const hermes_client_1 = require("@pythnetwork/hermes-client");
30
30
  const options = __importStar(require("../options"));
31
31
  const price_config_1 = require("../price-config");
32
32
  const fs_1 = __importDefault(require("fs"));
@@ -35,6 +35,7 @@ const pyth_price_listener_1 = require("../pyth-price-listener");
35
35
  const controller_1 = require("../controller");
36
36
  const networks_1 = require("@injectivelabs/networks");
37
37
  const pino_1 = __importDefault(require("pino"));
38
+ const utils_1 = require("../utils");
38
39
  exports.default = {
39
40
  command: "injective",
40
41
  describe: "run price pusher for injective",
@@ -66,27 +67,32 @@ exports.default = {
66
67
  ...options.pollingFrequency,
67
68
  ...options.pushingFrequency,
68
69
  ...options.logLevel,
69
- ...options.priceServiceConnectionLogLevel,
70
70
  ...options.controllerLogLevel,
71
71
  },
72
- handler: function (argv) {
72
+ handler: async function (argv) {
73
73
  // FIXME: type checks for this
74
- const { gasPrice, gasMultiplier, grpcEndpoint, priceConfigFile, priceServiceEndpoint, mnemonicFile, pythContractAddress, pushingFrequency, pollingFrequency, network, logLevel, priceServiceConnectionLogLevel, controllerLogLevel, } = argv;
74
+ const { gasPrice, gasMultiplier, grpcEndpoint, priceConfigFile, priceServiceEndpoint, mnemonicFile, pythContractAddress, pushingFrequency, pollingFrequency, network, logLevel, controllerLogLevel, } = argv;
75
75
  const logger = (0, pino_1.default)({ level: logLevel });
76
76
  if (network !== "testnet" && network !== "mainnet") {
77
77
  throw new Error("Please specify network. One of [testnet, mainnet]");
78
78
  }
79
79
  const priceConfigs = (0, price_config_1.readPriceConfigFile)(priceConfigFile);
80
- const priceServiceConnection = new price_service_client_1.PriceServiceConnection(priceServiceEndpoint, {
81
- logger: logger.child({ module: "PriceServiceConnection" }, { level: priceServiceConnectionLogLevel }),
82
- });
80
+ const hermesClient = new hermes_client_1.HermesClient(priceServiceEndpoint);
83
81
  const mnemonic = fs_1.default.readFileSync(mnemonicFile, "utf-8").trim();
84
- const priceItems = priceConfigs.map(({ id, alias }) => ({ id, alias }));
85
- const pythListener = new pyth_price_listener_1.PythPriceListener(priceServiceConnection, priceItems, logger.child({ module: "PythPriceListener" }));
82
+ let priceItems = priceConfigs.map(({ id, alias }) => ({ id, alias }));
83
+ // Better to filter out invalid price items before creating the pyth listener
84
+ const { existingPriceItems, invalidPriceItems } = await (0, utils_1.filterInvalidPriceItems)(hermesClient, priceItems);
85
+ if (invalidPriceItems.length > 0) {
86
+ logger.error(`Invalid price id submitted for: ${invalidPriceItems
87
+ .map(({ alias }) => alias)
88
+ .join(", ")}`);
89
+ }
90
+ priceItems = existingPriceItems;
91
+ const pythListener = new pyth_price_listener_1.PythPriceListener(hermesClient, priceItems, logger.child({ module: "PythPriceListener" }));
86
92
  const injectiveListener = new injective_1.InjectivePriceListener(pythContractAddress, grpcEndpoint, priceItems, logger.child({ module: "InjectivePriceListener" }), {
87
93
  pollingFrequency,
88
94
  });
89
- const injectivePusher = new injective_1.InjectivePricePusher(priceServiceConnection, pythContractAddress, grpcEndpoint, logger.child({ module: "InjectivePricePusher" }), mnemonic, {
95
+ const injectivePusher = new injective_1.InjectivePricePusher(hermesClient, pythContractAddress, grpcEndpoint, logger.child({ module: "InjectivePricePusher" }), mnemonic, {
90
96
  chainId: (0, networks_1.getNetworkInfo)(network).chainId,
91
97
  gasPrice,
92
98
  gasMultiplier,
@@ -1,4 +1,4 @@
1
- import { HexString, PriceServiceConnection } from "@pythnetwork/price-service-client";
1
+ import { HexString, HermesClient } from "@pythnetwork/hermes-client";
2
2
  import { IPricePusher, PriceInfo, ChainPriceListener, PriceItem } from "../interface";
3
3
  import { DurationInSeconds } from "../utils";
4
4
  import { Logger } from "pino";
@@ -17,14 +17,14 @@ type InjectiveConfig = {
17
17
  gasPrice: number;
18
18
  };
19
19
  export declare class InjectivePricePusher implements IPricePusher {
20
- private priceServiceConnection;
20
+ private hermesClient;
21
21
  private pythContractAddress;
22
22
  private grpcEndpoint;
23
23
  private logger;
24
24
  private wallet;
25
25
  private chainConfig;
26
26
  private account;
27
- constructor(priceServiceConnection: PriceServiceConnection, pythContractAddress: string, grpcEndpoint: string, logger: Logger, mnemonic: string, chainConfig?: Partial<InjectiveConfig>);
27
+ constructor(hermesClient: HermesClient, pythContractAddress: string, grpcEndpoint: string, logger: Logger, mnemonic: string, chainConfig?: Partial<InjectiveConfig>);
28
28
  private injectiveAddress;
29
29
  private signAndBroadcastMsg;
30
30
  getPriceFeedUpdateObject(priceIds: string[]): Promise<any>;
@@ -1 +1 @@
1
- {"version":3,"file":"injective.d.ts","sourceRoot":"","sources":["../../src/injective/injective.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,sBAAsB,EACvB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,YAAY,EACZ,SAAS,EACT,kBAAkB,EAClB,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAW7C,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAyB9B,qBAAa,sBAAuB,SAAQ,kBAAkB;IAE1D,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,YAAY;IAEpB,OAAO,CAAC,MAAM;gBAHN,mBAAmB,EAAE,MAAM,EAC3B,YAAY,EAAE,MAAM,EAC5B,UAAU,EAAE,SAAS,EAAE,EACf,MAAM,EAAE,MAAM,EACtB,MAAM,EAAE;QACN,gBAAgB,EAAE,iBAAiB,CAAC;KACrC;IAKG,mBAAmB,CACvB,OAAO,EAAE,SAAS,GACjB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;CA4BlC;AAED,KAAK,eAAe,GAAG;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AACF,qBAAa,oBAAqB,YAAW,YAAY;IAMrD,OAAO,CAAC,sBAAsB;IAC9B,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,MAAM;IARhB,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,OAAO,CAAwB;gBAG7B,sBAAsB,EAAE,sBAAsB,EAC9C,mBAAmB,EAAE,MAAM,EAC3B,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACtB,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;IAWxC,OAAO,CAAC,gBAAgB;YAIV,mBAAmB;IAkE3B,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAU1D,eAAe,CACnB,QAAQ,EAAE,MAAM,EAAE,EAClB,cAAc,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC;CAiEjB"}
1
+ {"version":3,"file":"injective.d.ts","sourceRoot":"","sources":["../../src/injective/injective.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EACL,YAAY,EACZ,SAAS,EACT,kBAAkB,EAClB,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAW7C,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAyB9B,qBAAa,sBAAuB,SAAQ,kBAAkB;IAE1D,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,YAAY;IAEpB,OAAO,CAAC,MAAM;gBAHN,mBAAmB,EAAE,MAAM,EAC3B,YAAY,EAAE,MAAM,EAC5B,UAAU,EAAE,SAAS,EAAE,EACf,MAAM,EAAE,MAAM,EACtB,MAAM,EAAE;QACN,gBAAgB,EAAE,iBAAiB,CAAC;KACrC;IAKG,mBAAmB,CACvB,OAAO,EAAE,SAAS,GACjB,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;CA4BlC;AAED,KAAK,eAAe,GAAG;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AACF,qBAAa,oBAAqB,YAAW,YAAY;IAMrD,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,mBAAmB;IAC3B,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,MAAM;IARhB,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,OAAO,CAAwB;gBAG7B,YAAY,EAAE,YAAY,EAC1B,mBAAmB,EAAE,MAAM,EAC3B,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACtB,QAAQ,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;IAWxC,OAAO,CAAC,gBAAgB;YAIV,mBAAmB;IAkE3B,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAa1D,eAAe,CACnB,QAAQ,EAAE,MAAM,EAAE,EAClB,cAAc,EAAE,MAAM,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC;CAiEjB"}