
Zerion
- 1 installs
- 1.2k repo stars
- Updated August 1, 2026
- bankrbot/moltbot-skills
Zerion is a Claude Code skill that returns interpreted crypto wallet data (portfolio, positions, PnL, NFTs, prices) across 41+ chains as agent-ready JSON, via API key or x402 pay-per-request.
About
Zerion is a Claude skill that gives an agent interpreted crypto wallet data across 41+ chains. It returns portfolio values, token and DeFi positions, NFT holdings, transaction history, PnL, prices and gas as agent-ready JSON with USD values and protocol labels. An agent uses it as the research layer to analyze wallets, then hands off to Bankr for execution.
- Interpreted crypto wallet data (portfolio, positions, PnL, NFTs) across 41+ chains
- Access via free API key or x402 pay-per-request ($0.01 USDC on Base)
- Research layer that hands off to Bankr for execution
Zerion by the numbers
- 1 all-time installs (skills.sh)
- Ranked #426 of 479 Web3 & Blockchain skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
zerion capabilities & compatibility
Free API key available; x402 pay-per-request is $0.01 USDC on Base.
- Capabilities
- portfolio analysis · pnl tracking · wallet analytics · nft tracking
- Use cases
- data analysis · research
- Runs
- Runs locally
- Pricing
- Freemium
What zerion says it does
Zerion provides interpreted, enriched crypto wallet data across 41+ chains including Ethereum, Base, Arbitrum, Optimism, Polygon, Solana, and more.
npx skills add https://github.com/bankrbot/moltbot-skills --skill zerionAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 1.2k |
| Last updated | August 1, 2026 |
| Repository | bankrbot/moltbot-skills ↗ |
What it does
Read a crypto wallet's portfolio, positions, PnL and NFTs as enriched JSON to inform agent trading decisions.
Who is it for?
Reading enriched wallet portfolio, position and PnL data as the research layer before execution.
Skip if: Executing trades or transactions - Zerion is read-only and hands off to Bankr for execution.
When should I use this skill?
The user asks about a wallet's portfolio, positions, transactions, PnL, DeFi, token balances, NFTs, swap quotes or gas prices.
What you get
Agent-ready JSON with portfolio values, labeled positions, PnL and NFT holdings across chains.
- Portfolio JSON
- Positions and DeFi breakdown
- PnL report
By the numbers
- Data across 41+ chains
- x402 costs $0.01 USDC per request on Base
Files
Zerion: Wallet Intelligence for AI Agents
Zerion provides interpreted, enriched crypto wallet data across 41+ chains including Ethereum, Base, Arbitrum, Optimism, Polygon, Solana, and more.
Unlike raw RPC data, Zerion returns:
- USD values for all positions
- Protocol labels (Uniswap, Aave, Lido, etc.)
- Human-readable transaction types (swap, stake, bridge, mint, burn)
- PnL calculations (realized, unrealized, per-asset, FIFO method)
- DeFi position breakdowns (deposits, borrows, LP positions with
group_id) - NFT portfolios with floor prices and collection metadata
- Spam filtering built-in
Two ways to access:
- x402 (no account needed): Pay $0.01 USDC per request on Base. No API key, no signup.
- API key: Get a free key instantly at dashboard.zerion.io for higher rate limits.
Research → Execute Pattern
Zerion is the research layer. Use it to analyze wallets, find opportunities, track PnL. Then hand off to Bankr for execution (swaps, stop-losses, DCA).
Zerion (Research) Bankr (Execute)
───────────────── ────────────────
Portfolio analysis → Rebalance trades
PnL tracking → Stop-loss orders
Position monitoring → Take-profit orders
Whale watching → Copy trades
Swap quotes → Execute best route
NFT floor tracking → Buy/sell NFTsCLI Quick Start
npm install -g zerion-cli
# Set API key
export ZERION_API_KEY="zk_..."
# Or use x402 (no key needed)
zerion-cli wallet portfolio 0x... --x402
# Commands
zerion-cli wallet portfolio <address> # Total USD value
zerion-cli wallet positions <address> # All token positions
zerion-cli wallet transactions <address> # Transaction history
zerion-cli wallet pnl <address> # Profit & loss
zerion-cli wallet analyze <address> # Full analysis
zerion-cli chains list # Supported chains---
Wallet Endpoints
GET /v1/wallets/{address}/portfolio
Returns aggregated portfolio value across all chains.
curl "https://api.zerion.io/v1/wallets/0x.../portfolio?currency=usd" \
-H "Authorization: Basic $(echo -n $ZERION_API_KEY: | base64)"Response:
{
"data": {
"attributes": {
"total": { "positions": 44469.60 },
"positions_distribution_by_type": {
"wallet": 40000,
"deposited": 3000,
"staked": 1469.60
},
"positions_distribution_by_chain": {
"base": 27495.06,
"ethereum": 6216.25,
"arbitrum": 1234.56
},
"changes": {
"absolute_1d": 305.86,
"percent_1d": 0.69
}
}
}
}GET /v1/wallets/{address}/positions
Returns all fungible token and DeFi positions.
Query params:
filter[positions]:only_simple(tokens only),only_defi(protocol positions),no_filter(all)filter[chain_ids]: Comma-separated chain IDs (e.g.,base,ethereum,arbitrum)filter[trash]:only_non_trash(exclude spam),only_trash,no_filtersort:valueor-value
Understanding LP Positions: Liquidity pools return multiple positions (one per token) with shared group_id. Group by group_id to display LP holdings together.
Response includes:
- Token symbol, name, icon URL
- Quantity (int, float, decimals, numeric)
- USD value and price
- Position type:
wallet,deposited,borrowed,staked,locked - Protocol name and DApp relationship
group_idfor LP position grouping
GET /v1/wallets/{address}/transactions
Returns interpreted transaction history.
Query params:
filter[chain_ids]: Filter by chainsfilter[asset_types]:fungible,nftfilter[trash]:only_non_trash,no_filterpage[size]: Results per page (default 20)page[after]: Cursor for pagination
Each transaction includes:
operation_type:trade,send,receive,approve,stake,unstake,borrow,repay,bridge,mint,burn,bid,executetransfersarray with direction, token info, quantities, USD valuesfeewith gas cost in native token and USDapplication_metadatawith contract address and method info- Related
dappandchainrelationships
GET /v1/wallets/{address}/pnl
Returns Profit and Loss using FIFO method.
Query params:
currency:usd(default)filter[chain_ids]: Comma-separated chain IDs
Response:
{
"data": {
"attributes": {
"total_gain": -15076.15,
"realized_gain": 45328.28,
"unrealized_gain": -60404.44,
"relative_total_gain_percentage": -5.65,
"relative_realized_gain_percentage": 28.08,
"relative_unrealized_gain_percentage": -57.36,
"total_fee": 681.81,
"total_invested": 266672.34,
"realized_cost_basis": 161370.01,
"net_invested": 105302.33,
"received_external": 128217.01,
"sent_external": 67415.77,
"sent_for_nfts": 4333.36,
"received_for_nfts": 423.01
}
}
}GET /v1/wallets/{address}/chart
Returns portfolio balance chart over time.
Query params:
currency:usdfilter[chain_ids]: Filter by chainsperiod: Time period for chart
GET /v1/wallets/{address}/nft-portfolio
Returns NFT portfolio overview with total estimated value.
GET /v1/wallets/{address}/nft-positions
Returns list of NFT positions held by wallet.
Query params:
filter[chain_ids]: Filter by chainssort: Sort order- Pagination supported
GET /v1/wallets/{address}/nft-collections
Returns NFT collections held by wallet with floor prices.
---
Fungibles (Token) Endpoints
GET /v1/fungibles
Returns paginated list of fungible assets. Supports search.
Query params:
filter[search_query]: Search by name or symbolfilter[implementation_chain_id]: Filter by chainfilter[implementation_address]: Filter by contract addresssort: Sort order
GET /v1/fungibles/{fungible_id}
Returns single fungible asset by ID.
GET /v1/fungibles/implementation/{chain}:{address}
Returns fungible by chain:address pair (e.g., ethereum:0xa5a4...).
GET /v1/fungibles/{fungible_id}/chart
Returns price chart for fungible asset.
Query params:
filter[period]:hour,day,week,month,year,max
---
NFT Endpoints
GET /v1/nfts
Returns list of NFTs with metadata.
Query params:
- Filter and pagination supported
GET /v1/nfts/{nft_id}
Returns single NFT by ID with full metadata, traits, and collection info.
---
DApp Endpoints
GET /v1/dapps
Returns list of DApps (protocols) indexed by Zerion.
GET /v1/dapps/{dapp_id}
Returns single DApp with metadata, supported chains, and categories.
---
Chain Endpoints
GET /v1/chains
Returns all 41+ supported chains with metadata.
GET /v1/chains/{chain_id}
Returns single chain by ID.
---
Gas Prices
GET /v1/gas-prices
Returns real-time gas prices across all supported chains.
Useful for:
- Estimating transaction costs
- Choosing optimal chain for execution
- Timing transactions for lower fees
---
Swap & Bridge Quotes
GET /v1/swap/offers
Returns swap/bridge quotes from multiple providers (aggregator).
Query params:
- Input/output tokens
- Amount
- Slippage tolerance
Returns quotes from 0x, 1inch, Uniswap, and more. Zerion charges 0.5% on L2/alt-L1 trades (waived with Genesis NFT).
Note: Response time is 5-10 seconds due to multi-provider aggregation.
GET /v1/swap/fungibles
Returns fungibles available for bridge exchange (cross-chain swaps).
---
Webhooks (Subscriptions)
Real-time notifications for wallet activity.
POST /v1/subscriptions/wallet-transactions
Create subscription for wallet transactions.
{
"data": {
"type": "subscriptions",
"attributes": {
"wallet_addresses": ["0x...", "0x..."],
"chain_ids": ["base", "ethereum"],
"callback_url": "https://your-server/webhook"
}
}
}GET /v1/subscriptions
List all subscriptions.
GET /v1/subscriptions/{id}
Get subscription by ID.
DELETE /v1/subscriptions/{id}
Delete subscription.
POST /v1/subscriptions/{id}/enable
Enable a disabled subscription.
POST /v1/subscriptions/{id}/disable
Disable subscription (pause notifications).
PATCH /v1/subscriptions/{id}/wallets
Add/remove wallets from subscription.
PUT /v1/subscriptions/{id}/wallets
Replace all wallets in subscription.
PUT /v1/subscriptions/{id}/callback-url
Update callback URL.
PUT /v1/subscriptions/{id}/chain-ids
Update monitored chains.
GET /v1/subscriptions/{id}/wallets
List wallets in subscription.
GET /v1/subscriptions/{id}/wallets/count
Count wallets in subscription.
Webhook Payload:
- Signed with X-Signature header (RSA, verify with certificate)
- Includes X-Timestamp and X-Certificate-URL headers
- Transaction data with full interpretation
- Prices are
nullin webhooks (query transactions endpoint for prices)
Limits:
- Dev key: 1 subscription, 5 wallets max
- Production: Contact api@zerion.io for whitelist
---
API Key Access
Get a free API key instantly — no credit card required:
1. Go to dashboard.zerion.io 2. Sign up with email or connect wallet 3. Click "Create API Key" — key starts with zk_... 4. Copy and use immediately
export ZERION_API_KEY="zk_your_api_key"
curl "https://api.zerion.io/v1/wallets/0x.../portfolio" \
-H "Authorization: Basic $(echo -n $ZERION_API_KEY: | base64)"Rate Limits
| Plan | Requests/Second | Requests/Day | Price |
|---|---|---|---|
| Free | 10 | 10,000 | $0 |
| Growth | 50 | 100,000 | $99/mo |
| Scale | 200 | 1,000,000 | $499/mo |
| Enterprise | Custom | Custom | Contact |
x402 has no rate limits — pay per request ($0.01 USDC each).
---
x402 Access (Recommended for Agents)
x402 allows agents to pay per request without API keys. Payment is $0.01 USDC on Base.
// Using x402 HTTP flow
const response = await fetch('https://api.zerion.io/v1/wallets/0x.../portfolio', {
headers: {
'X-402-Payment': signedPaymentHeader // ERC-3009 signature
}
});With zerion-cli:
zerion-cli wallet portfolio 0x... --x402---
Testnet Support
Add X-Env: testnet header to get testnet data:
curl "https://api.zerion.io/v1/wallets/0x.../portfolio" \
-H "Authorization: Basic ..." \
-H "X-Env: testnet"---
Integration with Bankr
Example: PnL Guardian
Monitor positions and auto-set stop-losses:
#!/bin/bash
# Research with Zerion
positions=$(zerion-cli wallet positions $WALLET --json)
# Find volatile tokens on Base
risky=$(echo $positions | jq '[.data[] | select(.relationships.chain.data.id == "base") | select(.attributes.value > 500)]')
# Execute with Bankr
for token in $(echo $risky | jq -r '.[].attributes.fungible_info.symbol'); do
bankr "set stop loss on $token at -20%"
doneExample: Whale Copy Trading
Watch a whale wallet and mirror trades:
// Webhook handler
app.post('/webhook/zerion', async (req, res) => {
const { type, data } = req.body;
if (type === 'transaction' && data.operation_type === 'trade') {
const { transfers } = data;
const bought = transfers.find(t => t.direction === 'in');
if (bought && bought.value > 1000) {
// Mirror the trade via Bankr
await bankr(`buy $100 of ${bought.fungible_info.symbol}`);
}
}
});Example: Best Swap Route
Get quotes from Zerion, execute via Bankr:
// Get swap quote from Zerion
const quote = await zerion.get('/v1/swap/offers', {
params: { from: 'USDC', to: 'ETH', amount: '1000' }
});
const bestRate = quote.data[0];
console.log(`Best rate: ${bestRate.rate} from ${bestRate.provider}`);
// Execute via Bankr
await bankr(`swap $1000 USDC to ETH on base`);---
Supported Chains
All 41+ chains including:
| Chain | Chain ID |
|---|---|
| Ethereum | ethereum |
| Base | base |
| Arbitrum | arbitrum |
| Optimism | optimism |
| Polygon | polygon |
| Solana | solana |
| zkSync Era | zksync-era |
| Linea | linea |
| Scroll | scroll |
| Blast | blast |
| Zora | zora |
| Degen | degen |
| Berachain | berachain |
| Monad | monad |
| Abstract | abstract |
| ... | +26 more |
Full list: https://developers.zerion.io/reference/supported-blockchains
---
MCP Server
Connect Claude, Cursor, or any MCP client:
{
"mcpServers": {
"zerion": {
"command": "npx",
"args": ["zerion-mcp-server"],
"env": {
"ZERION_API_KEY": "zk_..."
}
}
}
}---
Error Handling
| Code | Description |
|---|---|
| 200 | Success |
| 202 | Accepted - data being prepared, retry shortly |
| 400 | Bad Request - check query params |
| 401 | Unauthorized - invalid API key |
| 402 | Payment Required - x402 payment needed |
| 404 | Not Found - invalid address or resource |
| 429 | Rate Limited - back off with exponential backoff |
| 500 | Server Error - retry with backoff |
Note: 202 responses mean data is being indexed. Retry every few seconds until 200. Stop after 2 minutes if still 202.
---
Resources
- Get API Key: https://dashboard.zerion.io (free, instant, no credit card)
- API Documentation: https://developers.zerion.io
- Supported Chains: https://developers.zerion.io/reference/supported-blockchains
- CLI Repository: https://github.com/zeriontech/zerion-cli
- MCP Server: https://github.com/zeriontech/zerion-mcp-server
- x402 Protocol: https://developers.zerion.io/reference/x402
- Zerion for Agents: https://zerion.io/agents
- Spam Filtering: https://developers.zerion.io/reference/token-spam-filtering
- FAQs: https://developers.zerion.io/reference/faqs
Zerion API Reference
Complete endpoint reference for the Zerion API.
Authentication
API Key (Basic Auth)
Authorization: Basic {base64(API_KEY:)}Example:
curl "https://api.zerion.io/v1/wallets/0x.../portfolio" \
-H "Authorization: Basic $(echo -n $ZERION_API_KEY: | base64)"x402 Payment
X-402-Payment: {signed_erc3009_authorization}Testnet Access
X-Env: testnet---
Wallet Endpoints
GET /v1/wallets/{address}/portfolio
Returns aggregated portfolio value.
Parameters:
| Param | Type | Description |
|---|---|---|
currency | string | usd (default), eur, btc, eth |
filter[positions] | string | only_simple, only_defi, no_filter |
Response:
{
"data": {
"type": "portfolio",
"id": "0x...",
"attributes": {
"positions_distribution_by_type": {
"wallet": 44469.60,
"deposited": 1234.56,
"borrowed": 0,
"locked": 0,
"staked": 5678.90
},
"positions_distribution_by_chain": {
"base": 27495.06,
"ethereum": 6216.25
},
"total": {
"positions": 51383.06
},
"changes": {
"absolute_1d": 305.86,
"percent_1d": 0.69
}
}
}
}GET /v1/wallets/{address}/positions
Returns all fungible positions.
Parameters:
| Param | Type | Description |
|---|---|---|
filter[positions] | string | only_simple, only_defi, no_filter |
filter[chain_ids] | string | Comma-separated chain IDs |
filter[trash] | string | only_non_trash, only_trash, no_filter |
sort | string | value, -value |
page[size] | integer | Results per page (max 100) |
Response (single position):
{
"type": "positions",
"id": "...",
"attributes": {
"position_type": "wallet",
"quantity": {
"int": "6485257514999279000",
"decimals": 18,
"float": 6.485257514999279,
"numeric": "6.485257514999279"
},
"value": 13968.45,
"price": 2153.67,
"group_id": "abc123...",
"fungible_info": {
"name": "Ethereum",
"symbol": "ETH",
"icon": { "url": "https://cdn.zerion.io/eth.png" },
"flags": { "verified": true },
"implementations": [
{ "chain_id": "ethereum", "address": "", "decimals": 18 },
{ "chain_id": "base", "address": "", "decimals": 18 }
]
}
},
"relationships": {
"chain": { "data": { "type": "chains", "id": "base" } },
"dapp": { "data": { "type": "dapps", "id": "uniswap-v3" } }
}
}Note on LP Positions: Liquidity pool positions return multiple entries with the same group_id. Group by this field to display all tokens in a pool together.
GET /v1/wallets/{address}/transactions
Returns interpreted transaction history.
Parameters:
| Param | Type | Description |
|---|---|---|
filter[chain_ids] | string | Comma-separated chain IDs |
filter[asset_types] | string | fungible, nft |
filter[trash] | string | only_non_trash, no_filter |
page[size] | integer | Results per page |
page[after] | string | Cursor for pagination |
Response (single transaction):
{
"type": "transactions",
"id": "...",
"attributes": {
"operation_type": "trade",
"hash": "0x...",
"mined_at": "2024-03-21T15:22:35Z",
"mined_at_block": 12345678,
"status": "confirmed",
"nonce": 42,
"sent_from": "0x...",
"sent_to": "0x...",
"fee": {
"fungible_info": { "symbol": "ETH" },
"quantity": { "float": 0.001234 },
"value": 2.65
},
"transfers": [
{
"direction": "out",
"fungible_info": { "symbol": "USDC" },
"quantity": { "float": 1000 },
"value": 1000,
"sender": "0x...",
"recipient": "0x..."
},
{
"direction": "in",
"fungible_info": { "symbol": "ETH" },
"quantity": { "float": 0.45 },
"value": 970
}
],
"approvals": [],
"flags": { "is_trash": false },
"application_metadata": {
"contract_address": "0x...",
"method": { "id": "0x...", "name": "swap" }
}
},
"relationships": {
"chain": { "data": { "type": "chains", "id": "base" } },
"dapp": { "data": { "type": "dapps", "id": "uniswap-v3" } }
}
}Operation Types:
trade- Token swapsend- Outgoing transferreceive- Incoming transferapprove- Token approvalstake- Staking depositunstake- Staking withdrawalborrow- Lending borrowrepay- Lending repaymentbridge- Cross-chain transfermint- Token/NFT mintburn- Token burnbid- Auction bidexecute- Contract execution
GET /v1/wallets/{address}/pnl
Returns Profit & Loss (FIFO method).
Parameters:
| Param | Type | Description |
|---|---|---|
currency | string | usd (default) |
filter[chain_ids] | string | Comma-separated chain IDs |
Response:
{
"data": {
"type": "wallet_pnl",
"id": "0x...",
"attributes": {
"total_gain": -15076.15,
"realized_gain": 45328.28,
"unrealized_gain": -60404.44,
"relative_total_gain_percentage": -5.65,
"relative_realized_gain_percentage": 28.08,
"relative_unrealized_gain_percentage": -57.36,
"total_fee": 681.81,
"total_invested": 266672.34,
"realized_cost_basis": 161370.01,
"net_invested": 105302.33,
"received_external": 128217.01,
"sent_external": 67415.77,
"sent_for_nfts": 4333.36,
"received_for_nfts": 423.01
}
}
}GET /v1/wallets/{address}/chart
Returns portfolio balance chart.
Parameters:
| Param | Type | Description |
|---|---|---|
currency | string | usd |
filter[chain_ids] | string | Filter by chains |
period | string | Chart time period |
GET /v1/wallets/{address}/nft-portfolio
Returns NFT portfolio overview.
GET /v1/wallets/{address}/nft-positions
Returns NFT positions held.
GET /v1/wallets/{address}/nft-collections
Returns NFT collections held.
---
Fungibles Endpoints
GET /v1/fungibles
Returns list of fungible assets.
Parameters:
| Param | Type | Description |
|---|---|---|
filter[search_query] | string | Search by name/symbol |
filter[implementation_chain_id] | string | Filter by chain |
filter[implementation_address] | string | Filter by contract |
sort | string | Sort order |
page[size] | integer | Results per page |
GET /v1/fungibles/{fungible_id}
Returns single fungible by ID.
GET /v1/fungibles/implementation/{chain}:{address}
Returns fungible by implementation (e.g., ethereum:0xa5a4...).
GET /v1/fungibles/{fungible_id}/chart
Returns price chart.
Parameters:
| Param | Type | Description |
|---|---|---|
filter[period] | string | hour, day, week, month, year, max |
---
NFT Endpoints
GET /v1/nfts
Returns list of NFTs.
GET /v1/nfts/{nft_id}
Returns single NFT with metadata.
---
DApp Endpoints
GET /v1/dapps
Returns list of DApps/protocols.
GET /v1/dapps/{dapp_id}
Returns single DApp.
---
Chain Endpoints
GET /v1/chains
Returns all supported chains.
GET /v1/chains/{chain_id}
Returns single chain.
---
Gas Prices
GET /v1/gas-prices
Returns real-time gas prices for all chains.
---
Swap Endpoints
GET /v1/swap/offers
Returns swap/bridge quotes from multiple providers.
Note: Response time 5-10 seconds due to multi-provider aggregation.
GET /v1/swap/fungibles
Returns fungibles available for bridge.
---
Subscription (Webhook) Endpoints
POST /v1/subscriptions/wallet-transactions
Create transaction subscription.
Request:
{
"data": {
"type": "subscriptions",
"attributes": {
"wallet_addresses": ["0x..."],
"chain_ids": ["base", "ethereum"],
"callback_url": "https://your-server/webhook"
}
}
}GET /v1/subscriptions
List subscriptions. Limited to 1000.
GET /v1/subscriptions/{id}
Get subscription by ID.
DELETE /v1/subscriptions/{id}
Delete subscription.
POST /v1/subscriptions/{id}/enable
Enable subscription.
POST /v1/subscriptions/{id}/disable
Disable subscription.
PATCH /v1/subscriptions/{id}/wallets
Add/remove wallets.
PUT /v1/subscriptions/{id}/wallets
Replace all wallets.
PUT /v1/subscriptions/{id}/callback-url
Update callback URL.
PUT /v1/subscriptions/{id}/chain-ids
Update chain filters.
GET /v1/subscriptions/{id}/wallets
List wallets in subscription.
GET /v1/subscriptions/{id}/wallets/count
Count wallets.
---
Rate Limits
| Plan | Requests/Second | Requests/Day |
|---|---|---|
| Free | 10 | 10,000 |
| Growth | 50 | 100,000 |
| Scale | 200 | 1,000,000 |
| Enterprise | Custom | Unlimited |
| x402 | Unlimited | Pay per request |
---
Error Codes
| Code | Description |
|---|---|
| 200 | Success |
| 202 | Accepted - data being prepared, retry |
| 400 | Bad Request - invalid parameters |
| 401 | Unauthorized - invalid API key |
| 402 | Payment Required - x402 payment needed |
| 404 | Not Found - invalid address/resource |
| 429 | Rate Limited - back off |
| 500 | Server Error - retry |
202 Handling: Retry every 2-5 seconds until 200. Stop after 2 minutes.
Zerion + Bankr Integration Guide
Overview
Zerion provides the research layer (portfolio data, positions, PnL), while Bankr provides the execution layer (trading, stop-losses, DCA).
Architecture
┌─────────────────────────────────────────────────────────────┐
│ Your Agent │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Zerion │ Research │ Bankr │ Execute │
│ │ Skill │ ──────────▶ │ Skill │ ──────────▶ │
│ └─────────────┘ └─────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ • Portfolio data • Swaps │
│ • Positions • Stop-loss │
│ • PnL tracking • Take-profit │
│ • Transaction history • DCA orders │
│ • Webhooks • Limit orders │
│ │
└─────────────────────────────────────────────────────────────┘Use Cases
1. Portfolio Protection (PnL Guardian)
Monitor positions and auto-set protective orders:
#!/bin/bash
# Fetch positions from Zerion
POSITIONS=$(zerion-cli wallet positions $WALLET --positions simple --json)
# Find Base tokens over $500
RISKY=$(echo $POSITIONS | jq '[.data[]
| select(.relationships.chain.data.id == "base")
| select(.attributes.value > 500)
| select(.attributes.fungible_info.symbol != "ETH")
| select(.attributes.fungible_info.symbol != "USDC")
]')
# Set stop-losses via Bankr
for row in $(echo $RISKY | jq -c '.[]'); do
SYMBOL=$(echo $row | jq -r '.attributes.fungible_info.symbol')
VALUE=$(echo $row | jq -r '.attributes.value | floor')
echo "Setting stop-loss for $SYMBOL ($VALUE)"
bankr "set stop loss on $SYMBOL at -20%"
done2. PnL-Based Rebalancing
Rebalance based on performance:
# Check PnL
PNL=$(zerion-cli wallet pnl $WALLET --json)
UNREALIZED=$(echo $PNL | jq '.data.attributes.unrealized_gain')
if (( $(echo "$UNREALIZED > 5000" | bc -l) )); then
# Take some profit
bankr "sell 20% of my ETH for USDC"
elif (( $(echo "$UNREALIZED < -5000" | bc -l) )); then
# DCA more
bankr "DCA $100 into ETH daily for 7 days"
fi3. Whale Watching + Copy Trading
Mirror whale trades in real-time:
// Webhook handler for Zerion events
app.post('/webhook/zerion', async (req, res) => {
const { type, data } = req.body;
if (type !== 'transaction') return res.sendStatus(200);
if (data.operation_type !== 'trade') return res.sendStatus(200);
const bought = data.transfers.find(t => t.direction === 'in');
const sold = data.transfers.find(t => t.direction === 'out');
// Only copy if whale bought > $10k worth
if (bought && bought.value > 10000) {
const token = bought.fungible_info.symbol;
const myAmount = Math.min(bought.value * 0.01, 100); // 1% or max $100
console.log(`Whale bought ${token}, mirroring with $${myAmount}`);
await exec(`bankr "buy $${myAmount} of ${token}"`);
}
res.sendStatus(200);
});4. Smart DCA Based on Portfolio Allocation
DCA into underweight positions:
# Get current allocation
PORTFOLIO=$(zerion-cli wallet portfolio $WALLET --json)
TOTAL=$(echo $PORTFOLIO | jq '.data.attributes.total.positions')
POSITIONS=$(zerion-cli wallet positions $WALLET --positions simple --json)
# Check ETH allocation
ETH_VALUE=$(echo $POSITIONS | jq '[.data[] | select(.attributes.fungible_info.symbol == "ETH") | .attributes.value] | add')
ETH_PERCENT=$(echo "scale=2; $ETH_VALUE / $TOTAL * 100" | bc)
# Target: 50% ETH
if (( $(echo "$ETH_PERCENT < 45" | bc -l) )); then
DIFF=$(echo "scale=0; ($TOTAL * 0.50 - $ETH_VALUE) / 7" | bc)
bankr "DCA $${DIFF} into ETH daily for 7 days"
fi5. Transaction-Triggered Alerts
Set up automated responses to wallet activity:
// When receiving tokens, auto-set stop-loss
app.post('/webhook/zerion', async (req, res) => {
const { type, data } = req.body;
if (type === 'transaction' && data.operation_type === 'receive') {
for (const transfer of data.transfers) {
if (transfer.direction === 'in' && transfer.value > 500) {
const token = transfer.fungible_info.symbol;
// Skip stables
if (['USDC', 'USDT', 'DAI'].includes(token)) continue;
console.log(`Received ${token} worth $${transfer.value}`);
await exec(`bankr "set stop loss on ${token} at -15%"`);
}
}
}
res.sendStatus(200);
});CLI Cheatsheet
Zerion CLI
zerion-cli wallet portfolio <addr> # Total value
zerion-cli wallet positions <addr> # All positions
zerion-cli wallet transactions <addr> # History
zerion-cli wallet pnl <addr> # Profit/loss
zerion-cli wallet analyze <addr> # Full analysisBankr CLI
bankr "price of ETH" # Get price
bankr "my balances" # Check balances
bankr "swap $100 USDC to ETH" # Execute swap
bankr "stop loss on TOKEN at -20%" # Set stop-loss
bankr "DCA $50 into ETH daily" # Set up DCA
bankr "sell half my TOKEN" # Partial sellEnvironment Setup
# Both API keys
export ZERION_API_KEY="zk_..."
export BANKR_API_KEY="bk_..."
# Or use x402 for Zerion (no key needed)
export ZERION_X402=trueMCP Configuration
Use both skills in Claude/Cursor:
{
"mcpServers": {
"zerion": {
"command": "npx",
"args": ["zerion-mcp-server"],
"env": { "ZERION_API_KEY": "zk_..." }
},
"bankr": {
"command": "npx",
"args": ["bankr-mcp-server"],
"env": { "BANKR_API_KEY": "bk_..." }
}
}
}Best Practices
1. Research before execution: Always fetch current positions/prices before trading 2. Use webhooks for real-time: Don't poll - use Zerion webhooks for instant updates 3. Set reasonable thresholds: Avoid over-trading on small moves 4. Log everything: Keep audit trail of research → decision → execution 5. Handle errors gracefully: Both APIs can fail - implement retries
Zerion x402 Reference
Overview
x402 enables pay-per-request API access without signup or API keys. Agents pay $0.01 USDC on Base per request.
How It Works
1. Request: Agent sends GET request to Zerion API 2. 402 Response: Server returns payment requirements 3. Payment: Agent signs ERC-3009 USDC authorization 4. Retry: Agent retries with payment header 5. Data: Server validates payment, returns data
Payment Flow
Step 1: Initial Request
GET /v1/wallets/0x.../portfolio HTTP/1.1
Host: api.zerion.ioStep 2: 402 Response
HTTP/1.1 402 Payment Required
Content-Type: application/json
{
"x402": {
"version": "1.0",
"payment": {
"chain": "base",
"token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"amount": "10000",
"recipient": "0x...",
"validAfter": 0,
"validBefore": 1711036800,
"nonce": "0x..."
}
}
}Step 3: Sign Payment (ERC-3009)
import { signTypedData } from 'viem/accounts';
const signature = await signTypedData({
domain: {
name: 'USD Coin',
version: '2',
chainId: 8453, // Base
verifyingContract: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'
},
types: {
TransferWithAuthorization: [
{ name: 'from', type: 'address' },
{ name: 'to', type: 'address' },
{ name: 'value', type: 'uint256' },
{ name: 'validAfter', type: 'uint256' },
{ name: 'validBefore', type: 'uint256' },
{ name: 'nonce', type: 'bytes32' }
]
},
primaryType: 'TransferWithAuthorization',
message: paymentDetails
});Step 4: Retry with Payment
GET /v1/wallets/0x.../portfolio HTTP/1.1
Host: api.zerion.io
X-402-Payment: {"signature":"0x...","payment":{...}}Step 5: Success Response
HTTP/1.1 200 OK
Content-Type: application/json
X-402-Receipt: {"txHash":"0x...","amount":"10000"}
{
"data": {
"type": "portfolio",
...
}
}Using zerion-cli with x402
# Single request
zerion-cli wallet portfolio 0x... --x402
# Set as default
export ZERION_X402=true
zerion-cli wallet portfolio 0x...TypeScript SDK
import { createZerionX402Client } from '@zerion/x402';
const client = await createZerionX402Client({
network: 'base',
privateKey: process.env.PRIVATE_KEY
});
const portfolio = await client.fetch('/v1/wallets/0x.../portfolio');Pricing
| Request Type | Cost |
|---|---|
| Any API call | $0.01 USDC |
Payment is per successful request. Failed requests (4xx, 5xx) are not charged.
Supported Chains for Payment
Currently Base only. Payment happens on Base, but you can query data from all 41+ chains.
Error Handling
try {
const data = await client.fetch('/v1/wallets/0x.../portfolio');
} catch (error) {
if (error.code === 'INSUFFICIENT_BALANCE') {
// Agent needs more USDC on Base
}
if (error.code === 'PAYMENT_FAILED') {
// Transaction failed - retry
}
}Requirements
- Wallet with USDC on Base
- Private key access for signing
- Base RPC endpoint (for payment submission)
Resources
- x402 Protocol Spec: https://x402.org
- Zerion x402 Docs: https://developers.zerion.io/reference/x402
- ERC-3009 Standard: https://eips.ethereum.org/EIPS/eip-3009
Related skills
FAQ
How many chains does Zerion cover?
Interpreted, enriched wallet data across 41+ chains including Ethereum, Base, Arbitrum, Optimism, Polygon and Solana.
Do I need an account?
No. You can pay $0.01 USDC per request via x402 with no API key, or get a free API key for higher rate limits.