BETA — mainnet live (chain 482120); features are still being finished. Transparency →
Bitcoin Swap BETA Chain 482120
Developers · Guides

Read prices

Get BTCw and tracker-token prices over REST or on-chain (Chainlink AggregatorV3 standard).

Guides › Read prices

Option 1 — REST, the simplest

curl -s https://btcw.tech/api/price
{
  "symbol": "BTCw", "chain_id": 482120, "decimals": 18,
  "price_usd": 83380.39,            // oracle price × peg ratio
  "bid_usd": 83130.25,              // OracleAMM buys your BTCw at this price
  "ask_usd": 83630.53,              // OracleAMM sells you BTCw at this price
  "spread_pct": 0.3,
  "updated_at": 1790739823, "age_seconds": 5, "max_age_seconds": 300,
  "stale": false, "paused": false, "tradable": true,
  "liquidity": { "btcw": 1001, "usdw": 49916961.49, "max_trade_btcw": 10 },
  "oracle": { "address": "0x6E06…a96c", "decimals": 8, "sources": "median of 6: …" },
  "usdw_total_supply": 122171970.27, …
}

Safe to use when stale == false and paused == false. tradable combines both conditions with liquidity.

Prices of the 200 price-tracker tokens (crypto and US stocks)

curl -s https://btcw.tech/api/v2/pools          # per pool: oracleUsd, poolUsd, devBps, depthBtcw, priceAgeS…
curl -s https://btcw.tech/api/v2/swap/assets    # 202 assets: address, symbol, decimals, logoURI, priceUsd

Filter by class with the class field (crypto · stock · stable). oracleUsd is the oracle price (PriceHub); poolUsd is the current pool price; devBps is the deviation between the two. Staleness: check priceAgeS (a sensible threshold: 300 seconds).

Responses are cached for 5 seconds (cache-control: public, max-age=5) — polling more often won't return fresher data. Rate limit: 20 requests/second per IP.

Option 2 — on-chain, trust no server

BtcwPriceFeed follows the Chainlink interface, so any tool that reads Chainlink feeds can read it:

cast call 0x6E0687A5D5a5b98CC5fb05c4d8d742fBD75ba96c \
  "latestRoundData()(uint80,int256,uint256,uint256,uint80)" --rpc-url https://rpc.btcw.tech
import { JsonRpcProvider, Contract } from "ethers";
const p = new JsonRpcProvider("https://rpc.btcw.tech", 482120);
const feed = new Contract("0x6E0687A5D5a5b98CC5fb05c4d8d742fBD75ba96c",
  ["function latestRoundData() view returns (uint80,int256,uint256,uint256,uint80)"], p);
const [, answer, , updatedAt] = await feed.latestRoundData();
const age = Math.floor(Date.now() / 1000) - Number(updatedAt);
if (age > 300) throw new Error("oracle price is stale");
console.log("BTC/USD", Number(answer) / 1e8);

From a Solidity contract on chain 482120

interface AggregatorV3Interface {
    function latestRoundData() external view
        returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);
}

(, int256 answer,, uint256 updatedAt,) = AggregatorV3Interface(0x6E0687A5D5a5b98CC5fb05c4d8d742fBD75ba96c).latestRoundData();
require(block.timestamp - updatedAt <= 300, "stale");   // 8 decimals

Price-tracker token prices — PriceHub

# ETHw price (18 decimals) — substitute a token address from /api/v2/swap/assets
cast call 0xE87FDdCC0b668564a20B23F3bE1EE108C805ecb4 \
  "latestRoundData(address)(uint80,int256,uint256,uint256,uint80)" <token-address> --rpc-url https://rpc.btcw.tech

Several tokens at once: prices(address[]) returns two arrays, answers and updatedAts; tokens without a price return (0, 0) (whereas latestRoundData reverts with NoData).

Watch for price changes

Instead of polling, subscribe to events over WebSocket at wss://rpc.btcw.tech/ws:

// BtcwPriceFeed: AnswerUpdated(int256 indexed current, uint256 indexed roundId, uint256 updatedAt)
// PriceHub:      AnswerUpdated(address indexed asset, int256 answer, uint256 roundId, uint256 updatedAt)
const ws = new WebSocketProvider("wss://rpc.btcw.tech/ws", 482120);
feed.connect(ws).on("AnswerUpdated", (current) => console.log(Number(current) / 1e8));