EVM Wallet Scraper — Balances, Tokens, Transactions, Risk Flags avatar

EVM Wallet Scraper — Balances, Tokens, Transactions, Risk Flags

Pricing

from $3.50 / 1,000 address analyzeds

Go to Apify Store
EVM Wallet Scraper — Balances, Tokens, Transactions, Risk Flags

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

Samat Makatov

Maintained by Community

Actor stats

1

Bookmarked

1

Total users

1

Monthly active users

2 days ago

Last modified

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

FieldTypeDefaultNotes
addressesstring[]— (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).
chainenumbaseOne key from Reference → Chains (ethereum, not eth): the platform refuses a value outside that list before the run starts.
recentTxLimitint 0–20010Recent confirmed native transactions per address (pages of 50). Mempool transactions are skipped and counted in recentWindow.pendingTxs.
txDirectionall / from / toallfrom = signed by the address (outgoing), to = incoming.
sinceDatedate—Keep only txs / token transfers / internal txs on or after this date (YYYY-MM-DD or ISO 8601, UTC). Paging stops early → cheaper runs.
untilDatedate—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.
includeTokensbooltrueERC-20 balances with USD value, sorted by value. Auto-skipped for large contracts (tokensSkipped:true).
tokensLimitint 1–50050Max tokens kept per address.
minTokenUsdnumber0Drop positions worth less than this.
hideSpamTokensbooltrueDrop explorer-flagged scams and unpriced airdrop-lure tokens (URLs, "claim", "visit"…). Count in spamTokenCount.
includeTokenTransfersboolfalseRecent ERC-20/721/1155 transfers with direction, counterparty, USD value, likelySpam.
tokenTransfersLimitint 0–20025
tokenTransferTypeall / ERC-20 / ERC-721 / ERC-1155all
tokenFilterstring[][]Only transfers of these token contracts.
includeInternalTransactionsboolfalseValue-carrying internal calls (DEX payouts, bridge deliveries).
internalTxLimitint 0–20025
includeNftsboolfalseNFT collections held (first 50) with counts and sample image.
includeBalanceHistoryboolfalseDaily native balance, last ~90 days (only days with changes).
counterpartiesLimitint 0–5010Size of topCounterparties (ranked by interactions within the fetched transactions).
fieldsstring[][]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.
requestDelayMsint 0–5000200Minimum 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

chainNetworkChain IDNativeExplorer
ethereumEthereum mainnet1ETHeth.blockscout.com
baseBase8453ETHbase.blockscout.com
arbitrumArbitrum One42161ETHarbitrum.blockscout.com
optimismOP Mainnet10ETHexplorer.optimism.io
polygonPolygon PoS137POLpolygon.blockscout.com
gnosisGnosis Chain100xDAIgnosis.blockscout.com
zksyncZKsync Era324ETHzksync.blockscout.com
scrollScroll534352ETHscroll.blockscout.com
celoCelo42220CELOcelo.blockscout.com
unichainUnichain130ETHunichain.blockscout.com
soneiumSoneium1868ETHsoneium.blockscout.com
modeMode34443ETHexplorer.mode.network
inkInk57073ETHexplorer.inkonchain.com
worldchainWorld Chain480ETHworldchain-mainnet.explorer.alchemy.com
sepoliaEthereum Sepolia (testnet)11155111ETHeth-sepolia.blockscout.com
base-sepoliaBase Sepolia (testnet)84532ETHbase-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[])

FlagMeaning
not_found_on_chainAddress 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_explorerBlockscout is_scam / non-ok reputation.
unverified_contractContract without verified source code.
proxy_contractUpgradeable proxy (see proxyType, implementations).
eoa_with_delegated_code_eip7702Wallet that delegated code via EIP-7702 (smart-account features).
no_outgoing_transactions / fresh_wallet_under_5_txsVery young wallet.
inactive_over_180d / dormant_over_1yNo recent activity (wallets only).
near_zero_balance / whale_over_1m_usdPortfolio size (native + tokens, USD).
high_failed_tx_share≥ 30 % of the fetched confirmed transactions failed (wallets only).
labeled_exchangeExplorer tag names a CEX.
labeled_high_riskTag mentions sanctions/OFAC/hack/exploit/phishing/drainer.

Flags are a triage checklist, not a verdict.

Frequently used token contracts

TokenBaseEthereum
USDC0x833589fCD6eDb6E08f4c7C32D4f71b54bdA029130xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
USDT—0xdAC17F958D2ee523a2206206994597C13D831ec7
WETH0x42000000000000000000000000000000000000060xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2

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"
}
FieldDescription
query, address, ensNameInput value, resolved checksum address, ENS primary name if any. One item per address and chain.
chain, chainId, nativeSymbol, explorerUrlChain key, EVM chain id, native coin symbol and the address page on the explorer.
degradedtrue 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.
foundAlways 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, creationTxHashContract facts. proxyType: "eip7702" = wallet with delegated code.
tags, isScam, reputationExplorer labels (public tags, Kleros/OLI metadata) and scam status.
nativeBalance, nativeUsd, nativePriceUsdNative coin balance and USD value.
txCount, txCountIsLowerBoundTransactions 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, gasUsedActivity counters.
tokens[], tokenCount, tokenCountShown, spamTokenCount, totalTokenUsd, totalPortfolioUsdERC-20 holdings. tokenListPartial:true (and tokenCountIsLowerBound:true) when the full list timed out and the top-N-by-value fallback was used.
firstSeen, lastSeenlastSeen = 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.
recentWindowSummary 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, fetchedAtblockscout, 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 ApifyClient
client = 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 its Retry-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 in SUMMARY.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: recentTransactions holds recentTxLimit confirmed transactions, and recentWindow.pendingTxs tells 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's warnings then 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 + 2 pages per list (4 pages for 100). With untilDate far in the past on a busy wallet (an exchange hot wallet makes hundreds of transactions an hour) those pages may all be newer than untilDate: the list is then empty and the item's warnings say the window was not reached — it does not mean "no activity". Move untilDate closer to today, or use sinceDate alone.
  • 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 in SUMMARY.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 it degraded: 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 in warnings[]. 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 in SUMMARY (errors, notFound) and the status message; the run fails only if every address failed. Invalid chains, dates or fields lists 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