# Nibiru Oracle (EVM) - Usage Guide

Nibiru EVM includes a precompile for Nibiru's oracle mechanism, providing access to exchange rate data and ChainLink-like oracle smart contracts. This allows developers to query real-time price information for various markets directly on-chain.

The Oracle precompile integrates with ChainLink's AggregatorV3Interface, allowing access to decentralized price feeds.

Copy interface ChainLinkAggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); function getRoundData(uint80 _roundId) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); }

To query these oracles in a Web3 application, you can import the @nibiruchain/evm-core package on npm.

Copy npm i @nibiruchain/evm-core@latest ethers@6

Note that in this example, we use the address for ETH. We include the list of all active ChainLink-like feeds in the "Nibiru Mainnet - ChainLink-like Feeds" section.

Copy import { ethers } from "ethers"; import { chainlinkLike } from "@nibiruchain/evm-core/ethers"; const doReadChainlink = async (wallet: ethers.ContractRunner) => { const oracleAddr = "0x6187b99Cad5fbF30f98A06850d301cb1b31b27b2"; const oracleCaller = chainlinkLike(wallet, oracleAddr); const description = await oracleCaller.description(); const decimals = await oracleCaller.decimals(); const out = await oracleCaller.latestRoundData(); const [roundId, answer, startedAt, updatedAt, answeredInRound] = out; console.debug("DEBUG %o: ", { out, oracleAddr, description, decimals, outCleaner: { roundId, answer, startedAt, updatedAt, answeredInRound }, }); };

Example output - Oracle for ETH on mainnet

Copy DEBUG { out: [ 18859259n, 2705840000n, 1739818322n, 1739818322n, 420n ], oracleAddr: "0x6187b99Cad5fbF30f98A06850d301cb1b31b27b2", description: "Nibiru Oracle ChainLink-like price feed for ueth:uusd", decimals: 6n, outCleaner: { roundId: 18859259n, answer: 2705840000n, startedAt: 1739818322n, updatedAt: 1739818322n, answeredInRound: 420n, }, }:
Asset Decimals, Name Address
NIBI:USD 6, Nibiru 0x97412699a841fD936392C7efFd0c268eBE27a0Ec
ETH:USD 6, Ethereum 0x6187b99Cad5fbF30f98A06850d301cb1b31b27b2
  1. What is the smart contract implementation for these oracle feeds?
    These feeds are deployments of NibiruOracleChainLinkLike.sol (opens new window), a contract that sources data from the Nibiru Oracle Mechanism and exposes the data in the ChainLink AggregatorV3Interface format.
Copy npm i @nibiruchain/solidity

# Example: TypeScript, Ethers v6, and the Oracle Precompile

To communicate directly with the Nibiru EVM Oracle precompile, you can use the ethers.js library to interact with the contract. The script you provided already demonstrates how to query the Oracle for exchange rates and Chainlink prices using the correct contract address and ABI.

Here's a breakdown of the necessary steps to ensure a smooth communication with the precompile, along with some refinements:

Copy const { ethers } = require("hardhat"); async function main() { const provider = new ethers.JsonRpcProvider( "https://evm-rpc.testnet-2.nibiru.fi/" // Nibiru Testnet RPC URL ); const precompileAddress = "0x0000000000000000000000000000000000000801"; // Oracle Precompile Address // Define the IOracle ABI for querying the exchange rate and ChainLink data const abi = [ "function queryExchangeRate(string pair) view returns (uint256 price, uint64 blockTimeMs, uint64 blockHeight)", "function chainLinkLatestRoundData(string pair) view returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound)", ]; // Connect to the Oracle precompile contract using the ABI and provider const oracle = new ethers.Contract(precompileAddress, abi, provider); // Define asset pairs to query the exchange rates const pairs = [ "uatom:uusd", "ubtc:uusd", "ueth:uusd", "uusdc:uusd", "uusdt:uusd", ]; // Loop through the pairs and query the Oracle for exchange rates and ChainLink prices for (const pair of pairs) { try { // Query the exchange rate for the asset pair console.log(`Querying exchange rate for ${pair}...`); const [price, blockTimeMs, blockHeight] = await oracle.queryExchangeRate(pair); console.log(`Pair: ${pair}`); console.log(`Exchange Rate: ${ethers.formatUnits(price, 18)}`); // Format the price to 18 decimals console.log(`Block Time (ms): ${blockTimeMs.toString()}`); console.log(`Block Height: ${blockHeight.toString()}`); } catch (error) { console.error(`Error querying exchange rate for ${pair}:`, error); } try { // Query the ChainLink price for the asset pair console.log(`Querying ChainLink price for ${pair}...`); const [roundId, answer, startedAt, updatedAt, answeredInRound] = await oracle.chainLinkLatestRoundData(pair); console.log(`Pair: ${pair}`); console.log(`ChainLink Price: ${ethers.formatUnits(answer, 18)}`); // Format the price to 18 decimals console.log(`Round ID: ${roundId.toString()}`); console.log(`Started At: ${startedAt.toString()}`); console.log(`Updated At: ${updatedAt.toString()}`); console.log(`Answered In Round: ${answeredInRound.toString()}`); } catch (error) { console.error(`Error querying ChainLink price for ${pair}:`, error); } } } // Execute the script main().catch(console.error);

# How This Script Works

  1. The script connects to the Nibiru EVM Oracle precompile using the predefined address and ABI.
  2. It queries the queryExchangeRate function to get the price, block time, and block height for each asset pair.
  3. It also queries the chainLinkLatestRoundData function to fetch the latest ChainLink price data.
  4. The results are logged to the console for each pair, with appropriate formatting for clarity.

# Explanation of Key Components

  1. Provider Setup: Connects to the Nibiru Testnet via the RPC endpoint (https://evm-rpc.testnet-2.nibiru.fi/ (opens new window)) to establish communication with the Ethereum-compatible network.

  2. ABI Definition: Specifies the functions available for interaction with the Oracle smart contracts, allowing querying of prices and exchange rates.

  3. Supported Asset Pairs: Lists the asset pairs (e.g., "ueth:uusd", "unibi:uusd") supported by Nibiru’s Oracle system for querying price data.

  4. Error Handling: Implements robust error management using try-catch statements to handle potential failures gracefully during queries to the Oracle or ChainLink-like feeds.

  5. Formatted Output: Provides clear and precise price data formatted to 18 decimals, ensuring readability and ease of interpretation.

This approach directly communicates with the Nibiru Oracle precompile, and you can extend this to include other queries or add additional functionality as needed.


  1. Understanding the Oracle Precompile
  2. @nibiruchain/evm-core package on npm
  3. @nibiruchain/solidity package on npm