update_all_pricefeeds.ts 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import yargs from "yargs";
  2. import { hideBin } from "yargs/helpers";
  3. import { HermesClient, PriceFeedMetadata } from "@pythnetwork/hermes-client";
  4. import { DefaultStore } from "../src/node/utils/store";
  5. import { toPrivateKey } from "../src/core/base";
  6. const parser = yargs(hideBin(process.argv))
  7. .usage("Update the set of price feeds in a network. Usage: $0")
  8. .options({
  9. "private-key": {
  10. type: "string",
  11. demandOption: true,
  12. desc: "Private key to sign the transactions with",
  13. },
  14. contract: {
  15. type: "string",
  16. demandOption: true,
  17. desc: "Contract to update price feeds for (e.g mumbai_0xff1a0f4744e8582DF1aE09D5611b887B6a12925C)",
  18. },
  19. endpoint: {
  20. type: "string",
  21. desc: "Hermes endpoint to use, defaults to https://hermes.pyth.network",
  22. },
  23. encoding: {
  24. type: "string",
  25. desc: "Encoding to use for the price feeds (hex or base64), defaults to hex",
  26. choices: ["hex", "base64"],
  27. default: "hex",
  28. },
  29. "chunk-size": {
  30. type: "number",
  31. desc: "Chunk size to use for the price feeds, defaults to 150",
  32. default: 150,
  33. },
  34. });
  35. // This script is intended to update all pricefeeds after we deploy pyth pricefeeds contract.
  36. // It will fetch all pricefeeds from hermes and update the pricefeeds contract with the new pricefeeds.
  37. async function main() {
  38. const argv = await parser.argv;
  39. let priceFeedsMetadata: PriceFeedMetadata[] = [];
  40. const client = new HermesClient(
  41. argv.endpoint || "https://hermes.pyth.network",
  42. );
  43. const contract = DefaultStore.contracts[argv.contract];
  44. const privateKey = toPrivateKey(argv["private-key"]);
  45. const encoding = argv.encoding || "hex";
  46. priceFeedsMetadata = await client.getPriceFeeds();
  47. const priceFeedIds = priceFeedsMetadata.map((feed) => feed.id);
  48. console.log(`Fetched ${priceFeedIds.length} price feed IDs`);
  49. // We can adjust the chunk size based on the chain. Don't exceed 150 for now.
  50. // TODO: Add a check for the chain's block gas limit and adjust the chunk size accordingly.
  51. const chunkSize = argv.chunkSize;
  52. for (let i = 0; i < priceFeedIds.length; i += chunkSize) {
  53. console.log(
  54. `Processing chunk ${i / chunkSize + 1} of ${Math.ceil(
  55. priceFeedIds.length / chunkSize,
  56. )}`,
  57. );
  58. const chunk = priceFeedIds.slice(i, i + chunkSize);
  59. console.log(`length: ${chunk.length}`);
  60. const updates = await client.getLatestPriceUpdates(chunk, {
  61. parsed: false,
  62. });
  63. console.log(
  64. await contract.executeUpdatePriceFeed(
  65. privateKey,
  66. updates.binary.data.map((update) =>
  67. encoding === "hex"
  68. ? Buffer.from(update, "hex")
  69. : Buffer.from(update, "base64"),
  70. ),
  71. ),
  72. );
  73. // Wait for 2 seconds to avoid rate limiting and nonce collision
  74. await new Promise((resolve) => setTimeout(resolve, 2000));
  75. }
  76. }
  77. main();