@0xobelisk/sui-cli 1.2.0-pre.15 → 1.2.0-pre.16
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/dist/dubhe.js +45 -44
- package/dist/dubhe.js.map +1 -1
- package/package.json +3 -3
- package/src/commands/index.ts +3 -1
- package/src/commands/switchEnv.ts +24 -0
- package/src/utils/utils.ts +124 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@0xobelisk/sui-cli",
|
|
3
|
-
"version": "1.2.0-pre.
|
|
3
|
+
"version": "1.2.0-pre.16",
|
|
4
4
|
"description": "Tookit for interacting with move eps framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sui",
|
|
@@ -50,8 +50,8 @@
|
|
|
50
50
|
"yargs": "^17.7.1",
|
|
51
51
|
"zod": "^3.22.3",
|
|
52
52
|
"zod-validation-error": "^1.3.0",
|
|
53
|
-
"@0xobelisk/sui-client": "1.2.0-pre.
|
|
54
|
-
"@0xobelisk/sui-common": "1.2.0-pre.
|
|
53
|
+
"@0xobelisk/sui-client": "1.2.0-pre.16",
|
|
54
|
+
"@0xobelisk/sui-common": "1.2.0-pre.16"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"@types/ejs": "^3.1.1",
|
package/src/commands/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ import query from './query';
|
|
|
15
15
|
import call from './call';
|
|
16
16
|
import watch from './watch';
|
|
17
17
|
import wait from './wait';
|
|
18
|
+
import switchEnv from './switchEnv';
|
|
18
19
|
|
|
19
20
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Each command has different options
|
|
20
21
|
export const commands: CommandModule<any, any>[] = [
|
|
@@ -32,5 +33,6 @@ export const commands: CommandModule<any, any>[] = [
|
|
|
32
33
|
checkBalance,
|
|
33
34
|
configStore,
|
|
34
35
|
watch,
|
|
35
|
-
wait
|
|
36
|
+
wait,
|
|
37
|
+
switchEnv
|
|
36
38
|
];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CommandModule, ArgumentsCamelCase } from 'yargs';
|
|
2
|
+
import { switchEnv } from '../utils';
|
|
3
|
+
|
|
4
|
+
type Options = {
|
|
5
|
+
network: 'mainnet' | 'testnet' | 'devnet' | 'localnet';
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const commandModule: CommandModule<Options, Options> = {
|
|
9
|
+
command: 'switch-env',
|
|
10
|
+
describe: 'Switch environment',
|
|
11
|
+
builder(yargs) {
|
|
12
|
+
return yargs.option('network', {
|
|
13
|
+
type: 'string',
|
|
14
|
+
choices: ['mainnet', 'testnet', 'devnet', 'localnet'] as const,
|
|
15
|
+
default: 'localnet',
|
|
16
|
+
desc: 'Switch to node network (mainnet/testnet/devnet/localnet)'
|
|
17
|
+
}) as any;
|
|
18
|
+
},
|
|
19
|
+
async handler(argv: ArgumentsCamelCase<Options>) {
|
|
20
|
+
await switchEnv(argv.network as 'mainnet' | 'testnet' | 'devnet' | 'localnet');
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default commandModule;
|
package/src/utils/utils.ts
CHANGED
|
@@ -207,32 +207,147 @@ export async function updateDubheDependency(
|
|
|
207
207
|
fs.writeFileSync(filePath, updatedContent, 'utf-8');
|
|
208
208
|
console.log(`Updated Dubhe dependency in ${filePath} for ${network}.`);
|
|
209
209
|
}
|
|
210
|
+
|
|
211
|
+
async function checkRpcAvailability(rpcUrl: string): Promise<boolean> {
|
|
212
|
+
try {
|
|
213
|
+
const response = await fetch(rpcUrl, {
|
|
214
|
+
method: 'POST',
|
|
215
|
+
headers: {
|
|
216
|
+
'Content-Type': 'application/json'
|
|
217
|
+
},
|
|
218
|
+
body: JSON.stringify({
|
|
219
|
+
jsonrpc: '2.0',
|
|
220
|
+
id: 1,
|
|
221
|
+
method: 'sui_getLatestCheckpointSequenceNumber',
|
|
222
|
+
params: []
|
|
223
|
+
})
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
if (!response.ok) {
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const data = await response.json();
|
|
231
|
+
return !data.error;
|
|
232
|
+
} catch (error) {
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
export async function addEnv(
|
|
238
|
+
network: 'mainnet' | 'testnet' | 'devnet' | 'localnet'
|
|
239
|
+
): Promise<void> {
|
|
240
|
+
const rpcMap = {
|
|
241
|
+
localnet: 'http://127.0.0.1:9000',
|
|
242
|
+
devnet: 'https://fullnode.devnet.sui.io:443/',
|
|
243
|
+
testnet: 'https://fullnode.testnet.sui.io:443/',
|
|
244
|
+
mainnet: 'https://fullnode.mainnet.sui.io:443/'
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
const rpcUrl = rpcMap[network];
|
|
248
|
+
|
|
249
|
+
// Check RPC availability first
|
|
250
|
+
const isRpcAvailable = await checkRpcAvailability(rpcUrl);
|
|
251
|
+
if (!isRpcAvailable) {
|
|
252
|
+
throw new Error(
|
|
253
|
+
`RPC endpoint ${rpcUrl} is not available. Please check your network connection or try again later.`
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return new Promise<void>((resolve, reject) => {
|
|
258
|
+
let errorOutput = '';
|
|
259
|
+
let stdoutOutput = '';
|
|
260
|
+
|
|
261
|
+
const suiProcess = spawn(
|
|
262
|
+
'sui',
|
|
263
|
+
['client', 'new-env', '--alias', network, '--rpc', rpcMap[network]],
|
|
264
|
+
{
|
|
265
|
+
env: { ...process.env },
|
|
266
|
+
stdio: 'pipe'
|
|
267
|
+
}
|
|
268
|
+
);
|
|
269
|
+
|
|
270
|
+
// Capture standard output
|
|
271
|
+
suiProcess.stdout.on('data', (data) => {
|
|
272
|
+
stdoutOutput += data.toString();
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
// Capture error output
|
|
276
|
+
suiProcess.stderr.on('data', (data) => {
|
|
277
|
+
errorOutput += data.toString();
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// Handle process errors (e.g., command not found)
|
|
281
|
+
suiProcess.on('error', (error) => {
|
|
282
|
+
console.error(chalk.red(`\n❌ Failed to execute sui command: ${error.message}`));
|
|
283
|
+
reject(new Error(`Failed to execute sui command: ${error.message}`));
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
// Handle process exit
|
|
287
|
+
suiProcess.on('exit', (code) => {
|
|
288
|
+
// Check if "already exists" message is present
|
|
289
|
+
if (errorOutput.includes('already exists') || stdoutOutput.includes('already exists')) {
|
|
290
|
+
console.log(chalk.yellow(`Environment ${network} already exists, proceeding...`));
|
|
291
|
+
resolve();
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (code === 0) {
|
|
296
|
+
console.log(chalk.green(`Successfully added environment ${network}`));
|
|
297
|
+
resolve();
|
|
298
|
+
} else {
|
|
299
|
+
const finalError = errorOutput || stdoutOutput || `Process exited with code ${code}`;
|
|
300
|
+
console.error(chalk.red(`\n❌ Failed to add environment ${network}`));
|
|
301
|
+
console.error(chalk.red(` └─ ${finalError.trim()}`));
|
|
302
|
+
reject(new Error(finalError));
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
|
|
210
308
|
export async function switchEnv(network: 'mainnet' | 'testnet' | 'devnet' | 'localnet') {
|
|
211
309
|
try {
|
|
310
|
+
// First, try to add the environment
|
|
311
|
+
await addEnv(network);
|
|
312
|
+
|
|
313
|
+
// Then switch to the specified environment
|
|
212
314
|
return new Promise<void>((resolve, reject) => {
|
|
315
|
+
let errorOutput = '';
|
|
316
|
+
let stdoutOutput = '';
|
|
317
|
+
|
|
213
318
|
const suiProcess = spawn('sui', ['client', 'switch', '--env', network], {
|
|
214
319
|
env: { ...process.env },
|
|
215
320
|
stdio: 'pipe'
|
|
216
321
|
});
|
|
217
322
|
|
|
323
|
+
suiProcess.stdout.on('data', (data) => {
|
|
324
|
+
stdoutOutput += data.toString();
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
suiProcess.stderr.on('data', (data) => {
|
|
328
|
+
errorOutput += data.toString();
|
|
329
|
+
});
|
|
330
|
+
|
|
218
331
|
suiProcess.on('error', (error) => {
|
|
219
|
-
console.error(chalk.red(
|
|
220
|
-
|
|
221
|
-
reject(error); // Reject promise on error
|
|
332
|
+
console.error(chalk.red(`\n❌ Failed to execute sui command: ${error.message}`));
|
|
333
|
+
reject(new Error(`Failed to execute sui command: ${error.message}`));
|
|
222
334
|
});
|
|
223
335
|
|
|
224
336
|
suiProcess.on('exit', (code) => {
|
|
225
|
-
if (code
|
|
226
|
-
console.
|
|
227
|
-
|
|
337
|
+
if (code === 0) {
|
|
338
|
+
console.log(chalk.green(`Successfully switched to environment ${network}`));
|
|
339
|
+
resolve();
|
|
228
340
|
} else {
|
|
229
|
-
|
|
341
|
+
const finalError = errorOutput || stdoutOutput || `Process exited with code ${code}`;
|
|
342
|
+
console.error(chalk.red(`\n❌ Failed to switch to environment ${network}`));
|
|
343
|
+
console.error(chalk.red(` └─ ${finalError.trim()}`));
|
|
344
|
+
reject(new Error(finalError));
|
|
230
345
|
}
|
|
231
346
|
});
|
|
232
347
|
});
|
|
233
348
|
} catch (error) {
|
|
234
|
-
|
|
235
|
-
|
|
349
|
+
// Re-throw the error for the caller to handle
|
|
350
|
+
throw error;
|
|
236
351
|
}
|
|
237
352
|
}
|
|
238
353
|
|