mirror of
https://github.com/GMGNAI/gmgn-skills.git
synced 2026-07-27 16:57:44 +00:00
feat(config): add gmgn-cli config command for API Key onboarding
Add a new `gmgn-cli config` command that automates Ed25519 key pair generation for new users. The command reuses an existing keypair.pem if present, or generates a new one, then outputs a pre-filled API Key creation link with the public key embedded. Guidance text is output in the user's system locale (zh-CN, zh-TW, or English). All 6 SKILL.md files are updated with a BEFORE RUNNING ANY COMMAND block that detects missing GMGN_API_KEY, triggers gmgn-cli config, and instructs the Agent to write both GMGN_API_KEY and GMGN_PRIVATE_KEY into ~/.config/gmgn/.env once the user provides their API Key. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -6,6 +6,17 @@ metadata:
|
||||
cliHelp: "gmgn-cli cooking --help"
|
||||
---
|
||||
|
||||
**BEFORE RUNNING ANY COMMAND: Check whether `GMGN_API_KEY` exists in `<cwd>/.env` or `~/.config/gmgn/.env`. If found in either location, proceed normally. If not found in either location, stop and run `gmgn-cli config` first — this generates an Ed25519 key pair and outputs a pre-filled link. Show the link to the user and ask them to create their API Key. Once the user sends back the API Key, write `GMGN_API_KEY` and `GMGN_PRIVATE_KEY` together into `~/.config/gmgn/.env` using the following commands, then proceed:**
|
||||
|
||||
```bash
|
||||
PRIVATE_KEY=$(awk '/-----BEGIN PRIVATE KEY-----/{p=1} p{printf "%s\\n", $0} /-----END PRIVATE KEY-----/{p=0}' ~/.config/gmgn/keypair.pem)
|
||||
grep -v "^GMGN_API_KEY=\|^GMGN_PRIVATE_KEY=" ~/.config/gmgn/.env 2>/dev/null > /tmp/gmgn_env_tmp
|
||||
echo "GMGN_API_KEY=<key_from_user>" >> /tmp/gmgn_env_tmp
|
||||
echo "GMGN_PRIVATE_KEY=$PRIVATE_KEY" >> /tmp/gmgn_env_tmp
|
||||
mv /tmp/gmgn_env_tmp ~/.config/gmgn/.env
|
||||
chmod 600 ~/.config/gmgn/.env
|
||||
```
|
||||
|
||||
**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.**
|
||||
|
||||
**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.**
|
||||
|
||||
@@ -6,6 +6,17 @@ metadata:
|
||||
cliHelp: "gmgn-cli market --help"
|
||||
---
|
||||
|
||||
**BEFORE RUNNING ANY COMMAND: Check whether `GMGN_API_KEY` exists in `<cwd>/.env` or `~/.config/gmgn/.env`. If found in either location, proceed normally. If not found in either location, stop and run `gmgn-cli config` first — this generates an Ed25519 key pair and outputs a pre-filled link. Show the link to the user and ask them to create their API Key. Once the user sends back the API Key, write `GMGN_API_KEY` and `GMGN_PRIVATE_KEY` together into `~/.config/gmgn/.env` using the following commands, then proceed:**
|
||||
|
||||
```bash
|
||||
PRIVATE_KEY=$(awk '/-----BEGIN PRIVATE KEY-----/{p=1} p{printf "%s\\n", $0} /-----END PRIVATE KEY-----/{p=0}' ~/.config/gmgn/keypair.pem)
|
||||
grep -v "^GMGN_API_KEY=\|^GMGN_PRIVATE_KEY=" ~/.config/gmgn/.env 2>/dev/null > /tmp/gmgn_env_tmp
|
||||
echo "GMGN_API_KEY=<key_from_user>" >> /tmp/gmgn_env_tmp
|
||||
echo "GMGN_PRIVATE_KEY=$PRIVATE_KEY" >> /tmp/gmgn_env_tmp
|
||||
mv /tmp/gmgn_env_tmp ~/.config/gmgn/.env
|
||||
chmod 600 ~/.config/gmgn/.env
|
||||
```
|
||||
|
||||
**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.**
|
||||
|
||||
**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.**
|
||||
|
||||
@@ -6,6 +6,17 @@ metadata:
|
||||
cliHelp: "gmgn-cli portfolio --help"
|
||||
---
|
||||
|
||||
**BEFORE RUNNING ANY COMMAND: Check whether `GMGN_API_KEY` exists in `<cwd>/.env` or `~/.config/gmgn/.env`. If found in either location, proceed normally. If not found in either location, stop and run `gmgn-cli config` first — this generates an Ed25519 key pair and outputs a pre-filled link. Show the link to the user and ask them to create their API Key. Once the user sends back the API Key, write `GMGN_API_KEY` and `GMGN_PRIVATE_KEY` together into `~/.config/gmgn/.env` using the following commands, then proceed:**
|
||||
|
||||
```bash
|
||||
PRIVATE_KEY=$(awk '/-----BEGIN PRIVATE KEY-----/{p=1} p{printf "%s\\n", $0} /-----END PRIVATE KEY-----/{p=0}' ~/.config/gmgn/keypair.pem)
|
||||
grep -v "^GMGN_API_KEY=\|^GMGN_PRIVATE_KEY=" ~/.config/gmgn/.env 2>/dev/null > /tmp/gmgn_env_tmp
|
||||
echo "GMGN_API_KEY=<key_from_user>" >> /tmp/gmgn_env_tmp
|
||||
echo "GMGN_PRIVATE_KEY=$PRIVATE_KEY" >> /tmp/gmgn_env_tmp
|
||||
mv /tmp/gmgn_env_tmp ~/.config/gmgn/.env
|
||||
chmod 600 ~/.config/gmgn/.env
|
||||
```
|
||||
|
||||
**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.**
|
||||
|
||||
**⚠️ 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."**
|
||||
|
||||
@@ -6,6 +6,17 @@ metadata:
|
||||
cliHelp: "gmgn-cli swap --help"
|
||||
---
|
||||
|
||||
**BEFORE RUNNING ANY COMMAND: Check whether `GMGN_API_KEY` exists in `<cwd>/.env` or `~/.config/gmgn/.env`. If found in either location, proceed normally. If not found in either location, stop and run `gmgn-cli config` first — this generates an Ed25519 key pair and outputs a pre-filled link. Show the link to the user and ask them to create their API Key. Once the user sends back the API Key, write `GMGN_API_KEY` and `GMGN_PRIVATE_KEY` together into `~/.config/gmgn/.env` using the following commands, then proceed:**
|
||||
|
||||
```bash
|
||||
PRIVATE_KEY=$(awk '/-----BEGIN PRIVATE KEY-----/{p=1} p{printf "%s\\n", $0} /-----END PRIVATE KEY-----/{p=0}' ~/.config/gmgn/keypair.pem)
|
||||
grep -v "^GMGN_API_KEY=\|^GMGN_PRIVATE_KEY=" ~/.config/gmgn/.env 2>/dev/null > /tmp/gmgn_env_tmp
|
||||
echo "GMGN_API_KEY=<key_from_user>" >> /tmp/gmgn_env_tmp
|
||||
echo "GMGN_PRIVATE_KEY=$PRIVATE_KEY" >> /tmp/gmgn_env_tmp
|
||||
mv /tmp/gmgn_env_tmp ~/.config/gmgn/.env
|
||||
chmod 600 ~/.config/gmgn/.env
|
||||
```
|
||||
|
||||
**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.**
|
||||
|
||||
**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.**
|
||||
|
||||
@@ -6,6 +6,17 @@ metadata:
|
||||
cliHelp: "gmgn-cli token --help"
|
||||
---
|
||||
|
||||
**BEFORE RUNNING ANY COMMAND: Check whether `GMGN_API_KEY` exists in `<cwd>/.env` or `~/.config/gmgn/.env`. If found in either location, proceed normally. If not found in either location, stop and run `gmgn-cli config` first — this generates an Ed25519 key pair and outputs a pre-filled link. Show the link to the user and ask them to create their API Key. Once the user sends back the API Key, write `GMGN_API_KEY` and `GMGN_PRIVATE_KEY` together into `~/.config/gmgn/.env` using the following commands, then proceed:**
|
||||
|
||||
```bash
|
||||
PRIVATE_KEY=$(awk '/-----BEGIN PRIVATE KEY-----/{p=1} p{printf "%s\\n", $0} /-----END PRIVATE KEY-----/{p=0}' ~/.config/gmgn/keypair.pem)
|
||||
grep -v "^GMGN_API_KEY=\|^GMGN_PRIVATE_KEY=" ~/.config/gmgn/.env 2>/dev/null > /tmp/gmgn_env_tmp
|
||||
echo "GMGN_API_KEY=<key_from_user>" >> /tmp/gmgn_env_tmp
|
||||
echo "GMGN_PRIVATE_KEY=$PRIVATE_KEY" >> /tmp/gmgn_env_tmp
|
||||
mv /tmp/gmgn_env_tmp ~/.config/gmgn/.env
|
||||
chmod 600 ~/.config/gmgn/.env
|
||||
```
|
||||
|
||||
**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.**
|
||||
|
||||
**⚠️ 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."**
|
||||
|
||||
@@ -6,6 +6,17 @@ metadata:
|
||||
cliHelp: "gmgn-cli track --help"
|
||||
---
|
||||
|
||||
**BEFORE RUNNING ANY COMMAND: Check whether `GMGN_API_KEY` exists in `<cwd>/.env` or `~/.config/gmgn/.env`. If found in either location, proceed normally. If not found in either location, stop and run `gmgn-cli config` first — this generates an Ed25519 key pair and outputs a pre-filled link. Show the link to the user and ask them to create their API Key. Once the user sends back the API Key, write `GMGN_API_KEY` and `GMGN_PRIVATE_KEY` together into `~/.config/gmgn/.env` using the following commands, then proceed:**
|
||||
|
||||
```bash
|
||||
PRIVATE_KEY=$(awk '/-----BEGIN PRIVATE KEY-----/{p=1} p{printf "%s\\n", $0} /-----END PRIVATE KEY-----/{p=0}' ~/.config/gmgn/keypair.pem)
|
||||
grep -v "^GMGN_API_KEY=\|^GMGN_PRIVATE_KEY=" ~/.config/gmgn/.env 2>/dev/null > /tmp/gmgn_env_tmp
|
||||
echo "GMGN_API_KEY=<key_from_user>" >> /tmp/gmgn_env_tmp
|
||||
echo "GMGN_PRIVATE_KEY=$PRIVATE_KEY" >> /tmp/gmgn_env_tmp
|
||||
mv /tmp/gmgn_env_tmp ~/.config/gmgn/.env
|
||||
chmod 600 ~/.config/gmgn/.env
|
||||
```
|
||||
|
||||
**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.**
|
||||
|
||||
**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.**
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import { Command } from "commander";
|
||||
import * as crypto from "crypto";
|
||||
import * as fs from "fs";
|
||||
import * as path from "path";
|
||||
import * as os from "os";
|
||||
|
||||
const GMGN_CONFIG_DIR = path.join(os.homedir(), ".config", "gmgn");
|
||||
const KEYPAIR_FILE = path.join(GMGN_CONFIG_DIR, "keypair.pem");
|
||||
const GMGN_API_URL = "https://gmgn.ai/ai/generateapi";
|
||||
|
||||
export function registerConfigCommands(program: Command): void {
|
||||
program
|
||||
.command("config")
|
||||
.description("Generate an Ed25519 key pair and output a pre-filled GMGN API Key creation link")
|
||||
.action(async () => {
|
||||
fs.mkdirSync(GMGN_CONFIG_DIR, { recursive: true });
|
||||
|
||||
let publicPem: string;
|
||||
|
||||
if (fs.existsSync(KEYPAIR_FILE)) {
|
||||
// Reuse existing key pair
|
||||
const content = fs.readFileSync(KEYPAIR_FILE, "utf-8");
|
||||
const match = content.match(/(-----BEGIN PUBLIC KEY-----[\s\S]+?-----END PUBLIC KEY-----)/);
|
||||
if (!match) {
|
||||
console.error("Error: keypair.pem exists but public key could not be parsed. Delete ~/.config/gmgn/keypair.pem and try again.");
|
||||
process.exit(1);
|
||||
}
|
||||
publicPem = match[1] + "\n";
|
||||
} else {
|
||||
// Generate new Ed25519 key pair
|
||||
const { privateKey, publicKey } = crypto.generateKeyPairSync("ed25519");
|
||||
const privatePem = privateKey.export({ type: "pkcs8", format: "pem" }) as string;
|
||||
publicPem = publicKey.export({ type: "spki", format: "pem" }) as string;
|
||||
|
||||
const entry = `# Private Key\n${privatePem}\n# Public Key\n${publicPem}\n`;
|
||||
fs.writeFileSync(KEYPAIR_FILE, entry, { mode: 0o600 });
|
||||
}
|
||||
|
||||
const link = `${GMGN_API_URL}?pbk=${encodeURIComponent(publicPem)}`;
|
||||
|
||||
const locale = (process.env.LANG ?? process.env.LC_ALL ?? process.env.LC_MESSAGES ?? "").toLowerCase();
|
||||
let message: string;
|
||||
if (locale.startsWith("zh_tw") || locale.startsWith("zh_hk")) {
|
||||
message = "請點擊連結建立你的 GMGN API Key,完成後將 Key 發給我,我來幫你完成配置:";
|
||||
} else if (locale.startsWith("zh")) {
|
||||
message = "请点击链接创建你的 GMGN API Key,完成后将 Key 发给我,我来帮你完成配置:";
|
||||
} else {
|
||||
message = "Please click the link below to create your GMGN API Key. Once created, send me the API Key and I will finish the configuration:";
|
||||
}
|
||||
|
||||
console.log("");
|
||||
console.log(message);
|
||||
console.log(link);
|
||||
console.log("");
|
||||
});
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import { registerPortfolioCommands } from "./commands/portfolio.js";
|
||||
import { registerTrackCommands } from "./commands/track.js";
|
||||
import { registerSwapCommands } from "./commands/swap.js";
|
||||
import { registerCookingCommands } from "./commands/cooking.js";
|
||||
import { registerConfigCommands } from "./commands/config.js";
|
||||
|
||||
const proxy = process.env.HTTPS_PROXY ?? process.env.https_proxy
|
||||
?? process.env.HTTP_PROXY ?? process.env.http_proxy;
|
||||
@@ -60,6 +61,7 @@ registerPortfolioCommands(program);
|
||||
registerTrackCommands(program);
|
||||
registerSwapCommands(program);
|
||||
registerCookingCommands(program);
|
||||
registerConfigCommands(program);
|
||||
|
||||
program.parseAsync().catch((err) => {
|
||||
console.error(`[gmgn-cli] ${err.message}`);
|
||||
|
||||
Reference in New Issue
Block a user