gmgn-cli 1.4.9 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function registerConfigCommands(program: Command): void;
3
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyGpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgD7D"}
@@ -0,0 +1,138 @@
1
+ import { config as loadDotenv } from "dotenv";
2
+ import * as crypto from "crypto";
3
+ import * as fs from "fs";
4
+ import * as path from "path";
5
+ import * as os from "os";
6
+ import { execSync } from "child_process";
7
+ const GMGN_CONFIG_DIR = path.join(os.homedir(), ".config", "gmgn");
8
+ const KEYPAIR_FILE = path.join(GMGN_CONFIG_DIR, "keypair.pem");
9
+ const ENV_FILE = path.join(GMGN_CONFIG_DIR, ".env");
10
+ const GMGN_API_URL = "https://gmgn.ai/ai/generateapi";
11
+ function detectLang() {
12
+ const locale = process.env.LANG ||
13
+ process.env.LC_ALL ||
14
+ process.env.LC_MESSAGES ||
15
+ Intl.DateTimeFormat().resolvedOptions().locale ||
16
+ "en";
17
+ const l = locale.toLowerCase();
18
+ if (l.startsWith("zh_tw") || l.startsWith("zh-tw") || l.startsWith("zh_hk") || l.startsWith("zh-hk"))
19
+ return "zh-TW";
20
+ if (l.startsWith("zh"))
21
+ return "zh-CN";
22
+ return "en";
23
+ }
24
+ const MESSAGES = {
25
+ linkGuide: {
26
+ "zh-CN": (link) => `请点击下方链接创建你的 GMGN API Key,完成后将 Key 发给我,我来帮你完成配置:\n${link}`,
27
+ "zh-TW": (link) => `請點擊下方連結建立你的 GMGN API Key,完成後將 Key 發給我,我來幫你完成配置:\n${link}`,
28
+ en: (link) => `Please click the link below to create your GMGN API Key. Once created, send me the API Key and I will finish the configuration:\n${link}`,
29
+ },
30
+ verifySuccess: {
31
+ "zh-CN": "配置验证成功,可以开始使用了。",
32
+ "zh-TW": "配置驗證成功,可以開始使用了。",
33
+ en: "Configuration verified successfully. You are ready to use GMGN.",
34
+ },
35
+ verifyFail: {
36
+ "zh-CN": "配置验证失败:API Key 与本地密钥不匹配。\n请确认:\n1. API Key 是否填写正确;\n2. 创建 API Key 时,是否使用的是页面自动填入的公钥。",
37
+ "zh-TW": "配置驗證失敗:API Key 與本地密鑰不匹配。\n請確認:\n1. API Key 是否填寫正確;\n2. 創建 API Key 時,是否使用的是頁面自動填入的公鑰。",
38
+ en: "Configuration verification failed: API Key does not match your local key pair.\nPlease confirm:\n1. Whether the API Key was entered correctly.\n2. Whether you used the public key that was pre-filled on the page when creating the API Key.",
39
+ },
40
+ verifyNetworkFail: {
41
+ "zh-CN": "配置已写入,但验证请求失败(可能是网络问题)。你可以先尝试使用,如遇接口报错再重新配置。",
42
+ "zh-TW": "配置已寫入,但驗證請求失敗(可能是網路問題)。你可以先嘗試使用,如遇介面報錯再重新配置。",
43
+ en: "Configuration saved, but the verification request failed (possibly a network issue). You can try using it now and reconfigure if you encounter API errors.",
44
+ },
45
+ };
46
+ function getOrCreateKeypair() {
47
+ fs.mkdirSync(GMGN_CONFIG_DIR, { recursive: true });
48
+ if (fs.existsSync(KEYPAIR_FILE)) {
49
+ const content = fs.readFileSync(KEYPAIR_FILE, "utf-8");
50
+ const match = content.match(/(-----BEGIN PUBLIC KEY-----[\s\S]+?-----END PUBLIC KEY-----)/);
51
+ if (!match) {
52
+ console.error("Error: keypair.pem exists but public key could not be parsed. Delete ~/.config/gmgn/keypair.pem and try again.");
53
+ process.exit(1);
54
+ }
55
+ return match[1] + "\n";
56
+ }
57
+ const { privateKey, publicKey } = crypto.generateKeyPairSync("ed25519");
58
+ const privatePem = privateKey.export({ type: "pkcs8", format: "pem" });
59
+ const publicPem = publicKey.export({ type: "spki", format: "pem" });
60
+ const entry = `# Private Key\n${privatePem}\n# Public Key\n${publicPem}\n`;
61
+ fs.writeFileSync(KEYPAIR_FILE, entry, { mode: 0o600 });
62
+ return publicPem;
63
+ }
64
+ function writeEnv(apiKey, privatePem) {
65
+ const pkOneLine = privatePem.replace(/\r?\n/g, "\\n");
66
+ let existing = fs.existsSync(ENV_FILE) ? fs.readFileSync(ENV_FILE, "utf-8") : "";
67
+ existing = existing
68
+ .split("\n")
69
+ .filter((l) => !/^GMGN_API_KEY=|^GMGN_PRIVATE_KEY=/.test(l))
70
+ .join("\n")
71
+ .trim();
72
+ const content = (existing ? existing + "\n" : "") + `GMGN_API_KEY=${apiKey}\nGMGN_PRIVATE_KEY=${pkOneLine}\n`;
73
+ fs.mkdirSync(GMGN_CONFIG_DIR, { recursive: true });
74
+ fs.writeFileSync(ENV_FILE, content, { mode: 0o600 });
75
+ }
76
+ function verify() {
77
+ try {
78
+ execSync("gmgn-cli track follow-wallet --chain sol --limit 1", { stdio: "pipe" });
79
+ return "ok";
80
+ }
81
+ catch (e) {
82
+ const output = [
83
+ e.stderr?.toString() ?? "",
84
+ e.stdout?.toString() ?? "",
85
+ ].join(" ");
86
+ if (/401|403|unauthorized|forbidden|invalid.*key|key.*invalid|signature/i.test(output)) {
87
+ return "auth_fail";
88
+ }
89
+ return "network_fail";
90
+ }
91
+ }
92
+ export function registerConfigCommands(program) {
93
+ const cmd = program
94
+ .command("config")
95
+ .description("Generate an Ed25519 key pair and output a pre-filled GMGN API Key creation link, or apply an API Key");
96
+ cmd
97
+ .option("--check", "Check if GMGN_API_KEY is configured (exit 0 = found, exit 1 = not found)")
98
+ .option("--apply <api_key>", "Write API Key + private key to ~/.config/gmgn/.env and verify")
99
+ .action(async (opts) => {
100
+ const lang = detectLang();
101
+ if (opts.check) {
102
+ loadDotenv({ path: ENV_FILE, override: true });
103
+ loadDotenv();
104
+ process.exit(process.env.GMGN_API_KEY ? 0 : 1);
105
+ }
106
+ if (opts.apply) {
107
+ // --apply: read private key from keypair.pem, write .env, verify
108
+ if (!fs.existsSync(KEYPAIR_FILE)) {
109
+ console.error("Error: ~/.config/gmgn/keypair.pem not found. Run `gmgn-cli config` first to generate a key pair.");
110
+ process.exit(1);
111
+ }
112
+ const content = fs.readFileSync(KEYPAIR_FILE, "utf-8");
113
+ const match = content.match(/(-----BEGIN PRIVATE KEY-----[\s\S]+?-----END PRIVATE KEY-----)/);
114
+ if (!match) {
115
+ console.error("Error: keypair.pem exists but private key could not be parsed. Delete ~/.config/gmgn/keypair.pem and run `gmgn-cli config` again.");
116
+ process.exit(1);
117
+ }
118
+ writeEnv(opts.apply, match[1]);
119
+ const result = verify();
120
+ if (result === "ok") {
121
+ console.log(MESSAGES.verifySuccess[lang]);
122
+ }
123
+ else if (result === "auth_fail") {
124
+ console.error(MESSAGES.verifyFail[lang]);
125
+ process.exit(1);
126
+ }
127
+ else {
128
+ console.log(MESSAGES.verifyNetworkFail[lang]);
129
+ }
130
+ return;
131
+ }
132
+ // Default: generate/reuse keypair, output link with guidance
133
+ const publicPem = getOrCreateKeypair();
134
+ const link = `${GMGN_API_URL}?pbk=${encodeURIComponent(publicPem)}`;
135
+ console.log(MESSAGES.linkGuide[lang](link));
136
+ });
137
+ }
138
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -11,6 +11,7 @@ import { registerPortfolioCommands } from "./commands/portfolio.js";
11
11
  import { registerTrackCommands } from "./commands/track.js";
12
12
  import { registerSwapCommands } from "./commands/swap.js";
13
13
  import { registerCookingCommands } from "./commands/cooking.js";
14
+ import { registerConfigCommands } from "./commands/config.js";
14
15
  const proxy = process.env.HTTPS_PROXY ?? process.env.https_proxy
15
16
  ?? process.env.HTTP_PROXY ?? process.env.http_proxy;
16
17
  if (proxy) {
@@ -60,6 +61,7 @@ registerPortfolioCommands(program);
60
61
  registerTrackCommands(program);
61
62
  registerSwapCommands(program);
62
63
  registerCookingCommands(program);
64
+ registerConfigCommands(program);
63
65
  program.parseAsync().catch((err) => {
64
66
  console.error(`[gmgn-cli] ${err.message}`);
65
67
  process.exit(1);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,MAAM,EAAE,OAAO,EAAE,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAwB,CAAC;AAC7F,OAAO,EAAE,mBAAmB,EAAE,UAAU,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAChF,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACpC,OAAO,KAAK,GAAG,MAAM,KAAK,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW;OAClD,OAAO,CAAC,GAAG,CAAC,UAAU,IAAK,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;AAChE,IAAI,KAAK,EAAE,CAAC;IACV,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IACzB,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACzD,MAAM,IAAI,GAAG,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,mBAAmB,CAAC,IAAI,KAAK,CAAC;YAC5B,8DAA8D;YAC9D,OAAO,EAAE,KAAK,EAAE,OAAY,EAAE,QAAa,EAAE,EAAE;gBAC7C,IAAI,CAAC;oBACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,WAAW,CAAC,gBAAgB,CAAC;wBACpD,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC,EAAE,IAAI,EAAE;wBACnE,OAAO,EAAE,SAAS;wBAClB,WAAW,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,QAAS,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,IAAK,EAAE;wBAC9D,cAAc,EAAE,EAAE,MAAM,EAAE,CAAC,EAAS;qBACrC,CAAC,CAAC;oBACH,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;wBAClC,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,QAAQ,EAAE,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC;oBAClI,CAAC;yBAAM,CAAC;wBACN,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;oBACzB,CAAC;gBACH,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,QAAQ,CAAC,GAAY,EAAE,IAAI,CAAC,CAAC;gBAC/B,CAAC;YACH,CAAC;SACF,CAAC,CAAC,CAAC;IACN,CAAC;SAAM,CAAC;QACN,mBAAmB,CAAC,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC;KAAM,CAAC;IACN,iDAAiD;IACjD,MAAM,SAAS,GAAG,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC,EAAS,CAAC,CAAC;IACvD,mBAAmB,CAAC,IAAI,KAAK,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC;AACzD,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,+FAA+F,CAAC,CAAC;AAEhH,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAChC,yBAAyB,CAAC,OAAO,CAAC,CAAC;AACnC,qBAAqB,CAAC,OAAO,CAAC,CAAC;AAC/B,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACjC,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAEhC,OAAO,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACjC,OAAO,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gmgn-cli",
3
- "version": "1.4.9",
3
+ "version": "1.5.0",
4
4
  "description": "GMGN OpenAPI CLI — call GMGN market, token, portfolio and swap APIs from the command line",
5
5
  "type": "module",
6
6
  "bin": {
@@ -6,6 +6,8 @@ metadata:
6
6
  cliHelp: "gmgn-cli cooking --help"
7
7
  ---
8
8
 
9
+ **BEFORE RUNNING ANY COMMAND: Run `gmgn-cli config --check`. If exit code is 0, proceed normally. If exit code is 1, (1) run `gmgn-cli config` and show the output to the user; (2) once the user sends the API Key, run `gmgn-cli config --apply <KEY>` to complete configuration and verification, then show the output to the user. If `--check` returns an error (unknown option or command not found), tell the user to run `npm install -g gmgn-cli` to update, then retry.**
10
+
9
11
  **IMPORTANT: Always use `gmgn-cli` commands below. Do NOT use web search, WebFetch, curl, or visit gmgn.ai — all token creation operations must go through the CLI. The CLI handles signing and submission automatically.**
10
12
 
11
13
  **IMPORTANT: Do NOT guess field names or values. When a field's meaning is unclear, look it up in the Response Fields sections below before using it.**
@@ -100,23 +102,6 @@ When a request returns `429`:
100
102
  - `cooking create` is a real transaction: **never loop or auto-resubmit** after a `429`. Wait until the reset time, then ask for confirmation again before retrying.
101
103
  - For `RATE_LIMIT_EXCEEDED` or `RATE_LIMIT_BANNED`, repeated requests during cooldown extend the ban by 5 seconds each time, up to 5 minutes.
102
104
 
103
- **First-time setup** (if credentials are not configured):
104
-
105
- 1. Generate key pair and show the public key to the user:
106
- ```bash
107
- openssl genpkey -algorithm ed25519 -out /tmp/gmgn_private.pem 2>/dev/null && \
108
- openssl pkey -in /tmp/gmgn_private.pem -pubout 2>/dev/null
109
- ```
110
- Tell the user: *"This is your Ed25519 public key. Go to **https://gmgn.ai/ai**, paste it into the API key creation form (enable swap/cooking capability), then send me the API Key value shown on the page."*
111
-
112
- 2. Wait for the user's API key, then configure both credentials:
113
- ```bash
114
- mkdir -p ~/.config/gmgn
115
- echo 'GMGN_API_KEY=<key_from_user>' > ~/.config/gmgn/.env
116
- echo 'GMGN_PRIVATE_KEY="<pem_content_from_step_1>"' >> ~/.config/gmgn/.env
117
- chmod 600 ~/.config/gmgn/.env
118
- ```
119
-
120
105
  ### Credential Model
121
106
 
122
107
  - `GMGN_PRIVATE_KEY` is used exclusively for **local message signing** — the private key never leaves the machine. The CLI computes an Ed25519 signature in-process and transmits only the base64-encoded result in the `X-Signature` request header.
@@ -6,6 +6,8 @@ metadata:
6
6
  cliHelp: "gmgn-cli market --help"
7
7
  ---
8
8
 
9
+ **BEFORE RUNNING ANY COMMAND: Run `gmgn-cli config --check`. If exit code is 0, proceed normally. If exit code is 1, (1) run `gmgn-cli config` and show the output to the user; (2) once the user sends the API Key, run `gmgn-cli config --apply <KEY>` to complete configuration and verification, then show the output to the user. If `--check` returns an error (unknown option or command not found), tell the user to run `npm install -g gmgn-cli` to update, then retry.**
10
+
9
11
  **IMPORTANT: Always use `gmgn-cli` commands below. Do NOT use web search, WebFetch, curl, or visit gmgn.ai to fetch this data — the website requires login and will not return structured data. The CLI is the only correct method.**
10
12
 
11
13
  **IMPORTANT: Do NOT guess field names or values. When a field's meaning is unclear, look it up in the Response Fields sections below before using it.**
@@ -79,20 +81,6 @@ When a request returns `429`:
79
81
  - The CLI may wait and retry once automatically when the remaining cooldown is short. If it still fails, stop and tell the user the exact retry time instead of sending more requests.
80
82
  - For `RATE_LIMIT_EXCEEDED` or `RATE_LIMIT_BANNED`, repeated requests during the cooldown can extend the ban by 5 seconds each time, up to 5 minutes. Do not spam retries.
81
83
 
82
- **First-time setup** (if `GMGN_API_KEY` is not configured):
83
-
84
- 1. Generate key pair and show the public key to the user:
85
- ```bash
86
- openssl genpkey -algorithm ed25519 -out /tmp/gmgn_private.pem 2>/dev/null && \
87
- openssl pkey -in /tmp/gmgn_private.pem -pubout 2>/dev/null
88
- ```
89
- Tell the user: *"This is your Ed25519 public key. Go to **https://gmgn.ai/ai**, paste it into the API key creation form, then send me the API Key value shown on the page."*
90
-
91
- 2. Wait for the user's API key, then save it with `gmgn-cli config` (creates `~/.config/gmgn/.env` and sets `chmod 600` automatically — do not hand-edit the file):
92
- ```bash
93
- gmgn-cli config set-key <key_from_user>
94
- ```
95
-
96
84
  ## `market kline` Parameters
97
85
 
98
86
  | Parameter | Required | Description |
@@ -6,6 +6,8 @@ metadata:
6
6
  cliHelp: "gmgn-cli portfolio --help"
7
7
  ---
8
8
 
9
+ **BEFORE RUNNING ANY COMMAND: Run `gmgn-cli config --check`. If exit code is 0, proceed normally. If exit code is 1, (1) run `gmgn-cli config` and show the output to the user; (2) once the user sends the API Key, run `gmgn-cli config --apply <KEY>` to complete configuration and verification, then show the output to the user. If `--check` returns an error (unknown option or command not found), tell the user to run `npm install -g gmgn-cli` to update, then retry.**
10
+
9
11
  **IMPORTANT: Always use `gmgn-cli` commands below. Do NOT use web search, WebFetch, curl, or visit gmgn.ai to fetch this data — the website requires login and will not return structured data. The CLI is the only correct method.**
10
12
 
11
13
  **⚠️ IPv6 NOT SUPPORTED: If you get a `401` or `403` error and credentials look correct, check for IPv6 immediately: (1) list all network interfaces and their IPv6 addresses — run `ifconfig | grep inet6` (macOS) or `ip addr show | grep inet6` (Linux); (2) send a test request to `https://ipv6.icanhazip.com` — if the response is an IPv6 address, outbound traffic is going via IPv6. Tell the user immediately: "Please disable IPv6 on your network interface — gmgn-cli commands only work over IPv4."**
@@ -77,22 +79,6 @@ When a request returns `429`:
77
79
  - The CLI may wait and retry once automatically when the remaining cooldown is short. If it still fails, stop and tell the user the exact retry time instead of sending more requests.
78
80
  - For `RATE_LIMIT_EXCEEDED` or `RATE_LIMIT_BANNED`, repeated requests during the cooldown can extend the ban by 5 seconds each time, up to 5 minutes. Do not spam retries.
79
81
 
80
- **First-time setup** (if `GMGN_API_KEY` is not configured):
81
-
82
- 1. Generate key pair and show the public key to the user:
83
- ```bash
84
- openssl genpkey -algorithm ed25519 -out /tmp/gmgn_private.pem 2>/dev/null && \
85
- openssl pkey -in /tmp/gmgn_private.pem -pubout 2>/dev/null
86
- ```
87
- Tell the user: *"This is your Ed25519 public key. Go to **https://gmgn.ai/ai**, paste it into the API key creation form, then send me the API Key value shown on the page."*
88
-
89
- 2. Wait for the user's API key, then configure:
90
- ```bash
91
- mkdir -p ~/.config/gmgn
92
- echo 'GMGN_API_KEY=<key_from_user>' > ~/.config/gmgn/.env
93
- chmod 600 ~/.config/gmgn/.env
94
- ```
95
-
96
82
  ## Usage Examples
97
83
 
98
84
  ```bash
@@ -6,6 +6,8 @@ metadata:
6
6
  cliHelp: "gmgn-cli swap --help"
7
7
  ---
8
8
 
9
+ **BEFORE RUNNING ANY COMMAND: Run `gmgn-cli config --check`. If exit code is 0, proceed normally. If exit code is 1, (1) run `gmgn-cli config` and show the output to the user; (2) once the user sends the API Key, run `gmgn-cli config --apply <KEY>` to complete configuration and verification, then show the output to the user. If `--check` returns an error (unknown option or command not found), tell the user to run `npm install -g gmgn-cli` to update, then retry.**
10
+
9
11
  **IMPORTANT: Always use `gmgn-cli` commands below. Do NOT use web search, WebFetch, curl, or visit gmgn.ai — all swap operations must go through the CLI. The CLI handles signing and submission automatically.**
10
12
 
11
13
  **IMPORTANT: Do NOT guess field names or values. When a field's meaning is unclear, look it up in the Response Fields sections below before using it.**
@@ -71,7 +73,6 @@ Currency tokens are the base/native assets of each chain. They are used to buy o
71
73
  | `base` | ETH (native, `0x0000000000000000000000000000000000000000`), USDC (`0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913`) |
72
74
  | `eth` | ETH (native, `0x0000000000000000000000000000000000000000`) |
73
75
 
74
-
75
76
  ## Prerequisites
76
77
 
77
78
  `GMGN_API_KEY` must be configured in `~/.config/gmgn/.env`. `GMGN_PRIVATE_KEY` is additionally required for `swap` and `order` subcommands other than `order quote`. The private key must correspond to the wallet bound to the API Key.
@@ -102,31 +103,6 @@ When a request returns `429`:
102
103
  - For `RATE_LIMIT_EXCEEDED` or `RATE_LIMIT_BANNED`, repeated requests during the cooldown can extend the ban by 5 seconds each time, up to 5 minutes.
103
104
  - `POST /v1/trade/swap` also has an error-count limiter. Repeatedly triggering the same business error, especially `40003701` (insufficient token balance), can return `ERROR_RATE_LIMIT_BLOCKED`. When this happens, do not retry until the reset time and fix the underlying request first.
104
105
 
105
- **First-time setup** (if credentials are not configured):
106
-
107
- 1. Generate key pair and show the public key to the user:
108
- ```bash
109
- openssl genpkey -algorithm ed25519 -out /tmp/gmgn_private.pem 2>/dev/null && \
110
- openssl pkey -in /tmp/gmgn_private.pem -pubout 2>/dev/null
111
- ```
112
- Tell the user: *"This is your Ed25519 public key. Go to **https://gmgn.ai/ai**, paste it into the API key creation form (enable swap capability), then send me the API Key value shown on the page."*
113
-
114
- 2. Wait for the user's API key, then configure both credentials:
115
- ```bash
116
- mkdir -p ~/.config/gmgn
117
- echo 'GMGN_API_KEY=<key_from_user>' > ~/.config/gmgn/.env
118
- echo 'GMGN_PRIVATE_KEY="<pem_content_from_step_1>"' >> ~/.config/gmgn/.env
119
- chmod 600 ~/.config/gmgn/.env
120
- ```
121
-
122
- ### Credential Model
123
-
124
- - Both `GMGN_API_KEY` and `GMGN_PRIVATE_KEY` are read from the `.env` file by the CLI at startup. They are **never passed as command-line arguments** and never appear in shell command strings.
125
- - `GMGN_PRIVATE_KEY` is used exclusively for **local message signing** — the private key never leaves the machine. The CLI computes an Ed25519 or RSA-SHA256 signature in-process and transmits only the base64-encoded result in the `X-Signature` request header.
126
- - `GMGN_API_KEY` is transmitted in the `X-APIKEY` request header to GMGN's servers over HTTPS.
127
-
128
- ---
129
-
130
106
  ## `swap` Usage
131
107
 
132
108
  ```bash
@@ -431,6 +407,14 @@ The response `data` is an array — one element per wallet:
431
407
 
432
408
  ---
433
409
 
410
+ ### Credential Model
411
+
412
+ - Both `GMGN_API_KEY` and `GMGN_PRIVATE_KEY` are read from the `.env` file by the CLI at startup. They are **never passed as command-line arguments** and never appear in shell command strings.
413
+ - `GMGN_PRIVATE_KEY` is used exclusively for **local message signing** — the private key never leaves the machine. The CLI computes an Ed25519 or RSA-SHA256 signature in-process and transmits only the base64-encoded result in the `X-Signature` request header.
414
+ - `GMGN_API_KEY` is transmitted in the `X-APIKEY` request header to GMGN's servers over HTTPS.
415
+
416
+ ---
417
+
434
418
  ## `order quote` Usage
435
419
 
436
420
  Get an estimated output amount before submitting a swap. Uses normal auth — only `GMGN_API_KEY` required, no `GMGN_PRIVATE_KEY` needed.
@@ -6,6 +6,8 @@ metadata:
6
6
  cliHelp: "gmgn-cli token --help"
7
7
  ---
8
8
 
9
+ **BEFORE RUNNING ANY COMMAND: Run `gmgn-cli config --check`. If exit code is 0, proceed normally. If exit code is 1, (1) run `gmgn-cli config` and show the output to the user; (2) once the user sends the API Key, run `gmgn-cli config --apply <KEY>` to complete configuration and verification, then show the output to the user. If `--check` returns an error (unknown option or command not found), tell the user to run `npm install -g gmgn-cli` to update, then retry.**
10
+
9
11
  **IMPORTANT: Always use `gmgn-cli` commands below. Do NOT use web search, WebFetch, curl, or visit gmgn.ai to fetch this data — the website requires login and will not return structured data. The CLI is the only correct method.**
10
12
 
11
13
  **⚠️ IPv6 NOT SUPPORTED: If you get a `401` or `403` error and credentials look correct, check for IPv6 immediately: (1) list all network interfaces and their IPv6 addresses — run `ifconfig | grep inet6` (macOS) or `ip addr show | grep inet6` (Linux); (2) send a test request to `https://ipv6.icanhazip.com` — if the response is an IPv6 address, outbound traffic is going via IPv6. Tell the user immediately: "Please disable IPv6 on your network interface — gmgn-cli commands only work over IPv4."**
@@ -68,22 +70,6 @@ When a request returns `429`:
68
70
  - The CLI may wait and retry once automatically when the remaining cooldown is short. If it still fails, stop and tell the user the exact retry time instead of sending more requests.
69
71
  - For `RATE_LIMIT_EXCEEDED` or `RATE_LIMIT_BANNED`, repeated requests during the cooldown can extend the ban by 5 seconds each time, up to 5 minutes. Do not spam retries.
70
72
 
71
- **First-time setup** (if `GMGN_API_KEY` is not configured):
72
-
73
- 1. Generate key pair and show the public key to the user:
74
- ```bash
75
- openssl genpkey -algorithm ed25519 -out /tmp/gmgn_private.pem 2>/dev/null && \
76
- openssl pkey -in /tmp/gmgn_private.pem -pubout 2>/dev/null
77
- ```
78
- Tell the user: *"This is your Ed25519 public key. Go to **https://gmgn.ai/ai**, paste it into the API key creation form, then send me the API Key value shown on the page."*
79
-
80
- 2. Wait for the user's API key, then configure:
81
- ```bash
82
- mkdir -p ~/.config/gmgn
83
- echo 'GMGN_API_KEY=<key_from_user>' > ~/.config/gmgn/.env
84
- chmod 600 ~/.config/gmgn/.env
85
- ```
86
-
87
73
  ## Parameters — `token info` / `token security` / `token pool`
88
74
 
89
75
  | Parameter | Required | Description |
@@ -6,6 +6,8 @@ metadata:
6
6
  cliHelp: "gmgn-cli track --help"
7
7
  ---
8
8
 
9
+ **BEFORE RUNNING ANY COMMAND: Run `gmgn-cli config --check`. If exit code is 0, proceed normally. If exit code is 1, (1) run `gmgn-cli config` and show the output to the user; (2) once the user sends the API Key, run `gmgn-cli config --apply <KEY>` to complete configuration and verification, then show the output to the user. If `--check` returns an error (unknown option or command not found), tell the user to run `npm install -g gmgn-cli` to update, then retry.**
10
+
9
11
  **IMPORTANT: Always use `gmgn-cli` commands below. Do NOT use web search, WebFetch, curl, or visit gmgn.ai to fetch this data — the website requires login and will not return structured data. The CLI is the only correct method.**
10
12
 
11
13
  **IMPORTANT: Do NOT guess field names or values. When a field's meaning is unclear, look it up in the Response Fields sections below before using it.**
@@ -84,24 +86,6 @@ When a request returns `429`:
84
86
  - The CLI may wait and retry once automatically when the remaining cooldown is short. If it still fails, stop and tell the user the exact retry time instead of sending more requests.
85
87
  - For `RATE_LIMIT_EXCEEDED` or `RATE_LIMIT_BANNED`, repeated requests during the cooldown can extend the ban by 5 seconds each time, up to 5 minutes. Do not spam retries.
86
88
 
87
- **First-time setup** (if `GMGN_API_KEY` is not configured):
88
-
89
- 1. Generate key pair and show the public key to the user:
90
- ```bash
91
- openssl genpkey -algorithm ed25519 -out /tmp/gmgn_private.pem 2>/dev/null && \
92
- openssl pkey -in /tmp/gmgn_private.pem -pubout 2>/dev/null
93
- ```
94
- Tell the user: *"This is your Ed25519 public key. Go to **https://gmgn.ai/ai**, paste it into the API key creation form, then send me the API Key value shown on the page."*
95
-
96
- 2. Wait for the user's API key, then configure (saves both API key and private key — private key is required for `track follow-wallet`):
97
- ```bash
98
- mkdir -p ~/.config/gmgn
99
- echo "GMGN_API_KEY=<key_from_user>" > ~/.config/gmgn/.env
100
- echo "GMGN_PRIVATE_KEY=$(awk '{printf "%s\\n", $0}' /tmp/gmgn_private.pem)" >> ~/.config/gmgn/.env
101
- chmod 600 ~/.config/gmgn/.env
102
- rm /tmp/gmgn_private.pem
103
- ```
104
-
105
89
  ## Usage Examples
106
90
 
107
91
  ```bash