mirror of
https://github.com/GMGNAI/gmgn-skills.git
synced 2026-07-27 16:57:44 +00:00
feat: add cooking command and update swap/docs
This commit is contained in:
@@ -457,6 +457,171 @@ npx gmgn-cli order get --chain <chain> --order-id <order_id> [--raw]
|
|||||||
|
|
||||||
**Response fields (data):** Same structure as the `swap` response above.
|
**Response fields (data):** Same structure as the `swap` response above.
|
||||||
|
|
||||||
|
## order strategy create
|
||||||
|
|
||||||
|
Create a limit/strategy order. **Requires `GMGN_PRIVATE_KEY` configured in `.env`.**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gmgn-cli order strategy create \
|
||||||
|
--chain <chain> \
|
||||||
|
--from <wallet_address> \
|
||||||
|
--base-token <base_token_address> \
|
||||||
|
--quote-token <quote_token_address> \
|
||||||
|
--side <buy|sell> \
|
||||||
|
--open-price <price> \
|
||||||
|
--check-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>] \
|
||||||
|
[--priority-fee <sol>] \
|
||||||
|
[--tip-fee <amount>] \
|
||||||
|
[--gas-price <amount>] \
|
||||||
|
[--anti-mev] \
|
||||||
|
[--raw]
|
||||||
|
```
|
||||||
|
|
||||||
|
| Option | 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 |
|
||||||
|
| `--side` | Yes | `buy` / `sell` |
|
||||||
|
| `--open-price` | Yes | Open price |
|
||||||
|
| `--check-price` | Yes | Trigger check price |
|
||||||
|
| `--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% |
|
||||||
|
| `--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 |
|
||||||
|
|
||||||
|
**Response fields (data):**
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|-------|------|-------------|
|
||||||
|
| `order_id` | string | Created strategy order ID |
|
||||||
|
| `is_update` | bool | `true` if an existing order was updated |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## order strategy list
|
||||||
|
|
||||||
|
List strategy orders. Uses normal auth.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gmgn-cli order strategy list --chain <chain> [--type <open|history>] [--from <address>] [--base-token <address>] [--page-token <token>] [--limit <n>] [--raw]
|
||||||
|
```
|
||||||
|
|
||||||
|
| Option | Required | Description |
|
||||||
|
|--------|----------|-------------|
|
||||||
|
| `--chain` | Yes | `sol` / `bsc` / `base` |
|
||||||
|
| `--type` | No | `open` (default) / `history` |
|
||||||
|
| `--from` | No | Filter by wallet address |
|
||||||
|
| `--base-token` | No | Filter by token address |
|
||||||
|
| `--page-token` | No | Pagination cursor from previous response |
|
||||||
|
| `--limit` | No | Results per page |
|
||||||
|
|
||||||
|
**Response fields (data):**
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|-------|------|-------------|
|
||||||
|
| `next_page_token` | string | Cursor for next page; empty when no more data |
|
||||||
|
| `total` | int | Total count (only when `--type open`) |
|
||||||
|
| `list` | array | Strategy order list |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## order strategy cancel
|
||||||
|
|
||||||
|
Cancel a strategy order. **Requires `GMGN_PRIVATE_KEY` configured in `.env`.**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gmgn-cli order strategy cancel --chain <chain> --from <wallet_address> --order-id <id> [--close-sell-model <model>] [--raw]
|
||||||
|
```
|
||||||
|
|
||||||
|
| Option | Required | Description |
|
||||||
|
|--------|----------|-------------|
|
||||||
|
| `--chain` | Yes | `sol` / `bsc` / `base` |
|
||||||
|
| `--from` | Yes | Wallet address (must match API Key binding) |
|
||||||
|
| `--order-id` | Yes | Order ID to cancel |
|
||||||
|
| `--close-sell-model` | No | Sell model when closing |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## cooking stats
|
||||||
|
|
||||||
|
Get token creation statistics grouped by launchpad.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gmgn-cli cooking stats [--raw]
|
||||||
|
```
|
||||||
|
|
||||||
|
No additional options required. Returns an array of `{ launchpad, token_count }` entries.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## cooking create
|
||||||
|
|
||||||
|
Create a token on a launchpad platform. **Requires `GMGN_PRIVATE_KEY` configured in `.env`.**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gmgn-cli cooking create \
|
||||||
|
--chain <chain> \
|
||||||
|
--dex <dex> \
|
||||||
|
--from <wallet_address> \
|
||||||
|
--name <name> \
|
||||||
|
--symbol <symbol> \
|
||||||
|
--buy-amt <amount> \
|
||||||
|
[--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] \
|
||||||
|
[--raw]
|
||||||
|
```
|
||||||
|
|
||||||
|
| Option | Required | Description |
|
||||||
|
|--------|----------|-------------|
|
||||||
|
| `--chain` | Yes | `sol` / `bsc` / `base` / `eth` / `ton` |
|
||||||
|
| `--dex` | Yes | Launchpad: `pump` / `raydium` / `pancakeswap` / `flap` / `fourmeme` / `bonk` / `bags` / ... |
|
||||||
|
| `--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 |
|
||||||
|
| `--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 |
|
||||||
|
|
||||||
|
**Response fields (data):**
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|-------|------|-------------|
|
||||||
|
| `status` | string | `pending` / `confirmed` / `failed` |
|
||||||
|
| `hash` | string | Transaction hash |
|
||||||
|
| `order_id` | string | Order ID for polling |
|
||||||
|
| `error_code` | string | Error code on failure |
|
||||||
|
| `error_status` | string | Error description on failure |
|
||||||
|
|
||||||
|
Token creation is asynchronous. Poll `order get` with the returned `order_id` if `status` is `pending`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Rate Limit Handling
|
## Rate Limit Handling
|
||||||
|
|
||||||
All business routes are protected by GMGN's leaky-bucket limiter. Current production behavior is:
|
All business routes are protected by GMGN's leaky-bucket limiter. Current production behavior is:
|
||||||
|
|||||||
@@ -0,0 +1,123 @@
|
|||||||
|
---
|
||||||
|
name: gmgn-cooking
|
||||||
|
description: "[FINANCIAL EXECUTION] Create tokens on launchpad platforms (Pump.fun, Raydium, PancakeSwap, Flap, FourMeme, Bonk, BAGS, etc.) or query token creation statistics by launchpad. Token creation executes irreversible on-chain transactions. Requires explicit user confirmation before every create. Supports sol / bsc / 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"
|
||||||
|
---
|
||||||
|
|
||||||
|
**IMPORTANT: Always use `gmgn-cli` commands below. Do NOT use web search, WebFetch, curl, or visit gmgn.ai.**
|
||||||
|
|
||||||
|
**⚠️ Token creation executes REAL, IRREVERSIBLE blockchain transactions. Always require explicit user confirmation before running `cooking create`.**
|
||||||
|
|
||||||
|
## Sub-commands
|
||||||
|
|
||||||
|
| Sub-command | Description |
|
||||||
|
|-------------|-------------|
|
||||||
|
| `cooking stats` | Get token creation statistics grouped by launchpad (normal auth) |
|
||||||
|
| `cooking create` | Create a token on a launchpad platform (requires private key) |
|
||||||
|
|
||||||
|
## Supported Chains
|
||||||
|
|
||||||
|
`sol` / `bsc` / `base` / `eth` / `ton`
|
||||||
|
|
||||||
|
## Supported Launchpads by Chain
|
||||||
|
|
||||||
|
| Chain | Supported DEX / Launchpad |
|
||||||
|
|-------|--------------------------|
|
||||||
|
| `sol` | `pump` / `raydium` / `bonk` / `bags` / `memoo` / `letsbonk` / `bonkers` |
|
||||||
|
| `bsc` | `pancakeswap` / `flap` / `fourmeme` |
|
||||||
|
| `base` | `clanker` / `flaunch` / `baseapp` / `basememe` / `zora` / `virtuals_v2` |
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- `cooking stats`: Only `GMGN_API_KEY` required
|
||||||
|
- `cooking create`: Both `GMGN_API_KEY` and `GMGN_PRIVATE_KEY` must be configured in `~/.config/gmgn/.env`. 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`
|
||||||
|
|
||||||
|
## `cooking stats` Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gmgn-cli cooking stats [--raw]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response fields (data array):**
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|-------|------|-------------|
|
||||||
|
| `launchpad` | string | Launchpad identifier (e.g. `pump`, `raydium`, `pancakeswap`) |
|
||||||
|
| `token_count` | int | Number of tokens created on that launchpad |
|
||||||
|
|
||||||
|
## `cooking create` Parameters
|
||||||
|
|
||||||
|
| Parameter | Required | Description |
|
||||||
|
|-----------|----------|-------------|
|
||||||
|
| `--chain` | Yes | Chain: `sol` / `bsc` / `base` / `eth` / `ton` |
|
||||||
|
| `--dex` | Yes | Launchpad platform (see Supported Launchpads table) |
|
||||||
|
| `--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` for 0.01 SOL) |
|
||||||
|
| `--image` | No* | Token logo as base64-encoded data (max 2MB decoded). One of `--image` or `--image-url` is required |
|
||||||
|
| `--image-url` | No* | Token logo URL. One of `--image` or `--image-url` is required |
|
||||||
|
| `--website` | No | Website URL |
|
||||||
|
| `--twitter` | No | Twitter link |
|
||||||
|
| `--telegram` | No | Telegram link |
|
||||||
|
| `--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, ≥ 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 |
|
||||||
|
|
||||||
|
## `cooking create` Response Fields
|
||||||
|
|
||||||
|
| Field | Type | Description |
|
||||||
|
|-------|------|-------------|
|
||||||
|
| `status` | string | `pending` / `confirmed` / `failed` |
|
||||||
|
| `hash` | string | Transaction hash (may be empty while pending) |
|
||||||
|
| `order_id` | string | Order ID for polling via `order get` |
|
||||||
|
| `error_code` | string | Error code on failure |
|
||||||
|
| `error_status` | string | Error description on failure |
|
||||||
|
|
||||||
|
Token creation is asynchronous. If `status` is `pending`, poll with `gmgn-cli order get --chain <chain> --order-id <order_id>` every 2 seconds (up to 30 seconds). The new token's mint address is available in the order detail's `output_token` field once confirmed.
|
||||||
|
|
||||||
|
## Usage Examples
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Get launchpad creation statistics
|
||||||
|
gmgn-cli cooking stats
|
||||||
|
|
||||||
|
# Create a token on Pump.fun (SOL)
|
||||||
|
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 \
|
||||||
|
--slippage 0.01 \
|
||||||
|
--priority-fee 0.001
|
||||||
|
|
||||||
|
# Create a token on PancakeSwap (BSC)
|
||||||
|
gmgn-cli cooking create \
|
||||||
|
--chain bsc \
|
||||||
|
--dex pancakeswap \
|
||||||
|
--from <wallet_address> \
|
||||||
|
--name "BSC Token" \
|
||||||
|
--symbol BSCT \
|
||||||
|
--buy-amt 0.01 \
|
||||||
|
--image-url https://example.com/logo.png \
|
||||||
|
--slippage 0.02 \
|
||||||
|
--gas-price 5000000000 \
|
||||||
|
--website https://mytoken.io \
|
||||||
|
--twitter https://twitter.com/mytoken
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- `cooking create` uses **critical auth** (API Key + signature) — CLI handles signing automatically
|
||||||
|
- Either `--image` (base64) or `--image-url` is required; both `--slippage` and `--auto-slippage` cannot be omitted (provide one)
|
||||||
|
- After creation, poll `order get` to get `confirmed` status and the new token's mint address from `output_token`
|
||||||
|
- Use `--raw` to get single-line JSON for further processing
|
||||||
@@ -48,6 +48,9 @@ Use the `gmgn-cli` tool to submit a token swap or query an existing order. **Req
|
|||||||
| `swap` | Submit a token swap |
|
| `swap` | Submit a token swap |
|
||||||
| `order quote` | Get a swap quote (no transaction submitted) |
|
| `order quote` | Get a swap quote (no transaction submitted) |
|
||||||
| `order get` | Query order status |
|
| `order get` | Query order status |
|
||||||
|
| `order strategy create` | Create a limit/strategy order (requires private key) |
|
||||||
|
| `order strategy list` | List strategy orders (normal auth) |
|
||||||
|
| `order strategy cancel` | Cancel a strategy order (requires private key) |
|
||||||
|
|
||||||
## Supported Chains
|
## Supported Chains
|
||||||
|
|
||||||
@@ -279,11 +282,119 @@ Order ID: {order_id}
|
|||||||
|
|
||||||
Convert `filled_input_amount` and `filled_output_amount` from smallest unit using token decimals before displaying.
|
Convert `filled_input_amount` and `filled_output_amount` from smallest unit using 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 |
|
||||||
|
| `--side` | Yes | Direction: `buy` / `sell` |
|
||||||
|
| `--open-price` | Yes | Open price; compared with `--check-price` to infer order type |
|
||||||
|
| `--check-price` | Yes | Trigger check price; compared with `--open-price` to infer order type |
|
||||||
|
| `--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) / `hold_amount` |
|
||||||
|
| `--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 wei (EVM chains) |
|
||||||
|
| `--anti-mev` | No | Enable anti-MEV protection |
|
||||||
|
|
||||||
|
Order direction is inferred automatically from `--side` and the comparison between `--open-price` and `--check-price`:
|
||||||
|
|
||||||
|
| `--side` | open_price vs check_price | Inferred type |
|
||||||
|
|----------|--------------------------|---------------|
|
||||||
|
| `buy` | open_price > check_price | buy_low |
|
||||||
|
| `buy` | open_price < check_price | buy_high |
|
||||||
|
| `sell` | open_price > check_price | stop_loss |
|
||||||
|
| `sell` | open_price < check_price | take_profit |
|
||||||
|
|
||||||
|
**`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 |
|
||||||
|
| `--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 |
|
||||||
|
| `--close-sell-model` | No | Sell model when closing the order |
|
||||||
|
|
||||||
|
## `order strategy` Usage Examples
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Create a take-profit order: sell when price rises above open price
|
||||||
|
gmgn-cli order strategy create \
|
||||||
|
--chain sol \
|
||||||
|
--from <wallet_address> \
|
||||||
|
--base-token <token_address> \
|
||||||
|
--quote-token <sol_address> \
|
||||||
|
--side sell \
|
||||||
|
--open-price 0.001 \
|
||||||
|
--check-price 0.002 \
|
||||||
|
--amount-in 1000000 \
|
||||||
|
--slippage 0.01
|
||||||
|
|
||||||
|
# Create a stop-loss order: sell when price drops below open price
|
||||||
|
gmgn-cli order strategy create \
|
||||||
|
--chain sol \
|
||||||
|
--from <wallet_address> \
|
||||||
|
--base-token <token_address> \
|
||||||
|
--quote-token <sol_address> \
|
||||||
|
--side sell \
|
||||||
|
--open-price 0.001 \
|
||||||
|
--check-price 0.0005 \
|
||||||
|
--amount-in-percent 100 \
|
||||||
|
--slippage 0.01
|
||||||
|
|
||||||
|
# List open strategy orders
|
||||||
|
gmgn-cli order strategy list --chain sol
|
||||||
|
|
||||||
|
# List history orders with pagination
|
||||||
|
gmgn-cli order strategy list --chain sol --type history --limit 20
|
||||||
|
|
||||||
|
# Cancel a strategy order
|
||||||
|
gmgn-cli order strategy cancel \
|
||||||
|
--chain sol \
|
||||||
|
--from <wallet_address> \
|
||||||
|
--order-id <order_id>
|
||||||
|
```
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
- Swap uses **critical auth** (API Key + signature) — CLI handles signing automatically, no manual processing needed
|
- Swap uses **critical auth** (API Key + signature) — CLI handles signing automatically, no manual processing needed
|
||||||
- After submitting a swap, use `order get` to poll for confirmation
|
- After submitting a swap, use `order get` to poll for confirmation
|
||||||
- `--amount` is in the **smallest unit** (e.g., lamports for SOL)
|
- `--amount` is in the **smallest unit** (e.g., lamports for SOL)
|
||||||
|
- `order strategy create` and `order strategy cancel` use critical auth (require `GMGN_PRIVATE_KEY`); `order strategy list` uses normal auth
|
||||||
- Use `--raw` to get single-line JSON for further processing
|
- Use `--raw` to get single-line JSON for further processing
|
||||||
|
|
||||||
## Input Validation
|
## Input Validation
|
||||||
|
|||||||
@@ -87,6 +87,63 @@ export interface SwapParams {
|
|||||||
max_priority_fee_per_gas?: string;
|
max_priority_fee_per_gas?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface StrategyCreateParams {
|
||||||
|
chain: string;
|
||||||
|
from_address: string;
|
||||||
|
base_token: string;
|
||||||
|
quote_token: string;
|
||||||
|
side: string;
|
||||||
|
open_price: string;
|
||||||
|
check_price: string;
|
||||||
|
amount_in?: string;
|
||||||
|
amount_in_percent?: string;
|
||||||
|
limit_price_mode?: string;
|
||||||
|
price_gap_ratio?: string;
|
||||||
|
expire_in?: number;
|
||||||
|
sell_ratio_type?: string;
|
||||||
|
slippage?: number;
|
||||||
|
auto_slippage?: boolean;
|
||||||
|
fee?: string;
|
||||||
|
gas_price?: string;
|
||||||
|
max_fee_per_gas?: string;
|
||||||
|
max_priority_fee_per_gas?: string;
|
||||||
|
is_anti_mev?: boolean;
|
||||||
|
anti_mev_mode?: string;
|
||||||
|
priority_fee?: string;
|
||||||
|
tip_fee?: string;
|
||||||
|
custom_rpc?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface StrategyCancelParams {
|
||||||
|
chain: string;
|
||||||
|
from_address: string;
|
||||||
|
order_id: string;
|
||||||
|
close_sell_model?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CreateTokenParams {
|
||||||
|
chain: string;
|
||||||
|
dex: string;
|
||||||
|
from_address: string;
|
||||||
|
name: string;
|
||||||
|
symbol: string;
|
||||||
|
buy_amt: string;
|
||||||
|
image?: string;
|
||||||
|
image_url?: string;
|
||||||
|
website?: string;
|
||||||
|
twitter?: string;
|
||||||
|
telegram?: string;
|
||||||
|
slippage?: number;
|
||||||
|
auto_slippage?: boolean;
|
||||||
|
priority_fee?: string;
|
||||||
|
tip_fee?: string;
|
||||||
|
gas_price?: string;
|
||||||
|
max_priority_fee_per_gas?: string;
|
||||||
|
max_fee_per_gas?: string;
|
||||||
|
is_anti_mev?: boolean;
|
||||||
|
anti_mev_mode?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export class OpenApiClient {
|
export class OpenApiClient {
|
||||||
private readonly apiKey: string;
|
private readonly apiKey: string;
|
||||||
private readonly privateKeyPem: string | undefined;
|
private readonly privateKeyPem: string | undefined;
|
||||||
@@ -239,6 +296,30 @@ export class OpenApiClient {
|
|||||||
return this.criticalRequest("GET", "/v1/trade/query_order", { order_id: orderId, chain }, null);
|
return this.criticalRequest("GET", "/v1/trade/query_order", { order_id: orderId, chain }, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---- Strategy order endpoints ----
|
||||||
|
|
||||||
|
async createStrategyOrder(params: StrategyCreateParams): Promise<unknown> {
|
||||||
|
return this.criticalRequest("POST", "/v1/trade/strategy/create", {}, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getStrategyOrders(chain: string, extra: Record<string, string | number> = {}): Promise<unknown> {
|
||||||
|
return this.normalRequest("GET", "/v1/trade/strategy/orders", { chain, ...extra });
|
||||||
|
}
|
||||||
|
|
||||||
|
async cancelStrategyOrder(params: StrategyCancelParams): Promise<unknown> {
|
||||||
|
return this.criticalRequest("POST", "/v1/trade/strategy/cancel", {}, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- Cooking endpoints ----
|
||||||
|
|
||||||
|
async getCookingStatistics(): Promise<unknown> {
|
||||||
|
return this.normalRequest("GET", "/v1/cooking/statistics", {});
|
||||||
|
}
|
||||||
|
|
||||||
|
async createToken(params: CreateTokenParams): Promise<unknown> {
|
||||||
|
return this.criticalRequest("POST", "/v1/cooking/create_token", {}, params);
|
||||||
|
}
|
||||||
|
|
||||||
// ---- Internal methods ----
|
// ---- Internal methods ----
|
||||||
|
|
||||||
private async normalRequest(
|
private async normalRequest(
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
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 (normal 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>", "Chain: sol / bsc / base / eth / ton")
|
||||||
|
.requiredOption("--dex <dex>", "Launchpad: pump / raydium / pancakeswap / flap / fourmeme / bonk / bags / ...")
|
||||||
|
.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("--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("--auto-slippage", "Enable automatic slippage")
|
||||||
|
.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("--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);
|
||||||
|
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.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.priorityFee) params.priority_fee = opts.priorityFee;
|
||||||
|
if (opts.tipFee) params.tip_fee = opts.tipFee;
|
||||||
|
if (opts.gasPrice) params.gas_price = opts.gasPrice;
|
||||||
|
if (opts.antiMev) params.is_anti_mev = true;
|
||||||
|
const client = new OpenApiClient(getConfig(true));
|
||||||
|
const data = await client.createToken(params).catch(exitOnError);
|
||||||
|
printResult(data, opts.raw);
|
||||||
|
});
|
||||||
|
}
|
||||||
+104
-1
@@ -1,5 +1,5 @@
|
|||||||
import { Command } from "commander";
|
import { Command } from "commander";
|
||||||
import { OpenApiClient, SwapParams } from "../client/OpenApiClient.js";
|
import { OpenApiClient, SwapParams, StrategyCreateParams, StrategyCancelParams } from "../client/OpenApiClient.js";
|
||||||
import { getConfig } from "../config.js";
|
import { getConfig } from "../config.js";
|
||||||
import { exitOnError, printResult } from "../output.js";
|
import { exitOnError, printResult } from "../output.js";
|
||||||
import { validateAddress, validateChain, validatePercent, validatePositiveInt } from "../validate.js";
|
import { validateAddress, validateChain, validatePercent, validatePositiveInt } from "../validate.js";
|
||||||
@@ -97,4 +97,107 @@ export function registerSwapCommands(program: Command): void {
|
|||||||
const data = await client.queryOrder(opts.orderId, opts.chain).catch(exitOnError);
|
const data = await client.queryOrder(opts.orderId, opts.chain).catch(exitOnError);
|
||||||
printResult(data, opts.raw);
|
printResult(data, opts.raw);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const strategy = order.command("strategy").description("Limit/strategy order management");
|
||||||
|
|
||||||
|
strategy
|
||||||
|
.command("create")
|
||||||
|
.description("Create a limit/strategy order (requires private key)")
|
||||||
|
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
|
||||||
|
.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("--side <side>", "Direction: buy / sell")
|
||||||
|
.requiredOption("--open-price <price>", "Open price")
|
||||||
|
.requiredOption("--check-price <price>", "Trigger check price")
|
||||||
|
.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("--auto-slippage", "Enable automatic slippage")
|
||||||
|
.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("--raw", "Output raw JSON")
|
||||||
|
.action(async (opts) => {
|
||||||
|
if (!opts.amountIn && !opts.amountInPercent) {
|
||||||
|
console.error("[gmgn-cli] Either --amount-in or --amount-in-percent 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);
|
||||||
|
const params: StrategyCreateParams = {
|
||||||
|
chain: opts.chain,
|
||||||
|
from_address: opts.from,
|
||||||
|
base_token: opts.baseToken,
|
||||||
|
quote_token: opts.quoteToken,
|
||||||
|
side: opts.side,
|
||||||
|
open_price: opts.openPrice,
|
||||||
|
check_price: opts.checkPrice,
|
||||||
|
};
|
||||||
|
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.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.gasPrice) params.gas_price = opts.gasPrice;
|
||||||
|
if (opts.antiMev) params.is_anti_mev = true;
|
||||||
|
const client = new OpenApiClient(getConfig(true));
|
||||||
|
const data = await client.createStrategyOrder(params).catch(exitOnError);
|
||||||
|
printResult(data, opts.raw);
|
||||||
|
});
|
||||||
|
|
||||||
|
strategy
|
||||||
|
.command("list")
|
||||||
|
.description("List strategy orders (normal auth)")
|
||||||
|
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
|
||||||
|
.option("--type <type>", "open (default) / history")
|
||||||
|
.option("--from <address>", "Filter by wallet address")
|
||||||
|
.option("--base-token <address>", "Filter by token address")
|
||||||
|
.option("--page-token <token>", "Pagination cursor from previous response")
|
||||||
|
.option("--limit <n>", "Results per page", parseInt)
|
||||||
|
.option("--raw", "Output raw JSON")
|
||||||
|
.action(async (opts) => {
|
||||||
|
validateChain(opts.chain);
|
||||||
|
const extra: Record<string, string | number> = {};
|
||||||
|
if (opts.type) extra["type"] = opts.type;
|
||||||
|
if (opts.from) extra["from_address"] = opts.from;
|
||||||
|
if (opts.baseToken) extra["base_token"] = opts.baseToken;
|
||||||
|
if (opts.pageToken) extra["page_token"] = opts.pageToken;
|
||||||
|
if (opts.limit != null) extra["limit"] = opts.limit;
|
||||||
|
const client = new OpenApiClient(getConfig());
|
||||||
|
const data = await client.getStrategyOrders(opts.chain, extra).catch(exitOnError);
|
||||||
|
printResult(data, opts.raw);
|
||||||
|
});
|
||||||
|
|
||||||
|
strategy
|
||||||
|
.command("cancel")
|
||||||
|
.description("Cancel a strategy order (requires private key)")
|
||||||
|
.requiredOption("--chain <chain>", "Chain: sol / bsc / base")
|
||||||
|
.requiredOption("--from <address>", "Wallet address (must match API Key binding)")
|
||||||
|
.requiredOption("--order-id <id>", "Order ID to cancel")
|
||||||
|
.option("--close-sell-model <model>", "Sell model when closing")
|
||||||
|
.option("--raw", "Output raw JSON")
|
||||||
|
.action(async (opts) => {
|
||||||
|
validateChain(opts.chain);
|
||||||
|
const params: StrategyCancelParams = {
|
||||||
|
chain: opts.chain,
|
||||||
|
from_address: opts.from,
|
||||||
|
order_id: opts.orderId,
|
||||||
|
};
|
||||||
|
if (opts.closeSellModel) params.close_sell_model = opts.closeSellModel;
|
||||||
|
const client = new OpenApiClient(getConfig(true));
|
||||||
|
const data = await client.cancelStrategyOrder(params).catch(exitOnError);
|
||||||
|
printResult(data, opts.raw);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { registerMarketCommands } from "./commands/market.js";
|
|||||||
import { registerPortfolioCommands } from "./commands/portfolio.js";
|
import { registerPortfolioCommands } from "./commands/portfolio.js";
|
||||||
import { registerTrackCommands } from "./commands/track.js";
|
import { registerTrackCommands } from "./commands/track.js";
|
||||||
import { registerSwapCommands } from "./commands/swap.js";
|
import { registerSwapCommands } from "./commands/swap.js";
|
||||||
|
import { registerCookingCommands } from "./commands/cooking.js";
|
||||||
|
|
||||||
const proxy = process.env.HTTPS_PROXY ?? process.env.https_proxy
|
const proxy = process.env.HTTPS_PROXY ?? process.env.https_proxy
|
||||||
?? process.env.HTTP_PROXY ?? process.env.http_proxy;
|
?? process.env.HTTP_PROXY ?? process.env.http_proxy;
|
||||||
@@ -58,6 +59,7 @@ registerMarketCommands(program);
|
|||||||
registerPortfolioCommands(program);
|
registerPortfolioCommands(program);
|
||||||
registerTrackCommands(program);
|
registerTrackCommands(program);
|
||||||
registerSwapCommands(program);
|
registerSwapCommands(program);
|
||||||
|
registerCookingCommands(program);
|
||||||
|
|
||||||
program.parseAsync().catch((err) => {
|
program.parseAsync().catch((err) => {
|
||||||
console.error(`[gmgn-cli] ${err.message}`);
|
console.error(`[gmgn-cli] ${err.message}`);
|
||||||
|
|||||||
Reference in New Issue
Block a user