[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6H2PE8CWH90DEXNBCPPKEG1":3,"skill-same:01M6H2PE8CWH90DEXNBCPPKEG1":93},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":16,"sourceHtmlUrl":17,"categories":18,"keywords":24,"publishedAt":48,"linkOnly":49,"markdownContent":50,"markdownBody":51,"frontMatter":52,"refName":56,"commitSha":57,"skillDirectory":58,"forksCount":59,"repositoryHtmlUrl":60,"repositoryHomepageUrl":6,"ownerHtmlUrl":61,"ownerBlogUrl":62,"ownerDescription":63,"updatedAt":64,"install":65,"resources":78},"01M6H2PE8CWH90DEXNBCPPKEG1","gmgn-portfolio",null,"Analyze one or many crypto wallets by address — holdings, batch realized\u002Funrealized 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 when user asks about wallet holdings, P&L (including comparing up to 100 wallets), win rate, what tokens a dev has launched, the highest ATH token a dev ever created, or wants a wallet report to decide whether to copy-trade or follow.","jiayaoqijia\u002Fcryptoskill","jiayaoqijia","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F1453879?v=4","01M6GMYTX7Q7S504VC6E756ENR","YQ","01M6GMYV1QKJ1CC75MTTGT9PR0",81,"MIT","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Ftrading\u002Fgmgnai-official-gmgn-portfolio\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Ftrading\u002Fgmgnai-official-gmgn-portfolio\u002FSKILL.md",[19],{"categoryNo":20,"categoryName":21,"taxonomyType":22,"taxonomyTypeDesc":23},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47],"gmgn portfolio","portfolio","cap","when","rate","holdings","bsc","sol","activity","chain","avalanche","token","info","cli","Wallet","up","decide","analyze","api","ethereum","batch","status","performance","2026-11-10 10:12:30",false,"---\nname: gmgn-portfolio\ndescription: Analyze one or many crypto wallets by address — holdings, batch realized\u002Funrealized 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 when user asks about wallet holdings, P&L (including comparing up to 100 wallets), win rate, what tokens a dev has launched, the highest ATH token a dev ever created, or wants a wallet report to decide whether to copy-trade or follow.\nargument-hint: \"\u003Cinfo|holdings|activity|stats|profits|token-balance|created-tokens> [--chain \u003Csol|bsc|base|eth|arbitrum|hyperevm|robinhood|arc|stable|avalanche>] [--wallet \u003Cwallet_address...>]\"\nmetadata:\n  cliHelp: \"gmgn-cli portfolio --help\"\n---\n\n**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 \u003CKEY>` 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.**\n\n**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.**\n\n**⚠️ 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:\u002F\u002Fipv6.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.\"**\n\nUse the `gmgn-cli` tool to query wallet portfolio data based on the user's request.\n\n**For full wallet analysis (holdings + stats + activity + verdict), follow [`docs\u002Fworkflow-wallet-analysis.md`](..\u002F..\u002Fdocs\u002Fworkflow-wallet-analysis.md)**\n\n## Core Concepts\n\n- **`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.\"\n\n- **`profit_change`** — A multiplier ratio, not a dollar amount. `1.5` = +150% return. `0` = break-even. `-0.5` = -50% loss. Computed as `total_profit \u002F cost`. Do not display this as a raw decimal — convert to percentage for user-facing output.\n\n- **`pnl`** — Profit\u002Floss ratio from `portfolio stats`: `realized_profit \u002F 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.\n\n- **`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.\n\n- **`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.\n\n- **`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.\n\n- **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.\n\n## Sub-commands\n\n| Sub-command | Description |\n|-------------|-------------|\n| `portfolio info` | Wallets and main currency balances bound to the API Key |\n| `portfolio holdings` | Wallet token holdings with P&L |\n| `portfolio activity` | Transaction history |\n| `portfolio stats` | Trading statistics (supports batch) |\n| `portfolio profits` | Batch wallet P&L for 1–100 wallets |\n| `portfolio token-balance` | Token balance for a specific token |\n| `portfolio created-tokens` | Tokens created by a developer wallet, with market cap and ATH info |\n\n## Supported Chains\n\n`sol` \u002F `bsc` \u002F `base` \u002F `eth` \u002F `arbitrum` \u002F `hyperevm` \u002F `robinhood` \u002F `arc` \u002F `stable` \u002F `avalanche`\n\n## Prerequisites\n\n- `gmgn-cli` installed globally — if missing, run: `npm install -g gmgn-cli`\n- `GMGN_API_KEY` configured in `~\u002F.config\u002Fgmgn\u002F.env`\n\n## Rate Limit Handling\n\nAll portfolio routes used by this skill use GMGN's plan-based leaky bucket: Free `5\u002F5`, Plus `20\u002F20`, Pro `50\u002F50` (rate\u002Fcapacity). Sustained throughput is roughly `tier rate ÷ weight` requests\u002Fsecond, and the max burst is roughly `floor(tier capacity ÷ weight)`.\n\n**Critical auth** (`GMGN_API_KEY` + `GMGN_PRIVATE_KEY` required):\n\n| Command | Route | Weight |\n|---------|-------|--------|\n| `portfolio holdings` | `GET \u002Fv1\u002Fuser\u002Fwallet_holdings` | 2 |\n\n**Exist auth** (`GMGN_API_KEY` only):\n\n| Command | Route | Weight |\n|---------|-------|--------|\n| `portfolio info` | `GET \u002Fv1\u002Fuser\u002Finfo` | 2 |\n| `portfolio activity` | `GET \u002Fv1\u002Fuser\u002Fwallet_activity` | 3 |\n| `portfolio stats` | `GET \u002Fv1\u002Fuser\u002Fwallet_stats` | 3 |\n| `portfolio profits` | `POST \u002Fv1\u002Fuser\u002Fwallet_profits` | 3 |\n| `portfolio token-balance` | `GET \u002Fv1\u002Fuser\u002Fwallet_token_balance` | 2 |\n| `portfolio created-tokens` | `GET \u002Fv1\u002Fuser\u002Fcreated_tokens` | 2 |\n\nWhen a request returns `429`:\n\n- On `RATE_LIMIT_EXCEEDED`, tell the user exactly: `已达到当前套餐的限频上限，点击 https:\u002F\u002Fgmgn.ai\u002Fai?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.\n\n- Read `X-RateLimit-Reset` from the response headers. It is a Unix timestamp in seconds that marks when the limit is expected to reset.\n- 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.\n- 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.\n- 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.\n- On `RATE_LIMIT_BANNED_MAX`, the ban has hit the 5-minute ceiling because requests kept arriving during the cooldown. Stop **all** GMGN calls for this task (not just the failing one) and tell the user the exact reset time; any request before `reset_at` resets the ban to 5 minutes again.\n- On `403 PLAN_UPGRADE_REQUIRED`, the endpoint costs more rate-limit weight than the user's plan capacity, so it can never succeed on this plan — do not retry or wait. Tell the user the endpoint is unavailable on their current plan and show the `upgrade_message` from the response (it contains the upgrade link `https:\u002F\u002Fgmgn.ai\u002Fai?chain=bsc&tab=paid_plans`).\n\n## Usage Examples\n\n```bash\n# API Key wallet info (no --chain or --wallet needed)\ngmgn-cli portfolio info\n\n# Wallet holdings (default sort)\ngmgn-cli portfolio holdings --chain sol --wallet \u003Cwallet_address>\n\n# Holdings sorted by USD value, descending\ngmgn-cli portfolio holdings \\\n  --chain sol --wallet \u003Cwallet_address> \\\n  --order-by usd_value --direction desc --limit 20\n\n# Include sold-out positions\ngmgn-cli portfolio holdings --chain sol --wallet \u003Cwallet_address> --sell-out\n\n# Transaction activity\ngmgn-cli portfolio activity --chain sol --wallet \u003Cwallet_address>\n\n# Activity filtered by type\ngmgn-cli portfolio activity --chain sol --wallet \u003Cwallet_address> \\\n  --type buy --type sell\n\n# Activity for a specific token\ngmgn-cli portfolio activity --chain sol --wallet \u003Cwallet_address> \\\n  --token \u003Ctoken_address>\n\n# Trading stats (default 7d)\ngmgn-cli portfolio stats --chain sol --wallet \u003Cwallet_address>\n\n# Trading stats for 30 days\ngmgn-cli portfolio stats --chain sol --wallet \u003Cwallet_address> --period 30d\n\n# Batch stats for multiple wallets\ngmgn-cli portfolio stats --chain sol \\\n  --wallet \u003Cwallet_1> --wallet \u003Cwallet_2>\n\n# Batch P&L for multiple wallets (default 7d)\ngmgn-cli portfolio profits --chain sol \\\n  --wallet \u003Cwallet_1> --wallet \u003Cwallet_2>\n\n# All-time P&L for up to 100 wallets\ngmgn-cli portfolio profits --chain sol \\\n  --wallet \u003Cwallet_1> --wallet \u003Cwallet_2> --period all\n\n# Token balance\ngmgn-cli portfolio token-balance \\\n  --chain sol --wallet \u003Cwallet_address> --token \u003Ctoken_address>\n\n# Tokens created by a developer wallet\ngmgn-cli portfolio created-tokens --chain sol --wallet \u003Cwallet_address>\n\n# Created tokens sorted by all-time high market cap\ngmgn-cli portfolio created-tokens \\\n  --chain sol --wallet \u003Cwallet_address> \\\n  --order-by token_ath_mc --direction desc\n\n# Only migrated tokens\ngmgn-cli portfolio created-tokens \\\n  --chain sol --wallet \u003Cwallet_address> --migrate-state migrated\n\n# ETH wallet holdings\ngmgn-cli portfolio holdings --chain eth --wallet \u003C0x_wallet_address>\n\n# ETH wallet transaction activity\ngmgn-cli portfolio activity --chain eth --wallet \u003C0x_wallet_address>\n\n# ETH token balance\ngmgn-cli portfolio token-balance \\\n  --chain eth --wallet \u003C0x_wallet_address> --token \u003C0x_token_address>\n```\n\n## `portfolio created-tokens` Options\n\n| Option | Description |\n|--------|-------------|\n| `--order-by \u003Cfield>` | Sort field: `market_cap` \u002F `token_ath_mc` |\n| `--direction \u003Casc\\|desc>` | Sort direction (default `desc`) |\n| `--migrate-state \u003Cstate>` | Filter by migration status: `migrated` (graduated to DEX) \u002F `non_migrated` (still on bonding curve) |\n\n## `portfolio holdings` Options\n\n| Option | Description |\n|--------|-------------|\n| `--limit \u003Cn>` | Page size (default `20`, max 50) |\n| `--cursor \u003Ccursor>` | Pagination cursor |\n| `--order-by \u003Cfield>` | Sort field: `usd_value` \u002F `last_active_timestamp` \u002F `realized_profit` \u002F `unrealized_profit` \u002F `total_profit` \u002F `history_bought_cost` \u002F `history_sold_income` (default `usd_value`) |\n| `--direction \u003Casc\\|desc>` | Sort direction (default `desc`) |\n| `--hide-abnormal \u003Cbool>` | Hide abnormal positions: `true` \u002F `false` (default: `false`) |\n| `--hide-airdrop \u003Cbool>` | Hide airdrop positions: `true` \u002F `false` (default: `true`) |\n| `--hide-closed \u003Cbool>` | Hide closed positions: `true` \u002F `false` (default: `true`) |\n| `--hide-open` | Hide open positions |\n\n## `portfolio activity` Options\n\n| Option | Description |\n|--------|-------------|\n| `--token \u003Caddress>` | Filter by token |\n| `--limit \u003Cn>` | Page size |\n| `--cursor \u003Ccursor>` | Pagination cursor (pass the `next` value from the previous response) |\n| `--type \u003Ctype>` | Repeatable: `buy` \u002F `sell` \u002F `transferIn` \u002F `transferOut` \u002F `add` \u002F `remove` |\n\nThe activity response includes a `next` field. Pass it to `--cursor` to fetch the next page.\n\n## `portfolio stats` Options\n\n| Option | Description |\n|--------|-------------|\n| `--period \u003Cperiod>` | Stats period: `7d` \u002F `30d` (default `7d`) |\n\n## `portfolio profits` Options\n\n| Option | Description |\n|--------|-------------|\n| `--wallet \u003Caddress...>` | One or more wallet addresses (required, max 100) |\n| `--period \u003Cperiod>` | P&L period: `1d` \u002F `7d` \u002F `30d` \u002F `all` (default `7d`) |\n\n## Response Field Reference\n\n### Response envelopes — each route wraps differently\n\nCheck the envelope before reaching for a field name. Reading a field off the wrong level returns\n`undefined`, which becomes `0`, which reads as a real answer (\"this wallet made nothing\") rather\nthan as an error.\n\n| Route | Top-level shape | Where the rows are |\n|-------|-----------------|--------------------|\n| `portfolio stats` | bare object (array for batch) | the object itself |\n| `portfolio profits` | `{\"list\": [ {…} ]}` | `list[0]` — a single row, still inside an array |\n| `portfolio activity` | `{\"activities\": [...], \"next\": …}` | `activities` — **not** `list` |\n| `portfolio holdings` | `{\"list\": [...], \"next\": …}` | `list` — **not** `holdings` |\n| `portfolio created-tokens` | bare object | `tokens`, plus aggregate counts at the top level |\n\nSome deployments additionally wrap the whole body in `{\"data\": …}`.\n\n### `portfolio holdings` — Key Fields\n\nRows come back under **`list`**, with a `next` cursor. Confirmed against gmgn-cli 1.5.8 live\nresponses — several names differ from what earlier versions of this doc claimed, and the old\nnames are not accepted as aliases.\n\n| Field | Description |\n|-------|-------------|\n| `token.token_address` | Token contract address (**not** `token.address` — that name is `activity`'s) |\n| `token.symbol` \u002F `token.name` | Token ticker and full name |\n| `token.price` | Current token price in USD |\n| `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 \u002F tokenised-stock contracts trip naive simulators |\n| `token.launchpad_platform` \u002F `token.launchpad` | Where the token came from — the basis for \"where does this wallet hunt\" |\n| `token.liquidity`, `token.max_supply`, `token.total_supply`, `token.creation_timestamp` | Also inline |\n| `balance` | Current token balance (human-readable units) |\n| `usd_value` | Current USD value of this position |\n| `accu_cost` | Cost basis of the position still held (**not** `cost`) |\n| `history_bought_cost` \u002F `history_sold_income` | All-time buy cost \u002F sell proceeds |\n| `realized_profit` | Profit from completed sells (USD) |\n| `unrealized_profit` | Profit on current unsold holdings at current price (USD) |\n| `total_profit` | `realized_profit + unrealized_profit` (USD) |\n| `total_profit_pnl` | Total profit **ratio** (**not** `profit_change`); `realized_profit_pnl` \u002F `unrealized_profit_pnl` are the split |\n| `history_total_buys` \u002F `history_total_sells` | Buy \u002F sell transaction counts (**not** `buy_tx_count` \u002F `sell_tx_count`) |\n| `history_total_transfer_ins` \u002F `_outs` | Transfer counts — airdrops and internal moves, not trades |\n| `start_holding_at` \u002F `end_holding_at` \u002F `last_active_timestamp` | Position lifetime |\n| `wallet_token_tags` | Per-position tags |\n\nThere is **no `--sell-out` flag** — gmgn-cli 1.5.8 rejects it as an unknown option. `avg_cost`\nis not returned; derive it from `accu_cost \u002F balance`.\n\n### `portfolio activity` — Key Fields\n\nRows come back under **`activities`**, with a `next` cursor for pagination.\n\n| Field | Description |\n|-------|-------------|\n| `tx_hash` | On-chain transaction hash (**not** `transaction_hash`) |\n| `event_type` | Transaction type: `buy` \u002F `sell` \u002F `transferIn` \u002F `transferOut`. Some chains return `type` instead — read `event_type ?? type`. Transfer rows are airdrops and internal moves, **not trades** — exclude them from any ratio |\n| `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 |\n| `gas_usd` \u002F `priority_fee` \u002F `tip_fee` | Friction. Compare `gas_usd` against per-trade net, not against nothing |\n| `launchpad_platform` | Where the token came from |\n| `token.address` | Token contract address |\n| `token.symbol` | Token ticker |\n| `token_amount` | Token quantity in this transaction |\n| `cost_usd` | USD value of this transaction |\n| `price` | Token price denominated in the quote token of the trading pair at time of transaction |\n| `price_usd` | Token price in USD at time of transaction |\n| `timestamp` | Unix timestamp of the transaction |\n| `next` | Pagination cursor — pass to `--cursor` to fetch the next page |\n\n### `portfolio stats` — Key Fields\n\nThe response is an object (or array for batch). Key fields:\n\n| Field | Description |\n|-------|-------------|\n| `realized_profit` | Total realized profit over the period (USD) |\n| `unrealized_profit` | Total unrealized profit on open positions (USD) |\n| `winrate` | Win rate — ratio of profitable trades (0–1) |\n| `total_cost` | Total amount spent buying in the period (USD) |\n| `buy_count` | Number of buy transactions |\n| `sell_count` | Number of sell transactions |\n| `pnl` | Profit\u002Floss ratio = `realized_profit \u002F total_cost` |\n\nThe response also includes a `common` object when available (absent if the upstream identity service is unavailable):\n\n| Field | Description |\n|-------|-------------|\n| `common.avatar` | Wallet avatar URL |\n| `common.name` | Display name |\n| `common.ens` | ENS domain (EVM chains only) |\n| `common.tag` | Primary wallet tag |\n| `common.tags` | All wallet tags (e.g. `[\"smart_money\"]`) |\n| `common.twitter_username` | Twitter handle |\n| `common.twitter_name` | Twitter display name |\n| `common.followers_count` | Twitter follower count |\n| `common.is_blue_verified` | Twitter blue-verified badge |\n| `common.follow_count` | Number of GMGN users following this wallet |\n| `common.remark_count` | Number of GMGN users who have remarked this wallet |\n| `common.created_token_count` | Tokens created by this wallet |\n| `common.created_at` | Wallet creation time (Unix seconds) — records when the first funding transaction arrived; use this as the wallet's age indicator |\n| `common.fund_from` | Funding source label |\n| `common.fund_from_address` | Address that funded this wallet |\n| `common.fund_amount` | Funding amount |\n\nUse `common.tags` and `common.twitter_username` when building a wallet profile narrative. If `common` is absent in the response, omit identity fields silently — do not report it as an error.\n\n### `portfolio profits` — Key Fields\n\nThe response has a `list` array with one item per wallet. Monetary values are decimal strings; parse them with decimal arithmetic rather than binary floating point when exact calculations matter.\n\n| Field | Description |\n|-------|-------------|\n| `wallet_address` | Wallet address |\n| `realized_profit` | Realized profit in the selected period |\n| `realized_profit_cost` | Cost basis associated with selected-period realized profit |\n| `buy` \u002F `sell` | Buy and sell counts in the selected period |\n| `unrealized_profit` | Unrealized profit on current holdings |\n| `total_realized_profit` | All-time realized profit |\n| `total_realized_profit_cost` | Cost basis associated with all-time realized profit |\n| `total_profit` | Total profit |\n| `total_cost` | Total cost basis |\n\n### `portfolio created-tokens` — Key Fields\n\nThe response `data` object has a `tokens` array plus aggregate stats.\n\nTop-level fields:\n\n| Field | Description |\n|-------|-------------|\n| `last_create_timestamp` | Unix timestamp of the most recent token creation |\n| `inner_count` | Number of tokens still on the bonding curve (NOT graduated) |\n| `open_count` | Number of tokens that have graduated to DEX |\n| `open_ratio` | Graduation rate (string, e.g. `\"0.25\"`) |\n\n> **Total created = `inner_count + open_count`**. Do NOT use `len(tokens)` as the total — the `tokens` array is capped at 100 entries and may be truncated.\n| `creator_ath_info` | Best-performing token created by this wallet (ATH market cap) |\n| `tokens` | Array of created tokens — see below |\n\n`creator_ath_info` fields:\n\n| Field | Description |\n|-------|-------------|\n| `creator` | Wallet address |\n| `ath_token` | Token address with highest ATH market cap |\n| `ath_mc` | ATH market cap (USD string) |\n| `token_symbol` \u002F `token_name` | Token ticker and name |\n| `token_logo` | Logo URL |\n\nPer-token fields (`tokens[*]`):\n\n| Field | Description |\n|-------|-------------|\n| `token_address` | Token contract address |\n| `symbol` | Token ticker |\n| `chain` | Chain name |\n| `create_timestamp` | Unix timestamp of creation |\n| `is_open` | `true` if graduated to DEX |\n| `market_cap` | Current market cap (USD string) |\n| `token_ath_mc` | All-time high market cap (USD string) |\n| `pool_liquidity` | Current liquidity (USD string) |\n| `holders` | Current holder count |\n| `swap_1h` | Swap count in the last hour |\n| `volume_1h` | Trading volume in the last hour (USD string) |\n| `launchpad_platform` | Launch platform name (e.g. `Pump.fun`) |\n| `is_pump` | `true` if launched on Pump.fun |\n| `bundler_rate` | Bundler participation rate (0–1) |\n| `cto_flag` | `true` if community-takeover token |\n\n**Do NOT guess field names not listed here.** If a field appears in the response but is not in this table, do not interpret it without reading the raw output first.\n\n## Output Format\n\n**Do NOT dump raw JSON.** Always parse and present data in the structured formats below. Use `--raw` only when piping to `jq` or further processing.\n\n### `portfolio holdings` — Holdings Table\n\nPresent a table sorted by `usd_value` (descending). Show total portfolio value at the top.\n\n```\nWallet: {wallet} | Chain: {chain}\nTotal value: ~${sum of usd_value across all positions}\n\n# | Token | Balance | USD Value | Total P&L | P&L% | Avg Cost | Buys \u002F Sells\n```\n\nFlag positions where `profit_change` is strongly negative (e.g. \u003C -50%) or positive (e.g. > 200%) with a brief note.\n\n### `portfolio activity` — Activity Feed\n\nPresent as a chronological list (newest first). Use human-readable timestamps.\n\n```\n{type} {token.symbol}  |  {token_amount} tokens  |  ${cost_usd}  |  {timestamp}  |  tx: {short hash}\n```\n\nGroup by token if the user asks about a specific token.\n\n### `portfolio stats` — Stats Summary\n\n```\nWallet: {wallet} | Period: {period}\nRealized P&L:   ${realized_profit}\nUnrealized P&L: ${unrealized_profit}\nWin Rate:        {winrate × 100}%\nTotal Spent:     ${total_cost}\nBuys \u002F Sells:    {buy_count} \u002F {sell_count}\nPnL Ratio:       {pnl}x\n[Identity:       {common.name or common.twitter_username} | Tags: {common.tags}]\n```\n\nShow the `[Identity: ...]` line only if `common` is present in the response. For batch queries (multiple wallets), present one summary block per wallet.\n\n## Notes\n\n- `portfolio holdings` uses **critical auth** (`GMGN_API_KEY` + `GMGN_PRIVATE_KEY` required — CLI signs the request automatically). All other portfolio commands use exist auth (API Key only, no signature required).\n- `portfolio stats` supports multiple `--wallet` flags for batch queries\n- Use `--raw` to get single-line JSON for further processing\n- **Input validation** — Wallet and token addresses are validated against the expected chain format at runtime (sol: base58 32–44 chars; bsc\u002Fbase\u002Feth: `0x` + 40 hex digits). The CLI exits with an error on invalid input.\n- For follow-wallet, KOL, and Smart Money trade records, use the `gmgn-track` skill (`track follow-wallet` \u002F `track kol` \u002F `track smartmoney`)\n\n## Workflow\n\nFor full wallet analysis including trade history and follow-through on top holdings, see [`docs\u002Fworkflow-wallet-analysis.md`](..\u002F..\u002Fdocs\u002Fworkflow-wallet-analysis.md)\n\nFor in-depth trading style analysis, copy-trade ROI estimation, and smart money leaderboard comparison, see [`docs\u002Fworkflow-smart-money-profile.md`](..\u002F..\u002Fdocs\u002Fworkflow-smart-money-profile.md)\n\n**When to use which:**\n- User asks \"is this wallet worth following\" → [`docs\u002Fworkflow-wallet-analysis.md`](..\u002F..\u002Fdocs\u002Fworkflow-wallet-analysis.md)\n- User asks \"what's this wallet's trading style\", \"when does he take profit\", \"smart money profile\", \"if I copied this wallet what would my return be\" → [`docs\u002Fworkflow-smart-money-profile.md`](..\u002F..\u002Fdocs\u002Fworkflow-smart-money-profile.md)\n- User wants to compare multiple smart money wallets by winrate\u002FPnL → [`docs\u002Fworkflow-smart-money-profile.md`](..\u002F..\u002Fdocs\u002Fworkflow-smart-money-profile.md) Step 5 (leaderboard)\n- User asks \"what tokens did this dev create\", \"dev 发过哪些币\", \"查一下这个 dev 的代币\", \"dev 创建记录\" → use `portfolio created-tokens --chain \u003Cchain> --wallet \u003Ccreator_address>` directly. Get the creator address first via `token info` if only a token address is given.\n","**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 \u003CKEY>` 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.**\n\n**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.**\n\n**⚠️ 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:\u002F\u002Fipv6.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.\"**\n\nUse the `gmgn-cli` tool to query wallet portfolio data based on the user's request.\n\n**For full wallet analysis (holdings + stats + activity + verdict), follow [`docs\u002Fworkflow-wallet-analysis.md`](..\u002F..\u002Fdocs\u002Fworkflow-wallet-analysis.md)**\n\n## Core Concepts\n\n- **`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.\"\n\n- **`profit_change`** — A multiplier ratio, not a dollar amount. `1.5` = +150% return. `0` = break-even. `-0.5` = -50% loss. Computed as `total_profit \u002F cost`. Do not display this as a raw decimal — convert to percentage for user-facing output.\n\n- **`pnl`** — Profit\u002Floss ratio from `portfolio stats`: `realized_profit \u002F 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.\n\n- **`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.\n\n- **`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.\n\n- **`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.\n\n- **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.\n\n## Sub-commands\n\n| Sub-command | Description |\n|-------------|-------------|\n| `portfolio info` | Wallets and main currency balances bound to the API Key |\n| `portfolio holdings` | Wallet token holdings with P&L |\n| `portfolio activity` | Transaction history |\n| `portfolio stats` | Trading statistics (supports batch) |\n| `portfolio profits` | Batch wallet P&L for 1–100 wallets |\n| `portfolio token-balance` | Token balance for a specific token |\n| `portfolio created-tokens` | Tokens created by a developer wallet, with market cap and ATH info |\n\n## Supported Chains\n\n`sol` \u002F `bsc` \u002F `base` \u002F `eth` \u002F `arbitrum` \u002F `hyperevm` \u002F `robinhood` \u002F `arc` \u002F `stable` \u002F `avalanche`\n\n## Prerequisites\n\n- `gmgn-cli` installed globally — if missing, run: `npm install -g gmgn-cli`\n- `GMGN_API_KEY` configured in `~\u002F.config\u002Fgmgn\u002F.env`\n\n## Rate Limit Handling\n\nAll portfolio routes used by this skill use GMGN's plan-based leaky bucket: Free `5\u002F5`, Plus `20\u002F20`, Pro `50\u002F50` (rate\u002Fcapacity). Sustained throughput is roughly `tier rate ÷ weight` requests\u002Fsecond, and the max burst is roughly `floor(tier capacity ÷ weight)`.\n\n**Critical auth** (`GMGN_API_KEY` + `GMGN_PRIVATE_KEY` required):\n\n| Command | Route | Weight |\n|---------|-------|--------|\n| `portfolio holdings` | `GET \u002Fv1\u002Fuser\u002Fwallet_holdings` | 2 |\n\n**Exist auth** (`GMGN_API_KEY` only):\n\n| Command | Route | Weight |\n|---------|-------|--------|\n| `portfolio info` | `GET \u002Fv1\u002Fuser\u002Finfo` | 2 |\n| `portfolio activity` | `GET \u002Fv1\u002Fuser\u002Fwallet_activity` | 3 |\n| `portfolio stats` | `GET \u002Fv1\u002Fuser\u002Fwallet_stats` | 3 |\n| `portfolio profits` | `POST \u002Fv1\u002Fuser\u002Fwallet_profits` | 3 |\n| `portfolio token-balance` | `GET \u002Fv1\u002Fuser\u002Fwallet_token_balance` | 2 |\n| `portfolio created-tokens` | `GET \u002Fv1\u002Fuser\u002Fcreated_tokens` | 2 |\n\nWhen a request returns `429`:\n\n- On `RATE_LIMIT_EXCEEDED`, tell the user exactly: `已达到当前套餐的限频上限，点击 https:\u002F\u002Fgmgn.ai\u002Fai?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.\n\n- Read `X-RateLimit-Reset` from the response headers. It is a Unix timestamp in seconds that marks when the limit is expected to reset.\n- 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.\n- 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.\n- 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.\n- On `RATE_LIMIT_BANNED_MAX`, the ban has hit the 5-minute ceiling because requests kept arriving during the cooldown. Stop **all** GMGN calls for this task (not just the failing one) and tell the user the exact reset time; any request before `reset_at` resets the ban to 5 minutes again.\n- On `403 PLAN_UPGRADE_REQUIRED`, the endpoint costs more rate-limit weight than the user's plan capacity, so it can never succeed on this plan — do not retry or wait. Tell the user the endpoint is unavailable on their current plan and show the `upgrade_message` from the response (it contains the upgrade link `https:\u002F\u002Fgmgn.ai\u002Fai?chain=bsc&tab=paid_plans`).\n\n## Usage Examples\n\n```bash\n# API Key wallet info (no --chain or --wallet needed)\ngmgn-cli portfolio info\n\n# Wallet holdings (default sort)\ngmgn-cli portfolio holdings --chain sol --wallet \u003Cwallet_address>\n\n# Holdings sorted by USD value, descending\ngmgn-cli portfolio holdings \\\n  --chain sol --wallet \u003Cwallet_address> \\\n  --order-by usd_value --direction desc --limit 20\n\n# Include sold-out positions\ngmgn-cli portfolio holdings --chain sol --wallet \u003Cwallet_address> --sell-out\n\n# Transaction activity\ngmgn-cli portfolio activity --chain sol --wallet \u003Cwallet_address>\n\n# Activity filtered by type\ngmgn-cli portfolio activity --chain sol --wallet \u003Cwallet_address> \\\n  --type buy --type sell\n\n# Activity for a specific token\ngmgn-cli portfolio activity --chain sol --wallet \u003Cwallet_address> \\\n  --token \u003Ctoken_address>\n\n# Trading stats (default 7d)\ngmgn-cli portfolio stats --chain sol --wallet \u003Cwallet_address>\n\n# Trading stats for 30 days\ngmgn-cli portfolio stats --chain sol --wallet \u003Cwallet_address> --period 30d\n\n# Batch stats for multiple wallets\ngmgn-cli portfolio stats --chain sol \\\n  --wallet \u003Cwallet_1> --wallet \u003Cwallet_2>\n\n# Batch P&L for multiple wallets (default 7d)\ngmgn-cli portfolio profits --chain sol \\\n  --wallet \u003Cwallet_1> --wallet \u003Cwallet_2>\n\n# All-time P&L for up to 100 wallets\ngmgn-cli portfolio profits --chain sol \\\n  --wallet \u003Cwallet_1> --wallet \u003Cwallet_2> --period all\n\n# Token balance\ngmgn-cli portfolio token-balance \\\n  --chain sol --wallet \u003Cwallet_address> --token \u003Ctoken_address>\n\n# Tokens created by a developer wallet\ngmgn-cli portfolio created-tokens --chain sol --wallet \u003Cwallet_address>\n\n# Created tokens sorted by all-time high market cap\ngmgn-cli portfolio created-tokens \\\n  --chain sol --wallet \u003Cwallet_address> \\\n  --order-by token_ath_mc --direction desc\n\n# Only migrated tokens\ngmgn-cli portfolio created-tokens \\\n  --chain sol --wallet \u003Cwallet_address> --migrate-state migrated\n\n# ETH wallet holdings\ngmgn-cli portfolio holdings --chain eth --wallet \u003C0x_wallet_address>\n\n# ETH wallet transaction activity\ngmgn-cli portfolio activity --chain eth --wallet \u003C0x_wallet_address>\n\n# ETH token balance\ngmgn-cli portfolio token-balance \\\n  --chain eth --wallet \u003C0x_wallet_address> --token \u003C0x_token_address>\n```\n\n## `portfolio created-tokens` Options\n\n| Option | Description |\n|--------|-------------|\n| `--order-by \u003Cfield>` | Sort field: `market_cap` \u002F `token_ath_mc` |\n| `--direction \u003Casc\\|desc>` | Sort direction (default `desc`) |\n| `--migrate-state \u003Cstate>` | Filter by migration status: `migrated` (graduated to DEX) \u002F `non_migrated` (still on bonding curve) |\n\n## `portfolio holdings` Options\n\n| Option | Description |\n|--------|-------------|\n| `--limit \u003Cn>` | Page size (default `20`, max 50) |\n| `--cursor \u003Ccursor>` | Pagination cursor |\n| `--order-by \u003Cfield>` | Sort field: `usd_value` \u002F `last_active_timestamp` \u002F `realized_profit` \u002F `unrealized_profit` \u002F `total_profit` \u002F `history_bought_cost` \u002F `history_sold_income` (default `usd_value`) |\n| `--direction \u003Casc\\|desc>` | Sort direction (default `desc`) |\n| `--hide-abnormal \u003Cbool>` | Hide abnormal positions: `true` \u002F `false` (default: `false`) |\n| `--hide-airdrop \u003Cbool>` | Hide airdrop positions: `true` \u002F `false` (default: `true`) |\n| `--hide-closed \u003Cbool>` | Hide closed positions: `true` \u002F `false` (default: `true`) |\n| `--hide-open` | Hide open positions |\n\n## `portfolio activity` Options\n\n| Option | Description |\n|--------|-------------|\n| `--token \u003Caddress>` | Filter by token |\n| `--limit \u003Cn>` | Page size |\n| `--cursor \u003Ccursor>` | Pagination cursor (pass the `next` value from the previous response) |\n| `--type \u003Ctype>` | Repeatable: `buy` \u002F `sell` \u002F `transferIn` \u002F `transferOut` \u002F `add` \u002F `remove` |\n\nThe activity response includes a `next` field. Pass it to `--cursor` to fetch the next page.\n\n## `portfolio stats` Options\n\n| Option | Description |\n|--------|-------------|\n| `--period \u003Cperiod>` | Stats period: `7d` \u002F `30d` (default `7d`) |\n\n## `portfolio profits` Options\n\n| Option | Description |\n|--------|-------------|\n| `--wallet \u003Caddress...>` | One or more wallet addresses (required, max 100) |\n| `--period \u003Cperiod>` | P&L period: `1d` \u002F `7d` \u002F `30d` \u002F `all` (default `7d`) |\n\n## Response Field Reference\n\n### Response envelopes — each route wraps differently\n\nCheck the envelope before reaching for a field name. Reading a field off the wrong level returns\n`undefined`, which becomes `0`, which reads as a real answer (\"this wallet made nothing\") rather\nthan as an error.\n\n| Route | Top-level shape | Where the rows are |\n|-------|-----------------|--------------------|\n| `portfolio stats` | bare object (array for batch) | the object itself |\n| `portfolio profits` | `{\"list\": [ {…} ]}` | `list[0]` — a single row, still inside an array |\n| `portfolio activity` | `{\"activities\": [...], \"next\": …}` | `activities` — **not** `list` |\n| `portfolio holdings` | `{\"list\": [...], \"next\": …}` | `list` — **not** `holdings` |\n| `portfolio created-tokens` | bare object | `tokens`, plus aggregate counts at the top level |\n\nSome deployments additionally wrap the whole body in `{\"data\": …}`.\n\n### `portfolio holdings` — Key Fields\n\nRows come back under **`list`**, with a `next` cursor. Confirmed against gmgn-cli 1.5.8 live\nresponses — several names differ from what earlier versions of this doc claimed, and the old\nnames are not accepted as aliases.\n\n| Field | Description |\n|-------|-------------|\n| `token.token_address` | Token contract address (**not** `token.address` — that name is `activity`'s) |\n| `token.symbol` \u002F `token.name` | Token ticker and full name |\n| `token.price` | Current token price in USD |\n| `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 \u002F tokenised-stock contracts trip naive simulators |\n| `token.launchpad_platform` \u002F `token.launchpad` | Where the token came from — the basis for \"where does this wallet hunt\" |\n| `token.liquidity`, `token.max_supply`, `token.total_supply`, `token.creation_timestamp` | Also inline |\n| `balance` | Current token balance (human-readable units) |\n| `usd_value` | Current USD value of this position |\n| `accu_cost` | Cost basis of the position still held (**not** `cost`) |\n| `history_bought_cost` \u002F `history_sold_income` | All-time buy cost \u002F sell proceeds |\n| `realized_profit` | Profit from completed sells (USD) |\n| `unrealized_profit` | Profit on current unsold holdings at current price (USD) |\n| `total_profit` | `realized_profit + unrealized_profit` (USD) |\n| `total_profit_pnl` | Total profit **ratio** (**not** `profit_change`); `realized_profit_pnl` \u002F `unrealized_profit_pnl` are the split |\n| `history_total_buys` \u002F `history_total_sells` | Buy \u002F sell transaction counts (**not** `buy_tx_count` \u002F `sell_tx_count`) |\n| `history_total_transfer_ins` \u002F `_outs` | Transfer counts — airdrops and internal moves, not trades |\n| `start_holding_at` \u002F `end_holding_at` \u002F `last_active_timestamp` | Position lifetime |\n| `wallet_token_tags` | Per-position tags |\n\nThere is **no `--sell-out` flag** — gmgn-cli 1.5.8 rejects it as an unknown option. `avg_cost`\nis not returned; derive it from `accu_cost \u002F balance`.\n\n### `portfolio activity` — Key Fields\n\nRows come back under **`activities`**, with a `next` cursor for pagination.\n\n| Field | Description |\n|-------|-------------|\n| `tx_hash` | On-chain transaction hash (**not** `transaction_hash`) |\n| `event_type` | Transaction type: `buy` \u002F `sell` \u002F `transferIn` \u002F `transferOut`. Some chains return `type` instead — read `event_type ?? type`. Transfer rows are airdrops and internal moves, **not trades** — exclude them from any ratio |\n| `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 |\n| `gas_usd` \u002F `priority_fee` \u002F `tip_fee` | Friction. Compare `gas_usd` against per-trade net, not against nothing |\n| `launchpad_platform` | Where the token came from |\n| `token.address` | Token contract address |\n| `token.symbol` | Token ticker |\n| `token_amount` | Token quantity in this transaction |\n| `cost_usd` | USD value of this transaction |\n| `price` | Token price denominated in the quote token of the trading pair at time of transaction |\n| `price_usd` | Token price in USD at time of transaction |\n| `timestamp` | Unix timestamp of the transaction |\n| `next` | Pagination cursor — pass to `--cursor` to fetch the next page |\n\n### `portfolio stats` — Key Fields\n\nThe response is an object (or array for batch). Key fields:\n\n| Field | Description |\n|-------|-------------|\n| `realized_profit` | Total realized profit over the period (USD) |\n| `unrealized_profit` | Total unrealized profit on open positions (USD) |\n| `winrate` | Win rate — ratio of profitable trades (0–1) |\n| `total_cost` | Total amount spent buying in the period (USD) |\n| `buy_count` | Number of buy transactions |\n| `sell_count` | Number of sell transactions |\n| `pnl` | Profit\u002Floss ratio = `realized_profit \u002F total_cost` |\n\nThe response also includes a `common` object when available (absent if the upstream identity service is unavailable):\n\n| Field | Description |\n|-------|-------------|\n| `common.avatar` | Wallet avatar URL |\n| `common.name` | Display name |\n| `common.ens` | ENS domain (EVM chains only) |\n| `common.tag` | Primary wallet tag |\n| `common.tags` | All wallet tags (e.g. `[\"smart_money\"]`) |\n| `common.twitter_username` | Twitter handle |\n| `common.twitter_name` | Twitter display name |\n| `common.followers_count` | Twitter follower count |\n| `common.is_blue_verified` | Twitter blue-verified badge |\n| `common.follow_count` | Number of GMGN users following this wallet |\n| `common.remark_count` | Number of GMGN users who have remarked this wallet |\n| `common.created_token_count` | Tokens created by this wallet |\n| `common.created_at` | Wallet creation time (Unix seconds) — records when the first funding transaction arrived; use this as the wallet's age indicator |\n| `common.fund_from` | Funding source label |\n| `common.fund_from_address` | Address that funded this wallet |\n| `common.fund_amount` | Funding amount |\n\nUse `common.tags` and `common.twitter_username` when building a wallet profile narrative. If `common` is absent in the response, omit identity fields silently — do not report it as an error.\n\n### `portfolio profits` — Key Fields\n\nThe response has a `list` array with one item per wallet. Monetary values are decimal strings; parse them with decimal arithmetic rather than binary floating point when exact calculations matter.\n\n| Field | Description |\n|-------|-------------|\n| `wallet_address` | Wallet address |\n| `realized_profit` | Realized profit in the selected period |\n| `realized_profit_cost` | Cost basis associated with selected-period realized profit |\n| `buy` \u002F `sell` | Buy and sell counts in the selected period |\n| `unrealized_profit` | Unrealized profit on current holdings |\n| `total_realized_profit` | All-time realized profit |\n| `total_realized_profit_cost` | Cost basis associated with all-time realized profit |\n| `total_profit` | Total profit |\n| `total_cost` | Total cost basis |\n\n### `portfolio created-tokens` — Key Fields\n\nThe response `data` object has a `tokens` array plus aggregate stats.\n\nTop-level fields:\n\n| Field | Description |\n|-------|-------------|\n| `last_create_timestamp` | Unix timestamp of the most recent token creation |\n| `inner_count` | Number of tokens still on the bonding curve (NOT graduated) |\n| `open_count` | Number of tokens that have graduated to DEX |\n| `open_ratio` | Graduation rate (string, e.g. `\"0.25\"`) |\n\n> **Total created = `inner_count + open_count`**. Do NOT use `len(tokens)` as the total — the `tokens` array is capped at 100 entries and may be truncated.\n| `creator_ath_info` | Best-performing token created by this wallet (ATH market cap) |\n| `tokens` | Array of created tokens — see below |\n\n`creator_ath_info` fields:\n\n| Field | Description |\n|-------|-------------|\n| `creator` | Wallet address |\n| `ath_token` | Token address with highest ATH market cap |\n| `ath_mc` | ATH market cap (USD string) |\n| `token_symbol` \u002F `token_name` | Token ticker and name |\n| `token_logo` | Logo URL |\n\nPer-token fields (`tokens[*]`):\n\n| Field | Description |\n|-------|-------------|\n| `token_address` | Token contract address |\n| `symbol` | Token ticker |\n| `chain` | Chain name |\n| `create_timestamp` | Unix timestamp of creation |\n| `is_open` | `true` if graduated to DEX |\n| `market_cap` | Current market cap (USD string) |\n| `token_ath_mc` | All-time high market cap (USD string) |\n| `pool_liquidity` | Current liquidity (USD string) |\n| `holders` | Current holder count |\n| `swap_1h` | Swap count in the last hour |\n| `volume_1h` | Trading volume in the last hour (USD string) |\n| `launchpad_platform` | Launch platform name (e.g. `Pump.fun`) |\n| `is_pump` | `true` if launched on Pump.fun |\n| `bundler_rate` | Bundler participation rate (0–1) |\n| `cto_flag` | `true` if community-takeover token |\n\n**Do NOT guess field names not listed here.** If a field appears in the response but is not in this table, do not interpret it without reading the raw output first.\n\n## Output Format\n\n**Do NOT dump raw JSON.** Always parse and present data in the structured formats below. Use `--raw` only when piping to `jq` or further processing.\n\n### `portfolio holdings` — Holdings Table\n\nPresent a table sorted by `usd_value` (descending). Show total portfolio value at the top.\n\n```\nWallet: {wallet} | Chain: {chain}\nTotal value: ~${sum of usd_value across all positions}\n\n# | Token | Balance | USD Value | Total P&L | P&L% | Avg Cost | Buys \u002F Sells\n```\n\nFlag positions where `profit_change` is strongly negative (e.g. \u003C -50%) or positive (e.g. > 200%) with a brief note.\n\n### `portfolio activity` — Activity Feed\n\nPresent as a chronological list (newest first). Use human-readable timestamps.\n\n```\n{type} {token.symbol}  |  {token_amount} tokens  |  ${cost_usd}  |  {timestamp}  |  tx: {short hash}\n```\n\nGroup by token if the user asks about a specific token.\n\n### `portfolio stats` — Stats Summary\n\n```\nWallet: {wallet} | Period: {period}\nRealized P&L:   ${realized_profit}\nUnrealized P&L: ${unrealized_profit}\nWin Rate:        {winrate × 100}%\nTotal Spent:     ${total_cost}\nBuys \u002F Sells:    {buy_count} \u002F {sell_count}\nPnL Ratio:       {pnl}x\n[Identity:       {common.name or common.twitter_username} | Tags: {common.tags}]\n```\n\nShow the `[Identity: ...]` line only if `common` is present in the response. For batch queries (multiple wallets), present one summary block per wallet.\n\n## Notes\n\n- `portfolio holdings` uses **critical auth** (`GMGN_API_KEY` + `GMGN_PRIVATE_KEY` required — CLI signs the request automatically). All other portfolio commands use exist auth (API Key only, no signature required).\n- `portfolio stats` supports multiple `--wallet` flags for batch queries\n- Use `--raw` to get single-line JSON for further processing\n- **Input validation** — Wallet and token addresses are validated against the expected chain format at runtime (sol: base58 32–44 chars; bsc\u002Fbase\u002Feth: `0x` + 40 hex digits). The CLI exits with an error on invalid input.\n- For follow-wallet, KOL, and Smart Money trade records, use the `gmgn-track` skill (`track follow-wallet` \u002F `track kol` \u002F `track smartmoney`)\n\n## Workflow\n\nFor full wallet analysis including trade history and follow-through on top holdings, see [`docs\u002Fworkflow-wallet-analysis.md`](..\u002F..\u002Fdocs\u002Fworkflow-wallet-analysis.md)\n\nFor in-depth trading style analysis, copy-trade ROI estimation, and smart money leaderboard comparison, see [`docs\u002Fworkflow-smart-money-profile.md`](..\u002F..\u002Fdocs\u002Fworkflow-smart-money-profile.md)\n\n**When to use which:**\n- User asks \"is this wallet worth following\" → [`docs\u002Fworkflow-wallet-analysis.md`](..\u002F..\u002Fdocs\u002Fworkflow-wallet-analysis.md)\n- User asks \"what's this wallet's trading style\", \"when does he take profit\", \"smart money profile\", \"if I copied this wallet what would my return be\" → [`docs\u002Fworkflow-smart-money-profile.md`](..\u002F..\u002Fdocs\u002Fworkflow-smart-money-profile.md)\n- User wants to compare multiple smart money wallets by winrate\u002FPnL → [`docs\u002Fworkflow-smart-money-profile.md`](..\u002F..\u002Fdocs\u002Fworkflow-smart-money-profile.md) Step 5 (leaderboard)\n- User asks \"what tokens did this dev create\", \"dev 发过哪些币\", \"查一下这个 dev 的代币\", \"dev 创建记录\" → use `portfolio created-tokens --chain \u003Cchain> --wallet \u003Ccreator_address>` directly. Get the creator address first via `token info` if only a token address is given.\n",{"name":5,"metadata":53,"description":7,"argument-hint":55},{"cliHelp":54},"gmgn-cli portfolio --help","\u003Cinfo|holdings|activity|stats|profits|token-balance|created-tokens> [--chain \u003Csol|bsc|base|eth|arbitrum|hyperevm|robinhood|arc|stable|avalanche>] [--wallet \u003Cwallet_address...>]","main","3df1d0d67b30ff15236561f8c0f9f06d33f42dfd","skills\u002Ftrading\u002Fgmgnai-official-gmgn-portfolio",17,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia","https:\u002F\u002Feth2030.com","Hardcore infra. Building @alt-research and applied cryptography.","2026-11-12 02:28:42",{"source":8,"skillName":5,"commands":66,"prompt":76,"zipAvailable":77},[67,70,73],{"tool":68,"command":69},"npx","npx skills add jiayaoqijia\u002Fcryptoskill --skill gmgn-portfolio",{"tool":71,"command":72},"bunx","bunx skills add jiayaoqijia\u002Fcryptoskill --skill gmgn-portfolio",{"tool":74,"command":75},"pnpm","pnpm dlx skills add jiayaoqijia\u002Fcryptoskill --skill gmgn-portfolio","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Ftrading\u002Fgmgnai-official-gmgn-portfolio\u002FSKILL.md",true,[79,83,89],{"path":80,"resourceType":80,"resourceTypeDesc":81,"sizeBytes":82,"sourceHtmlUrl":16},"LICENSE","许可证",1061,{"path":84,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":87,"sourceHtmlUrl":88},"SOURCE.md","REFERENCE","参考文档",335,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Ftrading\u002Fgmgnai-official-gmgn-portfolio\u002FSOURCE.md",{"path":90,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":91,"sourceHtmlUrl":92},"TRUST.auto.yaml",2248,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Ftrading\u002Fgmgnai-official-gmgn-portfolio\u002FTRUST.auto.yaml",[94,121,143,160,173,183],{"skillNo":95,"name":96,"nameZh":6,"description":97,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":98,"sourceHtmlUrl":99,"categories":100,"keywords":101,"publishedAt":48},"01M712C436EQYE43342Q4E7GG1","recipe-performance","Diagnose a specific MetaMask user flow's real-app performance and Sentry critical-user-flow telemetry with deterministic mm-harness recipes. Use for CUF boundaries, cold\u002Fwarm\u002Fbackground-resume behavior, latency regressions, lifecycle tags, duplicate or blocking network requests, long tasks, layout\u002Fpaint cost, screen redraws, React rerenders, or browser trace analysis where tests alone cannot prove the real app.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fwallets\u002Fmetamask-official-recipe-performance\u002FSKILL.md",[],[47,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120],"recipe performance","recipe","mm","sentry","harness","app","deterministic","recipes","flow","cold","critical","analysis","tasks","react","browser","layout","screen","network","metamask",{"skillNo":122,"name":123,"nameZh":6,"description":124,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":125,"licenseFileUrl":126,"sourceHtmlUrl":127,"categories":128,"keywords":129,"publishedAt":48},"01M70XT2F8A5CQZ81JBP98KSW3","mexc-spot-websocket","MEXC Spot WebSocket workflows for public streams, protobuf handling, depth maintenance, listen keys, and private streams without exposing API keys.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-websocket\u002FSKILL.md",[],[130,131,132,43,133,134,135,136,137,138,139,140,141,142],"mexc spot websocket","spot","websocket","workflows","public","listen","streams","depth","keys","for","api keys","maintenance","protobuf",{"skillNo":144,"name":145,"nameZh":6,"description":146,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":125,"licenseFileUrl":147,"sourceHtmlUrl":148,"categories":149,"keywords":150,"publishedAt":48},"01M70XT0MBXN3WZY1BKN0CPNKR","mexc-spot-rest","MEXC Spot REST workflows for public data, signed account requests, orders, wallet\u002Fadmin actions, and secure signing without exposing API keys.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-spot-rest\u002FSKILL.md",[],[151,131,152,153,154,39,155,140,139,138,156,157,158,134,159,133,43],"mexc spot rest","REST","admin","signing","requests","actions","secure","data","orders",{"skillNo":161,"name":162,"nameZh":6,"description":163,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":125,"licenseFileUrl":164,"sourceHtmlUrl":165,"categories":166,"keywords":167,"publishedAt":48},"01M70XSYSVZ2N0N91XCAR2CAK0","mexc-futures-websocket","MEXC Futures WebSocket workflows for public streams, private account\u002Forder\u002Fposition streams, ping\u002Fpong, subscriptions, and depth maintenance.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fexchanges\u002Fmncrftfrcnm-mexc-futures-websocket\u002FSKILL.md",[],[168,169,132,170,171,141,139,172,137,136,134,133],"mexc futures websocket","futures","position","ping","subscriptions",{"skillNo":174,"name":175,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":176,"sourceHtmlUrl":177,"categories":178,"keywords":179,"publishedAt":48},"01M6H0ZWHVE5W04WG2DKQE2SQC","0xklen-version-and-refresh-sanctions-lists","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-version-and-refresh-sanctions-lists\u002FSKILL.md",[],[180,181,182],"refresh","0xklen version and refresh sanctions lists","version",{"skillNo":184,"name":185,"nameZh":6,"description":186,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":187,"sourceHtmlUrl":188,"categories":189,"keywords":190,"publishedAt":48},"01M6H0Z28Q3R8J0S799GJQWXM3","verify-tests-cover-changed-lines","Use when a PR adds code that the existing suite may not exercise. Measures patch coverage — the share of newly changed lines hit by tests — before approving.","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fpayments\u002F0xklen-verify-tests-cover-changed-lines\u002FSKILL.md",[],[191,192,193,194,195,196,197,198,199,200,201],"tests","cover","verify tests cover changed lines","verify","coverage","pr","exercise","use","patch","code","share"]