@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.
@@ -4,9 +4,13 @@ import localnode from './localnode';
4
4
  import faucet from './faucet';
5
5
  import schemagen from './schemagen';
6
6
  import publish from './publish';
7
- import upgrade from "./upgrade";
7
+ import upgrade from './upgrade';
8
8
  import test from './test';
9
+ import build from './build';
9
10
  import hello from './hello';
11
+ import generateKey from './generateKey';
12
+ import checkBalance from './checkBalance';
13
+ import storeConfig from './storeConfig';
10
14
 
11
15
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Each command has different options
12
16
  export const commands: CommandModule<any, any>[] = [
@@ -16,5 +20,9 @@ export const commands: CommandModule<any, any>[] = [
16
20
  schemagen,
17
21
  upgrade,
18
22
  test,
23
+ build,
19
24
  hello,
25
+ generateKey,
26
+ checkBalance,
27
+ storeConfig,
20
28
  ];
@@ -1,45 +1,18 @@
1
1
  import type { CommandModule } from 'yargs';
2
- import { startLocalnode, stopLocalnode, checkLocalNodeStatus } from '../utils';
2
+ import { startLocalNode } from '../utils/startNode';
3
3
 
4
4
  const commandModule: CommandModule = {
5
- command: 'localnode <action>',
5
+ command: 'node',
6
6
 
7
7
  describe: 'Manage local Sui node',
8
8
 
9
9
  builder(yargs) {
10
10
  return yargs
11
- .positional('action', {
12
- describe: 'Action to perform',
13
- choices: ['start', 'stop', 'status', 'restart'],
14
- type: 'string',
15
- demandOption: true,
16
- })
17
- .option('background', {
18
- alias: 'b',
19
- type: 'boolean',
20
- description: 'Run node in background',
21
- default: false,
22
- });
23
11
  },
24
12
 
25
- async handler(argv) {
26
- const { action, background } = argv;
27
-
13
+ async handler() {
28
14
  try {
29
- switch (action) {
30
- case 'start':
31
- await startLocalnode(background as boolean);
32
- break;
33
- case 'stop':
34
- await stopLocalnode();
35
- break;
36
- case 'status':
37
- await checkLocalNodeStatus();
38
- break;
39
- case 'restart':
40
- await restartNode(background as boolean);
41
- break;
42
- }
15
+ await startLocalNode();
43
16
  } catch (error) {
44
17
  console.error('Error executing command:', error);
45
18
  process.exit(1);
@@ -47,11 +20,4 @@ const commandModule: CommandModule = {
47
20
  },
48
21
  };
49
22
 
50
- async function restartNode(background: boolean) {
51
- console.log('Restarting local Sui node...');
52
- await stopLocalnode();
53
- await startLocalnode(background);
54
- console.log('Local node has been restarted');
55
- }
56
-
57
23
  export default commandModule;
@@ -0,0 +1,44 @@
1
+ import type { CommandModule } from 'yargs';
2
+ import { storeConfigHandler } from '../utils/storeConfig';
3
+ import { loadConfig, DubheConfig } from '@0xobelisk/sui-common';
4
+
5
+ type Options = {
6
+ 'config-path': string;
7
+ network: 'mainnet' | 'testnet' | 'devnet' | 'localnet';
8
+ 'output-path': string;
9
+ };
10
+
11
+ const commandModule: CommandModule<Options, Options> = {
12
+ command: 'store-config',
13
+
14
+ describe: 'Store configuration for the Dubhe project',
15
+
16
+ builder: {
17
+ 'config-path': {
18
+ type: 'string',
19
+ default: 'dubhe.config.ts',
20
+ desc: 'Path to the config file',
21
+ },
22
+ network: {
23
+ type: 'string',
24
+ choices: ['mainnet', 'testnet', 'devnet', 'localnet'],
25
+ desc: 'Network to store config for',
26
+ },
27
+ 'output-path': {
28
+ type: 'string',
29
+ desc: 'Path to output the configuration',
30
+ },
31
+ },
32
+ async handler({ 'config-path': configPath, network, outputPath }) {
33
+ try {
34
+ const dubheConfig = (await loadConfig(configPath)) as DubheConfig;
35
+ await storeConfigHandler(dubheConfig, network, outputPath);
36
+ } catch (error) {
37
+ console.error('Error storing config:', error);
38
+ process.exit(1);
39
+ }
40
+ process.exit(0);
41
+ },
42
+ };
43
+
44
+ export default commandModule;
@@ -1,9 +1,11 @@
1
1
  import type { CommandModule } from "yargs";
2
2
  import { execSync } from "child_process";
3
3
  import chalk from "chalk";
4
+ import { DubheConfig, loadConfig } from '@0xobelisk/sui-common';
4
5
 
5
6
  type Options = {
6
- packagePath: string;
7
+ 'config-path': string;
8
+ 'test'?: string;
7
9
  };
8
10
 
9
11
  const commandModule: CommandModule<Options, Options> = {
@@ -13,20 +15,28 @@ const commandModule: CommandModule<Options, Options> = {
13
15
 
14
16
  builder(yargs) {
15
17
  return yargs.options({
16
- packagePath: {
18
+ 'config-path': {
17
19
  type: "string",
18
- default: ".",
20
+ default: "dubhe.config.ts",
19
21
  description: "Options to pass to forge test",
20
22
  },
23
+ test: {
24
+ type: 'string',
25
+ desc: 'Run a specific test',
26
+ },
21
27
  });
22
28
  },
23
29
 
24
- async handler({ packagePath }) {
30
+ async handler({ 'config-path': configPath, test }) {
25
31
  // Start an internal anvil process if no world address is provided
26
32
  try {
27
- execSync(`sui move test --path ${packagePath}`, {
28
- encoding: "utf-8",
29
- });
33
+ console.log('šŸš€ Running move test');
34
+ const dubheConfig = (await loadConfig(configPath)) as DubheConfig;
35
+ const path = process.cwd();
36
+ const projectPath = `${path}/contracts/${dubheConfig.name}`;
37
+ const command = `sui move test --path ${projectPath} ${test ? ` --test ${test}` : ''}`;
38
+ const output = execSync(command, { encoding: "utf-8" });
39
+ console.log(output);
30
40
  } catch (error: any) {
31
41
  console.error(chalk.red("Error executing sui move test:"));
32
42
  console.log(error.stdout);
@@ -0,0 +1,55 @@
1
+ import { Dubhe, NetworkType } from '@0xobelisk/sui-client';
2
+ import chalk from 'chalk';
3
+ import dotenv from 'dotenv';
4
+ import { validatePrivateKey } from './utils';
5
+ import { DubheCliError } from './errors';
6
+ dotenv.config();
7
+
8
+ export async function checkBalanceHandler(
9
+ network: 'mainnet' | 'testnet' | 'devnet' | 'loclnet',
10
+ amount: number = 2
11
+ ) {
12
+ try {
13
+ console.log(
14
+ chalk.blue(
15
+ `Note: You need at least 2 SUI for transaction fees and staking, and registering a Dapp will reserve 1 SUI for Dubhe Dapp Staking, which can be retrieved upon unregistering.`
16
+ )
17
+ );
18
+
19
+ const privateKey = process.env.PRIVATE_KEY;
20
+ if (!privateKey) {
21
+ throw new DubheCliError(
22
+ `Missing PRIVATE_KEY environment variable.
23
+ Run 'echo "PRIVATE_KEY=YOUR_PRIVATE_KEY" > .env'
24
+ in your contracts directory to use the default sui private key.`
25
+ );
26
+ }
27
+ const privateKeyFormat = validatePrivateKey(privateKey);
28
+ if (privateKeyFormat === false) {
29
+ throw new DubheCliError(`Please check your privateKey.`);
30
+ }
31
+
32
+ const dubhe = new Dubhe({
33
+ secretKey: process.env.PRIVATE_KEY,
34
+ networkType: network as NetworkType,
35
+ });
36
+
37
+ const balance = await dubhe.getBalance();
38
+ const balanceInSUI = Number(balance.totalBalance) / 1_000_000_000;
39
+
40
+ if (balanceInSUI < amount) {
41
+ // console.log(chalk.yellow(`Account balance is less than 2 SUI.`));
42
+ throw new DubheCliError(
43
+ `Account balance is less than ${amount} SUI. Please get more SUI.`
44
+ );
45
+ }
46
+
47
+ console.log(
48
+ chalk.green(
49
+ `Current account balance: ${balanceInSUI.toFixed(4)} SUI`
50
+ )
51
+ );
52
+ } catch (error) {
53
+ throw new DubheCliError('Failed to check balance: ' + error);
54
+ }
55
+ }
@@ -1,46 +1,46 @@
1
- import chalk from "chalk";
2
- import { ZodError } from "zod";
3
- import { fromZodError, ValidationError } from "zod-validation-error";
1
+ import chalk from 'chalk';
2
+ import { ZodError } from 'zod';
3
+ import { fromZodError, ValidationError } from 'zod-validation-error';
4
4
 
5
5
  export class NotInsideProjectError extends Error {
6
- name = "NotInsideProjectError";
7
- message = "You are not inside a Dubhe project";
6
+ name = 'NotInsideProjectError';
7
+ message = 'You are not inside a Dubhe project';
8
8
  }
9
9
 
10
10
  export class DubheCliError extends Error {
11
- name = "DubheCliError";
11
+ name = 'DubheCliError';
12
12
  }
13
13
 
14
14
  export class UpgradeError extends Error {
15
- name = "UpgradeError";
15
+ name = 'UpgradeError';
16
16
  }
17
17
 
18
18
  export class FsIibError extends Error {
19
- name = "FsIibError";
19
+ name = 'FsIibError';
20
20
  }
21
21
 
22
22
  export function logError(error: unknown) {
23
- if (error instanceof ValidationError) {
24
- console.log(chalk.redBright(error.message));
25
- } else if (error instanceof ZodError) {
26
- // TODO currently this error shouldn't happen, use `fromZodErrorCustom`
27
- const validationError = fromZodError(error, {
28
- prefixSeparator: "\n- ",
29
- issueSeparator: "\n- ",
30
- });
31
- console.log(chalk.redBright(validationError.message));
32
- } else if (error instanceof NotInsideProjectError) {
33
- console.log(chalk.red(error.message));
34
- console.log("");
35
- // TODO add docs to the website and update the link to the specific page
36
- console.log(
37
- chalk.blue(
38
- `To learn more about Dubhe's configuration, please go to https://github.com/0xobelisk`
39
- )
40
- );
41
- } else if (error instanceof DubheCliError) {
42
- console.log(chalk.red(error));
43
- } else {
44
- console.log(error);
45
- }
23
+ if (error instanceof ValidationError) {
24
+ console.log(chalk.redBright(error.message));
25
+ } else if (error instanceof ZodError) {
26
+ // TODO currently this error shouldn't happen, use `fromZodErrorCustom`
27
+ const validationError = fromZodError(error, {
28
+ prefixSeparator: '\n- ',
29
+ issueSeparator: '\n- ',
30
+ });
31
+ console.log(chalk.redBright(validationError.message));
32
+ } else if (error instanceof NotInsideProjectError) {
33
+ console.log(chalk.red(error.message));
34
+ console.log('');
35
+ // TODO add docs to the website and update the link to the specific page
36
+ console.log(
37
+ chalk.blue(
38
+ `To learn more about Dubhe's configuration, please go to https://github.com/0xobelisk`
39
+ )
40
+ );
41
+ } else if (error instanceof DubheCliError) {
42
+ console.log(chalk.red(error));
43
+ } else {
44
+ console.log(error);
45
+ }
46
46
  }
@@ -0,0 +1,100 @@
1
+ import { Dubhe } from '@0xobelisk/sui-client';
2
+ import * as fs from 'fs';
3
+ import chalk from 'chalk';
4
+
5
+ export async function generateAccountHandler(
6
+ force: boolean = false,
7
+ outputTsPath: string
8
+ ) {
9
+ const path = process.cwd();
10
+ let privateKey: string;
11
+
12
+ if (force) {
13
+ const dubhe = new Dubhe();
14
+ const keypair = dubhe.getKeypair();
15
+ privateKey = keypair.getSecretKey();
16
+
17
+ fs.writeFileSync(`${path}/.env`, `PRIVATE_KEY=${privateKey}`);
18
+ console.log(chalk.green(`File created at: ${path}/.env`));
19
+
20
+ if (outputTsPath) {
21
+ const dir = outputTsPath.substring(
22
+ 0,
23
+ outputTsPath.lastIndexOf('/')
24
+ );
25
+ if (!fs.existsSync(dir)) {
26
+ fs.mkdirSync(dir, { recursive: true });
27
+ }
28
+ fs.writeFileSync(
29
+ outputTsPath,
30
+ `export const PRIVATEKEY = '${privateKey}';
31
+ export const ACCOUNT = '${keypair.toSuiAddress()}';
32
+ `
33
+ );
34
+ console.log(chalk.green(`File created at: ${outputTsPath}`));
35
+ }
36
+
37
+ console.log(
38
+ chalk.blue(`Force generate new Account: ${keypair.toSuiAddress()}`)
39
+ );
40
+ return;
41
+ }
42
+
43
+ // Check if .env file exists and has content
44
+ try {
45
+ const envContent = fs.readFileSync(`${path}/.env`, 'utf8');
46
+ const match = envContent.match(/PRIVATE_KEY=(.+)/);
47
+ if (match && match[1]) {
48
+ privateKey = match[1];
49
+ const dubhe = new Dubhe({ secretKey: privateKey });
50
+ const keypair = dubhe.getKeypair();
51
+
52
+ if (outputTsPath) {
53
+ const dir = outputTsPath.substring(
54
+ 0,
55
+ outputTsPath.lastIndexOf('/')
56
+ );
57
+ if (!fs.existsSync(dir)) {
58
+ fs.mkdirSync(dir, { recursive: true });
59
+ }
60
+ fs.writeFileSync(
61
+ outputTsPath,
62
+ `export const PRIVATEKEY = '${privateKey}';
63
+ export const ACCOUNT = '${keypair.toSuiAddress()}';
64
+ `
65
+ );
66
+ console.log(chalk.green(`File created at: ${outputTsPath}`));
67
+ }
68
+
69
+ console.log(
70
+ chalk.blue(`Using existing Account: ${keypair.toSuiAddress()}`)
71
+ );
72
+ return;
73
+ }
74
+ } catch (error) {
75
+ // .env file doesn't exist or failed to read, continue to generate new account
76
+ }
77
+
78
+ // If no existing private key, generate new account
79
+ const dubhe = new Dubhe();
80
+ const keypair = dubhe.getKeypair();
81
+ privateKey = keypair.getSecretKey();
82
+ fs.writeFileSync(`${path}/.env`, `PRIVATE_KEY=${privateKey}`);
83
+ console.log(chalk.green(`File created at: ${path}/.env`));
84
+
85
+ if (outputTsPath) {
86
+ const dir = outputTsPath.substring(0, outputTsPath.lastIndexOf('/'));
87
+ if (!fs.existsSync(dir)) {
88
+ fs.mkdirSync(dir, { recursive: true });
89
+ }
90
+ fs.writeFileSync(
91
+ outputTsPath,
92
+ `export const PRIVATEKEY = '${privateKey}';
93
+ export const ACCOUNT = '${keypair.toSuiAddress()}';
94
+ `
95
+ );
96
+ console.log(chalk.green(`File created at: ${outputTsPath}`));
97
+ }
98
+
99
+ console.log(chalk.blue(`Generate new Account: ${keypair.toSuiAddress()}`));
100
+ }
@@ -12,7 +12,11 @@ import {
12
12
  updateVersionInFile,
13
13
  saveContractData,
14
14
  validatePrivateKey,
15
- schema, getSchemaHub, updateDubheDependency, switchEnv, delay,
15
+ schema,
16
+ getSchemaHub,
17
+ updateDubheDependency,
18
+ switchEnv,
19
+ delay,
16
20
  } from './utils';
17
21
  import { DubheConfig } from '@0xobelisk/sui-common';
18
22
  import * as fs from 'fs';
@@ -22,9 +26,12 @@ async function getDappsObjectId(
22
26
  network: 'mainnet' | 'testnet' | 'devnet' | 'localnet'
23
27
  ) {
24
28
  switch (network) {
25
- case "localnet": {
29
+ case 'localnet': {
26
30
  const path = process.cwd();
27
- return await getSchemaHub(`${path}/contracts/dubhe-framework`, network)
31
+ return await getSchemaHub(
32
+ `${path}/contracts/dubhe-framework`,
33
+ network
34
+ );
28
35
  }
29
36
  case 'testnet':
30
37
  return '0x8dbf8d28ac027ba214c9e0951b09f6842843be6cb87242b7d9a326a2677cd47a';
@@ -33,12 +40,18 @@ async function getDappsObjectId(
33
40
  }
34
41
  }
35
42
 
36
- function removeEnvContent(filePath: string, networkType: 'mainnet' | 'testnet' | 'devnet' | 'localnet'): void {
43
+ function removeEnvContent(
44
+ filePath: string,
45
+ networkType: 'mainnet' | 'testnet' | 'devnet' | 'localnet'
46
+ ): void {
37
47
  if (!fs.existsSync(filePath)) {
38
48
  return;
39
49
  }
40
50
  const content = fs.readFileSync(filePath, 'utf-8');
41
- const regex = new RegExp(`\\[env\\.${networkType}\\][\\s\\S]*?(?=\\[|$)`, 'g');
51
+ const regex = new RegExp(
52
+ `\\[env\\.${networkType}\\][\\s\\S]*?(?=\\[|$)`,
53
+ 'g'
54
+ );
42
55
  const updatedContent = content.replace(regex, '');
43
56
  fs.writeFileSync(filePath, updatedContent, 'utf-8');
44
57
  }
@@ -56,12 +69,20 @@ const chainIds: { [key: string]: string } = {
56
69
  mainnet: '35834a8a',
57
70
  };
58
71
 
59
- function updateEnvFile(filePath: string, networkType: 'mainnet' | 'testnet' | 'devnet' | 'localnet', operation: 'publish' | 'upgrade', chainId: string, publishedId: string): void {
72
+ function updateEnvFile(
73
+ filePath: string,
74
+ networkType: 'mainnet' | 'testnet' | 'devnet' | 'localnet',
75
+ operation: 'publish' | 'upgrade',
76
+ chainId: string,
77
+ publishedId: string
78
+ ): void {
60
79
  const envFilePath = path.resolve(filePath);
61
80
  const envContent = fs.readFileSync(envFilePath, 'utf-8');
62
81
  const envLines = envContent.split('\n');
63
82
 
64
- const networkSectionIndex = envLines.findIndex(line => line.trim() === `[env.${networkType}]`);
83
+ const networkSectionIndex = envLines.findIndex(
84
+ line => line.trim() === `[env.${networkType}]`
85
+ );
65
86
  const config: EnvConfig = {
66
87
  chainId: chainId,
67
88
  originalPublishedId: '',
@@ -76,14 +97,18 @@ function updateEnvFile(filePath: string, networkType: 'mainnet' | 'testnet' | 'd
76
97
  config.latestPublishedId = publishedId;
77
98
  config.publishedVersion = 1;
78
99
  } else {
79
- throw new Error(`Network type [env.${networkType}] not found in the file and cannot upgrade.`);
100
+ throw new Error(
101
+ `Network type [env.${networkType}] not found in the file and cannot upgrade.`
102
+ );
80
103
  }
81
104
  } else {
82
105
  for (let i = networkSectionIndex + 1; i < envLines.length; i++) {
83
106
  const line = envLines[i].trim();
84
107
  if (line.startsWith('[')) break; // End of the current network section
85
108
 
86
- const [key, value] = line.split('=').map(part => part.trim().replace(/"/g, ''));
109
+ const [key, value] = line
110
+ .split('=')
111
+ .map(part => part.trim().replace(/"/g, ''));
87
112
  switch (key) {
88
113
  case 'original-published-id':
89
114
  config.originalPublishedId = value;
@@ -115,9 +140,11 @@ latest-published-id = "${config.latestPublishedId}"
115
140
  published-version = "${config.publishedVersion}"
116
141
  `;
117
142
 
118
- const newEnvContent = networkSectionIndex === -1
119
- ? envContent + updatedSection
120
- : envLines.slice(0, networkSectionIndex).join('\n') + updatedSection;
143
+ const newEnvContent =
144
+ networkSectionIndex === -1
145
+ ? envContent + updatedSection
146
+ : envLines.slice(0, networkSectionIndex).join('\n') +
147
+ updatedSection;
121
148
 
122
149
  fs.writeFileSync(envFilePath, newEnvContent, 'utf-8');
123
150
  }
@@ -137,7 +164,7 @@ function getLastSegment(input: string): string {
137
164
  return segments.length > 0 ? segments[segments.length - 1] : '';
138
165
  }
139
166
 
140
- function buildContract(projectPath: string): string[][] {
167
+ function buildContract(projectPath: string): string[][] {
141
168
  let modules: any, dependencies: any;
142
169
  try {
143
170
  const buildResult = JSON.parse(
@@ -145,6 +172,7 @@ function buildContract(projectPath: string): string[][] {
145
172
  `sui move build --dump-bytecode-as-base64 --path ${projectPath}`,
146
173
  {
147
174
  encoding: 'utf-8',
175
+ stdio: 'pipe',
148
176
  }
149
177
  )
150
178
  );
@@ -167,7 +195,7 @@ async function publishContract(
167
195
  projectPath: string
168
196
  ) {
169
197
  const dappsObjectId = await getDappsObjectId(network);
170
- console.log("dappsObjectId", dappsObjectId);
198
+ console.log('dappsObjectId', dappsObjectId);
171
199
  const chainId = await client.getChainIdentifier();
172
200
  removeEnvContent(`${projectPath}/Move.lock`, network);
173
201
  console.log('\nšŸš€ Starting Contract Publication...');
@@ -226,7 +254,7 @@ async function publishContract(
226
254
  }
227
255
  if (
228
256
  object.type === 'created' &&
229
- object.objectType.includes("schema_hub")
257
+ object.objectType.includes('schema_hub')
230
258
  ) {
231
259
  console.log(` ā”œā”€ Schema Hub: ${object.objectId}`);
232
260
  schemaHubId = object.objectId;
@@ -235,14 +263,20 @@ async function publishContract(
235
263
 
236
264
  console.log(` └─ Transaction: ${result.digest}`);
237
265
 
238
- updateEnvFile(`${projectPath}/Move.lock`, network, 'publish', chainId, packageId);
266
+ updateEnvFile(
267
+ `${projectPath}/Move.lock`,
268
+ network,
269
+ 'publish',
270
+ chainId,
271
+ packageId
272
+ );
239
273
 
240
274
  console.log('\n⚔ Executing Deploy Hook...');
241
275
  await delay(5000);
242
276
 
243
277
  const deployHookTx = new Transaction();
244
278
  deployHookTx.setGasBudget(2000000000);
245
- const [txCoin] = deployHookTx.splitCoins(deployHookTx.gas, ["1000000000"]);
279
+ const [txCoin] = deployHookTx.splitCoins(deployHookTx.gas, ['1000000000']);
246
280
  deployHookTx.moveCall({
247
281
  target: `${packageId}::deploy_hook::run`,
248
282
  arguments: [
@@ -250,7 +284,7 @@ async function publishContract(
250
284
  deployHookTx.object(dappsObjectId),
251
285
  deployHookTx.object(upgradeCapId),
252
286
  deployHookTx.object('0x6'),
253
- txCoin
287
+ txCoin,
254
288
  ],
255
289
  });
256
290
 
@@ -275,14 +309,18 @@ async function publishContract(
275
309
  deployHookResult.objectChanges?.map(object => {
276
310
  if (
277
311
  object.type === 'created' &&
278
- object.objectType.includes('_schema') && !object.objectType.includes("dynamic_field")
312
+ object.objectType.includes('_schema') &&
313
+ !object.objectType.includes('dynamic_field')
279
314
  ) {
280
315
  console.log(` ā”œā”€ ${object.objectType}`);
281
316
  console.log(` └─ ID: ${object.objectId}`);
282
317
 
283
318
  let structure: Record<string, string> = {};
284
319
  for (let schemaKey in dubheConfig.schemas) {
285
- if (capitalizeAndRemoveUnderscores(schemaKey) === getLastSegment(object.objectType)) {
320
+ if (
321
+ capitalizeAndRemoveUnderscores(schemaKey) ===
322
+ getLastSegment(object.objectType)
323
+ ) {
286
324
  structure = dubheConfig.schemas[schemaKey].structure;
287
325
  }
288
326
  }
@@ -302,7 +340,7 @@ async function publishContract(
302
340
  upgradeCapId,
303
341
  schemaHubId,
304
342
  version,
305
- schemas,
343
+ schemas
306
344
  );
307
345
  console.log('\nāœ… Contract Publication Complete\n');
308
346
  } else {
@@ -315,10 +353,10 @@ async function publishContract(
315
353
  }
316
354
  }
317
355
 
318
- async function publishDubheFramework(
356
+ export async function publishDubheFramework(
319
357
  client: SuiClient,
320
358
  dubhe: Dubhe,
321
- network: 'mainnet' | 'testnet' | 'devnet' | 'localnet',
359
+ network: 'mainnet' | 'testnet' | 'devnet' | 'localnet'
322
360
  ) {
323
361
  const path = process.cwd();
324
362
  const projectPath = `${path}/contracts/dubhe-framework`;
@@ -334,7 +372,6 @@ async function publishDubheFramework(
334
372
  const keypair = dubhe.getKeypair();
335
373
  console.log(` └─ Account: ${keypair.toSuiAddress()}`);
336
374
 
337
-
338
375
  console.log('\nšŸ“¦ Building Contract...');
339
376
  const [modules, dependencies] = buildContract(projectPath);
340
377
 
@@ -380,10 +417,7 @@ async function publishDubheFramework(
380
417
  console.log(` ā”œā”€ Upgrade Cap: ${object.objectId}`);
381
418
  upgradeCapId = object.objectId;
382
419
  }
383
- if (
384
- object.type === 'created' &&
385
- object.objectType.includes("dapps")
386
- ) {
420
+ if (object.type === 'created' && object.objectType.includes('dapps')) {
387
421
  console.log(` ā”œā”€ Dapps: ${object.objectId}`);
388
422
  schemaHubId = object.objectId;
389
423
  }
@@ -391,23 +425,29 @@ async function publishDubheFramework(
391
425
 
392
426
  console.log(` └─ Transaction: ${result.digest}`);
393
427
 
394
- updateEnvFile(`${projectPath}/Move.lock`, network, 'publish', chainId, packageId);
428
+ updateEnvFile(
429
+ `${projectPath}/Move.lock`,
430
+ network,
431
+ 'publish',
432
+ chainId,
433
+ packageId
434
+ );
395
435
 
396
436
  saveContractData(
397
- "dubhe-framework",
437
+ 'dubhe-framework',
398
438
  network,
399
439
  packageId,
400
440
  upgradeCapId,
401
441
  schemaHubId,
402
442
  version,
403
- schemas,
443
+ schemas
404
444
  );
405
445
  }
406
446
 
407
447
  export async function publishHandler(
408
448
  dubheConfig: DubheConfig,
409
449
  network: 'mainnet' | 'testnet' | 'devnet' | 'localnet',
410
- contractName?: string,
450
+ contractName?: string
411
451
  ) {
412
452
  await switchEnv(network);
413
453
 
@@ -427,7 +467,7 @@ in your contracts directory to use the default sui private key.`
427
467
  const dubhe = new Dubhe({ secretKey: privateKeyFormat });
428
468
  const client = new SuiClient({ url: getFullnodeUrl(network) });
429
469
 
430
- if (contractName == "dubhe-framework") {
470
+ if (contractName == 'dubhe-framework') {
431
471
  await publishDubheFramework(client, dubhe, network);
432
472
  } else {
433
473
  const path = process.cwd();