import { Command } from "commander"; import { OpenApiClient } from "../client/OpenApiClient.js"; import { getConfig } from "../config.js"; import { exitOnError, printResult } from "../output.js"; import { validateAddress, validateChain } from "../validate.js"; 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: sol / bsc / base") .requiredOption("--address
", "Token contract address") .requiredOption("--resolution ", "Candlestick resolution: 1m / 5m / 15m / 1h / 4h / 1d") .option("--from ", "Start time (Unix seconds)", parseInt) .option("--to ", "End time (Unix seconds)", parseInt) .option("--raw", "Output raw JSON") .action(async (opts) => { validateChain(opts.chain); validateAddress(opts.address, opts.chain, "--address"); const client = new OpenApiClient(getConfig()); const data = await client .getTokenKline( opts.chain, opts.address, opts.resolution, opts.from != null ? opts.from * 1000 : undefined, opts.to != null ? opts.to * 1000 : undefined ) .catch(exitOnError); printResult(data, opts.raw); }); market .command("trending") .description("Get trending token swap data") .requiredOption("--chain ", "Chain: sol / bsc / base") .requiredOption("--interval ", "Time interval: 1m / 5m / 1h / 6h / 24h") .option("--limit ", "Number of results (default 100, max 100)", parseInt) .option("--order-by ", "Sort field: default / volume / swaps / marketcap / holder_count / price / change1h / ... (see docs for full list)") .option("--direction ", "Sort direction: asc / desc") .option("--filter ", "Filter tags, repeatable. sol: renounced / frozen / has_social / not_wash_trading / ... evm: not_honeypot / verified / renounced / locked / ... (see docs for full list)") .option("--platform ", "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 = {}; 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; const client = new OpenApiClient(getConfig()); const data = await client.getTrendingSwaps(opts.chain, opts.interval, extra).catch(exitOnError); printResult(data, opts.raw); }); market .command("trenches") .description("Get Trenches token data (new creation, near completion, completed)") .requiredOption("--chain ", "Chain: sol / bsc / base") .option("--type ", "Categories to query, repeatable: new_creation / near_completion / completed (default: all three)") .option("--launchpad-platform ", "Launchpad platform filter, repeatable (default: all platforms for the chain)") .option("--limit ", "Max results per category, max 80 (default: 80)", parseInt) .option("--raw", "Output raw JSON") .action(async (opts) => { validateChain(opts.chain); const client = new OpenApiClient(getConfig()); const data = await client.getTrenches(opts.chain, opts.type, opts.launchpadPlatform, opts.limit).catch(exitOnError); printResult(data, opts.raw); }); }