@0xobelisk/sui-cli 1.2.0-pre.1 → 1.2.0-pre.100
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/dubhe.js +125 -66
- package/dist/dubhe.js.map +1 -1
- package/package.json +31 -19
- package/src/commands/build.ts +47 -16
- package/src/commands/call.ts +83 -83
- package/src/commands/checkBalance.ts +12 -5
- package/src/commands/configStore.ts +12 -4
- package/src/commands/convertJson.ts +70 -0
- package/src/commands/doctor.ts +1515 -0
- package/src/commands/faucet.ts +11 -7
- package/src/commands/generateKey.ts +3 -2
- package/src/commands/index.ts +16 -7
- package/src/commands/info.ts +55 -0
- package/src/commands/loadMetadata.ts +57 -0
- package/src/commands/localnode.ts +22 -12
- package/src/commands/publish.ts +21 -7
- package/src/commands/query.ts +101 -101
- package/src/commands/schemagen.ts +15 -4
- package/src/commands/shell.ts +198 -0
- package/src/commands/switchEnv.ts +26 -0
- package/src/commands/test.ts +54 -11
- package/src/commands/upgrade.ts +11 -4
- package/src/commands/wait.ts +333 -22
- package/src/commands/watch.ts +2 -1
- package/src/dubhe.ts +12 -4
- package/src/utils/axios-downloader.ts +116 -0
- package/src/utils/callHandler.ts +118 -118
- package/src/utils/constants.ts +5 -0
- package/src/utils/generateAccount.ts +1 -1
- package/src/utils/index.ts +4 -3
- package/src/utils/metadataHandler.ts +16 -0
- package/src/utils/publishHandler.ts +295 -290
- package/src/utils/queryStorage.ts +141 -141
- package/src/utils/startNode.ts +165 -108
- package/src/utils/storeConfig.ts +6 -12
- package/src/utils/upgradeHandler.ts +147 -86
- package/src/utils/utils.ts +771 -54
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import readline from 'readline';
|
|
2
|
+
|
|
3
|
+
import yargs, { CommandModule } from 'yargs';
|
|
4
|
+
import { commands } from '.';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { getDefaultNetwork, printDubhe } from '../utils';
|
|
7
|
+
import dotenv from 'dotenv';
|
|
8
|
+
import { spawn } from 'child_process';
|
|
9
|
+
|
|
10
|
+
dotenv.config();
|
|
11
|
+
|
|
12
|
+
let shouldHandlerExit = true;
|
|
13
|
+
|
|
14
|
+
// Blacklist of commands not available inside shell
|
|
15
|
+
const SHELL_BLACKLIST_COMMANDS = ['shell', 'wait'];
|
|
16
|
+
|
|
17
|
+
export const handlerExit = (status: number = 0) => {
|
|
18
|
+
if (shouldHandlerExit) process.exit(status);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
type Options = {
|
|
22
|
+
network: any;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const parseCommandNames = () => {
|
|
26
|
+
return commands
|
|
27
|
+
.filter((command) => !SHELL_BLACKLIST_COMMANDS.includes(command.command as string))
|
|
28
|
+
.map((command) => command.command);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const ShellCommand: CommandModule<Options, Options> = {
|
|
32
|
+
command: 'shell',
|
|
33
|
+
describe: 'Open a shell to interact with the Dubhe System',
|
|
34
|
+
builder(yargs) {
|
|
35
|
+
return yargs.options({
|
|
36
|
+
network: {
|
|
37
|
+
type: 'string',
|
|
38
|
+
choices: ['mainnet', 'testnet', 'devnet', 'localnet', 'default'],
|
|
39
|
+
default: 'default',
|
|
40
|
+
desc: 'Node network (mainnet/testnet/devnet/localnet)'
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
},
|
|
44
|
+
handler: async ({ network }) => {
|
|
45
|
+
if (network == 'default') {
|
|
46
|
+
network = await getDefaultNetwork();
|
|
47
|
+
console.log(chalk.yellow(`Use default network: [${network}]`));
|
|
48
|
+
}
|
|
49
|
+
shouldHandlerExit = false;
|
|
50
|
+
const commandHistory: string[] = [];
|
|
51
|
+
|
|
52
|
+
function completer(line: string) {
|
|
53
|
+
const hits = parseCommandNames().filter((c) => {
|
|
54
|
+
if (!c) return false;
|
|
55
|
+
return (c as string).startsWith(line.toLowerCase());
|
|
56
|
+
});
|
|
57
|
+
return [hits.length ? hits : parseCommandNames(), line];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const rl = readline.createInterface({
|
|
61
|
+
input: process.stdin,
|
|
62
|
+
output: process.stdout,
|
|
63
|
+
prompt: `dubhe(${chalk.green(network)}) ${chalk.bold('>')} `,
|
|
64
|
+
completer: completer,
|
|
65
|
+
historySize: 200
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
rl.on('line', async (line) => {
|
|
69
|
+
const fullCommand = line.trim();
|
|
70
|
+
if (!fullCommand) {
|
|
71
|
+
rl.prompt();
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Add command to history
|
|
76
|
+
commandHistory.push(fullCommand);
|
|
77
|
+
|
|
78
|
+
const parts = fullCommand.split(/\s+/);
|
|
79
|
+
const commandName = parts[0].toLowerCase();
|
|
80
|
+
|
|
81
|
+
const command = commands.find(
|
|
82
|
+
(c) => c.command === commandName && !SHELL_BLACKLIST_COMMANDS.includes(commandName)
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
// Check if user is asking for help
|
|
86
|
+
if (parts.includes('--help') || parts.includes('-h')) {
|
|
87
|
+
if (command) {
|
|
88
|
+
try {
|
|
89
|
+
// Use spawn to call dubhe help externally to avoid validation issues
|
|
90
|
+
const dubheProcess = spawn('node', [process.argv[1], commandName, '--help'], {
|
|
91
|
+
stdio: 'inherit',
|
|
92
|
+
env: { ...process.env }
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
dubheProcess.on('exit', () => {
|
|
96
|
+
rl.prompt();
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
dubheProcess.on('error', () => {
|
|
100
|
+
// Fallback: show basic help information
|
|
101
|
+
console.log(`\n${command.describe || `${commandName} command`}`);
|
|
102
|
+
console.log(`\nUsage: ${commandName} [options]`);
|
|
103
|
+
console.log('\nFor complete help with all options, please exit shell and run:');
|
|
104
|
+
console.log(chalk.cyan(` dubhe ${commandName} --help`));
|
|
105
|
+
rl.prompt();
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
return; // Don't call rl.prompt() here as it's handled in the callbacks
|
|
109
|
+
} catch {
|
|
110
|
+
// Fallback: show basic help information
|
|
111
|
+
console.log(`\n${command.describe || `${commandName} command`}`);
|
|
112
|
+
console.log(`\nUsage: ${commandName} [options]`);
|
|
113
|
+
console.log('\nFor complete help with all options, please exit shell and run:');
|
|
114
|
+
console.log(chalk.cyan(` dubhe ${commandName} --help`));
|
|
115
|
+
}
|
|
116
|
+
} else {
|
|
117
|
+
console.log(
|
|
118
|
+
`🤷 Unknown command: "${commandName}". Type 'help' to see available commands.`
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
rl.prompt();
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (command) {
|
|
126
|
+
try {
|
|
127
|
+
const { builder, handler } = command;
|
|
128
|
+
const yargsInstance = yargs().exitProcess(false);
|
|
129
|
+
if (builder) {
|
|
130
|
+
if (typeof builder === 'function') {
|
|
131
|
+
builder(yargsInstance);
|
|
132
|
+
} else {
|
|
133
|
+
yargsInstance.options(builder);
|
|
134
|
+
}
|
|
135
|
+
const argv = yargsInstance.parseSync([
|
|
136
|
+
commandName,
|
|
137
|
+
'--network',
|
|
138
|
+
network,
|
|
139
|
+
...parts.slice(1)
|
|
140
|
+
]);
|
|
141
|
+
if (handler) {
|
|
142
|
+
await handler(argv);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
} catch (error) {
|
|
146
|
+
console.log(chalk.red(error));
|
|
147
|
+
}
|
|
148
|
+
} else if (commandName == 'help') {
|
|
149
|
+
console.log('Available dubhe commands:');
|
|
150
|
+
|
|
151
|
+
// Find the longest command name for alignment (excluding blacklisted commands)
|
|
152
|
+
const availableCommands = commands.filter(
|
|
153
|
+
(c) => !SHELL_BLACKLIST_COMMANDS.includes(c.command as string)
|
|
154
|
+
);
|
|
155
|
+
const maxCommandLength = Math.max(
|
|
156
|
+
...availableCommands.map((c) => {
|
|
157
|
+
const command =
|
|
158
|
+
typeof c.command === 'string'
|
|
159
|
+
? c.command
|
|
160
|
+
: Array.isArray(c.command)
|
|
161
|
+
? c.command[0]
|
|
162
|
+
: '';
|
|
163
|
+
return command.length;
|
|
164
|
+
})
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
availableCommands.forEach((c) => {
|
|
168
|
+
const command =
|
|
169
|
+
typeof c.command === 'string'
|
|
170
|
+
? c.command
|
|
171
|
+
: Array.isArray(c.command)
|
|
172
|
+
? c.command[0]
|
|
173
|
+
: '';
|
|
174
|
+
const paddedCommand = command.padEnd(maxCommandLength);
|
|
175
|
+
console.log(` ${chalk.green(paddedCommand)} ${c.describe}`);
|
|
176
|
+
});
|
|
177
|
+
rl.prompt();
|
|
178
|
+
return;
|
|
179
|
+
} else if (['exit', 'quit'].indexOf(commandName) !== -1) {
|
|
180
|
+
console.log('Goodbye You will have a nice day! 👋');
|
|
181
|
+
rl.close();
|
|
182
|
+
return;
|
|
183
|
+
} else {
|
|
184
|
+
console.log(`🤷 Unknown command: "${fullCommand}". Type 'help' to see available commands.`);
|
|
185
|
+
}
|
|
186
|
+
rl.prompt();
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
rl.on('close', () => {
|
|
190
|
+
process.exit(0);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
printDubhe();
|
|
194
|
+
rl.prompt();
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
export default ShellCommand;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { CommandModule, ArgumentsCamelCase } from 'yargs';
|
|
2
|
+
import { switchEnv } from '../utils';
|
|
3
|
+
import { handlerExit } from './shell';
|
|
4
|
+
|
|
5
|
+
type Options = {
|
|
6
|
+
network: 'mainnet' | 'testnet' | 'devnet' | 'localnet' | 'default';
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const commandModule: CommandModule<Options, Options> = {
|
|
10
|
+
command: 'switch-env',
|
|
11
|
+
describe: 'Switch environment',
|
|
12
|
+
builder(yargs) {
|
|
13
|
+
return yargs.option('network', {
|
|
14
|
+
type: 'string',
|
|
15
|
+
choices: ['mainnet', 'testnet', 'devnet', 'localnet'] as const,
|
|
16
|
+
default: 'localnet',
|
|
17
|
+
desc: 'Switch to node network (mainnet/testnet/devnet/localnet)'
|
|
18
|
+
}) as any;
|
|
19
|
+
},
|
|
20
|
+
async handler(argv: ArgumentsCamelCase<Options>) {
|
|
21
|
+
await switchEnv(argv.network as 'mainnet' | 'testnet' | 'devnet' | 'localnet');
|
|
22
|
+
handlerExit();
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export default commandModule;
|
package/src/commands/test.ts
CHANGED
|
@@ -1,6 +1,19 @@
|
|
|
1
1
|
import type { CommandModule } from 'yargs';
|
|
2
2
|
import { execSync } from 'child_process';
|
|
3
3
|
import { DubheConfig, loadConfig } from '@0xobelisk/sui-common';
|
|
4
|
+
import { handlerExit } from './shell';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Returns the active Sui client environment (e.g. "localnet", "testnet").
|
|
8
|
+
* Falls back to "testnet" if the command fails.
|
|
9
|
+
*/
|
|
10
|
+
function getActiveSuiEnv(): string {
|
|
11
|
+
try {
|
|
12
|
+
return execSync('sui client active-env', { encoding: 'utf-8', stdio: 'pipe' }).trim();
|
|
13
|
+
} catch {
|
|
14
|
+
return 'testnet';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
4
17
|
|
|
5
18
|
type Options = {
|
|
6
19
|
'config-path': string;
|
|
@@ -8,21 +21,45 @@ type Options = {
|
|
|
8
21
|
'gas-limit'?: string;
|
|
9
22
|
};
|
|
10
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Core Move test runner for Dubhe contracts.
|
|
26
|
+
* Runs `sui move test` against the package at `src/<dubheConfig.name>`.
|
|
27
|
+
*
|
|
28
|
+
* Move unit tests compile packages locally — no network or published address required.
|
|
29
|
+
*/
|
|
30
|
+
export async function testHandler(
|
|
31
|
+
dubheConfig: DubheConfig,
|
|
32
|
+
test?: string,
|
|
33
|
+
gasLimit: string = '100000000',
|
|
34
|
+
buildEnv?: string
|
|
35
|
+
): Promise<string> {
|
|
36
|
+
const cwd = process.cwd();
|
|
37
|
+
const projectPath = `${cwd}/src/${dubheConfig.name}`;
|
|
38
|
+
// --build-env overrides the active Sui client environment for dependency resolution.
|
|
39
|
+
// Required for localnet (which is not in Move.toml [environments]) when the
|
|
40
|
+
// active client env has been set to localnet from a previous run.
|
|
41
|
+
const buildEnvFlag = buildEnv ? `--build-env ${buildEnv}` : '';
|
|
42
|
+
const command = `sui move test ${buildEnvFlag} --path ${projectPath} ${
|
|
43
|
+
test ? `--test ${test}` : ''
|
|
44
|
+
} --gas-limit ${gasLimit}`;
|
|
45
|
+
return execSync(command, { stdio: 'pipe', encoding: 'utf-8' });
|
|
46
|
+
}
|
|
47
|
+
|
|
11
48
|
const commandModule: CommandModule<Options, Options> = {
|
|
12
49
|
command: 'test',
|
|
13
50
|
|
|
14
|
-
describe: 'Run tests in Dubhe contracts',
|
|
51
|
+
describe: 'Run Move unit tests in Dubhe contracts',
|
|
15
52
|
|
|
16
53
|
builder(yargs) {
|
|
17
54
|
return yargs.options({
|
|
18
55
|
'config-path': {
|
|
19
56
|
type: 'string',
|
|
20
57
|
default: 'dubhe.config.ts',
|
|
21
|
-
description: '
|
|
58
|
+
description: 'Path to the Dubhe config file'
|
|
22
59
|
},
|
|
23
60
|
test: {
|
|
24
61
|
type: 'string',
|
|
25
|
-
desc: 'Run a specific test'
|
|
62
|
+
desc: 'Run a specific test by name'
|
|
26
63
|
},
|
|
27
64
|
'gas-limit': {
|
|
28
65
|
type: 'string',
|
|
@@ -33,19 +70,25 @@ const commandModule: CommandModule<Options, Options> = {
|
|
|
33
70
|
},
|
|
34
71
|
|
|
35
72
|
async handler({ 'config-path': configPath, test, 'gas-limit': gasLimit }) {
|
|
36
|
-
// Start an internal anvil process if no world address is provided
|
|
37
73
|
try {
|
|
38
74
|
console.log('🚀 Running move test');
|
|
39
75
|
const dubheConfig = (await loadConfig(configPath)) as DubheConfig;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
76
|
+
|
|
77
|
+
// Ephemeral networks (localnet/devnet) are not defined in Move.toml [environments].
|
|
78
|
+
// Use --build-env testnet for dependency resolution so `sui move test` can resolve
|
|
79
|
+
// git dependencies without requiring a localnet env entry.
|
|
80
|
+
const activeEnv = getActiveSuiEnv();
|
|
81
|
+
const buildEnv = activeEnv === 'localnet' || activeEnv === 'devnet' ? 'testnet' : undefined;
|
|
82
|
+
|
|
83
|
+
const output = await testHandler(dubheConfig, test, gasLimit, buildEnv);
|
|
84
|
+
if (output) process.stdout.write(output);
|
|
46
85
|
} catch (error: any) {
|
|
47
|
-
process.
|
|
86
|
+
if (error.stdout) process.stdout.write(error.stdout);
|
|
87
|
+
if (error.stderr) process.stderr.write(error.stderr);
|
|
88
|
+
if (!error.stdout && !error.stderr && error.message) process.stderr.write(error.message);
|
|
89
|
+
handlerExit(1);
|
|
48
90
|
}
|
|
91
|
+
handlerExit();
|
|
49
92
|
}
|
|
50
93
|
};
|
|
51
94
|
|
package/src/commands/upgrade.ts
CHANGED
|
@@ -2,6 +2,9 @@ import type { CommandModule } from 'yargs';
|
|
|
2
2
|
import { logError } from '../utils/errors';
|
|
3
3
|
import { upgradeHandler } from '../utils/upgradeHandler';
|
|
4
4
|
import { DubheConfig, loadConfig } from '@0xobelisk/sui-common';
|
|
5
|
+
import { handlerExit } from './shell';
|
|
6
|
+
import { getDefaultNetwork } from '../utils';
|
|
7
|
+
import chalk from 'chalk';
|
|
5
8
|
|
|
6
9
|
type Options = {
|
|
7
10
|
network: any;
|
|
@@ -17,8 +20,8 @@ const commandModule: CommandModule<Options, Options> = {
|
|
|
17
20
|
return yargs.options({
|
|
18
21
|
network: {
|
|
19
22
|
type: 'string',
|
|
20
|
-
choices: ['mainnet', 'testnet', 'devnet', 'localnet'],
|
|
21
|
-
default: '
|
|
23
|
+
choices: ['mainnet', 'testnet', 'devnet', 'localnet', 'default'],
|
|
24
|
+
default: 'default',
|
|
22
25
|
desc: 'Network of the node (mainnet/testnet/devnet/localnet)'
|
|
23
26
|
},
|
|
24
27
|
'config-path': {
|
|
@@ -31,13 +34,17 @@ const commandModule: CommandModule<Options, Options> = {
|
|
|
31
34
|
|
|
32
35
|
async handler({ network, 'config-path': configPath }) {
|
|
33
36
|
try {
|
|
37
|
+
if (network == 'default') {
|
|
38
|
+
network = await getDefaultNetwork();
|
|
39
|
+
console.log(chalk.yellow(`Use default network: [${network}]`));
|
|
40
|
+
}
|
|
34
41
|
const dubheConfig = (await loadConfig(configPath)) as DubheConfig;
|
|
35
42
|
await upgradeHandler(dubheConfig, dubheConfig.name, network);
|
|
36
43
|
} catch (error: any) {
|
|
37
44
|
logError(error);
|
|
38
|
-
|
|
45
|
+
handlerExit(1);
|
|
39
46
|
}
|
|
40
|
-
|
|
47
|
+
handlerExit();
|
|
41
48
|
}
|
|
42
49
|
};
|
|
43
50
|
|