|
1 | 1 | # Pyth Solana Receiver JS SDK
|
2 | 2 |
|
3 |
| -This is a Javascript SDK to interact with the Pyth Solana Receiver contract whose code lives [here](/target_chains/solana). |
| 3 | +[@pythnetwork/pyth-solana-receiver](https://www.npmjs.com/package/@pythnetwork/pyth-solana-receiver) is a Typescript SDK for interacting with the Pyth Solana Receiver contract. |
| 4 | +The SDK enables users to construct transactions that post Pyth price updates to the Solana blockchain and use them in downstream applications. |
4 | 5 |
|
5 |
| -It is available on [npm](https://www.npmjs.com/package/@pythnetwork/pyth-solana-receiver). |
| 6 | +The code for the underlying Pyth Solana Receiver program lives [here](/target_chains/solana). |
6 | 7 |
|
7 |
| -## Pull model |
| 8 | +## Installation |
8 | 9 |
|
9 |
| -The Pyth Solana Receiver allows users to consume Pyth price updates on a pull basis. This means that the user is responsible for submitting the price data on-chain whenever they want to interact with an app that requires a price update. |
| 10 | +You can install the package using your favorite typescript version manager |
10 | 11 |
|
11 |
| -Price updates get posted into price update accounts, owned by the Receiver contract. Once an update has been posted to a price update account, it can be used by anyone by simply passing the price update account as one of the accounts in a Solana instruction. |
12 |
| -Price update accounts can be closed by whoever wrote them to recover the rent. |
| 12 | +**NPM:** `npm install @pythnetwork/pyth-solana-receiver` |
13 | 13 |
|
14 |
| -## Example use |
| 14 | +**Yarn:** `yarn add @pythnetwork/pyth-solana-receiver` |
15 | 15 |
|
16 |
| -```ts |
17 |
| -import { Connection, PublicKey } from "@solana/web3.js"; |
18 |
| -import { PriceServiceConnection } from "@pythnetwork/price-service-client"; |
| 16 | +## Preliminaries |
| 17 | + |
| 18 | +### Accessing Pyth Prices |
| 19 | + |
| 20 | +This SDK is designed to be used in combination with a source of Pyth pricing data. |
| 21 | +There are two different sources of pricing data that users can choose from. |
| 22 | + |
| 23 | +- [Hermes](https://docs.pyth.network/price-feeds/pythnet-price-feeds/hermes) is a webservice that provides HTTP and websocket endpoints for retrieving real-time Pyth prices. |
| 24 | + The example code below uses the public Hermes instance hosted by the Pyth Data Association at `https://hermes.pyth.network/`. |
| 25 | + Hermes is also available from several infrastructure providers [listed here](https://docs.pyth.network/price-feeds/api-instances-and-providers/hermes). |
| 26 | + The [Price Service Client](https://github.com/pyth-network/pyth-crosschain/tree/main/price_service/client/js) can be used to access Hermes prices in a convenient way. |
| 27 | +- [Benchmarks](https://docs.pyth.network/benchmarks) is a webservice that provides HTTP endpoints for accessing historical Pyth prices. |
| 28 | + This service can be used for applications that require prices from specific times in the past. |
| 29 | + |
| 30 | +Both of these services return Pyth price updates, which are binary blobs of signed and timestamped prices. |
| 31 | +This SDK enables users to post price updates to the Solana blockchain, verify their validity, and consume them in downstream Solana applications. |
| 32 | + |
| 33 | +### Price Feed IDs |
| 34 | + |
| 35 | +Pyth identifies each pair of assets (e.g., BTC/USD) with a unique price feed id. |
| 36 | +The price feed id is a UUID written as a hexadecimal string. |
| 37 | +In order to get the price for a specific pair of assets, you will need its corresponding price feed id. |
| 38 | +You can look up all available price feed ids [here](https://pyth.network/developers/price-feed-ids). |
| 39 | + |
| 40 | +### Pyth Solana Receiver |
| 41 | + |
| 42 | +The Pyth Solana Receiver provides two different methods for posting and using price updates. |
| 43 | + |
| 44 | +First, a price update can be written to a **_price update account_**. |
| 45 | +Once the account has been written, other programs can read the Pyth price from the account by simply including it in their instruction. |
| 46 | +Price update accounts are ephemeral: they have an owner who can overwrite their contents or close the account. |
| 47 | +This method for using Pyth prices is a good fit for applications that need to use prices at specific timestamps (e.g., to settle a trade at a time). |
| 48 | + |
| 49 | +Second, a price update can be written to a **_price feed account_**. |
| 50 | +A price feed account is designed to work similarly to a Pyth price feed -- it holds a sequence of price updates that move forward in time. |
| 51 | +Applications can therefore store the address of a price feed account and read its contents whenever they need a recent price for the feed. |
| 52 | +Price feed accounts have a fixed address derived from the feed id and a shard id. |
| 53 | +The shard id allows different applications to use different accounts for the same feed, thereby reducing the impact of solana congestion. |
| 54 | +This method of using Pyth prices is a good fit for applications that always want to use the most recent price. |
| 55 | +Additionally, the [Price Scheduler](../../../../../../../price_pusher/) can be used to continuously write fresh updates to a price feed account, freeing applications from worrying about writing their own updates. |
| 56 | + |
| 57 | +This SDK provides methods for working with both types of accounts. |
| 58 | + |
| 59 | +## Usage |
| 60 | + |
| 61 | +The `PythSolanaReceiver` class is the main entrypoint for the SDK. |
| 62 | +Instantiate it with a Solana web3 `Connection` and anchor `Wallet`: |
| 63 | + |
| 64 | +```typescript |
19 | 65 | import { PythSolanaReceiver } from "@pythnetwork/pyth-solana-receiver";
|
20 |
| -import { MyFirstPythApp, IDL } from "./idl/my_first_pyth_app"; |
| 66 | +import { Connection, Keypair, PublicKey } from "@solana/web3.js"; |
| 67 | +import { Wallet } from "@coral-xyz/anchor"; |
| 68 | + |
| 69 | +const connection = new Connection("https://api.mainnet-beta.solana.com"); |
| 70 | +const wallet = new Wallet( |
| 71 | + Keypair.fromSecretKey(/* <insert private key here> */) |
| 72 | +); |
| 73 | +const pythSolanaReceiver = new PythSolanaReceiver({ connection, wallet }); |
| 74 | +``` |
| 75 | + |
| 76 | +### Post a price update |
| 77 | + |
| 78 | +Post an update to an ephemeral price update account: |
21 | 79 |
|
22 |
| -const SOL_PRICE_FEED_ID = |
23 |
| - "0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d"; |
24 |
| -const ETH_PRICE_FEED_ID = |
25 |
| - "0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace"; |
| 80 | +```ts |
| 81 | +// Fetch this from hermes or benchmarks. See Preliminaries section above for more info. |
| 82 | +const priceUpdateData = |
| 83 | + "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"; |
| 84 | + |
| 85 | +// Pass `closeUpdateAccounts: true` to the transaction builder constructor to automatically close the |
| 86 | +// price update accounts at the end of the sequence of transactions. |
| 87 | +const transactionBuilder = pythSolanaReceiver.newTransactionBuilder({ |
| 88 | + closeUpdateAccounts: false, |
| 89 | +}); |
| 90 | +await transactionBuilder.addPostPriceUpdates(priceUpdateData); |
26 | 91 |
|
27 |
| -const priceServiceConnection = new PriceServiceConnection( |
28 |
| - "https://hermes.pyth.network/", |
29 |
| - { priceFeedRequestConfig: { binary: true } } |
| 92 | +await transactionBuilder.addPriceConsumerInstructions( |
| 93 | + async ( |
| 94 | + getPriceUpdateAccount: (priceFeedId: string) => PublicKey |
| 95 | + ): Promise<InstructionWithEphemeralSigners[]> => { |
| 96 | + // Generate instructions here that use the price updates posted above. |
| 97 | + // getPriceUpdateAccount(<price feed id>) will give you the account for each price update. |
| 98 | + return []; |
| 99 | + } |
30 | 100 | );
|
31 |
| -const priceUpdateData = await priceServiceConnection.getLatestVaas([ |
32 |
| - SOL_PRICE_FEED_ID, |
33 |
| - ETH_PRICE_FEED_ID, |
34 |
| -]); // Fetch off-chain price update data |
35 |
| - |
36 |
| -const myFirstPythApp = new Program<MyFirstPythApp>( |
37 |
| - IDL as MyFirstPythApp, |
38 |
| - MY_FIRST_PYTH_APP_PROGRAM_ID, |
39 |
| - {} |
| 101 | + |
| 102 | +// Send the instructions in the builder in 1 or more transactions. |
| 103 | +// The builder will pack the instructions into transactions automatically. |
| 104 | +await pythSolanaReceiver.provider.sendAll( |
| 105 | + await transactionBuilder.buildVersionedTransactions({ |
| 106 | + computeUnitPriceMicroLamports: 100000, |
| 107 | + }) |
40 | 108 | );
|
| 109 | +``` |
| 110 | + |
| 111 | +The code snippet above will post every price update in `priceUpdateData` to a new ephemeral account. |
| 112 | + |
| 113 | +See `examples/post_price_update.ts` for a runnable example of posting a price update. |
| 114 | + |
| 115 | +### Update a price feed account |
| 116 | + |
| 117 | +Update the price feed account for shard id 1: |
| 118 | + |
| 119 | +```typescript |
| 120 | +// Fetch this from hermes or benchmarks. See Preliminaries section above for more info. |
| 121 | +const priceUpdateData = |
| 122 | + "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"; |
41 | 123 |
|
42 | 124 | const transactionBuilder = pythSolanaReceiver.newTransactionBuilder({});
|
43 |
| -await transactionBuilder.addPostPriceUpdates(priceUpdateData); |
| 125 | +// Update the price feed accounts for the feed ids in priceUpdateData and shard id 1 |
| 126 | +await transactionBuilder.addUpdatePriceFeed(priceUpdateData, 1); |
| 127 | + |
44 | 128 | await transactionBuilder.addPriceConsumerInstructions(
|
45 | 129 | async (
|
46 | 130 | getPriceUpdateAccount: (priceFeedId: string) => PublicKey
|
47 | 131 | ): Promise<InstructionWithEphemeralSigners[]> => {
|
48 |
| - return [ |
49 |
| - { |
50 |
| - instruction: await myFirstPythApp.methods |
51 |
| - .consume() |
52 |
| - .accounts({ |
53 |
| - solPriceUpdate: getPriceUpdateAccount(SOL_PRICE_FEED_ID), |
54 |
| - ethPriceUpdate: getPriceUpdateAccount(ETH_PRICE_FEED_ID), |
55 |
| - }) |
56 |
| - .instruction(), |
57 |
| - signers: [], |
58 |
| - }, |
59 |
| - ]; |
| 132 | + // Generate instructions here that use the price updates posted above. |
| 133 | + // getPriceUpdateAccount(<price feed id>) will give you the account for each price update. |
| 134 | + return []; |
60 | 135 | }
|
61 | 136 | );
|
| 137 | + |
| 138 | +// Send the instructions in the builder in 1 or more transactions. |
| 139 | +// The builder will pack the instructions into transactions automatically. |
62 | 140 | await pythSolanaReceiver.provider.sendAll(
|
63 | 141 | await transactionBuilder.buildVersionedTransactions({
|
64 |
| - computeUnitPriceMicroLamports: 1000000, |
| 142 | + computeUnitPriceMicroLamports: 100000, |
65 | 143 | })
|
66 | 144 | );
|
67 | 145 | ```
|
68 | 146 |
|
69 |
| -Alternatively you can use the instruction builder methods from `PythSolanaReceiver` : |
| 147 | +The code above will update the price feed accounts for the feeds in `priceUpdateData` (in this example, SOL/USD and ETH/USD). |
| 148 | +The address of the price feed accounts can be derived automatically from the feed id and the shard id: |
70 | 149 |
|
71 |
| -```ts |
72 |
| -import { PublicKey } from "@solana/web3.js"; |
73 |
| -import { PriceServiceConnection } from "@pythnetwork/price-service-client"; |
74 |
| -import { PythSolanaReceiver } from "@pythnetwork/pyth-solana-receiver"; |
75 |
| -import { MyFirstPythApp, IDL } from "./idl/my_first_pyth_app"; |
| 150 | +```typescript |
| 151 | +const solUsdPriceFeedAccount = pythSolanaReceiver |
| 152 | + .getPriceFeedAccountAddress(1, SOL_PRICE_FEED_ID) |
| 153 | + .toBase58(); |
| 154 | +``` |
76 | 155 |
|
77 |
| -const SOL_PRICE_FEED_ID = |
78 |
| - "0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d"; |
79 |
| -const ETH_PRICE_FEED_ID = |
80 |
| - "0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace"; |
| 156 | +Note that the example above uses a shard id of 1. |
| 157 | +Changing the shard id to a different value will give you a different account address. |
81 | 158 |
|
82 |
| -const priceServiceConnection = new PriceServiceConnection( |
83 |
| - "https://hermes.pyth.network/", |
84 |
| - { priceFeedRequestConfig: { binary: true } } |
85 |
| -); |
86 |
| -const priceUpdateData = await priceServiceConnection.getLatestVaas([ |
87 |
| - SOL_PRICE_FEED_ID, |
88 |
| - ETH_PRICE_FEED_ID, |
89 |
| -]); // Fetch off-chain price update data |
| 159 | +See `examples/update_price_feed.ts` for a runnable example of updating a price feed. |
90 | 160 |
|
91 |
| -const pythSolanaReceiver = new PythSolanaReceiver({ connection, wallet }); |
92 |
| -const { postInstructions, closeInstructions, priceFeedIdToPriceUpdateAccount } = |
93 |
| - await pythSolanaReceiver.buildPostPriceUpdateInstructions(priceUpdateData); // Get instructions to post the price update data and to close the accounts later |
| 161 | +### Partially verified price updates |
94 | 162 |
|
95 |
| -const myFirstPythApp = new Program<MyFirstPythApp>( |
96 |
| - IDL as MyFirstPythApp, |
97 |
| - MY_FIRST_PYTH_APP_PROGRAM_ID, |
98 |
| - {} |
99 |
| -); |
100 |
| -const consumerInstruction: InstructionWithEphemeralSigners = { |
101 |
| - instruction: await myFirstPythApp.methods |
102 |
| - .consume() |
103 |
| - .accounts({ |
104 |
| - solPriceUpdate: priceFeedIdToPriceUpdateAccount[SOL_PRICE_FEED_ID], |
105 |
| - ethPriceUpdate: priceFeedIdToPriceUpdateAccount[ETH_PRICE_FEED_ID], |
106 |
| - }) |
107 |
| - .instruction(), |
108 |
| - signers: [], |
109 |
| -}; |
110 |
| - |
111 |
| -const transactions = pythSolanaReceiver.batchIntoVersionedTransactions( |
112 |
| - [...postInstructions, consumerInstruction, ...closeInstructions], |
113 |
| - { computeUnitPriceMicroLamports: 1000000 } |
114 |
| -); // Put all the instructions together |
115 |
| -await pythSolanaReceiver.provider.sendAll(transactions); |
| 163 | +Price updates are relatively large and can take multiple transactions to post on the blockchain. |
| 164 | +You can reduce the size of the transaction payload by using `addPostPartiallyVerifiedPriceUpdates` instead of `addPostPriceUpdates`. |
| 165 | +This method does sacrifice some security however -- please see the method documentation for more details. |
| 166 | + |
| 167 | +### Get Instructions |
| 168 | + |
| 169 | +The `PythTransactionBuilder` class used in the examples above helps craft transactions that update prices and then use them in successive instructions. |
| 170 | +However, if you would like to craft your own transactions, `PythSolanaReceiver` exposes several methods for constructing the instructions for working with both price update accounts and price feed accounts. |
| 171 | +See `examples/post_price_update_instructions.ts` for an example of how to work with instructions. |
| 172 | + |
| 173 | +## Examples |
| 174 | + |
| 175 | +This SDK includes several runnable examples in the `examples/` directory. |
| 176 | +You can run these examples by performing the following steps. |
| 177 | +First, install and build any necessary typescript dependencies: |
| 178 | + |
| 179 | +1. Clone the `pyth-crosschain` git repo |
| 180 | +2. Run `npm install` in the root of the repo |
| 181 | +3. Run `npx lerna run build` anywhere in the repo |
| 182 | +4. From the `pyth_solana_receiver` directory, run `npx ts-node examples/<example filename>.ts` |
| 183 | + |
| 184 | +The examples require a Solana keypair with SOL to send Solana transactions. |
| 185 | +By default, the examples will use the same Solana keypair used by the Solana CLI (at `~/.config/solana/id.json`). |
| 186 | +You can override this default by setting the `SOLANA_KEYPAIR` environment variable: |
| 187 | + |
| 188 | +```bash |
| 189 | +export SOLANA_KEYPAIR=/path/to/keypair/id.json |
116 | 190 | ```
|
| 191 | + |
| 192 | +If you do not have a Solana keypair, you can generate one by downloading and installing the [Solana CLI](https://docs.solanalabs.com/cli/install), the running `solana-keygen new`. |
0 commit comments