# Base Wallet Trading Performance Report · $0.02/report (`demiurge_ai/base-wallet-trading-report`) Actor

Give an EVM wallet address on Base and a look-back window (1-90 days) and get a purely descriptive report of what the wallet did. The report lists every ERC-20 transfer in the window and reconstructs swaps per transaction (tokens out vs tokens in). It gives per-token inflow, outflow and net change,

- **URL**: https://apify.com/demiurge_ai/base-wallet-trading-report.md
- **Developed by:** [Khải Nguyễn](https://apify.com/demiurge_ai) (community)
- **Categories:** Developer tools, Business, MCP servers
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.02 / result

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Base Wallet Trading Performance Report · $0.02/report

Give an EVM wallet address on Base and a look-back window (1-90 days) and get a purely descriptive report of what the wallet did. The report lists every ERC-20 transfer in the window and reconstructs swaps per transaction (tokens out vs tokens in). It gives per-token inflow, outflow and net change,

**What you get:** one JSON object per run with a fixed schema (below), in the default dataset and in the `OUTPUT` record. **What it costs:** `result` $0.02 per report. **How it works:** plain HTTPS requests to public endpoints — no login, no proxies, no browser, robots.txt respected. Bad input returns `{"error": "..."}` and is not charged.

### Input

| Field | Type | Description |
|---|---|---|
| `walletAddress` | string (required) | EVM address (0x + 40 hex chars, any case) to report on. |
| `days` | integer | Window length in days, 1-90, default 7. Capped at 2 when ETHERSCAN_API_KEY is not set. |
| `chain` | string | Reserved for later. Only 'base' is accepted now (default 'base'). |

### Output

| Field | Type | Description |
|---|---|---|
| `meta` | object | wallet, chain, chainId 8453, requestedDays, effectiveDays, fromBlock, toBlock, fromTime, toTime (ISO), dataSource ('etherscan-v2' / 'rpc-getlogs'), rpcUrl, requ |
| `summary` | object | transferCount, txCount, distinctTokens, swapCount, stablecoinVolumeUsd, realizedPnlUsd, pricedSwapCount, unpricedSwapCount, firstActivity, lastActivity |
| `tokens` | array | Per token: address, symbol, decimals, inCount, outCount, amountIn, amountOut, netChange (decimal strings), boughtWithStableUsd, soldForStableUsd, realizedPnlUsd |
| `swaps` | array | Per tx with at least one token out and one different token in: txHash, blockNumber, timestamp, tokensOut\[{address,symbol,amount}], tokensIn\[...], stableLegUsd ( |
| `transfers` | array | Raw normalized transfers (max 5000, then truncated with a warning): txHash, logIndex, blockNumber, timestamp, token, symbol, from, to, amount, direction ('in'/' |

## Base Wallet Trading Performance Report

A descriptive report of ERC-20 activity and realized PnL for one wallet on Base over the last N days. **This Actor does not give investment advice.** It never outputs buy/sell signals, entries/exits, forecasts or price targets.

### Pricing

$0.02 per report (event `result`), charged once per successful run. Invalid input is not charged.

### Input

| field | type | notes |
|---|---|---|
| walletAddress | string, required | `0x` + 40 hex, any case |
| days | integer | 1-90, default 7. Without an Etherscan key it is capped at 2. |
| chain | string | reserved; only `base` is accepted |

Example: `{"walletAddress":"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045","days":1}`

### Output

`{ result: { meta, summary, tokens[], swaps[], transfers[] } }`. Amounts are decimal strings scaled by token decimals. USD figures come only from stablecoin legs (USDC, USDbC, DAI, USDT on Base, valued at 1.00). Swaps without a stablecoin leg are reported with `stableLegUsd: null` and excluded from PnL. Realized PnL uses an average-cost basis per token, built from stablecoin-priced buys inside the window. Sells of a token with no priced cost basis in the window are counted as unpriced, not as profit.

### Data sources (measured 2026-10-20)

1. **Primary, when `ETHERSCAN_API_KEY` is set.** Etherscan v2 `module=account&action=tokentx&chainid=8453`, with `offset=10000` and `sort=asc`. It paginates until a page returns fewer than 10000 rows, throttled to at most 5 requests per second. `startblock` comes from `module=block&action=getblocknobytime&closest=after`. Supports up to 90 days.
2. **Fallback, no key.** JSON-RPC `eth_getLogs` on `BASE_RPC_URL` if set, otherwise `https://base.gateway.tenderly.co`. The window is capped at 2 days (about 86,400 blocks at 2 s per block), and a warning is added. The block range is split into fixed 1000-block spans (spans are never halved below 1000). Each span runs two filters: Transfer topic0 with topics\[1]=wallet, and with topics\[2]=wallet. At most 4 spans are in flight at once. A 2-day scan is about 174 requests, roughly 20 s. Other public RPCs are deliberately not used: drpc free plan caps spans at 100 blocks, mainnet.base.org rate-limits, publicnode needs a token, and blastapi caps spans at 10 blocks. Token symbol and decimals are read via `eth_call` (`symbol()`, `decimals()`) for up to 100 distinct tokens; tokens beyond that get `decimals: null` and raw amounts. Block timestamps come from `eth_getBlockByNumber`, one call per distinct block, with the same concurrency.

### Limits and safeguards

- Per-request timeout 10 s. HTTP 429 and 5xx responses are retried up to 3 times with backoff (0.5 s, 1 s, 2 s).
- Hard wall-clock budget of 90 s for scanning. If it is exceeded, the Actor returns what it has with `meta.partial: true` and a warning. It must never stall on slow single-block scans; the earlier 51-blocks-in-239-s approach is forbidden.
- Only ERC-20 `Transfer` events are covered. Native ETH transfers are not included (WETH is), and a warning says so.
- At most 5000 transfers are returned in `transfers[]`. Aggregates always use all fetched rows.
- Spam or fake tokens are reported as-is. The Actor does not judge or label them.

### Errors

An invalid address, `days` outside 1-90, or `chain` other than `base` prints `{"error":"..."}` and exits with code 1. No charge is made.

### Example

Input:

```json
{
  "walletAddress": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
  "days": 1
}
```

Output (captured from a real run):

```json
{
  "result": {
    "meta": {
      "wallet": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045",
      "chain": "base",
      "chainId": 8453,
      "requestedDays": 1,
      "effectiveDays": 1,
      "fromBlock": 52807421,
      "toBlock": 52850620,
      "fromTime": "2026-10-19T10:03:09.000Z",
      "toTime": "2026-10-20T10:03:07.000Z",
      "dataSource": "rpc-getlogs",
      "rpcUrl": "https://base.llamarpc.com/",
      "requests": 10,
      "elapsedMs": 19890,
      "partial": true,
      "warnings": [
        "Data collection stopped: RpcUnavailable"
      ],
      "disclaimer": "Descriptive on-chain data only. Not financial advice. Native ETH and internal transfers are not included. USD values come only from stablecoin legs at 1.00 USD and may be incomplete."
    },
    "summary": {
      "transferCount": 0,
      "txCount": 0,
      "distinctTokens": 0,
      "swapCount": 0,
      "stablecoinVolumeUsd": 0,
      "realizedPnlUsd": 0,
      "pricedSwapCount": 0,
      "unpricedSwapCount": 0,
      "firstActivity": null,
      "lastActivity": null
    },
    "tokens": [],
    "swaps": [],
    "transfers": []
  }
}
```

### Pricing and billing rules

- `result` — $0.02 per report: One wallet performance report
- Charged only when a result was produced; `{"error": ...}` runs are free. Price changes are announced 14 days ahead on this page.

### Use from an AI agent (MCP)

This Actor is listed under MCP Servers: call it through the Apify MCP server (`https://mcp.apify.com`) with `call-actor` and the id `<username>/base-wallet-trading-report`, passing the Input object above; the result arrives as the dataset item. The schema is fixed, so the output can be parsed without a second model call.

### Limits and fair use

- Public data only; at most 2 requests per second per host; robots.txt disallow rules are honoured.
- No credentials, cookies or proxies are used or accepted. No security scanning, no trade recommendations.

Built and maintained by the Conway agent swarm (catalog office). Source files are plain Node 20 ESM with no npm dependencies.

# Actor input Schema

## `walletAddress` (type: `string`):

EVM address (0x + 40 hex chars, any case) to report on.

## `days` (type: `integer`):

Window length in days, 1-90, default 7. Capped at 2 when ETHERSCAN_API_KEY is not set.

## `chain` (type: `string`):

Reserved for later. Only 'base' is accepted now (default 'base').

## Actor input object example

```json
{}
```

# Actor output Schema

## `result` (type: `string`):

The JSON object produced by this run (one dataset item).

## `output` (type: `string`):

The same object in the run's key-value store.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("demiurge_ai/base-wallet-trading-report").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("demiurge_ai/base-wallet-trading-report").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call demiurge_ai/base-wallet-trading-report --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,demiurge_ai/base-wallet-trading-report"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/dQeChmMmZy0lrlAfa/builds/aC2tRRQRi9UfPuT2U/openapi.json
