@0xobelisk/sui-cli 0.5.8 → 0.5.10

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.
@@ -1,237 +1,248 @@
1
- import { TransactionBlock, UpgradePolicy } from "@mysten/sui.js/transactions";
2
- import { Ed25519Keypair } from "@mysten/sui.js/keypairs/ed25519";
3
- import { getFullnodeUrl, SuiClient } from "@mysten/sui.js/client";
4
- import { execSync } from "child_process";
5
- import chalk from "chalk";
6
- import { ObeliskCliError, UpgradeError } from "./errors";
1
+ import { Obelisk } from '@0xobelisk/sui-client';
2
+ import { Transaction, UpgradePolicy } from '@mysten/sui/transactions';
3
+ import { getFullnodeUrl, SuiClient } from '@mysten/sui/client';
4
+ import { execSync } from 'child_process';
5
+ import chalk from 'chalk';
6
+ import { ObeliskCliError, UpgradeError } from './errors';
7
7
  import {
8
- updateVersionInFile,
9
- getOldPackageId,
10
- getVersion,
11
- getWorldId,
12
- getUpgradeCap,
13
- saveContractData,
14
- validatePrivateKey,
15
- getAdminCap,
16
- } from "./utils";
8
+ updateVersionInFile,
9
+ getOldPackageId,
10
+ getVersion,
11
+ getWorldId,
12
+ getUpgradeCap,
13
+ saveContractData,
14
+ validatePrivateKey,
15
+ getAdminCap,
16
+ } from './utils';
17
17
 
18
18
  type ObjectContent = {
19
- type: string;
20
- fields: Record<string, any>;
21
- hasPublicTransfer: boolean;
22
- dataType: string;
19
+ type: string;
20
+ fields: Record<string, any>;
21
+ hasPublicTransfer: boolean;
22
+ dataType: string;
23
23
  };
24
24
 
25
25
  export async function upgradeHandler(
26
- name: string,
27
- network: "mainnet" | "testnet" | "devnet" | "localnet",
28
- schemaNames: string[]
26
+ name: string,
27
+ network: 'mainnet' | 'testnet' | 'devnet' | 'localnet',
28
+ schemaNames: string[]
29
29
  ) {
30
- const path = process.cwd();
31
- const projectPath = `${path}/contracts/${name}`;
32
- const privateKey = process.env.PRIVATE_KEY;
33
- if (!privateKey)
34
- throw new ObeliskCliError(
35
- `Missing PRIVATE_KEY environment variable.
30
+ const path = process.cwd();
31
+ const projectPath = `${path}/contracts/${name}`;
32
+ const privateKey = process.env.PRIVATE_KEY;
33
+ if (!privateKey)
34
+ throw new ObeliskCliError(
35
+ `Missing PRIVATE_KEY environment variable.
36
36
  Run 'echo "PRIVATE_KEY=YOUR_PRIVATE_KEY" > .env'
37
37
  in your contracts directory to use the default sui private key.`
38
- );
39
-
40
- const privateKeyFormat = validatePrivateKey(privateKey);
41
- if (privateKeyFormat === false) {
42
- throw new ObeliskCliError(`Please check your privateKey.`);
43
- }
44
- const privateKeyRaw = Buffer.from(privateKeyFormat as string, "hex");
45
- const keypair = Ed25519Keypair.fromSecretKey(privateKeyRaw);
46
-
47
- const client = new SuiClient({
48
- url: getFullnodeUrl(network),
49
- });
50
-
51
- let oldVersion = Number(await getVersion(projectPath, network));
52
- let oldPackageId = await getOldPackageId(projectPath, network);
53
- let worldId = await getWorldId(projectPath, network);
54
- let upgradeCap = await getUpgradeCap(projectPath, network);
55
- let adminCap = await getAdminCap(projectPath, network);
56
-
57
- const newVersion = oldVersion + 1;
58
- await updateVersionInFile(projectPath, newVersion.toString());
59
-
60
- try {
61
- let modules: any, dependencies: any, digest: any;
62
- try {
63
- const {
64
- modules: extractedModules,
65
- dependencies: extractedDependencies,
66
- digest: extractedDigest,
67
- } = JSON.parse(
68
- execSync(
69
- `sui move build --dump-bytecode-as-base64 --path ${path}/contracts/${name}`,
70
- {
71
- encoding: "utf-8",
72
- }
73
- )
74
- );
75
-
76
- modules = extractedModules;
77
- dependencies = extractedDependencies;
78
- digest = extractedDigest;
79
- } catch (error: any) {
80
- throw new UpgradeError(error.stdout);
81
- }
82
-
83
- const tx = new TransactionBlock();
84
- const ticket = tx.moveCall({
85
- target: "0x2::package::authorize_upgrade",
86
- arguments: [
87
- tx.object(upgradeCap),
88
- tx.pure(UpgradePolicy.COMPATIBLE),
89
- tx.pure(digest),
90
- ],
91
- });
92
-
93
- const receipt = tx.upgrade({
94
- modules,
95
- dependencies,
96
- packageId: oldPackageId,
97
- ticket,
98
- });
99
-
100
- tx.moveCall({
101
- target: "0x2::package::commit_upgrade",
102
- arguments: [tx.object(upgradeCap), receipt],
103
- });
104
-
105
- tx.transferObjects(
106
- [tx.object(upgradeCap)],
107
- tx.pure(keypair.getPublicKey().toSuiAddress())
108
- );
109
-
110
- const result = await client.signAndExecuteTransactionBlock({
111
- signer: keypair,
112
- transactionBlock: tx,
113
- options: {
114
- showObjectChanges: true,
115
- },
116
- });
117
-
118
- console.log("");
119
- console.log(`${name} WorldId: ${worldId}`);
120
-
121
- let newPackageId = "";
122
- let newUpgradeCap = "";
123
- result.objectChanges!.map((object) => {
124
- if (object.type === "published") {
125
- console.log(chalk.blue(`${name} PackageId: ${object.packageId}`));
126
- newPackageId = object.packageId;
127
- }
128
- if (
129
- object.type === "mutated" &&
130
- object.objectType === "0x2::package::UpgradeCap"
131
- ) {
132
- console.log(chalk.blue(`${name} UpgradeCap: ${object.objectId}`));
133
- newUpgradeCap = object.objectId;
134
- }
135
- });
136
-
137
- console.log(chalk.green(`Upgrade Transaction Digest: ${result.digest}`));
138
-
139
- saveContractData(
140
- name,
141
- network,
142
- newPackageId,
143
- worldId,
144
- newUpgradeCap,
145
- adminCap,
146
- newVersion
147
- );
148
-
149
- oldPackageId = newPackageId;
150
- upgradeCap = newUpgradeCap;
151
- oldVersion = newVersion;
152
-
153
- console.log("\nExecuting the migrate: ");
154
- const delay = (ms: number) =>
155
- new Promise((resolve) => setTimeout(resolve, ms));
156
- await delay(5000);
157
-
158
- const migrateTx = new TransactionBlock();
159
- migrateTx.moveCall({
160
- target: `${newPackageId}::world::migrate`,
161
- arguments: [migrateTx.object(worldId), migrateTx.object(adminCap)],
162
- });
163
-
164
- let newWorldObject = await client.getObject({
165
- id: worldId,
166
- options: {
167
- showContent: true,
168
- showDisplay: true,
169
- showType: true,
170
- showOwner: true,
171
- },
172
- });
173
- let newObjectContent = newWorldObject.data!.content as ObjectContent;
174
-
175
- const uniqueSchema: string[] = schemaNames.filter(
176
- (item) => !newObjectContent.fields["schema_names"].includes(item)
177
- );
178
-
179
- console.log("new schema:", uniqueSchema);
180
- let needRegisterSchema = [];
181
- for (const newSchema of uniqueSchema) {
182
- migrateTx.moveCall({
183
- target: `${newPackageId}::${newSchema}_schema::register`,
184
- arguments: [migrateTx.object(worldId), migrateTx.object(adminCap)],
185
- });
186
- needRegisterSchema.push(`${newSchema}_schema`);
187
- }
188
- const migrateResult = await client.signAndExecuteTransactionBlock({
189
- signer: keypair,
190
- transactionBlock: migrateTx,
191
- options: {
192
- showEffects: true,
193
- },
194
- });
195
-
196
- if (migrateResult.effects?.status.status === "success") {
197
- console.log(
198
- chalk.green(
199
- `${name} migrate world success, new world version is: ${newObjectContent.fields["version"]}, package version is ${newVersion}`
200
- )
201
- );
202
- if (needRegisterSchema.length !== 0) {
203
- console.log(
204
- chalk.green(
205
- `new schema: ${needRegisterSchema.toString()} register success.`
206
- )
207
- );
208
- }
209
-
210
- console.log(
211
- chalk.blue(
212
- `\n${name} world schemas is ${newObjectContent.fields["schema_names"]}`
213
- )
214
- );
215
- } else {
216
- console.log(
217
- chalk.red(
218
- `${name} migrate world failed, world version is: ${newObjectContent.fields["version"]}, package version is ${newVersion}`
219
- )
220
- );
221
- }
222
- } catch (error: any) {
223
- console.log(chalk.red("Upgrade failed!"));
224
- console.error(error.message);
225
-
226
- saveContractData(
227
- name,
228
- network,
229
- oldPackageId,
230
- worldId,
231
- upgradeCap,
232
- adminCap,
233
- oldVersion
234
- );
235
- await updateVersionInFile(projectPath, oldVersion.toString());
236
- }
38
+ );
39
+
40
+ const privateKeyFormat = validatePrivateKey(privateKey);
41
+ if (privateKeyFormat === false) {
42
+ throw new ObeliskCliError(`Please check your privateKey.`);
43
+ }
44
+ const obelisk = new Obelisk({
45
+ secretKey: privateKeyFormat,
46
+ });
47
+ const keypair = obelisk.getKeypair();
48
+
49
+ const client = new SuiClient({
50
+ url: getFullnodeUrl(network),
51
+ });
52
+
53
+ let oldVersion = Number(await getVersion(projectPath, network));
54
+ let oldPackageId = await getOldPackageId(projectPath, network);
55
+ let worldId = await getWorldId(projectPath, network);
56
+ let upgradeCap = await getUpgradeCap(projectPath, network);
57
+ let adminCap = await getAdminCap(projectPath, network);
58
+
59
+ const newVersion = oldVersion + 1;
60
+ await updateVersionInFile(projectPath, newVersion.toString());
61
+
62
+ try {
63
+ let modules: any, dependencies: any, digest: any;
64
+ try {
65
+ const {
66
+ modules: extractedModules,
67
+ dependencies: extractedDependencies,
68
+ digest: extractedDigest,
69
+ } = JSON.parse(
70
+ execSync(
71
+ `sui move build --dump-bytecode-as-base64 --path ${path}/contracts/${name}`,
72
+ {
73
+ encoding: 'utf-8',
74
+ }
75
+ )
76
+ );
77
+
78
+ modules = extractedModules;
79
+ dependencies = extractedDependencies;
80
+ digest = extractedDigest;
81
+ } catch (error: any) {
82
+ throw new UpgradeError(error.stdout);
83
+ }
84
+
85
+ const tx = new Transaction();
86
+ const ticket = tx.moveCall({
87
+ target: '0x2::package::authorize_upgrade',
88
+ arguments: [
89
+ tx.object(upgradeCap),
90
+ tx.pure.u8(UpgradePolicy.COMPATIBLE),
91
+ tx.object(digest),
92
+ ],
93
+ });
94
+
95
+ const receipt = tx.upgrade({
96
+ modules,
97
+ dependencies,
98
+ package: oldPackageId,
99
+ ticket,
100
+ });
101
+
102
+ tx.moveCall({
103
+ target: '0x2::package::commit_upgrade',
104
+ arguments: [tx.object(upgradeCap), receipt],
105
+ });
106
+
107
+ tx.transferObjects(
108
+ [tx.object(upgradeCap)],
109
+ tx.pure(keypair.getPublicKey().toSuiAddress())
110
+ );
111
+
112
+ const result = await client.signAndExecuteTransaction({
113
+ signer: keypair,
114
+ transaction: tx,
115
+ options: {
116
+ showObjectChanges: true,
117
+ },
118
+ });
119
+
120
+ console.log('');
121
+ console.log(`${name} WorldId: ${worldId}`);
122
+
123
+ let newPackageId = '';
124
+ let newUpgradeCap = '';
125
+ result.objectChanges!.map(object => {
126
+ if (object.type === 'published') {
127
+ console.log(
128
+ chalk.blue(`${name} PackageId: ${object.packageId}`)
129
+ );
130
+ newPackageId = object.packageId;
131
+ }
132
+ if (
133
+ object.type === 'mutated' &&
134
+ object.objectType === '0x2::package::UpgradeCap'
135
+ ) {
136
+ console.log(
137
+ chalk.blue(`${name} UpgradeCap: ${object.objectId}`)
138
+ );
139
+ newUpgradeCap = object.objectId;
140
+ }
141
+ });
142
+
143
+ console.log(
144
+ chalk.green(`Upgrade Transaction Digest: ${result.digest}`)
145
+ );
146
+
147
+ saveContractData(
148
+ name,
149
+ network,
150
+ newPackageId,
151
+ worldId,
152
+ newUpgradeCap,
153
+ adminCap,
154
+ newVersion
155
+ );
156
+
157
+ oldPackageId = newPackageId;
158
+ upgradeCap = newUpgradeCap;
159
+ oldVersion = newVersion;
160
+
161
+ console.log('\nExecuting the migrate: ');
162
+ const delay = (ms: number) =>
163
+ new Promise(resolve => setTimeout(resolve, ms));
164
+ await delay(5000);
165
+
166
+ const migrateTx = new Transaction();
167
+ migrateTx.moveCall({
168
+ target: `${newPackageId}::world::migrate`,
169
+ arguments: [migrateTx.object(worldId), migrateTx.object(adminCap)],
170
+ });
171
+
172
+ let newWorldObject = await client.getObject({
173
+ id: worldId,
174
+ options: {
175
+ showContent: true,
176
+ showDisplay: true,
177
+ showType: true,
178
+ showOwner: true,
179
+ },
180
+ });
181
+ let newObjectContent = newWorldObject.data!.content as ObjectContent;
182
+
183
+ const uniqueSchema: string[] = schemaNames.filter(
184
+ item => !newObjectContent.fields['schema_names'].includes(item)
185
+ );
186
+
187
+ console.log('new schema:', uniqueSchema);
188
+ let needRegisterSchema = [];
189
+ for (const newSchema of uniqueSchema) {
190
+ migrateTx.moveCall({
191
+ target: `${newPackageId}::${newSchema}_schema::register`,
192
+ arguments: [
193
+ migrateTx.object(worldId),
194
+ migrateTx.object(adminCap),
195
+ ],
196
+ });
197
+ needRegisterSchema.push(`${newSchema}_schema`);
198
+ }
199
+ const migrateResult = await client.signAndExecuteTransaction({
200
+ signer: keypair,
201
+ transaction: migrateTx,
202
+ options: {
203
+ showEffects: true,
204
+ },
205
+ });
206
+
207
+ if (migrateResult.effects?.status.status === 'success') {
208
+ console.log(
209
+ chalk.green(
210
+ `${name} migrate world success, new world version is: ${newObjectContent.fields['version']}, package version is ${newVersion}`
211
+ )
212
+ );
213
+ if (needRegisterSchema.length !== 0) {
214
+ console.log(
215
+ chalk.green(
216
+ `new schema: ${needRegisterSchema.toString()} register success.`
217
+ )
218
+ );
219
+ }
220
+
221
+ console.log(
222
+ chalk.blue(
223
+ `\n${name} world schemas is ${newObjectContent.fields['schema_names']}`
224
+ )
225
+ );
226
+ } else {
227
+ console.log(
228
+ chalk.red(
229
+ `${name} migrate world failed, world version is: ${newObjectContent.fields['version']}, package version is ${newVersion}`
230
+ )
231
+ );
232
+ }
233
+ } catch (error: any) {
234
+ console.log(chalk.red('Upgrade failed!'));
235
+ console.error(error.message);
236
+
237
+ saveContractData(
238
+ name,
239
+ network,
240
+ oldPackageId,
241
+ worldId,
242
+ upgradeCap,
243
+ adminCap,
244
+ oldVersion
245
+ );
246
+ await updateVersionInFile(projectPath, oldVersion.toString());
247
+ }
237
248
  }
@@ -1,10 +1,7 @@
1
1
  import * as fsAsync from 'fs/promises';
2
2
  import { mkdirSync, writeFileSync } from 'fs';
3
3
  import { dirname } from 'path';
4
- import {
5
- SUI_PRIVATE_KEY_PREFIX,
6
- decodeSuiPrivateKey,
7
- } from '@mysten/sui.js/cryptography';
4
+ import { SUI_PRIVATE_KEY_PREFIX } from '@mysten/sui/cryptography';
8
5
  import { FsIibError } from './errors';
9
6
 
10
7
  export type DeploymentJsonType = {
@@ -17,7 +14,7 @@ export type DeploymentJsonType = {
17
14
  version: number;
18
15
  };
19
16
 
20
- export function validatePrivateKey(privateKey: string): boolean | string {
17
+ export function validatePrivateKey(privateKey: string): false | string {
21
18
  if (privateKey.startsWith(SUI_PRIVATE_KEY_PREFIX)) {
22
19
  if (privateKey.length === 70) {
23
20
  return privateKey;