thecrownsk-bot 1.0.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/LICENSE +21 -0
- package/README.md +268 -0
- package/dist/blockchain/chain.d.ts +49 -0
- package/dist/blockchain/chain.d.ts.map +1 -0
- package/dist/blockchain/chain.js +33 -0
- package/dist/blockchain/chain.js.map +1 -0
- package/dist/blockchain/client.d.ts +19 -0
- package/dist/blockchain/client.d.ts.map +1 -0
- package/dist/blockchain/client.js +121 -0
- package/dist/blockchain/client.js.map +1 -0
- package/dist/config/constants.d.ts +53 -0
- package/dist/config/constants.d.ts.map +1 -0
- package/dist/config/constants.js +61 -0
- package/dist/config/constants.js.map +1 -0
- package/dist/config/env.d.ts +38 -0
- package/dist/config/env.d.ts.map +1 -0
- package/dist/config/env.js +38 -0
- package/dist/config/env.js.map +1 -0
- package/dist/crown-king.d.ts +3 -0
- package/dist/crown-king.d.ts.map +1 -0
- package/dist/crown-king.js +1093 -0
- package/dist/crown-king.js.map +1 -0
- package/dist/crownking/agent-alliance.d.ts +49 -0
- package/dist/crownking/agent-alliance.d.ts.map +1 -0
- package/dist/crownking/agent-alliance.js +260 -0
- package/dist/crownking/agent-alliance.js.map +1 -0
- package/dist/crownking/agent.d.ts +77 -0
- package/dist/crownking/agent.d.ts.map +1 -0
- package/dist/crownking/agent.js +361 -0
- package/dist/crownking/agent.js.map +1 -0
- package/dist/crownking/auto-poster.d.ts +43 -0
- package/dist/crownking/auto-poster.d.ts.map +1 -0
- package/dist/crownking/auto-poster.js +179 -0
- package/dist/crownking/auto-poster.js.map +1 -0
- package/dist/crownking/contract.d.ts +62 -0
- package/dist/crownking/contract.d.ts.map +1 -0
- package/dist/crownking/contract.js +130 -0
- package/dist/crownking/contract.js.map +1 -0
- package/dist/crownking/copy-trader.d.ts +77 -0
- package/dist/crownking/copy-trader.d.ts.map +1 -0
- package/dist/crownking/copy-trader.js +265 -0
- package/dist/crownking/copy-trader.js.map +1 -0
- package/dist/crownking/index.d.ts +16 -0
- package/dist/crownking/index.d.ts.map +1 -0
- package/dist/crownking/index.js +18 -0
- package/dist/crownking/index.js.map +1 -0
- package/dist/crownking/leaderboard.d.ts +51 -0
- package/dist/crownking/leaderboard.d.ts.map +1 -0
- package/dist/crownking/leaderboard.js +213 -0
- package/dist/crownking/leaderboard.js.map +1 -0
- package/dist/crownking/live-scanner.d.ts +85 -0
- package/dist/crownking/live-scanner.d.ts.map +1 -0
- package/dist/crownking/live-scanner.js +345 -0
- package/dist/crownking/live-scanner.js.map +1 -0
- package/dist/crownking/momentum.d.ts +41 -0
- package/dist/crownking/momentum.d.ts.map +1 -0
- package/dist/crownking/momentum.js +251 -0
- package/dist/crownking/momentum.js.map +1 -0
- package/dist/crownking/personality.d.ts +77 -0
- package/dist/crownking/personality.d.ts.map +1 -0
- package/dist/crownking/personality.js +222 -0
- package/dist/crownking/personality.js.map +1 -0
- package/dist/crownking/portfolio.d.ts +62 -0
- package/dist/crownking/portfolio.d.ts.map +1 -0
- package/dist/crownking/portfolio.js +183 -0
- package/dist/crownking/portfolio.js.map +1 -0
- package/dist/crownking/sniper.d.ts +68 -0
- package/dist/crownking/sniper.d.ts.map +1 -0
- package/dist/crownking/sniper.js +264 -0
- package/dist/crownking/sniper.js.map +1 -0
- package/dist/crownking/social-graph.d.ts +72 -0
- package/dist/crownking/social-graph.d.ts.map +1 -0
- package/dist/crownking/social-graph.js +219 -0
- package/dist/crownking/social-graph.js.map +1 -0
- package/dist/crownking/token-creator.d.ts +42 -0
- package/dist/crownking/token-creator.d.ts.map +1 -0
- package/dist/crownking/token-creator.js +159 -0
- package/dist/crownking/token-creator.js.map +1 -0
- package/dist/crownking/trading-signals.d.ts +56 -0
- package/dist/crownking/trading-signals.d.ts.map +1 -0
- package/dist/crownking/trading-signals.js +253 -0
- package/dist/crownking/trading-signals.js.map +1 -0
- package/dist/crownking/types.d.ts +3 -0
- package/dist/crownking/types.d.ts.map +1 -0
- package/dist/crownking/types.js +4 -0
- package/dist/crownking/types.js.map +1 -0
- package/dist/crownking/whale-tracker.d.ts +53 -0
- package/dist/crownking/whale-tracker.d.ts.map +1 -0
- package/dist/crownking/whale-tracker.js +188 -0
- package/dist/crownking/whale-tracker.js.map +1 -0
- package/dist/crownsk/agent-alliance.d.ts +49 -0
- package/dist/crownsk/agent-alliance.d.ts.map +1 -0
- package/dist/crownsk/agent-alliance.js +260 -0
- package/dist/crownsk/agent-alliance.js.map +1 -0
- package/dist/crownsk/agent.d.ts +77 -0
- package/dist/crownsk/agent.d.ts.map +1 -0
- package/dist/crownsk/agent.js +361 -0
- package/dist/crownsk/agent.js.map +1 -0
- package/dist/crownsk/auto-poster.d.ts +43 -0
- package/dist/crownsk/auto-poster.d.ts.map +1 -0
- package/dist/crownsk/auto-poster.js +179 -0
- package/dist/crownsk/auto-poster.js.map +1 -0
- package/dist/crownsk/contract.d.ts +62 -0
- package/dist/crownsk/contract.d.ts.map +1 -0
- package/dist/crownsk/contract.js +130 -0
- package/dist/crownsk/contract.js.map +1 -0
- package/dist/crownsk/copy-trader.d.ts +77 -0
- package/dist/crownsk/copy-trader.d.ts.map +1 -0
- package/dist/crownsk/copy-trader.js +265 -0
- package/dist/crownsk/copy-trader.js.map +1 -0
- package/dist/crownsk/index.d.ts +16 -0
- package/dist/crownsk/index.d.ts.map +1 -0
- package/dist/crownsk/index.js +18 -0
- package/dist/crownsk/index.js.map +1 -0
- package/dist/crownsk/leaderboard.d.ts +51 -0
- package/dist/crownsk/leaderboard.d.ts.map +1 -0
- package/dist/crownsk/leaderboard.js +213 -0
- package/dist/crownsk/leaderboard.js.map +1 -0
- package/dist/crownsk/live-scanner.d.ts +85 -0
- package/dist/crownsk/live-scanner.d.ts.map +1 -0
- package/dist/crownsk/live-scanner.js +345 -0
- package/dist/crownsk/live-scanner.js.map +1 -0
- package/dist/crownsk/momentum.d.ts +41 -0
- package/dist/crownsk/momentum.d.ts.map +1 -0
- package/dist/crownsk/momentum.js +251 -0
- package/dist/crownsk/momentum.js.map +1 -0
- package/dist/crownsk/personality.d.ts +77 -0
- package/dist/crownsk/personality.d.ts.map +1 -0
- package/dist/crownsk/personality.js +222 -0
- package/dist/crownsk/personality.js.map +1 -0
- package/dist/crownsk/portfolio.d.ts +62 -0
- package/dist/crownsk/portfolio.d.ts.map +1 -0
- package/dist/crownsk/portfolio.js +183 -0
- package/dist/crownsk/portfolio.js.map +1 -0
- package/dist/crownsk/sniper.d.ts +68 -0
- package/dist/crownsk/sniper.d.ts.map +1 -0
- package/dist/crownsk/sniper.js +264 -0
- package/dist/crownsk/sniper.js.map +1 -0
- package/dist/crownsk/social-graph.d.ts +72 -0
- package/dist/crownsk/social-graph.d.ts.map +1 -0
- package/dist/crownsk/social-graph.js +219 -0
- package/dist/crownsk/social-graph.js.map +1 -0
- package/dist/crownsk/trading-signals.d.ts +56 -0
- package/dist/crownsk/trading-signals.d.ts.map +1 -0
- package/dist/crownsk/trading-signals.js +253 -0
- package/dist/crownsk/trading-signals.js.map +1 -0
- package/dist/crownsk/types.d.ts +3 -0
- package/dist/crownsk/types.d.ts.map +1 -0
- package/dist/crownsk/types.js +4 -0
- package/dist/crownsk/types.js.map +1 -0
- package/dist/crownsk/whale-tracker.d.ts +53 -0
- package/dist/crownsk/whale-tracker.d.ts.map +1 -0
- package/dist/crownsk/whale-tracker.js +188 -0
- package/dist/crownsk/whale-tracker.js.map +1 -0
- package/dist/crownsk.d.ts +3 -0
- package/dist/crownsk.d.ts.map +1 -0
- package/dist/crownsk.js +1102 -0
- package/dist/crownsk.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/karma/agent.d.ts +81 -0
- package/dist/karma/agent.d.ts.map +1 -0
- package/dist/karma/agent.js +366 -0
- package/dist/karma/agent.js.map +1 -0
- package/dist/karma/contract.d.ts +62 -0
- package/dist/karma/contract.d.ts.map +1 -0
- package/dist/karma/contract.js +130 -0
- package/dist/karma/contract.js.map +1 -0
- package/dist/karma/index.d.ts +6 -0
- package/dist/karma/index.d.ts.map +1 -0
- package/dist/karma/index.js +7 -0
- package/dist/karma/index.js.map +1 -0
- package/dist/karma/live-scanner.d.ts +85 -0
- package/dist/karma/live-scanner.d.ts.map +1 -0
- package/dist/karma/live-scanner.js +345 -0
- package/dist/karma/live-scanner.js.map +1 -0
- package/dist/karma/social-graph.d.ts +72 -0
- package/dist/karma/social-graph.d.ts.map +1 -0
- package/dist/karma/social-graph.js +219 -0
- package/dist/karma/social-graph.js.map +1 -0
- package/dist/karma/trading-signals.d.ts +38 -0
- package/dist/karma/trading-signals.d.ts.map +1 -0
- package/dist/karma/trading-signals.js +291 -0
- package/dist/karma/trading-signals.js.map +1 -0
- package/dist/karma/types.d.ts +3 -0
- package/dist/karma/types.d.ts.map +1 -0
- package/dist/karma/types.js +4 -0
- package/dist/karma/types.js.map +1 -0
- package/dist/karma-king.d.ts +3 -0
- package/dist/karma-king.d.ts.map +1 -0
- package/dist/karma-king.js +580 -0
- package/dist/karma-king.js.map +1 -0
- package/dist/moltbook/client.d.ts +34 -0
- package/dist/moltbook/client.d.ts.map +1 -0
- package/dist/moltbook/client.js +280 -0
- package/dist/moltbook/client.js.map +1 -0
- package/dist/moltbook/index.d.ts +3 -0
- package/dist/moltbook/index.d.ts.map +1 -0
- package/dist/moltbook/index.js +4 -0
- package/dist/moltbook/index.js.map +1 -0
- package/dist/moltbook/types.d.ts +100 -0
- package/dist/moltbook/types.d.ts.map +1 -0
- package/dist/moltbook/types.js +3 -0
- package/dist/moltbook/types.js.map +1 -0
- package/dist/nadfun/abis.d.ts +403 -0
- package/dist/nadfun/abis.d.ts.map +1 -0
- package/dist/nadfun/abis.js +267 -0
- package/dist/nadfun/abis.js.map +1 -0
- package/dist/nadfun/client.d.ts +21 -0
- package/dist/nadfun/client.d.ts.map +1 -0
- package/dist/nadfun/client.js +349 -0
- package/dist/nadfun/client.js.map +1 -0
- package/dist/nadfun/index.d.ts +5 -0
- package/dist/nadfun/index.d.ts.map +1 -0
- package/dist/nadfun/index.js +5 -0
- package/dist/nadfun/index.js.map +1 -0
- package/dist/nadfun/types.d.ts +72 -0
- package/dist/nadfun/types.d.ts.map +1 -0
- package/dist/nadfun/types.js +2 -0
- package/dist/nadfun/types.js.map +1 -0
- package/dist/nadfun/websocket.d.ts +18 -0
- package/dist/nadfun/websocket.d.ts.map +1 -0
- package/dist/nadfun/websocket.js +110 -0
- package/dist/nadfun/websocket.js.map +1 -0
- package/dist/utils/format.d.ts +9 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +39 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logger.d.ts +3 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +81 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/wallet/manager.d.ts +76 -0
- package/dist/wallet/manager.d.ts.map +1 -0
- package/dist/wallet/manager.js +300 -0
- package/dist/wallet/manager.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,1093 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// CrownKing - Autonomous Trading Agent for Monad
|
|
3
|
+
// Moltiverse Hackathon 2026
|
|
4
|
+
import * as readline from 'readline';
|
|
5
|
+
import { formatEther, parseEther } from 'viem';
|
|
6
|
+
import { config } from 'dotenv';
|
|
7
|
+
import { crownKingAgent } from './crownking/agent.js';
|
|
8
|
+
import { moltbookClient } from './moltbook/client.js';
|
|
9
|
+
import { socialGraph } from './crownking/social-graph.js';
|
|
10
|
+
import { scanMoltbookForSignals, getTokenData, } from './crownking/trading-signals.js';
|
|
11
|
+
import { analyzeToken, fetchNewTokens, fetchTrendingTokens } from './crownking/live-scanner.js';
|
|
12
|
+
import { getTokenStatus, getAmountOut, buyTokens, sellTokens } from './nadfun/client.js';
|
|
13
|
+
import { getBribeHistory } from './crownking/contract.js';
|
|
14
|
+
import { getBalance, getAccount } from './blockchain/client.js';
|
|
15
|
+
import { logger } from './utils/logger.js';
|
|
16
|
+
// New feature imports
|
|
17
|
+
import { getPortfolioSummary, formatPortfolio, recordTrade, getWinRate } from './crownking/portfolio.js';
|
|
18
|
+
import { scanWhaleActivity, getTopWhales, getWhaleAccumulatingTokens, formatWhaleActivity } from './crownking/whale-tracker.js';
|
|
19
|
+
import { scanNewTokens, getDetectedTokens, attemptSnipe, startTokenWatcher, stopTokenWatcher, updateSniperConfig, formatNewToken } from './crownking/sniper.js';
|
|
20
|
+
// Wallet management
|
|
21
|
+
import { saveWallet, loadWallet, deleteWallet, walletExists, getWalletInfo, isWalletLoaded, updateWallet, changePassword, getWalletStoragePath, } from './wallet/manager.js';
|
|
22
|
+
import { hasWallet, resetWalletClient } from './blockchain/client.js';
|
|
23
|
+
// Advanced feature imports
|
|
24
|
+
import { runAllianceRoutine, getAllianceStats, discoverAllies } from './crownking/agent-alliance.js';
|
|
25
|
+
import { addTrackedWallet, getTrackedWallets, startCopyTrading, stopCopyTrading, getCopyTradingStats, updateCopyConfig, formatTrackedWallet } from './crownking/copy-trader.js';
|
|
26
|
+
import { fetchLeaderboard, formatLeaderboard, getCompetitiveInsights } from './crownking/leaderboard.js';
|
|
27
|
+
import { analyzeTokenMomentum, formatMomentum } from './crownking/momentum.js';
|
|
28
|
+
import { getPostQueueStatus, postGreeting } from './crownking/auto-poster.js';
|
|
29
|
+
config();
|
|
30
|
+
const BANNER = `
|
|
31
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
32
|
+
ā ā
|
|
33
|
+
ā āāāāāāāāāāāāāā āāāāāāā āāā āāāāāāā āāā ā
|
|
34
|
+
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāā āāāāāāāā āāā ā
|
|
35
|
+
ā āāā āāāāāāāāāāā āāāāāā āā āāāāāāāāā āāā ā
|
|
36
|
+
ā āāā āāāāāāāāāāā āāāāāāāāāāāāāāāāāāāāāāā ā
|
|
37
|
+
ā āāāāāāāāāāā āāāāāāāāāāāāāāāāāāāāāāāāā āāāāāā ā
|
|
38
|
+
ā āāāāāāāāāā āāā āāāāāāā āāāāāāāā āāā āāāāā ā
|
|
39
|
+
ā ā
|
|
40
|
+
ā āāāāāāāāāāā āāā ā
|
|
41
|
+
ā āāāāāāāāāāā āāāā ā
|
|
42
|
+
ā āāāāāāāāāāāāāāā ā
|
|
43
|
+
ā āāāāāāāāāāāāāāā ā
|
|
44
|
+
ā āāāāāāāāāāā āāā ā
|
|
45
|
+
ā āāāāāāāāāāā āāā ā
|
|
46
|
+
ā ā
|
|
47
|
+
ā š Monad Trading Bot | nad.fun | Moltiverse Hackathon 2026 ā
|
|
48
|
+
ā ā
|
|
49
|
+
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
50
|
+
`;
|
|
51
|
+
const HELP = `
|
|
52
|
+
=== š TRADING ===
|
|
53
|
+
tokens - Top tokens by market cap
|
|
54
|
+
new - Newest tokens on nad.fun
|
|
55
|
+
analyze <token> - Deep analysis of a token
|
|
56
|
+
momentum <token> - Price & volume momentum
|
|
57
|
+
quote <token> - Get price quotes
|
|
58
|
+
buy <token> <amt>- Buy tokens with MON
|
|
59
|
+
sell <token> <amt>- Sell tokens for MON
|
|
60
|
+
|
|
61
|
+
=== šÆ SNIPER ===
|
|
62
|
+
snipe scan - Scan for new token launches
|
|
63
|
+
snipe watch - Start real-time token watcher
|
|
64
|
+
snipe stop - Stop token watcher
|
|
65
|
+
snipe buy <token> <amt> - Snipe a specific token
|
|
66
|
+
snipe auto on/off - Toggle auto-snipe
|
|
67
|
+
|
|
68
|
+
=== š WHALE TRACKER ===
|
|
69
|
+
whales - Show top whales
|
|
70
|
+
whales scan - Scan for whale activity
|
|
71
|
+
whales tokens - Tokens whales are buying
|
|
72
|
+
|
|
73
|
+
=== š COPY TRADER ===
|
|
74
|
+
copy - Copy trading status
|
|
75
|
+
copy add <addr> <name> - Add wallet to copy
|
|
76
|
+
copy start - Start copy trading
|
|
77
|
+
copy stop - Stop copy trading
|
|
78
|
+
|
|
79
|
+
=== š¼ PORTFOLIO ===
|
|
80
|
+
portfolio - Full portfolio summary
|
|
81
|
+
pnl - Profit & Loss stats
|
|
82
|
+
history - Trade history
|
|
83
|
+
|
|
84
|
+
=== š” SIGNALS ===
|
|
85
|
+
scan - Scan for trading signals
|
|
86
|
+
signals - Show current signals
|
|
87
|
+
|
|
88
|
+
=== š WALLET ===
|
|
89
|
+
wallet - Show current wallet
|
|
90
|
+
wallet set - Add/set your private key
|
|
91
|
+
wallet unlock - Unlock saved wallet
|
|
92
|
+
wallet remove - Remove saved wallet
|
|
93
|
+
wallet change - Change to new wallet
|
|
94
|
+
wallet password - Change wallet password
|
|
95
|
+
|
|
96
|
+
=== š STATUS ===
|
|
97
|
+
status - Agent status
|
|
98
|
+
balance - Wallet balance
|
|
99
|
+
graph - Market overview
|
|
100
|
+
leaderboard - Your ranking vs other agents
|
|
101
|
+
|
|
102
|
+
=== š¤ MOLTBOOK ===
|
|
103
|
+
register - Register on Moltbook
|
|
104
|
+
me - Your agent info
|
|
105
|
+
feed - Recent feed
|
|
106
|
+
post <sub> <msg> - Create a post
|
|
107
|
+
gm - Post a GM greeting
|
|
108
|
+
gn - Post a GN greeting
|
|
109
|
+
|
|
110
|
+
=== š¤ ALLIANCES ===
|
|
111
|
+
allies - Alliance stats
|
|
112
|
+
allies discover - Find potential allies
|
|
113
|
+
allies run - Run alliance routine
|
|
114
|
+
|
|
115
|
+
=== āļø CONTROL ===
|
|
116
|
+
start - Start autonomous mode
|
|
117
|
+
stop - Stop autonomous mode
|
|
118
|
+
help - This help menu
|
|
119
|
+
exit - Exit CrownKing
|
|
120
|
+
`;
|
|
121
|
+
class CrownKingCLI {
|
|
122
|
+
rl;
|
|
123
|
+
isRunning = true;
|
|
124
|
+
constructor() {
|
|
125
|
+
this.rl = readline.createInterface({
|
|
126
|
+
input: process.stdin,
|
|
127
|
+
output: process.stdout,
|
|
128
|
+
});
|
|
129
|
+
this.rl.on('close', () => {
|
|
130
|
+
if (this.isRunning) {
|
|
131
|
+
this.isRunning = false;
|
|
132
|
+
crownKingAgent.stop();
|
|
133
|
+
stopTokenWatcher();
|
|
134
|
+
console.log('\nš CrownKing signing off. Goodbye!');
|
|
135
|
+
process.exit(0);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
async start() {
|
|
140
|
+
console.log(BANNER);
|
|
141
|
+
console.log('Type "help" for available commands\n');
|
|
142
|
+
// Check wallet status
|
|
143
|
+
if (hasWallet()) {
|
|
144
|
+
try {
|
|
145
|
+
const account = getAccount();
|
|
146
|
+
console.log(`š Wallet: ${account.address}`);
|
|
147
|
+
const balance = await getBalance();
|
|
148
|
+
console.log(`š° Balance: ${formatEther(balance)} MON`);
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
console.log('š Wallet: Error loading');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else if (walletExists()) {
|
|
155
|
+
console.log('š Wallet: š Locked (use "wallet unlock" to unlock)');
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
console.log('š Wallet: ā Not configured (use "wallet set" to add your private key)');
|
|
159
|
+
}
|
|
160
|
+
if (moltbookClient.isRegistered()) {
|
|
161
|
+
console.log('\nā
Moltbook: Registered');
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
console.log('\nā ļø Moltbook: Not registered (run "register")');
|
|
165
|
+
}
|
|
166
|
+
console.log('');
|
|
167
|
+
this.prompt();
|
|
168
|
+
}
|
|
169
|
+
prompt() {
|
|
170
|
+
if (!this.isRunning)
|
|
171
|
+
return;
|
|
172
|
+
this.rl.question('š CrownKing> ', async (input) => {
|
|
173
|
+
if (!this.isRunning)
|
|
174
|
+
return;
|
|
175
|
+
const trimmed = input?.trim() || '';
|
|
176
|
+
const parts = trimmed.split(' ');
|
|
177
|
+
const command = parts[0].toLowerCase();
|
|
178
|
+
const args = parts.slice(1);
|
|
179
|
+
try {
|
|
180
|
+
await this.handleCommand(command, args);
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
console.error('ā Error:', error instanceof Error ? error.message : error);
|
|
184
|
+
}
|
|
185
|
+
if (this.isRunning) {
|
|
186
|
+
this.prompt();
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
async handleCommand(command, args) {
|
|
191
|
+
switch (command) {
|
|
192
|
+
case 'help':
|
|
193
|
+
console.log(HELP);
|
|
194
|
+
break;
|
|
195
|
+
case 'exit':
|
|
196
|
+
case 'quit':
|
|
197
|
+
this.isRunning = false;
|
|
198
|
+
crownKingAgent.stop();
|
|
199
|
+
stopTokenWatcher();
|
|
200
|
+
console.log('š CrownKing signing off. Goodbye!');
|
|
201
|
+
this.rl.close();
|
|
202
|
+
process.exit(0);
|
|
203
|
+
break;
|
|
204
|
+
// === TRADING ===
|
|
205
|
+
case 'tokens':
|
|
206
|
+
await this.showTokens();
|
|
207
|
+
break;
|
|
208
|
+
case 'new':
|
|
209
|
+
await this.showNewTokens();
|
|
210
|
+
break;
|
|
211
|
+
case 'analyze':
|
|
212
|
+
await this.analyzeTokenCommand(args);
|
|
213
|
+
break;
|
|
214
|
+
case 'momentum':
|
|
215
|
+
await this.momentumCommand(args);
|
|
216
|
+
break;
|
|
217
|
+
case 'quote':
|
|
218
|
+
await this.getQuote(args);
|
|
219
|
+
break;
|
|
220
|
+
case 'buy':
|
|
221
|
+
await this.buyCommand(args);
|
|
222
|
+
break;
|
|
223
|
+
case 'sell':
|
|
224
|
+
await this.sellCommand(args);
|
|
225
|
+
break;
|
|
226
|
+
// === SNIPER ===
|
|
227
|
+
case 'snipe':
|
|
228
|
+
await this.handleSniper(args);
|
|
229
|
+
break;
|
|
230
|
+
// === WHALE TRACKER ===
|
|
231
|
+
case 'whales':
|
|
232
|
+
await this.handleWhales(args);
|
|
233
|
+
break;
|
|
234
|
+
// === COPY TRADER ===
|
|
235
|
+
case 'copy':
|
|
236
|
+
await this.handleCopyTrader(args);
|
|
237
|
+
break;
|
|
238
|
+
// === PORTFOLIO ===
|
|
239
|
+
case 'portfolio':
|
|
240
|
+
await this.showPortfolio();
|
|
241
|
+
break;
|
|
242
|
+
case 'pnl':
|
|
243
|
+
this.showPnL();
|
|
244
|
+
break;
|
|
245
|
+
case 'history':
|
|
246
|
+
this.showTradeHistory();
|
|
247
|
+
break;
|
|
248
|
+
// === SIGNALS ===
|
|
249
|
+
case 'scan':
|
|
250
|
+
await this.scan();
|
|
251
|
+
break;
|
|
252
|
+
case 'signals':
|
|
253
|
+
await this.showSignals();
|
|
254
|
+
break;
|
|
255
|
+
// === WALLET ===
|
|
256
|
+
case 'wallet':
|
|
257
|
+
await this.handleWallet(args);
|
|
258
|
+
break;
|
|
259
|
+
// === STATUS ===
|
|
260
|
+
case 'status':
|
|
261
|
+
await this.showStatus();
|
|
262
|
+
break;
|
|
263
|
+
case 'balance':
|
|
264
|
+
await this.showBalance();
|
|
265
|
+
break;
|
|
266
|
+
case 'graph':
|
|
267
|
+
this.showGraph();
|
|
268
|
+
break;
|
|
269
|
+
case 'leaderboard':
|
|
270
|
+
await this.showLeaderboard();
|
|
271
|
+
break;
|
|
272
|
+
// === MOLTBOOK ===
|
|
273
|
+
case 'register':
|
|
274
|
+
await this.register();
|
|
275
|
+
break;
|
|
276
|
+
case 'me':
|
|
277
|
+
await this.showMe();
|
|
278
|
+
break;
|
|
279
|
+
case 'feed':
|
|
280
|
+
await this.showFeed();
|
|
281
|
+
break;
|
|
282
|
+
case 'post':
|
|
283
|
+
await this.createPost(args);
|
|
284
|
+
break;
|
|
285
|
+
case 'gm':
|
|
286
|
+
this.postGM();
|
|
287
|
+
break;
|
|
288
|
+
case 'gn':
|
|
289
|
+
this.postGN();
|
|
290
|
+
break;
|
|
291
|
+
// === ALLIANCES ===
|
|
292
|
+
case 'allies':
|
|
293
|
+
await this.handleAllies(args);
|
|
294
|
+
break;
|
|
295
|
+
case 'bribes':
|
|
296
|
+
this.showBribes();
|
|
297
|
+
break;
|
|
298
|
+
case 'top':
|
|
299
|
+
this.showTopInfluencers();
|
|
300
|
+
break;
|
|
301
|
+
case 'rising':
|
|
302
|
+
this.showRisingStars();
|
|
303
|
+
break;
|
|
304
|
+
// === CONTROL ===
|
|
305
|
+
case 'start':
|
|
306
|
+
await this.startAutonomous();
|
|
307
|
+
break;
|
|
308
|
+
case 'stop':
|
|
309
|
+
this.stopAutonomous();
|
|
310
|
+
break;
|
|
311
|
+
case '':
|
|
312
|
+
break;
|
|
313
|
+
default:
|
|
314
|
+
console.log(`ā Unknown command: ${command}. Type "help" for commands.`);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
// === SNIPER COMMANDS ===
|
|
318
|
+
async handleSniper(args) {
|
|
319
|
+
const subCmd = args[0]?.toLowerCase();
|
|
320
|
+
switch (subCmd) {
|
|
321
|
+
case 'scan':
|
|
322
|
+
console.log('\nš Scanning for new tokens...');
|
|
323
|
+
const newTokens = await scanNewTokens(100);
|
|
324
|
+
if (newTokens.length === 0) {
|
|
325
|
+
console.log('No new tokens found in recent blocks.');
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
console.log(`\nš Found ${newTokens.length} new tokens:`);
|
|
329
|
+
for (const t of newTokens.slice(0, 10)) {
|
|
330
|
+
console.log(formatNewToken(t));
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
break;
|
|
334
|
+
case 'watch':
|
|
335
|
+
console.log('\nšļø Starting real-time token watcher...');
|
|
336
|
+
await startTokenWatcher((token) => {
|
|
337
|
+
console.log(`\nš NEW TOKEN: ${token.address}`);
|
|
338
|
+
console.log(` Creator: ${token.creator}`);
|
|
339
|
+
});
|
|
340
|
+
console.log('Watching for new tokens. Use "snipe stop" to stop.');
|
|
341
|
+
break;
|
|
342
|
+
case 'stop':
|
|
343
|
+
stopTokenWatcher();
|
|
344
|
+
console.log('Token watcher stopped.');
|
|
345
|
+
break;
|
|
346
|
+
case 'buy':
|
|
347
|
+
if (args.length < 3) {
|
|
348
|
+
console.log('Usage: snipe buy <token> <amount>');
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
const token = args[1];
|
|
352
|
+
const amount = parseEther(args[2]);
|
|
353
|
+
console.log(`\nšÆ Sniping ${token}...`);
|
|
354
|
+
const result = await attemptSnipe({ address: token, creator: '0x0', blockNumber: 0n, txHash: '', timestamp: Date.now(), virtualMon: 0n, virtualToken: 0n }, amount);
|
|
355
|
+
if (result.success) {
|
|
356
|
+
console.log(`ā
Snipe successful! TX: ${result.txHash}`);
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
console.log(`ā Snipe failed: ${result.error}`);
|
|
360
|
+
}
|
|
361
|
+
break;
|
|
362
|
+
case 'auto':
|
|
363
|
+
const enabled = args[1]?.toLowerCase() === 'on';
|
|
364
|
+
updateSniperConfig({ autoSnipe: enabled });
|
|
365
|
+
console.log(`Auto-snipe: ${enabled ? 'ā
ON' : 'ā OFF'}`);
|
|
366
|
+
break;
|
|
367
|
+
default:
|
|
368
|
+
const detected = getDetectedTokens(5);
|
|
369
|
+
console.log('\n=== šÆ Sniper Status ===');
|
|
370
|
+
console.log(`Detected tokens: ${detected.length}`);
|
|
371
|
+
if (detected.length > 0) {
|
|
372
|
+
console.log('\nRecent detections:');
|
|
373
|
+
detected.forEach(t => console.log(' ' + formatNewToken(t)));
|
|
374
|
+
}
|
|
375
|
+
console.log('\nCommands: scan, watch, stop, buy <token> <amt>, auto on/off');
|
|
376
|
+
}
|
|
377
|
+
console.log('');
|
|
378
|
+
}
|
|
379
|
+
// === WHALE COMMANDS ===
|
|
380
|
+
async handleWhales(args) {
|
|
381
|
+
const subCmd = args[0]?.toLowerCase();
|
|
382
|
+
switch (subCmd) {
|
|
383
|
+
case 'scan':
|
|
384
|
+
console.log('\nš Scanning for whale activity...');
|
|
385
|
+
const activities = await scanWhaleActivity(500);
|
|
386
|
+
console.log(`Found ${activities.length} whale transactions.`);
|
|
387
|
+
if (activities.length > 0) {
|
|
388
|
+
console.log('\nRecent activity:');
|
|
389
|
+
activities.slice(0, 5).forEach(a => console.log(' ' + formatWhaleActivity(a)));
|
|
390
|
+
}
|
|
391
|
+
break;
|
|
392
|
+
case 'tokens':
|
|
393
|
+
const accumulating = getWhaleAccumulatingTokens();
|
|
394
|
+
if (accumulating.length === 0) {
|
|
395
|
+
console.log('No whale accumulation detected. Run "whales scan" first.');
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
console.log('\n=== š Whales Accumulating ===');
|
|
399
|
+
accumulating.slice(0, 10).forEach((t, i) => {
|
|
400
|
+
console.log(`${i + 1}. ${t.token.slice(0, 10)}...`);
|
|
401
|
+
console.log(` Buys: ${t.buyCount} | Volume: ${formatEther(t.totalVolume)} MON`);
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
break;
|
|
405
|
+
default:
|
|
406
|
+
const whales = getTopWhales(10);
|
|
407
|
+
if (whales.length === 0) {
|
|
408
|
+
console.log('No whales tracked yet. Run "whales scan" first.');
|
|
409
|
+
}
|
|
410
|
+
else {
|
|
411
|
+
console.log('\n=== š Top Whales ===');
|
|
412
|
+
whales.forEach((w, i) => {
|
|
413
|
+
console.log(`${i + 1}. ${w.address.slice(0, 10)}...${w.address.slice(-6)}`);
|
|
414
|
+
console.log(` Volume: ${formatEther(w.totalVolume)} MON | Trades: ${w.totalBuys + w.totalSells}`);
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
console.log('');
|
|
419
|
+
}
|
|
420
|
+
// === PORTFOLIO COMMANDS ===
|
|
421
|
+
async showPortfolio() {
|
|
422
|
+
console.log('\nš Loading portfolio...');
|
|
423
|
+
const summary = await getPortfolioSummary();
|
|
424
|
+
console.log('\n' + formatPortfolio(summary));
|
|
425
|
+
console.log('');
|
|
426
|
+
}
|
|
427
|
+
showPnL() {
|
|
428
|
+
const stats = getWinRate();
|
|
429
|
+
console.log('\n=== š P&L Stats ===');
|
|
430
|
+
console.log(`Wins: ${stats.wins}`);
|
|
431
|
+
console.log(`Losses: ${stats.losses}`);
|
|
432
|
+
console.log(`Win Rate: ${stats.winRate.toFixed(1)}%`);
|
|
433
|
+
console.log('');
|
|
434
|
+
}
|
|
435
|
+
showTradeHistory() {
|
|
436
|
+
const { getTradeHistory } = require('./crownking/portfolio.js');
|
|
437
|
+
const trades = getTradeHistory(10);
|
|
438
|
+
if (trades.length === 0) {
|
|
439
|
+
console.log('No trades recorded yet.');
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
console.log('\n=== š Trade History ===');
|
|
443
|
+
trades.forEach((t) => {
|
|
444
|
+
const emoji = t.action === 'buy' ? 'š¢' : 'š“';
|
|
445
|
+
console.log(`${emoji} ${t.action.toUpperCase()} ${formatEther(t.monAmount)} MON`);
|
|
446
|
+
console.log(` Token: ${t.token.slice(0, 10)}...`);
|
|
447
|
+
});
|
|
448
|
+
console.log('');
|
|
449
|
+
}
|
|
450
|
+
// === WALLET MANAGEMENT ===
|
|
451
|
+
async handleWallet(args) {
|
|
452
|
+
const subCmd = args[0]?.toLowerCase();
|
|
453
|
+
switch (subCmd) {
|
|
454
|
+
case 'set':
|
|
455
|
+
await this.walletSet();
|
|
456
|
+
break;
|
|
457
|
+
case 'unlock':
|
|
458
|
+
await this.walletUnlock();
|
|
459
|
+
break;
|
|
460
|
+
case 'remove':
|
|
461
|
+
await this.walletRemove();
|
|
462
|
+
break;
|
|
463
|
+
case 'change':
|
|
464
|
+
await this.walletChange();
|
|
465
|
+
break;
|
|
466
|
+
case 'password':
|
|
467
|
+
await this.walletChangePassword();
|
|
468
|
+
break;
|
|
469
|
+
default:
|
|
470
|
+
// Show current wallet info
|
|
471
|
+
this.showWalletInfo();
|
|
472
|
+
}
|
|
473
|
+
console.log('');
|
|
474
|
+
}
|
|
475
|
+
showWalletInfo() {
|
|
476
|
+
console.log('\n=== š Wallet ===');
|
|
477
|
+
const info = getWalletInfo();
|
|
478
|
+
if (info) {
|
|
479
|
+
console.log(`Address: ${info.address}`);
|
|
480
|
+
console.log(`Status: š¢ Loaded`);
|
|
481
|
+
}
|
|
482
|
+
else if (walletExists()) {
|
|
483
|
+
console.log(`Status: š Locked (use "wallet unlock" to unlock)`);
|
|
484
|
+
console.log(`Storage: ${getWalletStoragePath()}`);
|
|
485
|
+
}
|
|
486
|
+
else if (hasWallet()) {
|
|
487
|
+
try {
|
|
488
|
+
const account = getAccount();
|
|
489
|
+
console.log(`Address: ${account.address}`);
|
|
490
|
+
console.log(`Status: š¢ From .env`);
|
|
491
|
+
}
|
|
492
|
+
catch {
|
|
493
|
+
console.log(`Status: ā No wallet configured`);
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
else {
|
|
497
|
+
console.log(`Status: ā No wallet configured`);
|
|
498
|
+
console.log(`\nUse "wallet set" to add your private key.`);
|
|
499
|
+
}
|
|
500
|
+
console.log('\nCommands: set, unlock, remove, change, password');
|
|
501
|
+
}
|
|
502
|
+
async walletSet() {
|
|
503
|
+
console.log('\nš Set Wallet Private Key');
|
|
504
|
+
console.log('Your private key will be encrypted and stored locally.');
|
|
505
|
+
console.log(`Storage location: ${getWalletStoragePath()}`);
|
|
506
|
+
if (walletExists()) {
|
|
507
|
+
console.log('\nā ļø A wallet already exists. Use "wallet change" to replace it.');
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
// Get private key
|
|
511
|
+
const privateKey = await this.askSecret('Enter private key (0x...): ');
|
|
512
|
+
if (!privateKey) {
|
|
513
|
+
console.log('ā Cancelled.');
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
// Get password
|
|
517
|
+
const password = await this.askSecret('Create a password: ');
|
|
518
|
+
if (!password) {
|
|
519
|
+
console.log('ā Cancelled.');
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
const confirmPassword = await this.askSecret('Confirm password: ');
|
|
523
|
+
if (password !== confirmPassword) {
|
|
524
|
+
console.log('ā Passwords do not match.');
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
// Save wallet
|
|
528
|
+
const result = saveWallet(privateKey, password);
|
|
529
|
+
if (result.success) {
|
|
530
|
+
resetWalletClient();
|
|
531
|
+
console.log(`\nā
Wallet saved successfully!`);
|
|
532
|
+
console.log(`Address: ${result.address}`);
|
|
533
|
+
}
|
|
534
|
+
else {
|
|
535
|
+
console.log(`\nā Failed: ${result.error}`);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
async walletUnlock() {
|
|
539
|
+
console.log('\nš Unlock Wallet');
|
|
540
|
+
if (!walletExists()) {
|
|
541
|
+
console.log('ā No saved wallet found. Use "wallet set" first.');
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
if (isWalletLoaded()) {
|
|
545
|
+
const info = getWalletInfo();
|
|
546
|
+
console.log(`ā
Wallet already unlocked: ${info?.address}`);
|
|
547
|
+
return;
|
|
548
|
+
}
|
|
549
|
+
const password = await this.askSecret('Enter password: ');
|
|
550
|
+
if (!password) {
|
|
551
|
+
console.log('ā Cancelled.');
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
const result = loadWallet(password);
|
|
555
|
+
if (result.success) {
|
|
556
|
+
resetWalletClient();
|
|
557
|
+
console.log(`\nā
Wallet unlocked!`);
|
|
558
|
+
console.log(`Address: ${result.address}`);
|
|
559
|
+
}
|
|
560
|
+
else {
|
|
561
|
+
console.log(`\nā Failed: ${result.error}`);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
async walletRemove() {
|
|
565
|
+
console.log('\nšļø Remove Saved Wallet');
|
|
566
|
+
if (!walletExists()) {
|
|
567
|
+
console.log('ā No saved wallet to remove.');
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
const confirm = await this.askQuestion('Are you sure? This will delete your saved wallet. (yes/no): ');
|
|
571
|
+
if (confirm.toLowerCase() !== 'yes') {
|
|
572
|
+
console.log('ā Cancelled.');
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
const result = deleteWallet();
|
|
576
|
+
if (result.success) {
|
|
577
|
+
resetWalletClient();
|
|
578
|
+
console.log('ā
Wallet removed successfully.');
|
|
579
|
+
}
|
|
580
|
+
else {
|
|
581
|
+
console.log(`ā Failed: ${result.error}`);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
async walletChange() {
|
|
585
|
+
console.log('\nš Change Wallet');
|
|
586
|
+
if (!walletExists()) {
|
|
587
|
+
console.log('No existing wallet. Use "wallet set" instead.');
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
const confirm = await this.askQuestion('This will replace your current wallet. Continue? (yes/no): ');
|
|
591
|
+
if (confirm.toLowerCase() !== 'yes') {
|
|
592
|
+
console.log('ā Cancelled.');
|
|
593
|
+
return;
|
|
594
|
+
}
|
|
595
|
+
// Get new private key
|
|
596
|
+
const privateKey = await this.askSecret('Enter new private key (0x...): ');
|
|
597
|
+
if (!privateKey) {
|
|
598
|
+
console.log('ā Cancelled.');
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
// Get password
|
|
602
|
+
const password = await this.askSecret('Create a password for new wallet: ');
|
|
603
|
+
if (!password) {
|
|
604
|
+
console.log('ā Cancelled.');
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
const confirmPassword = await this.askSecret('Confirm password: ');
|
|
608
|
+
if (password !== confirmPassword) {
|
|
609
|
+
console.log('ā Passwords do not match.');
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
// Update wallet
|
|
613
|
+
const result = updateWallet(privateKey, password);
|
|
614
|
+
if (result.success) {
|
|
615
|
+
resetWalletClient();
|
|
616
|
+
console.log(`\nā
Wallet changed successfully!`);
|
|
617
|
+
console.log(`New Address: ${result.address}`);
|
|
618
|
+
}
|
|
619
|
+
else {
|
|
620
|
+
console.log(`\nā Failed: ${result.error}`);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
async walletChangePassword() {
|
|
624
|
+
console.log('\nš Change Wallet Password');
|
|
625
|
+
if (!walletExists()) {
|
|
626
|
+
console.log('ā No saved wallet found.');
|
|
627
|
+
return;
|
|
628
|
+
}
|
|
629
|
+
const oldPassword = await this.askSecret('Enter current password: ');
|
|
630
|
+
if (!oldPassword) {
|
|
631
|
+
console.log('ā Cancelled.');
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
const newPassword = await this.askSecret('Enter new password: ');
|
|
635
|
+
if (!newPassword) {
|
|
636
|
+
console.log('ā Cancelled.');
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
const confirmPassword = await this.askSecret('Confirm new password: ');
|
|
640
|
+
if (newPassword !== confirmPassword) {
|
|
641
|
+
console.log('ā Passwords do not match.');
|
|
642
|
+
return;
|
|
643
|
+
}
|
|
644
|
+
const result = changePassword(oldPassword, newPassword);
|
|
645
|
+
if (result.success) {
|
|
646
|
+
console.log('ā
Password changed successfully.');
|
|
647
|
+
}
|
|
648
|
+
else {
|
|
649
|
+
console.log(`ā Failed: ${result.error}`);
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
askQuestion(question) {
|
|
653
|
+
return new Promise((resolve) => {
|
|
654
|
+
this.rl.question(question, (answer) => {
|
|
655
|
+
resolve(answer || '');
|
|
656
|
+
});
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
askSecret(question) {
|
|
660
|
+
return new Promise((resolve) => {
|
|
661
|
+
// Note: In a real implementation, you'd want to hide input
|
|
662
|
+
// For now, we use standard prompt with a warning
|
|
663
|
+
process.stdout.write(question);
|
|
664
|
+
this.rl.question('', (answer) => {
|
|
665
|
+
resolve(answer || '');
|
|
666
|
+
});
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
// === EXISTING COMMANDS (updated) ===
|
|
670
|
+
async showTokens() {
|
|
671
|
+
console.log('\nš Fetching top tokens...');
|
|
672
|
+
const tokens = await fetchTrendingTokens(10);
|
|
673
|
+
console.log('\n=== š Top Tokens by Market Cap ===');
|
|
674
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
675
|
+
const t = tokens[i];
|
|
676
|
+
const status = t.graduated ? 'š¢ DEX' : 'š” Curve';
|
|
677
|
+
console.log(`${i + 1}. ${t.symbol} (${t.name.substring(0, 20)})`);
|
|
678
|
+
console.log(` ${status} | ${t.holders || 0} holders`);
|
|
679
|
+
console.log(` ${t.address}`);
|
|
680
|
+
}
|
|
681
|
+
console.log('');
|
|
682
|
+
}
|
|
683
|
+
async showNewTokens() {
|
|
684
|
+
console.log('\nš Fetching newest tokens...');
|
|
685
|
+
const tokens = await fetchNewTokens(10);
|
|
686
|
+
console.log('\n=== š Newest Tokens ===');
|
|
687
|
+
for (let i = 0; i < tokens.length; i++) {
|
|
688
|
+
const t = tokens[i];
|
|
689
|
+
const status = t.graduated ? 'š¢ DEX' : 'š” Curve';
|
|
690
|
+
console.log(`${i + 1}. ${t.symbol} (${t.name.substring(0, 20)})`);
|
|
691
|
+
console.log(` ${status} | ${t.holders || 0} holders`);
|
|
692
|
+
console.log(` ${t.address}`);
|
|
693
|
+
}
|
|
694
|
+
console.log('');
|
|
695
|
+
}
|
|
696
|
+
async analyzeTokenCommand(args) {
|
|
697
|
+
if (args.length < 1) {
|
|
698
|
+
console.log('Usage: analyze <token_address>');
|
|
699
|
+
return;
|
|
700
|
+
}
|
|
701
|
+
const tokenAddress = args[0];
|
|
702
|
+
console.log(`\nš Analyzing: ${tokenAddress}`);
|
|
703
|
+
try {
|
|
704
|
+
const status = await getTokenStatus(tokenAddress);
|
|
705
|
+
console.log('\n=== Token Status ===');
|
|
706
|
+
console.log(`Graduated: ${status.graduated ? 'ā
Yes (DEX)' : 'ā No (Bonding Curve)'}`);
|
|
707
|
+
console.log(`Progress: ${status.progressPercent.toFixed(2)}%`);
|
|
708
|
+
const analysis = await analyzeToken(tokenAddress);
|
|
709
|
+
console.log('\n=== Analysis ===');
|
|
710
|
+
console.log(`Score: ${analysis.score}/100`);
|
|
711
|
+
const recEmoji = analysis.recommendation === 'buy' ? 'š¢' : analysis.recommendation === 'sell' ? 'š“' : 'āŖ';
|
|
712
|
+
console.log(`Recommendation: ${recEmoji} ${analysis.recommendation.toUpperCase()}`);
|
|
713
|
+
console.log('Signals:');
|
|
714
|
+
for (const signal of analysis.signals) {
|
|
715
|
+
console.log(` ⢠${signal}`);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
catch (error) {
|
|
719
|
+
console.log(`ā Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
720
|
+
}
|
|
721
|
+
console.log('');
|
|
722
|
+
}
|
|
723
|
+
async getQuote(args) {
|
|
724
|
+
if (args.length < 1) {
|
|
725
|
+
console.log('Usage: quote <token_address>');
|
|
726
|
+
return;
|
|
727
|
+
}
|
|
728
|
+
const tokenAddress = args[0];
|
|
729
|
+
console.log(`\nš± Getting quotes for ${tokenAddress}...`);
|
|
730
|
+
try {
|
|
731
|
+
const amounts = ['0.1', '1', '10'];
|
|
732
|
+
console.log('\n=== Buy Quotes (MON ā Token) ===');
|
|
733
|
+
for (const amt of amounts) {
|
|
734
|
+
const quote = await getAmountOut(tokenAddress, parseEther(amt), true);
|
|
735
|
+
console.log(`${amt} MON ā ${formatEther(quote.amountOut)} tokens`);
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
catch (error) {
|
|
739
|
+
console.log(`ā Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
740
|
+
}
|
|
741
|
+
console.log('');
|
|
742
|
+
}
|
|
743
|
+
async buyCommand(args) {
|
|
744
|
+
if (args.length < 2) {
|
|
745
|
+
console.log('Usage: buy <token_address> <mon_amount>');
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
const tokenAddress = args[0];
|
|
749
|
+
const monAmount = parseEther(args[1]);
|
|
750
|
+
console.log(`\nš Buying tokens...`);
|
|
751
|
+
console.log(`Token: ${tokenAddress}`);
|
|
752
|
+
console.log(`Amount: ${args[1]} MON`);
|
|
753
|
+
try {
|
|
754
|
+
const result = await buyTokens({ token: tokenAddress, monAmount, slippagePercent: 5 });
|
|
755
|
+
if (result.success) {
|
|
756
|
+
console.log(`\nā
Buy successful!`);
|
|
757
|
+
console.log(`TX: ${result.txHash}`);
|
|
758
|
+
console.log(`Received: ${formatEther(result.amountOut || 0n)} tokens`);
|
|
759
|
+
// Record trade
|
|
760
|
+
recordTrade({
|
|
761
|
+
token: tokenAddress,
|
|
762
|
+
action: 'buy',
|
|
763
|
+
monAmount,
|
|
764
|
+
tokenAmount: result.amountOut || 0n,
|
|
765
|
+
timestamp: Date.now(),
|
|
766
|
+
txHash: result.txHash || '',
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
else {
|
|
770
|
+
console.log(`\nā Buy failed: ${result.error}`);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
catch (error) {
|
|
774
|
+
console.log(`ā Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
775
|
+
}
|
|
776
|
+
console.log('');
|
|
777
|
+
}
|
|
778
|
+
async sellCommand(args) {
|
|
779
|
+
if (args.length < 2) {
|
|
780
|
+
console.log('Usage: sell <token_address> <token_amount>');
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
const tokenAddress = args[0];
|
|
784
|
+
const tokenAmount = parseEther(args[1]);
|
|
785
|
+
console.log(`\nšø Selling tokens...`);
|
|
786
|
+
console.log(`Token: ${tokenAddress}`);
|
|
787
|
+
console.log(`Amount: ${args[1]} tokens`);
|
|
788
|
+
try {
|
|
789
|
+
const result = await sellTokens({ token: tokenAddress, tokenAmount, slippagePercent: 5 });
|
|
790
|
+
if (result.success) {
|
|
791
|
+
console.log(`\nā
Sell successful!`);
|
|
792
|
+
console.log(`TX: ${result.txHash}`);
|
|
793
|
+
console.log(`Received: ${formatEther(result.amountOut || 0n)} MON`);
|
|
794
|
+
recordTrade({
|
|
795
|
+
token: tokenAddress,
|
|
796
|
+
action: 'sell',
|
|
797
|
+
monAmount: result.amountOut || 0n,
|
|
798
|
+
tokenAmount,
|
|
799
|
+
timestamp: Date.now(),
|
|
800
|
+
txHash: result.txHash || '',
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
else {
|
|
804
|
+
console.log(`\nā Sell failed: ${result.error}`);
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
catch (error) {
|
|
808
|
+
console.log(`ā Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
809
|
+
}
|
|
810
|
+
console.log('');
|
|
811
|
+
}
|
|
812
|
+
async showStatus() {
|
|
813
|
+
const status = crownKingAgent.getStatus();
|
|
814
|
+
const balance = await getBalance();
|
|
815
|
+
const account = getAccount();
|
|
816
|
+
console.log('\n=== š CrownKing Status ===');
|
|
817
|
+
console.log(`Wallet: ${account.address}`);
|
|
818
|
+
console.log(`Balance: ${formatEther(balance)} MON`);
|
|
819
|
+
console.log(`Agent Running: ${status.running ? 'ā
' : 'ā'}`);
|
|
820
|
+
console.log(`Daily Trades: ${status.dailyTrades}`);
|
|
821
|
+
const tokenData = getTokenData();
|
|
822
|
+
if (tokenData.length > 0) {
|
|
823
|
+
console.log(`\nTokens Tracked: ${tokenData.length}`);
|
|
824
|
+
const graduated = tokenData.filter(t => t.graduated).length;
|
|
825
|
+
console.log(`On DEX: ${graduated} | On Curve: ${tokenData.length - graduated}`);
|
|
826
|
+
}
|
|
827
|
+
console.log('');
|
|
828
|
+
}
|
|
829
|
+
async showSignals() {
|
|
830
|
+
const tokenData = getTokenData();
|
|
831
|
+
if (tokenData.length === 0) {
|
|
832
|
+
console.log('No signals yet. Run "scan" first.');
|
|
833
|
+
return;
|
|
834
|
+
}
|
|
835
|
+
console.log('\n=== š” Trading Signals ===');
|
|
836
|
+
for (const data of tokenData.slice(0, 10)) {
|
|
837
|
+
const emoji = data.recommendation === 'buy' ? 'š¢' : data.recommendation === 'sell' ? 'š“' : 'āŖ';
|
|
838
|
+
const status = data.graduated ? 'DEX' : `${data.progress.toFixed(0)}%`;
|
|
839
|
+
console.log(`${emoji} ${data.symbol} (${data.name.substring(0, 15)})`);
|
|
840
|
+
console.log(` Score: ${data.score} | ${data.recommendation.toUpperCase()} | ${status} | ${data.holders} holders`);
|
|
841
|
+
console.log(` ${data.token}`);
|
|
842
|
+
}
|
|
843
|
+
console.log('');
|
|
844
|
+
}
|
|
845
|
+
showGraph() {
|
|
846
|
+
const stats = socialGraph.getStats();
|
|
847
|
+
const tokenData = getTokenData();
|
|
848
|
+
console.log('\n=== š Market Overview ===');
|
|
849
|
+
if (tokenData.length > 0) {
|
|
850
|
+
console.log(`Tokens Tracked: ${tokenData.length}`);
|
|
851
|
+
const graduated = tokenData.filter(t => t.graduated).length;
|
|
852
|
+
console.log(`On DEX: ${graduated} | On Curve: ${tokenData.length - graduated}`);
|
|
853
|
+
const totalHolders = tokenData.reduce((sum, t) => sum + t.holders, 0);
|
|
854
|
+
console.log(`Total Holders: ${totalHolders}`);
|
|
855
|
+
const avgScore = tokenData.reduce((sum, t) => sum + t.score, 0) / tokenData.length;
|
|
856
|
+
console.log(`Avg Score: ${avgScore.toFixed(1)}`);
|
|
857
|
+
}
|
|
858
|
+
if (stats.nodeCount > 0) {
|
|
859
|
+
console.log(`\nSocial Graph: ${stats.nodeCount} nodes, ${stats.edgeCount} edges`);
|
|
860
|
+
}
|
|
861
|
+
console.log('');
|
|
862
|
+
}
|
|
863
|
+
async scan() {
|
|
864
|
+
console.log('š Scanning for signals...');
|
|
865
|
+
await scanMoltbookForSignals();
|
|
866
|
+
const tokenData = getTokenData();
|
|
867
|
+
console.log(`Found ${tokenData.length} tokens with activity.`);
|
|
868
|
+
}
|
|
869
|
+
async showBalance() {
|
|
870
|
+
const balance = await getBalance();
|
|
871
|
+
console.log(`\nš° Balance: ${formatEther(balance)} MON\n`);
|
|
872
|
+
}
|
|
873
|
+
async register() {
|
|
874
|
+
if (moltbookClient.isRegistered()) {
|
|
875
|
+
const creds = moltbookClient.getCredentials();
|
|
876
|
+
console.log('Already registered!');
|
|
877
|
+
console.log(`Agent ID: ${creds?.agentId}`);
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
880
|
+
console.log('š¤ Registering CrownKing on Moltbook...');
|
|
881
|
+
try {
|
|
882
|
+
const result = await moltbookClient.register('CrownKing', 'An autonomous AI trading agent for Monad. Tracks whales, snipes new tokens, and trades on nad.fun. Built for Moltiverse Hackathon 2026. š');
|
|
883
|
+
console.log('\nā
Registration successful!');
|
|
884
|
+
console.log(`Agent ID: ${result.agent_id}`);
|
|
885
|
+
console.log(`\nā ļø Claim your agent: ${result.claim_url}`);
|
|
886
|
+
}
|
|
887
|
+
catch (error) {
|
|
888
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
889
|
+
console.log(`ā Registration failed: ${msg}`);
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
async showMe() {
|
|
893
|
+
try {
|
|
894
|
+
const me = await moltbookClient.getMe();
|
|
895
|
+
console.log('\n=== š¤ My Agent ===');
|
|
896
|
+
console.log(`Name: ${me.name}`);
|
|
897
|
+
console.log(`ID: ${me.id}`);
|
|
898
|
+
console.log(`Karma: ${me.karma}`);
|
|
899
|
+
console.log(`Claimed: ${me.is_claimed ? 'ā
' : 'ā'}`);
|
|
900
|
+
}
|
|
901
|
+
catch {
|
|
902
|
+
console.log('Could not fetch agent info.');
|
|
903
|
+
}
|
|
904
|
+
console.log('');
|
|
905
|
+
}
|
|
906
|
+
async showFeed() {
|
|
907
|
+
try {
|
|
908
|
+
const feed = await moltbookClient.getFeed();
|
|
909
|
+
console.log('\n=== š° Recent Feed ===');
|
|
910
|
+
for (const post of feed.posts.slice(0, 5)) {
|
|
911
|
+
console.log(`[${post.submolt}] ${post.title}`);
|
|
912
|
+
console.log(` by ${post.author.name} | ā¬ļø ${post.upvotes}`);
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
catch {
|
|
916
|
+
console.log('Could not fetch feed.');
|
|
917
|
+
}
|
|
918
|
+
console.log('');
|
|
919
|
+
}
|
|
920
|
+
async createPost(args) {
|
|
921
|
+
if (args.length < 2) {
|
|
922
|
+
console.log('Usage: post <submolt> <title>');
|
|
923
|
+
return;
|
|
924
|
+
}
|
|
925
|
+
const [submolt, ...titleParts] = args;
|
|
926
|
+
const title = titleParts.join(' ');
|
|
927
|
+
try {
|
|
928
|
+
const post = await moltbookClient.createPost(submolt, title);
|
|
929
|
+
console.log(`ā
Posted: ${post.id}`);
|
|
930
|
+
}
|
|
931
|
+
catch (error) {
|
|
932
|
+
console.log('ā Failed to post');
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
showBribes() {
|
|
936
|
+
const history = getBribeHistory();
|
|
937
|
+
console.log(`\n=== šø Bribes ===`);
|
|
938
|
+
console.log(`Total: ${history.length}`);
|
|
939
|
+
console.log('');
|
|
940
|
+
}
|
|
941
|
+
showTopInfluencers() {
|
|
942
|
+
const top = socialGraph.getTopInfluencers(10);
|
|
943
|
+
if (top.length === 0) {
|
|
944
|
+
console.log('No influencer data. Run "scan" first.');
|
|
945
|
+
return;
|
|
946
|
+
}
|
|
947
|
+
console.log('\n=== š„ Top Influencers ===');
|
|
948
|
+
top.forEach((a, i) => console.log(`${i + 1}. ${a.agentName} (Karma: ${a.karma})`));
|
|
949
|
+
console.log('');
|
|
950
|
+
}
|
|
951
|
+
showRisingStars() {
|
|
952
|
+
const rising = socialGraph.getRisingStars(10);
|
|
953
|
+
if (rising.length === 0) {
|
|
954
|
+
console.log('No rising stars found.');
|
|
955
|
+
return;
|
|
956
|
+
}
|
|
957
|
+
console.log('\n=== ā Rising Stars ===');
|
|
958
|
+
rising.forEach(a => console.log(`${a.agentName} (Karma: ${a.karma})`));
|
|
959
|
+
console.log('');
|
|
960
|
+
}
|
|
961
|
+
async startAutonomous() {
|
|
962
|
+
console.log('š Starting autonomous mode...');
|
|
963
|
+
crownKingAgent.start(5 * 60 * 1000).catch(err => logger.error('Agent error', { err }));
|
|
964
|
+
console.log('Use "stop" to stop.');
|
|
965
|
+
}
|
|
966
|
+
stopAutonomous() {
|
|
967
|
+
crownKingAgent.stop();
|
|
968
|
+
console.log('ā¹ļø Autonomous mode stopped.');
|
|
969
|
+
}
|
|
970
|
+
// === NEW FEATURE COMMANDS ===
|
|
971
|
+
async momentumCommand(args) {
|
|
972
|
+
if (args.length < 1) {
|
|
973
|
+
console.log('Usage: momentum <token_address>');
|
|
974
|
+
return;
|
|
975
|
+
}
|
|
976
|
+
const tokenAddress = args[0];
|
|
977
|
+
console.log(`\nš Analyzing momentum for ${tokenAddress}...`);
|
|
978
|
+
try {
|
|
979
|
+
const momentum = await analyzeTokenMomentum(tokenAddress);
|
|
980
|
+
console.log('\n' + formatMomentum(momentum));
|
|
981
|
+
}
|
|
982
|
+
catch (error) {
|
|
983
|
+
console.log(`ā Error: ${error instanceof Error ? error.message : String(error)}`);
|
|
984
|
+
}
|
|
985
|
+
console.log('');
|
|
986
|
+
}
|
|
987
|
+
async handleCopyTrader(args) {
|
|
988
|
+
const subCmd = args[0]?.toLowerCase();
|
|
989
|
+
switch (subCmd) {
|
|
990
|
+
case 'add':
|
|
991
|
+
if (args.length < 3) {
|
|
992
|
+
console.log('Usage: copy add <address> <name>');
|
|
993
|
+
return;
|
|
994
|
+
}
|
|
995
|
+
const addr = args[1];
|
|
996
|
+
const name = args.slice(2).join(' ');
|
|
997
|
+
addTrackedWallet(addr, name);
|
|
998
|
+
console.log(`ā
Added ${name} to copy trading list.`);
|
|
999
|
+
break;
|
|
1000
|
+
case 'start':
|
|
1001
|
+
updateCopyConfig({ enabled: true });
|
|
1002
|
+
await startCopyTrading();
|
|
1003
|
+
console.log('š Copy trading started!');
|
|
1004
|
+
break;
|
|
1005
|
+
case 'stop':
|
|
1006
|
+
stopCopyTrading();
|
|
1007
|
+
updateCopyConfig({ enabled: false });
|
|
1008
|
+
console.log('ā¹ļø Copy trading stopped.');
|
|
1009
|
+
break;
|
|
1010
|
+
default:
|
|
1011
|
+
const stats = getCopyTradingStats();
|
|
1012
|
+
const wallets = getTrackedWallets();
|
|
1013
|
+
console.log('\n=== š Copy Trading ===');
|
|
1014
|
+
console.log(`Status: ${stats.enabled ? 'š¢ Active' : 'š“ Inactive'}`);
|
|
1015
|
+
console.log(`Tracked Wallets: ${stats.trackedWallets}`);
|
|
1016
|
+
console.log(`Total Copied: ${stats.totalCopied}`);
|
|
1017
|
+
console.log(`Success Rate: ${stats.successRate.toFixed(1)}%`);
|
|
1018
|
+
console.log(`Daily Remaining: ${stats.dailyRemaining}`);
|
|
1019
|
+
if (wallets.length > 0) {
|
|
1020
|
+
console.log('\n--- Tracked Wallets ---');
|
|
1021
|
+
wallets.forEach(w => console.log(' ' + formatTrackedWallet(w)));
|
|
1022
|
+
}
|
|
1023
|
+
console.log('\nCommands: add <addr> <name>, start, stop');
|
|
1024
|
+
}
|
|
1025
|
+
console.log('');
|
|
1026
|
+
}
|
|
1027
|
+
async showLeaderboard() {
|
|
1028
|
+
console.log('\nš Fetching leaderboard...');
|
|
1029
|
+
const stats = await fetchLeaderboard();
|
|
1030
|
+
console.log('\n' + formatLeaderboard(stats));
|
|
1031
|
+
const insights = await getCompetitiveInsights();
|
|
1032
|
+
if (insights.strengths.length > 0 || insights.opportunities.length > 0) {
|
|
1033
|
+
console.log('\n--- Competitive Insights ---');
|
|
1034
|
+
insights.strengths.forEach(s => console.log(`ā
${s}`));
|
|
1035
|
+
insights.opportunities.forEach(o => console.log(`š” ${o}`));
|
|
1036
|
+
}
|
|
1037
|
+
console.log('');
|
|
1038
|
+
}
|
|
1039
|
+
postGM() {
|
|
1040
|
+
postGreeting('gm');
|
|
1041
|
+
console.log('āļø GM post queued!');
|
|
1042
|
+
const status = getPostQueueStatus();
|
|
1043
|
+
if (!status.canPostNow) {
|
|
1044
|
+
console.log(`ā³ Will post in ~${status.nextPostIn} minutes`);
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
postGN() {
|
|
1048
|
+
postGreeting('gn');
|
|
1049
|
+
console.log('š GN post queued!');
|
|
1050
|
+
const status = getPostQueueStatus();
|
|
1051
|
+
if (!status.canPostNow) {
|
|
1052
|
+
console.log(`ā³ Will post in ~${status.nextPostIn} minutes`);
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
async handleAllies(args) {
|
|
1056
|
+
const subCmd = args[0]?.toLowerCase();
|
|
1057
|
+
switch (subCmd) {
|
|
1058
|
+
case 'discover':
|
|
1059
|
+
console.log('\nš Discovering potential allies...');
|
|
1060
|
+
const discovered = await discoverAllies();
|
|
1061
|
+
console.log(`Found ${discovered.length} potential allies.`);
|
|
1062
|
+
discovered.slice(0, 5).forEach((a, i) => {
|
|
1063
|
+
console.log(`${i + 1}. ${a.name} (Karma: ${a.karma})`);
|
|
1064
|
+
});
|
|
1065
|
+
break;
|
|
1066
|
+
case 'run':
|
|
1067
|
+
console.log('\nš¤ Running alliance routine...');
|
|
1068
|
+
const result = await runAllianceRoutine();
|
|
1069
|
+
console.log(`Discovered: ${result.discovered}`);
|
|
1070
|
+
console.log(`Followed: ${result.followed}`);
|
|
1071
|
+
console.log(`Engagements: ${result.engagements}`);
|
|
1072
|
+
console.log(`Comments: ${result.comments}`);
|
|
1073
|
+
break;
|
|
1074
|
+
default:
|
|
1075
|
+
const stats = getAllianceStats();
|
|
1076
|
+
console.log('\n=== š¤ Alliance Stats ===');
|
|
1077
|
+
console.log(`Total Allies: ${stats.totalAllies}`);
|
|
1078
|
+
console.log(`Following: ${stats.followingCount}`);
|
|
1079
|
+
console.log(`Total Interactions: ${stats.totalInteractions}`);
|
|
1080
|
+
if (stats.topAllies.length > 0) {
|
|
1081
|
+
console.log('\n--- Top Allies ---');
|
|
1082
|
+
stats.topAllies.forEach((a, i) => {
|
|
1083
|
+
console.log(`${i + 1}. ${a.name} (Karma: ${a.karma}, Benefit: ${a.mutualBenefit})`);
|
|
1084
|
+
});
|
|
1085
|
+
}
|
|
1086
|
+
console.log('\nCommands: discover, run');
|
|
1087
|
+
}
|
|
1088
|
+
console.log('');
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
const cli = new CrownKingCLI();
|
|
1092
|
+
cli.start().catch(console.error);
|
|
1093
|
+
//# sourceMappingURL=crown-king.js.map
|