From c9dbb6f58b24369662b9ef9d8f7769cf1d8aa0f2 Mon Sep 17 00:00:00 2001 From: David Lau Date: Tue, 17 Mar 2026 14:44:24 +0800 Subject: [PATCH] fix: rename --orderby to --order-by, expand holders/traders options, update chain-specific platform/filter values --- Readme.md | 4 ++-- Readme.zh.md | 4 ++-- docs/cli-usage.md | 12 +++++++++--- package-lock.json | 4 ++-- skills/gmgn-market/SKILL.md | 29 ++++++++++++++--------------- skills/gmgn-portfolio/SKILL.md | 6 ++++-- skills/gmgn-token/SKILL.md | 20 ++++++++++++++++++-- src/client/OpenApiClient.ts | 8 ++++---- src/commands/market.ts | 8 ++++---- src/commands/portfolio.ts | 2 +- src/commands/token.ts | 22 ++++++++++++++++++++-- 11 files changed, 80 insertions(+), 39 deletions(-) diff --git a/Readme.md b/Readme.md index 509dce8..7718ac8 100644 --- a/Readme.md +++ b/Readme.md @@ -162,7 +162,7 @@ token info (confirm token) → portfolio token-balance (check funds) → swa **Discover trading opportunities via trending:** ``` -market trending (top 50, score-ranked) → AI selects top 5 by multi-factor analysis → user reviews → token info / token security → swap +market trending (top 50) → AI selects top 5 by multi-factor analysis → user reviews → token info / token security → swap ``` --- @@ -183,7 +183,7 @@ npx gmgn-cli token info --chain sol --address npx gmgn-cli market trending \ --chain sol \ --interval 1h \ - --orderby volume --limit 20 \ + --order-by volume --limit 20 \ --filter not_risk --filter not_honeypot ``` diff --git a/Readme.zh.md b/Readme.zh.md index b1adfe5..2f48990 100644 --- a/Readme.zh.md +++ b/Readme.zh.md @@ -162,7 +162,7 @@ token info(确认 Token) → portfolio token-balance(检查余额) **通过 Trending 发现交易机会:** ``` -market trending(取 50 条,按 score 排序) → AI 多维度分析选出 top 5 → 用户确认 → token info / token security → swap +market trending(取 50 条) → AI 多维度分析选出 top 5 → 用户确认 → token info / token security → swap ``` --- @@ -183,7 +183,7 @@ npx gmgn-cli token info --chain sol --address npx gmgn-cli market trending \ --chain sol \ --interval 1h \ - --orderby volume --limit 20 \ + --order-by volume --limit 20 \ --filter not_risk --filter not_honeypot ``` diff --git a/docs/cli-usage.md b/docs/cli-usage.md index 742eb7f..f08bd34 100644 --- a/docs/cli-usage.md +++ b/docs/cli-usage.md @@ -116,7 +116,7 @@ npx gmgn-cli market trending \ --chain \ --interval \ [--limit ] \ - [--orderby ] \ + [--order-by ] \ [--direction asc|desc] \ [--filter ] \ [--platform ] \ @@ -128,10 +128,16 @@ npx gmgn-cli market trending \ | `--chain` | Yes | `sol` / `bsc` / `base` | | `--interval` | Yes | `1h` / `3h` / `6h` / `24h` | | `--limit` | No | Number of results (default 100, max 100) | -| `--orderby` | No | Sort field: `score` / `volume` / `swaps` / `liquidity` / `marketcap` / `holders` / `price` / `change` / `change1m` / `change5m` / `change1h` / `renowned_count` / `smart_degen_count` / `bluechip_owner_percentage` / `rank` / `creation_timestamp` / `square_mentions` / `history_highest_market_cap` / `gas_fee` | +| `--order-by` | No | Sort field: `volume` / `swaps` / `liquidity` / `marketcap` / `holders` / `price` / `change` / `change1m` / `change5m` / `change1h` / `renowned_count` / `smart_degen_count` / `bluechip_owner_percentage` / `rank` / `creation_timestamp` / `square_mentions` / `history_highest_market_cap` / `gas_fee` | | `--direction` | No | Sort direction: `asc` / `desc` (default `desc`) | | `--filter` | No | Filter tag (repeatable): `has_social` / `not_risk` / `not_honeypot` / `verified` / `locked` / `renounced` / `distributed` / `frozen` / `burn` / `token_burnt` / `creator_hold` / `creator_close` / `creator_add_liquidity` / `creator_remove_liquidity` / `creator_sell` / `creator_buy` / `not_wash_trading` / `not_social_dup` / `not_image_dup` / `is_internal_market` / `is_out_market` | -| `--platform` | No | Platform filter (repeatable): `pump` / `moonshot` / `launchlab` | +| `--platform` | No | Platform filter (repeatable). Omit (or pass an empty list) to include **all** platforms. Available values depend on chain — see below. | + +**`sol` platforms:** `Pump.fun` / `pump_mayhem` / `pump_mayhem_agent` / `pump_agent` / `letsbonk` / `bonkers` / `bags` / `memoo` / `liquid` / `bankr` / `zora` / `surge` / `anoncoin` / `moonshot_app` / `wendotdev` / `heaven` / `sugar` / `token_mill` / `believe` / `trendsfun` / `trends_fun` / `jup_studio` / `Moonshot` / `boop` / `xstocks` / `ray_launchpad` / `meteora_virtual_curve` / `pool_ray` / `pool_meteora` / `pool_pump_amm` / `pool_orca` + +**`bsc` platforms:** `fourmeme` / `fourmeme_agent` / `bn_fourmeme` / `flap` / `clanker` / `lunafun` / `pool_uniswap` / `pool_pancake` + +**`base` platforms:** `clanker` / `bankr` / `flaunch` / `zora` / `zora_creator` / `baseapp` / `basememe` / `virtuals_v2` / `klik` --- diff --git a/package-lock.json b/package-lock.json index d9ae8a3..e04d6ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "gmgn-cli", - "version": "1.0.0", + "version": "1.0.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "gmgn-cli", - "version": "1.0.0", + "version": "1.0.1", "license": "MIT", "dependencies": { "commander": "^12.1.0", diff --git a/skills/gmgn-market/SKILL.md b/skills/gmgn-market/SKILL.md index 613379a..ae89cf9 100644 --- a/skills/gmgn-market/SKILL.md +++ b/skills/gmgn-market/SKILL.md @@ -44,10 +44,10 @@ Use the `gmgn-cli` tool to query K-line data for a token or browse trending toke | `--chain` | Required. `sol` / `bsc` / `base` | | `--interval` | Required. `1h` / `3h` / `6h` / `24h` | | `--limit ` | Number of results (default 100, max 100) | -| `--orderby ` | Sort field: `score` / `volume` / `swaps` / `liquidity` / `marketcap` / `holders` / `price` / `change` / `change1m` / `change5m` / `change1h` / `renowned_count` / `smart_degen_count` / `bluechip_owner_percentage` / `rank` / `creation_timestamp` / `square_mentions` / `history_highest_market_cap` / `gas_fee` | +| `--order-by ` | Sort field: `default` / `swaps` / `marketcap` / `history_highest_market_cap` / `liquidity` / `volume` / `holder_count` / `smart_degen_count` / `renowned_count` / `gas_fee` / `price` / `change1m` / `change5m` / `change1h` / `creation_timestamp` | | `--direction ` | Sort direction (default `desc`) | -| `--filter ` | Repeatable filter tags: `has_social` / `not_risk` / `not_honeypot` / `verified` / `locked` / `renounced` / `distributed` / `frozen` / `burn` / `token_burnt` / `creator_hold` / `creator_close` / `creator_add_liquidity` / `creator_remove_liquidity` / `creator_sell` / `creator_buy` / `not_wash_trading` / `not_social_dup` / `not_image_dup` / `is_internal_market` / `is_out_market` | -| `--platform ` | Repeatable platform filter: `pump` / `moonshot` / `launchlab` | +| `--filter ` | Repeatable filter tags (chain-specific). **sol** (defaults: `renounced frozen`): `renounced` / `frozen` / `burn` / `token_burnt` / `has_social` / `not_social_dup` / `not_image_dup` / `dexscr_update_link` / `not_wash_trading` / `is_internal_market` / `is_out_market`. **evm** (defaults: `not_honeypot verified renounced`): `not_honeypot` / `verified` / `renounced` / `locked` / `token_burnt` / `has_social` / `not_social_dup` / `not_image_dup` / `dexscr_update_link` / `is_internal_market` / `is_out_market` | +| `--platform ` | Repeatable platform filter (chain-specific). **sol**: `Pump.fun` / `pump_mayhem` / `pump_mayhem_agent` / `pump_agent` / `letsbonk` / `bonkers` / `bags` / `memoo` / `liquid` / `bankr` / `zora` / `surge` / `anoncoin` / `moonshot_app` / `wendotdev` / `heaven` / `sugar` / `token_mill` / `believe` / `trendsfun` / `trends_fun` / `jup_studio` / `Moonshot` / `boop` / `xstocks` / `ray_launchpad` / `meteora_virtual_curve` / `pool_ray` / `pool_meteora` / `pool_pump_amm` / `pool_orca`. **bsc**: `fourmeme` / `fourmeme_agent` / `bn_fourmeme` / `flap` / `clanker` / `lunafun` / `pool_uniswap` / `pool_pancake`. **base**: `clanker` / `bankr` / `flaunch` / `zora` / `zora_creator` / `baseapp` / `basememe` / `virtuals_v2` / `klik` | ## Usage Examples @@ -73,15 +73,15 @@ gmgn-cli market kline \ # Linux: use $(date -d '24 hours ago' +%s) instead of $(date -v-24H +%s) # Top 20 hot tokens on SOL in the last 1 hour, sorted by volume -gmgn-cli market trending --chain sol --interval 1h --orderby volume --limit 20 +gmgn-cli market trending --chain sol --interval 1h --order-by volume --limit 20 -# Hot tokens with social links only, not risky, on BSC over 24h +# Hot tokens with social links only, verified and not honeypot, on BSC over 24h gmgn-cli market trending \ --chain bsc --interval 24h \ - --filter has_social --filter not_risk + --filter has_social --filter not_honeypot --filter verified -# Pump platform tokens on SOL, last 6 hours -gmgn-cli market trending --chain sol --interval 6h --platform pump +# Pump.fun platform tokens on SOL, last 6 hours +gmgn-cli market trending --chain sol --interval 6h --platform Pump.fun # Raw output for further processing gmgn-cli market kline --chain sol --address \ @@ -92,13 +92,13 @@ gmgn-cli market kline --chain sol --address \ ### Step 1 — Fetch trending data -Fetch a broad pool with safe filters, sorted by GMGN's composite score: +Fetch a broad pool with safe filters: ```bash gmgn-cli market trending \ --chain --interval 1h \ - --orderby score --limit 50 \ - --filter not_risk --filter not_honeypot --filter has_social --raw + --order-by volume --limit 50 \ + --filter not_honeypot --filter has_social --raw ``` ### Step 2 — AI multi-factor analysis @@ -107,7 +107,6 @@ Analyze each record in the response using the following signals (apply judgment, | Signal | Field(s) | Weight | Notes | |--------|----------|--------|-------| -| GMGN quality score | `score` | High | Primary ranking signal from GMGN | | Smart money interest | `smart_degen_count`, `renowned_count` | High | Key conviction indicator | | Bluechip ownership | `bluechip_owner_percentage` | Medium | Quality of holder base | | Real trading activity | `volume`, `swaps` | Medium | Distinguishes genuine interest from wash trading | @@ -115,7 +114,7 @@ Analyze each record in the response using the following signals (apply judgment, | Pool safety | `liquidity` | Medium | Low liquidity = high slippage risk | | Token maturity | `creation_timestamp` | Low | Avoid tokens less than ~1h old unless other signals are very strong | -Select the **top 5** tokens with the best composite profile. Prefer tokens that score well across multiple signals rather than excelling in just one. +Select the **top 5** tokens with the best composite profile. Prefer tokens that perform well across multiple signals rather than excelling in just one. ### Step 3 — Present top 5 to user @@ -124,8 +123,8 @@ Present results as a concise table, then give a one-line rationale for each pick ``` Top 5 Trending Tokens — SOL / 1h -# | Symbol | Address (short) | Score | Smart Degens | Volume | 1h Chg | Reasoning -1 | ... | ... | ... | ... | ... | ... | High score + smart money accumulating +# | Symbol | Address (short) | Smart Degens | Volume | 1h Chg | Reasoning +1 | ... | ... | ... | ... | ... | Smart money accumulating + high volume 2 | ... ... ``` diff --git a/skills/gmgn-portfolio/SKILL.md b/skills/gmgn-portfolio/SKILL.md index 94261b1..9dcbfa4 100644 --- a/skills/gmgn-portfolio/SKILL.md +++ b/skills/gmgn-portfolio/SKILL.md @@ -75,7 +75,7 @@ gmgn-cli portfolio token-balance \ |--------|-------------| | `--limit ` | Page size (default `20`, max 50) | | `--cursor ` | Pagination cursor | -| `--order-by ` | Sort field: `usd_value` / `price` / `unrealized_profit` / `realized_profit` / `total_profit` / `history_bought_cost` / `history_sold_income` (default `usd_value`) | +| `--order-by ` | Sort field: `usd_value` / `last_active_timestamp` / `realized_profit` / `unrealized_profit` / `total_profit` / `history_bought_cost` / `history_sold_income` (default `usd_value`) | | `--direction ` | Sort direction (default `desc`) | | `--sell-out` | Include sold-out positions | | `--show-small` | Include small-value positions | @@ -90,9 +90,11 @@ gmgn-cli portfolio token-balance \ |--------|-------------| | `--token
` | Filter by token | | `--limit ` | Page size | -| `--cursor ` | Pagination cursor | +| `--cursor ` | Pagination cursor (pass the `next` value from the previous response) | | `--type ` | Repeatable: `buy` / `sell` / `add` / `remove` / `transfer` | +The activity response includes a `next` field. Pass it to `--cursor` to fetch the next page. + ## Stats Options | Option | Description | diff --git a/skills/gmgn-token/SKILL.md b/skills/gmgn-token/SKILL.md index a695918..04c1103 100644 --- a/skills/gmgn-token/SKILL.md +++ b/skills/gmgn-token/SKILL.md @@ -26,6 +26,24 @@ Use the `gmgn-cli` tool to query token information based on the user's request. - Run from the directory where your `.env` file is located, or set `GMGN_HOST` in your environment - `gmgn-cli` installed globally: `npm install -g gmgn-cli@1.0.1` +## Info / Security / Pool Options + +| Option | Description | +|--------|-------------| +| `--chain` | Required. `sol` / `bsc` / `base` | +| `--address` | Required. Token contract address | + +## Holders / Traders Options + +| Option | Description | +|--------|-------------| +| `--chain` | Required. `sol` / `bsc` / `base` | +| `--address` | Required. Token contract address | +| `--limit ` | Number of results (default `20`, max `100`) | +| `--order-by ` | Sort field: `amount_percentage` / `profit` / `unrealized_profit` / `buy_volume_cur` / `sell_volume_cur` (default `amount_percentage`) | +| `--direction ` | Sort direction (default `desc`) | +| `--tag ` | Wallet tag filter: `renowned` / `smart_degen` (default `renowned`) | + ## Usage Examples ```bash @@ -39,11 +57,9 @@ gmgn-cli token security --chain sol --address gmgn-cli token pool --chain sol --address # Top holders -gmgn-cli token holders --chain sol --address gmgn-cli token holders --chain sol --address --limit 50 # Top traders -gmgn-cli token traders --chain sol --address gmgn-cli token traders --chain sol --address --limit 50 # Raw JSON output (for piping) diff --git a/src/client/OpenApiClient.ts b/src/client/OpenApiClient.ts index 2224295..3158966 100644 --- a/src/client/OpenApiClient.ts +++ b/src/client/OpenApiClient.ts @@ -61,12 +61,12 @@ export class OpenApiClient { return this.normalRequest("GET", "/v1/token/pool_info", { chain, address }); } - async getTokenTopHolders(chain: string, address: string): Promise { - return this.normalRequest("GET", "/v1/market/token_top_holders", { chain, address }); + async getTokenTopHolders(chain: string, address: string, extra: Record = {}): Promise { + return this.normalRequest("GET", "/v1/market/token_top_holders", { chain, address, ...extra }); } - async getTokenTopTraders(chain: string, address: string): Promise { - return this.normalRequest("GET", "/v1/market/token_top_traders", { chain, address }); + async getTokenTopTraders(chain: string, address: string, extra: Record = {}): Promise { + return this.normalRequest("GET", "/v1/market/token_top_traders", { chain, address, ...extra }); } // ---- Market endpoints (normal auth) ---- diff --git a/src/commands/market.ts b/src/commands/market.ts index c1dbbd9..39475da 100644 --- a/src/commands/market.ts +++ b/src/commands/market.ts @@ -32,16 +32,16 @@ export function registerMarketCommands(program: Command): void { .requiredOption("--chain ", "Chain: sol / bsc / base") .requiredOption("--interval ", "Time interval: 1h / 3h / 6h / 24h") .option("--limit ", "Number of results (default 100, max 100)", parseInt) - .option("--orderby ", "Sort field: score / volume / swaps / liquidity / marketcap / holders / price / change / ...") + .option("--order-by ", "Sort field: default / volume / swaps / marketcap / holder_count / price / change1h / ... (see docs for full list)") .option("--direction ", "Sort direction: asc / desc") - .option("--filter ", "Filter tags, repeatable: has_social / not_risk / not_honeypot / verified / locked / renounced / ...") - .option("--platform ", "Platform filter, repeatable: pump / moonshot / ...") + .option("--filter ", "Filter tags, repeatable. sol: renounced / frozen / has_social / not_wash_trading / ... evm: not_honeypot / verified / renounced / locked / ... (see docs for full list)") + .option("--platform ", "Platform filter, repeatable. sol: Pump.fun / letsbonk / moonshot_app / ... bsc: fourmeme / flap / clanker / ... base: clanker / flaunch / zora / ... (see docs for full list)") .option("--raw", "Output raw JSON") .action(async (opts) => { validateChain(opts.chain); const extra: Record = {}; if (opts.limit != null) extra["limit"] = opts.limit; - if (opts.orderby) extra["order_by"] = opts.orderby; + if (opts.orderBy) extra["order_by"] = opts.orderBy; if (opts.direction) extra["direction"] = opts.direction; if (opts.filter?.length) extra["filters"] = opts.filter; if (opts.platform?.length) extra["platforms"] = opts.platform; diff --git a/src/commands/portfolio.ts b/src/commands/portfolio.ts index d187131..b140d06 100644 --- a/src/commands/portfolio.ts +++ b/src/commands/portfolio.ts @@ -14,7 +14,7 @@ export function registerPortfolioCommands(program: Command): void { .requiredOption("--wallet
", "Wallet address") .option("--limit ", "Page size (default 20, max 50)", parseInt, 20) .option("--cursor ", "Pagination cursor") - .option("--order-by ", "Sort field: usd_value / price / price_change / unrealized_profit / realized_profit / ...", "usd_value") + .option("--order-by ", "Sort field: usd_value / last_active_timestamp / realized_profit / unrealized_profit / total_profit / history_bought_cost / history_sold_income", "usd_value") .option("--direction ", "Sort direction: asc / desc", "desc") .option("--interval ", "Stats interval (default 24h)") .option("--sell-out", "Include sold-out positions") diff --git a/src/commands/token.ts b/src/commands/token.ts index 780e14a..559a56b 100644 --- a/src/commands/token.ts +++ b/src/commands/token.ts @@ -54,12 +54,21 @@ export function registerTokenCommands(program: Command): void { .description("Get top token holders") .requiredOption("--chain ", "Chain: sol / bsc / base") .requiredOption("--address
", "Token contract address") + .option("--limit ", "Number of results (default 20, max 100)", parseInt) + .option("--order-by ", "Sort field: amount_percentage / profit / unrealized_profit / buy_volume_cur / sell_volume_cur", "amount_percentage") + .option("--direction ", "Sort direction: asc / desc", "desc") + .option("--tag ", "Wallet tag filter: renowned / smart_degen", "renowned") .option("--raw", "Output raw JSON") .action(async (opts) => { validateChain(opts.chain); validateAddress(opts.address, opts.chain, "--address"); + const extra: Record = {}; + if (opts.limit != null) extra["limit"] = opts.limit; + if (opts.orderBy) extra["order_by"] = opts.orderBy; + if (opts.direction) extra["direction"] = opts.direction; + if (opts.tag) extra["tag"] = opts.tag; const client = new OpenApiClient(getConfig()); - const data = await client.getTokenTopHolders(opts.chain, opts.address).catch(exitOnError); + const data = await client.getTokenTopHolders(opts.chain, opts.address, extra).catch(exitOnError); printResult(data, opts.raw); }); @@ -68,12 +77,21 @@ export function registerTokenCommands(program: Command): void { .description("Get top token traders") .requiredOption("--chain ", "Chain: sol / bsc / base") .requiredOption("--address
", "Token contract address") + .option("--limit ", "Number of results (default 20, max 100)", parseInt) + .option("--order-by ", "Sort field: amount_percentage / profit / unrealized_profit / buy_volume_cur / sell_volume_cur", "amount_percentage") + .option("--direction ", "Sort direction: asc / desc", "desc") + .option("--tag ", "Wallet tag filter: renowned / smart_degen", "renowned") .option("--raw", "Output raw JSON") .action(async (opts) => { validateChain(opts.chain); validateAddress(opts.address, opts.chain, "--address"); + const extra: Record = {}; + if (opts.limit != null) extra["limit"] = opts.limit; + if (opts.orderBy) extra["order_by"] = opts.orderBy; + if (opts.direction) extra["direction"] = opts.direction; + if (opts.tag) extra["tag"] = opts.tag; const client = new OpenApiClient(getConfig()); - const data = await client.getTokenTopTraders(opts.chain, opts.address).catch(exitOnError); + const data = await client.getTokenTopTraders(opts.chain, opts.address, extra).catch(exitOnError); printResult(data, opts.raw); }); }