@0xobelisk/sui-cli 1.2.0-pre.12 → 1.2.0-pre.120

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.
Files changed (40) hide show
  1. package/README.md +7 -7
  2. package/dist/dubhe.js +152 -51
  3. package/dist/dubhe.js.map +1 -1
  4. package/package.json +31 -19
  5. package/src/commands/build.ts +61 -18
  6. package/src/commands/call.ts +83 -83
  7. package/src/commands/checkBalance.ts +27 -12
  8. package/src/commands/convertJson.ts +84 -0
  9. package/src/commands/doctor.ts +1515 -0
  10. package/src/commands/faucet.ts +20 -10
  11. package/src/commands/generate.ts +61 -0
  12. package/src/commands/generateKey.ts +3 -2
  13. package/src/commands/index.ts +20 -11
  14. package/src/commands/info.ts +61 -0
  15. package/src/commands/loadMetadata.ts +68 -0
  16. package/src/commands/localnode.ts +22 -6
  17. package/src/commands/publish.ts +55 -7
  18. package/src/commands/query.ts +101 -101
  19. package/src/commands/shell.ts +208 -0
  20. package/src/commands/{configStore.ts → storeConfig.ts} +13 -5
  21. package/src/commands/switchEnv.ts +33 -0
  22. package/src/commands/test.ts +143 -31
  23. package/src/commands/upgrade.ts +46 -6
  24. package/src/commands/wait.ts +333 -22
  25. package/src/commands/watch.ts +9 -8
  26. package/src/dubhe.ts +12 -4
  27. package/src/utils/axios-downloader.ts +116 -0
  28. package/src/utils/callHandler.ts +118 -118
  29. package/src/utils/checkBalance.ts +6 -2
  30. package/src/utils/constants.ts +9 -0
  31. package/src/utils/generateAccount.ts +1 -1
  32. package/src/utils/index.ts +4 -3
  33. package/src/utils/metadataHandler.ts +17 -0
  34. package/src/utils/publishHandler.ts +404 -289
  35. package/src/utils/queryStorage.ts +141 -141
  36. package/src/utils/startNode.ts +115 -16
  37. package/src/utils/storeConfig.ts +50 -10
  38. package/src/utils/upgradeHandler.ts +210 -86
  39. package/src/utils/utils.ts +1025 -63
  40. package/src/commands/schemagen.ts +0 -40
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xobelisk/sui-cli",
3
- "version": "1.2.0-pre.12",
3
+ "version": "1.2.0-pre.120",
4
4
  "description": "Tookit for interacting with move eps framework",
5
5
  "keywords": [
6
6
  "sui",
@@ -8,8 +8,6 @@
8
8
  "move",
9
9
  "blockchain"
10
10
  ],
11
- "type": "module",
12
- "author": "team@obelisk.build",
13
11
  "homepage": "https://github.com/0xobelisk/dubhe/tree/main/packages/sui-cli#readme",
14
12
  "bugs": "https://github.com/0xobelisk/dubhe/issues",
15
13
  "repository": {
@@ -17,12 +15,8 @@
17
15
  "url": "https://github.com/0xobelisk/dubhe.git"
18
16
  },
19
17
  "license": "Apache-2.0",
20
- "publishConfig": {
21
- "access": "public"
22
- },
23
- "engines": {
24
- "node": ">=18"
25
- },
18
+ "author": "team@obelisk.build",
19
+ "type": "module",
26
20
  "exports": {
27
21
  ".": "./dist/index.js"
28
22
  },
@@ -31,34 +25,39 @@
31
25
  "dubhe": "./dist/dubhe.js"
32
26
  },
33
27
  "dependencies": {
34
- "@mysten/sui": "^1.19.0",
35
- "@types/sqlite3": "^3.1.11",
28
+ "@mysten/sui": "1.35.0",
36
29
  "@types/wait-on": "^5.3.4",
30
+ "axios": "^1.12.0",
37
31
  "chalk": "^5.0.1",
38
32
  "child_process": "^1.0.2",
39
33
  "chokidar": "^3.5.3",
34
+ "cli-progress": "^3.12.0",
35
+ "cli-table3": "^0.6.5",
40
36
  "dotenv": "^16.0.3",
41
37
  "ejs": "^3.1.8",
42
38
  "execa": "^7.0.0",
43
39
  "glob": "^8.0.3",
40
+ "http-proxy-agent": "^7.0.2",
41
+ "https-proxy-agent": "^7.0.6",
42
+ "inquirer": "^9.2.15",
44
43
  "ora": "^5.4.1",
45
44
  "path": "^0.12.7",
46
- "sqlite": "^5.1.1",
47
- "sqlite3": "^5.1.7",
48
- "typescript": "5.1.6",
45
+ "typescript": "^5.8.3",
49
46
  "wait-on": "^7.0.1",
50
47
  "yargs": "^17.7.1",
51
48
  "zod": "^3.22.3",
52
49
  "zod-validation-error": "^1.3.0",
53
- "@0xobelisk/sui-client": "1.2.0-pre.12",
54
- "@0xobelisk/sui-common": "1.2.0-pre.12"
50
+ "@0xobelisk/sui-client": "1.2.0-pre.120",
51
+ "@0xobelisk/sui-common": "1.2.0-pre.120"
55
52
  },
56
53
  "devDependencies": {
54
+ "@types/cli-progress": "^3.11.5",
57
55
  "@types/ejs": "^3.1.1",
58
56
  "@types/glob": "^7.2.0",
59
- "@types/node": "^18.15.11",
57
+ "@types/inquirer": "^9.0.7",
58
+ "@types/node": "^22.16.0",
60
59
  "@types/yargs": "^17.0.10",
61
- "eslint": "^8.56.0",
60
+ "eslint": "^9.0.0",
62
61
  "eslint-config-prettier": "^9.1.0",
63
62
  "prettier": "3.3.3",
64
63
  "ts-node": "^10.9.1",
@@ -66,15 +65,28 @@
66
65
  "tsx": "^3.12.6",
67
66
  "vitest": "0.31.4"
68
67
  },
68
+ "engines": {
69
+ "node": ">=22.0.0"
70
+ },
71
+ "publishConfig": {
72
+ "access": "public"
73
+ },
69
74
  "scripts": {
70
75
  "build": "pnpm run type-check && pnpm run build:js",
71
76
  "build:js": "tsup && chmod +x ./dist/dubhe.js",
72
77
  "clean": "pnpm run clean:js",
73
78
  "clean:js": "rimraf dist",
74
79
  "dev": "tsup --watch",
75
- "lint": "eslint . --ext .ts",
76
80
  "format": "prettier --write .",
77
81
  "format:check": "prettier --check .",
82
+ "lint": "eslint . --ext .ts",
83
+ "test": "vitest run",
84
+ "test:all": "pnpm test && pnpm test:integration",
85
+ "test:coverage": "vitest run --coverage",
86
+ "test:integration": "vitest run --config vitest.integration.config.ts",
87
+ "test:localnet": "vitest run --config vitest.integration.config.ts tests/integration/localnet.test.ts",
88
+ "test:testnet": "vitest run --config vitest.integration.config.ts tests/integration/testnet.test.ts",
89
+ "test:watch": "vitest",
78
90
  "type-check": "tsc --noEmit",
79
91
  "validate": "pnpm format:check && pnpm type-check"
80
92
  }
@@ -1,35 +1,71 @@
1
1
  import type { CommandModule } from 'yargs';
2
- import { execSync } from 'child_process';
2
+ import { execSync, exec } from 'child_process';
3
+ import nodePath from 'path';
3
4
  import chalk from 'chalk';
4
5
  import { DubheConfig, loadConfig } from '@0xobelisk/sui-common';
5
- import { switchEnv, updateDubheDependency } from '../utils';
6
+ import { handlerExit } from './shell';
7
+ import { getDefaultNetwork, switchEnv, lintSystemGuards, formatLintWarnings } from '../utils';
6
8
 
7
9
  type Options = {
8
10
  'config-path': string;
9
11
  network: any;
10
12
  'dump-bytecode-as-base64'?: boolean;
13
+ 'rpc-url'?: string;
11
14
  };
12
15
 
16
+ /**
17
+ * Core build logic for Dubhe contracts.
18
+ *
19
+ * - localnet: uses --build-env testnet + --pubfile-path Pub.localnet.toml so that
20
+ * dependency addresses are resolved through the ephemeral publication file created
21
+ * by publishHandler. Counter can only be built after dubhe is published on localnet.
22
+ * - Other networks: uses -e <network> (standard Sui CLI environment flag).
23
+ */
24
+ export async function buildHandler(
25
+ dubheConfig: DubheConfig,
26
+ network: 'mainnet' | 'testnet' | 'devnet' | 'localnet',
27
+ dumpBytecodeAsBase64: boolean = false
28
+ ): Promise<string> {
29
+ const cwd = process.cwd();
30
+ const projectPath = nodePath.join(cwd, 'src', dubheConfig.name);
31
+
32
+ let command: string;
33
+ if (network === 'localnet') {
34
+ const pubfilePath = nodePath.join(cwd, 'Pub.localnet.toml');
35
+ command = `sui move build --build-env testnet --pubfile-path ${pubfilePath} --path ${projectPath}`;
36
+ } else {
37
+ command = `sui move build -e ${network} --path ${projectPath}`;
38
+ }
39
+
40
+ if (dumpBytecodeAsBase64) command += ' --dump-bytecode-as-base64';
41
+
42
+ return execSync(command, { encoding: 'utf-8' });
43
+ }
44
+
13
45
  const commandModule: CommandModule<Options, Options> = {
14
46
  command: 'build',
15
- describe: 'Run tests in Dubhe contracts',
47
+ describe: 'Build Dubhe contracts',
16
48
  builder(yargs) {
17
49
  return yargs.options({
18
50
  'config-path': {
19
51
  type: 'string',
20
52
  default: 'dubhe.config.ts',
21
- description: 'Options to pass to forge test'
53
+ description: 'Path to the Dubhe config file'
22
54
  },
23
55
  network: {
24
56
  type: 'string',
25
- default: 'localnet',
26
- choices: ['mainnet', 'testnet', 'devnet', 'localnet'],
57
+ default: 'default',
58
+ choices: ['mainnet', 'testnet', 'devnet', 'localnet', 'default'],
27
59
  desc: 'Node network (mainnet/testnet/devnet/localnet)'
28
60
  },
29
61
  'dump-bytecode-as-base64': {
30
62
  type: 'boolean',
31
63
  default: false,
32
64
  desc: 'Dump bytecode as base64'
65
+ },
66
+ 'rpc-url': {
67
+ type: 'string',
68
+ desc: 'Custom RPC endpoint URL (overrides the default for the selected network)'
33
69
  }
34
70
  });
35
71
  },
@@ -37,25 +73,32 @@ const commandModule: CommandModule<Options, Options> = {
37
73
  async handler({
38
74
  'config-path': configPath,
39
75
  network,
40
- 'dump-bytecode-as-base64': dumpBytecodeAsBase64
76
+ 'dump-bytecode-as-base64': dumpBytecodeAsBase64,
77
+ 'rpc-url': rpcUrl
41
78
  }) {
42
- // Start an internal anvil process if no world address is provided
43
79
  try {
80
+ if (network == 'default') {
81
+ network = await getDefaultNetwork();
82
+ console.log(chalk.yellow(`Use default network: [${network}]`));
83
+ }
44
84
  console.log('🚀 Running move build');
45
85
  const dubheConfig = (await loadConfig(configPath)) as DubheConfig;
46
- const path = process.cwd();
47
- const projectPath = `${path}/src/${dubheConfig.name}`;
48
- await switchEnv(network);
49
- await updateDubheDependency(projectPath + '/Move.toml', network);
50
- const command = `sui move build --path ${projectPath} ${
51
- dumpBytecodeAsBase64 ? ` --dump-bytecode-as-base64` : ''
52
- }`;
53
- const output = execSync(command, { encoding: 'utf-8' });
86
+ await switchEnv(network, rpcUrl);
87
+
88
+ const projectPath = nodePath.join(process.cwd(), 'src', dubheConfig.name);
89
+ const lintResults = lintSystemGuards(projectPath);
90
+ const warnings = formatLintWarnings(lintResults);
91
+ if (warnings) process.stdout.write(warnings);
92
+
93
+ const output = await buildHandler(dubheConfig, network, dumpBytecodeAsBase64);
54
94
  console.log(output);
95
+ exec(`pnpm dubhe convert-json --config-path ${configPath}`);
55
96
  } catch (error: any) {
56
97
  console.error(chalk.red('Error executing sui move build:'));
57
- console.log(error.stdout);
58
- process.exit(0);
98
+ if (error.stdout) process.stdout.write(error.stdout);
99
+ if (error.stderr) process.stderr.write(error.stderr);
100
+ if (!error.stdout && !error.stderr && error.message) process.stderr.write(error.message);
101
+ handlerExit(1);
59
102
  }
60
103
  }
61
104
  };
@@ -1,90 +1,90 @@
1
- import type { CommandModule } from 'yargs';
2
- import { logError } from '../utils/errors';
3
- import { callHandler } from '../utils';
4
- import { loadConfig, DubheConfig } from '@0xobelisk/sui-common';
1
+ // import type { CommandModule } from 'yargs';
2
+ // import { logError } from '../utils/errors';
3
+ // import { callHandler } from '../utils';
4
+ // import { loadConfig, DubheConfig } from '@0xobelisk/sui-common';
5
5
 
6
- type Options = {
7
- network: 'mainnet' | 'testnet' | 'devnet' | 'localnet';
8
- module: string;
9
- function: string;
10
- 'config-path'?: string;
11
- 'package-id'?: string;
12
- 'metadata-path'?: string;
13
- params?: any[];
14
- };
6
+ // type Options = {
7
+ // network: 'mainnet' | 'testnet' | 'devnet' | 'localnet';
8
+ // module: string;
9
+ // function: string;
10
+ // 'config-path'?: string;
11
+ // 'package-id'?: string;
12
+ // 'metadata-path'?: string;
13
+ // params?: any[];
14
+ // };
15
15
 
16
- /**
17
- * CLI command for calling a function in a module
18
- */
19
- const commandModule: CommandModule<Options, Options> = {
20
- command: 'call',
16
+ // /**
17
+ // * CLI command for calling a function in a module
18
+ // */
19
+ // const commandModule: CommandModule<Options, Options> = {
20
+ // command: 'call',
21
21
 
22
- describe: 'Call a function in a module',
22
+ // describe: 'Call a function in a module',
23
23
 
24
- builder: {
25
- network: {
26
- type: 'string',
27
- choices: ['mainnet', 'testnet', 'devnet', 'localnet'],
28
- desc: 'Node network (mainnet/testnet/devnet/localnet)',
29
- default: 'localnet'
30
- },
31
- module: {
32
- type: 'string',
33
- desc: 'Module name',
34
- demandOption: true
35
- },
36
- function: {
37
- type: 'string',
38
- desc: 'Function name',
39
- demandOption: true
40
- },
41
- 'config-path': {
42
- type: 'string',
43
- default: 'dubhe.config.ts',
44
- desc: 'Configuration file path'
45
- },
46
- 'package-id': {
47
- type: 'string',
48
- desc: 'Package ID (optional)'
49
- },
50
- 'metadata-path': {
51
- type: 'string',
52
- desc: 'Path to metadata JSON file (optional)'
53
- },
54
- params: {
55
- type: 'array',
56
- desc: 'Params for the function',
57
- string: true
58
- }
59
- },
24
+ // builder: {
25
+ // network: {
26
+ // type: 'string',
27
+ // choices: ['mainnet', 'testnet', 'devnet', 'localnet'],
28
+ // desc: 'Node network (mainnet/testnet/devnet/localnet)',
29
+ // default: 'localnet'
30
+ // },
31
+ // module: {
32
+ // type: 'string',
33
+ // desc: 'Module name',
34
+ // demandOption: true
35
+ // },
36
+ // function: {
37
+ // type: 'string',
38
+ // desc: 'Function name',
39
+ // demandOption: true
40
+ // },
41
+ // 'config-path': {
42
+ // type: 'string',
43
+ // default: 'dubhe.config.ts',
44
+ // desc: 'Configuration file path'
45
+ // },
46
+ // 'package-id': {
47
+ // type: 'string',
48
+ // desc: 'Package ID (optional)'
49
+ // },
50
+ // 'metadata-path': {
51
+ // type: 'string',
52
+ // desc: 'Path to metadata JSON file (optional)'
53
+ // },
54
+ // params: {
55
+ // type: 'array',
56
+ // desc: 'Params for the function',
57
+ // string: true
58
+ // }
59
+ // },
60
60
 
61
- async handler({
62
- network,
63
- 'config-path': configPath,
64
- module: moduleName,
65
- function: funcName,
66
- 'package-id': packageId,
67
- 'metadata-path': metadataPath,
68
- params
69
- }) {
70
- try {
71
- const dubheConfig = (await loadConfig(configPath)) as DubheConfig;
61
+ // async handler({
62
+ // network,
63
+ // 'config-path': configPath,
64
+ // module: moduleName,
65
+ // function: funcName,
66
+ // 'package-id': packageId,
67
+ // 'metadata-path': metadataPath,
68
+ // params
69
+ // }) {
70
+ // try {
71
+ // const dubheConfig = (await loadConfig(configPath)) as DubheConfig;
72
72
 
73
- await callHandler({
74
- dubheConfig,
75
- moduleName,
76
- funcName,
77
- network,
78
- packageId,
79
- metadataFilePath: metadataPath,
80
- params
81
- });
82
- } catch (error: any) {
83
- logError(error);
84
- process.exit(1);
85
- }
86
- process.exit(0);
87
- }
88
- };
73
+ // await callHandler({
74
+ // dubheConfig,
75
+ // moduleName,
76
+ // funcName,
77
+ // network,
78
+ // packageId,
79
+ // metadataFilePath: metadataPath,
80
+ // params
81
+ // });
82
+ // } catch (error: any) {
83
+ // logError(error);
84
+ // process.exit(1);
85
+ // }
86
+ // process.exit(0);
87
+ // }
88
+ // };
89
89
 
90
- export default commandModule;
90
+ // export default commandModule;
@@ -1,29 +1,44 @@
1
1
  import type { CommandModule } from 'yargs';
2
2
  import { checkBalanceHandler } from '../utils/checkBalance';
3
+ import { handlerExit } from './shell';
4
+ import chalk from 'chalk';
5
+ import { getDefaultNetwork } from '../utils';
3
6
 
4
7
  type Options = {
5
- network: 'mainnet' | 'testnet' | 'devnet' | 'localnet';
8
+ network: 'mainnet' | 'testnet' | 'devnet' | 'localnet' | 'default';
9
+ 'rpc-url'?: string;
6
10
  };
7
11
 
8
12
  const commandModule: CommandModule<Options, Options> = {
9
13
  command: 'check-balance',
10
14
  describe: 'Check the balance of the account',
11
- builder: {
12
- network: {
13
- type: 'string',
14
- choices: ['mainnet', 'testnet', 'devnet', 'localnet'],
15
- desc: 'Network to check balance on',
16
- default: 'localnet'
17
- }
15
+ builder(yargs) {
16
+ return yargs.options({
17
+ network: {
18
+ type: 'string',
19
+ choices: ['mainnet', 'testnet', 'devnet', 'localnet', 'default'],
20
+ desc: 'Network to check balance on',
21
+ default: 'default'
22
+ },
23
+ 'rpc-url': {
24
+ type: 'string',
25
+ desc: 'Custom RPC endpoint URL (overrides the default for the selected network)'
26
+ }
27
+ }) as any;
18
28
  },
19
- async handler({ network }) {
29
+ async handler({ network, 'rpc-url': rpcUrl }) {
20
30
  try {
21
- await checkBalanceHandler(network);
31
+ if (network == 'default') {
32
+ network = await getDefaultNetwork();
33
+ console.log(chalk.yellow(`Use default network: [${network}]`));
34
+ }
35
+ const fullnodeUrls = rpcUrl ? [rpcUrl] : undefined;
36
+ await checkBalanceHandler(network, fullnodeUrls);
22
37
  } catch (error) {
23
38
  console.error('Error checking balance:', error);
24
- process.exit(1);
39
+ handlerExit(1);
25
40
  }
26
- process.exit(0);
41
+ handlerExit();
27
42
  }
28
43
  };
29
44
 
@@ -0,0 +1,84 @@
1
+ import type { CommandModule } from 'yargs';
2
+ import chalk from 'chalk';
3
+ import { DubheConfig, loadConfig } from '@0xobelisk/sui-common';
4
+ import { generateConfigJson } from '../utils';
5
+ import fs from 'fs';
6
+ import { handlerExit } from './shell';
7
+
8
+ type Options = {
9
+ 'config-path': string;
10
+ 'output-path': string;
11
+ };
12
+
13
+ const RUNTIME_FIELDS = [
14
+ 'original_package_id',
15
+ 'dubhe_object_id',
16
+ 'original_dubhe_package_id',
17
+ 'dapp_key',
18
+ 'start_checkpoint'
19
+ ];
20
+
21
+ export function mergeConfigJsonRuntimeFields(
22
+ schemaJson: Record<string, unknown>,
23
+ existing: Record<string, unknown>
24
+ ): Record<string, unknown> {
25
+ const merged: Record<string, unknown> = { ...schemaJson };
26
+ for (const field of RUNTIME_FIELDS) {
27
+ if (existing[field] !== undefined) {
28
+ merged[field] = existing[field];
29
+ }
30
+ }
31
+ // If dapp_key is missing but original_package_id is present, compute it.
32
+ // This handles configs created before dapp_key was introduced.
33
+ if (!merged['dapp_key'] && merged['original_package_id']) {
34
+ const hex = (merged['original_package_id'] as string).replace(/^0x/i, '').padStart(64, '0');
35
+ merged['dapp_key'] = `${hex}::dapp_key::DappKey`;
36
+ }
37
+ return merged;
38
+ }
39
+
40
+ const commandModule: CommandModule<Options, Options> = {
41
+ command: 'convert-json',
42
+ describe: 'Convert JSON from Dubhe config to config.json',
43
+ builder(yargs) {
44
+ return yargs.options({
45
+ 'config-path': {
46
+ type: 'string',
47
+ default: 'dubhe.config.ts',
48
+ description: 'Options to pass to forge test'
49
+ },
50
+ 'output-path': {
51
+ type: 'string',
52
+ default: 'dubhe.config.json',
53
+ description: 'Output path for the config.json file'
54
+ }
55
+ });
56
+ },
57
+
58
+ async handler({ 'config-path': configPath, 'output-path': outputPath }) {
59
+ try {
60
+ console.log('🚀 Running convert json');
61
+ const dubheConfig = (await loadConfig(configPath)) as DubheConfig;
62
+ const schemaJson = JSON.parse(generateConfigJson(dubheConfig));
63
+
64
+ let existing: Record<string, unknown> = {};
65
+ if (fs.existsSync(outputPath)) {
66
+ try {
67
+ existing = JSON.parse(fs.readFileSync(outputPath, 'utf-8'));
68
+ } catch {
69
+ // ignore parse errors – start fresh
70
+ }
71
+ }
72
+ const merged = mergeConfigJsonRuntimeFields(schemaJson, existing);
73
+
74
+ fs.writeFileSync(outputPath, JSON.stringify(merged, null, 2));
75
+ } catch (error: any) {
76
+ console.error(chalk.red('Error executing convert json:'));
77
+ console.log(error.stdout);
78
+ handlerExit(1);
79
+ }
80
+ handlerExit();
81
+ }
82
+ };
83
+
84
+ export default commandModule;