@0xobelisk/sui-cli 0.5.30 → 0.5.31
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/dist/dubhe.js +56 -40
- package/dist/dubhe.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/checkBalance.ts +35 -0
- package/src/commands/generateKey.ts +35 -0
- package/src/commands/index.ts +7 -1
- package/src/commands/storeConfig.ts +44 -0
- package/src/utils/checkBalance.ts +55 -0
- package/src/utils/errors.ts +31 -31
- package/src/utils/generateAccount.ts +100 -0
- package/src/utils/publishHandler.ts +71 -32
- package/src/utils/storeConfig.ts +79 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Dubhe, NetworkType } from '@0xobelisk/sui-client';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import dotenv from 'dotenv';
|
|
4
|
+
import { validatePrivateKey } from './utils';
|
|
5
|
+
import { DubheCliError } from './errors';
|
|
6
|
+
dotenv.config();
|
|
7
|
+
|
|
8
|
+
export async function checkBalanceHandler(
|
|
9
|
+
network: 'mainnet' | 'testnet' | 'devnet' | 'loclnet',
|
|
10
|
+
amount: number = 2
|
|
11
|
+
) {
|
|
12
|
+
try {
|
|
13
|
+
console.log(
|
|
14
|
+
chalk.blue(
|
|
15
|
+
`Note: You need at least 2 SUI for transaction fees and staking, and registering a Dapp will reserve 1 SUI for Dubhe Dapp Staking, which can be retrieved upon unregistering.`
|
|
16
|
+
)
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
const privateKey = process.env.PRIVATE_KEY;
|
|
20
|
+
if (!privateKey) {
|
|
21
|
+
throw new DubheCliError(
|
|
22
|
+
`Missing PRIVATE_KEY environment variable.
|
|
23
|
+
Run 'echo "PRIVATE_KEY=YOUR_PRIVATE_KEY" > .env'
|
|
24
|
+
in your contracts directory to use the default sui private key.`
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
const privateKeyFormat = validatePrivateKey(privateKey);
|
|
28
|
+
if (privateKeyFormat === false) {
|
|
29
|
+
throw new DubheCliError(`Please check your privateKey.`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const dubhe = new Dubhe({
|
|
33
|
+
secretKey: process.env.PRIVATE_KEY,
|
|
34
|
+
networkType: network as NetworkType,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const balance = await dubhe.getBalance();
|
|
38
|
+
const balanceInSUI = Number(balance.totalBalance) / 1_000_000_000;
|
|
39
|
+
|
|
40
|
+
if (balanceInSUI < amount) {
|
|
41
|
+
// console.log(chalk.yellow(`Account balance is less than 2 SUI.`));
|
|
42
|
+
throw new DubheCliError(
|
|
43
|
+
`Account balance is less than ${amount} SUI. Please get more SUI.`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
console.log(
|
|
48
|
+
chalk.green(
|
|
49
|
+
`Current account balance: ${balanceInSUI.toFixed(4)} SUI`
|
|
50
|
+
)
|
|
51
|
+
);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
throw new DubheCliError('Failed to check balance: ' + error);
|
|
54
|
+
}
|
|
55
|
+
}
|
package/src/utils/errors.ts
CHANGED
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
import chalk from
|
|
2
|
-
import { ZodError } from
|
|
3
|
-
import { fromZodError, ValidationError } from
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { ZodError } from 'zod';
|
|
3
|
+
import { fromZodError, ValidationError } from 'zod-validation-error';
|
|
4
4
|
|
|
5
5
|
export class NotInsideProjectError extends Error {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
name = 'NotInsideProjectError';
|
|
7
|
+
message = 'You are not inside a Dubhe project';
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export class DubheCliError extends Error {
|
|
11
|
-
|
|
11
|
+
name = 'DubheCliError';
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export class UpgradeError extends Error {
|
|
15
|
-
|
|
15
|
+
name = 'UpgradeError';
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export class FsIibError extends Error {
|
|
19
|
-
|
|
19
|
+
name = 'FsIibError';
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export function logError(error: unknown) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
23
|
+
if (error instanceof ValidationError) {
|
|
24
|
+
console.log(chalk.redBright(error.message));
|
|
25
|
+
} else if (error instanceof ZodError) {
|
|
26
|
+
// TODO currently this error shouldn't happen, use `fromZodErrorCustom`
|
|
27
|
+
const validationError = fromZodError(error, {
|
|
28
|
+
prefixSeparator: '\n- ',
|
|
29
|
+
issueSeparator: '\n- ',
|
|
30
|
+
});
|
|
31
|
+
console.log(chalk.redBright(validationError.message));
|
|
32
|
+
} else if (error instanceof NotInsideProjectError) {
|
|
33
|
+
console.log(chalk.red(error.message));
|
|
34
|
+
console.log('');
|
|
35
|
+
// TODO add docs to the website and update the link to the specific page
|
|
36
|
+
console.log(
|
|
37
|
+
chalk.blue(
|
|
38
|
+
`To learn more about Dubhe's configuration, please go to https://github.com/0xobelisk`
|
|
39
|
+
)
|
|
40
|
+
);
|
|
41
|
+
} else if (error instanceof DubheCliError) {
|
|
42
|
+
console.log(chalk.red(error));
|
|
43
|
+
} else {
|
|
44
|
+
console.log(error);
|
|
45
|
+
}
|
|
46
46
|
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { Dubhe } from '@0xobelisk/sui-client';
|
|
2
|
+
import * as fs from 'fs';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
|
|
5
|
+
export async function generateAccountHandler(
|
|
6
|
+
force: boolean = false,
|
|
7
|
+
outputTsPath: string
|
|
8
|
+
) {
|
|
9
|
+
const path = process.cwd();
|
|
10
|
+
let privateKey: string;
|
|
11
|
+
|
|
12
|
+
if (force) {
|
|
13
|
+
const dubhe = new Dubhe();
|
|
14
|
+
const keypair = dubhe.getKeypair();
|
|
15
|
+
privateKey = keypair.getSecretKey();
|
|
16
|
+
|
|
17
|
+
fs.writeFileSync(`${path}/.env`, `PRIVATE_KEY=${privateKey}`);
|
|
18
|
+
console.log(chalk.green(`File created at: ${path}/.env`));
|
|
19
|
+
|
|
20
|
+
if (outputTsPath) {
|
|
21
|
+
const dir = outputTsPath.substring(
|
|
22
|
+
0,
|
|
23
|
+
outputTsPath.lastIndexOf('/')
|
|
24
|
+
);
|
|
25
|
+
if (!fs.existsSync(dir)) {
|
|
26
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
27
|
+
}
|
|
28
|
+
fs.writeFileSync(
|
|
29
|
+
outputTsPath,
|
|
30
|
+
`export const PRIVATEKEY = '${privateKey}';
|
|
31
|
+
export const ACCOUNT = '${keypair.toSuiAddress()}';
|
|
32
|
+
`
|
|
33
|
+
);
|
|
34
|
+
console.log(chalk.green(`File created at: ${outputTsPath}`));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
console.log(
|
|
38
|
+
chalk.blue(`Force generate new Account: ${keypair.toSuiAddress()}`)
|
|
39
|
+
);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Check if .env file exists and has content
|
|
44
|
+
try {
|
|
45
|
+
const envContent = fs.readFileSync(`${path}/.env`, 'utf8');
|
|
46
|
+
const match = envContent.match(/PRIVATE_KEY=(.+)/);
|
|
47
|
+
if (match && match[1]) {
|
|
48
|
+
privateKey = match[1];
|
|
49
|
+
const dubhe = new Dubhe({ secretKey: privateKey });
|
|
50
|
+
const keypair = dubhe.getKeypair();
|
|
51
|
+
|
|
52
|
+
if (outputTsPath) {
|
|
53
|
+
const dir = outputTsPath.substring(
|
|
54
|
+
0,
|
|
55
|
+
outputTsPath.lastIndexOf('/')
|
|
56
|
+
);
|
|
57
|
+
if (!fs.existsSync(dir)) {
|
|
58
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
59
|
+
}
|
|
60
|
+
fs.writeFileSync(
|
|
61
|
+
outputTsPath,
|
|
62
|
+
`export const PRIVATEKEY = '${privateKey}';
|
|
63
|
+
export const ACCOUNT = '${keypair.toSuiAddress()}';
|
|
64
|
+
`
|
|
65
|
+
);
|
|
66
|
+
console.log(chalk.green(`File created at: ${outputTsPath}`));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
console.log(
|
|
70
|
+
chalk.blue(`Using existing Account: ${keypair.toSuiAddress()}`)
|
|
71
|
+
);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
} catch (error) {
|
|
75
|
+
// .env file doesn't exist or failed to read, continue to generate new account
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// If no existing private key, generate new account
|
|
79
|
+
const dubhe = new Dubhe();
|
|
80
|
+
const keypair = dubhe.getKeypair();
|
|
81
|
+
privateKey = keypair.getSecretKey();
|
|
82
|
+
fs.writeFileSync(`${path}/.env`, `PRIVATE_KEY=${privateKey}`);
|
|
83
|
+
console.log(chalk.green(`File created at: ${path}/.env`));
|
|
84
|
+
|
|
85
|
+
if (outputTsPath) {
|
|
86
|
+
const dir = outputTsPath.substring(0, outputTsPath.lastIndexOf('/'));
|
|
87
|
+
if (!fs.existsSync(dir)) {
|
|
88
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
89
|
+
}
|
|
90
|
+
fs.writeFileSync(
|
|
91
|
+
outputTsPath,
|
|
92
|
+
`export const PRIVATEKEY = '${privateKey}';
|
|
93
|
+
export const ACCOUNT = '${keypair.toSuiAddress()}';
|
|
94
|
+
`
|
|
95
|
+
);
|
|
96
|
+
console.log(chalk.green(`File created at: ${outputTsPath}`));
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
console.log(chalk.blue(`Generate new Account: ${keypair.toSuiAddress()}`));
|
|
100
|
+
}
|
|
@@ -12,7 +12,11 @@ import {
|
|
|
12
12
|
updateVersionInFile,
|
|
13
13
|
saveContractData,
|
|
14
14
|
validatePrivateKey,
|
|
15
|
-
schema,
|
|
15
|
+
schema,
|
|
16
|
+
getSchemaHub,
|
|
17
|
+
updateDubheDependency,
|
|
18
|
+
switchEnv,
|
|
19
|
+
delay,
|
|
16
20
|
} from './utils';
|
|
17
21
|
import { DubheConfig } from '@0xobelisk/sui-common';
|
|
18
22
|
import * as fs from 'fs';
|
|
@@ -22,9 +26,12 @@ async function getDappsObjectId(
|
|
|
22
26
|
network: 'mainnet' | 'testnet' | 'devnet' | 'localnet'
|
|
23
27
|
) {
|
|
24
28
|
switch (network) {
|
|
25
|
-
case
|
|
29
|
+
case 'localnet': {
|
|
26
30
|
const path = process.cwd();
|
|
27
|
-
return await getSchemaHub(
|
|
31
|
+
return await getSchemaHub(
|
|
32
|
+
`${path}/contracts/dubhe-framework`,
|
|
33
|
+
network
|
|
34
|
+
);
|
|
28
35
|
}
|
|
29
36
|
case 'testnet':
|
|
30
37
|
return '0x8dbf8d28ac027ba214c9e0951b09f6842843be6cb87242b7d9a326a2677cd47a';
|
|
@@ -33,12 +40,18 @@ async function getDappsObjectId(
|
|
|
33
40
|
}
|
|
34
41
|
}
|
|
35
42
|
|
|
36
|
-
function removeEnvContent(
|
|
43
|
+
function removeEnvContent(
|
|
44
|
+
filePath: string,
|
|
45
|
+
networkType: 'mainnet' | 'testnet' | 'devnet' | 'localnet'
|
|
46
|
+
): void {
|
|
37
47
|
if (!fs.existsSync(filePath)) {
|
|
38
48
|
return;
|
|
39
49
|
}
|
|
40
50
|
const content = fs.readFileSync(filePath, 'utf-8');
|
|
41
|
-
const regex = new RegExp(
|
|
51
|
+
const regex = new RegExp(
|
|
52
|
+
`\\[env\\.${networkType}\\][\\s\\S]*?(?=\\[|$)`,
|
|
53
|
+
'g'
|
|
54
|
+
);
|
|
42
55
|
const updatedContent = content.replace(regex, '');
|
|
43
56
|
fs.writeFileSync(filePath, updatedContent, 'utf-8');
|
|
44
57
|
}
|
|
@@ -56,12 +69,20 @@ const chainIds: { [key: string]: string } = {
|
|
|
56
69
|
mainnet: '35834a8a',
|
|
57
70
|
};
|
|
58
71
|
|
|
59
|
-
function updateEnvFile(
|
|
72
|
+
function updateEnvFile(
|
|
73
|
+
filePath: string,
|
|
74
|
+
networkType: 'mainnet' | 'testnet' | 'devnet' | 'localnet',
|
|
75
|
+
operation: 'publish' | 'upgrade',
|
|
76
|
+
chainId: string,
|
|
77
|
+
publishedId: string
|
|
78
|
+
): void {
|
|
60
79
|
const envFilePath = path.resolve(filePath);
|
|
61
80
|
const envContent = fs.readFileSync(envFilePath, 'utf-8');
|
|
62
81
|
const envLines = envContent.split('\n');
|
|
63
82
|
|
|
64
|
-
const networkSectionIndex = envLines.findIndex(
|
|
83
|
+
const networkSectionIndex = envLines.findIndex(
|
|
84
|
+
line => line.trim() === `[env.${networkType}]`
|
|
85
|
+
);
|
|
65
86
|
const config: EnvConfig = {
|
|
66
87
|
chainId: chainId,
|
|
67
88
|
originalPublishedId: '',
|
|
@@ -76,14 +97,18 @@ function updateEnvFile(filePath: string, networkType: 'mainnet' | 'testnet' | 'd
|
|
|
76
97
|
config.latestPublishedId = publishedId;
|
|
77
98
|
config.publishedVersion = 1;
|
|
78
99
|
} else {
|
|
79
|
-
throw new Error(
|
|
100
|
+
throw new Error(
|
|
101
|
+
`Network type [env.${networkType}] not found in the file and cannot upgrade.`
|
|
102
|
+
);
|
|
80
103
|
}
|
|
81
104
|
} else {
|
|
82
105
|
for (let i = networkSectionIndex + 1; i < envLines.length; i++) {
|
|
83
106
|
const line = envLines[i].trim();
|
|
84
107
|
if (line.startsWith('[')) break; // End of the current network section
|
|
85
108
|
|
|
86
|
-
const [key, value] = line
|
|
109
|
+
const [key, value] = line
|
|
110
|
+
.split('=')
|
|
111
|
+
.map(part => part.trim().replace(/"/g, ''));
|
|
87
112
|
switch (key) {
|
|
88
113
|
case 'original-published-id':
|
|
89
114
|
config.originalPublishedId = value;
|
|
@@ -115,9 +140,11 @@ latest-published-id = "${config.latestPublishedId}"
|
|
|
115
140
|
published-version = "${config.publishedVersion}"
|
|
116
141
|
`;
|
|
117
142
|
|
|
118
|
-
const newEnvContent =
|
|
119
|
-
|
|
120
|
-
|
|
143
|
+
const newEnvContent =
|
|
144
|
+
networkSectionIndex === -1
|
|
145
|
+
? envContent + updatedSection
|
|
146
|
+
: envLines.slice(0, networkSectionIndex).join('\n') +
|
|
147
|
+
updatedSection;
|
|
121
148
|
|
|
122
149
|
fs.writeFileSync(envFilePath, newEnvContent, 'utf-8');
|
|
123
150
|
}
|
|
@@ -137,7 +164,7 @@ function getLastSegment(input: string): string {
|
|
|
137
164
|
return segments.length > 0 ? segments[segments.length - 1] : '';
|
|
138
165
|
}
|
|
139
166
|
|
|
140
|
-
function buildContract(projectPath: string):
|
|
167
|
+
function buildContract(projectPath: string): string[][] {
|
|
141
168
|
let modules: any, dependencies: any;
|
|
142
169
|
try {
|
|
143
170
|
const buildResult = JSON.parse(
|
|
@@ -168,7 +195,7 @@ async function publishContract(
|
|
|
168
195
|
projectPath: string
|
|
169
196
|
) {
|
|
170
197
|
const dappsObjectId = await getDappsObjectId(network);
|
|
171
|
-
console.log(
|
|
198
|
+
console.log('dappsObjectId', dappsObjectId);
|
|
172
199
|
const chainId = await client.getChainIdentifier();
|
|
173
200
|
removeEnvContent(`${projectPath}/Move.lock`, network);
|
|
174
201
|
console.log('\n🚀 Starting Contract Publication...');
|
|
@@ -227,7 +254,7 @@ async function publishContract(
|
|
|
227
254
|
}
|
|
228
255
|
if (
|
|
229
256
|
object.type === 'created' &&
|
|
230
|
-
object.objectType.includes(
|
|
257
|
+
object.objectType.includes('schema_hub')
|
|
231
258
|
) {
|
|
232
259
|
console.log(` ├─ Schema Hub: ${object.objectId}`);
|
|
233
260
|
schemaHubId = object.objectId;
|
|
@@ -236,14 +263,20 @@ async function publishContract(
|
|
|
236
263
|
|
|
237
264
|
console.log(` └─ Transaction: ${result.digest}`);
|
|
238
265
|
|
|
239
|
-
updateEnvFile(
|
|
266
|
+
updateEnvFile(
|
|
267
|
+
`${projectPath}/Move.lock`,
|
|
268
|
+
network,
|
|
269
|
+
'publish',
|
|
270
|
+
chainId,
|
|
271
|
+
packageId
|
|
272
|
+
);
|
|
240
273
|
|
|
241
274
|
console.log('\n⚡ Executing Deploy Hook...');
|
|
242
275
|
await delay(5000);
|
|
243
276
|
|
|
244
277
|
const deployHookTx = new Transaction();
|
|
245
278
|
deployHookTx.setGasBudget(2000000000);
|
|
246
|
-
const [txCoin] = deployHookTx.splitCoins(deployHookTx.gas, [
|
|
279
|
+
const [txCoin] = deployHookTx.splitCoins(deployHookTx.gas, ['1000000000']);
|
|
247
280
|
deployHookTx.moveCall({
|
|
248
281
|
target: `${packageId}::deploy_hook::run`,
|
|
249
282
|
arguments: [
|
|
@@ -251,7 +284,7 @@ async function publishContract(
|
|
|
251
284
|
deployHookTx.object(dappsObjectId),
|
|
252
285
|
deployHookTx.object(upgradeCapId),
|
|
253
286
|
deployHookTx.object('0x6'),
|
|
254
|
-
txCoin
|
|
287
|
+
txCoin,
|
|
255
288
|
],
|
|
256
289
|
});
|
|
257
290
|
|
|
@@ -276,14 +309,18 @@ async function publishContract(
|
|
|
276
309
|
deployHookResult.objectChanges?.map(object => {
|
|
277
310
|
if (
|
|
278
311
|
object.type === 'created' &&
|
|
279
|
-
object.objectType.includes('_schema') &&
|
|
312
|
+
object.objectType.includes('_schema') &&
|
|
313
|
+
!object.objectType.includes('dynamic_field')
|
|
280
314
|
) {
|
|
281
315
|
console.log(` ├─ ${object.objectType}`);
|
|
282
316
|
console.log(` └─ ID: ${object.objectId}`);
|
|
283
317
|
|
|
284
318
|
let structure: Record<string, string> = {};
|
|
285
319
|
for (let schemaKey in dubheConfig.schemas) {
|
|
286
|
-
if (
|
|
320
|
+
if (
|
|
321
|
+
capitalizeAndRemoveUnderscores(schemaKey) ===
|
|
322
|
+
getLastSegment(object.objectType)
|
|
323
|
+
) {
|
|
287
324
|
structure = dubheConfig.schemas[schemaKey].structure;
|
|
288
325
|
}
|
|
289
326
|
}
|
|
@@ -303,7 +340,7 @@ async function publishContract(
|
|
|
303
340
|
upgradeCapId,
|
|
304
341
|
schemaHubId,
|
|
305
342
|
version,
|
|
306
|
-
schemas
|
|
343
|
+
schemas
|
|
307
344
|
);
|
|
308
345
|
console.log('\n✅ Contract Publication Complete\n');
|
|
309
346
|
} else {
|
|
@@ -319,7 +356,7 @@ async function publishContract(
|
|
|
319
356
|
export async function publishDubheFramework(
|
|
320
357
|
client: SuiClient,
|
|
321
358
|
dubhe: Dubhe,
|
|
322
|
-
network: 'mainnet' | 'testnet' | 'devnet' | 'localnet'
|
|
359
|
+
network: 'mainnet' | 'testnet' | 'devnet' | 'localnet'
|
|
323
360
|
) {
|
|
324
361
|
const path = process.cwd();
|
|
325
362
|
const projectPath = `${path}/contracts/dubhe-framework`;
|
|
@@ -335,7 +372,6 @@ export async function publishDubheFramework(
|
|
|
335
372
|
const keypair = dubhe.getKeypair();
|
|
336
373
|
console.log(` └─ Account: ${keypair.toSuiAddress()}`);
|
|
337
374
|
|
|
338
|
-
|
|
339
375
|
console.log('\n📦 Building Contract...');
|
|
340
376
|
const [modules, dependencies] = buildContract(projectPath);
|
|
341
377
|
|
|
@@ -381,10 +417,7 @@ export async function publishDubheFramework(
|
|
|
381
417
|
console.log(` ├─ Upgrade Cap: ${object.objectId}`);
|
|
382
418
|
upgradeCapId = object.objectId;
|
|
383
419
|
}
|
|
384
|
-
if (
|
|
385
|
-
object.type === 'created' &&
|
|
386
|
-
object.objectType.includes("dapps")
|
|
387
|
-
) {
|
|
420
|
+
if (object.type === 'created' && object.objectType.includes('dapps')) {
|
|
388
421
|
console.log(` ├─ Dapps: ${object.objectId}`);
|
|
389
422
|
schemaHubId = object.objectId;
|
|
390
423
|
}
|
|
@@ -392,23 +425,29 @@ export async function publishDubheFramework(
|
|
|
392
425
|
|
|
393
426
|
console.log(` └─ Transaction: ${result.digest}`);
|
|
394
427
|
|
|
395
|
-
updateEnvFile(
|
|
428
|
+
updateEnvFile(
|
|
429
|
+
`${projectPath}/Move.lock`,
|
|
430
|
+
network,
|
|
431
|
+
'publish',
|
|
432
|
+
chainId,
|
|
433
|
+
packageId
|
|
434
|
+
);
|
|
396
435
|
|
|
397
436
|
saveContractData(
|
|
398
|
-
|
|
437
|
+
'dubhe-framework',
|
|
399
438
|
network,
|
|
400
439
|
packageId,
|
|
401
440
|
upgradeCapId,
|
|
402
441
|
schemaHubId,
|
|
403
442
|
version,
|
|
404
|
-
schemas
|
|
443
|
+
schemas
|
|
405
444
|
);
|
|
406
445
|
}
|
|
407
446
|
|
|
408
447
|
export async function publishHandler(
|
|
409
448
|
dubheConfig: DubheConfig,
|
|
410
449
|
network: 'mainnet' | 'testnet' | 'devnet' | 'localnet',
|
|
411
|
-
contractName?: string
|
|
450
|
+
contractName?: string
|
|
412
451
|
) {
|
|
413
452
|
await switchEnv(network);
|
|
414
453
|
|
|
@@ -428,7 +467,7 @@ in your contracts directory to use the default sui private key.`
|
|
|
428
467
|
const dubhe = new Dubhe({ secretKey: privateKeyFormat });
|
|
429
468
|
const client = new SuiClient({ url: getFullnodeUrl(network) });
|
|
430
469
|
|
|
431
|
-
if (contractName ==
|
|
470
|
+
if (contractName == 'dubhe-framework') {
|
|
432
471
|
await publishDubheFramework(client, dubhe, network);
|
|
433
472
|
} else {
|
|
434
473
|
const path = process.cwd();
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import * as fsAsync from 'fs/promises';
|
|
2
|
+
import { mkdirSync, writeFileSync } from 'fs';
|
|
3
|
+
import { exit } from 'process';
|
|
4
|
+
import { dirname } from 'path';
|
|
5
|
+
import { DeploymentJsonType, schema } from './utils';
|
|
6
|
+
import { DubheConfig } from '@0xobelisk/sui-common';
|
|
7
|
+
|
|
8
|
+
async function getDeploymentJson(
|
|
9
|
+
projectPath: string,
|
|
10
|
+
network: string
|
|
11
|
+
): Promise<DeploymentJsonType> {
|
|
12
|
+
try {
|
|
13
|
+
const data = await fsAsync.readFile(
|
|
14
|
+
`${projectPath}/.history/sui_${network}/latest.json`,
|
|
15
|
+
'utf8'
|
|
16
|
+
);
|
|
17
|
+
return JSON.parse(data) as DeploymentJsonType;
|
|
18
|
+
} catch (error) {
|
|
19
|
+
throw new Error(
|
|
20
|
+
`read .history/sui_${network}/latest.json failed. ${error}`
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function storeConfig(
|
|
26
|
+
network: string,
|
|
27
|
+
packageId: string,
|
|
28
|
+
schemas: schema[],
|
|
29
|
+
outputPath: string
|
|
30
|
+
) {
|
|
31
|
+
let code = `type NetworkType = 'testnet' | 'mainnet' | 'devnet' | 'localnet';
|
|
32
|
+
|
|
33
|
+
export const NETWORK: NetworkType = '${network}';
|
|
34
|
+
|
|
35
|
+
export const PACKAGE_ID = '${packageId}'
|
|
36
|
+
|
|
37
|
+
${schemas
|
|
38
|
+
.map(
|
|
39
|
+
schema =>
|
|
40
|
+
`export const ${schema.name.split('::')[2]}_Object_Id = '${
|
|
41
|
+
schema.objectId
|
|
42
|
+
}'`
|
|
43
|
+
)
|
|
44
|
+
.join('\n')}
|
|
45
|
+
`;
|
|
46
|
+
// if (outputPath) {
|
|
47
|
+
writeOutput(code, outputPath, 'storeConfig');
|
|
48
|
+
// writeOutput(code, `${path}/src/chain/config.ts`, 'storeConfig');
|
|
49
|
+
// }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function writeOutput(
|
|
53
|
+
output: string,
|
|
54
|
+
fullOutputPath: string,
|
|
55
|
+
logPrefix?: string
|
|
56
|
+
): Promise<void> {
|
|
57
|
+
mkdirSync(dirname(fullOutputPath), { recursive: true });
|
|
58
|
+
|
|
59
|
+
writeFileSync(fullOutputPath, output);
|
|
60
|
+
if (logPrefix !== undefined) {
|
|
61
|
+
console.log(`${logPrefix}: ${fullOutputPath}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export async function storeConfigHandler(
|
|
66
|
+
dubheConfig: DubheConfig,
|
|
67
|
+
network: 'mainnet' | 'testnet' | 'devnet' | 'localnet',
|
|
68
|
+
outputPath: string
|
|
69
|
+
) {
|
|
70
|
+
const path = process.cwd();
|
|
71
|
+
const contractPath = `${path}/contracts/${dubheConfig.name}`;
|
|
72
|
+
const deployment = await getDeploymentJson(contractPath, network);
|
|
73
|
+
storeConfig(
|
|
74
|
+
deployment.network,
|
|
75
|
+
deployment.packageId,
|
|
76
|
+
deployment.schemas,
|
|
77
|
+
outputPath
|
|
78
|
+
);
|
|
79
|
+
}
|