EVM Wallet Scraper — Balances, Tokens, Transactions, Risk Flags
Pricing
from $3.50 / 1,000 address analyzeds
EVM Wallet Scraper — Balances, Tokens, Transactions, Risk Flags
Wallet & contract intelligence for Ethereum, Base, Arbitrum, Optimism, Polygon, Gnosis, ZKsync, Scroll and more: balances, ERC-20 holdings with USD value (spam filtered), recent transactions with counterparties, token transfers, internal txs, NFTs, balance history, risk flags. ENS names accepted.
Pricing
from $3.50 / 1,000 address analyzeds
Rating
0.0
(0)
Developer
Samat Makatov
Maintained by CommunityActor stats
1
Bookmarked
1
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Give it wallet or contract addresses (or ENS names) and get one clean JSON per address: native balance and USD value, ERC-20 holdings with prices (spam filtered), activity counters, recent transactions with direction and labelled counterparties, token transfers, internal transactions, NFTs, 90-day balance history and a deterministic list of risk flags. Works on Ethereum, Base, Arbitrum, OP Mainnet, Polygon, Gnosis, ZKsync, Scroll, Celo, Unichain, Soneium, Mode, Ink, World Chain and two testnets via the public Blockscout API. No API key, no proxy, no browser — and polite to the explorer: at most 2 requests in flight and 5 per second.
Built for AI agents and back-office automations that must answer "who is this address and what does it do?" in one call.
Use cases
- Counterparty due diligence — before paying or accepting an invoice in crypto: balance, age, activity, explorer scam flag, exchange labels, proxy/EIP-7702 delegation.
- KYT-lite monitoring — start a daily run on your treasury or customer wallets (from your code, or a schedule whose input you update) with
sinceDate= yesterday to get only new transactions and token transfers. - Payment reconciliation —
includeTokenTransfers+tokenFilter= USDC contract: "did wallet X receive ≥ 500 USDC since Monday?" - Portfolio snapshot —
totalPortfolioUsd, top tokens by value, spam removed, for a batch of wallets in one run (see Limits & FAQ → Capacity for how many fit). - Lead scoring / airdrop eligibility — flag whales, fresh wallets, dormant wallets, NFT collections held.
- Contract intel — verified? proxy type, implementations, creator and creation tx, who calls it most (top counterparties).
Input
| Field | Type | Default | Notes |
|---|---|---|---|
addresses | string[] | — (required) | 0x addresses or ENS names (vitalik.eth). Each address is analysed and charged once: a repeat, an ENS name together with its 0x address, or the same address in another letter case is skipped and listed in SUMMARY.duplicates. Invalid values are listed in SUMMARY.errors (not charged). |
chain | enum | base | One key from Reference → Chains (ethereum, not eth): the platform refuses a value outside that list before the run starts. |
recentTxLimit | int 0–200 | 10 | Recent confirmed native transactions per address (pages of 50). Mempool transactions are skipped and counted in recentWindow.pendingTxs. |
txDirection | all / from / to | all | from = signed by the address (outgoing), to = incoming. |
sinceDate | date | — | Keep only txs / token transfers / internal txs on or after this date (YYYY-MM-DD or ISO 8601, UTC). Paging stops early → cheaper runs. |
untilDate | date | — | Upper bound (UTC); a bare date keeps that whole day. Lists are read newest first, so a date far in the past on a busy wallet may not be reached — see Limits & FAQ. |
includeTokens | bool | true | ERC-20 balances with USD value, sorted by value. Auto-skipped for large contracts (tokensSkipped:true). |
tokensLimit | int 1–500 | 50 | Max tokens kept per address. |
minTokenUsd | number | 0 | Drop positions worth less than this. |
hideSpamTokens | bool | true | Drop explorer-flagged scams and unpriced airdrop-lure tokens (URLs, "claim", "visit"…). Count in spamTokenCount. |
includeTokenTransfers | bool | false | Recent ERC-20/721/1155 transfers with direction, counterparty, USD value, likelySpam. |
tokenTransfersLimit | int 0–200 | 25 | |
tokenTransferType | all / ERC-20 / ERC-721 / ERC-1155 | all | |
tokenFilter | string[] | [] | Only transfers of these token contracts. |
includeInternalTransactions | bool | false | Value-carrying internal calls (DEX payouts, bridge deliveries). |
internalTxLimit | int 0–200 | 25 | |
includeNfts | bool | false | NFT collections held (first 50) with counts and sample image. |
includeBalanceHistory | bool | false | Daily native balance, last ~90 days (only days with changes). |
counterpartiesLimit | int 0–50 | 10 | Size of topCounterparties (ranked by interactions within the fetched transactions). |
fields | string[] | [] | Keep only these top-level fields, in this order (address, chain, found, fetchedAt always kept). Letter case and snake_case do not matter; unknown names are left out with a note in the status and SUMMARY.notes; a list with no output field fails the run with the valid names. |
requestDelayMs | int 0–5000 | 200 | Minimum gap between two explorer requests (at most 2 in flight). Values below 200 are raised to 200 — Blockscout allows 300 requests per minute per IP. |
All original inputs (addresses, chain, recentTxLimit, includeTokens) keep their meaning.
Reference
Chains
chain | Network | Chain ID | Native | Explorer |
|---|---|---|---|---|
ethereum | Ethereum mainnet | 1 | ETH | eth.blockscout.com |
base | Base | 8453 | ETH | base.blockscout.com |
arbitrum | Arbitrum One | 42161 | ETH | arbitrum.blockscout.com |
optimism | OP Mainnet | 10 | ETH | explorer.optimism.io |
polygon | Polygon PoS | 137 | POL | polygon.blockscout.com |
gnosis | Gnosis Chain | 100 | xDAI | gnosis.blockscout.com |
zksync | ZKsync Era | 324 | ETH | zksync.blockscout.com |
scroll | Scroll | 534352 | ETH | scroll.blockscout.com |
celo | Celo | 42220 | CELO | celo.blockscout.com |
unichain | Unichain | 130 | ETH | unichain.blockscout.com |
soneium | Soneium | 1868 | ETH | soneium.blockscout.com |
mode | Mode | 34443 | ETH | explorer.mode.network |
ink | Ink | 57073 | ETH | explorer.inkonchain.com |
worldchain | World Chain | 480 | ETH | worldchain-mainnet.explorer.alchemy.com |
sepolia | Ethereum Sepolia (testnet) | 11155111 | ETH | eth-sepolia.blockscout.com |
base-sepolia | Base Sepolia (testnet) | 84532 | ETH | base-sepolia.blockscout.com |
Other Blockscout instances (e.g. Zora, Linea, Mantle) did not answer the public v2 API at the time of writing and are therefore not offered.
Flags (flags[])
| Flag | Meaning |
|---|---|
not_found_on_chain | Address unknown to the explorer on this chain. Such addresses are not dataset items (nothing to analyze, not charged) — they are listed in SUMMARY.notFound. |
flagged_scam_by_explorer | Blockscout is_scam / non-ok reputation. |
unverified_contract | Contract without verified source code. |
proxy_contract | Upgradeable proxy (see proxyType, implementations). |
eoa_with_delegated_code_eip7702 | Wallet that delegated code via EIP-7702 (smart-account features). |
no_outgoing_transactions / fresh_wallet_under_5_txs | Very young wallet. |
inactive_over_180d / dormant_over_1y | No recent activity (wallets only). |
near_zero_balance / whale_over_1m_usd | Portfolio size (native + tokens, USD). |
high_failed_tx_share | ≥ 30 % of the fetched confirmed transactions failed (wallets only). |
labeled_exchange | Explorer tag names a CEX. |
labeled_high_risk | Tag mentions sanctions/OFAC/hack/exploit/phishing/drainer. |
Flags are a triage checklist, not a verdict.
Frequently used token contracts
| Token | Base | Ethereum |
|---|---|---|
| USDC | 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913 | 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 |
| USDT | — | 0xdAC17F958D2ee523a2206206994597C13D831ec7 |
| WETH | 0x4200000000000000000000000000000000000006 | 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 |
Examples
1. Vet a counterparty before paying (Base)
{ "addresses": ["0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"], "chain": "base", "recentTxLimit": 25, "includeTokens": true, "counterpartiesLimit": 10 }
2. Daily monitor: what happened since yesterday on our treasury wallets (Ethereum)
{ "addresses": ["treasury.mycompany.eth", "0x…"], "chain": "ethereum", "recentTxLimit": 200, "sinceDate": "2026-09-12", "includeTokenTransfers": true, "tokenTransfersLimit": 200, "includeInternalTransactions": true, "includeTokens": false }
3. Did the customer pay in USDC? (Base)
{ "addresses": ["0xCustomerWallet…"], "chain": "base", "recentTxLimit": 0, "includeTokens": false, "includeTokenTransfers": true, "tokenTransferType": "ERC-20", "tokenFilter": ["0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"], "sinceDate": "2026-09-08" }
4. Portfolio snapshot for 100 wallets, only positions ≥ $50, compact output
{ "addresses": ["0x…", "0x…"], "chain": "arbitrum", "recentTxLimit": 0, "tokensLimit": 100, "minTokenUsd": 50, "fields": ["nativeBalance", "nativeUsd", "totalTokenUsd", "totalPortfolioUsd", "tokens", "flags"] }
5. Contract intel: who calls this contract and is it upgradeable?
{ "addresses": ["0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"], "chain": "base", "recentTxLimit": 100, "txDirection": "to", "includeTokens": false, "counterpartiesLimit": 25 }
Output
One item per input address (trimmed real example, Base):
{"query": "vitalik.eth","address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045","chain": "base", "chainId": 8453, "nativeSymbol": "ETH","explorerUrl": "https://base.blockscout.com/address/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045","found": true, "degraded": false,"isContract": true, "isVerifiedContract": true, "proxyType": "eip7702","implementations": [{ "address": "0x5A7FC11397E9a8AD41BF10bf13F22B0a63f96f6d", "name": "AmbireAccount7702" }],"ensName": "vitalik.eth", "tags": [], "isScam": false, "reputation": "ok","nativeBalance": 3.1287, "nativeUsd": 7896.08, "nativePriceUsd": 2523.71,"txCount": 51, "txCountIsLowerBound": true, "tokenTransferCount": 51, "internalTxCount": 51,"tokenCount": 2575, "tokenCountShown": 50, "spamTokenCount": 89, "tokensSkipped": false, "tokenListPartial": false,"totalTokenUsd": 19145.92, "totalPortfolioUsd": 27042.0,"tokens": [{ "symbol": "TRUE", "name": "True", "contract": "0x21CF…", "decimals": 18, "balance": 1066680, "priceUsd": 0.0139, "usdValue": 14802.9, "holdersCount": 24836, "reputation": "ok" }],"lastSeen": "2026-08-10T13:00:47.000000Z","recentWindow": { "txs": 10, "pendingTxs": 0, "direction": "all", "sentNative": 0.0, "receivedNative": 0.0, "feesNative": 0.00002, "failedTxs": 0, "uniqueCounterparties": 1 },"recentTransactions": [{ "hash": "0x1234…", "timestamp": "2026-08-10T13:00:47.000000Z", "direction": "out", "counterparty": "0x…", "counterpartyLabel": "PublicResolver", "valueNative": 0, "method": "setContenthash", "status": "ok", "feeNative": 0.0000277 }],"tokenTransfers": [], "internalTransactions": [], "nftCollections": [], "balanceHistory": [],"topCounterparties": [{ "address": "0x…", "label": "Deterministic Deployer", "txCount": 13, "sentNative": 0, "receivedNative": 0, "lastSeen": "2026-07-19T20:43:47.000000Z" }],"flags": ["eoa_with_delegated_code_eip7702"],"warnings": [],"source": "blockscout", "sourceUrl": "https://base.blockscout.com/api/v2/addresses/0xd8dA…", "fetchedAt": "2026-09-12T23:32:44.398Z"}
| Field | Description |
|---|---|
query, address, ensName | Input value, resolved checksum address, ENS primary name if any. One item per address and chain. |
chain, chainId, nativeSymbol, explorerUrl | Chain key, EVM chain id, native coin symbol and the address page on the explorer. |
degraded | true when the explorer's address endpoint was unavailable and the item was rebuilt from its other endpoints (see Limits & FAQ → Explorer outages). Facts that could not be read are null, and warnings[] says which. |
found | Always true on dataset items. Unknown addresses, ENS names that resolve to nothing, invalid inputs, failed lookups and repeated addresses are not items (not charged): the SUMMARY record lists them under notFound, errors (with the reason) and duplicates, with their counts, and the status message sums it up. The run fails only if every address failed. |
isContract, isVerifiedContract, contractName, proxyType, implementations, creator, creationTxHash | Contract facts. proxyType: "eip7702" = wallet with delegated code. |
tags, isScam, reputation | Explorer labels (public tags, Kleros/OLI metadata) and scam status. |
nativeBalance, nativeUsd, nativePriceUsd | Native coin balance and USD value. |
txCount, txCountIsLowerBound | Transactions signed by the address. Blockscout computes counters lazily; when it returns 0 for an active address the actor reports 51 with txCountIsLowerBound:true ("50+"). |
tokenTransferCount, internalTxCount, gasUsed | Activity counters. |
tokens[], tokenCount, tokenCountShown, spamTokenCount, totalTokenUsd, totalPortfolioUsd | ERC-20 holdings. tokenListPartial:true (and tokenCountIsLowerBound:true) when the full list timed out and the top-N-by-value fallback was used. |
firstSeen, lastSeen | lastSeen = newest block time across the fetched confirmed transactions, token transfers and internal transactions; firstSeen comes from the transactions only and only when the whole history fits. |
recentWindow | Summary of fetched transactions: counts, mempool transactions skipped (pendingTxs), native sent/received, fees, failures, unique counterparties. |
recentTransactions[] | Confirmed transactions: direction in/out/self, counterparty + counterpartyLabel, value, method, status, fee, createdContract. |
tokenTransfers[] | Token, amount, USD value, direction, counterparty, likelySpam. |
internalTransactions[], nftCollections[], nftCollectionCount, balanceHistory[] | Optional extras (nftCollectionCount is null when includeNfts is off). |
topCounterparties[] | Most frequent counterparties with labels and flows. |
flags[] | See Reference. |
source, sourceUrl, fetchedAt | blockscout, the explorer API record of the address, and when it was read (UTC). |
warnings[] | Sub-requests that failed/timed out for this address, which fallback filled in for them (item is still delivered), and lists whose sinceDate/untilDate window the page cap did not reach. |
Use it from code / agents
curl -X POST "https://api.apify.com/v2/acts/yadroo~wallet-intel/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H 'Content-Type: application/json' \-d '{"addresses":["vitalik.eth"],"chain":"base","recentTxLimit":25}'
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('yadroo/wallet-intel').call({ addresses: ['vitalik.eth'], chain: 'base' });const { items } = await client.dataset(run.defaultDatasetId).listItems();
from apify_client import ApifyClientclient = ApifyClient(token)run = client.actor("yadroo/wallet-intel").call(run_input={"addresses": ["vitalik.eth"], "chain": "base"})items = client.dataset(run["defaultDatasetId"]).list_items().items
MCP: add https://mcp.apify.com to Claude / Cursor / any MCP client and call the yadroo/wallet-intel tool with the same JSON input.
Pricing
Pay per event: $0.001 per run start + $0.005 per analyzed address. Bronze −10 %, Silver −20 %, Gold and above −30 % on the address price; the start event is the same on every plan; platform usage is included. Only analyzed addresses are charged — invalid inputs, unknown addresses, failed lookups and repeated addresses are free and listed in SUMMARY. A typical due-diligence run on 10 addresses costs $0.051; a daily monitor over 100 wallets costs $0.501 per day. Batch addresses to amortize the start fee.
Your maximum cost per run is respected: the run stops before the address that would cross it and says so ("Stopped at your spending limit: N rows delivered"); addresses it did not reach are listed in SUMMARY.notProcessedInputs.
Limits & FAQ
- Rate limits — Blockscout publishes 300 requests per minute per IP for its public API. The actor keeps at most 2 requests in flight per explorer and starts one at most every
requestDelayMs(≥ 200 ms), however many lookups an address needs. An HTTP 429 pauses all requests to that explorer for itsRetry-After(or an exponential backoff) and is never answered with extra fallback requests. If the explorer keeps answering 429 (6 in a row) or asks to wait more than 2 minutes, the run stops cleanly: addresses already saved stay saved, the rest are listed inSUMMARY.notProcessedInputs, and the status says "Stopped early: … rate limit" — start them again later. The actor runs without a proxy and does not rotate IPs. - Freshness — live explorer data (seconds behind the chain). Prices are the explorer's (CoinGecko-backed), refreshed every few minutes.
- Huge wallets/contracts — full token lists of whales can time out; the actor falls back to a paginated, value-sorted list (
tokenListPartial:true). Token balances are skipped for non-EOA contracts (tokensSkipped:true) because router/pool balance lists are enormous. - Pending transactions — the explorer lists mempool transactions before the confirmed ones, and a busy wallet (an exchange hot wallet) can have dozens of them at any moment. They have no block time, so they are skipped:
recentTransactionsholdsrecentTxLimitconfirmed transactions, andrecentWindow.pendingTxstells you how many mempool entries were passed over while collecting them. On the busiest contracts (USDT on Ethereum had 150 at once) the mempool entries can fill every page the limit reads; the item'swarningsthen say so instead of returning a silently empty list. - Counters — Blockscout computes some counters lazily; see
txCountIsLowerBound. - Date windows — the explorer lists transactions newest first, and the actor reads at most
limit / 50 + 2pages per list (4 pages for 100). WithuntilDatefar in the past on a busy wallet (an exchange hot wallet makes hundreds of transactions an hour) those pages may all be newer thanuntilDate: the list is then empty and the item'swarningssay the window was not reached — it does not mean "no activity". MoveuntilDatecloser to today, or usesinceDatealone. - Capacity — the default run timeout is 900 s, and the actor keeps the explorer's pace (≤ 5 requests per second, ≤ 2 in flight). Measured on 02.10.2026 on Ethereum: 150 addresses with the default settings took 6 min (2.4 s and about 5 requests per address; 2 s with
includeTokens: false), so about 300 addresses fit in one run. Each extra list (token transfers, internal transactions, NFTs, balance history, or 200 transactions = 4 pages) adds requests, and a whale whose token list is slow can take up to a minute. Addresses that do not fit are listed inSUMMARY.notProcessedInputs— split larger batches across runs or raise the timeout. - Timeout — a run near its timeout stops starting new addresses, keeps every address it saved and ends SUCCEEDED with "Stopped before the run timeout"; the addresses it did not reach are in
SUMMARY.notProcessedInputs. - Explorer outages — a single Blockscout instance can degrade on its own (on 28.09.2026 the Base instance answered
500/timeout on/addresses/{hash}for hours while its other endpoints worked). The address is then not lost: the actor rebuilds the item from the search, stats, balance-history and v1 balance endpoints and marks itdegraded: true. Such an item carries balance, USD value, contract/verification status, name, ENS and labels; transaction lists, token balances and counters can be empty, the balance can be up to a day old, and every gap is named inwarnings[]. When nothing at all can be read, the address counts as failed (not an item, not charged). - Errors — network/explorer failures on sub-requests never drop an address: the item is delivered with
warnings[](except while the explorer rate-limits the run — that address is then not saved and is listed with the rest, see Rate limits). Invalid inputs, addresses unknown to the explorer and lookups that fail entirely are not items and are not charged — they are listed inSUMMARY(errors,notFound) and the status message; the run fails only if every address failed. Invalid chains, dates orfieldslists fail the run immediately with a message that says what to change (malformed dates are refused by Apify before the run starts). - Roadmap — ERC-20 approval/allowance audit, per-token PnL, more Blockscout chains as they expose the v2 API.
Made by Yadroo. Siblings: base-token-intel · ens-resolver · dexscreener-tokens · bitcoin-mempool · sanctions-screen · domain-intel