Four onchain intelligence endpoints on Base, priced per call via the x402 protocol. No API keys, no accounts — request the endpoint, get an HTTP 402 with payment requirements, pay in USDC on Base mainnet, get your answer. Every route also has a free, rate-limited, no-payment /api/demo/* mirror with a smaller data window — that's what the homepage demo calls. Prefer a machine-readable schema? See the OpenAPI spec.
The same free, rate-limited demo from the homepage — no wallet needed.
Real USDC on Base: 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
eip155:8453)A plain fetch/requests call gets you the 402 — an x402 client library handles signing the payment and retrying automatically. Client library APIs move fast; check coinbase/x402 for the current package names if these have drifted.
TypeScript
import { wrapFetchWithPaymentFromConfig } from "@x402/fetch";import { ExactEvmScheme } from "@x402/evm";import { privateKeyToAccount } from "viem/accounts";const account = privateKeyToAccount("0xYOUR_PRIVATE_KEY");const fetchWithPayment = wrapFetchWithPaymentFromConfig(fetch, { schemes: [{ network: "eip155:8453", client: new ExactEvmScheme(account) }],});const res = await fetchWithPayment( "https://ulvane.xyz/api/token/0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913/risk");const data = await res.json();Python
from eth_account import Accountfrom x402.clients.requests import x402_requestsaccount = Account.from_key("0xYOUR_PRIVATE_KEY")session = x402_requests(account)res = session.get( "https://ulvane.xyz/api/token/0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913/risk")data = res.json()The wallet behind the private key needs a small amount of real USDC on Base mainnet — prices are cents-level ($0.01–$0.03 per call).
/api/token/{address}/risk$0.01Is this token a scam clone of a known name? Checks against a hand-verified allowlist and flags symbol impersonation.
Request
curl https://ulvane.xyz/api/token/0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913/riskResponse
{ "address": "0x8335...02913", "symbol": "USDC", "name": "USD Coin", "status": "verified", "note": "This exact address has been manually vetted by Ulvane.", "impersonatedSymbol": null, "asOf": "2026-09-18T17:55:00.476Z", "signature": "0x22629f79...ee922761c", "signerAddress": "0xdCac2E5680797cd6d7483764A76278cE5f91ECe8"}/api/pnl/{wallet}$0.02A wallet's realized/unrealized PnL, computed with a running-average cost basis — not just current balance × price.
Request
curl https://ulvane.xyz/api/pnl/0xYourWalletAddressResponse
{ "wallet": "0x...", "realizedUsd": 1234.56, "unrealizedUsd": 342.10, "wins": 14, "losses": 6, "totalTrades": 20, "points": [{ "time": 1737000000, "realizedUsd": 0 }], "positions": [ { "tokenAddress": "0x...", "symbol": "TOKEN", "avgCostUsd": 0.012, "amountHeld": 50000, "unrealizedUsd": 60.0 } ], "windowNote": "Based on the most recent swaps...", "asOf": "2026-09-18T00:00:00Z", "signature": "0x22629f79...ee922761c", "signerAddress": "0xdCac2E5680797cd6d7483764A76278cE5f91ECe8"}/api/token/{address}/top-traders$0.03Who's actually trading this token, ranked by volume moved — not just top balances.
Request
curl https://ulvane.xyz/api/token/0xTokenAddress/top-tradersResponse
{ "tokenAddress": "0x...", "currentPriceUsd": 0.0123, "traders": [ { "trader": "0x...", "boughtUsd": 50000, "soldUsd": 42000, "totalPnlUsd": 3900, "tradeCount": 14 } ], "windowNote": "Based on the most recent swaps...", "asOf": "2026-09-18T00:00:00Z", "signature": "0x22629f79...ee922761c", "signerAddress": "0xdCac2E5680797cd6d7483764A76278cE5f91ECe8"}/api/wallet/{wallet}/risk$0.02Should an agent trust this counterparty? Flags a wallet if it's recently traded any token on Ulvane's impersonator list — the wallet-level counterpart to the token risk check.
Request
curl https://ulvane.xyz/api/wallet/0xYourWalletAddress/riskResponse
{ "wallet": "0x...", "tradesAnalyzed": 42, "distinctTokensTraded": 11, "flaggedTokens": [], "status": "clean", "note": "No flagged-token activity found in this wallet's recent trade window...", "windowNote": "Based on the most recent swaps...", "asOf": "2026-09-18T00:00:00Z", "signature": "0x22629f79...ee922761c", "signerAddress": "0xdCac2E5680797cd6d7483764A76278cE5f91ECe8"}Every paid response includes a signature and signerAddress. It's a standard EIP-191 signature over the exact JSON body (minus those two fields) — proof this data came from Ulvane at this exact time, checkable by anyone, without asking our server again.
import { verifyMessage } from "viem";const { signature, signerAddress, ...data } = response;const valid = await verifyMessage({ address: signerAddress, message: JSON.stringify(data), signature,});Try it
Ulvane ships an MCP server, so Claude Desktop, Cursor or any MCP client can call the endpoints as tools. The agent's own wallet pays each call over x402 — the key stays on your machine and is only used to sign payment authorizations. Use a dedicated wallet with a few dollars of USDC on Base. A per-call spend cap (ULVANE_MAX_PRICE_USD, default $0.05) is built in. The leaderboard tool is free and needs no key.
// claude_desktop_config.json — no install step, runs via npx{ "mcpServers": { "ulvane": { "command": "npx", "args": ["-y", "ulvane-mcp"], "env": { "EVM_PRIVATE_KEY": "0x..." } } }}Tools: token_risk, wallet_pnl, wallet_risk, token_top_traders, base_leaderboard. The package is ulvane-mcp on npm; source is on GitHub.
windowNote).status: "unverified" on the risk endpoint means not on our hand-curated allowlist yet — not a signal that a token is unsafe.Build on