fix: rename --orderby to --order-by, expand holders/traders options, update chain-specific platform/filter values

This commit is contained in:
David Lau
2026-03-17 14:44:24 +08:00
committed by GMGN.AI
parent d9d1bf8200
commit c9dbb6f58b
11 changed files with 80 additions and 39 deletions
+2 -2
View File
@@ -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 <addr>
npx gmgn-cli market trending \
--chain sol \
--interval 1h \
--orderby volume --limit 20 \
--order-by volume --limit 20 \
--filter not_risk --filter not_honeypot
```
+2 -2
View File
@@ -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 <addr>
npx gmgn-cli market trending \
--chain sol \
--interval 1h \
--orderby volume --limit 20 \
--order-by volume --limit 20 \
--filter not_risk --filter not_honeypot
```
+9 -3
View File
@@ -116,7 +116,7 @@ npx gmgn-cli market trending \
--chain <chain> \
--interval <interval> \
[--limit <n>] \
[--orderby <field>] \
[--order-by <field>] \
[--direction asc|desc] \
[--filter <tag>] \
[--platform <name>] \
@@ -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`
---
+2 -2
View File
@@ -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",
+14 -15
View File
@@ -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 <n>` | Number of results (default 100, max 100) |
| `--orderby <field>` | 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 <field>` | 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 <asc\|desc>` | Sort direction (default `desc`) |
| `--filter <tag...>` | 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 <name...>` | Repeatable platform filter: `pump` / `moonshot` / `launchlab` |
| `--filter <tag...>` | 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 <name...>` | 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 <addr> \
@@ -92,13 +92,13 @@ gmgn-cli market kline --chain sol --address <addr> \
### 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 <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 | ...
...
```
+4 -2
View File
@@ -75,7 +75,7 @@ gmgn-cli portfolio token-balance \
|--------|-------------|
| `--limit <n>` | Page size (default `20`, max 50) |
| `--cursor <cursor>` | Pagination cursor |
| `--order-by <field>` | Sort field: `usd_value` / `price` / `unrealized_profit` / `realized_profit` / `total_profit` / `history_bought_cost` / `history_sold_income` (default `usd_value`) |
| `--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`) |
| `--sell-out` | Include sold-out positions |
| `--show-small` | Include small-value positions |
@@ -90,9 +90,11 @@ gmgn-cli portfolio token-balance \
|--------|-------------|
| `--token <address>` | Filter by token |
| `--limit <n>` | Page size |
| `--cursor <cursor>` | Pagination cursor |
| `--cursor <cursor>` | Pagination cursor (pass the `next` value from the previous response) |
| `--type <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 |
+18 -2
View File
@@ -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 <n>` | Number of results (default `20`, max `100`) |
| `--order-by <field>` | Sort field: `amount_percentage` / `profit` / `unrealized_profit` / `buy_volume_cur` / `sell_volume_cur` (default `amount_percentage`) |
| `--direction <asc\|desc>` | Sort direction (default `desc`) |
| `--tag <tag>` | Wallet tag filter: `renowned` / `smart_degen` (default `renowned`) |
## Usage Examples
```bash
@@ -39,11 +57,9 @@ gmgn-cli token security --chain sol --address <token_address>
gmgn-cli token pool --chain sol --address <token_address>
# Top holders
gmgn-cli token holders --chain sol --address <token_address>
gmgn-cli token holders --chain sol --address <token_address> --limit 50
# Top traders
gmgn-cli token traders --chain sol --address <token_address>
gmgn-cli token traders --chain sol --address <token_address> --limit 50
# Raw JSON output (for piping)
+4 -4
View File
@@ -61,12 +61,12 @@ export class OpenApiClient {
return this.normalRequest("GET", "/v1/token/pool_info", { chain, address });
}
async getTokenTopHolders(chain: string, address: string): Promise<unknown> {
return this.normalRequest("GET", "/v1/market/token_top_holders", { chain, address });
async getTokenTopHolders(chain: string, address: string, extra: Record<string, string | number> = {}): Promise<unknown> {
return this.normalRequest("GET", "/v1/market/token_top_holders", { chain, address, ...extra });
}
async getTokenTopTraders(chain: string, address: string): Promise<unknown> {
return this.normalRequest("GET", "/v1/market/token_top_traders", { chain, address });
async getTokenTopTraders(chain: string, address: string, extra: Record<string, string | number> = {}): Promise<unknown> {
return this.normalRequest("GET", "/v1/market/token_top_traders", { chain, address, ...extra });
}
// ---- Market endpoints (normal auth) ----
+4 -4
View File
@@ -32,16 +32,16 @@ export function registerMarketCommands(program: Command): void {
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--interval <interval>", "Time interval: 1h / 3h / 6h / 24h")
.option("--limit <n>", "Number of results (default 100, max 100)", parseInt)
.option("--orderby <field>", "Sort field: score / volume / swaps / liquidity / marketcap / holders / price / change / ...")
.option("--order-by <field>", "Sort field: default / volume / swaps / marketcap / holder_count / price / change1h / ... (see docs for full list)")
.option("--direction <dir>", "Sort direction: asc / desc")
.option("--filter <tag...>", "Filter tags, repeatable: has_social / not_risk / not_honeypot / verified / locked / renounced / ...")
.option("--platform <name...>", "Platform filter, repeatable: pump / moonshot / ...")
.option("--filter <tag...>", "Filter tags, repeatable. sol: renounced / frozen / has_social / not_wash_trading / ... evm: not_honeypot / verified / renounced / locked / ... (see docs for full list)")
.option("--platform <name...>", "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<string, string | number | string[]> = {};
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;
+1 -1
View File
@@ -14,7 +14,7 @@ export function registerPortfolioCommands(program: Command): void {
.requiredOption("--wallet <address>", "Wallet address")
.option("--limit <n>", "Page size (default 20, max 50)", parseInt, 20)
.option("--cursor <cursor>", "Pagination cursor")
.option("--order-by <field>", "Sort field: usd_value / price / price_change / unrealized_profit / realized_profit / ...", "usd_value")
.option("--order-by <field>", "Sort field: usd_value / last_active_timestamp / realized_profit / unrealized_profit / total_profit / history_bought_cost / history_sold_income", "usd_value")
.option("--direction <dir>", "Sort direction: asc / desc", "desc")
.option("--interval <interval>", "Stats interval (default 24h)")
.option("--sell-out", "Include sold-out positions")
+20 -2
View File
@@ -54,12 +54,21 @@ export function registerTokenCommands(program: Command): void {
.description("Get top token holders")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--address <address>", "Token contract address")
.option("--limit <n>", "Number of results (default 20, max 100)", parseInt)
.option("--order-by <field>", "Sort field: amount_percentage / profit / unrealized_profit / buy_volume_cur / sell_volume_cur", "amount_percentage")
.option("--direction <dir>", "Sort direction: asc / desc", "desc")
.option("--tag <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<string, string | number> = {};
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>", "Chain: sol / bsc / base")
.requiredOption("--address <address>", "Token contract address")
.option("--limit <n>", "Number of results (default 20, max 100)", parseInt)
.option("--order-by <field>", "Sort field: amount_percentage / profit / unrealized_profit / buy_volume_cur / sell_volume_cur", "amount_percentage")
.option("--direction <dir>", "Sort direction: asc / desc", "desc")
.option("--tag <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<string, string | number> = {};
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);
});
}