Getting accurate crypto and fiat exchange rates is no small feat, especially when those rates need to power smart contracts, determine conversion metrics, or underpin decentralised finance apps in real time. The Internet Computer Protocol’s (ICP) Exchange Rate Canister—known simply as the XRC—steps up to that challenge with a lean, on-chain system that fetches reliable, aggregated price data directly from top exchanges and public forex sources.
The XRC lives on the uzr34 system subnet, quietly doing its job by making HTTPS outcalls to public APIs. These calls pull data from major cryptocurrency exchanges like Coinbase, KuCoin, OKX, Gate.io, MEXC, Poloniex, Crypto.com, Bitget and DigiFinex, alongside foreign exchange data providers. Whether the request is for BTC/USD, USD/EUR, or even BTC/ICP, the XRC can deliver a rate based on its aggregation method. And yes, it does historical rates too, thanks to a UNIX epoch timestamp parameter in its request format.
Behind the scenes, the XRC doesn’t fall back on typical TWAP (time-weighted average price) or VWAP (volume-weighted average price) techniques. Instead, it collects candlestick data from exchanges at one-minute intervals, runs it through a filtering process, and then returns a median value. This system lets it calculate exchange rates between pairs that aren’t directly traded. For example, if you need an A/B rate, it can infer it using A/C and B/C values, which makes it a flexible tool in environments where direct liquidity may be scarce or pairs are not natively listed.
For developers building dapps, decentralised exchanges or other smart-contract-based tools, XRC is a critical building block. It answers the question of how much an asset is worth right now, in a way that’s verifiable by other canisters. Take the cycle minting canister of the Network Nervous System (NNS) as an example—it relies on the XRC to fetch up-to-date ICP/XDR rates when converting ICP into cycles. The entire system operates on deterministic logic, which helps maintain consistency and reduces manipulation risks.
Calling the XRC canister isn’t complicated. There’s a single endpoint—get_exchange_rate
—which takes a structured request including a base asset and quote asset. The optional timestamp adds functionality for those wanting a rate from the past. The asset information is standardised using symbols like “BTC” or “USD”, and a class value that indicates whether the asset is a cryptocurrency or fiat currency.
One area that’s key to understanding how the canister works is its cycle usage and pricing model. Every request costs one billion (1B) cycles upfront, and then depending on asset type and whether the result is cached, a portion of those cycles are actually used and the rest returned. For cached requests or fiat-only pairs, it’s relatively cheap at 20 million cycles. But if you’re requesting a rate between two crypto assets, it’ll cost 500 million. A mixed fiat-crypto pair or anything involving USDT comes in at 260 million. Even if a request fails due to error or lack of data, the XRC deducts at least one million cycles. This baseline fee protects the system from denial-of-service attacks, making sure malicious actors can’t clog the pipeline with zero-cost spam.
If you’re the kind who likes to get hands-on, there’s an XRC demo application you can run locally. It’s a very simple dapp, but it illustrates how the exchange rate data can be pulled and displayed within a Motoko project. Keep in mind, if the demo encounters an error, it returns a float value of 0, which isn’t particularly useful for production-grade apps, but still serves as a practical test bed.
Setting up the demo takes a few steps. First, you’ll need the Internet Computer SDK and Git installed. After cloning the demo repository from GitHub, you can install the project’s dependencies and then use dfx
to create and deploy the canisters locally. The local setup also requires a tweak to your networks.json file to ensure the subnet is recognised as type ‘system’. Once you’ve got that sorted, you can run the whole thing locally and even access the Candid interface for both the demo and the XRC itself through your web browser.
The project’s dfx.json
file handles configuration for the demo and XRC canisters, binding the network to a local address (typically 127.0.0.1:4812) and defining the location of the XRC’s Candid and Wasm files. The remote canister ID for the live XRC on the Internet Computer is uf6dk-hyaaa-aaaaq-qaaaq-cai
, which developers can call directly as well.
Here’s what a basic call to the canister looks like:
The response includes either the desired rate or an error message indicating what went wrong. The returned exchange rate is an object of type ExchangeRate
, and if there’s an issue—say, with insufficient cycles or a malformed request—you’ll get an ExchangeRateError
.
Calling the XRC directly from terminal or from within canister code allows for seamless integration into more complex applications. These might range from insurance pricing tools and stablecoin projects to DeFi yield protocols and even NFT marketplaces that need to benchmark values against fiat equivalents. With price manipulation still a concern across many decentralised platforms, the XRC’s use of median values from multiple sources provides a more dependable reference point than relying on one or two exchanges.
For developers used to hardcoding values or querying a single API off-chain, the XRC offers a better long-term solution that’s resistant to failure and vendor lock-in. Having this on-chain service means that canisters themselves stay autonomous and can verify pricing without relying on external oracles.
There’s a quiet efficiency in how the XRC operates—no fanfare, just solid tooling that makes ICP more developer-friendly while aligning with decentralisation principles. The system handles pricing so other projects can handle innovation, whether that’s enabling staking rewards based on market rates or rebalancing liquidity pools.
Behind all the technical documentation and call commands is a service designed to take away a small but crucial problem—figuring out how much something is worth at any given moment. Whether it’s a DEX comparing token values or a smart contract scheduling actions based on price thresholds, the XRC gives them a trusted voice to consult.
By aggregating data, rejecting stale rates, and weighting nothing more than time slices and source count, it creates clarity where other systems might give you noise. It won’t decide what your crypto is worth, but it will tell you what a lot of people think it’s worth, right now. That’s all some apps need. And for the rest, it’s a step toward building smarter logic that can act confidently on that information.