Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions apps/price_pusher/src/solana/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ export default {
type: "number",
default: 6,
} as Options,
"address-lookup-table-account": {
description: "The pubkey of the ALT to use when updating price feeds",
type: "string",
optional: true,
} as Options,
...options.priceConfigFile,
...options.priceServiceEndpoint,
...options.pythContractAddress,
Expand All @@ -107,6 +112,7 @@ export default {
maxJitoTipLamports,
jitoBundleSize,
updatesPerJitoBundle,
addressLookupTableAccount,
logLevel,
controllerLogLevel,
} = argv;
Expand Down Expand Up @@ -145,12 +151,21 @@ export default {
)
);

const connection = new Connection(endpoint, "processed");
const pythSolanaReceiver = new PythSolanaReceiver({
connection: new Connection(endpoint, "processed"),
connection,
wallet,
pushOracleProgramId: new PublicKey(pythContractAddress),
});

// Fetch the account lookup table if provided
const lookupTableAccount =
(
await connection.getAddressLookupTable(
new PublicKey(addressLookupTableAccount)
)
).value ?? undefined;

let solanaPricePusher;
if (jitoTipLamports) {
const jitoKeypair = Keypair.fromSecretKey(
Expand All @@ -168,7 +183,8 @@ export default {
maxJitoTipLamports,
jitoClient,
jitoBundleSize,
updatesPerJitoBundle
updatesPerJitoBundle,
lookupTableAccount
);

onBundleResult(jitoClient, logger.child({ module: "JitoClient" }));
Expand All @@ -178,7 +194,8 @@ export default {
hermesClient,
logger.child({ module: "SolanaPricePusher" }),
shardId,
computeUnitPriceMicroLamports
computeUnitPriceMicroLamports,
lookupTableAccount
);
}

Expand Down
26 changes: 17 additions & 9 deletions apps/price_pusher/src/solana/solana.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
import { SearcherClient } from "jito-ts/dist/sdk/block-engine/searcher";
import { sliceAccumulatorUpdateData } from "@pythnetwork/price-service-sdk";
import { Logger } from "pino";
import { LAMPORTS_PER_SOL } from "@solana/web3.js";
import { AddressLookupTableAccount, LAMPORTS_PER_SOL } from "@solana/web3.js";

const HEALTH_CHECK_TIMEOUT_SECONDS = 60;

Expand Down Expand Up @@ -97,7 +97,8 @@ export class SolanaPricePusher implements IPricePusher {
private hermesClient: HermesClient,
private logger: Logger,
private shardId: number,
private computeUnitPriceMicroLamports: number
private computeUnitPriceMicroLamports: number,
private addressLookupTableAccount?: AddressLookupTableAccount
) {}

async updatePriceFeed(priceIds: string[]): Promise<void> {
Expand Down Expand Up @@ -126,9 +127,12 @@ export class SolanaPricePusher implements IPricePusher {
return;
}

const transactionBuilder = this.pythSolanaReceiver.newTransactionBuilder({
closeUpdateAccounts: true,
});
const transactionBuilder = this.pythSolanaReceiver.newTransactionBuilder(
{
closeUpdateAccounts: true,
},
this.addressLookupTableAccount
);
await transactionBuilder.addUpdatePriceFeed(
priceFeedUpdateData,
this.shardId
Expand Down Expand Up @@ -164,7 +168,8 @@ export class SolanaPricePusherJito implements IPricePusher {
private maxJitoTipLamports: number,
private searcherClient: SearcherClient,
private jitoBundleSize: number,
private updatesPerJitoBundle: number
private updatesPerJitoBundle: number,
private addressLookupTableAccount?: AddressLookupTableAccount
) {}

async getRecentJitoTipLamports(): Promise<number | undefined> {
Expand Down Expand Up @@ -215,9 +220,12 @@ export class SolanaPricePusherJito implements IPricePusher {
}

for (let i = 0; i < priceIds.length; i += this.updatesPerJitoBundle) {
const transactionBuilder = this.pythSolanaReceiver.newTransactionBuilder({
closeUpdateAccounts: true,
});
const transactionBuilder = this.pythSolanaReceiver.newTransactionBuilder(
{
closeUpdateAccounts: true,
},
this.addressLookupTableAccount
);
await transactionBuilder.addUpdatePriceFeed(
priceFeedUpdateData.map((x) => {
return sliceAccumulatorUpdateData(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ const SOL_PRICE_FEED_ID =
"0xef0d8b6fda2ceba41da15d4095d1da392a0d2f8ed0c6c7bc0f4cfac8c280b56d";
const ETH_PRICE_FEED_ID =
"0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace";
const PRICE_FEED_IDS = [SOL_PRICE_FEED_ID, ETH_PRICE_FEED_ID];

// Optionally use an account lookup table to reduce tx sizes
const addressLookupTableAccount = new PublicKey(
"5DNCErWQFBdvCxWQXaC1mrEFsvL3ftrzZ2gVZWNybaSX"
);

let keypairFile = "";
if (process.env["SOLANA_KEYPAIR"]) {
Expand All @@ -29,21 +35,30 @@ async function main() {
const pythSolanaReceiver = new PythSolanaReceiver({ connection, wallet });

// Get the price update from hermes
const priceUpdateData = await getPriceUpdateData();
console.log(`Posting price update: ${priceUpdateData}`);
const priceUpdateData = await getPriceUpdateData(PRICE_FEED_IDS);
// console.log(`Posting price update: ${priceUpdateData}`);

// The shard indicates which set of price feed accounts you wish to update.
const shardId = 1;
const lookupTableAccount =
(await connection.getAddressLookupTable(addressLookupTableAccount)).value ??
undefined;
const transactionBuilder = pythSolanaReceiver.newTransactionBuilder(
{},
lookupTableAccount
);

const transactionBuilder = pythSolanaReceiver.newTransactionBuilder({});
// Update the price feed accounts for the feed ids in priceUpdateData (in this example, SOL and ETH) and shard id.
await transactionBuilder.addUpdatePriceFeed(priceUpdateData, shardId);
console.log(
"The SOL/USD price update will get posted to:",
pythSolanaReceiver
.getPriceFeedAccountAddress(shardId, SOL_PRICE_FEED_ID)
.toBase58()
);
// Print all price feed accounts that will be updated
for (const priceFeedId of PRICE_FEED_IDS) {
console.log(
`The ${priceFeedId} price update will get posted to:`,
pythSolanaReceiver
.getPriceFeedAccountAddress(shardId, priceFeedId)
.toBase58()
);
}

await transactionBuilder.addPriceConsumerInstructions(
async (
Expand All @@ -69,16 +84,12 @@ async function main() {
}

// Fetch price update data from Hermes
async function getPriceUpdateData() {
const priceServiceConnection = new HermesClient(
"https://hermes.pyth.network/",
{}
);
async function getPriceUpdateData(price_feed_ids: string[]) {
const hermesClient = new HermesClient("https://hermes.pyth.network/", {});

const response = await priceServiceConnection.getLatestPriceUpdates(
[SOL_PRICE_FEED_ID, ETH_PRICE_FEED_ID],
{ encoding: "base64" }
);
const response = await hermesClient.getLatestPriceUpdates(price_feed_ids, {
encoding: "base64",
});

return response.binary.data;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pythnetwork/pyth-solana-receiver",
"version": "0.9.1",
"version": "0.10.0",
"description": "Pyth solana receiver SDK",
"homepage": "https://pyth.network",
"main": "lib/index.js",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ export type PythTransactionBuilderConfig = {
closeUpdateAccounts?: boolean;
};

/**
* A stable treasury ID. This ID's corresponding treasury address
* can be cached in an account lookup table in order to reduce the overall txn size.
*/
export const DEFAULT_TREASURY_ID = 0;

/**
* A builder class to build transactions that:
* - Post price updates (fully or partially verified) or update price feed accounts
Expand Down Expand Up @@ -470,9 +476,10 @@ export class PythSolanaReceiver {
* Get a new transaction builder to build transactions that interact with the Pyth Solana Receiver program and consume price updates
*/
newTransactionBuilder(
config: PythTransactionBuilderConfig
config: PythTransactionBuilderConfig,
address_lookup_account?: AddressLookupTableAccount
): PythTransactionBuilder {
return new PythTransactionBuilder(this, config);
return new PythTransactionBuilder(this, config, address_lookup_account);
}

/**
Expand All @@ -497,7 +504,7 @@ export class PythSolanaReceiver {
const priceFeedIdToPriceUpdateAccount: Record<string, PublicKey> = {};
const closeInstructions: InstructionWithEphemeralSigners[] = [];

const treasuryId = getRandomTreasuryId();
const treasuryId = DEFAULT_TREASURY_ID;

for (const priceUpdateData of priceUpdateDataArray) {
const accumulatorUpdateData = parseAccumulatorUpdateData(
Expand Down Expand Up @@ -730,7 +737,7 @@ export class PythSolanaReceiver {
const priceFeedIdToPriceUpdateAccount: Record<string, PublicKey> = {};
const closeInstructions: InstructionWithEphemeralSigners[] = [];

const treasuryId = getRandomTreasuryId();
const treasuryId = DEFAULT_TREASURY_ID;

for (const priceUpdateData of priceUpdateDataArray) {
const accumulatorUpdateData = parseAccumulatorUpdateData(
Expand Down
5 changes: 3 additions & 2 deletions target_chains/solana/sdk/js/pyth_solana_receiver/src/vaa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,11 @@ export const VAA_START = 46;
*
* The first one writes the first `VAA_SPLIT_INDEX` bytes and the second one writes the rest.
*
* This number was chosen as the biggest number such that one can still call `createInstruction`, `initEncodedVaa` and `writeEncodedVaa` in a single Solana transaction.
* This number was chosen as the biggest number such that one can still call `createInstruction`,
* `initEncodedVaa` and `writeEncodedVaa` in a single Solana transaction, while using an address lookup table.
* This way, the packing of the instructions to post an encoded vaa is more efficient.
*/
export const VAA_SPLIT_INDEX = 755;
export const VAA_SPLIT_INDEX = 700;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't seem tight
i think you can go up to 737

Copy link
Contributor Author

@tejasbadadare tejasbadadare Feb 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

highest i could get it to is 721, not sure where the extra space is coming from


/**
* Trim the number of signatures of a VAA.
Expand Down
Loading