Block-Accurate Decentralized Token Price Feed for Uniswap V3

Block-Accurate Decentralized Token Price Feed for Uniswap V3

Most Uniswap based indexers provide you a token's USD represented price at its last seen swap. Powerloom's Decentralized Token Price Feed gives you the price at every block, for every indexed pool, in USD, finalized by a decentralized validator network.

That distinction matters when you are building agents, running risk models, or pricing anything on-chain. The last swap on a quiet pool might be six blocks old. The last swap on WETH might show zero movement while the alt pair you actually trade is drifting 2%. If your price gate depends on swap events, you are blind between trades.

Our feed closes that gap. Every ~12 seconds on ETH mainnet, every indexed pool gets a USD price derived from on-chain state (slot0), anchored through a consistent conversion graph: USDC, USDT, and DAI pinned at $1, ETH priced from the canonical USDC/WETH pool, and every other token routed through the deepest WETH or USDC reference pool. No interpolation, no stale oracle heartbeat, no centralized indexer.

Today the feed is live in production on BDS mainnet, the premium metering is active with weighted credit deductions, and the API is ready to consume.

Consume It Now

You need a BDS API key. Get one at bds-metering.powerloom.io/metering — email signup, no wallet, 2 free credits on the house.

The consumption pattern for any token is: find pools, then get prices per pool (not tokenPrices/all unless you know the token has at most ~20 pools). Here is a real example with Asteroid Shiba (ASTEROID, 0xf280B16EF293D8e534e370794ef26bF312694126).

Step 1: Find which pools list this token:

curl -s -H "Authorization: Bearer sk_live_... \
  "https://bds.powerloom.io/api/mpp/token/0xf280B16EF293D8e534e370794ef26bF312694126/pools" | jq '.pools | keys'

Returns six pools:

[
  "0x08989C58bC6b18e8e2910815309A89DE4F1275B2",
  "0x0e55Db2d5e07cc6B067f352bA35A6beaFB33c282",
  "0x168E9B3c9ddFB013A4130276F9c500A3CE50FdE7",
  "0x53e3d506F468c4BC30cc8CaA21Eb7E56c2fA2D55",
  "0x76718094c323e3F0d99A0521DFc66523d1e96083",
  "0xC41BB16Bb5F7121947E381BB2b20E2a723f39163"
]

Two are against USDC, two against WETH, two against USDT. Each pool entry includes full token metadata (symbol, decimals, fee tier).

Step 2: Get USD price in a specific pool:

curl -s -H "Authorization: Bearer sk_live_... \
  "https://bds.powerloom.io/api/mpp/token/price/0xf280B16EF293D8e534e370794ef26bF312694126/0x08989C58bC6b18e8e2910815309A89DE4F1275B2"

Returns a scalar USD price:

0.000162681

That is ASTEROID's USD price in the USDC pool at the latest finalized epoch. One HTTP call, one number.

Step 3: Get price at a specific block:

curl -s -H "Authorization: Bearer sk_live_... \
  "https://bds.powerloom.io/api/mpp/token/price/0xf280B16EF293D8e534e370794ef26bF312694126/0x08989C58bC6b18e8e2910815309A89DE4F1275B2/25215944"

Same scalar, but pinned to block 25215944. This is what Pulse uses for price gates: a verifiable, epoch-specific USD number.

Price history over time: the time series endpoint:

curl -s -H "Authorization: Bearer sk_live_... \
  "https://bds.powerloom.io/api/mpp/timeSeries/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2/0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640/3600/144"

This returns WETH price history from the USDC/WETH pool: 1-hour intervals (3600s), 144 steps. Real response:

{
  "priceSeries": [
    {"blockNumber": 25215644, "price": 2023.30, "timestamp": 1780234031},
    {"blockNumber": 25215656, "price": 2023.25, "timestamp": 1780234175},
    {"blockNumber": 25215668, "price": 2023.22, "timestamp": 1780234319},
    ...
    {"blockNumber": 25215944, "price": 2008.67, "timestamp": 1780237643}
  ]
}

Each entry has a block number, the USD price, and a Unix timestamp. This is the endpoint you reach for when building charts, computing moving averages, or backtesting strategies against historical prices.

Two-Line Agent Prompts

You do not need bds-agent to consume the feed. Here are prompts for any agent framework that can call HTTP APIs.

Screenshot 2026-06-06 at 1.34.33 PM.png

Hermes (cron job, periodic price report to Telegram):

Fetch the AAVE price in the WETH pool:
GET https://bds.powerloom.io/api/mpp/token/price/0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9/0x1353fE67fFf8f376762b7034DC9066f0bE15a723
with Authorization: Bearer sk_live_... Reply: "AAVE @ $<price>" and send to Telegram.

OpenClaw (one-shot, multi-pool price monitoring):

Use the powerloom-bds-univ3 skill. First call bds_mpp_token_pools for 0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9 to find pools. Then call bds_mpp_token_price_token_address_pool_address for each WETH pool. Report all USD prices.

Both hit the same weighted metering path. Both get DSV-finalized data. The agent framework is your choice; the data product is the same.

Premium Metering Is Live

The /mpp/ routes on the resolver node now apply weighted credit deductions. Premium endpoints like token/price (weight 5) and token/price/{block} (weight 10) cost more than standard snapshot reads (weight 1) because every price is a batched slot0 read through an anchored USD graph backed by DSV-finalized snapshots, not a cached last-trade lookup. Time series carries a base weight of 5 with a lookback multiplier that scales with how far back you query (4x at 1 hour, 128x at 24 hours, up to 2048x for >7 days).

For the full credit weight table and lookback multiplier breakdown, see Credit Weights in the Endpoint Catalog.

Do not use tokenPrices/all for USDC, WETH, or other hub tokens. Those tokens have thousands of indexed pools; the API only supports ≤20 pools per tokenPrices/all request and will error on majors. The supported pattern is always: GET /mpp/token/{token}/pools, then GET /mpp/token/price/{token}/{pool} (or .../{block}) for each pool you need — the same flow Pulse and Guard use on pinned pools.

Your balance and per-endpoint usage are visible at bds-metering.powerloom.io/metering/account. Paste your API key and you see the USAGE tab: balance, daily spend, top endpoints, recent activity.

How It Works

The pipeline reads on-chain pool state for every indexed Uniswap V3 pool, at every block, and converts every price to USD through a consistent anchor graph. USDC, USDT, and DAI are pinned at $1. ETH gets its USD price from the canonical USDC/WETH pool. Every other token routes through the deepest WETH or USDC reference pool available. Zero-trade blocks still get prices. No interpolation, no post-hoc inference.

The entire pipeline runs inside the Powerloom snapshotter, gets validated by the DSV network, and lands as a finalized snapshot with on-chain CID. Compute is open source at github.com/powerloom/snapshotter-computes.

Sneak Peek — Pulse

Screenshot 2026-05-31 at 3.04.42 PM.png

Pulse trades on this feed. It's a confluence-based auto-trader built into bds-agent that enters when price drift, volume burst, and directional flow align on the same pool. Full post coming next. Here's a live session from today:

▶ bds-agent trade run --profile bds-tgtest2 \
    --multi-pool --verbose --size 5 --price-source usd \
    --exit-take-profit-pct 0.25 --daily-loss-limit 5

trade mode=multi-pool watching=14 (USDC/WETH, USDC/SEI, uPEG/USDC,
  WBTC/USDC, USDC/ASTEROID, USDC/USDT, USDC/AEVO +6) size=$5.00 max_open=2

13:23:02  USDC/WETH  px=+0.00%  burst=0.00x  imb=0%  → warming up
13:24:32  USDC/WETH  px=+0.01%  burst=12.00x imb=95% → gates not met: price
13:25:20  AI/USDC    px=-0.29%  burst=12.00x imb=2%  → gates not met: imb
13:27:12  AI/USDC    px=-0.36%  burst=12.00x imb=1%  → gates not met: imb

  ... scanning continues across 14 pools ...

  ▶ OPEN LONG: USDC/ASTEROID  entry=0.000154927  size=$5.00
  ▶ OPEN LONG: USDC/SEI       entry=0.066940     size=$5.00

Position status as trades close:

▶ bds-agent trade status
  Position LONG×2  open=2
    [1] USDC/ASTEROID  entry=0.000154927  size=$5.0
    [2] USDC/SEI       entry=0.066940     size=$5.0
  daily P/L: $0.03

  ... SEI position closed (take-profit) ...

  Position LONG  open=1
    [1] USDC/ASTEROID  entry=0.000154927  size=$5.0
  daily P/L: $0.04

  ... ASTEROID position closed ...

  Position FLAT
  daily P/L: $0.04
  usdc_balance: 12.431457

Both LONGs closed in profit. +$0.04 across two $5 positions. WETH/USDC had 12× burst volume but the price was flat at +0.01%, so Pulse skipped it every time. ASTEROID and SEI had all three: price moving, volume spiking, flow tilting. That only shows up when you price every block, not just when swaps fire.

How This Is Different

Source Price when? USD basis
Last swap price Only when a swap fires Often ad-hoc
Subgraph / indexer spot Event-driven, laggy Mixed
Chainlink oracle Heartbeat (minutes) External oracle
BDS USD Price Feed Every block (~12s) Anchored graph: stables + ETH + liquidity routing

What's Next

This post covers the price feed itself. Pulse and Threshold Guard each get their own deep-dive posts next: how the confluence gates work, position management, exit strategies, and live trade walkthroughs. The feed is the product; Pulse and Guard prove why it matters.

Get your free API key, hit the endpoint, and see what block-accurate prices look like.


Resources

Spread the word. Discord | X | Telegram | GitHub