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-ids", { description: "Space separated price feed ids (in hex) to fetch" + " e.g: 0xf9c0172ba10dfa4d19088d...", type: "array", 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 priceIds = argv.priceIds as string[]; const priceFeeds = await connection.getLatestPriceFeeds(priceIds); console.log(priceFeeds); const priceFeedUpdateData = await connection.getPriceFeedsUpdateData( priceIds ); console.log(priceFeedUpdateData); const pythContract = new web3.eth.Contract( PythInterfaceAbi as any, pythContractAddr, { from: provider.getAddress(0), } ); const updateFee = await pythContract.methods .getUpdateFee(priceFeedUpdateData) .call(); console.log(`Update fee: ${updateFee}`); let txHash = undefined; await pythContract.methods .updatePriceFeeds(priceFeedUpdateData) .send({ value: updateFee }) .on("transactionHash", (hash: string) => { txHash = hash; }) .on("error", (err: any, receipt: any) => { console.error(receipt); throw err; }); console.log(`Tx hash: ${txHash}`); if (txHash === undefined) { console.error("Something went wrong. Could not send price update tx."); } else { console.log("Awaiting tx confirmation..."); let receipt = undefined; while (!receipt) { receipt = await web3.eth.getTransactionReceipt(txHash); } // For on-chain use, you will typically perform the getPrice call within the same transaction as updatePriceFeeds. // The call to getPrice below simply demonstrates that the on-chain price was in fact updated. // Note that the code above for waiting for tx confirmation is a little flaky -- if so, you may see an old price printed here. for (const priceId of priceIds) { const [price, conf, expo, publishTime] = await pythContract.methods .getPrice(priceId) .call(); console.log( `Updated ${priceId} to (${price} +- ${conf}) * 10^${expo} at unix timestamp ${publishTime}` ); } } provider.engine.stop(); } run();