@0xobelisk/sui-cli 1.1.5 → 1.1.7

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.
@@ -5,259 +5,233 @@ import { execSync } from 'child_process';
5
5
  import chalk from 'chalk';
6
6
  import { DubheCliError, UpgradeError } from './errors';
7
7
  import {
8
- getOldPackageId,
9
- getVersion,
10
- getUpgradeCap,
11
- saveContractData,
12
- validatePrivateKey,
13
- getOnchainSchemas,
14
- switchEnv, getSchemaId,
8
+ getOldPackageId,
9
+ getVersion,
10
+ getUpgradeCap,
11
+ saveContractData,
12
+ validatePrivateKey,
13
+ getOnchainSchemas,
14
+ switchEnv,
15
+ getSchemaId
15
16
  } from './utils';
16
17
  import * as fs from 'fs';
17
18
  import * as path from 'path';
18
19
  import { DubheConfig } from '@0xobelisk/sui-common';
19
20
 
20
21
  type Migration = {
21
- schemaName: string;
22
- fields: string;
22
+ schemaName: string;
23
+ fields: string;
23
24
  };
24
25
 
25
- function updateMigrateMethod(
26
- projectPath: string,
27
- migrations: Migration[]
28
- ): void {
29
- let filePath = `${projectPath}/sources/codegen/schema.move`;
30
- const fileContent = fs.readFileSync(filePath, 'utf-8');
31
- const migrateMethodRegex = new RegExp(
32
- `public fun migrate\\(_schema: &mut Schema, _cap: &UpgradeCap, _ctx: &mut TxContext\\) {[^}]*}`
33
- );
34
- const newMigrateMethod = `
26
+ function updateMigrateMethod(projectPath: string, migrations: Migration[]): void {
27
+ let filePath = `${projectPath}/sources/codegen/schema.move`;
28
+ const fileContent = fs.readFileSync(filePath, 'utf-8');
29
+ const migrateMethodRegex = new RegExp(
30
+ `public fun migrate\\(_schema: &mut Schema, _cap: &UpgradeCap, _ctx: &mut TxContext\\) {[^}]*}`
31
+ );
32
+ const newMigrateMethod = `
35
33
  public fun migrate(_schema: &mut Schema, _cap: &UpgradeCap, _ctx: &mut TxContext) {
36
- ${migrations.map(migration => {
37
- let storage_type = '';
38
- if (migration.fields.includes('StorageValue')) {
39
- storage_type = `storage_value::new(b"${migration.schemaName}", _ctx)`;
40
- } else if (migration.fields.includes('StorageMap')) {
41
- storage_type = `storage_map::new(b"${migration.schemaName}", _ctx)`;
42
- } else if (migration.fields.includes('StorageDoubleMap')) {
43
- storage_type = `storage_double_map::new(b"${migration.schemaName}", _ctx)`;
44
- }
45
- return `storage::add_field<${migration.fields}>(&mut _schema.id, b"${migration.schemaName}", ${storage_type});`;
46
- })
47
- .join('')}
34
+ ${migrations
35
+ .map((migration) => {
36
+ let storage_type = '';
37
+ if (migration.fields.includes('StorageValue')) {
38
+ storage_type = `storage_value::new(b"${migration.schemaName}", _ctx)`;
39
+ } else if (migration.fields.includes('StorageMap')) {
40
+ storage_type = `storage_map::new(b"${migration.schemaName}", _ctx)`;
41
+ } else if (migration.fields.includes('StorageDoubleMap')) {
42
+ storage_type = `storage_double_map::new(b"${migration.schemaName}", _ctx)`;
43
+ }
44
+ return `storage::add_field<${migration.fields}>(&mut _schema.id, b"${migration.schemaName}", ${storage_type});`;
45
+ })
46
+ .join('')}
48
47
  }
49
48
  `;
50
49
 
51
- const updatedContent = fileContent.replace(
52
- migrateMethodRegex,
53
- newMigrateMethod
54
- );
55
- fs.writeFileSync(filePath, updatedContent, 'utf-8');
50
+ const updatedContent = fileContent.replace(migrateMethodRegex, newMigrateMethod);
51
+ fs.writeFileSync(filePath, updatedContent, 'utf-8');
56
52
  }
57
53
 
58
54
  function replaceEnvField(
59
- filePath: string,
60
- networkType: 'mainnet' | 'testnet' | 'devnet' | 'localnet',
61
- field:
62
- | 'original-published-id'
63
- | 'latest-published-id'
64
- | 'published-version',
65
- newValue: string
55
+ filePath: string,
56
+ networkType: 'mainnet' | 'testnet' | 'devnet' | 'localnet',
57
+ field: 'original-published-id' | 'latest-published-id' | 'published-version',
58
+ newValue: string
66
59
  ): string {
67
- const envFilePath = path.resolve(filePath);
68
- const envContent = fs.readFileSync(envFilePath, 'utf-8');
69
- const envLines = envContent.split('\n');
70
-
71
- const networkSectionIndex = envLines.findIndex(
72
- line => line.trim() === `[env.${networkType}]`
73
- );
74
- if (networkSectionIndex === -1) {
75
- console.log(`Network type [env.${networkType}] not found in the file.`);
76
- return '';
77
- }
78
-
79
- let fieldIndex = -1;
80
- let previousValue: string = '';
81
- for (let i = networkSectionIndex + 1; i < envLines.length; i++) {
82
- const line = envLines[i].trim();
83
- if (line.startsWith('[')) break; // End of the current network section
84
-
85
- if (line.startsWith(field)) {
86
- fieldIndex = i;
87
- previousValue = line.split('=')[1].trim().replace(/"/g, '');
88
- break;
89
- }
90
- }
91
-
92
- if (fieldIndex !== -1) {
93
- envLines[fieldIndex] = `${field} = "${newValue}"`;
94
- const newEnvContent = envLines.join('\n');
95
- fs.writeFileSync(envFilePath, newEnvContent, 'utf-8');
96
- } else {
97
- console.log(`${field} not found for [env.${networkType}].`);
98
- }
99
-
100
- return previousValue;
60
+ const envFilePath = path.resolve(filePath);
61
+ const envContent = fs.readFileSync(envFilePath, 'utf-8');
62
+ const envLines = envContent.split('\n');
63
+
64
+ const networkSectionIndex = envLines.findIndex((line) => line.trim() === `[env.${networkType}]`);
65
+ if (networkSectionIndex === -1) {
66
+ console.log(`Network type [env.${networkType}] not found in the file.`);
67
+ return '';
68
+ }
69
+
70
+ let fieldIndex = -1;
71
+ let previousValue: string = '';
72
+ for (let i = networkSectionIndex + 1; i < envLines.length; i++) {
73
+ const line = envLines[i].trim();
74
+ if (line.startsWith('[')) break; // End of the current network section
75
+
76
+ if (line.startsWith(field)) {
77
+ fieldIndex = i;
78
+ previousValue = line.split('=')[1].trim().replace(/"/g, '');
79
+ break;
80
+ }
81
+ }
82
+
83
+ if (fieldIndex !== -1) {
84
+ envLines[fieldIndex] = `${field} = "${newValue}"`;
85
+ const newEnvContent = envLines.join('\n');
86
+ fs.writeFileSync(envFilePath, newEnvContent, 'utf-8');
87
+ } else {
88
+ console.log(`${field} not found for [env.${networkType}].`);
89
+ }
90
+
91
+ return previousValue;
101
92
  }
102
93
  export async function upgradeHandler(
103
- config: DubheConfig,
104
- name: string,
105
- network: 'mainnet' | 'testnet' | 'devnet' | 'localnet'
94
+ config: DubheConfig,
95
+ name: string,
96
+ network: 'mainnet' | 'testnet' | 'devnet' | 'localnet'
106
97
  ) {
107
- await switchEnv(network);
108
-
109
- const path = process.cwd();
110
- const projectPath = `${path}/contracts/${name}`;
111
- const privateKey = process.env.PRIVATE_KEY;
112
- if (!privateKey)
113
- throw new DubheCliError(
114
- `Missing PRIVATE_KEY environment variable.
98
+ await switchEnv(network);
99
+
100
+ const path = process.cwd();
101
+ const projectPath = `${path}/contracts/${name}`;
102
+ const privateKey = process.env.PRIVATE_KEY;
103
+ if (!privateKey)
104
+ throw new DubheCliError(
105
+ `Missing PRIVATE_KEY environment variable.
115
106
  Run 'echo "PRIVATE_KEY=YOUR_PRIVATE_KEY" > .env'
116
107
  in your contracts directory to use the default sui private key.`
117
- );
118
-
119
- const privateKeyFormat = validatePrivateKey(privateKey);
120
- if (privateKeyFormat === false) {
121
- throw new DubheCliError(`Please check your privateKey.`);
122
- }
123
- const dubhe = new Dubhe({
124
- secretKey: privateKeyFormat,
125
- });
126
- const keypair = dubhe.getSigner();
127
-
128
- const client = new SuiClient({
129
- url: getFullnodeUrl(network),
130
- });
131
-
132
- let oldVersion = Number(await getVersion(projectPath, network));
133
- let oldPackageId = await getOldPackageId(projectPath, network);
134
- let upgradeCap = await getUpgradeCap(projectPath, network);
135
- let schemaId = await getSchemaId(projectPath, network);
136
-
137
- const original_published_id = replaceEnvField(
138
- `${projectPath}/Move.lock`,
139
- network,
140
- 'original-published-id',
141
- '0x0000000000000000000000000000000000000000000000000000000000000000'
142
- );
143
-
144
- let pendingMigration: Migration[] = [];
145
- let schemas = await getOnchainSchemas(projectPath, network);
146
- Object.entries(config.schemas).forEach(([key, value]) => {
147
- if (!schemas.hasOwnProperty(key)) {
148
- pendingMigration.push({ schemaName: key, fields: value });
149
- }
150
- });
151
-
152
- pendingMigration.forEach(migration => {
153
- console.log(`\nšŸš€ Starting Migration for ${migration.schemaName}...`);
154
- console.log('šŸ“‹ Migration Fields:', migration.fields);
155
- });
156
- updateMigrateMethod(projectPath, pendingMigration);
157
-
158
- try {
159
- let modules: any, dependencies: any, digest: any;
160
- try {
161
- const {
162
- modules: extractedModules,
163
- dependencies: extractedDependencies,
164
- digest: extractedDigest,
165
- } = JSON.parse(
166
- execSync(
167
- `sui move build --dump-bytecode-as-base64 --path ${path}/contracts/${name}`,
168
- {
169
- encoding: 'utf-8',
170
- }
171
- )
172
- );
173
-
174
- modules = extractedModules;
175
- dependencies = extractedDependencies;
176
- digest = extractedDigest;
177
- } catch (error: any) {
178
- throw new UpgradeError(error.stdout);
179
- }
180
-
181
- console.log('\nšŸš€ Starting Upgrade Process...');
182
- console.log('šŸ“‹ OldPackageId:', oldPackageId);
183
- console.log('šŸ“‹ UpgradeCap Object Id:', upgradeCap);
184
- console.log('šŸ“‹ OldVersion:', oldVersion);
185
-
186
- const tx = new Transaction();
187
- const ticket = tx.moveCall({
188
- target: '0x2::package::authorize_upgrade',
189
- arguments: [
190
- tx.object(upgradeCap),
191
- tx.pure.u8(UpgradePolicy.COMPATIBLE),
192
- tx.pure.vector('u8', digest),
193
- ],
194
- });
195
-
196
- const receipt = tx.upgrade({
197
- modules,
198
- dependencies,
199
- package: oldPackageId,
200
- ticket,
201
- });
202
-
203
- tx.moveCall({
204
- target: '0x2::package::commit_upgrade',
205
- arguments: [tx.object(upgradeCap), receipt],
206
- });
207
-
208
- const result = await client.signAndExecuteTransaction({
209
- signer: keypair,
210
- transaction: tx,
211
- options: {
212
- showObjectChanges: true,
213
- },
214
- });
215
-
216
- let newPackageId = '';
217
- result.objectChanges!.map(object => {
218
- if (object.type === 'published') {
219
- console.log(
220
- chalk.blue(`${name} PackageId: ${object.packageId}`)
221
- );
222
- console.log(chalk.blue(`${name} Version: ${oldVersion + 1}`));
223
- newPackageId = object.packageId;
224
- }
225
- });
226
-
227
- replaceEnvField(
228
- `${projectPath}/Move.lock`,
229
- network,
230
- 'original-published-id',
231
- original_published_id
232
- );
233
- replaceEnvField(
234
- `${projectPath}/Move.lock`,
235
- network,
236
- 'latest-published-id',
237
- newPackageId
238
- );
239
- replaceEnvField(
240
- `${projectPath}/Move.lock`,
241
- network,
242
- 'published-version',
243
- oldVersion + 1 + ''
244
- );
245
-
246
- console.log(
247
- chalk.green(`Upgrade Transaction Digest: ${result.digest}`)
248
- );
249
-
250
- saveContractData(
251
- name,
252
- network,
253
- newPackageId,
254
- schemaId,
255
- upgradeCap,
256
- oldVersion + 1,
257
- config.schemas
258
- );
259
- } catch (error: any) {
260
- console.log(chalk.red('Upgrade failed!'));
261
- console.error(error.message);
262
- }
108
+ );
109
+
110
+ const privateKeyFormat = validatePrivateKey(privateKey);
111
+ if (privateKeyFormat === false) {
112
+ throw new DubheCliError(`Please check your privateKey.`);
113
+ }
114
+ const dubhe = new Dubhe({
115
+ secretKey: privateKeyFormat
116
+ });
117
+ const keypair = dubhe.getSigner();
118
+
119
+ const client = new SuiClient({
120
+ url: getFullnodeUrl(network)
121
+ });
122
+
123
+ let oldVersion = Number(await getVersion(projectPath, network));
124
+ let oldPackageId = await getOldPackageId(projectPath, network);
125
+ let upgradeCap = await getUpgradeCap(projectPath, network);
126
+ let schemaId = await getSchemaId(projectPath, network);
127
+
128
+ const original_published_id = replaceEnvField(
129
+ `${projectPath}/Move.lock`,
130
+ network,
131
+ 'original-published-id',
132
+ '0x0000000000000000000000000000000000000000000000000000000000000000'
133
+ );
134
+
135
+ let pendingMigration: Migration[] = [];
136
+ let schemas = await getOnchainSchemas(projectPath, network);
137
+ Object.entries(config.schemas).forEach(([key, value]) => {
138
+ if (!schemas.hasOwnProperty(key)) {
139
+ pendingMigration.push({ schemaName: key, fields: value });
140
+ }
141
+ });
142
+
143
+ pendingMigration.forEach((migration) => {
144
+ console.log(`\nšŸš€ Starting Migration for ${migration.schemaName}...`);
145
+ console.log('šŸ“‹ Migration Fields:', migration.fields);
146
+ });
147
+ updateMigrateMethod(projectPath, pendingMigration);
148
+
149
+ try {
150
+ let modules: any, dependencies: any, digest: any;
151
+ try {
152
+ const {
153
+ modules: extractedModules,
154
+ dependencies: extractedDependencies,
155
+ digest: extractedDigest
156
+ } = JSON.parse(
157
+ execSync(`sui move build --dump-bytecode-as-base64 --path ${path}/contracts/${name}`, {
158
+ encoding: 'utf-8'
159
+ })
160
+ );
161
+
162
+ modules = extractedModules;
163
+ dependencies = extractedDependencies;
164
+ digest = extractedDigest;
165
+ } catch (error: any) {
166
+ throw new UpgradeError(error.stdout);
167
+ }
168
+
169
+ console.log('\nšŸš€ Starting Upgrade Process...');
170
+ console.log('šŸ“‹ OldPackageId:', oldPackageId);
171
+ console.log('šŸ“‹ UpgradeCap Object Id:', upgradeCap);
172
+ console.log('šŸ“‹ OldVersion:', oldVersion);
173
+
174
+ const tx = new Transaction();
175
+ const ticket = tx.moveCall({
176
+ target: '0x2::package::authorize_upgrade',
177
+ arguments: [
178
+ tx.object(upgradeCap),
179
+ tx.pure.u8(UpgradePolicy.COMPATIBLE),
180
+ tx.pure.vector('u8', digest)
181
+ ]
182
+ });
183
+
184
+ const receipt = tx.upgrade({
185
+ modules,
186
+ dependencies,
187
+ package: oldPackageId,
188
+ ticket
189
+ });
190
+
191
+ tx.moveCall({
192
+ target: '0x2::package::commit_upgrade',
193
+ arguments: [tx.object(upgradeCap), receipt]
194
+ });
195
+
196
+ const result = await client.signAndExecuteTransaction({
197
+ signer: keypair,
198
+ transaction: tx,
199
+ options: {
200
+ showObjectChanges: true
201
+ }
202
+ });
203
+
204
+ let newPackageId = '';
205
+ result.objectChanges!.map((object) => {
206
+ if (object.type === 'published') {
207
+ console.log(chalk.blue(`${name} PackageId: ${object.packageId}`));
208
+ console.log(chalk.blue(`${name} Version: ${oldVersion + 1}`));
209
+ newPackageId = object.packageId;
210
+ }
211
+ });
212
+
213
+ replaceEnvField(
214
+ `${projectPath}/Move.lock`,
215
+ network,
216
+ 'original-published-id',
217
+ original_published_id
218
+ );
219
+ replaceEnvField(`${projectPath}/Move.lock`, network, 'latest-published-id', newPackageId);
220
+ replaceEnvField(`${projectPath}/Move.lock`, network, 'published-version', oldVersion + 1 + '');
221
+
222
+ console.log(chalk.green(`Upgrade Transaction Digest: ${result.digest}`));
223
+
224
+ saveContractData(
225
+ name,
226
+ network,
227
+ newPackageId,
228
+ schemaId,
229
+ upgradeCap,
230
+ oldVersion + 1,
231
+ config.schemas
232
+ );
233
+ } catch (error: any) {
234
+ console.log(chalk.red('Upgrade failed!'));
235
+ console.error(error.message);
236
+ }
263
237
  }