added customGasStation (#644)
This commit is contained in:
parent
b9cb10fe65
commit
b3c697e5f5
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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}`);
|
||||
})
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue