-
Notifications
You must be signed in to change notification settings - Fork 39
Feat(pricefeed/price feed id) add data #445
Changes from 9 commits
bd4dd97
abffe78
bbae1ca
845fdf3
a307c5d
ac05f76
9191ced
8420aec
09e8501
5a3980e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| import { useState, useCallback } from "react"; | ||
| import { StyledTd } from "./Table"; | ||
|
|
||
| interface PriceFeed { | ||
| ids: string; | ||
| assetType: string; | ||
| name: string; | ||
| } | ||
|
|
||
| interface TableColumnWidths { | ||
| assetType: string; | ||
| name: string; | ||
| ids: any; | ||
| } | ||
|
|
||
| const columnWidths: TableColumnWidths = { | ||
| assetType: "w-3/10", | ||
| name: "w-1/5", | ||
| ids: "w-1/2", | ||
| }; | ||
|
|
||
| const PriceFeedTable = ({ priceFeeds }: { priceFeeds: PriceFeed[] }) => { | ||
| const [selectedAssetType, setSelectedAssetType] = useState<string>("All"); | ||
| const [copiedId, setCopiedId] = useState<string | null>(null); | ||
|
||
|
|
||
| const assetTypes = [ | ||
| "All", | ||
| ...Array.from(new Set(priceFeeds.map((feed) => feed.assetType))), | ||
| ]; | ||
|
|
||
| const filteredFeeds = | ||
| selectedAssetType === "All" | ||
| ? priceFeeds | ||
| : priceFeeds.filter((feed) => feed.assetType === selectedAssetType); | ||
|
|
||
| const copyToClipboard = useCallback((text: string) => { | ||
| navigator.clipboard | ||
| .writeText(text) | ||
| .then(() => { | ||
| setCopiedId(text); | ||
| setTimeout(() => setCopiedId(null), 2000); // Hide the popup after 2 seconds | ||
| }) | ||
| .catch((err) => { | ||
| console.error("Failed to copy: ", err); | ||
| }); | ||
| }, []); | ||
|
|
||
| return ( | ||
| <div> | ||
| <div className="mb-4"> | ||
| <label htmlFor="assetTypeFilter" className="mr-2"> | ||
| Filter by Asset Type: | ||
| </label> | ||
| <select | ||
| id="assetTypeFilter" | ||
| value={selectedAssetType} | ||
| onChange={(e) => setSelectedAssetType(e.target.value)} | ||
| className="p-2 border rounded" | ||
| > | ||
| {assetTypes.map((type) => ( | ||
| <option key={type} value={type}> | ||
| {type} | ||
| </option> | ||
| ))} | ||
| </select> | ||
| </div> | ||
| <table> | ||
| <thead> | ||
| <tr> | ||
| <th className={columnWidths.assetType}>Asset Type</th> | ||
| <th className={columnWidths.name}>Name</th> | ||
| <th className={columnWidths.ids}>Feed ID</th> | ||
| </tr> | ||
| </thead> | ||
| <tbody> | ||
| {filteredFeeds.map((feed, index) => ( | ||
| <tr key={index}> | ||
|
||
| <StyledTd>{feed.assetType}</StyledTd> | ||
| <StyledTd>{feed.name}</StyledTd> | ||
| <StyledTd> | ||
| <div className="relative"> | ||
| <button | ||
| onClick={() => copyToClipboard(feed.ids)} | ||
| className="flex items-center space-x-2 px-2 py-1 bg-gray-100 hover:bg-gray-200 dark:bg-darkGray2 dark:hover:bg-darkGray3 rounded transition duration-200" | ||
| > | ||
| <code className="dark:text-darkLinks text-lightLinks dark:bg-darkGray2 bg-gray-100 px-2 py-1 rounded"> | ||
| {feed.ids} | ||
| </code> | ||
| <svg | ||
| xmlns="http://www.w3.org/2000/svg" | ||
| className="h-4 w-4" | ||
| fill="none" | ||
| viewBox="0 0 24 24" | ||
| stroke="currentColor" | ||
| > | ||
| <path | ||
| strokeLinecap="round" | ||
| strokeLinejoin="round" | ||
| strokeWidth={2} | ||
| d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" | ||
| /> | ||
| </svg> | ||
|
||
| </button> | ||
| {copiedId === feed.ids && ( | ||
| <div className="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 px-2 py-1 bg-gray-800 text-white text-sm rounded shadow"> | ||
| Copied to clipboard | ||
| </div> | ||
| )} | ||
| </div> | ||
|
||
| </StyledTd> | ||
| </tr> | ||
| ))} | ||
| </tbody> | ||
| </table> | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| export default PriceFeedTable; | ||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| # Price Feeds | ||
|
|
||
| Pyth Price Feeds provide real-time, first-party, market data for a wide range of assets. | ||
|
|
||
| Every price feed has a **unique ID**, representing the specific pair of assets being priced. | ||
| These specific pairs are part of an asset class, which is a broader category of assets. | ||
|
|
||
| Anyone can fetch available price feeds and their IDs via [Hermes API](https://hermes.pyth.network/docs/#/rest/price_feeds_metadata). | ||
|
|
||
| ## Asset Classes | ||
|
|
||
| Every price feed belongs to an asset class. These asset classes distinguish between different types of assets, such as crypto, US equities, and metals. | ||
|
|
||
| Refer to the [Asset Classes](./price-feeds/asset-classes.md) page to learn more about the existing asset classes. | ||
|
|
||
| ## Price Feed IDs | ||
|
|
||
| Price Feed IDs are unique identifiers for each specific pair of assets being priced (e.g. BTC/USD). | ||
| Every price update is tagged with the corresponding price feed ID. | ||
|
|
||
| Applications need to store the IDs of the feeds they wish to read. | ||
| However, the IDs may be represented in different formats (e.g. hex or base58) depending on the blockchain. | ||
| Price feeds also have different IDs in the Stable and Beta channels. | ||
|
|
||
| Refer to the [Price Feed ID reference catalog](./price-feeds/price-feed-ids.md) to identify a feed's ID in your chosen ecosystem. | ||
|
|
||
| ### Solana Price Feed Accounts | ||
|
|
||
| On Solana, each feed additionally has a collection of **price feed accounts** containing the feed's data. | ||
| The addresses of these accounts are programmatically derived from the feed id and a shard id, which is simply a 16-bit number. | ||
| See [How to Use Real-Time Data on Solana](./use-real-time-data/solana#price-feed-accounts) for more information on price feed accounts. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| { | ||
| "asset-classes": "Asset Classes", | ||
| "price-feed-ids": "Price Feed IDs" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| # Asset Classes | ||
|
|
||
| [Pyth price feeds](https://www.pyth.network/price-feeds) provide market data for the following asset classes: | ||
|
|
||
| | Asset Class | Subclass | Definition | | ||
| | ----------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | Crypto | Spot Prices | Real-time prices for cryptocurrencies and digital assets | | ||
| | | Redemption Rates | Real-time swap rates derived from smart contracts for the redemption of liquid staking and liquid restaking tokens (LSTs and LRTs), liquidity provider tokens (LP Tokens) and interest-bearing assets, including tokenised notes | | ||
| | | Indices | Real-time prices that measure the performance of baskets of cryptocurrencies and digital assets | | ||
| | US Equities | Spot Prices | Real-time prices for US equities | | ||
| | FX | Spot Prices | Real-time prices for fiat currency pairs | | ||
| | Metals | Spot Prices | Real-time prices for precious metals | | ||
| | Rates | Future Prices | Real-time prices for fixed income products, including bond futures | | ||
| | Commodities | Futures Prices | Real-time prices for commodity futures | |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| import PriceFeedTable from "../../../components/PriceFeedTable"; | ||
| import { useState, useEffect } from 'react'; | ||
|
|
||
| export const PriceFeedData = () => { | ||
| const [priceFeeds, setPriceFeeds] = useState([]); | ||
|
|
||
| useEffect(() => { | ||
| const fetchPriceFeeds = async () => { | ||
| try { | ||
| const response = await fetch('https://hermes.pyth.network/v2/price_feeds'); | ||
| const data = await response.json(); | ||
|
||
|
|
||
| // Transform the data to match our PriceFeed interface | ||
| const transformedData = data.map(feed => ({ | ||
| assetType: feed.attributes.asset_type, | ||
| name: feed.attributes.display_symbol, | ||
| ids: feed.id | ||
| })); | ||
|
|
||
| setPriceFeeds(transformedData); | ||
| } catch (error) { | ||
| console.error('Error fetching price feeds:', error); | ||
| } | ||
| }; | ||
|
|
||
| fetchPriceFeeds(); | ||
|
||
|
|
||
| }, []); | ||
|
|
||
| return <PriceFeedTable priceFeeds={priceFeeds} />; | ||
| }; | ||
|
|
||
| # Price Feed IDs | ||
|
|
||
| Below is a table of all available price feed IDs: | ||
|
|
||
| <PriceFeedData /> | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think there's any reason to extract all this out, just put the tailwind classes in at the call sites where they're being consumed (i.e. lines 70 - 72)