Chain Candles
by Tanod chainpeek in Onchain & crypto
chainpeek (Tanod) ETH and BTC OHLCV price candles (5m to 1d) computed from on-chain Uniswap v3 swaps on Base. Use when an agent needs ETH or BTC price history as OHLCV candles for charting or backtesting.
POST https://tanod.dev/v1/chain/candles
Last 30 days
Status and outage history · Atom feed
- Uptime
- 100%
- Response time
- 742 ms typical, 1.1 s slowest 5%
- Last check
- 3 h ago
- Next check
- any minute now
How to call it
POST https://tanod.dev/v1/chain/candles
Each call costs $0.003 in USDC on Base, paid with the request over x402.
Run a free test callOne unpaid request, the way an agent sends it. You see the payment challenge it gets back. Nothing is charged.
Example request
From the listing.
POST https://tanod.dev/v1/chain/candles
content-type: application/json
{
"interval": "1h",
"limit": 3,
"pair": "WETH/USDC"
}Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
interval | string | No | Candle length, UTC-aligned. One of: 5m, 15m, 1h, 4h, 1d. Default: "1h". |
limit | integer or null | No | Number of candles, newest last. Default 48 (1d: 30). Lookback caps: 5m and 15m 200, 1h 168, 4h 42, 1d 30. Default: null. |
pair | string | Yes | WETH/USDC (ETH in USDC, Uniswap v3 0.3% pool on Base) or cbBTC/USDC (BTC in USDC, Uniswap v3 0.05% pool on Base). One of: WETH/USDC, cbBTC/USDC. |
Example response
The provider's example. We can't check it without paying.
Example response, 60 lines
{
"as_of": 1791459117,
"as_of_block": 52334885,
"as_of_iso": "2026-10-08T11:31:57Z",
"base": {
"address": "0x4200000000000000000000000000000000000006",
"decimals": 18,
"symbol": "WETH"
},
"candles": [
{
"close": 2562.440508,
"high": 2564.536011,
"low": 2562.420829,
"open": 2564.53549,
"swaps": 162,
"t": 1791450000,
"volume_base": 283.1768169,
"volume_quote": 723823.9884
},
{
"close": 2554.931473,
"high": 2562.444764,
"low": 2554.931469,
"open": 2562.440275,
"swaps": 332,
"t": 1791453600,
"volume_base": 978.302039,
"volume_quote": 2495689.547
},
{
"close": 2533.963891,
"high": 2554.934474,
"low": 2533.962543,
"open": 2554.932156,
"swaps": 409,
"t": 1791457200,
"volume_base": 2643.973295,
"volume_quote": 6707581.103
}
],
"chain": "base",
"count": 3,
"dex": "uniswap_v3",
"fee": 3000,
"interval": "1h",
"interval_seconds": 3600,
"last_candle_partial": true,
"note": "Computed by Tanod from public Uniswap v3 Swap events of one pool on Base: open/high/low/close are the pool's post-swap prices, volumes the absolute swapped amounts. DEX prices can differ from centralized exchanges (fees, arbitrage lag, MEV and sandwich trades inside a block, depegs of the quote stablecoin). A candle without swaps carries the previous close with zero volume; the last candle is still forming. Informational only, not investment advice.",
"pair": "WETH/USDC",
"pool": "0x6c561B446416E1A00E8E93E221854d6eA4171372",
"price_unit": "USDC per WETH",
"quote": {
"address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"decimals": 6,
"symbol": "USDC"
},
"source": "Uniswap v3 swaps on Base (on-chain)",
"timestamps": "Bucketed by block timestamp (UTC, interval-aligned): each log's blockTimestamp, else estimated from Base's fixed 2 s block time anchored at the latest block."
}Call it from code
The curl command shows the payment challenge. The JavaScript and Python versions pay and call, and never pay more than $0.003.
curl: see the payment challenge
# bash or zsh: see the payment challenge. Nothing is charged.
curl -sS -g -i -X POST 'https://tanod.dev/v1/chain/candles' \
-H 'content-type: application/json' \
--data-raw '{"interval":"1h","limit":3,"pair":"WETH/USDC"}'
# x402 v2 sends the challenge base64-encoded in the PAYMENT-REQUIRED header (v1 sends it in the body).
# To read the header:
curl -sS -g -o /dev/null -D - -X POST 'https://tanod.dev/v1/chain/candles' \
-H 'content-type: application/json' \
--data-raw '{"interval":"1h","limit":3,"pair":"WETH/USDC"}' \
| grep -i '^payment-required:' | cut -d' ' -f2 | tr -d '\r' | base64 --decodeJavaScript: pay and call
// npm i @x402/fetch @x402/evm viem
import { wrapFetchWithPayment, x402Client } from "@x402/fetch";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";
// Pays at most $0.003 per call.
const client = new x402Client().setSpendControls({ maxAmountPerPayment: "$0.003" });
registerExactEvmScheme(client, { signer: privateKeyToAccount(process.env.EVM_PRIVATE_KEY) });
const pay = wrapFetchWithPayment(fetch, client);
// Not sure it's safe to pay? ToolVet checks it first for $0.005. Pay for that from a separate
// client: this one is capped at $0.003 per payment. GET https://toolvet.app/api/v1/check?url=https%3A%2F%2Ftanod.dev%2Fv1%2Fchain%2Fcandles&method=POST
const res = await pay("https://tanod.dev/v1/chain/candles", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
"interval": "1h",
"limit": 3,
"pair": "WETH/USDC"
}),
});
console.log(res.status, await res.text());Python: pay and call
# pip install "x402[requests,evm]"
import os
from eth_account import Account
from x402 import x402ClientSync
from x402.http.clients import x402_requests
from x402.mechanisms.evm import EthAccountSigner
from x402.mechanisms.evm.exact.register import register_exact_evm_client
# Pays at most $0.003 per call.
client = x402ClientSync().set_spend_controls({"max_amount_per_payment": "$0.003"})
register_exact_evm_client(client, EthAccountSigner(Account.from_key(os.environ["EVM_PRIVATE_KEY"])))
with x402_requests(client) as session:
res = session.post(
"https://tanod.dev/v1/chain/candles",
json={
"interval": "1h",
"limit": 3,
"pair": "WETH/USDC",
},
)
print(res.status_code, res.text)Security scan
- No findings. We scan names, descriptions and tool definitions for hidden instructions and other prompt-injection patterns.
Recent checks
| When | Result | HTTP | Time | Price |
|---|---|---|---|---|
| 3 h ago | Passed | 402 | 1.0 s | $0.003 |
| 7 h ago | Passed | 402 | 367 ms | $0.003 |
| 11 h ago | Passed | 402 | 392 ms | $0.003 |
| 14 h ago | Passed | 402 | 1.1 s | $0.003 |
| 18 h ago | Passed | 402 | 1.1 s | $0.003 |
| 22 h ago | Passed | 402 | 1.1 s | $0.003 |
| 26 h ago | Passed | 402 | 1.1 s | $0.003 |
| 29 h ago | Passed | 402 | 1.1 s | $0.003 |
| 33 h ago | Passed | 402 | 1.2 s | $0.003 |
| 37 h ago | Passed | 402 | 353 ms | $0.003 |
| 40 h ago | Passed | 402 | 264 ms | $0.003 |
| 44 h ago | Passed | 402 | 370 ms | $0.003 |
| 47 h ago | Passed | 402 | 823 ms | $0.003 |
| 2 days ago | Passed | 402 | 818 ms | $0.003 |
| 2 days ago | Passed | 402 | 356 ms | $0.003 |