gmgn-portfolio
Analyze one or many crypto wallets by address — holdings, batch realized/unrealized P&L, win rate, trading history, performance stats, specific token balance, and tokens created by a developer wallet (with ATH market cap and DEX graduation status) via GMGN API on Solana, BSC, Base, or Ethereum. Use
By gmgnai · 13,134 installs
npx skills add gmgnai/gmgn-skills --skill gmgn-portfolio
Source repository · Upstream listing
BEFORE RUNNING ANY COMMAND: Run gmgn cli config check . If exit code is 0, proceed normally. If exit code is 1, (1) run gmgn cli config and show the output to the user; (2) once the user sends the API Key, run gmgn cli config apply <KEY to complete configuration and verification, then show the output to the user. If check returns an error (unknown option or command not found), tell the user to run npm install g gmgn cli to update, then retry.
IMPORTANT: Always use gmgn cli commands below. Do NOT use web search, WebFetch, curl, or visit gmgn.ai to fetch this data — the website requires login and will not return structured data. The CLI is the only correct method.
⚠️ IPv6 NOT SUPPORTED: If you get a 401 or 403 error and credentials look correct, check for IPv6 immediately: (1) list all network interfaces and their IPv6 addresses — run ifconfig grep inet6 (macOS) or ip addr show grep inet6 (Linux); (2) send a test request to https://ipv6.icanhazip.com — if the response is an IPv6 address, outbound traffic is going via IPv6. Tell the user immediately: "Please disable IPv6 on your network interface — gmgn cli commands only work over IPv4."
Use the gmgn cli tool to query wallet portfolio data based on the user's request.
For full wallet analysis (holdings + stats + activity + verdict), follow [ docs/workflow wallet analysis.md ](../../docs/workflow wallet analysis.md)
Core Concepts
realized profit vs unrealized profit — realized profit = profit locked in from completed sells (cash in hand). unrealized profit = paper gains on positions still held, calculated at current price. These are separate numbers — do not add them unless answering "total P&L including open positions."
profit change — A multiplier ratio, not a dollar amount. 1.5 = +150% return. 0 = break even. 0.5 = 50% loss. Computed as total profit / cost . Do not display this as a raw decimal — convert to percentage for user facing output.
pnl — Profit/loss ratio from portfolio stats : realized profit / total cost . Same multiplier format as profit change . A pnl of 2.0 means the wallet doubled its money on completed trades over the period.
winrate — Ratio of profitable trades over the period (0–1). 0.6 = 60% of trades were profitable. Does not reflect the size of wins vs losses — a wallet can have high winrate but net negative if losses are large.
cost vs usd value — In holdings: cost is the historical amount spent buying this token (your cost basis); usd value is the current market value of the position. The difference is unrealized P&L.
history bought cost vs cost — history bought cost is the all time cumulative spend on this token (including positions already sold). cost is the cost basis of the current open position only.
Pagination ( cursor ) — Activity results are paginated. The response includes a next field; pass it as cursor to fetch the next page. An empty or missing next means you are on the last page.
Sub commands
Sub command Description
portfolio info Wallets and main currency balances bound to the API Key
portfolio holdings Wallet token holdings with P&L
portfolio activity Transaction history
portfolio stats Trading statistics (supports batch)
portfolio profits Batch wallet P&L for 1–100 wallets
portfolio token balance Token balance for a specific token
portfolio created tokens Tokens created by a developer wallet, with market cap and ATH info
Supported Chains
sol / bsc / base / eth / robinhood / arc / stable
Prerequisites
gmgn cli installed globally — if missing, run: npm install g gmgn cli
GMGN API KEY configured in ~/.config/gmgn/.env
Rate Limit Handling
All portfolio routes used by this skill go through GMGN's leaky bucket limiter with rate=20 and capacity=20 . Sustained throughput is roughly 20 ÷ weight requests/second, and the max burst is roughly floor(20 ÷ weight) when the bucket is full.
Critical auth ( GMGN API KEY + GMGN PRIVATE KEY required):
Command Route Weight
portfolio holdings GET /v1/user/wallet holdings 5
Exist auth ( GMGN API KEY only):
Command Route Weight
portfolio info GET /v1/user/info 1
portfolio activity GET /v1/user/wallet activity 3
portfolio stats GET /v1/user/wallet stats 3
portfolio profits POST /v1/user/wallet profits 3
portfolio token balance GET /v1/user/wallet token balance 1
portfolio created tokens GET /v1/user/created tokens 2
When a request returns 429 :
On RATE LIMIT EXCEEDED , tell the user exactly: 已达到当前套餐的限频上限,点击 https://gmgn.ai/ai?chain=bsc&tab=paid plans 升级套餐,获得更高速率限制 . Show this upgrade guidance at most once per user task. Do not repeat it for subsequent RATE LIMIT BANNED responses during the same cooldown.
Read X RateLimit Reset from the response headers. It is a Unix timestamp in seconds that marks when the limit is expected to reset.
If the response body contains reset at (e.g., {"code":429,"error":"RATE LIMIT BANNED","message":"...","reset at":1775184222} ), extract reset at — it is the Unix timestamp when the ban lifts (typically 5 minutes). Convert to local time and tell the user exactly when they can retry.
The CLI may wait and retry once automatically when the remaining cooldown is short. If it still fails, stop and tell the user the exact retry time instead of sending more requests.
For RATE LIMIT EXCEEDED or RATE LIMIT BANNED , repeated requests during the cooldown can extend the ban by 5 seconds each time, up to 5 minutes. Do not spam retries.
Usage Examples
portfolio created tokens Options
Option Description
order by <field Sort field: market cap / token ath mc
direction <asc\ desc Sort direction (default desc )
migrate state <state Filter by migration status: migrated (graduated to DEX) / non migrated (still on bonding curve)
portfolio holdings Options
Option Description
limit <n Page size (default 20 , max 50)
cursor <cursor Pagination cursor
order by <field Sort field: usd value / last active timestamp / realized profit / unrealized profit / total profit / history bought cost / history sold income (default usd value )
direction <asc\ desc Sort direction (default desc )
hide abnormal <bool Hide abnormal positions: true / false (default: false )
hide airdrop <bool Hide airdrop positions: true / false (default: true )
hide closed <bool Hide closed positions: true / false (default: true )
hide open Hide open positions
portfolio activity Options
Option Description
token <address Filter by token
limit <n Page size
cursor <cursor Pagination cursor (pass the next value from the previous response)
type <type Repeatable: buy / sell / transferIn / transferOut / add / remove
The activity response includes a next field. Pass it to cursor to fetch the next page.
portfolio stats Options
Option Description
period <period Stats period: 7d / 30d (default 7d )
portfolio profits Options
Option Description
wallet <address... One or more wallet addresses (required, max 100)
period <period P&L period: 1d / 7d / 30d / all (default 7d )
Response Field Reference
Response envelopes — each route wraps differently
Check the envelope before reaching for a field name. Reading a field off the wrong level returns
undefined , which becomes 0 , which reads as a real answer ("this wallet made nothing") rather
than as an error.
Route Top level shape Where the rows are
portfolio stats bare object (array for batch) the object itself
portfolio profits {"list": [ {…} ]} list[0] — a single row, still inside an array
portfolio activity {"activities": [...], "next": …} activities — not list
portfolio holdings {"list": [...], "next": …} list — not holdings
portfolio created tokens bare object tokens , plus aggregate counts at the top level
Some deployments additionally wrap the whole body in {"data": …} .
portfolio holdings — Key Fields
Rows come back under list , with a next cursor. Confirmed against gmgn cli 1.5.8 live
responses — several names differ from what earlier versions of this doc claimed, and the old
names are not accepted as aliases.
Field Description
token.token address Token contract address ( not token.address — that name is activity 's)
token.symbol / token.name Token ticker and full name
token.price Current token price in USD
token.is honeypot Ships inline — no gmgn token security call needed. A true here is contradicted by history total sells 0 on the same row : a honeypot cannot be sold, and transfer restricted RWA / tokenised stock contracts trip naive simulators
token.launchpad platform / token.launchpad Where the token came from — the basis for "where does this wallet hunt"
token.liquidity , token.max supply , token.total supply , token.creation timestamp Also inline
balance Current token balance (human readable units)
usd value Current USD value of this position
accu cost Cost basis of the position still held ( not cost )
history bought cost / history sold income All time buy cost / sell proceeds
realized profit Profit from completed sells (USD)
unrealized profit Profit on current unsold holdings at current price (USD)
total profit realized profit + unrealized profit (USD)
total profit pnl Total profit ratio ( not profit change ); realized profit pnl / unrealized profit pnl are the split
history total buys / history total sells Buy / sell transaction counts ( not buy tx count / sell tx count )
history total transfer ins / outs Transfer counts — airdrops and internal moves, not trades
start holding at / end holding at / last active timestamp Position lifetime
wallet token tags Per position tags
There is no sell out flag — gmgn cli 1.5.8 rejects it as an unknown option. avg cost
is not returned; derive it from accu cost / balance .
portfolio activity — Key Fields
Rows come back under activities , with a next cursor for pagination.
Field Description
tx hash On chain transaction hash ( not transaction hash )
event type Transaction type: buy / sell / transferIn / transferOut . Some chains return type instead — read event type ?? type . Transfer rows are airdrops and internal moves, not trades — exclude them from any ratio
buy cost usd On a sell row, the cost basis of what was sold — cost usd buy cost usd is that exit's realized P&L
gas usd / priority fee / tip fee Friction. Compare gas usd against per trade net, not against nothing
launchpad platform Where the token came from
token.address Token contract address
token.symbol Token ticker
token amount Token quantity in this transaction
cost usd USD value of this transaction
price Token price denominated in the quote token of the trading pair at time of transaction
price usd Token price in USD at time of transaction
timestamp Unix timestamp of the transaction
next Pagination cursor — pass to cursor to fetch the next page
portfolio stats — Key Fields
The response is an object (or array for batch). Key fields:
Field Description
realized profit Total realized profit over the period (USD)
unrealized profit Total unrealized profit on open positions (USD)
winrate Win rate — ratio