@0xobelisk/sui-cli 1.0.7 → 1.0.9

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,98 +5,79 @@ import { execSync } from 'child_process';
5
5
  import chalk from 'chalk';
6
6
  import { DubheCliError, UpgradeError } from './errors';
7
7
  import {
8
- updateVersionInFile,
9
- getOldPackageId,
10
- getVersion,
11
- getUpgradeCap,
12
- saveContractData,
13
- validatePrivateKey, getOnchainSchemas, switchEnv, delay,
8
+ getOldPackageId,
9
+ getVersion,
10
+ getUpgradeCap,
11
+ saveContractData,
12
+ validatePrivateKey,
13
+ getOnchainSchemas,
14
+ switchEnv, getSchemaId,
14
15
  } from './utils';
15
16
  import * as fs from 'fs';
16
17
  import * as path from 'path';
17
18
  import { DubheConfig } from '@0xobelisk/sui-common';
18
19
 
19
- type ObjectContent = {
20
- type: string;
21
- fields: Record<string, any>;
22
- hasPublicTransfer: boolean;
23
- dataType: string;
24
- };
25
-
26
- type Field = {
27
- name: string;
28
- type: string;
29
- }
30
-
31
20
  type Migration = {
32
21
  schemaName: string;
33
- fields: Field[];
22
+ fields: string;
34
23
  };
35
24
 
36
- function updateMigrateMethod(projectPath: string, migrations: Migration[]): void {
37
- migrations.forEach((migration) => {
38
- let filePath = `${projectPath}/sources/codegen/schemas/${migration.schemaName}.move`;
25
+ function updateMigrateMethod(
26
+ projectPath: string,
27
+ migrations: Migration[]
28
+ ): void {
29
+ let filePath = `${projectPath}/sources/codegen/schema.move`;
39
30
  const fileContent = fs.readFileSync(filePath, 'utf-8');
40
- const migrateMethodRegex = new RegExp(`public fun migrate\\(_${migration.schemaName}: &mut ${capitalizeAndRemoveUnderscores(migration.schemaName)}, _cap: &UpgradeCap\\) {[^}]*}`);
31
+ const migrateMethodRegex = new RegExp(
32
+ `public fun migrate\\(_schema: &mut Schema, _cap: &UpgradeCap, _ctx: &mut TxContext\\) {[^}]*}`
33
+ );
41
34
  const newMigrateMethod = `
42
- public fun migrate(${migration.schemaName}: &mut ${capitalizeAndRemoveUnderscores(migration.schemaName)}, _cap: &UpgradeCap) {
43
- ${migration.fields.map((field) => {
44
- let storage_type = '';
45
- if (field.type.includes('StorageValue')) {
46
- storage_type = `storage_value::new()`;
47
- } else if (field.type.includes('StorageMap')) {
48
- storage_type = `storage_map::new()`;
49
- } else if (
50
- field.type.includes('StorageDoubleMap')
51
- ) {
52
- storage_type = `storage_double_map::new()`;
53
- }
54
- return `storage_migration::add_field<${field.type}>(&mut ${migration.schemaName}.id, b"${field.name}", ${storage_type});`;
55
- }).join('')}
35
+ 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('')}
56
48
  }
57
49
  `;
58
50
 
59
- const updatedContent = fileContent.replace(migrateMethodRegex, newMigrateMethod);
51
+ const updatedContent = fileContent.replace(
52
+ migrateMethodRegex,
53
+ newMigrateMethod
54
+ );
60
55
  fs.writeFileSync(filePath, updatedContent, 'utf-8');
61
- });
62
-
63
-
64
- }
65
-
66
- function capitalizeAndRemoveUnderscores(input: string): string {
67
- return input
68
- .split('_')
69
- .map((word, index) => {
70
- return index === 0
71
- ? word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()
72
- : word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
73
- })
74
- .join('');
75
- }
76
-
77
- function getLastSegment(input: string): string {
78
- const segments = input.split('::');
79
- return segments.length > 0 ? segments[segments.length - 1] : '';
80
56
  }
81
57
 
82
58
  function replaceEnvField(
83
59
  filePath: string,
84
60
  networkType: 'mainnet' | 'testnet' | 'devnet' | 'localnet',
85
- field: 'original-published-id' | 'latest-published-id' | 'published-version',
61
+ field:
62
+ | 'original-published-id'
63
+ | 'latest-published-id'
64
+ | 'published-version',
86
65
  newValue: string
87
66
  ): string {
88
67
  const envFilePath = path.resolve(filePath);
89
68
  const envContent = fs.readFileSync(envFilePath, 'utf-8');
90
69
  const envLines = envContent.split('\n');
91
70
 
92
- const networkSectionIndex = envLines.findIndex(line => line.trim() === `[env.${networkType}]`);
71
+ const networkSectionIndex = envLines.findIndex(
72
+ line => line.trim() === `[env.${networkType}]`
73
+ );
93
74
  if (networkSectionIndex === -1) {
94
75
  console.log(`Network type [env.${networkType}] not found in the file.`);
95
- return "";
76
+ return '';
96
77
  }
97
78
 
98
79
  let fieldIndex = -1;
99
- let previousValue: string = "";
80
+ let previousValue: string = '';
100
81
  for (let i = networkSectionIndex + 1; i < envLines.length; i++) {
101
82
  const line = envLines[i].trim();
102
83
  if (line.startsWith('[')) break; // End of the current network section
@@ -121,7 +102,7 @@ function replaceEnvField(
121
102
  export async function upgradeHandler(
122
103
  config: DubheConfig,
123
104
  name: string,
124
- network: 'mainnet' | 'testnet' | 'devnet' | 'localnet',
105
+ network: 'mainnet' | 'testnet' | 'devnet' | 'localnet'
125
106
  ) {
126
107
  await switchEnv(network);
127
108
 
@@ -132,7 +113,7 @@ export async function upgradeHandler(
132
113
  throw new DubheCliError(
133
114
  `Missing PRIVATE_KEY environment variable.
134
115
  Run 'echo "PRIVATE_KEY=YOUR_PRIVATE_KEY" > .env'
135
- in your contracts directory to use the default sui private key.`,
116
+ in your contracts directory to use the default sui private key.`
136
117
  );
137
118
 
138
119
  const privateKeyFormat = validatePrivateKey(privateKey);
@@ -142,7 +123,7 @@ in your contracts directory to use the default sui private key.`,
142
123
  const dubhe = new Dubhe({
143
124
  secretKey: privateKeyFormat,
144
125
  });
145
- const keypair = dubhe.getKeypair();
126
+ const keypair = dubhe.getSigner();
146
127
 
147
128
  const client = new SuiClient({
148
129
  url: getFullnodeUrl(network),
@@ -151,38 +132,24 @@ in your contracts directory to use the default sui private key.`,
151
132
  let oldVersion = Number(await getVersion(projectPath, network));
152
133
  let oldPackageId = await getOldPackageId(projectPath, network);
153
134
  let upgradeCap = await getUpgradeCap(projectPath, network);
135
+ let schemaId = await getSchemaId(projectPath, network);
154
136
 
155
- const original_published_id = replaceEnvField(`${projectPath}/Move.lock`, network, 'original-published-id', "0x0000000000000000000000000000000000000000000000000000000000000000");
137
+ const original_published_id = replaceEnvField(
138
+ `${projectPath}/Move.lock`,
139
+ network,
140
+ 'original-published-id',
141
+ '0x0000000000000000000000000000000000000000000000000000000000000000'
142
+ );
156
143
 
157
144
  let pendingMigration: Migration[] = [];
158
145
  let schemas = await getOnchainSchemas(projectPath, network);
159
- for (let schemaKey in config.schemas) {
160
- schemas.forEach((schema) => {
161
- if (capitalizeAndRemoveUnderscores(schemaKey) == getLastSegment(schema.name)) {
162
- let migrate: Migration = { schemaName: '', fields: [] };
163
- let fields: Field[] = [];
164
- let isMigration = false;
165
- for (const key in config.schemas[schemaKey].structure) {
166
- if (!(key in schema.structure)) {
167
- isMigration = true;
168
- fields.push({
169
- name: key,
170
- type: config.schemas[schemaKey].structure[key],
171
- });
172
- schema.structure[key] = config.schemas[schemaKey].structure[key];
173
- }
174
- }
175
- if (isMigration) {
176
- migrate.schemaName = schemaKey;
177
- migrate.fields = fields;
178
- pendingMigration.push(migrate);
179
- }
180
- }
181
- });
182
- }
183
-
146
+ Object.entries(config.schemas).forEach(([key, value]) => {
147
+ if (!schemas.hasOwnProperty(key)) {
148
+ pendingMigration.push({ schemaName: key, fields: value });
149
+ }
150
+ });
184
151
 
185
- pendingMigration.forEach((migration) => {
152
+ pendingMigration.forEach(migration => {
186
153
  console.log(`\n🚀 Starting Migration for ${migration.schemaName}...`);
187
154
  console.log('📋 Migration Fields:', migration.fields);
188
155
  });
@@ -200,8 +167,8 @@ in your contracts directory to use the default sui private key.`,
200
167
  `sui move build --dump-bytecode-as-base64 --path ${path}/contracts/${name}`,
201
168
  {
202
169
  encoding: 'utf-8',
203
- },
204
- ),
170
+ }
171
+ )
205
172
  );
206
173
 
207
174
  modules = extractedModules;
@@ -250,32 +217,45 @@ in your contracts directory to use the default sui private key.`,
250
217
  result.objectChanges!.map(object => {
251
218
  if (object.type === 'published') {
252
219
  console.log(
253
- chalk.blue(`${name} PackageId: ${object.packageId}`),
254
- );
255
- console.log(
256
- chalk.blue(`${name} Version: ${oldVersion + 1}`),
220
+ chalk.blue(`${name} PackageId: ${object.packageId}`)
257
221
  );
222
+ console.log(chalk.blue(`${name} Version: ${oldVersion + 1}`));
258
223
  newPackageId = object.packageId;
259
224
  }
260
225
  });
261
226
 
262
- replaceEnvField(`${projectPath}/Move.lock`, network, 'original-published-id', original_published_id);
263
- replaceEnvField(`${projectPath}/Move.lock`, network, 'latest-published-id', newPackageId);
264
- replaceEnvField(`${projectPath}/Move.lock`, network, 'published-version', (oldVersion + 1) + "");
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
+ );
265
245
 
266
246
  console.log(
267
- chalk.green(`Upgrade Transaction Digest: ${result.digest}`),
247
+ chalk.green(`Upgrade Transaction Digest: ${result.digest}`)
268
248
  );
269
249
 
270
250
  saveContractData(
271
251
  name,
272
252
  network,
273
253
  newPackageId,
254
+ schemaId,
274
255
  upgradeCap,
275
256
  oldVersion + 1,
276
- schemas,
257
+ config.schemas
277
258
  );
278
-
279
259
  } catch (error: any) {
280
260
  console.log(chalk.red('Upgrade failed!'));
281
261
  console.error(error.message);
@@ -7,19 +7,14 @@ import * as fs from 'fs';
7
7
  import chalk from 'chalk';
8
8
  import { spawn } from 'child_process';
9
9
 
10
- export type schema = {
11
- name: string;
12
- objectId: string;
13
- structure: Record<string, string>;
14
- };
15
-
16
10
  export type DeploymentJsonType = {
17
11
  projectName: string;
18
12
  network: 'mainnet' | 'testnet' | 'devnet' | 'localnet';
19
13
  packageId: string;
14
+ schemaId: string;
20
15
  upgradeCap: string;
21
16
  version: number;
22
- schemas: schema[];
17
+ schemas: Record<string, string>;
23
18
  };
24
19
 
25
20
  export function validatePrivateKey(privateKey: string): false | string {
@@ -81,7 +76,7 @@ async function getDeploymentJson(projectPath: string, network: string) {
81
76
  export async function getOnchainSchemas(
82
77
  projectPath: string,
83
78
  network: string
84
- ): Promise<schema[]> {
79
+ ): Promise<Record<string, string>> {
85
80
  const deployment = await getDeploymentJson(projectPath, network);
86
81
  return deployment.schemas;
87
82
  }
@@ -110,25 +105,12 @@ export async function getOldPackageId(
110
105
  return deployment.packageId;
111
106
  }
112
107
 
113
- export async function getObjectId(
108
+ export async function getSchemaId(
114
109
  projectPath: string,
115
- network: string,
116
- schemaName: string
110
+ network: string
117
111
  ): Promise<string> {
118
112
  const deployment = await getDeploymentJson(projectPath, network);
119
- const schema = deployment.schemas.find(schema =>
120
- schema.name
121
- .toLowerCase()
122
- .endsWith(`::${schemaName.toLowerCase()}_schema::${schemaName}`)
123
- );
124
-
125
- if (!schema?.objectId) {
126
- throw new Error(
127
- `Schema '${schemaName}' not found in deployment history`
128
- );
129
- }
130
-
131
- return schema.objectId;
113
+ return deployment.schemaId;
132
114
  }
133
115
 
134
116
  export async function getUpgradeCap(
@@ -139,28 +121,20 @@ export async function getUpgradeCap(
139
121
  return deployment.upgradeCap;
140
122
  }
141
123
 
142
- export async function getObjectIdBySchemaName(
143
- projectPath: string,
144
- network: string,
145
- schemaName: string
146
- ): Promise<string | undefined> {
147
- const deployment = await getDeploymentJson(projectPath, network);
148
- return deployment.schemas.find(schema => schema.name.includes(schemaName))
149
- ?.objectId;
150
- }
151
-
152
124
  export function saveContractData(
153
125
  projectName: string,
154
126
  network: 'mainnet' | 'testnet' | 'devnet' | 'localnet',
155
127
  packageId: string,
128
+ schemaId: string,
156
129
  upgradeCap: string,
157
130
  version: number,
158
- schemas: schema[]
131
+ schemas: Record<string, string>
159
132
  ) {
160
133
  const DeploymentData: DeploymentJsonType = {
161
134
  projectName,
162
135
  network,
163
136
  packageId,
137
+ schemaId,
164
138
  schemas,
165
139
  upgradeCap,
166
140
  version,
@@ -203,7 +177,7 @@ function getDubheDependency(
203
177
  }
204
178
  }
205
179
 
206
- export function updateDubheDependency(
180
+ export async function updateDubheDependency(
207
181
  filePath: string,
208
182
  network: 'mainnet' | 'testnet' | 'devnet' | 'localnet'
209
183
  ) {