[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:
parent
f5620ecbd2
commit
945910778b
|
@ -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",
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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],
|
||||
});
|
||||
|
|
|
@ -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[]
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue