mirror of
https://github.com/GMGNAI/gmgn-skills.git
synced 2026-07-27 16:57:44 +00:00
refactor(auth): rename normalRequest/criticalRequest; align auth terminology
- Rename private methods: normalRequest → authExistRequest,
criticalRequest → authSignedRequest in OpenApiClient.ts (both gmgn-skills
and scripts/src)
- Replace all "normal auth" / "critical auth" labels across SKILL.md files,
cli-usage.md, Readme.md, and CLI command descriptions with:
exist auth — API Key only, no private key required
signed auth — API Key + GMGN_PRIVATE_KEY signature required
- Add explicit "requires GMGN_PRIVATE_KEY" notes to signed-auth commands
and "API Key only" notes to exist-auth commands throughout docs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -557,7 +557,7 @@ gmgn-cli order quote \
|
||||
--amount 1000000 \
|
||||
--slippage 0.01
|
||||
|
||||
# Quotes use critical auth and require GMGN_PRIVATE_KEY on every chain
|
||||
# Quotes use signed auth and require GMGN_PRIVATE_KEY on every chain
|
||||
gmgn-cli order quote \
|
||||
--chain bsc \
|
||||
--from <wallet-address> \
|
||||
@@ -579,7 +579,7 @@ gmgn-cli multi-swap \
|
||||
--slippage 0.01
|
||||
```
|
||||
|
||||
> `order quote` uses critical auth on `sol` / `bsc` / `base` / `eth` and requires `GMGN_PRIVATE_KEY`.
|
||||
> `order quote` uses signed auth on `sol` / `bsc` / `base` / `eth` and requires `GMGN_PRIVATE_KEY`.
|
||||
|
||||
### Swap with Take-Profit / Stop-Loss Orders (requires private key)
|
||||
|
||||
|
||||
+3
-3
@@ -351,7 +351,7 @@ gmgn-cli market signal --chain sol --groups '<json_array>' [--raw]
|
||||
|
||||
## portfolio follow-wallet
|
||||
|
||||
Query follow-wallet trade records. Returns trades from wallets you personally follow on the GMGN platform. The follow list is resolved automatically from the GMGN user account bound to the API Key — `--wallet` is optional. Normal auth (API Key only, no private key needed).
|
||||
Query follow-wallet trade records. Returns trades from wallets you personally follow on the GMGN platform. The follow list is resolved automatically from the GMGN user account bound to the API Key — `--wallet` is optional. Signed auth (API Key + private key signature).
|
||||
|
||||
```bash
|
||||
gmgn-cli track follow-wallet \
|
||||
@@ -411,7 +411,7 @@ gmgn-cli track smartmoney [--chain <chain>] [--limit <n>] [--side <side>] [--raw
|
||||
|
||||
## order quote
|
||||
|
||||
Get a swap quote without submitting a transaction. All supported quote chains use critical auth and require `GMGN_PRIVATE_KEY`.
|
||||
Get a swap quote without submitting a transaction. All supported quote chains use signed auth and require `GMGN_PRIVATE_KEY`.
|
||||
|
||||
```bash
|
||||
npx gmgn-cli order quote \
|
||||
@@ -801,7 +801,7 @@ Important notes:
|
||||
| `AUTH_SIGNATURE_INVALID` | 401 | Signature verification failed |
|
||||
| `AUTH_TIMESTAMP_EXPIRED` | 401 | Timestamp is outside the valid window (±5s) |
|
||||
| `AUTH_CLIENT_ID_REPLAYED` | 401 | client_id replayed within 7s |
|
||||
| `AUTH_REPLAY_CHECK_UNAVAILABLE` | 503 | Anti-replay Redis unavailable (critical auth only) |
|
||||
| `AUTH_REPLAY_CHECK_UNAVAILABLE` | 503 | Anti-replay Redis unavailable (signed auth only) |
|
||||
| `RATE_LIMIT_EXCEEDED` | 429 | Rate limit exceeded |
|
||||
| `RATE_LIMIT_BANNED` | 429 | Temporarily banned due to repeated rate limit violations |
|
||||
| `ERROR_RATE_LIMIT_BLOCKED` | 429 | Temporarily blocked after repeated business errors on `swap` |
|
||||
|
||||
@@ -26,7 +26,7 @@ Use the `gmgn-cli` tool to create a token on a launchpad platform or query token
|
||||
|
||||
- **Status polling via `order get`** — `cooking create` is asynchronous. The immediate response may show `pending`. Poll with `gmgn-cli order get --chain <chain> --order-id <order_id>` until `confirmed`. The new token's contract address is in the `output_token` field of the `order get` response, not in the initial create response.
|
||||
|
||||
- **Critical auth** — `cooking create` requires both `GMGN_API_KEY` and `GMGN_PRIVATE_KEY`. The private key never leaves the machine — the CLI uses it only for local signing. `cooking stats` uses normal auth (API Key only).
|
||||
- **Signed auth** — `cooking create` requires both `GMGN_API_KEY` and `GMGN_PRIVATE_KEY`. The private key never leaves the machine — the CLI uses it only for local signing. `cooking stats` uses exist auth (API Key only).
|
||||
|
||||
- **Slippage** — The initial buy is executed as part of the same transaction as token creation. Slippage applies to that buy. Use `--slippage` (decimal, e.g. `0.01` = 1%) or `--auto-slippage`. One of the two is required when `--buy-amt` is set.
|
||||
|
||||
@@ -43,8 +43,8 @@ Use the `gmgn-cli` tool to create a token on a launchpad platform or query token
|
||||
|
||||
| Sub-command | Description |
|
||||
|-------------|-------------|
|
||||
| `cooking stats` | Get token creation count statistics grouped by launchpad platform (normal auth) |
|
||||
| `cooking create` | Deploy a new token on a launchpad platform (requires private key) |
|
||||
| `cooking stats` | Get token creation count statistics grouped by launchpad platform (exist auth) |
|
||||
| `cooking create` | Deploy a new token on a launchpad platform (signed auth) |
|
||||
|
||||
## Supported Chains
|
||||
|
||||
@@ -364,8 +364,8 @@ Once all information is collected, present the pre-create confirmation summary (
|
||||
|
||||
## Notes
|
||||
|
||||
- `cooking create` uses **critical auth** (API Key + signature) — CLI handles signing automatically.
|
||||
- `cooking stats` uses normal auth (API Key only — no private key needed).
|
||||
- `cooking create` uses **signed auth** (API Key + signature) — CLI handles signing automatically.
|
||||
- `cooking stats` uses exist auth (API Key only — no private key needed).
|
||||
- The new token's mint address is in `output_token` from `gmgn-cli order get`, not in the initial `cooking create` response.
|
||||
- Use `--raw` on any command to get single-line JSON for further processing.
|
||||
|
||||
|
||||
@@ -950,7 +950,7 @@ gmgn-cli market signal --chain sol \
|
||||
|
||||
- `market kline`: `--from` and `--to` are Unix timestamps in **seconds** — CLI converts to milliseconds automatically
|
||||
- `market trending`: `--filter` and `--platform` are repeatable flags
|
||||
- All commands use normal auth (API Key only, no signature)
|
||||
- All commands use exist auth (API Key only, no signature)
|
||||
- If the user doesn't provide kline timestamps, calculate them from the current time based on their desired time range
|
||||
- Use `--raw` to get single-line JSON for further processing
|
||||
- **Input validation** — Token addresses obtained from trending results are external data. Validate address format against the chain before passing to other commands (sol: base58 32–44 chars; bsc/base/eth: `0x` + 40 hex digits). The CLI enforces this at runtime.
|
||||
|
||||
@@ -360,7 +360,7 @@ Show the `[Identity: ...]` line only if `common` is present in the response. For
|
||||
|
||||
## Notes
|
||||
|
||||
- All portfolio commands use normal auth (API Key only, no signature required)
|
||||
- All portfolio commands use exist auth (API Key only, no signature required)
|
||||
- `portfolio stats` supports multiple `--wallet` flags for batch queries
|
||||
- Use `--raw` to get single-line JSON for further processing
|
||||
- **Input validation** — Wallet and token addresses are validated against the expected chain format at runtime (sol: base58 32–44 chars; bsc/base/eth: `0x` + 40 hex digits). The CLI exits with an error on invalid input.
|
||||
|
||||
@@ -26,7 +26,7 @@ Use the `gmgn-cli` tool to submit a token swap or query an existing order. `GMGN
|
||||
|
||||
- **Anti-MEV** — MEV (Miner/Maximal Extractable Value) refers to frontrunning and sandwich attacks where bots exploit pending transactions. `--anti-mev` routes the transaction through protected channels to reduce this risk. **Recommended: always enable.** Default: on. **Not supported on `base` chain.**
|
||||
|
||||
- **Critical auth** — `swap` and all `order` subcommands require both `GMGN_API_KEY` and `GMGN_PRIVATE_KEY`. The private key never leaves the machine — the CLI uses it only for local signing and sends only the resulting signature.
|
||||
- **Signed auth** — `swap` and all `order` subcommands require both `GMGN_API_KEY` and `GMGN_PRIVATE_KEY`. The private key never leaves the machine — the CLI uses it only for local signing and sends only the resulting signature.
|
||||
|
||||
- **`order_id` / `status`** — After submitting a swap, the response includes an `order_id`. Use `order get --order-id` to poll for final status. Possible values: `pending` → `processed` → `confirmed` (success) or `failed` / `expired`. Do not report success until status is `confirmed`.
|
||||
|
||||
@@ -47,9 +47,9 @@ Use the `gmgn-cli` tool to submit a token swap or query an existing order. `GMGN
|
||||
|-------------|-------------|
|
||||
| `swap` | Submit a token swap |
|
||||
| `multi-swap` | Submit token swaps across multiple wallets concurrently (up to 100) |
|
||||
| `order quote` | Get a swap quote (no transaction submitted; requires critical auth) |
|
||||
| `order quote` | Get a swap quote (no transaction submitted; requires signed auth) |
|
||||
| `order get` | Query order status |
|
||||
| `gas-price` | Query recommended gas price (low / average / high tiers) for any chain; normal auth |
|
||||
| `gas-price` | Query recommended gas price (low / average / high tiers) for any chain; exist auth (API Key only) |
|
||||
| `order strategy create` | Create a limit/strategy order (requires private key) |
|
||||
| `order strategy list` | List strategy orders (requires private key) |
|
||||
| `order strategy cancel` | Cancel a strategy order (requires private key) |
|
||||
@@ -291,7 +291,7 @@ gmgn-cli swap \
|
||||
|
||||
### Pre-swap Confirmation
|
||||
|
||||
Before displaying the confirmation, run `order quote` to get the estimated output (requires critical auth and `GMGN_PRIVATE_KEY` on every supported quote chain):
|
||||
Before displaying the confirmation, run `order quote` to get the estimated output (requires signed auth and `GMGN_PRIVATE_KEY` on every supported quote chain):
|
||||
|
||||
```bash
|
||||
gmgn-cli order quote \
|
||||
@@ -430,7 +430,7 @@ The response `data` is an array — one element per wallet:
|
||||
|
||||
## `order quote` Usage
|
||||
|
||||
Get an estimated output amount before submitting a swap. All supported quote chains use critical auth and require `GMGN_PRIVATE_KEY`.
|
||||
Get an estimated output amount before submitting a swap. All supported quote chains use signed auth and require `GMGN_PRIVATE_KEY`.
|
||||
|
||||
```bash
|
||||
gmgn-cli order quote \
|
||||
@@ -467,7 +467,7 @@ Response fields are shared with `swap` — see [`swap` / `order get` Response Fi
|
||||
|
||||
## `gas-price` Usage
|
||||
|
||||
Query recommended gas price tiers for any chain. Uses normal auth (API Key only — no private key required).
|
||||
Query recommended gas price tiers for any chain. API Key only — no signature or private key required.
|
||||
|
||||
```bash
|
||||
gmgn-cli gas-price --chain eth
|
||||
@@ -632,10 +632,10 @@ gmgn-cli order strategy cancel \
|
||||
|
||||
## Notes
|
||||
|
||||
- Swap uses **critical auth** (API Key + signature) — CLI handles signing automatically, no manual processing needed
|
||||
- Swap uses **signed auth** (API Key + signature) — CLI handles signing automatically, no manual processing needed
|
||||
- After submitting a swap, use `order get` to poll for confirmation
|
||||
- `--amount` is in the **smallest unit** (e.g., lamports for SOL)
|
||||
- `order strategy create`, `order strategy list`, and `order strategy cancel` use critical auth (require `GMGN_PRIVATE_KEY`)
|
||||
- `order strategy create`, `order strategy list`, and `order strategy cancel` use signed auth (require `GMGN_PRIVATE_KEY`)
|
||||
- Use `--raw` to get single-line JSON for further processing
|
||||
- **Chain restrictions for fee flags** — see the `Chain` column in each parameter table above. `--priority-fee` and `--tip-fee` are SOL/BSC only; `--gas-price`, `--max-fee-per-gas`, `--max-priority-fee-per-gas` are BSC/BASE/ETH only; `--gas-level` and `--auto-fee` are ETH only. The server returns 400 if a chain-restricted flag is sent on the wrong chain. (`gas-price` itself supports all four chains including `sol`.)
|
||||
- **EIP-1559 minimum values per chain:**
|
||||
@@ -680,7 +680,7 @@ For full token research before swapping, see [`docs/workflow-token-research.md`]
|
||||
|
||||
## Execution Guidelines
|
||||
|
||||
- **[REQUIRED] Token security check** — Run before every swap. See **Pre-Swap Safety Check (REQUIRED)** section above. Uses normal auth (API Key only — no private key needed for this step).
|
||||
- **[REQUIRED] Token security check** — Run before every swap. See **Pre-Swap Safety Check (REQUIRED)** section above. Uses exist auth (API Key only — no private key needed for this step).
|
||||
- **Currency resolution** — When the user names a currency (SOL/BNB/ETH/USDC) instead of providing an address, look up its address in the Chain Currencies table and apply it automatically — never ask the user for it.
|
||||
- Buy ("buy X SOL of TOKEN", "spend 0.5 USDC on TOKEN") → resolve currency to `--input-token`
|
||||
- Sell ("sell TOKEN for SOL", "sell 50% of TOKEN to USDC") → resolve currency to `--output-token`
|
||||
|
||||
@@ -725,7 +725,7 @@ Show top rows only. Highlight wallets tagged `kol`, `smart_degen`, or flagged `b
|
||||
|
||||
- **Market cap is not returned directly** — calculate it as `price.price × circulating_supply` (`price` is now a nested object; use `price.price` for the current USD price string, and `circulating_supply` is a top-level field already in human-readable token units). Example: `price.price="3.11"` × `circulating_supply=999999151` ≈ $3.11B market cap.
|
||||
- **Trading volume (1h, 24h, etc.) is not included in `token info`** — to get volume or OHLCV data, use the `gmgn-market` skill and query K-line data: `gmgn-cli market kline --chain <chain> --address <token_address> --resolution <1m|5m|15m|1h|4h|1d>`. See the `gmgn-market` SKILL.md for full details.
|
||||
- All token commands use normal auth (API Key only, no signature required)
|
||||
- All token commands use exist auth (API Key only, no signature required)
|
||||
- Use `--raw` to get single-line JSON for further processing
|
||||
- `--tag` applies to both `holders` and `traders` and filters to only wallets with that tag — if few results are returned, try the other tag value
|
||||
- `amount_percentage` in holders/traders is a ratio (0–1), not a percentage — `0.05` means 5% of supply
|
||||
|
||||
@@ -61,7 +61,7 @@ Use the `gmgn-cli` tool to query on-chain tracking data based on the user's requ
|
||||
|
||||
- `gmgn-cli` installed globally — if missing, run: `npm install -g gmgn-cli`
|
||||
- `GMGN_API_KEY` configured in `~/.config/gmgn/.env` — required for all sub-commands
|
||||
- `GMGN_PRIVATE_KEY` — required for `track follow-wallet` only (critical auth); not needed for `kol` or `smartmoney`
|
||||
- `GMGN_PRIVATE_KEY` — required for `track follow-wallet` only (signed auth); not needed for `kol` or `smartmoney`
|
||||
|
||||
## Rate Limit Handling
|
||||
|
||||
@@ -311,7 +311,7 @@ To research any token surfaced by smart money activity, follow [`docs/workflow-t
|
||||
|
||||
## Notes
|
||||
|
||||
- `track follow-wallet` uses critical auth (API Key + private key signature); `track kol` and `track smartmoney` use normal auth (API Key only)
|
||||
- `track follow-wallet` uses signed auth (API Key + private key signature); `track kol` and `track smartmoney` use exist auth (API Key only)
|
||||
- `track follow-wallet` returns trades from wallets followed on the GMGN platform; the follow list is resolved automatically from the GMGN user account bound to the API Key — `--wallet` is optional
|
||||
- Use `--raw` to get single-line JSON for further processing
|
||||
- `track kol` / `track smartmoney` `--side` is a **client-side filter** — the CLI fetches all results then filters locally; it is NOT sent to the API
|
||||
|
||||
+39
-39
@@ -2,8 +2,8 @@
|
||||
* OpenApiClient — GMGN OpenAPI external client
|
||||
*
|
||||
* Auth modes:
|
||||
* Normal (market/token/portfolio): X-APIKEY + timestamp + client_id
|
||||
* Critical (swap and order routes): normal auth + X-Signature (private key signature)
|
||||
* Exist (market/token/portfolio): X-APIKEY + timestamp + client_id
|
||||
* Signed (swap and order routes): X-APIKEY + timestamp + client_id + X-Signature (private key signature)
|
||||
*/
|
||||
|
||||
import { buildAuthQuery, buildMessage, detectAlgorithm, sign } from "./signer.js";
|
||||
@@ -204,29 +204,29 @@ export class OpenApiClient {
|
||||
this.host = config.host.replace(/\/$/, "");
|
||||
}
|
||||
|
||||
// ---- Token endpoints (normal auth) ----
|
||||
// ---- Token endpoints (exist auth) ----
|
||||
|
||||
async getTokenInfo(chain: string, address: string): Promise<unknown> {
|
||||
return this.normalRequest("GET", "/v1/token/info", { chain, address });
|
||||
return this.authExistRequest("GET", "/v1/token/info", { chain, address });
|
||||
}
|
||||
|
||||
async getTokenSecurity(chain: string, address: string): Promise<unknown> {
|
||||
return this.normalRequest("GET", "/v1/token/security", { chain, address });
|
||||
return this.authExistRequest("GET", "/v1/token/security", { chain, address });
|
||||
}
|
||||
|
||||
async getTokenPoolInfo(chain: string, address: string): Promise<unknown> {
|
||||
return this.normalRequest("GET", "/v1/token/pool_info", { chain, address });
|
||||
return this.authExistRequest("GET", "/v1/token/pool_info", { chain, address });
|
||||
}
|
||||
|
||||
async getTokenTopHolders(chain: string, address: string, extra: Record<string, string | number> = {}): Promise<unknown> {
|
||||
return this.normalRequest("GET", "/v1/market/token_top_holders", { chain, address, ...extra });
|
||||
return this.authExistRequest("GET", "/v1/market/token_top_holders", { chain, address, ...extra });
|
||||
}
|
||||
|
||||
async getTokenTopTraders(chain: string, address: string, extra: Record<string, string | number> = {}): Promise<unknown> {
|
||||
return this.normalRequest("GET", "/v1/market/token_top_traders", { chain, address, ...extra });
|
||||
return this.authExistRequest("GET", "/v1/market/token_top_traders", { chain, address, ...extra });
|
||||
}
|
||||
|
||||
// ---- Market endpoints (normal auth) ----
|
||||
// ---- Market endpoints (exist auth) ----
|
||||
|
||||
async getTokenKline(
|
||||
chain: string,
|
||||
@@ -238,17 +238,17 @@ export class OpenApiClient {
|
||||
const query: Record<string, string | number> = { chain, address, resolution };
|
||||
if (from != null) query["from"] = from;
|
||||
if (to != null) query["to"] = to;
|
||||
return this.normalRequest("GET", "/v1/market/token_kline", query);
|
||||
return this.authExistRequest("GET", "/v1/market/token_kline", query);
|
||||
}
|
||||
|
||||
// ---- Portfolio endpoints (normal auth) ----
|
||||
// ---- Portfolio endpoints (exist auth) ----
|
||||
|
||||
async getWalletHoldings(
|
||||
chain: string,
|
||||
walletAddress: string,
|
||||
extra: Record<string, string | number> = {}
|
||||
): Promise<unknown> {
|
||||
return this.normalRequest("GET", "/v1/user/wallet_holdings", {
|
||||
return this.authExistRequest("GET", "/v1/user/wallet_holdings", {
|
||||
chain,
|
||||
wallet_address: walletAddress,
|
||||
...extra,
|
||||
@@ -260,7 +260,7 @@ export class OpenApiClient {
|
||||
walletAddress: string,
|
||||
extra: Record<string, string | number | string[]> = {}
|
||||
): Promise<unknown> {
|
||||
return this.normalRequest("GET", "/v1/user/wallet_activity", {
|
||||
return this.authExistRequest("GET", "/v1/user/wallet_activity", {
|
||||
chain,
|
||||
wallet_address: walletAddress,
|
||||
...extra,
|
||||
@@ -268,7 +268,7 @@ export class OpenApiClient {
|
||||
}
|
||||
|
||||
async getWalletStats(chain: string, walletAddresses: string[], period = "7d"): Promise<unknown> {
|
||||
return this.normalRequest("GET", "/v1/user/wallet_stats", {
|
||||
return this.authExistRequest("GET", "/v1/user/wallet_stats", {
|
||||
chain,
|
||||
wallet_address: walletAddresses,
|
||||
period,
|
||||
@@ -280,54 +280,54 @@ export class OpenApiClient {
|
||||
walletAddress: string,
|
||||
tokenAddress: string
|
||||
): Promise<unknown> {
|
||||
return this.normalRequest("GET", "/v1/user/wallet_token_balance", { chain, wallet_address: walletAddress, token_address: tokenAddress });
|
||||
return this.authExistRequest("GET", "/v1/user/wallet_token_balance", { chain, wallet_address: walletAddress, token_address: tokenAddress });
|
||||
}
|
||||
|
||||
async getTrenches(chain: string, types?: string[], platforms?: string[], limit?: number, filters?: Record<string, number | string>): Promise<unknown> {
|
||||
const body = buildTrenchesBody(chain, types, platforms, limit, filters);
|
||||
return this.normalRequest("POST", "/v1/trenches", { chain }, body);
|
||||
return this.authExistRequest("POST", "/v1/trenches", { chain }, body);
|
||||
}
|
||||
|
||||
// ---- Market trending endpoints (normal auth) ----
|
||||
// ---- Market trending endpoints (exist auth) ----
|
||||
|
||||
async getTrendingSwaps(
|
||||
chain: string,
|
||||
interval: string,
|
||||
extra: Record<string, string | number | string[]> = {}
|
||||
): Promise<unknown> {
|
||||
return this.normalRequest("GET", "/v1/market/rank", { chain, interval, ...extra });
|
||||
return this.authExistRequest("GET", "/v1/market/rank", { chain, interval, ...extra });
|
||||
}
|
||||
|
||||
async getTokenSignalV2(chain: string, groups: TokenSignalGroup[]): Promise<unknown> {
|
||||
return this.normalRequest("POST", "/v1/market/token_signal", {}, { chain, groups });
|
||||
return this.authExistRequest("POST", "/v1/market/token_signal", {}, { chain, groups });
|
||||
}
|
||||
|
||||
// ---- User endpoints (normal auth) ----
|
||||
// ---- User endpoints (exist auth) ----
|
||||
|
||||
async getUserInfo(): Promise<unknown> {
|
||||
return this.normalRequest("GET", "/v1/user/info", {});
|
||||
return this.authExistRequest("GET", "/v1/user/info", {});
|
||||
}
|
||||
|
||||
async getFollowWallet(chain: string, extra: Record<string, string | number | string[]> = {}): Promise<unknown> {
|
||||
return this.criticalRequest("GET", "/v1/trade/follow_wallet", { chain, ...extra }, null);
|
||||
return this.authSignedRequest("GET", "/v1/trade/follow_wallet", { chain, ...extra }, null);
|
||||
}
|
||||
|
||||
async getKol(chain?: string, limit?: number): Promise<unknown> {
|
||||
const query: Record<string, string | number> = {};
|
||||
if (chain) query["chain"] = chain;
|
||||
if (limit != null) query["limit"] = limit;
|
||||
return this.normalRequest("GET", "/v1/user/kol", query);
|
||||
return this.authExistRequest("GET", "/v1/user/kol", query);
|
||||
}
|
||||
|
||||
async getSmartMoney(chain?: string, limit?: number): Promise<unknown> {
|
||||
const query: Record<string, string | number> = {};
|
||||
if (chain) query["chain"] = chain;
|
||||
if (limit != null) query["limit"] = limit;
|
||||
return this.normalRequest("GET", "/v1/user/smartmoney", query);
|
||||
return this.authExistRequest("GET", "/v1/user/smartmoney", query);
|
||||
}
|
||||
|
||||
async getCreatedTokens(chain: string, walletAddress: string, extra: Record<string, string | number> = {}): Promise<unknown> {
|
||||
return this.normalRequest("GET", "/v1/user/created_tokens", { chain, wallet_address: walletAddress, ...extra });
|
||||
return this.authExistRequest("GET", "/v1/user/created_tokens", { chain, wallet_address: walletAddress, ...extra });
|
||||
}
|
||||
|
||||
async quoteOrder(
|
||||
@@ -339,54 +339,54 @@ export class OpenApiClient {
|
||||
slippage: number
|
||||
): Promise<unknown> {
|
||||
const query = { chain, from_address, input_token, output_token, input_amount, slippage };
|
||||
return this.criticalRequest("GET", "/v1/trade/quote", query, null);
|
||||
return this.authSignedRequest("GET", "/v1/trade/quote", query, null);
|
||||
}
|
||||
|
||||
// ---- Swap endpoints (critical auth) ----
|
||||
// ---- Swap endpoints (signed auth) ----
|
||||
|
||||
async swap(params: SwapParams): Promise<unknown> {
|
||||
return this.criticalRequest("POST", "/v1/trade/swap", {}, params);
|
||||
return this.authSignedRequest("POST", "/v1/trade/swap", {}, params);
|
||||
}
|
||||
|
||||
async multiSwap(params: MultiSwapParams): Promise<unknown> {
|
||||
return this.criticalRequest("POST", "/v1/trade/multi_swap", {}, params);
|
||||
return this.authSignedRequest("POST", "/v1/trade/multi_swap", {}, params);
|
||||
}
|
||||
|
||||
async queryOrder(orderId: string, chain: string): Promise<unknown> {
|
||||
return this.criticalRequest("GET", "/v1/trade/query_order", { order_id: orderId, chain }, null);
|
||||
return this.authSignedRequest("GET", "/v1/trade/query_order", { order_id: orderId, chain }, null);
|
||||
}
|
||||
|
||||
async getGasPrice(chain: string): Promise<unknown> {
|
||||
return this.normalRequest("GET", "/v1/trade/gas_price", { chain });
|
||||
return this.authExistRequest("GET", "/v1/trade/gas_price", { chain });
|
||||
}
|
||||
|
||||
// ---- Strategy order endpoints (critical auth) ----
|
||||
// ---- Strategy order endpoints (signed auth) ----
|
||||
|
||||
async createStrategyOrder(params: StrategyCreateParams): Promise<unknown> {
|
||||
return this.criticalRequest("POST", "/v1/trade/strategy/create", {}, params);
|
||||
return this.authSignedRequest("POST", "/v1/trade/strategy/create", {}, params);
|
||||
}
|
||||
|
||||
async getStrategyOrders(chain: string, extra: Record<string, string | number> = {}): Promise<unknown> {
|
||||
return this.criticalRequest("GET", "/v1/trade/strategy/orders", { chain, ...extra }, null);
|
||||
return this.authSignedRequest("GET", "/v1/trade/strategy/orders", { chain, ...extra }, null);
|
||||
}
|
||||
|
||||
async cancelStrategyOrder(params: StrategyCancelParams): Promise<unknown> {
|
||||
return this.criticalRequest("POST", "/v1/trade/strategy/cancel", {}, params);
|
||||
return this.authSignedRequest("POST", "/v1/trade/strategy/cancel", {}, params);
|
||||
}
|
||||
|
||||
// ---- Cooking endpoints ----
|
||||
|
||||
async getCookingStatistics(): Promise<unknown> {
|
||||
return this.normalRequest("GET", "/v1/cooking/statistics", {});
|
||||
return this.authExistRequest("GET", "/v1/cooking/statistics", {});
|
||||
}
|
||||
|
||||
async createToken(params: CreateTokenParams): Promise<unknown> {
|
||||
return this.criticalRequest("POST", "/v1/cooking/create_token", {}, params);
|
||||
return this.authSignedRequest("POST", "/v1/cooking/create_token", {}, params);
|
||||
}
|
||||
|
||||
// ---- Internal methods ----
|
||||
|
||||
private async normalRequest(
|
||||
private async authExistRequest(
|
||||
method: string,
|
||||
subPath: string,
|
||||
queryExtra: Record<string, string | number | string[]>,
|
||||
@@ -412,7 +412,7 @@ export class OpenApiClient {
|
||||
}, true);
|
||||
}
|
||||
|
||||
private async criticalRequest(
|
||||
private async authSignedRequest(
|
||||
method: string,
|
||||
subPath: string,
|
||||
queryExtra: Record<string, string | number | string[]>,
|
||||
|
||||
@@ -30,7 +30,7 @@ export function buildAuthQuery(): { timestamp: number; client_id: string } {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the signature message (critical auth)
|
||||
* Build the signature message (signed auth)
|
||||
* Format: {sub_path}:{sorted_query_string}:{request_body}:{timestamp}
|
||||
* sorted_query_string: all query params (including timestamp, client_id) sorted alphabetically by key.
|
||||
* Array values are serialized as repeated k=v pairs (same as buildUrl / URLSearchParams), sorted by value.
|
||||
|
||||
@@ -9,7 +9,7 @@ export function registerCookingCommands(program: Command): void {
|
||||
|
||||
cooking
|
||||
.command("stats")
|
||||
.description("Get token creation statistics by launchpad (normal auth)")
|
||||
.description("Get token creation statistics by launchpad (exist auth)")
|
||||
.option("--raw", "Output raw JSON")
|
||||
.action(async (opts) => {
|
||||
const client = new OpenApiClient(getConfig());
|
||||
|
||||
@@ -149,7 +149,7 @@ export function registerSwapCommands(program: Command): void {
|
||||
|
||||
order
|
||||
.command("quote")
|
||||
.description("Get a swap quote without submitting a transaction (requires critical auth)")
|
||||
.description("Get a swap quote without submitting a transaction (signed auth — requires GMGN_PRIVATE_KEY)")
|
||||
.requiredOption("--chain <chain>", "Chain: sol / bsc / base / eth (requires GMGN_PRIVATE_KEY)")
|
||||
.requiredOption("--from <address>", "Wallet address (must match API Key binding)")
|
||||
.requiredOption("--input-token <address>", "Input token contract address")
|
||||
@@ -185,7 +185,7 @@ export function registerSwapCommands(program: Command): void {
|
||||
|
||||
program
|
||||
.command("gas-price")
|
||||
.description("Query recommended gas price tiers for any chain (normal auth; eth / bsc / base / sol)")
|
||||
.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")
|
||||
.option("--raw", "Output raw JSON")
|
||||
.action(async (opts) => {
|
||||
|
||||
Reference in New Issue
Block a user