---
name: wallet-book
description: "Reconstruct any crypto wallet's full position book and P&L (open + closed, cost basis, realised/unrealised). Use whenever asked what a wallet holds, what someone bought, or how much a trader is up — before brute-forcing the chain."
---

# Wallet book

**Never brute-force the chain first.** `gmgn-cli portfolio` answers most of this in two
minutes. Reach for `eth_getLogs` only to reconcile, or when the CLI comes back empty.

## The tool

Installed on Ben's Mac at `~/.npm-global/bin/gmgn-cli`. It is NOT on the cloud container.
Run it through the device bridge (`Desktop_Commander start_process`, or `device_bash` if a
folder is connected), and always prefix:

```sh
export PATH="$HOME/.npm-global/bin:$PATH"
```

Chains: `sol / bsc / base / eth / arbitrum / hyperevm / robinhood / arc / stable`.
The wallet flag is **`--wallet`**, not `--address`. (`market kline` uses `--address`.)

## Step 1 — holdings

```sh
gmgn-cli portfolio holdings --chain robinhood --wallet 0x... \
  --hide-closed false --limit 50 --order-by total_profit --raw
```

Per token: `balance`, `usd_value`, `accu_cost`, `history_bought_cost`,
`history_sold_income`, `realized_profit`, `unrealized_profit`, `total_profit`,
`total_profit_pnl`, buy/sell counts, `start_holding_at`. `--hide-closed false` is what
returns the whole history rather than just open positions. Page with `--cursor` from `next`.

## Step 2 — stats

```sh
gmgn-cli portfolio stats --chain robinhood --wallet 0x... --period 30d --raw
```

Gives `pnl_stat` (token_num, winrate, buckets) and any `tags`. Takes up to 100 wallets
(`--wallet a --wallet b`), so it is the cheap way to rank a candidate list.

Other subcommands: `activity`, `profits`, `info`, `token-balance`, `created-tokens`.

## Step 3 — THE TRAP: an empty `list` does not mean an empty wallet

If `holdings` returns `{"list":[],"next":""}` while `stats` shows real token counts, the
wallet trades through an **app router** (Robinhood app, pump.fun app) rather than hitting a
DEX itself. Every fill lands as a plain ERC20 transfer from one omnibus address, gas 0.
The default activity view skips those. The fix is the type filter:

```sh
gmgn-cli portfolio activity --chain robinhood --wallet 0x... --limit 50 \
  --type buy sell transferIn transferOut add remove --raw
```

Each event carries `cost_usd`, `price_usd`, `timestamp`, `from_address`, `tx_hash`.

Tell-tale of a router: one counterparty on every row, gas 0, and its own `stats` showing
thousands of tokens and an absurd `total_cost`. On Robinhood Chain that address is
`0xb92fe925dc43a0ecde6c8b1a2709c170ec4fff4f`.

**For such a wallet, GMGN's headline P&L is garbage** — no cost basis for transfers, so it
prints a large negative realised number and a 0% win rate. Never quote it. Rebuild from the
events instead.

## Step 4 — reconcile against the chain

GMGN's feed drops events (on one 4-week wallet: 82 returned vs 93 real). Sweep
`eth_getLogs` for the Transfer topic
`0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef` with the wallet padded
into topic1 (out) and topic2 (in), filtered by the token address list from step 1–3.
Then price the missing events:

```sh
gmgn-cli market kline --chain robinhood --address 0xTOKEN \
  --resolution 1m --from <ts-180> --to <ts+180> --raw
```

RPC notes (Robinhood Chain): `https://rpc.mainnet.chain.robinhood.com` works from the
cloud container **via curl only** — urllib/requests get 403 from the agent proxy, and
`rpc.robinhood.com` fails TLS. 200k blocks max per `getLogs` call; halve recursively on
403/429. Batch `eth_call` as a JSON-RPC array (~120 per round trip).

## Step 5 — cross-check balances, always

`balanceOf(wallet)` per token, and **read `decimals()` first**. Assuming 18 is how a real
position reads as 0.00 (NET on Robinhood Chain has 9 decimals and 85,188 total supply).
If reconstructed `in_amt - out_amt` matches `balanceOf`, the book is sound.

Current prices for open positions: DexScreener
`https://api.dexscreener.com/latest/dex/tokens/{address}` — pick the highest-liquidity
pair, but rank by **volume** when a ticker collides.

## Manual check in the browser

`https://gmgn.ai/<chain>/address/<0xwallet>`

e.g. `https://gmgn.ai/robinhood/address/0xa8ab5a838b50c14cfc5c3e788c37c77140481c41`.
Tabs: Recent PnL / Holdings / Trades / Callout / Deployed Tokens; 1D/7D/30D/All.
**gmgn.ai 403s the container — open it in Chrome on Ben's Mac only.**

## Report format

One table, sorted by P&L. Columns: token, cost $, sold $, value now $, P&L $, P&L %.
Then the three numbers that actually matter:

1. total deployed / total returned / net
2. closed positions: count, winners vs losers, realised P&L
3. **the book with the single best position stripped out** — for memecoin traders this is
   usually the whole story, and it is what separates a good trader from one lucky ticket.

Never shorten an address; 42 characters everywhere. State what the data does not cover
(unindexed events, staking contracts, a second wallet) rather than implying completeness.