@pulsadev/price-feed
v0.1.0
Published
Chainlink oracle price feed reader — real-time token prices, batch queries, built-in feed registry. Zero dependencies, pure RPC.
Readme
@pulsadev/price-feed
Chainlink oracle price feed reader — real-time token prices, batch queries, built-in feed registry. Zero dependencies, pure RPC.
Read live token prices directly from Chainlink oracles. No API key, no CoinGecko, no rate limits. Just an RPC URL.
Features
- Real-time prices — read
latestRoundData()from Chainlink aggregators - Batch price queries — fetch ETH, BTC, LINK prices in parallel
- Built-in feed registry — 50+ Chainlink feed addresses across 7 chains
- Historical prices —
getRoundData(roundId)for past price data - Staleness detection — check if price data is stale based on heartbeat
- Feed metadata — query decimals and description from feed contracts
- Price formatting — raw answer to human-readable price conversion
- 7 chains — Ethereum, Polygon, Arbitrum, BSC, Avalanche, Optimism, Base
- Zero dependencies — ~9 KB bundled, ESM + CJS, pure TypeScript
Install
npm install @pulsadev/price-feedQuick Start
Get a price
import { getPriceByPair } from '@pulsadev/price-feed'
const eth = await getPriceByPair('ETH/USD', {
rpcUrl: 'https://ethereum-rpc.publicnode.com',
})
console.log(`ETH: $${eth.price}`) // ETH: $2534.12
console.log(`Updated: ${eth.updatedAt}`) // Unix timestamp
console.log(`Stale: ${eth.stale}`) // falseBatch prices
import { getPrices } from '@pulsadev/price-feed'
const prices = await getPrices(['ETH/USD', 'BTC/USD', 'LINK/USD'], {
rpcUrl: 'https://ethereum-rpc.publicnode.com',
chainId: 1,
})
prices.forEach(p => console.log(`${p.pair}: $${p.price}`))All prices for a chain
import { getAllPrices } from '@pulsadev/price-feed'
const all = await getAllPrices({ rpcUrl: '...', chainId: 1 })
// Returns 20+ prices for all registered Ethereum feedsDirect feed address
import { getPrice } from '@pulsadev/price-feed'
const data = await getPrice('0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419', {
rpcUrl: '...',
})Historical price
import { getHistoricalPrice } from '@pulsadev/price-feed'
const past = await getHistoricalPrice(feedAddress, roundId, { rpcUrl: '...' })Staleness check
import { isStale } from '@pulsadev/price-feed'
if (isStale(priceData.updatedAt, 3600)) {
console.log('Price is stale!')
}Browse available feeds
import { getSupportedPairs, getFeedByPair, getSupportedChainIds } from '@pulsadev/price-feed'
getSupportedChainIds() // [1, 56, 137, 42161, 43114, 10, 8453]
getSupportedPairs(1) // ['ETH/USD', 'BTC/USD', 'LINK/USD', ...]
getFeedByPair(1, 'ETH/USD') // { address, decimals, heartbeatSeconds }API
Price Reading
| Function | Description |
|----------|-------------|
| getPrice(feedAddress, options) | Read latest price from feed |
| getPriceByPair(pair, options) | Read price by pair name (e.g. 'ETH/USD') |
| getPrices(pairs, options) | Batch read multiple pairs |
| getAllPrices(options) | Read all registered feeds for a chain |
| getHistoricalPrice(feed, roundId, options) | Read historical round data |
Feed Registry
| Function | Description |
|----------|-------------|
| getFeedByPair(chainId, pair) | Get feed config by pair name |
| getFeedsByChain(chainId) | Get all feeds for a chain |
| getSupportedPairs(chainId) | List available pairs |
| getSupportedChainIds() | List supported chains |
Utilities
| Function | Description |
|----------|-------------|
| getFeedDecimals(feed, rpcUrl) | Query feed decimals |
| getFeedDescription(feed, rpcUrl) | Query feed description |
| isStale(updatedAt, threshold) | Check price staleness |
| formatPrice(rawAnswer, decimals) | Convert raw to human-readable |
PriceData
interface PriceData {
pair: string // 'ETH/USD'
price: number // 2534.12
decimals: number // 8
rawAnswer: bigint // 253412000000n
roundId: bigint // round ID
updatedAt: number // Unix timestamp
answeredInRound: bigint
feed: Address // feed contract address
stale: boolean // true if data exceeds heartbeat
}Supported Chains
| Chain | Feeds | |-------|-------| | Ethereum (1) | 20 (ETH, BTC, LINK, USDC, USDT, DAI, UNI, AAVE, SOL, ARB, OP, ...) | | Polygon (137) | 5 | | Arbitrum (42161) | 5 | | BSC (56) | 4 | | Avalanche (43114) | 3 | | Optimism (10) | 4 | | Base (8453) | 2 |
License
MIT © Yuto Nakamura
