Skip to content

thevolcanomanishere/gud-price

Repository files navigation

gud-price

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.

Tests npm PyPI Crates.io Go

What prices are available?

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.

Quick start

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.

Install

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.

TypeScript

npm install gud-price
import { 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

go get github.com/thevolcanomanishere/gud-price/generated/go
package 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)
}

Rust

cargo add gud-price
use 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);
}

Python

pip install gud-price
from 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}")

Zig

Add to build.zig.zon:

zig fetch --save https://github.com/thevolcanomanishere/gud-price/archive/refs/tags/v0.1.0.tar.gz
const 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});
}

API (all languages)

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).

Supported chains

Ethereum, Polygon, Arbitrum, Base.

See FEEDS.md for the full list of all 691 feeds and their addresses.

How it works

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.

RPC endpoints

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");

Architecture

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

Code generation

npm run generate                        # All languages
npm run generate -- --lang=go           # Just Go
npm run generate -- --lang=rust,python  # Multiple

Updating feed addresses

npm run updateAllFeeds

Scrapes the latest addresses from data.chain.link using Playwright, then run npm run generate to update all languages.

License

MIT

About

Typescript / Python / Go / Rust / Zig library for interacting with Chainlink datafeeds

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors