@bfun-bot/cli 1.0.7 → 1.0.9
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 +6 -6
- package/dist/commands/balances.js +16 -16
- package/dist/commands/fees.d.ts +3 -3
- package/dist/commands/fees.js +71 -27
- package/dist/commands/llm.js +1 -2
- package/dist/commands/quota.js +10 -7
- package/dist/commands/token.js +5 -5
- package/dist/index.js +0 -2
- package/dist/lib/display.d.ts +6 -0
- package/dist/lib/display.js +59 -7
- package/dist/types.d.ts +2 -0
- package/package.json +10 -3
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ bfunbot login
|
|
|
17
17
|
# Create a token
|
|
18
18
|
bfunbot token create --name "My Token" --symbol MYT
|
|
19
19
|
|
|
20
|
-
# Check balances
|
|
20
|
+
# Check balances (with live USD values)
|
|
21
21
|
bfunbot balances
|
|
22
22
|
|
|
23
23
|
# Check fee earnings
|
|
@@ -35,15 +35,15 @@ bfunbot fees
|
|
|
35
35
|
| `bfunbot token info <address>` | Get token details |
|
|
36
36
|
| `bfunbot tokens created` | List tokens you've created |
|
|
37
37
|
| `bfunbot status <jobId>` | Check job status |
|
|
38
|
-
| `bfunbot balances` | Show wallet balances (BSC) |
|
|
39
|
-
| `bfunbot quota` | Show daily
|
|
40
|
-
| `bfunbot fees` | Check fee earnings summary |
|
|
41
|
-
| `bfunbot fees
|
|
38
|
+
| `bfunbot balances` | Show wallet balances (BSC) with live USD values |
|
|
39
|
+
| `bfunbot quota` | Show daily token creation quota |
|
|
40
|
+
| `bfunbot fees` | Check total fee earnings summary (with live USD) |
|
|
41
|
+
| `bfunbot fees breakdown` | Per-platform fee breakdown (flap + fourmeme) |
|
|
42
|
+
| `bfunbot fees --platform <p> --token <addr>` | Per-token fee detail |
|
|
42
43
|
| `bfunbot llm models` | List available LLM models |
|
|
43
44
|
| `bfunbot llm credits` | Check BFun.bot Credits balance |
|
|
44
45
|
| `bfunbot llm reload` | Reload credits from trading wallet |
|
|
45
46
|
| `bfunbot llm setup openclaw` | Configure OpenClaw integration |
|
|
46
|
-
| `bfunbot skills` | List agent capabilities |
|
|
47
47
|
| `bfunbot config get` | Show current config |
|
|
48
48
|
| `bfunbot config set` | Set a config value |
|
|
49
49
|
| `bfunbot about` | About BFunBot CLI |
|
|
@@ -1,24 +1,23 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { agent, handleApiError } from '../lib/api.js';
|
|
3
|
-
import { fmtBalance, shortAddr } from '../lib/display.js';
|
|
4
|
-
function printWallet(label, slot) {
|
|
3
|
+
import { fmtBalance, fmtBnbWithUsd, shortAddr } from '../lib/display.js';
|
|
4
|
+
function printWallet(label, slot, bnbPriceUsd) {
|
|
5
5
|
if (!slot.address) {
|
|
6
6
|
console.log(` ${chalk.dim(label + ':')} ${chalk.dim('Not configured')}`);
|
|
7
7
|
return;
|
|
8
8
|
}
|
|
9
9
|
console.log(` ${chalk.bold(label)} ${chalk.dim(shortAddr(slot.address))}`);
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
10
|
+
if (slot.bnb_error) {
|
|
11
|
+
console.log(` ${'BNB (BSC)'.padEnd(14)} ${chalk.red('error')}`);
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
console.log(` ${'BNB (BSC)'.padEnd(14)} ${fmtBnbWithUsd(slot.balance_bnb, bnbPriceUsd)}`);
|
|
15
|
+
}
|
|
16
|
+
if (slot.usdt_bsc_error) {
|
|
17
|
+
console.log(` ${'USDT (BSC)'.padEnd(14)} ${chalk.red('error')}`);
|
|
18
|
+
}
|
|
19
|
+
else if (slot.balance_usdt_bsc && parseFloat(slot.balance_usdt_bsc) > 0) {
|
|
20
|
+
console.log(` ${'USDT (BSC)'.padEnd(14)} ${fmtBalance(slot.balance_usdt_bsc, 'USDT')}`);
|
|
22
21
|
}
|
|
23
22
|
console.log();
|
|
24
23
|
}
|
|
@@ -38,8 +37,9 @@ export function registerBalances(program) {
|
|
|
38
37
|
console.log(chalk.bold.cyan('Wallet Balances'));
|
|
39
38
|
console.log(chalk.dim('─'.repeat(40)));
|
|
40
39
|
console.log();
|
|
41
|
-
|
|
42
|
-
printWallet('EVM
|
|
40
|
+
const bnbPrice = res.bnb_price_usd ?? 0;
|
|
41
|
+
printWallet('EVM Main', res.evm_main, bnbPrice);
|
|
42
|
+
printWallet('EVM Trading', res.evm_trading, bnbPrice);
|
|
43
43
|
}
|
|
44
44
|
catch (err) {
|
|
45
45
|
handleApiError(err);
|
package/dist/commands/fees.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* bfunbot fees
|
|
3
|
-
* bfunbot fees
|
|
4
|
-
* bfunbot fees --token <addr>
|
|
2
|
+
* bfunbot fees — summary (total earned)
|
|
3
|
+
* bfunbot fees breakdown — per-platform table
|
|
4
|
+
* bfunbot fees --token <addr> --platform <plat> — per-token detail
|
|
5
5
|
*/
|
|
6
6
|
import { Command } from 'commander';
|
|
7
7
|
export declare function registerFees(program: Command): void;
|
package/dist/commands/fees.js
CHANGED
|
@@ -1,28 +1,40 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { agent, handleApiError } from '../lib/api.js';
|
|
3
|
-
import { fmtBalance, printTable } from '../lib/display.js';
|
|
3
|
+
import { fmtBalance, fmtBnbWithUsd, printTable } from '../lib/display.js';
|
|
4
4
|
const VALID_PLATFORMS = ['flap', 'fourmeme'];
|
|
5
5
|
// ─── Display Helpers ─────────────────────────────────────
|
|
6
6
|
function printSummary(res) {
|
|
7
|
+
const bnbPrice = res.bnb_price_usd ?? 0;
|
|
7
8
|
console.log();
|
|
8
9
|
console.log(chalk.bold.cyan('Fee Earnings Summary'));
|
|
9
10
|
console.log(chalk.dim('─'.repeat(44)));
|
|
10
11
|
console.log();
|
|
11
|
-
console.log(` ${chalk.bold('BSC (BNB Chain)')}
|
|
12
|
-
console.log(` ${'Total Earned'.padEnd(22)} ${
|
|
12
|
+
console.log(` ${chalk.bold('BSC (BNB Chain)')}`);
|
|
13
|
+
console.log(` ${'Total Earned'.padEnd(22)} ${fmtBnbWithUsd(res.bsc.total_earned_bnb.toString(), bnbPrice)}`);
|
|
14
|
+
console.log();
|
|
15
|
+
console.log(chalk.dim(` For per-platform breakdown: bfunbot fees breakdown`));
|
|
13
16
|
console.log();
|
|
14
17
|
}
|
|
15
|
-
function
|
|
18
|
+
function printBreakdown(res, bnbPriceUsd) {
|
|
16
19
|
console.log();
|
|
17
|
-
console.log(chalk.bold.cyan(
|
|
20
|
+
console.log(chalk.bold.cyan('Fee Earnings · Platform Breakdown'));
|
|
18
21
|
console.log(chalk.dim('─'.repeat(44)));
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
printTable(['Platform', 'Earned', 'USD Value', 'Tokens'], [
|
|
23
|
+
[
|
|
24
|
+
'flap',
|
|
25
|
+
fmtBalance(res.flap.total_earned_bnb.toString(), 'BNB'),
|
|
26
|
+
bnbPriceUsd ? chalk.dim(`~$${(res.flap.total_earned_bnb * bnbPriceUsd).toFixed(2)}`) : chalk.dim('—'),
|
|
27
|
+
res.flap.earning_token_count.toString(),
|
|
28
|
+
],
|
|
29
|
+
[
|
|
30
|
+
'fourmeme',
|
|
31
|
+
fmtBalance(res.fourmeme.total_earned_bnb.toString(), 'BNB'),
|
|
32
|
+
bnbPriceUsd ? chalk.dim(`~$${(res.fourmeme.total_earned_bnb * bnbPriceUsd).toFixed(2)}`) : chalk.dim('—'),
|
|
33
|
+
res.fourmeme.earning_token_count.toString(),
|
|
34
|
+
],
|
|
23
35
|
]);
|
|
24
36
|
}
|
|
25
|
-
function printToken(res) {
|
|
37
|
+
function printToken(res, bnbPriceUsd) {
|
|
26
38
|
if ('supported' in res && res.supported === false) {
|
|
27
39
|
console.log();
|
|
28
40
|
console.log(chalk.yellow('⚠') + ' ' + res.message);
|
|
@@ -37,16 +49,16 @@ function printToken(res) {
|
|
|
37
49
|
console.log(` ${'Token'.padEnd(14)} ${bsc.token_name} (${bsc.token_symbol})`);
|
|
38
50
|
console.log(` ${'Address'.padEnd(14)} ${chalk.dim(bsc.token_address)}`);
|
|
39
51
|
console.log(` ${'Platform'.padEnd(14)} ${bsc.platform}`);
|
|
40
|
-
console.log(` ${'Earned'.padEnd(14)} ${
|
|
52
|
+
console.log(` ${'Earned'.padEnd(14)} ${fmtBnbWithUsd(bsc.earned_bnb.toString(), bnbPriceUsd)}`);
|
|
41
53
|
console.log();
|
|
42
54
|
}
|
|
43
55
|
// ─── Command Registration ─────────────────────────────────
|
|
44
56
|
export function registerFees(program) {
|
|
45
|
-
program
|
|
57
|
+
const feesCmd = program
|
|
46
58
|
.command('fees')
|
|
47
|
-
.description('Check fee earnings (summary,
|
|
48
|
-
.option('--platform <platform>', 'Platform: flap or fourmeme')
|
|
49
|
-
.option('--token <address>', 'Token contract address')
|
|
59
|
+
.description('Check fee earnings (summary, breakdown, or per-token)')
|
|
60
|
+
.option('--platform <platform>', 'Platform for per-token lookup: flap or fourmeme')
|
|
61
|
+
.option('--token <address>', 'Token contract address (requires --platform)')
|
|
50
62
|
.action(async (opts, cmd) => {
|
|
51
63
|
const isJson = cmd.optsWithGlobals().json;
|
|
52
64
|
try {
|
|
@@ -61,27 +73,35 @@ export function registerFees(program) {
|
|
|
61
73
|
console.error(chalk.red('Error:') + ` Platform must be one of: ${VALID_PLATFORMS.join(', ')}`);
|
|
62
74
|
process.exit(1);
|
|
63
75
|
}
|
|
64
|
-
const
|
|
76
|
+
const tokenRes = await agent.feesToken('bsc', platform, opts.token);
|
|
65
77
|
if (isJson) {
|
|
66
|
-
console.log(JSON.stringify(
|
|
78
|
+
console.log(JSON.stringify(tokenRes, null, 2));
|
|
67
79
|
return;
|
|
68
80
|
}
|
|
69
|
-
|
|
81
|
+
// Fetch price separately — graceful fallback if summary is unavailable
|
|
82
|
+
let bnbPrice = 0;
|
|
83
|
+
try {
|
|
84
|
+
bnbPrice = (await agent.feesSummary()).bnb_price_usd ?? 0;
|
|
85
|
+
}
|
|
86
|
+
catch { /* non-fatal */ }
|
|
87
|
+
printToken(tokenRes, bnbPrice);
|
|
70
88
|
return;
|
|
71
89
|
}
|
|
72
|
-
//
|
|
90
|
+
// --platform alone (legacy): route to breakdown with deprecation hint
|
|
73
91
|
if (opts.platform) {
|
|
74
|
-
if (!
|
|
75
|
-
console.
|
|
76
|
-
|
|
77
|
-
}
|
|
78
|
-
// Show full breakdown (both platforms) — the platform flag is for future filtering
|
|
79
|
-
const res = await agent.feesEarnings('bsc');
|
|
92
|
+
if (!isJson)
|
|
93
|
+
console.log(chalk.dim(' Tip: use `bfunbot fees breakdown` for per-platform earnings'));
|
|
94
|
+
const earningsRes = await agent.feesEarnings('bsc');
|
|
80
95
|
if (isJson) {
|
|
81
|
-
console.log(JSON.stringify(
|
|
96
|
+
console.log(JSON.stringify(earningsRes, null, 2));
|
|
82
97
|
return;
|
|
83
98
|
}
|
|
84
|
-
|
|
99
|
+
let bnbPrice = 0;
|
|
100
|
+
try {
|
|
101
|
+
bnbPrice = (await agent.feesSummary()).bnb_price_usd ?? 0;
|
|
102
|
+
}
|
|
103
|
+
catch { /* non-fatal */ }
|
|
104
|
+
printBreakdown(earningsRes, bnbPrice);
|
|
85
105
|
return;
|
|
86
106
|
}
|
|
87
107
|
// Default: summary
|
|
@@ -96,4 +116,28 @@ export function registerFees(program) {
|
|
|
96
116
|
handleApiError(err);
|
|
97
117
|
}
|
|
98
118
|
});
|
|
119
|
+
// ── fees breakdown ────────────────────────────────────
|
|
120
|
+
feesCmd
|
|
121
|
+
.command('breakdown')
|
|
122
|
+
.description('Per-platform fee earnings (flap + fourmeme)')
|
|
123
|
+
.action(async (_, cmd) => {
|
|
124
|
+
const isJson = cmd.optsWithGlobals().json;
|
|
125
|
+
try {
|
|
126
|
+
const earningsRes = await agent.feesEarnings('bsc');
|
|
127
|
+
if (isJson) {
|
|
128
|
+
console.log(JSON.stringify(earningsRes, null, 2));
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
// Price fetch is non-fatal — breakdown still works without USD values
|
|
132
|
+
let bnbPrice = 0;
|
|
133
|
+
try {
|
|
134
|
+
bnbPrice = (await agent.feesSummary()).bnb_price_usd ?? 0;
|
|
135
|
+
}
|
|
136
|
+
catch { /* non-fatal */ }
|
|
137
|
+
printBreakdown(earningsRes, bnbPrice);
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
handleApiError(err);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
99
143
|
}
|
package/dist/commands/llm.js
CHANGED
|
@@ -49,12 +49,11 @@ export function registerLlm(program) {
|
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
51
|
printCard('BFun.bot Credits', [
|
|
52
|
-
['Balance', `$${res.balance_usd}`],
|
|
52
|
+
['Balance', chalk.bold.white(`$${res.balance_usd}`)],
|
|
53
53
|
]);
|
|
54
54
|
// Show agent reload config
|
|
55
55
|
if (res.agent_reload) {
|
|
56
56
|
const r = res.agent_reload;
|
|
57
|
-
console.log();
|
|
58
57
|
if (r.enabled) {
|
|
59
58
|
console.log(` ${chalk.dim('Agent Reload:')} ${chalk.green('ON')}`);
|
|
60
59
|
console.log(` ${chalk.dim('Amount:')} $${r.amount_usd.toFixed(2)}`);
|
package/dist/commands/quota.js
CHANGED
|
@@ -13,13 +13,16 @@ export function registerQuota(program) {
|
|
|
13
13
|
console.log(JSON.stringify(res, null, 2));
|
|
14
14
|
return;
|
|
15
15
|
}
|
|
16
|
-
printTable(['Chain', '
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
printTable(['Chain', 'Used Today', 'Daily Limit', 'Remaining', 'Can Create'], res.chains.map((c) => {
|
|
17
|
+
const canCreate = c.sponsored_remaining > 0 || c.can_create_paid;
|
|
18
|
+
return [
|
|
19
|
+
chalk.bold(c.chain.charAt(0).toUpperCase() + c.chain.slice(1)),
|
|
20
|
+
`${c.free_used_today}`,
|
|
21
|
+
`${c.free_limit}`,
|
|
22
|
+
`${c.sponsored_remaining}`,
|
|
23
|
+
canCreate ? chalk.green('Yes') : chalk.dim('No'),
|
|
24
|
+
];
|
|
25
|
+
}));
|
|
23
26
|
}
|
|
24
27
|
catch (err) {
|
|
25
28
|
handleApiError(err);
|
package/dist/commands/token.js
CHANGED
|
@@ -4,8 +4,8 @@ import { agent, handleApiError } from '../lib/api.js';
|
|
|
4
4
|
import { printCard, fmtUsd, fmtDate } from '../lib/display.js';
|
|
5
5
|
const POLL_INTERVAL_MS = 2000;
|
|
6
6
|
const POLL_TIMEOUT_MS = 120_000;
|
|
7
|
-
const
|
|
8
|
-
bsc: 'https://
|
|
7
|
+
const TOKEN_VIEW_URLS = {
|
|
8
|
+
bsc: 'https://bfun.bot/tokens/',
|
|
9
9
|
};
|
|
10
10
|
export function registerToken(program) {
|
|
11
11
|
const tokenCmd = program
|
|
@@ -97,7 +97,7 @@ export function registerToken(program) {
|
|
|
97
97
|
printCard('Token Deployed', [
|
|
98
98
|
['Address', job.token_address],
|
|
99
99
|
['Chain', 'BSC'],
|
|
100
|
-
['View', `${
|
|
100
|
+
['View', `${TOKEN_VIEW_URLS.bsc}${job.token_address}`],
|
|
101
101
|
]);
|
|
102
102
|
return;
|
|
103
103
|
}
|
|
@@ -129,7 +129,7 @@ export function registerToken(program) {
|
|
|
129
129
|
console.log(JSON.stringify(res, null, 2));
|
|
130
130
|
return;
|
|
131
131
|
}
|
|
132
|
-
const
|
|
132
|
+
const viewBase = TOKEN_VIEW_URLS[res.chain] || '';
|
|
133
133
|
printCard(`${res.symbol} — ${res.name}`, [
|
|
134
134
|
['Address', res.token_address],
|
|
135
135
|
['Chain', res.chain],
|
|
@@ -140,7 +140,7 @@ export function registerToken(program) {
|
|
|
140
140
|
['24h Volume', fmtUsd(res.volume_24h_usd)],
|
|
141
141
|
['Creator Reward', fmtUsd(res.creator_reward_usd)],
|
|
142
142
|
['Created', fmtDate(res.created_at)],
|
|
143
|
-
['
|
|
143
|
+
['View', viewBase ? `${viewBase}${res.token_address}` : undefined],
|
|
144
144
|
]);
|
|
145
145
|
}
|
|
146
146
|
catch (err) {
|
package/dist/index.js
CHANGED
|
@@ -17,7 +17,6 @@ import { registerToken } from './commands/token.js';
|
|
|
17
17
|
import { registerStatus } from './commands/status.js';
|
|
18
18
|
import { registerBalances } from './commands/balances.js';
|
|
19
19
|
import { registerQuota } from './commands/quota.js';
|
|
20
|
-
import { registerSkills } from './commands/skills.js';
|
|
21
20
|
import { registerLlm } from './commands/llm.js';
|
|
22
21
|
import { registerConfig } from './commands/config.js';
|
|
23
22
|
import { registerAbout } from './commands/about.js';
|
|
@@ -78,7 +77,6 @@ registerToken(program);
|
|
|
78
77
|
registerStatus(program);
|
|
79
78
|
registerBalances(program);
|
|
80
79
|
registerQuota(program);
|
|
81
|
-
registerSkills(program);
|
|
82
80
|
registerLlm(program);
|
|
83
81
|
registerConfig(program);
|
|
84
82
|
registerAbout(program);
|
package/dist/lib/display.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
export declare function printCard(title: string, fields: [string, string | undefined][]): void;
|
|
5
5
|
/**
|
|
6
6
|
* Print a simple table with headers.
|
|
7
|
+
* Uses ANSI-stripped lengths for column width calculation so chalk colors don't break alignment.
|
|
7
8
|
*/
|
|
8
9
|
export declare function printTable(headers: string[], rows: string[][]): void;
|
|
9
10
|
/**
|
|
@@ -14,6 +15,11 @@ export declare function shortAddr(addr: string | undefined | null, chars?: numbe
|
|
|
14
15
|
* Format a balance value.
|
|
15
16
|
*/
|
|
16
17
|
export declare function fmtBalance(value: string | undefined | null, symbol: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Format a BNB value with USD equivalent in parentheses.
|
|
20
|
+
* e.g. "0.00412 BNB (~$2.47)"
|
|
21
|
+
*/
|
|
22
|
+
export declare function fmtBnbWithUsd(value: string | undefined | null, bnbPriceUsd: number): string;
|
|
17
23
|
/**
|
|
18
24
|
* Format a USD value.
|
|
19
25
|
*/
|
package/dist/lib/display.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Terminal display helpers — tables, cards, formatting.
|
|
3
3
|
*/
|
|
4
4
|
import chalk from 'chalk';
|
|
5
|
+
import stringWidth from 'string-width';
|
|
5
6
|
/**
|
|
6
7
|
* Print a key-value card.
|
|
7
8
|
*/
|
|
@@ -16,23 +17,38 @@ export function printCard(title, fields) {
|
|
|
16
17
|
}
|
|
17
18
|
console.log();
|
|
18
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Get the visible terminal width of a string.
|
|
22
|
+
* Uses string-width which correctly handles ANSI codes, CJK wide chars,
|
|
23
|
+
* ZWJ emoji sequences, variation selectors, and all Unicode edge cases.
|
|
24
|
+
*/
|
|
25
|
+
function visibleWidth(str) {
|
|
26
|
+
return stringWidth(str);
|
|
27
|
+
}
|
|
19
28
|
/**
|
|
20
29
|
* Print a simple table with headers.
|
|
30
|
+
* Uses ANSI-stripped lengths for column width calculation so chalk colors don't break alignment.
|
|
21
31
|
*/
|
|
22
32
|
export function printTable(headers, rows) {
|
|
23
|
-
// Calculate column widths
|
|
33
|
+
// Calculate column widths using visible terminal width (handles ANSI + CJK wide chars)
|
|
24
34
|
const widths = headers.map((h, i) => {
|
|
25
|
-
const maxRow = rows.reduce((max, row) => Math.max(max, (row[i] || '')
|
|
26
|
-
return Math.max(h
|
|
35
|
+
const maxRow = rows.reduce((max, row) => Math.max(max, visibleWidth(row[i] || '')), 0);
|
|
36
|
+
return Math.max(visibleWidth(h), maxRow);
|
|
27
37
|
});
|
|
28
38
|
// Header
|
|
29
|
-
const headerLine = headers.map((h, i) =>
|
|
39
|
+
const headerLine = headers.map((h, i) => {
|
|
40
|
+
const padding = widths[i] - visibleWidth(h);
|
|
41
|
+
return h + ' '.repeat(Math.max(0, padding));
|
|
42
|
+
}).join(' ');
|
|
30
43
|
console.log();
|
|
31
44
|
console.log(chalk.bold(headerLine));
|
|
32
45
|
console.log(chalk.dim(widths.map(w => '─'.repeat(w)).join(' ')));
|
|
33
|
-
// Rows
|
|
46
|
+
// Rows — pad by visible terminal width, not raw string length
|
|
34
47
|
for (const row of rows) {
|
|
35
|
-
const line = row.map((cell, i) =>
|
|
48
|
+
const line = row.map((cell, i) => {
|
|
49
|
+
const padding = widths[i] - visibleWidth(cell || '');
|
|
50
|
+
return (cell || '') + ' '.repeat(Math.max(0, padding));
|
|
51
|
+
}).join(' ');
|
|
36
52
|
console.log(line);
|
|
37
53
|
}
|
|
38
54
|
console.log();
|
|
@@ -59,9 +75,45 @@ export function fmtBalance(value, symbol) {
|
|
|
59
75
|
return chalk.dim(`0 ${symbol}`);
|
|
60
76
|
if (num === 0)
|
|
61
77
|
return chalk.dim(`0 ${symbol}`);
|
|
62
|
-
|
|
78
|
+
// Use enough decimal places to always show significant digits for very small values.
|
|
79
|
+
// toFixed(10) rounds below 5e-11 to zero, so fall back to toPrecision for anything smaller.
|
|
80
|
+
let formatted;
|
|
81
|
+
if (num >= 0.0001) {
|
|
82
|
+
formatted = num.toFixed(6).replace(/0+$/, '').replace(/\.$/, '');
|
|
83
|
+
}
|
|
84
|
+
else if (num >= 5e-11) {
|
|
85
|
+
formatted = num.toFixed(10).replace(/0+$/, '').replace(/\.$/, '');
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// Extremely small: toPrecision gives enough sig figs, then convert from sci notation
|
|
89
|
+
formatted = parseFloat(num.toPrecision(4)).toFixed(20).replace(/0+$/, '').replace(/\.$/, '');
|
|
90
|
+
}
|
|
63
91
|
return `${formatted} ${symbol}`;
|
|
64
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Format a BNB value with USD equivalent in parentheses.
|
|
95
|
+
* e.g. "0.00412 BNB (~$2.47)"
|
|
96
|
+
*/
|
|
97
|
+
export function fmtBnbWithUsd(value, bnbPriceUsd) {
|
|
98
|
+
const bnbStr = fmtBalance(value, 'BNB');
|
|
99
|
+
if (!value || value === '0' || value === '0.0' || !bnbPriceUsd)
|
|
100
|
+
return bnbStr;
|
|
101
|
+
const num = parseFloat(value);
|
|
102
|
+
if (isNaN(num) || num === 0)
|
|
103
|
+
return bnbStr;
|
|
104
|
+
const usd = num * bnbPriceUsd;
|
|
105
|
+
return `${bnbStr} ${chalk.dim('(~' + fmtUsdInline(usd) + ')')}`;
|
|
106
|
+
}
|
|
107
|
+
function fmtUsdInline(usd) {
|
|
108
|
+
if (usd >= 1)
|
|
109
|
+
return `$${usd.toFixed(2)}`;
|
|
110
|
+
if (usd === 0)
|
|
111
|
+
return '$0';
|
|
112
|
+
const str = usd.toFixed(10);
|
|
113
|
+
const match = str.match(/^0\.(0*)/);
|
|
114
|
+
const leadingZeros = match ? match[1].length : 0;
|
|
115
|
+
return `$${usd.toFixed(leadingZeros + 4)}`;
|
|
116
|
+
}
|
|
65
117
|
/**
|
|
66
118
|
* Format a USD value.
|
|
67
119
|
*/
|
package/dist/types.d.ts
CHANGED
|
@@ -85,6 +85,7 @@ export interface WalletSlot {
|
|
|
85
85
|
export interface WalletBalanceResponse {
|
|
86
86
|
evm_main: WalletSlot;
|
|
87
87
|
evm_trading: WalletSlot;
|
|
88
|
+
bnb_price_usd?: number;
|
|
88
89
|
}
|
|
89
90
|
export interface CreditBalanceResponse {
|
|
90
91
|
balance_usd: string;
|
|
@@ -144,6 +145,7 @@ export interface FeeSummaryBsc {
|
|
|
144
145
|
}
|
|
145
146
|
export interface FeeSummaryResponse {
|
|
146
147
|
bsc: FeeSummaryBsc;
|
|
148
|
+
bnb_price_usd?: number;
|
|
147
149
|
}
|
|
148
150
|
export interface FeeEarningsBsc {
|
|
149
151
|
chain: 'bsc';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bfun-bot/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "BFunBot CLI — deploy tokens, check balances, and manage your AI agent from the terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -10,12 +10,16 @@
|
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
11
11
|
"files": [
|
|
12
12
|
"dist",
|
|
13
|
+
"!dist/__tests__",
|
|
13
14
|
"bin",
|
|
14
15
|
"scripts"
|
|
15
16
|
],
|
|
16
17
|
"scripts": {
|
|
17
18
|
"build": "tsc",
|
|
18
19
|
"dev": "tsc --watch",
|
|
20
|
+
"test": "vitest run",
|
|
21
|
+
"test:watch": "vitest",
|
|
22
|
+
"test:coverage": "vitest run --coverage",
|
|
19
23
|
"prepublishOnly": "npm run build"
|
|
20
24
|
},
|
|
21
25
|
"engines": {
|
|
@@ -35,10 +39,13 @@
|
|
|
35
39
|
"dependencies": {
|
|
36
40
|
"chalk": "^5.3.0",
|
|
37
41
|
"commander": "^12.1.0",
|
|
38
|
-
"ora": "^8.1.1"
|
|
42
|
+
"ora": "^8.1.1",
|
|
43
|
+
"string-width": "^8.2.0"
|
|
39
44
|
},
|
|
40
45
|
"devDependencies": {
|
|
41
46
|
"@types/node": "^22.0.0",
|
|
42
|
-
"
|
|
47
|
+
"@vitest/coverage-v8": "^4.1.2",
|
|
48
|
+
"typescript": "^5.5.4",
|
|
49
|
+
"vitest": "^4.1.2"
|
|
43
50
|
}
|
|
44
51
|
}
|