mirror of
https://github.com/GMGNAI/gmgn-skills.git
synced 2026-08-17 18:18:05 +00:00
Add EVM chains arc and stable everywhere robinhood is supported:
- src/validate.ts: add arc + stable to VALID_CHAINS and EVM address check
- src/commands/{token,market,portfolio,swap,track}.ts: extend --chain
option help and the market-signal chain gate
- src/client/OpenApiClient.ts: HotSearchesParam chain comment
- Sync SKILL.md files, Readme.md, Readme.zh.md, docs/cli-usage.md;
update the default hot-search set wording from 6-chain to 7-chain
Cooking/create_token remains sol/bsc/base/robinhood only (no launchpad
on arc or stable), matching the openapi service.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
110 lines
5.5 KiB
TypeScript
110 lines
5.5 KiB
TypeScript
import { Command } from "commander";
|
||
import { OpenApiClient } from "../client/OpenApiClient.js";
|
||
import { getConfig } from "../config.js";
|
||
import { exitOnError, printResult } from "../output.js";
|
||
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 / robinhood / arc / stable")
|
||
.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 / robinhood / arc / stable")
|
||
.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 / eth / robinhood / arc / stable")
|
||
.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")
|
||
.option("--filter <tag...>", "Filter conditions, repeatable")
|
||
.option("--min-amount-usd <n>", "Minimum trade amount (USD)", parseFloat)
|
||
.option("--max-amount-usd <n>", "Maximum trade amount (USD)", parseFloat)
|
||
.option("--raw", "Output raw JSON")
|
||
.action(async (opts) => {
|
||
validateChain(opts.chain);
|
||
const extra: Record<string, string | number | string[]> = {};
|
||
if (opts.wallet) extra["wallet_address"] = opts.wallet;
|
||
if (opts.limit != null) extra["limit"] = opts.limit;
|
||
if (opts.side) extra["side"] = opts.side;
|
||
if (opts.filter?.length) extra["filters"] = opts.filter;
|
||
if (opts.minAmountUsd != null) extra["min_amount_usd"] = opts.minAmountUsd;
|
||
if (opts.maxAmountUsd != null) extra["max_amount_usd"] = opts.maxAmountUsd;
|
||
const client = new OpenApiClient(getConfig());
|
||
const data = await client.getFollowWallet(opts.chain, extra).catch(exitOnError);
|
||
printResult(data, opts.raw);
|
||
});
|
||
|
||
track
|
||
.command("kol")
|
||
.description("Get KOL trade records")
|
||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood / arc / stable")
|
||
.option("--limit <n>", "Page size (1–200, default 100)", parseInt)
|
||
.option("--side <side>", "Filter by trade direction: buy / sell (client-side filter)")
|
||
.option("--raw", "Output raw JSON")
|
||
.action(async (opts) => {
|
||
if (opts.chain) validateChain(opts.chain);
|
||
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) {
|
||
data.list = data.list.filter((item) => item.side === opts.side);
|
||
}
|
||
printResult(data, opts.raw);
|
||
});
|
||
|
||
track
|
||
.command("smartmoney")
|
||
.description("Get Smart Money trade records")
|
||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth / robinhood / arc / stable")
|
||
.option("--limit <n>", "Page size (1–200, default 100)", parseInt)
|
||
.option("--side <side>", "Filter by trade direction: buy / sell (client-side filter)")
|
||
.option("--raw", "Output raw JSON")
|
||
.action(async (opts) => {
|
||
if (opts.chain) validateChain(opts.chain);
|
||
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) {
|
||
data.list = data.list.filter((item) => item.side === opts.side);
|
||
}
|
||
printResult(data, opts.raw);
|
||
});
|
||
}
|