@0xobelisk/sui-cli 0.5.29 β 0.5.31
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 +60 -60
- package/dist/dubhe.js.map +1 -1
- package/package.json +2 -2
- package/src/commands/build.ts +56 -0
- package/src/commands/checkBalance.ts +35 -0
- package/src/commands/generateKey.ts +35 -0
- package/src/commands/index.ts +9 -1
- package/src/commands/localnode.ts +4 -38
- package/src/commands/storeConfig.ts +44 -0
- package/src/commands/test.ts +17 -7
- package/src/utils/checkBalance.ts +55 -0
- package/src/utils/errors.ts +31 -31
- package/src/utils/generateAccount.ts +100 -0
- package/src/utils/publishHandler.ts +73 -33
- package/src/utils/startNode.ts +117 -0
- package/src/utils/storeConfig.ts +79 -0
- package/src/utils/utils.ts +0 -2
- package/src/utils/localnode/index.ts +0 -3
- package/src/utils/localnode/start.ts +0 -87
- package/src/utils/localnode/status.ts +0 -38
- package/src/utils/localnode/stop.ts +0 -58
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { execSync, spawn } from 'child_process';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { printDubhe } from './printDubhe';
|
|
4
|
+
import { delay, DubheCliError, publishDubheFramework, validatePrivateKey } from '../utils';
|
|
5
|
+
import { Dubhe } from '@0xobelisk/sui-client';
|
|
6
|
+
import { getFullnodeUrl, SuiClient } from '@mysten/sui/client';
|
|
7
|
+
|
|
8
|
+
function isSuiStartRunning(): boolean {
|
|
9
|
+
try {
|
|
10
|
+
const cmd =
|
|
11
|
+
process.platform === 'win32'
|
|
12
|
+
? `tasklist /FI "IMAGENAME eq sui.exe" /FO CSV /NH`
|
|
13
|
+
: 'pgrep -f "sui start"';
|
|
14
|
+
|
|
15
|
+
const result = execSync(cmd).toString().trim();
|
|
16
|
+
return process.platform === 'win32'
|
|
17
|
+
? result.toLowerCase().includes('sui.exe')
|
|
18
|
+
: result.length > 0;
|
|
19
|
+
} catch (error) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function printAccounts() {
|
|
25
|
+
// These private keys are used for testing purposes only, do not use them in production.
|
|
26
|
+
const privateKeys = [
|
|
27
|
+
"suiprivkey1qq3ez3dje66l8pypgxynr7yymwps6uhn7vyczespj84974j3zya0wdpu76v",
|
|
28
|
+
"suiprivkey1qp6vcyg8r2x88fllmjmxtpzjl95gd9dugqrgz7xxf50w6rqdqzetg7x4d7s",
|
|
29
|
+
"suiprivkey1qpy3a696eh3m55fwa8h38ss063459u4n2dm9t24w2hlxxzjp2x34q8sdsnc",
|
|
30
|
+
"suiprivkey1qzxwp29favhzrjd95f6uj9nskjwal6nh9g509jpun395y6g72d6jqlmps4c",
|
|
31
|
+
"suiprivkey1qzhq4lv38sesah4uzsqkkmeyjx860xqjdz8qgw36tmrdd5tnle3evxpng57",
|
|
32
|
+
"suiprivkey1qzez45sjjsepjgtksqvpq6jw7dzw3zq0dx7a4sulfypd73acaynw5jl9x2c",
|
|
33
|
+
]
|
|
34
|
+
console.log("πAccounts")
|
|
35
|
+
console.log("==========")
|
|
36
|
+
privateKeys.forEach((privateKey, index) => {
|
|
37
|
+
const dubhe = new Dubhe({ secretKey: privateKey });
|
|
38
|
+
const keypair = dubhe.getKeypair();
|
|
39
|
+
spawn(
|
|
40
|
+
'curl',
|
|
41
|
+
['--location', '--request', 'POST', 'http://127.0.0.1:9123/gas', '--header', 'Content-Type: application/json', '--data-raw', `{"FixedAmountRequest": {"recipient": "${keypair.toSuiAddress()}"}}`],
|
|
42
|
+
{
|
|
43
|
+
env: { ...process.env },
|
|
44
|
+
stdio: 'ignore',
|
|
45
|
+
detached: true,
|
|
46
|
+
}
|
|
47
|
+
)
|
|
48
|
+
console.log(` ββ Account #${index}: ${keypair.toSuiAddress()}(1000 SUI)`);
|
|
49
|
+
console.log(` ββ Private Key: ${privateKey}`);
|
|
50
|
+
});
|
|
51
|
+
console.log("==========")
|
|
52
|
+
console.log(chalk.yellow("β οΈWARNING: These accounts, and their private keys, are publicly known."));
|
|
53
|
+
console.log(chalk.yellow("Any funds sent to them on Mainnet or any other live network WILL BE LOST."));
|
|
54
|
+
}
|
|
55
|
+
export async function startLocalNode() {
|
|
56
|
+
if (isSuiStartRunning()) {
|
|
57
|
+
console.log(chalk.yellow('\nβ οΈ Warning: Local Node Already Running'));
|
|
58
|
+
console.log(chalk.yellow(' ββ Cannot start a new instance'));
|
|
59
|
+
console.log(
|
|
60
|
+
chalk.yellow(' ββ Please stop the existing process first')
|
|
61
|
+
);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
printDubhe();
|
|
66
|
+
console.log('π Starting Local Node...');
|
|
67
|
+
try {
|
|
68
|
+
const suiProcess = spawn(
|
|
69
|
+
'sui',
|
|
70
|
+
['start', '--with-faucet', '--force-regenesis'],
|
|
71
|
+
{
|
|
72
|
+
env: { ...process.env, RUST_LOG: 'off,sui_node=info' },
|
|
73
|
+
stdio: 'ignore',
|
|
74
|
+
detached: true,
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
suiProcess.on('error', error => {
|
|
79
|
+
console.error(chalk.red('\nβ Failed to Start Local Node'));
|
|
80
|
+
console.error(chalk.red(` ββ Error: ${error.message}`));
|
|
81
|
+
});
|
|
82
|
+
await delay(5000);
|
|
83
|
+
console.log(' ββ Faucet: Enabled');
|
|
84
|
+
console.log(' ββ Force Regenesis: Yes');
|
|
85
|
+
console.log(' ββ HTTP server: http://127.0.0.1:9000/');
|
|
86
|
+
console.log(' ββ Faucet server: http://127.0.0.1:9123/');
|
|
87
|
+
|
|
88
|
+
await printAccounts();
|
|
89
|
+
|
|
90
|
+
await delay(2000);
|
|
91
|
+
|
|
92
|
+
const privateKeyFormat = validatePrivateKey("suiprivkey1qzez45sjjsepjgtksqvpq6jw7dzw3zq0dx7a4sulfypd73acaynw5jl9x2c");
|
|
93
|
+
if (privateKeyFormat === false) {
|
|
94
|
+
throw new DubheCliError(`Please check your privateKey.`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const dubhe = new Dubhe({ secretKey: privateKeyFormat });
|
|
98
|
+
const client = new SuiClient({ url: getFullnodeUrl('localnet') });
|
|
99
|
+
const originalLog = console.log;
|
|
100
|
+
|
|
101
|
+
console.log = () => {};
|
|
102
|
+
await publishDubheFramework(client, dubhe, 'localnet');
|
|
103
|
+
console.log = originalLog;
|
|
104
|
+
|
|
105
|
+
process.on('SIGINT', () => {
|
|
106
|
+
console.log(chalk.yellow('\nπ Stopping Local Node...'));
|
|
107
|
+
if (suiProcess) {
|
|
108
|
+
suiProcess.kill();
|
|
109
|
+
console.log(chalk.green('β
Local Node Stopped'));
|
|
110
|
+
}
|
|
111
|
+
process.exit();
|
|
112
|
+
});
|
|
113
|
+
} catch (error: any) {
|
|
114
|
+
console.error(chalk.red('\nβ Failed to Start Local Node'));
|
|
115
|
+
console.error(chalk.red(` ββ Error: ${error.message}`));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import * as fsAsync from 'fs/promises';
|
|
2
|
+
import { mkdirSync, writeFileSync } from 'fs';
|
|
3
|
+
import { exit } from 'process';
|
|
4
|
+
import { dirname } from 'path';
|
|
5
|
+
import { DeploymentJsonType, schema } from './utils';
|
|
6
|
+
import { DubheConfig } from '@0xobelisk/sui-common';
|
|
7
|
+
|
|
8
|
+
async function getDeploymentJson(
|
|
9
|
+
projectPath: string,
|
|
10
|
+
network: string
|
|
11
|
+
): Promise<DeploymentJsonType> {
|
|
12
|
+
try {
|
|
13
|
+
const data = await fsAsync.readFile(
|
|
14
|
+
`${projectPath}/.history/sui_${network}/latest.json`,
|
|
15
|
+
'utf8'
|
|
16
|
+
);
|
|
17
|
+
return JSON.parse(data) as DeploymentJsonType;
|
|
18
|
+
} catch (error) {
|
|
19
|
+
throw new Error(
|
|
20
|
+
`read .history/sui_${network}/latest.json failed. ${error}`
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function storeConfig(
|
|
26
|
+
network: string,
|
|
27
|
+
packageId: string,
|
|
28
|
+
schemas: schema[],
|
|
29
|
+
outputPath: string
|
|
30
|
+
) {
|
|
31
|
+
let code = `type NetworkType = 'testnet' | 'mainnet' | 'devnet' | 'localnet';
|
|
32
|
+
|
|
33
|
+
export const NETWORK: NetworkType = '${network}';
|
|
34
|
+
|
|
35
|
+
export const PACKAGE_ID = '${packageId}'
|
|
36
|
+
|
|
37
|
+
${schemas
|
|
38
|
+
.map(
|
|
39
|
+
schema =>
|
|
40
|
+
`export const ${schema.name.split('::')[2]}_Object_Id = '${
|
|
41
|
+
schema.objectId
|
|
42
|
+
}'`
|
|
43
|
+
)
|
|
44
|
+
.join('\n')}
|
|
45
|
+
`;
|
|
46
|
+
// if (outputPath) {
|
|
47
|
+
writeOutput(code, outputPath, 'storeConfig');
|
|
48
|
+
// writeOutput(code, `${path}/src/chain/config.ts`, 'storeConfig');
|
|
49
|
+
// }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function writeOutput(
|
|
53
|
+
output: string,
|
|
54
|
+
fullOutputPath: string,
|
|
55
|
+
logPrefix?: string
|
|
56
|
+
): Promise<void> {
|
|
57
|
+
mkdirSync(dirname(fullOutputPath), { recursive: true });
|
|
58
|
+
|
|
59
|
+
writeFileSync(fullOutputPath, output);
|
|
60
|
+
if (logPrefix !== undefined) {
|
|
61
|
+
console.log(`${logPrefix}: ${fullOutputPath}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export async function storeConfigHandler(
|
|
66
|
+
dubheConfig: DubheConfig,
|
|
67
|
+
network: 'mainnet' | 'testnet' | 'devnet' | 'localnet',
|
|
68
|
+
outputPath: string
|
|
69
|
+
) {
|
|
70
|
+
const path = process.cwd();
|
|
71
|
+
const contractPath = `${path}/contracts/${dubheConfig.name}`;
|
|
72
|
+
const deployment = await getDeploymentJson(contractPath, network);
|
|
73
|
+
storeConfig(
|
|
74
|
+
deployment.network,
|
|
75
|
+
deployment.packageId,
|
|
76
|
+
deployment.schemas,
|
|
77
|
+
outputPath
|
|
78
|
+
);
|
|
79
|
+
}
|
package/src/utils/utils.ts
CHANGED
|
@@ -3,7 +3,6 @@ import { mkdirSync, writeFileSync } from 'fs';
|
|
|
3
3
|
import { dirname } from 'path';
|
|
4
4
|
import { SUI_PRIVATE_KEY_PREFIX } from '@mysten/sui/cryptography';
|
|
5
5
|
import { FsIibError } from './errors';
|
|
6
|
-
export * from './localnode';
|
|
7
6
|
import * as fs from 'fs';
|
|
8
7
|
import chalk from 'chalk';
|
|
9
8
|
import { spawn } from 'child_process';
|
|
@@ -231,7 +230,6 @@ export async function switchEnv(network: 'mainnet' | 'testnet' | 'devnet' | 'loc
|
|
|
231
230
|
console.error(chalk.red(`\nβ Process exited with code: ${code}`));
|
|
232
231
|
reject(new Error(`Process exited with code: ${code}`));
|
|
233
232
|
} else {
|
|
234
|
-
console.log(chalk.green('\nβ
Environment switched successfully.'));
|
|
235
233
|
resolve(); // Resolve promise on successful exit
|
|
236
234
|
}
|
|
237
235
|
});
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { execSync, spawn } from 'child_process';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
|
|
4
|
-
function isSuiStartRunning(): boolean {
|
|
5
|
-
try {
|
|
6
|
-
const cmd =
|
|
7
|
-
process.platform === 'win32'
|
|
8
|
-
? `tasklist /FI "IMAGENAME eq sui.exe" /FO CSV /NH`
|
|
9
|
-
: 'pgrep -f "sui start"';
|
|
10
|
-
|
|
11
|
-
const result = execSync(cmd).toString().trim();
|
|
12
|
-
return process.platform === 'win32'
|
|
13
|
-
? result.toLowerCase().includes('sui.exe')
|
|
14
|
-
: result.length > 0;
|
|
15
|
-
} catch (error) {
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export async function startLocalnode(background: boolean = false) {
|
|
21
|
-
console.log('\nπ Checking Local Node Status...');
|
|
22
|
-
console.log(' ββ Scanning running processes');
|
|
23
|
-
|
|
24
|
-
if (isSuiStartRunning()) {
|
|
25
|
-
console.log(chalk.yellow('\nβ οΈ Warning: Local Node Already Running'));
|
|
26
|
-
console.log(chalk.yellow(' ββ Cannot start a new instance'));
|
|
27
|
-
console.log(
|
|
28
|
-
chalk.yellow(' ββ Please stop the existing process first')
|
|
29
|
-
);
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
console.log('\nπ Starting Local Node...');
|
|
34
|
-
console.log(' ββ Mode: ' + (background ? 'Background' : 'Foreground'));
|
|
35
|
-
console.log(' ββ Faucet: Enabled');
|
|
36
|
-
console.log(' ββ Force Regenesis: Yes');
|
|
37
|
-
|
|
38
|
-
try {
|
|
39
|
-
const suiProcess = spawn(
|
|
40
|
-
'sui',
|
|
41
|
-
['start', '--with-faucet', '--force-regenesis'],
|
|
42
|
-
{
|
|
43
|
-
env: { ...process.env, RUST_LOG: 'off,sui_node=info' },
|
|
44
|
-
stdio: background ? 'ignore' : 'inherit',
|
|
45
|
-
detached: background,
|
|
46
|
-
}
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
suiProcess.on('error', error => {
|
|
50
|
-
console.error(chalk.red('\nβ Failed to Start Local Node'));
|
|
51
|
-
console.error(chalk.red(` ββ Error: ${error.message}`));
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
if (!background) {
|
|
55
|
-
suiProcess.on('exit', code => {
|
|
56
|
-
if (code === 0) {
|
|
57
|
-
console.log(chalk.green('\nβ
Local Node Stopped'));
|
|
58
|
-
console.log(chalk.green(' ββ Exit Status: Normal'));
|
|
59
|
-
} else {
|
|
60
|
-
console.error(chalk.red('\nβ Local Node Crashed'));
|
|
61
|
-
console.error(chalk.red(` ββ Exit Code: ${code}`));
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
console.log(chalk.cyan('\nπ‘ Local Node Running'));
|
|
66
|
-
console.log(chalk.cyan(' ββ Press Ctrl+C to stop'));
|
|
67
|
-
|
|
68
|
-
await new Promise(() => {});
|
|
69
|
-
} else {
|
|
70
|
-
suiProcess.unref();
|
|
71
|
-
console.log(chalk.green('\nβ
Local Node Started in Background'));
|
|
72
|
-
|
|
73
|
-
if (process.platform === 'win32') {
|
|
74
|
-
console.log('\nπ‘ Helpful Commands:');
|
|
75
|
-
console.log(' ββ Check Process: tasklist | findstr sui.exe');
|
|
76
|
-
console.log(' ββ Stop Node: taskkill /PID <process_id> /F');
|
|
77
|
-
} else {
|
|
78
|
-
console.log('\nπ‘ Helpful Commands:');
|
|
79
|
-
console.log(" ββ Check Process: pgrep -f 'sui start'");
|
|
80
|
-
console.log(' ββ Stop Node: kill <process_id>');
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
} catch (error: any) {
|
|
84
|
-
console.error(chalk.red('\nβ Failed to Start Local Node'));
|
|
85
|
-
console.error(chalk.red(` ββ Error: ${error.message}`));
|
|
86
|
-
}
|
|
87
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { execSync } from 'child_process';
|
|
2
|
-
import chalk from 'chalk';
|
|
3
|
-
|
|
4
|
-
export async function checkLocalNodeStatus() {
|
|
5
|
-
console.log('\nπ Checking Local Node Status...');
|
|
6
|
-
|
|
7
|
-
try {
|
|
8
|
-
const cmd =
|
|
9
|
-
process.platform === 'win32'
|
|
10
|
-
? `tasklist /FI "IMAGENAME eq sui.exe" /FO CSV /NH`
|
|
11
|
-
: "ps aux | grep '[s]ui start --with-faucet --force-regenesis'";
|
|
12
|
-
|
|
13
|
-
const output = execSync(cmd, {
|
|
14
|
-
encoding: 'utf8',
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
const isRunning =
|
|
18
|
-
process.platform === 'win32'
|
|
19
|
-
? output.toLowerCase().includes('sui.exe')
|
|
20
|
-
: output.split('\n').filter(Boolean).length > 0;
|
|
21
|
-
|
|
22
|
-
if (isRunning) {
|
|
23
|
-
console.log(chalk.green('\nβ
Node Status: Running'));
|
|
24
|
-
console.log(chalk.gray('\nπ Process Details:'));
|
|
25
|
-
console.log(chalk.gray(` ββ ${output.trim()}`));
|
|
26
|
-
} else {
|
|
27
|
-
console.log(chalk.red('\nβ Node Status: Not Running'));
|
|
28
|
-
console.log(chalk.yellow('\nπ‘ Quick Start:'));
|
|
29
|
-
console.log(chalk.yellow(' ββ Run `dubhe localnode start`'));
|
|
30
|
-
}
|
|
31
|
-
} catch (error) {
|
|
32
|
-
console.log(chalk.red('\nβ Node Status: Not Running'));
|
|
33
|
-
console.log(chalk.yellow('\nπ‘ Quick Start:'));
|
|
34
|
-
console.log(chalk.yellow(' ββ Run `dubhe localnode start`'));
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// checkLocalNodeStatus();
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { execSync } from 'child_process';
|
|
2
|
-
|
|
3
|
-
export async function stopLocalnode() {
|
|
4
|
-
console.log('Stopping local node...');
|
|
5
|
-
|
|
6
|
-
try {
|
|
7
|
-
// Choose different commands based on the operating system
|
|
8
|
-
const cmd =
|
|
9
|
-
process.platform === 'win32'
|
|
10
|
-
? `tasklist /FI "IMAGENAME eq sui.exe" /FO CSV /NH`
|
|
11
|
-
: "ps aux | grep '[s]ui start --with-faucet --force-regenesis'";
|
|
12
|
-
|
|
13
|
-
const output = execSync(cmd, {
|
|
14
|
-
encoding: 'utf8',
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
if (!output) {
|
|
18
|
-
console.log('No running local node process found');
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// Parse process ID based on the operating system
|
|
23
|
-
let pid;
|
|
24
|
-
if (process.platform === 'win32') {
|
|
25
|
-
// Windows output format: "sui.exe","1234",... (CSV format)
|
|
26
|
-
const match = output.match(/"sui\.exe",["']?(\d+)/i);
|
|
27
|
-
pid = match ? match[1] : null;
|
|
28
|
-
} else {
|
|
29
|
-
// Unix system output format: user pid %cpu ...
|
|
30
|
-
pid = output.toString().split(/\s+/)[1];
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (!pid) {
|
|
34
|
-
console.log('No running local node process found');
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Choose the command to terminate the process based on the operating system
|
|
39
|
-
if (process.platform === 'win32') {
|
|
40
|
-
execSync(`taskkill /PID ${pid} /F`);
|
|
41
|
-
} else {
|
|
42
|
-
process.kill(Number(pid));
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
console.log('β
Local node stopped successfully');
|
|
46
|
-
} catch (error: any) {
|
|
47
|
-
if (
|
|
48
|
-
error.code === 'ESRCH' ||
|
|
49
|
-
error.message.includes('no running tasks')
|
|
50
|
-
) {
|
|
51
|
-
console.log('No running local node process found');
|
|
52
|
-
} else {
|
|
53
|
-
console.error('β Error stopping local node:', error.message);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// stopLocalnode();
|