added customGasStation (#644)

This commit is contained in:
Maurechi 2023-02-28 21:58:48 +01:00 committed by GitHub
parent b9cb10fe65
commit b3c697e5f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 82 additions and 5 deletions

View File

@ -0,0 +1,34 @@
import Web3 from "web3";
import {
CustomGasChainId,
TxSpeed,
verifyValidOption,
txSpeeds,
customGasChainIds,
} from "./utils";
type chainMethods = Record<CustomGasChainId, () => Promise<string>>;
export class CustomGasStation {
private chain: CustomGasChainId;
private speed: TxSpeed;
private chainMethods: chainMethods = {
137: this.fetchMaticMainnetGasPrice.bind(this),
};
constructor(chain: number, speed: string) {
this.speed = verifyValidOption(speed, txSpeeds);
this.chain = verifyValidOption(chain, customGasChainIds);
}
async getCustomGasPrice() {
return this.chainMethods[this.chain]();
}
private async fetchMaticMainnetGasPrice() {
const res = await fetch("https://gasstation-mainnet.matic.network/v2");
const jsonRes = await res.json();
const gasPrice = jsonRes[this.speed].maxFee;
const gweiGasPrice = Web3.utils.toWei(gasPrice.toFixed(2), "Gwei");
return gweiGasPrice.toString();
}
}

View File

@ -17,6 +17,7 @@ import {
HexString,
UnixTimestamp,
} from "@pythnetwork/pyth-common-js";
import { CustomGasStation } from "./custom-gas-station";
export class EvmPriceListener extends ChainPriceListener {
private pythContractFactory: PythContractFactory;
@ -117,10 +118,14 @@ export class EvmPriceListener extends ChainPriceListener {
}
export class EvmPricePusher implements ChainPricePusher {
private customGasStation?: CustomGasStation;
constructor(
private connection: PriceServiceConnection,
private pythContract: Contract
) {}
private pythContract: Contract,
customGasStation?: CustomGasStation
) {
this.customGasStation = customGasStation;
}
// The pubTimes are passed here to use the values that triggered the push.
// This is an optimization to avoid getting a newer value (as an update comes)
// and will help multiple price pushers to have consistent behaviour.
@ -145,19 +150,20 @@ export class EvmPricePusher implements ChainPricePusher {
"Pushing ",
priceIdsWith0x.map((priceIdWith0x) => `${priceIdWith0x}`)
);
const updateFee = await this.pythContract.methods
.getUpdateFee(priceFeedUpdateData)
.call();
console.log(`Update fee: ${updateFee}`);
const gasPrice = await this.customGasStation?.getCustomGasPrice();
this.pythContract.methods
.updatePriceFeedsIfNecessary(
priceFeedUpdateData,
priceIdsWith0x,
pubTimesToPush
)
.send({ value: updateFee })
.send({ value: updateFee, gasPrice })
.on("transactionHash", (hash: string) => {
console.log(`Successful. Tx hash: ${hash}`);
})

View File

@ -12,6 +12,7 @@ import { readPriceConfigFile } from "./price-config";
import { PriceServiceConnection } from "@pythnetwork/pyth-common-js";
import { InjectivePriceListener, InjectivePricePusher } from "./injective";
import { ChainPricePusher, IPriceListener } from "./interface";
import { CustomGasStation } from "./custom-gas-station";
const argv = yargs(hideBin(process.argv))
.option("network", {
@ -69,6 +70,18 @@ const argv = yargs(hideBin(process.argv))
required: false,
default: 5,
})
.option("custom-gas-station", {
description:
"If using a custom gas station, chainId of custom gas station to use",
type: "number",
required: false,
})
.option("tx-speed", {
description:
"txSpeed for custom gas station. choose between 'slow'|'standard'|'fast'",
type: "string",
required: false,
})
.help()
.alias("help", "h")
.parserConfiguration({
@ -139,6 +152,7 @@ function getNetworkPriceListener(network: string): IPriceListener {
}
function getNetworkPricePusher(network: string): ChainPricePusher {
const gasStation = getCustomGasStation(argv.customGasStation, argv.txSpeed);
switch (network) {
case "evm": {
const pythContractFactory = new PythContractFactory(
@ -148,7 +162,8 @@ function getNetworkPricePusher(network: string): ChainPricePusher {
);
return new EvmPricePusher(
priceServiceConnection,
pythContractFactory.createPythContractWithPayer()
pythContractFactory.createPythContractWithPayer(),
gasStation
);
}
case "injective":
@ -163,6 +178,12 @@ function getNetworkPricePusher(network: string): ChainPricePusher {
}
}
function getCustomGasStation(customGasStation?: number, txSpeed?: string) {
if (customGasStation && txSpeed) {
return new CustomGasStation(customGasStation, txSpeed);
}
}
start({
sourcePriceListener: pythPriceListener,
targetPriceListener: getNetworkPriceListener(argv.network),

View File

@ -2,6 +2,10 @@ import { HexString } from "@pythnetwork/pyth-common-js";
export type PctNumber = number;
export type DurationInSeconds = number;
export const txSpeeds = ["slow", "standard", "fast"] as const;
export type TxSpeed = typeof txSpeeds[number];
export const customGasChainIds = [137] as const;
export type CustomGasChainId = typeof customGasChainIds[number];
export async function sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
@ -31,3 +35,15 @@ export function isWsEndpoint(endpoint: string): boolean {
return false;
}
export function verifyValidOption<
options extends Readonly<Array<any>>,
validOption extends options[number]
>(option: any, validOptions: options) {
if (validOptions.includes(option)) {
return option as validOption;
}
const errorString =
option + " is not a valid option. Please choose between " + validOptions;
throw new Error(errorString);
}