@0xobelisk/sui-cli 1.1.4 → 1.1.6

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.
@@ -3,105 +3,96 @@ import { execSync } from 'child_process';
3
3
  import chalk from 'chalk';
4
4
  import { DubheCliError } from './errors';
5
5
  import {
6
- saveContractData,
7
- validatePrivateKey,
8
- switchEnv,
9
- delay,
6
+ saveContractData,
7
+ validatePrivateKey,
8
+ updateDubheDependency,
9
+ switchEnv,
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
- filePath: string,
20
- networkType: 'mainnet' | 'testnet' | 'devnet' | 'localnet'
17
+ filePath: string,
18
+ networkType: 'mainnet' | 'testnet' | 'devnet' | 'localnet'
21
19
  ): Promise<void> {
22
- if (!fs.existsSync(filePath)) {
23
- return;
24
- }
25
- const content = fs.readFileSync(filePath, 'utf-8');
26
- const regex = new RegExp(
27
- `\\[env\\.${networkType}\\][\\s\\S]*?(?=\\[|$)`,
28
- 'g'
29
- );
30
- const updatedContent = content.replace(regex, '');
31
- fs.writeFileSync(filePath, updatedContent, 'utf-8');
20
+ if (!fs.existsSync(filePath)) {
21
+ return;
22
+ }
23
+ const content = fs.readFileSync(filePath, 'utf-8');
24
+ const regex = new RegExp(`\\[env\\.${networkType}\\][\\s\\S]*?(?=\\[|$)`, 'g');
25
+ const updatedContent = content.replace(regex, '');
26
+ fs.writeFileSync(filePath, updatedContent, 'utf-8');
32
27
  }
33
28
 
34
29
  interface EnvConfig {
35
- chainId: string;
36
- originalPublishedId: string;
37
- latestPublishedId: string;
38
- publishedVersion: number;
30
+ chainId: string;
31
+ originalPublishedId: string;
32
+ latestPublishedId: string;
33
+ publishedVersion: number;
39
34
  }
40
35
 
41
36
  function updateEnvFile(
42
- filePath: string,
43
- networkType: 'mainnet' | 'testnet' | 'devnet' | 'localnet',
44
- operation: 'publish' | 'upgrade',
45
- chainId: string,
46
- publishedId: string
37
+ filePath: string,
38
+ networkType: 'mainnet' | 'testnet' | 'devnet' | 'localnet',
39
+ operation: 'publish' | 'upgrade',
40
+ chainId: string,
41
+ publishedId: string
47
42
  ): void {
48
- const envFilePath = path.resolve(filePath);
49
- const envContent = fs.readFileSync(envFilePath, 'utf-8');
50
- const envLines = envContent.split('\n');
51
-
52
- const networkSectionIndex = envLines.findIndex(
53
- line => line.trim() === `[env.${networkType}]`
54
- );
55
- const config: EnvConfig = {
56
- chainId: chainId,
57
- originalPublishedId: '',
58
- latestPublishedId: '',
59
- publishedVersion: 0,
60
- };
61
-
62
- if (networkSectionIndex === -1) {
63
- // If network section is not found, add a new section
64
- if (operation === 'publish') {
65
- config.originalPublishedId = publishedId;
66
- config.latestPublishedId = publishedId;
67
- config.publishedVersion = 1;
68
- } else {
69
- throw new Error(
70
- `Network type [env.${networkType}] not found in the file and cannot upgrade.`
71
- );
72
- }
73
- } else {
74
- for (let i = networkSectionIndex + 1; i < envLines.length; i++) {
75
- const line = envLines[i].trim();
76
- if (line.startsWith('[')) break; // End of the current network section
77
-
78
- const [key, value] = line
79
- .split('=')
80
- .map(part => part.trim().replace(/"/g, ''));
81
- switch (key) {
82
- case 'original-published-id':
83
- config.originalPublishedId = value;
84
- break;
85
- case 'latest-published-id':
86
- config.latestPublishedId = value;
87
- break;
88
- case 'published-version':
89
- config.publishedVersion = parseInt(value, 10);
90
- break;
91
- }
92
- }
93
-
94
- if (operation === 'publish') {
95
- config.originalPublishedId = publishedId;
96
- config.latestPublishedId = publishedId;
97
- config.publishedVersion = 1;
98
- } else if (operation === 'upgrade') {
99
- config.latestPublishedId = publishedId;
100
- config.publishedVersion += 1;
101
- }
102
- }
103
-
104
- const updatedSection = `
43
+ const envFilePath = path.resolve(filePath);
44
+ const envContent = fs.readFileSync(envFilePath, 'utf-8');
45
+ const envLines = envContent.split('\n');
46
+
47
+ const networkSectionIndex = envLines.findIndex((line) => line.trim() === `[env.${networkType}]`);
48
+ const config: EnvConfig = {
49
+ chainId: chainId,
50
+ originalPublishedId: '',
51
+ latestPublishedId: '',
52
+ publishedVersion: 0
53
+ };
54
+
55
+ if (networkSectionIndex === -1) {
56
+ // If network section is not found, add a new section
57
+ if (operation === 'publish') {
58
+ config.originalPublishedId = publishedId;
59
+ config.latestPublishedId = publishedId;
60
+ config.publishedVersion = 1;
61
+ } else {
62
+ throw new Error(
63
+ `Network type [env.${networkType}] not found in the file and cannot upgrade.`
64
+ );
65
+ }
66
+ } else {
67
+ for (let i = networkSectionIndex + 1; i < envLines.length; i++) {
68
+ const line = envLines[i].trim();
69
+ if (line.startsWith('[')) break; // End of the current network section
70
+
71
+ const [key, value] = line.split('=').map((part) => part.trim().replace(/"/g, ''));
72
+ switch (key) {
73
+ case 'original-published-id':
74
+ config.originalPublishedId = value;
75
+ break;
76
+ case 'latest-published-id':
77
+ config.latestPublishedId = value;
78
+ break;
79
+ case 'published-version':
80
+ config.publishedVersion = parseInt(value, 10);
81
+ break;
82
+ }
83
+ }
84
+
85
+ if (operation === 'publish') {
86
+ config.originalPublishedId = publishedId;
87
+ config.latestPublishedId = publishedId;
88
+ config.publishedVersion = 1;
89
+ } else if (operation === 'upgrade') {
90
+ config.latestPublishedId = publishedId;
91
+ config.publishedVersion += 1;
92
+ }
93
+ }
94
+
95
+ const updatedSection = `
105
96
  [env.${networkType}]
106
97
  chain-id = "${config.chainId}"
107
98
  original-published-id = "${config.originalPublishedId}"
@@ -109,13 +100,12 @@ latest-published-id = "${config.latestPublishedId}"
109
100
  published-version = "${config.publishedVersion}"
110
101
  `;
111
102
 
112
- const newEnvContent =
113
- networkSectionIndex === -1
114
- ? envContent + updatedSection
115
- : envLines.slice(0, networkSectionIndex).join('\n') +
116
- updatedSection;
103
+ const newEnvContent =
104
+ networkSectionIndex === -1
105
+ ? envContent + updatedSection
106
+ : envLines.slice(0, networkSectionIndex).join('\n') + updatedSection;
117
107
 
118
- fs.writeFileSync(envFilePath, newEnvContent, 'utf-8');
108
+ fs.writeFileSync(envFilePath, newEnvContent, 'utf-8');
119
109
  }
120
110
  // function capitalizeAndRemoveUnderscores(input: string): string {
121
111
  // return input
@@ -134,274 +124,263 @@ published-version = "${config.publishedVersion}"
134
124
  // }
135
125
 
136
126
  function buildContract(projectPath: string): string[][] {
137
- let modules: any, dependencies: any;
138
- try {
139
- const buildResult = JSON.parse(
140
- execSync(
141
- `sui move build --dump-bytecode-as-base64 --path ${projectPath}`,
142
- {
143
- encoding: 'utf-8',
144
- stdio: 'pipe',
145
- }
146
- )
147
- );
148
- modules = buildResult.modules;
149
- dependencies = buildResult.dependencies;
150
- } catch (error: any) {
151
- console.error(chalk.red(' └─ Build failed'));
152
- console.error(error.stdout);
153
- process.exit(1);
154
- }
155
- return [modules, dependencies];
127
+ let modules: any, dependencies: any;
128
+ try {
129
+ const buildResult = JSON.parse(
130
+ execSync(`sui move build --dump-bytecode-as-base64 --path ${projectPath}`, {
131
+ encoding: 'utf-8',
132
+ stdio: 'pipe'
133
+ })
134
+ );
135
+ modules = buildResult.modules;
136
+ dependencies = buildResult.dependencies;
137
+ } catch (error: any) {
138
+ console.error(chalk.red(' └─ Build failed'));
139
+ console.error(error.stdout);
140
+ process.exit(1);
141
+ }
142
+ return [modules, dependencies];
156
143
  }
157
144
 
158
145
  async function publishContract(
159
- dubhe: Dubhe,
160
- dubheConfig: DubheConfig,
161
- network: 'mainnet' | 'testnet' | 'devnet' | 'localnet',
162
- projectPath: string,
163
- gasBudget?: number
146
+ dubhe: Dubhe,
147
+ dubheConfig: DubheConfig,
148
+ network: 'mainnet' | 'testnet' | 'devnet' | 'localnet',
149
+ projectPath: string,
150
+ gasBudget?: number
164
151
  ) {
165
- const chainId =
166
- await dubhe.suiInteractor.currentClient.getChainIdentifier();
167
- await removeEnvContent(`${projectPath}/Move.lock`, network);
168
- console.log('\n🚀 Starting Contract Publication...');
169
- console.log(` ├─ Project: ${projectPath}`);
170
- console.log(` ├─ Network: ${network}`);
171
- console.log(` ├─ ChainId: ${chainId}`);
172
- console.log(' ├─ Validating Environment...');
173
-
174
- console.log(` └─ Account: ${dubhe.getAddress()}`);
175
-
176
- console.log('\n📦 Building Contract...');
177
- const [modules, dependencies] = buildContract(projectPath);
178
-
179
- console.log('\n🔄 Publishing Contract...');
180
- const tx = new Transaction();
181
- if (gasBudget) {
182
- tx.setGasBudget(gasBudget);
183
- }
184
- const [upgradeCap] = tx.publish({ modules, dependencies });
185
- tx.transferObjects([upgradeCap], dubhe.getAddress());
186
-
187
- let result;
188
- try {
189
- result = await dubhe.signAndSendTxn({tx});
190
- } catch (error: any) {
191
- console.error(chalk.red(' └─ Publication failed'));
192
- console.error(error.message);
193
- process.exit(1);
194
- }
195
-
196
- if (result.effects?.status.status === 'failure') {
197
- console.log(chalk.red(' └─ Publication failed'));
198
- process.exit(1);
199
- }
200
-
201
- console.log(' ├─ Processing publication results...');
202
- let version = 1;
203
- let packageId = '';
204
- let schemaId = '';
205
- let schemas = dubheConfig.schemas;
206
- let upgradeCapId = '';
207
-
208
- result.objectChanges!.map(object => {
209
- if (object.type === 'published') {
210
- console.log(` ├─ Package ID: ${object.packageId}`);
211
- packageId = object.packageId;
212
- }
213
- if (
214
- object.type === 'created' &&
215
- object.objectType === '0x2::package::UpgradeCap'
216
- ) {
217
- console.log(` ├─ Upgrade Cap: ${object.objectId}`);
218
- upgradeCapId = object.objectId;
219
- }
220
- });
221
-
222
- console.log(` └─ Transaction: ${result.digest}`);
223
-
224
- updateEnvFile(
225
- `${projectPath}/Move.lock`,
226
- network,
227
- 'publish',
228
- chainId,
229
- packageId
230
- );
231
-
232
- console.log('\n⚡ Executing Deploy Hook...');
233
- await delay(5000);
234
-
235
- const deployHookTx = new Transaction();
236
- deployHookTx.moveCall({
237
- target: `${packageId}::${dubheConfig.name}_genesis::run`,
238
- arguments: [deployHookTx.object('0x6')],
239
- });
240
-
241
- let deployHookResult;
242
- try {
243
- deployHookResult = await dubhe.signAndSendTxn({tx: deployHookTx});
244
- } catch (error: any) {
245
- console.error(chalk.red(' └─ Deploy hook execution failed'));
246
- console.error(error.message);
247
- process.exit(1);
248
- }
249
-
250
- if (deployHookResult.effects?.status.status === 'success') {
251
- console.log(' ├─ Hook execution successful');
252
- console.log(` ├─ Transaction: ${deployHookResult.digest}`);
253
-
254
- console.log('\n📋 Created Schemas:');
255
- deployHookResult.objectChanges?.map(object => {
256
- if (object.type === 'created' && object.objectType.includes('schema::Schema')) {
257
- schemaId = object.objectId;
258
- }
259
- if (
260
- object.type === 'created' &&
261
- object.objectType.includes('schema') &&
262
- !object.objectType.includes('dynamic_field')
263
- ) {
264
- console.log(` ├─ ${object.objectType}`);
265
- console.log(` └─ ID: ${object.objectId}`);
266
- }
267
- });
268
-
269
- saveContractData(
270
- dubheConfig.name,
271
- network,
272
- packageId,
273
- schemaId,
274
- upgradeCapId,
275
- version,
276
- schemas
277
- );
278
- console.log('\n✅ Contract Publication Complete\n');
279
- } else {
280
- console.log(chalk.yellow(' └─ Deploy hook execution failed'));
281
- console.log(
282
- chalk.yellow(
283
- ' Please republish or manually call deploy_hook::run'
284
- )
285
- );
286
- console.log(chalk.yellow(' Please check the transaction digest:'));
287
- console.log(chalk.yellow(` ${deployHookResult.digest}`));
288
- process.exit(1);
289
- }
152
+ const chainId = await dubhe.suiInteractor.currentClient.getChainIdentifier();
153
+ await removeEnvContent(`${projectPath}/Move.lock`, network);
154
+ console.log('\n🚀 Starting Contract Publication...');
155
+ console.log(` ├─ Project: ${projectPath}`);
156
+ console.log(` ├─ Network: ${network}`);
157
+ console.log(` ├─ ChainId: ${chainId}`);
158
+ console.log(' ├─ Validating Environment...');
159
+
160
+ console.log(` └─ Account: ${dubhe.getAddress()}`);
161
+
162
+ console.log('\n📦 Building Contract...');
163
+ const [modules, dependencies] = buildContract(projectPath);
164
+
165
+ console.log('\n🔄 Publishing Contract...');
166
+ const tx = new Transaction();
167
+ if (gasBudget) {
168
+ tx.setGasBudget(gasBudget);
169
+ }
170
+ const [upgradeCap] = tx.publish({ modules, dependencies });
171
+ tx.transferObjects([upgradeCap], dubhe.getAddress());
172
+
173
+ let result;
174
+ try {
175
+ result = await dubhe.signAndSendTxn({ tx });
176
+ } catch (error: any) {
177
+ console.error(chalk.red(' └─ Publication failed'));
178
+ console.error(error.message);
179
+ process.exit(1);
180
+ }
181
+
182
+ if (result.effects?.status.status === 'failure') {
183
+ console.log(chalk.red(' └─ Publication failed'));
184
+ process.exit(1);
185
+ }
186
+
187
+ console.log(' ├─ Processing publication results...');
188
+ let version = 1;
189
+ let packageId = '';
190
+ let schemaId = '';
191
+ let schemas = dubheConfig.schemas;
192
+ let upgradeCapId = '';
193
+
194
+ result.objectChanges!.map((object) => {
195
+ if (object.type === 'published') {
196
+ console.log(` ├─ Package ID: ${object.packageId}`);
197
+ packageId = object.packageId;
198
+ }
199
+ if (object.type === 'created' && object.objectType === '0x2::package::UpgradeCap') {
200
+ console.log(` ├─ Upgrade Cap: ${object.objectId}`);
201
+ upgradeCapId = object.objectId;
202
+ }
203
+ });
204
+
205
+ console.log(` └─ Transaction: ${result.digest}`);
206
+
207
+ updateEnvFile(`${projectPath}/Move.lock`, network, 'publish', chainId, packageId);
208
+
209
+ console.log('\n⚡ Executing Deploy Hook...');
210
+ await delay(5000);
211
+
212
+ const deployHookTx = new Transaction();
213
+ deployHookTx.moveCall({
214
+ target: `${packageId}::${dubheConfig.name}_genesis::run`,
215
+ arguments: [deployHookTx.object('0x6')]
216
+ });
217
+
218
+ let deployHookResult;
219
+ try {
220
+ deployHookResult = await dubhe.signAndSendTxn({ tx: deployHookTx });
221
+ } catch (error: any) {
222
+ console.error(chalk.red(' └─ Deploy hook execution failed'));
223
+ console.error(error.message);
224
+ process.exit(1);
225
+ }
226
+
227
+ if (deployHookResult.effects?.status.status === 'success') {
228
+ console.log(' ├─ Hook execution successful');
229
+ console.log(` ├─ Transaction: ${deployHookResult.digest}`);
230
+
231
+ console.log('\n📋 Created Schemas:');
232
+ deployHookResult.objectChanges?.map((object) => {
233
+ if (object.type === 'created' && object.objectType.includes('schema::Schema')) {
234
+ schemaId = object.objectId;
235
+ }
236
+ if (
237
+ object.type === 'created' &&
238
+ object.objectType.includes('schema') &&
239
+ !object.objectType.includes('dynamic_field')
240
+ ) {
241
+ console.log(` ├─ ${object.objectType}`);
242
+ console.log(` └─ ID: ${object.objectId}`);
243
+ }
244
+ });
245
+
246
+ saveContractData(
247
+ dubheConfig.name,
248
+ network,
249
+ packageId,
250
+ schemaId,
251
+ upgradeCapId,
252
+ version,
253
+ schemas
254
+ );
255
+ console.log('\n✅ Contract Publication Complete\n');
256
+ } else {
257
+ console.log(chalk.yellow(' └─ Deploy hook execution failed'));
258
+ console.log(chalk.yellow(' Please republish or manually call deploy_hook::run'));
259
+ console.log(chalk.yellow(' Please check the transaction digest:'));
260
+ console.log(chalk.yellow(` ${deployHookResult.digest}`));
261
+ process.exit(1);
262
+ }
263
+ }
264
+
265
+ async function checkDubheFramework(projectPath: string): Promise<boolean> {
266
+ if (!fs.existsSync(projectPath)) {
267
+ console.log(chalk.yellow('\nℹ️ Dubhe Framework Files Not Found'));
268
+ console.log(chalk.yellow(' ├─ Expected Path:'), projectPath);
269
+ console.log(chalk.yellow(' ├─ To set up Dubhe Framework:'));
270
+ console.log(chalk.yellow(' │ 1. Create directory: mkdir -p contracts/dubhe-framework'));
271
+ console.log(
272
+ chalk.yellow(
273
+ ' │ 2. Clone repository: git clone https://github.com/0xobelisk/dubhe-framework contracts/dubhe-framework'
274
+ )
275
+ );
276
+ console.log(
277
+ chalk.yellow(' │ 3. Or download from: https://github.com/0xobelisk/dubhe-framework')
278
+ );
279
+ console.log(chalk.yellow(' └─ After setup, restart the local node'));
280
+ return false;
281
+ }
282
+ return true;
290
283
  }
291
284
 
292
285
  export async function publishDubheFramework(
293
- dubheConfig: DubheConfig,
294
- dubhe: Dubhe,
295
- network: 'mainnet' | 'testnet' | 'devnet' | 'localnet'
286
+ dubhe: Dubhe,
287
+ network: 'mainnet' | 'testnet' | 'devnet' | 'localnet'
296
288
  ) {
297
- const chainId =
298
- 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
- }
313
-
314
- await removeEnvContent(`${projectPath}/Move.lock`, network);
315
- const [modules, dependencies] = buildContract(projectPath);
316
-
317
- const tx = new Transaction();
318
- const [upgradeCap] = tx.publish({ modules, dependencies });
319
- tx.transferObjects([upgradeCap], dubhe.getAddress());
320
-
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
- }
329
-
330
- if (result.effects?.status.status === 'failure') {
331
- console.log(chalk.red(' └─ Publication failed'));
332
- process.exit(1);
333
- }
334
-
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
- });
373
- }
289
+ const path = process.cwd();
290
+ const projectPath = `${path}/contracts/dubhe-framework`;
291
+
292
+ if (!(await checkDubheFramework(projectPath))) {
293
+ console.log(chalk.yellow('\n❗ Framework Deployment Skipped'));
294
+ return;
295
+ }
296
+
297
+ // const chainId = await client.getChainIdentifier();
298
+ const chainId = await dubhe.suiInteractor.currentClient.getChainIdentifier();
299
+ await removeEnvContent(`${projectPath}/Move.lock`, network);
300
+ console.log('\n🚀 Starting Contract Publication...');
301
+ console.log(` ├─ Project: ${projectPath}`);
302
+ console.log(` ├─ Network: ${network}`);
303
+
304
+ console.log(` └─ Account: ${dubhe.getAddress()}`);
305
+
306
+ console.log('\n📦 Building Contract...');
307
+ const [modules, dependencies] = buildContract(projectPath);
308
+
309
+ console.log('\n🔄 Publishing Contract...');
310
+ const tx = new Transaction();
311
+ const [upgradeCap] = tx.publish({ modules, dependencies });
312
+ tx.transferObjects([upgradeCap], dubhe.getAddress());
313
+
314
+ let result;
315
+ try {
316
+ result = await dubhe.signAndSendTxn({ tx });
317
+ } catch (error: any) {
318
+ console.error(chalk.red(' └─ Publication failed'));
319
+ console.error(error.message);
320
+ process.exit(1);
321
+ }
322
+
323
+ if (result.effects?.status.status === 'failure') {
324
+ console.log(chalk.red(' └─ Publication failed'));
325
+ process.exit(1);
326
+ }
327
+
328
+ let version = 1;
329
+ let packageId = '';
330
+ let schemas: Record<string, string> = {};
331
+ let upgradeCapId = '';
332
+
333
+ result.objectChanges!.map((object) => {
334
+ if (object.type === 'published') {
335
+ console.log(` ├─ Package ID: ${object.packageId}`);
336
+ packageId = object.packageId;
337
+ }
338
+ if (object.type === 'created' && object.objectType === '0x2::package::UpgradeCap') {
339
+ console.log(` ├─ Upgrade Cap: ${object.objectId}`);
340
+ upgradeCapId = object.objectId;
341
+ }
342
+ });
343
+
344
+ console.log(` └─ Transaction: ${result.digest}`);
345
+
346
+ updateEnvFile(`${projectPath}/Move.lock`, network, 'publish', chainId, packageId);
347
+
348
+ saveContractData('dubhe-framework', network, packageId, '', upgradeCapId, version, schemas);
349
+ await delay(1000);
350
+ console.log(chalk.green('\n✅ Dubhe Framework deployed successfully'));
374
351
  }
375
352
 
376
353
  export async function publishHandler(
377
- dubheConfig: DubheConfig,
378
- network: 'mainnet' | 'testnet' | 'devnet' | 'localnet',
379
- gasBudget?: number
354
+ dubheConfig: DubheConfig,
355
+ network: 'mainnet' | 'testnet' | 'devnet' | 'localnet',
356
+ gasBudget?: number
380
357
  ) {
381
- await switchEnv(network);
358
+ await switchEnv(network);
382
359
 
383
- const privateKey = process.env.PRIVATE_KEY;
384
- if (!privateKey) {
385
- throw new DubheCliError(
386
- `Missing PRIVATE_KEY environment variable.
360
+ const privateKey = process.env.PRIVATE_KEY;
361
+ if (!privateKey) {
362
+ throw new DubheCliError(
363
+ `Missing PRIVATE_KEY environment variable.
387
364
  Run 'echo "PRIVATE_KEY=YOUR_PRIVATE_KEY" > .env'
388
365
  in your contracts directory to use the default sui private key.`
389
- );
390
- }
391
- const privateKeyFormat = validatePrivateKey(privateKey);
392
- if (privateKeyFormat === false) {
393
- throw new DubheCliError(`Please check your privateKey.`);
394
- }
395
-
396
- const dubhe = new Dubhe({
397
- secretKey: privateKeyFormat,
398
- networkType: network,
399
- });
400
-
401
- const path = process.cwd();
402
- 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
-
406
- await publishContract(dubhe, dubheConfig, network, projectPath, gasBudget);
366
+ );
367
+ }
368
+ const privateKeyFormat = validatePrivateKey(privateKey);
369
+ if (privateKeyFormat === false) {
370
+ throw new DubheCliError(`Please check your privateKey.`);
371
+ }
372
+
373
+ const dubhe = new Dubhe({
374
+ secretKey: privateKeyFormat,
375
+ networkType: network
376
+ });
377
+
378
+ if (network === 'localnet') {
379
+ await publishDubheFramework(dubhe, network);
380
+ }
381
+
382
+ const path = process.cwd();
383
+ const projectPath = `${path}/contracts/${dubheConfig.name}`;
384
+ await updateDubheDependency(`${projectPath}/Move.toml`, network);
385
+ await publishContract(dubhe, dubheConfig, network, projectPath, gasBudget);
407
386
  }