mirror of
https://github.com/GMGNAI/gmgn-skills.git
synced 2026-07-27 16:57:44 +00:00
feat(chain): add robinhood support; disable monad/megaeth/hyperevm/tron
Add robinhood as a supported chain across the CLI and skills, and stop advertising chains that are not publicly supported yet. robinhood: - validate.ts: add to VALID_CHAINS and treat as EVM for address checks - reject guards for commands that do not support it: track kol, track smartmoney, cooking create (mirrors market signal) - --chain help updated for supported commands (token/portfolio/swap/ market kline·trending·trenches·hot-searches/track follow-*/order get/ gas-price); OpenApiClient chain comment - docs: all SKILL.md, Readme.md, Readme.zh.md (split-out row for unsupported commands), cli-usage.md, plugin/marketplace descriptions disable monad/megaeth/hyperevm/tron: - comment monad out of VALID_CHAINS (kept for quick re-enable) - strip these chains from all --chain help, SKILL.md, cli-usage.md (hot-searches default now 4 chains: sol/bsc/base/eth) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -187,7 +187,7 @@ export interface TokenSignalGroup {
|
||||
export interface HotSearchesParam {
|
||||
label?: string;
|
||||
interval: string; // "1m" | "5m" | "1h" | "6h" | "24h"
|
||||
chain: string; // "sol" | "bsc" | "base" | "eth" | "monad" | "megaeth" | "hyperevm" | "tron"
|
||||
chain: string; // "sol" | "bsc" | "base" | "eth" | "robinhood"
|
||||
filters?: string[];
|
||||
limit?: number;
|
||||
[key: string]: string[] | number | string | undefined;
|
||||
|
||||
@@ -81,6 +81,10 @@ export function registerCookingCommands(program: Command): void {
|
||||
process.exit(1);
|
||||
}
|
||||
validateChain(opts.chain);
|
||||
if (opts.chain === "robinhood") {
|
||||
console.error(`[gmgn-cli] cooking create does not support robinhood, got "${opts.chain}"`);
|
||||
process.exit(1);
|
||||
}
|
||||
const params: CreateTokenParams = {
|
||||
chain: opts.chain,
|
||||
dex: opts.dex,
|
||||
|
||||
@@ -26,7 +26,7 @@ export function registerMarketCommands(program: Command): void {
|
||||
market
|
||||
.command("kline")
|
||||
.description("Get token K-line (candlestick) data")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.requiredOption("--address <address>", "Token contract address")
|
||||
.requiredOption("--resolution <resolution>", "Candlestick resolution: 30s / 1m / 5m / 15m / 1h / 4h / 1d")
|
||||
.option("--from <timestamp>", "Start time (Unix seconds)", parseInt)
|
||||
@@ -51,7 +51,7 @@ export function registerMarketCommands(program: Command): void {
|
||||
const trendingCmd = market
|
||||
.command("trending")
|
||||
.description("Get trending token swap data")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.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)")
|
||||
@@ -96,7 +96,7 @@ export function registerMarketCommands(program: Command): void {
|
||||
const trenchesCmd = market
|
||||
.command("trenches")
|
||||
.description("Get Trenches token data (new creation, near completion, completed)")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.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)
|
||||
@@ -207,7 +207,7 @@ export function registerMarketCommands(program: Command): void {
|
||||
const hotSearchesCmd = market
|
||||
.command("hot-searches")
|
||||
.description("Get the hot-search ranking (most-searched tokens) for one or more chains")
|
||||
.option("--chain <chain...>", "Chain(s), repeatable: sol / bsc / base / eth / monad / megaeth / hyperevm / tron (default: all 7 chains)")
|
||||
.option("--chain <chain...>", "Chain(s), repeatable: sol / bsc / base / eth / robinhood (default: all default chains)")
|
||||
.option("--interval <interval>", "Time window: 1m / 5m / 1h / 6h / 24h (default 24h)", "24h")
|
||||
.option("--limit <n>", "Max results per chain (default 500)", parseInt)
|
||||
.option("--filter <tag...>", "Boolean filter tags, repeatable. sol defaults: renounced / frozen; EVM defaults: not_honeypot / verified / renounced")
|
||||
|
||||
@@ -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 / eth")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.requiredOption("--wallet <address>", "Wallet address")
|
||||
.option("--limit <n>", "Page size (default 20, max 50)", parseInt, 20)
|
||||
.option("--cursor <cursor>", "Pagination cursor")
|
||||
@@ -46,7 +46,7 @@ export function registerPortfolioCommands(program: Command): void {
|
||||
portfolio
|
||||
.command("activity")
|
||||
.description("Get wallet transaction activity")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.requiredOption("--wallet <address>", "Wallet address")
|
||||
.option("--token <address>", "Filter by token contract address")
|
||||
.option("--limit <n>", "Page size", parseInt)
|
||||
@@ -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 / eth")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.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 / eth")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.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 / eth")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.requiredOption("--wallet <address>", "Developer wallet address")
|
||||
.option("--order-by <field>", "Sort field: market_cap / token_ath_mc")
|
||||
.option("--direction <dir>", "Sort direction: asc / desc")
|
||||
|
||||
@@ -8,7 +8,7 @@ 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 / robinhood")
|
||||
.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")
|
||||
@@ -76,7 +76,7 @@ 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 / eth")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.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")
|
||||
@@ -150,7 +150,7 @@ export function registerSwapCommands(program: Command): void {
|
||||
order
|
||||
.command("quote")
|
||||
.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("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.requiredOption("--from <address>", "Wallet address")
|
||||
.requiredOption("--input-token <address>", "Input token contract address")
|
||||
.requiredOption("--output-token <address>", "Output token contract address")
|
||||
@@ -173,7 +173,7 @@ export function registerSwapCommands(program: Command): void {
|
||||
order
|
||||
.command("get")
|
||||
.description("Query order status (requires private key)")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / monad")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.requiredOption("--order-id <id>", "Order ID")
|
||||
.option("--raw", "Output raw JSON")
|
||||
.action(async (opts) => {
|
||||
@@ -185,8 +185,8 @@ export function registerSwapCommands(program: Command): void {
|
||||
|
||||
program
|
||||
.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")
|
||||
.description("Query recommended gas price tiers for any chain (exist auth — API Key only; eth / bsc / base / sol / robinhood)")
|
||||
.requiredOption("--chain <chain>", "Chain: eth / bsc / base / sol / robinhood")
|
||||
.option("--raw", "Output raw JSON")
|
||||
.action(async (opts) => {
|
||||
const client = new OpenApiClient(getConfig(false));
|
||||
@@ -199,7 +199,7 @@ 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 / eth")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.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")
|
||||
@@ -283,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 / eth")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.option("--type <type>", "open (default) / history")
|
||||
.option("--from <address>", "Filter by wallet address")
|
||||
.option("--group-tag <tag>", "Filter by group: LimitOrder / STMix")
|
||||
@@ -308,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 / eth")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.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")
|
||||
|
||||
@@ -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 / eth")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.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 / eth")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.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 / eth")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.requiredOption("--address <address>", "Token contract address")
|
||||
.option("--raw", "Output raw JSON")
|
||||
.action(async (opts) => {
|
||||
@@ -52,7 +52,7 @@ export function registerTokenCommands(program: Command): void {
|
||||
token
|
||||
.command("holders")
|
||||
.description("Get top token holders")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.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")
|
||||
@@ -75,7 +75,7 @@ export function registerTokenCommands(program: Command): void {
|
||||
token
|
||||
.command("traders")
|
||||
.description("Get top token traders")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.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")
|
||||
|
||||
+11
-3
@@ -10,7 +10,7 @@ export function registerTrackCommands(program: Command): void {
|
||||
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("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.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)")
|
||||
@@ -38,7 +38,7 @@ export function registerTrackCommands(program: Command): void {
|
||||
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("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.requiredOption("--wallet <address>", "Wallet address")
|
||||
.option("--raw", "Output raw JSON")
|
||||
.action(async (opts) => {
|
||||
@@ -51,7 +51,7 @@ export function registerTrackCommands(program: Command): void {
|
||||
track
|
||||
.command("follow-wallet")
|
||||
.description("Get follow-wallet trade records")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood")
|
||||
.option("--wallet <address>", "Filter by wallet address")
|
||||
.option("--limit <n>", "Page size (1–100, default 10)", parseInt)
|
||||
.option("--side <side>", "Trade direction filter: buy / sell")
|
||||
@@ -82,6 +82,10 @@ export function registerTrackCommands(program: Command): void {
|
||||
.option("--raw", "Output raw JSON")
|
||||
.action(async (opts) => {
|
||||
if (opts.chain) validateChain(opts.chain);
|
||||
if (opts.chain === "robinhood") {
|
||||
console.error(`[gmgn-cli] track kol does not support robinhood, got "${opts.chain}"`);
|
||||
process.exit(1);
|
||||
}
|
||||
const client = new OpenApiClient(getConfig());
|
||||
const data = await client.getKol(opts.chain, opts.limit).catch(exitOnError) as { list?: { side: string }[] };
|
||||
if (opts.side && data?.list) {
|
||||
@@ -99,6 +103,10 @@ export function registerTrackCommands(program: Command): void {
|
||||
.option("--raw", "Output raw JSON")
|
||||
.action(async (opts) => {
|
||||
if (opts.chain) validateChain(opts.chain);
|
||||
if (opts.chain === "robinhood") {
|
||||
console.error(`[gmgn-cli] track smartmoney does not support robinhood, got "${opts.chain}"`);
|
||||
process.exit(1);
|
||||
}
|
||||
const client = new OpenApiClient(getConfig());
|
||||
const data = await client.getSmartMoney(opts.chain, opts.limit).catch(exitOnError) as { list?: { side: string }[] };
|
||||
if (opts.side && data?.list) {
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
const VALID_CHAINS = new Set(["sol", "bsc", "base", "eth", "monad"]);
|
||||
const VALID_CHAINS = new Set(["sol", "bsc", "base", "eth", "robinhood" /*, "monad" */]);
|
||||
const SOL_ADDRESS_RE = /^[1-9A-HJ-NP-Za-km-z]{32,44}$/;
|
||||
const EVM_ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
|
||||
const POSITIVE_INT_RE = /^\d+$/;
|
||||
@@ -13,7 +13,7 @@ export function validateChain(chain: string): void {
|
||||
}
|
||||
|
||||
export function validateAddress(address: string, chain: string, label: string): void {
|
||||
const isEvm = chain === "bsc" || chain === "base" || chain === "eth" || chain === "monad";
|
||||
const isEvm = chain === "bsc" || chain === "base" || chain === "eth" || chain === "robinhood" /* || chain === "monad" */;
|
||||
const valid = isEvm ? EVM_ADDRESS_RE.test(address) : SOL_ADDRESS_RE.test(address);
|
||||
if (!valid) {
|
||||
console.error(
|
||||
|
||||
Reference in New Issue
Block a user