Decentralized Oracle
The NAVI decentralized oracle consistently produces stable and reliable prices by integrating data from multiple trusted oracle providers on Sui. Currently, we have selected Pyth and Supra as our price providers. To learn more, please refer to our medium post.
The Oracle operates on a PUSH model, allowing anyone to trigger updates. To ensure the protocol's security, we enforce a valid price interval of 15 seconds, meaning that any price older than 15 seconds is considered stale and not allowed. It is always recommended to update the price before using the NAVI lending protocol.
API Reference
getPriceFeeds
Get all available price feeds from the configuration. See documentation for details.
Usage Example
import { getPriceFeeds } from '@naviprotocol/lending'
// Get all price feeds
const priceFeeds = await getPriceFeeds()
// Get price feeds for specific market
const marketPriceFeeds = await getPriceFeeds({
market: 'main' // Optional: market identifier
})Result Example
[
{
"oracleId": 0,
"assetId": 0,
"coinType": "0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI",
"feedId": "0x2cab9b151ca1721624b09b421cc57d0bb26a1feb5da1f821492204b098ec35c9",
"pythPriceFeedId": "0x23d7315113f5b1d3ba7a83604c44b94d79f4fd69af77f804fc7f920a6dc65744",
"pythPriceInfoObject": "0x801dbc2f0053d34734814b2d6df491ce7807a725fe9a01ad74a07e9c51396c37",
"priceDecimal": 9,
"supraPairId": 90
}
]filterPriceFeeds
Filter price feeds based on lending state and pools. See documentation for details.
Usage Example
import { filterPriceFeeds, getPriceFeeds, getLendingState, getPool } from '@naviprotocol/lending'
const allFeeds = await getPriceFeeds()
const userLendingState = await getLendingState('0x...')
const suiPool = await getPool('0x2::sui::SUI')
// Filter by user's lending state
const filteredFeeds = filterPriceFeeds(allFeeds, {
lendingState: userLendingState
})
// Filter by available pools
const filteredFeeds = filterPriceFeeds(allFeeds, {
pools: [suiPool]
})Result Example
[
{
"oracleId": 0,
"assetId": 0,
"coinType": "0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI",
"feedId": "0x2cab9b151ca1721624b09b421cc57d0bb26a1feb5da1f821492204b098ec35c9",
"pythPriceFeedId": "0x23d7315113f5b1d3ba7a83604c44b94d79f4fd69af77f804fc7f920a6dc65744",
"pythPriceInfoObject": "0x801dbc2f0053d34734814b2d6df491ce7807a725fe9a01ad74a07e9c51396c37",
"priceDecimal": 9,
"supraPairId": 90
}
]getPythStalePriceFeedId
Get stale price feed IDs from Pyth Network. Identifies price feeds that have not been updated recently (more than 30 seconds old). See documentation for details.
Usage Example
import { getPythStalePriceFeedId, getPriceFeeds } from '@naviprotocol/lending'
const allPriceFeeds = await getPriceFeeds()
const stalePriceFeedIds = await getPythStalePriceFeedId([allPriceFeeds[0].pythPriceFeedId])Result Example
["0x..."]getPythStalePriceFeedIdV2
Get stale price feed IDs by reading on-chain PriceInfoObject data directly, instead of relying on the Pyth Hermes endpoint. This is a more reliable alternative to getPythStalePriceFeedId as it reads price freshness from the Sui blockchain. See documentation for details.
Usage Example
import { getPythStalePriceFeedIdV2, getPriceFeeds } from '@naviprotocol/lending'
const allPriceFeeds = await getPriceFeeds()
const stalePriceFeedIds = await getPythStalePriceFeedIdV2(
allPriceFeeds.map((feed) => ({
priceFeedId: feed.pythPriceFeedId,
priceInfoObject: feed.pythPriceInfoObject,
expiration: 30 // Optional: max age in seconds (default: 60)
}))
)Parameters
pythInfos: Array of Pyth info objects:priceFeedId: Pyth price feed IDpriceInfoObject: On-chain PriceInfoObject IDexpiration(optional): Maximum allowed age in seconds before a price is considered stale (default: 60)
options(optional):client: Sui client instance
Result Example
["0x23d7315113f5b1d3ba7a83604c44b94d79f4fd69af77f804fc7f920a6dc65744"]updatePythPriceFeeds
Update Pyth price feeds in a transaction. Fetches the latest price update data from Pyth Network and adds the update operations to the transaction block. See documentation for details.
Usage Example
import { updatePythPriceFeeds, getPythStalePriceFeedId } from '@naviprotocol/lending'
import { Transaction } from '@mysten/sui/transactions'
const tx = new Transaction()
const allPriceFeeds = await getPriceFeeds()
const stalePriceFeedIds = await getPythStalePriceFeedId([allPriceFeeds[0].pythPriceFeedId])
await updatePythPriceFeeds(tx, stalePriceFeedIds)updateOraclePricesPTB
Update oracle prices in the PTB (Programmable Transaction Block). This function updates price feeds for the lending protocol. When updatePythPriceFeeds is enabled, it uses on-chain price staleness detection (getPythStalePriceFeedIdV2) to automatically refresh stale Pyth feeds before updating oracle prices. See documentation for details.
Usage Example
import { updateOraclePricesPTB, getPriceFeeds } from '@naviprotocol/lending'
import { Transaction } from '@mysten/sui/transactions'
const tx = new Transaction()
const allPriceFeeds = await getPriceFeeds()
await updateOraclePricesPTB(tx, allPriceFeeds, {
updatePythPriceFeeds: true, // Optional: update Pyth feeds if stale
market: 'main' // Optional: market identifier
})
// With custom Sui client
import { SuiClient } from '@mysten/sui/client'
const client = new SuiClient({ url: 'https://fullnode.mainnet.sui.io' })
await updateOraclePricesPTB(tx, allPriceFeeds, {
updatePythPriceFeeds: true,
client, // Optional: custom Sui client for on-chain price staleness detection
env: 'prod' // Optional: environment configuration
})Parameters
tx: Transaction objectpriceFeeds: Array ofOraclePriceFeedobjectsoptions(optional):updatePythPriceFeeds: Whether to check and update stale Pyth price feeds before updating oracle pricesmarket: Market identifierenv: Environment configuration ('dev' or 'prod')client: Sui client instance (used for on-chain price staleness detection)
Complete Example
Here's a complete example showing how to use the oracle module:
import {
getPriceFeeds,
filterPriceFeeds,
getPythStalePriceFeedId,
updateOraclePricesPTB,
getLendingState
} from '@naviprotocol/lending'
import { Transaction } from '@mysten/sui/transactions'
// 1. Get all available price feeds
const allPriceFeeds = await getPriceFeeds()
// 2. Get user's lending state
const userAddress = '0x...'
const lendingState = await getLendingState(userAddress)
// 3. Filter price feeds based on user's lending state
const relevantFeeds = filterPriceFeeds(allPriceFeeds, {
lendingState
})
// 4. Update oracle prices in a transaction
const tx = new Transaction()
const updatedTx = await updateOraclePricesPTB(tx, relevantFeeds, {
updatePythPriceFeeds: true
})
// 5. Execute the transaction
// ... execute the transaction with your walletType Definitions
PythPriceInfo
On-chain Pyth price information retrieved from PriceInfoObject.
type PythPriceInfo = {
priceFeedId: string
priceInfoObject: string
price: string
conf: string
publishTime: number
expiration?: number
}priceFeedId: Pyth price feed IDpriceInfoObject: On-chain PriceInfoObject IDprice: Price value (negative if the price magnitude is negative)conf: Confidence intervalpublishTime: Unix timestamp when the price was publishedexpiration: Maximum allowed age in seconds (optional)