LogoNAVI Protocol SDKS

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 ID
    • priceInfoObject: On-chain PriceInfoObject ID
    • expiration (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 object
  • priceFeeds: Array of OraclePriceFeed objects
  • options (optional):
    • updatePythPriceFeeds: Whether to check and update stale Pyth price feeds before updating oracle prices
    • market: Market identifier
    • env: 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 wallet

Type 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 ID
  • priceInfoObject: On-chain PriceInfoObject ID
  • price: Price value (negative if the price magnitude is negative)
  • conf: Confidence interval
  • publishTime: Unix timestamp when the price was published
  • expiration: Maximum allowed age in seconds (optional)