[price-pusher]cleanup (#650)

* remove dependency pyth-common-js

* PriceConfig -> PriceItem in pyth price listener

* consistently name contract address variable

* release a version after this pr

* remove comment

* improve logging

* rename chain price pusher
This commit is contained in:
Dev Kalra 2023-03-02 20:29:19 +05:30 committed by GitHub
parent f5620ecbd2
commit 945910778b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 63 additions and 64 deletions

View File

@ -47,8 +47,8 @@
"typescript": "^4.6.3"
},
"dependencies": {
"@pythnetwork/price-service-client": "*",
"@injectivelabs/sdk-ts": "^1.0.457",
"@pythnetwork/pyth-common-js": "^1.4.0",
"@pythnetwork/pyth-sdk-solidity": "^2.2.0",
"@truffle/hdwallet-provider": "^2.1.3",
"joi": "^17.6.0",

View File

@ -1,6 +1,6 @@
import { UnixTimestamp } from "@pythnetwork/pyth-common-js";
import { UnixTimestamp } from "@pythnetwork/price-service-client";
import { DurationInSeconds, sleep } from "./utils";
import { ChainPricePusher, IPriceListener } from "./interface";
import { IPricePusher, IPriceListener } from "./interface";
import { PriceConfig, shouldUpdate } from "./price-config";
export class Controller {
@ -9,7 +9,7 @@ export class Controller {
private priceConfigs: PriceConfig[],
private sourcePriceListener: IPriceListener,
private targetPriceListener: IPriceListener,
private targetChainPricePusher: ChainPricePusher,
private targetChainPricePusher: IPricePusher,
config: {
cooldownDuration: DurationInSeconds;
}
@ -39,9 +39,20 @@ export class Controller {
pubTimesToPush.push((targetLatestPrice?.publishTime || 0) + 1);
}
}
// note that the priceIds are without leading "0x"
const priceIds = pricesToPush.map((priceConfig) => priceConfig.id);
this.targetChainPricePusher.updatePriceFeed(priceIds, pubTimesToPush);
if (pricesToPush.length !== 0) {
console.log(
"Some of the above values passed the threshold. Will push the price."
);
// note that the priceIds are without leading "0x"
const priceIds = pricesToPush.map((priceConfig) => priceConfig.id);
this.targetChainPricePusher.updatePriceFeed(priceIds, pubTimesToPush);
} else {
console.log(
"None of the above values passed the threshold. No push needed."
);
}
await sleep(this.cooldownDuration * 1000);
}
}

View File

@ -1,4 +1,4 @@
import { PriceServiceConnection } from "@pythnetwork/pyth-common-js";
import { PriceServiceConnection } from "@pythnetwork/price-service-client";
import * as options from "../options";
import { readPriceConfigFile } from "../price-config";
import fs from "fs";
@ -68,7 +68,7 @@ export default {
const pythListener = new PythPriceListener(
priceServiceConnection,
priceConfigs
priceItems
);
const pythContractFactory = new PythContractFactory(

View File

@ -1,6 +1,6 @@
import { Contract, EventData } from "web3-eth-contract";
import {
ChainPricePusher,
IPricePusher,
PriceInfo,
ChainPriceListener,
PriceItem,
@ -16,7 +16,7 @@ import {
PriceServiceConnection,
HexString,
UnixTimestamp,
} from "@pythnetwork/pyth-common-js";
} from "@pythnetwork/price-service-client";
import { CustomGasStation } from "./custom-gas-station";
export class EvmPriceListener extends ChainPriceListener {
@ -98,7 +98,7 @@ export class EvmPriceListener extends ChainPriceListener {
.getPriceUnsafe(addLeading0x(priceId))
.call();
} catch (e) {
console.error(`Getting on-chain price for ${priceId} failed. Error:`);
console.error(`Polling on-chain price for ${priceId} failed. Error:`);
console.error(e);
return undefined;
}
@ -117,7 +117,7 @@ export class EvmPriceListener extends ChainPriceListener {
}
}
export class EvmPricePusher implements ChainPricePusher {
export class EvmPricePusher implements IPricePusher {
private customGasStation?: CustomGasStation;
constructor(
private connection: PriceServiceConnection,
@ -221,7 +221,7 @@ export class PythContractFactory {
constructor(
private endpoint: string,
private mnemonic: string,
private pythContractAddr: string
private pythContractAddress: string
) {}
/**
@ -243,7 +243,7 @@ export class PythContractFactory {
return new web3.eth.Contract(
AbstractPythAbi as any,
this.pythContractAddr,
this.pythContractAddress,
{
from: provider.getAddress(0),
}
@ -259,7 +259,10 @@ export class PythContractFactory {
createPythContract(): Contract {
const provider = this.createWeb3Provider();
const web3 = new Web3(provider);
return new web3.eth.Contract(AbstractPythAbi as any, this.pythContractAddr);
return new web3.eth.Contract(
AbstractPythAbi as any,
this.pythContractAddress
);
}
hasWebsocketProvider(): boolean {

View File

@ -1,6 +1,4 @@
// #!/usr/bin/env node
// // FIXME: update readme and compose files
// // FIXME: release a new version
import yargs from "yargs";
import { hideBin } from "yargs/helpers";
import injective from "./injective/command";

View File

@ -1,4 +1,4 @@
import { PriceServiceConnection } from "@pythnetwork/pyth-common-js";
import { PriceServiceConnection } from "@pythnetwork/price-service-client";
import * as options from "../options";
import { readPriceConfigFile } from "../price-config";
import fs from "fs";
@ -51,7 +51,7 @@ export default {
const pythListener = new PythPriceListener(
priceServiceConnection,
priceConfigs
priceItems
);
const injectiveListener = new InjectivePriceListener(

View File

@ -1,6 +1,9 @@
import { HexString, PriceServiceConnection } from "@pythnetwork/pyth-common-js";
import {
ChainPricePusher,
HexString,
PriceServiceConnection,
} from "@pythnetwork/price-service-client";
import {
IPricePusher,
PriceInfo,
ChainPriceListener,
PriceItem,
@ -35,11 +38,10 @@ type UpdateFeeResponse = {
amount: string;
};
// FIXME: CLEANUP contractAddr variable name consistency
// this use price without leading 0x
export class InjectivePriceListener extends ChainPriceListener {
constructor(
private contractAddress: string,
private pythContractAddress: string,
private grpcEndpoint: string,
priceItems: PriceItem[],
config: {
@ -56,14 +58,14 @@ export class InjectivePriceListener extends ChainPriceListener {
try {
const api = new ChainGrpcWasmApi(this.grpcEndpoint);
const { data } = await api.fetchSmartContractState(
this.contractAddress,
this.pythContractAddress,
Buffer.from(`{"price_feed":{"id":"${priceId}"}}`).toString("base64")
);
const json = Buffer.from(data as string, "base64").toString();
priceQueryResponse = JSON.parse(json);
} catch (e) {
console.error(`Getting on-chain price for ${priceId} failed. Error:`);
console.error(`Polling on-chain price for ${priceId} failed. Error:`);
console.error(e);
return undefined;
}
@ -82,11 +84,11 @@ export class InjectivePriceListener extends ChainPriceListener {
}
}
export class InjectivePricePusher implements ChainPricePusher {
export class InjectivePricePusher implements IPricePusher {
private wallet: PrivateKey;
constructor(
private priceServiceConnection: PriceServiceConnection,
private pythContract: string,
private pythContractAddress: string,
private grpcEndpoint: string,
mnemonic: string
) {
@ -160,7 +162,7 @@ export class InjectivePricePusher implements ChainPricePusher {
try {
const api = new ChainGrpcWasmApi(this.grpcEndpoint);
const { data } = await api.fetchSmartContractState(
this.pythContract,
this.pythContractAddress,
Buffer.from(
JSON.stringify({
get_update_fee: {
@ -178,11 +180,10 @@ export class InjectivePricePusher implements ChainPricePusher {
return;
}
// TODO: add specific error messages
try {
const executeMsg = MsgExecuteContract.fromJSON({
sender: this.injectiveAddress(),
contractAddress: this.pythContract,
contractAddress: this.pythContractAddress,
msg: priceFeedUpdateObject,
funds: [updateFeeQueryResponse],
});

View File

@ -1,4 +1,4 @@
import { HexString, UnixTimestamp } from "@pythnetwork/pyth-common-js";
import { HexString, UnixTimestamp } from "@pythnetwork/price-service-client";
import { DurationInSeconds } from "./utils";
export type PriceItem = {
@ -34,14 +34,15 @@ export abstract class ChainPriceListener implements IPriceListener {
}
async start() {
console.log(`Polling the prices every ${this.pollingFrequency} seconds...`);
console.log(
`Polling the prices on ${this.chain} every ${this.pollingFrequency} seconds...`
);
setInterval(this.pollPrices.bind(this), this.pollingFrequency * 1000);
await this.pollPrices();
}
private async pollPrices() {
console.log(`Polling ${this.chain} prices...`);
for (const { id: priceId } of this.priceItems) {
const currentPriceInfo = await this.getOnChainPriceInfo(priceId);
if (currentPriceInfo !== undefined) {
@ -79,7 +80,7 @@ export abstract class ChainPriceListener implements IPriceListener {
): Promise<PriceInfo | undefined>;
}
export interface ChainPricePusher {
export interface IPricePusher {
updatePriceFeed(
priceIds: string[],
pubTimesToPush: UnixTimestamp[]

View File

@ -1,4 +1,4 @@
import { HexString } from "@pythnetwork/pyth-common-js";
import { HexString } from "@pythnetwork/price-service-client";
import Joi from "joi";
import YAML from "yaml";
import fs from "fs";
@ -99,17 +99,13 @@ export function shouldUpdate(
console.log("Target latest price: ", targetLatestPrice);
console.log(
`Time difference: ${timeDifference} (< ${priceConfig.timeDifference}?)`
);
console.log(
`Price deviation: ${priceDeviationPct.toFixed(5)}% (< ${
priceConfig.priceDeviation
}%?)`
);
console.log(
`Confidence ratio: ${confidenceRatioPct.toFixed(5)}% (< ${
priceConfig.confidenceRatio
}%?)`
`Time difference: ${timeDifference} (< ${priceConfig.timeDifference}?) OR ` +
`Price deviation: ${priceDeviationPct.toFixed(5)}% (< ${
priceConfig.priceDeviation
}%?) OR ` +
`Confidence ratio: ${confidenceRatioPct.toFixed(5)}% (< ${
priceConfig.confidenceRatio
}%?)`
);
const result =
@ -117,15 +113,5 @@ export function shouldUpdate(
priceDeviationPct >= priceConfig.priceDeviation ||
confidenceRatioPct >= priceConfig.confidenceRatio;
if (result == true) {
console.log(
"Some of the above values passed the threshold. Will push the price."
);
} else {
console.log(
"None of the above values passed the threshold. No push needed."
);
}
return result;
}

View File

@ -2,9 +2,8 @@ import {
HexString,
PriceFeed,
PriceServiceConnection,
} from "@pythnetwork/pyth-common-js";
import { PriceConfig } from "./price-config";
import { PriceInfo, IPriceListener } from "./interface";
} from "@pythnetwork/price-service-client";
import { PriceInfo, IPriceListener, PriceItem } from "./interface";
export class PythPriceListener implements IPriceListener {
private connection: PriceServiceConnection;
@ -12,11 +11,11 @@ export class PythPriceListener implements IPriceListener {
private priceIdToAlias: Map<HexString, string>;
private latestPriceInfo: Map<HexString, PriceInfo>;
constructor(connection: PriceServiceConnection, priceConfigs: PriceConfig[]) {
constructor(connection: PriceServiceConnection, priceItems: PriceItem[]) {
this.connection = connection;
this.priceIds = priceConfigs.map((priceConfig) => priceConfig.id);
this.priceIds = priceItems.map((priceItem) => priceItem.id);
this.priceIdToAlias = new Map(
priceConfigs.map((priceConfig) => [priceConfig.id, priceConfig.alias])
priceItems.map((priceItem) => [priceItem.id, priceItem.alias])
);
this.latestPriceInfo = new Map();
}

View File

@ -1,4 +1,4 @@
import { HexString } from "@pythnetwork/pyth-common-js";
import { HexString } from "@pythnetwork/price-service-client";
export type PctNumber = number;
export type DurationInSeconds = number;