@kibibot/cli 1.0.15 → 1.0.17

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @kibibot/cli
2
2
 
3
- The official KibiBot command-line interface. Deploy tokens on-chain, check balances, manage Kibi Credits, and control your AI agent from the terminal.
3
+ The official KibiBot command-line interface. Deploy tokens on-chain, check balances, check fee earnings, manage Kibi Credits, and control your AI agent from the terminal.
4
4
 
5
5
  ## Installation
6
6
 
@@ -55,13 +55,14 @@ kibi logout # clear stored credentials
55
55
  ### Token Creation
56
56
 
57
57
  ```bash
58
- # Interactive (prompts for name, symbol, chain)
58
+ # Interactive (prompts for name, symbol, chain, source, image)
59
59
  kibi token create
60
60
 
61
61
  # Headless
62
62
  kibi token create --name "MyToken" --symbol MTK --chain base
63
63
  kibi token create --name "Moon" --symbol MOON --chain solana --description "To the moon"
64
64
  kibi token create --name "Moon" --symbol MOON --chain base --image-url https://example.com/moon.png
65
+ kibi token create --name "Moon" --symbol MOON --chain base --source https://x.com/user/status/123
65
66
  kibi token create --name "Test" --symbol TST --chain base --no-wait # return job ID immediately
66
67
 
67
68
  # Check deployment status
@@ -85,6 +86,25 @@ kibi balances # on-chain wallet balances across all chains
85
86
  kibi quota # daily token creation quota per chain
86
87
  ```
87
88
 
89
+ ### Fee Earnings
90
+
91
+ ```bash
92
+ # Summary across all chains
93
+ kibi fees
94
+
95
+ # Per-platform breakdown for a specific chain
96
+ kibi fees --chain bsc
97
+ kibi fees --chain base
98
+ kibi fees --chain solana
99
+
100
+ # Fee earnings for a specific token
101
+ kibi fees --chain bsc --platform flap --token 0x1234...
102
+ kibi fees --chain bsc --platform fourmeme --token 0x1234...
103
+ kibi fees --chain solana --platform pumpfun --token 5Yz8K...
104
+ ```
105
+
106
+ Supported platforms: `flap` · `fourmeme` (BSC) · `basememe` · `clanker` (Base) · `pumpfun` (Solana)
107
+
88
108
  ### Kibi Credits & Kibi LLM Gateway
89
109
 
90
110
  ```bash
@@ -28,10 +28,10 @@ export function registerAbout(program) {
28
28
  }
29
29
  const lines = [
30
30
  '',
31
- ' K I B I B O T',
31
+ ' K I B I . B O T',
32
32
  '',
33
33
  ' Deploy tokens. Earn fees.',
34
- ' Power your AI agent.',
34
+ ' Self-fund your AI agent.',
35
35
  '',
36
36
  ` Version ${version}`,
37
37
  ' Website kibi.bot',
@@ -0,0 +1,7 @@
1
+ /**
2
+ * kibi fees — summary across all chains
3
+ * kibi fees --chain — per-platform breakdown for a chain
4
+ * kibi fees --token — single token fee detail
5
+ */
6
+ import { Command } from 'commander';
7
+ export declare function registerFees(program: Command): void;
@@ -0,0 +1,136 @@
1
+ import chalk from 'chalk';
2
+ import { agent, handleApiError } from '../lib/api.js';
3
+ import { fmtBalance, printTable } from '../lib/display.js';
4
+ // ─── Display Helpers ─────────────────────────────────────
5
+ function printSummary(res) {
6
+ console.log();
7
+ console.log(chalk.bold.cyan('Fee Earnings Summary'));
8
+ console.log(chalk.dim('─'.repeat(44)));
9
+ console.log();
10
+ // BSC
11
+ console.log(` ${chalk.bold('BSC (BNB Chain)')} ${chalk.dim(res.bsc.token_count + ' tokens')}`);
12
+ console.log(` ${'Total Earned'.padEnd(22)} ${fmtBalance(res.bsc.total_earned_bnb.toString(), 'BNB')}`);
13
+ console.log();
14
+ // Base
15
+ console.log(` ${chalk.bold('Base')} ${chalk.dim(res.base.token_count + ' tokens')}`);
16
+ console.log(` ${'Basememe Earned'.padEnd(22)} ${fmtBalance(res.base.basememe_total_earned_eth, 'ETH')}`);
17
+ console.log(` ${'Basememe Claimable'.padEnd(22)} ${fmtBalance(res.base.basememe_claimable_eth, 'ETH')}`);
18
+ console.log(` ${'Clanker Claimable'.padEnd(22)} ${fmtBalance(res.base.clanker_claimable_weth_eth, 'WETH')}`);
19
+ console.log();
20
+ // Solana
21
+ console.log(` ${chalk.bold('Solana')} ${chalk.dim(res.solana.token_count + ' tokens')}`);
22
+ console.log(` ${'Total Earned'.padEnd(22)} ${fmtBalance(res.solana.total_earnings_sol.toString(), 'SOL')}`);
23
+ console.log(` ${'Claimable'.padEnd(22)} ${fmtBalance(res.solana.total_claimable_sol.toString(), 'SOL')}`);
24
+ console.log();
25
+ }
26
+ function printEarnings(res) {
27
+ console.log();
28
+ console.log(chalk.bold.cyan(`Fee Earnings · ${res.chain.toUpperCase()}`));
29
+ console.log(chalk.dim('─'.repeat(44)));
30
+ console.log();
31
+ if (res.chain === 'bsc') {
32
+ const bsc = res;
33
+ printTable(['Platform', 'Earned', 'Tokens'], [
34
+ ['flap', fmtBalance(bsc.flap.total_earned_bnb.toString(), 'BNB'), bsc.flap.earning_token_count.toString()],
35
+ ['fourmeme', fmtBalance(bsc.fourmeme.total_earned_bnb.toString(), 'BNB'), bsc.fourmeme.earning_token_count.toString()],
36
+ ]);
37
+ }
38
+ else if (res.chain === 'base') {
39
+ const base = res;
40
+ // Split earned/claimable into separate columns to avoid chalk width issues
41
+ printTable(['Platform', 'Total Earned', 'Claimable', 'Tokens'], [
42
+ ['basememe', fmtBalance(base.basememe.total_earned_eth, 'ETH'), fmtBalance(base.basememe.claimable_eth, 'ETH'), base.basememe.token_count.toString()],
43
+ ['clanker', chalk.dim('—'), fmtBalance(base.clanker.claimable_weth_eth, 'WETH'), base.clanker.token_count.toString()],
44
+ ]);
45
+ }
46
+ else {
47
+ const sol = res;
48
+ printTable(['Platform', 'Earned', 'Claimable', 'Tokens'], [
49
+ ['pumpfun', fmtBalance(sol.pumpfun.total_earnings_sol.toString(), 'SOL'), fmtBalance(sol.pumpfun.total_claimable_sol.toString(), 'SOL'), sol.pumpfun.earning_token_count.toString()],
50
+ ]);
51
+ }
52
+ }
53
+ function printToken(res) {
54
+ // Unsupported platform
55
+ if ('supported' in res && res.supported === false) {
56
+ console.log();
57
+ console.log(chalk.yellow('⚠') + ' ' + res.message);
58
+ console.log();
59
+ return;
60
+ }
61
+ console.log();
62
+ console.log(chalk.bold.cyan('Token Fee Earnings'));
63
+ console.log(chalk.dim('─'.repeat(44)));
64
+ console.log();
65
+ if ('earned_bnb' in res) {
66
+ const bsc = res;
67
+ console.log(` ${'Token'.padEnd(14)} ${bsc.token_name} (${bsc.token_symbol})`);
68
+ console.log(` ${'Address'.padEnd(14)} ${chalk.dim(bsc.token_address)}`);
69
+ console.log(` ${'Platform'.padEnd(14)} ${bsc.platform} · ${bsc.chain.toUpperCase()}`);
70
+ console.log(` ${'Earned'.padEnd(14)} ${fmtBalance(bsc.earned_bnb.toString(), 'BNB')}`);
71
+ }
72
+ else {
73
+ const sol = res;
74
+ console.log(` ${'Token'.padEnd(14)} ${sol.token_name} (${sol.token_symbol})`);
75
+ console.log(` ${'Mint'.padEnd(14)} ${chalk.dim(sol.mint)}`);
76
+ console.log(` ${'Platform'.padEnd(14)} ${sol.platform} · ${sol.chain.toUpperCase()}`);
77
+ console.log(` ${'Earned'.padEnd(14)} ${fmtBalance(sol.actual_sol.toString(), 'SOL')}`);
78
+ console.log(` ${'Claimable'.padEnd(14)} ${fmtBalance(sol.distributable_sol.toString(), 'SOL')}`);
79
+ console.log(` ${'Total'.padEnd(14)} ${fmtBalance(sol.total_sol.toString(), 'SOL')}`);
80
+ console.log(` ${'Graduated'.padEnd(14)} ${sol.is_graduated ? chalk.green('Yes') : chalk.dim('No')}`);
81
+ }
82
+ console.log();
83
+ }
84
+ // ─── Command Registration ─────────────────────────────────
85
+ export function registerFees(program) {
86
+ program
87
+ .command('fees')
88
+ .description('Check fee earnings (summary, by chain, or per token)')
89
+ .option('--chain <chain>', 'Chain to query: bsc, base, or solana')
90
+ .option('--platform <platform>', 'Platform: flap, fourmeme, pumpfun, basememe, clanker')
91
+ .option('--token <address>', 'Token contract address or mint')
92
+ .action(async (opts, cmd) => {
93
+ const isJson = cmd.optsWithGlobals().json;
94
+ try {
95
+ // Per-token: requires --chain, --platform, --token
96
+ if (opts.token) {
97
+ if (!opts.chain || !opts.platform) {
98
+ console.error(chalk.red('Error:') + ' --chain and --platform are required with --token');
99
+ process.exit(1);
100
+ }
101
+ const res = await agent.feesToken(opts.chain, opts.platform, opts.token);
102
+ if (isJson) {
103
+ console.log(JSON.stringify(res, null, 2));
104
+ return;
105
+ }
106
+ printToken(res);
107
+ return;
108
+ }
109
+ // --platform without --token: warn and exit
110
+ if (opts.platform && !opts.token) {
111
+ console.error(chalk.red('Error:') + ' --platform requires --token. Use: kibi fees --chain <chain> --platform <platform> --token <address>');
112
+ process.exit(1);
113
+ }
114
+ // By chain: requires --chain only
115
+ if (opts.chain) {
116
+ const res = await agent.feesEarnings(opts.chain);
117
+ if (isJson) {
118
+ console.log(JSON.stringify(res, null, 2));
119
+ return;
120
+ }
121
+ printEarnings(res);
122
+ return;
123
+ }
124
+ // Default: summary across all chains
125
+ const res = await agent.feesSummary();
126
+ if (isJson) {
127
+ console.log(JSON.stringify(res, null, 2));
128
+ return;
129
+ }
130
+ printSummary(res);
131
+ }
132
+ catch (err) {
133
+ handleApiError(err);
134
+ }
135
+ });
136
+ }
@@ -21,7 +21,8 @@ export function registerToken(program) {
21
21
  .option('--symbol <symbol>', 'Token symbol')
22
22
  .option('--chain <chain>', 'Chain: base, bsc, or solana')
23
23
  .option('--description <desc>', 'Token description')
24
- .option('--image-url <url>', 'Image URL (HTTPS or IPFS)')
24
+ .option('--source <url>', 'Twitter/X post URL (insight source). Tweet image used as token image if --image-url not provided')
25
+ .option('--image-url <url>', 'Image URL (HTTPS or IPFS) — overrides source tweet image')
25
26
  .option('--platform <platform>', 'Platform override')
26
27
  .option('--no-wait', 'Return job ID without waiting for deployment')
27
28
  .action(async (opts, cmd) => {
@@ -42,8 +43,14 @@ export function registerToken(program) {
42
43
  symbol = await ask('Symbol: ');
43
44
  if (!chain)
44
45
  chain = await ask('Chain (base/bsc/solana): ');
46
+ if (!opts.source) {
47
+ const srcAnswer = await ask('Source tweet URL (optional, press Enter to skip): ');
48
+ if (srcAnswer)
49
+ opts.source = srcAnswer;
50
+ }
45
51
  if (!opts.imageUrl) {
46
- const imgAnswer = await ask('Token image URL (optional, press Enter to skip): ');
52
+ const imgHint = opts.source ? ' (overrides source tweet image)' : '';
53
+ const imgAnswer = await ask(`Token image URL${imgHint} (optional, press Enter to skip): `);
47
54
  if (imgAnswer)
48
55
  opts.imageUrl = imgAnswer;
49
56
  }
@@ -56,12 +63,21 @@ export function registerToken(program) {
56
63
  console.error(`Error: Chain must be one of: ${VALID_CHAINS.join(', ')}`);
57
64
  process.exit(1);
58
65
  }
66
+ // Validate source URL if provided
67
+ if (opts.source) {
68
+ const twitterPattern = /^https?:\/\/(?:(?:www\.)?twitter\.com|x\.com)\/[A-Za-z0-9_]+\/status\/\d+/;
69
+ if (!twitterPattern.test(opts.source)) {
70
+ console.error(chalk.red('Error:') + ' --source must be a valid Twitter/X post URL (e.g. https://x.com/user/status/123)');
71
+ process.exit(1);
72
+ }
73
+ }
59
74
  const spinner = ora('Creating token...').start();
60
75
  const result = await agent.tokenCreate({
61
76
  name,
62
77
  symbol: symbol.toUpperCase(),
63
78
  chain,
64
79
  description: opts.description,
80
+ source_url: opts.source,
65
81
  image_url: opts.imageUrl,
66
82
  platform: opts.platform,
67
83
  });
@@ -108,6 +124,7 @@ export function registerToken(program) {
108
124
  console.log(` Check status with: ${chalk.cyan(`kibi status ${result.job_id}`)}`);
109
125
  }
110
126
  catch (err) {
127
+ ora().fail('Token creation failed');
111
128
  handleApiError(err);
112
129
  }
113
130
  });
package/dist/index.js CHANGED
@@ -21,6 +21,7 @@ import { registerSkills } from './commands/skills.js';
21
21
  import { registerLlm } from './commands/llm.js';
22
22
  import { registerConfig } from './commands/config.js';
23
23
  import { registerAbout } from './commands/about.js';
24
+ import { registerFees } from './commands/fees.js';
24
25
  // Read version from package.json
25
26
  const __filename = fileURLToPath(import.meta.url);
26
27
  const __dirname = dirname(__filename);
@@ -81,4 +82,5 @@ registerSkills(program);
81
82
  registerLlm(program);
82
83
  registerConfig(program);
83
84
  registerAbout(program);
85
+ registerFees(program);
84
86
  program.parse();
package/dist/lib/api.d.ts CHANGED
@@ -22,6 +22,9 @@ export declare const agent: {
22
22
  disableReload: () => Promise<void>;
23
23
  quota: () => Promise<import("../types.js").QuotaResponse>;
24
24
  skills: () => Promise<import("../types.js").SkillsResponse>;
25
+ feesSummary: () => Promise<import("../types.js").FeeSummaryResponse>;
26
+ feesEarnings: (chain: string) => Promise<import("../types.js").FeeEarningsResponse>;
27
+ feesToken: (chain: string, platform: string, tokenAddress: string) => Promise<import("../types.js").FeeTokenResponse>;
25
28
  };
26
29
  export declare const llm: {
27
30
  models: () => Promise<import("../types.js").LlmModelsResponse>;
package/dist/lib/api.js CHANGED
@@ -40,11 +40,19 @@ function friendlyError(err) {
40
40
  return detail;
41
41
  return 'Rate limited. Try again later.';
42
42
  }
43
- default:
43
+ default: {
44
44
  if (err.statusCode >= 500) {
45
45
  return 'Server error. Try again later.';
46
46
  }
47
- return err.body?.detail || err.message || `HTTP ${err.statusCode}`;
47
+ const detail = err.body?.detail;
48
+ if (typeof detail === 'string')
49
+ return detail;
50
+ if (typeof detail === 'object' && detail !== null) {
51
+ const d = detail;
52
+ return d.message || d.error || JSON.stringify(detail);
53
+ }
54
+ return err.message || `HTTP ${err.statusCode}`;
55
+ }
48
56
  }
49
57
  }
50
58
  /**
@@ -148,6 +156,9 @@ export const agent = {
148
156
  }),
149
157
  quota: () => request('/agent/v1/quota'),
150
158
  skills: () => request('/agent/v1/skills', { auth: false }),
159
+ feesSummary: () => request('/agent/v1/fees/summary'),
160
+ feesEarnings: (chain) => request(`/agent/v1/fees/earnings?chain=${chain}`),
161
+ feesToken: (chain, platform, tokenAddress) => request(`/agent/v1/fees/token?chain=${chain}&platform=${platform}&token_address=${encodeURIComponent(tokenAddress)}`),
151
162
  };
152
163
  // LLM Gateway (base: /llm/v1)
153
164
  export const llm = {
package/dist/types.d.ts CHANGED
@@ -34,6 +34,7 @@ export interface TokenCreateRequest {
34
34
  symbol: string;
35
35
  chain: string;
36
36
  description?: string;
37
+ source_url?: string;
37
38
  image_url?: string;
38
39
  platform?: string;
39
40
  }
@@ -150,6 +151,89 @@ export interface OpenclawConfigResponse {
150
151
  api: string;
151
152
  models: OpenclawModelEntry[];
152
153
  }
154
+ export interface FeeSummaryBsc {
155
+ chain_id: number;
156
+ token_count: number;
157
+ total_earned_bnb: number;
158
+ }
159
+ export interface FeeSummaryBase {
160
+ chain_id: number;
161
+ token_count: number;
162
+ basememe_total_earned_eth: string;
163
+ basememe_claimable_eth: string;
164
+ clanker_claimable_weth_eth: string;
165
+ }
166
+ export interface FeeSummarySolana {
167
+ chain_id: number;
168
+ token_count: number;
169
+ total_earnings_sol: number;
170
+ total_claimable_sol: number;
171
+ }
172
+ export interface FeeSummaryResponse {
173
+ bsc: FeeSummaryBsc;
174
+ base: FeeSummaryBase;
175
+ solana: FeeSummarySolana;
176
+ }
177
+ export interface FeeEarningsBsc {
178
+ chain: string;
179
+ chain_id: number;
180
+ flap: {
181
+ total_earned_bnb: number;
182
+ earning_token_count: number;
183
+ };
184
+ fourmeme: {
185
+ total_earned_bnb: number;
186
+ earning_token_count: number;
187
+ };
188
+ }
189
+ export interface FeeEarningsBase {
190
+ chain: string;
191
+ chain_id: number;
192
+ basememe: {
193
+ total_earned_eth: string;
194
+ claimable_eth: string;
195
+ token_count: number;
196
+ };
197
+ clanker: {
198
+ claimable_weth_eth: string;
199
+ token_count: number;
200
+ };
201
+ }
202
+ export interface FeeEarningsSolana {
203
+ chain: string;
204
+ chain_id: number;
205
+ pumpfun: {
206
+ total_earnings_sol: number;
207
+ total_claimable_sol: number;
208
+ earning_token_count: number;
209
+ };
210
+ }
211
+ export type FeeEarningsResponse = FeeEarningsBsc | FeeEarningsBase | FeeEarningsSolana;
212
+ export interface FeeTokenBsc {
213
+ token_address: string;
214
+ token_name: string;
215
+ token_symbol: string;
216
+ platform: string;
217
+ chain: string;
218
+ earned_bnb: number;
219
+ }
220
+ export interface FeeTokenSolana {
221
+ mint: string;
222
+ token_name: string;
223
+ token_symbol: string;
224
+ platform: string;
225
+ chain: string;
226
+ actual_sol: number;
227
+ distributable_sol: number;
228
+ total_sol: number;
229
+ is_graduated: boolean;
230
+ }
231
+ export interface FeeTokenUnsupported {
232
+ platform: string;
233
+ supported: false;
234
+ message: string;
235
+ }
236
+ export type FeeTokenResponse = FeeTokenBsc | FeeTokenSolana | FeeTokenUnsupported;
153
237
  export interface ApiErrorResponse {
154
238
  detail?: string;
155
239
  message?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kibibot/cli",
3
- "version": "1.0.15",
3
+ "version": "1.0.17",
4
4
  "description": "KibiBot CLI — deploy tokens, check balances, and manage your AI agent from the terminal",
5
5
  "type": "module",
6
6
  "bin": {