Skip to main content
The IFÁ Labs oracle contract emits events on every successful price update. These events are the foundation of any off-chain infrastructure built on top of IFÁ Labs — monitoring systems, subgraphs, alert pipelines, analytics dashboards, and historical price databases all depend on them. This page documents every event, its parameters, and how to consume it correctly in JavaScript, Python, and via on-chain indexing tools.

Events

PriceUpdated

Emitted every time a price is successfully pushed on-chain by the relayer network.
Parameters: When it fires:
  • On every successful deviation-triggered update
  • On every successful heartbeat-triggered update
  • Never fires on failed or rejected submissions
Key properties:
  • assetId is indexed — you can filter logs for a specific asset without downloading all events
  • timestamp matches the lastUpdateTime field returned by getAssetInfo — the two values are always in sync
  • One event is emitted per asset per update — batch submissions emit one event per asset

Listening to Events

JavaScript — Real-Time with ethers.js

Listen for live price updates as they happen on-chain:
WebSocket connections are required for real-time event listening. HTTP RPC providers do not support eth_subscribe. Use a dedicated WebSocket provider — Alchemy, QuickNode, or Infura — not the public Base RPC endpoint.

JavaScript — Historical Query with ethers.js

Query past price update events for a specific asset over a block range:

Python — Real-Time with web3.py


Basescan — Manual Event Inspection

To inspect price update events without writing code:
1

Open the Events tab

Go to the contract on Basescan and click the Events tab: basescan.org/address/0xA9F17344689C2c2328F94464998db1d3e35B80dC#events
2

Filter by asset ID

Use the topic filter to narrow results to a specific asset. The assetId parameter is indexed — enter the bytes32 value for the asset you want to inspect as Topic 1.
3

Read the event data

Each row shows the transaction hash, block number, and decoded event parameters — price, decimal, and timestamp. The price field is the raw scaled integer — divide by 1e18 for the human-readable value.

Building a Price History Database

For analytics dashboards, historical price charts, or audit trails, persist PriceUpdated events to a database as they arrive:

Indexing with The Graph

For production-grade historical data access, index PriceUpdated events using The Graph:

Event Monitoring Best Practices

Use WebSockets for real-time feeds, HTTP for historical queries. WebSocket providers support eth_subscribe for live event streaming. HTTP providers require polling with queryFilter — adequate for historical data but not for real-time monitoring. Store raw values alongside human-readable values. Always persist both raw_price (the unscaled int256) and the human-readable price in your database. The raw value is lossless — the human-readable conversion may lose precision depending on your numeric type. If you ever need to reprocess historical data, the raw value is the authoritative source. Index by assetId and updated_at. These are the two axes on which you will query price history — “all updates for CNGN/USD” and “all updates in the last 24 hours.” Both should be indexed in your database for acceptable query performance at scale. Handle WebSocket reconnections. WebSocket connections to RPC providers drop periodically. Any production event listener must implement reconnection logic — either manually or through a library that handles it automatically. Backfill from genesis block on first deployment. When deploying a price history database for the first time, backfill all historical PriceUpdated events from the oracle contract’s deployment block before switching to live streaming. Otherwise your historical data will have a gap.

Next Steps

ABI Download

Get the official ABI for use in your monitoring scripts and indexers.

Running Price Monitoring

Production-ready monitoring scripts built on the event patterns documented here.