-
Notifications
You must be signed in to change notification settings - Fork 222
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(solana-receiver-js-sdk): verify & post TWAPs (#2186)
* feat: update IDL * feat: add postTwapUpdates function * refactor: clean up * feat: add priceFeedIdToTwapUpdateAccount and update docs * doc: update readme * Apply suggestions from code review Co-authored-by: guibescos <[email protected]> * refactor: address pr comments * refactor: extract shared VAA instruction building into `generateVaaInstructionGroups`, allowing for flexible ix ordering and batching while sharing core logic * refactor: keep buildCloseEncodedVaaInstruction in PythSolanaReceiver for backward compat * fix: update compute budget for postTwapUpdate based on devnet runs * fix: fix comment * fix: imports, compute budget * fix: add reclaimTwapRent to recv contract * fix(cli): increase compute budget to avoid serde issues, add print statements * Apply suggestions from code review Co-authored-by: guibescos <[email protected]> * doc: update docstring --------- Co-authored-by: guibescos <[email protected]>
- Loading branch information
1 parent
eda14ad
commit 956f53e
Showing
10 changed files
with
965 additions
and
146 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
94 changes: 94 additions & 0 deletions
94
target_chains/solana/sdk/js/pyth_solana_receiver/examples/post_twap_update.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
import { Connection, Keypair, PublicKey } from "@solana/web3.js"; | ||
import { InstructionWithEphemeralSigners, PythSolanaReceiver } from "../"; | ||
import { Wallet } from "@coral-xyz/anchor"; | ||
import fs from "fs"; | ||
import os from "os"; | ||
import { HermesClient } from "@pythnetwork/hermes-client"; | ||
import { sendTransactions } from "@pythnetwork/solana-utils"; | ||
|
||
// Get price feed ids from https://pyth.network/developers/price-feed-ids#pyth-evm-stable | ||
const SOL_PRICE_FEED_ID = | ||
"0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d"; | ||
const ETH_PRICE_FEED_ID = | ||
"0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace"; | ||
|
||
let keypairFile = ""; | ||
if (process.env["SOLANA_KEYPAIR"]) { | ||
keypairFile = process.env["SOLANA_KEYPAIR"]; | ||
} else { | ||
keypairFile = `${os.homedir()}/.config/solana/id.json`; | ||
} | ||
|
||
async function main() { | ||
const connection = new Connection("https://api.devnet.solana.com"); | ||
const keypair = await loadKeypairFromFile(keypairFile); | ||
console.log( | ||
`Sending transactions from account: ${keypair.publicKey.toBase58()}` | ||
); | ||
const wallet = new Wallet(keypair); | ||
const pythSolanaReceiver = new PythSolanaReceiver({ connection, wallet }); | ||
|
||
// Get the TWAP update from hermes | ||
const twapUpdateData = await getTwapUpdateData(); | ||
console.log(`Posting TWAP update: ${twapUpdateData}`); | ||
|
||
// Similar to price updates, we'll keep closeUpdateAccounts = false for easy exploration | ||
const transactionBuilder = pythSolanaReceiver.newTransactionBuilder({ | ||
closeUpdateAccounts: false, | ||
}); | ||
|
||
// Post the TWAP updates to ephemeral accounts, one per price feed | ||
await transactionBuilder.addPostTwapUpdates(twapUpdateData); | ||
console.log( | ||
"The SOL/USD TWAP update will get posted to:", | ||
transactionBuilder.getTwapUpdateAccount(SOL_PRICE_FEED_ID).toBase58() | ||
); | ||
|
||
await transactionBuilder.addTwapConsumerInstructions( | ||
async ( | ||
getTwapUpdateAccount: (priceFeedId: string) => PublicKey | ||
): Promise<InstructionWithEphemeralSigners[]> => { | ||
// You can generate instructions here that use the TWAP updates posted above. | ||
// getTwapUpdateAccount(<price feed id>) will give you the account you need. | ||
return []; | ||
} | ||
); | ||
|
||
// Send the instructions in the builder in 1 or more transactions | ||
sendTransactions( | ||
await transactionBuilder.buildVersionedTransactions({ | ||
computeUnitPriceMicroLamports: 100000, | ||
tightComputeBudget: true, | ||
}), | ||
pythSolanaReceiver.connection, | ||
pythSolanaReceiver.wallet | ||
); | ||
} | ||
|
||
// Fetch TWAP update data from Hermes | ||
async function getTwapUpdateData() { | ||
const hermesConnection = new HermesClient("https://hermes.pyth.network/", {}); | ||
|
||
// Request TWAP updates for the last hour (3600 seconds) | ||
const response = await hermesConnection.getLatestTwapUpdates( | ||
[SOL_PRICE_FEED_ID, ETH_PRICE_FEED_ID], | ||
3600, | ||
{ encoding: "base64" } | ||
); | ||
|
||
return response.binary.data; | ||
} | ||
|
||
// Load a solana keypair from an id.json file | ||
async function loadKeypairFromFile(filePath: string): Promise<Keypair> { | ||
try { | ||
const keypairData = JSON.parse( | ||
await fs.promises.readFile(filePath, "utf8") | ||
); | ||
return Keypair.fromSecretKey(Uint8Array.from(keypairData)); | ||
} catch (error) { | ||
throw new Error(`Error loading keypair from file: ${error}`); | ||
} | ||
} | ||
|
||
main(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.