Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
9 changes: 5 additions & 4 deletions target_chains/sui/sdk/js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Pyth prices and submit them to the network:

```typescript
const connection = new SuiPriceServiceConnection(
"https://hermes-beta.pyth.network"
"https://hermes-beta.pyth.network",
); // See Hermes endpoints section below for other endpoints

const priceIds = [
Expand Down Expand Up @@ -104,8 +104,9 @@ You can run this example with `pnpm turbo --filter @pythnetwork/pyth-sui-js run

```bash
export SUI_KEY=YOUR_PRIV_KEY;
pnpm turbo --filter @pythnetwork/pyth-sui-js run example-relay -- --feed-id "5a035d5440f5c163069af66062bac6c79377bf88396fa27e6067bfca8096d280" \
--price-service "https://hermes-beta.pyth.network" \
pnpm turbo run example-relay --filter @pythnetwork/pyth-sui-js -- \
--feed-id "5a035d5440f5c163069af66062bac6c79377bf88396fa27e6067bfca8096d280" \
--hermes "https://hermes-beta.pyth.network" \
--full-node "https://fullnode.testnet.sui.io:443" \
--pyth-state-id "0xd3e79c2c083b934e78b3bd58a490ec6b092561954da6e7322e1e2b3c8abfddc0" \
--wormhole-state-id "0x31358d198147da50db32eda2562951d53973a0c0ad5ed738e9b17d88b213d790"
Expand Down Expand Up @@ -136,7 +137,7 @@ This method is useful if you want to show continuously updating real-time prices
// gets a price update.
connection.subscribePriceFeedUpdates(priceIds, (priceFeed) => {
console.log(
`Received update for ${priceFeed.id}: ${priceFeed.getPriceNoOlderThan(60)}`
`Received update for ${priceFeed.id}: ${priceFeed.getPriceNoOlderThan(60)}`,
);
});

Expand Down
2 changes: 1 addition & 1 deletion target_chains/sui/sdk/js/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pythnetwork/pyth-sui-js",
"version": "2.1.0",
"version": "2.2.0",
"description": "Pyth Network Sui Utilities",
"homepage": "https://pyth.network",
"author": {
Expand Down
98 changes: 80 additions & 18 deletions target_chains/sui/sdk/js/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import { HexString } from "@pythnetwork/price-service-client";
import { Buffer } from "buffer";

const MAX_ARGUMENT_SIZE = 16 * 1024;
type Coin = {
Copy link
Collaborator

Choose a reason for hiding this comment

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

i wonder whether they had a type for this themselves.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah I couldn't find one myself. Their TS docs use the splitCoins function but they never provide an example of what explicit type it is. In their github repo, they have that function return this type: Extract<Argument, { Result: unknown }> & Extract<Argument, { NestedResult: unknown }>[]

In any case, I figured why not just use the type the IDE supplies me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So there is a TransactionResult type which almost matches this. But we seem to explicitly use the nestedResult version. So I just redefined it and use that. We can use the SDK type if we dont do [hotPotato] and such but I dont know what that would do and don't want to change things so drastically right now.

$kind: "NestedResult";
NestedResult: [number, number];
};
export type ObjectId = string;

export class SuiPythClient {
Expand Down Expand Up @@ -104,28 +108,19 @@ export class SuiPythClient {
return verifiedVaas;
}

/**
* Adds the necessary commands for updating the pyth price feeds to the transaction block.
* @param tx transaction block to add commands to
* @param updates array of price feed updates received from the price service
* @param feedIds array of feed ids to update (in hex format)
*/
async updatePriceFeeds(
async verifyVaasAndGetHotPotato(
tx: Transaction,
updates: Buffer[],
feedIds: HexString[],
): Promise<ObjectId[]> {
const packageId = await this.getPythPackageId();

let priceUpdatesHotPotato;
packageId: string,
): Promise<any> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

please don't use any. if the type is not known and you can extract it later use unknown

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Gotcha, will do!

if (updates.length > 1) {
throw new Error(
"SDK does not support sending multiple accumulator messages in a single transaction",
);
}
const vaa = this.extractVaaBytesFromAccumulatorMessage(updates[0]);
const verifiedVaas = await this.verifyVaas([vaa], tx);
[priceUpdatesHotPotato] = tx.moveCall({
const [priceUpdatesHotPotato] = tx.moveCall({
target: `${packageId}::pyth::create_authenticated_price_infos_using_accumulator`,
arguments: [
tx.object(this.pythStateId),
Expand All @@ -141,13 +136,17 @@ export class SuiPythClient {
tx.object(SUI_CLOCK_OBJECT_ID),
],
});
return priceUpdatesHotPotato;
}

async executePriceFeedUpdates(
tx: Transaction,
packageId: string,
feedIds: HexString[],
priceUpdatesHotPotato: any,
coins: Coin[],
) {
const priceInfoObjects: ObjectId[] = [];
const baseUpdateFee = await this.getBaseUpdateFee();
const coins = tx.splitCoins(
tx.gas,
feedIds.map(() => tx.pure.u64(baseUpdateFee)),
);
let coinId = 0;
for (const feedId of feedIds) {
const priceInfoObjectId = await this.getPriceFeedObjectId(feedId);
Expand Down Expand Up @@ -176,6 +175,69 @@ export class SuiPythClient {
});
return priceInfoObjects;
}

/**
* Adds the necessary commands for updating the pyth price feeds to the transaction block.
* @param tx transaction block to add commands to
* @param updates array of price feed updates received from the price service
* @param feedIds array of feed ids to update (in hex format)
*/
async updatePriceFeeds(
tx: Transaction,
updates: Buffer[],
feedIds: HexString[],
): Promise<ObjectId[]> {
const packageId = await this.getPythPackageId();
const priceUpdatesHotPotato = await this.verifyVaasAndGetHotPotato(
tx,
updates,
packageId,
);

const baseUpdateFee = await this.getBaseUpdateFee();
const coins = tx.splitCoins(
tx.gas,
feedIds.map(() => tx.pure.u64(baseUpdateFee)),
);

return await this.executePriceFeedUpdates(
tx,
packageId,
feedIds,
priceUpdatesHotPotato,
coins,
);
}

/**
* Updates price feeds using the coin input for payment. Coins can be generated by calling splitCoin on tx.gas.
* @param tx transaction block to add commands to
* @param updates array of price feed updates received from the price service
* @param feedIds array of feed ids to update (in hex format)
* @param coins array of Coins for payment of update operations
*/
async updatePriceFeedsWithCoins(
tx: Transaction,
updates: Buffer[],
feedIds: HexString[],
coins: Coin[],
): Promise<ObjectId[]> {
const packageId = await this.getPythPackageId();
const priceUpdatesHotPotato = await this.verifyVaasAndGetHotPotato(
tx,
updates,
packageId,
);

return await this.executePriceFeedUpdates(
tx,
packageId,
feedIds,
priceUpdatesHotPotato,
coins,
);
}

async createPriceFeed(tx: Transaction, updates: Buffer[]) {
const packageId = await this.getPythPackageId();
if (updates.length > 1) {
Expand Down
Loading