From db55c77a26c63ce6accfbd3f999f537e7d546935 Mon Sep 17 00:00:00 2001 From: David Lau Date: Tue, 14 Apr 2026 16:37:00 +0800 Subject: [PATCH] feat(portfolio): add created-tokens command for developer wallet token history Add GET /v1/user/created_tokens support: portfolio created-tokens CLI command, OpenApiClient method, SKILL.md docs, cli-usage.md, and Readme examples. Co-Authored-By: Claude Sonnet 4.6 --- Readme.md | 3 ++ Readme.zh.md | 3 ++ docs/cli-usage.md | 24 ++++++++++++ skills/gmgn-portfolio/SKILL.md | 71 +++++++++++++++++++++++++++++++++- src/client/OpenApiClient.ts | 4 ++ src/commands/portfolio.ts | 21 ++++++++++ 6 files changed, 124 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 32274e7..45485a2 100644 --- a/Readme.md +++ b/Readme.md @@ -490,6 +490,9 @@ gmgn-cli portfolio info # Single token balance gmgn-cli portfolio token-balance --chain sol --wallet --token + +# Tokens created by a developer wallet +gmgn-cli portfolio created-tokens --chain sol --wallet ``` ### Track diff --git a/Readme.zh.md b/Readme.zh.md index 447ea38..fdc1a02 100644 --- a/Readme.zh.md +++ b/Readme.zh.md @@ -521,6 +521,9 @@ gmgn-cli portfolio info # 单个 token 余额 gmgn-cli portfolio token-balance --chain sol --wallet --token + +# 查询开发者钱包创建的代币列表 +gmgn-cli portfolio created-tokens --chain sol --wallet ``` ### Track diff --git a/docs/cli-usage.md b/docs/cli-usage.md index 510d7ef..c5a9fc6 100644 --- a/docs/cli-usage.md +++ b/docs/cli-usage.md @@ -255,6 +255,30 @@ npx gmgn-cli portfolio token-balance \ --- +## portfolio created-tokens + +Query tokens created by a developer wallet. + +```bash +npx gmgn-cli portfolio created-tokens \ + --chain \ + --wallet \ + [--order-by ] \ + [--direction asc|desc] \ + [--migrate-state ] \ + [--raw] +``` + +| Option | Required | Description | +|--------|----------|-------------| +| `--chain` | Yes | `sol` / `bsc` / `base` | +| `--wallet` | Yes | Developer wallet address | +| `--order-by` | No | Sort field: `market_cap` / `token_ath_mc` | +| `--direction` | No | Sort direction: `asc` / `desc` | +| `--migrate-state` | No | Filter: `migrated` / `non_migrated` | + +--- + ## market trenches Query Trenches token lists (new creation, near completion, completed). diff --git a/skills/gmgn-portfolio/SKILL.md b/skills/gmgn-portfolio/SKILL.md index e8118cb..346def9 100644 --- a/skills/gmgn-portfolio/SKILL.md +++ b/skills/gmgn-portfolio/SKILL.md @@ -1,7 +1,7 @@ --- name: gmgn-portfolio -description: Query GMGN wallet portfolio — API Key wallet info, holdings, transaction activity, trading stats, and token balance. Supports sol / bsc / base. -argument-hint: " [--chain ] [--wallet ]" +description: Query GMGN wallet portfolio — API Key wallet info, holdings, transaction activity, trading stats, token balance, and developer-created tokens. Supports sol / bsc / base. +argument-hint: " [--chain ] [--wallet ]" metadata: cliHelp: "gmgn-cli portfolio --help" --- @@ -39,6 +39,7 @@ Use the `gmgn-cli` tool to query wallet portfolio data based on the user's reque | `portfolio activity` | Transaction history | | `portfolio stats` | Trading statistics (supports batch) | | `portfolio token-balance` | Token balance for a specific token | +| `portfolio created-tokens` | Tokens created by a developer wallet, with market cap and ATH info | ## Supported Chains @@ -60,6 +61,7 @@ All portfolio routes used by this skill go through GMGN's leaky-bucket limiter w | `portfolio activity` | `GET /v1/user/wallet_activity` | 3 | | `portfolio stats` | `GET /v1/user/wallet_stats` | 3 | | `portfolio token-balance` | `GET /v1/user/wallet_token_balance` | 1 | +| `portfolio created-tokens` | `GET /v1/user/created_tokens` | 2 | When a request returns `429`: @@ -125,8 +127,28 @@ gmgn-cli portfolio stats --chain sol \ # Token balance gmgn-cli portfolio token-balance \ --chain sol --wallet --token + +# Tokens created by a developer wallet +gmgn-cli portfolio created-tokens --chain sol --wallet + +# Created tokens sorted by all-time high market cap +gmgn-cli portfolio created-tokens \ + --chain sol --wallet \ + --order-by token_ath_mc --direction desc + +# Only migrated tokens +gmgn-cli portfolio created-tokens \ + --chain sol --wallet --migrate-state migrated ``` +## `portfolio created-tokens` Options + +| Option | Description | +|--------|-------------| +| `--order-by ` | Sort field: `market_cap` / `token_ath_mc` | +| `--direction ` | Sort direction (default `desc`) | +| `--migrate-state ` | Filter by migration status: `migrated` (graduated to DEX) / `non_migrated` (still on bonding curve) | + ## `portfolio holdings` Options | Option | Description | @@ -235,6 +257,51 @@ The response also includes a `common` object when available (absent if the upstr Use `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. +### `portfolio created-tokens` — Key Fields + +The response `data` object has a `tokens` array plus aggregate stats. + +Top-level fields: + +| Field | Description | +|-------|-------------| +| `last_create_timestamp` | Unix timestamp of the most recent token creation | +| `inner_count` | Number of tokens still on the bonding curve | +| `open_count` | Number of tokens that have graduated to DEX | +| `open_ratio` | Graduation rate (string, e.g. `"0.25"`) | +| `creator_ath_info` | Best-performing token created by this wallet (ATH market cap) | +| `tokens` | Array of created tokens — see below | + +`creator_ath_info` fields: + +| Field | Description | +|-------|-------------| +| `creator` | Wallet address | +| `ath_token` | Token address with highest ATH market cap | +| `ath_mc` | ATH market cap (USD string) | +| `token_symbol` / `token_name` | Token ticker and name | +| `token_logo` | Logo URL | + +Per-token fields (`tokens[*]`): + +| Field | Description | +|-------|-------------| +| `token_address` | Token contract address | +| `symbol` | Token ticker | +| `chain` | Chain name | +| `create_timestamp` | Unix timestamp of creation | +| `is_open` | `true` if graduated to DEX | +| `market_cap` | Current market cap (USD string) | +| `token_ath_mc` | All-time high market cap (USD string) | +| `pool_liquidity` | Current liquidity (USD string) | +| `holders` | Current holder count | +| `swap_1h` | Swap count in the last hour | +| `volume_1h` | Trading volume in the last hour (USD string) | +| `launchpad_platform` | Launch platform name (e.g. `Pump.fun`) | +| `is_pump` | `true` if launched on Pump.fun | +| `bundler_rate` | Bundler participation rate (0–1) | +| `cto_flag` | `true` if community-takeover token | + **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. ## Output Format diff --git a/src/client/OpenApiClient.ts b/src/client/OpenApiClient.ts index 7fe356d..5122f90 100644 --- a/src/client/OpenApiClient.ts +++ b/src/client/OpenApiClient.ts @@ -308,6 +308,10 @@ export class OpenApiClient { return this.normalRequest("GET", "/v1/user/smartmoney", query); } + async getCreatedTokens(chain: string, walletAddress: string, extra: Record = {}): Promise { + return this.normalRequest("GET", "/v1/user/created_tokens", { chain, wallet_address: walletAddress, ...extra }); + } + async quoteOrder( chain: string, from_address: string, diff --git a/src/commands/portfolio.ts b/src/commands/portfolio.ts index f273757..2a4d821 100644 --- a/src/commands/portfolio.ts +++ b/src/commands/portfolio.ts @@ -109,5 +109,26 @@ export function registerPortfolioCommands(program: Command): void { printResult(data, opts.raw); }); + portfolio + .command("created-tokens") + .description("Get tokens created by a developer wallet") + .requiredOption("--chain ", "Chain: sol / bsc / base") + .requiredOption("--wallet
", "Developer wallet address") + .option("--order-by ", "Sort field: market_cap / token_ath_mc") + .option("--direction ", "Sort direction: asc / desc") + .option("--migrate-state ", "Filter: migrated / non_migrated") + .option("--raw", "Output raw JSON") + .action(async (opts) => { + validateChain(opts.chain); + validateAddress(opts.wallet, opts.chain, "--wallet"); + const extra: Record = {}; + if (opts.orderBy) extra["order_by"] = opts.orderBy; + if (opts.direction) extra["direction"] = opts.direction; + if (opts.migrateState) extra["migrate_state"] = opts.migrateState; + const client = new OpenApiClient(getConfig()); + const data = await client.getCreatedTokens(opts.chain, opts.wallet, extra).catch(exitOnError); + printResult(data, opts.raw); + }); + }