Skip to content

Commit 1ca310e

Browse files
committed
go
1 parent fb09981 commit 1ca310e

File tree

1 file changed

+92
-0
lines changed

1 file changed

+92
-0
lines changed
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
2+
import { PriceServiceConnection } from "@pythnetwork/price-service-client";
3+
import { InstructionWithEphemeralSigners, PythSolanaReceiver } from "../";
4+
import { Wallet } from "@coral-xyz/anchor";
5+
import fs from "fs";
6+
import os from "os";
7+
8+
// Get price feed ids from https://pyth.network/developers/price-feed-ids#pyth-evm-stable
9+
const SOL_PRICE_FEED_ID =
10+
"0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d";
11+
12+
let keypairFile = "";
13+
if (process.env["SOLANA_KEYPAIR"]) {
14+
keypairFile = process.env["SOLANA_KEYPAIR"];
15+
} else {
16+
keypairFile = `${os.homedir()}/.config/solana/id.json`;
17+
}
18+
19+
async function main() {
20+
const connection = new Connection("https://api.devnet.solana.com");
21+
const keypair = await loadKeypairFromFile(keypairFile);
22+
console.log(
23+
`Sending transactions from account: ${keypair.publicKey.toBase58()}`
24+
);
25+
const wallet = new Wallet(keypair);
26+
const pythSolanaReceiver = new PythSolanaReceiver({ connection, wallet });
27+
28+
// Get the price update from hermes
29+
const priceUpdateData = await getPriceUpdateDataFromOneDayAgo();
30+
console.log(`Posting price update: ${priceUpdateData}`);
31+
32+
// If closeUpdateAccounts = true, the builder will automatically generate instructions to close the ephemeral price update accounts
33+
// at the end of the transaction. Closing the accounts will reclaim their rent.
34+
// The example is using closeUpdateAccounts = false so you can easily look up the price update account in an explorer.
35+
const transactionBuilder = pythSolanaReceiver.newTransactionBuilder({
36+
closeUpdateAccounts: false,
37+
});
38+
// Post the price updates to ephemeral accounts, one per price feed.
39+
await transactionBuilder.addPostPriceUpdates(priceUpdateData);
40+
console.log(
41+
"The SOL/USD price update will get posted to:",
42+
transactionBuilder.getPriceUpdateAccount(SOL_PRICE_FEED_ID).toBase58()
43+
);
44+
45+
await transactionBuilder.addPriceConsumerInstructions(
46+
async (
47+
getPriceUpdateAccount: (priceFeedId: string) => PublicKey
48+
): Promise<InstructionWithEphemeralSigners[]> => {
49+
// You can generate instructions here that use the price updates posted above.
50+
// getPriceUpdateAccount(<price feed id>) will give you the account you need.
51+
// These accounts will be packed into transactions by the builder.
52+
return [];
53+
}
54+
);
55+
56+
// Send the instructions in the builder in 1 or more transactions.
57+
// The builder will pack the instructions into transactions automatically.
58+
await pythSolanaReceiver.provider.sendAll(
59+
await transactionBuilder.buildVersionedTransactions({
60+
computeUnitPriceMicroLamports: 100000,
61+
}),
62+
{ preflightCommitment: "processed" }
63+
);
64+
}
65+
66+
// Fetch price update data from Hermes
67+
async function getPriceUpdateDataFromOneDayAgo() {
68+
const priceServiceConnection = new PriceServiceConnection(
69+
"https://hermes.pyth.network/",
70+
{ priceFeedRequestConfig: { binary: true } }
71+
);
72+
73+
const oneDayAgo = Math.floor(Date.now() / 1000) - 86400;
74+
75+
return [
76+
(await priceServiceConnection.getVaa(SOL_PRICE_FEED_ID, oneDayAgo))[0],
77+
];
78+
}
79+
80+
// Load a solana keypair from an id.json file
81+
async function loadKeypairFromFile(filePath: string): Promise<Keypair> {
82+
try {
83+
const keypairData = JSON.parse(
84+
await fs.promises.readFile(filePath, "utf8")
85+
);
86+
return Keypair.fromSecretKey(Uint8Array.from(keypairData));
87+
} catch (error) {
88+
throw new Error(`Error loading keypair from file: ${error}`);
89+
}
90+
}
91+
92+
main();

0 commit comments

Comments
 (0)