@@ -9,84 +9,304 @@ price feeds, handling the retrieval and updating of price data.
9
9
The two Key functions in the Pyth receiver contract to get started
10
10
are as follows:
11
11
12
- - ` update_price_feeds ` : Updates multiple price feeds if they are fresh.
13
- - ` get_price ` : Retrieves the current price from a specific price feed.
12
+ 1 . [ ` update_price_feeds ` ] ( #update_price_feeds )
13
+ _ (updates Pyth smart contract with the price feed you provide)_
14
+ - args: ` data `
15
+ - type: ` object `
16
+ - example: ` { "data": "504e41...' } `
17
+
18
+ 2 . [ ` get_price ` ] ( #get_price ) (fetches the most recent price stored in the contract)\_
19
+ - args: ` price_identifier `
20
+ - type: ` object `
21
+ - example: ` { price_identifier: 'f9c0172ba10dfa8...' } `
14
22
15
23
These functions are core for interacting with Pyth price feeds in
16
24
NEAR-based applications, providing a reliable and up-to-date source of
17
- price information. For a full overview of methods provided by the NEAR
18
- contract, see [ the interface] [ ] exposed by the receiver contract.
19
-
20
- [ the interface ] : https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/near/receiver/src/ext.rs
21
-
22
- ## How to Update and Consume Price Feeds
23
-
24
- 1 . Install NEAR JavaScript SDK: First, add the NEAR JavaScript SDK to
25
- your project. You can do this using npm or yarn:
26
- ```
27
- npm install near-api-js
28
- ```
29
- or
30
- ```
31
- yarn add near-api-js
32
- ```
33
- 2 . Interact with the NEAR contract. This can be done with the Contract
34
- interface. Updating a price feed can be achieved using the NEAR JS
35
- API. See the [ official docs] ( https://docs.near.org/tools/near-api-js/quick-reference )
36
- for a guide on setting up a keystore correctly as this will depend
37
- heavily on your app. The skeleton you can use to get started for
38
- calling the Pyth contract looks like so:
39
-
40
- ``` js
41
- // @data: A payload containing price feed update information fetched from Hermes.
42
- async function updatePriceFeeds (data ) {
43
- const near = await connect (config);
44
- const result = await account .functionCall ({
45
- " pyth.testnet" ,
46
- methodName: " update_price_feeds" ,
47
- args: { data },
48
- gas: new utils.BN (" 30000000000000" ),
49
- attachedDeposit: utils .format .parseNearAmount (" 1" ),
50
- });
51
- console .log (" Update Price Feeds Result: " , result);
52
- }
53
- ```
54
-
55
- You can find an update to submit with this call from the Hermes API
56
- which for example [ can be found for testnet here.] ( https://hermes-beta.pyth.network/ )
57
- To try this out, use the ` get_vaa ` endpoint to request a price feed
58
- update for a price feed. You must convert the returned base64 blob to
59
- hex before using it in the ` update_price_feeds ` call due to NEAR passing
60
- bytes around with hex encoding.
61
-
62
- It's also possible to integrate this process into your contract itself
63
- to reduce the number of transactions required. See the example contract
64
- linked below.
65
-
66
- Note: gas and attachedDeposit are NEAR-specific parameters that you
67
- may need to set depending on the contract's requirements. Unused
68
- deposit will be refunded, but you can calculate an esimtate by calling
69
- the ` get_update_fee_estimate ` method against the Pyth contract.
70
-
71
- Fetching a price feed is similar:
72
-
73
- ``` js
74
- async function fetchPriceFeed () {
75
- const near = await connect (config);
76
- const account = await near .account ();
77
- const contractId = " pyth-oracle.testnet" ;
78
- const identifier = " PriceIdentifier" ;
79
-
80
- const priceFeed = await account .viewFunction (
81
- contractId,
82
- " get_price" ,
83
- args: { identifier }
84
- );
85
-
86
- console .log (" Price Feed Data: " , priceFeed);
87
- }
88
- ```
25
+ price information.
26
+
27
+ For a full overview of methods provided by the NEAR
28
+ contract, see [ the interface] ( https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/near/receiver/src/ext.rs )] exposed by the receiver contract.
29
+
30
+ ## Getting Started
31
+
32
+ To get started with Pyth oracle you will need to gather the following information which differ between networks:
33
+
34
+ - Price ID(s)
35
+ - HermesAPI Endpoint
36
+ - Smart contract address
37
+
38
+ | Network | Price Feed IDs | Hermes API Address | Contract Address |
39
+ | --------- | ------------------------------------------------------------------------------------------------ | -------------------------- | -------------------------------------------------------------------------------- |
40
+ | ` testnet ` | [ NEAR ` testnet ` Price Feed IDs] ( https://www.pyth.network/developers/price-feed-ids#near-testnet ) | ` hermes-beta.pyth.network ` | [ pyth-oracle.testnet] ( https://testnet.nearblocks.io/address/pyth-oracle.testnet ) |
41
+ | ` mainnet ` | [ NEAR ` mainnet ` Price Feed IDs] ( https://www.pyth.network/developers/price-feed-ids#near-mainnet ) | ` hermes.pyth.network ` | [ pyth-oracle.near] ( https://nearblocks.io/address/pyth-oracle.near ) |
42
+
43
+ Note: When using Price Feed IDs, you will need to remove the ` 0x ` prefix.
44
+
45
+ ---
46
+
47
+ ### ` update_price_feeds `
48
+
49
+ > Updates the Pyth Oracle contract data with the price feed you provide.
50
+
51
+ - args: ` data ` _ (off-chain hex-encoded price feed)_
52
+ - type: ` object `
53
+ - example: ` { "data": "504e41...' } `
54
+
55
+ Update the Pyth Oracle contract with new price feed data in two main steps:
56
+
57
+ 1 . [ Fetch off-chain price feed] ( #1-fetch-off-chain-price-feed )
58
+ 2 . [ Update Pyth Oracle contract with off-chain price feed] ( #2-update-pyth-oracle-contract-price-feed )
59
+
60
+ #### 1) Fetch off-chain price feed
61
+
62
+ You can obtain an off-chain price feed using Pyth's [ Hermes API] ( https://hermes-beta.pyth.network/docs/ ) .
63
+
64
+ To use these endpoints, you will need to provide a Price Feed ID and ensure you are targeting the correct network. See [ Getting Started] ( #getting-started ) for more information.
65
+
66
+ Here is a node.js example of fetching the latest price feed using ` /v2/updates/price/latest ` endpoint:
67
+
68
+ ` Example: `
69
+
70
+ ``` js
71
+ const axios = require (' axios' );
72
+
73
+ // There are separate endpoints for testnet and mainnet
74
+ const HERMES_TESTNET_URL = ' https://hermes-beta.pyth.network' ;
75
+ const HERMES_MAINNET_URL = ' https://hermes.pyth.network' ;
76
+
77
+ async function getHermesPriceData (priceId , network ) {
78
+ try {
79
+ let url;
80
+ network === ' testnet'
81
+ ? (url = HERMES_TESTNET_URL )
82
+ : (url = HERMES_MAINNET_URL );
83
+
84
+ // Fetch the price data from the Hermes API
85
+ const response = await axios .get (` ${ url} /v2/updates/price/latest?ids[]=${ priceId} ` );
86
+
87
+ return response .data .binary .data [0 ];
88
+ } catch (error) {
89
+ console .error (' Error:' , error .response ? error .response .data : error .message );
90
+ }
91
+ }
92
+
93
+ module .exports = { getHermesPriceData };
94
+ ```
95
+
96
+ <center >z
97
+ [ See full example on GitHub] ( https://github.com/near-examples/near-js/blob/main/node-js/utils/fetch-hermes-price-data.js )
98
+ </center >
99
+
100
+ ---
101
+
102
+ ### 2) Update Pyth Oracle Contract Price Feed
103
+
104
+ After [ fetching an off-chain price feed] ( #1-fetch-off-chain-price-feed ) , you can now perform a contract call to the Pyth Oracle contract to update.
105
+ Call ` update_price_feeds ` on the Pyth Oracle contract deployed on NEAR with ` data ` as your arguments.
106
+
107
+ ` example args: `
108
+
109
+ ``` json
110
+ {
111
+ "data": "504e41550100000000a00100000000010070b0ee3a00d1a3c07ee440887eb34a5a35860e6f4b9230fd62f0593fe35c8a3561735a6a37d269c5f166b84ead8918f710dc1be2ee6b51db5b22340ea2c173fc01673d544b00000000001ae101faedac5851e32b9b23b5f9411a8c2bac4aae3ed4dd7b811dd1a72ea4aa7100000000061bc18c014155575600000000000ab0f04600002710f41bc8c224ed983c68dbf5dab7dd34c9129fecfa03005500ca80ba6dc32e08d06f1aa886011eed1d77c77be9eb761cc10d72b7d0a2fd57a600000047e2eb4ef0000000000692480ffffffff800000000673d544b00000000673d544b00000048200e66a00000000005e495a60bb9370c458dd50558b34699b5b179f45e56be22f0a1a0feb1db8469adc8c5efeb53988495bac07bf9efed07f5eee43818150c55055882f6872a228e8e9bc78459ed3ea7fe0b86f3048f6bf0aad34befc46063ab7d200beb8bc9fe5839844d2233546f0742bb665f1e610370fcf8ce5be83d0f47e584b685af87cf3ebcb79e714827dcb99dba579e1a03785052ab3c7c7147d3f7bba822b04dbda159670e9a8d29e7ccf68474b2ca85e00224d29bf65b06b09f95e91703313e053b697b48ac1e4d1c57605a71ab77e7ef276bfe8a369c268333b9a37461bf2b7cb7fd4c005500ecf553770d9b10965f8fb64771e93f5690a182edc32be4a3236e0caaa6e0581a0000000e2ba8cd280000000001b40517fffffff800000000673d544b00000000673d544b0000000e3ea44c6800000000016aee120b47b853f55949284cb8ba0b63824ff9b48cd1da8417f45421b79ee3195fc8d107540a0bbb95c2445b66065754f135cb842db09a7e7ab33f79c546a48db872bd7197b04e3d7b52fbb55b3b9f51707c5a55fac3707cb563dbcde4aadeecc3649c237454cecf519dc567c0da03d81808523aa4fa71815eab25ce7da61b48647bac645d403208135002aab5fde2d7ab3c7c7147d3f7bba822b04dbda159670e9a8d29e7ccf68474b2ca85e00224d29bf65b06b09f95e91703313e053b697b48ac1e4d1c57605a71ab77e7ef276bfe8a369c268333b9a37461bf2b7cb7fd4c"
112
+ }
113
+ ```
114
+
115
+ To perform this contract call you must first create a NEAR account which can be done using ` near-cli ` .
116
+
117
+ Fist, install ` near-cli ` :
118
+
119
+ ``` bash
120
+
121
+ npm install -g near-cli-rs@latest
122
+
123
+ ```
124
+
125
+ This CLI allows you to simply run ` near ` and let the prompts guide you through the process.
126
+
127
+ To quickly create a NEAR account, run the following command (replacing ` your-new-account.testnet ` with your desired account name):
128
+
129
+ ``` bash
130
+ near account \
131
+ create-account sponsor-by-faucet-service \
132
+ your-new-account.testnet \
133
+ autogenerate-new-keypair save-to-legacy-keychain \
134
+ network-config testnet \
135
+ create
136
+ ```
137
+
138
+ To perform a contract call to the Pyth Oracle contract, run the following command:
139
+
140
+ Replace:
141
+ - ` your-account.testnet ` with your account name
142
+ - ` '{"data": "504e41550100..."}' ` with your off-chain price feed
89
143
144
+ ```
145
+ near contract \
146
+ call-function \
147
+ as-transaction pyth-oracle.testnet update_price_feeds \
148
+ json-args '{"data": "504e41550100..."}' \
149
+ prepaid-gas '300.0 Tgas' \
150
+ attached-deposit '0.01 NEAR' \
151
+ sign-as your-account.testnet \
152
+ network-config testnet \
153
+ sign-with-legacy-keychain \
154
+ send
155
+ ```
156
+
157
+ Alternatively, you can use ` near-js ` libraries to perform the contract call. For this example we will create a simple node.js project.
158
+
159
+ First, install the ` near-js ` libraries we will use:
160
+
161
+ ``` bash
162
+ npm install @near-js/client @near-js/keystores-node
163
+ ```
164
+
165
+ To setup a NEAR connection, we'll create a ` connect.js ` file that will initialize an RPC provider and signer. This will look for your NEAR credentials in your ` .near-credentials ` directory.
166
+
167
+ ``` js
168
+ // node.js imports
169
+ const { join } = require (' node:path' );
170
+ const { homedir } = require (' node:os' );
171
+
172
+ // near-js imports
173
+ const { getTestnetRpcProvider , getSignerFromKeystore } = require (' @near-js/client' );
174
+ const { UnencryptedFileSystemKeyStore } = require (' @near-js/keystores-node' );
175
+
176
+ // initialize RPC provider and signer
177
+ const nearConnect = (sender , network ) => ({
178
+ rpcProvider: getTestnetRpcProvider (),
179
+ signer: getSignerFromKeystore (
180
+ sender,
181
+ network,
182
+ new UnencryptedFileSystemKeyStore (join (homedir (), ' .near-credentials' ))
183
+ )
184
+ });
185
+
186
+ module .exports = { nearConnect };
187
+ ```
188
+
189
+ Next we can create a ` update-oracle.js ` file that will perform the contract call to update the Pyth Oracle contract's price feed.
190
+ ``` js
191
+
192
+ // near-js imports
193
+ // https://www.npmjs.com/package/@near-js/client
194
+ const { nearConnect } = require (' ../utils/connect' );
195
+ const { functionCall } = require (' @near-js/client' );
196
+
197
+ const sender = ' your-account.testnet' ;
198
+ const receiver = ' pyth-oracle.testnet' ;
199
+ const network = ' testnet' ;
200
+
201
+ const PRICE_IDS = [
202
+ // Price ids can be found at https://www.pyth.network/developers/price-feed-ids#near-testnet
203
+ // NOTE: Ensure you are using NEAR specific price ids & remove the '0x' prefix before using them
204
+ ' f9c0172ba10dfa4d19088d94f5bf61d3b54d5bd7483a322a982e1373ee8ea31b' , // BTC/USD price id
205
+ ' ca80ba6dc32e08d06f1aa886011eed1d77c77be9eb761cc10d72b7d0a2fd57a6' , // ETH/USD price id
206
+ ];
207
+
208
+ async function updatePythContractPriceFeeds (network ) {
209
+ // Connect to the NEAR network
210
+ const { rpcProvider , signer } = nearConnect (sender, network);
211
+
212
+ // Update the Pyth Oracle contract with the price data
213
+ // Performs a NEAR function call to the Pyth Oracle contract
214
+ // Deposit for transaction fee (balance will be refunded)
215
+ const result = await functionCall ({
216
+ sender,
217
+ receiver,
218
+ method: ' update_price_feeds' ,
219
+ args: { data: ' 504e4155010...' },
220
+ deposit: 10000000000000000000000 ,
221
+ deps: { rpcProvider, signer },
222
+ });
223
+
224
+ console .log (
225
+ ` Transaction 👉 https://testnet.nearblocks.io/txns/${ result .outcome .transaction .hash } `
226
+ );
227
+ return result;
228
+ }
229
+
230
+ updatePythOracle ();
231
+
232
+ ```
233
+
234
+ <center >
235
+ [ See full example on GitHub] ( https://github.com/near-examples/near-js/blob/main/node-js/oracle-example/pyth-oracle-update.js )
236
+ </center >
237
+
238
+ Although unused deposit will be refunded, you can calculate an estimate by calling the ` get_update_fee_estimate ` method against the Pyth contract.
239
+
240
+ ---
241
+
242
+ ### ` get_price `
243
+
244
+ > Fetches the most recent price feed stored in the Pyth Oracle contract. Is a view method, so does not require a signature or payment.
245
+
246
+ - args: ` price_identifier ` _ (unique [ price feed identifier] ( #environment-variables ) )_
247
+ - type: ` object `
248
+ - example: ` { price_identifier: 'f9c0172ba10dfa8...' } `
249
+
250
+ After [ updating the price feed] ( #update_price_feeds ) , you can view the feed on-chain by calling ` get_price ` on the Pyth Oracle contract. Note that this is a view method and does not require a signature or deposit.
251
+
252
+ #### NEAR CLI example
253
+
254
+ ``` bash
255
+ near contract \
256
+ call-function \
257
+ as-read-only pyth-oracle.testnet get_price \
258
+ json-args ' {"price_identifier": "f9c0172ba10dfa4d19088d94f5bf61d3b54d5bd7483a322a982e1373ee8ea31b"}' \
259
+ network-config testnet \
260
+ now
261
+
262
+ ```
263
+
264
+ #### NEAR-JS Example
265
+
266
+ For this example we will create a simple node.js project. First, install the [ ` near-js\client ` ] ( https://www.npmjs.com/package/@near-js/client ) library:
267
+
268
+ ``` bash
269
+ npm install @near-js/client
270
+ ```
271
+
272
+ Create a ` get-price.js ` file that will perform the view call from the Pyth Oracle contract. Note that this does not require a signature or deposit.
273
+
274
+ ``` js
275
+ // near-js import
276
+ // https://www.npmjs.com/package/@near-js/client
277
+ const { getTestnetRpcProvider , view } = require (' @near-js/client' );
278
+
279
+ const PRICE_IDS = [
280
+ // Price ids can be found at https://www.pyth.network/developers/price-feed-ids#near-testnet
281
+ // NOTE: Ensure you are using NEAR specific price ids & remove the '0x' prefix before using them
282
+ ' f9c0172ba10dfa4d19088d94f5bf61d3b54d5bd7483a322a982e1373ee8ea31b' , // BTC/USD price id
283
+ ' ca80ba6dc32e08d06f1aa886011eed1d77c77be9eb761cc10d72b7d0a2fd57a6' , // ETH/USD price id
284
+ ];
285
+
286
+ async function getPrice (price_ID , symbol ) {
287
+ try {
288
+ const rpcProvider = getTestnetRpcProvider ();
289
+ const result = await view ({
290
+ account: ' pyth-oracle.testnet' ,
291
+ method: ' get_price' ,
292
+ args: { price_identifier: price_ID },
293
+ deps: { rpcProvider },
294
+ });
295
+ console .log (symbol, result);
296
+ } catch (error) {
297
+ console .error (` Error fetching ${ symbol} price:` , error .message );
298
+ }
299
+ }
300
+
301
+ getPrice (PRICE_IDS [0 ], ' BTC/USD:' );
302
+
303
+ ```
304
+
305
+ <center >
306
+ [ See full example on GitHub] ( https://github.com/near-examples/near-js/blob/main/node-js/oracle-example/pyth-oracle-view.js )
307
+ </center >
308
+
309
+ ---
90
310
## On-Chain Prices
91
311
92
312
For on-chain price interactions, see the [ example contract] [ ] in the
@@ -100,8 +320,3 @@ see the [update.sh][] example script in the repository to see how to
100
320
pull prices with the official NEAR cli.
101
321
102
322
[ update.sh ] : https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/near/scripts/update.sh
103
-
104
- ## Contract Addresses
105
-
106
- Developers will need the address of the Pyth price feed contract on their blockchain in order to use Pyth.
107
- Please consult [ Near Contract Addresses] ( ../contract-addresses/near ) to find the address for your blockchain.
0 commit comments