From c22091f5c2102794e46f002cc7965403b3b3a164 Mon Sep 17 00:00:00 2001 From: Josh Date: Sat, 26 Oct 2024 14:16:17 -0700 Subject: [PATCH 01/10] fix: update oracle intro with high level explanation --- docs/2.build/5.primitives/oracles.md | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/docs/2.build/5.primitives/oracles.md b/docs/2.build/5.primitives/oracles.md index 47c25a7bb55..5b9dc147081 100644 --- a/docs/2.build/5.primitives/oracles.md +++ b/docs/2.build/5.primitives/oracles.md @@ -1,18 +1,18 @@ --- id: oracles -title: Price Oracles +title: Oracles --- import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -Oracles are smart contracts that enable you to query the current price of an asset. +[Oracles](https://en.wikipedia.org/wiki/Blockchain_oracle) act as a bridge between a blockchain platform and off-chain data allowing smart contracts the ability to access information from the outside-world. Because blockchain platforms operate in a closed ecosystem or "walled garden", these third party oracle services are essential in providing access to external data, events, or APIs. -Since smart contracts cannot connect to -internet and pull information, Oracles rely on having someone constantly updating their prices. Because of that, be mindful -when using an oracle that there might be a delay between the market's latest information and the Oracles data. +Examples include: -Oracle contract's are not standardized. We will here list different providers and how to use their Oracle as they are built. +- **Price Feeds** -> _Real-time price information for cryptocurrencies, stocks, or commodities._ +- **Event Information** -> _Reporting occurrences such as sporting events or weather conditions_ +- **APIs** -> _Connecting smart contracts to external web services or systems._ --- @@ -23,8 +23,6 @@ Oracle contract's are not standardized. We will here list different providers an - Smart contract: https://github.com/NearDeFi/price-oracle - Bot to fill contract: https://github.com/NearDeFi/near-price-oracle-bot ---- - ## Query Assets @@ -32,7 +30,7 @@ Oracle contract's are not standardized. We will here list different providers an ```bash near view priceoracle.near get_assets -``` +``` From b1b7d14b1e66d110c450992cf0816401650a0f09 Mon Sep 17 00:00:00 2001 From: Josh Date: Tue, 29 Oct 2024 07:46:12 -0700 Subject: [PATCH 02/10] fix: update formatting/structure and add pyth --- docs/2.build/5.primitives/oracles.md | 168 +++++++++++++++++++++------ 1 file changed, 135 insertions(+), 33 deletions(-) diff --git a/docs/2.build/5.primitives/oracles.md b/docs/2.build/5.primitives/oracles.md index 5b9dc147081..7cc1da3e524 100644 --- a/docs/2.build/5.primitives/oracles.md +++ b/docs/2.build/5.primitives/oracles.md @@ -6,24 +6,42 @@ title: Oracles import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -[Oracles](https://en.wikipedia.org/wiki/Blockchain_oracle) act as a bridge between a blockchain platform and off-chain data allowing smart contracts the ability to access information from the outside-world. Because blockchain platforms operate in a closed ecosystem or "walled garden", these third party oracle services are essential in providing access to external data, events, or APIs. +[Blockchain Oracles](https://en.wikipedia.org/wiki/Blockchain_oracle) serve as intermediaries that connect blockchain platforms with off-chain data. As blockchain platforms operate in a closed ecosystem or "walled garden", these third party oracle services are essential in providing access to external data, events, or APIs. -Examples include: +Oracles can provide: -- **Price Feeds** -> _Real-time price information for cryptocurrencies, stocks, or commodities._ -- **Event Information** -> _Reporting occurrences such as sporting events or weather conditions_ -- **APIs** -> _Connecting smart contracts to external web services or systems._ +- **Price Feeds:** Real-time pricing for cryptocurrencies, stocks, or commodities. +- **Event Information:** Updates on real-world events like sports results or weather conditions. +- **API Access:** Connections to external web services and systems. + +:::info +Oracles, being external third-party services, require careful consideration of their reliability, security, and decentralization to avoid risks such as incorrect data, manipulation, or single points of failure. +::: + +--- + +## Deployed Oracles on NEAR + +Here is a directory of third-party oracle services deployed on the NEAR blockchain: + +| Name | Creator | Description | +| -------------------------------------------------------------------------------------------------------- | --------------------------------------- | -------------------------------------------------- | +| [Price Oracle](#price-oracle) | [NearDefi](https://github.com/NearDeFi) | Open source oracle for real-time asset pricing | +| [Pyth Network Oracle](#pyth-network-oracle) | [Pyth Network](https://pyth.network/) | High-frequency, low-latency oracle for price feeds | +| **[[Your Project Here]](https://github.com/near/docs/edit/master/docs/2.build/5.primitives/oracles.md)** | - | - | --- -## Price Oracles +## Price Oracle by NearDefi -- Account: **priceoracle.near** | **priceoracle.testnet** -- Creator: [NearDefi](https://github.com/NearDeFi) -- Smart contract: https://github.com/NearDeFi/price-oracle -- Bot to fill contract: https://github.com/NearDeFi/near-price-oracle-bot +- **Creator:** [NearDefi](https://github.com/NearDeFi) +- **Codebase:** [NearDefi/price-oracle](https://github.com/NearDeFi/price-oracle) +- **Bot for Data Feeds:** [NearDefi/near-price-oracle-bot](https://github.com/NearDeFi/near-price-oracle-bot) +- **Deployed Addresses:** + - Mainnet: [priceoracle.near](https://nearblocks.io/address/priceoracle.near) + - Testnet: [priceoracle.testnet](https://testnet.nearblocks.io/address/priceoracle.testnet) -## Query Assets +### Query Assets @@ -32,13 +50,9 @@ Examples include: near view priceoracle.near get_assets ``` - - - - -
- -Example response +
+ + Example Response ```json [ @@ -51,24 +65,18 @@ near view priceoracle.near get_assets timestamp: '1669795900809627816', price: { multiplier: '17030', decimals: 28 } }, - { - oracle_id: 'npo-aurora.near', - timestamp: '1706631791706032710', - price: { multiplier: '30641', decimals: 28 } - }, - { - oracle_id: 'gloriafoster.near', - timestamp: '1706631808550973590', - price: { multiplier: '30666', decimals: 28 } - }, ... + ] + } + ] +] ``` -
- ---- +
+ +
-## Get Assets Price +### Get Assets Price @@ -111,7 +119,101 @@ near view priceoracle.near get_price_data :::tip +For USD values, divide the `multiplier` by `10^4`. +::: + +--- + +## Pyth Network Oracle + +- **Creator:** [Pyth Network](https://pyth.network) +- **Documentation:** [Pyth NEAR Docs](https://docs.pyth.network/price-feeds/use-real-time-data/near) +- **Codebase:** [pyth-network/pyth-crosschain](https://github.com/pyth-network/pyth-crosschain/tree/main/target_chains/near) +- **Deployed Addresses:** + - Mainnet: [pyth-oracle.near](https://nearblocks.io/address/pyth-oracle.near) + - Testnet: [pyth-oracle.testnet](https://testnet.nearblocks.io/address/pyth-oracle.testnet) + +### Pyth Network Capabilities + +Pyth's NEAR smart contract provides the following core price feed methods: + +- `update_price_feeds`: Refreshes multiple feeds with fresh data. +- `get_price`: Fetches current prices for specific feeds. + +See Pyth's [`receiver` contract methods documentation](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/near/receiver/src/ext.rs) for a complete detailed list. + +### Integrating Price Feeds + +1. **Install the NEAR JavaScript SDK:** + + ```bash + npm install near-api-js + # or + yarn add near-api-js + ``` + +2. **Interact with the Contract:** + + ```javascript + // Using async/await for NEAR API calls + async function updatePriceFeeds(data) { + const near = await connect(config); + const result = await account.functionCall({ + contractId: 'pyth.testnet', + methodName: 'update_price_feeds', + args: { data }, + gas: new utils.BN('30000000000000'), + attachedDeposit: utils.format.parseNearAmount('1'), + }); + console.log('Update Price Feeds Result: ', result); + } + ``` + + ```js + async function fetchPriceFeed() { + const near = await connect(config); + const account = await near.account(); + const contractId = "pyth-oracle.testnet"; + const identifier = "PriceIdentifier"; -Divide the returned `multiplier` by `10000` to obtain the price in USD. + const priceFeed = await account.viewFunction( + contractId, + "get_price", + args: { identifier } + ); + console.log("Price Feed Data: ", priceFeed); + } + ``` + +Furthermore, + +Note: The parameters gas and attachedDeposit are specific to NEAR and must be adjusted based on your contract's demands. While any unused deposit will be refunded, it's advisable to estimate potential costs by invoking the get_update_fee_estimate method on the Pyth contract. + +Updates can be submitted to this call and sourced from the [Hermes API](https://hermes-beta.pyth.network/) for testnet. To try this out, use the `get_vaa` endpoint to request a price feed +update. Remember, you must convert the returned base64 blob to +hex before using it in the `update_price_feeds` call due to NEAR requiring hex encoding for byte data. + +Integrating this updating process directly within your contract can streamline operations by reducing the number of transactions needed. For implementation details, refer to the example contract linked below. + +Refer to the [Pyth example contract](https://github.com/pyth-network/pyth-crosschain/tree/main/target_chains/near/example) for more detailed integration approaches. + +:::info +Gas and attachedDeposit are NEAR-specific parameters that you +may need to set depending on the contract's requirements. Unused +deposit will be refunded, but you can calculate an esimtate by calling +the `get_update_fee_estimate` method against the Pyth contract. ::: + + +## On-Chain Prices + +For on-chain price interactions, see the [example contract](https://github.com/pyth-network/pyth-crosschain/tree/main/target_chains/near/example) in the Pyth Github repo for an example of how to update and use prices within a NEAR contract. + +A CLI-based approach can also be taken for interacting with Pyth prices, +see the [update.sh](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/near/scripts/update.sh) example script in the repository to see how to pull prices with the official NEAR cli. + +## Contract Addresses + +Developers will need the address of the Pyth price feed contract on their blockchain in order to use Pyth. +Please consult [Near Contract Addresses](https://docs.pyth.network/price-feeds/contract-addresses/near) to find the address for your blockchain. From 7d68bfd113ea375d2e5dd973f316fdc55c961c02 Mon Sep 17 00:00:00 2001 From: Guille Date: Sat, 9 Nov 2024 09:40:42 +0700 Subject: [PATCH 03/10] Update docs/2.build/5.primitives/oracles.md --- docs/2.build/5.primitives/oracles.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/2.build/5.primitives/oracles.md b/docs/2.build/5.primitives/oracles.md index 7cc1da3e524..292ce579319 100644 --- a/docs/2.build/5.primitives/oracles.md +++ b/docs/2.build/5.primitives/oracles.md @@ -6,7 +6,7 @@ title: Oracles import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -[Blockchain Oracles](https://en.wikipedia.org/wiki/Blockchain_oracle) serve as intermediaries that connect blockchain platforms with off-chain data. As blockchain platforms operate in a closed ecosystem or "walled garden", these third party oracle services are essential in providing access to external data, events, or APIs. +[Blockchain Oracles](https://en.wikipedia.org/wiki/Blockchain_oracle) serve as intermediaries that connect smart contracts with external (off-chain) data. Oracles can provide: From 6eabb27e1186e5cd55c187c849a747cc7a3e5e78 Mon Sep 17 00:00:00 2001 From: Josh Date: Mon, 11 Nov 2024 16:04:05 -0800 Subject: [PATCH 04/10] dev-changelog --- docs/2.build/5.primitives/oracles.md | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/docs/2.build/5.primitives/oracles.md b/docs/2.build/5.primitives/oracles.md index 7cc1da3e524..a25691726c1 100644 --- a/docs/2.build/5.primitives/oracles.md +++ b/docs/2.build/5.primitives/oracles.md @@ -48,6 +48,7 @@ Here is a directory of third-party oracle services deployed on the NEAR blockcha ```bash near view priceoracle.near get_assets +near contract call-function as-read-only priceoracle.near get_assets json-args {} network-config mainnet now ```
@@ -144,15 +145,7 @@ See Pyth's [`receiver` contract methods documentation](https://github.com/pyth-n ### Integrating Price Feeds -1. **Install the NEAR JavaScript SDK:** - - ```bash - npm install near-api-js - # or - yarn add near-api-js - ``` - -2. **Interact with the Contract:** +1. **Interact with the Contract:** ```javascript // Using async/await for NEAR API calls @@ -186,8 +179,6 @@ See Pyth's [`receiver` contract methods documentation](https://github.com/pyth-n } ``` -Furthermore, - Note: The parameters gas and attachedDeposit are specific to NEAR and must be adjusted based on your contract's demands. While any unused deposit will be refunded, it's advisable to estimate potential costs by invoking the get_update_fee_estimate method on the Pyth contract. Updates can be submitted to this call and sourced from the [Hermes API](https://hermes-beta.pyth.network/) for testnet. To try this out, use the `get_vaa` endpoint to request a price feed @@ -205,7 +196,6 @@ deposit will be refunded, but you can calculate an esimtate by calling the `get_update_fee_estimate` method against the Pyth contract. ::: - ## On-Chain Prices For on-chain price interactions, see the [example contract](https://github.com/pyth-network/pyth-crosschain/tree/main/target_chains/near/example) in the Pyth Github repo for an example of how to update and use prices within a NEAR contract. From 2d1d49ebc4fce7c3cd3ac688fd1d40184562e37d Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 14 Nov 2024 10:00:22 -0800 Subject: [PATCH 05/10] wip --- docs/2.build/5.primitives/oracles.md | 93 +++++++++++++++++----------- 1 file changed, 58 insertions(+), 35 deletions(-) diff --git a/docs/2.build/5.primitives/oracles.md b/docs/2.build/5.primitives/oracles.md index ad091c2734a..0bc794e7550 100644 --- a/docs/2.build/5.primitives/oracles.md +++ b/docs/2.build/5.primitives/oracles.md @@ -3,11 +3,14 @@ id: oracles title: Oracles --- +import {CodeTabs, Language, Github} from "@site/src/components/codetabs"; import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; [Blockchain Oracles](https://en.wikipedia.org/wiki/Blockchain_oracle) serve as intermediaries that connect smart contracts with external (off-chain) data. +--- + Oracles can provide: - **Price Feeds:** Real-time pricing for cryptocurrencies, stocks, or commodities. @@ -143,41 +146,61 @@ Pyth's NEAR smart contract provides the following core price feed methods: See Pyth's [`receiver` contract methods documentation](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/near/receiver/src/ext.rs) for a complete detailed list. -### Integrating Price Feeds - -1. **Interact with the Contract:** - - ```javascript - // Using async/await for NEAR API calls - async function updatePriceFeeds(data) { - const near = await connect(config); - const result = await account.functionCall({ - contractId: 'pyth.testnet', - methodName: 'update_price_feeds', - args: { data }, - gas: new utils.BN('30000000000000'), - attachedDeposit: utils.format.parseNearAmount('1'), - }); - console.log('Update Price Feeds Result: ', result); - } - ``` - - ```js - async function fetchPriceFeed() { - const near = await connect(config); - const account = await near.account(); - const contractId = "pyth-oracle.testnet"; - const identifier = "PriceIdentifier"; - - const priceFeed = await account.viewFunction( - contractId, - "get_price", - args: { identifier } - ); - - console.log("Price Feed Data: ", priceFeed); - } - ``` +### `update_price_feeds` + +Calling Pyth Network Oracle's `update_price_feeds` smart contract method Updating price feeds on the Pyth Oracle contract is done through a few steps: + +1. Get Price IDs from [NEAR Pyth Price Feeds](https://www.pyth.network/developers/price-feed-ids#near-testnet) +2. Fetch the current price feed update from Hermes API +3. Convert the returned base64 blob to hex +4. Call `update_price_feeds` with the hex-encoded price feed + +#### Get Price IDs + +- **Testnet:** [NEAR Pyth Price Feeds](https://www.pyth.network/developers/price-feed-ids#near-testnet) +- **Mainnet:** [NEAR Mainnet Price Feeds](https://www.pyth.network/developers/price-feed-ids#near) + +#### Fetch Price Feeds + +https://docs.pyth.network/price-feeds/how-pyth-works/hermes + + +Using the price ID, fetch the current price using `/get_vaa` endpoint. + +- **Testnet:** [hermes-beta.pyth.network](https://hermes-beta.pyth.network/) +- **Mainnet:** [hermes.pyth.network](https://hermes.pyth.network/) +- Fetch the current price feed update from the [Hermes API](https://hermes-beta.pyth.network/). + + +https://hermes-beta.pyth.network/api/get_vaa?id=${priceId}&publish_time=${publishTime} + + +``` + +#### Convert to Hex + +Convert the returned base64 blob to hex. + +Here is an example of the entire process: + +Check `_app.js` and `index.js` to understand how components are displayed and interacting with the contract. + + + + + +You have two options to start the Counter Example. + +1. You can use the app through `GitHub Codespaces`, which will open a web-based interactive environment. +2. Clone the repository locally and use it from your computer. + +| Codespaces | Clone locally | +| ---------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | +| [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/near-examples/near-js) | 🌐 `https://github.com/near-examples/near-js` | + +### Updating Pyth Oracle Price Feeds + Note: The parameters gas and attachedDeposit are specific to NEAR and must be adjusted based on your contract's demands. While any unused deposit will be refunded, it's advisable to estimate potential costs by invoking the get_update_fee_estimate method on the Pyth contract. From 70b85abfb4a2d78b175380afc7b583bea85f32f8 Mon Sep 17 00:00:00 2001 From: Josh Date: Thu, 14 Nov 2024 20:39:14 -0800 Subject: [PATCH 06/10] feat: update using oracle and code snippets --- docs/2.build/5.primitives/oracles.md | 134 ++++++++++++++++++++------- 1 file changed, 101 insertions(+), 33 deletions(-) diff --git a/docs/2.build/5.primitives/oracles.md b/docs/2.build/5.primitives/oracles.md index 0bc794e7550..ad3ff70e140 100644 --- a/docs/2.build/5.primitives/oracles.md +++ b/docs/2.build/5.primitives/oracles.md @@ -137,70 +137,138 @@ For USD values, divide the `multiplier` by `10^4`. - Mainnet: [pyth-oracle.near](https://nearblocks.io/address/pyth-oracle.near) - Testnet: [pyth-oracle.testnet](https://testnet.nearblocks.io/address/pyth-oracle.testnet) -### Pyth Network Capabilities +### Using Pyth Network Oracle -Pyth's NEAR smart contract provides the following core price feed methods: +Pyth's NEAR smart contract has two core methods to update & get prices. -- `update_price_feeds`: Refreshes multiple feeds with fresh data. -- `get_price`: Fetches current prices for specific feeds. +1. [`update_price_feeds`](#update_price_feeds) + _(updates Pyth smart contract with the price feed you provide)_ + - args: `data` + - type: `object` + - example: `{ "data": "504e41...' }` +2. [`get_price`](#get_price) (fetches the most recent price stored in the contract)\_ + - args: `price_identifer` + - type: `object` + - example: `{ price_identifier: 'f9c0172ba10dfa8...' }` -See Pyth's [`receiver` contract methods documentation](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/near/receiver/src/ext.rs) for a complete detailed list. +:::info +For a complete list of endpoints to interact with, see [Pyth's `receiver` contract](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/near/receiver/src/ext.rs). +::: + +### Network Configuration + +When interacting with Pyth oracle you will need: + +- Price ID(s) +- HermesAPI Endpoint +- Smart contract address + +Each of these variables differ between networks: + +| Network | Price Feed IDs | Hermes API Address | Contract Address | +| --------- | ------------------------------------------------------------------------------------------------ | -------------------------- | --------------------------- | +| `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) | +| `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) | + +Price ID Example: + +| Network | Asset | Price Feed ID | +| --------- | ------- | -------------------------------------------------------------------- | +| `testnet` | BTC/USD | `0xf9c0172ba10dfa4d19088d94f5bf61d3b54d5bd7483a322a982e1373ee8ea31b` | +| `mainnet` | BTC/USD | `0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43` | ### `update_price_feeds` -Calling Pyth Network Oracle's `update_price_feeds` smart contract method Updating price feeds on the Pyth Oracle contract is done through a few steps: +This method updates the Pyth oracle smart contract's stored price feed with a real-time price feed data blob you provide. To obtain a price feed data payload you can use Pyth's [Hermes API](https://docs.pyth.network/price-feeds/api-instances-and-providers/hermes) endpoint. + +Be sure you are using the correct API for the network you are targeting (e.g. `hermes-beta.pyth.network` for `testnet`) See network section above. + +This process involves: -1. Get Price IDs from [NEAR Pyth Price Feeds](https://www.pyth.network/developers/price-feed-ids#near-testnet) -2. Fetch the current price feed update from Hermes API -3. Convert the returned base64 blob to hex -4. Call `update_price_feeds` with the hex-encoded price feed +1. Get Price IDs +2. Fetch feed from Hermes API +3. Encode API response to hex +4. Call `update_price_feeds` with hex-encoded price feed -#### Get Price IDs +### Price Feed IDs -- **Testnet:** [NEAR Pyth Price Feeds](https://www.pyth.network/developers/price-feed-ids#near-testnet) -- **Mainnet:** [NEAR Mainnet Price Feeds](https://www.pyth.network/developers/price-feed-ids#near) +Pyth Network uses price feed IDs that map to their contract addresses to uniquely identify price feeds. Please note: -#### Fetch Price Feeds +- Each price feed ID is unique to an asset and network. +- When using the Price Feed ID you will need to remove the `0x` prefix. +- List of `testnet` price feed IDs can be found [here](https://www.pyth.network/developers/price-feed-ids#near-testnet). +- List of `mainnet` price feed IDs can be found [here](https://www.pyth.network/developers/price-feed-ids#near). -https://docs.pyth.network/price-feeds/how-pyth-works/hermes -Using the price ID, fetch the current price using `/get_vaa` endpoint. +### Fetch Price Feeds -- **Testnet:** [hermes-beta.pyth.network](https://hermes-beta.pyth.network/) -- **Mainnet:** [hermes.pyth.network](https://hermes.pyth.network/) -- Fetch the current price feed update from the [Hermes API](https://hermes-beta.pyth.network/). +Fetch price feeds using the [Hermes API](https://docs.pyth.network/price-feeds/how-pyth-works/hermes) `/get_vaa` endpoint using the following parameters: +- Price Feed ID +- Publish Time in milliseconds -https://hermes-beta.pyth.network/api/get_vaa?id=${priceId}&publish_time=${publishTime} +_Example using node.js & [`axios`](https://www.npmjs.com/package/axios):_ +```js +// Define priceId and publishTime variables +// NOTE: Remove the `0x` prefix from the price feed ID +const priceId = 'f9c0172ba10dfa4d19088d94f5bf61d3b54d5bd7483a322a982e1373ee8ea31b'; // BTC testnet price feed ID +const publishTime = Math.floor(Date.now() / 1000) - 1; // Current time minus 1 millisecond to account for latency +// Fetch price data from Hermes API beta endpoint for testnet +const response = await axios.get( + `https://hermes-beta.pyth.network/api/get_vaa?id=${priceId}&publish_time=${publishTime}` +); + +// Convert base64 response to hex format for NEAR +const base64 = Buffer.from(response.data.vaa, 'base64').toString('hex'); + +// Log the hex value +console.log(base64); ``` -#### Convert to Hex +### Calling `update_price_feeds` + + + +```js +// https://www.npmjs.com/package/@near-js/client +const { nearConnect } = require('../utils/connect'); +const { functionCall } = require('@near-js/client'); + +async function updatePythContractPriceFeeds() { + const { rpcProvider, signer } = nearConnect(sender, 'testnet'); -Convert the returned base64 blob to hex. + const publishTime = Math.floor(Date.now() / 1000) - 1; + const data = await getHermesPriceData(PRICE_IDS[0], publishTime); -Here is an example of the entire process: + const result = await functionCall({ + sender, + receiver, + method: 'update_price_feeds', + args: { data }, + deposit: 100000000000000000000000, + deps: { rpcProvider, signer }, + }); -Check `_app.js` and `index.js` to understand how components are displayed and interacting with the contract. + console.log( + `Transaction 👉 https://testnet.nearblocks.io/txns/${result.outcome.transaction.hash}` + ); + return result; +} + +updatePythContractPriceFeeds(); +``` -You have two options to start the Counter Example. - -1. You can use the app through `GitHub Codespaces`, which will open a web-based interactive environment. -2. Clone the repository locally and use it from your computer. - -| Codespaces | Clone locally | -| ---------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | -| [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/near-examples/near-js) | 🌐 `https://github.com/near-examples/near-js` | - ### Updating Pyth Oracle Price Feeds +### `get_price` Note: The parameters gas and attachedDeposit are specific to NEAR and must be adjusted based on your contract's demands. While any unused deposit will be refunded, it's advisable to estimate potential costs by invoking the get_update_fee_estimate method on the Pyth contract. From b0708e1fd7c2bc4d856427e2be7a6dd4da7bd696 Mon Sep 17 00:00:00 2001 From: Josh Date: Fri, 15 Nov 2024 15:06:25 -0800 Subject: [PATCH 07/10] feat: add update_price_feed example code --- docs/2.build/5.primitives/oracles.md | 68 +++++++++++++--------------- 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/docs/2.build/5.primitives/oracles.md b/docs/2.build/5.primitives/oracles.md index ad3ff70e140..ebe14284732 100644 --- a/docs/2.build/5.primitives/oracles.md +++ b/docs/2.build/5.primitives/oracles.md @@ -9,9 +9,7 @@ import TabItem from '@theme/TabItem'; [Blockchain Oracles](https://en.wikipedia.org/wiki/Blockchain_oracle) serve as intermediaries that connect smart contracts with external (off-chain) data. ---- - -Oracles can provide: +`Example:` - **Price Feeds:** Real-time pricing for cryptocurrencies, stocks, or commodities. - **Event Information:** Updates on real-world events like sports results or weather conditions. @@ -165,72 +163,68 @@ When interacting with Pyth oracle you will need: Each of these variables differ between networks: -| Network | Price Feed IDs | Hermes API Address | Contract Address | -| --------- | ------------------------------------------------------------------------------------------------ | -------------------------- | --------------------------- | +| Network | Price Feed IDs | Hermes API Address | Contract Address | +| --------- | ------------------------------------------------------------------------------------------------ | -------------------------- | -------------------------------------------------------------------------------- | | `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) | -| `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) | - -Price ID Example: - -| Network | Asset | Price Feed ID | -| --------- | ------- | -------------------------------------------------------------------- | -| `testnet` | BTC/USD | `0xf9c0172ba10dfa4d19088d94f5bf61d3b54d5bd7483a322a982e1373ee8ea31b` | -| `mainnet` | BTC/USD | `0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43` | +| `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) | ### `update_price_feeds` -This method updates the Pyth oracle smart contract's stored price feed with a real-time price feed data blob you provide. To obtain a price feed data payload you can use Pyth's [Hermes API](https://docs.pyth.network/price-feeds/api-instances-and-providers/hermes) endpoint. +This method updates Pyth Oracle smart contract with the price feed from an external source. -Be sure you are using the correct API for the network you are targeting (e.g. `hermes-beta.pyth.network` for `testnet`) See network section above. +This process requires the following steps: -This process involves: +1. [Get Price IDs](#1-get-price-ids) +2. [Fetch feed from Hermes API](#2-fetch-feed-from-hermes-api) +3. [Encode API response to hex for NEAR](#3-encode-api-response-to-hex-for-near) +4. [Call `update_price_feeds`](#4-call-update_price_feeds) -1. Get Price IDs -2. Fetch feed from Hermes API -3. Encode API response to hex -4. Call `update_price_feeds` with hex-encoded price feed - -### Price Feed IDs - -Pyth Network uses price feed IDs that map to their contract addresses to uniquely identify price feeds. Please note: +--- -- Each price feed ID is unique to an asset and network. -- When using the Price Feed ID you will need to remove the `0x` prefix. -- List of `testnet` price feed IDs can be found [here](https://www.pyth.network/developers/price-feed-ids#near-testnet). -- List of `mainnet` price feed IDs can be found [here](https://www.pyth.network/developers/price-feed-ids#near). +#### 1) Get Price IDs +Pyth Network uses price feed IDs that map to their contract addresses to uniquely identify price feeds. Find the price ID(s) for the feed you want to update: +- [NEAR `testnet` Price Feed IDs](https://www.pyth.network/developers/price-feed-ids#near-testnet) +- [NEAR `mainnet` Price Feed IDs](https://www.pyth.network/developers/price-feed-ids#near) -### Fetch Price Feeds +#### 2) Fetch feed from Hermes API Fetch price feeds using the [Hermes API](https://docs.pyth.network/price-feeds/how-pyth-works/hermes) `/get_vaa` endpoint using the following parameters: - Price Feed ID - Publish Time in milliseconds -_Example using node.js & [`axios`](https://www.npmjs.com/package/axios):_ +`Example:` ```js // Define priceId and publishTime variables // NOTE: Remove the `0x` prefix from the price feed ID -const priceId = 'f9c0172ba10dfa4d19088d94f5bf61d3b54d5bd7483a322a982e1373ee8ea31b'; // BTC testnet price feed ID +const priceId = + 'f9c0172ba10dfa4d19088d94f5bf61d3b54d5bd7483a322a982e1373ee8ea31b'; // BTC testnet price feed ID const publishTime = Math.floor(Date.now() / 1000) - 1; // Current time minus 1 millisecond to account for latency // Fetch price data from Hermes API beta endpoint for testnet const response = await axios.get( `https://hermes-beta.pyth.network/api/get_vaa?id=${priceId}&publish_time=${publishTime}` ); +``` -// Convert base64 response to hex format for NEAR -const base64 = Buffer.from(response.data.vaa, 'base64').toString('hex'); +#### 3) Encode API response to hex for NEAR + +NEAR requires hex-encoded price feeds, so you will need to convert the base64 response to hex. + +`Example:` -// Log the hex value -console.log(base64); +```js +const base64 = Buffer.from(response.data.vaa, 'base64').toString('hex'); ``` -### Calling `update_price_feeds` +#### 4) Call `update_price_feeds` +With the hex-encoded price feed data, call `update_price_feeds` on the NEAR Pyth contract. You can do this using the `near-js/client` library. +`Example:` ```js // https://www.npmjs.com/package/@near-js/client @@ -261,6 +255,8 @@ async function updatePythContractPriceFeeds() { updatePythContractPriceFeeds(); ``` +### Full example for `testnet` using a node.js script + From 97ed169ba70de091bbcb50296f4af9eb42706bbc Mon Sep 17 00:00:00 2001 From: Josh Date: Fri, 15 Nov 2024 15:10:33 -0800 Subject: [PATCH 08/10] fix: remove duplicate contract ID listing --- docs/2.build/5.primitives/oracles.md | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/docs/2.build/5.primitives/oracles.md b/docs/2.build/5.primitives/oracles.md index ebe14284732..b90e317798f 100644 --- a/docs/2.build/5.primitives/oracles.md +++ b/docs/2.build/5.primitives/oracles.md @@ -262,16 +262,10 @@ updatePythContractPriceFeeds(); url="https://github.com/near-examples/near-js/blob/2b28f287faeecd20ef4bccaea1606434594b9507/node-js/oracle-example/pyth-oracle-update.js"/> -### Updating Pyth Oracle Price Feeds - ### `get_price` Note: The parameters gas and attachedDeposit are specific to NEAR and must be adjusted based on your contract's demands. While any unused deposit will be refunded, it's advisable to estimate potential costs by invoking the get_update_fee_estimate method on the Pyth contract. -Updates can be submitted to this call and sourced from the [Hermes API](https://hermes-beta.pyth.network/) for testnet. To try this out, use the `get_vaa` endpoint to request a price feed -update. Remember, you must convert the returned base64 blob to -hex before using it in the `update_price_feeds` call due to NEAR requiring hex encoding for byte data. - Integrating this updating process directly within your contract can streamline operations by reducing the number of transactions needed. For implementation details, refer to the example contract linked below. Refer to the [Pyth example contract](https://github.com/pyth-network/pyth-crosschain/tree/main/target_chains/near/example) for more detailed integration approaches. @@ -290,7 +284,3 @@ For on-chain price interactions, see the [example contract](https://github.com/p A CLI-based approach can also be taken for interacting with Pyth prices, see the [update.sh](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/near/scripts/update.sh) example script in the repository to see how to pull prices with the official NEAR cli. -## Contract Addresses - -Developers will need the address of the Pyth price feed contract on their blockchain in order to use Pyth. -Please consult [Near Contract Addresses](https://docs.pyth.network/price-feeds/contract-addresses/near) to find the address for your blockchain. From f48d12090a1d8a377934a243e320a6a89e0a9ee0 Mon Sep 17 00:00:00 2001 From: Josh Date: Fri, 15 Nov 2024 15:25:38 -0800 Subject: [PATCH 09/10] feat: add get_price code example --- docs/2.build/5.primitives/oracles.md | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/docs/2.build/5.primitives/oracles.md b/docs/2.build/5.primitives/oracles.md index b90e317798f..dd5ecefb4bc 100644 --- a/docs/2.build/5.primitives/oracles.md +++ b/docs/2.build/5.primitives/oracles.md @@ -144,7 +144,7 @@ Pyth's NEAR smart contract has two core methods to update & get prices. - args: `data` - type: `object` - example: `{ "data": "504e41...' }` -2. [`get_price`](#get_price) (fetches the most recent price stored in the contract)\_ +2. [`get_price`](#get_price) (fetches the most recent price stored in the contract)_ - args: `price_identifer` - type: `object` - example: `{ price_identifier: 'f9c0172ba10dfa8...' }` @@ -153,7 +153,7 @@ Pyth's NEAR smart contract has two core methods to update & get prices. For a complete list of endpoints to interact with, see [Pyth's `receiver` contract](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/near/receiver/src/ext.rs). ::: -### Network Configuration +### Environment Variables When interacting with Pyth oracle you will need: @@ -172,6 +172,10 @@ Each of these variables differ between networks: This method updates Pyth Oracle smart contract with the price feed from an external source. +- args: `data` +- type: `object` +- example: `{ "data": "504e41...' }` + This process requires the following steps: 1. [Get Price IDs](#1-get-price-ids) @@ -224,6 +228,8 @@ const base64 = Buffer.from(response.data.vaa, 'base64').toString('hex'); With the hex-encoded price feed data, call `update_price_feeds` on the NEAR Pyth contract. You can do this using the `near-js/client` library. +Note: The parameters gas and attachedDeposit are specific to NEAR and must be adjusted based on your contract's demands. While any unused deposit will be refunded, it's advisable to estimate potential costs by invoking the get_update_fee_estimate method on the Pyth contract. + `Example:` ```js @@ -264,7 +270,20 @@ updatePythContractPriceFeeds(); ### `get_price` -Note: The parameters gas and attachedDeposit are specific to NEAR and must be adjusted based on your contract's demands. While any unused deposit will be refunded, it's advisable to estimate potential costs by invoking the get_update_fee_estimate method on the Pyth contract. +This method fetches the most recent price stored in the Pyth Oracle contract. + +- args: `price_identifier` +- type: `object` +- example: `{ price_identifier: 'f9c0172ba10dfa8...' }` + +The price identifier is the unique [Price Feed ID](#environment-variables) for the price feed you want to fetch. Once you have the price identifier, you can call `get_price` on the Pyth Oracle contract. This contract call is a `view` method, so it does not require a signature or payment. + +`Example:` + + + + Integrating this updating process directly within your contract can streamline operations by reducing the number of transactions needed. For implementation details, refer to the example contract linked below. @@ -283,4 +302,3 @@ For on-chain price interactions, see the [example contract](https://github.com/p A CLI-based approach can also be taken for interacting with Pyth prices, see the [update.sh](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/near/scripts/update.sh) example script in the repository to see how to pull prices with the official NEAR cli. - From d30fad4880d2c30e3a1355c0a3d531f91ba3ae52 Mon Sep 17 00:00:00 2001 From: Josh Date: Mon, 18 Nov 2024 13:58:33 -0800 Subject: [PATCH 10/10] fix: update API endpoint example --- docs/2.build/5.primitives/oracles.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/2.build/5.primitives/oracles.md b/docs/2.build/5.primitives/oracles.md index dd5ecefb4bc..f9d6ff2b403 100644 --- a/docs/2.build/5.primitives/oracles.md +++ b/docs/2.build/5.primitives/oracles.md @@ -197,16 +197,18 @@ Pyth Network uses price feed IDs that map to their contract addresses to uniquel Fetch price feeds using the [Hermes API](https://docs.pyth.network/price-feeds/how-pyth-works/hermes) `/get_vaa` endpoint using the following parameters: - Price Feed ID -- Publish Time in milliseconds +- Publish Time -`Example:` +`Example Endpoint:` + +https://hermes-beta.pyth.network/api/get_vaa?id=f9c0172ba10dfa4d19088d94f5bf61d3b54d5bd7483a322a982e1373ee8ea31b&publish_time=1731713981 ```js // Define priceId and publishTime variables // NOTE: Remove the `0x` prefix from the price feed ID const priceId = 'f9c0172ba10dfa4d19088d94f5bf61d3b54d5bd7483a322a982e1373ee8ea31b'; // BTC testnet price feed ID -const publishTime = Math.floor(Date.now() / 1000) - 1; // Current time minus 1 millisecond to account for latency +const publishTime = Math.floor(Date.now() / 1000) - .5; // Current time minus 0.5 seconds // Fetch price data from Hermes API beta endpoint for testnet const response = await axios.get(