clawreum-sdk 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/clawreum.js +316 -0
- package/package.json +6 -3
package/bin/clawreum.js
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Clawreum CLI
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* npm install -g clawreum-sdk
|
|
8
|
+
* clawreum start
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const readline = require('readline');
|
|
12
|
+
const fs = require('fs');
|
|
13
|
+
const path = require('path');
|
|
14
|
+
|
|
15
|
+
// Colors
|
|
16
|
+
const colors = {
|
|
17
|
+
orange: '\x1b[38;5;208m',
|
|
18
|
+
green: '\x1b[32m',
|
|
19
|
+
red: '\x1b[31m',
|
|
20
|
+
cyan: '\x1b[36m',
|
|
21
|
+
yellow: '\x1b[33m',
|
|
22
|
+
reset: '\x1b[0m',
|
|
23
|
+
bold: '\x1b[1m'
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const CONFIG_DIR = path.join(process.env.HOME || process.env.USERPROFILE, '.clawreum');
|
|
27
|
+
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
28
|
+
|
|
29
|
+
const rl = readline.createInterface({
|
|
30
|
+
input: process.stdin,
|
|
31
|
+
output: process.stdout
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
function ask(question) {
|
|
35
|
+
return new Promise(resolve => {
|
|
36
|
+
rl.question(`${colors.orange}? ${question}${colors.reset} `, resolve);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function select(question, options) {
|
|
41
|
+
return new Promise(resolve => {
|
|
42
|
+
console.log(`${colors.orange}? ${question}${colors.reset}`);
|
|
43
|
+
options.forEach((opt, i) => {
|
|
44
|
+
console.log(` ${colors.cyan}${i + 1}.${colors.reset} ${opt}`);
|
|
45
|
+
});
|
|
46
|
+
rl.question(`${colors.orange} Enter number (1-${options.length}): ${colors.reset}`, answer => {
|
|
47
|
+
const idx = parseInt(answer) - 1;
|
|
48
|
+
resolve(options[idx] || options[0]);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function success(msg) {
|
|
54
|
+
console.log(`${colors.green}✓${colors.reset} ${msg}`);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function error(msg) {
|
|
58
|
+
console.log(`${colors.red}✗${colors.reset} ${msg}`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function info(msg) {
|
|
62
|
+
console.log(`${colors.cyan}ℹ${colors.reset} ${msg}`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function banner() {
|
|
66
|
+
console.log(`
|
|
67
|
+
${colors.orange}${colors.bold}
|
|
68
|
+
██████╗██╗ █████╗ ██╗ ██╗██████╗ ███████╗██╗ ██╗███╗ ███╗
|
|
69
|
+
██╔════╝██║ ██╔══██╗██║ ██║██╔══██╗██╔════╝██║ ██║████╗ ████║
|
|
70
|
+
██║ ██║ ███████║██║ █╗ ██║██████╔╝█████╗ ██║ ██║██╔████╔██║
|
|
71
|
+
██║ ██║ ██╔══██║██║███╗██║██╔══██╗██╔══╝ ██║ ██║██║╚██╔╝██║
|
|
72
|
+
╚██████╗███████╗██║ ██║╚███╔███╔╝██║ ██║███████╗╚██████╔╝██║ ╚═╝ ██║
|
|
73
|
+
╚═════╝╚══════╝╚═╝ ╚═╝ ╚══╝╚══╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝
|
|
74
|
+
${colors.reset}
|
|
75
|
+
${colors.cyan}Mining Bot CLI v2.0.0${colors.reset}
|
|
76
|
+
`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function extractBotInfo(platform, token) {
|
|
80
|
+
if (platform === 'telegram') {
|
|
81
|
+
// Telegram token format: BOT_ID:SECRET
|
|
82
|
+
const parts = token.split(':');
|
|
83
|
+
if (parts.length === 2 && /^\d+$/.test(parts[0])) {
|
|
84
|
+
return { botId: parts[0], valid: true };
|
|
85
|
+
}
|
|
86
|
+
} else if (platform === 'discord') {
|
|
87
|
+
// Discord token is base64 encoded, first part is bot ID
|
|
88
|
+
try {
|
|
89
|
+
const parts = token.split('.');
|
|
90
|
+
if (parts.length >= 1) {
|
|
91
|
+
const decoded = Buffer.from(parts[0], 'base64').toString();
|
|
92
|
+
if (/^\d+$/.test(decoded)) {
|
|
93
|
+
return { botId: decoded, valid: true };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
} catch (e) {}
|
|
97
|
+
}
|
|
98
|
+
return { botId: null, valid: false };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function getBotName(platform, token) {
|
|
102
|
+
try {
|
|
103
|
+
if (platform === 'telegram') {
|
|
104
|
+
const response = await fetch(`https://api.telegram.org/bot${token}/getMe`);
|
|
105
|
+
const data = await response.json();
|
|
106
|
+
if (data.ok) {
|
|
107
|
+
return data.result.username || data.result.first_name;
|
|
108
|
+
}
|
|
109
|
+
} else if (platform === 'discord') {
|
|
110
|
+
const response = await fetch('https://discord.com/api/v10/users/@me', {
|
|
111
|
+
headers: { Authorization: `Bot ${token}` }
|
|
112
|
+
});
|
|
113
|
+
const data = await response.json();
|
|
114
|
+
if (data.username) {
|
|
115
|
+
return data.username;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
} catch (e) {}
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function saveConfig(config) {
|
|
123
|
+
if (!fs.existsSync(CONFIG_DIR)) {
|
|
124
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
125
|
+
}
|
|
126
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function loadConfig() {
|
|
130
|
+
try {
|
|
131
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
132
|
+
return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf8'));
|
|
133
|
+
}
|
|
134
|
+
} catch (e) {}
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
async function setup() {
|
|
139
|
+
banner();
|
|
140
|
+
console.log(`${colors.yellow}Let's set up your mining bot!${colors.reset}\n`);
|
|
141
|
+
|
|
142
|
+
// Platform selection
|
|
143
|
+
const platform = await select('Select platform:', ['Telegram', 'Discord']);
|
|
144
|
+
const platformLower = platform.toLowerCase();
|
|
145
|
+
|
|
146
|
+
// Token input
|
|
147
|
+
const tokenPrompt = platformLower === 'telegram'
|
|
148
|
+
? 'Enter your Telegram Bot Token (from @BotFather):'
|
|
149
|
+
: 'Enter your Discord Bot Token:';
|
|
150
|
+
|
|
151
|
+
const token = await ask(tokenPrompt);
|
|
152
|
+
|
|
153
|
+
// Extract bot ID
|
|
154
|
+
const { botId, valid } = extractBotInfo(platformLower, token);
|
|
155
|
+
|
|
156
|
+
if (!valid || !botId) {
|
|
157
|
+
error('Invalid token format. Please check and try again.');
|
|
158
|
+
rl.close();
|
|
159
|
+
process.exit(1);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
success(`Bot ID extracted: ${botId}`);
|
|
163
|
+
|
|
164
|
+
// Get bot name from API
|
|
165
|
+
info('Fetching bot info...');
|
|
166
|
+
const botName = await getBotName(platformLower, token);
|
|
167
|
+
|
|
168
|
+
if (botName) {
|
|
169
|
+
success(`Bot name: @${botName}`);
|
|
170
|
+
} else {
|
|
171
|
+
error('Could not fetch bot name. Using default.');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Bot display name
|
|
175
|
+
const displayName = await ask(`Enter display name for your bot (default: ${botName || 'ClawBot'}):`) || botName || 'ClawBot';
|
|
176
|
+
|
|
177
|
+
// Save config
|
|
178
|
+
const config = {
|
|
179
|
+
platform: platformLower,
|
|
180
|
+
botId,
|
|
181
|
+
botName: displayName,
|
|
182
|
+
token,
|
|
183
|
+
createdAt: new Date().toISOString()
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
saveConfig(config);
|
|
187
|
+
success('Configuration saved!\n');
|
|
188
|
+
|
|
189
|
+
return config;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
async function start(config) {
|
|
193
|
+
console.log(`\n${colors.yellow}Starting mining bot...${colors.reset}\n`);
|
|
194
|
+
|
|
195
|
+
info(`Platform: ${config.platform}`);
|
|
196
|
+
info(`Bot ID: ${config.botId}`);
|
|
197
|
+
info(`Bot Name: ${config.botName}`);
|
|
198
|
+
console.log('');
|
|
199
|
+
|
|
200
|
+
// Load SDK and start
|
|
201
|
+
const ClawreumMiner = require('../src/index.js');
|
|
202
|
+
|
|
203
|
+
const miner = new ClawreumMiner({
|
|
204
|
+
platform: config.platform,
|
|
205
|
+
botId: config.botId,
|
|
206
|
+
botName: config.botName
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
miner.on('log', (msg) => {
|
|
210
|
+
console.log(`${colors.cyan}[LOG]${colors.reset} ${msg}`);
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
miner.on('error', (err) => {
|
|
214
|
+
console.log(`${colors.red}[ERROR]${colors.reset} ${err.message}`);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
miner.on('registered', ({ botId, characterName }) => {
|
|
218
|
+
success(`Registered as ${characterName} (${botId})`);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
miner.on('authenticated', ({ botName }) => {
|
|
222
|
+
success(`Authenticated: ${botName}`);
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
miner.on('joined', ({ room }) => {
|
|
226
|
+
success(`Joined room: ${room}`);
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
miner.on('rockStatus', ({ available, total }) => {
|
|
230
|
+
info(`Rocks: ${available}/${total} available`);
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
miner.on('mining', ({ rockId }) => {
|
|
234
|
+
console.log(`${colors.yellow}⛏${colors.reset} Mining at rock ${rockId}...`);
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
miner.on('reward', ({ reward, bonus }) => {
|
|
238
|
+
console.log(`${colors.green}💰 +${reward.toFixed(4)} CLAWREUM${colors.reset}${bonus > 0 ? ` (bonus: +${bonus.toFixed(4)})` : ''}`);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
miner.on('balance', ({ refining, claimable }) => {
|
|
242
|
+
info(`Balance - Refining: ${refining?.toFixed(2) || 0}, Claimable: ${claimable?.toFixed(2) || 0}`);
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
miner.on('disconnected', () => {
|
|
246
|
+
error('Disconnected from server');
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
// Handle Ctrl+C
|
|
250
|
+
process.on('SIGINT', () => {
|
|
251
|
+
console.log(`\n${colors.yellow}Stopping...${colors.reset}`);
|
|
252
|
+
miner.stop();
|
|
253
|
+
process.exit(0);
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
await miner.start();
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
async function main() {
|
|
260
|
+
const args = process.argv.slice(2);
|
|
261
|
+
const command = args[0] || 'start';
|
|
262
|
+
|
|
263
|
+
switch (command) {
|
|
264
|
+
case 'start':
|
|
265
|
+
let config = loadConfig();
|
|
266
|
+
|
|
267
|
+
if (!config) {
|
|
268
|
+
config = await setup();
|
|
269
|
+
} else {
|
|
270
|
+
banner();
|
|
271
|
+
info('Using saved configuration');
|
|
272
|
+
info(`Platform: ${config.platform}, Bot: ${config.botName}`);
|
|
273
|
+
|
|
274
|
+
const useExisting = await ask('Use this config? (Y/n):');
|
|
275
|
+
if (useExisting.toLowerCase() === 'n') {
|
|
276
|
+
config = await setup();
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
rl.close();
|
|
281
|
+
await start(config);
|
|
282
|
+
break;
|
|
283
|
+
|
|
284
|
+
case 'config':
|
|
285
|
+
await setup();
|
|
286
|
+
rl.close();
|
|
287
|
+
success('Run "clawreum start" to begin mining!');
|
|
288
|
+
break;
|
|
289
|
+
|
|
290
|
+
case 'reset':
|
|
291
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
292
|
+
fs.unlinkSync(CONFIG_FILE);
|
|
293
|
+
success('Configuration reset!');
|
|
294
|
+
} else {
|
|
295
|
+
info('No configuration found.');
|
|
296
|
+
}
|
|
297
|
+
rl.close();
|
|
298
|
+
break;
|
|
299
|
+
|
|
300
|
+
case 'help':
|
|
301
|
+
default:
|
|
302
|
+
banner();
|
|
303
|
+
console.log(`${colors.yellow}Commands:${colors.reset}`);
|
|
304
|
+
console.log(` ${colors.cyan}clawreum start${colors.reset} - Start mining (setup if needed)`);
|
|
305
|
+
console.log(` ${colors.cyan}clawreum config${colors.reset} - Configure bot settings`);
|
|
306
|
+
console.log(` ${colors.cyan}clawreum reset${colors.reset} - Reset configuration`);
|
|
307
|
+
console.log(` ${colors.cyan}clawreum help${colors.reset} - Show this help`);
|
|
308
|
+
rl.close();
|
|
309
|
+
break;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
main().catch(err => {
|
|
314
|
+
error(err.message);
|
|
315
|
+
process.exit(1);
|
|
316
|
+
});
|
package/package.json
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clawreum-sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Clawreum Mining SDK - Bot client for mining CLAWREUM tokens",
|
|
5
5
|
"main": "src/index.js",
|
|
6
|
-
"
|
|
6
|
+
"bin": {
|
|
7
|
+
"clawreum": "./bin/clawreum.js"
|
|
8
|
+
},
|
|
7
9
|
"keywords": [
|
|
8
10
|
"clawreum",
|
|
9
11
|
"mining",
|
|
@@ -11,7 +13,8 @@
|
|
|
11
13
|
"bsc",
|
|
12
14
|
"crypto",
|
|
13
15
|
"bot",
|
|
14
|
-
"sdk"
|
|
16
|
+
"sdk",
|
|
17
|
+
"cli"
|
|
15
18
|
],
|
|
16
19
|
"author": "Clawreum Team",
|
|
17
20
|
"license": "MIT",
|