Free, real-time price data for currencies, stocks, commodities, and crypto -- no API keys, no subscriptions.
gud-price reads from Chainlink price feeds, the same oracle network used to secure billions in DeFi. Available for TypeScript, Go, Rust, Python, and Zig.
691 feeds across 4 chains (Ethereum, Arbitrum, Base, Polygon). Here are some highlights:
| Category | Feeds | Chains |
|---|---|---|
| Forex | EUR/USD, GBP/USD, JPY/USD, AUD/USD, CAD/USD, CHF/USD, CNY/USD, KRW/USD, INR/USD, MXN/USD, ZAR/USD, and 15 more currency pairs | 26 fiat currencies across all 4 chains |
| Equities | AAPL, TSLA, AMZN, GOOGL, MSFT, NVDA, META, SPY | Arbitrum and Polygon |
| Commodities | XAU (Gold), XAG (Silver), XPT (Platinum), WTI (Crude Oil) | Gold and silver on all 4 chains |
| Crypto | BTC, ETH, SOL, LINK, ARB, UNI, AAVE, and hundreds more | All chains |
| Stablecoins | USDC/USD, USDT/USD, DAI/USD, EURC/USD | All chains |
| Market indices | Total Crypto Market Cap, SPY/USD | Ethereum and Arbitrum |
All prices are denominated in USD. Data is sourced from Chainlink's decentralized oracle network, the same infrastructure securing billions in DeFi.
See FEEDS.md for the complete list of all 691 feeds and their contract addresses.
Get the EUR/USD exchange rate in 3 lines:
import { readLatestPrice } from "gud-price/rpc";
import { EUR_USD } from "gud-price/feeds/ethereum";
const data = await readLatestPrice(EUR_USD);
console.log(`EUR/USD: ${data.answer}`); // "EUR/USD: 1.0847"You can also pass any Chainlink feed contract address directly:
const data = await readLatestPrice("0xb49f677943BC038e9857d61E7d053CaA2C1734C1");For addresses not built into the library, pass an RPC URL as the second argument:
const data = await readLatestPrice("0xYourFeedAddress", "https://ethereum-rpc.publicnode.com");Find more feed addresses at data.chain.link.
| Language | Install | Docs |
|---|---|---|
| TypeScript | npm install gud-price |
Usage |
| Go | go get github.com/thevolcanomanishere/gud-price/generated/go |
Usage |
| Rust | cargo add gud-price |
Usage |
| Python | pip install gud-price |
Usage |
| Zig | Add via build.zig.zon |
generated/zig/ |
All implementations are zero-dependency (or minimal-dependency) and use raw JSON-RPC calls under the hood. No ethers, no web3, no ABIs.
npm install gud-priceimport { readLatestPrice } from "gud-price/rpc";
import { EUR_USD, BTC_USD } from "gud-price/feeds/ethereum";
import { AAPL_USD, TSLA_USD } from "gud-price/feeds/arbitrum";
const [eur, btc, aapl, tsla] = await Promise.all([
readLatestPrice(EUR_USD),
readLatestPrice(BTC_USD),
readLatestPrice(AAPL_USD),
readLatestPrice(TSLA_USD),
]);
console.log(`EUR/USD: ${eur.answer}`);
console.log(`BTC/USD: $${btc.answer}`);
console.log(`AAPL: $${aapl.answer}`);
console.log(`TSLA: $${tsla.answer}`);go get github.com/thevolcanomanishere/gud-price/generated/gopackage main
import (
"fmt"
"github.com/thevolcanomanishere/gud-price/generated/go/rpc"
"github.com/thevolcanomanishere/gud-price/generated/go/ethereum"
)
func main() {
data, err := rpc.ReadLatestPrice(ethereum.EUR_USD)
if err != nil {
panic(err)
}
fmt.Printf("EUR/USD: %s\n", data.Answer)
}cargo add gud-priceuse gud_price::rpc::read_latest_price;
use gud_price::ethereum::EUR_USD;
fn main() {
let data = read_latest_price(EUR_USD, None).unwrap();
println!("EUR/USD: {}", data.answer);
}pip install gud-pricefrom gud_price.rpc import read_latest_price
from gud_price.ethereum import EUR_USD
data = read_latest_price(EUR_USD)
print(f"EUR/USD: {data.answer}")Add to build.zig.zon:
zig fetch --save https://github.com/thevolcanomanishere/gud-price/archive/refs/tags/v0.1.0.tar.gzconst gud_price = @import("gud-price");
pub fn main() !void {
const price = try gud_price.readLatestPrice(gud_price.ethereum.EUR_USD, null);
std.debug.print("EUR/USD: {s}\n", .{price.answer});
}| Function | Description |
|---|---|
readLatestPrice(address) |
Latest price, formatted with metadata |
readLatestPriceWithMeta(address, meta) |
Latest price using pre-fetched metadata (1 RPC call) |
readLatestPriceRaw(address) |
Latest price as raw integers |
readPriceAtRound(address, roundId) |
Price at a specific Chainlink round |
readFeedMetadata(address) |
Decimals and description |
readPrices(feeds) |
Multiple feeds in parallel |
readPhaseId(address) |
Current phase ID |
readAggregator(address) |
Current aggregator address |
readPhaseAggregator(address, phaseId) |
Aggregator for a specific phase |
formatPrice(raw, decimals) |
Format raw integer price to decimal string |
All functions accept an optional RPC URL as the last argument. When omitted, built-in public endpoints are used with automatic fallback.
Function names follow each language's conventions (e.g. ReadLatestPrice in Go, read_latest_price in Rust/Python).
Ethereum, Polygon, Arbitrum, Base.
See FEEDS.md for the full list of all 691 feeds and their addresses.
Chainlink price feeds are smart contracts deployed on EVM blockchains. Each feed (e.g. EUR/USD) has a contract address that anyone can read from using an RPC endpoint. gud-price makes a single eth_call JSON-RPC request to read the latest price -- no wallet, no transaction, no gas fees.
gud-price ships with built-in public RPC endpoints and automatically selects the right ones based on which feed you're reading. If an endpoint fails, the library falls back to the next one and remembers which endpoints are down.
These are shared public endpoints -- please use them responsibly and don't hammer them with high-frequency requests.
For production use or higher throughput, supply your own RPC endpoint as the last argument to any function. Free tiers are available from providers like Alchemy, QuickNode, Infura, and others. You can also find more public endpoints on Chainlist.
// Uses built-in public RPCs automatically
const data = await readLatestPrice(EUR_USD);
// Or supply your own for better reliability and limits
const data = await readLatestPrice(EUR_USD, "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY");feeds/*.json <- single source of truth (691 feed addresses)
codegen/generate.js <- generates typed code for all languages
src/ <- TypeScript (npm: gud-price)
generated/go/ <- Go (stdlib only)
generated/rust/ <- Rust (ureq + phf)
generated/python/ <- Python (stdlib only)
generated/zig/ <- Zig
npm run generate # All languages
npm run generate -- --lang=go # Just Go
npm run generate -- --lang=rust,python # Multiplenpm run updateAllFeedsScrapes the latest addresses from data.chain.link using Playwright, then run npm run generate to update all languages.
MIT