@bankr/cli 0.1.0-beta.6 → 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/README.md +27 -1
- package/dist/cli.js +222 -4
- package/dist/commands/balances.d.ts +5 -0
- package/dist/commands/balances.js +113 -0
- package/dist/commands/fees.d.ts +18 -0
- package/dist/commands/fees.js +793 -0
- package/dist/commands/launch.d.ts +13 -0
- package/dist/commands/launch.js +174 -0
- package/dist/commands/llm.d.ts +11 -0
- package/dist/commands/llm.js +319 -3
- package/dist/commands/login.d.ts +9 -0
- package/dist/commands/login.js +464 -147
- package/dist/commands/profile.d.ts +26 -0
- package/dist/commands/profile.js +183 -0
- package/dist/commands/prompt.js +5 -0
- package/dist/commands/sign.js +3 -0
- package/dist/commands/sounds.d.ts +12 -0
- package/dist/commands/sounds.js +262 -0
- package/dist/commands/submit.js +14 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/lib/api.d.ts +213 -0
- package/dist/lib/api.js +177 -3
- package/dist/lib/cesp/engine.d.ts +13 -0
- package/dist/lib/cesp/engine.js +132 -0
- package/dist/lib/cesp/player.d.ts +6 -0
- package/dist/lib/cesp/player.js +50 -0
- package/dist/lib/cesp/types.d.ts +38 -0
- package/dist/lib/cesp/types.js +2 -0
- package/dist/lib/config.d.ts +4 -0
- package/dist/lib/config.js +1 -0
- package/dist/lib/output.d.ts +1 -0
- package/dist/lib/output.js +3 -0
- package/package.json +4 -2
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/commands/cancel.d.ts.map +0 -1
- package/dist/commands/cancel.js.map +0 -1
- package/dist/commands/capabilities.d.ts.map +0 -1
- package/dist/commands/capabilities.js.map +0 -1
- package/dist/commands/config.d.ts.map +0 -1
- package/dist/commands/config.js.map +0 -1
- package/dist/commands/llm.d.ts.map +0 -1
- package/dist/commands/llm.js.map +0 -1
- package/dist/commands/login.d.ts.map +0 -1
- package/dist/commands/login.js.map +0 -1
- package/dist/commands/logout.d.ts.map +0 -1
- package/dist/commands/logout.js.map +0 -1
- package/dist/commands/prompt.d.ts.map +0 -1
- package/dist/commands/prompt.js.map +0 -1
- package/dist/commands/sign.d.ts.map +0 -1
- package/dist/commands/sign.js.map +0 -1
- package/dist/commands/status.d.ts.map +0 -1
- package/dist/commands/status.js.map +0 -1
- package/dist/commands/submit.d.ts.map +0 -1
- package/dist/commands/submit.js.map +0 -1
- package/dist/commands/whoami.d.ts.map +0 -1
- package/dist/commands/whoami.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/api.d.ts.map +0 -1
- package/dist/lib/api.js.map +0 -1
- package/dist/lib/config.d.ts.map +0 -1
- package/dist/lib/config.js.map +0 -1
- package/dist/lib/output.d.ts.map +0 -1
- package/dist/lib/output.js.map +0 -1
package/README.md
CHANGED
|
@@ -26,9 +26,17 @@ bankr "what is the price of ETH?"
|
|
|
26
26
|
### Authentication
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
|
-
# Log in (interactive
|
|
29
|
+
# Log in (interactive menu)
|
|
30
30
|
bankr login
|
|
31
31
|
|
|
32
|
+
# Log in with email (interactive — prompts for OTP and key options)
|
|
33
|
+
bankr login email
|
|
34
|
+
|
|
35
|
+
# Log in with email (headless two-step, for scripts and agents):
|
|
36
|
+
bankr login email user@example.com # Step 1: send OTP
|
|
37
|
+
bankr login email user@example.com --code 123456 \ # Step 2: verify + complete
|
|
38
|
+
--accept-terms --key-name "My Key" --read-write --llm
|
|
39
|
+
|
|
32
40
|
# Log in directly with an API key (non-interactive)
|
|
33
41
|
bankr login --api-key bk_YOUR_KEY
|
|
34
42
|
|
|
@@ -65,6 +73,24 @@ bankr prompt -c "compare them"
|
|
|
65
73
|
bankr prompt --thread thr_ABC123 "tell me more"
|
|
66
74
|
```
|
|
67
75
|
|
|
76
|
+
### Token Launch
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
# Interactive wizard — guides you through name, image, tweet, and fee recipient
|
|
80
|
+
bankr launch
|
|
81
|
+
|
|
82
|
+
# Non-interactive with all options
|
|
83
|
+
bankr launch --name "TESTCOIN" --image "https://example.com/img.png" \
|
|
84
|
+
--tweet "https://x.com/user/status/123" --fee "@vitalik" --fee-type x -y
|
|
85
|
+
|
|
86
|
+
# Quick launch (name only, skip confirmation)
|
|
87
|
+
bankr launch --name "TESTCOIN" -y
|
|
88
|
+
|
|
89
|
+
# Fee recipient types: x, farcaster, ens, wallet
|
|
90
|
+
bankr launch --name "TESTCOIN" --fee "vitalik.eth" --fee-type ens -y
|
|
91
|
+
bankr launch --name "TESTCOIN" --fee "0x1234..." --fee-type wallet -y
|
|
92
|
+
```
|
|
93
|
+
|
|
68
94
|
### Job Management
|
|
69
95
|
|
|
70
96
|
```bash
|
package/dist/cli.js
CHANGED
|
@@ -2,18 +2,23 @@
|
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
import { input } from "@inquirer/prompts";
|
|
5
|
+
import { balancesCommand } from "./commands/balances.js";
|
|
5
6
|
import { skillsCommand } from "./commands/capabilities.js";
|
|
6
7
|
import { cancelCommand } from "./commands/cancel.js";
|
|
7
8
|
import { configGetCommand, configSetCommand } from "./commands/config.js";
|
|
8
9
|
import { setConfigPath } from "./lib/config.js";
|
|
9
|
-
import { claudeCommand, creditsCommand, modelsCommand, opencodeCommand, setupClaudeCodeCommand, setupCursorCommand, setupOpenclawCommand, setupOpenCodeCommand, } from "./commands/llm.js";
|
|
10
|
+
import { claudeCommand, creditsCommand, creditsAddCommand, creditsAutoCommand, modelsCommand, opencodeCommand, setupClaudeCodeCommand, setupCursorCommand, setupOpenclawCommand, setupOpenCodeCommand, } from "./commands/llm.js";
|
|
11
|
+
import { feesCommand, feesClaimCommand, feesClaimWalletCommand, } from "./commands/fees.js";
|
|
12
|
+
import { launchCommand } from "./commands/launch.js";
|
|
10
13
|
import { loginCommand } from "./commands/login.js";
|
|
11
14
|
import { logoutCommand } from "./commands/logout.js";
|
|
12
15
|
import { promptCommand } from "./commands/prompt.js";
|
|
13
16
|
import { signCommand } from "./commands/sign.js";
|
|
17
|
+
import { soundsDisableCommand, soundsEnableCommand, soundsInstallCommand, soundsListCommand, soundsMuteCommand, soundsSearchCommand, soundsStatusCommand, soundsTestCommand, soundsUnmuteCommand, soundsUseCommand, soundsVolumeCommand, } from "./commands/sounds.js";
|
|
14
18
|
import { statusCommand } from "./commands/status.js";
|
|
15
19
|
import { submitCommand, submitJsonCommand } from "./commands/submit.js";
|
|
16
20
|
import { whoamiCommand } from "./commands/whoami.js";
|
|
21
|
+
import { profileViewCommand, profileCreateCommand, profileUpdateCommand, profileDeleteCommand, profileAddUpdateCommand, } from "./commands/profile.js";
|
|
17
22
|
import * as output from "./lib/output.js";
|
|
18
23
|
const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
|
|
19
24
|
/**
|
|
@@ -84,7 +89,7 @@ program
|
|
|
84
89
|
setConfigPath(configPath);
|
|
85
90
|
}
|
|
86
91
|
});
|
|
87
|
-
program
|
|
92
|
+
const loginCmd = program
|
|
88
93
|
.command("login")
|
|
89
94
|
.description("Authenticate with the Bankr API")
|
|
90
95
|
.option("--api-url <url>", "Custom Bankr API URL (default: https://api.bankr.bot)")
|
|
@@ -99,6 +104,45 @@ program
|
|
|
99
104
|
url: opts.url,
|
|
100
105
|
});
|
|
101
106
|
});
|
|
107
|
+
loginCmd
|
|
108
|
+
.command("email [address]")
|
|
109
|
+
.description("Sign in with email (sends verification code)")
|
|
110
|
+
.option("--code <otp>", "OTP code (step 2 of headless login)")
|
|
111
|
+
.option("--accept-terms", "Accept Terms of Service (skips prompt)")
|
|
112
|
+
.option("--key-name <name>", "API key name (default: CLI)")
|
|
113
|
+
.option("--read-write", "Enable write operations on the API key")
|
|
114
|
+
.option("--llm", "Enable LLM gateway on the API key")
|
|
115
|
+
.action(async (address, opts, cmd) => {
|
|
116
|
+
const parentOpts = cmd.parent.opts();
|
|
117
|
+
await loginCommand({
|
|
118
|
+
apiUrl: parentOpts.apiUrl,
|
|
119
|
+
llmKey: parentOpts.llmKey,
|
|
120
|
+
email: address ?? "",
|
|
121
|
+
code: opts.code,
|
|
122
|
+
acceptTerms: opts.acceptTerms,
|
|
123
|
+
keyName: opts.keyName,
|
|
124
|
+
readWrite: opts.readWrite,
|
|
125
|
+
llm: opts.llm,
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
loginCmd
|
|
129
|
+
.command("siwe")
|
|
130
|
+
.description("Sign in with Ethereum wallet (SIWE, for headless agents)")
|
|
131
|
+
.requiredOption("--private-key <key>", "Ethereum private key (0x...)")
|
|
132
|
+
.option("--partner-key <key>", "Partner API key for fee attribution")
|
|
133
|
+
.option("--key-name <name>", "API key name (default: SIWE-<date>)")
|
|
134
|
+
.option("--read-write", "Enable write operations on the API key")
|
|
135
|
+
.action(async (opts, cmd) => {
|
|
136
|
+
const parentOpts = cmd.parent.opts();
|
|
137
|
+
await loginCommand({
|
|
138
|
+
apiUrl: parentOpts.apiUrl,
|
|
139
|
+
siwe: true,
|
|
140
|
+
privateKey: opts.privateKey,
|
|
141
|
+
partnerKey: opts.partnerKey,
|
|
142
|
+
keyName: opts.keyName,
|
|
143
|
+
readWrite: opts.readWrite,
|
|
144
|
+
});
|
|
145
|
+
});
|
|
102
146
|
program
|
|
103
147
|
.command("logout")
|
|
104
148
|
.description("Clear stored credentials")
|
|
@@ -107,6 +151,14 @@ program
|
|
|
107
151
|
.command("whoami")
|
|
108
152
|
.description("Show current authentication info")
|
|
109
153
|
.action(whoamiCommand);
|
|
154
|
+
program
|
|
155
|
+
.command("balances")
|
|
156
|
+
.description("Show wallet token balances across chains")
|
|
157
|
+
.option("--chain <chains>", "Chain(s) to fetch: base, polygon, mainnet, unichain, solana (comma-separated)")
|
|
158
|
+
.option("--json", "Output raw JSON")
|
|
159
|
+
.action(async (opts) => {
|
|
160
|
+
await balancesCommand({ chain: opts.chain, json: opts.json });
|
|
161
|
+
});
|
|
110
162
|
program
|
|
111
163
|
.command("prompt [text...]")
|
|
112
164
|
.description("Send a prompt to the Bankr AI agent")
|
|
@@ -139,6 +191,157 @@ program
|
|
|
139
191
|
.command("skills")
|
|
140
192
|
.description("Show all Bankr AI agent skills with examples")
|
|
141
193
|
.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
|
+
program
|
|
239
|
+
.command("launch")
|
|
240
|
+
.description("Launch a token on Base (interactive wizard)")
|
|
241
|
+
.option("--name <name>", "Token name")
|
|
242
|
+
.option("--symbol <symbol>", "Token symbol (default: auto-generated from name)")
|
|
243
|
+
.option("--image <url>", "Token image URL")
|
|
244
|
+
.option("--tweet <url>", "Associated tweet URL")
|
|
245
|
+
.option("--website <url>", "Project website URL")
|
|
246
|
+
.option("--fee <recipient>", "Fee recipient (username, ENS, or address)")
|
|
247
|
+
.option("--fee-type <type>", "Fee recipient type: x, farcaster, ens, wallet (default: x)")
|
|
248
|
+
.option("-y, --yes", "Skip confirmation prompt")
|
|
249
|
+
.option("--simulate", "Simulate the deploy without broadcasting a transaction")
|
|
250
|
+
.action(async (opts) => {
|
|
251
|
+
await launchCommand({
|
|
252
|
+
name: opts.name,
|
|
253
|
+
symbol: opts.symbol,
|
|
254
|
+
image: opts.image,
|
|
255
|
+
tweet: opts.tweet,
|
|
256
|
+
website: opts.website,
|
|
257
|
+
fee: opts.fee,
|
|
258
|
+
feeType: opts.feeType,
|
|
259
|
+
yes: opts.yes,
|
|
260
|
+
simulate: opts.simulate,
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
const feesCmd = program
|
|
264
|
+
.command("fees [address]")
|
|
265
|
+
.description("View and claim creator token fee earnings")
|
|
266
|
+
.option("--days <n>", "Lookback period for daily chart (1-90, default: 30)")
|
|
267
|
+
.option("--token <address>", "Look up fees by token contract address")
|
|
268
|
+
.option("--json", "Output raw JSON")
|
|
269
|
+
.action(feesCommand);
|
|
270
|
+
feesCmd
|
|
271
|
+
.command("claim <tokenAddress>")
|
|
272
|
+
.description("Claim earned fees for a token")
|
|
273
|
+
.option("-y, --yes", "Skip confirmation prompt")
|
|
274
|
+
.action(feesClaimCommand);
|
|
275
|
+
feesCmd
|
|
276
|
+
.command("claim-wallet [address]")
|
|
277
|
+
.description("Claim earned fees using your own private key (no Bankr account needed). Reads .env from current directory automatically.")
|
|
278
|
+
.option("--private-key <key>", "Private key (0x...). Also reads BANKR_PRIVATE_KEY from .env or environment. If neither set, prompted interactively. Address is derived from the key when not provided.")
|
|
279
|
+
.option("--rpc <url>", "Custom RPC URL (default: https://mainnet.base.org)")
|
|
280
|
+
.option("--all", "Claim all tokens without selection prompt")
|
|
281
|
+
.option("-y, --yes", "Skip confirmation prompt")
|
|
282
|
+
.action(feesClaimWalletCommand);
|
|
283
|
+
const profileCmd = program
|
|
284
|
+
.command("profile")
|
|
285
|
+
.description("Manage your agent profile page")
|
|
286
|
+
.option("--json", "Output raw JSON")
|
|
287
|
+
.action(async (opts) => {
|
|
288
|
+
await profileViewCommand({ json: opts.json });
|
|
289
|
+
});
|
|
290
|
+
profileCmd
|
|
291
|
+
.command("create")
|
|
292
|
+
.description("Create a new agent profile")
|
|
293
|
+
.option("--name <name>", "Project name")
|
|
294
|
+
.option("--description <text>", "Project description")
|
|
295
|
+
.option("--token <address>", "Token contract address")
|
|
296
|
+
.option("--image <url>", "Profile image URL")
|
|
297
|
+
.option("--website <url>", "Project website URL")
|
|
298
|
+
.option("--json", "Output raw JSON")
|
|
299
|
+
.action(async (opts) => {
|
|
300
|
+
await profileCreateCommand({
|
|
301
|
+
name: opts.name,
|
|
302
|
+
description: opts.description,
|
|
303
|
+
token: opts.token,
|
|
304
|
+
image: opts.image,
|
|
305
|
+
website: opts.website,
|
|
306
|
+
json: opts.json,
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
profileCmd
|
|
310
|
+
.command("update")
|
|
311
|
+
.description("Update your agent profile")
|
|
312
|
+
.option("--name <name>", "Project name")
|
|
313
|
+
.option("--description <text>", "Project description")
|
|
314
|
+
.option("--token <address>", "Token contract address")
|
|
315
|
+
.option("--image <url>", "Profile image URL")
|
|
316
|
+
.option("--website <url>", "Project website URL")
|
|
317
|
+
.option("--json", "Output raw JSON")
|
|
318
|
+
.action(async (opts) => {
|
|
319
|
+
await profileUpdateCommand({
|
|
320
|
+
name: opts.name,
|
|
321
|
+
description: opts.description,
|
|
322
|
+
token: opts.token,
|
|
323
|
+
image: opts.image,
|
|
324
|
+
website: opts.website,
|
|
325
|
+
json: opts.json,
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
profileCmd
|
|
329
|
+
.command("delete")
|
|
330
|
+
.description("Delete your agent profile")
|
|
331
|
+
.action(profileDeleteCommand);
|
|
332
|
+
profileCmd
|
|
333
|
+
.command("add-update")
|
|
334
|
+
.description("Add a project update to your profile")
|
|
335
|
+
.option("--title <title>", "Update title")
|
|
336
|
+
.option("--content <text>", "Update content")
|
|
337
|
+
.option("--json", "Output raw JSON")
|
|
338
|
+
.action(async (opts) => {
|
|
339
|
+
await profileAddUpdateCommand({
|
|
340
|
+
title: opts.title,
|
|
341
|
+
content: opts.content,
|
|
342
|
+
json: opts.json,
|
|
343
|
+
});
|
|
344
|
+
});
|
|
142
345
|
program
|
|
143
346
|
.command("sign")
|
|
144
347
|
.description("Sign messages, typed data, or transactions")
|
|
@@ -207,10 +410,25 @@ llmCmd
|
|
|
207
410
|
.command("models")
|
|
208
411
|
.description("List available models")
|
|
209
412
|
.action(modelsCommand);
|
|
210
|
-
llmCmd
|
|
413
|
+
const llmCreditsCmd = llmCmd
|
|
211
414
|
.command("credits")
|
|
212
|
-
.description("
|
|
415
|
+
.description("LLM credit management")
|
|
213
416
|
.action(creditsCommand);
|
|
417
|
+
llmCreditsCmd
|
|
418
|
+
.command("add <amount>")
|
|
419
|
+
.description("Add LLM credits from your wallet")
|
|
420
|
+
.option("--token <address>", "Source token address (default: USDC)")
|
|
421
|
+
.option("-y, --yes", "Skip confirmation prompt")
|
|
422
|
+
.action(creditsAddCommand);
|
|
423
|
+
llmCreditsCmd
|
|
424
|
+
.command("auto")
|
|
425
|
+
.description("View or configure auto top-up")
|
|
426
|
+
.option("--enable", "Enable auto top-up")
|
|
427
|
+
.option("--disable", "Disable auto top-up")
|
|
428
|
+
.option("--amount <usd>", "Top-up amount in USD")
|
|
429
|
+
.option("--threshold <usd>", "Trigger when balance drops below this USD amount")
|
|
430
|
+
.option("--tokens <symbols>", "Comma-separated token symbols (e.g. USDC,DAI)")
|
|
431
|
+
.action(creditsAutoCommand);
|
|
214
432
|
const llmSetupCmd = llmCmd
|
|
215
433
|
.command("setup")
|
|
216
434
|
.description("Generate agent config (openclaw, claude, opencode, cursor)");
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
2
|
+
import { getBalances, } from "../lib/api.js";
|
|
3
|
+
import * as output from "../lib/output.js";
|
|
4
|
+
const BRAND = chalk.hex("#FF613D");
|
|
5
|
+
const DIM = chalk.dim;
|
|
6
|
+
const BOLD = chalk.bold;
|
|
7
|
+
const GREEN = chalk.greenBright;
|
|
8
|
+
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
|
+
function printChainBalances(chain, data) {
|
|
41
|
+
const label = CHAIN_LABELS[chain] || chain;
|
|
42
|
+
const total = parseFloat(data.total);
|
|
43
|
+
const totalStr = total > 0 ? GREEN(formatUsd(total)) : DIM(formatUsd(total));
|
|
44
|
+
console.log();
|
|
45
|
+
console.log();
|
|
46
|
+
console.log(` ${BRAND.bold(label)} ${totalStr}`);
|
|
47
|
+
console.log(` ${DIM("─".repeat(58))}`);
|
|
48
|
+
// Native balance
|
|
49
|
+
const nativeUsd = parseFloat(data.nativeUsd);
|
|
50
|
+
if (nativeUsd > 0 || parseFloat(data.nativeBalance) > 0) {
|
|
51
|
+
const nativeSymbol = chain === "solana" ? "SOL" : chain === "polygon" ? "POL" : "ETH";
|
|
52
|
+
console.log(` ${BOLD(WHITE(nativeSymbol.padEnd(12)))} ${formatBalance(data.nativeBalance).padStart(18)} ${DIM(formatUsd(nativeUsd))}`);
|
|
53
|
+
}
|
|
54
|
+
// Token balances sorted by USD value descending
|
|
55
|
+
const sorted = [...data.tokenBalances].sort((a, b) => b.token.balanceUSD - a.token.balanceUSD);
|
|
56
|
+
for (const tb of sorted) {
|
|
57
|
+
const symbol = tb.token.baseToken.symbol || "???";
|
|
58
|
+
const bal = formatBalance(tb.token.balance);
|
|
59
|
+
const usd = formatUsd(tb.token.balanceUSD);
|
|
60
|
+
console.log(` ${WHITE(symbol.padEnd(12))} ${bal.padStart(18)} ${DIM(usd)}`);
|
|
61
|
+
}
|
|
62
|
+
if (sorted.length === 0 && (nativeUsd === 0 || isNaN(nativeUsd))) {
|
|
63
|
+
console.log(DIM(" No token balances"));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export async function balancesCommand(opts) {
|
|
67
|
+
// Validate chain option
|
|
68
|
+
const chains = opts.chain
|
|
69
|
+
? opts.chain.split(",").map((c) => c.trim().toLowerCase())
|
|
70
|
+
: undefined;
|
|
71
|
+
if (chains) {
|
|
72
|
+
const invalid = chains.filter((c) => !VALID_CHAINS.has(c));
|
|
73
|
+
if (invalid.length > 0) {
|
|
74
|
+
output.error(`Invalid chain${invalid.length > 1 ? "s" : ""}: ${invalid.join(", ")}. Valid chains: ${[...VALID_CHAINS].join(", ")}`);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const spin = output.spinner("Fetching balances...");
|
|
79
|
+
let data;
|
|
80
|
+
try {
|
|
81
|
+
data = await getBalances(chains);
|
|
82
|
+
spin.succeed("Balances loaded");
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
spin.fail(`Failed to fetch balances: ${err.message}`);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
// JSON output mode
|
|
89
|
+
if (opts.json) {
|
|
90
|
+
console.log(JSON.stringify(data, null, 2));
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
// Calculate grand total
|
|
94
|
+
let grandTotal = 0;
|
|
95
|
+
const chainEntries = Object.entries(data.balances);
|
|
96
|
+
for (const [, chainData] of chainEntries) {
|
|
97
|
+
grandTotal += parseFloat(chainData.total) || 0;
|
|
98
|
+
}
|
|
99
|
+
console.log();
|
|
100
|
+
output.label("Wallet", "");
|
|
101
|
+
console.log(` ${"EVM".padEnd(8)} ${data.evmAddress}`);
|
|
102
|
+
if (data.solAddress) {
|
|
103
|
+
console.log(` ${"SOLANA".padEnd(8)} ${data.solAddress}`);
|
|
104
|
+
}
|
|
105
|
+
console.log();
|
|
106
|
+
output.label("Total", GREEN(formatUsd(grandTotal)));
|
|
107
|
+
// Print each chain
|
|
108
|
+
for (const [chain, chainData] of chainEntries) {
|
|
109
|
+
printChainBalances(chain, chainData);
|
|
110
|
+
}
|
|
111
|
+
console.log();
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=balances.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface FeesOptions {
|
|
2
|
+
days?: string;
|
|
3
|
+
json?: boolean;
|
|
4
|
+
token?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function feesCommand(address: string | undefined, opts: FeesOptions): Promise<void>;
|
|
7
|
+
export interface FeesClaimOptions {
|
|
8
|
+
yes?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export declare function feesClaimCommand(tokenAddress: string, opts: FeesClaimOptions): Promise<void>;
|
|
11
|
+
export interface FeesClaimWalletOptions {
|
|
12
|
+
privateKey?: string;
|
|
13
|
+
rpc?: string;
|
|
14
|
+
yes?: boolean;
|
|
15
|
+
all?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare function feesClaimWalletCommand(address: string | undefined, opts: FeesClaimWalletOptions): Promise<void>;
|
|
18
|
+
//# sourceMappingURL=fees.d.ts.map
|