Skip to content

Commit 20e8e15

Browse files
author
Dev Kalra
authored
[pice-pusher] add injective pusher (#633)
* add injective pusher * remove cwPriceServiceConnection
1 parent 7c728a5 commit 20e8e15

File tree

4 files changed

+150
-20
lines changed

4 files changed

+150
-20
lines changed

price_pusher/package-lock.json

Lines changed: 15 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

price_pusher/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
},
4545
"dependencies": {
4646
"@injectivelabs/sdk-ts": "^1.0.457",
47-
"@pythnetwork/pyth-common-js": "^1.2.0",
47+
"@pythnetwork/pyth-common-js": "^1.4.0",
4848
"@pythnetwork/pyth-evm-js": "^1.1.0",
4949
"@pythnetwork/pyth-sdk-solidity": "^2.2.0",
5050
"@truffle/hdwallet-provider": "^2.1.3",

price_pusher/src/index.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,18 @@ async function injectiveRun() {
103103
{ pollingFrequency: argv.pollingFrequency }
104104
);
105105

106+
const injectivePricePusher = new InjectivePricePusher(
107+
connection,
108+
argv.pythContract,
109+
argv.endpoint,
110+
fs.readFileSync(argv.mnemonicFile, "utf-8").trim()
111+
);
112+
106113
const handler = new Controller(
107114
priceConfigs,
108115
pythPriceListener,
109116
injectivePriceListener,
110-
new InjectivePricePusher(),
117+
injectivePricePusher,
111118
{
112119
cooldownDuration: argv.cooldownDuration,
113120
}

price_pusher/src/injective.ts

Lines changed: 126 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,18 @@
1-
import { HexString } from "@pythnetwork/pyth-common-js";
1+
import { HexString, PriceServiceConnection } from "@pythnetwork/pyth-common-js";
22
import { ChainPricePusher, PriceInfo, PriceListener } from "./interface";
33
import { DurationInSeconds } from "./utils";
44
import { PriceConfig } from "./price-config";
5-
import { ChainGrpcWasmApi } from "@injectivelabs/sdk-ts";
5+
import {
6+
ChainGrpcAuthApi,
7+
ChainGrpcWasmApi,
8+
DEFAULT_STD_FEE,
9+
MsgExecuteContract,
10+
Msgs,
11+
PrivateKey,
12+
TxGrpcClient,
13+
TxResponse,
14+
createTransactionFromMsg,
15+
} from "@injectivelabs/sdk-ts";
616

717
type PriceQueryResponse = {
818
price_feed: {
@@ -16,6 +26,11 @@ type PriceQueryResponse = {
1626
};
1727
};
1828

29+
type UpdateFeeResponse = {
30+
denom: string;
31+
amount: string;
32+
};
33+
1934
// this use price without leading 0x
2035
// FIXME: implement common methods in the parent class
2136
export class InjectivePriceListener implements PriceListener {
@@ -103,10 +118,118 @@ export class InjectivePriceListener implements PriceListener {
103118
}
104119

105120
export class InjectivePricePusher implements ChainPricePusher {
121+
private wallet: PrivateKey;
122+
constructor(
123+
private priceServiceConnection: PriceServiceConnection,
124+
private pythContract: string,
125+
private grpcEndpoint: string,
126+
mnemonic: string
127+
) {
128+
this.wallet = PrivateKey.fromMnemonic(mnemonic);
129+
}
130+
131+
private injectiveAddress(): string {
132+
return this.wallet.toBech32();
133+
}
134+
135+
private async signAndBroadcastMsg(
136+
msg: Msgs,
137+
fee = DEFAULT_STD_FEE
138+
): Promise<TxResponse> {
139+
const chainGrpcAuthApi = new ChainGrpcAuthApi(this.grpcEndpoint);
140+
const account = await chainGrpcAuthApi.fetchAccount(
141+
this.injectiveAddress()
142+
);
143+
const { signBytes, txRaw } = createTransactionFromMsg({
144+
sequence: account.baseAccount.sequence,
145+
accountNumber: account.baseAccount.accountNumber,
146+
message: msg,
147+
chainId: "injective-888",
148+
fee,
149+
pubKey: this.wallet.toPublicKey().toBase64(),
150+
});
151+
152+
const sig = await this.wallet.sign(Buffer.from(signBytes));
153+
154+
/** Append Signatures */
155+
txRaw.setSignaturesList([sig]);
156+
157+
const txService = new TxGrpcClient(this.grpcEndpoint);
158+
const txResponse = await txService.broadcast(txRaw);
159+
160+
return txResponse;
161+
}
162+
163+
async getPriceFeedUpdateObject(priceIds: string[]): Promise<any> {
164+
const vaas = await this.priceServiceConnection.getLatestVaas(priceIds);
165+
166+
return {
167+
update_price_feeds: {
168+
data: vaas,
169+
},
170+
};
171+
}
172+
106173
async updatePriceFeed(
107174
priceIds: string[],
108175
pubTimesToPush: number[]
109176
): Promise<void> {
110-
console.log("dummy pushed");
177+
if (priceIds.length === 0) {
178+
return;
179+
}
180+
181+
if (priceIds.length !== pubTimesToPush.length)
182+
throw new Error("Invalid arguments");
183+
184+
let priceFeedUpdateObject;
185+
try {
186+
// get the latest VAAs for updatePriceFeed and then push them
187+
priceFeedUpdateObject = await this.getPriceFeedUpdateObject(priceIds);
188+
} catch (e) {
189+
console.error("Error fetching the latest vaas to push");
190+
console.error(e);
191+
return;
192+
}
193+
194+
let updateFeeQueryResponse: UpdateFeeResponse;
195+
try {
196+
const api = new ChainGrpcWasmApi(this.grpcEndpoint);
197+
const { data } = await api.fetchSmartContractState(
198+
this.pythContract,
199+
Buffer.from(
200+
JSON.stringify({
201+
get_update_fee: {
202+
vaas: priceFeedUpdateObject.update_price_feeds.data,
203+
},
204+
})
205+
).toString("base64")
206+
);
207+
208+
const json = Buffer.from(data as string, "base64").toString();
209+
updateFeeQueryResponse = JSON.parse(json);
210+
} catch (e) {
211+
console.error("Error fetching update fee");
212+
console.error(e);
213+
return;
214+
}
215+
216+
// TODO: add specific error messages
217+
try {
218+
const executeMsg = MsgExecuteContract.fromJSON({
219+
sender: this.injectiveAddress(),
220+
contractAddress: this.pythContract,
221+
msg: priceFeedUpdateObject,
222+
funds: [updateFeeQueryResponse],
223+
});
224+
225+
const rs = await this.signAndBroadcastMsg(executeMsg);
226+
227+
if (rs.code !== 0) throw new Error("Error: transaction failed");
228+
229+
console.log("Succesfully broadcasted txHash:", rs.txHash);
230+
} catch (e) {
231+
console.error("Error executing messages");
232+
console.log(e);
233+
}
111234
}
112235
}

0 commit comments

Comments
 (0)