@pythnetwork/pyth-solana-receiver 0.13.0 → 0.14.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 +0 -44
- package/dist/{PythSolanaReceiver.cjs → cjs/PythSolanaReceiver.cjs} +8 -147
- package/dist/{PythSolanaReceiver.d.ts → cjs/PythSolanaReceiver.d.ts} +0 -76
- package/dist/{address.cjs → cjs/address.cjs} +7 -5
- package/dist/{compute_budget.cjs → cjs/compute_budget.cjs} +0 -4
- package/dist/{compute_budget.d.ts → cjs/compute_budget.d.ts} +0 -4
- package/dist/{vaa.cjs → cjs/vaa.cjs} +4 -33
- package/dist/{vaa.d.ts → cjs/vaa.d.ts} +0 -25
- package/dist/esm/PythSolanaReceiver.d.ts +318 -0
- package/dist/esm/PythSolanaReceiver.mjs +462 -0
- package/dist/esm/address.d.ts +29 -0
- package/dist/esm/address.mjs +45 -0
- package/dist/esm/compute_budget.d.ts +28 -0
- package/dist/esm/compute_budget.mjs +21 -0
- package/dist/esm/idl/pyth_push_oracle.d.ts +117 -0
- package/dist/esm/idl/pyth_push_oracle.mjs +122 -0
- package/dist/esm/idl/pyth_solana_receiver.d.ts +840 -0
- package/dist/esm/idl/pyth_solana_receiver.mjs +848 -0
- package/dist/esm/idl/wormhole_core_bridge_solana.d.ts +1606 -0
- package/dist/esm/idl/wormhole_core_bridge_solana.mjs +1741 -0
- package/dist/esm/index.d.ts +5 -0
- package/dist/esm/index.mjs +5 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/vaa.d.ts +75 -0
- package/dist/esm/vaa.mjs +197 -0
- package/package.json +74 -25
- /package/dist/{address.d.ts → cjs/address.d.ts} +0 -0
- /package/dist/{idl → cjs/idl}/pyth_push_oracle.cjs +0 -0
- /package/dist/{idl → cjs/idl}/pyth_push_oracle.d.ts +0 -0
- /package/dist/{idl → cjs/idl}/pyth_solana_receiver.cjs +0 -0
- /package/dist/{idl → cjs/idl}/pyth_solana_receiver.d.ts +0 -0
- /package/dist/{idl → cjs/idl}/wormhole_core_bridge_solana.cjs +0 -0
- /package/dist/{idl → cjs/idl}/wormhole_core_bridge_solana.d.ts +0 -0
- /package/dist/{index.cjs → cjs/index.cjs} +0 -0
- /package/dist/{index.d.ts → cjs/index.d.ts} +0 -0
- /package/dist/{package.json → cjs/package.json} +0 -0
package/README.md
CHANGED
|
@@ -175,50 +175,6 @@ Price updates are relatively large and can take multiple transactions to post on
|
|
|
175
175
|
You can reduce the size of the transaction payload by using `addPostPartiallyVerifiedPriceUpdates` instead of `addPostPriceUpdates`.
|
|
176
176
|
This method does sacrifice some security however -- please see the method documentation for more details.
|
|
177
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
|
-
|
|
222
178
|
### Get Instructions
|
|
223
179
|
|
|
224
180
|
The `PythTransactionBuilder` class used in the examples above helps craft transactions that update prices and then use them in successive instructions.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-non-null-assertion */ /* eslint-disable tsdoc/syntax */
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-non-null-assertion */ /* eslint-disable tsdoc/syntax */ // eslint-disable-next-line unicorn/prefer-node-protocol
|
|
2
|
+
"use strict";
|
|
2
3
|
Object.defineProperty(exports, "__esModule", {
|
|
3
4
|
value: true
|
|
4
5
|
});
|
|
@@ -22,6 +23,7 @@ _export(exports, {
|
|
|
22
23
|
return getPriceFeedAccountForProgram;
|
|
23
24
|
}
|
|
24
25
|
});
|
|
26
|
+
const _buffer = require("buffer");
|
|
25
27
|
const _anchor = require("@coral-xyz/anchor");
|
|
26
28
|
const _priceservicesdk = require("@pythnetwork/price-service-sdk");
|
|
27
29
|
const _solanautils = require("@pythnetwork/solana-utils");
|
|
@@ -37,14 +39,12 @@ class PythTransactionBuilder extends _solanautils.TransactionBuilder {
|
|
|
37
39
|
pythSolanaReceiver;
|
|
38
40
|
closeInstructions;
|
|
39
41
|
priceFeedIdToPriceUpdateAccount;
|
|
40
|
-
priceFeedIdToTwapUpdateAccount;
|
|
41
42
|
closeUpdateAccounts;
|
|
42
43
|
constructor(pythSolanaReceiver, config, addressLookupTable){
|
|
43
44
|
super(pythSolanaReceiver.wallet.publicKey, pythSolanaReceiver.connection, addressLookupTable);
|
|
44
45
|
this.pythSolanaReceiver = pythSolanaReceiver;
|
|
45
46
|
this.closeInstructions = [];
|
|
46
47
|
this.priceFeedIdToPriceUpdateAccount = {};
|
|
47
|
-
this.priceFeedIdToTwapUpdateAccount = {};
|
|
48
48
|
this.closeUpdateAccounts = config.closeUpdateAccounts ?? true;
|
|
49
49
|
}
|
|
50
50
|
/**
|
|
@@ -102,31 +102,6 @@ class PythTransactionBuilder extends _solanautils.TransactionBuilder {
|
|
|
102
102
|
this.addInstructions(postInstructions);
|
|
103
103
|
}
|
|
104
104
|
/**
|
|
105
|
-
* Add instructions to post TWAP updates to the builder.
|
|
106
|
-
* Use this function to post fully verified TWAP updates from the present or from the past for your program to consume.
|
|
107
|
-
*
|
|
108
|
-
* @param twapUpdateDataArray the output of the `@pythnetwork/hermes-client`'s `getLatestTwaps`. This is an array of verifiable price updates.
|
|
109
|
-
*
|
|
110
|
-
* @example
|
|
111
|
-
* ```typescript
|
|
112
|
-
* // Get the price feed ids from https://pyth.network/developers/price-feed-ids#pyth-evm-stable
|
|
113
|
-
* const twapUpdateData = await hermesClient.getLatestTwaps([
|
|
114
|
-
* SOL_PRICE_FEED_ID,
|
|
115
|
-
* ETH_PRICE_FEED_ID,
|
|
116
|
-
* ]);
|
|
117
|
-
*
|
|
118
|
-
* const transactionBuilder = pythSolanaReceiver.newTransactionBuilder({});
|
|
119
|
-
* await transactionBuilder.addPostTwapUpdates(priceUpdateData);
|
|
120
|
-
* console.log("The SOL/USD price update will get posted to:", transactionBuilder.getTwapUpdateAccount(SOL_PRICE_FEED_ID).toBase58())
|
|
121
|
-
* await transactionBuilder.addTwapConsumerInstructions(...)
|
|
122
|
-
* ```
|
|
123
|
-
*/ async addPostTwapUpdates(twapUpdateDataArray) {
|
|
124
|
-
const { postInstructions, priceFeedIdToTwapUpdateAccount, closeInstructions } = await this.pythSolanaReceiver.buildPostTwapUpdateInstructions(twapUpdateDataArray);
|
|
125
|
-
this.closeInstructions.push(...closeInstructions);
|
|
126
|
-
Object.assign(this.priceFeedIdToTwapUpdateAccount, priceFeedIdToTwapUpdateAccount);
|
|
127
|
-
this.addInstructions(postInstructions);
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
105
|
* Add instructions to update price feed accounts to the builder.
|
|
131
106
|
* Price feed accounts are fixed accounts per price feed id that can only be updated with a more recent price.
|
|
132
107
|
*
|
|
@@ -184,38 +159,6 @@ class PythTransactionBuilder extends _solanautils.TransactionBuilder {
|
|
|
184
159
|
*/ async addPriceConsumerInstructions(getInstructions) {
|
|
185
160
|
this.addInstructions(await getInstructions(this.getPriceUpdateAccount.bind(this)));
|
|
186
161
|
}
|
|
187
|
-
/**
|
|
188
|
-
* Add instructions that consume TWAP updates to the builder.
|
|
189
|
-
*
|
|
190
|
-
* @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.
|
|
191
|
-
* 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.
|
|
192
|
-
*
|
|
193
|
-
* @example
|
|
194
|
-
* ```typescript
|
|
195
|
-
* ...
|
|
196
|
-
* await transactionBuilder.addPostTwapUpdates(twapUpdateData);
|
|
197
|
-
* await transactionBuilder.addTwapConsumerInstructions(
|
|
198
|
-
* async (
|
|
199
|
-
* getTwapUpdateAccount: ( priceFeedId: string) => PublicKey
|
|
200
|
-
* ): Promise<InstructionWithEphemeralSigners[]> => {
|
|
201
|
-
* return [
|
|
202
|
-
* {
|
|
203
|
-
* instruction: await myFirstPythApp.methods
|
|
204
|
-
* .consume()
|
|
205
|
-
* .accounts({
|
|
206
|
-
* solTwapUpdate: getTwapUpdateAccount(SOL_PRICE_FEED_ID),
|
|
207
|
-
* ethTwapUpdate: getTwapUpdateAccount(ETH_PRICE_FEED_ID),
|
|
208
|
-
* })
|
|
209
|
-
* .instruction(),
|
|
210
|
-
* signers: [],
|
|
211
|
-
* },
|
|
212
|
-
* ];
|
|
213
|
-
* }
|
|
214
|
-
* );
|
|
215
|
-
* ```
|
|
216
|
-
*/ async addTwapConsumerInstructions(getInstructions) {
|
|
217
|
-
this.addInstructions(await getInstructions(this.getTwapUpdateAccount.bind(this)));
|
|
218
|
-
}
|
|
219
162
|
/** Add instructions to close encoded VAA accounts from previous actions.
|
|
220
163
|
* 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.
|
|
221
164
|
* 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.
|
|
@@ -248,16 +191,6 @@ class PythTransactionBuilder extends _solanautils.TransactionBuilder {
|
|
|
248
191
|
}
|
|
249
192
|
return priceUpdateAccount;
|
|
250
193
|
}
|
|
251
|
-
/**
|
|
252
|
-
* 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.
|
|
253
|
-
* 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.
|
|
254
|
-
* */ getTwapUpdateAccount(priceFeedId) {
|
|
255
|
-
const twapUpdateAccount = this.priceFeedIdToTwapUpdateAccount[priceFeedId];
|
|
256
|
-
if (!twapUpdateAccount) {
|
|
257
|
-
throw new Error(`No TWAP update account found for the price feed ID ${priceFeedId}. Make sure to call addPostTwapUpdates before calling this function.`);
|
|
258
|
-
}
|
|
259
|
-
return twapUpdateAccount;
|
|
260
|
-
}
|
|
261
194
|
}
|
|
262
195
|
class PythSolanaReceiver {
|
|
263
196
|
connection;
|
|
@@ -302,7 +235,7 @@ class PythSolanaReceiver {
|
|
|
302
235
|
const closeInstructions = [];
|
|
303
236
|
const treasuryId = this.treasuryId ?? (0, _address.getRandomTreasuryId)();
|
|
304
237
|
for (const priceUpdateData of priceUpdateDataArray){
|
|
305
|
-
const accumulatorUpdateData = (0, _priceservicesdk.parseAccumulatorUpdateData)(Buffer.from(priceUpdateData, "base64"));
|
|
238
|
+
const accumulatorUpdateData = (0, _priceservicesdk.parseAccumulatorUpdateData)(_buffer.Buffer.from(priceUpdateData, "base64"));
|
|
306
239
|
const guardianSetIndex = (0, _vaa.getGuardianSetIndex)(accumulatorUpdateData.vaa);
|
|
307
240
|
const trimmedVaa = (0, _vaa.trimSignatures)(accumulatorUpdateData.vaa);
|
|
308
241
|
for (const update of accumulatorUpdateData.updates){
|
|
@@ -346,7 +279,7 @@ class PythSolanaReceiver {
|
|
|
346
279
|
const closeInstructions = [];
|
|
347
280
|
const treasuryId = this.treasuryId ?? (0, _address.getRandomTreasuryId)();
|
|
348
281
|
for (const priceUpdateData of priceUpdateDataArray){
|
|
349
|
-
const accumulatorUpdateData = (0, _priceservicesdk.parseAccumulatorUpdateData)(Buffer.from(priceUpdateData, "base64"));
|
|
282
|
+
const accumulatorUpdateData = (0, _priceservicesdk.parseAccumulatorUpdateData)(_buffer.Buffer.from(priceUpdateData, "base64"));
|
|
350
283
|
const { postInstructions: postEncodedVaaInstructions, encodedVaaAddress: encodedVaa, closeInstructions: postEncodedVaacloseInstructions } = await this.buildPostEncodedVaaInstructions(accumulatorUpdateData.vaa);
|
|
351
284
|
postInstructions.push(...postEncodedVaaInstructions);
|
|
352
285
|
closeInstructions.push(...postEncodedVaacloseInstructions);
|
|
@@ -378,67 +311,6 @@ class PythSolanaReceiver {
|
|
|
378
311
|
};
|
|
379
312
|
}
|
|
380
313
|
/**
|
|
381
|
-
* 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.
|
|
382
|
-
*
|
|
383
|
-
* @param twapUpdateDataArray the output of the `@pythnetwork/price-service-client`'s `PriceServiceConnection.getLatestTwaps`. This is an array of verifiable price updates.
|
|
384
|
-
* @returns `postInstructions`: the instructions to post the TWAP updates, these should be called before consuming the price updates
|
|
385
|
-
* @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.
|
|
386
|
-
* @returns `closeInstructions`: the instructions to close the TWAP update accounts, these should be called after consuming the TWAP updates
|
|
387
|
-
*/ async buildPostTwapUpdateInstructions(twapUpdateDataArray) {
|
|
388
|
-
const postInstructions = [];
|
|
389
|
-
const priceFeedIdToTwapUpdateAccount = {};
|
|
390
|
-
const closeInstructions = [];
|
|
391
|
-
const treasuryId = this.treasuryId ?? (0, _address.getRandomTreasuryId)();
|
|
392
|
-
if (twapUpdateDataArray.length !== 2) {
|
|
393
|
-
throw new Error("twapUpdateDataArray must contain exactly two updates (start and end)");
|
|
394
|
-
}
|
|
395
|
-
const [startUpdateData, endUpdateData] = twapUpdateDataArray.map((data)=>(0, _priceservicesdk.parseAccumulatorUpdateData)(Buffer.from(data, "base64")));
|
|
396
|
-
if (!startUpdateData) {
|
|
397
|
-
throw new Error("startUpdateData is undefined. this is a bug 🐛");
|
|
398
|
-
}
|
|
399
|
-
if (!endUpdateData) {
|
|
400
|
-
throw new Error("startUpdateData is undefined. this is a bug 🐛");
|
|
401
|
-
}
|
|
402
|
-
// Validate that the start and end updates contain the same number of price feeds
|
|
403
|
-
if (startUpdateData.updates.length !== endUpdateData.updates.length) {
|
|
404
|
-
throw new Error("Start and end updates must contain the same number of price feeds");
|
|
405
|
-
}
|
|
406
|
-
// Post encoded VAAs
|
|
407
|
-
const { postInstructions: buildVaasInstructions, closeInstructions: closeVaasInstructions, startEncodedVaaAddress, endEncodedVaaAddress } = await (0, _vaa.buildPostEncodedVaasForTwapInstructions)(this.wormhole, startUpdateData, endUpdateData);
|
|
408
|
-
postInstructions.push(...buildVaasInstructions);
|
|
409
|
-
closeInstructions.push(...closeVaasInstructions);
|
|
410
|
-
// Post a TWAP update to the receiver contract for each price feed
|
|
411
|
-
for(let i = 0; i < startUpdateData.updates.length; i++){
|
|
412
|
-
const startUpdate = startUpdateData.updates[i];
|
|
413
|
-
const endUpdate = endUpdateData.updates[i];
|
|
414
|
-
const twapUpdateKeypair = new _web3.Keypair();
|
|
415
|
-
postInstructions.push({
|
|
416
|
-
instruction: await this.receiver.methods.postTwapUpdate({
|
|
417
|
-
startMerklePriceUpdate: startUpdate,
|
|
418
|
-
endMerklePriceUpdate: endUpdate,
|
|
419
|
-
treasuryId
|
|
420
|
-
}).accounts({
|
|
421
|
-
startEncodedVaa: startEncodedVaaAddress,
|
|
422
|
-
endEncodedVaa: endEncodedVaaAddress,
|
|
423
|
-
twapUpdateAccount: twapUpdateKeypair.publicKey,
|
|
424
|
-
treasury: (0, _address.getTreasuryPda)(treasuryId, this.receiver.programId),
|
|
425
|
-
config: (0, _address.getConfigPda)(this.receiver.programId)
|
|
426
|
-
}).instruction(),
|
|
427
|
-
signers: [
|
|
428
|
-
twapUpdateKeypair
|
|
429
|
-
],
|
|
430
|
-
computeUnits: _compute_budget.POST_TWAP_UPDATE_COMPUTE_BUDGET
|
|
431
|
-
});
|
|
432
|
-
priceFeedIdToTwapUpdateAccount["0x" + (0, _priceservicesdk.parseTwapMessage)(startUpdate.message).feedId.toString("hex")] = twapUpdateKeypair.publicKey;
|
|
433
|
-
closeInstructions.push(await this.buildCloseTwapUpdateInstruction(twapUpdateKeypair.publicKey));
|
|
434
|
-
}
|
|
435
|
-
return {
|
|
436
|
-
postInstructions,
|
|
437
|
-
priceFeedIdToTwapUpdateAccount,
|
|
438
|
-
closeInstructions
|
|
439
|
-
};
|
|
440
|
-
}
|
|
441
|
-
/**
|
|
442
314
|
* 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.
|
|
443
315
|
*
|
|
444
316
|
* @param priceUpdateDataArray the output of the `@pythnetwork/price-service-client`'s `PriceServiceConnection.getLatestVaas`. This is an array of verifiable price updates.
|
|
@@ -452,7 +324,7 @@ class PythSolanaReceiver {
|
|
|
452
324
|
const closeInstructions = [];
|
|
453
325
|
const treasuryId = this.treasuryId ?? (0, _address.getRandomTreasuryId)();
|
|
454
326
|
for (const priceUpdateData of priceUpdateDataArray){
|
|
455
|
-
const accumulatorUpdateData = (0, _priceservicesdk.parseAccumulatorUpdateData)(Buffer.from(priceUpdateData, "base64"));
|
|
327
|
+
const accumulatorUpdateData = (0, _priceservicesdk.parseAccumulatorUpdateData)(_buffer.Buffer.from(priceUpdateData, "base64"));
|
|
456
328
|
const { postInstructions: postEncodedVaaInstructions, encodedVaaAddress: encodedVaa, closeInstructions: postEncodedVaacloseInstructions } = await this.buildPostEncodedVaaInstructions(accumulatorUpdateData.vaa);
|
|
457
329
|
postInstructions.push(...postEncodedVaaInstructions);
|
|
458
330
|
closeInstructions.push(...postEncodedVaacloseInstructions);
|
|
@@ -520,17 +392,6 @@ class PythSolanaReceiver {
|
|
|
520
392
|
};
|
|
521
393
|
}
|
|
522
394
|
/**
|
|
523
|
-
* Build an instruction to close a TWAP update account, recovering the rent.
|
|
524
|
-
*/ async buildCloseTwapUpdateInstruction(twapUpdateAccount) {
|
|
525
|
-
const instruction = await this.receiver.methods.reclaimTwapRent().accounts({
|
|
526
|
-
twapUpdateAccount
|
|
527
|
-
}).instruction();
|
|
528
|
-
return {
|
|
529
|
-
instruction,
|
|
530
|
-
signers: []
|
|
531
|
-
};
|
|
532
|
-
}
|
|
533
|
-
/**
|
|
534
395
|
* Returns a set of versioned transactions that contain the provided instructions in the same order and with efficient batching
|
|
535
396
|
*/ async batchIntoVersionedTransactions(instructions, priorityFeeConfig, addressLookupTable) {
|
|
536
397
|
return _solanautils.TransactionBuilder.batchIntoVersionedTransactions(this.wallet.publicKey, this.connection, instructions, priorityFeeConfig, addressLookupTable);
|
|
@@ -567,12 +428,12 @@ class PythSolanaReceiver {
|
|
|
567
428
|
}
|
|
568
429
|
function getPriceFeedAccountForProgram(shardId, priceFeedId, pushOracleProgramId) {
|
|
569
430
|
if (typeof priceFeedId == "string") {
|
|
570
|
-
priceFeedId = priceFeedId.startsWith("0x") ? Buffer.from(priceFeedId.slice(2), "hex") : Buffer.from(priceFeedId, "hex");
|
|
431
|
+
priceFeedId = priceFeedId.startsWith("0x") ? _buffer.Buffer.from(priceFeedId.slice(2), "hex") : _buffer.Buffer.from(priceFeedId, "hex");
|
|
571
432
|
}
|
|
572
433
|
if (priceFeedId.length != 32) {
|
|
573
434
|
throw new Error("Feed ID should be 32 bytes long");
|
|
574
435
|
}
|
|
575
|
-
const shardBuffer = Buffer.alloc(2);
|
|
436
|
+
const shardBuffer = _buffer.Buffer.alloc(2);
|
|
576
437
|
shardBuffer.writeUint16LE(shardId, 0);
|
|
577
438
|
return _web3.PublicKey.findProgramAddressSync([
|
|
578
439
|
shardBuffer,
|
|
@@ -8,7 +8,6 @@ import type { PythPushOracle } from "./idl/pyth_push_oracle";
|
|
|
8
8
|
import type { PythSolanaReceiver as PythSolanaReceiverProgram } from "./idl/pyth_solana_receiver";
|
|
9
9
|
import type { WormholeCoreBridgeSolana } from "./idl/wormhole_core_bridge_solana";
|
|
10
10
|
export type PriceUpdateAccount = IdlAccounts<PythSolanaReceiverProgram>["priceUpdateV2"];
|
|
11
|
-
export type TwapUpdateAccount = IdlAccounts<PythSolanaReceiverProgram>["twapUpdate"];
|
|
12
11
|
/**
|
|
13
12
|
* Configuration for the PythTransactionBuilder
|
|
14
13
|
* @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
|
|
@@ -55,7 +54,6 @@ export declare class PythTransactionBuilder extends TransactionBuilder {
|
|
|
55
54
|
readonly pythSolanaReceiver: PythSolanaReceiver;
|
|
56
55
|
readonly closeInstructions: InstructionWithEphemeralSigners[];
|
|
57
56
|
readonly priceFeedIdToPriceUpdateAccount: Record<string, PublicKey>;
|
|
58
|
-
readonly priceFeedIdToTwapUpdateAccount: Record<string, PublicKey>;
|
|
59
57
|
readonly closeUpdateAccounts: boolean;
|
|
60
58
|
constructor(pythSolanaReceiver: PythSolanaReceiver, config: PythTransactionBuilderConfig, addressLookupTable?: AddressLookupTableAccount);
|
|
61
59
|
/**
|
|
@@ -104,27 +102,6 @@ export declare class PythTransactionBuilder extends TransactionBuilder {
|
|
|
104
102
|
* ```
|
|
105
103
|
*/
|
|
106
104
|
addPostPartiallyVerifiedPriceUpdates(priceUpdateDataArray: string[]): Promise<void>;
|
|
107
|
-
/**
|
|
108
|
-
* Add instructions to post TWAP updates to the builder.
|
|
109
|
-
* Use this function to post fully verified TWAP updates from the present or from the past for your program to consume.
|
|
110
|
-
*
|
|
111
|
-
* @param twapUpdateDataArray the output of the `@pythnetwork/hermes-client`'s `getLatestTwaps`. This is an array of verifiable price updates.
|
|
112
|
-
*
|
|
113
|
-
* @example
|
|
114
|
-
* ```typescript
|
|
115
|
-
* // Get the price feed ids from https://pyth.network/developers/price-feed-ids#pyth-evm-stable
|
|
116
|
-
* const twapUpdateData = await hermesClient.getLatestTwaps([
|
|
117
|
-
* SOL_PRICE_FEED_ID,
|
|
118
|
-
* ETH_PRICE_FEED_ID,
|
|
119
|
-
* ]);
|
|
120
|
-
*
|
|
121
|
-
* const transactionBuilder = pythSolanaReceiver.newTransactionBuilder({});
|
|
122
|
-
* await transactionBuilder.addPostTwapUpdates(priceUpdateData);
|
|
123
|
-
* console.log("The SOL/USD price update will get posted to:", transactionBuilder.getTwapUpdateAccount(SOL_PRICE_FEED_ID).toBase58())
|
|
124
|
-
* await transactionBuilder.addTwapConsumerInstructions(...)
|
|
125
|
-
* ```
|
|
126
|
-
*/
|
|
127
|
-
addPostTwapUpdates(twapUpdateDataArray: string[]): Promise<void>;
|
|
128
105
|
/**
|
|
129
106
|
* Add instructions to update price feed accounts to the builder.
|
|
130
107
|
* Price feed accounts are fixed accounts per price feed id that can only be updated with a more recent price.
|
|
@@ -178,37 +155,6 @@ export declare class PythTransactionBuilder extends TransactionBuilder {
|
|
|
178
155
|
* ```
|
|
179
156
|
*/
|
|
180
157
|
addPriceConsumerInstructions(getInstructions: (getPriceUpdateAccount: (priceFeedId: string) => PublicKey) => Promise<InstructionWithEphemeralSigners[]>): Promise<void>;
|
|
181
|
-
/**
|
|
182
|
-
* Add instructions that consume TWAP updates to the builder.
|
|
183
|
-
*
|
|
184
|
-
* @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.
|
|
185
|
-
* 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.
|
|
186
|
-
*
|
|
187
|
-
* @example
|
|
188
|
-
* ```typescript
|
|
189
|
-
* ...
|
|
190
|
-
* await transactionBuilder.addPostTwapUpdates(twapUpdateData);
|
|
191
|
-
* await transactionBuilder.addTwapConsumerInstructions(
|
|
192
|
-
* async (
|
|
193
|
-
* getTwapUpdateAccount: ( priceFeedId: string) => PublicKey
|
|
194
|
-
* ): Promise<InstructionWithEphemeralSigners[]> => {
|
|
195
|
-
* return [
|
|
196
|
-
* {
|
|
197
|
-
* instruction: await myFirstPythApp.methods
|
|
198
|
-
* .consume()
|
|
199
|
-
* .accounts({
|
|
200
|
-
* solTwapUpdate: getTwapUpdateAccount(SOL_PRICE_FEED_ID),
|
|
201
|
-
* ethTwapUpdate: getTwapUpdateAccount(ETH_PRICE_FEED_ID),
|
|
202
|
-
* })
|
|
203
|
-
* .instruction(),
|
|
204
|
-
* signers: [],
|
|
205
|
-
* },
|
|
206
|
-
* ];
|
|
207
|
-
* }
|
|
208
|
-
* );
|
|
209
|
-
* ```
|
|
210
|
-
*/
|
|
211
|
-
addTwapConsumerInstructions(getInstructions: (getTwapUpdateAccount: (priceFeedId: string) => PublicKey) => Promise<InstructionWithEphemeralSigners[]>): Promise<void>;
|
|
212
158
|
/** Add instructions to close encoded VAA accounts from previous actions.
|
|
213
159
|
* 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.
|
|
214
160
|
* 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.
|
|
@@ -233,11 +179,6 @@ export declare class PythTransactionBuilder extends TransactionBuilder {
|
|
|
233
179
|
* 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.
|
|
234
180
|
* */
|
|
235
181
|
getPriceUpdateAccount(priceFeedId: string): PublicKey;
|
|
236
|
-
/**
|
|
237
|
-
* 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.
|
|
238
|
-
* 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.
|
|
239
|
-
* */
|
|
240
|
-
getTwapUpdateAccount(priceFeedId: string): PublicKey;
|
|
241
182
|
}
|
|
242
183
|
/**
|
|
243
184
|
* A class to interact with the Pyth Solana Receiver program.
|
|
@@ -295,19 +236,6 @@ export declare class PythSolanaReceiver {
|
|
|
295
236
|
priceFeedIdToPriceUpdateAccount: Record<string, PublicKey>;
|
|
296
237
|
closeInstructions: InstructionWithEphemeralSigners[];
|
|
297
238
|
}>;
|
|
298
|
-
/**
|
|
299
|
-
* 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.
|
|
300
|
-
*
|
|
301
|
-
* @param twapUpdateDataArray the output of the `@pythnetwork/price-service-client`'s `PriceServiceConnection.getLatestTwaps`. This is an array of verifiable price updates.
|
|
302
|
-
* @returns `postInstructions`: the instructions to post the TWAP updates, these should be called before consuming the price updates
|
|
303
|
-
* @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.
|
|
304
|
-
* @returns `closeInstructions`: the instructions to close the TWAP update accounts, these should be called after consuming the TWAP updates
|
|
305
|
-
*/
|
|
306
|
-
buildPostTwapUpdateInstructions(twapUpdateDataArray: string[]): Promise<{
|
|
307
|
-
postInstructions: InstructionWithEphemeralSigners[];
|
|
308
|
-
priceFeedIdToTwapUpdateAccount: Record<string, PublicKey>;
|
|
309
|
-
closeInstructions: InstructionWithEphemeralSigners[];
|
|
310
|
-
}>;
|
|
311
239
|
/**
|
|
312
240
|
* 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.
|
|
313
241
|
*
|
|
@@ -347,10 +275,6 @@ export declare class PythSolanaReceiver {
|
|
|
347
275
|
* Build an instruction to close a price update account, recovering the rent.
|
|
348
276
|
*/
|
|
349
277
|
buildClosePriceUpdateInstruction(priceUpdateAccount: PublicKey): Promise<InstructionWithEphemeralSigners>;
|
|
350
|
-
/**
|
|
351
|
-
* Build an instruction to close a TWAP update account, recovering the rent.
|
|
352
|
-
*/
|
|
353
|
-
buildCloseTwapUpdateInstruction(twapUpdateAccount: PublicKey): Promise<InstructionWithEphemeralSigners>;
|
|
354
278
|
/**
|
|
355
279
|
* Returns a set of versioned transactions that contain the provided instructions in the same order and with efficient batching
|
|
356
280
|
*/
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// eslint-disable-next-line unicorn/prefer-node-protocol
|
|
1
2
|
"use strict";
|
|
2
3
|
Object.defineProperty(exports, "__esModule", {
|
|
3
4
|
value: true
|
|
@@ -31,15 +32,16 @@ _export(exports, {
|
|
|
31
32
|
return getTreasuryPda;
|
|
32
33
|
}
|
|
33
34
|
});
|
|
35
|
+
const _buffer = require("buffer");
|
|
34
36
|
const _web3 = require("@solana/web3.js");
|
|
35
37
|
const DEFAULT_RECEIVER_PROGRAM_ID = new _web3.PublicKey("rec5EKMGg6MxZYaMdyBfgwp4d5rB9T1VQH5pJv5LtFJ");
|
|
36
38
|
const DEFAULT_WORMHOLE_PROGRAM_ID = new _web3.PublicKey("HDwcJBJXjL9FpJ7UBsYBtaDjsBUhuLCUYoz3zr8SWWaQ");
|
|
37
39
|
const DEFAULT_PUSH_ORACLE_PROGRAM_ID = new _web3.PublicKey("pythWSnswVUd12oZpeFP8e9CVaEqJg25g1Vtc2biRsT");
|
|
38
40
|
const getGuardianSetPda = (guardianSetIndex, wormholeProgramId)=>{
|
|
39
|
-
const guardianSetIndexBuf = Buffer.alloc(4);
|
|
41
|
+
const guardianSetIndexBuf = _buffer.Buffer.alloc(4);
|
|
40
42
|
guardianSetIndexBuf.writeUInt32BE(guardianSetIndex, 0);
|
|
41
43
|
return _web3.PublicKey.findProgramAddressSync([
|
|
42
|
-
Buffer.from("GuardianSet"),
|
|
44
|
+
_buffer.Buffer.from("GuardianSet"),
|
|
43
45
|
guardianSetIndexBuf
|
|
44
46
|
], wormholeProgramId)[0];
|
|
45
47
|
};
|
|
@@ -48,14 +50,14 @@ function getRandomTreasuryId() {
|
|
|
48
50
|
}
|
|
49
51
|
const getTreasuryPda = (treasuryId, receiverProgramId)=>{
|
|
50
52
|
return _web3.PublicKey.findProgramAddressSync([
|
|
51
|
-
Buffer.from("treasury"),
|
|
52
|
-
Buffer.from([
|
|
53
|
+
_buffer.Buffer.from("treasury"),
|
|
54
|
+
_buffer.Buffer.from([
|
|
53
55
|
treasuryId
|
|
54
56
|
])
|
|
55
57
|
], receiverProgramId)[0];
|
|
56
58
|
};
|
|
57
59
|
const getConfigPda = (receiverProgramId)=>{
|
|
58
60
|
return _web3.PublicKey.findProgramAddressSync([
|
|
59
|
-
Buffer.from("config")
|
|
61
|
+
_buffer.Buffer.from("config")
|
|
60
62
|
], receiverProgramId)[0];
|
|
61
63
|
};
|
|
@@ -17,9 +17,6 @@ _export(exports, {
|
|
|
17
17
|
get INIT_ENCODED_VAA_COMPUTE_BUDGET () {
|
|
18
18
|
return INIT_ENCODED_VAA_COMPUTE_BUDGET;
|
|
19
19
|
},
|
|
20
|
-
get POST_TWAP_UPDATE_COMPUTE_BUDGET () {
|
|
21
|
-
return POST_TWAP_UPDATE_COMPUTE_BUDGET;
|
|
22
|
-
},
|
|
23
20
|
get POST_UPDATE_ATOMIC_COMPUTE_BUDGET () {
|
|
24
21
|
return POST_UPDATE_ATOMIC_COMPUTE_BUDGET;
|
|
25
22
|
},
|
|
@@ -39,7 +36,6 @@ _export(exports, {
|
|
|
39
36
|
const VERIFY_ENCODED_VAA_COMPUTE_BUDGET = 350_000;
|
|
40
37
|
const POST_UPDATE_ATOMIC_COMPUTE_BUDGET = 170_000;
|
|
41
38
|
const POST_UPDATE_COMPUTE_BUDGET = 35_000;
|
|
42
|
-
const POST_TWAP_UPDATE_COMPUTE_BUDGET = 50_000;
|
|
43
39
|
const UPDATE_PRICE_FEED_COMPUTE_BUDGET = 55_000;
|
|
44
40
|
const INIT_ENCODED_VAA_COMPUTE_BUDGET = 3000;
|
|
45
41
|
const WRITE_ENCODED_VAA_COMPUTE_BUDGET = 3000;
|
|
@@ -10,10 +10,6 @@ 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;
|
|
17
13
|
/**
|
|
18
14
|
* A hard-coded budget for the compute units required for the `updatePriceFeed` instruction in the Pyth Push Oracle program.
|
|
19
15
|
*/
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// eslint-disable-next-line unicorn/prefer-node-protocol
|
|
1
2
|
"use strict";
|
|
2
3
|
Object.defineProperty(exports, "__esModule", {
|
|
3
4
|
value: true
|
|
@@ -30,9 +31,6 @@ _export(exports, {
|
|
|
30
31
|
get buildPostEncodedVaaInstructions () {
|
|
31
32
|
return buildPostEncodedVaaInstructions;
|
|
32
33
|
},
|
|
33
|
-
get buildPostEncodedVaasForTwapInstructions () {
|
|
34
|
-
return buildPostEncodedVaasForTwapInstructions;
|
|
35
|
-
},
|
|
36
34
|
get findEncodedVaaAccountsByWriteAuthority () {
|
|
37
35
|
return findEncodedVaaAccountsByWriteAuthority;
|
|
38
36
|
},
|
|
@@ -43,6 +41,7 @@ _export(exports, {
|
|
|
43
41
|
return trimSignatures;
|
|
44
42
|
}
|
|
45
43
|
});
|
|
44
|
+
const _buffer = require("buffer");
|
|
46
45
|
const _bytes = require("@coral-xyz/anchor/dist/cjs/utils/bytes");
|
|
47
46
|
const _sha256 = require("@noble/hashes/sha256");
|
|
48
47
|
const _web3 = require("@solana/web3.js");
|
|
@@ -63,7 +62,7 @@ function trimSignatures(vaa, n = DEFAULT_REDUCED_GUARDIAN_SET_SIZE) {
|
|
|
63
62
|
if (n > currentNumSignatures) {
|
|
64
63
|
throw new Error("Resulting VAA can't have more signatures than the original VAA");
|
|
65
64
|
}
|
|
66
|
-
const trimmedVaa = Buffer.concat([
|
|
65
|
+
const trimmedVaa = _buffer.Buffer.concat([
|
|
67
66
|
vaa.subarray(0, 6 + n * VAA_SIGNATURE_SIZE),
|
|
68
67
|
vaa.subarray(6 + currentNumSignatures * VAA_SIGNATURE_SIZE)
|
|
69
68
|
]);
|
|
@@ -153,34 +152,6 @@ async function buildPostEncodedVaaInstructions(wormhole, vaa) {
|
|
|
153
152
|
closeInstructions: groups.closeInstructions
|
|
154
153
|
};
|
|
155
154
|
}
|
|
156
|
-
async function buildPostEncodedVaasForTwapInstructions(wormhole, startUpdateData, endUpdateData) {
|
|
157
|
-
const startGroups = await generateVaaInstructionGroups(wormhole, startUpdateData.vaa);
|
|
158
|
-
const endGroups = await generateVaaInstructionGroups(wormhole, endUpdateData.vaa);
|
|
159
|
-
// Pack instructions for optimal 3-transaction pattern:
|
|
160
|
-
// TX1: start VAA init + first write
|
|
161
|
-
// TX2: end VAA init + first write
|
|
162
|
-
// TX3: both VAAs second write + verify
|
|
163
|
-
const postInstructions = [
|
|
164
|
-
// TX1
|
|
165
|
-
...startGroups.initInstructions,
|
|
166
|
-
...startGroups.writeFirstPartInstructions,
|
|
167
|
-
// TX2
|
|
168
|
-
...endGroups.initInstructions,
|
|
169
|
-
...endGroups.writeFirstPartInstructions,
|
|
170
|
-
// TX3
|
|
171
|
-
...startGroups.writeSecondPartAndVerifyInstructions,
|
|
172
|
-
...endGroups.writeSecondPartAndVerifyInstructions
|
|
173
|
-
];
|
|
174
|
-
return {
|
|
175
|
-
startEncodedVaaAddress: startGroups.encodedVaaAddress,
|
|
176
|
-
endEncodedVaaAddress: endGroups.encodedVaaAddress,
|
|
177
|
-
postInstructions,
|
|
178
|
-
closeInstructions: [
|
|
179
|
-
...startGroups.closeInstructions,
|
|
180
|
-
...endGroups.closeInstructions
|
|
181
|
-
]
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
155
|
async function buildCloseEncodedVaaInstruction(wormhole, encodedVaa) {
|
|
185
156
|
const instruction = await wormhole.methods.closeEncodedVaa().accounts({
|
|
186
157
|
encodedVaa
|
|
@@ -206,7 +177,7 @@ async function findEncodedVaaAccountsByWriteAuthority(connection, writeAuthority
|
|
|
206
177
|
{
|
|
207
178
|
memcmp: {
|
|
208
179
|
offset: 0,
|
|
209
|
-
bytes: _bytes.bs58.encode(Buffer.from((0, _sha256.sha256)("account:EncodedVaa").slice(0, 8)))
|
|
180
|
+
bytes: _bytes.bs58.encode(_buffer.Buffer.from((0, _sha256.sha256)("account:EncodedVaa").slice(0, 8)))
|
|
210
181
|
}
|
|
211
182
|
},
|
|
212
183
|
{
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Program } from "@coral-xyz/anchor";
|
|
2
|
-
import type { AccumulatorUpdateData } from "@pythnetwork/price-service-sdk";
|
|
3
2
|
import type { InstructionWithEphemeralSigners } from "@pythnetwork/solana-utils";
|
|
4
3
|
import { Connection, Keypair, PublicKey } from "@solana/web3.js";
|
|
5
4
|
import type { WormholeCoreBridgeSolana } from "./idl/wormhole_core_bridge_solana";
|
|
@@ -59,30 +58,6 @@ export declare function buildPostEncodedVaaInstructions(wormhole: Program<Wormho
|
|
|
59
58
|
postInstructions: InstructionWithEphemeralSigners[];
|
|
60
59
|
closeInstructions: InstructionWithEphemeralSigners[];
|
|
61
60
|
}>;
|
|
62
|
-
/**
|
|
63
|
-
* Build instructions to post two VAAs for TWAP (Time-Weighted Average Price) calculations,
|
|
64
|
-
* optimized for 3 transactions. This is specifically designed for posting start and end
|
|
65
|
-
* accumulator update VAAs efficiently.
|
|
66
|
-
* The instructions are packed into 3 transactions:
|
|
67
|
-
* - TX1: Initialize and write first part of start VAA
|
|
68
|
-
* - TX2: Initialize and write first part of end VAA
|
|
69
|
-
* - TX3: Write second part and verify both VAAs
|
|
70
|
-
*
|
|
71
|
-
* @param wormhole - The Wormhole program instance
|
|
72
|
-
* @param startUpdateData - Accumulator update data containing the start VAA
|
|
73
|
-
* @param endUpdateData - Accumulator update data containing the end VAA
|
|
74
|
-
* @returns Result containing:
|
|
75
|
-
* - startEncodedVaaAddress: Public key of the start VAA account
|
|
76
|
-
* - endEncodedVaaAddress: Public key of the end VAA account
|
|
77
|
-
* - postInstructions: Instructions to post and verify both VAAs
|
|
78
|
-
* - closeInstructions: Instructions to close both encoded VAA accounts
|
|
79
|
-
*/
|
|
80
|
-
export declare function buildPostEncodedVaasForTwapInstructions(wormhole: Program<WormholeCoreBridgeSolana>, startUpdateData: AccumulatorUpdateData, endUpdateData: AccumulatorUpdateData): Promise<{
|
|
81
|
-
startEncodedVaaAddress: PublicKey;
|
|
82
|
-
endEncodedVaaAddress: PublicKey;
|
|
83
|
-
postInstructions: InstructionWithEphemeralSigners[];
|
|
84
|
-
closeInstructions: InstructionWithEphemeralSigners[];
|
|
85
|
-
}>;
|
|
86
61
|
/**
|
|
87
62
|
* Build an instruction to close an encoded VAA account, recovering the rent.
|
|
88
63
|
*/
|