@0xobelisk/sui-cli 1.2.0-pre.99 → 2.0.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/LICENSE +92 -0
- package/README.md +5 -5
- package/dist/dubhe.js +117 -103
- package/dist/dubhe.js.map +1 -1
- package/package.json +24 -24
- package/src/commands/build.ts +15 -3
- package/src/commands/checkBalance.ts +17 -9
- package/src/commands/convertJson.ts +39 -16
- package/src/commands/faucet.ts +9 -3
- package/src/commands/{schemagen.ts → generate.ts} +16 -6
- package/src/commands/index.ts +4 -4
- package/src/commands/info.ts +8 -2
- package/src/commands/loadMetadata.ts +13 -2
- package/src/commands/publish.ts +39 -5
- package/src/commands/shell.ts +15 -5
- package/src/commands/{configStore.ts → storeConfig.ts} +2 -1
- package/src/commands/switchEnv.ts +13 -6
- package/src/commands/test.ts +106 -37
- package/src/commands/upgrade.ts +36 -3
- package/src/commands/watch.ts +7 -7
- package/src/dubhe.ts +0 -0
- package/src/utils/checkBalance.ts +6 -2
- package/src/utils/constants.ts +8 -4
- package/src/utils/metadataHandler.ts +4 -3
- package/src/utils/publishHandler.ts +168 -152
- package/src/utils/storeConfig.ts +55 -9
- package/src/utils/upgradeHandler.ts +127 -98
- package/src/utils/utils.ts +405 -123
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@0xobelisk/sui-cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Tookit for interacting with move eps framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sui",
|
|
@@ -24,28 +24,7 @@
|
|
|
24
24
|
"bin": {
|
|
25
25
|
"dubhe": "./dist/dubhe.js"
|
|
26
26
|
},
|
|
27
|
-
"scripts": {
|
|
28
|
-
"build": "pnpm run type-check && pnpm run build:js",
|
|
29
|
-
"build:js": "tsup && chmod +x ./dist/dubhe.js",
|
|
30
|
-
"clean": "pnpm run clean:js",
|
|
31
|
-
"clean:js": "rimraf dist",
|
|
32
|
-
"dev": "tsup --watch",
|
|
33
|
-
"format": "prettier --write .",
|
|
34
|
-
"format:check": "prettier --check .",
|
|
35
|
-
"lint": "eslint . --ext .ts",
|
|
36
|
-
"test": "vitest run",
|
|
37
|
-
"test:all": "pnpm test && pnpm test:integration",
|
|
38
|
-
"test:coverage": "vitest run --coverage",
|
|
39
|
-
"test:integration": "vitest run --config vitest.integration.config.ts",
|
|
40
|
-
"test:localnet": "vitest run --config vitest.integration.config.ts tests/integration/localnet.test.ts",
|
|
41
|
-
"test:testnet": "vitest run --config vitest.integration.config.ts tests/integration/testnet.test.ts",
|
|
42
|
-
"test:watch": "vitest",
|
|
43
|
-
"type-check": "tsc --noEmit",
|
|
44
|
-
"validate": "pnpm format:check && pnpm type-check"
|
|
45
|
-
},
|
|
46
27
|
"dependencies": {
|
|
47
|
-
"@0xobelisk/sui-client": "workspace:*",
|
|
48
|
-
"@0xobelisk/sui-common": "workspace:*",
|
|
49
28
|
"@mysten/sui": "1.35.0",
|
|
50
29
|
"@types/wait-on": "^5.3.4",
|
|
51
30
|
"axios": "^1.12.0",
|
|
@@ -67,7 +46,9 @@
|
|
|
67
46
|
"wait-on": "^7.0.1",
|
|
68
47
|
"yargs": "^17.7.1",
|
|
69
48
|
"zod": "^3.22.3",
|
|
70
|
-
"zod-validation-error": "^1.3.0"
|
|
49
|
+
"zod-validation-error": "^1.3.0",
|
|
50
|
+
"@0xobelisk/sui-common": "2.0.0",
|
|
51
|
+
"@0xobelisk/sui-client": "2.0.0"
|
|
71
52
|
},
|
|
72
53
|
"devDependencies": {
|
|
73
54
|
"@types/cli-progress": "^3.11.5",
|
|
@@ -89,5 +70,24 @@
|
|
|
89
70
|
},
|
|
90
71
|
"publishConfig": {
|
|
91
72
|
"access": "public"
|
|
73
|
+
},
|
|
74
|
+
"scripts": {
|
|
75
|
+
"build": "pnpm run type-check && pnpm run build:js",
|
|
76
|
+
"build:js": "tsup && chmod +x ./dist/dubhe.js",
|
|
77
|
+
"clean": "pnpm run clean:js",
|
|
78
|
+
"clean:js": "rimraf dist",
|
|
79
|
+
"dev": "tsup --watch",
|
|
80
|
+
"format": "prettier --write .",
|
|
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",
|
|
90
|
+
"type-check": "tsc --noEmit",
|
|
91
|
+
"validate": "pnpm format:check && pnpm type-check"
|
|
92
92
|
}
|
|
93
|
-
}
|
|
93
|
+
}
|
package/src/commands/build.ts
CHANGED
|
@@ -4,12 +4,13 @@ import nodePath from 'path';
|
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import { DubheConfig, loadConfig } from '@0xobelisk/sui-common';
|
|
6
6
|
import { handlerExit } from './shell';
|
|
7
|
-
import { getDefaultNetwork, switchEnv } from '../utils';
|
|
7
|
+
import { getDefaultNetwork, switchEnv, lintSystemGuards, formatLintWarnings } from '../utils';
|
|
8
8
|
|
|
9
9
|
type Options = {
|
|
10
10
|
'config-path': string;
|
|
11
11
|
network: any;
|
|
12
12
|
'dump-bytecode-as-base64'?: boolean;
|
|
13
|
+
'rpc-url'?: string;
|
|
13
14
|
};
|
|
14
15
|
|
|
15
16
|
/**
|
|
@@ -61,6 +62,10 @@ const commandModule: CommandModule<Options, Options> = {
|
|
|
61
62
|
type: 'boolean',
|
|
62
63
|
default: false,
|
|
63
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)'
|
|
64
69
|
}
|
|
65
70
|
});
|
|
66
71
|
},
|
|
@@ -68,7 +73,8 @@ const commandModule: CommandModule<Options, Options> = {
|
|
|
68
73
|
async handler({
|
|
69
74
|
'config-path': configPath,
|
|
70
75
|
network,
|
|
71
|
-
'dump-bytecode-as-base64': dumpBytecodeAsBase64
|
|
76
|
+
'dump-bytecode-as-base64': dumpBytecodeAsBase64,
|
|
77
|
+
'rpc-url': rpcUrl
|
|
72
78
|
}) {
|
|
73
79
|
try {
|
|
74
80
|
if (network == 'default') {
|
|
@@ -77,7 +83,13 @@ const commandModule: CommandModule<Options, Options> = {
|
|
|
77
83
|
}
|
|
78
84
|
console.log('🚀 Running move build');
|
|
79
85
|
const dubheConfig = (await loadConfig(configPath)) as DubheConfig;
|
|
80
|
-
await switchEnv(network);
|
|
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
|
+
|
|
81
93
|
const output = await buildHandler(dubheConfig, network, dumpBytecodeAsBase64);
|
|
82
94
|
console.log(output);
|
|
83
95
|
exec(`pnpm dubhe convert-json --config-path ${configPath}`);
|
|
@@ -6,26 +6,34 @@ import { getDefaultNetwork } from '../utils';
|
|
|
6
6
|
|
|
7
7
|
type Options = {
|
|
8
8
|
network: 'mainnet' | 'testnet' | 'devnet' | 'localnet' | 'default';
|
|
9
|
+
'rpc-url'?: string;
|
|
9
10
|
};
|
|
10
11
|
|
|
11
12
|
const commandModule: CommandModule<Options, Options> = {
|
|
12
13
|
command: 'check-balance',
|
|
13
14
|
describe: 'Check the balance of the account',
|
|
14
|
-
builder
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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;
|
|
21
28
|
},
|
|
22
|
-
async handler({ network }) {
|
|
29
|
+
async handler({ network, 'rpc-url': rpcUrl }) {
|
|
23
30
|
try {
|
|
24
31
|
if (network == 'default') {
|
|
25
32
|
network = await getDefaultNetwork();
|
|
26
33
|
console.log(chalk.yellow(`Use default network: [${network}]`));
|
|
27
34
|
}
|
|
28
|
-
|
|
35
|
+
const fullnodeUrls = rpcUrl ? [rpcUrl] : undefined;
|
|
36
|
+
await checkBalanceHandler(network, fullnodeUrls);
|
|
29
37
|
} catch (error) {
|
|
30
38
|
console.error('Error checking balance:', error);
|
|
31
39
|
handlerExit(1);
|
|
@@ -10,6 +10,34 @@ type Options = {
|
|
|
10
10
|
'output-path': string;
|
|
11
11
|
};
|
|
12
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
|
+
'package_ids'
|
|
20
|
+
];
|
|
21
|
+
|
|
22
|
+
export function mergeConfigJsonRuntimeFields(
|
|
23
|
+
schemaJson: Record<string, unknown>,
|
|
24
|
+
existing: Record<string, unknown>
|
|
25
|
+
): Record<string, unknown> {
|
|
26
|
+
const merged: Record<string, unknown> = { ...schemaJson };
|
|
27
|
+
for (const field of RUNTIME_FIELDS) {
|
|
28
|
+
if (existing[field] !== undefined) {
|
|
29
|
+
merged[field] = existing[field];
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// If dapp_key is missing but original_package_id is present, compute it.
|
|
33
|
+
// This handles configs created before dapp_key was introduced.
|
|
34
|
+
if (!merged['dapp_key'] && merged['original_package_id']) {
|
|
35
|
+
const hex = (merged['original_package_id'] as string).replace(/^0x/i, '').padStart(64, '0');
|
|
36
|
+
merged['dapp_key'] = `${hex}::dapp_key::DappKey`;
|
|
37
|
+
}
|
|
38
|
+
return merged;
|
|
39
|
+
}
|
|
40
|
+
|
|
13
41
|
const commandModule: CommandModule<Options, Options> = {
|
|
14
42
|
command: 'convert-json',
|
|
15
43
|
describe: 'Convert JSON from Dubhe config to config.json',
|
|
@@ -18,7 +46,7 @@ const commandModule: CommandModule<Options, Options> = {
|
|
|
18
46
|
'config-path': {
|
|
19
47
|
type: 'string',
|
|
20
48
|
default: 'dubhe.config.ts',
|
|
21
|
-
description: '
|
|
49
|
+
description: 'Path to the Dubhe config file'
|
|
22
50
|
},
|
|
23
51
|
'output-path': {
|
|
24
52
|
type: 'string',
|
|
@@ -34,33 +62,28 @@ const commandModule: CommandModule<Options, Options> = {
|
|
|
34
62
|
const dubheConfig = (await loadConfig(configPath)) as DubheConfig;
|
|
35
63
|
const schemaJson = JSON.parse(generateConfigJson(dubheConfig));
|
|
36
64
|
|
|
37
|
-
// Preserve runtime fields written by publishHandler (package IDs, checkpoint, etc.)
|
|
38
|
-
// so that re-running convert-json after publish does not wipe deployment info.
|
|
39
|
-
const RUNTIME_FIELDS = [
|
|
40
|
-
'original_package_id',
|
|
41
|
-
'dubhe_object_id',
|
|
42
|
-
'original_dubhe_package_id',
|
|
43
|
-
'start_checkpoint'
|
|
44
|
-
];
|
|
45
65
|
let existing: Record<string, unknown> = {};
|
|
46
|
-
|
|
66
|
+
const isUpdate = fs.existsSync(outputPath);
|
|
67
|
+
if (isUpdate) {
|
|
47
68
|
try {
|
|
48
69
|
existing = JSON.parse(fs.readFileSync(outputPath, 'utf-8'));
|
|
49
70
|
} catch {
|
|
50
71
|
// ignore parse errors – start fresh
|
|
51
72
|
}
|
|
52
73
|
}
|
|
53
|
-
const merged
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
74
|
+
const merged = mergeConfigJsonRuntimeFields(schemaJson, existing);
|
|
75
|
+
|
|
76
|
+
// Log which runtime fields were preserved from the existing file
|
|
77
|
+
const preserved = RUNTIME_FIELDS.filter((f) => existing[f] !== undefined);
|
|
78
|
+
if (preserved.length > 0) {
|
|
79
|
+
console.log(chalk.gray(` preserved runtime fields: ${preserved.join(', ')}`));
|
|
58
80
|
}
|
|
59
81
|
|
|
60
82
|
fs.writeFileSync(outputPath, JSON.stringify(merged, null, 2));
|
|
83
|
+
console.log(chalk.green(`✅ ${isUpdate ? 'Updated' : 'Created'} ${outputPath}`));
|
|
61
84
|
} catch (error: any) {
|
|
62
85
|
console.error(chalk.red('Error executing convert json:'));
|
|
63
|
-
console.
|
|
86
|
+
if (error.message) console.error(error.message);
|
|
64
87
|
handlerExit(1);
|
|
65
88
|
}
|
|
66
89
|
handlerExit();
|
package/src/commands/faucet.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { handlerExit } from './shell';
|
|
|
7
7
|
type Options = {
|
|
8
8
|
network: any;
|
|
9
9
|
recipient?: string;
|
|
10
|
+
'rpc-url'?: string;
|
|
10
11
|
};
|
|
11
12
|
|
|
12
13
|
const MAX_RETRIES = 60; // 60s timeout
|
|
@@ -28,15 +29,20 @@ const commandModule: CommandModule<Options, Options> = {
|
|
|
28
29
|
},
|
|
29
30
|
recipient: {
|
|
30
31
|
type: 'string',
|
|
32
|
+
alias: 'r',
|
|
31
33
|
desc: 'Sui address to fund'
|
|
34
|
+
},
|
|
35
|
+
'rpc-url': {
|
|
36
|
+
type: 'string',
|
|
37
|
+
desc: 'Custom RPC endpoint URL for balance check (overrides the default for the selected network)'
|
|
32
38
|
}
|
|
33
39
|
});
|
|
34
40
|
},
|
|
35
41
|
|
|
36
|
-
async handler({ network, recipient }) {
|
|
42
|
+
async handler({ network, recipient, 'rpc-url': rpcUrl }) {
|
|
37
43
|
let faucet_address = '';
|
|
38
44
|
if (recipient === undefined) {
|
|
39
|
-
const dubhe = initializeDubhe(network);
|
|
45
|
+
const dubhe = initializeDubhe({ network });
|
|
40
46
|
faucet_address = dubhe.getAddress();
|
|
41
47
|
} else {
|
|
42
48
|
faucet_address = recipient;
|
|
@@ -107,7 +113,7 @@ const commandModule: CommandModule<Options, Options> = {
|
|
|
107
113
|
process.stdout.write('\r' + ' '.repeat(50) + '\r');
|
|
108
114
|
|
|
109
115
|
console.log(' └─ Checking balance...');
|
|
110
|
-
const client = new SuiClient({ url: getFullnodeUrl(network) });
|
|
116
|
+
const client = new SuiClient({ url: rpcUrl || getFullnodeUrl(network) });
|
|
111
117
|
let params = {
|
|
112
118
|
owner: faucet_address
|
|
113
119
|
} as GetBalanceParams;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CommandModule } from 'yargs';
|
|
2
|
-
import {
|
|
2
|
+
import { codegen, loadConfig, DubheConfig } from '@0xobelisk/sui-common';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
import { handlerExit } from './shell';
|
|
@@ -8,12 +8,15 @@ import { getDefaultNetwork } from '../utils';
|
|
|
8
8
|
type Options = {
|
|
9
9
|
'config-path'?: string;
|
|
10
10
|
network?: 'mainnet' | 'testnet' | 'devnet' | 'localnet' | 'default';
|
|
11
|
+
mode?: 'user_pays' | 'dapp_subsidizes';
|
|
11
12
|
};
|
|
12
13
|
|
|
13
14
|
const commandModule: CommandModule<Options, Options> = {
|
|
14
|
-
command: '
|
|
15
|
+
command: 'generate',
|
|
16
|
+
// 'schemagen' kept as a deprecated alias for backward compatibility
|
|
17
|
+
aliases: ['schemagen'],
|
|
15
18
|
|
|
16
|
-
describe: '
|
|
19
|
+
describe: 'Generate Move code from dubhe.config.ts',
|
|
17
20
|
|
|
18
21
|
builder: {
|
|
19
22
|
'config-path': {
|
|
@@ -26,10 +29,16 @@ const commandModule: CommandModule<Options, Options> = {
|
|
|
26
29
|
choices: ['mainnet', 'testnet', 'devnet', 'localnet', 'default'] as const,
|
|
27
30
|
default: 'default',
|
|
28
31
|
desc: 'Node network (mainnet/testnet/devnet/localnet)'
|
|
32
|
+
},
|
|
33
|
+
mode: {
|
|
34
|
+
type: 'string',
|
|
35
|
+
choices: ['user_pays', 'dapp_subsidizes'] as const,
|
|
36
|
+
default: 'user_pays',
|
|
37
|
+
desc: 'Initial settlement mode for this DApp (only applies on first generate)'
|
|
29
38
|
}
|
|
30
39
|
},
|
|
31
40
|
|
|
32
|
-
async handler({ 'config-path': configPath, network }) {
|
|
41
|
+
async handler({ 'config-path': configPath, network, mode }) {
|
|
33
42
|
try {
|
|
34
43
|
if (!configPath) throw new Error('Config path is required');
|
|
35
44
|
if (network == 'default') {
|
|
@@ -38,10 +47,11 @@ const commandModule: CommandModule<Options, Options> = {
|
|
|
38
47
|
}
|
|
39
48
|
const dubheConfig = (await loadConfig(configPath)) as DubheConfig;
|
|
40
49
|
const rootDir = path.dirname(configPath);
|
|
41
|
-
|
|
50
|
+
const initialMode: 0 | 1 = mode === 'dapp_subsidizes' ? 0 : 1;
|
|
51
|
+
await codegen(rootDir, dubheConfig, network, initialMode);
|
|
42
52
|
handlerExit();
|
|
43
53
|
} catch (error: any) {
|
|
44
|
-
console.log(chalk.red('
|
|
54
|
+
console.log(chalk.red('Generate failed!'));
|
|
45
55
|
console.error(error.message);
|
|
46
56
|
handlerExit(1);
|
|
47
57
|
}
|
package/src/commands/index.ts
CHANGED
|
@@ -2,14 +2,14 @@ import { CommandModule } from 'yargs';
|
|
|
2
2
|
|
|
3
3
|
import localnode from './localnode';
|
|
4
4
|
import faucet from './faucet';
|
|
5
|
-
import
|
|
5
|
+
import generate from './generate';
|
|
6
6
|
import publish from './publish';
|
|
7
7
|
import test from './test';
|
|
8
8
|
import build from './build';
|
|
9
9
|
import hello from './hello';
|
|
10
10
|
import generateKey from './generateKey';
|
|
11
11
|
import checkBalance from './checkBalance';
|
|
12
|
-
import
|
|
12
|
+
import storeConfig from './storeConfig';
|
|
13
13
|
import watch from './watch';
|
|
14
14
|
import wait from './wait';
|
|
15
15
|
import switchEnv from './switchEnv';
|
|
@@ -26,14 +26,14 @@ export const commands: CommandModule<any, any>[] = [
|
|
|
26
26
|
// call,
|
|
27
27
|
// query,
|
|
28
28
|
faucet,
|
|
29
|
-
|
|
29
|
+
generate,
|
|
30
30
|
upgrade,
|
|
31
31
|
test,
|
|
32
32
|
build,
|
|
33
33
|
hello,
|
|
34
34
|
generateKey,
|
|
35
35
|
checkBalance,
|
|
36
|
-
|
|
36
|
+
storeConfig,
|
|
37
37
|
watch,
|
|
38
38
|
wait,
|
|
39
39
|
switchEnv,
|
package/src/commands/info.ts
CHANGED
|
@@ -7,6 +7,7 @@ dotenv.config();
|
|
|
7
7
|
|
|
8
8
|
type Options = {
|
|
9
9
|
network: any;
|
|
10
|
+
'rpc-url'?: string;
|
|
10
11
|
};
|
|
11
12
|
|
|
12
13
|
const InfoCommand: CommandModule<Options, Options> = {
|
|
@@ -19,16 +20,21 @@ const InfoCommand: CommandModule<Options, Options> = {
|
|
|
19
20
|
choices: ['mainnet', 'testnet', 'devnet', 'localnet', 'default'],
|
|
20
21
|
default: 'default',
|
|
21
22
|
desc: 'Node network (mainnet/testnet/devnet/localnet)'
|
|
23
|
+
},
|
|
24
|
+
'rpc-url': {
|
|
25
|
+
type: 'string',
|
|
26
|
+
desc: 'Custom RPC endpoint URL (overrides the default for the selected network)'
|
|
22
27
|
}
|
|
23
28
|
});
|
|
24
29
|
},
|
|
25
|
-
handler: async ({ network }) => {
|
|
30
|
+
handler: async ({ network, 'rpc-url': rpcUrl }) => {
|
|
26
31
|
try {
|
|
27
32
|
if (network == 'default') {
|
|
28
33
|
network = await getDefaultNetwork();
|
|
29
34
|
console.log(chalk.yellow(`Use default network: [${network}]`));
|
|
30
35
|
}
|
|
31
|
-
const
|
|
36
|
+
const fullnodeUrls = rpcUrl ? [rpcUrl] : undefined;
|
|
37
|
+
const dubhe = initializeDubhe({ network, fullnodeUrls });
|
|
32
38
|
const keypair = dubhe.getSigner();
|
|
33
39
|
|
|
34
40
|
console.log(chalk.blue('Account Information:'));
|
|
@@ -10,6 +10,7 @@ type Options = {
|
|
|
10
10
|
network: any;
|
|
11
11
|
'config-path': string;
|
|
12
12
|
'package-id'?: string;
|
|
13
|
+
'rpc-url'?: string;
|
|
13
14
|
};
|
|
14
15
|
|
|
15
16
|
const commandModule: CommandModule<Options, Options> = {
|
|
@@ -34,18 +35,28 @@ const commandModule: CommandModule<Options, Options> = {
|
|
|
34
35
|
type: 'string',
|
|
35
36
|
desc: 'Package ID to load metadata for',
|
|
36
37
|
optional: true
|
|
38
|
+
},
|
|
39
|
+
'rpc-url': {
|
|
40
|
+
type: 'string',
|
|
41
|
+
desc: 'Custom RPC endpoint URL (overrides the default for the selected network)'
|
|
37
42
|
}
|
|
38
43
|
});
|
|
39
44
|
},
|
|
40
45
|
|
|
41
|
-
async handler({
|
|
46
|
+
async handler({
|
|
47
|
+
network,
|
|
48
|
+
'config-path': configPath,
|
|
49
|
+
'package-id': packageId,
|
|
50
|
+
'rpc-url': rpcUrl
|
|
51
|
+
}) {
|
|
42
52
|
try {
|
|
43
53
|
if (network == 'default') {
|
|
44
54
|
network = await getDefaultNetwork();
|
|
45
55
|
console.log(chalk.yellow(`Use default network: [${network}]`));
|
|
46
56
|
}
|
|
47
57
|
const dubheConfig = (await loadConfig(configPath)) as DubheConfig;
|
|
48
|
-
|
|
58
|
+
const fullnodeUrls = rpcUrl ? [rpcUrl] : undefined;
|
|
59
|
+
await loadMetadataHandler(dubheConfig, network, packageId, fullnodeUrls);
|
|
49
60
|
} catch (error: any) {
|
|
50
61
|
logError(error);
|
|
51
62
|
handlerExit(1);
|
package/src/commands/publish.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import type { CommandModule } from 'yargs';
|
|
2
2
|
import { logError } from '../utils/errors';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
getDefaultNetwork,
|
|
5
|
+
publishHandler,
|
|
6
|
+
lintSystemGuards,
|
|
7
|
+
formatLintWarnings,
|
|
8
|
+
confirm
|
|
9
|
+
} from '../utils';
|
|
4
10
|
import { loadConfig, DubheConfig } from '@0xobelisk/sui-common';
|
|
5
11
|
import { execSync } from 'child_process';
|
|
12
|
+
import { join as pathJoin } from 'path';
|
|
6
13
|
import { handlerExit } from './shell';
|
|
7
14
|
import chalk from 'chalk';
|
|
8
15
|
|
|
@@ -11,6 +18,7 @@ type Options = {
|
|
|
11
18
|
'config-path': string;
|
|
12
19
|
force: boolean;
|
|
13
20
|
'gas-budget'?: number;
|
|
21
|
+
'rpc-url'?: string;
|
|
14
22
|
};
|
|
15
23
|
|
|
16
24
|
const commandModule: CommandModule<Options, Options> = {
|
|
@@ -38,21 +46,47 @@ const commandModule: CommandModule<Options, Options> = {
|
|
|
38
46
|
},
|
|
39
47
|
force: {
|
|
40
48
|
type: 'boolean',
|
|
41
|
-
default:
|
|
42
|
-
desc: '
|
|
49
|
+
default: false,
|
|
50
|
+
desc: 'Clear existing published state for this network before build (use when re-publishing or to fix PublishErrorNonZeroAddress)'
|
|
51
|
+
},
|
|
52
|
+
'rpc-url': {
|
|
53
|
+
type: 'string',
|
|
54
|
+
desc: 'Custom RPC endpoint URL (overrides the default for the selected network)'
|
|
43
55
|
}
|
|
44
56
|
});
|
|
45
57
|
},
|
|
46
58
|
|
|
47
|
-
async handler({
|
|
59
|
+
async handler({
|
|
60
|
+
network,
|
|
61
|
+
'config-path': configPath,
|
|
62
|
+
'gas-budget': gasBudget,
|
|
63
|
+
force,
|
|
64
|
+
'rpc-url': rpcUrl
|
|
65
|
+
}) {
|
|
48
66
|
try {
|
|
49
67
|
if (network == 'default') {
|
|
50
68
|
network = await getDefaultNetwork();
|
|
51
69
|
console.log(chalk.yellow(`Use default network: [${network}]`));
|
|
52
70
|
}
|
|
53
71
|
const dubheConfig = (await loadConfig(configPath)) as DubheConfig;
|
|
72
|
+
|
|
73
|
+
const projectPath = pathJoin(process.cwd(), 'src', dubheConfig.name);
|
|
74
|
+
const lintResults = lintSystemGuards(projectPath);
|
|
75
|
+
if (lintResults.length > 0) {
|
|
76
|
+
process.stdout.write(formatLintWarnings(lintResults));
|
|
77
|
+
const proceed = await confirm(
|
|
78
|
+
'Some entry functions are missing ensure_latest_version. Proceed with publish anyway?'
|
|
79
|
+
);
|
|
80
|
+
if (!proceed) {
|
|
81
|
+
console.log(chalk.red('Publish cancelled.'));
|
|
82
|
+
handlerExit(1);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const fullnodeUrls = rpcUrl ? [rpcUrl] : undefined;
|
|
54
88
|
execSync(`pnpm dubhe convert-json --config-path ${configPath}`, { encoding: 'utf-8' });
|
|
55
|
-
await publishHandler(dubheConfig, network, force, gasBudget);
|
|
89
|
+
await publishHandler(dubheConfig, network, force, gasBudget, fullnodeUrls);
|
|
56
90
|
} catch (error: any) {
|
|
57
91
|
logError(error);
|
|
58
92
|
handlerExit(1);
|
package/src/commands/shell.ts
CHANGED
|
@@ -20,6 +20,7 @@ export const handlerExit = (status: number = 0) => {
|
|
|
20
20
|
|
|
21
21
|
type Options = {
|
|
22
22
|
network: any;
|
|
23
|
+
'rpc-url'?: string;
|
|
23
24
|
};
|
|
24
25
|
|
|
25
26
|
const parseCommandNames = () => {
|
|
@@ -38,10 +39,14 @@ const ShellCommand: CommandModule<Options, Options> = {
|
|
|
38
39
|
choices: ['mainnet', 'testnet', 'devnet', 'localnet', 'default'],
|
|
39
40
|
default: 'default',
|
|
40
41
|
desc: 'Node network (mainnet/testnet/devnet/localnet)'
|
|
42
|
+
},
|
|
43
|
+
'rpc-url': {
|
|
44
|
+
type: 'string',
|
|
45
|
+
desc: 'Custom RPC endpoint URL injected into every sub-command (overrides the default for the selected network)'
|
|
41
46
|
}
|
|
42
47
|
});
|
|
43
48
|
},
|
|
44
|
-
handler: async ({ network }) => {
|
|
49
|
+
handler: async ({ network, 'rpc-url': rpcUrl }) => {
|
|
45
50
|
if (network == 'default') {
|
|
46
51
|
network = await getDefaultNetwork();
|
|
47
52
|
console.log(chalk.yellow(`Use default network: [${network}]`));
|
|
@@ -60,7 +65,9 @@ const ShellCommand: CommandModule<Options, Options> = {
|
|
|
60
65
|
const rl = readline.createInterface({
|
|
61
66
|
input: process.stdin,
|
|
62
67
|
output: process.stdout,
|
|
63
|
-
prompt: `dubhe(${chalk.green(network)}
|
|
68
|
+
prompt: `dubhe(${chalk.green(network)}${
|
|
69
|
+
rpcUrl ? chalk.gray('[custom-rpc]') : ''
|
|
70
|
+
}) ${chalk.bold('>')} `,
|
|
64
71
|
completer: completer,
|
|
65
72
|
historySize: 200
|
|
66
73
|
});
|
|
@@ -132,11 +139,14 @@ const ShellCommand: CommandModule<Options, Options> = {
|
|
|
132
139
|
} else {
|
|
133
140
|
yargsInstance.options(builder);
|
|
134
141
|
}
|
|
142
|
+
const userArgs = parts.slice(1);
|
|
143
|
+
const hasNetworkFlag = userArgs.includes('--network') || userArgs.includes('-n');
|
|
144
|
+
const hasRpcUrlFlag = userArgs.includes('--rpc-url');
|
|
135
145
|
const argv = yargsInstance.parseSync([
|
|
136
146
|
commandName,
|
|
137
|
-
'--network',
|
|
138
|
-
|
|
139
|
-
...
|
|
147
|
+
...(hasNetworkFlag ? [] : ['--network', network]),
|
|
148
|
+
...(hasRpcUrlFlag || !rpcUrl ? [] : ['--rpc-url', rpcUrl]),
|
|
149
|
+
...userArgs
|
|
140
150
|
]);
|
|
141
151
|
if (handler) {
|
|
142
152
|
await handler(argv);
|
|
@@ -12,7 +12,7 @@ type Options = {
|
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
const commandModule: CommandModule<Options, Options> = {
|
|
15
|
-
command: 'config
|
|
15
|
+
command: 'store-config',
|
|
16
16
|
|
|
17
17
|
describe: 'Store configuration for the Dubhe project',
|
|
18
18
|
|
|
@@ -30,6 +30,7 @@ const commandModule: CommandModule<Options, Options> = {
|
|
|
30
30
|
},
|
|
31
31
|
'output-ts-path': {
|
|
32
32
|
type: 'string',
|
|
33
|
+
default: './deployment.ts',
|
|
33
34
|
desc: 'Specify the output path for the generated TypeScript configuration file (e.g., ./src/config/generated.ts)'
|
|
34
35
|
}
|
|
35
36
|
},
|
|
@@ -4,21 +4,28 @@ import { handlerExit } from './shell';
|
|
|
4
4
|
|
|
5
5
|
type Options = {
|
|
6
6
|
network: 'mainnet' | 'testnet' | 'devnet' | 'localnet' | 'default';
|
|
7
|
+
'rpc-url'?: string;
|
|
7
8
|
};
|
|
8
9
|
|
|
9
10
|
const commandModule: CommandModule<Options, Options> = {
|
|
10
11
|
command: 'switch-env',
|
|
11
12
|
describe: 'Switch environment',
|
|
12
13
|
builder(yargs) {
|
|
13
|
-
return yargs.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
return yargs.options({
|
|
15
|
+
network: {
|
|
16
|
+
type: 'string',
|
|
17
|
+
choices: ['mainnet', 'testnet', 'devnet', 'localnet'] as const,
|
|
18
|
+
default: 'localnet',
|
|
19
|
+
desc: 'Switch to node network (mainnet/testnet/devnet/localnet)'
|
|
20
|
+
},
|
|
21
|
+
'rpc-url': {
|
|
22
|
+
type: 'string',
|
|
23
|
+
desc: 'Custom RPC endpoint URL (overrides the default for the selected network)'
|
|
24
|
+
}
|
|
18
25
|
}) as any;
|
|
19
26
|
},
|
|
20
27
|
async handler(argv: ArgumentsCamelCase<Options>) {
|
|
21
|
-
await switchEnv(argv.network as 'mainnet' | 'testnet' | 'devnet' | 'localnet');
|
|
28
|
+
await switchEnv(argv.network as 'mainnet' | 'testnet' | 'devnet' | 'localnet', argv['rpc-url']);
|
|
22
29
|
handlerExit();
|
|
23
30
|
}
|
|
24
31
|
};
|