From deb804617bf86c546ebf0b62b06971d4f99fc5bb Mon Sep 17 00:00:00 2001 From: Jayant Krishnamurthy Date: Wed, 1 Mar 2023 12:34:32 -0800 Subject: [PATCH] add an example for benchmarks (#647) --- target_chains/ethereum/sdk/js/package.json | 1 + .../sdk/js/src/examples/EvmBenchmark.ts | 117 ++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 target_chains/ethereum/sdk/js/src/examples/EvmBenchmark.ts diff --git a/target_chains/ethereum/sdk/js/package.json b/target_chains/ethereum/sdk/js/package.json index 88a0c531..41eeeb47 100644 --- a/target_chains/ethereum/sdk/js/package.json +++ b/target_chains/ethereum/sdk/js/package.json @@ -21,6 +21,7 @@ "build": "tsc", "example-client": "npm run build && node lib/examples/EvmPriceServiceClient.js", "example-relay": "npm run build && node lib/examples/EvmRelay.js", + "example-benchmark": "npm run build && node lib/examples/EvmBenchmark.js", "format": "prettier --write \"src/**/*.ts\"", "lint": "eslint src/", "prepublishOnly": "npm run build && npm test && npm run lint", diff --git a/target_chains/ethereum/sdk/js/src/examples/EvmBenchmark.ts b/target_chains/ethereum/sdk/js/src/examples/EvmBenchmark.ts new file mode 100644 index 00000000..6fcde043 --- /dev/null +++ b/target_chains/ethereum/sdk/js/src/examples/EvmBenchmark.ts @@ -0,0 +1,117 @@ +import Web3 from "web3"; +import yargs from "yargs"; +import { hideBin } from "yargs/helpers"; + +import { EvmPriceServiceConnection } from "../index"; +import HDWalletProvider from "@truffle/hdwallet-provider"; +import PythInterfaceAbi from "@pythnetwork/pyth-sdk-solidity/abis/IPyth.json"; + +const argv = yargs(hideBin(process.argv)) + .option("network", { + description: "RPC of the network to relay on.", + type: "string", + required: true, + }) + .option("endpoint", { + description: + "Endpoint URL for the price service. e.g: https://endpoint/example", + type: "string", + required: true, + }) + .option("pyth-contract", { + description: "Pyth contract address.", + type: "string", + required: true, + }) + .option("price-id", { + description: + "Price feed id (in hex) to fetch" + " e.g: 0xf9c0172ba10dfa4d19088d...", + type: "string", + required: true, + }) + .option("timestamp", { + description: "Timestamp of the prices to fetch" + " e.g., 2022-", // TODO + type: "string", + required: true, + }) + .option("mnemonic", { + description: "Mnemonic (private key) for sender", + type: "string", + required: true, + }) + .help() + .alias("help", "h") + .parserConfiguration({ + "parse-numbers": false, + }) + .parseSync(); + +const network = argv.network; +const pythContractAddr = argv.pythContract; + +const connection = new EvmPriceServiceConnection(argv.endpoint); + +async function run() { + const provider = new HDWalletProvider({ + mnemonic: { + phrase: argv.mnemonic, + }, + providerOrUrl: network, + }); + + // @ts-ignore + const web3 = new Web3(provider); + const priceId = argv.priceId as string; + // The unix timestamp in seconds + const unixTimestamp = Date.parse(argv.timestamp) / 1000; + + console.log(`Querying unix timestamp: ${unixTimestamp}`); + + const [priceFeedUpdateVaa, updateTimestamp] = await connection.getVaa( + priceId, + unixTimestamp + ); + console.log(`Next pyth update was at: ${updateTimestamp}`); + console.log(priceFeedUpdateVaa); + + const priceFeedUpdate = + "0x" + Buffer.from(priceFeedUpdateVaa, "base64").toString("hex"); + + const pythContract = new web3.eth.Contract( + PythInterfaceAbi as any, + pythContractAddr, + { + from: provider.getAddress(0), + } + ); + + const updateFee = await pythContract.methods + .getUpdateFee([priceFeedUpdate]) + .call(); + console.log(`Update fee: ${updateFee}`); + + // In real use cases, you would pass the update to your contract, then call parsePriceFeedUpdates within your contract. + // When invoked on-chain, this function will return a PriceFeed struct containing the data in the price update + // (such as the current price). + await pythContract.methods + .parsePriceFeedUpdates( + [priceFeedUpdate], + [priceId], + // parsePriceFeedUpdates will reject any price update outside of the time window provided in the following + // two arguments. Integrators can use this to specify the timestamp of the update they are expecting. + unixTimestamp, + unixTimestamp + 5 + ) + .send({ value: updateFee }) + .on("transactionHash", (hash: string) => { + console.log(`Tx hash: ${hash}`); + }) + .on("error", (err: any, receipt: any) => { + console.error(receipt); + throw err; + }); + + provider.engine.stop(); +} + +run();