@bankr/cli 0.3.1 → 0.3.11
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/README.md +7 -7
- package/dist/cli.js +146 -83
- package/dist/commands/club.d.ts +1 -0
- package/dist/commands/club.js +47 -5
- package/dist/commands/fees.js +10 -2
- package/dist/commands/launch.js +16 -23
- package/dist/commands/llm.d.ts +3 -1
- package/dist/commands/llm.js +240 -63
- package/dist/commands/login.d.ts +0 -1
- package/dist/commands/login.js +28 -23
- package/dist/commands/profile.d.ts +5 -1
- package/dist/commands/profile.js +54 -10
- package/dist/commands/prompt.js +6 -0
- package/dist/commands/swap.d.ts +8 -0
- package/dist/commands/swap.js +107 -0
- package/dist/commands/transfer.js +38 -25
- package/dist/commands/webhooks.js +2 -7
- package/dist/commands/x402.js +57 -41
- package/dist/lib/api.d.ts +50 -3
- package/dist/lib/api.js +41 -16
- package/dist/lib/config.d.ts +0 -1
- package/dist/lib/output.d.ts +1 -0
- package/dist/lib/output.js +3 -0
- package/dist/lib/tokens.d.ts +21 -0
- package/dist/lib/tokens.js +40 -0
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -109,19 +109,19 @@ Launch Claude Code / OpenCode routed through the Bankr gateway:
|
|
|
109
109
|
|
|
110
110
|
```bash
|
|
111
111
|
# Claude Code (auto-translates dotted model IDs to the Anthropic wire format)
|
|
112
|
-
bankr llm claude --model claude-opus-4-
|
|
112
|
+
bankr llm claude --model claude-opus-4-8
|
|
113
113
|
|
|
114
|
-
# Or use dotted form — bankr llm claude rewrites it to claude-opus-4-
|
|
115
|
-
bankr llm claude --model claude-opus-4.
|
|
114
|
+
# Or use dotted form — bankr llm claude rewrites it to claude-opus-4-8
|
|
115
|
+
bankr llm claude --model claude-opus-4.8
|
|
116
116
|
|
|
117
117
|
# OpenCode (use the bankr/ prefix with the gateway-canonical dotted form)
|
|
118
|
-
bankr llm opencode -m bankr/claude-opus-4.
|
|
118
|
+
bankr llm opencode -m bankr/claude-opus-4.8
|
|
119
119
|
```
|
|
120
120
|
|
|
121
121
|
**Claude Code model format**: Claude Code's `--model` flag expects
|
|
122
|
-
Anthropic-style dashed IDs (`claude-opus-4-
|
|
122
|
+
Anthropic-style dashed IDs (`claude-opus-4-8`, `claude-sonnet-4-6`,
|
|
123
123
|
`claude-haiku-4-5`). If you pass the gateway-canonical dotted form
|
|
124
|
-
(`claude-opus-4.
|
|
124
|
+
(`claude-opus-4.8`), Claude Code silently falls back to its default —
|
|
125
125
|
the flag appears honored but the real request is a different model.
|
|
126
126
|
|
|
127
127
|
`bankr llm claude` translates dotted → dashed for you. If you use older
|
|
@@ -159,7 +159,7 @@ Environment variables override stored values:
|
|
|
159
159
|
|
|
160
160
|
## API Key
|
|
161
161
|
|
|
162
|
-
Generate an API key at [bankr.bot/api](https://bankr.bot/api). Keys start with `bk_` and require Agent API access to be enabled.
|
|
162
|
+
Generate an API key at [bankr.bot/api-keys](https://bankr.bot/api-keys). Keys start with `bk_` and require Agent API access to be enabled.
|
|
163
163
|
|
|
164
164
|
## License
|
|
165
165
|
|
package/dist/cli.js
CHANGED
|
@@ -5,6 +5,7 @@ import { input } from "@inquirer/prompts";
|
|
|
5
5
|
import { balancesCommand } from "./commands/balances.js";
|
|
6
6
|
import { portfolioCommand } from "./commands/portfolio.js";
|
|
7
7
|
import { transferCommand } from "./commands/transfer.js";
|
|
8
|
+
import { swapCommand } from "./commands/swap.js";
|
|
8
9
|
import { skillsCommand } from "./commands/capabilities.js";
|
|
9
10
|
import { cancelCommand } from "./commands/cancel.js";
|
|
10
11
|
import { configGetCommand, configSetCommand } from "./commands/config.js";
|
|
@@ -48,6 +49,10 @@ async function readPromptInput() {
|
|
|
48
49
|
}
|
|
49
50
|
return text;
|
|
50
51
|
}
|
|
52
|
+
if (output.isNonInteractive()) {
|
|
53
|
+
output.error('No prompt provided. Pass it as an argument: bankr agent "your prompt"');
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
51
56
|
// Interactive input — shell expansion does not apply here
|
|
52
57
|
const text = await input({
|
|
53
58
|
message: "Enter your prompt:",
|
|
@@ -61,15 +66,6 @@ function colorizeHelp(text) {
|
|
|
61
66
|
return text
|
|
62
67
|
.split("\n")
|
|
63
68
|
.map((line) => {
|
|
64
|
-
// "Usage: ..." line
|
|
65
|
-
if (line.startsWith("Usage:"))
|
|
66
|
-
return output.fmt.brandBold(line);
|
|
67
|
-
// Section headers: "Options:" and "Commands:"
|
|
68
|
-
if (/^(Options|Commands):/.test(line))
|
|
69
|
-
return output.fmt.brandBold(line);
|
|
70
|
-
// Description line (standalone, no leading whitespace, no colon)
|
|
71
|
-
if (line === "Bankr AI agent CLI")
|
|
72
|
-
return output.fmt.brandBold(line);
|
|
73
69
|
// Command/option rows: leading whitespace then content
|
|
74
70
|
if (/^\s{2,}\S/.test(line)) {
|
|
75
71
|
const match = line.match(/^(\s+)([\w<>[\].\-,/ ]+?)(\s{2,}.+)$/);
|
|
@@ -86,19 +82,27 @@ program
|
|
|
86
82
|
.description("Bankr AI agent CLI\n\n Docs: https://docs.bankr.bot\n Skills: https://docs.bankr.bot/skills/overview")
|
|
87
83
|
.version(pkg.version, "-v, --version", "Show CLI version")
|
|
88
84
|
.helpOption("-h, --help", "Display help")
|
|
89
|
-
.
|
|
85
|
+
.helpCommand(false)
|
|
90
86
|
.option("--config <path>", "Path to config file (default: ~/.bankr/config.json)")
|
|
87
|
+
.option("--ni, --not-interactive", "Non-interactive mode: skip confirmation prompts (implies --yes) and fail fast on required input. Also enabled by BANKR_NOT_INTERACTIVE=1")
|
|
88
|
+
.configureHelp({
|
|
89
|
+
styleTitle: (str) => output.fmt.brandBold(str),
|
|
90
|
+
})
|
|
91
91
|
.configureOutput({
|
|
92
92
|
writeOut: (str) => process.stdout.write(colorizeHelp(str)),
|
|
93
93
|
writeErr: (str) => process.stderr.write(colorizeHelp(str)),
|
|
94
94
|
})
|
|
95
95
|
.hook("preAction", (thisCommand) => {
|
|
96
|
-
const
|
|
97
|
-
if (
|
|
98
|
-
|
|
96
|
+
const opts = thisCommand.opts();
|
|
97
|
+
if (opts.notInteractive) {
|
|
98
|
+
process.env.BANKR_NOT_INTERACTIVE = "1";
|
|
99
|
+
}
|
|
100
|
+
if (opts.config) {
|
|
101
|
+
setConfigPath(opts.config);
|
|
99
102
|
}
|
|
100
103
|
});
|
|
101
104
|
// ── Core commands ───────────────────────────────────────────────────────
|
|
105
|
+
program.commandsGroup("Account");
|
|
102
106
|
const loginCmd = program
|
|
103
107
|
.command("login")
|
|
104
108
|
.description("Authenticate with the Bankr API")
|
|
@@ -120,10 +124,12 @@ loginCmd
|
|
|
120
124
|
.option("--code <otp>", "OTP code (step 2 of headless login)")
|
|
121
125
|
.option("--accept-terms", "Accept Terms of Service (skips prompt)")
|
|
122
126
|
.option("--key-name <name>", "API key name (default: CLI)")
|
|
127
|
+
.optionsGroup("API Permissions")
|
|
123
128
|
.option("--read-write", "Disable read-only mode (allow transactions)")
|
|
124
129
|
.option("--no-wallet-api", "Disable Wallet API (enabled by default)")
|
|
125
130
|
.option("--no-token-launch", "Disable Token Launch API (enabled by default)")
|
|
126
131
|
.option("--llm", "Enable LLM gateway on the API key")
|
|
132
|
+
.optionsGroup("Security")
|
|
127
133
|
.option("--allowed-ips <ips>", "Comma-separated IP/CIDR allowlist, e.g. 1.2.3.4,10.0.0.0/24")
|
|
128
134
|
.option("--allowed-recipients <addresses>", "Comma-separated EVM/Solana addresses (agent will only send funds to these)")
|
|
129
135
|
.action(async (address, opts, cmd) => {
|
|
@@ -147,11 +153,12 @@ loginCmd
|
|
|
147
153
|
.command("siwe")
|
|
148
154
|
.description("Sign in with Ethereum wallet (SIWE, for headless agents)")
|
|
149
155
|
.requiredOption("--private-key <key>", "Ethereum private key (0x...)")
|
|
150
|
-
.option("--partner-key <key>", "Partner API key for fee attribution")
|
|
151
156
|
.option("--key-name <name>", "API key name (default: SIWE-<date>)")
|
|
157
|
+
.optionsGroup("API Permissions")
|
|
152
158
|
.option("--read-write", "Disable read-only mode (allow transactions)")
|
|
153
159
|
.option("--no-wallet-api", "Disable Wallet API (enabled by default)")
|
|
154
160
|
.option("--no-token-launch", "Disable Token Launch API (enabled by default)")
|
|
161
|
+
.optionsGroup("Security")
|
|
155
162
|
.option("--allowed-ips <ips>", "Comma-separated IP/CIDR allowlist, e.g. 1.2.3.4,10.0.0.0/24")
|
|
156
163
|
.option("--allowed-recipients <addresses>", "Comma-separated EVM/Solana addresses (agent will only send funds to these)")
|
|
157
164
|
.action(async (opts, cmd) => {
|
|
@@ -160,7 +167,6 @@ loginCmd
|
|
|
160
167
|
apiUrl: parentOpts.apiUrl,
|
|
161
168
|
siwe: true,
|
|
162
169
|
privateKey: opts.privateKey,
|
|
163
|
-
partnerKey: opts.partnerKey,
|
|
164
170
|
keyName: opts.keyName,
|
|
165
171
|
readWrite: opts.readWrite,
|
|
166
172
|
walletApi: opts.walletApi,
|
|
@@ -174,6 +180,7 @@ program
|
|
|
174
180
|
.description("Show wallet info and account details")
|
|
175
181
|
.action(whoamiCommand);
|
|
176
182
|
// Wallet commands (non-agentic operations)
|
|
183
|
+
program.commandsGroup("Wallet");
|
|
177
184
|
const walletCmd = program
|
|
178
185
|
.command("wallet")
|
|
179
186
|
.description("Wallet info, portfolio, transfer, sign, and submit")
|
|
@@ -209,6 +216,23 @@ walletCmd
|
|
|
209
216
|
chain: opts.chain,
|
|
210
217
|
});
|
|
211
218
|
});
|
|
219
|
+
walletCmd
|
|
220
|
+
.command("swap")
|
|
221
|
+
.description("Swap tokens on an EVM chain (same-chain)")
|
|
222
|
+
.requiredOption("--from <symbol or address>", "Token to sell: symbol (ETH, USDC) or contract address")
|
|
223
|
+
.requiredOption("--to <symbol or address>", "Token to buy: symbol (ETH, USDC) or contract address")
|
|
224
|
+
.requiredOption("--amount <amount>", "Amount of --from to sell (human-readable)")
|
|
225
|
+
.option("--chain <chain>", "EVM chain: base, polygon, mainnet, unichain, worldchain, arbitrum, bnb (default: base)")
|
|
226
|
+
.option("--quote-only", "Print the quote without executing the swap")
|
|
227
|
+
.action(async (opts) => {
|
|
228
|
+
await swapCommand({
|
|
229
|
+
from: opts.from,
|
|
230
|
+
to: opts.to,
|
|
231
|
+
amount: opts.amount,
|
|
232
|
+
chain: opts.chain,
|
|
233
|
+
quoteOnly: opts.quoteOnly,
|
|
234
|
+
});
|
|
235
|
+
});
|
|
212
236
|
walletCmd
|
|
213
237
|
.command("sign")
|
|
214
238
|
.description("Sign messages, typed data, or transactions")
|
|
@@ -268,6 +292,7 @@ walletSubmitCmd
|
|
|
268
292
|
});
|
|
269
293
|
});
|
|
270
294
|
// Agent commands (agentic operations that use LLM)
|
|
295
|
+
program.commandsGroup("Agent");
|
|
271
296
|
const agentCmd = program
|
|
272
297
|
.command("agent [text...]")
|
|
273
298
|
.description("AI agent commands (prompt, status, cancel, profile, skills)")
|
|
@@ -278,10 +303,14 @@ const agentCmd = program
|
|
|
278
303
|
opts.model ?? (opts.model = cmd.parent?.opts()?.model);
|
|
279
304
|
const joined = text.join(" ").trim();
|
|
280
305
|
if (!joined) {
|
|
306
|
+
if (output.isNonInteractive()) {
|
|
307
|
+
output.error('No prompt provided. Pass it as an argument: bankr agent "your prompt"');
|
|
308
|
+
process.exit(1);
|
|
309
|
+
}
|
|
281
310
|
agentCmd.help();
|
|
282
311
|
return;
|
|
283
312
|
}
|
|
284
|
-
await promptCommand(joined
|
|
313
|
+
await promptCommand(joined, opts);
|
|
285
314
|
});
|
|
286
315
|
agentCmd
|
|
287
316
|
.command("prompt [text...]")
|
|
@@ -308,16 +337,21 @@ agentCmd
|
|
|
308
337
|
.command("skills")
|
|
309
338
|
.description("Show all Bankr AI agent skills with examples")
|
|
310
339
|
.action(skillsCommand);
|
|
340
|
+
program.commandsGroup("Tokens");
|
|
311
341
|
program
|
|
312
342
|
.command("launch")
|
|
313
343
|
.description("Launch a token on Base (interactive wizard)")
|
|
344
|
+
.optionsGroup("Token")
|
|
314
345
|
.option("--name <name>", "Token name")
|
|
315
346
|
.option("--symbol <symbol>", "Token symbol (default: auto-generated from name)")
|
|
316
347
|
.option("--image <url>", "Token image URL")
|
|
348
|
+
.optionsGroup("Links")
|
|
317
349
|
.option("--tweet <url>", "Associated tweet URL")
|
|
318
350
|
.option("--website <url>", "Project website URL")
|
|
351
|
+
.optionsGroup("Fees")
|
|
319
352
|
.option("--fee <recipient>", "Fee recipient (username, ENS, or address)")
|
|
320
353
|
.option("--fee-type <type>", "Fee recipient type: x, farcaster, ens, wallet (default: x)")
|
|
354
|
+
.optionsGroup("")
|
|
321
355
|
.option("-y, --yes", "Skip confirmation prompt")
|
|
322
356
|
.option("--simulate", "Simulate the deploy without broadcasting a transaction")
|
|
323
357
|
.action(async (opts) => {
|
|
@@ -333,6 +367,7 @@ program
|
|
|
333
367
|
simulate: opts.simulate,
|
|
334
368
|
});
|
|
335
369
|
});
|
|
370
|
+
program.commandsGroup("Tokens");
|
|
336
371
|
const feesCmd = program
|
|
337
372
|
.command("fees [address]")
|
|
338
373
|
.description("View and claim creator token fee earnings")
|
|
@@ -383,6 +418,7 @@ profileCmd
|
|
|
383
418
|
profileCmd
|
|
384
419
|
.command("update")
|
|
385
420
|
.description("Update your agent profile")
|
|
421
|
+
.option("--slug <slug>", "Project slug (required if multiple profiles)")
|
|
386
422
|
.option("--name <name>", "Project name")
|
|
387
423
|
.option("--description <text>", "Project description")
|
|
388
424
|
.option("--token <address>", "Token contract address")
|
|
@@ -391,6 +427,7 @@ profileCmd
|
|
|
391
427
|
.option("--json", "Output raw JSON")
|
|
392
428
|
.action(async (opts) => {
|
|
393
429
|
await profileUpdateCommand({
|
|
430
|
+
slug: opts.slug,
|
|
394
431
|
name: opts.name,
|
|
395
432
|
description: opts.description,
|
|
396
433
|
token: opts.token,
|
|
@@ -402,20 +439,26 @@ profileCmd
|
|
|
402
439
|
profileCmd
|
|
403
440
|
.command("delete")
|
|
404
441
|
.description("Delete your agent profile")
|
|
405
|
-
.
|
|
442
|
+
.option("--slug <slug>", "Project slug (required if multiple profiles)")
|
|
443
|
+
.action(async (opts) => {
|
|
444
|
+
await profileDeleteCommand({ slug: opts.slug });
|
|
445
|
+
});
|
|
406
446
|
profileCmd
|
|
407
447
|
.command("add-update")
|
|
408
448
|
.description("Add a project update to your profile")
|
|
449
|
+
.option("--slug <slug>", "Project slug (required if multiple profiles)")
|
|
409
450
|
.option("--title <title>", "Update title")
|
|
410
451
|
.option("--content <text>", "Update content")
|
|
411
452
|
.option("--json", "Output raw JSON")
|
|
412
453
|
.action(async (opts) => {
|
|
413
454
|
await profileAddUpdateCommand({
|
|
455
|
+
slug: opts.slug,
|
|
414
456
|
title: opts.title,
|
|
415
457
|
content: opts.content,
|
|
416
458
|
json: opts.json,
|
|
417
459
|
});
|
|
418
460
|
});
|
|
461
|
+
program.commandsGroup("LLM");
|
|
419
462
|
const llmCmd = program
|
|
420
463
|
.command("llm")
|
|
421
464
|
.description("LLM Gateway tools")
|
|
@@ -425,6 +468,7 @@ const llmCmd = program
|
|
|
425
468
|
llmCmd
|
|
426
469
|
.command("models")
|
|
427
470
|
.description("List available models")
|
|
471
|
+
.option("--private", "Show only models that support private (:private) inference")
|
|
428
472
|
.action(modelsCommand);
|
|
429
473
|
const llmCreditsCmd = llmCmd
|
|
430
474
|
.command("credits")
|
|
@@ -487,6 +531,7 @@ llmCmd
|
|
|
487
531
|
await opencodeCommand(args);
|
|
488
532
|
});
|
|
489
533
|
// Token search and info
|
|
534
|
+
program.commandsGroup("Tokens");
|
|
490
535
|
const tokensCmd = program
|
|
491
536
|
.command("tokens")
|
|
492
537
|
.description("Token search and info")
|
|
@@ -507,62 +552,7 @@ tokensCmd
|
|
|
507
552
|
.action(async (address, opts) => {
|
|
508
553
|
await tokensInfoCommand(address, opts);
|
|
509
554
|
});
|
|
510
|
-
|
|
511
|
-
const configCmd = program
|
|
512
|
-
.command("config")
|
|
513
|
-
.description("Manage CLI configuration");
|
|
514
|
-
configCmd
|
|
515
|
-
.command("get [key]")
|
|
516
|
-
.description("Get config value(s). Keys: apiKey, apiUrl, llmKey, llmUrl")
|
|
517
|
-
.action(configGetCommand);
|
|
518
|
-
configCmd
|
|
519
|
-
.command("set <key> <value>")
|
|
520
|
-
.description("Set a config value. Keys: apiKey, apiUrl, llmKey, llmUrl")
|
|
521
|
-
.action(configSetCommand);
|
|
522
|
-
const soundsCmd = program
|
|
523
|
-
.command("sounds")
|
|
524
|
-
.description("Manage CESP sound packs")
|
|
525
|
-
.action(soundsStatusCommand);
|
|
526
|
-
soundsCmd
|
|
527
|
-
.command("enable")
|
|
528
|
-
.description("Enable sounds")
|
|
529
|
-
.action(soundsEnableCommand);
|
|
530
|
-
soundsCmd
|
|
531
|
-
.command("disable")
|
|
532
|
-
.description("Disable sounds")
|
|
533
|
-
.action(soundsDisableCommand);
|
|
534
|
-
soundsCmd
|
|
535
|
-
.command("install <pack>")
|
|
536
|
-
.description("Install a sound pack from the CESP registry")
|
|
537
|
-
.action(soundsInstallCommand);
|
|
538
|
-
soundsCmd
|
|
539
|
-
.command("search [query]")
|
|
540
|
-
.description("Search available packs in the CESP registry")
|
|
541
|
-
.action(soundsSearchCommand);
|
|
542
|
-
soundsCmd
|
|
543
|
-
.command("list")
|
|
544
|
-
.description("List installed sound packs")
|
|
545
|
-
.action(soundsListCommand);
|
|
546
|
-
soundsCmd
|
|
547
|
-
.command("use <pack>")
|
|
548
|
-
.description("Set active sound pack")
|
|
549
|
-
.action(soundsUseCommand);
|
|
550
|
-
soundsCmd
|
|
551
|
-
.command("volume [level]")
|
|
552
|
-
.description("Get or set volume (0.0-1.0)")
|
|
553
|
-
.action(soundsVolumeCommand);
|
|
554
|
-
soundsCmd
|
|
555
|
-
.command("mute")
|
|
556
|
-
.description("Mute all sounds")
|
|
557
|
-
.action(soundsMuteCommand);
|
|
558
|
-
soundsCmd
|
|
559
|
-
.command("unmute")
|
|
560
|
-
.description("Unmute sounds")
|
|
561
|
-
.action(soundsUnmuteCommand);
|
|
562
|
-
soundsCmd
|
|
563
|
-
.command("test [category]")
|
|
564
|
-
.description("Play a test sound")
|
|
565
|
-
.action(soundsTestCommand);
|
|
555
|
+
program.commandsGroup("Account");
|
|
566
556
|
program
|
|
567
557
|
.command("logout")
|
|
568
558
|
.description("Clear stored credentials")
|
|
@@ -641,6 +631,7 @@ profileAliasCmd
|
|
|
641
631
|
});
|
|
642
632
|
profileAliasCmd
|
|
643
633
|
.command("update")
|
|
634
|
+
.option("--slug <slug>", "Project slug")
|
|
644
635
|
.option("--name <name>", "Project name")
|
|
645
636
|
.option("--description <text>", "Project description")
|
|
646
637
|
.option("--token <address>", "Token contract address")
|
|
@@ -650,6 +641,7 @@ profileAliasCmd
|
|
|
650
641
|
.action(async (opts) => {
|
|
651
642
|
deprecatedCmd("profile update", "agent profile update");
|
|
652
643
|
await profileUpdateCommand({
|
|
644
|
+
slug: opts.slug,
|
|
653
645
|
name: opts.name,
|
|
654
646
|
description: opts.description,
|
|
655
647
|
token: opts.token,
|
|
@@ -658,18 +650,23 @@ profileAliasCmd
|
|
|
658
650
|
json: opts.json,
|
|
659
651
|
});
|
|
660
652
|
});
|
|
661
|
-
profileAliasCmd
|
|
653
|
+
profileAliasCmd
|
|
654
|
+
.command("delete")
|
|
655
|
+
.option("--slug <slug>", "Project slug")
|
|
656
|
+
.action(async (opts) => {
|
|
662
657
|
deprecatedCmd("profile delete", "agent profile delete");
|
|
663
|
-
await profileDeleteCommand();
|
|
658
|
+
await profileDeleteCommand({ slug: opts.slug });
|
|
664
659
|
});
|
|
665
660
|
profileAliasCmd
|
|
666
661
|
.command("add-update")
|
|
662
|
+
.option("--slug <slug>", "Project slug")
|
|
667
663
|
.option("--title <title>", "Update title")
|
|
668
664
|
.option("--content <text>", "Update content")
|
|
669
665
|
.option("--json", "Output raw JSON")
|
|
670
666
|
.action(async (opts) => {
|
|
671
667
|
deprecatedCmd("profile add-update", "agent profile add-update");
|
|
672
668
|
await profileAddUpdateCommand({
|
|
669
|
+
slug: opts.slug,
|
|
673
670
|
title: opts.title,
|
|
674
671
|
content: opts.content,
|
|
675
672
|
json: opts.json,
|
|
@@ -736,14 +733,8 @@ submitAliasCmd
|
|
|
736
733
|
description: opts.description,
|
|
737
734
|
});
|
|
738
735
|
});
|
|
739
|
-
program
|
|
740
|
-
.command("update")
|
|
741
|
-
.description("Update the Bankr CLI to the latest version")
|
|
742
|
-
.option("--check", "Check for updates without installing")
|
|
743
|
-
.action(async (opts) => {
|
|
744
|
-
await updateCommand({ check: opts.check });
|
|
745
|
-
});
|
|
746
736
|
// ── File Storage ────────────────────────────────────────────────────────
|
|
737
|
+
program.commandsGroup("Protocol");
|
|
747
738
|
const filesCmd = program
|
|
748
739
|
.command("files")
|
|
749
740
|
.description("Manage your file storage")
|
|
@@ -814,6 +805,7 @@ filesCmd
|
|
|
814
805
|
.description("Show file metadata")
|
|
815
806
|
.action(filesInfoCommand);
|
|
816
807
|
// ── Bankr Club ────────────────────────────────────────────────────────
|
|
808
|
+
program.commandsGroup("Account");
|
|
817
809
|
const clubCmd = program
|
|
818
810
|
.command("club")
|
|
819
811
|
.description("View Bankr Club membership, sign up, or cancel")
|
|
@@ -824,8 +816,9 @@ clubCmd
|
|
|
824
816
|
.action(clubStatusCommand);
|
|
825
817
|
clubCmd
|
|
826
818
|
.command("signup")
|
|
827
|
-
.description("Sign up for Bankr Club (
|
|
819
|
+
.description("Sign up for Bankr Club (default: USDC; --token BNKR | ETH | <0x...>)")
|
|
828
820
|
.option("--yearly", "Subscribe yearly instead of monthly")
|
|
821
|
+
.option("--token <symbolOrAddress>", "Payment token: USDC (default), BNKR, ETH, or a 0x... Base address")
|
|
829
822
|
.option("-y, --yes", "Skip confirmation prompt")
|
|
830
823
|
.action(clubSignupCommand);
|
|
831
824
|
clubCmd
|
|
@@ -834,6 +827,7 @@ clubCmd
|
|
|
834
827
|
.option("-y, --yes", "Skip confirmation prompt")
|
|
835
828
|
.action(clubCancelCommand);
|
|
836
829
|
// ── x402 Endpoint Hosting ─────────────────────────────────────────────
|
|
830
|
+
program.commandsGroup("Protocol");
|
|
837
831
|
const x402Cmd = program
|
|
838
832
|
.command("x402")
|
|
839
833
|
.description("Deploy and manage x402 paid API endpoints");
|
|
@@ -889,6 +883,7 @@ x402EnvCmd
|
|
|
889
883
|
.description("Remove an env var")
|
|
890
884
|
.action(x402EnvUnsetCommand);
|
|
891
885
|
// ── User Webhooks ─────────────────────────────────────────────────────
|
|
886
|
+
program.commandsGroup("Protocol");
|
|
892
887
|
const webhooksCmd = program
|
|
893
888
|
.command("webhooks")
|
|
894
889
|
.description("Deploy and manage user webhooks that trigger the Bankr agent on external events");
|
|
@@ -960,6 +955,70 @@ x402Cmd
|
|
|
960
955
|
.option("-y, --yes", "Skip payment confirmation")
|
|
961
956
|
.option("--raw", "Output raw JSON (unformatted)")
|
|
962
957
|
.action(async (url, opts) => x402CallCommand(url, opts));
|
|
958
|
+
// ── Settings ────────────────────────────────────────────────────────────
|
|
959
|
+
program.commandsGroup("Settings");
|
|
960
|
+
const configCmd = program
|
|
961
|
+
.command("config")
|
|
962
|
+
.description("Manage CLI configuration");
|
|
963
|
+
configCmd
|
|
964
|
+
.command("get [key]")
|
|
965
|
+
.description("Get config value(s). Keys: apiKey, apiUrl, llmKey, llmUrl")
|
|
966
|
+
.action(configGetCommand);
|
|
967
|
+
configCmd
|
|
968
|
+
.command("set <key> <value>")
|
|
969
|
+
.description("Set a config value. Keys: apiKey, apiUrl, llmKey, llmUrl")
|
|
970
|
+
.action(configSetCommand);
|
|
971
|
+
const soundsCmd = program
|
|
972
|
+
.command("sounds")
|
|
973
|
+
.description("Manage CESP sound packs")
|
|
974
|
+
.action(soundsStatusCommand);
|
|
975
|
+
soundsCmd
|
|
976
|
+
.command("enable")
|
|
977
|
+
.description("Enable sounds")
|
|
978
|
+
.action(soundsEnableCommand);
|
|
979
|
+
soundsCmd
|
|
980
|
+
.command("disable")
|
|
981
|
+
.description("Disable sounds")
|
|
982
|
+
.action(soundsDisableCommand);
|
|
983
|
+
soundsCmd
|
|
984
|
+
.command("install <pack>")
|
|
985
|
+
.description("Install a sound pack from the CESP registry")
|
|
986
|
+
.action(soundsInstallCommand);
|
|
987
|
+
soundsCmd
|
|
988
|
+
.command("search [query]")
|
|
989
|
+
.description("Search available packs in the CESP registry")
|
|
990
|
+
.action(soundsSearchCommand);
|
|
991
|
+
soundsCmd
|
|
992
|
+
.command("list")
|
|
993
|
+
.description("List installed sound packs")
|
|
994
|
+
.action(soundsListCommand);
|
|
995
|
+
soundsCmd
|
|
996
|
+
.command("use <pack>")
|
|
997
|
+
.description("Set active sound pack")
|
|
998
|
+
.action(soundsUseCommand);
|
|
999
|
+
soundsCmd
|
|
1000
|
+
.command("volume [level]")
|
|
1001
|
+
.description("Get or set volume (0.0-1.0)")
|
|
1002
|
+
.action(soundsVolumeCommand);
|
|
1003
|
+
soundsCmd
|
|
1004
|
+
.command("mute")
|
|
1005
|
+
.description("Mute all sounds")
|
|
1006
|
+
.action(soundsMuteCommand);
|
|
1007
|
+
soundsCmd
|
|
1008
|
+
.command("unmute")
|
|
1009
|
+
.description("Unmute sounds")
|
|
1010
|
+
.action(soundsUnmuteCommand);
|
|
1011
|
+
soundsCmd
|
|
1012
|
+
.command("test [category]")
|
|
1013
|
+
.description("Play a test sound")
|
|
1014
|
+
.action(soundsTestCommand);
|
|
1015
|
+
program
|
|
1016
|
+
.command("update")
|
|
1017
|
+
.description("Update the Bankr CLI to the latest version")
|
|
1018
|
+
.option("--check", "Check for updates without installing")
|
|
1019
|
+
.action(async (opts) => {
|
|
1020
|
+
await updateCommand({ check: opts.check });
|
|
1021
|
+
});
|
|
963
1022
|
// Default: treat unrecognized arguments as a prompt
|
|
964
1023
|
program
|
|
965
1024
|
.arguments("[text...]")
|
|
@@ -968,6 +1027,10 @@ program
|
|
|
968
1027
|
.option("-m, --model <model>", "Use Max Mode with a specific model (e.g. claude-opus-4.6)")
|
|
969
1028
|
.action(async (text, opts) => {
|
|
970
1029
|
if (text.length === 0) {
|
|
1030
|
+
if (output.isNonInteractive()) {
|
|
1031
|
+
output.error('No prompt provided. Pass it as an argument: bankr "your prompt"');
|
|
1032
|
+
process.exit(1);
|
|
1033
|
+
}
|
|
971
1034
|
program.help();
|
|
972
1035
|
return;
|
|
973
1036
|
}
|
package/dist/commands/club.d.ts
CHANGED
package/dist/commands/club.js
CHANGED
|
@@ -8,6 +8,33 @@ function authHeaders() {
|
|
|
8
8
|
"User-Agent": CLI_USER_AGENT,
|
|
9
9
|
};
|
|
10
10
|
}
|
|
11
|
+
// Common Base tokens accepted as `--token` shortcuts. Lowercase to bypass
|
|
12
|
+
// viem's strict EIP-55 checksum on the API's isAddress() check; the route
|
|
13
|
+
// resolves to lowercase server-side anyway. Inlined here (not imported
|
|
14
|
+
// from the monorepo) because @bankr/cli is published standalone.
|
|
15
|
+
const TOKEN_ALIASES = {
|
|
16
|
+
USDC: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
|
|
17
|
+
BNKR: "0x22af33fe49fd1fa80c7149773dde5890d3c76f3b",
|
|
18
|
+
// Native-asset sentinel address used by 0x and most aggregators.
|
|
19
|
+
ETH: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
|
|
20
|
+
};
|
|
21
|
+
const ADDRESS_RE = /^0x[a-fA-F0-9]{40}$/;
|
|
22
|
+
/**
|
|
23
|
+
* Resolve a user-supplied `--token` value to a Base ERC-20 address.
|
|
24
|
+
* Accepts a known symbol (USDC | BNKR | ETH, case-insensitive) or any
|
|
25
|
+
* 0x-prefixed 40-char address. Returns null for invalid input.
|
|
26
|
+
*/
|
|
27
|
+
function resolvePaymentToken(input) {
|
|
28
|
+
if (!input)
|
|
29
|
+
return null;
|
|
30
|
+
const normalized = input.trim();
|
|
31
|
+
const upper = normalized.toUpperCase();
|
|
32
|
+
if (TOKEN_ALIASES[upper])
|
|
33
|
+
return TOKEN_ALIASES[upper];
|
|
34
|
+
if (ADDRESS_RE.test(normalized))
|
|
35
|
+
return normalized;
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
11
38
|
async function fetchStatus() {
|
|
12
39
|
const res = await fetch(`${getApiUrl()}/bankr-club/`, {
|
|
13
40
|
headers: authHeaders(),
|
|
@@ -63,8 +90,20 @@ export async function clubSignupCommand(opts) {
|
|
|
63
90
|
output.warn("You already have an active Bankr Club subscription.");
|
|
64
91
|
return;
|
|
65
92
|
}
|
|
93
|
+
let tokenAddress;
|
|
94
|
+
if (opts.token) {
|
|
95
|
+
const resolved = resolvePaymentToken(opts.token);
|
|
96
|
+
if (!resolved) {
|
|
97
|
+
output.error(`Unknown token "${opts.token}". Use one of USDC, BNKR, ETH, or pass a 0x-prefixed Base address.`);
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
tokenAddress = resolved;
|
|
101
|
+
}
|
|
66
102
|
const yearly = !!opts.yearly;
|
|
67
|
-
|
|
103
|
+
// Reused for /quote and /sign-up so both endpoints agree on the token.
|
|
104
|
+
// The API rejects sign-up with `quote-token-mismatch` if they diverge.
|
|
105
|
+
const tokenParam = tokenAddress ? `&token=${tokenAddress}` : "";
|
|
106
|
+
const quoteRes = await fetch(`${getApiUrl()}/bankr-club/quote?yearly=${yearly}${tokenParam}`, { headers: authHeaders() });
|
|
68
107
|
if (!quoteRes.ok) {
|
|
69
108
|
const body = await quoteRes
|
|
70
109
|
.json()
|
|
@@ -72,13 +111,15 @@ export async function clubSignupCommand(opts) {
|
|
|
72
111
|
throw new Error(body.error || quoteRes.statusText);
|
|
73
112
|
}
|
|
74
113
|
const quote = (await quoteRes.json());
|
|
114
|
+
const symbol = quote.tokenSymbol ?? "USDC";
|
|
75
115
|
output.label("Plan", yearly ? "Yearly" : "Monthly");
|
|
76
|
-
output.label("Price", `${output.formatUsd(quote.usdPrice)} (in $
|
|
77
|
-
output.label("Cost", `${quote.
|
|
116
|
+
output.label("Price", `${output.formatUsd(quote.usdPrice)} (in ${symbol})`);
|
|
117
|
+
output.label("Cost", `${quote.priceInToken} ${symbol}`);
|
|
78
118
|
output.dim(`Quote expires ${new Date(quote.expiresAt * 1000).toLocaleString()}.`);
|
|
79
119
|
output.blank();
|
|
80
|
-
output.dim(
|
|
120
|
+
output.dim(`Payment is deducted from your ${symbol} balance in your Bankr wallet.`);
|
|
81
121
|
const ok = opts.yes ||
|
|
122
|
+
output.isNonInteractive() ||
|
|
82
123
|
(await confirm({
|
|
83
124
|
message: "Confirm subscription?",
|
|
84
125
|
default: false,
|
|
@@ -89,7 +130,7 @@ export async function clubSignupCommand(opts) {
|
|
|
89
130
|
return;
|
|
90
131
|
}
|
|
91
132
|
const spinner = output.spinner("Signing up for Bankr Club...");
|
|
92
|
-
const signUpRes = await fetch(`${getApiUrl()}/bankr-club/sign-up?yearly=${yearly}`, { headers: authHeaders() });
|
|
133
|
+
const signUpRes = await fetch(`${getApiUrl()}/bankr-club/sign-up?yearly=${yearly}${tokenParam}`, { headers: authHeaders() });
|
|
93
134
|
spinner.stop();
|
|
94
135
|
if (!signUpRes.ok) {
|
|
95
136
|
const body = await signUpRes
|
|
@@ -121,6 +162,7 @@ export async function clubCancelCommand(opts) {
|
|
|
121
162
|
return;
|
|
122
163
|
}
|
|
123
164
|
const ok = opts.yes ||
|
|
165
|
+
output.isNonInteractive() ||
|
|
124
166
|
(await confirm({
|
|
125
167
|
message: "Cancel Bankr Club? You'll keep access until the current billing period ends.",
|
|
126
168
|
default: false,
|
package/dist/commands/fees.js
CHANGED
|
@@ -386,7 +386,7 @@ export async function feesCommand(address, opts) {
|
|
|
386
386
|
export async function feesClaimCommand(tokenAddress, opts) {
|
|
387
387
|
requireApiKey();
|
|
388
388
|
// Confirm — we send one request that builds, signs, and broadcasts.
|
|
389
|
-
if (!opts.yes) {
|
|
389
|
+
if (!opts.yes && !output.isNonInteractive()) {
|
|
390
390
|
console.log();
|
|
391
391
|
output.keyValue("Token", tokenAddress);
|
|
392
392
|
output.keyValue("Action", "Claim trading fees");
|
|
@@ -452,6 +452,10 @@ export async function feesClaimWalletCommand(address, opts) {
|
|
|
452
452
|
if (address && !isAddress(address)) {
|
|
453
453
|
address = undefined;
|
|
454
454
|
}
|
|
455
|
+
if (output.isNonInteractive() && !opts.all) {
|
|
456
|
+
output.error("Use --all to select all tokens in non-interactive mode, or run interactively to choose");
|
|
457
|
+
process.exit(1);
|
|
458
|
+
}
|
|
455
459
|
// Load .env from cwd if present (no dependency needed)
|
|
456
460
|
try {
|
|
457
461
|
const { readFileSync, existsSync } = await import("node:fs");
|
|
@@ -492,6 +496,10 @@ export async function feesClaimWalletCommand(address, opts) {
|
|
|
492
496
|
process.exit(1);
|
|
493
497
|
}
|
|
494
498
|
else {
|
|
499
|
+
if (output.isNonInteractive()) {
|
|
500
|
+
output.error("Private key required in non-interactive mode. Use --private-key or set BANKR_PRIVATE_KEY");
|
|
501
|
+
process.exit(1);
|
|
502
|
+
}
|
|
495
503
|
privateKey = await password({
|
|
496
504
|
message: "Enter private key for this wallet (0x...):",
|
|
497
505
|
mask: "*",
|
|
@@ -680,7 +688,7 @@ export async function feesClaimWalletCommand(address, opts) {
|
|
|
680
688
|
console.log(` ${DIM("To:")} ${tx.to} ${DIM("Gas:")} ~${gasCostEth.toFixed(6)} ETH`);
|
|
681
689
|
console.log();
|
|
682
690
|
}
|
|
683
|
-
if (!opts.yes) {
|
|
691
|
+
if (!opts.yes && !output.isNonInteractive()) {
|
|
684
692
|
const proceed = await confirm({
|
|
685
693
|
message: `Submit ${readyTxs.length} claim transaction${readyTxs.length !== 1 ? "s" : ""}?`,
|
|
686
694
|
default: true,
|