Compare commits

..

118 Commits

Author SHA1 Message Date
David Lau ed58e67180 docs(market): address PR review — ETH trenches docs + created-unit clarity
ETH trenches/trending (SKILL.md, cli-usage.md):
- Add per-chain --launchpad-platform value tables incl. ETH for `market trenches`
- Add ETH trenches usage examples (all / new_creation / completed)
- Rename "Trending — ETH (No Platform Filter)" to "Trending — ETH by Launchpad
  Platform" and add --platform ETH examples (platform list is now supported)

min_created/max_created units (market trending):
- Clarify that the raw upstream rank interface accepts minutes only; the
  openapi-service does NOT forward this field — it evaluates the age window itself
  (cutoff = now - duration, native for m/h/d), so 6h/7d work via this CLI.
- Note a bare number with no unit suffix is rejected. Update --help text and
  code comment accordingly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 21:15:22 +08:00
David Lau ca55a80d12 feat(market): add min/max range filters to trending command
- Register dynamic --min-*/--max-* flags on `market trending`, mirroring the
  trenches pattern; forwarded as min_<metric>/max_<metric> query params to
  /v1/market/rank
- Add RANK_RANGE_FIELDS covering the 18 numeric metrics plus min/max-created
  token-age windows (m/h/d duration strings, passed through as-is)
- Document range filters and web-client filter aliases in SKILL.md, cli-usage.md,
  Readme.md and Readme.zh.md

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 20:30:25 +08:00
David Lau 4205bda0af feat(market): add eth chain support for trenches
- Add eth to TRENCHES_PLATFORMS and TRENCHES_QUOTE_ADDRESS_TYPES
- Allow --chain eth for market trenches
- Document eth platforms in CLI help, SKILL.md, and cli-usage.md

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 16:21:19 +08:00
David Lau 0b140b4a5f feat(market): support 30s kline resolution
- Add 30s to --resolution help text in market kline command
- Sync SKILL.md argument-hint and parameters table
- Sync docs/cli-usage.md resolution values

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 15:00:46 +08:00
GMGN.AI aa74d04839 1.4.7 2026-06-24 16:23:07 +08:00
GMGN.AI 6461d2f8df chore: ignore local Claude Code dev configs 2026-06-24 16:22:55 +08:00
GMGN.AI 22d2ad25d5 Merge pull request #167 from GMGNAI/feat-quote-exist-auth
docs(order-quote): order quote now uses normal auth, no private key needed
2026-06-24 16:21:20 +08:00
David Lau 25f4207351 fix(order-quote): switch quoteOrder to exist auth and update CLI help text
- OpenApiClient.quoteOrder now calls authExistRequest instead of authSignedRequest
- Remove all GMGN_PRIVATE_KEY references from the quote command description and options

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-24 16:13:37 +08:00
David Lau d0ca1b40ce docs(order-quote): order quote now uses normal auth, no private key needed
quote endpoint downgraded to exist auth (API Key only); from_address
no longer needs to match the key's bound wallet. Update all auth
references in cli-usage.md, SKILL.md, and CLAUDE.md.
2026-06-22 16:55:51 +08:00
GMGN.AI 4e54086137 1.4.6 2026-06-18 11:59:38 +08:00
GMGN.AI fcd14effbf Merge pull request #165 from GumpOnchain/feat/add-bsc-launchpad-platforms
feat(bsc): add new BSC launchpad platforms
2026-06-18 11:57:14 +08:00
gumponchain d34315ce98 fix(bsc): update --platform hint text with new BSC launchpad names
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 11:52:04 +08:00
gumponchain b6c4ff50f2 feat(bsc): add new BSC launchpad platforms
Add cubepeg, likwid, goplus_creator, goplus_skills, openfour after
four_xmode_agent; add flap_stocks and flap_aioracle after flap.
Updates both TRENCHES_PLATFORMS defaults and SKILL.md examples.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-18 11:47:18 +08:00
GMGN.AI e6dfca48d8 1.4.5 2026-06-16 11:19:13 +08:00
deepfeature 362d180910 Merge pull request #161 from GMGNAI/feat/add-user-agent-header
feat(client): send User-Agent header on all API requests
2026-06-16 11:13:35 +08:00
deepfeature d5c43eed51 feat(client): send User-Agent header on all API requests
Add a `User-Agent: gmgn-cli/<version>` header (version read from
package.json) to both authExistRequest and authSignedRequest, so
upstream can identify CLI traffic and gateways that reject empty/default
UAs do not block requests.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 11:12:10 +08:00
GMGN.AI 968013ebce Merge pull request #160 from nova-0328/feat/cooking
docs(cooking): clarify Flap fee-share schema and add real-world examples
2026-06-12 15:04:24 +08:00
prodev-nova 3d11f8c6d6 docs(cooking): clarify Flap fee-share schema and add real-world examples
- Correct mkt_bps: it's the tax-recipient share (X handle in gift mode or
  split_conf addresses in split mode), not a generic "marketing" fund
- Make twitter_account / split_conf conditional-required based on recipient_type
  instead of always required
- Add two end-to-end Flap examples (split mode → BSC address, gift mode → X handle)
- Merge "Full worked examples" into the Usage Examples section

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 14:54:11 +08:00
GMGN.AI f15e8271f9 1.4.4 2026-06-11 12:07:35 +08:00
GMGN.AI eda0ac9f52 Merge pull request #158 from GMGNAI/feat-add-follow-tokens-command
Feat add follow tokens command
2026-06-11 11:53:40 +08:00
davidsx b940c66c00 Merge pull request #156 from prodev-nova/feat/cooking
fix(cooking): remove deprecated --interval-seconds flag
2026-06-05 21:18:04 +08:00
prodev-nova 1964e927cd fix(cooking): remove deprecated --interval-seconds flag
The interval_seconds param is no longer used. Removed from the CLI
option, params assembly, CreateTokenParams, SKILL.md and cli-usage.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-05 21:03:23 +08:00
David Lau 0f3d550736 feat(track): add follow-token-groups subcommand
Adds `track follow-token-groups` command that calls
GET /v1/user/follow_token_groups to retrieve a wallet's token follow
group names (id, name, rank) for a given chain.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 17:08:44 +08:00
GMGN.AI 23ca9d8670 1.4.3 2026-06-05 13:41:15 +08:00
GMGN.AI 67d53cd3e4 Merge pull request #154 from GMGNAI/fix/strategy-sell-buy-param
fix(swap): add --sell-param and --buy-param to order strategy create
2026-06-05 13:40:28 +08:00
David Lau ca51ee6a7a fix(swap): add --sell-param and --buy-param to order strategy create
Add CLI options and StrategyCreateParams fields for sell_param and
buy_param, which were documented in SKILL.md but missing from the
source. Reuses the existing TradeParam interface.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-05 12:04:47 +08:00
GMGN.AI f5442f6247 1.4.2 2026-06-04 20:55:31 +08:00
GMGN.AI 0dabd4b93b Merge pull request #153 from GMGNAI/fix/strategy-slippage-and-sell-param-docs
fix(docs): update strategy examples slippage to integer and add sell-param
2026-06-04 20:54:53 +08:00
David Lau 73d81fa0b2 fix(docs): align slippage to integer 0–100 in all remaining files
Update Readme.md, Readme.zh.md, src/commands/swap.ts and cooking.ts
with integer 0–100 slippage examples (e.g. 30 = 30%) to match the
updated API validation and skill docs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 20:09:27 +08:00
David Lau 4ef54b0bcc fix(docs): update strategy examples slippage to integer and add sell-param
- Change example slippage values from 0.01 to 30 (integer 0-100 scale)
- Add --sell-param option doc (required for smart_trade)
- Add --buy-param option doc
- Clarify --slippage description as integer 0-100

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 19:40:37 +08:00
David Lau dd41e38755 feat(track): add follow-tokens subcommand
Adds gmgn-cli track follow-tokens to query a wallet's followed token
list on a given chain via GET /v1/user/follow_tokens.

- Add getFollowTokens() to OpenApiClient (authExist)
- Add track follow-tokens command with --chain, --wallet (required),
  --group-id, --interval, --order-by, --direction, --limit, --cursor,
  --search optional flags
- Update SKILL.md: sub-commands table, rate limit table (weight 3),
  usage examples, options table, response fields
- Update docs/cli-usage.md and Readme.md / Readme.zh.md

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 18:37:43 +08:00
GMGN.AI 2d0cb7348d 1.4.1 2026-06-04 17:12:00 +08:00
GMGN.AI ddc025bb97 Merge pull request #152 from prodev-nova/feat/cooking
docs(cooking): worked examples, platform matrix, TradeParam, anti-mev-mode fix
2026-06-04 17:11:17 +08:00
GMGN.AI e9b08214a2 1.4.0 2026-06-04 17:08:55 +08:00
GMGN.AI f96519941e Merge pull request #151 from GMGNAI/feat/smart-trade-order-strategy
feat(swap): add smart_trade order type to order strategy create
2026-06-04 17:04:37 +08:00
prodev-nova fd8a1c4d2a fix(cooking): anti-mev-mode values off / normal / secure
Correct the --anti-mev-mode enum to off / normal / secure
(across cooking.ts, SKILL.md, cli-usage.md, and the TradeParam examples).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 17:00:23 +08:00
prodev-nova 0282a9a09b docs(cooking): add worked examples, platform matrix, TradeParam; fix anti-mev-mode values
- Fix --anti-mev-mode values: off / jito / 0slot (was normal / secure)
- Add platform capability matrix (per-platform fields, bundle/sniper
  wallet limits, cashback/mayhem support)
- Add Quote Token conversion guidance for --raised-token launches
- Add full TradeParam field table for --buy/sell-trade-config
- Add two full worked CLI examples (Pump bundle+sniper+autosell+buyback,
  FourMeme fee-split + USDT raise token)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 16:34:27 +08:00
David Lau 17d7de841e feat(swap): add smart_trade order type to order strategy create
- Add --order-type smart_trade and --sub-order-type mix_trade support
- Make --check-price optional (required for limit_order, omitted for smart_trade)
- Add --open-price, --quote-investment, --condition-orders options
- Update StrategyCreateParams interface: check_price optional, add condition_orders/quote_investment
- Update SKILL.md and cli-usage.md docs with smart_trade examples and parameter table

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-04 14:27:01 +08:00
davidsx bc64360e80 Merge pull request #150 from prodev-nova/fix/pump-fee-share-provider
fix(cooking): correct pump fee-share provider values
2026-06-03 21:00:53 +08:00
prodev-nova 134a11593c fix(cooking): correct pump fee-share provider values
The pump_fee_share_list `provider` field rejected "wallet" with
"unknown provider: wallet". Valid values are solana / twitter / github.

- OpenApiClient: update PumpFeeShareInfo provider comment
- SKILL.md / cli-usage.md: provider enum solana / twitter / github,
  username is a SOL address when provider = solana

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-03 20:50:54 +08:00
GMGN.AI 32d2fd2aac 1.3.9 2026-06-03 19:25:23 +08:00
GMGN.AI 8ed53df6d7 Merge pull request #149 from GMGNAI/fix/activity-type-camelcase
fix(portfolio): rename activity type values to camelCase
2026-06-03 16:50:32 +08:00
David Lau a161bd733d fix(portfolio): rename activity type values to camelCase
- Rename transfer_in/transfer_out → transferIn/transferOut in portfolio activity --type filter
- Update SKILL.md and portfolio.ts help text to reflect new enum values

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 16:27:53 +08:00
GMGN.AI f172b1922d 1.3.8 2026-06-02 17:18:54 +08:00
GMGN.AI 31f5b9f5b6 Merge pull request #148 from prodev-nova/feat/cooking
feat(cooking): complete create_token params, auto-sell, and fixes
2026-06-02 15:15:48 +08:00
prodev-nova c6fae6afe7 docs(cooking): use "exist auth" not "normal auth" for cooking stats
Address review feedback on PR #148: cooking stats uses exist auth
(authExistRequest), matching the CLI client and project terminology.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 14:50:49 +08:00
prodev-nova ec5719ce12 feat(cooking): complete create params, fix Flap split & pump provider
- Add advanced create_token params: description, fee, dev_max_fee_per_gas,
  raised_token, anti_mev_mode, dev_wallet_bps, source, approve_vision
- Add fee-share configs: pump_fee_share_list, bags_fee_share_list,
  flap_rate_conf (+ V6 buy/sell_tax_rate), fourmeme_rate_conf
- Add multi-wallet buy: buy_wallets, snip_buy_wallets, interval_seconds
- Add CondMarket TradeParam (buy/sell_trade_config) and auto-sell sell_configs
- Pump modes: --is-mayhem / --is-cashback / --is-buy-back (Agent Auto Buyback)
- Fix Flap split_conf field: split_bps -> bps
- Pump fee-share provider: github / wallet only (drop twitter)
- Drop is_revoke_fee_auth and is_agent/agent_bps
- Sync SKILL.md and cli-usage.md with all flags, JSON schemas,
  guided launch flow (platform-aware advanced options) and percentage-based
  fee-share UX

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-02 14:04:35 +08:00
GMGN.AI aebe509f29 1.3.7 2026-05-29 19:37:00 +08:00
GMGN.AI 26ebfe6843 Merge pull request #146 from GMGNAI/fix/signer-encode-query-params
fix(signer): percent-encode query params in buildMessage to match server
2026-05-29 19:34:22 +08:00
David Lau 412531f04e fix(signer): percent-encode query params in buildMessage to match server
Server's CanonicalQueryString uses url.QueryEscape on all keys and values,
but buildMessage was using raw string interpolation. Cursor values (base64)
contain +, =, / which diverge under encoding — causing 401 on all paginated
signed requests (e.g. portfolio holdings page 2+).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 19:32:54 +08:00
GMGN.AI b0b25118aa Merge pull request #143 from GMGNAI/docs/swap-ratelimit-weights
docs(swap): add rate limit weights for strategy and multi_swap routes
2026-05-29 17:25:39 +08:00
David Lau 0a12f0615d docs(swap): add rate limit weights for strategy and multi_swap routes
- order strategy create: POST /v1/trade/strategy/create — weight 1
- order strategy cancel: POST /v1/trade/strategy/cancel — weight 1
- order strategy list:   GET  /v1/trade/strategy/orders — weight 1
- multi-swap already listed; confirms weight 5 (same as swap)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 17:15:25 +08:00
GMGN.AI 0979d14d6a Merge pull request #142 from GMGNAI/docs/strategy-order-list-response-fields
docs(swap): expand order strategy list response fields
2026-05-29 12:05:09 +08:00
David Lau 8729cff4d3 docs(swap): expand order strategy list response fields
Add full sub-tables for list[], condition_orders[], order_statistic,
and sell_param objects in the `order strategy list` response section.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 12:03:35 +08:00
GMGN.AI 0cf2e514e6 Merge pull request #141 from gina888666/fix/portfolio-activity-price-fields-and-strategy-check-price
docs: clarify price/price_usd in portfolio activity and check-price unit in strategy create
2026-05-29 12:03:13 +08:00
gina888666 693a63c723 docs(gmgn-portfolio): remove example from price field description
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 10:53:20 +08:00
gina888666 81d67808fa docs(gmgn-portfolio): fix price field description to mention quote token may vary (SOL or USDC)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 10:51:34 +08:00
gina888666 8a095a99a8 docs: clarify price/price_usd in portfolio activity and check-price unit in strategy create
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 10:47:39 +08:00
GMGN.AI 0bc73a6430 1.3.6 2026-05-27 12:08:27 +08:00
gumponchain d00a1d3ce3 fix(swap): preserve Solana address case when normalizing wallet addresses
toLowerCase() breaks base58 Solana addresses which are case-sensitive.
Only apply lowercase normalization on EVM chains (bsc/base/eth).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-27 12:06:22 +08:00
GMGN.AI 30e535617f 1.3.5 2026-05-26 20:03:37 +08:00
GMGN.AI f64a3e086b ci: add workflow_dispatch to Release workflow 2026-05-26 20:01:04 +08:00
GMGN.AI 60438dff5c 1.3.4 2026-05-26 19:55:08 +08:00
deepfeature 6f0d4464e2 Merge pull request #138 from GMGNAI/feat/wallet-holdings-critical-auth
breaking(portfolio): upgrade wallet_holdings to critical auth
2026-05-26 19:48:09 +08:00
David Lau 48e7346d8e fix(swap): normalize wallet addresses to lowercase before API call
Ensures from_address and multi-swap accounts are lowercased at the CLI
boundary to prevent case-sensitivity issues on the API side.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 13:55:25 +08:00
deepfeature 2f76b375c5 breaking(portfolio): upgrade wallet_holdings to critical auth
Align CLI with server-side breaking change: GET /v1/user/wallet_holdings
was upgraded from authExistMW to authCriticalMW on the openapi-service.

- OpenApiClient: switch getWalletHoldings to authSignedRequest
- SKILL.md: split rate-limit table by auth level; update Notes section
- CLAUDE.md: move portfolio holdings from Normal to Critical auth row

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-26 11:19:30 +08:00
GMGN.AI a65d5fd1cb Merge pull request #136 from gina888666/fix/token-info-skill-doc-corrections-v2
fix(gmgn-token): correct fee_distribution usage hint and volume fields note
2026-05-25 17:34:10 +08:00
gina888666 7d16bd80e8 fix(gmgn-token): correct fee_distribution usage hint and volume fields note
- Add usage context to fee_distribution section so agents know to use
  token info when querying claim status and royalty allocation
- Fix incorrect Note that said trading volume is not in token info;
  price.volume_{window}, buys_{window}, sells_{window}, swaps_{window}
  are all available in the token info price object

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 16:02:17 +08:00
GMGN.AI 9dfccd129d 1.3.3 2026-05-19 21:03:49 +08:00
GMGN.AI ce7f762e5b Merge pull request #132 from GMGNAI/feat/gas-price-all-chains
refactor(auth): rename normalRequest/criticalRequest; align auth terminology
2026-05-19 20:35:11 +08:00
David Lau d51f1c49d3 refactor(auth): rename normalRequest/criticalRequest; align auth terminology
- Rename private methods: normalRequest → authExistRequest,
  criticalRequest → authSignedRequest in OpenApiClient.ts (both gmgn-skills
  and scripts/src)
- Replace all "normal auth" / "critical auth" labels across SKILL.md files,
  cli-usage.md, Readme.md, and CLI command descriptions with:
    exist auth  — API Key only, no private key required
    signed auth — API Key + GMGN_PRIVATE_KEY signature required
- Add explicit "requires GMGN_PRIVATE_KEY" notes to signed-auth commands
  and "API Key only" notes to exist-auth commands throughout docs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 17:45:10 +08:00
gumponchain 17b901c29f docs: add gas-price command and ETH gas control examples to README
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 16:19:22 +08:00
GMGN.AI f3738e0bd4 Merge pull request #130 from GMGNAI/feat/gas-price-all-chains
docs: remove "trading bot" references; label condition-orders-only flags
2026-05-19 15:55:37 +08:00
David Lau f05e1d5d20 docs: remove "trading bot" references; label condition-orders-only flags
- Replace "trading bot" with user-facing language throughout SKILL.md
  and cli-usage.md
- Mark --auto-fee and --sell-ratio-type as "Only with --condition-orders"
  in swap and multi-swap parameter tables
- TRADING_BOT_UNAVAILABLE error now describes the symptom, not the
  internal service name

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 15:51:11 +08:00
GMGN.AI beedf14b5b 1.3.2 2026-05-19 15:22:14 +08:00
GMGN.AI 1b9e2c24d6 Merge pull request #129 from GMGNAI/feat/gas-price-all-chains
feat(swap): promote gas-price to top-level command, support all chains
2026-05-19 15:20:59 +08:00
GMGN.AI a3dfa99763 1.3.1 2026-05-19 14:49:12 +08:00
David Lau 317c7d982b docs(swap): expand gas-price response fields to match full upstream schema
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 14:25:48 +08:00
David Lau 15872373cd feat(swap): promote gas-price to top-level command, support all chains
- Move `order gas-price` → `gmgn-cli gas-price` (top-level command)
- Expand chain support to include sol alongside eth / bsc / base
- Reorder commands in swap.ts to match SKILL.md: swap → multi-swap →
  order quote/get → gas-price → order strategy create/list/cancel

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 12:05:39 +08:00
GMGN.AI 674c7032a8 Merge pull request #126 from gina888666/fix/base-chain-no-anti-mev
fix(gmgn-swap): note that --anti-mev is not supported on base chain
2026-05-18 20:49:05 +08:00
gina888666 4649a7a287 fix(gmgn-swap): note that --anti-mev is not supported on base chain
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 20:41:12 +08:00
GMGN.AI 2b33ee666c Merge pull request #125 from GMGNAI/feat/gas-level-remove-auto-tip-fee
Feat/gas level remove auto tip fee
2026-05-18 19:13:53 +08:00
GMGN.AI 123bdba738 1.3.0 2026-05-14 20:47:03 +08:00
GMGN.AI 1d03fb1672 1.2.10 2026-05-14 20:46:10 +08:00
GMGN.AI 6f79600869 Merge pull request #122 from GumpOnchain/docs/token-native-transfer-shared-funding
docs(token): move native_transfer to Shared Funding section with updated description
2026-05-14 20:44:38 +08:00
GMGN.AI 12ab55bb63 docs(token): move native_transfer to Shared Funding section with updated description
native_transfer records the first native token (SOL/BNB/ETH) transfer into a
wallet, not the most recent — it indicates the original funding source. Wallets
sharing the same native_transfer.address are likely funded from a common origin
(coordinated wallets / same operator).

Move it out of Last Transaction Records into its own Shared Funding section to
reflect its distinct purpose.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 20:43:36 +08:00
GMGN.AI aa09490a9b Merge pull request #121 from GumpOnchain/fix/trenches-volume-filter
fix(trenches): fix apiFieldToCliKey for numeric suffix flags (--min/max-volume-24h etc.)
2026-05-14 20:08:22 +08:00
David Lau b3e99dde94 docs(swap): add Chain column to fee params; reorder SKILL.md by sub-command
- Add Chain column to swap, multi-swap, and strategy-create parameter
  tables in SKILL.md and cli-usage.md, explicitly scoping each fee flag
  to its supported chain(s)
- Reorder SKILL.md sections to follow Sub-commands table order: swap →
  multi-swap → order quote → order get → order gas-price →
  order strategy create/list/cancel
- Group each command's Usage + Parameters + Response Fields together
- Add horizontal dividers between command groups for readability
- Add order get cross-reference to shared swap response fields
- Collapse separate strategy usage examples into their respective command sections

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 19:59:24 +08:00
GMGN.AI 2b6c220581 fix(trenches): fix apiFieldToCliKey to match Commander.js camelCase for numeric suffixes
Commander.js removes hyphens before digits (e.g. -24h → 24h) but does not
uppercase them. The previous regex only handled -[a-z] patterns, leaving
a residual hyphen: minVolume-24h instead of minVolume24h.

This caused all 24h-suffixed filter flags to be silently ignored:
--min-volume-24h, --max-volume-24h, --min-net-buy-24h, --min-swaps-24h,
--min-buys-24h, --min-sells-24h.

Fix: add .replace(/-(\d)/g, '$1') to strip hyphens before digit sequences.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 19:53:45 +08:00
David Lau 072b180119 feat: add gas-level/auto-fee/gas-price endpoint; remove auto_tip_fee/max_auto_fee
- Add --gas-level (eth only), --auto-fee (eth only) to swap, multi-swap,
  and strategy create commands
- Add order gas-price subcommand (GET /v1/trade/gas_price, normal auth)
- Add --max-fee-per-gas / --max-priority-fee-per-gas to strategy create
- Remove --auto-tip-fee and --max-auto-fee from swap and multi-swap
- Update token SKILL.md: price field is now a nested object (price.price),
  add price window fields and fee_distribution object docs
- Update EIP-1559 chain coverage from Base-only to BSC/BASE/ETH

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-14 18:55:49 +08:00
deepfeature e181cba142 fix(skills): update rate limit settings for cooking, market, portfolio, swap, token, and track routes 2026-05-13 17:13:26 +08:00
deepfeature ee04212098 1.2.9 2026-05-04 09:41:21 +08:00
deepfeature e4496eafeb fix(config): update dotenv loading order and simplify host assignment 2026-05-04 09:35:54 +08:00
GMGN.AI f56cf1f966 Merge pull request #117 from GMGNAI/fix/remove-bluechip-owner-stat-fields
fix(token): remove bluechip_owner_count and bluechip_owner_percentage from stat fields
2026-04-24 15:23:21 +08:00
David Lau 698ae707e8 fix(token): remove bluechip_owner_count and bluechip_owner_percentage from stat fields
These fields were removed from the TokenStatData struct in the openapi-service
and are no longer returned in the token info response.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 15:01:47 +08:00
GMGN.AI 34fc2f9e2a 1.2.8 2026-04-23 19:37:48 +08:00
GMGN.AI 5ef03579cf Merge pull request #114 from gina888666/fix/swap-currency-address-warning
fix(swap): add critical warning to Chain Currencies table to prevent address guessing
2026-04-23 19:30:20 +08:00
wuyanling 1d433724d3 fix(swap): add critical warning to Chain Currencies table to prevent address guessing
AI models may use incorrect currency addresses from training data (e.g.
So11111111111111111111111111111111111111111 vs the correct ...112), causing
silent failures or misleading "jupiter has no route" errors. Added a warning
above the table and wrapped all addresses in backticks for clarity.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 19:17:53 +08:00
GMGN.AI 26a50c7046 Merge pull request #113 from GMGNAI/feat/eth-chain-support
feat(eth): add ETH chain support to multi-swap, strategy, kol, smartmoney, created-tokens
2026-04-23 18:17:32 +08:00
David Lau 56a3a60352 feat(eth): add ETH chain support to multi-swap, strategy, kol, smartmoney, created-tokens
- multi-swap --chain: add eth
- order strategy create/list/cancel --chain: add eth
- track kol/smartmoney --chain: add eth, change to requiredOption
- portfolio created-tokens --chain: add eth
- SKILL.md files updated accordingly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 18:16:58 +08:00
GMGN.AI 211f7d6fd0 docs(swap): remove USDC from ETH chain currencies (ETH-only for now)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 20:41:35 +08:00
GMGN.AI 5e1560188e docs: remove USDC from ETH chain currencies (ETH-only for now)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 20:39:31 +08:00
GMGN.AI 08f7b66251 docs: add ETH chain to multi-chain descriptions in README
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 20:31:56 +08:00
GMGN.AI 48c596ab10 1.2.7 2026-04-22 19:31:47 +08:00
GMGN.AI ec099ea399 Merge pull request #112 from GMGNAI/feat-add-eth-chain-support
feat(eth): add Ethereum mainnet chain support (P0 commands)
2026-04-22 17:40:24 +08:00
David Lau 1012cfffb8 feat(eth): add Ethereum mainnet chain support (P0 commands)
Add ETH chain support to all P0 commands across CLI and SKILL.md docs:

Commands with ETH support added:
- token info/security/pool/holders/traders
- market kline/trending
- portfolio info/holdings/activity/stats/token-balance
- track follow-wallet
- swap, order quote/get

P1/P2 commands remain sol/bsc/base only:
- track kol/smartmoney (P1)
- multi-swap, order strategy create/list/cancel (P1)
- portfolio created-tokens (P2)

Also adds ETH chain currencies, explorer links, and gas price bounds
to gmgn-swap SKILL.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 16:08:36 +08:00
GMGN.AI f6f1d56b82 Merge pull request #111 from gina888666/fix/trenches-created-duration-unit
fix(trenches): require unit suffix for --min-created / --max-created
2026-04-22 15:26:48 +08:00
wuyanling b83422769f fix(trenches): remove 1h example from min/max-created desc, align with s/m only
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 15:22:44 +08:00
GMGN.AI 8922811e04 Merge pull request #110 from GMGNAI/expand-trader-holder-tag-filter
feat(token): expand --tag filter for holders and traders to all 10 values
2026-04-22 15:14:20 +08:00
wuyanling cc1cb48db9 fix(trenches): treat bare duration numbers as minutes with warning, update skill docs
- parseDuration: bare numbers now default to minutes (e.g. "5" → "5m") instead of hard error
- Print a warning to stderr so users know the implicit conversion is happening
- Update SKILL.md: document unit suffix recommendation and bare-number fallback behavior

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 11:52:01 +08:00
wuyanling 981600f170 fix(trenches): require unit suffix for --min-created / --max-created
Bare numbers like 0.5 were silently accepted but caused inconsistent
server-side filtering. This change:

- Adds a parseDuration() validator that rejects values without a unit
- Accepts seconds (e.g. 30s) and minutes (e.g. 0.5m / 1m / 5m)
- Prints a clear error message when a bare number is passed
- Updates desc strings to document the required unit format
- Adds a new TrenchesFieldType 'duration' to distinguish these fields
2026-04-22 11:37:44 +08:00
David Lau 1f49d61363 feat(token): expand --tag filter for holders and traders to all 10 values
Update --tag option description and SKILL.md docs to reflect the full
backend allowlist: smart_degen, renowned, fresh_wallet, dev, sniper,
rat_trader, bundler, transfer_in, dex_bot, bluechip_owner.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 16:42:06 +08:00
GMGN.AI 3046c6d6cd 1.2.6 2026-04-20 11:46:18 +08:00
GMGN.AI ee4838d565 Merge pull request #108 from GumpOnchain/fix/follow-wallet-critical-auth
fix(track): switch follow-wallet to critical auth (fix HTTP 401 AUTH_INVALID)
2026-04-20 11:44:20 +08:00
GMGN.AI f19a1919da fix(track): switch follow-wallet to critical auth and fix signer array support
GET /v1/trade/follow_wallet requires X-Signature (critical auth) but was
called via normalRequest (API Key only), causing HTTP 401 AUTH_INVALID
with "missing signature".

- OpenApiClient: getFollowWallet now calls criticalRequest; criticalRequest
  queryExtra type widened to accept string[] to support the --filter option
- signer: buildMessage handles string[] values as sorted repeated k=v pairs,
  consistent with buildUrl / URLSearchParams serialization
- config: update PRIVATE_KEY_REQUIRED_MSG to include follow-wallet
- SKILL.md: prerequisites note GMGN_PRIVATE_KEY for follow-wallet; first-time
  setup now saves private key to ~/.config/gmgn/.env and removes /tmp copy;
  Notes section corrected to reflect split auth modes
- CLAUDE.md: Auth Modes table updated — follow-wallet moved to Critical row

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 11:42:56 +08:00
davidsx 4cfe0e0fb5 Merge pull request #107 from GMGNAI/docs/market-signal-disallow-types-14-16
docs(gmgn-market): document token_signal types 14–16 rejected by API
2026-04-20 11:42:04 +08:00
David Lau 5755206b58 docs(gmgn-market): document token_signal types 14–16 rejected by API
Align SKILL with OpenAPI validation: signal_type must not include 14, 15,
or 16 (400 BAD_REQUEST). Update examples and clarify behavior when
--signal-type is omitted.

Made-with: Cursor
2026-04-20 11:41:40 +08:00
davidsx 6ab9cb108b Update SKILL.md 2026-04-17 14:37:42 +08:00
23 changed files with 2066 additions and 643 deletions
+1
View File
@@ -4,6 +4,7 @@ on:
push:
tags:
- "v*"
workflow_dispatch:
permissions:
contents: read
+5
View File
@@ -18,3 +18,8 @@ dist
# Internal / testing (not for public release)
testing/
# Local Claude Code configs (dev environment only)
.claude/
.agents/
skills-lock.json
+3 -3
View File
@@ -20,7 +20,7 @@ This includes: trending tokens, token info, security checks, K-line / price hist
## Project Overview
This is a **Claude Code plugin** — a collection of GMGN OpenAPI skills for on-chain operations. It provides CLI tools and skills for token queries, market data, wallet portfolio analysis, and swap execution across sol / bsc / base.
This is a **Claude Code plugin** — a collection of GMGN OpenAPI skills for on-chain operations. It provides CLI tools and skills for token queries, market data, wallet portfolio analysis, and swap execution across sol / bsc / base / eth.
## Available Skills
@@ -93,8 +93,8 @@ EOF
| Mode | Commands | Requirements |
|------|----------|--------------|
| Normal | token / market / portfolio | `GMGN_API_KEY` only, no signature |
| Critical | swap / order | `GMGN_API_KEY` + `GMGN_PRIVATE_KEY` — CLI handles signing automatically |
| Normal | token / market / portfolio (except holdings) / track kol / track smartmoney / **order quote** | `GMGN_API_KEY` only, no signature |
| Critical | swap / order (except order quote) / portfolio holdings / track follow-wallet | `GMGN_API_KEY` + `GMGN_PRIVATE_KEY` — CLI handles signing automatically |
## SKILL.md Authoring Rules
+59 -14
View File
@@ -22,7 +22,7 @@ With GMGN Agent Skills, you can use AI agents to query real-time trending token
### 1. Real-time on-chain data — faster
Data across SOL / BSC / Base is live on every query. Supports multi-parameter customization, no snapshot cache — built for AI agent real-time decision-making (including but not limited to):
Data across SOL / BSC / Base / ETH is live on every query. Supports multi-parameter customization, no snapshot cache — built for AI agent real-time decision-making (including but not limited to):
| Data | Granularity |
|------|-------------|
@@ -461,6 +461,13 @@ gmgn-cli market trending \
--order-by volume --limit 20 \
--filter not_risk --filter not_honeypot
# Trending with numeric range filters (min_*/max_* are forwarded as query params)
gmgn-cli market trending \
--chain sol --interval 1h \
--min-liquidity 10000 --max-liquidity 1000000 \
--max-created 30m --min-smart-degen-count 1 \
--order-by volume --limit 30
gmgn-cli market trenches \
--chain sol \
--type new_creation --type near_completion --type completed \
@@ -505,6 +512,9 @@ gmgn-cli portfolio created-tokens --chain sol --wallet <addr>
### Track
```bash
# Followed token map for a wallet
gmgn-cli track follow-tokens --chain sol --wallet <wallet_address>
# Follow-wallet trade records
gmgn-cli track follow-wallet --chain sol
gmgn-cli track follow-wallet --chain sol --limit 20 --min-amount-usd 1000
@@ -528,7 +538,7 @@ gmgn-cli swap \
--input-token <input-token-addr> \
--output-token <output-token-addr> \
--amount 1000000 \
--slippage 0.01
--slippage 30
# Submit swap with automatic slippage
gmgn-cli swap \
@@ -555,20 +565,26 @@ gmgn-cli order quote \
--input-token <input-token-addr> \
--output-token <output-token-addr> \
--amount 1000000 \
--slippage 0.01
--slippage 30
# Quotes use critical auth and require GMGN_PRIVATE_KEY on every chain
# Quotes use signed auth and require GMGN_PRIVATE_KEY on every chain
gmgn-cli order quote \
--chain bsc \
--from <wallet-address> \
--input-token <input-token-addr> \
--output-token <output-token-addr> \
--amount 1000000000000000000 \
--slippage 0.01
--slippage 30
# Query order
gmgn-cli order get --chain sol --order-id <order-id>
# Query real-time gas price (all chains)
gmgn-cli gas-price --chain sol
gmgn-cli gas-price --chain eth
gmgn-cli gas-price --chain bsc
gmgn-cli gas-price --chain base
# Multi-wallet concurrent swap
gmgn-cli multi-swap \
--chain sol \
@@ -576,10 +592,38 @@ gmgn-cli multi-swap \
--input-token <input-token-addr> \
--output-token <output-token-addr> \
--input-amount '{"<addr1>":"1000000","<addr2>":"2000000"}' \
--slippage 0.01
--slippage 30
```
> `order quote` uses critical auth on `sol` / `bsc` / `base` and requires `GMGN_PRIVATE_KEY`.
> `order quote` uses signed auth on `sol` / `bsc` / `base` / `eth` and requires `GMGN_PRIVATE_KEY`.
### ETH Gas Control (ETH only)
```bash
# Pick a gas tier instead of entering gwei manually (low / average / high)
gmgn-cli swap \
--chain eth \
--from <wallet-address> \
--input-token <input-token-addr> \
--output-token <output-token-addr> \
--amount <amount> \
--slippage 30 \
--gas-level high
# Let GMGN auto-select the optimal gas fee for condition orders
gmgn-cli swap \
--chain eth \
--from <wallet-address> \
--input-token <input-token-addr> \
--output-token <output-token-addr> \
--amount <amount> \
--slippage 30 \
--condition-orders '[...]' \
--auto-fee
```
> `--gas-level` and `--auto-fee` are ETH only. `--auto-fee` only takes effect when used with `--condition-orders`.
> For other chains (SOL / BSC / BASE), use `gas-price` to query the current gas, then pass the result via `--gas-price`.
### Swap with Take-Profit / Stop-Loss Orders (requires private key)
@@ -593,7 +637,7 @@ gmgn-cli swap \
--input-token So11111111111111111111111111111111111111112 \
--output-token <token_A_address> \
--amount 10000000 \
--slippage 0.3 \
--slippage 30 \
--anti-mev \
--condition-orders '[{"order_type":"profit_stop","side":"sell","price_scale":"100","sell_ratio":"50"},{"order_type":"profit_stop","side":"sell","price_scale":"300","sell_ratio":"100"},{"order_type":"loss_stop","side":"sell","price_scale":"65","sell_ratio":"100"}]' \
--sell-ratio-type hold_amount
@@ -612,7 +656,7 @@ gmgn-cli swap \
--input-token So11111111111111111111111111111111111111112 \
--output-token <token_A_address> \
--amount 10000000 \
--slippage 0.3 \
--slippage 30 \
--anti-mev \
--condition-orders '[{"order_type":"profit_stop","side":"sell","price_scale":"100","sell_ratio":"50"},{"order_type":"profit_stop","side":"sell","price_scale":"300","sell_ratio":"50"},{"order_type":"loss_stop","side":"sell","price_scale":"65","sell_ratio":"100"}]' \
--sell-ratio-type buy_amount
@@ -634,7 +678,7 @@ gmgn-cli order strategy create \
--sub-order-type take_profit \
--check-price 0.002 \
--amount-in-percent 100 \
--slippage 0.01
--slippage 30
# Create a stop-loss order
gmgn-cli order strategy create \
@@ -645,7 +689,7 @@ gmgn-cli order strategy create \
--sub-order-type stop_loss \
--check-price 0.0005 \
--amount-in-percent 100 \
--slippage 0.01
--slippage 30
# List open strategy orders (requires private key)
gmgn-cli order strategy list --chain sol
@@ -664,7 +708,7 @@ gmgn-cli cooking \
--input-token So11111111111111111111111111111111111111112 \
--output-token <token_address> \
--amount 1000000000 \
--slippage 0.3 \
--slippage 30 \
--condition-orders '[{"order_type":"profit_stop","side":"sell","price_scale":"100","sell_ratio":"100"},{"order_type":"loss_stop","side":"sell","price_scale":"50","sell_ratio":"100"}]'
```
@@ -672,8 +716,9 @@ gmgn-cli cooking \
| Commands | Chains | Chain Currencies |
|----------|--------|-----------------|
| token / market / portfolio / track | `sol` / `bsc` / `base` | — |
| swap / order | `sol` / `bsc` / `base` | sol: SOL, USDC · bsc: BNB, USDC · base: ETH, USDC |
| token / market / portfolio / track | `sol` / `bsc` / `base` / `eth` | — |
| swap / order | `sol` / `bsc` / `base` / `eth` | sol: SOL, USDC · bsc: BNB, USDC · base: ETH, USDC · eth: ETH |
| gas-price | `sol` / `bsc` / `base` / `eth` | — |
---
+58 -13
View File
@@ -22,7 +22,7 @@
### 1. 链上实时数据查询快
SOL / BSC / Base 多链数据每次查询均为实时,支持多参数个性化调用,无快照缓存,方便AI Agent实时决策(包括不限于下表)。
SOL / BSC / Base / ETH 多链数据每次查询均为实时,支持多参数个性化调用,无快照缓存,方便AI Agent实时决策(包括不限于下表)。
| 数据类型 | 粒度 |
|---------|------|
@@ -491,6 +491,13 @@ gmgn-cli market trending \
--order-by volume --limit 20 \
--filter not_risk --filter not_honeypot
# 热门榜 + 数值范围过滤(min_*/max_* 以查询参数透传)
gmgn-cli market trending \
--chain sol --interval 1h \
--min-liquidity 10000 --max-liquidity 1000000 \
--max-created 30m --min-smart-degen-count 1 \
--order-by volume --limit 30
# 战壕新币列表
gmgn-cli market trenches \
--chain sol \
@@ -529,6 +536,9 @@ gmgn-cli portfolio created-tokens --chain sol --wallet <addr>
### Track
```bash
# 查询钱包收藏的代币列表
gmgn-cli track follow-tokens --chain sol --wallet <wallet_address>
# 追踪关注钱包的交易动态
gmgn-cli track follow-wallet --chain sol
gmgn-cli track follow-wallet --chain sol --limit 20 --min-amount-usd 1000
@@ -552,7 +562,7 @@ gmgn-cli swap \
--input-token <input-token-addr> \
--output-token <output-token-addr> \
--amount 1000000 \
--slippage 0.01
--slippage 30
# 提交兑换(自动滑点)
gmgn-cli swap \
@@ -579,7 +589,7 @@ gmgn-cli order quote \
--input-token <input-token-addr> \
--output-token <output-token-addr> \
--amount 1000000 \
--slippage 0.01
--slippage 30
# 所有链上的 quote 都走关键鉴权,需要 GMGN_PRIVATE_KEY
gmgn-cli order quote \
@@ -588,11 +598,17 @@ gmgn-cli order quote \
--input-token <input-token-addr> \
--output-token <output-token-addr> \
--amount 1000000000000000000 \
--slippage 0.01
--slippage 30
# 查询订单状态
gmgn-cli order get --chain sol --order-id <order-id>
# 查询实时 Gas 价格(支持全链)
gmgn-cli gas-price --chain sol
gmgn-cli gas-price --chain eth
gmgn-cli gas-price --chain bsc
gmgn-cli gas-price --chain base
# 多钱包并发 Swap
gmgn-cli multi-swap \
--chain sol \
@@ -600,10 +616,38 @@ gmgn-cli multi-swap \
--input-token <input-token-addr> \
--output-token <output-token-addr> \
--input-amount '{"<addr1>":"1000000","<addr2>":"2000000"}' \
--slippage 0.01
--slippage 30
```
> `order quote` 在 `sol` / `bsc` / `base` 上都走关键鉴权,必须配置 `GMGN_PRIVATE_KEY`。
> `order quote` 在 `sol` / `bsc` / `base` / `eth` 上都走关键鉴权,必须配置 `GMGN_PRIVATE_KEY`。
### ETH Gas 档位控制(仅限 ETH
```bash
# 按档位设置 Gaslow / average / high),替代手动填写 gwei
gmgn-cli swap \
--chain eth \
--from <wallet-address> \
--input-token <input-token-addr> \
--output-token <output-token-addr> \
--amount <amount> \
--slippage 30 \
--gas-level high
# 策略单(condition-orders)由 GMGN 自动选择最优 Gas Fee
gmgn-cli swap \
--chain eth \
--from <wallet-address> \
--input-token <input-token-addr> \
--output-token <output-token-addr> \
--amount <amount> \
--slippage 30 \
--condition-orders '[...]' \
--auto-fee
```
> `--gas-level` 和 `--auto-fee` 仅支持 ETH 链。`--auto-fee` 仅在携带 `--condition-orders` 时生效。
> 其他链(SOL / BSC / BASE)请先用 `gas-price` 查询当前 Gas,再通过 `--gas-price` 手动传入。
### 带止盈止损的 Swap(需要私钥)
@@ -617,7 +661,7 @@ gmgn-cli swap \
--input-token So11111111111111111111111111111111111111112 \
--output-token <token_A_address> \
--amount 10000000 \
--slippage 0.3 \
--slippage 30 \
--anti-mev \
--condition-orders '[{"order_type":"profit_stop","side":"sell","price_scale":"100","sell_ratio":"50"},{"order_type":"profit_stop","side":"sell","price_scale":"300","sell_ratio":"100"},{"order_type":"loss_stop","side":"sell","price_scale":"65","sell_ratio":"100"}]' \
--sell-ratio-type hold_amount
@@ -636,7 +680,7 @@ gmgn-cli swap \
--input-token So11111111111111111111111111111111111111112 \
--output-token <token_A_address> \
--amount 10000000 \
--slippage 0.3 \
--slippage 30 \
--anti-mev \
--condition-orders '[{"order_type":"profit_stop","side":"sell","price_scale":"100","sell_ratio":"50"},{"order_type":"profit_stop","side":"sell","price_scale":"300","sell_ratio":"50"},{"order_type":"loss_stop","side":"sell","price_scale":"65","sell_ratio":"100"}]' \
--sell-ratio-type buy_amount
@@ -658,7 +702,7 @@ gmgn-cli order strategy create \
--sub-order-type take_profit \
--check-price 0.002 \
--amount-in-percent 100 \
--slippage 0.01
--slippage 30
# 创建止损单
gmgn-cli order strategy create \
@@ -669,7 +713,7 @@ gmgn-cli order strategy create \
--sub-order-type stop_loss \
--check-price 0.0005 \
--amount-in-percent 100 \
--slippage 0.01
--slippage 30
# 查看当前挂单(需要私钥)
gmgn-cli order strategy list --chain sol
@@ -688,7 +732,7 @@ gmgn-cli cooking \
--input-token So11111111111111111111111111111111111111112 \
--output-token <token_address> \
--amount 1000000000 \
--slippage 0.3 \
--slippage 30 \
--condition-orders '[{"order_type":"profit_stop","side":"sell","price_scale":"100","sell_ratio":"100"},{"order_type":"loss_stop","side":"sell","price_scale":"50","sell_ratio":"100"}]'
```
@@ -696,8 +740,9 @@ gmgn-cli cooking \
| 接口类型 | 支持的链 | 链原生货币 |
|----------|----------|-----------|
| token / market / portfolio / track | `sol` / `bsc` / `base` | — |
| swap / order | `sol` / `bsc` / `base` | sol: SOL、USDC · bsc: BNB、USDC · base: ETH、USDC |
| token / market / portfolio / track | `sol` / `bsc` / `base` / `eth` | — |
| swap / order | `sol` / `bsc` / `base` / `eth` | sol: SOL、USDC · bsc: BNB、USDC · base: ETH、USDC · eth: ETH |
| gas-price | `sol` / `bsc` / `base` / `eth` | — |
---
+177 -75
View File
@@ -101,7 +101,7 @@ npx gmgn-cli market kline \
|--------|----------|-------------|
| `--chain` | Yes | `sol` / `bsc` / `base` |
| `--address` | Yes | Token contract address |
| `--resolution` | Yes | Candlestick resolution: `1m` / `5m` / `15m` / `1h` / `4h` / `1d` |
| `--resolution` | Yes | Candlestick resolution: `30s` / `1m` / `5m` / `15m` / `1h` / `4h` / `1d` |
| `--from` | No | Start time (Unix seconds) |
| `--to` | No | End time (Unix seconds) |
@@ -120,18 +120,21 @@ npx gmgn-cli market trending \
[--direction asc|desc] \
[--filter <tag>] \
[--platform <name>] \
[--min-<metric> <n>] [--max-<metric> <n>] \
[--raw]
```
| Option | Required | Description |
|--------|----------|-------------|
| `--chain` | Yes | `sol` / `bsc` / `base` |
| `--interval` | Yes | `1h` / `3h` / `6h` / `24h` |
| `--chain` | Yes | `sol` / `bsc` / `base` / `eth` |
| `--interval` | Yes | `1m` / `5m` / `1h` / `6h` / `24h` |
| `--limit` | No | Number of results (default 100, max 100) |
| `--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` |
| `--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`. The gmgn web client also sends aliases `social_not_duplicate` / `img_not_duplicate` / `is_burnt` / `launching` / `migrated`, which are accepted but only the canonical tags change behavior. |
| `--platform` | No | Platform filter (repeatable). Omit (or pass an empty list) to include **all** platforms. Available values depend on chain — see below. |
| `--min-<metric>` / `--max-<metric>` | No | Numeric range filters (inclusive). Supported metrics: `volume` / `liquidity` / `marketcap` / `history-highest-marketcap` / `swaps` / `holder-count` / `gas-fee` / `renowned-count` / `smart-degen-count` / `bot-degen-count` / `visiting-count` / `price-change-percent` / `insider-rate` / `bundler-rate` / `entrapment-ratio` / `top10-holder-rate` / `top70-sniper-hold-rate` / `dev-team-hold-rate`. Unknown metrics are ignored by the service. |
| `--min-created` / `--max-created` | No | Token-age window, duration string with a `m` (minutes) / `h` (hours) / `d` (days) suffix, e.g. `30m` / `6h` / `7d`. `--min-created` is a minimum age (excludes younger tokens); `--max-created` a maximum age (excludes older tokens). The raw upstream rank interface accepts minutes only; the openapi-service does not forward this field — it evaluates the age window itself (cutoff = now duration, native for `m`/`h`/`d`), so `6h`/`7d` work here. A bare number with no unit suffix is not accepted. |
**`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`
@@ -139,6 +142,8 @@ npx gmgn-cli market trending \
**`base` platforms:** `clanker` / `bankr` / `flaunch` / `zora` / `zora_creator` / `baseapp` / `basememe` / `virtuals_v2` / `klik`
**`eth` platforms:** `trench` / `clanker` / `klik` / `livo` / `stroid` / `pool_uniswap_v2` / `pool_uniswap_v3` / `printr`
---
## portfolio holdings
@@ -289,11 +294,19 @@ npx gmgn-cli market trenches --chain <chain> [--type <type...>] [--launchpad-pla
| Option | Required | Description |
|--------|----------|-------------|
| `--chain` | Yes | `sol` / `bsc` / `base` |
| `--chain` | Yes | `sol` / `bsc` / `base` / `eth` |
| `--type` | No | Categories to query, repeatable: `new_creation` / `near_completion` / `completed` (default: all three) |
| `--launchpad-platform` | No | Launchpad platform filter, repeatable (default: all platforms for the chain) |
| `--launchpad-platform` | No | Launchpad platform filter, repeatable (default: all platforms for the chain). Values depend on chain — see below. |
| `--limit` | No | Max results per category, max 80 (default: 80) |
**`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` / `ray_launchpad` / `meteora_virtual_curve` / `xstocks`
**`bsc` platforms:** `fourmeme` / `fourmeme_agent` / `bn_fourmeme` / `four_xmode_agent` / `cubepeg` / `likwid` / `goplus_creator` / `goplus_skills` / `openfour` / `flap` / `flap_stocks` / `flap_aioracle` / `clanker` / `lunafun`
**`base` platforms:** `clanker` / `bankr` / `flaunch` / `zora` / `zora_creator` / `baseapp` / `basememe` / `virtuals_v2` / `klik`
**`eth` platforms:** `trench` / `clanker` / `klik` / `livo` / `stroid` / `pool_uniswap_v2` / `pool_uniswap_v3` / `printr`
**Response:** `data.new_creation`, `data.pump`, `data.completed` — each is an array of `RankItem` (same structure as `market trending` rank items). **Note: `data.pump` in the response corresponds to `--type near_completion` in the request. The API always returns this category under the key `pump`, not `near_completion`.**
---
@@ -349,9 +362,57 @@ gmgn-cli market signal --chain sol --groups '<json_array>' [--raw]
---
## track follow-tokens
Query the followed token list for a wallet. Returns a paginated list of tokens the wallet has bookmarked on GMGN, with full market data. API Key auth only.
```bash
gmgn-cli track follow-tokens \
--chain <chain> \
--wallet <wallet_address> \
[--group-id <id>] \
[--order-by <field>] \
[--direction <asc|desc>] \
[--limit <n>] \
[--cursor <cursor>] \
[--raw]
```
| Option | Required | Description |
|--------|----------|-------------|
| `--chain` | Yes | `sol` / `bsc` / `base` / `eth` |
| `--wallet` | Yes | Wallet address |
| `--group-id` | No | `all_group` (all tokens), `default`, or a user-defined group ID |
| `--interval` | No | Time interval for price change stats: `1m` / `5m` / `1h` / `6h` / `24h` |
| `--order-by` | No | `created_at` / `swaps` / `volume` / `market_cap` / `liquidity` / `price` / `open_timestamp` |
| `--direction` | No | Sort direction: `asc` / `desc` |
| `--limit` | No | Page size |
| `--cursor` | No | Pagination cursor from previous response |
| `--search` | No | Search by token name or address |
---
## track follow-token-groups
Query the follow token group names for a wallet. Returns the groups a wallet uses to organise its followed tokens on GMGN. API Key auth only.
```bash
gmgn-cli track follow-token-groups \
--chain <chain> \
--wallet <wallet_address> \
[--raw]
```
| Option | Required | Description |
|--------|----------|-------------|
| `--chain` | Yes | `sol` / `bsc` / `base` / `eth` |
| `--wallet` | Yes | Wallet address |
---
## portfolio follow-wallet
Query follow-wallet trade records. Returns trades from wallets you personally follow on the GMGN platform. The follow list is resolved automatically from the GMGN user account bound to the API Key — `--wallet` is optional. Normal auth (API Key only, no private key needed).
Query follow-wallet trade records. Returns trades from wallets you personally follow on the GMGN platform. The follow list is resolved automatically from the GMGN user account bound to the API Key — `--wallet` is optional. Signed auth (API Key + private key signature).
```bash
gmgn-cli track follow-wallet \
@@ -411,7 +472,7 @@ gmgn-cli track smartmoney [--chain <chain>] [--limit <n>] [--side <side>] [--raw
## order quote
Get a swap quote without submitting a transaction. All supported quote chains use critical auth and require `GMGN_PRIVATE_KEY`.
Get a swap quote without submitting a transaction. Uses normal auth — only `GMGN_API_KEY` is required, no `GMGN_PRIVATE_KEY` needed.
```bash
npx gmgn-cli order quote \
@@ -426,12 +487,12 @@ npx gmgn-cli order quote \
| Option | Required | Description |
|--------|----------|-------------|
| `--chain` | Yes | `sol` / `bsc` / `base` (all require `GMGN_PRIVATE_KEY` for quote) |
| `--from` | Yes | Wallet address (must match API Key binding) |
| `--chain` | Yes | `sol` / `bsc` / `base` |
| `--from` | Yes | Wallet address |
| `--input-token` | Yes | Input token contract address |
| `--output-token` | Yes | Output token contract address |
| `--amount` | Yes | Input amount (smallest unit) |
| `--slippage` | Yes | Slippage tolerance, e.g. `0.01` = 1% |
| `--slippage` | Yes | Slippage tolerance as an integer 0100, e.g. `30` = 30% |
**Response fields (data):**
@@ -463,7 +524,6 @@ npx gmgn-cli swap \
[--anti-mev] \
[--priority-fee <sol>] \
[--tip-fee <amount>] \
[--max-auto-fee <amount>] \
[--gas-price <gwei>] \
[--max-fee-per-gas <amount>] \
[--max-priority-fee-per-gas <amount>] \
@@ -472,26 +532,27 @@ npx gmgn-cli swap \
[--raw]
```
| Option | Required | Description |
|--------|----------|-------------|
| `--chain` | Yes | `sol` / `bsc` / `base` / `eth` |
| `--from` | Yes | Wallet address (must match the wallet bound to the API Key) |
| `--input-token` | Yes | Input token contract address |
| `--output-token` | Yes | Output token contract address |
| `--amount` | No* | Input raw amount in minimal unit (e.g., lamports for SOL); required unless `--percent` is used |
| `--percent` | No* | Input amount as a percentage, e.g. `50` = 50%; required unless `--amount` is used; only valid when input token is not a currency (not SOL/BNB/ETH/USDC) |
| `--slippage` | No | Slippage tolerance, e.g. `0.01` = 1% |
| `--auto-slippage` | No | Enable automatic slippage |
| `--min-output` | No | Minimum output amount (raw amount) |
| `--anti-mev` | No | Enable anti-MEV protection (default true) |
| `--priority-fee` | No | Priority fee in SOL (≥ 0.00001 SOL, SOL only) |
| `--tip-fee` | No | Tip fee (SOL ≥ 0.00001 SOL / BSC ≥ 0.000001 BNB) |
| `--max-auto-fee` | No | Max automatic fee cap |
| `--gas-price` | No | Gas price in gwei (BSC ≥ 0.05 gwei / BASE/ETH ≥ 0.01 gwei) |
| `--max-fee-per-gas` | No | EIP-1559 max fee per gas (Base/ETH only) |
| `--max-priority-fee-per-gas` | No | EIP-1559 max priority fee per gas (Base/ETH only) |
| `--condition-orders` | No | JSON array of take-profit/stop-loss conditions attached after a successful swap (see example below); only `profit_stop` and `loss_stop` are supported |
| `--sell-ratio-type` | No | Sell ratio base for `--condition-orders`: `buy_amount` (default) / `hold_amount` |
| Option | Required | Chain | Description |
|--------|----------|-------|-------------|
| `--chain` | Yes | all | `sol` / `bsc` / `base` / `eth` |
| `--from` | Yes | all | Wallet address (must match the wallet bound to the API Key) |
| `--input-token` | Yes | all | Input token contract address |
| `--output-token` | Yes | all | Output token contract address |
| `--amount` | No* | all | Input raw amount in minimal unit (e.g., lamports for SOL); required unless `--percent` is used |
| `--percent` | No* | all | Input amount as a percentage, e.g. `50` = 50%; required unless `--amount` is used; only valid when input token is not a currency (not SOL/BNB/ETH/USDC) |
| `--slippage` | No | all | Slippage tolerance as an integer 0100, e.g. `30` = 30% |
| `--auto-slippage` | No | all | Enable automatic slippage |
| `--min-output` | No | all | Minimum output amount (raw amount) |
| `--anti-mev` | No | all | Enable anti-MEV protection (default true) |
| `--priority-fee` | No | `sol` | Priority fee in SOL (≥ 0.00001) |
| `--tip-fee` | No | `sol` / `bsc` | Tip fee (SOL ≥ 0.00001 / BSC ≥ 0.000001 BNB) |
| `--gas-price` | No | `bsc` / `base` / `eth` | Gas price in gwei (BSC ≥ 0.05 / BASE/ETH ≥ 0.01) |
| `--gas-level` | No | `eth` | Gas price tier: `low` / `average` / `high`. Mutually exclusive with `--gas-price`. |
| `--auto-fee` | No | `eth` | **Only with `--condition-orders`.** GMGN automatically selects the optimal fee. |
| `--max-fee-per-gas` | No | `bsc` / `base` / `eth` | EIP-1559 max fee per gas |
| `--max-priority-fee-per-gas` | No | `bsc` / `base` / `eth` | EIP-1559 max priority fee per gas |
| `--condition-orders` | No | all | JSON array of take-profit/stop-loss conditions attached after a successful swap (see example below) |
| `--sell-ratio-type` | No | all | **Only with `--condition-orders`.** Sell ratio base: `buy_amount` (default) / `hold_amount` |
**`--condition-orders` example** (100% sell at 2× price, 100% sell at 50% price):
@@ -540,8 +601,6 @@ gmgn-cli multi-swap \
[--anti-mev] \
[--priority-fee <sol>] \
[--tip-fee <amount>] \
[--auto-tip-fee] \
[--max-auto-fee <amount>] \
[--gas-price <gwei>] \
[--max-fee-per-gas <amount>] \
[--max-priority-fee-per-gas <amount>] \
@@ -550,27 +609,27 @@ gmgn-cli multi-swap \
[--raw]
```
| Option | Required | Description |
|--------|----------|-------------|
| `--chain` | Yes | `sol` / `bsc` / `base` |
| `--accounts` | Yes | Comma-separated wallet addresses (1100, all bound to API Key) |
| `--input-token` | Yes | Input token contract address |
| `--output-token` | Yes | Output token contract address |
| `--input-amount` | No* | JSON map `{"addr":"amount"}` in smallest unit; one of the three amount fields is required |
| `--input-amount-bps` | No* | JSON map `{"addr":"bps"}` where 5000 = 50%; only valid when input token is not a currency |
| `--output-amount` | No* | JSON map `{"addr":"amount"}` target output in smallest unit |
| `--slippage` | No | Slippage tolerance, e.g. `0.01` = 1% |
| `--auto-slippage` | No | Enable automatic slippage |
| `--anti-mev` | No | Enable anti-MEV protection |
| `--priority-fee` | No | Priority fee in SOL (≥ 0.00001, SOL only) |
| `--tip-fee` | No | Tip fee (SOL ≥ 0.00001 / BSC ≥ 0.000001 BNB) |
| `--auto-tip-fee` | No | Enable automatic tip fee |
| `--max-auto-fee` | No | Max automatic fee cap |
| `--gas-price` | No | Gas price in gwei (BSC ≥ 0.05 / BASE/ETH ≥ 0.01) |
| `--max-fee-per-gas` | No | EIP-1559 max fee per gas (Base only) |
| `--max-priority-fee-per-gas` | No | EIP-1559 max priority fee per gas (Base only) |
| `--condition-orders` | No | JSON array of take-profit/stop-loss conditions, attached to each successful wallet's swap (best-effort) |
| `--sell-ratio-type` | No | Sell ratio base: `buy_amount` (default) / `hold_amount` |
| Option | Required | Chain | Description |
|--------|----------|-------|-------------|
| `--chain` | Yes | all | `sol` / `bsc` / `base` / `eth` |
| `--accounts` | Yes | all | Comma-separated wallet addresses (1100, all bound to API Key) |
| `--input-token` | Yes | all | Input token contract address |
| `--output-token` | Yes | all | Output token contract address |
| `--input-amount` | No* | all | JSON map `{"addr":"amount"}` in smallest unit; one of the three amount fields is required |
| `--input-amount-bps` | No* | all | JSON map `{"addr":"bps"}` where 5000 = 50%; only valid when input token is not a currency |
| `--output-amount` | No* | all | JSON map `{"addr":"amount"}` target output in smallest unit |
| `--slippage` | No | all | Slippage tolerance as an integer 0100, e.g. `30` = 30% |
| `--auto-slippage` | No | all | Enable automatic slippage |
| `--anti-mev` | No | all | Enable anti-MEV protection |
| `--priority-fee` | No | `sol` | Priority fee in SOL (≥ 0.00001) |
| `--tip-fee` | No | `sol` / `bsc` | Tip fee (SOL ≥ 0.00001 / BSC ≥ 0.000001 BNB) |
| `--gas-price` | No | `bsc` / `base` / `eth` | Gas price in gwei (BSC ≥ 0.05 / BASE/ETH ≥ 0.01) |
| `--gas-level` | No | `eth` | Gas price tier: `low` / `average` / `high`. Mutually exclusive with `--gas-price`. |
| `--auto-fee` | No | `eth` | **Only with `--condition-orders`.** GMGN automatically selects the optimal fee. |
| `--max-fee-per-gas` | No | `bsc` / `base` / `eth` | EIP-1559 max fee per gas |
| `--max-priority-fee-per-gas` | No | `bsc` / `base` / `eth` | EIP-1559 max priority fee per gas |
| `--condition-orders` | No | all | JSON array of take-profit/stop-loss conditions, attached to each successful wallet's swap (best-effort) |
| `--sell-ratio-type` | No | all | **Only with `--condition-orders`.** Sell ratio base: `buy_amount` (default) / `hold_amount` |
**Response fields (data):** Array of per-wallet results:
@@ -610,14 +669,17 @@ gmgn-cli order strategy create \
--from <wallet_address> \
--base-token <base_token_address> \
--quote-token <quote_token_address> \
--order-type <limit_order> \
--sub-order-type <buy_low|buy_high|stop_loss|take_profit> \
--check-price <price> \
--order-type <limit_order|smart_trade> \
--sub-order-type <buy_low|buy_high|stop_loss|take_profit|mix_trade> \
[--check-price <price>] \
[--open-price <price>] \
[--amount-in <amount> | --amount-in-percent <pct>] \
[--slippage <n> | --auto-slippage] \
[--limit-price-mode <exact|slippage>] \
[--expire-in <seconds>] \
[--sell-ratio-type <buy_amount|hold_amount>] \
[--quote-investment <amount>] \
[--condition-orders <json>] \
[--priority-fee <sol>] \
[--tip-fee <amount>] \
[--gas-price <gwei>] \
@@ -627,19 +689,22 @@ gmgn-cli order strategy create \
| Option | Required | Description |
|--------|----------|-------------|
| `--chain` | Yes | `sol` / `bsc` / `base` |
| `--chain` | Yes | `sol` / `bsc` / `base` / `eth` |
| `--from` | Yes | Wallet address (must match API Key binding) |
| `--base-token` | Yes | Base token contract address |
| `--quote-token` | Yes | Quote token contract address |
| `--order-type` | Yes | Order type: `limit_order` |
| `--sub-order-type` | Yes | Sub-order type: `buy_low` / `buy_high` / `stop_loss` / `take_profit` |
| `--check-price` | Yes | Trigger check price |
| `--order-type` | Yes | Order type: `limit_order` / `smart_trade` |
| `--sub-order-type` | Yes | `limit_order`: `buy_low` / `buy_high` / `stop_loss` / `take_profit`; `smart_trade` with condition_orders: `mix_trade` |
| `--check-price` | No* | Trigger check price — required for `limit_order`; omit for `smart_trade` (trigger is in the `buy_low` condition order) |
| `--open-price` | No | Open price of the position |
| `--amount-in` | No* | Input amount (smallest unit); required unless `--amount-in-percent` is used |
| `--amount-in-percent` | No* | Input as percentage (e.g. `50` = 50%); required unless `--amount-in` is used |
| `--limit-price-mode` | No | `exact` / `slippage` (default: `slippage`) |
| `--expire-in` | No | Order expiry in seconds |
| `--sell-ratio-type` | No | `buy_amount` (default) / `hold_amount` |
| `--slippage` | No | Slippage tolerance, e.g. `0.01` = 1% |
| `--quote-investment` | No | Quote token investment amount (`smart_trade`) |
| `--condition-orders` | No | JSON array of condition sub-orders for `smart_trade`. Must include one `buy_low` entry (with `check_price` lower than `open_price`) plus at least one TP/SL entry |
| `--slippage` | No | Slippage tolerance as an integer 0100, e.g. `30` = 30% |
| `--auto-slippage` | No | Enable automatic slippage |
| `--priority-fee` | No | Priority fee in SOL (**required for SOL chain**) |
| `--tip-fee` | No | Tip fee (**required for SOL chain**) |
@@ -733,30 +798,67 @@ gmgn-cli cooking create \
[--image <base64> | --image-url <url>] \
[--slippage <n> | --auto-slippage] \
[--website <url>] [--twitter <url>] [--telegram <url>] \
[--priority-fee <sol>] [--tip-fee <amount>] [--gas-price <amount>] \
[--anti-mev] \
[--fee <amount>] [--priority-fee <sol>] [--tip-fee <amount>] [--gas-price <amount>] \
[--max-fee-per-gas <amount>] [--max-priority-fee-per-gas <amount>] \
[--anti-mev] [--anti-mev-mode <off|normal|secure>] \
[--raised-token <symbol>] \
[--dev-wallet-bps <n>] [--dev-gas <amount>] [--dev-priority <amount>] [--dev-tip <amount>] [--dev-max-fee-per-gas <amount>] \
[--approve-vision <v1|v2>] [--source <source>] \
[--is-mayhem] [--is-cashback] [--is-buy-back] \
[--pump-fee-share-list <json>] \
[--flap-rate-conf <json>] \
[--fourmeme-rate-conf <json>] \
[--bags-fee-share-list <json>] \
[--bonk-model <model>] \
[--buy-wallets <json>] [--snip-buy-wallets <json>] \
[--buy-trade-config <json>] [--sell-trade-config <json>] [--sell-configs <json>] \
[--raw]
```
| Option | Required | Description |
|--------|----------|-------------|
| `--chain` | Yes | `sol` / `bsc` / `base` / `eth` / `ton` |
| `--dex` | Yes | Launchpad: `pump` / `raydium` / `pancakeswap` / `flap` / `fourmeme` / `bonk` / `bags` / ... |
| `--chain` | Yes | `sol` / `bsc` / `base` |
| `--dex` | Yes | Launchpad per chain: `pump` / `bonk` / `bags` (sol), `fourmeme` / `flap` (bsc), `klik` / `clanker` (base) |
| `--from` | Yes | Wallet address (must match API Key binding) |
| `--name` | Yes | Token name |
| `--symbol` | Yes | Token symbol |
| `--buy-amt` | Yes | Initial buy amount in native token (e.g. `0.01` SOL) |
| `--image` | No* | Token logo as base64-encoded data (max 2MB decoded); required unless `--image-url` is used |
| `--image-url` | No* | Token logo URL; required unless `--image` is used |
| `--slippage` | No* | Slippage tolerance as an integer 0100, e.g. `30` = 30%; required unless `--auto-slippage` is used |
| `--auto-slippage` | No* | Enable automatic slippage; required unless `--slippage` is used |
| `--website` | No | Website URL |
| `--twitter` | No | Twitter link |
| `--telegram` | No | Telegram link |
| `--slippage` | No | Slippage tolerance, e.g. `0.01` = 1% |
| `--auto-slippage` | No | Enable automatic slippage |
| `--priority-fee` | No | Priority fee in SOL (SOL only) |
| `--tip-fee` | No | Tip fee |
| `--gas-price` | No | Gas price in wei (EVM chains) |
| `--anti-mev` | No | Enable anti-MEV protection |
| `--fee` | No | Base gas / fee |
| `--priority-fee` | No | Priority fee in SOL (**SOL only**, ≥ 0.0001 SOL) |
| `--tip-fee` | No | Tip fee (SOL ≥ 0.00001 / BSC ≥ 0.000001 BNB; ignored on BASE) |
| `--gas-price` | No | Gas price in wei (**EVM only**) |
| `--max-fee-per-gas` | No | Max fee per gas in wei (**EVM only**) |
| `--max-priority-fee-per-gas` | No | Max priority fee per gas in wei (**EVM only**) |
| `--anti-mev` | No | Enable anti-MEV protection (**SOL only**) |
| `--anti-mev-mode` | No | Anti-MEV mode: `off` / `normal` / `secure` (**SOL only**) |
| `--raised-token` | No | Raise token symbol: `pump``USDC`; `bonk``USD1`; `fourmeme``USDT`/`USD1`; omit for native |
| `--dev-wallet-bps` | No | Dev wallet fee share in basis points (100 = 1%) |
| `--dev-gas` | No | Dev gas amount |
| `--dev-priority` | No | Dev priority fee |
| `--dev-tip` | No | Dev tip fee |
| `--dev-max-fee-per-gas` | No | Dev tx feeCap in wei (**EVM EIP-1559**) |
| `--approve-vision` | No | Approve vision version: `v1` / `v2` (default: `v2`) |
| `--source` | No | Traffic source identifier |
| `--is-mayhem` | No | Enable Mayhem mode (**Pump.fun only**) |
| `--is-cashback` | No | Enable Cashback (**Pump.fun only**) |
| `--is-buy-back` | No | Enable Agent Auto Buyback (**Pump.fun only**) |
| `--pump-fee-share-list` | No | Fee share list as JSON array: `[{"provider":"twitter","username":"<handle>","basic_points":<n>}]` (**Pump.fun only**) |
| `--flap-rate-conf` | No | Rate config as JSON object (**Flap only**) |
| `--fourmeme-rate-conf` | No | Rate config as JSON object (**FourMeme only**) |
| `--bags-fee-share-list` | No | Fee share list as JSON array: `[{"provider":"twitter","username":"<handle>","basic_points":<n>}]` (**BAGS only**) |
| `--bonk-model` | No | Bonk model identifier (**bonk DEX only**) |
| `--buy-wallets` | No | Multi-wallet buy config as JSON array: `[{"from_address":"<addr>","buy_amt":"<n>"}]` |
| `--snip-buy-wallets` | No | Snipe-buy wallet config as JSON array: `[{"from_address":"<addr>","buy_amt":"<n>"}]` |
| `--buy-trade-config` | No | Buy-side trade config for CondMarket orders as JSON (TradeParam) |
| `--sell-trade-config` | No | Sell-side trade config for auto-sell / pending_sell as JSON (TradeParam) |
| `--sell-configs` | No | Auto-sell strategy list as JSON array (CookingSellConfig[]): `[{"sell_type":"delay_sell","delay_sec":<n>,"sell_ratio":"0.5","wallet_addresses":["<addr>"]}]` |
**Response fields (data):**
@@ -803,7 +905,7 @@ Important notes:
| `AUTH_SIGNATURE_INVALID` | 401 | Signature verification failed |
| `AUTH_TIMESTAMP_EXPIRED` | 401 | Timestamp is outside the valid window (±5s) |
| `AUTH_CLIENT_ID_REPLAYED` | 401 | client_id replayed within 7s |
| `AUTH_REPLAY_CHECK_UNAVAILABLE` | 503 | Anti-replay Redis unavailable (critical auth only) |
| `AUTH_REPLAY_CHECK_UNAVAILABLE` | 503 | Anti-replay Redis unavailable (signed auth only) |
| `RATE_LIMIT_EXCEEDED` | 429 | Rate limit exceeded |
| `RATE_LIMIT_BANNED` | 429 | Temporarily banned due to repeated rate limit violations |
| `ERROR_RATE_LIMIT_BLOCKED` | 429 | Temporarily blocked after repeated business errors on `swap` |
@@ -812,5 +914,5 @@ Important notes:
| `BAD_REQUEST` | 400 | Missing or invalid request parameters |
| `INTERNAL_API_UNAVAILABLE` | 502 | Downstream market API unavailable |
| `BROKER_UNAVAILABLE` | 502 | Downstream trade broker unavailable |
| `TRADING_BOT_UNAVAILABLE` | 502 | Trading bot service unreachable (strategy endpoints) |
| `TRADING_BOT_UNAVAILABLE` | 502 | Strategy order service temporarily unreachable |
| `INTERNAL_ERROR` | 500 | Internal server error |
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "gmgn-cli",
"version": "1.2.5",
"version": "1.4.7",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "gmgn-cli",
"version": "1.2.5",
"version": "1.4.7",
"license": "MIT",
"dependencies": {
"commander": "^12.1.0",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "gmgn-cli",
"version": "1.2.5",
"version": "1.4.7",
"description": "GMGN OpenAPI CLI — call GMGN market, token, portfolio and swap APIs from the command line",
"type": "module",
"bin": {
+382 -65
View File
@@ -1,6 +1,6 @@
---
name: gmgn-cooking
description: "[FINANCIAL EXECUTION] Create and launch meme coins and crypto tokens on launchpads (Pump.fun, PancakeSwap, FourMeme, Bonk, BAGS, Flap, Raydium, etc.) via bonding curve fair launch, or query token creation stats by launchpad via GMGN API. Requires explicit user confirmation. Use when user asks to create a token, launch a meme coin, cook a coin, deploy on a launchpad, or check launchpad creation stats on Solana, BSC, Base, ETH, or TON."
description: "[FINANCIAL EXECUTION] Create and launch meme coins and crypto tokens on launchpads (Pump.fun, FourMeme, Bonk, BAGS, Flap, Klik, Clanker, etc.) via bonding curve fair launch, or query token creation stats by launchpad via GMGN API. Requires explicit user confirmation. Use when user asks to create a token, launch a meme coin, cook a coin, deploy on a launchpad, or check launchpad creation stats on Solana, BSC, or Base."
argument-hint: "stats | [create --chain <chain> --dex <dex> --from <addr> --name <name> --symbol <sym> --buy-amt <n> (--image <base64> | --image-url <url>)]"
metadata:
cliHelp: "gmgn-cli cooking --help"
@@ -24,11 +24,11 @@ Use the `gmgn-cli` tool to create a token on a launchpad platform or query token
- **Image input** — Token logo can be provided as base64-encoded data (`--image`, max 2MB decoded) or a publicly accessible URL (`--image-url`). Provide one or the other — not both. If the user gives a file path, read and base64-encode it before passing to `--image`. If they give a URL, use `--image-url` directly.
- **Status polling via `order get`** — `cooking create` is asynchronous. The immediate response may show `pending`. Poll with `gmgn-cli order get --chain <chain> --order-id <order_id>` until `confirmed`. The new token's contract address is in the `output_token` field of the `order get` response, not in the initial create response.
- **Status polling via `order get`** — `cooking create` is asynchronous. The immediate response may show `pending`. Poll with `gmgn-cli order get --chain <chain> --order-id <order_id>` until `confirmed`. The new token's contract address is in the `report.output_token` field of the `order get` response, not in the initial create response.
- **Critical auth** — `cooking create` requires both `GMGN_API_KEY` and `GMGN_PRIVATE_KEY`. The private key never leaves the machine — the CLI uses it only for local signing. `cooking stats` uses normal auth (API Key only).
- **Signed auth** — `cooking create` requires both `GMGN_API_KEY` and `GMGN_PRIVATE_KEY`. The private key never leaves the machine — the CLI uses it only for local signing. `cooking stats` uses exist auth (API Key only).
- **Slippage** — The initial buy is executed as part of the same transaction as token creation. Slippage applies to that buy. Use `--slippage` (decimal, e.g. `0.01` = 1%) or `--auto-slippage`. One of the two is required when `--buy-amt` is set.
- **Slippage** — The initial buy is executed as part of the same transaction as token creation. Slippage applies to that buy. Use `--slippage` (integer 0100, e.g. `30` = 30%) or `--auto-slippage`. One of the two is required when `--buy-amt` is set.
## Financial Risk Notice
@@ -43,22 +43,34 @@ Use the `gmgn-cli` tool to create a token on a launchpad platform or query token
| Sub-command | Description |
|-------------|-------------|
| `cooking stats` | Get token creation count statistics grouped by launchpad platform (normal auth) |
| `cooking create` | Deploy a new token on a launchpad platform (requires private key) |
| `cooking stats` | Get token creation count statistics grouped by launchpad platform (exist auth) |
| `cooking create` | Deploy a new token on a launchpad platform (signed auth) |
## Supported Chains
`sol` / `bsc` / `base` / `eth` / `ton`
`sol` / `bsc` / `base`
## Supported Launchpads by Chain
| Chain | `--dex` values |
|-------|----------------|
| `sol` | `pump` / `raydium` / `bonk` / `bags` / `memoo` / `letsbonk` / `bonkers` |
| `bsc` | `pancakeswap` / `flap` / `fourmeme` |
| `base` | `clanker` / `flaunch` / `baseapp` / `basememe` / `zora` / `virtuals_v2` |
| Chain | `--dex` values | Raise token (`--raised-token`) |
| ------ | ---------------------- | ------------------------------ |
| `sol` | `pump`, `bonk`, `bags` | `pump`: `""` (SOL) or `USDC`; `bonk`: `""` (SOL) or `USD1`; `bags`: `""` (SOL only) |
| `bsc` | `fourmeme`, `flap` | `fourmeme`: `""` (BNB), `USD1`, `USDT`; `flap`: `""` (BNB only) |
| `base` | `klik`, `clanker` | `""` only (quote token fixed to WETH) |
When the user names a platform colloquially (e.g. "pump.fun", "four.meme", "PancakeSwap"), map it to the correct `--dex` identifier from this table before running the command.
When the user names a platform colloquially (e.g. "pump.fun", "four.meme"), map it to the correct `--dex` identifier from this table before running the command.
**Anti-MEV** (`--anti-mev`) is only supported on `sol`. Passing it on `bsc` or `base` will return a 400 error.
### Quote Token conversion (when `--raised-token` is set)
`--buy-amt` is **always in native token units** (SOL / BNB / ETH), even when raising with a quote token like USDC / USD1 / USDT. If the user states the amount in the quote token, convert it to native yourself before passing it:
```
buy_amt_in_native = quote_amount × quote_price / native_price
```
This conversion applies to **`--buy-amt`, and the `buy_amt` field inside `--buy-wallets` and `--snip-buy-wallets`**. It does **not** apply to `--sell-configs` (`check_price` there is always a USD market cap, not a token amount). Round to the chain's native decimals. When `--raised-token` is empty/native, no conversion is needed.
## Prerequisites
@@ -74,7 +86,7 @@ If a local `.env` exists but lacks `GMGN_API_KEY` / `GMGN_PRIVATE_KEY`, either a
## Rate Limit Handling
All cooking routes go through GMGN's leaky-bucket limiter with `rate=10` and `capacity=10`. Sustained throughput is roughly `10 ÷ weight` requests/second.
All cooking routes go through GMGN's leaky-bucket limiter with `rate=20` and `capacity=20`. Sustained throughput is roughly `20 ÷ weight` requests/second.
| Command | Weight |
|---------|--------|
@@ -121,34 +133,222 @@ gmgn-cli cooking stats [--raw]
| Field | Type | Description |
|-------|------|-------------|
| `launchpad` | string | Launchpad identifier (e.g. `pump`, `raydium`, `pancakeswap`) |
| `launchpad` | string | Launchpad identifier (e.g. `pump`, `bonk`, `fourmeme`) |
| `token_count` | int | Number of tokens created via GMGN on that launchpad |
## `cooking create` Parameters
| Parameter | Required | Description |
|-----------|----------|-------------|
| `--chain` | Yes | Chain: `sol` / `bsc` / `base` / `eth` / `ton` |
| `--chain` | Yes | Chain: `sol` / `bsc` / `base` |
| `--dex` | Yes | Launchpad platform identifier — see Supported Launchpads table. Never guess this value. |
| `--from` | Yes | Wallet address (must match API Key binding) |
| `--name` | Yes | Token full name (e.g. `Doge Killer`) |
| `--symbol` | Yes | Token ticker symbol (e.g. `DOGEK`) |
| `--description` | No | Token description / project pitch |
| `--buy-amt` | Yes | Initial buy amount in **human-readable native token units** (e.g. `0.01` = 0.01 SOL). This is NOT in smallest unit. |
| `--image` | No* | Token logo as **base64-encoded** data (max 2MB decoded). Mutually exclusive with `--image-url`. One of the two is required. |
| `--image-url` | No* | Token logo as a publicly accessible URL. Mutually exclusive with `--image`. One of the two is required. |
| `--slippage` | No* | Slippage tolerance, e.g. `0.01` = 1%. **Mutually exclusive with `--auto-slippage`** — provide one or the other. |
| `--slippage` | No* | Slippage tolerance as an integer 0100, e.g. `30` = 30%. **Mutually exclusive with `--auto-slippage`** — provide one or the other. |
| `--auto-slippage` | No* | Enable automatic slippage. **Mutually exclusive with `--slippage`.** |
| `--description` | No | Token description / project pitch |
| `--website` | No | Project website URL |
| `--twitter` | No | Twitter / X URL |
| `--telegram` | No | Telegram group URL |
| `--priority-fee` | No | Priority fee in SOL (SOL only, ≥ 0.0001 SOL) |
| `--tip-fee` | No | Tip fee (SOL ≥ 0.00001 / BSC ≥ 0.000001 BNB; ignored on ETH/BASE) |
| `--gas-price` | No | Gas price in wei (EVM chains) |
| `--anti-mev` | No | Enable anti-MEV protection |
| `--fee` | No | Base gas / fee |
| `--priority-fee` | No | Priority fee in SOL (**SOL only**, ≥ 0.0001 SOL) |
| `--tip-fee` | No | Tip fee (SOL ≥ 0.00001 / BSC ≥ 0.000001 BNB; ignored on BASE) |
| `--gas-price` | No | Gas price in wei (EVM chains: BSC / BASE) |
| `--max-fee-per-gas` | No | Max fee per gas in wei (**EVM only**) |
| `--max-priority-fee-per-gas` | No | Max priority fee per gas in wei (**EVM only**) |
| `--anti-mev` | No | Enable anti-MEV protection (**SOL only**; rejected on BSC / BASE) |
| `--anti-mev-mode` | No | Anti-MEV mode: `off` / `normal` / `secure` (**SOL only**) |
| `--raised-token` | No | Raise token symbol. `pump`: `USDC`; `bonk`: `USD1`; `fourmeme`: `USDT` / `USD1`; omit or `""` for native |
| `--dev-wallet-bps` | No | Dev wallet fee share in basis points (100 = 1%) |
| `--dev-gas` | No | Dev gas amount |
| `--dev-priority` | No | Dev priority fee |
| `--dev-tip` | No | Dev tip fee |
| `--dev-max-fee-per-gas` | No | Dev tx feeCap in wei (**EVM EIP-1559**) |
| `--approve-vision` | No | Approve vision version: `v1` / `v2` (default: `v2`) |
| `--source` | No | Traffic source identifier |
| `--is-mayhem` | No | Enable Mayhem mode (**Pump.fun only**) |
| `--is-cashback` | No | Enable Cashback (**Pump.fun only**) |
| `--is-buy-back` | No | Enable Agent Auto Buyback (**Pump.fun only**) |
| `--pump-fee-share-list` | No | Pump.fun fee share list as JSON array: `[{"provider":"twitter","username":"<handle>","basic_points":<n>}]` (**Pump.fun only**) |
| `--flap-rate-conf` | No | Flap rate config as JSON object (**Flap only**) |
| `--fourmeme-rate-conf` | No | FourMeme rate config as JSON object (**FourMeme only**) |
| `--bags-fee-share-list` | No | BAGS fee share list as JSON array: `[{"provider":"twitter","username":"<handle>","basic_points":<n>}]` (**BAGS only**) |
| `--bonk-model` | No | Bonk model identifier (**bonk DEX only**) |
| `--buy-wallets` | No | Multi-wallet buy config as JSON array: `[{"from_address":"<addr>","buy_amt":"<n>"}]` |
| `--snip-buy-wallets` | No | Snipe-buy wallet config as JSON array: `[{"from_address":"<addr>","buy_amt":"<n>"}]` |
| `--buy-trade-config` | No | Buy-side trade config for CondMarket orders as JSON (TradeParam) — see Advanced API Fields |
| `--sell-trade-config` | No | Sell-side trade config for auto-sell / pending_sell as JSON (TradeParam) — see Advanced API Fields |
| `--sell-configs` | No | Auto-sell strategy list as JSON array (CookingSellConfig[]) — see Auto-Sell Configuration |
\* `--image` or `--image-url`: provide exactly one. `--slippage` or `--auto-slippage`: provide exactly one.
## Advanced API Fields
The structured flags (`--pump-fee-share-list`, `--bags-fee-share-list`, `--flap-rate-conf`, `--fourmeme-rate-conf`, `--buy-wallets`, `--snip-buy-wallets`, `--buy-trade-config`, `--sell-trade-config`, `--sell-configs`) each accept a **JSON string**. This section documents the exact JSON schema for each.
### Platform capability matrix
Which advanced features each platform supports. Do not send a field a platform does not support.
| Platform | `--dex` | Chain | Platform-specific fields | Bundle (`--buy-wallets`) | Sniper (`--snip-buy-wallets`) | Cashback | Mayhem |
|---|---|---|---|---|---|---|---|
| Pump.fun | `pump` | SOL | `--pump-fee-share-list` / `--dev-wallet-bps` / `--is-buy-back` | ✅ up to 12 wallets | ✅ up to 10 | ✅ | ✅ |
| Bonk | `bonk` | SOL | `--bonk-model` | ❌ | ✅ up to 10 | ❌ | ❌ |
| BAGS | `bags` | SOL | `--bags-fee-share-list` / `--dev-wallet-bps` | ❌ | ✅ up to 10 | ❌ | ❌ |
| FourMeme | `fourmeme` | BSC | `--fourmeme-rate-conf` | ✅ up to 3 wallets | ✅ up to 10 | ❌ | ❌ |
| Flap | `flap` | BSC | `--flap-rate-conf` | ❌ | ✅ up to 10 | ❌ | ❌ |
| Klik | `klik` | Base | — | ❌ | ✅ up to 10 | ❌ | ❌ |
| Clanker | `clanker` | Base | — | ❌ | ✅ up to 10 | ❌ | ❌ |
- `--is-cashback` / `--is-mayhem` are **Pump.fun only** — other platforms reject them.
- Bundle/auto-sell (`--sell-configs`) and sniper (`--snip-buy-wallets`) are available where the matrix shows ✅.
**Basis-points rule:** any field named `*_bps` / `basic_points` is in basis points (`100` = 1%). Where a section says the shares must sum, all entries must add up to exactly **10000** (FourMeme uses whole percents summing to **100** instead — see below).
**Always talk to the user in percentages, never basis points.** When asking for or confirming any share, fee, or split, phrase it as a percentage (e.g. *"What % goes to this wallet?"* → user says `"50%"`). Convert to the field's unit yourself when building the JSON — never ask the user for a raw bps number:
| User says | `*_bps` field (×100) | FourMeme `*_rate` field (×1) |
|---|---|---|
| `5%` | `500` | `5` |
| `50%` | `5000` | `50` |
| `100%` | `10000` | `100` |
Never set a fee-share split without the user's explicit instruction — it permanently routes token revenue to the listed accounts.
### Pump.fun (`--dex pump`)
> `is_mayhem`, `is_cashback`, `is_buy_back` use their matching CLI flags (`--is-mayhem`, `--is-cashback`, `--is-buy-back`). `pump_fee_share_list` is passed via `--pump-fee-share-list`.
| Field | CLI flag | Description |
|---|---|---|
| `pump_fee_share_list` | `--pump-fee-share-list <json>` | Fee-share list — see JSON schema below |
| `is_buy_back` | `--is-buy-back` | Enable Agent Auto Buyback |
**JSON schema for `--pump-fee-share-list`** — array of objects:
| Field | Type | Required | Description |
|---|---|---|---|
| `provider` | string | Yes | `solana` / `twitter` / `github` |
| `username` | string | Yes | Platform username; a SOL address when `provider` = `solana` |
| `basic_points` | int | Yes | Share in bps — all entries must sum to **10000** |
Example: `--pump-fee-share-list '[{"provider":"twitter","username":"handle","basic_points":10000}]'`
### Bonk (`--dex bonk`)
`dev_wallet_bps` → `--dev-wallet-bps`, `bonk_model` → `--bonk-model`. No additional structured fields.
### BAGS (`--dex bags`)
`dev_wallet_bps` → `--dev-wallet-bps`. `bags_fee_share_list` is passed via `--bags-fee-share-list`.
**JSON schema for `--bags-fee-share-list`** — array of objects:
| Field | Type | Required | Description |
|---|---|---|---|
| `provider` | string | Yes | `twitter` / `solana` / `kick` / `github` |
| `username` | string | Yes | Platform username |
| `basic_points` | int | Yes | Share in bps — combined with `dev_wallet_bps`, all must sum to **10000** |
### Flap (`--dex flap`)
`flap_rate_conf` is passed via `--flap-rate-conf`.
**JSON schema for `--flap-rate-conf`** — single object:
| Field | Type | Required | Description |
|---|---|---|---|
| `buy_tax_rate` | int | Conditional | V6 separate buy tax rate in bps, e.g. 1% → `100`. Use together with `sell_tax_rate`. |
| `sell_tax_rate` | int | Conditional | V6 separate sell tax rate in bps |
| `tax_rate` | int | Conditional | V5 unified tax rate in bps, e.g. 5% → `500`. Use instead of `buy_tax_rate` + `sell_tax_rate`. |
| `mkt_bps` | int | Yes | **Tax recipient share** — the slice of the collected tax routed to the recipient(s): the X handle when `recipient_type = gift`, or the `split_conf` addresses when `recipient_type = split`. This is NOT a generic "marketing" fund. |
| `deflation_bps` | int | Yes | Burn (supply-reduction) share |
| `dividend_bps` | int | Yes | Dividend (holder-reward) share |
| `lp_bps` | int | Yes | Liquidity share |
| `recipient_type` | string | Yes | `gift` (route the recipient share to an X handle) / `split` (route it to specific addresses) |
| `twitter_account` | string | Conditional | X / Twitter handle that receives the recipient share — **required when `recipient_type = gift`**; leave `""` when `split`. |
| `split_conf` | array | Conditional | Recipient address split list — **required when `recipient_type = split`**; leave `[]` when `gift`. |
| `minimum_share_balance` | int | Yes | Min holding to qualify for dividends — minimum **10000** tokens |
| `beneficiary` | string | No | Legacy single fee-recipient address. Omit when using `recipient_type` + `twitter_account` / `split_conf`. |
`split_conf` entries: `{ "recipient": "<address>", "bps": <n> }` — all `bps` must sum to **10000**.
> - **Tax distribution:** whenever the tax rate > 0, `mkt_bps + deflation_bps + dividend_bps + lp_bps` must sum to **10000**. `mkt_bps` is the recipient's cut; the other three are burn / dividend / liquidity.
> - **Recipient routing:** set `recipient_type = gift` + `twitter_account` to send the recipient cut to an X handle, OR `recipient_type = split` + `split_conf` to send it to one or more addresses. Fill only the field that matches the chosen mode; leave the other empty (`""` / `[]`).
> - Use `tax_rate` for V5 (unified rate); use `buy_tax_rate` + `sell_tax_rate` for V6 (separate rates).
> - When `lp_bps > 0`: `minimum_share_balance` must be > 0.
### FourMeme (`--dex fourmeme`)
`fourmeme_rate_conf` is passed via `--fourmeme-rate-conf`.
> `fourmeme_user_login_sign`, `is_approve_allowance`, `is_raised_swap` are broker/jobs **internal** fields — the public API does not accept them, so there is no flag. The multi-quote raise-token retry is handled server-side automatically (poll `order get`); the caller never sets these.
**JSON schema for `--fourmeme-rate-conf`** — single object:
| Field | Type | Required | Description |
|---|---|---|---|
| `fee_plan` | bool | No | Enable the fee plan |
| `recipient_address` | string | Yes | Fee recipient address |
| `fee_rate` | int | Yes | Fee rate, e.g. 5% → `5` (whole percent, not bps) |
| `burn_rate` | int | Yes | Burn share |
| `divide_rate` | int | Yes | Dividend share |
| `liquidity_rate` | int | Yes | Liquidity share |
| `recipient_rate` | int | Yes | Recipient share |
| `min_sharing` | int | Yes | Minimum sharing threshold |
> When `fee_rate > 0`: `burn_rate + divide_rate + liquidity_rate + recipient_rate` must sum to **100**. When `recipient_rate > 0`: `min_sharing` must be > 0.
## Auto-Sell Configuration
`sell_configs` is passed via `--sell-configs` as a JSON array. It schedules conditional sell orders to execute automatically once the token launch succeeds. Omit entirely for a standard launch with no auto-sell.
`--sell-configs` is a JSON array of `CookingSellConfig` objects:
| Field | Type | Required | Description |
|---|---|---|---|
| `sell_type` | string | Yes | `delay_sell` / `limit_order` |
| `delay_sec` | int64 | Conditional | Seconds after buy to trigger; required when `sell_type = delay_sell` |
| `delay_mili_sec` | int64 | No | Milliseconds after buy to trigger; takes precedence over `delay_sec` |
| `sell_ratio` | string | Yes | Fraction to sell — `"1"` = 100%, `"0.5"` = 50% |
| `check_price` | string | Conditional | Market cap in USD to trigger sell; required when `sell_type = limit_order` |
| `wallet_addresses` | []string | Yes | Wallets this strategy applies to (empty array = inert) |
Example: `--sell-configs '[{"sell_type":"delay_sell","delay_sec":60,"sell_ratio":"0.5","wallet_addresses":["<addr>"]}]'`
The buy/sell execution params for these CondMarket orders (slippage, fees, anti-MEV) can be tuned separately via `--buy-trade-config` / `--sell-trade-config` (TradeParam JSON). They do **not** affect the main creation tx, and fall back to the outer-level transaction flags when omitted.
> - **`check_price` is total market cap in USD** — e.g. `"50000"` triggers at a $50,000 market cap.
> - `wallet_addresses` may mix `from_address` and `buy_wallets` entries. The server creates `signal_cooking` for snipe wallets and `pending_sell` for main/bundle wallets automatically.
> - A wallet can carry multiple strategies (e.g. delay-sell 50%, then limit-sell the rest); each applies independently.
### TradeParam (`--buy-trade-config` / `--sell-trade-config`)
These tune the **execution params for the CondMarket buy/sell orders** (bundle buys, sniper buys, and auto-sell). They do **not** affect the main creation transaction (the dev tx uses the outer-level `--dev-*` flags). When omitted, they fall back to the outer-level transaction flags.
`--buy-trade-config` / `--sell-trade-config` each accept a single JSON object:
| Field | Type | Description |
|---|---|---|
| `slippage` | number | Slippage; only sent when truthy |
| `fee` | string | Base gas / fee; only sent when truthy |
| `priority_fee` | string | Priority fee; only sent when truthy |
| `tip_fee` | string | SOL Jito tip; only sent when truthy |
| `gas_price` | string | Gas price in wei (EVM); only sent when truthy |
| `max_priority_fee_per_gas` | string | EVM EIP-1559; only sent when truthy |
| `max_fee_per_gas` | string | EVM EIP-1559; only sent when truthy |
| `auto_slippage` | bool | Always sent |
| `is_anti_mev` | bool | Always sent |
| `anti_mev_mode` | string | `off` / `normal` / `secure`; always sent |
Example: `--buy-trade-config '{"slippage":50,"auto_slippage":false,"priority_fee":"0.0005","tip_fee":"0.0001","is_anti_mev":true,"anti_mev_mode":"secure"}'`
> A standard launch with no `buyConfig` sends `{"is_anti_mev":false,"anti_mev_mode":"off"}` and an empty `buy_wallets` list.
## `cooking create` Response Fields
| Field | Type | Description |
@@ -174,6 +374,8 @@ Token creation is **asynchronous**. If the initial `cooking create` response sho
## Usage Examples
Examples run shortest-first: basic single-launch commands, then full end-to-end configurations. Every JSON flag below is a valid payload shape — copy and adapt.
```bash
# Get token creation statistics per launchpad
gmgn-cli cooking stats
@@ -187,24 +389,10 @@ gmgn-cli cooking create \
--symbol MAT \
--buy-amt 0.01 \
--image-url https://example.com/logo.png \
--slippage 0.01 \
--slippage 30 \
--priority-fee 0.001
# Create a token on PancakeSwap (BSC) — with URL image and social links
gmgn-cli cooking create \
--chain bsc \
--dex pancakeswap \
--from <wallet_address> \
--name "BSC Token" \
--symbol BSCT \
--buy-amt 0.05 \
--image-url https://example.com/logo.png \
--slippage 0.02 \
--gas-price 5000000000 \
--website https://mytoken.io \
--twitter https://twitter.com/mytoken
# Create a token on FourMeme (BSC) — using base64 image from local file
# Create a token on FourMeme (BSC) — base64 image + USD1 raise token
gmgn-cli cooking create \
--chain bsc \
--dex fourmeme \
@@ -213,12 +401,13 @@ gmgn-cli cooking create \
--symbol FOUR \
--buy-amt 0.05 \
--image "$(base64 -i /path/to/logo.png)" \
--auto-slippage
--auto-slippage \
--raised-token USD1
# Create a token on letsbonk (SOL)
# Create a token on Bonk (SOL) with anti-MEV
gmgn-cli cooking create \
--chain sol \
--dex letsbonk \
--dex bonk \
--from <wallet_address> \
--name "Bonk Token" \
--symbol BNKT \
@@ -227,8 +416,112 @@ gmgn-cli cooking create \
--auto-slippage \
--anti-mev
# Create on Pump.fun with auto-sell: sell 50% 60s after buy
gmgn-cli cooking create \
--chain sol \
--dex pump \
--from <wallet_address> \
--name "My Token" \
--symbol MAT \
--buy-amt 0.01 \
--image-url https://example.com/logo.png \
--auto-slippage \
--sell-configs '[{"sell_type":"delay_sell","delay_sec":60,"sell_ratio":"0.5","wallet_addresses":["<wallet_address>"]}]'
```
These mirror real launch configurations end-to-end.
**Pump.fun (SOL) — Bundle + Sniper + Auto-Sell + Agent Auto Buyback**
```bash
gmgn-cli cooking create \
--chain sol \
--dex pump \
--from DevWallet... \
--name "Demo Coin" \
--symbol DEMO \
--buy-amt 0.5 \
--image-url https://cdn.example.com/coin.png \
--twitter https://x.com/handle/status/123 \
--priority-fee 0.0005 \
--tip-fee 0.0001 \
--is-buy-back \
--buy-trade-config '{"slippage":50,"auto_slippage":false,"priority_fee":"0.0005","tip_fee":"0.0001","is_anti_mev":true,"anti_mev_mode":"secure"}' \
--buy-wallets '[{"from_address":"Wallet1...","buy_amt":"0.1"},{"from_address":"Wallet2...","buy_amt":"0.1"}]' \
--snip-buy-wallets '[{"from_address":"Sniper1...","buy_amt":"0.05"}]' \
--sell-configs '[{"sell_type":"delay_sell","sell_ratio":"1","wallet_addresses":["Wallet1..."],"delay_mili_sec":5000}]'
```
- `--is-buy-back` is the Agent Auto Buyback mode (the backend also sets the agent fee internally).
- `buy_amt` values in `--buy-wallets` / `--snip-buy-wallets` are in native SOL.
- Bundle wallets ≤ 12, sniper wallets ≤ 10 on Pump.fun (see capability matrix).
**FourMeme (BSC) — user fee split + raise token USDT**
```bash
gmgn-cli cooking create \
--chain bsc \
--dex fourmeme \
--from 0xDev... \
--name "Demo BSC" \
--symbol DBSC \
--buy-amt 0.0123 \
--image-url https://cdn.example.com/coin.png \
--raised-token USDT \
--website https://demo.com \
--gas-price 1000000000 \
--auto-slippage \
--fourmeme-rate-conf '{"fee_rate":1,"recipient_rate":50,"burn_rate":20,"divide_rate":20,"liquidity_rate":10,"min_sharing":100000,"recipient_address":"0xDev..."}'
```
- `--buy-amt 0.0123` is **already converted to native BNB** from the USDT amount the user wanted (see Quote Token conversion). Do the conversion before building the command.
- `--gas-price 1000000000` is wei (1 Gwei).
- In `--fourmeme-rate-conf`, `recipient_rate + burn_rate + divide_rate + liquidity_rate` must sum to **100**.
**Flap (BSC) — `split` mode: route the recipient cut to a BSC address**
```bash
gmgn-cli cooking create \
--chain bsc \
--dex flap \
--from 0x1f8d977b6843e1bbcb306c4a3664c9fb0277979d \
--name "refer" \
--symbol refer \
--buy-amt 2 \
--image-url https://gmgn.ai/external-res-va/11ad7747dcefcfaae87d3f53a4d7330d_v2l.webp \
--website https://www.refercoins.bond/ \
--twitter https://x.com/referdotfun \
--dev-gas 50000000 \
--auto-slippage \
--flap-rate-conf '{"buy_tax_rate":100,"sell_tax_rate":100,"mkt_bps":10000,"deflation_bps":0,"dividend_bps":0,"lp_bps":0,"minimum_share_balance":10000,"recipient_type":"split","twitter_account":"","split_conf":[{"recipient":"0x1f8d977b6843e1bbcb306c4a3664c9fb0277979d","bps":10000}]}'
```
- `recipient_type: split` → the recipient cut goes to `split_conf` addresses; `twitter_account` is left `""`.
- `mkt_bps:10000` means the **entire** tax (1% buy / 1% sell) goes to the recipient — `deflation_bps + dividend_bps + lp_bps` are all `0`, and the four still sum to **10000**.
- `split_conf` has one address taking all `10000` bps (100%). Multiple addresses are allowed as long as their `bps` sum to `10000`.
**Flap (BSC) — `gift` mode: route the recipient cut to an X handle, split the rest across burn / dividend / LP**
```bash
gmgn-cli cooking create \
--chain bsc \
--dex flap \
--from 0x1f8d977b6843e1bbcb306c4a3664c9fb0277979d \
--name "refer" \
--symbol refer \
--buy-amt 2 \
--image-url https://gmgn.ai/external-res-va/11ad7747dcefcfaae87d3f53a4d7330d_v2l.webp \
--website https://www.refercoins.bond/ \
--twitter https://x.com/referdotfun \
--dev-gas 50000000 \
--auto-slippage \
--flap-rate-conf '{"buy_tax_rate":100,"sell_tax_rate":100,"mkt_bps":5000,"deflation_bps":2700,"dividend_bps":1800,"lp_bps":500,"minimum_share_balance":10000,"recipient_type":"gift","twitter_account":"handleName","split_conf":[]}'
```
- `recipient_type: gift` → the recipient cut goes to the `twitter_account` X handle; `split_conf` is left `[]`.
- Tax distribution: `mkt_bps:5000` (50% to the handle) + `deflation_bps:2700` (27% burn) + `dividend_bps:1800` (18% dividend) + `lp_bps:500` (5% LP) = **10000**.
- `lp_bps > 0`, so `minimum_share_balance` must be > 0 (`10000` here).
## Output Format
### Pre-create Confirmation
@@ -247,10 +540,15 @@ Initial Buy: {--buy-amt} {native currency} (e.g. 0.01 SOL)
Slippage: {--slippage}% (or "auto")
Image: {--image-url or "base64 provided"}
Social: {twitter / telegram / website if provided}
Modes: {Mayhem / Cashback / Agent Auto Buyback if set, else "none"}
Fee Share: {recipient → % list if set, else "none"}
Auto-Sell: {sell_configs summary if set, else "none"}
Reply "confirm" to deploy this token. This action is IRREVERSIBLE.
```
Omit the Modes / Fee Share / Auto-Sell lines if none were configured — or show them as `none` — but if any **are** set, they MUST appear here so the user re-confirms them explicitly.
### Post-create Receipt
After polling confirms a successful deployment:
@@ -259,7 +557,7 @@ After polling confirms a successful deployment:
✅ Token Created
Token: {--name} ({--symbol})
Address: {output_token from order get}
Address: {report.output_token from order get}
Chain: {chain}
Platform: {--dex}
Tx: {explorer link for hash}
@@ -273,7 +571,6 @@ Block explorer links:
| sol | `https://solscan.io/tx/<hash>` |
| bsc | `https://bscscan.com/tx/<hash>` |
| base | `https://basescan.org/tx/<hash>` |
| eth | `https://etherscan.io/tx/<hash>` |
## Guided Launch Flow
@@ -287,24 +584,20 @@ Ask: *"Which chain and platform?"*
Show the options concisely:
| Chain | Platform | `--dex` |
|-------|----------|---------|
| Solana | Pump.fun | `pump` |
| Solana | letsbonk | `letsbonk` |
| Solana | Raydium | `raydium` |
| Solana | BAGS | `bags` |
| Solana | Memoo | `memoo` |
| Solana | Bonkers | `bonkers` |
| BSC | FourMeme | `fourmeme` |
| BSC | PancakeSwap | `pancakeswap` |
| BSC | Flap | `flap` |
| Base | Clanker | `clanker` |
| Base | Zora | `zora` |
| Base | Flaunch | `flaunch` |
| Base | Virtuals | `virtuals_v2` |
| Chain | Platform | `--dex` |
| ------ | ---------- | ---------- |
| Solana | Pump.fun | `pump` |
| Solana | Bonk | `bonk` |
| Solana | BAGS | `bags` |
| BSC | FourMeme | `fourmeme` |
| BSC | Flap | `flap` |
| Base | Klik | `klik` |
| Base | Clanker | `clanker` |
If the user is unsure, recommend: **Pump.fun (SOL)** or **FourMeme (BSC)**.
The chosen platform determines which advanced options are available later in Step 7 (e.g. Mayhem/Cashback/Agent Auto Buyback on Pump.fun, fee-share splits on BAGS/Flap/FourMeme). Note the platform now; do not ask about advanced options yet.
### Step 2 — Token Name
Ask: *"Token name?"*
@@ -343,9 +636,32 @@ Ask all optional fields together in one message:
The user can reply with just the ones they have, or say "skip" / "none" to proceed.
### Step 7 — Confirmation & Execute
### Step 7 — Platform Modes, Fees & Auto-Sell (platform-dependent)
Once all information is collected, present the pre-create confirmation summary (see Output Format section) and wait for the user to reply "confirm" before executing.
After the basics are collected, ask **once** whether the user wants any advanced options for the platform they chose. Default everyone to a plain fair launch — only configure these when the user explicitly asks. Tailor the question to the selected platform; do not list options that don't apply to it.
Ask: *"Want any advanced options, or launch with defaults? (reply 'defaults' to skip)"* — then offer the relevant subset.
**Phrase the question around the platform the user picked — only ask about modes that exist on that platform.** For example, on **Pump.fun** ask specifically:
- *"Enable Cashback mode?"* (`--is-cashback`)
- *"Enable Agent Auto Buyback mode?"* (`--is-buy-back`)
- *"Enable Mayhem mode?"* (`--is-mayhem`)
- *"Set up a fee-share split?"* (`--pump-fee-share-list`)
- *"Want me to remember these advanced settings for your next launch?"* — if yes, save them to memory so future launches can pre-fill the same choices.
Bonk / BAGS / Flap / FourMeme have **no mode toggles** — for those, skip the mode questions and only ask about fee-share split and auto-sell.
The relevant options per platform:
- **Pump.fun modes** — Mayhem (`--is-mayhem`), Cashback (`--is-cashback`), Agent Auto Buyback (`--is-buy-back`).
- **Fee-share split** — Pump.fun (`--pump-fee-share-list`), BAGS (`--dev-wallet-bps` + `--bags-fee-share-list`), Bonk (`--dev-wallet-bps`), Flap (`--flap-rate-conf`), FourMeme (`--fourmeme-rate-conf`). See [Advanced API Fields](#advanced-api-fields) for JSON schemas. **Warn the user this permanently routes token revenue to the listed accounts.** Always ask the user for shares as percentages — convert to bps yourself. Shares must add up to 100%.
- **Auto-sell** — `--sell-configs` (JSON): delay-sell (sell a fraction N seconds after the buy) and/or limit-sell (sell once market cap hits a USD target). See [Auto-Sell Configuration](#auto-sell-configuration). Confirm the sell ratio and trigger before setting it.
If the user says "defaults" / "skip" / "none", proceed with none of these set.
### Step 8 — Confirmation & Execute
Once all information is collected, present the pre-create confirmation summary (see Output Format section) and wait for the user to reply "confirm" before executing. If any advanced options from Step 7 were set, they MUST appear in the summary so the user re-confirms them explicitly.
---
@@ -355,18 +671,19 @@ Once all information is collected, present the pre-create confirmation summary (
- **[REQUIRED] `--dex` validation** — Before running, look up the user's named platform in the Supported Launchpads table and resolve to the correct `--dex` identifier. Never guess or pass a freeform platform name. If the chain/platform combination is not in the table, tell the user it is unsupported.
- **Slippage requirement** — Either `--slippage` or `--auto-slippage` must be provided. If the user did not specify, suggest `--auto-slippage` for volatile new tokens or ask for a preference.
- **Image handling** — If the user provides a file path, run `base64 -i <path>` and pass the result to `--image`. If they provide a URL, use `--image-url`. If neither is provided, ask before building the confirmation — most platforms require a logo.
- **Fee-share / bps inputs** — Always collect and confirm shares as percentages with the user; convert to basis points yourself (50% → `5000`). Never ask for a raw bps value.
- **Address validation** — Validate `--from` wallet address format before submitting:
- `sol`: base58, 3244 characters
- `bsc` / `base` / `eth`: `0x` + 40 hex digits
- `bsc` / `base`: `0x` + 40 hex digits
- **Chain-wallet compatibility** — SOL addresses are incompatible with EVM chains and vice versa. Warn the user and abort if the address format does not match the chain.
- **Order polling** — After `cooking create`, if `status` is `pending`, poll `order get` every 2 seconds up to 30 seconds. The token address is in `output_token`. Do not report success until `status` is `confirmed`.
- **Order polling** — After `cooking create`, if `status` is `pending`, poll `order get` every 2 seconds up to 30 seconds. The token address is in `report.output_token`. Do not report success until `status` is `confirmed`.
- **Credential sensitivity** — `GMGN_API_KEY` and `GMGN_PRIVATE_KEY` can execute real transactions. Never log, display, or expose these values.
## Notes
- `cooking create` uses **critical auth** (API Key + signature) — CLI handles signing automatically.
- `cooking stats` uses normal auth (API Key only — no private key needed).
- The new token's mint address is in `output_token` from `gmgn-cli order get`, not in the initial `cooking create` response.
- `cooking create` uses **signed auth** (API Key + signature) — CLI handles signing automatically.
- `cooking stats` uses exist auth (API Key only — no private key needed).
- The new token's mint address is in `report.output_token` from `gmgn-cli order get`, not in the initial `cooking create` response.
- Use `--raw` on any command to get single-line JSON for further processing.
## References
+154 -28
View File
@@ -1,7 +1,7 @@
---
name: gmgn-market
description: Get crypto and meme token price charts (K-line, candlestick, OHLCV), trending meme coin rankings by volume, and newly launched tokens on launchpads (pump.fun, fourmeme, letsbonk, Raydium, etc.) via GMGN API on Solana, BSC, or Base. Use when user asks for price chart, trending tokens, what's pumping, hot coins, new launches, token signals, or wants to discover early-stage opportunities.
argument-hint: "kline --chain <sol|bsc|base> --address <token_address> --resolution <1m|5m|15m|1h|4h|1d> [--from <unix_ts>] [--to <unix_ts>] | trending --chain <sol|bsc|base> --interval <1m|5m|1h|6h|24h> | trenches --chain <sol|bsc|base> | signal --chain <sol|bsc>""
description: Get crypto and meme token price charts (K-line, candlestick, OHLCV), trending meme coin rankings by volume, and newly launched tokens on launchpads (pump.fun, fourmeme, letsbonk, Raydium, etc.) via GMGN API on Solana, BSC, Base, or Ethereum. Use when user asks for price chart, trending tokens, what's pumping, hot coins, new launches, token signals, or wants to discover early-stage opportunities.
argument-hint: "kline --chain <sol|bsc|base|eth> --address <token_address> --resolution <30s|1m|5m|15m|1h|4h|1d> [--from <unix_ts>] [--to <unix_ts>] | trending --chain <sol|bsc|base|eth> --interval <1m|5m|1h|6h|24h> | trenches --chain <sol|bsc|base|eth> | signal --chain <sol|bsc>"
metadata:
cliHelp: "gmgn-cli market --help"
---
@@ -18,7 +18,7 @@ Use the `gmgn-cli` tool to query K-line data for a token, browse trending tokens
- **`--filter` chain defaults** — SOL and EVM chains have different default safety filters that are applied automatically when `--filter` is omitted. Do not assume the same defaults apply across chains:
- **SOL**: defaults to `renounced frozen` (mint and freeze authority renounced)
- **BSC / Base (EVM)**: defaults to `not_honeypot verified renounced`
- **BSC / Base / ETH (EVM)**: defaults to `not_honeypot verified renounced`
- Omitting `--filter` is NOT the same as "no filter" — the chain defaults are always applied. To use a custom filter set, explicitly specify all desired filter tags.
- **`volume` vs `amount` (kline)** — Naming is counterintuitive. `volume` = USD dollar value of trades; `amount` = token units traded. For a token priced at $0.0002, these differ by 5,000×. Always use `volume` for "how much USD was traded" and `amount` for "how many tokens changed hands."
@@ -52,7 +52,7 @@ Use the `gmgn-cli` tool to query K-line data for a token, browse trending tokens
## Supported Chains
`sol` / `bsc` / `base` (signal: `sol` / `bsc` only)
`sol` / `bsc` / `base` / `eth` (kline / trending / trenches; signal: `sol` / `bsc` only)
## Prerequisites
@@ -61,7 +61,7 @@ Use the `gmgn-cli` tool to query K-line data for a token, browse trending tokens
## Rate Limit Handling
All market routes used by this skill go through GMGN's leaky-bucket limiter with `rate=10` and `capacity=10`. Sustained throughput is roughly `10 ÷ weight` requests/second, and the max burst is roughly `floor(10 ÷ weight)` when the bucket is full.
All market routes used by this skill go through GMGN's leaky-bucket limiter with `rate=20` and `capacity=20`. Sustained throughput is roughly `20 ÷ weight` requests/second, and the max burst is roughly `floor(20 ÷ weight)` when the bucket is full.
| Command | Route | Weight |
|---------|-------|--------|
@@ -86,20 +86,18 @@ When a request returns `429`:
```
Tell the user: *"This is your Ed25519 public key. Go to **https://gmgn.ai/ai**, paste it into the API key creation form, then send me the API Key value shown on the page."*
2. Wait for the user's API key, then configure:
2. Wait for the user's API key, then save it with `gmgn-cli config` (creates `~/.config/gmgn/.env` and sets `chmod 600` automatically — do not hand-edit the file):
```bash
mkdir -p ~/.config/gmgn
echo 'GMGN_API_KEY=<key_from_user>' > ~/.config/gmgn/.env
chmod 600 ~/.config/gmgn/.env
gmgn-cli config set-key <key_from_user>
```
## `market kline` Parameters
| Parameter | Required | Description |
|-----------|----------|-------------|
| `--chain` | Yes | `sol` / `bsc` / `base` |
| `--chain` | Yes | `sol` / `bsc` / `base` / `eth` |
| `--address` | Yes | Token contract address |
| `--resolution` | Yes | Candlestick resolution: `1m` / `5m` / `15m` / `1h` / `4h` / `1d` |
| `--resolution` | Yes | Candlestick resolution: `30s` / `1m` / `5m` / `15m` / `1h` / `4h` / `1d` |
| `--from` | No | Start time (Unix seconds) |
| `--to` | No | End time (Unix seconds) |
@@ -140,13 +138,39 @@ The response is an object with a `list` array. Each element in `list` is one can
| Option | Description |
|--------|-------------|
| `--chain` | Required. `sol` / `bsc` / `base` |
| `--chain` | Required. `sol` / `bsc` / `base` / `eth` |
| `--interval` | Required. `1m` / `5m` / `1h` / `6h` / `24h` (default `1h`) |
| `--limit <n>` | Number of results (default 100, max 100) |
| `--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 (chain-specific). **⚠️ SOL defaults: `renounced frozen`; BSC/Base defaults: `not_honeypot verified renounced`.** Omitting `--filter` is NOT "no filter" — chain defaults always apply. **sol** tags: `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** tags: `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` |
| `--filter <tag...>` | Repeatable filter tags (chain-specific). **⚠️ SOL defaults: `renounced frozen`; BSC/Base/ETH defaults: `not_honeypot verified renounced`.** Omitting `--filter` is NOT "no filter" — chain defaults always apply. **sol** tags: `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** tags: `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` / `four_xmode_agent` / `cubepeg` / `likwid` / `goplus_creator` / `goplus_skills` / `openfour` / `flap` / `flap_stocks` / `flap_aioracle` / `clanker` / `lunafun` / `pool_uniswap` / `pool_pancake`. **base**: `clanker` / `bankr` / `flaunch` / `zora` / `zora_creator` / `baseapp` / `basememe` / `virtuals_v2` / `klik`. **eth**: `trench` / `clanker` / `klik` / `livo` / `stroid` / `pool_uniswap_v2` / `pool_uniswap_v3` / `printr` |
### `market trending` Range Filters
Optional `--min-*` / `--max-*` flags apply server-side numeric range filtering (inclusive). Unknown metrics are ignored by the service.
| Option | Description |
|--------|-------------|
| `--min-volume` / `--max-volume` | Trading volume (USD) |
| `--min-liquidity` / `--max-liquidity` | Liquidity (USD) |
| `--min-marketcap` / `--max-marketcap` | Market cap (USD) |
| `--min-history-highest-marketcap` / `--max-history-highest-marketcap` | Historical highest market cap (USD) |
| `--min-swaps` / `--max-swaps` | Swap count |
| `--min-holder-count` / `--max-holder-count` | Holder count |
| `--min-gas-fee` / `--max-gas-fee` | Gas fee |
| `--min-renowned-count` / `--max-renowned-count` | KOL / renowned wallet count |
| `--min-smart-degen-count` / `--max-smart-degen-count` | Smart-money holder count |
| `--min-bot-degen-count` / `--max-bot-degen-count` | Bot-degen wallet count |
| `--min-visiting-count` / `--max-visiting-count` | Visitor count |
| `--min-price-change-percent` / `--max-price-change-percent` | Price change ratio over the interval |
| `--min-insider-rate` / `--max-insider-rate` | Insider trading ratio (01); tokens lacking this field are excluded |
| `--min-bundler-rate` / `--max-bundler-rate` | Bundle-bot trading ratio (01); tokens lacking this field are excluded |
| `--min-entrapment-ratio` / `--max-entrapment-ratio` | Entrapment trading ratio (01); tokens lacking this field are excluded |
| `--min-top10-holder-rate` / `--max-top10-holder-rate` | Top-10 holder concentration (01) |
| `--min-top70-sniper-hold-rate` / `--max-top70-sniper-hold-rate` | Top-70 sniper holding ratio (01) |
| `--min-dev-team-hold-rate` / `--max-dev-team-hold-rate` | Dev-team holding ratio (01); `--min-dev-team-hold-rate` also excludes creator-close tokens |
| `--min-created` / `--max-created` | Token age window, duration string with a `m` (minutes) / `h` (hours) / `d` (days) suffix, e.g. `30m` / `6h` / `7d`. `--min-created` is a minimum age (excludes younger tokens); `--max-created` a maximum age (excludes older tokens). **Note:** the raw upstream rank interface accepts minutes only; the openapi-service does not forward this field — it evaluates the age window itself (cutoff = now duration, computed natively for `m`/`h`/`d`), so `6h` / `7d` work here. Always include a unit suffix — a bare number is **not** accepted. |
## Usage Examples
@@ -176,6 +200,14 @@ gmgn-cli market kline \
# Raw output for further processing
gmgn-cli market kline --chain sol --address <addr> \
--resolution 5m --from <ts> --to <ts> --raw | jq '.[]'
# ETH token kline — last 24h, 1h candles (macOS)
gmgn-cli market kline \
--chain eth \
--address 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 \
--resolution 1h \
--from $(date -v-24H +%s) \
--to $(date +%s)
```
### Trending — General
@@ -234,20 +266,73 @@ gmgn-cli market trending \
--platform fourmeme --platform four_xmode_agent \
--order-by volume --limit 50 --raw
# BSC 5m hottest — fourmeme family, sorted by volume
# BSC 5m hottest — all BSC launchpads, sorted by volume
gmgn-cli market trending \
--chain bsc --interval 5m \
--platform fourmeme --platform fourmeme_agent --platform bn_fourmeme --platform four_xmode_agent \
--platform cubepeg --platform likwid --platform goplus_creator --platform goplus_skills --platform openfour \
--platform flap --platform flap_stocks --platform flap_aioracle --platform clanker --platform lunafun \
--order-by volume --limit 50 --raw
# BSC 1h trending — fourmeme with safety filters
# BSC 1h trending — all BSC launchpads with safety filters
gmgn-cli market trending \
--chain bsc --interval 1h \
--platform fourmeme --platform fourmeme_agent --platform bn_fourmeme --platform four_xmode_agent \
--platform cubepeg --platform likwid --platform goplus_creator --platform goplus_skills --platform openfour \
--platform flap --platform flap_stocks --platform flap_aioracle --platform clanker --platform lunafun \
--filter not_honeypot --filter verified \
--order-by volume --limit 20 --raw
```
### Trending — ETH by Launchpad Platform
```bash
# ETH 1h trending — all platforms, sorted by volume
gmgn-cli market trending --chain eth --interval 1h --order-by volume --limit 20
# ETH 1h trending — specific platforms only
gmgn-cli market trending \
--chain eth --interval 1h \
--platform trench --platform clanker --platform klik \
--order-by volume --limit 50 --raw
# ETH 1h trending — all ETH platforms with safety filters
gmgn-cli market trending \
--chain eth --interval 1h \
--platform trench --platform clanker --platform klik --platform livo --platform stroid \
--platform pool_uniswap_v2 --platform pool_uniswap_v3 --platform printr \
--filter not_honeypot --filter verified \
--order-by volume --limit 20 --raw
# ETH 24h trending — sorted by smart money count
gmgn-cli market trending \
--chain eth --interval 24h \
--filter not_honeypot --filter verified \
--order-by smart_degen_count --limit 20 --raw
```
### Trending — Numeric Range Filters
```bash
# SOL 1h trending — liquidity 10k1M, market cap above 50k, sorted by volume
gmgn-cli market trending \
--chain sol --interval 1h \
--min-liquidity 10000 --max-liquidity 1000000 --min-marketcap 50000 \
--order-by volume --limit 30 --raw
# SOL 5m hottest — fresh tokens (under 30 min old) with smart money interest
gmgn-cli market trending \
--chain sol --interval 5m \
--max-created 30m --min-smart-degen-count 1 \
--order-by volume --limit 50 --raw
# SOL 1h trending — exclude high-insider / high-bundler tokens
gmgn-cli market trending \
--chain sol --interval 1h \
--max-insider-rate 0.3 --max-bundler-rate 0.3 \
--order-by volume --limit 20 --raw
```
### Trending — Base by Launchpad Platform
```bash
@@ -467,7 +552,7 @@ Use field combinations to determine what stage a token is in. This affects how s
| Parameter | Required | Description |
|-----------|----------|-------------|
| `--chain` | Yes | `sol` / `bsc` / `base` |
| `--chain` | Yes | `sol` / `bsc` / `base` / `eth` |
| `--type` | No | Categories to query, repeatable: `new_creation` / `near_completion` / `completed` (default: all three) |
| `--launchpad-platform` | No | Launchpad platform filter, repeatable (default: all platforms for the chain) |
| `--limit` | No | Max results per category, max 80 (default: 80) |
@@ -476,6 +561,15 @@ Use field combinations to determine what stage a token is in. This affects how s
| `--direction` | No | Sort direction: `asc` / `desc` (default: `desc`; `asc` for `rug_ratio`) |
| `--min-*` / `--max-*` | No | Server-side filter range flags — see Filter Fields Reference below |
**`--launchpad-platform` values by chain** (omit `--launchpad-platform` to use all of the chain's platforms):
| Chain | Platforms |
|-------|-----------|
| `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` / `ray_launchpad` / `meteora_virtual_curve` / `xstocks` |
| `bsc` | `fourmeme` / `fourmeme_agent` / `bn_fourmeme` / `four_xmode_agent` / `cubepeg` / `likwid` / `goplus_creator` / `goplus_skills` / `openfour` / `flap` / `flap_stocks` / `flap_aioracle` / `clanker` / `lunafun` |
| `base` | `clanker` / `bankr` / `flaunch` / `zora` / `zora_creator` / `baseapp` / `basememe` / `virtuals_v2` / `klik` |
| `eth` | `trench` / `clanker` / `klik` / `livo` / `stroid` / `pool_uniswap_v2` / `pool_uniswap_v3` / `printr` |
### Filter Presets
Presets are applied server-side: the API filters tokens before returning results.
@@ -507,7 +601,7 @@ All filter flags are sent as part of the API request body — the server filters
| `--min-progress` / `--max-progress` | float | Bonding curve progress (01) |
| `--min-marketcap` / `--max-marketcap` | float | Market cap (USD) |
| `--min-liquidity` / `--max-liquidity` | float | Liquidity (USD) |
| `--min-created` / `--max-created` | string | Token age (e.g. `1m` / `5m` / `1h` / `24h`) |
| `--min-created` / `--max-created` | duration | Token age — unit suffix recommended: seconds (`30s`, `10s`) or minutes (`0.5m`, `1m`, `5m`, `30m`). Bare numbers (e.g. `5`) are treated as minutes with a warning. |
| `--min-holder-count` / `--max-holder-count` | int | Holder count |
| `--min-top-holder-rate` / `--max-top-holder-rate` | float | Top-10 holder concentration (01) |
| `--min-rug-ratio` / `--max-rug-ratio` | float | Rug pull risk score (01) |
@@ -718,25 +812,33 @@ gmgn-cli market trenches --chain sol --raw \
# All three categories at once
gmgn-cli market trenches --chain bsc --raw \
--type new_creation --type near_completion --type completed \
--launchpad-platform fourmeme --launchpad-platform fourmeme_agent --launchpad-platform bn_fourmeme --launchpad-platform four_xmode_agent --launchpad-platform flap --launchpad-platform clanker --launchpad-platform lunafun \
--launchpad-platform fourmeme --launchpad-platform fourmeme_agent --launchpad-platform bn_fourmeme --launchpad-platform four_xmode_agent \
--launchpad-platform cubepeg --launchpad-platform likwid --launchpad-platform goplus_creator --launchpad-platform goplus_skills --launchpad-platform openfour \
--launchpad-platform flap --launchpad-platform flap_stocks --launchpad-platform flap_aioracle --launchpad-platform clanker --launchpad-platform lunafun \
--limit 80
# New creation only
gmgn-cli market trenches --chain bsc --raw \
--type new_creation \
--launchpad-platform fourmeme --launchpad-platform fourmeme_agent --launchpad-platform bn_fourmeme --launchpad-platform four_xmode_agent --launchpad-platform flap --launchpad-platform clanker --launchpad-platform lunafun \
--launchpad-platform fourmeme --launchpad-platform fourmeme_agent --launchpad-platform bn_fourmeme --launchpad-platform four_xmode_agent \
--launchpad-platform cubepeg --launchpad-platform likwid --launchpad-platform goplus_creator --launchpad-platform goplus_skills --launchpad-platform openfour \
--launchpad-platform flap --launchpad-platform flap_stocks --launchpad-platform flap_aioracle --launchpad-platform clanker --launchpad-platform lunafun \
--limit 80
# Near completion only
gmgn-cli market trenches --chain bsc --raw \
--type near_completion \
--launchpad-platform fourmeme --launchpad-platform fourmeme_agent --launchpad-platform bn_fourmeme --launchpad-platform four_xmode_agent --launchpad-platform flap --launchpad-platform clanker --launchpad-platform lunafun \
--launchpad-platform fourmeme --launchpad-platform fourmeme_agent --launchpad-platform bn_fourmeme --launchpad-platform four_xmode_agent \
--launchpad-platform cubepeg --launchpad-platform likwid --launchpad-platform goplus_creator --launchpad-platform goplus_skills --launchpad-platform openfour \
--launchpad-platform flap --launchpad-platform flap_stocks --launchpad-platform flap_aioracle --launchpad-platform clanker --launchpad-platform lunafun \
--limit 80
# Completed (open market) only
gmgn-cli market trenches --chain bsc --raw \
--type completed \
--launchpad-platform fourmeme --launchpad-platform fourmeme_agent --launchpad-platform bn_fourmeme --launchpad-platform four_xmode_agent --launchpad-platform flap --launchpad-platform clanker --launchpad-platform lunafun \
--launchpad-platform fourmeme --launchpad-platform fourmeme_agent --launchpad-platform bn_fourmeme --launchpad-platform four_xmode_agent \
--launchpad-platform cubepeg --launchpad-platform likwid --launchpad-platform goplus_creator --launchpad-platform goplus_skills --launchpad-platform openfour \
--launchpad-platform flap --launchpad-platform flap_stocks --launchpad-platform flap_aioracle --launchpad-platform clanker --launchpad-platform lunafun \
--limit 80
```
@@ -768,6 +870,28 @@ gmgn-cli market trenches --chain base --raw \
--limit 80
```
### ETH Trenches Examples
```bash
# All three categories at once
gmgn-cli market trenches --chain eth --raw \
--type new_creation --type near_completion --type completed \
--launchpad-platform trench --launchpad-platform clanker --launchpad-platform klik --launchpad-platform livo --launchpad-platform stroid --launchpad-platform pool_uniswap_v2 --launchpad-platform pool_uniswap_v3 --launchpad-platform printr \
--limit 80
# New creation only
gmgn-cli market trenches --chain eth --raw \
--type new_creation \
--launchpad-platform trench --launchpad-platform clanker --launchpad-platform klik --launchpad-platform livo --launchpad-platform stroid --launchpad-platform pool_uniswap_v2 --launchpad-platform pool_uniswap_v3 --launchpad-platform printr \
--limit 80
# Completed (open market) only
gmgn-cli market trenches --chain eth --raw \
--type completed \
--launchpad-platform trench --launchpad-platform clanker --launchpad-platform klik --launchpad-platform livo --launchpad-platform stroid --launchpad-platform pool_uniswap_v2 --launchpad-platform pool_uniswap_v3 --launchpad-platform printr \
--limit 80
```
## Output Format
### `market kline` — Price Summary
@@ -817,6 +941,8 @@ Chains: `sol` / `bsc` only. **Maximum 50 results per group** — use multiple gr
**Single-group (individual flags):**
Do **not** pass signal types **14, 15, or 16** in `signal_type` / `--signal-type` / `--groups` JSON — OpenAPI returns **400** if any group includes them. Omitting `--signal-type` (empty filter) still queries all types upstream; responses may still include 1416 in that case.
| Option | Required | Description |
|--------|----------|-------------|
| `--chain` | Yes | `sol` / `bsc` |
@@ -836,7 +962,7 @@ Pass `--groups '<json_array>'` to query multiple filter groups in a single reque
```bash
gmgn-cli market signal --chain sol \
--groups '[{"signal_type":[12,14]},{"signal_type":[6,7],"mc_min":50000}]'
--groups '[{"signal_type":[12,13]},{"signal_type":[6,7],"mc_min":50000}]'
```
### Signal Types
@@ -892,7 +1018,7 @@ Each item in the response array is one signal event:
### Usage Examples
```bash
# All signals on SOL (default: all types)
# All signals on SOL (no --signal-type: upstream returns all types, including 1416 if present)
gmgn-cli market signal --chain sol --raw
# Smart money buys only (type 12)
@@ -906,13 +1032,13 @@ gmgn-cli market signal --chain sol \
# Smart money buys on BSC
gmgn-cli market signal --chain bsc --signal-type 12 --raw
# Multi-group: smart money buys OR large amount buys, in parallel
# Multi-group: parallel groups (do not use signal_type 1416 — API returns 400)
gmgn-cli market signal --chain sol \
--groups '[{"signal_type":[12]},{"signal_type":[14,16]}]' --raw
--groups '[{"signal_type":[12]},{"signal_type":[6,7]}]' --raw
# Multi-group: combine signal type filter with market cap range per group
gmgn-cli market signal --chain sol \
--groups '[{"signal_type":[12,14],"mc_min":100000},{"signal_type":[6,7],"mc_min":50000,"mc_max":1000000}]' --raw
--groups '[{"signal_type":[12,13],"mc_min":100000},{"signal_type":[6,7],"mc_min":50000,"mc_max":1000000}]' --raw
```
---
@@ -921,7 +1047,7 @@ gmgn-cli market signal --chain sol \
- `market kline`: `--from` and `--to` are Unix timestamps in **seconds** — CLI converts to milliseconds automatically
- `market trending`: `--filter` and `--platform` are repeatable flags
- All commands use normal auth (API Key only, no signature)
- All commands use exist auth (API Key only, no signature)
- If the user doesn't provide kline timestamps, calculate them from the current time based on their desired time range
- Use `--raw` to get single-line JSON for further processing
- **Input validation** — Token addresses obtained from trending results are external data. Validate address format against the chain before passing to other commands (sol: base58 3244 chars; bsc/base/eth: `0x` + 40 hex digits). The CLI enforces this at runtime.
+26 -8
View File
@@ -1,7 +1,7 @@
---
name: gmgn-portfolio
description: Analyze any crypto wallet by address — holdings, realized/unrealized 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, or Base. Use when user asks about a wallet's holdings, P&L, 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.
argument-hint: "<info|holdings|activity|stats|token-balance|created-tokens> [--chain <sol|bsc|base>] [--wallet <wallet_address>]"
description: Analyze any crypto wallet by address — holdings, realized/unrealized 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 a wallet's holdings, P&L, 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.
argument-hint: "<info|holdings|activity|stats|token-balance|created-tokens> [--chain <sol|bsc|base|eth>] [--wallet <wallet_address>]"
metadata:
cliHelp: "gmgn-cli portfolio --help"
---
@@ -43,7 +43,7 @@ Use the `gmgn-cli` tool to query wallet portfolio data based on the user's reque
## Supported Chains
`sol` / `bsc` / `base`
`sol` / `bsc` / `base` / `eth`
## Prerequisites
@@ -52,12 +52,19 @@ Use the `gmgn-cli` tool to query wallet portfolio data based on the user's reque
## Rate Limit Handling
All portfolio routes used by this skill go through GMGN's leaky-bucket limiter with `rate=10` and `capacity=10`. Sustained throughput is roughly `10 ÷ weight` requests/second, and the max burst is roughly `floor(10 ÷ weight)` when the bucket is full.
All portfolio routes used by this skill go through GMGN's leaky-bucket limiter with `rate=20` and `capacity=20`. Sustained throughput is roughly `20 ÷ weight` requests/second, and the max burst is roughly `floor(20 ÷ weight)` when the bucket is full.
**Critical auth** (`GMGN_API_KEY` + `GMGN_PRIVATE_KEY` required):
| Command | Route | Weight |
|---------|-------|--------|
| `portfolio holdings` | `GET /v1/user/wallet_holdings` | 5 |
**Exist auth** (`GMGN_API_KEY` only):
| Command | Route | Weight |
|---------|-------|--------|
| `portfolio info` | `GET /v1/user/info` | 1 |
| `portfolio holdings` | `GET /v1/user/wallet_holdings` | 2 |
| `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 |
@@ -139,6 +146,16 @@ gmgn-cli portfolio created-tokens \
# Only migrated tokens
gmgn-cli portfolio created-tokens \
--chain sol --wallet <wallet_address> --migrate-state migrated
# ETH wallet holdings
gmgn-cli portfolio holdings --chain eth --wallet <0x_wallet_address>
# ETH wallet transaction activity
gmgn-cli portfolio activity --chain eth --wallet <0x_wallet_address>
# ETH token balance
gmgn-cli portfolio token-balance \
--chain eth --wallet <0x_wallet_address> --token <0x_token_address>
```
## `portfolio created-tokens` Options
@@ -169,7 +186,7 @@ gmgn-cli portfolio created-tokens \
| `--token <address>` | Filter by token |
| `--limit <n>` | Page size |
| `--cursor <cursor>` | Pagination cursor (pass the `next` value from the previous response) |
| `--type <type>` | Repeatable: `buy` / `sell` / `add` / `remove` / `transfer` |
| `--type <type>` | Repeatable: `buy` / `sell` / `transferIn` / `transferOut` / `add` / `remove` |
The activity response includes a `next` field. Pass it to `--cursor` to fetch the next page.
@@ -216,7 +233,8 @@ The response has a `activities` array and a `next` cursor field for pagination.
| `token.symbol` | Token ticker |
| `token_amount` | Token quantity in this transaction |
| `cost_usd` | USD value of this transaction |
| `price` | Token price in USD at time of transaction |
| `price` | Token price denominated in the quote token of the trading pair at time of transaction |
| `price_usd` | Token price in USD at time of transaction |
| `timestamp` | Unix timestamp of the transaction |
| `next` | Pagination cursor — pass to `--cursor` to fetch the next page |
@@ -350,7 +368,7 @@ Show the `[Identity: ...]` line only if `common` is present in the response. For
## Notes
- All portfolio commands use normal auth (API Key only, no signature required)
- `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).
- `portfolio stats` supports multiple `--wallet` flags for batch queries
- Use `--raw` to get single-line JSON for further processing
- **Input validation** — Wallet and token addresses are validated against the expected chain format at runtime (sol: base58 3244 chars; bsc/base/eth: `0x` + 40 hex digits). The CLI exits with an error on invalid input.
+429 -211
View File
@@ -1,7 +1,7 @@
---
name: gmgn-swap
description: "[FINANCIAL EXECUTION] Buy and sell meme coins and crypto tokens on Solana, BSC, or Base — single swap, multi-wallet batch trading, limit orders, stop loss, take profit, trailing stop loss, trailing take profit via GMGN API. Requires explicit user confirmation. Use when user asks to buy, sell, or swap a token, trade from multiple wallets, set a limit order, stop loss, take profit, or check order status."
argument-hint: "[--chain <chain> --from <wallet> --input-token <addr> --output-token <addr> --amount <n>] | [order get --chain <chain> --order-id <id>] | [order strategy list --chain <chain> --group-tag <LimitOrder|STMix>] | [order strategy create --chain <chain> --order-type limit_order --sub-order-type <buy_low|buy_high|stop_loss|take_profit> ...]"
description: "[FINANCIAL EXECUTION] Buy and sell meme coins and crypto tokens on Solana, BSC, Base, or Ethereum — single swap, multi-wallet batch trading, limit orders, stop loss, take profit, trailing stop loss, trailing take profit via GMGN API. Requires explicit user confirmation. Use when user asks to buy, sell, or swap a token, trade from multiple wallets, set a limit order, stop loss, take profit, or check order status."
argument-hint: "[--chain <chain> --from <wallet> --input-token <addr> --output-token <addr> --amount <n>] | [order get --chain <chain> --order-id <id>] | [gas-price --chain <eth|bsc|base|sol>] | [order strategy list --chain <chain> --group-tag <LimitOrder|STMix>] | [order strategy create --chain <chain> --order-type <limit_order|smart_trade> --sub-order-type <buy_low|buy_high|stop_loss|take_profit|mix_trade> ...]"
metadata:
cliHelp: "gmgn-cli swap --help"
---
@@ -12,21 +12,21 @@ metadata:
**⚠️ 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://ipv6.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."**
Use the `gmgn-cli` tool to submit a token swap or query an existing order. `GMGN_API_KEY` is always required. `GMGN_PRIVATE_KEY` is required for critical-auth commands such as `swap` and all `order` subcommands, including `order quote`.
Use the `gmgn-cli` tool to submit a token swap or query an existing order. `GMGN_API_KEY` is always required. `GMGN_PRIVATE_KEY` is required for critical-auth commands such as `swap` and `order` subcommands — except `order quote`, which only requires `GMGN_API_KEY`.
## Core Concepts
- **Smallest unit**`--amount` is always in the token's smallest indivisible unit, not human-readable amounts. For SOL: 1 SOL = 1,000,000,000 lamports. For EVM tokens: depends on decimals (most ERC-20 tokens use 18 decimals). Always convert before passing to the command — do not pass human amounts directly.
- **`slippage`** — Price tolerance expressed as a decimal, not a percentage. `0.01` = 1% slippage. `0.5` = 50% slippage. If the price moves beyond this threshold before the transaction confirms, the swap is rejected. Use `--auto-slippage` for volatile tokens to let GMGN set an appropriate value automatically.
- **`slippage`** — Price tolerance as an integer 0100, e.g. `30` = 30%. If the price moves beyond this threshold before the transaction confirms, the swap is rejected. Use `--auto-slippage` for volatile tokens to let GMGN set an appropriate value automatically.
- **`--amount` vs `--percent`** — Mutually exclusive. `--amount` specifies an exact input quantity (in smallest unit). `--percent` sells a percentage of the current balance and is only valid when `input_token` is NOT a currency (SOL/BNB/ETH/USDC). Never use `--percent` to spend a fraction of SOL/BNB/ETH.
- **Currency tokens** — Each chain has designated currency tokens (SOL, BNB, ETH, USDC). These are the base assets used to buy other tokens or receive swap proceeds. Their contract addresses are fixed — look them up in the Chain Currencies table, never guess them.
- **Anti-MEV** — MEV (Miner/Maximal Extractable Value) refers to frontrunning and sandwich attacks where bots exploit pending transactions. `--anti-mev` routes the transaction through protected channels to reduce this risk. **Recommended: always enable.** Default: on.
- **Anti-MEV** — MEV (Miner/Maximal Extractable Value) refers to frontrunning and sandwich attacks where bots exploit pending transactions. `--anti-mev` routes the transaction through protected channels to reduce this risk. **Recommended: always enable.** Default: on. **Not supported on `base` chain.**
- **Critical auth**`swap` and all `order` subcommands require both `GMGN_API_KEY` and `GMGN_PRIVATE_KEY`. The private key never leaves the machine — the CLI uses it only for local signing and sends only the resulting signature.
- **Signed auth**`swap` and most `order` subcommands require both `GMGN_API_KEY` and `GMGN_PRIVATE_KEY`. The private key never leaves the machine — the CLI uses it only for local signing and sends only the resulting signature. Exception: `order quote` only requires `GMGN_API_KEY`.
- **`order_id` / `status`** — After submitting a swap, the response includes an `order_id`. Use `order get --order-id` to poll for final status. Possible values: `pending``processed``confirmed` (success) or `failed` / `expired`. Do not report success until status is `confirmed`.
@@ -47,37 +47,40 @@ Use the `gmgn-cli` tool to submit a token swap or query an existing order. `GMGN
|-------------|-------------|
| `swap` | Submit a token swap |
| `multi-swap` | Submit token swaps across multiple wallets concurrently (up to 100) |
| `order quote` | Get a swap quote (no transaction submitted; requires critical auth) |
| `order quote` | Get a swap quote (no transaction submitted; exist auth — API Key only, no private key needed) |
| `order get` | Query order status |
| `gas-price` | Query recommended gas price (low / average / high tiers) for any chain; exist auth (API Key only) |
| `order strategy create` | Create a limit/strategy order (requires private key) |
| `order strategy list` | List strategy orders (requires private key) |
| `order strategy cancel` | Cancel a strategy order (requires private key) |
## Supported Chains
`sol` / `bsc` / `base`
`sol` / `bsc` / `base` / `eth`
## Chain Currencies
Currency tokens are the base/native assets of each chain. They are used to buy other tokens or receive proceeds from selling. Knowing which tokens are currencies is critical for `--percent` usage (see Swap Parameters below).
| Chain | Currency tokens |
|-------|----------------|
| `sol` | SOL (native, So11111111111111111111111111111111111111112), USDC (`EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v`) |
| `bsc` | BNB (native, 0x0000000000000000000000000000000000000000), USDC (`0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d`) |
| `base` | ETH (native, 0x0000000000000000000000000000000000000000), USDC (`0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913`) |
> ⚠️ **CRITICAL: Always copy currency addresses from this table — NEVER rely on memory or training data.** A wrong address (e.g. `So11111111111111111111111111111111111111111` instead of `So11111111111111111111111111111111111111112`) will cause silent failures or `jupiter has no route` errors with no clear indication of what went wrong.
| Chain | Currency tokens |
| ------ | --------------- |
| `sol` | SOL (native, `So11111111111111111111111111111111111111112`), USDC (`EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v`) |
| `bsc` | BNB (native, `0x0000000000000000000000000000000000000000`), USDC (`0x8ac76a51cc950d9822d68b83fe1ad97b32cd580d`) |
| `base` | ETH (native, `0x0000000000000000000000000000000000000000`), USDC (`0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913`) |
| `eth` | ETH (native, `0x0000000000000000000000000000000000000000`) |
## Prerequisites
`GMGN_API_KEY` must be configured in `~/.config/gmgn/.env`. `GMGN_PRIVATE_KEY` is additionally required for `swap` and all `order` subcommands. The private key must correspond to the wallet bound to the API Key.
`GMGN_API_KEY` must be configured in `~/.config/gmgn/.env`. `GMGN_PRIVATE_KEY` is additionally required for `swap` and `order` subcommands other than `order quote`. The private key must correspond to the wallet bound to the API Key.
- `gmgn-cli` installed globally — if missing, run: `npm install -g gmgn-cli`
## Rate Limit Handling
All swap-related routes used by this skill go through GMGN's leaky-bucket limiter with `rate=10` and `capacity=10`. Sustained throughput is roughly `10 ÷ weight` requests/second, and the max burst is roughly `floor(10 ÷ weight)` when the bucket is full.
All swap-related routes used by this skill go through GMGN's leaky-bucket limiter with `rate=20` and `capacity=20`. Sustained throughput is roughly `20 ÷ weight` requests/second, and the max burst is roughly `floor(20 ÷ weight)` when the bucket is full.
| Command | Route | Weight |
|---------|-------|--------|
@@ -85,6 +88,10 @@ All swap-related routes used by this skill go through GMGN's leaky-bucket limite
| `multi-swap` | `POST /v1/trade/multi_swap` | 5 |
| `order quote` | `GET /v1/trade/quote` | 2 |
| `order get` | `GET /v1/trade/query_order` | 1 |
| `order strategy create` | `POST /v1/trade/strategy/create` | 5 |
| `order strategy cancel` | `POST /v1/trade/strategy/cancel` | 2 |
| `order strategy list` | `GET /v1/trade/strategy/orders` | 1 |
| `gas-price` | `GET /v1/trade/gas_price` | 1 |
When a request returns `429`:
@@ -118,6 +125,8 @@ When a request returns `429`:
- `GMGN_PRIVATE_KEY` is used exclusively for **local message signing** — the private key never leaves the machine. The CLI computes an Ed25519 or RSA-SHA256 signature in-process and transmits only the base64-encoded result in the `X-Signature` request header.
- `GMGN_API_KEY` is transmitted in the `X-APIKEY` request header to GMGN's servers over HTTPS.
---
## `swap` Usage
```bash
@@ -136,7 +145,7 @@ gmgn-cli swap \
--input-token <input_token_address> \
--output-token <output_token_address> \
--amount 1000000 \
--slippage 0.01
--slippage 30
# With automatic slippage
gmgn-cli swap \
@@ -165,132 +174,29 @@ gmgn-cli swap \
--percent 50
```
## `multi-swap` Usage
Submit a token swap across multiple wallets concurrently. Each wallet executes independently — one wallet's failure does not affect others. Up to 100 wallets per request. All wallets must be bound to the API Key. Requires `GMGN_PRIVATE_KEY`.
```bash
# Basic multi-wallet swap
gmgn-cli multi-swap \
--chain sol \
--accounts <addr1>,<addr2> \
--input-token <input_token_address> \
--output-token <output_token_address> \
--input-amount '{"<addr1>":"1000000","<addr2>":"2000000"}' \
--slippage 0.01
# Sell a percentage of each wallet's balance (use --input-amount-bps)
gmgn-cli multi-swap \
--chain sol \
--accounts <addr1>,<addr2> \
--input-token <token_address> \
--output-token <sol_address> \
--input-amount-bps '{"<addr1>":"5000","<addr2>":"10000"}' \
--slippage 0.01
# With per-wallet take-profit / stop-loss (condition_orders)
gmgn-cli multi-swap \
--chain sol \
--accounts <addr1>,<addr2> \
--input-token So11111111111111111111111111111111111111112 \
--output-token <token_address> \
--input-amount '{"<addr1>":"1000000","<addr2>":"2000000"}' \
--slippage 0.3 \
--priority-fee 0.00001 \
--tip-fee 0.00001 \
--condition-orders '[{"order_type":"profit_stop","side":"sell","price_scale":"100","sell_ratio":"100"},{"order_type":"loss_stop","side":"sell","price_scale":"50","sell_ratio":"100"}]'
```
## `multi-swap` Parameters
| Parameter | Required | Description |
|-----------|----------|-------------|
| `--chain` | Yes | `sol` / `bsc` / `base` |
| `--accounts` | Yes | Comma-separated wallet addresses (1100, all must be bound to the API Key) |
| `--input-token` | Yes | Input token contract address |
| `--output-token` | Yes | Output token contract address |
| `--input-amount` | No* | JSON map of `wallet_address → input amount` (smallest unit). One of `--input-amount`, `--input-amount-bps`, or `--output-amount` is required. |
| `--input-amount-bps` | No* | JSON map of `wallet_address → percent in bps` (110000; 5000 = 50%). Only valid when `input_token` is NOT a currency. |
| `--output-amount` | No* | JSON map of `wallet_address → target output amount` (smallest unit). |
| `--slippage <n>` | No | Slippage tolerance, e.g. `0.01` = 1%. Mutually exclusive with `--auto-slippage`. |
| `--auto-slippage` | No | Enable automatic slippage. |
| `--anti-mev` | No | Enable anti-MEV protection. |
| `--priority-fee <sol>` | No | Priority fee in SOL (≥ 0.00001, SOL only). Required when using `--condition-orders` on SOL. |
| `--tip-fee <amount>` | No | Tip fee (SOL ≥ 0.00001 / BSC ≥ 0.000001 BNB). Required when using `--condition-orders` on SOL. |
| `--auto-tip-fee` | No | Enable automatic tip fee. |
| `--max-auto-fee <amount>` | No | Max automatic fee cap. |
| `--gas-price <gwei>` | No | Gas price in gwei (BSC ≥ 0.05 / BASE/ETH ≥ 0.01). Required when using `--condition-orders` on BSC. |
| `--max-fee-per-gas <amount>` | No | EIP-1559 max fee per gas (Base only). |
| `--max-priority-fee-per-gas <amount>` | No | EIP-1559 max priority fee per gas (Base only). |
| `--condition-orders <json>` | No | JSON array of condition sub-orders (take-profit / stop-loss) attached to each successful wallet's swap. Same structure as `swap --condition-orders`. Strategy creation is best-effort per wallet. |
| `--sell-ratio-type <type>` | No | Sell ratio base for `--condition-orders`: `buy_amount` (default) / `hold_amount`. |
## `multi-swap` Response Fields
The response `data` is an array — one element per wallet:
| Field | Type | Description |
|-------|------|-------------|
| `account` | string | Wallet address |
| `success` | bool | Whether this wallet's swap succeeded |
| `error` | string | Error message on failure; absent on success |
| `error_code` | string | Error code on failure; absent on success |
| `result` | object | On success: OrderResponse (same fields as `swap` response). On failure: absent. |
| `result.strategy_order_id` | string | Strategy order ID; only present when `--condition-orders` was passed and strategy creation succeeded (best-effort) |
## `order quote` Usage
Get an estimated output amount before submitting a swap. All supported quote chains use critical auth and require `GMGN_PRIVATE_KEY`.
```bash
gmgn-cli order quote \
--chain sol \
--from <wallet_address> \
--input-token <input_token_address> \
--output-token <output_token_address> \
--amount <input_amount_smallest_unit> \
--slippage 0.01
```
### `order quote` Response Fields
| Field | Type | Description |
|-------|------|-------------|
| `input_token` | string | Input token contract address |
| `output_token` | string | Output token contract address |
| `input_amount` | string | Input amount (smallest unit) |
| `output_amount` | string | Expected output amount (smallest unit) |
| `min_output_amount` | string | Minimum output after slippage |
| `slippage` | number | Actual slippage percentage |
## `order get` Usage
```bash
gmgn-cli order get --chain sol --order-id <order_id>
```
## `swap` Parameters
| Parameter | Required | Description |
|-----------|----------|-------------|
| `--chain` | Yes | `sol` / `bsc` / `base` |
| `--from` | Yes | Wallet address (must match API Key binding) |
| `--input-token` | Yes | Input token contract address |
| `--output-token` | Yes | Output token contract address |
| `--amount` | No* | Input amount in smallest unit. **Mutually exclusive with `--percent`** — provide one or the other, never both. Required unless `--percent` is used. |
| `--percent <pct>` | No* | Sell percentage of `input_token`, e.g. `50` = 50%, `1` = 1%. Sets `input_amount` to `0` automatically. **Mutually exclusive with `--amount`. Only valid when `input_token` is NOT a currency (SOL/BNB/ETH/USDC).** |
| `--slippage <n>` | No | Slippage tolerance, e.g. `0.01` = 1%. **Mutually exclusive with `--auto-slippage`** — use one or the other. |
| `--auto-slippage` | No | Enable automatic slippage. **Mutually exclusive with `--slippage`.** |
| `--min-output <n>` | No | Minimum output amount |
| `--anti-mev` | No | Enable anti-MEV protection — **recommended**; protects against frontrunning and sandwich attacks. Default: on |
| `--priority-fee <sol>` | No | Priority fee in SOL (≥ 0.00001, SOL only) |
| `--tip-fee <n>` | No | Tip fee (SOL ≥ 0.00001 / BSC ≥ 0.000001 BNB) |
| `--max-auto-fee <n>` | No | Max automatic fee cap |
| `--gas-price <gwei>` | No | Gas price in gwei (BSC ≥ 0.05 / BASE/ETH ≥ 0.01) |
| `--max-fee-per-gas <n>` | No | EIP-1559 max fee per gas (Base only) |
| `--max-priority-fee-per-gas <n>` | No | EIP-1559 max priority fee per gas (Base only) |
| `--condition-orders <json>` | No | JSON array of condition sub-orders (take-profit / stop-loss) to attach after a successful swap. **Max 10 sub-orders.** Strategy creation is best-effort: if the swap succeeds but strategy creation fails, the swap result is still returned. See ConditionOrder fields below. |
| `--sell-ratio-type <type>` | No | Sell ratio basis for `--condition-orders`: `buy_amount` (default) — when triggered, sells a fixed token amount stored at strategy creation time; `hold_amount` — when triggered, sells a fixed percentage of the position held at trigger time |
| Parameter | Required | Chain | Description |
|-----------|----------|-------|-------------|
| `--chain` | Yes | all | `sol` / `bsc` / `base` / `eth` |
| `--from` | Yes | all | Wallet address (must match API Key binding) |
| `--input-token` | Yes | all | Input token contract address |
| `--output-token` | Yes | all | Output token contract address |
| `--amount` | No* | all | Input amount in smallest unit. **Mutually exclusive with `--percent`** — provide one or the other, never both. Required unless `--percent` is used. |
| `--percent <pct>` | No* | all | Sell percentage of `input_token`, e.g. `50` = 50%, `1` = 1%. Sets `input_amount` to `0` automatically. **Mutually exclusive with `--amount`. Only valid when `input_token` is NOT a currency (SOL/BNB/ETH/USDC).** |
| `--slippage <n>` | No | all | Slippage tolerance as an integer 0100, e.g. `30` = 30%. **Mutually exclusive with `--auto-slippage`** — use one or the other. |
| `--auto-slippage` | No | all | Enable automatic slippage. **Mutually exclusive with `--slippage`.** |
| `--min-output <n>` | No | all | Minimum output amount |
| `--anti-mev` | No | sol / bsc / eth | Enable anti-MEV protection — **recommended**; protects against frontrunning and sandwich attacks. Default: on. **Not supported on `base`.** |
| `--priority-fee <sol>` | No | `sol` | Priority fee in SOL (≥ 0.00001). Required when using `--condition-orders` on SOL. |
| `--tip-fee <n>` | No | `sol` / `bsc` | Tip fee (SOL ≥ 0.00001 / BSC ≥ 0.000001 BNB). Required when using `--condition-orders` on SOL. |
| `--gas-price <gwei>` | No | `bsc` / `base` / `eth` | Gas price in gwei (BSC ≥ 0.05 / BASE/ETH ≥ 0.01). Required when using `--condition-orders` on BSC. Mutually exclusive with `--gas-level`. |
| `--gas-level <level>` | No | `eth` | Gas price tier: `low` / `average` / `high`. Mutually exclusive with `--gas-price`. |
| `--auto-fee` | No | `eth` | **Only with `--condition-orders`.** GMGN automatically selects the optimal fee. |
| `--max-fee-per-gas <n>` | No | `bsc` / `base` / `eth` | EIP-1559 max fee per gas. Clamped per chain minimums. Defaults to `--gas-price` if omitted (BASE/ETH). |
| `--max-priority-fee-per-gas <n>` | No | `bsc` / `base` / `eth` | EIP-1559 max priority fee per gas. Clamped per chain minimums; capped to `--max-fee-per-gas`. |
| `--condition-orders <json>` | No | all | JSON array of condition sub-orders (take-profit / stop-loss) to attach after a successful swap. **Max 10 sub-orders.** Strategy creation is best-effort: if the swap succeeds but strategy creation fails, the swap result is still returned. See ConditionOrder fields below. |
| `--sell-ratio-type <type>` | No | all | **Only with `--condition-orders`.** Sell ratio basis: `buy_amount` (default) — sells a fixed token amount stored at strategy creation time; `hold_amount` — sells a fixed percentage of the position held at trigger time |
### ConditionOrder Fields (for `--condition-orders`)
@@ -322,7 +228,7 @@ gmgn-cli swap \
--input-token So11111111111111111111111111111111111111112 \
--output-token <token_A_address> \
--amount 10000000 \
--slippage 0.3 \
--slippage 30 \
--anti-mev \
--condition-orders '[{"order_type":"profit_stop","side":"sell","price_scale":"100","sell_ratio":"50"},{"order_type":"profit_stop","side":"sell","price_scale":"300","sell_ratio":"100"},{"order_type":"loss_stop","side":"sell","price_scale":"65","sell_ratio":"100"}]' \
--sell-ratio-type hold_amount
@@ -340,7 +246,7 @@ gmgn-cli swap \
--input-token So11111111111111111111111111111111111111112 \
--output-token <token_A_address> \
--amount 10000000 \
--slippage 0.3 \
--slippage 30 \
--anti-mev \
--condition-orders '[{"order_type":"profit_stop","side":"sell","price_scale":"100","sell_ratio":"50"},{"order_type":"profit_stop","side":"sell","price_scale":"300","sell_ratio":"50"},{"order_type":"loss_stop","side":"sell","price_scale":"65","sell_ratio":"100"}]' \
--sell-ratio-type buy_amount
@@ -388,7 +294,7 @@ gmgn-cli swap \
### Pre-swap Confirmation
Before displaying the confirmation, run `order quote` to get the estimated output (requires critical auth and `GMGN_PRIVATE_KEY` on every supported quote chain):
Before displaying the confirmation, run `order quote` to get the estimated output (requires signed auth and `GMGN_PRIVATE_KEY` on every supported quote chain):
```bash
gmgn-cli order quote \
@@ -438,71 +344,175 @@ Order ID: {order_id}
Convert `report.input_amount` and `report.output_amount` from smallest unit using `report.input_token_decimals` and `report.output_token_decimals` before displaying.
## `order strategy create` Parameters
---
| Parameter | Required | Description |
|-----------|----------|-------------|
| `--chain` | Yes | `sol` / `bsc` / `base` |
| `--from` | Yes | Wallet address (must match API Key binding) |
| `--base-token` | Yes | Base token contract address |
| `--quote-token` | Yes | Quote token contract address |
| `--order-type` | Yes | Order type: `limit_order` |
| `--sub-order-type` | Yes | Sub-order type: `buy_low` / `buy_high` / `stop_loss` / `take_profit` |
| `--check-price` | Yes | Trigger check price |
| `--amount-in` | No* | Input amount (smallest unit). Mutually exclusive with `--amount-in-percent` |
| `--amount-in-percent` | No* | Input as percentage (e.g. `50` = 50%). Mutually exclusive with `--amount-in` |
| `--limit-price-mode` | No | `exact` / `slippage` (default: `slippage`) |
| `--expire-in` | No | Order expiry in seconds |
| `--sell-ratio-type` | No | `buy_amount` (default) — when triggered, sells a fixed token amount stored at strategy creation time; `hold_amount` — when triggered, sells a fixed percentage of the position held at trigger time |
| `--slippage` | No | Slippage tolerance, e.g. `0.01` = 1%. Mutually exclusive with `--auto-slippage` |
| `--auto-slippage` | No | Enable automatic slippage |
| `--priority-fee` | No | Priority fee in SOL (SOL only) |
| `--tip-fee` | No | Tip fee |
| `--gas-price` | No | Gas price in gwei (BSC ≥ 0.05 gwei / BASE/ETH ≥ 0.01 gwei) |
| `--anti-mev` | No | Enable anti-MEV protection |
## `multi-swap` Usage
### `order strategy create` Response Fields
| Field | Type | Description |
|-------|------|-------------|
| `order_id` | string | Created strategy order ID |
| `is_update` | bool | `true` if an existing order was updated, `false` if newly created |
## `order strategy list` Parameters
| Parameter | Required | Description |
|-----------|----------|-------------|
| `--chain` | Yes | `sol` / `bsc` / `base` |
| `--type` | No | `open` (default) / `history` |
| `--from` | No | Filter by wallet address |
| `--group-tag` | Yes | Filter by order group: `LimitOrder` (limit orders only) / `STMix` (mixed strategy orders: take-profit, stop-loss, trailing take-profit, trailing stop-loss) |
| `--base-token` | No | Filter by token address |
| `--page-token` | No | Pagination cursor from previous response |
| `--limit` | No | Results per page (default 10 for history) |
### `order strategy list` Response Fields
| Field | Type | Description |
|-------|------|-------------|
| `next_page_token` | string | Cursor for next page; empty when no more data |
| `total` | int | Total count (only returned when `--type open`) |
| `list` | array | Strategy order list |
## `order strategy cancel` Parameters
| Parameter | Required | Description |
|-----------|----------|-------------|
| `--chain` | Yes | `sol` / `bsc` / `base` |
| `--from` | Yes | Wallet address (must match API Key binding) |
| `--order-id` | Yes | Order ID to cancel |
| `--order-type` | No | Order type: `limit_order` (limit order) / `smart_trade` (mixed strategy order: take-profit, stop-loss, trailing take-profit, trailing stop-loss) |
| `--close-sell-model` | No | Sell model when closing the order |
## `order strategy` Usage Examples
Submit a token swap across multiple wallets concurrently. Each wallet executes independently — one wallet's failure does not affect others. Up to 100 wallets per request. All wallets must be bound to the API Key. Requires `GMGN_PRIVATE_KEY`.
```bash
# Create a take-profit order: sell when price rises to target
# Basic multi-wallet swap
gmgn-cli multi-swap \
--chain sol \
--accounts <addr1>,<addr2> \
--input-token <input_token_address> \
--output-token <output_token_address> \
--input-amount '{"<addr1>":"1000000","<addr2>":"2000000"}' \
--slippage 30
# Sell a percentage of each wallet's balance (use --input-amount-bps)
gmgn-cli multi-swap \
--chain sol \
--accounts <addr1>,<addr2> \
--input-token <token_address> \
--output-token <sol_address> \
--input-amount-bps '{"<addr1>":"5000","<addr2>":"10000"}' \
--slippage 30
# With per-wallet take-profit / stop-loss (condition_orders)
gmgn-cli multi-swap \
--chain sol \
--accounts <addr1>,<addr2> \
--input-token So11111111111111111111111111111111111111112 \
--output-token <token_address> \
--input-amount '{"<addr1>":"1000000","<addr2>":"2000000"}' \
--slippage 30 \
--priority-fee 0.00001 \
--tip-fee 0.00001 \
--condition-orders '[{"order_type":"profit_stop","side":"sell","price_scale":"100","sell_ratio":"100"},{"order_type":"loss_stop","side":"sell","price_scale":"50","sell_ratio":"100"}]'
# ETH multi-wallet swap (EIP-1559 gas)
gmgn-cli multi-swap \
--chain eth \
--accounts <0xaddr1>,<0xaddr2> \
--input-token 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48 \
--output-token <token_address> \
--input-amount '{"<0xaddr1>":"1000000","<0xaddr2>":"2000000"}' \
--slippage 30 \
--gas-price 5
```
## `multi-swap` Parameters
| Parameter | Required | Chain | Description |
|-----------|----------|-------|-------------|
| `--chain` | Yes | all | `sol` / `bsc` / `base` / `eth` |
| `--accounts` | Yes | all | Comma-separated wallet addresses (1100, all must be bound to the API Key) |
| `--input-token` | Yes | all | Input token contract address |
| `--output-token` | Yes | all | Output token contract address |
| `--input-amount` | No* | all | JSON map of `wallet_address → input amount` (smallest unit). One of `--input-amount`, `--input-amount-bps`, or `--output-amount` is required. |
| `--input-amount-bps` | No* | all | JSON map of `wallet_address → percent in bps` (110000; 5000 = 50%). Only valid when `input_token` is NOT a currency. |
| `--output-amount` | No* | all | JSON map of `wallet_address → target output amount` (smallest unit). |
| `--slippage <n>` | No | all | Slippage tolerance as an integer 0100, e.g. `30` = 30%. Mutually exclusive with `--auto-slippage`. |
| `--auto-slippage` | No | all | Enable automatic slippage. |
| `--anti-mev` | No | sol / bsc / eth | Enable anti-MEV protection. Not supported on `base`. |
| `--priority-fee <sol>` | No | `sol` | Priority fee in SOL (≥ 0.00001). Required when using `--condition-orders` on SOL. |
| `--tip-fee <amount>` | No | `sol` / `bsc` | Tip fee (SOL ≥ 0.00001 / BSC ≥ 0.000001 BNB). Required when using `--condition-orders` on SOL. |
| `--gas-price <gwei>` | No | `bsc` / `base` / `eth` | Gas price in gwei (BSC ≥ 0.05 / BASE/ETH ≥ 0.01). Required when using `--condition-orders` on BSC. Mutually exclusive with `--gas-level`. |
| `--gas-level <level>` | No | `eth` | Gas price tier: `low` / `average` / `high`. Mutually exclusive with `--gas-price`. |
| `--auto-fee` | No | `eth` | **Only with `--condition-orders`.** GMGN automatically selects the optimal fee. |
| `--max-fee-per-gas <amount>` | No | `bsc` / `base` / `eth` | EIP-1559 max fee per gas. Clamped per chain minimums. Defaults to `--gas-price` if omitted (BASE/ETH). |
| `--max-priority-fee-per-gas <amount>` | No | `bsc` / `base` / `eth` | EIP-1559 max priority fee per gas. Clamped per chain minimums; capped to `--max-fee-per-gas`. |
| `--condition-orders <json>` | No | all | JSON array of condition sub-orders (take-profit / stop-loss) attached to each successful wallet's swap. Same structure as `swap --condition-orders`. Strategy creation is best-effort per wallet. |
| `--sell-ratio-type <type>` | No | all | **Only with `--condition-orders`.** Sell ratio base: `buy_amount` (default) / `hold_amount`. |
## `multi-swap` Response Fields
The response `data` is an array — one element per wallet:
| Field | Type | Description |
|-------|------|-------------|
| `account` | string | Wallet address |
| `success` | bool | Whether this wallet's swap succeeded |
| `error` | string | Error message on failure; absent on success |
| `error_code` | string | Error code on failure; absent on success |
| `result` | object | On success: OrderResponse (same fields as `swap` response). On failure: absent. |
| `result.strategy_order_id` | string | Strategy order ID; only present when `--condition-orders` was passed and strategy creation succeeded (best-effort) |
---
## `order quote` Usage
Get an estimated output amount before submitting a swap. Uses normal auth — only `GMGN_API_KEY` required, no `GMGN_PRIVATE_KEY` needed.
```bash
gmgn-cli order quote \
--chain sol \
--from <wallet_address> \
--input-token <input_token_address> \
--output-token <output_token_address> \
--amount <input_amount_smallest_unit> \
--slippage 30
```
### `order quote` Response Fields
| Field | Type | Description |
|-------|------|-------------|
| `input_token` | string | Input token contract address |
| `output_token` | string | Output token contract address |
| `input_amount` | string | Input amount (smallest unit) |
| `output_amount` | string | Expected output amount (smallest unit) |
| `min_output_amount` | string | Minimum output after slippage |
| `slippage` | number | Actual slippage percentage |
---
## `order get` Usage
```bash
gmgn-cli order get --chain sol --order-id <order_id>
```
Response fields are shared with `swap` — see [`swap` / `order get` Response Fields](#swap--order-get-response-fields) above.
---
## `gas-price` Usage
Query recommended gas price tiers for any chain. API Key only — no signature or private key required.
```bash
gmgn-cli gas-price --chain eth
gmgn-cli gas-price --chain bsc
gmgn-cli gas-price --chain base
gmgn-cli gas-price --chain sol
```
### `gas-price` Response Fields
All fields are omitempty — fields unsupported by a chain are omitted. Units are chain-native (wei for EVM chains; lamports / chain-native for SOL).
| Field | Type | Description |
| ------------------------ | ------- | ----------- |
| `chain` | string | Chain identifier |
| `auto` | string | Automatic gas price |
| `auto_mev` | string | Anti-MEV automatic gas price |
| `last_block` | int64 | Latest block number |
| `high` | string | High-priority gas price |
| `average` | string | Average-priority gas price |
| `low` | string | Low-priority gas price |
| `suggest_base_fee` | string | Suggested base fee |
| `high_prio_fee` | string | High-priority fee |
| `average_prio_fee` | string | Average-priority fee |
| `low_prio_fee` | string | Low-priority fee |
| `high_prio_fee_mixed` | string | High mixed priority fee |
| `average_prio_fee_mixed` | string | Average mixed priority fee |
| `low_prio_fee_mixed` | string | Low mixed priority fee |
| `native_token_usd_price` | float32 | Native token USD price |
| `high_estimate_time` | int64 | Estimated confirmation time for high tier (seconds) |
| `average_estimate_time` | int64 | Estimated confirmation time for average tier (seconds) |
| `low_estimate_time` | int64 | Estimated confirmation time for low tier (seconds) |
| `high_orign` | string | High-priority raw origin value |
| `average_orign` | string | Average-priority raw origin value |
| `low_orign` | string | Low-priority raw origin value |
---
## `order strategy create` Usage
```bash
# Create a take-profit order: sell when price rises to target (limit_order)
gmgn-cli order strategy create \
--chain sol \
--from <wallet_address> \
@@ -512,9 +522,9 @@ gmgn-cli order strategy create \
--sub-order-type take_profit \
--check-price 0.002 \
--amount-in 1000000 \
--slippage 0.01
--slippage 30
# Create a stop-loss order: sell when price drops to target
# Create a stop-loss order: sell when price drops to target (limit_order)
gmgn-cli order strategy create \
--chain sol \
--from <wallet_address> \
@@ -524,8 +534,67 @@ gmgn-cli order strategy create \
--sub-order-type stop_loss \
--check-price 0.0005 \
--amount-in-percent 100 \
--slippage 0.01
--slippage 30
# Create a smart_trade with buy_low entry + take-profit + stop-loss (smart_trade)
gmgn-cli order strategy create \
--chain sol \
--from <wallet_address> \
--base-token <token_address> \
--quote-token <sol_address> \
--order-type smart_trade \
--sub-order-type mix_trade \
--open-price 0.000082 \
--amount-in 1000000 \
--slippage 30 \
--sell-param '{"slippage":30,"priority_fee":"0.00001","tip_fee":"0.00001"}' \
--condition-orders '[{"order_type":"buy_low","side":"buy","check_price":"0.00008"},{"order_type":"profit_stop","side":"sell","price_scale":"100","sell_ratio":"50"},{"order_type":"loss_stop","side":"sell","price_scale":"50","sell_ratio":"100"}]'
```
## `order strategy create` Parameters
| Parameter | Required | Chain | Description |
|-----------|----------|-------|-------------|
| `--chain` | Yes | all | `sol` / `bsc` / `base` / `eth` |
| `--from` | Yes | all | Wallet address (must match API Key binding) |
| `--base-token` | Yes | all | Base token contract address |
| `--quote-token` | Yes | all | Quote token contract address |
| `--order-type` | Yes | all | Order type: `limit_order` / `smart_trade` |
| `--sub-order-type` | Yes | all | `limit_order`: `buy_low` / `buy_high` / `stop_loss` / `take_profit`; `smart_trade` with condition_orders: `mix_trade` |
| `--check-price` | No* | all | Trigger price — required for `limit_order`; omit for `smart_trade` (trigger is in the `buy_low` condition order) |
| `--open-price` | No | all | Open price of the position |
| `--amount-in` | No* | all | Input amount (smallest unit). Mutually exclusive with `--amount-in-percent` |
| `--amount-in-percent` | No* | all | Input as percentage (e.g. `50` = 50%). Mutually exclusive with `--amount-in` |
| `--limit-price-mode` | No | all | `exact` / `slippage` (default: `slippage`) |
| `--expire-in` | No | all | Order expiry in seconds |
| `--sell-ratio-type` | No | all | `buy_amount` (default) — when triggered, sells a fixed token amount stored at strategy creation time; `hold_amount` — when triggered, sells a fixed percentage of the position held at trigger time |
| `--quote-investment` | No | all | Quote token investment amount (`smart_trade`) |
| `--sell-param` | Yes (`smart_trade`) | all | JSON object of sell-side trade params (slippage, fee, gas, etc.) used when a TP/SL condition fires. **Required for `smart_trade`.** Same fields as the root TradeParam; `slippage` is 0100 integer. |
| `--buy-param` | No | all | JSON object of buy-side trade params override for `smart_trade`. Same fields as root TradeParam; `slippage` is 0100 integer. |
| `--slippage` | No | all | Slippage tolerance as an integer 0100, e.g. `30` = 30%. Mutually exclusive with `--auto-slippage`. Defaults to auto-slippage if neither is set. |
| `--auto-slippage` | No | all | Enable automatic slippage |
| `--priority-fee` | No | `sol` | Priority fee in SOL (≥ 0.00001). **Required** for SOL. |
| `--tip-fee` | No | `sol` / `bsc` | Tip fee (SOL ≥ 0.00001 / BSC ≥ 0.000001 BNB). **Required** for SOL. |
| `--auto-fee` | No | `eth` | Auto fee mode — GMGN automatically selects the optimal fee. |
| `--gas-price` | No | `bsc` / `base` / `eth` | Gas price in gwei (BSC ≥ 0.05 / BASE/ETH ≥ 0.01). **Required** for BSC. Mutually exclusive with `--gas-level`. |
| `--gas-level` | No | `eth` | Gas price tier: `low` / `average` / `high`. Mutually exclusive with `--gas-price`. |
| `--max-fee-per-gas` | No | `bsc` / `base` / `eth` | EIP-1559 max fee per gas. Clamped per chain minimums. |
| `--max-priority-fee-per-gas` | No | `bsc` / `base` / `eth` | EIP-1559 max priority fee per gas. Clamped per chain minimums; capped to `--max-fee-per-gas`. |
| `--anti-mev` | No | sol / bsc / eth | Enable anti-MEV protection. Not supported on `base`. |
| `--condition-orders` | No | all | JSON array of condition sub-orders for `smart_trade`. Must include one `buy_low` entry (with `check_price` lower than `open_price`) plus at least one TP/SL entry. |
### `order strategy create` Response Fields
| Field | Type | Description |
|-------|------|-------------|
| `order_id` | string | Created strategy order ID |
| `is_update` | bool | `true` if an existing order was updated, `false` if newly created |
---
## `order strategy list` Usage
```bash
# List open condition orders (profit_stop / loss_stop / trace types) — use STMix
gmgn-cli order strategy list --chain sol --group-tag STMix
@@ -537,7 +606,139 @@ gmgn-cli order strategy list --chain sol --group-tag STMix --type history --limi
# Filter by token
gmgn-cli order strategy list --chain sol --group-tag STMix --base-token <token_address>
```
## `order strategy list` Parameters
| Parameter | Required | Description |
|-----------|----------|-------------|
| `--chain` | Yes | `sol` / `bsc` / `base` / `eth` |
| `--type` | No | `open` (default) / `history` |
| `--from` | No | Filter by wallet address |
| `--group-tag` | Yes | Filter by order group: `LimitOrder` (limit orders only) / `STMix` (mixed strategy orders: take-profit, stop-loss, trailing take-profit, trailing stop-loss) |
| `--base-token` | No | Filter by token address |
| `--page-token` | No | Pagination cursor from previous response |
| `--limit` | No | Results per page (default 10 for history) |
### `order strategy list` Response Fields
| Field | Type | Description |
| ----------------- | ------ | ---- |
| `next_page_token` | string | Cursor for next page; empty when no more data |
| `total` | int | Total count (only returned when `--type open`) |
| `list` | array | Array of strategy order objects; see fields below |
#### `list[]` — Strategy Order Object
| Field | Type | Description |
| -------------------------- | ------ | ---- |
| `anti_mev_mode` | string | Anti-MEV mode string; empty when not set |
| `auto_slippage` | bool | Whether auto slippage is enabled |
| `base_decimal` | int | Base token decimal places |
| `base_token` | string | Base token contract address |
| `chain` | string | Chain: `sol` / `bsc` / `base` / `eth` |
| `close_amount` | string | Token amount sold on close; empty when order is open |
| `close_price` | string | Token price at close; empty when order is open |
| `close_sell_model` | string | Sell model used on close; empty when order is open |
| `close_sign_hash` | string | Close transaction hash; empty when order is open |
| `close_time` | int | Close timestamp (ms); `0` when order is open |
| `condition_orders` | array | Condition sub-orders; each element is an object — see `condition_orders[]` below |
| `create_time` | int | Creation timestamp (ms) |
| `custom_rpc` | string | Custom RPC endpoint; empty string when not set |
| `dev_sell_ratio` | string | Dev sell trigger ratio; empty when not set |
| `drawdown_rate` | string | Trailing drawdown rate for `profit_stop_trace` / `loss_stop_trace`; empty when not set |
| `expire_time` | int | Expiration timestamp (ms) |
| `fee` | string | Base transaction fee |
| `gas_price` | string | Gas price |
| `is_anti_mev` | bool | Whether anti-MEV protection is active |
| `limit_price_mode` | string | Limit price mode; empty when not set |
| `loss_stop` | string | Stop-loss trigger price; empty when not set |
| `loss_stop_type` | string | Stop-loss type; empty when not set |
| `max_fee_per_gas` | string | EIP-1559 max fee per gas; EVM only; empty on SOL |
| `max_priority_fee_per_gas` | string | EIP-1559 max priority fee per gas; EVM only; empty on SOL |
| `open_amount` | string | Token amount at open (smallest unit) |
| `open_price` | string | Token price at open |
| `open_sign_hash` | string | Open transaction hash; empty before confirmed |
| `order_id` | string | Unique order ID (UUID) |
| `order_statistic` | object | Cumulative order statistics; see `order_statistic` Object below |
| `order_type` | string | Order type: `smart_trade` / `limit_order` |
| `place_action` | string | Placement action; empty when not applicable |
| `prepare_status` | string | Preparation status; empty when not applicable |
| `priority_fee` | string | Priority fee; SOL / BSC only |
| `profit_stop` | string | Take-profit trigger price; empty when not set |
| `profit_stop_type` | string | Take-profit type; empty when not set |
| `quote_decimal` | int | Quote token decimal places |
| `quote_investment` | string | Quote token investment amount (smallest unit) |
| `quote_token` | string | Quote token contract address |
| `reason_by` | string | Entity that triggered the close; empty when open |
| `reason_code` | string | Reason code for the close action; empty when open |
| `record_high_price` | string | Highest recorded price since open; used for trailing stops |
| `sell_param` | object | Sell transaction parameters; see `sell_param` Object below |
| `sell_ratio` | string | Sell ratio; empty when not set |
| `sell_ratio_type` | string | Sell ratio base: `buy_amount` / others |
| `slippage` | int | Slippage tolerance (0 = auto) |
| `status` | string | Order lifecycle status: `open` / `closed` |
| `strategy_status` | string | Strategy running status: `running` / `stopped` |
| `sub_order_type` | string | Sub-order type: `mix_trade` / others |
| `tip_fee` | string | Tip fee; SOL only |
| `token_balance` | string | Remaining token balance; empty when not available |
| `token_logo` | string | Token logo URL |
| `token_name` | string | Token display name |
| `token_price` | string | Current token price; empty when not available |
| `total_supply` | string | Token total supply |
| `version` | int | Order schema version |
| `wallet_address` | string | Wallet address that placed the order |
#### `condition_orders[]` — Condition Sub-Order Object
| Field | Type | Description |
| ------------- | ------ | ---- |
| `cid` | string | Condition sub-order ID (UUID) |
| `order_type` | string | Sub-order type: `profit_stop` / `loss_stop` / `profit_stop_trace` / `loss_stop_trace` |
| `side` | string | Trade side: `sell` |
| `price_scale` | string | Price ratio relative to open price (string); `profit_stop` / `loss_stop` required |
| `sell_ratio` | string | Sell ratio (string), e.g. `"100"` |
| `check_price` | string | Computed trigger price derived from `price_scale` and open price |
| `status` | string | Sub-order status: `cancel` / `success` / `failed` |
#### `order_statistic` Object
| Field | Type | Description |
| ---------------------- | ------ | ---- |
| `buy_amount` | string | Bought token amount (smallest unit) |
| `buy_quote_price` | string | Quote token price at buy |
| `buy_usdt_price` | string | USDT-denominated price at buy |
| `quote_profit` | string | Realized profit in quote token |
| `sell_amount` | string | Total token amount sold |
| `sell_num` | int | Total number of sell attempts |
| `success_sell_amount` | string | Successfully sold token amount |
| `success_sell_num` | int | Number of successful sells |
| `usdt_profit` | string | Realized profit in USDT |
#### `sell_param` Object
| Field | Type | Description |
| -------------------------- | ------ | ---- |
| `anti_mev_mode` | string | Anti-MEV mode for the sell transaction |
| `auto_fee` | bool | Whether auto fee is enabled for the sell |
| `auto_slippage` | bool | Whether auto slippage is enabled for the sell |
| `auto_tip` | bool | Whether auto tip is enabled |
| `custom_rpc` | string | Custom RPC endpoint; empty string when not set |
| `fee` | string | Sell transaction fee |
| `gas_price` | string | Gas price for the sell |
| `is_anti_mev` | bool | Whether anti-MEV protection is active for the sell |
| `max_fee_per_gas` | string | EIP-1559 max fee per gas for the sell; EVM only |
| `max_priority_fee_per_gas` | string | EIP-1559 max priority fee per gas for the sell; EVM only |
| `max_tip_fee` | string | Maximum tip fee; empty when not set |
| `priority_fee` | string | Priority fee for the sell; SOL / BSC only |
| `slippage` | int | Slippage tolerance for the sell (0 = auto) |
| `tip_fee` | string | Tip fee for the sell; SOL only |
---
## `order strategy cancel` Usage
```bash
# Cancel a strategy order
gmgn-cli order strategy cancel \
--chain sol \
@@ -545,13 +746,30 @@ gmgn-cli order strategy cancel \
--order-id <order_id>
```
## `order strategy cancel` Parameters
| Parameter | Required | Description |
|-----------|----------|-------------|
| `--chain` | Yes | `sol` / `bsc` / `base` / `eth` |
| `--from` | Yes | Wallet address (must match API Key binding) |
| `--order-id` | Yes | Order ID to cancel |
| `--order-type` | No | Order type: `limit_order` (limit order) / `smart_trade` (mixed strategy order: take-profit, stop-loss, trailing take-profit, trailing stop-loss) |
| `--close-sell-model` | No | Sell model when closing the order |
---
## Notes
- Swap uses **critical auth** (API Key + signature) — CLI handles signing automatically, no manual processing needed
- Swap uses **signed auth** (API Key + signature) — CLI handles signing automatically, no manual processing needed
- After submitting a swap, use `order get` to poll for confirmation
- `--amount` is in the **smallest unit** (e.g., lamports for SOL)
- `order strategy create`, `order strategy list`, and `order strategy cancel` use critical auth (require `GMGN_PRIVATE_KEY`)
- `order strategy create`, `order strategy list`, and `order strategy cancel` use signed auth (require `GMGN_PRIVATE_KEY`)
- Use `--raw` to get single-line JSON for further processing
- **Chain restrictions for fee flags** — see the `Chain` column in each parameter table above. `--priority-fee` and `--tip-fee` are SOL/BSC only; `--gas-price`, `--max-fee-per-gas`, `--max-priority-fee-per-gas` are BSC/BASE/ETH only; `--gas-level` and `--auto-fee` are ETH only. The server returns 400 if a chain-restricted flag is sent on the wrong chain. (`gas-price` itself supports all four chains including `sol`.)
- **EIP-1559 minimum values per chain:**
- BSC: `max_fee_per_gas` and `max_priority_fee_per_gas` min 50 000 000 wei (≈ 0.05 gwei); passing `"0"` returns 400
- BASE / ETH: `max_fee_per_gas` and `max_priority_fee_per_gas` min 200 000 wei
- EIP-1559 clamping applies only when `--condition-orders` is present (swap / multi-swap) or on every request (strategy/create)
## Input Validation
@@ -590,7 +808,7 @@ For full token research before swapping, see [`docs/workflow-token-research.md`]
## Execution Guidelines
- **[REQUIRED] Token security check** — Run before every swap. See **Pre-Swap Safety Check (REQUIRED)** section above. Uses normal auth (API Key only — no private key needed for this step).
- **[REQUIRED] Token security check** — Run before every swap. See **Pre-Swap Safety Check (REQUIRED)** section above. Uses exist auth (API Key only — no private key needed for this step).
- **Currency resolution** — When the user names a currency (SOL/BNB/ETH/USDC) instead of providing an address, look up its address in the Chain Currencies table and apply it automatically — never ask the user for it.
- Buy ("buy X SOL of TOKEN", "spend 0.5 USDC on TOKEN") → resolve currency to `--input-token`
- Sell ("sell TOKEN for SOL", "sell 50% of TOKEN to USDC") → resolve currency to `--output-token`
+101 -22
View File
@@ -1,7 +1,7 @@
---
name: gmgn-token
description: Research any crypto or meme token by address — real-time price, market cap, liquidity, holder list, trader list, top Smart Money and KOL positions, security audit (honeypot, rug pull risk, dev wallet, renounced status), social links (Twitter/X, website) via GMGN API on Solana, BSC, or Base. Use when user asks about a token's price, safety, holders, traders, smart money exposure, or wants due diligence before buying.
argument-hint: "<sub-command> --chain <sol|bsc|base> --address <token_address>"
description: Research any crypto or meme token by address — real-time price, market cap, liquidity, holder list, trader list, top Smart Money and KOL positions, security audit (honeypot, rug pull risk, dev wallet, renounced status), social links (Twitter/X, website) via GMGN API on Solana, BSC, Base, or Ethereum. Use when user asks about a token's price, safety, holders, traders, smart money exposure, or wants due diligence before buying.
argument-hint: "<sub-command> --chain <sol|bsc|base|eth> --address <token_address>"
metadata:
cliHelp: "gmgn-cli token --help"
---
@@ -17,8 +17,8 @@ Use the `gmgn-cli` tool to query token information based on the user's request.
## Core Concepts
- **Token address** — The on-chain contract address that uniquely identifies a token on its chain. Required for all token sub-commands. Format: base58 (SOL) or `0x...` hex (BSC/Base).
- **Chain** — The blockchain network: `sol` = Solana, `bsc` = BNB Smart Chain, `base` = Base (Coinbase L2).
- **Market cap** — Not returned directly by `token info`. Calculate as `price × circulating_supply` (both are top-level fields in the response, already in human-readable units).
- **Chain** — The blockchain network: `sol` = Solana, `bsc` = BNB Smart Chain, `base` = Base (Coinbase L2), `eth` = Ethereum mainnet.
- **Market cap** — Not returned directly by `token info`. Calculate as `price.price × circulating_supply` (`price` is a nested object; use `price.price` for the current USD price string).
- **Liquidity** — USD value of token reserves in the main trading pool. Low liquidity (< $10k) means high price impact / slippage when buying or selling.
- **Holder** — A wallet that currently holds the token. `token holders` returns wallets ranked by current balance.
- **Trader** — Any wallet that has transacted with the token (bought or sold), regardless of current holdings. `token traders` covers both current holders and past traders.
@@ -34,7 +34,7 @@ Use the `gmgn-cli` tool to query token information based on the user's request.
| Sub-command | Description |
|-------------|-------------|
| `token info` | Basic info + realtime price, liquidity, market cap, total supply, holder count, social links (market cap = price × circulating_supply) |
| `token info` | Basic info + realtime price, liquidity, market cap, total supply, holder count, social links (market cap = price.price × circulating_supply) |
| `token security` | Security metrics (honeypot, taxes, holder concentration, contract risks) |
| `token pool` | Liquidity pool info (DEX, reserves, liquidity depth) |
| `token holders` | Top token holders list with profit/loss breakdown |
@@ -42,7 +42,7 @@ Use the `gmgn-cli` tool to query token information based on the user's request.
## Supported Chains
`sol` / `bsc` / `base`
`sol` / `bsc` / `base` / `eth`
## Prerequisites
@@ -51,7 +51,7 @@ Use the `gmgn-cli` tool to query token information based on the user's request.
## Rate Limit Handling
All token routes used by this skill go through GMGN's leaky-bucket limiter with `rate=10` and `capacity=10`. Sustained throughput is roughly `10 ÷ weight` requests/second, and the max burst is roughly `floor(10 ÷ weight)` when the bucket is full.
All token routes used by this skill go through GMGN's leaky-bucket limiter with `rate=20` and `capacity=20`. Sustained throughput is roughly `20 ÷ weight` requests/second, and the max burst is roughly `floor(20 ÷ weight)` when the bucket is full.
| Command | Route | Weight |
|---------|-------|--------|
@@ -88,7 +88,7 @@ When a request returns `429`:
| Parameter | Required | Description |
|-----------|----------|-------------|
| `--chain` | Yes | `sol` / `bsc` / `base` |
| `--chain` | Yes | `sol` / `bsc` / `base` / `eth` |
| `--address` | Yes | Token contract address |
| `--raw` | No | Output raw single-line JSON (for piping or further processing) |
@@ -96,12 +96,12 @@ When a request returns `429`:
| Parameter | Required | Default | Description |
|-----------|----------|---------|-------------|
| `--chain` | Yes | — | `sol` / `bsc` / `base` |
| `--chain` | Yes | — | `sol` / `bsc` / `base` / `eth` |
| `--address` | Yes | — | Token contract address |
| `--limit` | No | `20` | Number of results, max `100` |
| `--order-by` | No | `amount_percentage` | Sort field — see table below |
| `--direction` | No | `desc` | Sort direction: `asc` / `desc` |
| `--tag` | No | — | Wallet filter: `renowned` (KOL wallets) / `smart_degen` (smart money). Omit to return all wallets. |
| `--tag` | No | — | Wallet filter: `smart_degen` / `renowned` / `fresh_wallet` / `dev` / `sniper` / `rat_trader` / `bundler` / `transfer_in` / `dex_bot` / `bluechip_owner`. Omit to return all wallets. |
| `--raw` | No | — | Output raw single-line JSON |
### `--order-by` Values
@@ -116,10 +116,18 @@ When a request returns `429`:
### `--tag` Values
| Value | Description |
|-------|-------------|
| `renowned` | KOL / well-known wallets (influencers, funds, public figures) |
| `smart_degen` | Smart money wallets (historically high-performing traders) |
| Value | Description |
| -------------- | ----------- |
| `smart_degen` | Smart money wallets (historically high-performing traders) |
| `renowned` | KOL / well-known wallets (influencers, funds, public figures) |
| `fresh_wallet` | New wallets with no prior trading history |
| `dev` | Token developer / creator wallets |
| `sniper` | Wallets that sniped the token at launch |
| `rat_trader` | Insider / sneak-trading wallets |
| `bundler` | Bot-bundled buy wallets |
| `transfer_in` | Wallets with a transfer-in record for this token |
| `dex_bot` | DEX bot wallets (Axiom, Photon, BullX, Trojan, GMGN, Drops, PepeBoost, Padre) |
| `bluechip_owner` | Wallets holding established bluechip tokens |
### `--tag` + `--order-by` Combination Guide
@@ -154,7 +162,7 @@ The response has five nested objects: `pool`, `dev`, `link`, `stat`, `wallet_tag
| `total_supply` | Total token supply (same as `circulating_supply` for most tokens) |
| `circulating_supply` | Circulating supply |
| `max_supply` | Maximum supply |
| `price` | Current price in USD |
| `price` | **Object** — price and trading stats (see `price` Object below). Access current price as `price.price`. |
| `liquidity` | Total liquidity in USD (from biggest pool) |
| `holder_count` | Number of unique token holders |
| `logo` | Token logo image URL |
@@ -241,8 +249,6 @@ The response has five nested objects: `pool`, `dev`, `link`, `stat`, `wallet_tag
| Field | Description |
|-------|-------------|
| `stat.holder_count` | Number of holders (same as top-level `holder_count`) |
| `stat.bluechip_owner_count` | Number of bluechip wallet holders |
| `stat.bluechip_owner_percentage` | Ratio of holders that are bluechip wallets (01) |
| `stat.top_10_holder_rate` | Ratio of supply held by top 10 wallets (01) |
| `stat.dev_team_hold_rate` | Ratio held by dev team wallets |
| `stat.creator_hold_rate` | Ratio held by creator wallet |
@@ -268,6 +274,57 @@ The response has five nested objects: `pool`, `dev`, `link`, `stat`, `wallet_tag
| `wallet_tags_stat.fresh_wallets` | Number of fresh wallets |
| `wallet_tags_stat.top_wallets` | Number of top-ranked wallets |
**`price` Object** — Price and trading statistics (access current price via `price.price`)
| Field | Description |
|-------|-------------|
| `price.price` | Current price in USD (string) |
| `price.price_{window}` | Price at the start of the window; windows: `1m`, `5m`, `1h`, `6h`, `24h` |
| `price.buys_{window}` | Buy transaction count in the window |
| `price.sells_{window}` | Sell transaction count in the window |
| `price.volume_{window}` | Total trading volume in USD for the window |
| `price.buy_volume_{window}` | Buy volume in USD for the window |
| `price.sell_volume_{window}` | Sell volume in USD for the window |
| `price.swaps_{window}` | Total swap count for the window |
| `price.hot_level` | Heat level integer |
**`fee_distribution` Object** — Launchpad fee-sharing config (optional; present for `pump` / `bankr` tokens). Use `token info` to check fee distribution, creator reward claim status (`has_claimed_fee`), and royalty allocation for pump/bankr tokens.
| Field | Description |
|-------|-------------|
| `fee_distribution.launchpad` | Launchpad identifier: `"pump"`, `"bankr"`, or `""` (unknown) |
| `fee_distribution.platform_data` | Platform-specific fee config; structure varies by `launchpad` (see below) |
When `fee_distribution.launchpad = "pump"`:
| Field | Description |
|-------|-------------|
| `platform_data.fee_authority` | Fee authority wallet address |
| `platform_data.is_locked` | Whether the fee config is locked |
| `platform_data.show` | Whether fee distribution is displayed in the UI |
| `platform_data.list` | Array of fee-share holders (see FeeShareHolder below) |
| `platform_data.bonus_category` | Bonus category list (e.g. `creator_reward`, `cashback`) |
When `fee_distribution.launchpad = "bankr"`:
| Field | Description |
|-------|-------------|
| `platform_data.deployer` | Original deployer wallet address |
| `platform_data.fee_recipient` | Fee recipient wallet address |
| `platform_data.list` | Array of fee-share holders (see FeeShareHolder below) |
FeeShareHolder fields (each item in `platform_data.list`):
| Field | Description |
|-------|-------------|
| `wallet` | Wallet address |
| `royalty_bps` | Royalty share in basis points (10000 = 100%) |
| `is_creator` | Whether this is the original creator |
| `has_claimed_fee` | Whether fees have been claimed |
| `username` | Display name |
| `pfp` | Avatar URL |
| `twitter_username` | Twitter / X username |
---
### `token security` — Key Fields
@@ -412,13 +469,18 @@ The response is an object with a `list` array. Each item in `list` represents on
| `maker_token_tags` | Token-specific behavior tags for this wallet (e.g. `["bundler"]`, `["paper_hands"]`, `["top_holder"]`) |
| `created_at` | Wallet creation timestamp (Unix seconds); `0` if unknown |
**Shared Funding**
| Field | Description |
|-------|-------------|
| `native_transfer` | First native token (SOL/BNB/ETH) transfer into this wallet — indicates the original funding source; wallets sharing the same `native_transfer.address` are likely funded from a common origin (coordinated wallets / same operator) |
**Last Transaction Records**
Each of the following is an object with `name`, `address`, `timestamp`, `tx_hash`, `type`:
| Field | Description |
|-------|-------------|
| `native_transfer` | Most recent native token (SOL/BNB/ETH) transfer associated with this wallet |
| `token_transfer` | Most recent token transfer (buy or sell) |
| `token_transfer_in` | Most recent inbound token transfer |
| `token_transfer_out` | Most recent outbound token transfer |
@@ -439,6 +501,9 @@ gmgn-cli token info --chain bsc --address 0x2170Ed0880ac9A755fd29B2688956BD959F9
# Get basic info for a Base token
gmgn-cli token info --chain base --address 0x4200000000000000000000000000000000000006
# Get basic info for an ETH token
gmgn-cli token info --chain eth --address 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
# Raw JSON output for downstream processing
gmgn-cli token info --chain sol --address EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v --raw
```
@@ -455,6 +520,9 @@ gmgn-cli token security --chain bsc --address 0x2170Ed0880ac9A755fd29B2688956BD9
# Check a Base token for tax, rug ratio, and insider concentration
gmgn-cli token security --chain base --address 0x4200000000000000000000000000000000000006
# Check an ETH token for honeypot and contract risks
gmgn-cli token security --chain eth --address 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
# Raw output for parsing key fields (e.g. is_honeypot, buy_tax, rug_ratio)
gmgn-cli token security --chain bsc --address 0x2170Ed0880ac9A755fd29B2688956BD959F933F8 --raw
```
@@ -467,6 +535,9 @@ gmgn-cli token pool --chain sol --address EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZw
# Get pool info for a BSC token
gmgn-cli token pool --chain bsc --address 0x2170Ed0880ac9A755fd29B2688956BD959F933F8
# Get pool info for an ETH token
gmgn-cli token pool --chain eth --address 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
```
### `token holders` — Analyze Holder Distribution
@@ -503,6 +574,10 @@ gmgn-cli token holders --chain sol --address EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGG
gmgn-cli token holders --chain bsc --address 0x2170Ed0880ac9A755fd29B2688956BD959F933F8 \
--tag renowned --order-by profit --direction desc --limit 50
# ETH token holders — smart money by supply percentage
gmgn-cli token holders --chain eth --address 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 \
--tag smart_degen --order-by amount_percentage --direction desc --limit 20
# Raw output for downstream analysis
gmgn-cli token holders --chain sol --address EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v \
--limit 100 --raw
@@ -551,6 +626,10 @@ gmgn-cli token traders --chain sol --address EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGG
# BSC token traders by profit
gmgn-cli token traders --chain bsc --address 0x2170Ed0880ac9A755fd29B2688956BD959F933F8 \
--tag smart_degen --order-by profit --direction desc --limit 50
# ETH token traders by profit
gmgn-cli token traders --chain eth --address 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 \
--tag smart_degen --order-by profit --direction desc --limit 50
```
---
@@ -601,7 +680,7 @@ Present as a concise card. Do not dump raw JSON.
```
{symbol} ({name})
Price: ${price} | Market Cap: ~${price × circulating_supply} | Liquidity: ${liquidity}
Price: ${price.price} | Market Cap: ~${price.price × circulating_supply} | Liquidity: ${liquidity}
Holders: {holder_count} | Smart Money: {wallet_tags_stat.smart_wallets} | KOLs: {wallet_tags_stat.renowned_wallets}
Social: @{link.twitter_username} | {link.website} | {link.telegram}
```
@@ -644,9 +723,9 @@ Show top rows only. Highlight wallets tagged `kol`, `smart_degen`, or flagged `b
## Notes
- **Market cap is not returned directly** — calculate it as `price × circulating_supply` (both fields are top-level; `circulating_supply` is already in human-readable token units, no decimal adjustment needed). Example: `price=3.11` × `circulating_supply=999999151` ≈ $3.11B market cap.
- **Trading volume (1h, 24h, etc.) is not included in `token info`** — to get volume or OHLCV data, use the `gmgn-market` skill and query K-line data: `gmgn-cli market kline --chain <chain> --address <token_address> --resolution <1m|5m|15m|1h|4h|1d>`. See the `gmgn-market` SKILL.md for full details.
- All token commands use normal auth (API Key only, no signature required)
- **Market cap is not returned directly** — calculate it as `price.price × circulating_supply` (`price` is now a nested object; use `price.price` for the current USD price string, and `circulating_supply` is a top-level field already in human-readable token units). Example: `price.price="3.11"` × `circulating_supply=999999151` ≈ $3.11B market cap.
- **Trading volume and swap counts by window are available in `token info`** via the `price` object: `volume_{window}`, `buy_volume_{window}`, `sell_volume_{window}`, `buys_{window}`, `sells_{window}`, `swaps_{window}` (windows: `1m`, `5m`, `1h`, `6h`, `24h`). For OHLCV candlestick data, use `gmgn-market kline`.
- All token commands use exist auth (API Key only, no signature required)
- Use `--raw` to get single-line JSON for further processing
- `--tag` applies to both `holders` and `traders` and filters to only wallets with that tag — if few results are returned, try the other tag value
- `amount_percentage` in holders/traders is a ratio (01), not a percentage — `0.05` means 5% of supply
+90 -10
View File
@@ -1,7 +1,7 @@
---
name: gmgn-track
description: Get real-time crypto buy/sell activity from Smart Money wallets, KOL influencer wallets, and personally followed wallets via GMGN API — alpha signals, whale tracking, meme token copy-trading ideas on Solana, BSC, or Base. Use when user asks what smart money or KOLs are buying, wants whale alerts, on-chain alpha, or copy-trade signals. (For a specific wallet address, use gmgn-portfolio.)
argument-hint: "<follow-wallet|kol|smartmoney> [--chain <sol|bsc|base>] [--wallet <wallet_address>]"
description: Get real-time crypto buy/sell activity from Smart Money wallets, KOL influencer wallets, and personally followed wallets via GMGN API — alpha signals, whale tracking, meme token copy-trading ideas on Solana, BSC, Base, or Ethereum. Also query which tokens a wallet has followed (bookmarked) on GMGN. Use when user asks what smart money or KOLs are buying, wants whale alerts, on-chain alpha, copy-trade signals, or wants to check a wallet's followed tokens. (For a specific wallet address's portfolio, use gmgn-portfolio.)
argument-hint: "<follow-tokens|follow-wallet|kol|smartmoney> --chain <sol|bsc|base|eth> [--wallet <wallet_address>]"
metadata:
cliHelp: "gmgn-cli track --help"
---
@@ -49,25 +49,30 @@ Use the `gmgn-cli` tool to query on-chain tracking data based on the user's requ
| Sub-command | Description |
|-------------|-------------|
| `track follow-tokens` | Followed token list for a wallet — which tokens a wallet has bookmarked on GMGN, with full market data |
| `track follow-token-groups` | Follow token group names for a wallet — the group names and IDs the wallet uses to organise followed tokens |
| `track follow-wallet` | Trade records from wallets the user personally follows on GMGN |
| `track kol` | Real-time trades from KOL / influencer wallets tagged by GMGN |
| `track smartmoney` | Real-time trades from smart money / whale wallets tagged by GMGN |
## Supported Chains
`sol` / `bsc` / `base`
`sol` / `bsc` / `base` / `eth`
## Prerequisites
- `gmgn-cli` installed globally — if missing, run: `npm install -g gmgn-cli`
- `GMGN_API_KEY` configured in `~/.config/gmgn/.env` — required for all sub-commands; no private key needed
- `GMGN_API_KEY` configured in `~/.config/gmgn/.env` — required for all sub-commands
- `GMGN_PRIVATE_KEY` — required for `track follow-wallet` only (signed auth); not needed for `follow-tokens`, `kol`, or `smartmoney`
## Rate Limit Handling
All tracking routes used by this skill go through GMGN's leaky-bucket limiter with `rate=10` and `capacity=10`. Sustained throughput is roughly `10 ÷ weight` requests/second, and the max burst is roughly `floor(10 ÷ weight)` when the bucket is full.
All tracking routes used by this skill go through GMGN's leaky-bucket limiter with `rate=20` and `capacity=20`. Sustained throughput is roughly `20 ÷ weight` requests/second, and the max burst is roughly `floor(20 ÷ weight)` when the bucket is full.
| Command | Route | Weight |
|---------|-------|--------|
| `track follow-tokens` | `GET /v1/user/follow_tokens` | 3 |
| `track follow-token-groups` | `GET /v1/user/follow_token_groups` | 1 |
| `track follow-wallet` | `GET /v1/trade/follow_wallet` | 3 |
| `track kol` | `GET /v1/user/kol` | 1 |
| `track smartmoney` | `GET /v1/user/smartmoney` | 1 |
@@ -88,16 +93,30 @@ When a request returns `429`:
```
Tell the user: *"This is your Ed25519 public key. Go to **https://gmgn.ai/ai**, paste it into the API key creation form, then send me the API Key value shown on the page."*
2. Wait for the user's API key, then configure:
2. Wait for the user's API key, then configure (saves both API key and private key — private key is required for `track follow-wallet`):
```bash
mkdir -p ~/.config/gmgn
echo 'GMGN_API_KEY=<key_from_user>' > ~/.config/gmgn/.env
echo "GMGN_API_KEY=<key_from_user>" > ~/.config/gmgn/.env
echo "GMGN_PRIVATE_KEY=$(awk '{printf "%s\\n", $0}' /tmp/gmgn_private.pem)" >> ~/.config/gmgn/.env
chmod 600 ~/.config/gmgn/.env
rm /tmp/gmgn_private.pem
```
## Usage Examples
```bash
# Followed token list for a wallet on SOL
gmgn-cli track follow-tokens --chain sol --wallet <wallet_address>
# Followed token list on BSC, raw JSON output
gmgn-cli track follow-tokens --chain bsc --wallet <wallet_address> --raw
# Follow token group names for a wallet on SOL
gmgn-cli track follow-token-groups --chain sol --wallet <wallet_address>
# Follow token group names, raw JSON output
gmgn-cli track follow-token-groups --chain sol --wallet <wallet_address> --raw
# Follow-wallet trades (all wallets you follow)
gmgn-cli track follow-wallet --chain sol
@@ -123,11 +142,71 @@ gmgn-cli track smartmoney --limit 10 --raw
gmgn-cli track smartmoney --chain sol --side sell --limit 10 --raw
```
## `track follow-tokens` Options
| Option | Description |
|--------|-------------|
| `--chain` | Required. `sol` / `bsc` / `base` / `eth` |
| `--wallet <address>` | Required. Wallet address to query |
| `--group-id <id>` | Filter by group: `all_group` (all tokens across groups), `default` (default group), or a user-defined group ID |
| `--interval <interval>` | Time interval for price change stats (e.g. `1m`, `5m`, `1h`, `6h`, `24h`) |
| `--order-by <field>` | Sort field: `created_at` / `swaps` / `volume` / `market_cap` / `liquidity` / `price` / `open_timestamp` |
| `--direction <dir>` | Required when `--order-by` is set. `asc` / `desc` |
| `--limit <n>` | Page size |
| `--cursor <cursor>` | Pagination cursor from previous response |
| `--search <text>` | Search by token name or address |
## `track follow-tokens` Response Fields
Top-level fields:
| Field | Description |
|-------|-------------|
| `cursor` | Opaque cursor for fetching the next page |
| `all_following` | Total number of followed tokens |
| `is_recommend` | Whether results include recommended tokens |
| `followings` | Array of followed token objects |
Each item in `followings` contains:
| Field | Description |
|-------|-------------|
| `address` | Token contract address |
| `symbol` | Token ticker symbol |
| `name` | Token name |
| `chain` | Chain the token is on |
| `price` | Current token price |
| `price_change_percent` | Price change percentage |
| `volume` | Trading volume |
| `liquidity` | Pool liquidity |
| `market_cap` | Market cap |
| `swaps` | Total swaps |
| `group_ids` | Follow groups this token belongs to |
| `open_timestamp` | Unix timestamp when trading opened |
## `track follow-token-groups` Options
| Option | Description |
|--------|-------------|
| `--chain` | Required. `sol` / `bsc` / `base` / `eth` |
| `--wallet <address>` | Required. Wallet address to query |
## `track follow-token-groups` Response Fields
`data` is an array. Each item contains:
| Field | Description |
|-------|-------------|
| `chain` | Chain the group is on |
| `group_id` | Group identifier (e.g. `default`, or a user-defined ID) |
| `group_name` | Human-readable group name |
| `rank` | Display order / sort rank |
## `track follow-wallet` Options
| Option | Description |
|--------|-------------|
| `--chain` | Required. `sol` / `bsc` / `base` |
| `--chain` | Required. `sol` / `bsc` / `base` / `eth` |
| `--wallet <address>` | Filter by wallet address |
| `--limit <n>` | Page size (1100, default 10) |
| `--side <side>` | Trade direction: `buy` / `sell` |
@@ -139,7 +218,7 @@ gmgn-cli track smartmoney --chain sol --side sell --limit 10 --raw
| Option | Description |
|--------|-------------|
| `--chain <chain>` | Chain: `sol` / `bsc` / `base` (default `sol`) |
| `--chain <chain>` | Required. Chain: `sol` / `bsc` / `base` / `eth` |
| `--limit <n>` | Page size (1200, default 100) |
| `--side <side>` | Filter by trade direction: `buy` / `sell` (client-side filter — applied locally after fetching results) |
@@ -308,7 +387,8 @@ To research any token surfaced by smart money activity, follow [`docs/workflow-t
## Notes
- All sub-commands use normal auth (API Key only, no signature required)
- `track follow-tokens` uses exist auth (API Key only); `--wallet` is required
- `track follow-wallet` uses signed auth (API Key + private key signature); `track kol` and `track smartmoney` use exist auth (API Key only)
- `track follow-wallet` returns trades from wallets followed on the GMGN platform; the follow list is resolved automatically from the GMGN user account bound to the API Key — `--wallet` is optional
- Use `--raw` to get single-line JSON for further processing
- `track kol` / `track smartmoney` `--side` is a **client-side filter** — the CLI fetches all results then filters locally; it is NOT sent to the API
+198 -48
View File
@@ -2,15 +2,20 @@
* OpenApiClient GMGN OpenAPI external client
*
* Auth modes:
* Normal (market/token/portfolio): X-APIKEY + timestamp + client_id
* Critical (swap and order routes): normal auth + X-Signature (private key signature)
* Exist (market/token/portfolio): X-APIKEY + timestamp + client_id
* Signed (swap and order routes): X-APIKEY + timestamp + client_id + X-Signature (private key signature)
*/
import { createRequire } from "node:module";
import { buildAuthQuery, buildMessage, detectAlgorithm, sign } from "./signer.js";
const RATE_LIMIT_RETRY_BUFFER_MS = 1000;
const DEFAULT_RATE_LIMIT_AUTO_RETRY_MAX_WAIT_MS = 5000;
const { version: CLI_VERSION } = createRequire(import.meta.url)("../../package.json") as { version: string };
const USER_AGENT = `gmgn-cli/${CLI_VERSION}`;
interface PreparedRequest {
method: string;
subPath: string;
@@ -80,9 +85,9 @@ export interface SwapParams {
is_anti_mev?: boolean;
priority_fee?: string;
tip_fee?: string;
auto_tip_fee?: boolean;
max_auto_fee?: string;
gas_price?: string;
gas_level?: string;
auto_fee?: boolean;
max_fee_per_gas?: string;
max_priority_fee_per_gas?: string;
condition_orders?: StrategyConditionOrder[];
@@ -111,9 +116,9 @@ export interface MultiSwapParams {
is_anti_mev?: boolean;
priority_fee?: string;
tip_fee?: string;
auto_tip_fee?: boolean;
max_auto_fee?: string;
gas_price?: string;
gas_level?: string;
auto_fee?: boolean;
max_fee_per_gas?: string;
max_priority_fee_per_gas?: string;
condition_orders?: StrategyConditionOrder[];
@@ -127,7 +132,7 @@ export interface StrategyCreateParams {
quote_token: string;
order_type: string;
sub_order_type: string;
check_price: string;
check_price?: string;
open_price?: string;
amount_in?: string;
amount_in_percent?: string;
@@ -138,7 +143,9 @@ export interface StrategyCreateParams {
slippage?: number;
auto_slippage?: boolean;
fee?: string;
auto_fee?: boolean;
gas_price?: string;
gas_level?: string;
max_fee_per_gas?: string;
max_priority_fee_per_gas?: string;
is_anti_mev?: boolean;
@@ -146,6 +153,10 @@ export interface StrategyCreateParams {
priority_fee?: string;
tip_fee?: string;
custom_rpc?: string;
condition_orders?: StrategyConditionOrder[];
quote_investment?: string;
sell_param?: TradeParam;
buy_param?: TradeParam;
}
export interface StrategyCancelParams {
@@ -168,27 +179,146 @@ export interface TokenSignalGroup {
max_create_or_open_ts?: string;
}
export interface PumpFeeShareInfo {
provider: string; // "solana" | "twitter" | "github"
username: string; // platform username; a SOL address when provider = "solana"
basic_points: number;
}
export interface BAGSFeeShareInfo {
provider: string; // "twitter" | "solana" | "kick" | "github"
username: string;
basic_points: number;
}
export interface FlapRateConf {
tax_rate?: number; // V5 unified tax rate, e.g. 5% -> 500
buy_tax_rate?: number; // V6 separate buy tax rate
sell_tax_rate?: number; // V6 separate sell tax rate
mkt_bps?: number;
deflation_bps?: number;
dividend_bps?: number;
lp_bps?: number;
minimum_share_balance?: number;
recipient_type?: string;
beneficiary?: string;
twitter_account?: string;
split_conf?: Array<{ recipient: string; bps: number }>;
}
export interface FourmemeRateConf {
fee_plan?: boolean;
fee_rate?: number;
burn_rate?: number;
divide_rate?: number;
liquidity_rate?: number;
recipient_rate?: number;
recipient_address?: string;
min_sharing?: number;
}
export interface BuyWalletInfo {
from_address: string;
buy_amt: string;
}
// Buy/sell execution config for CondMarket orders (snipe buy, auto-sell, pending_sell).
// Does NOT affect the main creation tx. Falls back to outer-level fields when omitted.
export interface TradeParam {
slippage?: number;
auto_slippage?: boolean;
fee?: string;
priority_fee?: string;
tip_fee?: string;
gas_price?: string;
max_priority_fee_per_gas?: string;
max_fee_per_gas?: string;
is_anti_mev?: boolean; // backend currently forces true; passing has no effect
anti_mev_mode?: string; // backend currently forces "secure"; passing has no effect
}
export interface CookingSellConfig {
sell_type: string; // "delay_sell" | "limit_order"
delay_sec?: number; // required when sell_type = "delay_sell"
delay_mili_sec?: number; // optional; takes precedence over delay_sec
sell_ratio: string; // "1" = 100%, "0.5" = 50%
check_price?: string; // trigger market cap in USD; required when sell_type = "limit_order"
wallet_addresses: string[]; // empty array means the strategy is inert
}
export interface CreateTokenParams {
// Required
chain: string;
dex: string;
from_address: string;
name: string;
symbol: string;
buy_amt: string;
// Image (one required)
image?: string;
image_url?: string;
// Social
description?: string;
website?: string;
twitter?: string;
telegram?: string;
// Transaction
slippage?: number;
auto_slippage?: boolean;
// Fees
fee?: string;
priority_fee?: string;
tip_fee?: string;
gas_price?: string;
max_priority_fee_per_gas?: string;
max_fee_per_gas?: string;
// Anti-MEV (SOL only)
is_anti_mev?: boolean;
anti_mev_mode?: string;
// Advanced
raised_token?: string;
dev_gas?: string;
dev_priority?: string;
dev_tip?: string;
dev_max_fee_per_gas?: string;
approve_vision?: string;
source?: string;
dev_wallet_bps?: number;
// CondMarket buy/sell execution config (snipe / bundle / auto-sell)
buy_trade_config?: TradeParam;
sell_trade_config?: TradeParam;
// Auto-sell strategies created after a successful launch
sell_configs?: CookingSellConfig[];
// Pump.fun specific
is_mayhem?: boolean;
is_cashback?: boolean;
is_buy_back?: boolean;
pump_fee_share_list?: PumpFeeShareInfo[];
// Flap specific
flap_rate_conf?: FlapRateConf;
// FourMeme specific
fourmeme_rate_conf?: FourmemeRateConf;
// BAGS specific
bags_fee_share_list?: BAGSFeeShareInfo[];
// Bonk specific
bonk_model?: string;
// Multi-wallet buy
buy_wallets?: BuyWalletInfo[];
snip_buy_wallets?: BuyWalletInfo[];
}
export class OpenApiClient {
@@ -202,29 +332,29 @@ export class OpenApiClient {
this.host = config.host.replace(/\/$/, "");
}
// ---- Token endpoints (normal auth) ----
// ---- Token endpoints (exist auth) ----
async getTokenInfo(chain: string, address: string): Promise<unknown> {
return this.normalRequest("GET", "/v1/token/info", { chain, address });
return this.authExistRequest("GET", "/v1/token/info", { chain, address });
}
async getTokenSecurity(chain: string, address: string): Promise<unknown> {
return this.normalRequest("GET", "/v1/token/security", { chain, address });
return this.authExistRequest("GET", "/v1/token/security", { chain, address });
}
async getTokenPoolInfo(chain: string, address: string): Promise<unknown> {
return this.normalRequest("GET", "/v1/token/pool_info", { chain, address });
return this.authExistRequest("GET", "/v1/token/pool_info", { 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 });
return this.authExistRequest("GET", "/v1/market/token_top_holders", { chain, address, ...extra });
}
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 });
return this.authExistRequest("GET", "/v1/market/token_top_traders", { chain, address, ...extra });
}
// ---- Market endpoints (normal auth) ----
// ---- Market endpoints (exist auth) ----
async getTokenKline(
chain: string,
@@ -236,21 +366,21 @@ export class OpenApiClient {
const query: Record<string, string | number> = { chain, address, resolution };
if (from != null) query["from"] = from;
if (to != null) query["to"] = to;
return this.normalRequest("GET", "/v1/market/token_kline", query);
return this.authExistRequest("GET", "/v1/market/token_kline", query);
}
// ---- Portfolio endpoints (normal auth) ----
// ---- Portfolio endpoints ----
async getWalletHoldings(
chain: string,
walletAddress: string,
extra: Record<string, string | number> = {}
): Promise<unknown> {
return this.normalRequest("GET", "/v1/user/wallet_holdings", {
return this.authSignedRequest("GET", "/v1/user/wallet_holdings", {
chain,
wallet_address: walletAddress,
...extra,
});
}, null);
}
async getWalletActivity(
@@ -258,7 +388,7 @@ export class OpenApiClient {
walletAddress: string,
extra: Record<string, string | number | string[]> = {}
): Promise<unknown> {
return this.normalRequest("GET", "/v1/user/wallet_activity", {
return this.authExistRequest("GET", "/v1/user/wallet_activity", {
chain,
wallet_address: walletAddress,
...extra,
@@ -266,7 +396,7 @@ export class OpenApiClient {
}
async getWalletStats(chain: string, walletAddresses: string[], period = "7d"): Promise<unknown> {
return this.normalRequest("GET", "/v1/user/wallet_stats", {
return this.authExistRequest("GET", "/v1/user/wallet_stats", {
chain,
wallet_address: walletAddresses,
period,
@@ -278,54 +408,62 @@ export class OpenApiClient {
walletAddress: string,
tokenAddress: string
): Promise<unknown> {
return this.normalRequest("GET", "/v1/user/wallet_token_balance", { chain, wallet_address: walletAddress, token_address: tokenAddress });
return this.authExistRequest("GET", "/v1/user/wallet_token_balance", { chain, wallet_address: walletAddress, token_address: tokenAddress });
}
async getTrenches(chain: string, types?: string[], platforms?: string[], limit?: number, filters?: Record<string, number | string>): Promise<unknown> {
const body = buildTrenchesBody(chain, types, platforms, limit, filters);
return this.normalRequest("POST", "/v1/trenches", { chain }, body);
return this.authExistRequest("POST", "/v1/trenches", { chain }, body);
}
// ---- Market trending endpoints (normal auth) ----
// ---- Market trending endpoints (exist auth) ----
async getTrendingSwaps(
chain: string,
interval: string,
extra: Record<string, string | number | string[]> = {}
): Promise<unknown> {
return this.normalRequest("GET", "/v1/market/rank", { chain, interval, ...extra });
return this.authExistRequest("GET", "/v1/market/rank", { chain, interval, ...extra });
}
async getTokenSignalV2(chain: string, groups: TokenSignalGroup[]): Promise<unknown> {
return this.normalRequest("POST", "/v1/market/token_signal", {}, { chain, groups });
return this.authExistRequest("POST", "/v1/market/token_signal", {}, { chain, groups });
}
// ---- User endpoints (normal auth) ----
// ---- User endpoints (exist auth) ----
async getUserInfo(): Promise<unknown> {
return this.normalRequest("GET", "/v1/user/info", {});
return this.authExistRequest("GET", "/v1/user/info", {});
}
async getFollowWallet(chain: string, extra: Record<string, string | number | string[]> = {}): Promise<unknown> {
return this.normalRequest("GET", "/v1/trade/follow_wallet", { chain, ...extra });
return this.authSignedRequest("GET", "/v1/trade/follow_wallet", { chain, ...extra }, null);
}
async getFollowTokens(chain: string, walletAddress: string, extra: Record<string, string | number> = {}): Promise<unknown> {
return this.authExistRequest("GET", "/v1/user/follow_tokens", { chain, wallet_address: walletAddress, ...extra });
}
async getFollowGroupNames(chain: string, walletAddress: string): Promise<unknown> {
return this.authExistRequest("GET", "/v1/user/follow_token_groups", { chain, wallet_address: walletAddress });
}
async getKol(chain?: string, limit?: number): Promise<unknown> {
const query: Record<string, string | number> = {};
if (chain) query["chain"] = chain;
if (limit != null) query["limit"] = limit;
return this.normalRequest("GET", "/v1/user/kol", query);
return this.authExistRequest("GET", "/v1/user/kol", query);
}
async getSmartMoney(chain?: string, limit?: number): Promise<unknown> {
const query: Record<string, string | number> = {};
if (chain) query["chain"] = chain;
if (limit != null) query["limit"] = limit;
return this.normalRequest("GET", "/v1/user/smartmoney", query);
return this.authExistRequest("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 });
return this.authExistRequest("GET", "/v1/user/created_tokens", { chain, wallet_address: walletAddress, ...extra });
}
async quoteOrder(
@@ -337,50 +475,54 @@ export class OpenApiClient {
slippage: number
): Promise<unknown> {
const query = { chain, from_address, input_token, output_token, input_amount, slippage };
return this.criticalRequest("GET", "/v1/trade/quote", query, null);
return this.authExistRequest("GET", "/v1/trade/quote", query);
}
// ---- Swap endpoints (critical auth) ----
// ---- Swap endpoints (signed auth) ----
async swap(params: SwapParams): Promise<unknown> {
return this.criticalRequest("POST", "/v1/trade/swap", {}, params);
return this.authSignedRequest("POST", "/v1/trade/swap", {}, params);
}
async multiSwap(params: MultiSwapParams): Promise<unknown> {
return this.criticalRequest("POST", "/v1/trade/multi_swap", {}, params);
return this.authSignedRequest("POST", "/v1/trade/multi_swap", {}, params);
}
async queryOrder(orderId: string, chain: string): Promise<unknown> {
return this.criticalRequest("GET", "/v1/trade/query_order", { order_id: orderId, chain }, null);
return this.authSignedRequest("GET", "/v1/trade/query_order", { order_id: orderId, chain }, null);
}
// ---- Strategy order endpoints (critical auth) ----
async getGasPrice(chain: string): Promise<unknown> {
return this.authExistRequest("GET", "/v1/trade/gas_price", { chain });
}
// ---- Strategy order endpoints (signed auth) ----
async createStrategyOrder(params: StrategyCreateParams): Promise<unknown> {
return this.criticalRequest("POST", "/v1/trade/strategy/create", {}, params);
return this.authSignedRequest("POST", "/v1/trade/strategy/create", {}, params);
}
async getStrategyOrders(chain: string, extra: Record<string, string | number> = {}): Promise<unknown> {
return this.criticalRequest("GET", "/v1/trade/strategy/orders", { chain, ...extra }, null);
return this.authSignedRequest("GET", "/v1/trade/strategy/orders", { chain, ...extra }, null);
}
async cancelStrategyOrder(params: StrategyCancelParams): Promise<unknown> {
return this.criticalRequest("POST", "/v1/trade/strategy/cancel", {}, params);
return this.authSignedRequest("POST", "/v1/trade/strategy/cancel", {}, params);
}
// ---- Cooking endpoints ----
async getCookingStatistics(): Promise<unknown> {
return this.normalRequest("GET", "/v1/cooking/statistics", {});
return this.authExistRequest("GET", "/v1/cooking/statistics", {});
}
async createToken(params: CreateTokenParams): Promise<unknown> {
return this.criticalRequest("POST", "/v1/cooking/create_token", {}, params);
return this.authSignedRequest("POST", "/v1/cooking/create_token", {}, params);
}
// ---- Internal methods ----
private async normalRequest(
private async authExistRequest(
method: string,
subPath: string,
queryExtra: Record<string, string | number | string[]>,
@@ -393,6 +535,7 @@ export class OpenApiClient {
const headers: Record<string, string> = {
"X-APIKEY": this.apiKey,
"Content-Type": "application/json",
"User-Agent": USER_AGENT,
};
const bodyStr = body !== null ? JSON.stringify(body) : null;
return {
@@ -406,19 +549,19 @@ export class OpenApiClient {
}, true);
}
private async criticalRequest(
private async authSignedRequest(
method: string,
subPath: string,
queryExtra: Record<string, string | number>,
queryExtra: Record<string, string | number | string[]>,
body: unknown
): Promise<unknown> {
if (!this.privateKeyPem) {
throw new Error("GMGN_PRIVATE_KEY is required for critical-auth commands (swap and all order commands)");
throw new Error("GMGN_PRIVATE_KEY is required for critical-auth commands (swap, order, follow-wallet, and portfolio holdings commands)");
}
return this.executePreparedRequest(() => {
const { timestamp, client_id } = buildAuthQuery();
const query: Record<string, string | number> = { ...queryExtra, timestamp, client_id };
const query: Record<string, string | number | string[]> = { ...queryExtra, timestamp, client_id };
const bodyStr = body !== null ? JSON.stringify(body) : "";
const message = buildMessage(subPath, query, bodyStr, timestamp);
const signature = sign(message, this.privateKeyPem!, detectAlgorithm(this.privateKeyPem!));
@@ -428,6 +571,7 @@ export class OpenApiClient {
"X-APIKEY": this.apiKey,
"X-Signature": signature,
"Content-Type": "application/json",
"User-Agent": USER_AGENT,
};
return {
method,
@@ -669,18 +813,24 @@ const TRENCHES_PLATFORMS: Record<string, string[]> = {
],
bsc: [
"fourmeme", "fourmeme_agent", "bn_fourmeme", "four_xmode_agent",
"flap", "clanker", "lunafun",
"cubepeg", "likwid", "goplus_creator", "goplus_skills", "openfour",
"flap", "flap_stocks", "flap_aioracle", "clanker", "lunafun",
],
base: [
"clanker", "bankr", "flaunch", "zora", "zora_creator",
"baseapp", "basememe", "virtuals_v2", "klik",
],
eth: [
"trench", "clanker", "klik", "livo", "stroid",
"pool_uniswap_v2", "pool_uniswap_v3", "printr",
],
};
const TRENCHES_QUOTE_ADDRESS_TYPES: Record<string, number[]> = {
sol: [4, 5, 3, 1, 13, 0],
bsc: [6, 7, 1, 16, 8, 3, 9, 10, 2, 17, 18, 0],
base: [11, 3, 12, 13, 0],
eth: [20, 11, 8, 3, 12, 1, 0],
};
function buildTrenchesBody(chain: string, types?: string[], platforms?: string[], limit?: number, filters?: Record<string, number | string>): Record<string, unknown> {
+12 -4
View File
@@ -30,19 +30,27 @@ export function buildAuthQuery(): { timestamp: number; client_id: string } {
}
/**
* Build the signature message (critical auth)
* Build the signature message (signed auth)
* Format: {sub_path}:{sorted_query_string}:{request_body}:{timestamp}
* sorted_query_string: all query params (including timestamp, client_id) sorted alphabetically by key
* sorted_query_string: all query params (including timestamp, client_id) sorted alphabetically by key.
* Array values are serialized as repeated k=v pairs (same as buildUrl / URLSearchParams), sorted by value.
*/
export function buildMessage(
subPath: string,
queryParams: Record<string, string | number>,
queryParams: Record<string, string | number | string[]>,
body: string,
timestamp: number
): string {
const sortedQs = Object.keys(queryParams)
.sort()
.map((k) => `${k}=${queryParams[k]}`)
.flatMap((k) => {
const ek = encodeURIComponent(k);
const v = queryParams[k];
if (Array.isArray(v)) {
return [...v].sort().map((item) => `${ek}=${encodeURIComponent(item)}`);
}
return [`${ek}=${encodeURIComponent(String(v))}`];
})
.join("&");
return `${subPath}:${sortedQs}:${body}:${timestamp}`;
}
+64 -5
View File
@@ -9,7 +9,7 @@ export function registerCookingCommands(program: Command): void {
cooking
.command("stats")
.description("Get token creation statistics by launchpad (normal auth)")
.description("Get token creation statistics by launchpad (exist auth)")
.option("--raw", "Output raw JSON")
.action(async (opts) => {
const client = new OpenApiClient(getConfig());
@@ -20,23 +20,56 @@ export function registerCookingCommands(program: Command): void {
cooking
.command("create")
.description("Create a token on a launchpad platform (requires private key)")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / ton")
.requiredOption("--dex <dex>", "Launchpad: pump / raydium / pancakeswap / flap / fourmeme / bonk / bags / ...")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--dex <dex>", "Launchpad: pump / bonk / bags (sol) / fourmeme / flap (bsc) / klik / clanker (base)")
.requiredOption("--from <address>", "Wallet address (must match API Key binding)")
.requiredOption("--name <name>", "Token name")
.requiredOption("--symbol <symbol>", "Token symbol")
.requiredOption("--buy-amt <amount>", "Initial buy amount in native token (e.g. 0.01 SOL)")
.option("--image <base64>", "Token logo as base64-encoded data (max 2MB decoded)")
.option("--image-url <url>", "Token logo URL")
.option("--description <text>", "Token description / project pitch")
.option("--website <url>", "Website URL")
.option("--twitter <url>", "Twitter link")
.option("--telegram <url>", "Telegram link")
.option("--slippage <n>", "Slippage tolerance (e.g. 0.01 = 1%)", parseFloat)
.option("--slippage <n>", "Slippage tolerance (e.g. 30 = 30%)", parseFloat)
.option("--auto-slippage", "Enable automatic slippage")
.option("--fee <amount>", "Base gas / fee")
.option("--priority-fee <sol>", "Priority fee in SOL (SOL only)")
.option("--tip-fee <amount>", "Tip fee")
.option("--gas-price <amount>", "Gas price in wei (EVM chains)")
.option("--anti-mev", "Enable anti-MEV protection")
.option("--max-fee-per-gas <amount>", "Max fee per gas in wei (EVM only)")
.option("--max-priority-fee-per-gas <amount>", "Max priority fee per gas in wei (EVM only)")
.option("--anti-mev", "Enable anti-MEV protection (SOL only)")
.option("--anti-mev-mode <mode>", "Anti-MEV mode: off / normal / secure (SOL only)")
.option("--raised-token <symbol>", "Raise token symbol: pump→USDC; bonk→USD1; fourmeme→USDT/USD1; leave empty for native")
.option("--dev-wallet-bps <n>", "Dev wallet fee in basis points (100 = 1%)", parseInt)
.option("--dev-gas <amount>", "Dev gas amount")
.option("--dev-priority <amount>", "Dev priority fee")
.option("--dev-tip <amount>", "Dev tip fee")
.option("--dev-max-fee-per-gas <amount>", "Dev tx feeCap in wei (EVM EIP-1559)")
.option("--approve-vision <version>", "Approve vision version: v1 / v2 (default: v2)")
.option("--source <source>", "Traffic source identifier")
// Pump.fun specific
.option("--is-mayhem", "Enable Mayhem mode (Pump.fun only)")
.option("--is-cashback", "Enable Cashback (Pump.fun only)")
.option("--is-buy-back", "Enable Agent Auto Buyback (Pump.fun only)")
.option("--pump-fee-share-list <json>", "Pump.fun fee share list as JSON array (Pump.fun only)")
// Flap specific
.option("--flap-rate-conf <json>", "Flap rate config as JSON object (Flap only)")
// FourMeme specific
.option("--fourmeme-rate-conf <json>", "FourMeme rate config as JSON object (FourMeme only)")
// BAGS specific
.option("--bags-fee-share-list <json>", "BAGS fee share list as JSON array (BAGS only)")
// Bonk specific
.option("--bonk-model <model>", "Bonk model identifier (bonk DEX only)")
// Multi-wallet buy
.option("--buy-wallets <json>", "Multi-wallet buy config as JSON array [{from_address, buy_amt}]")
.option("--snip-buy-wallets <json>", "Snipe-buy wallet config as JSON array [{from_address, buy_amt}]")
// CondMarket execution config + auto-sell (JSON)
.option("--buy-trade-config <json>", "Buy-side trade config for CondMarket orders as JSON (TradeParam)")
.option("--sell-trade-config <json>", "Sell-side trade config for auto-sell / pending_sell as JSON (TradeParam)")
.option("--sell-configs <json>", "Auto-sell strategy list as JSON array (CookingSellConfig[])")
.option("--raw", "Output raw JSON")
.action(async (opts) => {
if (!opts.image && !opts.imageUrl) {
@@ -58,15 +91,41 @@ export function registerCookingCommands(program: Command): void {
};
if (opts.image) params.image = opts.image;
if (opts.imageUrl) params.image_url = opts.imageUrl;
if (opts.description) params.description = opts.description;
if (opts.website) params.website = opts.website;
if (opts.twitter) params.twitter = opts.twitter;
if (opts.telegram) params.telegram = opts.telegram;
if (opts.slippage != null) params.slippage = opts.slippage;
if (opts.autoSlippage) params.auto_slippage = true;
if (opts.fee) params.fee = opts.fee;
if (opts.priorityFee) params.priority_fee = opts.priorityFee;
if (opts.tipFee) params.tip_fee = opts.tipFee;
if (opts.gasPrice) params.gas_price = opts.gasPrice;
if (opts.maxFeePerGas) params.max_fee_per_gas = opts.maxFeePerGas;
if (opts.maxPriorityFeePerGas) params.max_priority_fee_per_gas = opts.maxPriorityFeePerGas;
if (opts.antiMev) params.is_anti_mev = true;
if (opts.antiMevMode) params.anti_mev_mode = opts.antiMevMode;
if (opts.raisedToken != null) params.raised_token = opts.raisedToken;
if (opts.devWalletBps != null) params.dev_wallet_bps = opts.devWalletBps;
if (opts.devGas) params.dev_gas = opts.devGas;
if (opts.devPriority) params.dev_priority = opts.devPriority;
if (opts.devTip) params.dev_tip = opts.devTip;
if (opts.devMaxFeePerGas) params.dev_max_fee_per_gas = opts.devMaxFeePerGas;
if (opts.approveVision) params.approve_vision = opts.approveVision;
if (opts.source) params.source = opts.source;
if (opts.isMayhem) params.is_mayhem = true;
if (opts.isCashback) params.is_cashback = true;
if (opts.isBuyBack) params.is_buy_back = true;
if (opts.pumpFeeShareList) params.pump_fee_share_list = JSON.parse(opts.pumpFeeShareList);
if (opts.flapRateConf) params.flap_rate_conf = JSON.parse(opts.flapRateConf);
if (opts.fourmemeRateConf) params.fourmeme_rate_conf = JSON.parse(opts.fourmemeRateConf);
if (opts.bagsFeeShareList) params.bags_fee_share_list = JSON.parse(opts.bagsFeeShareList);
if (opts.bonkModel) params.bonk_model = opts.bonkModel;
if (opts.buyWallets) params.buy_wallets = JSON.parse(opts.buyWallets);
if (opts.snipBuyWallets) params.snip_buy_wallets = JSON.parse(opts.snipBuyWallets);
if (opts.buyTradeConfig) params.buy_trade_config = JSON.parse(opts.buyTradeConfig);
if (opts.sellTradeConfig) params.sell_trade_config = JSON.parse(opts.sellTradeConfig);
if (opts.sellConfigs) params.sell_configs = JSON.parse(opts.sellConfigs);
const client = new OpenApiClient(getConfig(true));
const data = await client.createToken(params).catch(exitOnError);
printResult(data, opts.raw);
+115 -26
View File
@@ -4,15 +4,31 @@ import { getConfig } from "../config.js";
import { exitOnError, printResult } from "../output.js";
import { validateAddress, validateChain } from "../validate.js";
// Parse token age string. If a unit suffix is present (s/m), use it as-is.
// Bare numbers (no unit) are treated as minutes with a warning.
function parseDuration(value: string): string {
if (/^\d+(\.\d+)?[sm]$/.test(value)) return value;
if (/^\d+(\.\d+)?$/.test(value)) {
console.warn(
`[gmgn-cli] Warning: no unit specified for duration "${value}" — treating as minutes (${value}m). Use a suffix to be explicit: ${value}s for seconds or ${value}m for minutes.`
);
return `${value}m`;
}
console.error(
`[gmgn-cli] Invalid duration "${value}". Use seconds (e.g. 30s) or minutes (e.g. 0.5m / 1m / 5m).`
);
process.exit(1);
}
export function registerMarketCommands(program: Command): void {
const market = program.command("market").description("Market data commands");
market
.command("kline")
.description("Get token K-line (candlestick) data")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.requiredOption("--address <address>", "Token contract address")
.requiredOption("--resolution <resolution>", "Candlestick resolution: 1m / 5m / 15m / 1h / 4h / 1d")
.requiredOption("--resolution <resolution>", "Candlestick resolution: 30s / 1m / 5m / 15m / 1h / 4h / 1d")
.option("--from <timestamp>", "Start time (Unix seconds)", parseInt)
.option("--to <timestamp>", "End time (Unix seconds)", parseInt)
.option("--raw", "Output raw JSON")
@@ -32,35 +48,55 @@ export function registerMarketCommands(program: Command): void {
printResult(data, opts.raw);
});
market
const trendingCmd = market
.command("trending")
.description("Get trending token swap data")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.requiredOption("--interval <interval>", "Time interval: 1m / 5m / 1h / 6h / 24h")
.option("--limit <n>", "Number of results (default 100, max 100)", parseInt)
.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. 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.direction) extra["direction"] = opts.direction;
if (opts.filter?.length) extra["filters"] = opts.filter;
if (opts.platform?.length) extra["platforms"] = opts.platform;
.option("--platform <name...>", "Platform filter, repeatable. sol: Pump.fun / letsbonk / moonshot_app / ... bsc: fourmeme / four_xmode_agent / cubepeg / likwid / goplus_creator / goplus_skills / openfour / flap / flap_stocks / flap_aioracle / clanker / ... base: clanker / flaunch / zora / ... eth: trench / clanker / klik / livo / stroid / pool_uniswap_v2 / pool_uniswap_v3 / printr (see docs for full list)")
.option("--raw", "Output raw JSON");
const client = new OpenApiClient(getConfig());
const data = await client.getTrendingSwaps(opts.chain, opts.interval, extra).catch(exitOnError);
printResult(data, opts.raw);
});
// Dynamically register all server-side min_*/max_* range filter flags
for (const def of RANK_RANGE_FIELDS) {
const flag = def.api.replace(/_/g, "-");
if (def.type === "int") {
trendingCmd.option(`--${flag} <${def.type}>`, def.desc, parseInt);
} else if (def.type === "float") {
trendingCmd.option(`--${flag} <${def.type}>`, def.desc, parseFloat);
} else {
trendingCmd.option(`--${flag} <value>`, def.desc);
}
}
trendingCmd.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.direction) extra["direction"] = opts.direction;
if (opts.filter?.length) extra["filters"] = opts.filter;
if (opts.platform?.length) extra["platforms"] = opts.platform;
// Apply server-side min_*/max_* range filters
const optsMap = opts as Record<string, unknown>;
for (const def of RANK_RANGE_FIELDS) {
const val = optsMap[apiFieldToCliKey(def.api)];
if (val != null) extra[def.api] = val as string | number;
}
const client = new OpenApiClient(getConfig());
const data = await client.getTrendingSwaps(opts.chain, opts.interval, extra).catch(exitOnError);
printResult(data, opts.raw);
});
const trenchesCmd = market
.command("trenches")
.description("Get Trenches token data (new creation, near completion, completed)")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.option("--type <type...>", "Categories to query, repeatable: new_creation / near_completion / completed (default: all three)")
.option("--launchpad-platform <platform...>", "Launchpad platform filter, repeatable (default: all platforms for the chain)")
.option("--limit <n>", "Max results per category, max 80 (default: 80)", parseInt)
@@ -76,6 +112,8 @@ export function registerMarketCommands(program: Command): void {
trenchesCmd.option(`--${flag} <${def.type}>`, def.desc, parseInt);
} else if (def.type === "float") {
trenchesCmd.option(`--${flag} <${def.type}>`, def.desc, parseFloat);
} else if (def.type === "duration") {
trenchesCmd.option(`--${flag} <duration>`, def.desc, parseDuration);
} else {
trenchesCmd.option(`--${flag} <value>`, def.desc);
}
@@ -169,7 +207,7 @@ export function registerMarketCommands(program: Command): void {
// ---- Trenches filter field definitions ----
type TrenchesFieldType = "int" | "float" | "string";
type TrenchesFieldType = "int" | "float" | "string" | "duration";
interface TrenchesFilterField {
api: string;
@@ -201,8 +239,8 @@ const TRENCHES_FILTER_FIELDS: TrenchesFilterField[] = [
{ api: "min_liquidity", type: "float", desc: "Min liquidity (USD)" },
{ api: "max_liquidity", type: "float", desc: "Max liquidity (USD)" },
// Token age
{ api: "min_created", type: "string", desc: "Min token age (e.g. 1m / 5m / 30m / 1h / 6h / 24h)" },
{ api: "max_created", type: "string", desc: "Max token age (e.g. 1m / 5m / 30m / 1h / 6h / 24h)" },
{ api: "min_created", type: "duration", desc: "Min token age — unit recommended: seconds (e.g. 30s) or minutes (e.g. 0.5m / 1m / 5m / 30m). Bare numbers treated as minutes." },
{ api: "max_created", type: "duration", desc: "Max token age — unit recommended: seconds (e.g. 30s) or minutes (e.g. 0.5m / 1m / 5m / 30m). Bare numbers treated as minutes." },
// Holders
{ api: "min_holder_count", type: "int", desc: "Min holder count" },
{ api: "max_holder_count", type: "int", desc: "Max holder count" },
@@ -252,6 +290,56 @@ const TRENCHES_FILTER_FIELDS: TrenchesFilterField[] = [
{ api: "max_tg_call_count", type: "int", desc: "Max Telegram call count" },
];
// Server-side numeric range filters for `market trending` (/v1/market/rank).
// Passed through as min_<metric>/max_<metric> query params; the service applies the
// metrics it understands and ignores the rest. min_created/max_created are token-age
// windows expressed as duration strings (e.g. 30m / 6h / 7d) — note these use m/h/d,
// NOT the s/m form used by trenches; min_created is a minimum age, max_created a maximum.
// The raw upstream rank interface accepts minutes only; the openapi-service does not
// forward this field — it evaluates the age window itself (cutoff = now - duration,
// native for m/h/d), so h/d are valid through this CLI. Passed through verbatim
// (string); a bare number with no unit suffix is rejected.
const RANK_RANGE_FIELDS: TrenchesFilterField[] = [
{ api: "min_volume", type: "float", desc: "Min trading volume (USD)" },
{ api: "max_volume", type: "float", desc: "Max trading volume (USD)" },
{ api: "min_liquidity", type: "float", desc: "Min liquidity (USD)" },
{ api: "max_liquidity", type: "float", desc: "Max liquidity (USD)" },
{ api: "min_marketcap", type: "float", desc: "Min market cap (USD)" },
{ api: "max_marketcap", type: "float", desc: "Max market cap (USD)" },
{ api: "min_history_highest_marketcap", type: "float", desc: "Min historical highest market cap (USD)" },
{ api: "max_history_highest_marketcap", type: "float", desc: "Max historical highest market cap (USD)" },
{ api: "min_swaps", type: "int", desc: "Min swap count" },
{ api: "max_swaps", type: "int", desc: "Max swap count" },
{ api: "min_holder_count", type: "int", desc: "Min holder count" },
{ api: "max_holder_count", type: "int", desc: "Max holder count" },
{ api: "min_gas_fee", type: "float", desc: "Min gas fee" },
{ api: "max_gas_fee", type: "float", desc: "Max gas fee" },
{ api: "min_renowned_count", type: "int", desc: "Min KOL / renowned wallet count" },
{ api: "max_renowned_count", type: "int", desc: "Max KOL / renowned wallet count" },
{ api: "min_smart_degen_count", type: "int", desc: "Min smart-money holder count" },
{ api: "max_smart_degen_count", type: "int", desc: "Max smart-money holder count" },
{ api: "min_bot_degen_count", type: "int", desc: "Min bot-degen wallet count" },
{ api: "max_bot_degen_count", type: "int", desc: "Max bot-degen wallet count" },
{ api: "min_visiting_count", type: "int", desc: "Min visitor count" },
{ api: "max_visiting_count", type: "int", desc: "Max visitor count" },
{ api: "min_price_change_percent", type: "float", desc: "Min price change ratio over the interval" },
{ api: "max_price_change_percent", type: "float", desc: "Max price change ratio over the interval" },
{ api: "min_insider_rate", type: "float", desc: "Min insider trading ratio (01); tokens lacking this field are excluded" },
{ api: "max_insider_rate", type: "float", desc: "Max insider trading ratio (01); tokens lacking this field are excluded" },
{ api: "min_bundler_rate", type: "float", desc: "Min bundle-bot trading ratio (01); tokens lacking this field are excluded" },
{ api: "max_bundler_rate", type: "float", desc: "Max bundle-bot trading ratio (01); tokens lacking this field are excluded" },
{ api: "min_entrapment_ratio", type: "float", desc: "Min entrapment trading ratio (01); tokens lacking this field are excluded" },
{ api: "max_entrapment_ratio", type: "float", desc: "Max entrapment trading ratio (01); tokens lacking this field are excluded" },
{ api: "min_top10_holder_rate", type: "float", desc: "Min top-10 holder concentration (01)" },
{ api: "max_top10_holder_rate", type: "float", desc: "Max top-10 holder concentration (01)" },
{ api: "min_top70_sniper_hold_rate", type: "float", desc: "Min top-70 sniper holding ratio (01)" },
{ api: "max_top70_sniper_hold_rate", type: "float", desc: "Max top-70 sniper holding ratio (01)" },
{ api: "min_dev_team_hold_rate", type: "float", desc: "Min dev-team holding ratio (01); also excludes creator-close tokens" },
{ api: "max_dev_team_hold_rate", type: "float", desc: "Max dev-team holding ratio (01)" },
{ api: "min_created", type: "string", desc: "Min token age (minimum age). Duration with unit suffix m/h/d, e.g. 30m / 6h / 7d (h/d evaluated server-side; raw upstream takes minutes only). A bare number with no unit is rejected." },
{ api: "max_created", type: "string", desc: "Max token age (maximum age). Duration with unit suffix m/h/d, e.g. 600m / 24h (h/d evaluated server-side; raw upstream takes minutes only). A bare number with no unit is rejected." },
];
// Named filter presets using actual server-side API field names
const TRENCHES_FILTER_PRESETS: Record<string, Record<string, number | string>> = {
safe: {
@@ -272,13 +360,14 @@ const TRENCHES_FILTER_PRESETS: Record<string, Record<string, number | string>> =
};
// Convert API snake_case field to Commander.js opts key
// Commander.js camelCase: only converts -[a-z] patterns, digits stay as-is
// e.g. min_volume_24h → min-volume-24h → minVolume-24h (digit prefix -24 is NOT converted)
// e.g. min_smart_degen_count → min-smart-degen-count → minSmartDegenCount (all letters, converts fully)
// Commander.js camelCase: converts -[a-z] to uppercase, and removes hyphen before digits
// e.g. min_volume_24h → min-volume-24h → minVolume-24h → minVolume24h
// e.g. min_smart_degen_count → min-smart-degen-count → minSmartDegenCount
function apiFieldToCliKey(apiField: string): string {
return apiField
.replace(/_/g, '-')
.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase());
.replace(/-([a-z])/g, (_, c: string) => c.toUpperCase())
.replace(/-(\d)/g, '$1');
}
// Client-side sort helpers (API does not support server-side sort for trenches)
+6 -6
View File
@@ -10,7 +10,7 @@ export function registerPortfolioCommands(program: Command): void {
portfolio
.command("holdings")
.description("Get wallet token holdings")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.requiredOption("--wallet <address>", "Wallet address")
.option("--limit <n>", "Page size (default 20, max 50)", parseInt, 20)
.option("--cursor <cursor>", "Pagination cursor")
@@ -46,12 +46,12 @@ export function registerPortfolioCommands(program: Command): void {
portfolio
.command("activity")
.description("Get wallet transaction activity")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.requiredOption("--wallet <address>", "Wallet address")
.option("--token <address>", "Filter by token contract address")
.option("--limit <n>", "Page size", parseInt)
.option("--cursor <cursor>", "Pagination cursor")
.option("--type <type...>", "Activity type filter, repeatable: buy / sell / add / remove / transfer")
.option("--type <type...>", "Activity type filter, repeatable: buy / sell / transferIn / transferOut / add / remove")
.option("--raw", "Output raw JSON")
.action(async (opts) => {
validateChain(opts.chain);
@@ -71,7 +71,7 @@ export function registerPortfolioCommands(program: Command): void {
portfolio
.command("stats")
.description("Get wallet trading statistics (supports multiple wallets)")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.requiredOption("--wallet <address...>", "Wallet address(es), repeatable")
.option("--period <period>", "Stats period: 7d / 30d", "7d")
.option("--raw", "Output raw JSON")
@@ -96,7 +96,7 @@ export function registerPortfolioCommands(program: Command): void {
portfolio
.command("token-balance")
.description("Get wallet token balance for a single token")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.requiredOption("--wallet <address>", "Wallet address")
.requiredOption("--token <address>", "Token contract address")
.option("--raw", "Output raw JSON")
@@ -112,7 +112,7 @@ export function registerPortfolioCommands(program: Command): void {
portfolio
.command("created-tokens")
.description("Get tokens created by a developer wallet")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.requiredOption("--wallet <address>", "Developer wallet address")
.option("--order-by <field>", "Sort field: market_cap / token_ath_mc")
.option("--direction <dir>", "Sort direction: asc / desc")
+127 -87
View File
@@ -8,22 +8,23 @@ export function registerSwapCommands(program: Command): void {
program
.command("swap")
.description("Submit a token swap")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth ")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.requiredOption("--from <address>", "Wallet address (must match API Key binding)")
.requiredOption("--input-token <address>", "Input token contract address")
.requiredOption("--output-token <address>", "Output token contract address")
.option("--amount <amount>", "Input raw amount (smallest unit)")
.option("--percent <pct>", "Input amount as a percentage, e.g. 50 = 50%, 1 = 1%; only valid when input_token is NOT a currency", parseFloat)
.option("--slippage <n>", "Slippage tolerance (e.g. 0.01 = 1%)", parseFloat)
.option("--slippage <n>", "Slippage tolerance (e.g. 30 = 30%)", parseFloat)
.option("--auto-slippage", "Enable automatic slippage")
.option("--min-output <amount>", "Minimum output amount")
.option("--anti-mev", "Enable anti-MEV protection, default true")
.option("--priority-fee <sol>", "Priority fee in SOL (≥ 0.00001, SOL only)")
.option("--tip-fee <amount>", "Tip fee (SOL ≥ 0.00001 SOL / BSC ≥ 0.000001 BNB)")
.option("--max-auto-fee <amount>", "Max auto fee cap")
.option("--gas-price <gwei>", "Gas price in gwei (BSC ≥ 0.05 / BASE/ETH ≥ 0.01)")
.option("--max-fee-per-gas <amount>", "EIP-1559 max fee per gas (Base)")
.option("--max-priority-fee-per-gas <amount>", "EIP-1559 max priority fee per gas (Base)")
.option("--gas-price <gwei>", "Gas price in gwei (BSC ≥ 0.05 / BASE/ETH ≥ 0.01); mutually exclusive with --gas-level")
.option("--gas-level <level>", "Gas price tier (eth only): low / average / high; mutually exclusive with --gas-price")
.option("--auto-fee", "Auto fee mode (eth only); delegates fee selection to trading bot for condition_orders strategy")
.option("--max-fee-per-gas <amount>", "EIP-1559 max fee per gas (BSC / BASE / ETH)")
.option("--max-priority-fee-per-gas <amount>", "EIP-1559 max priority fee per gas (BSC / BASE / ETH)")
.option("--condition-orders <json>", 'JSON array of take-profit/stop-loss conditions, e.g. \'[{"order_type":"profit_stop","side":"sell","price_scale":"150","sell_ratio":"100"}]\'; trace types: \'[{"order_type":"profit_stop_trace","side":"sell","price_scale":"150","sell_ratio":"100","drawdown_rate":"50"}]\'')
.option("--sell-ratio-type <type>", "Sell ratio base: buy_amount (default) / hold_amount; only used with --condition-orders")
.option("--raw", "Output raw JSON")
@@ -40,7 +41,7 @@ export function registerSwapCommands(program: Command): void {
if (opts.percent != null) validatePercent(opts.percent);
const params: SwapParams = {
chain: opts.chain,
from_address: opts.from,
from_address: opts.chain === "sol" ? opts.from : opts.from.toLowerCase(),
input_token: opts.inputToken,
output_token: opts.outputToken,
input_amount: opts.percent != null ? (opts.amount ?? "0") : opts.amount,
@@ -52,8 +53,9 @@ export function registerSwapCommands(program: Command): void {
if (opts.antiMev) params.is_anti_mev = true;
if (opts.priorityFee) params.priority_fee = opts.priorityFee;
if (opts.tipFee) params.tip_fee = opts.tipFee;
if (opts.maxAutoFee) params.max_auto_fee = opts.maxAutoFee;
if (opts.autoFee) params.auto_fee = true;
if (opts.gasPrice) params.gas_price = String(Math.round(parseFloat(opts.gasPrice) * 1e9));
if (opts.gasLevel) params.gas_level = opts.gasLevel;
if (opts.maxFeePerGas) params.max_fee_per_gas = opts.maxFeePerGas;
if (opts.maxPriorityFeePerGas) params.max_priority_fee_per_gas = opts.maxPriorityFeePerGas;
if (opts.conditionOrders) {
@@ -71,17 +73,89 @@ export function registerSwapCommands(program: Command): void {
printResult(data, opts.raw);
});
program
.command("multi-swap")
.description("Submit token swaps across multiple wallets concurrently (up to 100 wallets)")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.requiredOption("--accounts <addresses>", "Comma-separated wallet addresses (all must be bound to the API Key)")
.requiredOption("--input-token <address>", "Input token contract address")
.requiredOption("--output-token <address>", "Output token contract address")
.option("--input-amount <json>", 'JSON map of wallet→amount (smallest unit), e.g. \'{"addr1":"1000000","addr2":"2000000"}\'')
.option("--input-amount-bps <json>", 'JSON map of wallet→percent in bps (110000, e.g. 5000=50%), e.g. \'{"addr1":"5000"}\'')
.option("--output-amount <json>", "JSON map of wallet→target output amount")
.option("--slippage <n>", "Slippage tolerance (e.g. 30 = 30%)", parseFloat)
.option("--auto-slippage", "Enable automatic slippage")
.option("--anti-mev", "Enable anti-MEV protection")
.option("--priority-fee <sol>", "Priority fee in SOL (SOL only, ≥ 0.00001)")
.option("--tip-fee <amount>", "Tip fee (SOL ≥ 0.00001 / BSC ≥ 0.000001 BNB)")
.option("--gas-price <gwei>", "Gas price in gwei (BSC ≥ 0.05 / BASE/ETH ≥ 0.01); mutually exclusive with --gas-level")
.option("--gas-level <level>", "Gas price tier (eth only): low / average / high; mutually exclusive with --gas-price")
.option("--auto-fee", "Auto fee mode (eth only); delegates fee selection to trading bot for condition_orders strategy")
.option("--max-fee-per-gas <amount>", "EIP-1559 max fee per gas (BSC / BASE / ETH)")
.option("--max-priority-fee-per-gas <amount>", "EIP-1559 max priority fee per gas (BSC / BASE / ETH)")
.option("--condition-orders <json>", "JSON array of take-profit/stop-loss conditions attached to each successful wallet's swap")
.option("--sell-ratio-type <type>", "Sell ratio base: buy_amount (default) / hold_amount; only used with --condition-orders")
.option("--raw", "Output raw JSON")
.action(async (opts) => {
if (!opts.inputAmount && !opts.inputAmountBps && !opts.outputAmount) {
console.error("[gmgn-cli] At least one of --input-amount, --input-amount-bps, or --output-amount must be provided");
process.exit(1);
}
validateChain(opts.chain);
const accounts = (opts.accounts as string).split(",").map((a: string) => a.trim()).filter(Boolean);
if (accounts.length === 0 || accounts.length > 100) {
console.error("[gmgn-cli] --accounts must be 1100 comma-separated wallet addresses");
process.exit(1);
}
const params: MultiSwapParams = {
chain: opts.chain,
accounts: opts.chain === "sol" ? accounts : accounts.map((a: string) => a.toLowerCase()),
input_token: opts.inputToken,
output_token: opts.outputToken,
};
if (opts.inputAmount) {
try { params.input_amount = JSON.parse(opts.inputAmount); }
catch { console.error("[gmgn-cli] --input-amount must be valid JSON"); process.exit(1); }
}
if (opts.inputAmountBps) {
try { params.input_amount_bps = JSON.parse(opts.inputAmountBps); }
catch { console.error("[gmgn-cli] --input-amount-bps must be valid JSON"); process.exit(1); }
}
if (opts.outputAmount) {
try { params.output_amount = JSON.parse(opts.outputAmount); }
catch { console.error("[gmgn-cli] --output-amount must be valid JSON"); process.exit(1); }
}
if (opts.slippage != null) params.slippage = opts.slippage;
if (opts.autoSlippage) params.auto_slippage = true;
if (opts.antiMev) params.is_anti_mev = true;
if (opts.priorityFee) params.priority_fee = opts.priorityFee;
if (opts.tipFee) params.tip_fee = opts.tipFee;
if (opts.autoFee) params.auto_fee = true;
if (opts.gasPrice) params.gas_price = String(Math.round(parseFloat(opts.gasPrice) * 1e9));
if (opts.gasLevel) params.gas_level = opts.gasLevel;
if (opts.maxFeePerGas) params.max_fee_per_gas = opts.maxFeePerGas;
if (opts.maxPriorityFeePerGas) params.max_priority_fee_per_gas = opts.maxPriorityFeePerGas;
if (opts.conditionOrders) {
try { params.condition_orders = JSON.parse(opts.conditionOrders); }
catch { console.error("[gmgn-cli] --condition-orders must be valid JSON"); process.exit(1); }
}
if (opts.sellRatioType) params.sell_ratio_type = opts.sellRatioType;
const client = new OpenApiClient(getConfig(true));
const data = await client.multiSwap(params).catch(exitOnError);
printResult(data, opts.raw);
});
const order = program.command("order").description("Order management commands");
order
.command("quote")
.description("Get a swap quote without submitting a transaction (requires critical auth)")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base (requires GMGN_PRIVATE_KEY)")
.requiredOption("--from <address>", "Wallet address (must match API Key binding)")
.description("Get a swap quote without submitting a transaction (exist auth — GMGN_API_KEY only, no private key needed)")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.requiredOption("--from <address>", "Wallet address")
.requiredOption("--input-token <address>", "Input token contract address")
.requiredOption("--output-token <address>", "Output token contract address")
.requiredOption("--amount <amount>", "Input amount (smallest unit)")
.requiredOption("--slippage <n>", "Slippage tolerance (e.g. 0.01 = 1%)", parseFloat)
.requiredOption("--slippage <n>", "Slippage tolerance (e.g. 30 = 30%)", parseFloat)
.option("--raw", "Output raw JSON")
.action(async (opts) => {
validateChain(opts.chain);
@@ -110,74 +184,13 @@ export function registerSwapCommands(program: Command): void {
});
program
.command("multi-swap")
.description("Submit token swaps across multiple wallets concurrently (up to 100 wallets)")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--accounts <addresses>", "Comma-separated wallet addresses (all must be bound to the API Key)")
.requiredOption("--input-token <address>", "Input token contract address")
.requiredOption("--output-token <address>", "Output token contract address")
.option("--input-amount <json>", 'JSON map of wallet→amount (smallest unit), e.g. \'{"addr1":"1000000","addr2":"2000000"}\'')
.option("--input-amount-bps <json>", 'JSON map of wallet→percent in bps (110000, e.g. 5000=50%), e.g. \'{"addr1":"5000"}\'')
.option("--output-amount <json>", "JSON map of wallet→target output amount")
.option("--slippage <n>", "Slippage tolerance (e.g. 0.01 = 1%)", parseFloat)
.option("--auto-slippage", "Enable automatic slippage")
.option("--anti-mev", "Enable anti-MEV protection")
.option("--priority-fee <sol>", "Priority fee in SOL (SOL only, ≥ 0.00001)")
.option("--tip-fee <amount>", "Tip fee (SOL ≥ 0.00001 / BSC ≥ 0.000001 BNB)")
.option("--auto-tip-fee", "Enable automatic tip fee")
.option("--max-auto-fee <amount>", "Max auto fee cap")
.option("--gas-price <gwei>", "Gas price in gwei (BSC ≥ 0.05 / BASE/ETH ≥ 0.01)")
.option("--max-fee-per-gas <amount>", "EIP-1559 max fee per gas (Base only)")
.option("--max-priority-fee-per-gas <amount>", "EIP-1559 max priority fee per gas (Base only)")
.option("--condition-orders <json>", "JSON array of take-profit/stop-loss conditions attached to each successful wallet's swap")
.option("--sell-ratio-type <type>", "Sell ratio base: buy_amount (default) / hold_amount; only used with --condition-orders")
.command("gas-price")
.description("Query recommended gas price tiers for any chain (exist auth — API Key only; eth / bsc / base / sol)")
.requiredOption("--chain <chain>", "Chain: eth / bsc / base / sol")
.option("--raw", "Output raw JSON")
.action(async (opts) => {
if (!opts.inputAmount && !opts.inputAmountBps && !opts.outputAmount) {
console.error("[gmgn-cli] At least one of --input-amount, --input-amount-bps, or --output-amount must be provided");
process.exit(1);
}
validateChain(opts.chain);
const accounts = (opts.accounts as string).split(",").map((a: string) => a.trim()).filter(Boolean);
if (accounts.length === 0 || accounts.length > 100) {
console.error("[gmgn-cli] --accounts must be 1100 comma-separated wallet addresses");
process.exit(1);
}
const params: MultiSwapParams = {
chain: opts.chain,
accounts,
input_token: opts.inputToken,
output_token: opts.outputToken,
};
if (opts.inputAmount) {
try { params.input_amount = JSON.parse(opts.inputAmount); }
catch { console.error("[gmgn-cli] --input-amount must be valid JSON"); process.exit(1); }
}
if (opts.inputAmountBps) {
try { params.input_amount_bps = JSON.parse(opts.inputAmountBps); }
catch { console.error("[gmgn-cli] --input-amount-bps must be valid JSON"); process.exit(1); }
}
if (opts.outputAmount) {
try { params.output_amount = JSON.parse(opts.outputAmount); }
catch { console.error("[gmgn-cli] --output-amount must be valid JSON"); process.exit(1); }
}
if (opts.slippage != null) params.slippage = opts.slippage;
if (opts.autoSlippage) params.auto_slippage = true;
if (opts.antiMev) params.is_anti_mev = true;
if (opts.priorityFee) params.priority_fee = opts.priorityFee;
if (opts.tipFee) params.tip_fee = opts.tipFee;
if (opts.autoTipFee) params.auto_tip_fee = true;
if (opts.maxAutoFee) params.max_auto_fee = opts.maxAutoFee;
if (opts.gasPrice) params.gas_price = String(Math.round(parseFloat(opts.gasPrice) * 1e9));
if (opts.maxFeePerGas) params.max_fee_per_gas = opts.maxFeePerGas;
if (opts.maxPriorityFeePerGas) params.max_priority_fee_per_gas = opts.maxPriorityFeePerGas;
if (opts.conditionOrders) {
try { params.condition_orders = JSON.parse(opts.conditionOrders); }
catch { console.error("[gmgn-cli] --condition-orders must be valid JSON"); process.exit(1); }
}
if (opts.sellRatioType) params.sell_ratio_type = opts.sellRatioType;
const client = new OpenApiClient(getConfig(true));
const data = await client.multiSwap(params).catch(exitOnError);
const client = new OpenApiClient(getConfig(false));
const data = await client.getGasPrice(opts.chain).catch(exitOnError);
printResult(data, opts.raw);
});
@@ -186,24 +199,33 @@ export function registerSwapCommands(program: Command): void {
strategy
.command("create")
.description("Create a limit/strategy order (requires private key)")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.requiredOption("--from <address>", "Wallet address (must match API Key binding)")
.requiredOption("--base-token <address>", "Base token contract address")
.requiredOption("--quote-token <address>", "Quote token contract address")
.requiredOption("--order-type <type>", "Order type: limit_order")
.requiredOption("--sub-order-type <type>", "Sub-order type: buy_low / buy_high / stop_loss / take_profit")
.requiredOption("--check-price <price>", "Trigger check price")
.requiredOption("--order-type <type>", "Order type: limit_order / smart_trade")
.requiredOption("--sub-order-type <type>", "Sub-order type: buy_low / buy_high / stop_loss / take_profit (limit_order); mix_trade (smart_trade with condition_orders)")
.option("--check-price <price>", "Trigger check price (required for limit_order; omit for smart_trade)")
.option("--open-price <price>", "Open price of the position")
.option("--amount-in <amount>", "Input amount (smallest unit)")
.option("--amount-in-percent <pct>", "Input amount as a percentage (e.g. 50 = 50%)")
.option("--limit-price-mode <mode>", "Price mode: exact / slippage (default: slippage)")
.option("--expire-in <seconds>", "Order expiry in seconds", parseInt)
.option("--sell-ratio-type <type>", "Sell ratio basis: buy_amount (default) / hold_amount")
.option("--slippage <n>", "Slippage tolerance (e.g. 0.01 = 1%)", parseFloat)
.option("--quote-investment <amount>", "Quote token investment amount (smart_trade)")
.option("--slippage <n>", "Slippage tolerance (e.g. 30 = 30%)", parseFloat)
.option("--auto-slippage", "Enable automatic slippage")
.option("--priority-fee <sol>", "Priority fee in SOL (required for SOL chain)")
.option("--tip-fee <amount>", "Tip fee (required for SOL chain)")
.option("--gas-price <gwei>", "Gas price in gwei (required for BSC; ≥ 0.05 gwei / BASE/ETH ≥ 0.01 gwei)")
.option("--auto-fee", "Auto fee mode (eth only); delegates fee selection to trading bot")
.option("--gas-price <gwei>", "Gas price in gwei (BSC ≥ 0.05 / BASE/ETH ≥ 0.01 gwei); mutually exclusive with --gas-level")
.option("--gas-level <level>", "Gas price tier (eth only): low / average / high; mutually exclusive with --gas-price")
.option("--max-fee-per-gas <amount>", "EIP-1559 max fee per gas (BSC / BASE / ETH)")
.option("--max-priority-fee-per-gas <amount>", "EIP-1559 max priority fee per gas (BSC / BASE / ETH)")
.option("--anti-mev", "Enable anti-MEV protection")
.option("--condition-orders <json>", "JSON array of condition sub-orders for smart_trade (must include a buy_low entry + TP/SL entries)")
.option("--sell-param <json>", "JSON object of sell-side trade params used when a TP/SL condition fires (required for smart_trade)")
.option("--buy-param <json>", "JSON object of buy-side trade params override for smart_trade")
.option("--raw", "Output raw JSON")
.action(async (opts) => {
if (!opts.amountIn && !opts.amountInPercent) {
@@ -222,19 +244,37 @@ export function registerSwapCommands(program: Command): void {
quote_token: opts.quoteToken,
order_type: opts.orderType,
sub_order_type: opts.subOrderType,
check_price: opts.checkPrice,
};
if (opts.checkPrice) params.check_price = opts.checkPrice;
if (opts.openPrice) params.open_price = opts.openPrice;
if (opts.amountIn) params.amount_in = opts.amountIn;
if (opts.amountInPercent) params.amount_in_percent = opts.amountInPercent;
if (opts.limitPriceMode) params.limit_price_mode = opts.limitPriceMode;
if (opts.expireIn != null) params.expire_in = opts.expireIn;
if (opts.sellRatioType) params.sell_ratio_type = opts.sellRatioType;
if (opts.quoteInvestment) params.quote_investment = opts.quoteInvestment;
if (opts.slippage != null) params.slippage = opts.slippage;
if (opts.autoSlippage) params.auto_slippage = true;
if (opts.priorityFee) params.priority_fee = opts.priorityFee;
if (opts.tipFee) params.tip_fee = opts.tipFee;
if (opts.autoFee) params.auto_fee = true;
if (opts.gasPrice) params.gas_price = String(Math.round(parseFloat(opts.gasPrice) * 1e9));
if (opts.gasLevel) params.gas_level = opts.gasLevel;
if (opts.maxFeePerGas) params.max_fee_per_gas = opts.maxFeePerGas;
if (opts.maxPriorityFeePerGas) params.max_priority_fee_per_gas = opts.maxPriorityFeePerGas;
if (opts.antiMev) params.is_anti_mev = true;
if (opts.conditionOrders) {
try { params.condition_orders = JSON.parse(opts.conditionOrders); }
catch { console.error("[gmgn-cli] --condition-orders must be valid JSON"); process.exit(1); }
}
if (opts.sellParam) {
try { params.sell_param = JSON.parse(opts.sellParam); }
catch { console.error("[gmgn-cli] --sell-param must be valid JSON"); process.exit(1); }
}
if (opts.buyParam) {
try { params.buy_param = JSON.parse(opts.buyParam); }
catch { console.error("[gmgn-cli] --buy-param must be valid JSON"); process.exit(1); }
}
const client = new OpenApiClient(getConfig(true));
const data = await client.createStrategyOrder(params).catch(exitOnError);
printResult(data, opts.raw);
@@ -243,7 +283,7 @@ export function registerSwapCommands(program: Command): void {
strategy
.command("list")
.description("List strategy orders (requires private key)")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.option("--type <type>", "open (default) / history")
.option("--from <address>", "Filter by wallet address")
.option("--group-tag <tag>", "Filter by group: LimitOrder / STMix")
@@ -268,7 +308,7 @@ export function registerSwapCommands(program: Command): void {
strategy
.command("cancel")
.description("Cancel a strategy order (requires private key)")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.requiredOption("--from <address>", "Wallet address (must match API Key binding)")
.requiredOption("--order-id <id>", "Order ID to cancel")
.option("--order-type <type>", "Order type: limit_order / smart_trade")
+7 -7
View File
@@ -10,7 +10,7 @@ export function registerTokenCommands(program: Command): void {
token
.command("info")
.description("Get token basic information and realtime price")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.requiredOption("--address <address>", "Token contract address")
.option("--raw", "Output raw JSON")
.action(async (opts) => {
@@ -24,7 +24,7 @@ export function registerTokenCommands(program: Command): void {
token
.command("security")
.description("Get token security metrics")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.requiredOption("--address <address>", "Token contract address")
.option("--raw", "Output raw JSON")
.action(async (opts) => {
@@ -38,7 +38,7 @@ export function registerTokenCommands(program: Command): void {
token
.command("pool")
.description("Get token liquidity pool information")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.requiredOption("--address <address>", "Token contract address")
.option("--raw", "Output raw JSON")
.action(async (opts) => {
@@ -52,12 +52,12 @@ export function registerTokenCommands(program: Command): void {
token
.command("holders")
.description("Get top token holders")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.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")
.option("--tag <tag>", "Wallet tag filter: smart_degen / renowned / fresh_wallet / dev / sniper / rat_trader / bundler / transfer_in / dex_bot / bluechip_owner")
.option("--raw", "Output raw JSON")
.action(async (opts) => {
validateChain(opts.chain);
@@ -75,12 +75,12 @@ export function registerTokenCommands(program: Command): void {
token
.command("traders")
.description("Get top token traders")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.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")
.option("--tag <tag>", "Wallet tag filter: smart_degen / renowned / fresh_wallet / dev / sniper / rat_trader / bundler / transfer_in / dex_bot / bluechip_owner")
.option("--raw", "Output raw JSON")
.action(async (opts) => {
validateChain(opts.chain);
+44 -3
View File
@@ -7,10 +7,51 @@ import { validateChain } from "../validate.js";
export function registerTrackCommands(program: Command): void {
const track = program.command("track").description("On-chain tracking commands: follow-wallet trades, KOL trades, Smart Money trades");
track
.command("follow-tokens")
.description("Get the followed token list for a wallet on a given chain")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.requiredOption("--wallet <address>", "Wallet address")
.option("--group-id <id>", "Filter by group: all_group (all), default, or a user-defined group ID")
.option("--interval <interval>", "Time interval for price change stats (e.g. 1m, 5m, 1h, 6h, 24h)")
.option("--order-by <field>", "Sort field: created_at / swaps / volume / market_cap / liquidity / price / open_timestamp")
.option("--direction <dir>", "Sort direction: asc / desc")
.option("--limit <n>", "Page size", parseInt)
.option("--cursor <cursor>", "Pagination cursor")
.option("--search <text>", "Search by token name or address")
.option("--raw", "Output raw JSON")
.action(async (opts) => {
validateChain(opts.chain);
const extra: Record<string, string | number> = {};
if (opts.groupId) extra["group_id"] = opts.groupId;
if (opts.interval) extra["interval"] = opts.interval;
if (opts.orderBy) extra["order_by"] = opts.orderBy;
if (opts.direction) extra["direction"] = opts.direction;
if (opts.limit != null) extra["limit"] = opts.limit;
if (opts.cursor) extra["cursor"] = opts.cursor;
if (opts.search) extra["search_text"] = opts.search;
const client = new OpenApiClient(getConfig());
const data = await client.getFollowTokens(opts.chain, opts.wallet, extra).catch(exitOnError);
printResult(data, opts.raw);
});
track
.command("follow-token-groups")
.description("Get the follow token group names for a wallet on a given chain")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.requiredOption("--wallet <address>", "Wallet address")
.option("--raw", "Output raw JSON")
.action(async (opts) => {
validateChain(opts.chain);
const client = new OpenApiClient(getConfig());
const data = await client.getFollowGroupNames(opts.chain, opts.wallet).catch(exitOnError);
printResult(data, opts.raw);
});
track
.command("follow-wallet")
.description("Get follow-wallet trade records")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.option("--wallet <address>", "Filter by wallet address")
.option("--limit <n>", "Page size (1100, default 10)", parseInt)
.option("--side <side>", "Trade direction filter: buy / sell")
@@ -35,7 +76,7 @@ export function registerTrackCommands(program: Command): void {
track
.command("kol")
.description("Get KOL trade records")
.option("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.option("--limit <n>", "Page size (1200, default 100)", parseInt)
.option("--side <side>", "Filter by trade direction: buy / sell (client-side filter)")
.option("--raw", "Output raw JSON")
@@ -52,7 +93,7 @@ export function registerTrackCommands(program: Command): void {
track
.command("smartmoney")
.description("Get Smart Money trade records")
.option("--chain <chain>", "Chain: sol / bsc / base")
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
.option("--limit <n>", "Page size (1200, default 100)", parseInt)
.option("--side <side>", "Filter by trade direction: buy / sell (client-side filter)")
.option("--raw", "Output raw JSON")
+5 -5
View File
@@ -3,9 +3,9 @@ import { homedir } from "os";
import { join } from "path";
// Load global config first (~/.config/gmgn/.env), then project .env (project takes precedence)
loadDotenv({ path: join(homedir(), ".config", "gmgn", ".env") });
loadDotenv({ override: true });
// Load global config first (~/.config/gmgn/.env, takes precedence), then project .env (supplements only)
loadDotenv({ path: join(homedir(), ".config", "gmgn", ".env"), override: true });
loadDotenv();
export interface Config {
apiKey: string;
@@ -15,7 +15,7 @@ export interface Config {
let _config: Config | null = null;
const PRIVATE_KEY_REQUIRED_MSG =
"GMGN_PRIVATE_KEY is required for critical-auth commands (swap and all order commands)";
"GMGN_PRIVATE_KEY is required for critical-auth commands (swap, order, and follow-wallet commands)";
export function getConfig(requirePrivateKey = false): Config {
if (_config) {
@@ -39,7 +39,7 @@ export function getConfig(requirePrivateKey = false): Config {
die(PRIVATE_KEY_REQUIRED_MSG);
}
const host = process.env.GMGN_HOST ?? "https://openapi.gmgn.ai";
const host = "https://openapi.gmgn.ai";
_config = { apiKey: apiKey!, privateKeyPem, host };
return _config;
}