Skip to content

Commit 26236b8

Browse files
authored
chore: add post partially verified updates example (#2177)
* go * go
1 parent b451050 commit 26236b8

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
2+
import { InstructionWithEphemeralSigners, PythSolanaReceiver } from "../";
3+
import { Wallet } from "@coral-xyz/anchor";
4+
import fs from "fs";
5+
import os from "os";
6+
import { HermesClient } from "@pythnetwork/hermes-client";
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 getPriceUpdateData();
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+
// Using this method we can post the price update in a single transaction.
40+
// With 5 signatures, the transaction size is 1197 bytes
41+
// With 3 signatures, the transaction size is 1065 bytes
42+
await transactionBuilder.addPostPartiallyVerifiedPriceUpdates(
43+
priceUpdateData
44+
);
45+
console.log(
46+
"The SOL/USD price update will get posted to:",
47+
transactionBuilder.getPriceUpdateAccount(SOL_PRICE_FEED_ID).toBase58()
48+
);
49+
50+
await transactionBuilder.addPriceConsumerInstructions(
51+
async (
52+
getPriceUpdateAccount: (priceFeedId: string) => PublicKey
53+
): Promise<InstructionWithEphemeralSigners[]> => {
54+
// You can generate instructions here that use the price updates posted above.
55+
// getPriceUpdateAccount(<price feed id>) will give you the account you need.
56+
// These accounts will be packed into transactions by the builder.
57+
return [];
58+
}
59+
);
60+
61+
// Send the instructions in the builder in 1 or more transactions.
62+
// The builder will pack the instructions into transactions automatically.
63+
await pythSolanaReceiver.provider.sendAll(
64+
await transactionBuilder.buildVersionedTransactions({
65+
computeUnitPriceMicroLamports: 100000,
66+
}),
67+
{ preflightCommitment: "processed" }
68+
);
69+
}
70+
71+
// Fetch price update data from Hermes
72+
async function getPriceUpdateData() {
73+
const priceServiceConnection = new HermesClient(
74+
"https://hermes.pyth.network/",
75+
{}
76+
);
77+
78+
const response = await priceServiceConnection.getLatestPriceUpdates(
79+
[SOL_PRICE_FEED_ID],
80+
{ encoding: "base64" }
81+
);
82+
83+
return response.binary.data;
84+
}
85+
86+
// Load a solana keypair from an id.json file
87+
async function loadKeypairFromFile(filePath: string): Promise<Keypair> {
88+
try {
89+
const keypairData = JSON.parse(
90+
await fs.promises.readFile(filePath, "utf8")
91+
);
92+
return Keypair.fromSecretKey(Uint8Array.from(keypairData));
93+
} catch (error) {
94+
throw new Error(`Error loading keypair from file: ${error}`);
95+
}
96+
}
97+
98+
main();

0 commit comments

Comments
 (0)