This repository was archived by the owner on Nov 28, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 38
Add Solana TWAP documentation #650
Merged
Merged
Changes from 4 commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
0c8893d
Add Solana TWAP documentation
devin-ai-integration[bot] 8d43b1b
Fix formatting issues in Solana TWAP documentation
devin-ai-integration[bot] a7269f2
Add references to example scripts for Hermes client and Solana TWAP
devin-ai-integration[bot] 6449055
Fix formatting in skipPreflight option
devin-ai-integration[bot] 2d21106
Address PR comments: Move TWAP limitation to main paragraph, remove u…
devin-ai-integration[bot] 05a352c
Clarify that the Solana TWAP example is an existing demo with added f…
devin-ai-integration[bot] 89cf7b0
clarify example
tejasbadadare File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 |
|---|---|---|
|
|
@@ -241,6 +241,141 @@ The [SDK documentation](https://github.com/pyth-network/pyth-crosschain/tree/mai | |
| partially verified price updates. | ||
| </Callout> | ||
|
|
||
| ## Time-Weighted Average Price (TWAP) | ||
|
|
||
| Pyth also provides Time-Weighted Average Price (TWAP) for Solana applications. TWAP represents the average price over a specified time window, which can be useful for reducing the impact of short-term price volatility. | ||
|
|
||
| <Callout type="warning" emoji="⚠️"> | ||
| The TWAP window is currently limited to a maximum of 10 minutes (600 seconds). | ||
| </Callout> | ||
|
|
||
| ### Using TWAP in Solana Programs | ||
|
|
||
| To use TWAP in your Solana program, import the `TwapUpdate` struct from the Pyth Solana receiver SDK: | ||
|
||
|
|
||
| ```rust copy | ||
| use pyth_solana_receiver_sdk::price_update::{TwapUpdate}; | ||
|
|
||
| #[derive(Accounts)] | ||
| #[instruction(amount_in_usd : u64, twap_window_seconds: u64)] | ||
|
||
| pub struct SampleWithTwap<'info> { | ||
| #[account(mut)] | ||
| pub payer: Signer<'info>, | ||
| // Add this account to any instruction Context that needs TWAP data | ||
| pub twap_update: Account<'info, TwapUpdate>, | ||
| } | ||
| ``` | ||
|
|
||
| Update your instruction logic to read the TWAP from the update account: | ||
|
|
||
| ```rust copy | ||
| pub fn sample_with_twap( | ||
| ctx: Context<SampleWithTwap>, | ||
| amount_in_usd: u64, | ||
| twap_window_seconds: u64, | ||
| ) -> Result<()> { | ||
| let twap_update = &mut ctx.accounts.twap_update; | ||
| // get_twap_no_older_than will fail if the price update is more than 30 seconds old | ||
| let maximum_age: u64 = 30; | ||
| // Specify the price feed ID and the window in seconds for the TWAP | ||
| let feed_id: [u8; 32] = get_feed_id_from_hex("0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43")?; | ||
| let price = twap_update.get_twap_no_older_than( | ||
| &Clock::get()?, | ||
| maximum_age, | ||
| twap_window_seconds, | ||
| &feed_id, | ||
| )?; | ||
|
|
||
| // Sample output: | ||
| // The TWAP price is (7160106530699 ± 5129162301) * 10^-8 | ||
| msg!("The TWAP price is ({} ± {}) * 10^{}", price.price, price.conf, price.exponent); | ||
|
|
||
| Ok(()) | ||
| } | ||
| ``` | ||
|
|
||
| ### Fetching and Posting TWAP Updates | ||
|
|
||
| To use TWAP updates in your application, you need to fetch them from Hermes and post them to Solana: | ||
|
|
||
| #### Fetch TWAP updates from Hermes | ||
|
|
||
| Use `HermesClient` from `@pythnetwork/hermes-client` to fetch TWAP updates: | ||
|
|
||
| ```typescript copy | ||
| import { HermesClient } from "@pythnetwork/hermes-client"; | ||
|
|
||
| // The URL below is a public Hermes instance operated by the Pyth Data Association. | ||
| // Hermes is also available from several third-party providers listed here: | ||
| // https://docs.pyth.network/price-feeds/api-instances-and-providers/hermes | ||
| const hermesClient = new HermesClient("https://hermes.pyth.network/", {}); | ||
|
|
||
| // Specify the price feed ID and the TWAP window in seconds (maximum 600 seconds) | ||
| const twapWindowSeconds = 300; // 5 minutes | ||
| const twapUpdateData = await hermesClient.getLatestTwaps( | ||
| ["0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43"], // BTC/USD feed ID | ||
| twapWindowSeconds, | ||
| { encoding: "base64" } | ||
| ); | ||
|
|
||
| // TWAP updates are strings of base64-encoded binary data | ||
| console.log(twapUpdateData.binary.data); | ||
| ``` | ||
|
|
||
| For a complete example of fetching TWAP updates from Hermes, see the [HermesClient example script](https://github.com/pyth-network/pyth-crosschain/blob/main/apps/hermes/client/js/src/examples/HermesClient.ts) in the Pyth crosschain repository. | ||
|
|
||
| #### Post TWAP updates to Solana | ||
|
|
||
| Use `PythSolanaReceiver` to post the TWAP updates and consume them in your application: | ||
|
|
||
| ```typescript copy | ||
| import { PythSolanaReceiver } from "@pythnetwork/pyth-solana-receiver"; | ||
|
|
||
| // You will need a Connection from @solana/web3.js and a Wallet from @coral-xyz/anchor | ||
| const connection: Connection; | ||
| const wallet: Wallet; | ||
| const pythSolanaReceiver = new PythSolanaReceiver({ connection, wallet }); | ||
|
|
||
| // Create a transaction builder | ||
| const transactionBuilder = pythSolanaReceiver.newTransactionBuilder({ | ||
| closeUpdateAccounts: false, | ||
| }); | ||
|
|
||
| // Add the TWAP update to the transaction | ||
| await transactionBuilder.addPostTwapUpdates(twapUpdateData.binary.data); | ||
|
|
||
| // Add your application's instructions that use the TWAP update | ||
| await transactionBuilder.addTwapConsumerInstructions( | ||
| async ( | ||
| getTwapUpdateAccount: (priceFeedId: string) => PublicKey | ||
| ): Promise<InstructionWithEphemeralSigners[]> => { | ||
| // Generate instructions here that use the TWAP updates posted above | ||
| // getTwapUpdateAccount(<price feed id>) will give you the account for each TWAP update | ||
| return []; // Replace with your actual instructions | ||
| } | ||
| ); | ||
|
|
||
| // Send the instructions | ||
| await pythSolanaReceiver.provider.sendAll( | ||
| await transactionBuilder.buildVersionedTransactions({ | ||
| computeUnitPriceMicroLamports: 50000, | ||
| }), | ||
| { skipPreflight: true } | ||
| ); | ||
| ``` | ||
|
|
||
| For a complete example of posting TWAP updates to Solana, see the [post_twap_update.ts example script](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/solana/sdk/js/pyth_solana_receiver/examples/post_twap_update.ts) in the Pyth crosschain repository. | ||
|
|
||
| ### Example Application | ||
|
|
||
| The [Solana TWAP example](https://github.com/pyth-network/pyth-examples/tree/main/price_feeds/solana/send_usd) demonstrates how to fetch TWAP data from Hermes, post it to Solana, and consume it from a smart contract. The example includes: | ||
|
|
||
| - A React frontend for interacting with the contract | ||
| - A Solana program that consumes TWAP updates | ||
| - Complete transaction building for posting and consuming TWAP data | ||
|
|
||
| The example allows users to send a USD-denominated amount of SOL using either spot prices or TWAP prices, demonstrating how TWAP can be used to reduce the impact of price volatility. | ||
|
|
||
|
||
| ## Additional Resources | ||
|
|
||
| You may find these additional resources helpful for developing your Solana application. | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't make this a callout, just add the sentence to the previous block