@0xobelisk/sui-common 0.5.22 → 0.5.24

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.
@@ -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
+ }
@@ -0,0 +1,51 @@
1
+ import { BaseType, SchemaType } from '../../types';
2
+ import { formatAndWriteMove } from '../formatAndWrite';
3
+ import {
4
+ getStructAttrsWithType,
5
+ getStructAttrs,
6
+ getStructTypes,
7
+ getStructAttrsQuery,
8
+ } from './common';
9
+
10
+ function convertToSnakeCase(input: string): string {
11
+ return input
12
+ .replace(/([A-Z])/g, '_$1')
13
+ .toLowerCase()
14
+ .replace(/^_/, '');
15
+ }
16
+
17
+ export async function generateSchemaError(
18
+ projectName: string,
19
+ schemas: Record<string, SchemaType>,
20
+ path: string
21
+ ) {
22
+ console.log('\nšŸ“¦ Starting Schema Error Generation...');
23
+ for (const schemaName in schemas) {
24
+ const schema = schemas[schemaName];
25
+ if (schema.errors) {
26
+ console.log(` ā”œā”€ Processing schema: ${schemaName}`);
27
+ for (const item of schema.errors) {
28
+ console.log(
29
+ ` └─ Generating ${item.name} message: ${item.message}`);
30
+
31
+ let code = `module ${projectName}::${schemaName}_error_${convertToSnakeCase(item.name)} {
32
+ #[error]
33
+ const ${item.name}: vector<u8> = b"${item.message}";
34
+ /// Get the error message.
35
+ public fun message(): vector<u8> { ${item.name} }
36
+ /// Abort execution with the given error code.
37
+ public fun emit() { abort ${item.name} }
38
+ /// Require that the given condition is true, otherwise abort with the given error code.
39
+ public fun require(condition: bool) { if (!condition) { emit() } }`
40
+ await formatAndWriteMove(
41
+ code,
42
+ `${path}/contracts/${projectName}/sources/codegen/errors/${schemaName}_error_${convertToSnakeCase(
43
+ item.name
44
+ )}.move`,
45
+ 'formatAndWriteMove'
46
+ );
47
+ }
48
+ }
49
+ }
50
+ console.log('āœ… Schema Error Generation Complete\n');
51
+ }
@@ -42,7 +42,7 @@ export async function generateSchemaEvent(
42
42
  }`
43
43
  );
44
44
 
45
- let code = `module ${projectName}::${schemaName}_${convertToSnakeCase(item.name)}_event {
45
+ let code = `module ${projectName}::${schemaName}_event_${convertToSnakeCase(item.name)} {
46
46
  use sui::event;
47
47
  use std::ascii::String;
48
48
  public struct ${item.name}Event has copy, drop {
@@ -62,9 +62,9 @@ export async function generateSchemaEvent(
62
62
  }`;
63
63
  await formatAndWriteMove(
64
64
  code,
65
- `${path}/contracts/${projectName}/sources/codegen/events/${schemaName}_${convertToSnakeCase(
65
+ `${path}/contracts/${projectName}/sources/codegen/events/${schemaName}_event_${convertToSnakeCase(
66
66
  item.name
67
- )}_event.move`,
67
+ )}.move`,
68
68
  'formatAndWriteMove'
69
69
  );
70
70
  }
@@ -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::dapps_system;
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
- storage_migrate::borrow_field(&self.id, b"${key}")
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
- storage_migrate::borrow_mut_field(&mut self.id, b"${key}")
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 `storage_migrate::add_field<${value}>(&mut id, b"${key}", ${storage_type});`;
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 = 'try_get()';
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 = 'try_get(key)';
283
- extra_code = `public fun get_${key}_keys(self: &${capitalizeAndRemoveUnderscores(schemaName)}) : vector<${all_types[0]}> {
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 = 'try_get(key1, key2)';
294
- extra_code = `public fun get_${key}_keys(self: &${capitalizeAndRemoveUnderscores(schemaName)}) : (vector<${all_types[0]}>, vector<${all_types[1]}>) {
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}) : Option<${para_value}> {
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;