Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion price_pusher/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
23 changes: 17 additions & 6 deletions price_pusher/src/controller.ts
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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;
}
Expand Down Expand Up @@ -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);
}
}
Expand Down
4 changes: 2 additions & 2 deletions price_pusher/src/evm/command.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -68,7 +68,7 @@ export default {

const pythListener = new PythPriceListener(
priceServiceConnection,
priceConfigs
priceItems
);

const pythContractFactory = new PythContractFactory(
Expand Down
17 changes: 10 additions & 7 deletions price_pusher/src/evm/evm.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Contract, EventData } from "web3-eth-contract";
import {
ChainPricePusher,
IPricePusher,
PriceInfo,
ChainPriceListener,
PriceItem,
Expand All @@ -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 {
Expand Down Expand Up @@ -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;
}
Expand All @@ -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,
Expand Down Expand Up @@ -221,7 +221,7 @@ export class PythContractFactory {
constructor(
private endpoint: string,
private mnemonic: string,
private pythContractAddr: string
private pythContractAddress: string
) {}

/**
Expand All @@ -243,7 +243,7 @@ export class PythContractFactory {

return new web3.eth.Contract(
AbstractPythAbi as any,
this.pythContractAddr,
this.pythContractAddress,
{
from: provider.getAddress(0),
}
Expand All @@ -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 {
Expand Down
2 changes: 0 additions & 2 deletions price_pusher/src/index.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand Down
4 changes: 2 additions & 2 deletions price_pusher/src/injective/command.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -51,7 +51,7 @@ export default {

const pythListener = new PythPriceListener(
priceServiceConnection,
priceConfigs
priceItems
);

const injectiveListener = new InjectivePriceListener(
Expand Down
23 changes: 12 additions & 11 deletions price_pusher/src/injective/injective.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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: {
Expand All @@ -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;
}
Expand All @@ -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
) {
Expand Down Expand Up @@ -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: {
Expand All @@ -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],
});
Expand Down
9 changes: 5 additions & 4 deletions price_pusher/src/interface.ts
Original file line number Diff line number Diff line change
@@ -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 = {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -79,7 +80,7 @@ export abstract class ChainPriceListener implements IPriceListener {
): Promise<PriceInfo | undefined>;
}

export interface ChainPricePusher {
export interface IPricePusher {
updatePriceFeed(
priceIds: string[],
pubTimesToPush: UnixTimestamp[]
Expand Down
30 changes: 8 additions & 22 deletions price_pusher/src/price-config.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -99,33 +99,19 @@ 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 =
timeDifference >= priceConfig.timeDifference ||
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;
}
11 changes: 5 additions & 6 deletions price_pusher/src/pyth-price-listener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,20 @@ 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;
private priceIds: HexString[];
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();
}
Expand Down
2 changes: 1 addition & 1 deletion price_pusher/src/utils.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand Down