Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 2 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 22 additions & 22 deletions target_chains/sui/sdk/js/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ const priceUpdateData = await connection.getPriceFeedsUpdateData(priceIds); // s
// It is either injected from browser or instantiated in backend via some private key
const wallet: SignerWithProvider = getWallet();
// Get the state ids of the Pyth and Wormhole contracts from
// https://docs.pyth.network/documentation/pythnet-price-feeds/sui
// https://docs.pyth.network/price-feeds/contract-addresses/sui
const wormholeStateId = " 0xFILL_ME";
const pythStateId = "0xFILL_ME";

Expand Down Expand Up @@ -115,36 +115,36 @@ pnpm turbo run example-relay --filter @pythnetwork/pyth-sui-js -- \
## Off-chain prices

Many applications additionally need to display Pyth prices off-chain, for example, in their frontend application.
The `SuiPriceServiceConnection` provides two different ways to fetch the current Pyth price.
The `SuiPriceServiceConnection` is an extension of the [Hermes client](https://github.com/pyth-network/pyth-crosschain/tree/main/apps/hermes/client/js)
and provides two different ways to fetch the current Pyth price.
The code blocks below assume that the `connection` and `priceIds` objects have been initialized as shown above.
The first method is a single-shot query:

```typescript
// `getLatestPriceFeeds` returns a `PriceFeed` for each price id. It contains all information about a price and has
// utility functions to get the current and exponentially-weighted moving average price, and other functionality.
const priceFeeds = await connection.getLatestPriceFeeds(priceIds);
// Get the price if it is not older than 60 seconds from the current time.
console.log(priceFeeds[0].getPriceNoOlderThan(60)); // Price { conf: '1234', expo: -8, price: '12345678' }
// Get the exponentially-weighted moving average price if it is not older than 60 seconds from the current time.
console.log(priceFeeds[1].getEmaPriceNoOlderThan(60));
// `getLatestPriceFeeds` returns a `PriceUpdate`; see the [hermes-client](https://github.com/pyth-network/pyth-crosschain/tree/main/apps/hermes/client/js) documentation for details.
const priceUpdate: PriceUpdate = await connection.getLatestPriceUpdates(priceIds, { parsed: true });
if (priceUpdate.parsed) {
console.log("ParsedPriceUpdate:", priceUpdate.parsed);
}
```

The object also supports a streaming websocket connection that allows you to subscribe to every new price update for a given feed.
The object also supports a streaming Server-Sent Events (SSE) connection that allows you to subscribe to every new price update for a given feed.
This method is useful if you want to show continuously updating real-time prices in your frontend:

```typescript
// Subscribe to the price feeds given by `priceId`. The callback will be invoked every time the requested feed
// gets a price update.
connection.subscribePriceFeedUpdates(priceIds, (priceFeed) => {
console.log(
`Received update for ${priceFeed.id}: ${priceFeed.getPriceNoOlderThan(60)}`,
);
});

// When using the subscription, make sure to close the websocket upon termination to finish the process gracefully.
setTimeout(() => {
connection.closeWebSocket();
}, 60000);
// Streaming price updates
const eventSource = await connection.getPriceUpdatesStream(priceIds, { parsed: true });
eventSource.onmessage = (event) => {
console.log("Received price update:", event.data);
};
eventSource.onerror = (error) => {
console.error("Error receiving updates:", error);
eventSource.close();
};
await sleep(5000);
// To stop listening to the updates, you can call eventSource.close();
console.log("Closing event source.");
eventSource.close();
```

## Hermes endpoints
Expand Down
4 changes: 2 additions & 2 deletions 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.2.0",
"version": "2.3.0",
"description": "Pyth Network Sui Utilities",
"homepage": "https://pyth.network",
"author": {
Expand Down Expand Up @@ -55,7 +55,7 @@
},
"dependencies": {
"@mysten/sui": "^1.3.0",
"@pythnetwork/price-service-client": "workspace:*",
"@pythnetwork/hermes-client": "workspace:*",
"buffer": "^6.0.3"
}
}
16 changes: 11 additions & 5 deletions target_chains/sui/sdk/js/src/SuiPriceServiceConnection.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import {
PriceServiceConnection,
HermesClient,
HexString,
} from "@pythnetwork/price-service-client";
PriceUpdate,
} from "@pythnetwork/hermes-client";
import { Buffer } from "buffer";

export class SuiPriceServiceConnection extends PriceServiceConnection {
export class SuiPriceServiceConnection extends HermesClient {
/**
* Gets price update data (either batch price attestation VAAs or accumulator messages, depending on the chosen endpoint), which then
* can be submitted to the Pyth contract to update the prices. This will throw an axios error if there is a network problem or
Expand All @@ -15,7 +16,12 @@ export class SuiPriceServiceConnection extends PriceServiceConnection {
*/
async getPriceFeedsUpdateData(priceIds: HexString[]): Promise<Buffer[]> {
// Fetch the latest price feed update VAAs from the price service
const latestVaas = await this.getLatestVaas(priceIds);
return latestVaas.map((vaa) => Buffer.from(vaa, "base64"));
const updateData: PriceUpdate = await this.getLatestPriceUpdates(priceIds, {
encoding: "base64",
parsed: false,
});
return updateData.binary.data.map((update) =>
Buffer.from(update, "base64"),
);
}
}
2 changes: 1 addition & 1 deletion target_chains/sui/sdk/js/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { SuiClient } from "@mysten/sui/client";
import { SUI_CLOCK_OBJECT_ID } from "@mysten/sui/utils";
import { Transaction } from "@mysten/sui/transactions";
import { bcs } from "@mysten/sui/bcs";
import { HexString } from "@pythnetwork/price-service-client";
import { HexString } from "@pythnetwork/hermes-client";
import { Buffer } from "buffer";

const MAX_ARGUMENT_SIZE = 16 * 1024;
Expand Down
2 changes: 1 addition & 1 deletion target_chains/sui/sdk/js/src/examples/SuiRelay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ async function run() {
const wallet = Ed25519Keypair.fromSecretKey(
Buffer.from(process.env.SUI_KEY, "hex"),
);

tx.setGasBudget(1000000);
const result = await provider.signAndExecuteTransaction({
signer: wallet,
transaction: tx,
Expand Down
15 changes: 11 additions & 4 deletions target_chains/sui/sdk/js/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,17 @@ export { SuiPriceServiceConnection } from "./SuiPriceServiceConnection";
export { SuiPythClient } from "./client";

export {
AssetType,
BinaryPriceUpdate,
DurationInMs,
DurationInSeconds,
EncodingType,
HermesClientConfig,
HexString,
Price,
PriceFeed,
PriceServiceConnectionConfig,
PriceFeedMetadata,
PriceIdInput,
PriceUpdate,
PublisherCaps,
TwapsResponse,
UnixTimestamp,
} from "@pythnetwork/price-service-client";
} from "@pythnetwork/hermes-client";
Loading