Skip to content

Commit 29b9644

Browse files
authored
feat: Support Sui Price Update with Coin Input (#2861)
* add update price feeds function for sui which takes coin input * lint * fix prettier issues * prettier on fuel * fix eslint * use explicit types
1 parent 5def9c3 commit 29b9644

File tree

3 files changed

+86
-23
lines changed

3 files changed

+86
-23
lines changed

target_chains/sui/sdk/js/README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Pyth prices and submit them to the network:
2222

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

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

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

target_chains/sui/sdk/js/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pythnetwork/pyth-sui-js",
3-
"version": "2.1.0",
3+
"version": "2.2.0",
44
"description": "Pyth Network Sui Utilities",
55
"homepage": "https://pyth.network",
66
"author": {

target_chains/sui/sdk/js/src/client.ts

Lines changed: 80 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import { HexString } from "@pythnetwork/price-service-client";
66
import { Buffer } from "buffer";
77

88
const MAX_ARGUMENT_SIZE = 16 * 1024;
9+
type NestedTransactionResult = {
10+
$kind: "NestedResult";
11+
NestedResult: [number, number];
12+
};
913
export type ObjectId = string;
1014

1115
export class SuiPythClient {
@@ -104,28 +108,19 @@ export class SuiPythClient {
104108
return verifiedVaas;
105109
}
106110

107-
/**
108-
* Adds the necessary commands for updating the pyth price feeds to the transaction block.
109-
* @param tx transaction block to add commands to
110-
* @param updates array of price feed updates received from the price service
111-
* @param feedIds array of feed ids to update (in hex format)
112-
*/
113-
async updatePriceFeeds(
111+
async verifyVaasAndGetHotPotato(
114112
tx: Transaction,
115113
updates: Buffer[],
116-
feedIds: HexString[],
117-
): Promise<ObjectId[]> {
118-
const packageId = await this.getPythPackageId();
119-
120-
let priceUpdatesHotPotato;
114+
packageId: string,
115+
): Promise<NestedTransactionResult> {
121116
if (updates.length > 1) {
122117
throw new Error(
123118
"SDK does not support sending multiple accumulator messages in a single transaction",
124119
);
125120
}
126121
const vaa = this.extractVaaBytesFromAccumulatorMessage(updates[0]);
127122
const verifiedVaas = await this.verifyVaas([vaa], tx);
128-
[priceUpdatesHotPotato] = tx.moveCall({
123+
const [priceUpdatesHotPotato] = tx.moveCall({
129124
target: `${packageId}::pyth::create_authenticated_price_infos_using_accumulator`,
130125
arguments: [
131126
tx.object(this.pythStateId),
@@ -141,13 +136,17 @@ export class SuiPythClient {
141136
tx.object(SUI_CLOCK_OBJECT_ID),
142137
],
143138
});
139+
return priceUpdatesHotPotato;
140+
}
144141

142+
async executePriceFeedUpdates(
143+
tx: Transaction,
144+
packageId: string,
145+
feedIds: HexString[],
146+
priceUpdatesHotPotato: any,
147+
coins: NestedTransactionResult[],
148+
) {
145149
const priceInfoObjects: ObjectId[] = [];
146-
const baseUpdateFee = await this.getBaseUpdateFee();
147-
const coins = tx.splitCoins(
148-
tx.gas,
149-
feedIds.map(() => tx.pure.u64(baseUpdateFee)),
150-
);
151150
let coinId = 0;
152151
for (const feedId of feedIds) {
153152
const priceInfoObjectId = await this.getPriceFeedObjectId(feedId);
@@ -176,6 +175,69 @@ export class SuiPythClient {
176175
});
177176
return priceInfoObjects;
178177
}
178+
179+
/**
180+
* Adds the necessary commands for updating the pyth price feeds to the transaction block.
181+
* @param tx transaction block to add commands to
182+
* @param updates array of price feed updates received from the price service
183+
* @param feedIds array of feed ids to update (in hex format)
184+
*/
185+
async updatePriceFeeds(
186+
tx: Transaction,
187+
updates: Buffer[],
188+
feedIds: HexString[],
189+
): Promise<ObjectId[]> {
190+
const packageId = await this.getPythPackageId();
191+
const priceUpdatesHotPotato = await this.verifyVaasAndGetHotPotato(
192+
tx,
193+
updates,
194+
packageId,
195+
);
196+
197+
const baseUpdateFee = await this.getBaseUpdateFee();
198+
const coins = tx.splitCoins(
199+
tx.gas,
200+
feedIds.map(() => tx.pure.u64(baseUpdateFee)),
201+
);
202+
203+
return await this.executePriceFeedUpdates(
204+
tx,
205+
packageId,
206+
feedIds,
207+
priceUpdatesHotPotato,
208+
coins,
209+
);
210+
}
211+
212+
/**
213+
* Updates price feeds using the coin input for payment. Coins can be generated by calling splitCoin on tx.gas.
214+
* @param tx transaction block to add commands to
215+
* @param updates array of price feed updates received from the price service
216+
* @param feedIds array of feed ids to update (in hex format)
217+
* @param coins array of Coins for payment of update operations
218+
*/
219+
async updatePriceFeedsWithCoins(
220+
tx: Transaction,
221+
updates: Buffer[],
222+
feedIds: HexString[],
223+
coins: NestedTransactionResult[],
224+
): Promise<ObjectId[]> {
225+
const packageId = await this.getPythPackageId();
226+
const priceUpdatesHotPotato = await this.verifyVaasAndGetHotPotato(
227+
tx,
228+
updates,
229+
packageId,
230+
);
231+
232+
return await this.executePriceFeedUpdates(
233+
tx,
234+
packageId,
235+
feedIds,
236+
priceUpdatesHotPotato,
237+
coins,
238+
);
239+
}
240+
179241
async createPriceFeed(tx: Transaction, updates: Buffer[]) {
180242
const packageId = await this.getPythPackageId();
181243
if (updates.length > 1) {

0 commit comments

Comments
 (0)