import { Command } from "commander"; import { OpenApiClient, CreateTokenParams } from "../client/OpenApiClient.js"; import { getConfig } from "../config.js"; import { exitOnError, printResult } from "../output.js"; import { validateChain } from "../validate.js"; export function registerCookingCommands(program: Command): void { const cooking = program.command("cooking").description("Token creation and launchpad commands"); cooking .command("stats") .description("Get token creation statistics by launchpad (exist auth)") .option("--raw", "Output raw JSON") .action(async (opts) => { const client = new OpenApiClient(getConfig()); const data = await client.getCookingStatistics().catch(exitOnError); printResult(data, opts.raw); }); cooking .command("create") .description("Create a token on a launchpad platform (requires private key)") .requiredOption("--chain ", "Chain: sol / bsc / base") .requiredOption("--dex ", "Launchpad: pump / bonk / bags (sol) / fourmeme / flap (bsc) / klik / clanker (base)") .requiredOption("--from
", "Wallet address (must match API Key binding)") .requiredOption("--name ", "Token name") .requiredOption("--symbol ", "Token symbol") .requiredOption("--buy-amt ", "Initial buy amount in native token (e.g. 0.01 SOL)") .option("--image ", "Token logo as base64-encoded data (max 2MB decoded)") .option("--image-url ", "Token logo URL") .option("--description ", "Token description / project pitch") .option("--website ", "Website URL") .option("--twitter ", "Twitter link") .option("--telegram ", "Telegram link") .option("--slippage ", "Slippage tolerance (e.g. 30 = 30%)", parseFloat) .option("--auto-slippage", "Enable automatic slippage") .option("--fee ", "Base gas / fee") .option("--priority-fee ", "Priority fee in SOL (SOL only)") .option("--tip-fee ", "Tip fee") .option("--gas-price ", "Gas price in wei (EVM chains)") .option("--max-fee-per-gas ", "Max fee per gas in wei (EVM only)") .option("--max-priority-fee-per-gas ", "Max priority fee per gas in wei (EVM only)") .option("--anti-mev", "Enable anti-MEV protection (SOL only)") .option("--anti-mev-mode ", "Anti-MEV mode: off / normal / secure (SOL only)") .option("--raised-token ", "Raise token symbol: pump→USDC; bonk→USD1; fourmeme→USDT/USD1; leave empty for native") .option("--dev-wallet-bps ", "Dev wallet fee in basis points (100 = 1%)", parseInt) .option("--dev-gas ", "Dev gas amount") .option("--dev-priority ", "Dev priority fee") .option("--dev-tip ", "Dev tip fee") .option("--dev-max-fee-per-gas ", "Dev tx feeCap in wei (EVM EIP-1559)") .option("--approve-vision ", "Approve vision version: v1 / v2 (default: v2)") .option("--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 ", "Pump.fun fee share list as JSON array (Pump.fun only)") // Flap specific .option("--flap-rate-conf ", "Flap rate config as JSON object (Flap only)") // FourMeme specific .option("--fourmeme-rate-conf ", "FourMeme rate config as JSON object (FourMeme only)") // BAGS specific .option("--bags-fee-share-list ", "BAGS fee share list as JSON array (BAGS only)") // Bonk specific .option("--bonk-model ", "Bonk model identifier (bonk DEX only)") // Multi-wallet buy .option("--buy-wallets ", "Multi-wallet buy config as JSON array [{from_address, buy_amt}]") .option("--snip-buy-wallets ", "Snipe-buy wallet config as JSON array [{from_address, buy_amt}]") // CondMarket execution config + auto-sell (JSON) .option("--buy-trade-config ", "Buy-side trade config for CondMarket orders as JSON (TradeParam)") .option("--sell-trade-config ", "Sell-side trade config for auto-sell / pending_sell as JSON (TradeParam)") .option("--sell-configs ", "Auto-sell strategy list as JSON array (CookingSellConfig[])") .option("--raw", "Output raw JSON") .action(async (opts) => { if (!opts.image && !opts.imageUrl) { console.error("[gmgn-cli] Either --image or --image-url must be provided"); process.exit(1); } if (!opts.slippage && !opts.autoSlippage) { console.error("[gmgn-cli] Either --slippage or --auto-slippage must be provided"); 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, from_address: opts.from, name: opts.name, symbol: opts.symbol, buy_amt: opts.buyAmt, }; 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); }); }