@bankr/cli 0.1.3 → 0.2.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/dist/cli.js +379 -133
- package/dist/commands/balances.d.ts +1 -0
- package/dist/commands/balances.js +7 -32
- package/dist/commands/llm.js +47 -3
- package/dist/commands/login.d.ts +5 -0
- package/dist/commands/login.js +139 -33
- package/dist/commands/portfolio.d.ts +9 -0
- package/dist/commands/portfolio.js +134 -0
- package/dist/commands/tokens.d.ts +7 -0
- package/dist/commands/tokens.js +60 -0
- package/dist/commands/transfer.d.ts +8 -0
- package/dist/commands/transfer.js +80 -0
- package/dist/commands/update.d.ts +4 -0
- package/dist/commands/update.js +116 -0
- package/dist/lib/api.d.ts +59 -2
- package/dist/lib/api.js +34 -8
- package/dist/lib/chains.d.ts +5 -0
- package/dist/lib/chains.js +35 -0
- package/dist/lib/output.d.ts +2 -0
- package/dist/lib/output.js +17 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3,6 +3,8 @@ import { readFileSync } from "node:fs";
|
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
import { input } from "@inquirer/prompts";
|
|
5
5
|
import { balancesCommand } from "./commands/balances.js";
|
|
6
|
+
import { portfolioCommand } from "./commands/portfolio.js";
|
|
7
|
+
import { transferCommand } from "./commands/transfer.js";
|
|
6
8
|
import { skillsCommand } from "./commands/capabilities.js";
|
|
7
9
|
import { cancelCommand } from "./commands/cancel.js";
|
|
8
10
|
import { configGetCommand, configSetCommand } from "./commands/config.js";
|
|
@@ -17,7 +19,9 @@ import { signCommand } from "./commands/sign.js";
|
|
|
17
19
|
import { soundsDisableCommand, soundsEnableCommand, soundsInstallCommand, soundsListCommand, soundsMuteCommand, soundsSearchCommand, soundsStatusCommand, soundsTestCommand, soundsUnmuteCommand, soundsUseCommand, soundsVolumeCommand, } from "./commands/sounds.js";
|
|
18
20
|
import { statusCommand } from "./commands/status.js";
|
|
19
21
|
import { submitCommand, submitJsonCommand } from "./commands/submit.js";
|
|
22
|
+
import { updateCommand } from "./commands/update.js";
|
|
20
23
|
import { whoamiCommand } from "./commands/whoami.js";
|
|
24
|
+
import { tokensSearchCommand, tokensInfoCommand } from "./commands/tokens.js";
|
|
21
25
|
import { profileViewCommand, profileCreateCommand, profileUpdateCommand, profileDeleteCommand, profileAddUpdateCommand, } from "./commands/profile.js";
|
|
22
26
|
import * as output from "./lib/output.js";
|
|
23
27
|
const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
|
|
@@ -74,7 +78,7 @@ function colorizeHelp(text) {
|
|
|
74
78
|
}
|
|
75
79
|
program
|
|
76
80
|
.name("bankr")
|
|
77
|
-
.description("Bankr AI agent CLI")
|
|
81
|
+
.description("Bankr AI agent CLI\n\n Docs: https://docs.bankr.bot\n Skills: https://docs.bankr.bot/openclaw/installation")
|
|
78
82
|
.version(pkg.version, "-v, --version", "Show CLI version")
|
|
79
83
|
.helpOption("-h, --help", "Display help")
|
|
80
84
|
.addHelpCommand("help [command]", "Display help for command")
|
|
@@ -89,6 +93,7 @@ program
|
|
|
89
93
|
setConfigPath(configPath);
|
|
90
94
|
}
|
|
91
95
|
});
|
|
96
|
+
// ── Core commands ───────────────────────────────────────────────────────
|
|
92
97
|
const loginCmd = program
|
|
93
98
|
.command("login")
|
|
94
99
|
.description("Authenticate with the Bankr API")
|
|
@@ -110,8 +115,13 @@ loginCmd
|
|
|
110
115
|
.option("--code <otp>", "OTP code (step 2 of headless login)")
|
|
111
116
|
.option("--accept-terms", "Accept Terms of Service (skips prompt)")
|
|
112
117
|
.option("--key-name <name>", "API key name (default: CLI)")
|
|
113
|
-
.option("--read-write", "
|
|
118
|
+
.option("--read-write", "Disable read-only mode (allow transactions)")
|
|
119
|
+
.option("--no-wallet-api", "Disable Wallet API (enabled by default)")
|
|
120
|
+
.option("--agent-api", "Enable Agent API (AI prompts)")
|
|
121
|
+
.option("--no-token-launch", "Disable Token Launch API (enabled by default)")
|
|
114
122
|
.option("--llm", "Enable LLM gateway on the API key")
|
|
123
|
+
.option("--allowed-ips <ips>", "Comma-separated IP allowlist (requests from other IPs will be blocked)")
|
|
124
|
+
.option("--allowed-recipients <addresses>", "Comma-separated EVM/Solana addresses (agent will only send funds to these)")
|
|
115
125
|
.action(async (address, opts, cmd) => {
|
|
116
126
|
const parentOpts = cmd.parent.opts();
|
|
117
127
|
await loginCommand({
|
|
@@ -122,7 +132,12 @@ loginCmd
|
|
|
122
132
|
acceptTerms: opts.acceptTerms,
|
|
123
133
|
keyName: opts.keyName,
|
|
124
134
|
readWrite: opts.readWrite,
|
|
135
|
+
walletApi: opts.walletApi,
|
|
136
|
+
agentApi: opts.agentApi,
|
|
137
|
+
tokenLaunch: opts.tokenLaunch,
|
|
125
138
|
llm: opts.llm,
|
|
139
|
+
allowedIps: opts.allowedIps,
|
|
140
|
+
allowedRecipients: opts.allowedRecipients,
|
|
126
141
|
});
|
|
127
142
|
});
|
|
128
143
|
loginCmd
|
|
@@ -131,7 +146,12 @@ loginCmd
|
|
|
131
146
|
.requiredOption("--private-key <key>", "Ethereum private key (0x...)")
|
|
132
147
|
.option("--partner-key <key>", "Partner API key for fee attribution")
|
|
133
148
|
.option("--key-name <name>", "API key name (default: SIWE-<date>)")
|
|
134
|
-
.option("--read-write", "
|
|
149
|
+
.option("--read-write", "Disable read-only mode (allow transactions)")
|
|
150
|
+
.option("--no-wallet-api", "Disable Wallet API (enabled by default)")
|
|
151
|
+
.option("--agent-api", "Enable Agent API (AI prompts)")
|
|
152
|
+
.option("--no-token-launch", "Disable Token Launch API (enabled by default)")
|
|
153
|
+
.option("--allowed-ips <ips>", "Comma-separated IP allowlist (requests from other IPs will be blocked)")
|
|
154
|
+
.option("--allowed-recipients <addresses>", "Comma-separated EVM/Solana addresses (agent will only send funds to these)")
|
|
135
155
|
.action(async (opts, cmd) => {
|
|
136
156
|
const parentOpts = cmd.parent.opts();
|
|
137
157
|
await loginCommand({
|
|
@@ -141,25 +161,126 @@ loginCmd
|
|
|
141
161
|
partnerKey: opts.partnerKey,
|
|
142
162
|
keyName: opts.keyName,
|
|
143
163
|
readWrite: opts.readWrite,
|
|
164
|
+
walletApi: opts.walletApi,
|
|
165
|
+
agentApi: opts.agentApi,
|
|
166
|
+
tokenLaunch: opts.tokenLaunch,
|
|
167
|
+
allowedIps: opts.allowedIps,
|
|
168
|
+
allowedRecipients: opts.allowedRecipients,
|
|
144
169
|
});
|
|
145
170
|
});
|
|
146
|
-
program
|
|
147
|
-
.command("logout")
|
|
148
|
-
.description("Clear stored credentials")
|
|
149
|
-
.action(logoutCommand);
|
|
150
171
|
program
|
|
151
172
|
.command("whoami")
|
|
152
|
-
.description("Show
|
|
173
|
+
.description("Show wallet info and account details")
|
|
153
174
|
.action(whoamiCommand);
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
.
|
|
157
|
-
.
|
|
175
|
+
// Wallet commands (non-agentic operations)
|
|
176
|
+
const walletCmd = program
|
|
177
|
+
.command("wallet")
|
|
178
|
+
.description("Wallet info, portfolio, transfer, sign, and submit")
|
|
179
|
+
.action(async () => {
|
|
180
|
+
await whoamiCommand();
|
|
181
|
+
});
|
|
182
|
+
walletCmd
|
|
183
|
+
.command("portfolio")
|
|
184
|
+
.description("Show wallet portfolio: balances, PnL, and NFTs")
|
|
185
|
+
.option("--chain <chains>", "Chain(s): base, polygon, mainnet, unichain, solana (comma-separated)")
|
|
186
|
+
.option("--pnl", "Include profit/loss per token")
|
|
187
|
+
.option("--nfts", "Include NFT holdings")
|
|
188
|
+
.option("--all", "Include everything (pnl + nfts)")
|
|
158
189
|
.option("--json", "Output raw JSON")
|
|
190
|
+
.option("--low-value", "Include low-value tokens (under $1)")
|
|
159
191
|
.action(async (opts) => {
|
|
160
|
-
await
|
|
192
|
+
await portfolioCommand(opts);
|
|
161
193
|
});
|
|
162
|
-
|
|
194
|
+
walletCmd
|
|
195
|
+
.command("transfer")
|
|
196
|
+
.description("Transfer tokens to an EVM address")
|
|
197
|
+
.requiredOption("--to <address>", "Recipient address")
|
|
198
|
+
.requiredOption("--amount <amount>", "Amount to send (human-readable)")
|
|
199
|
+
.option("--token <symbol or address>", "Token symbol (USDC) or contract address")
|
|
200
|
+
.option("--native", "Send native token (ETH, POL) instead of ERC20")
|
|
201
|
+
.option("--chain <chain>", "EVM chain: base, polygon, mainnet, unichain (default: base)")
|
|
202
|
+
.action(async (opts) => {
|
|
203
|
+
await transferCommand({
|
|
204
|
+
to: opts.to,
|
|
205
|
+
amount: opts.amount,
|
|
206
|
+
token: opts.token,
|
|
207
|
+
native: opts.native,
|
|
208
|
+
chain: opts.chain,
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
walletCmd
|
|
212
|
+
.command("sign")
|
|
213
|
+
.description("Sign messages, typed data, or transactions")
|
|
214
|
+
.requiredOption("-t, --type <type>", "Signature type: personal_sign, eth_signTypedData_v4, eth_signTransaction")
|
|
215
|
+
.option("-m, --message <message>", "Message to sign (for personal_sign)")
|
|
216
|
+
.option("--typed-data <json>", "EIP-712 typed data as JSON (for eth_signTypedData_v4)")
|
|
217
|
+
.option("--transaction <json>", "Transaction as JSON (for eth_signTransaction)")
|
|
218
|
+
.action(async (opts) => {
|
|
219
|
+
await signCommand({
|
|
220
|
+
type: opts.type,
|
|
221
|
+
message: opts.message,
|
|
222
|
+
typedData: opts.typedData,
|
|
223
|
+
transaction: opts.transaction,
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
const walletSubmitCmd = walletCmd
|
|
227
|
+
.command("submit")
|
|
228
|
+
.description("Submit a transaction to the blockchain");
|
|
229
|
+
walletSubmitCmd
|
|
230
|
+
.command("tx")
|
|
231
|
+
.description("Submit transaction with explicit parameters")
|
|
232
|
+
.requiredOption("--to <address>", "Destination address")
|
|
233
|
+
.requiredOption("--chain-id <id>", "Chain ID (8453=Base, 1=Ethereum, 137=Polygon)")
|
|
234
|
+
.option("--value <wei>", "Value in wei")
|
|
235
|
+
.option("--data <hex>", "Calldata (hex string)")
|
|
236
|
+
.option("--gas <limit>", "Gas limit")
|
|
237
|
+
.option("--gas-price <wei>", "Gas price (legacy)")
|
|
238
|
+
.option("--max-fee-per-gas <wei>", "Max fee per gas (EIP-1559)")
|
|
239
|
+
.option("--max-priority-fee-per-gas <wei>", "Max priority fee (EIP-1559)")
|
|
240
|
+
.option("--nonce <n>", "Transaction nonce")
|
|
241
|
+
.option("-d, --description <text>", "Description for logging")
|
|
242
|
+
.option("--no-wait", "Don't wait for confirmation")
|
|
243
|
+
.action(async (opts) => {
|
|
244
|
+
await submitCommand({
|
|
245
|
+
to: opts.to,
|
|
246
|
+
chainId: opts.chainId,
|
|
247
|
+
value: opts.value,
|
|
248
|
+
data: opts.data,
|
|
249
|
+
gas: opts.gas,
|
|
250
|
+
gasPrice: opts.gasPrice,
|
|
251
|
+
maxFeePerGas: opts.maxFeePerGas,
|
|
252
|
+
maxPriorityFeePerGas: opts.maxPriorityFeePerGas,
|
|
253
|
+
nonce: opts.nonce,
|
|
254
|
+
description: opts.description,
|
|
255
|
+
noWait: !opts.wait,
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
walletSubmitCmd
|
|
259
|
+
.command("json <transaction>")
|
|
260
|
+
.description("Submit transaction from JSON: {to, chainId, value?, data?}")
|
|
261
|
+
.option("-d, --description <text>", "Description for logging")
|
|
262
|
+
.option("--no-wait", "Don't wait for confirmation")
|
|
263
|
+
.action(async (transaction, opts) => {
|
|
264
|
+
await submitJsonCommand(transaction, {
|
|
265
|
+
noWait: !opts.wait,
|
|
266
|
+
description: opts.description,
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
// Agent commands (agentic operations that use LLM)
|
|
270
|
+
const agentCmd = program
|
|
271
|
+
.command("agent [text...]")
|
|
272
|
+
.description("AI agent commands (prompt, status, cancel, profile, skills)")
|
|
273
|
+
.option("--thread <id>", "Continue a specific conversation thread")
|
|
274
|
+
.option("-c, --continue", "Continue the most recent thread")
|
|
275
|
+
.action(async (text, opts) => {
|
|
276
|
+
const joined = text.join(" ").trim();
|
|
277
|
+
if (!joined) {
|
|
278
|
+
agentCmd.help();
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
await promptCommand(joined || (await readPromptInput()), opts);
|
|
282
|
+
});
|
|
283
|
+
agentCmd
|
|
163
284
|
.command("prompt [text...]")
|
|
164
285
|
.description("Send a prompt to the Bankr AI agent")
|
|
165
286
|
.option("--thread <id>", "Continue a specific conversation thread")
|
|
@@ -168,73 +289,18 @@ program
|
|
|
168
289
|
const joined = text.join(" ").trim();
|
|
169
290
|
await promptCommand(joined || (await readPromptInput()), opts);
|
|
170
291
|
});
|
|
171
|
-
|
|
292
|
+
agentCmd
|
|
172
293
|
.command("status <jobId>")
|
|
173
294
|
.description("Check the status of a job")
|
|
174
295
|
.action(statusCommand);
|
|
175
|
-
|
|
296
|
+
agentCmd
|
|
176
297
|
.command("cancel <jobId>")
|
|
177
298
|
.description("Cancel a running job")
|
|
178
299
|
.action(cancelCommand);
|
|
179
|
-
|
|
180
|
-
.command("config")
|
|
181
|
-
.description("Manage CLI configuration");
|
|
182
|
-
configCmd
|
|
183
|
-
.command("get [key]")
|
|
184
|
-
.description("Get config value(s). Keys: apiKey, apiUrl, llmKey, llmUrl")
|
|
185
|
-
.action(configGetCommand);
|
|
186
|
-
configCmd
|
|
187
|
-
.command("set <key> <value>")
|
|
188
|
-
.description("Set a config value. Keys: apiKey, apiUrl, llmKey, llmUrl")
|
|
189
|
-
.action(configSetCommand);
|
|
190
|
-
program
|
|
300
|
+
agentCmd
|
|
191
301
|
.command("skills")
|
|
192
302
|
.description("Show all Bankr AI agent skills with examples")
|
|
193
303
|
.action(skillsCommand);
|
|
194
|
-
const soundsCmd = program
|
|
195
|
-
.command("sounds")
|
|
196
|
-
.description("Manage CESP sound packs")
|
|
197
|
-
.action(soundsStatusCommand);
|
|
198
|
-
soundsCmd
|
|
199
|
-
.command("enable")
|
|
200
|
-
.description("Enable sounds")
|
|
201
|
-
.action(soundsEnableCommand);
|
|
202
|
-
soundsCmd
|
|
203
|
-
.command("disable")
|
|
204
|
-
.description("Disable sounds")
|
|
205
|
-
.action(soundsDisableCommand);
|
|
206
|
-
soundsCmd
|
|
207
|
-
.command("install <pack>")
|
|
208
|
-
.description("Install a sound pack from the CESP registry")
|
|
209
|
-
.action(soundsInstallCommand);
|
|
210
|
-
soundsCmd
|
|
211
|
-
.command("search [query]")
|
|
212
|
-
.description("Search available packs in the CESP registry")
|
|
213
|
-
.action(soundsSearchCommand);
|
|
214
|
-
soundsCmd
|
|
215
|
-
.command("list")
|
|
216
|
-
.description("List installed sound packs")
|
|
217
|
-
.action(soundsListCommand);
|
|
218
|
-
soundsCmd
|
|
219
|
-
.command("use <pack>")
|
|
220
|
-
.description("Set active sound pack")
|
|
221
|
-
.action(soundsUseCommand);
|
|
222
|
-
soundsCmd
|
|
223
|
-
.command("volume [level]")
|
|
224
|
-
.description("Get or set volume (0.0-1.0)")
|
|
225
|
-
.action(soundsVolumeCommand);
|
|
226
|
-
soundsCmd
|
|
227
|
-
.command("mute")
|
|
228
|
-
.description("Mute all sounds")
|
|
229
|
-
.action(soundsMuteCommand);
|
|
230
|
-
soundsCmd
|
|
231
|
-
.command("unmute")
|
|
232
|
-
.description("Unmute sounds")
|
|
233
|
-
.action(soundsUnmuteCommand);
|
|
234
|
-
soundsCmd
|
|
235
|
-
.command("test [category]")
|
|
236
|
-
.description("Play a test sound")
|
|
237
|
-
.action(soundsTestCommand);
|
|
238
304
|
program
|
|
239
305
|
.command("launch")
|
|
240
306
|
.description("Launch a token on Base (interactive wizard)")
|
|
@@ -280,7 +346,8 @@ feesCmd
|
|
|
280
346
|
.option("--all", "Claim all tokens without selection prompt")
|
|
281
347
|
.option("-y, --yes", "Skip confirmation prompt")
|
|
282
348
|
.action(feesClaimWalletCommand);
|
|
283
|
-
|
|
349
|
+
// Profile under agent namespace
|
|
350
|
+
const profileCmd = agentCmd
|
|
284
351
|
.command("profile")
|
|
285
352
|
.description("Manage your agent profile page")
|
|
286
353
|
.option("--json", "Output raw JSON")
|
|
@@ -342,64 +409,6 @@ profileCmd
|
|
|
342
409
|
json: opts.json,
|
|
343
410
|
});
|
|
344
411
|
});
|
|
345
|
-
program
|
|
346
|
-
.command("sign")
|
|
347
|
-
.description("Sign messages, typed data, or transactions")
|
|
348
|
-
.requiredOption("-t, --type <type>", "Signature type: personal_sign, eth_signTypedData_v4, eth_signTransaction")
|
|
349
|
-
.option("-m, --message <message>", "Message to sign (for personal_sign)")
|
|
350
|
-
.option("--typed-data <json>", "EIP-712 typed data as JSON (for eth_signTypedData_v4)")
|
|
351
|
-
.option("--transaction <json>", "Transaction as JSON (for eth_signTransaction)")
|
|
352
|
-
.action(async (opts) => {
|
|
353
|
-
await signCommand({
|
|
354
|
-
type: opts.type,
|
|
355
|
-
message: opts.message,
|
|
356
|
-
typedData: opts.typedData,
|
|
357
|
-
transaction: opts.transaction,
|
|
358
|
-
});
|
|
359
|
-
});
|
|
360
|
-
const submitCmd = program
|
|
361
|
-
.command("submit")
|
|
362
|
-
.description("Submit a transaction to the blockchain");
|
|
363
|
-
submitCmd
|
|
364
|
-
.command("tx")
|
|
365
|
-
.description("Submit transaction with explicit parameters")
|
|
366
|
-
.requiredOption("--to <address>", "Destination address")
|
|
367
|
-
.requiredOption("--chain-id <id>", "Chain ID (8453=Base, 1=Ethereum, 137=Polygon)")
|
|
368
|
-
.option("--value <wei>", "Value in wei")
|
|
369
|
-
.option("--data <hex>", "Calldata (hex string)")
|
|
370
|
-
.option("--gas <limit>", "Gas limit")
|
|
371
|
-
.option("--gas-price <wei>", "Gas price (legacy)")
|
|
372
|
-
.option("--max-fee-per-gas <wei>", "Max fee per gas (EIP-1559)")
|
|
373
|
-
.option("--max-priority-fee-per-gas <wei>", "Max priority fee (EIP-1559)")
|
|
374
|
-
.option("--nonce <n>", "Transaction nonce")
|
|
375
|
-
.option("-d, --description <text>", "Description for logging")
|
|
376
|
-
.option("--no-wait", "Don't wait for confirmation")
|
|
377
|
-
.action(async (opts) => {
|
|
378
|
-
await submitCommand({
|
|
379
|
-
to: opts.to,
|
|
380
|
-
chainId: opts.chainId,
|
|
381
|
-
value: opts.value,
|
|
382
|
-
data: opts.data,
|
|
383
|
-
gas: opts.gas,
|
|
384
|
-
gasPrice: opts.gasPrice,
|
|
385
|
-
maxFeePerGas: opts.maxFeePerGas,
|
|
386
|
-
maxPriorityFeePerGas: opts.maxPriorityFeePerGas,
|
|
387
|
-
nonce: opts.nonce,
|
|
388
|
-
description: opts.description,
|
|
389
|
-
noWait: !opts.wait,
|
|
390
|
-
});
|
|
391
|
-
});
|
|
392
|
-
submitCmd
|
|
393
|
-
.command("json <transaction>")
|
|
394
|
-
.description("Submit transaction from JSON: {to, chainId, value?, data?}")
|
|
395
|
-
.option("-d, --description <text>", "Description for logging")
|
|
396
|
-
.option("--no-wait", "Don't wait for confirmation")
|
|
397
|
-
.action(async (transaction, opts) => {
|
|
398
|
-
await submitJsonCommand(transaction, {
|
|
399
|
-
noWait: !opts.wait,
|
|
400
|
-
description: opts.description,
|
|
401
|
-
});
|
|
402
|
-
});
|
|
403
412
|
const llmCmd = program
|
|
404
413
|
.command("llm")
|
|
405
414
|
.description("LLM Gateway tools")
|
|
@@ -470,13 +479,250 @@ llmCmd
|
|
|
470
479
|
const args = idx >= 0 ? process.argv.slice(idx + 1) : [];
|
|
471
480
|
await opencodeCommand(args);
|
|
472
481
|
});
|
|
482
|
+
// Token search and info
|
|
483
|
+
const tokensCmd = program
|
|
484
|
+
.command("tokens")
|
|
485
|
+
.description("Token search and info")
|
|
486
|
+
.action(() => {
|
|
487
|
+
tokensCmd.help();
|
|
488
|
+
});
|
|
489
|
+
tokensCmd
|
|
490
|
+
.command("search <query>")
|
|
491
|
+
.description("Search tokens by name, symbol, or address")
|
|
492
|
+
.option("--chain <chainId>", "Chain ID (default: 8453 for Base)")
|
|
493
|
+
.action(async (query, opts) => {
|
|
494
|
+
await tokensSearchCommand(query, opts);
|
|
495
|
+
});
|
|
496
|
+
tokensCmd
|
|
497
|
+
.command("info <address>")
|
|
498
|
+
.description("Get detailed token info by contract address")
|
|
499
|
+
.option("--chain <chainId>", "Chain ID (default: 8453 for Base)")
|
|
500
|
+
.action(async (address, opts) => {
|
|
501
|
+
await tokensInfoCommand(address, opts);
|
|
502
|
+
});
|
|
503
|
+
// ── Utility commands ────────────────────────────────────────────────────
|
|
504
|
+
const configCmd = program
|
|
505
|
+
.command("config")
|
|
506
|
+
.description("Manage CLI configuration");
|
|
507
|
+
configCmd
|
|
508
|
+
.command("get [key]")
|
|
509
|
+
.description("Get config value(s). Keys: apiKey, apiUrl, llmKey, llmUrl")
|
|
510
|
+
.action(configGetCommand);
|
|
511
|
+
configCmd
|
|
512
|
+
.command("set <key> <value>")
|
|
513
|
+
.description("Set a config value. Keys: apiKey, apiUrl, llmKey, llmUrl")
|
|
514
|
+
.action(configSetCommand);
|
|
515
|
+
const soundsCmd = program
|
|
516
|
+
.command("sounds")
|
|
517
|
+
.description("Manage CESP sound packs")
|
|
518
|
+
.action(soundsStatusCommand);
|
|
519
|
+
soundsCmd
|
|
520
|
+
.command("enable")
|
|
521
|
+
.description("Enable sounds")
|
|
522
|
+
.action(soundsEnableCommand);
|
|
523
|
+
soundsCmd
|
|
524
|
+
.command("disable")
|
|
525
|
+
.description("Disable sounds")
|
|
526
|
+
.action(soundsDisableCommand);
|
|
527
|
+
soundsCmd
|
|
528
|
+
.command("install <pack>")
|
|
529
|
+
.description("Install a sound pack from the CESP registry")
|
|
530
|
+
.action(soundsInstallCommand);
|
|
531
|
+
soundsCmd
|
|
532
|
+
.command("search [query]")
|
|
533
|
+
.description("Search available packs in the CESP registry")
|
|
534
|
+
.action(soundsSearchCommand);
|
|
535
|
+
soundsCmd
|
|
536
|
+
.command("list")
|
|
537
|
+
.description("List installed sound packs")
|
|
538
|
+
.action(soundsListCommand);
|
|
539
|
+
soundsCmd
|
|
540
|
+
.command("use <pack>")
|
|
541
|
+
.description("Set active sound pack")
|
|
542
|
+
.action(soundsUseCommand);
|
|
543
|
+
soundsCmd
|
|
544
|
+
.command("volume [level]")
|
|
545
|
+
.description("Get or set volume (0.0-1.0)")
|
|
546
|
+
.action(soundsVolumeCommand);
|
|
547
|
+
soundsCmd
|
|
548
|
+
.command("mute")
|
|
549
|
+
.description("Mute all sounds")
|
|
550
|
+
.action(soundsMuteCommand);
|
|
551
|
+
soundsCmd
|
|
552
|
+
.command("unmute")
|
|
553
|
+
.description("Unmute sounds")
|
|
554
|
+
.action(soundsUnmuteCommand);
|
|
555
|
+
soundsCmd
|
|
556
|
+
.command("test [category]")
|
|
557
|
+
.description("Play a test sound")
|
|
558
|
+
.action(soundsTestCommand);
|
|
559
|
+
program
|
|
560
|
+
.command("logout")
|
|
561
|
+
.description("Clear stored credentials")
|
|
562
|
+
.action(logoutCommand);
|
|
563
|
+
// ── Deprecated aliases (kept for backward compat) ──────────────────────
|
|
564
|
+
program
|
|
565
|
+
.command("balances")
|
|
566
|
+
.description("Deprecated: use `bankr wallet portfolio` instead")
|
|
567
|
+
.option("--chain <chains>", "Chain(s) to fetch (comma-separated)")
|
|
568
|
+
.option("--json", "Output raw JSON")
|
|
569
|
+
.option("--low-value", "Include low-value tokens (under $1)")
|
|
570
|
+
.action(async (opts) => {
|
|
571
|
+
await balancesCommand({
|
|
572
|
+
chain: opts.chain,
|
|
573
|
+
json: opts.json,
|
|
574
|
+
showLowValueTokens: opts.lowValue,
|
|
575
|
+
});
|
|
576
|
+
});
|
|
577
|
+
program
|
|
578
|
+
.command("prompt [text...]")
|
|
579
|
+
.description("Deprecated: use `bankr agent <prompt>` instead")
|
|
580
|
+
.option("--thread <id>")
|
|
581
|
+
.option("-c, --continue")
|
|
582
|
+
.action(async (text, opts) => {
|
|
583
|
+
const joined = text.join(" ").trim();
|
|
584
|
+
await promptCommand(joined || (await readPromptInput()), opts);
|
|
585
|
+
});
|
|
586
|
+
program
|
|
587
|
+
.command("status <jobId>")
|
|
588
|
+
.description("Deprecated: use `bankr agent status` instead")
|
|
589
|
+
.action(statusCommand);
|
|
590
|
+
program
|
|
591
|
+
.command("cancel <jobId>")
|
|
592
|
+
.description("Deprecated: use `bankr agent cancel` instead")
|
|
593
|
+
.action(cancelCommand);
|
|
594
|
+
const profileAliasCmd = program
|
|
595
|
+
.command("profile")
|
|
596
|
+
.description("Deprecated: use `bankr agent profile` instead")
|
|
597
|
+
.option("--json", "Output raw JSON")
|
|
598
|
+
.action(async (opts) => {
|
|
599
|
+
await profileViewCommand({ json: opts.json });
|
|
600
|
+
});
|
|
601
|
+
profileAliasCmd
|
|
602
|
+
.command("create")
|
|
603
|
+
.option("--name <name>", "Project name")
|
|
604
|
+
.option("--description <text>", "Project description")
|
|
605
|
+
.option("--token <address>", "Token contract address")
|
|
606
|
+
.option("--image <url>", "Profile image URL")
|
|
607
|
+
.option("--website <url>", "Project website URL")
|
|
608
|
+
.option("--json", "Output raw JSON")
|
|
609
|
+
.action(async (opts) => {
|
|
610
|
+
await profileCreateCommand({
|
|
611
|
+
name: opts.name,
|
|
612
|
+
description: opts.description,
|
|
613
|
+
token: opts.token,
|
|
614
|
+
image: opts.image,
|
|
615
|
+
website: opts.website,
|
|
616
|
+
json: opts.json,
|
|
617
|
+
});
|
|
618
|
+
});
|
|
619
|
+
profileAliasCmd
|
|
620
|
+
.command("update")
|
|
621
|
+
.option("--name <name>", "Project name")
|
|
622
|
+
.option("--description <text>", "Project description")
|
|
623
|
+
.option("--token <address>", "Token contract address")
|
|
624
|
+
.option("--image <url>", "Profile image URL")
|
|
625
|
+
.option("--website <url>", "Project website URL")
|
|
626
|
+
.option("--json", "Output raw JSON")
|
|
627
|
+
.action(async (opts) => {
|
|
628
|
+
await profileUpdateCommand({
|
|
629
|
+
name: opts.name,
|
|
630
|
+
description: opts.description,
|
|
631
|
+
token: opts.token,
|
|
632
|
+
image: opts.image,
|
|
633
|
+
website: opts.website,
|
|
634
|
+
json: opts.json,
|
|
635
|
+
});
|
|
636
|
+
});
|
|
637
|
+
profileAliasCmd.command("delete").action(profileDeleteCommand);
|
|
638
|
+
profileAliasCmd
|
|
639
|
+
.command("add-update")
|
|
640
|
+
.option("--title <title>", "Update title")
|
|
641
|
+
.option("--content <text>", "Update content")
|
|
642
|
+
.option("--json", "Output raw JSON")
|
|
643
|
+
.action(async (opts) => {
|
|
644
|
+
await profileAddUpdateCommand({
|
|
645
|
+
title: opts.title,
|
|
646
|
+
content: opts.content,
|
|
647
|
+
json: opts.json,
|
|
648
|
+
});
|
|
649
|
+
});
|
|
650
|
+
program
|
|
651
|
+
.command("sign")
|
|
652
|
+
.description("Deprecated: use `bankr wallet sign` instead")
|
|
653
|
+
.requiredOption("-t, --type <type>", "Signature type")
|
|
654
|
+
.option("-m, --message <message>", "Message to sign")
|
|
655
|
+
.option("--typed-data <json>", "EIP-712 typed data as JSON")
|
|
656
|
+
.option("--transaction <json>", "Transaction as JSON")
|
|
657
|
+
.action(async (opts) => {
|
|
658
|
+
await signCommand({
|
|
659
|
+
type: opts.type,
|
|
660
|
+
message: opts.message,
|
|
661
|
+
typedData: opts.typedData,
|
|
662
|
+
transaction: opts.transaction,
|
|
663
|
+
});
|
|
664
|
+
});
|
|
665
|
+
const submitAliasCmd = program
|
|
666
|
+
.command("submit")
|
|
667
|
+
.description("Deprecated: use `bankr wallet submit` instead");
|
|
668
|
+
submitAliasCmd
|
|
669
|
+
.command("tx")
|
|
670
|
+
.description("Submit transaction with explicit parameters")
|
|
671
|
+
.requiredOption("--to <address>", "Destination address")
|
|
672
|
+
.requiredOption("--chain-id <id>", "Chain ID")
|
|
673
|
+
.option("--value <wei>", "Value in wei")
|
|
674
|
+
.option("--data <hex>", "Calldata")
|
|
675
|
+
.option("--gas <limit>", "Gas limit")
|
|
676
|
+
.option("--gas-price <wei>", "Gas price")
|
|
677
|
+
.option("--max-fee-per-gas <wei>", "Max fee per gas")
|
|
678
|
+
.option("--max-priority-fee-per-gas <wei>", "Max priority fee")
|
|
679
|
+
.option("--nonce <n>", "Transaction nonce")
|
|
680
|
+
.option("-d, --description <text>", "Description")
|
|
681
|
+
.option("--no-wait", "Don't wait for confirmation")
|
|
682
|
+
.action(async (opts) => {
|
|
683
|
+
await submitCommand({
|
|
684
|
+
to: opts.to,
|
|
685
|
+
chainId: opts.chainId,
|
|
686
|
+
value: opts.value,
|
|
687
|
+
data: opts.data,
|
|
688
|
+
gas: opts.gas,
|
|
689
|
+
gasPrice: opts.gasPrice,
|
|
690
|
+
maxFeePerGas: opts.maxFeePerGas,
|
|
691
|
+
maxPriorityFeePerGas: opts.maxPriorityFeePerGas,
|
|
692
|
+
nonce: opts.nonce,
|
|
693
|
+
description: opts.description,
|
|
694
|
+
noWait: !opts.wait,
|
|
695
|
+
});
|
|
696
|
+
});
|
|
697
|
+
submitAliasCmd
|
|
698
|
+
.command("json <transaction>")
|
|
699
|
+
.description("Submit from JSON")
|
|
700
|
+
.option("-d, --description <text>", "Description")
|
|
701
|
+
.option("--no-wait", "Don't wait for confirmation")
|
|
702
|
+
.action(async (transaction, opts) => {
|
|
703
|
+
await submitJsonCommand(transaction, {
|
|
704
|
+
noWait: !opts.wait,
|
|
705
|
+
description: opts.description,
|
|
706
|
+
});
|
|
707
|
+
});
|
|
708
|
+
program
|
|
709
|
+
.command("update")
|
|
710
|
+
.description("Update the Bankr CLI to the latest version")
|
|
711
|
+
.option("--check", "Check for updates without installing")
|
|
712
|
+
.action(async (opts) => {
|
|
713
|
+
await updateCommand({ check: opts.check });
|
|
714
|
+
});
|
|
473
715
|
// Default: treat unrecognized arguments as a prompt
|
|
474
|
-
program
|
|
716
|
+
program
|
|
717
|
+
.arguments("[text...]")
|
|
718
|
+
.option("--thread <id>", "Continue a specific conversation thread")
|
|
719
|
+
.option("-c, --continue", "Continue the most recent thread")
|
|
720
|
+
.action(async (text, opts) => {
|
|
475
721
|
if (text.length === 0) {
|
|
476
722
|
program.help();
|
|
477
723
|
return;
|
|
478
724
|
}
|
|
479
|
-
await promptCommand(text.join(" "));
|
|
725
|
+
await promptCommand(text.join(" "), opts);
|
|
480
726
|
});
|
|
481
727
|
async function main() {
|
|
482
728
|
try {
|
|
@@ -1,42 +1,13 @@
|
|
|
1
1
|
import chalk from "chalk";
|
|
2
2
|
import { getBalances, } from "../lib/api.js";
|
|
3
3
|
import * as output from "../lib/output.js";
|
|
4
|
+
import { formatUsd, formatBalance } from "../lib/output.js";
|
|
5
|
+
import { CHAIN_LABELS, VALID_CHAINS } from "../lib/chains.js";
|
|
4
6
|
const BRAND = chalk.hex("#FF613D");
|
|
5
7
|
const DIM = chalk.dim;
|
|
6
8
|
const BOLD = chalk.bold;
|
|
7
9
|
const GREEN = chalk.greenBright;
|
|
8
10
|
const WHITE = chalk.whiteBright;
|
|
9
|
-
const CHAIN_LABELS = {
|
|
10
|
-
base: "Base",
|
|
11
|
-
polygon: "Polygon",
|
|
12
|
-
mainnet: "Ethereum",
|
|
13
|
-
unichain: "Unichain",
|
|
14
|
-
solana: "Solana",
|
|
15
|
-
};
|
|
16
|
-
const VALID_CHAINS = new Set([
|
|
17
|
-
"base",
|
|
18
|
-
"polygon",
|
|
19
|
-
"mainnet",
|
|
20
|
-
"unichain",
|
|
21
|
-
"solana",
|
|
22
|
-
]);
|
|
23
|
-
function formatUsd(value) {
|
|
24
|
-
const num = typeof value === "string" ? parseFloat(value) : value;
|
|
25
|
-
if (isNaN(num) || num === 0)
|
|
26
|
-
return DIM("$0.00");
|
|
27
|
-
return `$${num.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
|
|
28
|
-
}
|
|
29
|
-
function formatBalance(value, decimals = 6) {
|
|
30
|
-
const num = typeof value === "string" ? parseFloat(value) : value;
|
|
31
|
-
if (isNaN(num) || num === 0)
|
|
32
|
-
return "0";
|
|
33
|
-
if (num < 0.000001)
|
|
34
|
-
return "<0.000001";
|
|
35
|
-
return num.toLocaleString("en-US", {
|
|
36
|
-
minimumFractionDigits: 0,
|
|
37
|
-
maximumFractionDigits: decimals,
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
11
|
function printChainBalances(chain, data) {
|
|
41
12
|
const label = CHAIN_LABELS[chain] || chain;
|
|
42
13
|
const total = parseFloat(data.total);
|
|
@@ -78,7 +49,7 @@ export async function balancesCommand(opts) {
|
|
|
78
49
|
const spin = output.spinner("Fetching balances...");
|
|
79
50
|
let data;
|
|
80
51
|
try {
|
|
81
|
-
data = await getBalances(chains);
|
|
52
|
+
data = await getBalances(chains, opts.showLowValueTokens);
|
|
82
53
|
spin.succeed("Balances loaded");
|
|
83
54
|
}
|
|
84
55
|
catch (err) {
|
|
@@ -104,6 +75,10 @@ export async function balancesCommand(opts) {
|
|
|
104
75
|
}
|
|
105
76
|
console.log();
|
|
106
77
|
output.label("Total", GREEN(formatUsd(grandTotal)));
|
|
78
|
+
if (opts.showLowValueTokens) {
|
|
79
|
+
console.log();
|
|
80
|
+
output.info("Including low-value tokens");
|
|
81
|
+
}
|
|
107
82
|
// Print each chain
|
|
108
83
|
for (const [chain, chainData] of chainEntries) {
|
|
109
84
|
printChainBalances(chain, chainData);
|