Skip to content

Commit 71404fb

Browse files
feat: enhance near pyth docs
1 parent b5ac946 commit 71404fb

File tree

1 file changed

+294
-79
lines changed
  • pages/price-feeds/use-real-time-data

1 file changed

+294
-79
lines changed

pages/price-feeds/use-real-time-data/near.mdx

Lines changed: 294 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -9,84 +9,304 @@ price feeds, handling the retrieval and updating of price data.
99
The two Key functions in the Pyth receiver contract to get started
1010
are as follows:
1111

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...' }`
1422

1523
These functions are core for interacting with Pyth price feeds in
1624
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
89143

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+
---
90310
## On-Chain Prices
91311

92312
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
100320
pull prices with the official NEAR cli.
101321

102322
[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

Comments
 (0)