pyth-crosschain/target_chains/ethereum/sdk/js/src/examples/EvmRelay.ts

122 lines
3.3 KiB
TypeScript

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();