@0xobelisk/sui-cli 1.1.4 → 1.1.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xobelisk/sui-cli",
3
- "version": "1.1.4",
3
+ "version": "1.1.5",
4
4
  "description": "Tookit for interacting with move eps framework",
5
5
  "keywords": [
6
6
  "sui",
@@ -49,8 +49,8 @@
49
49
  "yargs": "^17.7.1",
50
50
  "zod": "^3.22.3",
51
51
  "zod-validation-error": "^1.3.0",
52
- "@0xobelisk/sui-client": "1.1.4",
53
- "@0xobelisk/sui-common": "1.1.5"
52
+ "@0xobelisk/sui-common": "1.1.6",
53
+ "@0xobelisk/sui-client": "1.1.4"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@types/ejs": "^3.1.1",
@@ -2,9 +2,7 @@ import type { CommandModule } from 'yargs';
2
2
  import { execSync } from 'child_process';
3
3
  import chalk from 'chalk';
4
4
  import { DubheConfig, loadConfig } from '@0xobelisk/sui-common';
5
- import { switchEnv } from '../utils';
6
- import {generateCargoToml} from "./install";
7
- import {writeFileSync} from "fs";
5
+ import { switchEnv, updateDubheDependency } from '../utils';
8
6
 
9
7
  type Options = {
10
8
  'config-path': string;
@@ -48,8 +46,7 @@ const commandModule: CommandModule<Options, Options> = {
48
46
  const path = process.cwd();
49
47
  const projectPath = `${path}/contracts/${dubheConfig.name}`;
50
48
  await switchEnv(network);
51
- const cargoTomlContent = generateCargoToml(dubheConfig.dependencies, dubheConfig.name, network);
52
- writeFileSync(`${projectPath}/Move.toml`, cargoTomlContent, { encoding: 'utf-8' });
49
+ await updateDubheDependency(projectPath + '/Move.toml', network);
53
50
  const command = `sui move build --path ${projectPath} ${
54
51
  dumpBytecodeAsBase64 ? ` --dump-bytecode-as-base64` : ''
55
52
  }`;
@@ -15,7 +15,6 @@ import query from './query';
15
15
  import call from './call';
16
16
  import indexer from './indexer';
17
17
  import watch from './watch';
18
- import install from "./install";
19
18
 
20
19
  // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Each command has different options
21
20
  export const commands: CommandModule<any, any>[] = [
@@ -34,5 +33,4 @@ export const commands: CommandModule<any, any>[] = [
34
33
  configStore,
35
34
  indexer,
36
35
  watch,
37
- install
38
36
  ];
@@ -1,33 +1,18 @@
1
1
  import type { CommandModule } from 'yargs';
2
2
  import { startLocalNode } from '../utils/startNode';
3
- import {DubheConfig, loadConfig} from "@0xobelisk/sui-common";
4
- import {dubheInstall} from "./install";
5
3
 
6
- type Options = {
7
- 'config-path': string;
8
- };
9
-
10
- const commandModule: CommandModule<Options, Options> = {
4
+ const commandModule: CommandModule = {
11
5
  command: 'node',
12
6
 
13
7
  describe: 'Manage local Sui node',
14
8
 
15
9
  builder(yargs) {
16
10
  return yargs
17
- .options({
18
- 'config-path': {
19
- type: 'string',
20
- default: 'dubhe.config.ts',
21
- description: 'Path to the configuration file',
22
- },
23
- })
24
11
  },
25
12
 
26
- async handler({ 'config-path': configPath }) {
13
+ async handler() {
27
14
  try {
28
- const dubheConfig = (await loadConfig(configPath)) as DubheConfig;
29
- await dubheInstall(dubheConfig, 'localnet');
30
- await startLocalNode(dubheConfig);
15
+ await startLocalNode();
31
16
  } catch (error) {
32
17
  console.error('Error executing command:', error);
33
18
  process.exit(1);
@@ -5,15 +5,13 @@ import { DubheCliError } from './errors';
5
5
  import {
6
6
  saveContractData,
7
7
  validatePrivateKey,
8
+ updateDubheDependency,
8
9
  switchEnv,
9
10
  delay,
10
11
  } from './utils';
11
12
  import { DubheConfig } from '@0xobelisk/sui-common';
12
13
  import * as fs from 'fs';
13
14
  import * as path from 'path';
14
- import {homedir} from "node:os";
15
- import {generateCargoToml, getRepoNameFromUrl} from "../commands/install";
16
- import {writeFileSync} from "fs";
17
15
 
18
16
  async function removeEnvContent(
19
17
  filePath: string,
@@ -289,88 +287,116 @@ async function publishContract(
289
287
  }
290
288
  }
291
289
 
290
+ async function checkDubheFramework(projectPath: string): Promise<boolean> {
291
+ if (!fs.existsSync(projectPath)) {
292
+ console.log(chalk.yellow('\nℹ️ Dubhe Framework Files Not Found'));
293
+ console.log(chalk.yellow(' ├─ Expected Path:'), projectPath);
294
+ console.log(chalk.yellow(' ├─ To set up Dubhe Framework:'));
295
+ console.log(
296
+ chalk.yellow(
297
+ ' │ 1. Create directory: mkdir -p contracts/dubhe-framework'
298
+ )
299
+ );
300
+ console.log(
301
+ chalk.yellow(
302
+ ' │ 2. Clone repository: git clone https://github.com/0xobelisk/dubhe-framework contracts/dubhe-framework'
303
+ )
304
+ );
305
+ console.log(
306
+ chalk.yellow(
307
+ ' │ 3. Or download from: https://github.com/0xobelisk/dubhe-framework'
308
+ )
309
+ );
310
+ console.log(chalk.yellow(' └─ After setup, restart the local node'));
311
+ return false;
312
+ }
313
+ return true;
314
+ }
315
+
292
316
  export async function publishDubheFramework(
293
- dubheConfig: DubheConfig,
294
317
  dubhe: Dubhe,
295
318
  network: 'mainnet' | 'testnet' | 'devnet' | 'localnet'
296
319
  ) {
320
+ const path = process.cwd();
321
+ const projectPath = `${path}/contracts/dubhe-framework`;
322
+
323
+ if (!(await checkDubheFramework(projectPath))) {
324
+ console.log(chalk.yellow('\n❗ Framework Deployment Skipped'));
325
+ return;
326
+ }
327
+
328
+ // const chainId = await client.getChainIdentifier();
297
329
  const chainId =
298
330
  await dubhe.suiInteractor.currentClient.getChainIdentifier();
299
- for (const dependency of dubheConfig.dependencies) {
300
- const projectName = getRepoNameFromUrl(dependency.git);
301
- let projectPath = `${homedir()}/.dubhe/dependencies/${projectName}`
302
- if (dependency.subdir) {
303
- projectPath += `/${dependency.subdir}`;
304
- }
305
- console.log(`\n🚀 Initialize dependencies...`);
306
- console.log(` ├─ Project: ${projectPath}`);
307
- if (!fs.existsSync(projectPath)) {
308
- console.log(chalk.yellow('\nℹ️ Please install Dubhe Framework'));
309
- console.log(chalk.yellow('\nℹ️ Execute the following command:'));
310
- console.log(chalk.yellow(`pnpm dubhe install`));
311
- continue;
312
- }
331
+ await removeEnvContent(`${projectPath}/Move.lock`, network);
332
+ console.log('\n🚀 Starting Contract Publication...');
333
+ console.log(` ├─ Project: ${projectPath}`);
334
+ console.log(` ├─ Network: ${network}`);
313
335
 
314
- await removeEnvContent(`${projectPath}/Move.lock`, network);
315
- const [modules, dependencies] = buildContract(projectPath);
336
+ console.log(` └─ Account: ${dubhe.getAddress()}`);
316
337
 
317
- const tx = new Transaction();
318
- const [upgradeCap] = tx.publish({ modules, dependencies });
319
- tx.transferObjects([upgradeCap], dubhe.getAddress());
338
+ console.log('\n📦 Building Contract...');
339
+ const [modules, dependencies] = buildContract(projectPath);
320
340
 
321
- let result;
322
- try {
323
- result = await dubhe.signAndSendTxn({ tx });
324
- } catch (error: any) {
325
- console.error(chalk.red(' └─ Publication failed'));
326
- console.error(error.message);
327
- process.exit(1);
328
- }
341
+ console.log('\n🔄 Publishing Contract...');
342
+ const tx = new Transaction();
343
+ const [upgradeCap] = tx.publish({ modules, dependencies });
344
+ tx.transferObjects([upgradeCap], dubhe.getAddress());
329
345
 
330
- if (result.effects?.status.status === 'failure') {
331
- console.log(chalk.red(' └─ Publication failed'));
332
- process.exit(1);
333
- }
346
+ let result;
347
+ try {
348
+ result = await dubhe.signAndSendTxn({ tx });
349
+ } catch (error: any) {
350
+ console.error(chalk.red(' └─ Publication failed'));
351
+ console.error(error.message);
352
+ process.exit(1);
353
+ }
334
354
 
335
- result.objectChanges!.map(async object => {
336
- if (object.type === 'published') {
337
- console.log(` ├─ Package ID: ${object.packageId}`);
338
- updateEnvFile(
339
- `${projectPath}/Move.lock`,
340
- network,
341
- 'publish',
342
- chainId,
343
- object.packageId
344
- );
345
-
346
- if (dependency.name === 'merak') {
347
- await delay(2000);
348
- const deployHookTx = new Transaction();
349
- deployHookTx.moveCall({
350
- target: `${object.packageId}::genesis::run`,
351
- arguments: [deployHookTx.object('0x6')],
352
- });
353
-
354
- let deployHookResult;
355
- try {
356
- deployHookResult = await dubhe.signAndSendTxn({tx: deployHookTx});
357
- } catch (error: any) {
358
- console.error(chalk.red(' └─ Deploy hook execution failed'));
359
- console.error(error.message);
360
- process.exit(1);
361
- }
362
-
363
- if (deployHookResult.effects?.status.status === 'success') {
364
- deployHookResult.objectChanges?.map(object => {
365
- if (object.type === 'created' && object.objectType.includes('schema::Schema')) {
366
- console.log(` ├─ Schema ID: ${object.objectId}`);
367
- }
368
- });
369
- }
370
- }
371
- }
372
- });
355
+ if (result.effects?.status.status === 'failure') {
356
+ console.log(chalk.red(' └─ Publication failed'));
357
+ process.exit(1);
373
358
  }
359
+
360
+ let version = 1;
361
+ let packageId = '';
362
+ let schemas: Record<string, string> = {};
363
+ let upgradeCapId = '';
364
+
365
+ result.objectChanges!.map(object => {
366
+ if (object.type === 'published') {
367
+ console.log(` ├─ Package ID: ${object.packageId}`);
368
+ packageId = object.packageId;
369
+ }
370
+ if (
371
+ object.type === 'created' &&
372
+ object.objectType === '0x2::package::UpgradeCap'
373
+ ) {
374
+ console.log(` ├─ Upgrade Cap: ${object.objectId}`);
375
+ upgradeCapId = object.objectId;
376
+ }
377
+ });
378
+
379
+ console.log(` └─ Transaction: ${result.digest}`);
380
+
381
+ updateEnvFile(
382
+ `${projectPath}/Move.lock`,
383
+ network,
384
+ 'publish',
385
+ chainId,
386
+ packageId
387
+ );
388
+
389
+ saveContractData(
390
+ 'dubhe-framework',
391
+ network,
392
+ packageId,
393
+ '',
394
+ upgradeCapId,
395
+ version,
396
+ schemas
397
+ );
398
+ await delay(1000);
399
+ console.log(chalk.green('\n✅ Dubhe Framework deployed successfully'));
374
400
  }
375
401
 
376
402
  export async function publishHandler(
@@ -398,10 +424,12 @@ in your contracts directory to use the default sui private key.`
398
424
  networkType: network,
399
425
  });
400
426
 
427
+ if (network === 'localnet') {
428
+ await publishDubheFramework(dubhe, network);
429
+ }
430
+
401
431
  const path = process.cwd();
402
432
  const projectPath = `${path}/contracts/${dubheConfig.name}`;
403
- const cargoTomlContent = generateCargoToml(dubheConfig.dependencies, dubheConfig.name, network);
404
- writeFileSync(`${projectPath}/Move.toml`, cargoTomlContent, { encoding: 'utf-8' });
405
-
433
+ await updateDubheDependency(`${projectPath}/Move.toml`, network);
406
434
  await publishContract(dubhe, dubheConfig, network, projectPath, gasBudget);
407
435
  }
@@ -1,9 +1,8 @@
1
1
  import { execSync, spawn } from 'child_process';
2
2
  import chalk from 'chalk';
3
3
  import { printDubhe } from './printDubhe';
4
- import {delay, DubheCliError, publishDubheFramework, validatePrivateKey} from '../utils';
4
+ import { delay, DubheCliError, validatePrivateKey } from '../utils';
5
5
  import { Dubhe } from '@0xobelisk/sui-client';
6
- import {DubheConfig} from "@0xobelisk/sui-common";
7
6
 
8
7
  function isSuiStartRunning(): boolean {
9
8
  try {
@@ -71,7 +70,7 @@ async function printAccounts() {
71
70
  )
72
71
  );
73
72
  }
74
- export async function startLocalNode(dubheConfig: DubheConfig) {
73
+ export async function startLocalNode() {
75
74
  if (isSuiStartRunning()) {
76
75
  console.log(chalk.yellow('\n⚠️ Warning: Local Node Already Running'));
77
76
  console.log(chalk.yellow(' ├─ Cannot start a new instance'));
@@ -103,6 +102,7 @@ export async function startLocalNode(dubheConfig: DubheConfig) {
103
102
  console.log(' └─ Force Regenesis: Yes');
104
103
  console.log(' └─ HTTP server: http://127.0.0.1:9000/');
105
104
  console.log(' └─ Faucet server: http://127.0.0.1:9123/');
105
+
106
106
  await printAccounts();
107
107
 
108
108
  await delay(2000);
@@ -114,13 +114,7 @@ export async function startLocalNode(dubheConfig: DubheConfig) {
114
114
  throw new DubheCliError(`Please check your privateKey.`);
115
115
  }
116
116
 
117
- console.log(chalk.green('🎉 Local environment is ready!'))
118
- const dubhe = new Dubhe({
119
- secretKey: privateKeyFormat,
120
- networkType: "localnet",
121
- });
122
-
123
- await publishDubheFramework(dubheConfig, dubhe, 'localnet');
117
+ console.log(chalk.green('🎉 Local environment is ready!'));
124
118
 
125
119
  process.on('SIGINT', () => {
126
120
  console.log(chalk.yellow('\n🔔 Stopping Local Node...'));
@@ -135,4 +129,4 @@ export async function startLocalNode(dubheConfig: DubheConfig) {
135
129
  console.error(chalk.red(` └─ Error: ${error.message}`));
136
130
  process.exit(1);
137
131
  }
138
- }
132
+ }
@@ -1,126 +0,0 @@
1
- import type { CommandModule } from 'yargs';
2
- import { execSync } from 'child_process';
3
- import { DubheConfig, loadConfig } from '@0xobelisk/sui-common';
4
- import {existsSync, writeFileSync} from 'fs';
5
- import {homedir} from "node:os";
6
- import {join} from "path";
7
- import {readFileSync} from "node:fs";
8
-
9
- type Options = {
10
- 'config-path': string;
11
- network: any;
12
- };
13
-
14
- export function getRepoNameFromUrl(url: string): string {
15
- // Split the URL by '/' and filter out empty strings
16
- const parts = url.split('/').filter(part => part.length > 0);
17
-
18
- // Get the last part and remove any ${} syntax if present
19
- const lastPart = parts[parts.length - 1];
20
- return lastPart.replace(/^\${(.*)}$/, '$1');
21
- }
22
-
23
- export function generateCargoToml(
24
- dependencies: DubheConfig['dependencies'],
25
- projectName: string,
26
- network: 'mainnet' | 'testnet' | 'devnet' | 'localnet'
27
- ): string {
28
- let cargoToml = `[package]\nname = "${projectName}"\nversion = "1.0.0"\nedition = "2024"\n\n[dependencies]\n`;
29
- cargoToml += `Sui = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/sui-framework", rev = "mainnet-v1.38.3" }\n`;
30
-
31
- if (network === 'localnet') {
32
- const dubhePath = `${homedir()}/.dubhe/dependencies/dubhe-framework`;
33
- cargoToml += `Dubhe = { local = "${dubhePath}" }\n`;
34
-
35
- dependencies.forEach(dep => {
36
- const repoName = getRepoNameFromUrl(dep.git);
37
- if (dep.name && dep.name.toLowerCase() === 'dubhe') {
38
- return;
39
- }
40
-
41
- let localPath = `${homedir()}/.dubhe/dependencies/${repoName}`;
42
- if (dep.subdir) {
43
- localPath += `/${dep.subdir}`;
44
- }
45
- const depName = dep.name || repoName;
46
- cargoToml += `${depName} = { local = "${localPath}" }\n`;
47
-
48
- const moveTomlPath = join(localPath, 'Move.toml');
49
- if (existsSync(moveTomlPath)) {
50
- try {
51
- let moveTomlContent = readFileSync(moveTomlPath, 'utf-8');
52
- const dubheRegex = /Dubhe\s*=\s*{[^}]*}/g;
53
- if (moveTomlContent.match(dubheRegex)) {
54
- moveTomlContent = moveTomlContent.replace(
55
- dubheRegex,
56
- `Dubhe = { local = "${dubhePath}" }`
57
- );
58
- writeFileSync(moveTomlPath, moveTomlContent, 'utf-8');
59
- }
60
- } catch (error) {
61
- console.error(`Failed to update Move.toml at ${moveTomlPath}: ${error}`);
62
- }
63
- }
64
- });
65
- } else {
66
- dependencies.forEach(dep => {
67
- const repoName = getRepoNameFromUrl(dep.git);
68
- const depName = dep.name || repoName;
69
- cargoToml += `${depName} = { git = "${dep.git}", rev = "${dep.rev}"`;
70
- if (dep.subdir) {
71
- cargoToml += `, subdir = "${dep.subdir}"`;
72
- }
73
- cargoToml += ` }\n`;
74
- });
75
- }
76
- cargoToml += `\n[addresses]\nsui = "0x2"\n${projectName} = "0x0"\n`;
77
- return cargoToml;
78
- }
79
-
80
- const commandModule: CommandModule<Options, Options> = {
81
- command: 'install',
82
- describe: 'Install a repository in Dubhe contracts',
83
- builder(yargs) {
84
- return yargs
85
- .options({
86
- 'config-path': {
87
- type: 'string',
88
- default: 'dubhe.config.ts',
89
- description: 'Path to the configuration file',
90
- },
91
- }).options({
92
- 'network': {
93
- type: 'string',
94
- default: 'localnet',
95
- description: 'Path to the configuration file',
96
- },
97
- });
98
-
99
- },
100
- async handler({ 'config-path': configPath, network }) {
101
- try {
102
- const dubheConfig = (await loadConfig(configPath)) as DubheConfig;
103
- await dubheInstall(dubheConfig, network);
104
- } catch (error: any) {
105
- console.error(`Error installing repository: ${error.message}`);
106
- process.exit(1);
107
- }
108
- },
109
- };
110
-
111
- export async function dubheInstall(dubheConfig: DubheConfig, network: 'mainnet' | 'testnet' | 'devnet' | 'localnet') {
112
- dubheConfig.dependencies.forEach(dependency => {
113
- const projectName = getRepoNameFromUrl(dependency.git);
114
- const dependencyPath = join(homedir(), '.dubhe', 'dependencies', projectName);
115
- if (!existsSync(dependencyPath)) {
116
- console.log(`🚀 Installing repository: ${dependency.git}`);
117
- const command = `git clone --depth 1 --branch ${dependency.rev} ${dependency.git} ${dependencyPath}`;
118
- execSync(command, { stdio: 'inherit', encoding: 'utf-8' });
119
- }
120
- });
121
- const cargoTomlContent = generateCargoToml(dubheConfig.dependencies, dubheConfig.name, network);
122
- const projectPath = `${process.cwd()}/contracts/${dubheConfig.name}/Move.toml`;
123
- writeFileSync(projectPath, cargoTomlContent, { encoding: 'utf-8' });
124
- }
125
-
126
- export default commandModule;