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 <noreply@anthropic.com>
This commit is contained in:
David Lau
2026-04-14 16:43:25 +08:00
co-authored by Claude Sonnet 4.6
parent 91473cc366
commit db55c77a26
6 changed files with 124 additions and 2 deletions
+3
View File
@@ -490,6 +490,9 @@ gmgn-cli portfolio info
# Single token balance
gmgn-cli portfolio token-balance --chain sol --wallet <addr> --token <token_addr>
# Tokens created by a developer wallet
gmgn-cli portfolio created-tokens --chain sol --wallet <addr>
```
### Track
+3
View File
@@ -521,6 +521,9 @@ gmgn-cli portfolio info
# 单个 token 余额
gmgn-cli portfolio token-balance --chain sol --wallet <addr> --token <token_addr>
# 查询开发者钱包创建的代币列表
gmgn-cli portfolio created-tokens --chain sol --wallet <addr>
```
### Track
+24
View File
@@ -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 <chain> \
--wallet <wallet_address> \
[--order-by <field>] \
[--direction asc|desc] \
[--migrate-state <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).
+69 -2
View File
@@ -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: "<info|holdings|activity|stats|token-balance> [--chain <sol|bsc|base>] [--wallet <wallet_address>]"
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: "<info|holdings|activity|stats|token-balance|created-tokens> [--chain <sol|bsc|base>] [--wallet <wallet_address>]"
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 <wallet_address> --token <token_address>
# Tokens created by a developer wallet
gmgn-cli portfolio created-tokens --chain sol --wallet <wallet_address>
# Created tokens sorted by all-time high market cap
gmgn-cli portfolio created-tokens \
--chain sol --wallet <wallet_address> \
--order-by token_ath_mc --direction desc
# Only migrated tokens
gmgn-cli portfolio created-tokens \
--chain sol --wallet <wallet_address> --migrate-state migrated
```
## `portfolio created-tokens` Options
| Option | Description |
|--------|-------------|
| `--order-by <field>` | Sort field: `market_cap` / `token_ath_mc` |
| `--direction <asc\|desc>` | Sort direction (default `desc`) |
| `--migrate-state <state>` | Filter by migration status: `migrated` (graduated to DEX) / `non_migrated` (still on bonding curve) |
## `portfolio holdings` Options
| Option | Description |
@@ -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 (01) |
| `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
+4
View File
@@ -308,6 +308,10 @@ export class OpenApiClient {
return this.normalRequest("GET", "/v1/user/smartmoney", query);
}
async getCreatedTokens(chain: string, walletAddress: string, extra: Record<string, string | number> = {}): Promise<unknown> {
return this.normalRequest("GET", "/v1/user/created_tokens", { chain, wallet_address: walletAddress, ...extra });
}
async quoteOrder(
chain: string,
from_address: string,
+21
View File
@@ -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>", "Chain: sol / bsc / base")
.requiredOption("--wallet <address>", "Developer wallet address")
.option("--order-by <field>", "Sort field: market_cap / token_ath_mc")
.option("--direction <dir>", "Sort direction: asc / desc")
.option("--migrate-state <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<string, string | number> = {};
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);
});
}