@0xobelisk/sui-common 0.5.23 ā 0.5.25
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/index.d.ts +2 -3
- package/dist/index.js +413 -198
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/codegen/types/index.ts +1 -2
- package/src/codegen/utils/formatAndWrite.ts +6 -4
- package/src/codegen/utils/renderMove/generateDefaultSchema.ts +327 -0
- package/src/codegen/utils/renderMove/generateError.ts +5 -4
- package/src/codegen/utils/renderMove/generateInit.ts +40 -0
- package/src/codegen/utils/renderMove/generateSchema.ts +18 -14
- package/src/codegen/utils/renderMove/generateScript.ts +78 -82
- package/src/codegen/utils/renderMove/generateToml.ts +1 -2
- package/src/codegen/utils/renderMove/schemaGen.ts +7 -25
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { DubheConfig } from '../../types';
|
|
2
|
+
import { formatAndWriteMove } from '../formatAndWrite';
|
|
3
|
+
import { existsSync } from 'fs';
|
|
4
|
+
import { capitalizeAndRemoveUnderscores } from './generateSchema';
|
|
5
|
+
|
|
6
|
+
export async function generateDefaultSchema(
|
|
7
|
+
config: DubheConfig,
|
|
8
|
+
srcPrefix: string
|
|
9
|
+
) {
|
|
10
|
+
await generateDappSchemaMetadata(config, srcPrefix);
|
|
11
|
+
await generateDappSchema(config, srcPrefix);
|
|
12
|
+
await generateDappSystem(config, srcPrefix);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function generateDappSchemaMetadata(config: DubheConfig, srcPrefix: string) {
|
|
16
|
+
const path = `${srcPrefix}/contracts/${config.name}/sources/codegen/schemas/default/dapp/metadata.move`
|
|
17
|
+
if (!existsSync(path)) {
|
|
18
|
+
let code = `module ${config.name}::dapp_metadata {
|
|
19
|
+
use std::ascii::String;
|
|
20
|
+
|
|
21
|
+
public struct DappMetadata has drop, copy, store {
|
|
22
|
+
name: String,
|
|
23
|
+
description: String,
|
|
24
|
+
icon_url: String,
|
|
25
|
+
website_url: String,
|
|
26
|
+
created_at: u64,
|
|
27
|
+
partners: vector<String>,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public fun new(
|
|
31
|
+
name: String,
|
|
32
|
+
description: String,
|
|
33
|
+
icon_url: String,
|
|
34
|
+
website_url: String,
|
|
35
|
+
created_at: u64,
|
|
36
|
+
partners: vector<String>,
|
|
37
|
+
): DappMetadata {
|
|
38
|
+
DappMetadata {
|
|
39
|
+
name,
|
|
40
|
+
description,
|
|
41
|
+
icon_url,
|
|
42
|
+
website_url,
|
|
43
|
+
created_at,
|
|
44
|
+
partners,
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public fun set(
|
|
49
|
+
self: &mut DappMetadata,
|
|
50
|
+
name: String,
|
|
51
|
+
description: String,
|
|
52
|
+
icon_url: String,
|
|
53
|
+
website_url: String,
|
|
54
|
+
created_at: u64,
|
|
55
|
+
partners: vector<String>,
|
|
56
|
+
) {
|
|
57
|
+
self.name = name;
|
|
58
|
+
self.description = description;
|
|
59
|
+
self.icon_url = icon_url;
|
|
60
|
+
self.website_url = website_url;
|
|
61
|
+
self.created_at = created_at;
|
|
62
|
+
self.partners = partners;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public fun set_name(self: &mut DappMetadata, name: String) {
|
|
66
|
+
self.name = name;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
public fun set_description(self: &mut DappMetadata, description: String) {
|
|
70
|
+
self.description = description;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public fun set_icon_url(self: &mut DappMetadata, icon_url: String) {
|
|
74
|
+
self.icon_url = icon_url;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public fun set_website_url(self: &mut DappMetadata, website_url: String) {
|
|
78
|
+
self.website_url = website_url;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
public fun set_created_at(self: &mut DappMetadata, created_at: u64) {
|
|
82
|
+
self.created_at = created_at;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
public fun set_partners(self: &mut DappMetadata, partners: vector<String>) {
|
|
86
|
+
self.partners = partners;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public fun get_name(self: DappMetadata): String {
|
|
90
|
+
self.name
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public fun get_description(self: DappMetadata): String {
|
|
94
|
+
self.description
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public fun get_icon_url(self: DappMetadata): String {
|
|
98
|
+
self.icon_url
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public fun get_website_url(self: DappMetadata): String {
|
|
102
|
+
self.website_url
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
public fun get_created_at(self: DappMetadata): u64 {
|
|
106
|
+
self.created_at
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
public fun get_partners(self: DappMetadata): vector<String> {
|
|
110
|
+
self.partners
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
}
|
|
114
|
+
`;
|
|
115
|
+
await formatAndWriteMove(
|
|
116
|
+
code,
|
|
117
|
+
path,
|
|
118
|
+
'formatAndWriteMove'
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
async function generateDappSchema(config: DubheConfig, srcPrefix: string) {
|
|
125
|
+
const path = `${srcPrefix}/contracts/${config.name}/sources/codegen/schemas/default/dapp/schema.move`
|
|
126
|
+
if (!existsSync(path)) {
|
|
127
|
+
let code = `module ${config.name}::dapp_schema {
|
|
128
|
+
use ${config.name}::dapp_metadata::DappMetadata;
|
|
129
|
+
use dubhe::storage_value;
|
|
130
|
+
use dubhe::storage_value::StorageValue;
|
|
131
|
+
use dubhe::storage_migration;
|
|
132
|
+
use sui::transfer::public_share_object;
|
|
133
|
+
use dubhe::type_info;
|
|
134
|
+
|
|
135
|
+
public struct Dapp has key, store { id: UID }
|
|
136
|
+
|
|
137
|
+
public fun borrow_admin(self: &Dapp): &StorageValue<address> {
|
|
138
|
+
storage_migration::borrow_field(&self.id, b"admin")
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
public(package) fun borrow_mut_admin(self: &mut Dapp): &mut StorageValue<address> {
|
|
142
|
+
storage_migration::borrow_mut_field(&mut self.id, b"admin")
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
public fun borrow_package_id(self: &Dapp): &StorageValue<address> {
|
|
146
|
+
storage_migration::borrow_field(&self.id, b"package_id")
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
public(package) fun borrow_mut_package_id(self: &mut Dapp): &mut StorageValue<address> {
|
|
150
|
+
storage_migration::borrow_mut_field(&mut self.id, b"package_id")
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
public fun borrow_version(self: &Dapp): &StorageValue<u32> {
|
|
154
|
+
storage_migration::borrow_field(&self.id, b"version")
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
public(package) fun borrow_mut_version(self: &mut Dapp): &mut StorageValue<u32> {
|
|
158
|
+
storage_migration::borrow_mut_field(&mut self.id, b"version")
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
public fun borrow_metadata(self: &Dapp): &StorageValue<DappMetadata> {
|
|
162
|
+
storage_migration::borrow_field(&self.id, b"metadata")
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
public(package) fun borrow_mut_metadata(self: &mut Dapp): &mut StorageValue<DappMetadata> {
|
|
166
|
+
storage_migration::borrow_mut_field(&mut self.id, b"metadata")
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
public fun borrow_schemas(self: &Dapp): &StorageValue<vector<address>> {
|
|
170
|
+
storage_migration::borrow_field(&self.id, b"schemas")
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
public(package) fun borrow_mut_schemas(self: &mut Dapp): &mut StorageValue<vector<address>> {
|
|
174
|
+
storage_migration::borrow_mut_field(&mut self.id, b"schemas")
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
public fun borrow_safe_mode(self: &Dapp): &StorageValue<bool> {
|
|
178
|
+
storage_migration::borrow_field(&self.id, b"safe_mode")
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
public(package) fun borrow_mut_safe_mode(self: &mut Dapp): &mut StorageValue<bool> {
|
|
182
|
+
storage_migration::borrow_mut_field(&mut self.id, b"safe_mode")
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
public(package) fun create(ctx: &mut TxContext): Dapp {
|
|
186
|
+
let mut id = object::new(ctx);
|
|
187
|
+
storage_migration::add_field<StorageValue<address>>(&mut id, b"admin", storage_value::new());
|
|
188
|
+
storage_migration::add_field<StorageValue<address>>(&mut id, b"package_id", storage_value::new());
|
|
189
|
+
storage_migration::add_field<StorageValue<u32>>(&mut id, b"version", storage_value::new());
|
|
190
|
+
storage_migration::add_field<StorageValue<DappMetadata>>(&mut id, b"metadata", storage_value::new());
|
|
191
|
+
storage_migration::add_field<StorageValue<vector<address>>>(&mut id, b"schemas", storage_value::new());
|
|
192
|
+
storage_migration::add_field<StorageValue<bool>>(&mut id, b"safe_mode", storage_value::new());
|
|
193
|
+
Dapp { id }
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
public(package) fun upgrade<DappKey: drop>(dapp: &mut Dapp, ctx: &TxContext) {
|
|
197
|
+
assert!(dapp.borrow_metadata().contains(), 0);
|
|
198
|
+
assert!(dapp.borrow_admin().get() == ctx.sender(), 0);
|
|
199
|
+
|
|
200
|
+
let new_package_id = type_info::current_package_id<DappKey>();
|
|
201
|
+
dapp.borrow_mut_package_id().set(new_package_id);
|
|
202
|
+
dapp.borrow_mut_version().mutate!(|version| {
|
|
203
|
+
*version = *version + 1;
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
public(package) fun add_schema<Schema: key + store>(dapp: &mut Dapp, schema: Schema, ctx: &TxContext) {
|
|
208
|
+
assert!(dapp.borrow_metadata().contains(), 0);
|
|
209
|
+
assert!(dapp.borrow_admin().get() == ctx.sender(), 0);
|
|
210
|
+
|
|
211
|
+
let schema_id = object::id_address(&schema);
|
|
212
|
+
dapp.borrow_mut_schemas().borrow_mut().push_back(schema_id);
|
|
213
|
+
public_share_object(schema);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
#[test_only]
|
|
217
|
+
public fun create_dapp_for_testing(ctx: &mut TxContext): Dapp {
|
|
218
|
+
create(ctx)
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
#[test_only]
|
|
222
|
+
public fun distroy_dapp_for_testing(dapp: Dapp) {
|
|
223
|
+
let Dapp { id } = dapp;
|
|
224
|
+
id.delete();
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
`;
|
|
228
|
+
await formatAndWriteMove(
|
|
229
|
+
code,
|
|
230
|
+
path,
|
|
231
|
+
'formatAndWriteMove'
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
async function generateDappSystem(config: DubheConfig, srcPrefix: string) {
|
|
237
|
+
const path = `${srcPrefix}/contracts/${config.name}/sources/codegen/schemas/default/dapp/system.move`
|
|
238
|
+
if (!existsSync(path)) {
|
|
239
|
+
let code = `module ${config.name}::dapp_system {
|
|
240
|
+
use std::ascii::String;
|
|
241
|
+
use std::ascii;
|
|
242
|
+
use dubhe::type_info;
|
|
243
|
+
use sui::clock::Clock;
|
|
244
|
+
use ${config.name}::dapp_schema;
|
|
245
|
+
use ${config.name}::dapp_metadata;
|
|
246
|
+
use ${config.name}::dapp_schema::Dapp;
|
|
247
|
+
|
|
248
|
+
public struct DappKey has drop {}
|
|
249
|
+
|
|
250
|
+
public(package) fun new(): DappKey {
|
|
251
|
+
DappKey { }
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
public(package) fun create(name: String, description: String, clock: &Clock, ctx: &mut TxContext): Dapp {
|
|
255
|
+
let mut dapp = dapp_schema::create(ctx);
|
|
256
|
+
assert!(!dapp.borrow_metadata().contains(), 0);
|
|
257
|
+
dapp.borrow_mut_metadata().set(
|
|
258
|
+
dapp_metadata::new(
|
|
259
|
+
name,
|
|
260
|
+
description,
|
|
261
|
+
ascii::string(b""),
|
|
262
|
+
ascii::string(b""),
|
|
263
|
+
clock.timestamp_ms(),
|
|
264
|
+
vector[]
|
|
265
|
+
)
|
|
266
|
+
);
|
|
267
|
+
let package_id = type_info::current_package_id<DappKey>();
|
|
268
|
+
dapp.borrow_mut_package_id().set(package_id);
|
|
269
|
+
dapp.borrow_mut_admin().set(ctx.sender());
|
|
270
|
+
dapp.borrow_mut_version().set(1);
|
|
271
|
+
dapp.borrow_mut_safe_mode().set(false);
|
|
272
|
+
dapp.borrow_mut_schemas().set(vector[]);
|
|
273
|
+
dapp
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
public entry fun set_metadata(dapp: &mut Dapp, name: String, description: String, icon_url: String, website_url: String, partners: vector<String>, ctx: &TxContext) {
|
|
277
|
+
assert!(dapp.borrow_admin().contains(), 0);
|
|
278
|
+
assert!(dapp.borrow_admin().get() == ctx.sender(), 0);
|
|
279
|
+
let created_at = dapp.borrow_mut_metadata().take().get_created_at();
|
|
280
|
+
dapp.borrow_mut_metadata().set(
|
|
281
|
+
dapp_metadata::new(
|
|
282
|
+
name,
|
|
283
|
+
description,
|
|
284
|
+
icon_url,
|
|
285
|
+
website_url,
|
|
286
|
+
created_at,
|
|
287
|
+
partners
|
|
288
|
+
)
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
public entry fun transfer_ownership(dapp: &mut Dapp, new_admin: address, ctx: &mut TxContext) {
|
|
293
|
+
assert!(dapp.borrow_admin().contains(), 0);
|
|
294
|
+
assert!(dapp.borrow_admin().get() == ctx.sender(), 0);
|
|
295
|
+
|
|
296
|
+
dapp.borrow_mut_admin().set(new_admin);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
public entry fun set_safe_mode(dapp: &mut Dapp, safe_mode: bool, ctx: &TxContext) {
|
|
300
|
+
assert!(dapp.borrow_admin().contains(), 0);
|
|
301
|
+
assert!(dapp.borrow_admin().get() == ctx.sender(), 0);
|
|
302
|
+
|
|
303
|
+
dapp.borrow_mut_safe_mode().set(safe_mode);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
public fun ensure_no_safe_mode(dapp: &Dapp) {
|
|
307
|
+
assert!(!dapp.borrow_safe_mode().get(), 0);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
public fun ensure_has_authority(dapp: &Dapp, ctx: &TxContext) {
|
|
311
|
+
assert!(dapp.borrow_admin().get() == ctx.sender(), 0);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
public fun ensure_has_schema<Schema: key + store>(dapp: &Dapp, schema: &Schema) {
|
|
315
|
+
let schema_id = object::id_address(schema);
|
|
316
|
+
assert!(dapp.borrow_schemas().get().contains(&schema_id), 0);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
`;
|
|
321
|
+
await formatAndWriteMove(
|
|
322
|
+
code,
|
|
323
|
+
path,
|
|
324
|
+
'formatAndWriteMove'
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
@@ -26,12 +26,13 @@ export async function generateSchemaError(
|
|
|
26
26
|
console.log(` āā Processing schema: ${schemaName}`);
|
|
27
27
|
for (const item of schema.errors) {
|
|
28
28
|
console.log(
|
|
29
|
-
` āā Generating ${item.name}
|
|
29
|
+
` āā Generating ${item.name} message: ${item.message}`);
|
|
30
30
|
|
|
31
31
|
let code = `module ${projectName}::${schemaName}_error_${convertToSnakeCase(item.name)} {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
#[error]
|
|
33
|
+
const ${item.name}: vector<u8> = b"${item.message}";
|
|
34
|
+
/// Get the error message.
|
|
35
|
+
public fun message(): vector<u8> { ${item.name} }
|
|
35
36
|
/// Abort execution with the given error code.
|
|
36
37
|
public fun emit() { abort ${item.name} }
|
|
37
38
|
/// Require that the given condition is true, otherwise abort with the given error code.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { DubheConfig } from '../../types';
|
|
2
|
+
import { formatAndWriteMove } from '../formatAndWrite';
|
|
3
|
+
import { existsSync } from 'fs';
|
|
4
|
+
import { capitalizeAndRemoveUnderscores } from './generateSchema';
|
|
5
|
+
|
|
6
|
+
export async function generateInit(
|
|
7
|
+
config: DubheConfig,
|
|
8
|
+
srcPrefix: string
|
|
9
|
+
) {
|
|
10
|
+
console.log('\nš Starting Init Generation...');
|
|
11
|
+
console.log(
|
|
12
|
+
` āā Output path: ${srcPrefix}/contracts/${config.name}/sources/tests/init.move`
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
let code = `module ${config.name}::init_test {
|
|
16
|
+
use ${config.name}::dapp_schema::Dapp;
|
|
17
|
+
use sui::clock;
|
|
18
|
+
use sui::test_scenario;
|
|
19
|
+
use sui::test_scenario::Scenario;
|
|
20
|
+
|
|
21
|
+
public fun deploy_dapp_for_testing(sender: address): (Scenario, Dapp) {
|
|
22
|
+
let mut scenario = test_scenario::begin(sender);
|
|
23
|
+
let ctx = test_scenario::ctx(&mut scenario);
|
|
24
|
+
let clock = clock::create_for_testing(ctx);
|
|
25
|
+
${config.name}::deploy_hook::run(&clock, ctx);
|
|
26
|
+
clock::destroy_for_testing(clock);
|
|
27
|
+
test_scenario::next_tx(&mut scenario,sender);
|
|
28
|
+
let dapp = test_scenario::take_shared<Dapp>(&scenario);
|
|
29
|
+
(scenario, dapp)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
await formatAndWriteMove(
|
|
34
|
+
code,
|
|
35
|
+
`${srcPrefix}/contracts/${config.name}/sources/tests/init.move`,
|
|
36
|
+
'formatAndWriteMove'
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
console.log('ā
Deploy Hook Generation Complete\n');
|
|
40
|
+
}
|
|
@@ -201,15 +201,15 @@ export async function generateSchemaStructure(
|
|
|
201
201
|
use std::ascii::String;
|
|
202
202
|
use std::ascii::string;
|
|
203
203
|
use sui::package::UpgradeCap;
|
|
204
|
-
use std::type_name;
|
|
205
|
-
use dubhe::
|
|
206
|
-
use dubhe::storage_migrate;
|
|
207
|
-
use dubhe::dapps_schema::Dapps;
|
|
204
|
+
use std::type_name;
|
|
205
|
+
use dubhe::storage_migration;
|
|
208
206
|
use dubhe::storage_value::{Self, StorageValue};
|
|
209
207
|
use dubhe::storage_map::{Self, StorageMap};
|
|
210
208
|
use dubhe::storage_double_map::{Self, StorageDoubleMap};
|
|
211
|
-
use ${projectName}::dapp_key::DappKey;
|
|
212
209
|
use sui::dynamic_field as df;
|
|
210
|
+
use sui::sui::SUI;
|
|
211
|
+
use sui::coin::Coin;
|
|
212
|
+
use sui::balance::Balance;
|
|
213
213
|
${generateImport(projectName, schemaName, schema)}
|
|
214
214
|
|
|
215
215
|
public struct ${capitalizeAndRemoveUnderscores(
|
|
@@ -223,13 +223,13 @@ export async function generateSchemaStructure(
|
|
|
223
223
|
return `public fun borrow_${key}(self: &${capitalizeAndRemoveUnderscores(
|
|
224
224
|
schemaName,
|
|
225
225
|
)}) : &${value} {
|
|
226
|
-
|
|
226
|
+
storage_migration::borrow_field(&self.id, b"${key}")
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
public(package) fun borrow_mut_${key}(self: &mut ${capitalizeAndRemoveUnderscores(
|
|
230
230
|
schemaName,
|
|
231
231
|
)}): &mut ${value} {
|
|
232
|
-
|
|
232
|
+
storage_migration::borrow_mut_field(&mut self.id, b"${key}")
|
|
233
233
|
}
|
|
234
234
|
`;
|
|
235
235
|
})
|
|
@@ -252,7 +252,7 @@ export async function generateSchemaStructure(
|
|
|
252
252
|
) {
|
|
253
253
|
storage_type = `storage_double_map::new()`;
|
|
254
254
|
}
|
|
255
|
-
return `
|
|
255
|
+
return `storage_migration::add_field<${value}>(&mut id, b"${key}", ${storage_type});`;
|
|
256
256
|
})
|
|
257
257
|
.join('')}
|
|
258
258
|
|
|
@@ -275,31 +275,35 @@ export async function generateSchemaStructure(
|
|
|
275
275
|
if (value.includes('StorageValue')) {
|
|
276
276
|
para_key = [];
|
|
277
277
|
para_value = `${all_types[0]}`;
|
|
278
|
-
borrow_key = '
|
|
278
|
+
borrow_key = 'borrow()';
|
|
279
279
|
} else if (value.includes('StorageMap')) {
|
|
280
280
|
para_key = [`key: ${all_types[0]}`];
|
|
281
281
|
para_value = `${all_types[1]}`;
|
|
282
|
-
borrow_key = '
|
|
283
|
-
|
|
282
|
+
borrow_key = 'borrow(key)';
|
|
283
|
+
if (!value.includes('Balance') && !value.includes('Coin')) {
|
|
284
|
+
extra_code = `public fun get_${key}_keys(self: &${capitalizeAndRemoveUnderscores(schemaName)}) : vector<${all_types[0]}> {
|
|
284
285
|
self.borrow_${key}().keys()
|
|
285
286
|
}
|
|
286
287
|
|
|
287
288
|
public fun get_${key}_values(self: &${capitalizeAndRemoveUnderscores(schemaName)}) : vector<${all_types[1]}> {
|
|
288
289
|
self.borrow_${key}().values()
|
|
289
290
|
}`;
|
|
291
|
+
}
|
|
290
292
|
} else if (value.includes('StorageDoubleMap')) {
|
|
291
293
|
para_key = [`key1: ${all_types[0]}`, `key2: ${all_types[1]}`];
|
|
292
294
|
para_value = `${all_types[2]}`;
|
|
293
|
-
borrow_key = '
|
|
294
|
-
|
|
295
|
+
borrow_key = 'borrow(key1, key2)';
|
|
296
|
+
if (!value.includes('Balance') && !value.includes('Coin')) {
|
|
297
|
+
extra_code = `public fun get_${key}_keys(self: &${capitalizeAndRemoveUnderscores(schemaName)}) : (vector<${all_types[0]}>, vector<${all_types[1]}>) {
|
|
295
298
|
self.borrow_${key}().keys()
|
|
296
299
|
}
|
|
297
300
|
|
|
298
301
|
public fun get_${key}_values(self: &${capitalizeAndRemoveUnderscores(schemaName)}) : vector<${all_types[2]}> {
|
|
299
302
|
self.borrow_${key}().values()
|
|
300
303
|
}`;
|
|
304
|
+
}
|
|
301
305
|
}
|
|
302
|
-
return `public fun get_${key}(self: &${capitalizeAndRemoveUnderscores(schemaName)}, ${para_key}) :
|
|
306
|
+
return `public fun get_${key}(self: &${capitalizeAndRemoveUnderscores(schemaName)}, ${para_key}) : &${para_value} {
|
|
303
307
|
self.borrow_${key}().${borrow_key}
|
|
304
308
|
}
|
|
305
309
|
` + extra_code;
|
|
@@ -3,6 +3,20 @@ import { formatAndWriteMove } from '../formatAndWrite';
|
|
|
3
3
|
import { existsSync } from 'fs';
|
|
4
4
|
import { capitalizeAndRemoveUnderscores } from './generateSchema';
|
|
5
5
|
|
|
6
|
+
import { readFileSync } from 'fs';
|
|
7
|
+
|
|
8
|
+
export function extractLogicAndAuthorizationContent(filePath: string): string {
|
|
9
|
+
const fileContent = readFileSync(filePath, 'utf-8');
|
|
10
|
+
const logicAndAuthRegex = /\/\/ Logic that needs to be automated once the contract is deployed\s*\{([\s\S]*?)\}\s*;\s*\/\/ Authorize schemas and public share objects/;
|
|
11
|
+
const match = fileContent.match(logicAndAuthRegex);
|
|
12
|
+
|
|
13
|
+
if (match) {
|
|
14
|
+
return match[1].trim();
|
|
15
|
+
} else {
|
|
16
|
+
throw new Error('Logic and authorization block not found in the file.');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
6
20
|
export async function generateDeployHook(
|
|
7
21
|
config: DubheConfig,
|
|
8
22
|
srcPrefix: string
|
|
@@ -12,89 +26,71 @@ export async function generateDeployHook(
|
|
|
12
26
|
` āā Output path: ${srcPrefix}/contracts/${config.name}/sources/scripts/deploy_hook.move`
|
|
13
27
|
);
|
|
14
28
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
#[test_only]
|
|
34
|
-
use sui::clock;
|
|
35
|
-
#[test_only]
|
|
36
|
-
use sui::coin;
|
|
37
|
-
#[test_only]
|
|
38
|
-
use sui::test_scenario;
|
|
39
|
-
#[test_only]
|
|
40
|
-
use sui::package;
|
|
41
|
-
#[test_only]
|
|
42
|
-
use ${config.name}::schema_hub;
|
|
43
|
-
#[test_only]
|
|
44
|
-
use dubhe::dapps_schema;
|
|
45
|
-
#[test_only]
|
|
46
|
-
use sui::test_scenario::Scenario;
|
|
47
|
-
|
|
48
|
-
public entry fun run(schema_hub: &mut SchemaHub, dapps: &mut Dapps, cap: &UpgradeCap, clock: &Clock, coin: Coin<SUI>, ctx: &mut TxContext) {
|
|
49
|
-
// Register the dapp to dubhe.
|
|
50
|
-
dapps_system::register(dapps,cap,string(b"${config.name}"),string(b"${config.description}"),clock,coin,ctx);
|
|
51
|
-
// Create schemas
|
|
52
|
-
${Object.keys(config.schemas).map(schemaName => {
|
|
53
|
-
return `let ${schemaName} = ${config.name}::${schemaName}_schema::create(ctx);`;
|
|
54
|
-
}).join('\n')}
|
|
55
|
-
// Logic that needs to be automated once the contract is deployed
|
|
56
|
-
${`\n`}
|
|
57
|
-
${`\n`}
|
|
58
|
-
|
|
59
|
-
// Authorize schemas and public share objects
|
|
60
|
-
${Object.keys(config.schemas).map(schemaName => {
|
|
61
|
-
return `
|
|
62
|
-
schema_hub.authorize_schema<${capitalizeAndRemoveUnderscores(schemaName)}>();
|
|
63
|
-
public_share_object(${schemaName});
|
|
64
|
-
`;
|
|
29
|
+
const schemas = Object.keys(config.schemas).map(schemaName => { return `_${schemaName}: &mut ${capitalizeAndRemoveUnderscores(schemaName)}`}).join(',')
|
|
30
|
+
const importSchemas = Object.keys(config.schemas).map(schemaName => { return `use ${config.name}::${schemaName}_schema::${capitalizeAndRemoveUnderscores(schemaName)};`}).join('\n')
|
|
31
|
+
const path = `${srcPrefix}/contracts/${config.name}/sources/scripts/deploy_hook.move`;
|
|
32
|
+
let code = '';
|
|
33
|
+
if (!existsSync(path)) {
|
|
34
|
+
code = `module ${config.name}::deploy_hook {
|
|
35
|
+
use std::ascii::string;
|
|
36
|
+
use sui::clock::Clock;
|
|
37
|
+
use ${config.name}::dapp_system;
|
|
38
|
+
${importSchemas}
|
|
39
|
+
public entry fun run(clock: &Clock, ctx: &mut TxContext) {
|
|
40
|
+
// Create a dapp.
|
|
41
|
+
let mut dapp = dapp_system::create(string(b"${config.name}"),string(b"${config.description}"), clock , ctx);
|
|
42
|
+
|
|
43
|
+
// Create schemas
|
|
44
|
+
${Object.keys(config.schemas).map(schemaName => {
|
|
45
|
+
return `let mut ${schemaName} = ${config.name}::${schemaName}_schema::create(ctx);`;
|
|
65
46
|
}).join('\n')}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
47
|
+
// Logic that needs to be automated once the contract is deployed
|
|
48
|
+
{
|
|
49
|
+
};
|
|
50
|
+
// Authorize schemas and public share objects
|
|
51
|
+
${Object.keys(config.schemas).map(schemaName => {
|
|
52
|
+
return `
|
|
53
|
+
dapp.add_schema<${capitalizeAndRemoveUnderscores(schemaName)}>(${schemaName}, ctx);
|
|
54
|
+
`;
|
|
55
|
+
}).join('\n')}
|
|
56
|
+
sui::transfer::public_share_object(dapp);
|
|
57
|
+
}
|
|
58
|
+
}` } else {
|
|
59
|
+
const content = extractLogicAndAuthorizationContent(path);
|
|
60
|
+
code = `module ${config.name}::deploy_hook {
|
|
61
|
+
use std::ascii::string;
|
|
62
|
+
use sui::clock::Clock;
|
|
63
|
+
use ${config.name}::dapp_system;
|
|
64
|
+
${importSchemas}
|
|
65
|
+
public entry fun run(clock: &Clock, ctx: &mut TxContext) {
|
|
66
|
+
// Create a dapp.
|
|
67
|
+
let mut dapp = dapp_system::create(string(b"${config.name}"),string(b"${config.description}"), clock , ctx);
|
|
68
|
+
|
|
69
|
+
// Create schemas
|
|
70
|
+
${Object.keys(config.schemas).map(schemaName => {
|
|
71
|
+
return `let mut ${schemaName} = ${config.name}::${schemaName}_schema::create(ctx);`;
|
|
72
|
+
}).join('\n')}
|
|
73
|
+
// Logic that needs to be automated once the contract is deployed
|
|
74
|
+
|
|
75
|
+
{
|
|
76
|
+
${content}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// Authorize schemas and public share objects
|
|
80
|
+
${Object.keys(config.schemas).map(schemaName => {
|
|
81
|
+
return `
|
|
82
|
+
dapp.add_schema<${capitalizeAndRemoveUnderscores(schemaName)}>(${schemaName}, ctx);
|
|
83
|
+
`;
|
|
84
|
+
}).join('\n')}
|
|
85
|
+
sui::transfer::public_share_object(dapp);
|
|
86
|
+
}
|
|
87
|
+
}`
|
|
97
88
|
}
|
|
89
|
+
await formatAndWriteMove(
|
|
90
|
+
code,
|
|
91
|
+
path,
|
|
92
|
+
'formatAndWriteMove'
|
|
93
|
+
);
|
|
98
94
|
console.log('ā
Deploy Hook Generation Complete\n');
|
|
99
95
|
}
|
|
100
96
|
|
|
@@ -105,7 +101,7 @@ export async function generateMigrate(config: DubheConfig, srcPrefix: string) {
|
|
|
105
101
|
)
|
|
106
102
|
) {
|
|
107
103
|
let code = `module ${config.name}::migrate {
|
|
108
|
-
const ON_CHAIN_VERSION: u32 =
|
|
104
|
+
const ON_CHAIN_VERSION: u32 = 1;
|
|
109
105
|
|
|
110
106
|
public fun on_chain_version(): u32 {
|
|
111
107
|
ON_CHAIN_VERSION
|
|
@@ -4,7 +4,6 @@ import { formatAndWriteMove } from '../formatAndWrite';
|
|
|
4
4
|
export async function generateToml(
|
|
5
5
|
config: DubheConfig,
|
|
6
6
|
srcPrefix: string,
|
|
7
|
-
frameworkId: string
|
|
8
7
|
) {
|
|
9
8
|
console.log('\nš Starting Move.toml Generation...');
|
|
10
9
|
console.log(
|
|
@@ -18,7 +17,7 @@ edition = "2024"
|
|
|
18
17
|
|
|
19
18
|
[dependencies]
|
|
20
19
|
Sui = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/sui-framework", rev = "mainnet-v1.38.3" }
|
|
21
|
-
Dubhe = { git = "https://github.com/0xobelisk/dubhe-framework.git", rev = "dubhe-testnet-v1.
|
|
20
|
+
Dubhe = { git = "https://github.com/0xobelisk/dubhe-framework.git", rev = "dubhe-testnet-v1.1.0" }
|
|
22
21
|
|
|
23
22
|
[addresses]
|
|
24
23
|
sui = "0x2"
|