@aeon-ai-pay/aigateway 0.1.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.
- package/CHANGELOG.md +60 -0
- package/LICENSE +21 -0
- package/README.md +116 -0
- package/bin/cli.mjs +155 -0
- package/docs/env-vars.md +73 -0
- package/docs/exit-codes.md +65 -0
- package/docs/ide-setup.md +60 -0
- package/docs/output-schema.md +188 -0
- package/docs/recipes/cron-issue-cards.md +69 -0
- package/docs/recipes/error-recovery.md +53 -0
- package/docs/recipes/integrate-in-agent.md +108 -0
- package/docs/recipes/merchant-integration.md +243 -0
- package/docs/release-process.md +98 -0
- package/docs/troubleshooting.md +200 -0
- package/package.json +58 -0
- package/scripts/postinstall.mjs +40 -0
- package/skills/aigateway/SKILL.md +370 -0
- package/skills/aigateway/references/check-status.md +68 -0
- package/skills/aigateway/references/create-card.md +114 -0
- package/skills/aigateway/references/store.md +87 -0
- package/skills/aigateway/references/x402-protocol.md +143 -0
- package/src/balance.mjs +92 -0
- package/src/commands/clean.mjs +65 -0
- package/src/commands/create-card-status.mjs +67 -0
- package/src/commands/create-card.mjs +333 -0
- package/src/commands/create-image.mjs +428 -0
- package/src/commands/wallet-balance.mjs +47 -0
- package/src/commands/wallet-gas.mjs +99 -0
- package/src/commands/wallet-init.mjs +42 -0
- package/src/commands/wallet-topup.mjs +221 -0
- package/src/commands/wallet-withdraw.mjs +183 -0
- package/src/config.mjs +50 -0
- package/src/constants.mjs +22 -0
- package/src/error-codes.mjs +50 -0
- package/src/funding.mjs +216 -0
- package/src/output.mjs +85 -0
- package/src/sanitize.mjs +48 -0
- package/src/update-check.mjs +69 -0
- package/src/walletconnect.mjs +712 -0
- package/src/x402.mjs +120 -0
- package/templates/cline/.clinerules +53 -0
- package/templates/codex/AGENTS.md +56 -0
- package/templates/cursor/.cursor/rules/aigateway.mdc +60 -0
- package/templates/windsurf/.windsurfrules +48 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [0.1.0] — 2026-05-18
|
|
11
|
+
|
|
12
|
+
Initial release of **AEON AI Gateway**, merging the prior `@aeon-ai-pay/aicard` and `@aeon-ai-pay/agentos` projects into a single unified CLI and agent skill.
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- Unified CLI surface (`aigateway`) supporting both **virtual card** and **AI image** capabilities backed by a shared session-key wallet.
|
|
17
|
+
- Commands:
|
|
18
|
+
- `wallet-init` — pure-local session-wallet check / auto-create (no QR, no on-chain).
|
|
19
|
+
- `wallet-topup` — WalletConnect USDT top-up (≥5 USDT, presets 5/10/20/50) + one-time facilitator approve.
|
|
20
|
+
- `wallet-balance` — query session-key USDT / BNB balance + saved main wallet.
|
|
21
|
+
- `wallet-gas` — main wallet → session BNB transfer (for withdraw gas).
|
|
22
|
+
- `wallet-withdraw` — on-chain reclaim of USDT + BNB back to main wallet.
|
|
23
|
+
- `create-card` — x402-paid virtual debit card issuance ($0.6 ~ $800), `--poll` and `--dry-run` supported.
|
|
24
|
+
- `create-image` — x402-paid Skill Boss image generation, with prompt / aspect-ratio / format / model controls.
|
|
25
|
+
- `create-card-status` — query the status of a `create-card` order.
|
|
26
|
+
- `clean` — uninstall skill and clear npm/npx caches.
|
|
27
|
+
- Stable JSON envelope on stdout for every command: `{ ok, command, version, data | error }`.
|
|
28
|
+
- Stable `error.code` taxonomy (24 codes) mapped to four exit-code categories: `1` user / `2` timeout / `3` service / `4` internal.
|
|
29
|
+
- `--app-id <id>` on every command (default `TEST000001`) for merchant attribution.
|
|
30
|
+
- `--legacy-output` flag for consumers still parsing the pre-envelope JSON shape.
|
|
31
|
+
- `--verbose` / `--quiet` global logging controls.
|
|
32
|
+
- `--dry-run` on `create-card` for preflight validation without signing or transacting.
|
|
33
|
+
- Foreground auto-upgrade via `src/update-check.mjs`: every CLI invocation checks `npm view` and silently background-installs the new version + re-syncs the skill via `postinstall`.
|
|
34
|
+
- Multi-IDE adoption templates under `templates/` for Cursor, Windsurf, Cline / Roo Code, and Codex.
|
|
35
|
+
- Agent skill at `skills/aigateway/SKILL.md` with end-user workflow, copy-exact templates, and decision routing.
|
|
36
|
+
- Developer documentation:
|
|
37
|
+
- `docs/output-schema.md` — full envelope schema per command.
|
|
38
|
+
- `docs/exit-codes.md` — exit code + `error.code` reference.
|
|
39
|
+
- `docs/env-vars.md` — environment variable reference.
|
|
40
|
+
- `docs/troubleshooting.md` — common issues & remedies.
|
|
41
|
+
- `docs/release-process.md` — release workflow + version lock-step rules.
|
|
42
|
+
- `docs/ide-setup.md` — manual IDE adoption guide.
|
|
43
|
+
- `docs/recipes/integrate-in-agent.md` — generic spawn-and-parse Node.js / Python wrappers.
|
|
44
|
+
- `docs/recipes/error-recovery.md` — recovery actions per error code.
|
|
45
|
+
- `docs/recipes/cron-issue-cards.md` — scheduled paid calls.
|
|
46
|
+
- `docs/recipes/merchant-integration.md` — merchant integration patterns (user-managed vs. custodial wallet).
|
|
47
|
+
|
|
48
|
+
### Removed (compared to upstream `aicard` / `agentos`)
|
|
49
|
+
|
|
50
|
+
- `setup --check` (folded into the new `wallet-init` command).
|
|
51
|
+
- `setup --service-url` / per-command `--service-url` flag (use `AIGATEWAY_SERVICE_URL` env var instead).
|
|
52
|
+
- `aicard topup` (renamed to `wallet-topup`).
|
|
53
|
+
- `agentos prepare` (folded into `wallet-topup`).
|
|
54
|
+
- `aicard create` (renamed to `create-card`).
|
|
55
|
+
- `aicard wallet` / `aicard gas` / `aicard withdraw` (renamed to `wallet-balance` / `wallet-gas` / `wallet-withdraw`).
|
|
56
|
+
- `aicard status` (renamed to `create-card-status` to match `create-card-*` naming).
|
|
57
|
+
- `INVALID_USAGE` error code (no longer needed after `setup` simplification).
|
|
58
|
+
|
|
59
|
+
[Unreleased]: https://github.com/AEON-Project/aigateway/compare/v0.1.0...HEAD
|
|
60
|
+
[0.1.0]: https://github.com/AEON-Project/aigateway/releases/tag/v0.1.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 AEON-Project
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# AEON AI Gateway
|
|
2
|
+
|
|
3
|
+
> AI Agents discover, invoke, and settle paid LLMs, APIs, and Skills — starting with **Skill Boss**.
|
|
4
|
+
>
|
|
5
|
+
> **No manual key setup. No prepayment. Pay-per-call via x402 or Agent Card.**
|
|
6
|
+
|
|
7
|
+
A unified CLI + agent skill that lets an AI agent **purchase virtual debit cards** *and* **invoke AI services (image generation via Skill Boss)** in the same wallet, paid per-call with USDT on BSC via the [x402 protocol](https://www.x402.org/).
|
|
8
|
+
|
|
9
|
+
Published as `@aeon-ai-pay/aigateway` (CLI: `aigateway`).
|
|
10
|
+
|
|
11
|
+
## Install Skill
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Install to all detected agents (Claude Code, Cursor, Codex, OpenClaw, Gemini CLI, etc.)
|
|
15
|
+
npx skills add AEON-Project/aigateway -g -y
|
|
16
|
+
|
|
17
|
+
# Install to specific agents
|
|
18
|
+
npx skills add AEON-Project/aigateway -a claude-code -a cursor -a codex -g -y
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Supported agents: Claude Code, Cursor, Codex, OpenClaw, Gemini CLI, GitHub Copilot, Windsurf, Roo Code, and [39+ more](https://agentskills.io).
|
|
22
|
+
|
|
23
|
+
## One-Glance Flow
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
aigateway wallet-init # 1. auto-create local session wallet (pure local, no QR)
|
|
27
|
+
aigateway wallet-topup --amount 5 # 2. WalletConnect: USDT top-up + one-time facilitator approve
|
|
28
|
+
aigateway create-card --amount 5 # 3a. paid call: $5 virtual card via x402
|
|
29
|
+
aigateway create-image --prompt "cyberpunk fox" # 3b. paid call: AI image via x402
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Step 2 covers the **only** manual moment — scanning a WalletConnect QR with your phone wallet to load ≥5 USDT once. Every subsequent paid call is a gasless EIP-712 signature against the local session key.
|
|
33
|
+
|
|
34
|
+
## CLI Commands
|
|
35
|
+
|
|
36
|
+
Every command accepts `--app-id <id>` (merchant identifier, default `TEST000001`). Every command emits a JSON *envelope* on stdout (`{ ok, command, version, data | error }`).
|
|
37
|
+
|
|
38
|
+
| Command | Description | Key Options |
|
|
39
|
+
| --- | --- | --- |
|
|
40
|
+
| `wallet-init` | Check / create the local session wallet (pure local — no QR, no on-chain) | `--app-id <id>` |
|
|
41
|
+
| `wallet-topup` | WalletConnect USDT top-up (≥5 USDT, presets 5/10/20/50) + one-time facilitator approve | `--amount <usdt>`, `--app-id <id>`, `--private-key <key>` |
|
|
42
|
+
| `create-card` | Issue a one-time virtual Visa/Mastercard ($0.6 ~ $800) | `--amount <usd>` (required), `--app-id <id>`, `--poll`, `--dry-run`, `--topup-amount <usdt>` |
|
|
43
|
+
| `create-image` | Generate an AI image via Skill Boss | `--prompt <text>` (required), `--app-id <id>`, `--aspect-ratio`, `--output-format`, `--model`, `--output <dir>`, `--topup-amount <usdt>` |
|
|
44
|
+
| `create-card-status` | Query the status of a card issued via `create-card` | `--order-no <orderNo>` (required), `--app-id <id>`, `--poll` |
|
|
45
|
+
| `wallet` | Show local wallet USDT + BNB balance | `--app-id <id>`, `--private-key` |
|
|
46
|
+
| `wallet-gas` | Send BNB from main wallet to session key via WalletConnect | `--amount <bnb>` (default `0.001`), `--app-id <id>` |
|
|
47
|
+
| `wallet-withdraw` | Reclaim USDT + BNB from session key back to main wallet | `--amount <usdt>` (default: all), `--to <address>`, `--app-id <id>` |
|
|
48
|
+
| `clean` | Remove skill + uninstall global package | — |
|
|
49
|
+
|
|
50
|
+
Global flags: `--legacy-output` (old JSON shape), `--verbose`, `--quiet`.
|
|
51
|
+
|
|
52
|
+
## Wallet & Funding Model
|
|
53
|
+
|
|
54
|
+
- **Session key**: A locally-generated private key stored at `~/.aigateway/config.json` (mode 0o600). It signs all paid calls and never leaves your machine.
|
|
55
|
+
- **Main wallet**: Your existing MetaMask / OKX / Trust wallet. Connects only via WalletConnect QR — its key never touches the CLI.
|
|
56
|
+
- **First-funding floor**: ≥ **1 USDT** (`LOW_BALANCE_THRESHOLD`) is enforced before any paid call.
|
|
57
|
+
- **Per-top-up minimum**: ≥ **5 USDT** (`MIN_TOPUP_USDT`). Presets: 5 / 10 / 20 / 50, or custom ≥ 5.
|
|
58
|
+
- **Approve once**: `wallet-topup` broadcasts a one-time `ERC20.approve(facilitator, MaxUint256)` (consumes ~0.0003 BNB). Subsequent paid calls reuse this allowance — no more on-chain transactions for the user.
|
|
59
|
+
- **Gasless paid calls**: Both `create-card` and `create-image` are pure EIP-712 signatures; the facilitator pays gas for the actual USDT transfer.
|
|
60
|
+
|
|
61
|
+
## Prerequisites
|
|
62
|
+
|
|
63
|
+
- Node.js ≥ 25
|
|
64
|
+
- A mobile wallet app with WalletConnect support (MetaMask, OKX Wallet, Trust Wallet, etc.)
|
|
65
|
+
- USDT (BEP-20) and a small BNB balance in your main wallet for the one-time approve gas (~$0.002)
|
|
66
|
+
|
|
67
|
+
## Quickstart for Developers
|
|
68
|
+
|
|
69
|
+
Bundling `aigateway` inside your own agent product or merchant service? See:
|
|
70
|
+
|
|
71
|
+
**Reference**
|
|
72
|
+
- [docs/output-schema.md](docs/output-schema.md) — full envelope schema per command
|
|
73
|
+
- [docs/exit-codes.md](docs/exit-codes.md) — exit code categories + `error.code` reference
|
|
74
|
+
- [docs/env-vars.md](docs/env-vars.md) — `AIGATEWAY_SERVICE_URL`, `EVM_PRIVATE_KEY`, and the config-file fallback
|
|
75
|
+
- [docs/troubleshooting.md](docs/troubleshooting.md) — common issues + remedies
|
|
76
|
+
|
|
77
|
+
**Recipes**
|
|
78
|
+
- [docs/recipes/integrate-in-agent.md](docs/recipes/integrate-in-agent.md) — generic Node.js / Python subprocess wrappers
|
|
79
|
+
- [docs/recipes/merchant-integration.md](docs/recipes/merchant-integration.md) — merchant patterns (user-managed vs. custodial wallet, Express backend example)
|
|
80
|
+
- [docs/recipes/error-recovery.md](docs/recipes/error-recovery.md) — code-by-code recovery strategy
|
|
81
|
+
- [docs/recipes/cron-issue-cards.md](docs/recipes/cron-issue-cards.md) — scheduled paid calls
|
|
82
|
+
|
|
83
|
+
**Agent / IDE adoption**
|
|
84
|
+
- [docs/ide-setup.md](docs/ide-setup.md) — manual install templates for Cursor / Windsurf / Cline / Codex
|
|
85
|
+
|
|
86
|
+
**Releasing**
|
|
87
|
+
- [docs/release-process.md](docs/release-process.md) — version lock-step, publish, auto-upgrade flow
|
|
88
|
+
- [CHANGELOG.md](CHANGELOG.md) — release history
|
|
89
|
+
|
|
90
|
+
Minimal Node.js example:
|
|
91
|
+
|
|
92
|
+
```js
|
|
93
|
+
import { spawn } from "node:child_process";
|
|
94
|
+
|
|
95
|
+
const child = spawn("aigateway", [
|
|
96
|
+
"--quiet", "create-card", "--amount", "5", "--app-id", "MY_AGENT_001", "--poll",
|
|
97
|
+
]);
|
|
98
|
+
let stdout = "";
|
|
99
|
+
child.stdout.on("data", (b) => { stdout += b; });
|
|
100
|
+
child.on("close", (code) => {
|
|
101
|
+
const env = JSON.parse(stdout.trim().split("\n").pop());
|
|
102
|
+
if (env.ok) console.log("Card ready:", env.data.orderNo);
|
|
103
|
+
else console.error(`[${env.error.code}] ${env.error.message}`);
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Configuration
|
|
108
|
+
|
|
109
|
+
Config lives at `~/.aigateway/config.json` (file mode 600). The default service URL (`https://ai-api.aeon.xyz`) is wired into the CLI; staging / custom backends can be overridden through environment variables only:
|
|
110
|
+
|
|
111
|
+
- `AIGATEWAY_SERVICE_URL` — x402 service base URL
|
|
112
|
+
- `EVM_PRIVATE_KEY` — override the saved session key (developer use)
|
|
113
|
+
|
|
114
|
+
## License
|
|
115
|
+
|
|
116
|
+
MIT
|
package/bin/cli.mjs
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const [major] = process.versions.node.split(".").map(Number);
|
|
4
|
+
if (major < 25) {
|
|
5
|
+
console.error(`aigateway requires Node.js >= 25. Current: v${process.versions.node}`);
|
|
6
|
+
console.error("Upgrade: https://nodejs.org/");
|
|
7
|
+
process.exit(1);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// WalletConnect v2 SDK 已知缺陷:relay 偶发 null WebSocket 帧导致
|
|
11
|
+
// isJsonRpcPayload 内部 'id' in null 抛 TypeError,不影响业务流程,静默忽略
|
|
12
|
+
process.on("uncaughtException", (err) => {
|
|
13
|
+
if (
|
|
14
|
+
err instanceof TypeError &&
|
|
15
|
+
err.message.includes("Cannot use 'in' operator") &&
|
|
16
|
+
err.stack?.includes("isJsonRpcPayload")
|
|
17
|
+
) {
|
|
18
|
+
console.error("[WC guard] Caught null-frame TypeError via uncaughtException, ignored.");
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
console.error(err);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
import { Command } from "commander";
|
|
26
|
+
import { checkForUpdates } from "../src/update-check.mjs";
|
|
27
|
+
import { setLegacyMode, setVerboseMode, setQuietMode } from "../src/output.mjs";
|
|
28
|
+
import { readFileSync } from "node:fs";
|
|
29
|
+
import { fileURLToPath } from "node:url";
|
|
30
|
+
import { dirname, join } from "node:path";
|
|
31
|
+
|
|
32
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
33
|
+
const CURRENT_VERSION = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8")).version;
|
|
34
|
+
checkForUpdates(CURRENT_VERSION);
|
|
35
|
+
|
|
36
|
+
const program = new Command();
|
|
37
|
+
|
|
38
|
+
const DEFAULT_APP_ID = "TEST000001";
|
|
39
|
+
|
|
40
|
+
program
|
|
41
|
+
.name("aigateway")
|
|
42
|
+
.description("AEON AI Gateway — AI Agents discover, invoke, and settle paid LLMs, APIs, and Skills via x402 or Agent Card.")
|
|
43
|
+
.version(CURRENT_VERSION)
|
|
44
|
+
.option("--legacy-output", "Emit legacy JSON shape instead of the new envelope", false)
|
|
45
|
+
.option("--verbose", "Verbose stderr logs", false)
|
|
46
|
+
.option("--quiet", "Suppress non-error stderr logs", false)
|
|
47
|
+
.hook("preAction", (thisCommand) => {
|
|
48
|
+
const opts = thisCommand.opts();
|
|
49
|
+
setLegacyMode(opts.legacyOutput);
|
|
50
|
+
setVerboseMode(opts.verbose);
|
|
51
|
+
setQuietMode(opts.quiet);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
program
|
|
55
|
+
.command("wallet-init")
|
|
56
|
+
.description("Check / create the local session wallet (pure local, no on-chain, no QR)")
|
|
57
|
+
.option("--app-id <id>", "Merchant app ID", DEFAULT_APP_ID)
|
|
58
|
+
.action(async (opts) => {
|
|
59
|
+
const { initWallet } = await import("../src/commands/wallet-init.mjs");
|
|
60
|
+
return initWallet(opts);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
program
|
|
64
|
+
.command("wallet-topup")
|
|
65
|
+
.description("Top-up USDT (≥1 USDT floor / ≥5 USDT minimum per top-up) and one-time facilitator approve via WalletConnect")
|
|
66
|
+
.option("--app-id <id>", "Merchant app ID", DEFAULT_APP_ID)
|
|
67
|
+
.option("--amount <usdt>", "USDT amount to top-up (presets: 5/10/20/50, or custom ≥5)")
|
|
68
|
+
.option("--private-key <key>", "Override EVM private key")
|
|
69
|
+
.action(async (opts) => {
|
|
70
|
+
const { topup } = await import("../src/commands/wallet-topup.mjs");
|
|
71
|
+
return topup(opts);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
program
|
|
75
|
+
.command("wallet-balance")
|
|
76
|
+
.description("Check local wallet USDT/BNB balance on BSC")
|
|
77
|
+
.option("--app-id <id>", "Merchant app ID", DEFAULT_APP_ID)
|
|
78
|
+
.option("--private-key <key>", "Override EVM private key")
|
|
79
|
+
.action(async (opts) => {
|
|
80
|
+
const { wallet } = await import("../src/commands/wallet-balance.mjs");
|
|
81
|
+
return wallet(opts);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
program
|
|
85
|
+
.command("wallet-gas")
|
|
86
|
+
.description("Send BNB from main wallet to session key via WalletConnect (for withdraw / approve gas)")
|
|
87
|
+
.option("--app-id <id>", "Merchant app ID", DEFAULT_APP_ID)
|
|
88
|
+
.option("--amount <bnb>", "BNB amount to send", "0.001")
|
|
89
|
+
.option("--project-id <id>", "WalletConnect Cloud project ID")
|
|
90
|
+
.action(async (opts) => {
|
|
91
|
+
const { gas } = await import("../src/commands/wallet-gas.mjs");
|
|
92
|
+
return gas(opts);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
program
|
|
96
|
+
.command("wallet-withdraw")
|
|
97
|
+
.description("Withdraw USDT and remaining BNB from session key back to main wallet")
|
|
98
|
+
.option("--app-id <id>", "Merchant app ID", DEFAULT_APP_ID)
|
|
99
|
+
.option("--amount <usdt>", "USDT amount to withdraw (default: all)")
|
|
100
|
+
.option("--to <address>", "Override destination address")
|
|
101
|
+
.action(async (opts) => {
|
|
102
|
+
const { withdraw } = await import("../src/commands/wallet-withdraw.mjs");
|
|
103
|
+
return withdraw(opts);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
program
|
|
107
|
+
.command("create-card")
|
|
108
|
+
.description("Create a one-time virtual card by paying with USDT on BSC via x402")
|
|
109
|
+
.requiredOption("--amount <usd>", "Card amount in USD ($0.6 ~ $800)")
|
|
110
|
+
.option("--app-id <id>", "Merchant app ID", DEFAULT_APP_ID)
|
|
111
|
+
.option("--topup-amount <usdt>", "USDT top-up amount when balance is insufficient (≥5)")
|
|
112
|
+
.option("--private-key <key>", "Override EVM private key")
|
|
113
|
+
.option("--poll", "Auto-poll status after creation", false)
|
|
114
|
+
.option("--dry-run", "Run all preflight checks but do not sign/transact", false)
|
|
115
|
+
.action(async (opts) => {
|
|
116
|
+
const { createCard } = await import("../src/commands/create-card.mjs");
|
|
117
|
+
return createCard(opts);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
program
|
|
121
|
+
.command("create-image")
|
|
122
|
+
.description("Generate an AI image via Skill Boss, paying with USDT on BSC via x402")
|
|
123
|
+
.requiredOption("--prompt <text>", "Image prompt text")
|
|
124
|
+
.option("--app-id <id>", "Merchant app ID", DEFAULT_APP_ID)
|
|
125
|
+
.option("--aspect-ratio <ratio>", "Image aspect ratio", "16:9")
|
|
126
|
+
.option("--output-format <fmt>", "Image format (png/jpeg/webp)", "png")
|
|
127
|
+
.option("--model <id>", "Model identifier")
|
|
128
|
+
.option("--output <dir>", "Output directory (default ~/aigateway-images)")
|
|
129
|
+
.option("--topup-amount <usdt>", "USDT top-up amount when balance is insufficient (≥5)")
|
|
130
|
+
.option("--private-key <key>", "Override EVM private key")
|
|
131
|
+
.action(async (opts) => {
|
|
132
|
+
const { createImage } = await import("../src/commands/create-image.mjs");
|
|
133
|
+
return createImage(opts);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
program
|
|
137
|
+
.command("create-card-status")
|
|
138
|
+
.description("Query the status of a virtual card created via create-card")
|
|
139
|
+
.requiredOption("--order-no <orderNo>", "Order number returned by create-card")
|
|
140
|
+
.option("--app-id <id>", "Merchant app ID", DEFAULT_APP_ID)
|
|
141
|
+
.option("--poll", "Poll until terminal status", false)
|
|
142
|
+
.action(async (opts) => {
|
|
143
|
+
const { status } = await import("../src/commands/create-card-status.mjs");
|
|
144
|
+
return status(opts);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
program
|
|
148
|
+
.command("clean")
|
|
149
|
+
.description("Remove skill, uninstall package, and clear npm/npx cache")
|
|
150
|
+
.action(async () => {
|
|
151
|
+
const { clean } = await import("../src/commands/clean.mjs");
|
|
152
|
+
return clean();
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
program.parse();
|
package/docs/env-vars.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Environment Variables
|
|
2
|
+
|
|
3
|
+
All environment variables that affect the `aigateway` CLI. Resolution priority for any setting: **CLI flag > env var > `~/.aigateway/config.json` > built-in default**.
|
|
4
|
+
|
|
5
|
+
| Variable | Used by | Default | Purpose |
|
|
6
|
+
| --- | --- | --- | --- |
|
|
7
|
+
| `AIGATEWAY_SERVICE_URL` | All paid commands (`create-card`, `create-image`, `create-card-status`) | `https://ai-api.aeon.xyz` | Override the x402 service base URL. Useful for staging / local backends. |
|
|
8
|
+
| `EVM_PRIVATE_KEY` | All commands needing a session key | (read from config file) | Override the saved session key. Required when running in custodial / containerised mode where you don't want a config file on disk. **Treat as a secret.** |
|
|
9
|
+
| `AICARD_LEGACY_NOOP` | — | — | Reserved. Not currently used. |
|
|
10
|
+
|
|
11
|
+
## Config file
|
|
12
|
+
|
|
13
|
+
`~/.aigateway/config.json` (mode `0o600`). Persisted fields:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"serviceUrl": "https://ai-api.aeon.xyz",
|
|
18
|
+
"privateKey": "0x...",
|
|
19
|
+
"address": "0x...",
|
|
20
|
+
"mode": "private-key",
|
|
21
|
+
"mainWallet": "0x..."
|
|
22
|
+
}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
- `serviceUrl` — written when overridden (rare).
|
|
26
|
+
- `privateKey` / `address` / `mode` — written by `wallet-init` when auto-generating a session key.
|
|
27
|
+
- `mainWallet` — auto-recorded after a successful `wallet-topup` so `wallet-withdraw` can default to that address.
|
|
28
|
+
|
|
29
|
+
## CLI flag priority example
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# All four set, --service-url wins
|
|
33
|
+
AIGATEWAY_SERVICE_URL=https://env.example.com \
|
|
34
|
+
aigateway create-card --amount 5 --service-url=... # (no such flag now — env wins)
|
|
35
|
+
|
|
36
|
+
# Only env set
|
|
37
|
+
AIGATEWAY_SERVICE_URL=https://staging.example.com \
|
|
38
|
+
aigateway create-card --amount 5
|
|
39
|
+
|
|
40
|
+
# Nothing set → built-in default https://ai-api.aeon.xyz
|
|
41
|
+
aigateway create-card --amount 5
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The `--service-url` CLI flag has been removed in 0.1.0+ — use the env var or edit the config file directly.
|
|
45
|
+
|
|
46
|
+
## Production hardening
|
|
47
|
+
|
|
48
|
+
| Goal | How |
|
|
49
|
+
| --- | --- |
|
|
50
|
+
| Don't write key to disk | Set `EVM_PRIVATE_KEY` from a Vault / KMS fetch at process boot; never call `wallet-init` |
|
|
51
|
+
| Pin to staging in CI | `export AIGATEWAY_SERVICE_URL=https://staging-x402.aeon.xyz` in your CI environment |
|
|
52
|
+
| Confidential logging | Combine with `--quiet` to suppress stderr; pipe stdout to your structured logger |
|
|
53
|
+
| Multi-tenant | Set `EVM_PRIVATE_KEY` per request via spawn `env` option (don't leak across tenants) |
|
|
54
|
+
|
|
55
|
+
## Quick reference
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Default production
|
|
59
|
+
aigateway wallet-init
|
|
60
|
+
|
|
61
|
+
# Custodial server (key from Vault, no config file)
|
|
62
|
+
EVM_PRIVATE_KEY=$(vault kv get -field=key merchants/acme-prod) \
|
|
63
|
+
aigateway create-card --amount 5 --app-id MERCHANT_ACME_001 --poll
|
|
64
|
+
|
|
65
|
+
# Staging
|
|
66
|
+
AIGATEWAY_SERVICE_URL=https://staging-x402.aeon.xyz \
|
|
67
|
+
aigateway create-card --amount 5 --app-id YOUR_TEST_APPID --poll
|
|
68
|
+
|
|
69
|
+
# Both
|
|
70
|
+
AIGATEWAY_SERVICE_URL=https://staging-x402.aeon.xyz \
|
|
71
|
+
EVM_PRIVATE_KEY=$STAGING_KEY \
|
|
72
|
+
aigateway wallet-balance
|
|
73
|
+
```
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Exit Codes
|
|
2
|
+
|
|
3
|
+
The `aigateway` CLI returns a stable exit code that maps to the category of outcome. Combine this with the `error.code` field in the JSON envelope (see [output-schema.md](./output-schema.md)) for precise programmatic handling.
|
|
4
|
+
|
|
5
|
+
| Exit | Category | Meaning |
|
|
6
|
+
| ---: | -------- | ------- |
|
|
7
|
+
| `0` | Success | Command completed and produced an `ok: true` envelope. |
|
|
8
|
+
| `1` | User error | Validation, configuration, balance, or user-side rejection. Caller should fix input and retry. |
|
|
9
|
+
| `2` | Timeout | Polling, WalletConnect, signature, or on-chain wait exceeded its limit. The underlying operation may still complete asynchronously (e.g. card may still be provisioning). |
|
|
10
|
+
| `3` | Service / network | Upstream service unavailable, network error, on-chain revert. Generally retryable after backoff. |
|
|
11
|
+
| `4` | Internal | Unexpected internal error in the CLI. Please file an issue if reproducible. |
|
|
12
|
+
|
|
13
|
+
## Error Code Reference
|
|
14
|
+
|
|
15
|
+
The full set of `error.code` values, grouped by exit code, is defined in [`src/error-codes.mjs`](../src/error-codes.mjs).
|
|
16
|
+
|
|
17
|
+
### Exit 1 — User Error
|
|
18
|
+
|
|
19
|
+
| Code | When |
|
|
20
|
+
| ---- | ---- |
|
|
21
|
+
| `WALLET_NOT_CONFIGURED` | No local wallet. Run `aigateway wallet-init`. |
|
|
22
|
+
| `SERVICE_URL_MISSING` | Service URL not configured. |
|
|
23
|
+
| `AMOUNT_INVALID` | Amount could not be parsed. |
|
|
24
|
+
| `AMOUNT_OUT_OF_RANGE` | Amount outside `amountLimits.min` ~ `amountLimits.max`. |
|
|
25
|
+
| `AMOUNT_EXCEEDS_BALANCE` | `withdraw --amount` exceeds available USDT. |
|
|
26
|
+
| `INSUFFICIENT_USDT` | USDT balance still insufficient after funding. |
|
|
27
|
+
| `INSUFFICIENT_BNB` | No BNB for approve / withdraw gas. |
|
|
28
|
+
| `NO_FUNDS` | Session wallet has zero USDT and zero BNB. |
|
|
29
|
+
| `NO_MAIN_WALLET` | `wallet-withdraw` invoked without `--to` and no `mainWallet` in config. |
|
|
30
|
+
| `MISSING_PROMPT` | `create-image` invoked without `--prompt`. |
|
|
31
|
+
| `TOPUP_REQUIRED` | `wallet-topup` / `create-card` / `create-image` running non-TTY with `usdt < 1` and no amount argument. Choose from `error.presets` (5/10/20/50) and rerun (`topup --amount <n>` or pass `--topup-amount <n>` to `create-*`). |
|
|
32
|
+
| `TOPUP_AMOUNT_TOO_SMALL` | `topup --amount` (or `create-* --topup-amount`) below `MIN_TOPUP_USDT` (5 USDT) or the per-call minimum (`error.minTopup`). |
|
|
33
|
+
| `PAYMENT_REJECTED` | User rejected the transaction in their wallet. |
|
|
34
|
+
|
|
35
|
+
### Exit 2 — Timeout
|
|
36
|
+
|
|
37
|
+
| Code | When |
|
|
38
|
+
| ---- | ---- |
|
|
39
|
+
| `PAYMENT_TIMEOUT` | WalletConnect / signature request timed out (5 minutes). |
|
|
40
|
+
| `WC_SESSION_EXPIRED` | WalletConnect session dropped mid-flow. |
|
|
41
|
+
| `POLL_TIMEOUT` | `status --poll` exhausted attempts. Card may still be provisioning. |
|
|
42
|
+
| `TX_TIMEOUT` | On-chain receipt wait exceeded 60 s. |
|
|
43
|
+
|
|
44
|
+
### Exit 3 — Service / Network
|
|
45
|
+
|
|
46
|
+
| Code | When |
|
|
47
|
+
| ---- | ---- |
|
|
48
|
+
| `SERVICE_UNAVAILABLE` | Generic upstream / network failure. |
|
|
49
|
+
| `PAYMENT_FETCH_FAILED` | First 402 request to the service failed. |
|
|
50
|
+
| `BALANCE_CHECK_FAILED` | RPC query to BSC failed. |
|
|
51
|
+
| `ALLOWANCE_CHECK_FAILED` | RPC `allowance()` query failed. |
|
|
52
|
+
| `TX_REVERTED` | On-chain transaction reverted. |
|
|
53
|
+
| `WITHDRAW_FAILED` | Withdraw transaction failed (revert / RPC). |
|
|
54
|
+
| `APPROVE_FAILED` | `wallet-init` could not broadcast or confirm the facilitator `approve()` tx. |
|
|
55
|
+
| `FUNDING_FAILED` | WalletConnect funding flow failed (non-timeout / non-reject path). |
|
|
56
|
+
| `IMAGE_DOWNLOAD_FAILED` | Generated image URL returned a non-200 / timed out. |
|
|
57
|
+
| `INVALID_PAYMENT_AMOUNT` | Service returned a 402 with `amount === 0`. |
|
|
58
|
+
| `PAYMENT_FAILED` | Service rejected the signed payment request. |
|
|
59
|
+
|
|
60
|
+
### Exit 4 — Internal
|
|
61
|
+
|
|
62
|
+
| Code | When |
|
|
63
|
+
| ---- | ---- |
|
|
64
|
+
| `INTERNAL_ERROR` | Unexpected error inside the CLI. |
|
|
65
|
+
| `WALLET_ERROR` | Generic non-classified WalletConnect failure. (Exit 1 — treated as user-resolvable.) |
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# IDE Setup
|
|
2
|
+
|
|
3
|
+
The fastest path for most IDEs is the [skills CLI](https://agentskills.io), which auto-installs the bundled `skills/aigateway/SKILL.md` into every detected agent:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npx skills add AEON-Project/aigateway -g -y
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
For IDEs the skills CLI doesn't cover natively, copy the matching template from `templates/` into your project.
|
|
10
|
+
|
|
11
|
+
## Cursor
|
|
12
|
+
|
|
13
|
+
Cursor reads `.cursor/rules/*.mdc` from the project root.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
mkdir -p .cursor/rules
|
|
17
|
+
cp node_modules/@aeon-ai-pay/aigateway/templates/cursor/.cursor/rules/aigateway.mdc .cursor/rules/
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
If you installed `@aeon-ai-pay/aigateway` globally (`npm i -g`), substitute the `npm root -g` path. The `.mdc` file includes a `description:` line so Cursor can decide when to apply it.
|
|
21
|
+
|
|
22
|
+
## Windsurf
|
|
23
|
+
|
|
24
|
+
Windsurf reads `.windsurfrules` from the project root.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
cp node_modules/@aeon-ai-pay/aigateway/templates/windsurf/.windsurfrules ./.windsurfrules
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
If you already have project-level Windsurf rules, append the contents of the template instead of overwriting.
|
|
31
|
+
|
|
32
|
+
## Cline / Roo Code
|
|
33
|
+
|
|
34
|
+
Both Cline and Roo Code read `.clinerules` from the project root.
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
cp node_modules/@aeon-ai-pay/aigateway/templates/cline/.clinerules ./.clinerules
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Codex / OpenAI Codex
|
|
41
|
+
|
|
42
|
+
Codex reads `AGENTS.md` from the project root (or nested folders).
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
cp node_modules/@aeon-ai-pay/aigateway/templates/codex/AGENTS.md ./AGENTS.md
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
If your repo already has an `AGENTS.md`, append the `aigateway` section rather than overwriting.
|
|
49
|
+
|
|
50
|
+
## Claude Code & 40+ Other Agents
|
|
51
|
+
|
|
52
|
+
For Claude Code, OpenClaw, Gemini CLI, GitHub Copilot, and 30+ others, the [skills CLI](https://agentskills.io) installs the full `SKILL.md` automatically. No manual copying needed.
|
|
53
|
+
|
|
54
|
+
## Verifying It Works
|
|
55
|
+
|
|
56
|
+
After installation, in your IDE chat say:
|
|
57
|
+
|
|
58
|
+
> Create me a $5 virtual card.
|
|
59
|
+
|
|
60
|
+
The agent should propose running `aigateway wallet-init` (one-time, auto-creates a wallet) followed by `aigateway create-card --amount 5 --poll`. If it doesn't, the rule file isn't being picked up — check that the file path matches what your IDE expects and that the IDE has been restarted.
|