@@ -72,39 +72,43 @@ Pyth also provides a javascript SDK to construct transaction blocks that update
7272The code snippet below provides a general template for what your contract code should look like:
7373
7474``` rust {18} copy
75- module pyth_example :: main {
76- use sui :: clock :: Clock ;
77- use pyth :: price_info;
78- use pyth :: price_identifier;
79- use pyth :: price;
80- use pyth :: pyth;
81- use pyth :: price_info :: PriceInfoObject ;
82-
83- const E_INVALID_ID : u64 = 1 ;
84-
85- public fun use_pyth_price (
86- // Other arguments
87- clock : & Clock ,
88- price_info_object : & PriceInfoObject ,
89- ){
90- let max_age = 60 ;
91- // Make sure the price is not older than max_age seconds
92- let price_struct = pyth :: get_price_no_older_than (price_info_object ,clock , max_age );
93-
94- // Check the price feed ID
95- let price_info = price_info :: get_price_info_from_price_info_object (price_info_object );
96- let price_id = price_identifier :: get_bytes (& price_info :: get_price_identifier (& price_info ));
97-
98- // ETH/USD price feed ID
99- // The complete list of feed IDs is available at https://pyth.network/developers/price-feed-ids
100- // Note: Sui uses the Pyth price feed ID without the `0x` prefix.
101- assert! (price_id! = x " ff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace" , E_INVALID_ID );
102-
103- // Extract the price, decimal, and timestamp from the price struct and use them
104- let decimal_i64 = price :: get_expo (& price_struct );
105- let price_i64 = price :: get_price (& price_struct );
106- let timestamp_sec = price :: get_timestamp (& price_struct );
107- }
75+ /// Module: oracle
76+ module oracle :: oracle ;
77+
78+ use sui :: clock :: Clock ;
79+ use pyth :: price_info;
80+ use pyth :: price_identifier;
81+ use pyth :: price;
82+ use pyth :: i64 :: I64 ;
83+ use pyth :: pyth;
84+ use pyth :: price_info :: PriceInfoObject ;
85+
86+ const E_INVALID_ID : u64 = 1 ;
87+
88+ public fun get_sui_price (
89+ // Other arguments
90+ clock : & Clock ,
91+ price_info_object : & PriceInfoObject ,
92+ ): I64 {
93+ let max_age = 60 ;
94+
95+ // Make sure the price is not older than max_age seconds
96+ let price_struct = pyth :: get_price_no_older_than (price_info_object , clock , max_age );
97+
98+ // Check the price feed ID
99+ let price_info = price_info :: get_price_info_from_price_info_object (price_info_object );
100+ let price_id = price_identifier :: get_bytes (& price_info :: get_price_identifier (& price_info ));
101+
102+ // SUI/USD price feed ID
103+ // The complete list of feed IDs is available at https://pyth.network/developers/price-feed-ids
104+ // Note: Sui uses the Pyth price feed ID without the `0x` prefix.
105+ let testnet_sui_price_id = x " 50c67b3fd225db8912a424dd4baed60ffdde625ed2feaaf283724f9608fea266" ;
106+ assert! (price_id == testnet_sui_price_id , E_INVALID_ID );
107+
108+ // Extract the price, decimal, and timestamp from the price struct and use them.
109+ let decimal_i64 = price :: get_expo (& price_struct );
110+ let price_i64 = price :: get_price (& price_struct );
111+ let timestamp_sec = price :: get_timestamp (& price_struct );
108112}
109113```
110114
@@ -113,48 +117,74 @@ One can consume the price by calling `pyth::get_price` abovementioned or other u
113117The code snippet below provides an example of how to update the Pyth price feeds:
114118
115119``` ts copy
116- import { SuiPriceServiceConnection , SuiPythClient } from " @pythnetwork/pyth-sui-js" ;
117- import { TransactionBlock } from " @mysten/sui.js" ;
120+ import { SuiPythClient , SuiPriceServiceConnection } from " @pythnetwork/pyth-sui-js"
121+ import { SuiClient } from " @mysten/sui/client"
122+ import { Transaction } from " @mysten/sui/transactions"
123+ import { Ed25519Keypair } from " @mysten/sui/keypairs/ed25519" ;
124+
125+ // / Step 1: Get the off-chain data.
126+ const connection = new SuiPriceServiceConnection (
127+ " https://hermes-beta.pyth.network" , // [!] Only for Sui Testnet
128+ // "https://hermes.pyth.network/", // Use this for Mainnet
129+ {
130+ // Provide this option to retrieve signed price updates for on-chain contracts!
131+ priceFeedRequestConfig: {
132+ ' binary' : true
133+ }
134+ }
135+ );
136+ const priceIDs = [
137+ // You can find the IDs of prices at:
138+ // - https://pyth.network/developers/price-feed-ids for Mainnet
139+ // - https://www.pyth.network/developers/price-feed-ids#beta for Testnet
140+ " 0x50c67b3fd225db8912a424dd4baed60ffdde625ed2feaaf283724f9608fea266" , // SUI/USD price ID
141+ ];
142+ const priceUpdateData = await connection .getPriceFeedsUpdateData (priceIDs );
118143
119- // Get the Stable Hermes service URL from https://docs.pyth.network/price-feeds/api-instances-and-providers/hermes
120- const connection = new SuiPriceServiceConnection ( " https://hermes-beta.pyth.network " );
144+ // / Step 2: Submit the new price on-chain and verify it using the contract.
145+ const suiClient = new SuiClient ({ url: ' https://fullnode.testnet.sui.io:443 ' } );
121146
122- const priceIDs = [
123- // You can find the IDs of prices at https://pyth.network/developers/price-feed-ids
124- " 0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43" , // BTC/USD price ID
125- " 0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace" , // ETH/USD price ID
126- ];
127-
128- const priceUpdateData = await connection .getPriceFeedsUpdateData (priceIDs );
129-
130- // It is either injected from the browser or instantiated in the backend via some private key
131- const wallet: SignerWithProvider = getWallet ();
132- // Get the state IDs of the Pyth and Wormhole contracts from
133- // https://docs.pyth.network/price-feeds/contract-addresses/sui
134- const wormholeStateId = " 0x5306f64e312b581766351c07af79c72fcb1cd25147157fdc2f8ad76de9a3fb6a" ;
135- const pythStateId = " 0x1f9310238ee9298fb703c3419030b35b22bb1cc37113e3bb5007c99aec79e5b8" ;
136-
137- const client = new SuiPythClient (wallet .provider , pythStateId , wormholeStateId );
138- const tx = new TransactionBlock ();
139- const priceInfoObjectIds = await client .updatePriceFeeds (tx , priceFeedUpdateData , priceIDs );
140-
141- tx .moveCall ({
142- target: ` pyth_example::main::use_pyth_price ` ,
147+ // Fixed the StateIds using the CLI example extracting them from
148+ // here: https://docs.pyth.network/price-feeds/contract-addresses/sui
149+ const pythTestnetStateId = " 0x243759059f4c3111179da5878c12f68d612c21a8d54d85edc86164bb18be1c7c" ; // Testnet
150+ const wormholeTestnetStateId = " 0x31358d198147da50db32eda2562951d53973a0c0ad5ed738e9b17d88b213d790" ; // Testnet
151+
152+ const pythClient = new SuiPythClient (suiClient , pythTestnetStateId , wormholeTestnetStateId );
153+
154+ const transaction = new Transaction ();
155+
156+ // / By calling the updatePriceFeeds function, the SuiPythClient adds the necessary
157+ // / transactions to the transaction block to update the price feeds.
158+ const priceInfoObjectIds = await pythClient .updatePriceFeeds (transaction , priceUpdateData , priceIDs );
159+
160+ let suiPriceObjectId = priceInfoObjectIds [0 ]
161+ if (! suiPriceObjectId ) {
162+ throw new Error (" suiPriceObjectId is undefined" );
163+ }
164+
165+ // / This is the package id that we receive after publishing `oracle` contract from the previous step.
166+ let testnetExampleContractPackageId = " 0x42d05111a160febe4144338647e0b7a80daea459c765c1e29a7a6198b235f67c" ;
167+ const CLOCK = " 0x0000000000000000000000000000000000000000000000000000000000000006" ;
168+ transaction .moveCall ({
169+ target: ` ${testnetExampleContractPackageId }::oracle::get_sui_price ` ,
143170 arguments: [
144- ... , // other arguments needed for your contract
145- tx .object (priceInfoObjectIds [ 0 ] ),
171+ transaction . object ( CLOCK ),
172+ transaction .object (suiPriceObjectId ),
146173 ],
147174});
148-
149- const txBlock = {
150- transactionBlock: tx ,
151- options: {
175+ transaction .setGasBudget (1000000000 );
176+
177+ const keypair = Ed25519Keypair .fromSecretKey (
178+ process .env .ADMIN_SECRET_KEY ! .toLowerCase ()
179+ );
180+ const result = await suiClient .signAndExecuteTransaction ({
181+ transaction ,
182+ signer: keypair ,
183+ options: {
152184 showEffects: true ,
153185 showEvents: true ,
154186 },
155- };
156-
157- const result = await wallet .signAndExecuteTransactionBlock (txBlock );
187+ });
158188```
159189
160190By calling the ` updatePriceFeeds ` function, the ` SuiPythClient ` adds the necessary transactions to the transaction block to update the price feeds.
@@ -190,7 +220,7 @@ export SUI_KEY=YOUR_PRIV_KEY;
190220npm run example-relay -- --feed-id " 5a035d5440f5c163069af66062bac6c79377bf88396fa27e6067bfca8096d280" \
191221--hermes " https://hermes-beta.pyth.network" \
192222--full-node " https://fullnode.testnet.sui.io:443" \
193- --pyth-state-id " 0xd3e79c2c083b934e78b3bd58a490ec6b092561954da6e7322e1e2b3c8abfddc0 " \
223+ --pyth-state-id " 0x243759059f4c3111179da5878c12f68d612c21a8d54d85edc86164bb18be1c7c " \
194224--wormhole-state-id " 0x31358d198147da50db32eda2562951d53973a0c0ad5ed738e9b17d88b213d790"
195225```
196226
0 commit comments