Install
openclaw skills install @plagtech/crypto-skillReal-time crypto prices, gas, trending tokens, wallet balances, ENS resolution, and token info for OpenClaw agents. Zero API keys required. Use when the user asks about crypto prices, token info, wallet balances, gas costs, trending coins, name resolution, or any blockchain data lookup.
openclaw skills install @plagtech/crypto-skillReal-time crypto intelligence. No API keys. No setup. Just ask.
Most lookups go through the Spraay free tier at https://gateway.spraay.app/free/*:
no wallet, no payment, no API key. It is rate-limited to 60 requests per minute per IP,
so batch lookups into one call where the endpoint allows it.
Use this skill when the user asks about:
ETH, USDC, SOL and USDG are always returned. Add any other symbols with tokens
(comma-separated, up to 25) — one call covers them all:
curl -s "https://gateway.spraay.app/free/prices?tokens=BTC,LINK,ARB" | jq '.prices'
Response shape:
{"prices":{"ETH":{"usd":2493.22},"USDC":{"usd":0.9996},"SOL":{"usd":110.51},"USDG":{"usd":0.9998},"BTC":{"usd":82422},"LINK":{"usd":12.89},"ARB":{"usd":0.1781}},"unknown":[],"timestamp":1791524571868}
Prices are cached for 60 seconds. A symbol the gateway can't map comes back as
{"usd": null} and is listed in unknown — for those, fall back to DexScreener search
(see Token Info) and use the priceUsd of the most liquid pair.
When the user asks for a price conversion (e.g. "how much is 2 ETH in USD" or "500 USDC in ETH"):
/free/prices callWhen comparing tokens, fetch both prices in one call and calculate the ratio.
Trending tokens (DexScreener boosts) via the Spraay free tier:
curl -s "https://gateway.spraay.app/free/dex/trending" | jq '.trending[:10]'
Each entry has chain, symbol, tokenAddress, url (and sometimes description) —
no price. To get price, volume, 24h change and liquidity for an entry, look up its pairs:
curl -s "https://gateway.spraay.app/free/dex/tokens/TOKEN_ADDRESS" | jq '.pairs[:3]'
Many trending entries have no real symbol (the symbol field is just the start of the
address). Use the description or the DexScreener url to identify them, and say so
rather than inventing a name.
When presenting trending tokens:
One call returns current gas for 9 EVM chains (Base, Ethereum, Arbitrum, Polygon, Optimism, Avalanche, BNB Chain, Robinhood Chain, peaq), already converted to gwei:
curl -s "https://gateway.spraay.app/free/gas" | jq '.gas | map_values(.gasPriceGwei)'
Each chain entry has name, chainId, gasPriceWei and gasPriceGwei. Cached 15 seconds.
Present as: "[Chain]: X.XXX gwei" (L2 gas is often well under 1 gwei — show enough decimals that it doesn't round to 0). For a standard transfer cost estimate: gasPriceGwei × 21,000 ÷ 1,000,000,000 = cost in the native token, then multiply by the native token's USD price. Polygon gas is priced in POL and Avalanche in AVAX, not ETH — fetch the right native price.
curl -s "https://gateway.spraay.app/free/resolve?name=vitalik.eth"
Returns {"name":..., "address":..., "source":"ens"|"basenames", "resolved":true|false}.
Basenames can be given as jesse.base or jesse.base.eth.
If resolved is false, try a public resolver before telling the user the name doesn't exist:
ENS (.eth):
curl -s "https://api.ensideas.com/ens/resolve/vitalik.eth" | jq -r '.address'
Basenames (.base / .base.eth):
curl -s "https://api.web3.bio/ns/jesse.base" | jq -r '.[0].address'
When the user provides a name anywhere in a crypto context, resolve it automatically before using the address.
Check native token balance on EVM chains using public RPCs. RPC results are hex — always
convert with python3 (bash printf %d overflows above ~9.2 ETH).
Native balance (replace ADDRESS; pick the RPC for the chain):
curl -s -X POST https://mainnet.base.org -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_getBalance","params":["ADDRESS","latest"],"id":1}' \
| jq -r '.result' | python3 -c "import sys; print(int(sys.stdin.read().strip(), 16) / 1e18)"
Public RPCs:
https://mainnet.base.orghttps://ethereum-rpc.publicnode.comhttps://arbitrum-one-rpc.publicnode.comhttps://optimism-rpc.publicnode.comhttps://polygon-bor-rpc.publicnode.com (balance is in POL)The output above is already in whole tokens (wei ÷ 10^18).
For ERC-20 token balances (e.g. USDC on Base):
# USDC on Base: 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
# balanceOf(address) selector: 0x70a08231, then the address without 0x, left-padded to 32 bytes
curl -s -X POST https://mainnet.base.org -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_call","params":[{"to":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","data":"0x70a08231000000000000000000000000ADDRESS_WITHOUT_0x"},"latest"],"id":1}' \
| jq -r '.result' | python3 -c "import sys; print(int(sys.stdin.read().strip(), 16) / 1e6)"
Divide by 10^decimals for the token — USDC is 6 decimals (1e6), most others 18 (1e18).
If the user provides a name (e.g. vitalik.eth), resolve it first, then check the balance.
When reporting balances:
Look up token details — contract address, decimals, chain.
Common Base tokens (use these addresses for balance checks):
0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 (6 decimals)0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2 (6 decimals)0x60a3E35Cc302bFA44Cb288Bc5a4F316Fdb1adb42 (6 decimals)0x4200000000000000000000000000000000000006 (18 decimals)0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb (18 decimals)0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf (8 decimals)0x2Ae3F1Ec7F1F5012CFEab0185bfc7aa3cf0DEc22 (18 decimals)0xd9aAEc86B65D86f6A7B5B1b0c42FFA531710b6CA (6 decimals)For tokens not in this list, search DexScreener through the free tier:
curl -s "https://gateway.spraay.app/free/dex/search?q=TOKEN_SYMBOL" | jq '.pairs[:5]'
Each pair has chain, dex, baseToken (symbol, name, address), priceUsd,
volume24h, priceChange24h, liquidity and url. Many unrelated tokens share popular
symbols — prefer the pair with the highest liquidity on the chain the user cares about,
and show the contract address so the user can verify.
All pairs for a known contract address:
curl -s "https://gateway.spraay.app/free/dex/tokens/TOKEN_ADDRESS" | jq '.pairs[:5]'
Live status and block height for the 9 EVM chains the free tier tracks:
curl -s "https://gateway.spraay.app/free/chain-status" | jq '.chains | map_values({name, chainId, blockNumber, status})'
Chains where Spraay batch payments are live, with contract addresses and popular tokens:
curl -s "https://gateway.spraay.app/api/v1/tokens" | jq '.chains'
Report what these endpoints return rather than a list from memory.
/free/prices call → present portfolio summary./free/gas and present the relevant chain in both gwei and estimated USD cost.curl -s https://gateway.spraay.app/ lists the current endpoints.