Built for autonomous agents: every endpoint is POST + JSON and returns a structured verdict your code branches on. Wire it in as MCP tools, pay per call via x402 (no account), or use an API key with a prepaid balance.
The fastest path. The Salvo MCP server exposes all 6 endpoints as native tools in any MCP-compatible agent (Claude, Cursor, your own runtime). Calls are billed to your prepaid balance via your API key — your agent just calls pretrade, token-safety, wallet-risk and branches on the verdict.
{
"mcpServers": {
"salvo": {
"command": "npx",
"args": ["-y", "salvo-mcp"],
"env": { "SALVO_API_KEY": "sk_live_...", "SALVO_BASE_URL": "https://salvo.one" }
}
}
}
For fully autonomous agents with their own wallet and no Salvo account: each request is paid on-chain over HTTP 402. No signup, no key — just a signer.
import { wrapFetchWithPayment, createSigner } from 'x402-fetch'
const pay = wrapFetchWithPayment(fetch, await createSigner('base', AGENT_PK))
// pre-trade gate in a sniper / MEV / Telegram bot's hot path
const r = await pay('https://salvo.one/v1/pretrade', {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ token: tokenIn, chain: 'base' }),
}).then(r => r.json())
if (r.data.verdict !== 'go') return skip() // can't sell / honeypot / shallow LP
await buy(tokenIn)
curl -X POST https://salvo.one/v1/token-safety \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"token":"0x...","chain":"ethereum"}'
{ "ok": true, "product": "token-safety", "data": { ... },
"_meta": { "billedVia": "apikey", "priceUsd": 0.005 } }
POST /v1/token-safety $0.005Scores rugpull/honeypot risk of an ERC20 token from on-chain signals: mint/pause functions, ownership, upgradeable proxy, ERC20 sanity.
| Field | Description |
|---|---|
token required | ERC20 contract address (0x...) |
chain | Data chain (ethereum|base|arbitrum|optimism|...). Default ethereum. |
{
"token": "0x...",
"chain": "ethereum",
"riskScore": 18,
"verdict": "safe",
"name": "Example",
"symbol": "EXM",
"decimals": 18,
"ownerRenounced": true,
"flags": [],
"capabilities": []
}POST /v1/pretrade $0.003Single go/caution/block verdict for an ERC20 before buying: safety scan + honeypot sell-simulation (routed to the liquidity pair) + liquidity depth. Built for trading bots (one call).
| Field | Description |
|---|---|
token required | ERC20 contract address (0x...) |
chain | Data chain (ethereum|base|arbitrum|optimism|bsc|...). Default ethereum. |
{
"token": "0x...",
"chain": "ethereum",
"verdict": "go",
"canSell": true,
"riskScore": 12,
"liquidity": {
"pairExists": true,
"pooledNative": 41.2,
"nativeSymbol": "WETH",
"tier": "deep",
"dex": "uniswap-v2"
},
"reasons": [
"passed safety, sell-simulation, and liquidity checks"
],
"confidence": 0.9
}POST /v1/wallet-risk $0.01AML risk assessment: OFAC + mixer blocklist screening of the address and its counterparties, an ERC20 + native ETH value graph, and behavioral laundering typologies — with an explainable score and recommendation.
| Field | Description |
|---|---|
address required | Wallet address (0x...) |
chain | Data chain. Default ethereum. |
depth | Analysis depth 1–3 (wider history window, more thorough, higher cost). Default 1. |
{
"address": "0x...",
"chain": "ethereum",
"sanctioned": false,
"riskScore": 12,
"verdict": "safe",
"recommendation": "ALLOW",
"signals": [],
"exposure": {
"directBadContacts": [],
"counterparties": 14
}
}POST /v1/token-unlock $0.004Reads vesting/lockup schedule from standard contracts (OZ VestingWallet, TokenTimelock): start, end, progress, unlock date.
| Field | Description |
|---|---|
contract required | Vesting/lockup contract address (0x...) |
chain | Data chain. Default ethereum. |
now | UNIX time for progress calc (optional; otherwise taken from block). |
{
"contract": "0x...",
"chain": "ethereum",
"standard": "OZ VestingWallet",
"start": 1700000000,
"end": 1731536000,
"percentVested": 42.5
}POST /v1/wallet-score $0.006Composite 0–100 wallet score from lifetime activity, counterparty/token diversity (multi-day window) and balance. Gauges organic behavior (anti-sybil) and wallet "quality". Known infrastructure is flagged, not scored.
| Field | Description |
|---|---|
address required | Wallet address (0x...) |
chain | Data chain. Default ethereum. |
{
"address": "0x...",
"chain": "ethereum",
"score": 73,
"tier": "good",
"breakdown": {
"activity": 26,
"diversity": 32,
"balance": 15
},
"stats": {
"txCount": 412,
"uniqueCounterparties": 180,
"uniqueTokens": 24
}
}POST /v1/wallet-graph $0.008Transfer graph around a wallet with risk-classified nodes (sanctioned/exploit/scam/mixer/infra) and edges — for tracing flows and connections. Powers the interactive investigation view.
| Field | Description |
|---|---|
address required | Wallet/contract address (0x...) |
chain | Data chain. Default ethereum. |
depth | Graph depth 1–2 (2 expands active neighbors to reveal paths). Default 1. |
{
"address": "0x...",
"chain": "ethereum",
"depth": 1,
"nodes": [
{
"id": "0x...",
"category": "clean",
"label": "",
"subject": true
}
],
"edges": [
{
"from": "0x...",
"to": "0x...",
"kind": "erc20",
"count": 3
}
],
"stats": {
"nodes": 24,
"edges": 31,
"flagged": 1
},
"scanned": {
"fromBlock": 25160000,
"toBlock": 25290000,
"blocks": 130000,
"incomplete": false
}
}
ethereum, base, arbitrum, optimism, bsc, celo, linea, scroll, blast, mantle, zksync, fantom, mode — via the chain field (default ethereum).