@pythnetwork/pyth-solana-receiver 0.8.2 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -5
- package/lib/PythSolanaReceiver.d.ts +90 -14
- package/lib/PythSolanaReceiver.d.ts.map +1 -1
- package/lib/PythSolanaReceiver.js +152 -54
- package/lib/compute_budget.d.ts +4 -0
- package/lib/compute_budget.d.ts.map +1 -1
- package/lib/compute_budget.js +5 -1
- package/lib/idl/pyth_solana_receiver.d.ts +167 -1
- package/lib/idl/pyth_solana_receiver.d.ts.map +1 -1
- package/lib/idl/pyth_solana_receiver.js +167 -1
- package/lib/idl/wormhole_core_bridge_solana.d.ts +1 -1
- package/lib/idl/wormhole_core_bridge_solana.d.ts.map +1 -1
- package/lib/idl/wormhole_core_bridge_solana.js +1 -1
- package/lib/vaa.d.ts +56 -18
- package/lib/vaa.d.ts.map +1 -1
- package/lib/vaa.js +172 -40
- package/package.json +8 -9
package/README.md
CHANGED
|
@@ -65,6 +65,7 @@ Instantiate it with a Solana web3 `Connection` and anchor `Wallet`:
|
|
|
65
65
|
import { PythSolanaReceiver } from "@pythnetwork/pyth-solana-receiver";
|
|
66
66
|
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
|
|
67
67
|
import { Wallet } from "@coral-xyz/anchor";
|
|
68
|
+
import { sendTransactions } from "@pythnetwork/solana-utils";
|
|
68
69
|
|
|
69
70
|
const connection = new Connection("https://api.mainnet-beta.solana.com");
|
|
70
71
|
const wallet = new Wallet(
|
|
@@ -101,10 +102,15 @@ await transactionBuilder.addPriceConsumerInstructions(
|
|
|
101
102
|
|
|
102
103
|
// Send the instructions in the builder in 1 or more transactions.
|
|
103
104
|
// The builder will pack the instructions into transactions automatically.
|
|
104
|
-
|
|
105
|
+
// We use some custom transaction dispatch logic instead of the simple `provider.sendAll` to increase landing rate,
|
|
106
|
+
// feel free to use your own optimized logic.
|
|
107
|
+
sendTransactions(
|
|
105
108
|
await transactionBuilder.buildVersionedTransactions({
|
|
106
109
|
computeUnitPriceMicroLamports: 100000,
|
|
107
|
-
|
|
110
|
+
tightComputeBudget: true,
|
|
111
|
+
}),
|
|
112
|
+
pythSolanaReceiver.connection,
|
|
113
|
+
pythSolanaReceiver.wallet
|
|
108
114
|
);
|
|
109
115
|
```
|
|
110
116
|
|
|
@@ -137,10 +143,15 @@ await transactionBuilder.addPriceConsumerInstructions(
|
|
|
137
143
|
|
|
138
144
|
// Send the instructions in the builder in 1 or more transactions.
|
|
139
145
|
// The builder will pack the instructions into transactions automatically.
|
|
140
|
-
|
|
146
|
+
// We use some custom transaction dispatch logic instead of the simple `provider.sendAll` to increase landing rate,
|
|
147
|
+
// feel free to use your own optimized logic.
|
|
148
|
+
sendTransactions(
|
|
141
149
|
await transactionBuilder.buildVersionedTransactions({
|
|
142
150
|
computeUnitPriceMicroLamports: 100000,
|
|
143
|
-
|
|
151
|
+
tightComputeBudget: true,
|
|
152
|
+
}),
|
|
153
|
+
pythSolanaReceiver.connection,
|
|
154
|
+
pythSolanaReceiver.wallet
|
|
144
155
|
);
|
|
145
156
|
```
|
|
146
157
|
|
|
@@ -164,6 +175,50 @@ Price updates are relatively large and can take multiple transactions to post on
|
|
|
164
175
|
You can reduce the size of the transaction payload by using `addPostPartiallyVerifiedPriceUpdates` instead of `addPostPriceUpdates`.
|
|
165
176
|
This method does sacrifice some security however -- please see the method documentation for more details.
|
|
166
177
|
|
|
178
|
+
### Post a TWAP price update
|
|
179
|
+
|
|
180
|
+
TWAP price updates are calculated using a pair of verifiable cumulative price updates per price feed (the "start" and "end" updates for the given time window), and then performing an averaging calculation on-chain to create the time-weighted average price.
|
|
181
|
+
|
|
182
|
+
The flow of using, verifying, posting, and consuming these prices is the same as standard price updates. Get the binary update data from Hermes or Benchmarks, post and verify the VAAs via the Wormhole contract, and verify the updates against the VAAs via Pyth receiver contract. After this, you can consume the calculated TWAP posted to the TwapUpdate account. You can also optionally close these ephemeral accounts after the TWAP has been consumed to save on rent.
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
// Fetch the binary TWAP data from hermes or benchmarks. See Preliminaries section above for more info.
|
|
186
|
+
const binaryDataArray = ["UE5BV...khz609", "UE5BV...BAg8i6"];
|
|
187
|
+
|
|
188
|
+
// Pass `closeUpdateAccounts: true` to automatically close the TWAP update accounts
|
|
189
|
+
// after they're consumed
|
|
190
|
+
const transactionBuilder = pythSolanaReceiver.newTransactionBuilder({
|
|
191
|
+
closeUpdateAccounts: false,
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
// Post the updates and calculate the TWAP
|
|
195
|
+
await transactionBuilder.addPostTwapUpdates(binaryDataArray);
|
|
196
|
+
|
|
197
|
+
// You can now use the TWAP prices in subsequent instructions
|
|
198
|
+
await transactionBuilder.addTwapConsumerInstructions(
|
|
199
|
+
async (
|
|
200
|
+
getTwapUpdateAccount: (priceFeedId: string) => PublicKey
|
|
201
|
+
): Promise<InstructionWithEphemeralSigners[]> => {
|
|
202
|
+
// Generate instructions here that use the TWAP updates posted above.
|
|
203
|
+
// getTwapUpdateAccount(<price feed id>) will give you the account for each TWAP update.
|
|
204
|
+
return [];
|
|
205
|
+
}
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
// Send the instructions in the builder in 1 or more transactions.
|
|
209
|
+
// The builder will pack the instructions into transactions automatically.
|
|
210
|
+
sendTransactions(
|
|
211
|
+
await transactionBuilder.buildVersionedTransactions({
|
|
212
|
+
computeUnitPriceMicroLamports: 100000,
|
|
213
|
+
tightComputeBudget: true,
|
|
214
|
+
}),
|
|
215
|
+
pythSolanaReceiver.connection,
|
|
216
|
+
pythSolanaReceiver.wallet
|
|
217
|
+
);
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
See `examples/post_twap_update.ts` for a runnable example of posting a TWAP price update.
|
|
221
|
+
|
|
167
222
|
### Get Instructions
|
|
168
223
|
|
|
169
224
|
The `PythTransactionBuilder` class used in the examples above helps craft transactions that update prices and then use them in successive instructions.
|
|
@@ -178,7 +233,7 @@ First, install and build any necessary typescript dependencies:
|
|
|
178
233
|
|
|
179
234
|
1. Clone the `pyth-crosschain` git repo
|
|
180
235
|
2. Run `pnpm i` in the root of the repo
|
|
181
|
-
3. Run `pnpm
|
|
236
|
+
3. Run `pnpm turbo build` anywhere in the repo
|
|
182
237
|
4. From the `pyth_solana_receiver` directory, run `pnpm exec ts-node examples/<example filename>.ts`
|
|
183
238
|
|
|
184
239
|
The examples require a Solana keypair with SOL to send Solana transactions.
|
|
@@ -8,6 +8,7 @@ import { Wallet } from "@coral-xyz/anchor";
|
|
|
8
8
|
import { TransactionBuilder, InstructionWithEphemeralSigners, PriorityFeeConfig } from "@pythnetwork/solana-utils";
|
|
9
9
|
import { PythPushOracle } from "./idl/pyth_push_oracle";
|
|
10
10
|
export type PriceUpdateAccount = IdlAccounts<PythSolanaReceiverProgram>["priceUpdateV2"];
|
|
11
|
+
export type TwapUpdateAccount = IdlAccounts<PythSolanaReceiverProgram>["twapUpdate"];
|
|
11
12
|
/**
|
|
12
13
|
* Configuration for the PythTransactionBuilder
|
|
13
14
|
* @property closeUpdateAccounts (default: true) if true, the builder will add instructions to close the price update accounts and the encoded vaa accounts to recover the rent
|
|
@@ -42,13 +43,14 @@ export type PythTransactionBuilderConfig = {
|
|
|
42
43
|
* console.log("The SOL/USD price update will get posted to:", transactionBuilder.getPriceUpdateAccount(SOL_PRICE_FEED_ID).toBase58())
|
|
43
44
|
* await transactionBuilder.addPriceConsumerInstructions(...)
|
|
44
45
|
*
|
|
45
|
-
* await pythSolanaReceiver.provider.sendAll(await transactionBuilder.buildVersionedTransactions({computeUnitPriceMicroLamports:100000}))
|
|
46
|
+
* await pythSolanaReceiver.provider.sendAll(await transactionBuilder.buildVersionedTransactions({computeUnitPriceMicroLamports:100000, tightComputeBudget: true}))
|
|
46
47
|
* ```
|
|
47
48
|
*/
|
|
48
49
|
export declare class PythTransactionBuilder extends TransactionBuilder {
|
|
49
50
|
readonly pythSolanaReceiver: PythSolanaReceiver;
|
|
50
51
|
readonly closeInstructions: InstructionWithEphemeralSigners[];
|
|
51
52
|
readonly priceFeedIdToPriceUpdateAccount: Record<string, PublicKey>;
|
|
53
|
+
readonly priceFeedIdToTwapUpdateAccount: Record<string, PublicKey>;
|
|
52
54
|
readonly closeUpdateAccounts: boolean;
|
|
53
55
|
constructor(pythSolanaReceiver: PythSolanaReceiver, config: PythTransactionBuilderConfig, addressLookupTable?: AddressLookupTableAccount);
|
|
54
56
|
/**
|
|
@@ -97,6 +99,27 @@ export declare class PythTransactionBuilder extends TransactionBuilder {
|
|
|
97
99
|
* ```
|
|
98
100
|
*/
|
|
99
101
|
addPostPartiallyVerifiedPriceUpdates(priceUpdateDataArray: string[]): Promise<void>;
|
|
102
|
+
/**
|
|
103
|
+
* Add instructions to post TWAP updates to the builder.
|
|
104
|
+
* Use this function to post fully verified TWAP updates from the present or from the past for your program to consume.
|
|
105
|
+
*
|
|
106
|
+
* @param twapUpdateDataArray the output of the `@pythnetwork/hermes-client`'s `getLatestTwaps`. This is an array of verifiable price updates.
|
|
107
|
+
*
|
|
108
|
+
* @example
|
|
109
|
+
* ```typescript
|
|
110
|
+
* // Get the price feed ids from https://pyth.network/developers/price-feed-ids#pyth-evm-stable
|
|
111
|
+
* const twapUpdateData = await hermesClient.getLatestTwaps([
|
|
112
|
+
* SOL_PRICE_FEED_ID,
|
|
113
|
+
* ETH_PRICE_FEED_ID,
|
|
114
|
+
* ]);
|
|
115
|
+
*
|
|
116
|
+
* const transactionBuilder = pythSolanaReceiver.newTransactionBuilder({});
|
|
117
|
+
* await transactionBuilder.addPostTwapUpdates(priceUpdateData);
|
|
118
|
+
* console.log("The SOL/USD price update will get posted to:", transactionBuilder.getTwapUpdateAccount(SOL_PRICE_FEED_ID).toBase58())
|
|
119
|
+
* await transactionBuilder.addTwapConsumerInstructions(...)
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
addPostTwapUpdates(twapUpdateDataArray: string[]): Promise<void>;
|
|
100
123
|
/**
|
|
101
124
|
* Add instructions to update price feed accounts to the builder.
|
|
102
125
|
* Price feed accounts are fixed accounts per price feed id that can only be updated with a more recent price.
|
|
@@ -150,6 +173,37 @@ export declare class PythTransactionBuilder extends TransactionBuilder {
|
|
|
150
173
|
* ```
|
|
151
174
|
*/
|
|
152
175
|
addPriceConsumerInstructions(getInstructions: (getPriceUpdateAccount: (priceFeedId: string) => PublicKey) => Promise<InstructionWithEphemeralSigners[]>): Promise<void>;
|
|
176
|
+
/**
|
|
177
|
+
* Add instructions that consume TWAP updates to the builder.
|
|
178
|
+
*
|
|
179
|
+
* @param getInstructions a function that given a mapping of price feed IDs to TWAP update accounts, generates a series of instructions. TWAP updates get posted to ephemeral accounts and this function allows the user to indicate which accounts in their instruction need to be "replaced" with each price update account.
|
|
180
|
+
* If multiple TWAP updates for the same price feed ID are posted with the same builder, the account corresponding to the last update to get posted will be used.
|
|
181
|
+
*
|
|
182
|
+
* @example
|
|
183
|
+
* ```typescript
|
|
184
|
+
* ...
|
|
185
|
+
* await transactionBuilder.addPostTwapUpdates(twapUpdateData);
|
|
186
|
+
* await transactionBuilder.addTwapConsumerInstructions(
|
|
187
|
+
* async (
|
|
188
|
+
* getTwapUpdateAccount: ( priceFeedId: string) => PublicKey
|
|
189
|
+
* ): Promise<InstructionWithEphemeralSigners[]> => {
|
|
190
|
+
* return [
|
|
191
|
+
* {
|
|
192
|
+
* instruction: await myFirstPythApp.methods
|
|
193
|
+
* .consume()
|
|
194
|
+
* .accounts({
|
|
195
|
+
* solTwapUpdate: getTwapUpdateAccount(SOL_PRICE_FEED_ID),
|
|
196
|
+
* ethTwapUpdate: getTwapUpdateAccount(ETH_PRICE_FEED_ID),
|
|
197
|
+
* })
|
|
198
|
+
* .instruction(),
|
|
199
|
+
* signers: [],
|
|
200
|
+
* },
|
|
201
|
+
* ];
|
|
202
|
+
* }
|
|
203
|
+
* );
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
addTwapConsumerInstructions(getInstructions: (getTwapUpdateAccount: (priceFeedId: string) => PublicKey) => Promise<InstructionWithEphemeralSigners[]>): Promise<void>;
|
|
153
207
|
/** Add instructions to close encoded VAA accounts from previous actions.
|
|
154
208
|
* If you have previously used the PythTransactionBuilder with closeUpdateAccounts set to false or if you posted encoded VAAs but the transaction to close them did not land on-chain, your wallet might own many encoded VAA accounts.
|
|
155
209
|
* The rent cost for these accounts is 0.008 SOL per encoded VAA account. You can recover this rent calling this function when building a set of transactions.
|
|
@@ -174,6 +228,11 @@ export declare class PythTransactionBuilder extends TransactionBuilder {
|
|
|
174
228
|
* If multiple price updates for the same price feed ID will be posted with the same builder, the address of the account corresponding to the last update to get posted will be returned.
|
|
175
229
|
* */
|
|
176
230
|
getPriceUpdateAccount(priceFeedId: string): PublicKey;
|
|
231
|
+
/**
|
|
232
|
+
* This method is used to retrieve the address of the TWAP update account where the TWAP update for a given price feed ID will be posted.
|
|
233
|
+
* If multiple updates for the same price feed ID will be posted with the same builder, the address of the account corresponding to the last update to get posted will be returned.
|
|
234
|
+
* */
|
|
235
|
+
getTwapUpdateAccount(priceFeedId: string): PublicKey;
|
|
177
236
|
}
|
|
178
237
|
/**
|
|
179
238
|
* A class to interact with the Pyth Solana Receiver program.
|
|
@@ -216,19 +275,6 @@ export declare class PythSolanaReceiver {
|
|
|
216
275
|
priceFeedIdToPriceUpdateAccount: Record<string, PublicKey>;
|
|
217
276
|
closeInstructions: InstructionWithEphemeralSigners[];
|
|
218
277
|
}>;
|
|
219
|
-
/**
|
|
220
|
-
* Build a series of helper instructions that post a VAA in an encoded VAA account. This function is bespoke for posting Pyth VAAs and might not work for other usecases.
|
|
221
|
-
*
|
|
222
|
-
* @param vaa a Wormhole VAA
|
|
223
|
-
* @returns `postInstructions`: the instructions to post the VAA
|
|
224
|
-
* @returns `encodedVaaAddress`: the address of the encoded VAA account where the VAA will be posted
|
|
225
|
-
* @returns `closeInstructions`: the instructions to close the encoded VAA account
|
|
226
|
-
*/
|
|
227
|
-
buildPostEncodedVaaInstructions(vaa: Buffer): Promise<{
|
|
228
|
-
postInstructions: InstructionWithEphemeralSigners[];
|
|
229
|
-
encodedVaaAddress: PublicKey;
|
|
230
|
-
closeInstructions: InstructionWithEphemeralSigners[];
|
|
231
|
-
}>;
|
|
232
278
|
/**
|
|
233
279
|
* Build a series of helper instructions that post price updates to the Pyth Solana Receiver program and another series to close the encoded vaa accounts and the price update accounts.
|
|
234
280
|
*
|
|
@@ -242,6 +288,19 @@ export declare class PythSolanaReceiver {
|
|
|
242
288
|
priceFeedIdToPriceUpdateAccount: Record<string, PublicKey>;
|
|
243
289
|
closeInstructions: InstructionWithEphemeralSigners[];
|
|
244
290
|
}>;
|
|
291
|
+
/**
|
|
292
|
+
* Build a series of helper instructions that post TWAP updates to the Pyth Solana Receiver program and another series to close the encoded vaa accounts and the TWAP update accounts.
|
|
293
|
+
*
|
|
294
|
+
* @param twapUpdateDataArray the output of the `@pythnetwork/price-service-client`'s `PriceServiceConnection.getLatestTwaps`. This is an array of verifiable price updates.
|
|
295
|
+
* @returns `postInstructions`: the instructions to post the TWAP updates, these should be called before consuming the price updates
|
|
296
|
+
* @returns `priceFeedIdToTwapUpdateAccount`: this is a map of price feed IDs to Solana address. Given a price feed ID, you can use this map to find the account where `postInstructions` will post the TWAP update.
|
|
297
|
+
* @returns `closeInstructions`: the instructions to close the TWAP update accounts, these should be called after consuming the TWAP updates
|
|
298
|
+
*/
|
|
299
|
+
buildPostTwapUpdateInstructions(twapUpdateDataArray: string[]): Promise<{
|
|
300
|
+
postInstructions: InstructionWithEphemeralSigners[];
|
|
301
|
+
priceFeedIdToTwapUpdateAccount: Record<string, PublicKey>;
|
|
302
|
+
closeInstructions: InstructionWithEphemeralSigners[];
|
|
303
|
+
}>;
|
|
245
304
|
/**
|
|
246
305
|
* Build a series of helper instructions that update one or many price feed accounts and another series to close the encoded vaa accounts used to update the price feed accounts.
|
|
247
306
|
*
|
|
@@ -256,6 +315,19 @@ export declare class PythSolanaReceiver {
|
|
|
256
315
|
priceFeedIdToPriceUpdateAccount: Record<string, PublicKey>;
|
|
257
316
|
closeInstructions: InstructionWithEphemeralSigners[];
|
|
258
317
|
}>;
|
|
318
|
+
/**
|
|
319
|
+
* Build a series of helper instructions that post a VAA in an encoded VAA account. This function is bespoke for posting Pyth VAAs and might not work for other usecases.
|
|
320
|
+
*
|
|
321
|
+
* @param vaa a Wormhole VAA
|
|
322
|
+
* @returns `encodedVaaAddress`: the address of the encoded VAA account where the VAA will be posted
|
|
323
|
+
* @returns `postInstructions`: the instructions to post the VAA
|
|
324
|
+
* @returns `closeInstructions`: the instructions to close the encoded VAA account
|
|
325
|
+
*/
|
|
326
|
+
buildPostEncodedVaaInstructions(vaa: Buffer): Promise<{
|
|
327
|
+
encodedVaaAddress: PublicKey;
|
|
328
|
+
postInstructions: InstructionWithEphemeralSigners[];
|
|
329
|
+
closeInstructions: InstructionWithEphemeralSigners[];
|
|
330
|
+
}>;
|
|
259
331
|
/**
|
|
260
332
|
* Build an instruction to close an encoded VAA account, recovering the rent.
|
|
261
333
|
*/
|
|
@@ -268,6 +340,10 @@ export declare class PythSolanaReceiver {
|
|
|
268
340
|
* Build an instruction to close a price update account, recovering the rent.
|
|
269
341
|
*/
|
|
270
342
|
buildClosePriceUpdateInstruction(priceUpdateAccount: PublicKey): Promise<InstructionWithEphemeralSigners>;
|
|
343
|
+
/**
|
|
344
|
+
* Build an instruction to close a TWAP update account, recovering the rent.
|
|
345
|
+
*/
|
|
346
|
+
buildCloseTwapUpdateInstruction(twapUpdateAccount: PublicKey): Promise<InstructionWithEphemeralSigners>;
|
|
271
347
|
/**
|
|
272
348
|
* Returns a set of versioned transactions that contain the provided instructions in the same order and with efficient batching
|
|
273
349
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PythSolanaReceiver.d.ts","sourceRoot":"","sources":["../src/PythSolanaReceiver.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EACL,yBAAyB,EACzB,UAAU,EACV,MAAM,EACN,WAAW,EACX,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,kBAAkB,IAAI,yBAAyB,EAEhD,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,wBAAwB,EAEzB,MAAM,mCAAmC,CAAC;AAU3C,OAAO,EAAE,SAAS,EAAW,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"PythSolanaReceiver.d.ts","sourceRoot":"","sources":["../src/PythSolanaReceiver.ts"],"names":[],"mappings":"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"}
|
|
@@ -38,19 +38,21 @@ const pyth_push_oracle_1 = require("./idl/pyth_push_oracle");
|
|
|
38
38
|
* console.log("The SOL/USD price update will get posted to:", transactionBuilder.getPriceUpdateAccount(SOL_PRICE_FEED_ID).toBase58())
|
|
39
39
|
* await transactionBuilder.addPriceConsumerInstructions(...)
|
|
40
40
|
*
|
|
41
|
-
* await pythSolanaReceiver.provider.sendAll(await transactionBuilder.buildVersionedTransactions({computeUnitPriceMicroLamports:100000}))
|
|
41
|
+
* await pythSolanaReceiver.provider.sendAll(await transactionBuilder.buildVersionedTransactions({computeUnitPriceMicroLamports:100000, tightComputeBudget: true}))
|
|
42
42
|
* ```
|
|
43
43
|
*/
|
|
44
44
|
class PythTransactionBuilder extends solana_utils_1.TransactionBuilder {
|
|
45
45
|
pythSolanaReceiver;
|
|
46
46
|
closeInstructions;
|
|
47
47
|
priceFeedIdToPriceUpdateAccount;
|
|
48
|
+
priceFeedIdToTwapUpdateAccount;
|
|
48
49
|
closeUpdateAccounts;
|
|
49
50
|
constructor(pythSolanaReceiver, config, addressLookupTable) {
|
|
50
51
|
super(pythSolanaReceiver.wallet.publicKey, pythSolanaReceiver.connection, addressLookupTable);
|
|
51
52
|
this.pythSolanaReceiver = pythSolanaReceiver;
|
|
52
53
|
this.closeInstructions = [];
|
|
53
54
|
this.priceFeedIdToPriceUpdateAccount = {};
|
|
55
|
+
this.priceFeedIdToTwapUpdateAccount = {};
|
|
54
56
|
this.closeUpdateAccounts = config.closeUpdateAccounts ?? true;
|
|
55
57
|
}
|
|
56
58
|
/**
|
|
@@ -109,6 +111,32 @@ class PythTransactionBuilder extends solana_utils_1.TransactionBuilder {
|
|
|
109
111
|
Object.assign(this.priceFeedIdToPriceUpdateAccount, priceFeedIdToPriceUpdateAccount);
|
|
110
112
|
this.addInstructions(postInstructions);
|
|
111
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Add instructions to post TWAP updates to the builder.
|
|
116
|
+
* Use this function to post fully verified TWAP updates from the present or from the past for your program to consume.
|
|
117
|
+
*
|
|
118
|
+
* @param twapUpdateDataArray the output of the `@pythnetwork/hermes-client`'s `getLatestTwaps`. This is an array of verifiable price updates.
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```typescript
|
|
122
|
+
* // Get the price feed ids from https://pyth.network/developers/price-feed-ids#pyth-evm-stable
|
|
123
|
+
* const twapUpdateData = await hermesClient.getLatestTwaps([
|
|
124
|
+
* SOL_PRICE_FEED_ID,
|
|
125
|
+
* ETH_PRICE_FEED_ID,
|
|
126
|
+
* ]);
|
|
127
|
+
*
|
|
128
|
+
* const transactionBuilder = pythSolanaReceiver.newTransactionBuilder({});
|
|
129
|
+
* await transactionBuilder.addPostTwapUpdates(priceUpdateData);
|
|
130
|
+
* console.log("The SOL/USD price update will get posted to:", transactionBuilder.getTwapUpdateAccount(SOL_PRICE_FEED_ID).toBase58())
|
|
131
|
+
* await transactionBuilder.addTwapConsumerInstructions(...)
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
async addPostTwapUpdates(twapUpdateDataArray) {
|
|
135
|
+
const { postInstructions, priceFeedIdToTwapUpdateAccount, closeInstructions, } = await this.pythSolanaReceiver.buildPostTwapUpdateInstructions(twapUpdateDataArray);
|
|
136
|
+
this.closeInstructions.push(...closeInstructions);
|
|
137
|
+
Object.assign(this.priceFeedIdToTwapUpdateAccount, priceFeedIdToTwapUpdateAccount);
|
|
138
|
+
this.addInstructions(postInstructions);
|
|
139
|
+
}
|
|
112
140
|
/**
|
|
113
141
|
* Add instructions to update price feed accounts to the builder.
|
|
114
142
|
* Price feed accounts are fixed accounts per price feed id that can only be updated with a more recent price.
|
|
@@ -169,6 +197,39 @@ class PythTransactionBuilder extends solana_utils_1.TransactionBuilder {
|
|
|
169
197
|
async addPriceConsumerInstructions(getInstructions) {
|
|
170
198
|
this.addInstructions(await getInstructions(this.getPriceUpdateAccount.bind(this)));
|
|
171
199
|
}
|
|
200
|
+
/**
|
|
201
|
+
* Add instructions that consume TWAP updates to the builder.
|
|
202
|
+
*
|
|
203
|
+
* @param getInstructions a function that given a mapping of price feed IDs to TWAP update accounts, generates a series of instructions. TWAP updates get posted to ephemeral accounts and this function allows the user to indicate which accounts in their instruction need to be "replaced" with each price update account.
|
|
204
|
+
* If multiple TWAP updates for the same price feed ID are posted with the same builder, the account corresponding to the last update to get posted will be used.
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```typescript
|
|
208
|
+
* ...
|
|
209
|
+
* await transactionBuilder.addPostTwapUpdates(twapUpdateData);
|
|
210
|
+
* await transactionBuilder.addTwapConsumerInstructions(
|
|
211
|
+
* async (
|
|
212
|
+
* getTwapUpdateAccount: ( priceFeedId: string) => PublicKey
|
|
213
|
+
* ): Promise<InstructionWithEphemeralSigners[]> => {
|
|
214
|
+
* return [
|
|
215
|
+
* {
|
|
216
|
+
* instruction: await myFirstPythApp.methods
|
|
217
|
+
* .consume()
|
|
218
|
+
* .accounts({
|
|
219
|
+
* solTwapUpdate: getTwapUpdateAccount(SOL_PRICE_FEED_ID),
|
|
220
|
+
* ethTwapUpdate: getTwapUpdateAccount(ETH_PRICE_FEED_ID),
|
|
221
|
+
* })
|
|
222
|
+
* .instruction(),
|
|
223
|
+
* signers: [],
|
|
224
|
+
* },
|
|
225
|
+
* ];
|
|
226
|
+
* }
|
|
227
|
+
* );
|
|
228
|
+
* ```
|
|
229
|
+
*/
|
|
230
|
+
async addTwapConsumerInstructions(getInstructions) {
|
|
231
|
+
this.addInstructions(await getInstructions(this.getTwapUpdateAccount.bind(this)));
|
|
232
|
+
}
|
|
172
233
|
/** Add instructions to close encoded VAA accounts from previous actions.
|
|
173
234
|
* If you have previously used the PythTransactionBuilder with closeUpdateAccounts set to false or if you posted encoded VAAs but the transaction to close them did not land on-chain, your wallet might own many encoded VAA accounts.
|
|
174
235
|
* The rent cost for these accounts is 0.008 SOL per encoded VAA account. You can recover this rent calling this function when building a set of transactions.
|
|
@@ -205,6 +266,17 @@ class PythTransactionBuilder extends solana_utils_1.TransactionBuilder {
|
|
|
205
266
|
}
|
|
206
267
|
return priceUpdateAccount;
|
|
207
268
|
}
|
|
269
|
+
/**
|
|
270
|
+
* This method is used to retrieve the address of the TWAP update account where the TWAP update for a given price feed ID will be posted.
|
|
271
|
+
* If multiple updates for the same price feed ID will be posted with the same builder, the address of the account corresponding to the last update to get posted will be returned.
|
|
272
|
+
* */
|
|
273
|
+
getTwapUpdateAccount(priceFeedId) {
|
|
274
|
+
const twapUpdateAccount = this.priceFeedIdToTwapUpdateAccount[priceFeedId];
|
|
275
|
+
if (!twapUpdateAccount) {
|
|
276
|
+
throw new Error(`No TWAP update account found for the price feed ID ${priceFeedId}. Make sure to call addPostTwapUpdates before calling this function.`);
|
|
277
|
+
}
|
|
278
|
+
return twapUpdateAccount;
|
|
279
|
+
}
|
|
208
280
|
}
|
|
209
281
|
exports.PythTransactionBuilder = PythTransactionBuilder;
|
|
210
282
|
/**
|
|
@@ -286,50 +358,6 @@ class PythSolanaReceiver {
|
|
|
286
358
|
closeInstructions,
|
|
287
359
|
};
|
|
288
360
|
}
|
|
289
|
-
/**
|
|
290
|
-
* Build a series of helper instructions that post a VAA in an encoded VAA account. This function is bespoke for posting Pyth VAAs and might not work for other usecases.
|
|
291
|
-
*
|
|
292
|
-
* @param vaa a Wormhole VAA
|
|
293
|
-
* @returns `postInstructions`: the instructions to post the VAA
|
|
294
|
-
* @returns `encodedVaaAddress`: the address of the encoded VAA account where the VAA will be posted
|
|
295
|
-
* @returns `closeInstructions`: the instructions to close the encoded VAA account
|
|
296
|
-
*/
|
|
297
|
-
async buildPostEncodedVaaInstructions(vaa) {
|
|
298
|
-
const trimmedVaa = (0, vaa_1.trimSignatures)(vaa, 13);
|
|
299
|
-
const postInstructions = [];
|
|
300
|
-
const closeInstructions = [];
|
|
301
|
-
const encodedVaaKeypair = new web3_js_1.Keypair();
|
|
302
|
-
const guardianSetIndex = (0, vaa_1.getGuardianSetIndex)(trimmedVaa);
|
|
303
|
-
postInstructions.push(await (0, vaa_1.buildEncodedVaaCreateInstruction)(this.wormhole, trimmedVaa, encodedVaaKeypair));
|
|
304
|
-
postInstructions.push({
|
|
305
|
-
instruction: await this.wormhole.methods
|
|
306
|
-
.initEncodedVaa()
|
|
307
|
-
.accounts({
|
|
308
|
-
encodedVaa: encodedVaaKeypair.publicKey,
|
|
309
|
-
})
|
|
310
|
-
.instruction(),
|
|
311
|
-
signers: [],
|
|
312
|
-
computeUnits: compute_budget_1.INIT_ENCODED_VAA_COMPUTE_BUDGET,
|
|
313
|
-
});
|
|
314
|
-
postInstructions.push(...(await (0, vaa_1.buildWriteEncodedVaaWithSplitInstructions)(this.wormhole, trimmedVaa, encodedVaaKeypair.publicKey)));
|
|
315
|
-
postInstructions.push({
|
|
316
|
-
instruction: await this.wormhole.methods
|
|
317
|
-
.verifyEncodedVaaV1()
|
|
318
|
-
.accounts({
|
|
319
|
-
guardianSet: (0, address_1.getGuardianSetPda)(guardianSetIndex, this.wormhole.programId),
|
|
320
|
-
draftVaa: encodedVaaKeypair.publicKey,
|
|
321
|
-
})
|
|
322
|
-
.instruction(),
|
|
323
|
-
signers: [],
|
|
324
|
-
computeUnits: compute_budget_1.VERIFY_ENCODED_VAA_COMPUTE_BUDGET,
|
|
325
|
-
});
|
|
326
|
-
closeInstructions.push(await this.buildCloseEncodedVaaInstruction(encodedVaaKeypair.publicKey));
|
|
327
|
-
return {
|
|
328
|
-
postInstructions,
|
|
329
|
-
encodedVaaAddress: encodedVaaKeypair.publicKey,
|
|
330
|
-
closeInstructions,
|
|
331
|
-
};
|
|
332
|
-
}
|
|
333
361
|
/**
|
|
334
362
|
* Build a series of helper instructions that post price updates to the Pyth Solana Receiver program and another series to close the encoded vaa accounts and the price update accounts.
|
|
335
363
|
*
|
|
@@ -376,6 +404,63 @@ class PythSolanaReceiver {
|
|
|
376
404
|
closeInstructions,
|
|
377
405
|
};
|
|
378
406
|
}
|
|
407
|
+
/**
|
|
408
|
+
* Build a series of helper instructions that post TWAP updates to the Pyth Solana Receiver program and another series to close the encoded vaa accounts and the TWAP update accounts.
|
|
409
|
+
*
|
|
410
|
+
* @param twapUpdateDataArray the output of the `@pythnetwork/price-service-client`'s `PriceServiceConnection.getLatestTwaps`. This is an array of verifiable price updates.
|
|
411
|
+
* @returns `postInstructions`: the instructions to post the TWAP updates, these should be called before consuming the price updates
|
|
412
|
+
* @returns `priceFeedIdToTwapUpdateAccount`: this is a map of price feed IDs to Solana address. Given a price feed ID, you can use this map to find the account where `postInstructions` will post the TWAP update.
|
|
413
|
+
* @returns `closeInstructions`: the instructions to close the TWAP update accounts, these should be called after consuming the TWAP updates
|
|
414
|
+
*/
|
|
415
|
+
async buildPostTwapUpdateInstructions(twapUpdateDataArray) {
|
|
416
|
+
const postInstructions = [];
|
|
417
|
+
const priceFeedIdToTwapUpdateAccount = {};
|
|
418
|
+
const closeInstructions = [];
|
|
419
|
+
const treasuryId = (0, address_1.getRandomTreasuryId)();
|
|
420
|
+
if (twapUpdateDataArray.length !== 2) {
|
|
421
|
+
throw new Error("twapUpdateDataArray must contain exactly two updates (start and end)");
|
|
422
|
+
}
|
|
423
|
+
const [startUpdateData, endUpdateData] = twapUpdateDataArray.map((data) => (0, price_service_sdk_1.parseAccumulatorUpdateData)(Buffer.from(data, "base64")));
|
|
424
|
+
// Validate that the start and end updates contain the same number of price feeds
|
|
425
|
+
if (startUpdateData.updates.length !== endUpdateData.updates.length) {
|
|
426
|
+
throw new Error("Start and end updates must contain the same number of price feeds");
|
|
427
|
+
}
|
|
428
|
+
// Post encoded VAAs
|
|
429
|
+
const { postInstructions: buildVaasInstructions, closeInstructions: closeVaasInstructions, startEncodedVaaAddress, endEncodedVaaAddress, } = await (0, vaa_1.buildPostEncodedVaasForTwapInstructions)(this.wormhole, startUpdateData, endUpdateData);
|
|
430
|
+
postInstructions.push(...buildVaasInstructions);
|
|
431
|
+
closeInstructions.push(...closeVaasInstructions);
|
|
432
|
+
// Post a TWAP update to the receiver contract for each price feed
|
|
433
|
+
for (let i = 0; i < startUpdateData.updates.length; i++) {
|
|
434
|
+
const startUpdate = startUpdateData.updates[i];
|
|
435
|
+
const endUpdate = endUpdateData.updates[i];
|
|
436
|
+
const twapUpdateKeypair = new web3_js_1.Keypair();
|
|
437
|
+
postInstructions.push({
|
|
438
|
+
instruction: await this.receiver.methods
|
|
439
|
+
.postTwapUpdate({
|
|
440
|
+
startMerklePriceUpdate: startUpdate,
|
|
441
|
+
endMerklePriceUpdate: endUpdate,
|
|
442
|
+
treasuryId,
|
|
443
|
+
})
|
|
444
|
+
.accounts({
|
|
445
|
+
startEncodedVaa: startEncodedVaaAddress,
|
|
446
|
+
endEncodedVaa: endEncodedVaaAddress,
|
|
447
|
+
twapUpdateAccount: twapUpdateKeypair.publicKey,
|
|
448
|
+
treasury: (0, address_1.getTreasuryPda)(treasuryId, this.receiver.programId),
|
|
449
|
+
config: (0, address_1.getConfigPda)(this.receiver.programId),
|
|
450
|
+
})
|
|
451
|
+
.instruction(),
|
|
452
|
+
signers: [twapUpdateKeypair],
|
|
453
|
+
computeUnits: compute_budget_1.POST_TWAP_UPDATE_COMPUTE_BUDGET,
|
|
454
|
+
});
|
|
455
|
+
priceFeedIdToTwapUpdateAccount["0x" + (0, price_service_sdk_1.parseTwapMessage)(startUpdate.message).feedId.toString("hex")] = twapUpdateKeypair.publicKey;
|
|
456
|
+
closeInstructions.push(await this.buildCloseTwapUpdateInstruction(twapUpdateKeypair.publicKey));
|
|
457
|
+
}
|
|
458
|
+
return {
|
|
459
|
+
postInstructions,
|
|
460
|
+
priceFeedIdToTwapUpdateAccount,
|
|
461
|
+
closeInstructions,
|
|
462
|
+
};
|
|
463
|
+
}
|
|
379
464
|
/**
|
|
380
465
|
* Build a series of helper instructions that update one or many price feed accounts and another series to close the encoded vaa accounts used to update the price feed accounts.
|
|
381
466
|
*
|
|
@@ -423,19 +508,22 @@ class PythSolanaReceiver {
|
|
|
423
508
|
closeInstructions,
|
|
424
509
|
};
|
|
425
510
|
}
|
|
511
|
+
/**
|
|
512
|
+
* Build a series of helper instructions that post a VAA in an encoded VAA account. This function is bespoke for posting Pyth VAAs and might not work for other usecases.
|
|
513
|
+
*
|
|
514
|
+
* @param vaa a Wormhole VAA
|
|
515
|
+
* @returns `encodedVaaAddress`: the address of the encoded VAA account where the VAA will be posted
|
|
516
|
+
* @returns `postInstructions`: the instructions to post the VAA
|
|
517
|
+
* @returns `closeInstructions`: the instructions to close the encoded VAA account
|
|
518
|
+
*/
|
|
519
|
+
async buildPostEncodedVaaInstructions(vaa) {
|
|
520
|
+
return (0, vaa_1.buildPostEncodedVaaInstructions)(this.wormhole, vaa);
|
|
521
|
+
}
|
|
426
522
|
/**
|
|
427
523
|
* Build an instruction to close an encoded VAA account, recovering the rent.
|
|
428
524
|
*/
|
|
429
525
|
async buildCloseEncodedVaaInstruction(encodedVaa) {
|
|
430
|
-
|
|
431
|
-
.closeEncodedVaa()
|
|
432
|
-
.accounts({ encodedVaa })
|
|
433
|
-
.instruction();
|
|
434
|
-
return {
|
|
435
|
-
instruction,
|
|
436
|
-
signers: [],
|
|
437
|
-
computeUnits: compute_budget_1.CLOSE_ENCODED_VAA_COMPUTE_BUDGET,
|
|
438
|
-
};
|
|
526
|
+
return (0, vaa_1.buildCloseEncodedVaaInstruction)(this.wormhole, encodedVaa);
|
|
439
527
|
}
|
|
440
528
|
/**
|
|
441
529
|
* Build aset of instructions to close all the existing encoded VAA accounts owned by this PythSolanaReceiver's wallet
|
|
@@ -458,6 +546,16 @@ class PythSolanaReceiver {
|
|
|
458
546
|
.instruction();
|
|
459
547
|
return { instruction, signers: [] };
|
|
460
548
|
}
|
|
549
|
+
/**
|
|
550
|
+
* Build an instruction to close a TWAP update account, recovering the rent.
|
|
551
|
+
*/
|
|
552
|
+
async buildCloseTwapUpdateInstruction(twapUpdateAccount) {
|
|
553
|
+
const instruction = await this.receiver.methods
|
|
554
|
+
.reclaimTwapRent()
|
|
555
|
+
.accounts({ twapUpdateAccount })
|
|
556
|
+
.instruction();
|
|
557
|
+
return { instruction, signers: [] };
|
|
558
|
+
}
|
|
461
559
|
/**
|
|
462
560
|
* Returns a set of versioned transactions that contain the provided instructions in the same order and with efficient batching
|
|
463
561
|
*/
|
package/lib/compute_budget.d.ts
CHANGED
|
@@ -10,6 +10,10 @@ export declare const POST_UPDATE_ATOMIC_COMPUTE_BUDGET = 170000;
|
|
|
10
10
|
* A hard-coded budget for the compute units required for the `postUpdate` instruction in the Pyth Solana Receiver program.
|
|
11
11
|
*/
|
|
12
12
|
export declare const POST_UPDATE_COMPUTE_BUDGET = 35000;
|
|
13
|
+
/**
|
|
14
|
+
* A hard-coded budget for the compute units required for the `postTwapUpdate` instruction in the Pyth Solana Receiver program.
|
|
15
|
+
*/
|
|
16
|
+
export declare const POST_TWAP_UPDATE_COMPUTE_BUDGET = 50000;
|
|
13
17
|
/**
|
|
14
18
|
* A hard-coded budget for the compute units required for the `updatePriceFeed` instruction in the Pyth Push Oracle program.
|
|
15
19
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compute_budget.d.ts","sourceRoot":"","sources":["../src/compute_budget.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,iCAAiC,SAAS,CAAC;AACxD;;GAEG;AACH,eAAO,MAAM,iCAAiC,SAAS,CAAC;AACxD;;GAEG;AACH,eAAO,MAAM,0BAA0B,QAAQ,CAAC;AAChD;;GAEG;AACH,eAAO,MAAM,gCAAgC,QAAQ,CAAC;AACtD;;GAEG;AACH,eAAO,MAAM,+BAA+B,OAAO,CAAC;AACpD;;GAEG;AACH,eAAO,MAAM,gCAAgC,OAAO,CAAC;AACrD;;GAEG;AACH,eAAO,MAAM,gCAAgC,QAAQ,CAAC"}
|
|
1
|
+
{"version":3,"file":"compute_budget.d.ts","sourceRoot":"","sources":["../src/compute_budget.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,eAAO,MAAM,iCAAiC,SAAS,CAAC;AACxD;;GAEG;AACH,eAAO,MAAM,iCAAiC,SAAS,CAAC;AACxD;;GAEG;AACH,eAAO,MAAM,0BAA0B,QAAQ,CAAC;AAChD;;GAEG;AACH,eAAO,MAAM,+BAA+B,QAAS,CAAC;AACtD;;GAEG;AACH,eAAO,MAAM,gCAAgC,QAAQ,CAAC;AACtD;;GAEG;AACH,eAAO,MAAM,+BAA+B,OAAO,CAAC;AACpD;;GAEG;AACH,eAAO,MAAM,gCAAgC,OAAO,CAAC;AACrD;;GAEG;AACH,eAAO,MAAM,gCAAgC,QAAQ,CAAC"}
|
package/lib/compute_budget.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CLOSE_ENCODED_VAA_COMPUTE_BUDGET = exports.WRITE_ENCODED_VAA_COMPUTE_BUDGET = exports.INIT_ENCODED_VAA_COMPUTE_BUDGET = exports.UPDATE_PRICE_FEED_COMPUTE_BUDGET = exports.POST_UPDATE_COMPUTE_BUDGET = exports.POST_UPDATE_ATOMIC_COMPUTE_BUDGET = exports.VERIFY_ENCODED_VAA_COMPUTE_BUDGET = void 0;
|
|
3
|
+
exports.CLOSE_ENCODED_VAA_COMPUTE_BUDGET = exports.WRITE_ENCODED_VAA_COMPUTE_BUDGET = exports.INIT_ENCODED_VAA_COMPUTE_BUDGET = exports.UPDATE_PRICE_FEED_COMPUTE_BUDGET = exports.POST_TWAP_UPDATE_COMPUTE_BUDGET = exports.POST_UPDATE_COMPUTE_BUDGET = exports.POST_UPDATE_ATOMIC_COMPUTE_BUDGET = exports.VERIFY_ENCODED_VAA_COMPUTE_BUDGET = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* A hard-coded budget for the compute units required for the `verifyEncodedVaa` instruction in the Wormhole program.
|
|
6
6
|
*/
|
|
@@ -13,6 +13,10 @@ exports.POST_UPDATE_ATOMIC_COMPUTE_BUDGET = 170000;
|
|
|
13
13
|
* A hard-coded budget for the compute units required for the `postUpdate` instruction in the Pyth Solana Receiver program.
|
|
14
14
|
*/
|
|
15
15
|
exports.POST_UPDATE_COMPUTE_BUDGET = 35000;
|
|
16
|
+
/**
|
|
17
|
+
* A hard-coded budget for the compute units required for the `postTwapUpdate` instruction in the Pyth Solana Receiver program.
|
|
18
|
+
*/
|
|
19
|
+
exports.POST_TWAP_UPDATE_COMPUTE_BUDGET = 50_000;
|
|
16
20
|
/**
|
|
17
21
|
* A hard-coded budget for the compute units required for the `updatePriceFeed` instruction in the Pyth Push Oracle program.
|
|
18
22
|
*/
|