@0xobelisk/sui-client 0.5.27 → 0.5.28

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/README.md CHANGED
@@ -1,78 +1,57 @@
1
1
  # Dubhe Client SDK
2
2
 
3
- Dubhe is client agnostic: any client -- a browser, a game engine, or an ios/android app -- can implement the synchronization protocol and a client-side cache to replicate Store tables, along with the necessary infrastructure to send transactions to the World.
4
-
5
- Currently we only support browsers, Node and the COCOS game engine.
3
+ Dubhe is a client-agnostic SDK that supports various platforms including browsers, Node.js, and the COCOS game engine. It provides a simple interface to interact with your Sui Move contracts.
6
4
 
7
5
  ## Getting Started
8
6
 
9
- Before proceeding with the next steps, make sure you have deployed your own world contract via cli.
7
+ ### Prerequisites
10
8
 
11
- When the world contract is deployed successfully, it will return a PackageId (the contract's ObjectId) and a WorldId (the World Store's ObjectId).
9
+ Before using the SDK, make sure you have:
12
10
 
13
- ### Data preparation
11
+ 1. Created and deployed your contract using the Dubhe CLI
12
+ 2. Obtained the `packageId` after deployment
14
13
 
15
- We create a Project called Counter and declare sigleton schema called counter, which is of type `u64` and has an initial value of `0`.
14
+ ### Data Model Setup
16
15
 
16
+ First, define your contract's configuration using `DubheConfig`:
17
17
 
18
18
  ```typescript
19
19
  import { DubheConfig } from '@0xobelisk/sui-common';
20
20
 
21
- export const obeliskConfig = {
21
+ export const dubheConfig = {
22
22
  name: 'counter',
23
23
  description: 'counter',
24
- systems: ['counter_system'],
24
+ systems: ['counter'],
25
25
  schemas: {
26
26
  counter: {
27
- valueType: 'u64',
28
- defaultValue: 0,
27
+ structure: {
28
+ value: 'StorageValue<u32>',
29
+ },
29
30
  },
30
31
  },
31
- sample_schema: 'u64',
32
32
  } as DubheConfig;
33
33
  ```
34
34
 
35
- Through the CLI, we will generate the corresponding contract based on dubhe.config.ts At this point we need to write the system logic.
35
+ Generate the contract code using CLI:
36
36
 
37
37
  ```bash
38
- obelisk schemagen dubhe.config.ts
38
+ dubhe schemagen --configPath dubhe.config.ts
39
39
  ```
40
40
 
41
- The next step is simply to write the system file method.
42
-
43
- ```rust
44
- // contracts/counter/system/counter_system.move
45
- module counter::counter_system {
46
- use counter::world::World;
47
- use counter::counter_schema;
48
-
49
- public entry fun inc(world: &mut World){
50
- let value = counter_schema::get(world) + 1;
51
- counter_schema::set(world,value);
52
- }
53
- }
54
- ```
41
+ ### Initializing the Client
55
42
 
56
- Finally we deploy the complete contract to devnet
43
+ There are two ways to initialize the Dubhe client:
57
44
 
58
-
59
- ```bash
60
- obelisk publish --network devnet --configPath dubhe.config.ts
61
- ```
62
-
63
- We'll get the `packageId` and `worldId` on the command line.
64
-
65
- ### Init Dubhe Client
45
+ 1. Using dynamic metadata loading:
66
46
 
67
47
  ```typescript
68
- import { getMetadata, Dubhe, NetworkType } from "@0xobelisk/sui-client";
69
-
70
- const network = "devnet" as NetworkType
71
- const packageId = "0x804578b9eed47d461bba52c393cf148302819e2ba0a0f558356cc419b3e941ed"
48
+ import { loadMetadata, Dubhe, NetworkType } from "@0xobelisk/sui-client";
72
49
 
73
- const metadata = await getMetadata(network, packageId);
50
+ const network = "devnet" as NetworkType;
51
+ const packageId = "YOUR_PACKAGE_ID";
74
52
 
75
- const obelisk = new Dubhe({
53
+ const metadata = await loadMetadata(network, packageId);
54
+ const dubhe = new Dubhe({
76
55
  networkType: network,
77
56
  packageId: packageId,
78
57
  metadata: metadata,
@@ -80,205 +59,119 @@ const obelisk = new Dubhe({
80
59
  });
81
60
  ```
82
61
 
83
- ### World Tx
84
-
85
- If you need to call a method in the system, you can do so using the `obelisk.tx.moudleName.funcName()` form.
62
+ 2. Using pre-saved metadata (recommended for better performance):
86
63
 
87
64
  ```typescript
88
- import { getMetadata, Dubhe, TransactionBlock } from "@0xobelisk/sui-client";
89
-
90
- const metadata = await getMetadata(network, packageId);
65
+ import metadata from './metadata.json';
91
66
 
92
- const obelisk = new Dubhe({
67
+ const dubhe = new Dubhe({
93
68
  networkType: network,
94
69
  packageId: packageId,
95
70
  metadata: metadata,
96
71
  secretKey: privkey
97
72
  });
98
-
99
- // Initiate transactions through the account set up by obelisk
100
- const tx = new TransactionBlock()
101
-
102
- const world = tx.pure(WORLD_ID)
103
- const params = [
104
- world,
105
- ]
106
-
107
- const res_tx = await obelisk.tx.counter_system.inc(tx, params)
108
-
109
- // If you want to encapsulate the TransactionBlock
110
- const tx = new TransactionBlock()
111
- const world = tx.pure(WORLD_ID)
112
- const params = [
113
- world,
114
- ]
115
- // By isolating the signature from the transactionBlock construction in this way,
116
- // the front-end wallet plugin can signAndSend() directly to the transactionBlock,
117
- // facilitating front-end interaction.
118
- const new_tx = await obelisk.tx.counter_system.inc(tx, params, undefined, true) as TransactionBlock;
119
-
120
- const response = await obelisk.signAndSendTxn(
121
- new_tx
122
- )
123
73
  ```
124
74
 
125
- ### World Query
75
+ ### Executing Transactions
126
76
 
127
- #### Query public contract view func
128
-
129
- If your system method provides a method with no modification status and a return, then you can query it via `obelisk.query.moudleName.funcName()`.
77
+ To call contract methods:
130
78
 
131
79
  ```typescript
132
- const metadata = await getMetadata(NETWORK, PACKAGE_ID);
133
- const obelisk = new Dubhe({
134
- networkType: NETWORK,
135
- packageId: PACKAGE_ID,
136
- metadata: metadata,
137
- });
138
-
139
- const tx = new TransactionBlock()
140
- const world = tx.pure(WORLD_ID)
141
- const params = [
142
- world,
143
- ]
144
- const query_value = await obelisk.query.counter_system.get(tx, params);
145
- ```
80
+ import { Transaction } from "@0xobelisk/sui-client";
146
81
 
147
- #### Get world
82
+ // Create transaction
83
+ const tx = new Transaction();
84
+ const params = [/* your parameters */];
148
85
 
149
- Queries the Object information of worldId.
86
+ // Execute transaction
87
+ const response = await dubhe.tx.counter_system.inc(tx, params);
150
88
 
151
- ```typescript
152
- const metadata = await getMetadata(NETWORK, PACKAGE_ID);
153
- const obelisk = new Dubhe({
154
- networkType: NETWORK,
155
- packageId: PACKAGE_ID,
156
- metadata: metadata,
157
- });
158
- const world_value = await obelisk.getWorld(WORLD_ID)
89
+ // For wallet integration
90
+ await dubhe.tx.counter_system.inc(tx, params, undefined, true);
91
+ const response = await dubhe.signAndSendTxn(tx);
159
92
  ```
160
93
 
94
+ ### Querying Data
161
95
 
162
- #### List schema names
163
-
164
- List all schema name in the world store.
96
+ To query contract state:
165
97
 
166
98
  ```typescript
167
- const metadata = await getMetadata(NETWORK, PACKAGE_ID);
168
- const obelisk = new Dubhe({
169
- networkType: NETWORK,
170
- packageId: PACKAGE_ID,
171
- metadata: metadata,
172
- });
173
- const schemaNames = await obelisk.listSchemaNames(
174
- '0x1541f3a2e7ac48e3e68e60bb97a7cee94e16316cc3f9043a9c0f5e6790ea3af0'
175
- );
176
- ```
99
+ const tx = new Transaction();
100
+ const params = [/* your parameters */];
101
+ const result = await dubhe.query.counter_system.get(tx, params);
177
102
 
103
+ // For BCS encoded results
104
+ const decodedData = dubhe.view(result);
105
+ ```
178
106
 
179
- #### Get entity
107
+ ### BCS Data Decoding
180
108
 
181
- Get the entity's data based on schema name and entity id(option).
109
+ The SDK provides a `view()` method to decode BCS-encoded return values from contract queries.
182
110
 
183
- ```typescript
184
- const metadata = await getMetadata(NETWORK, PACKAGE_ID);
185
- const obelisk = new Dubhe({
186
- networkType: NETWORK,
187
- packageId: PACKAGE_ID,
188
- metadata: metadata,
189
- });
111
+ #### Supported Types
190
112
 
191
- const worldId = "0x1541f3a2e7ac48e3e68e60bb97a7cee94e16316cc3f9043a9c0f5e6790ea3af0";
113
+ - Basic types (u8, u16, u32, u64, u128, u256)
114
+ - Boolean
115
+ - String
116
+ - Vector
117
+ - Struct
118
+ - Option
119
+ - Custom objects
192
120
 
193
- // get schema entity data
194
- const schemaName = "simple_schema"
195
- const entityId = "0x00000000000000000000000000000000000000000000000000000000000003ed"
196
- const entities = await obelisk.getEntity(
197
- worldId,
198
- schemaName,
199
- entityId
200
- );
121
+ #### Example with Complex Types
201
122
 
202
- // get singleton schema entity data
203
- const singletonSchemaName = "counter"
204
- const entities = await obelisk.getEntity(
205
- worldId,
206
- singletonSchemaName
207
- );
123
+ ```typescript
124
+ // Example contract return type
125
+ struct GameState {
126
+ score: u64,
127
+ player_name: String,
128
+ is_active: bool,
129
+ items: vector<Item>
130
+ }
208
131
 
132
+ // Query and decode
133
+ const tx = new Transaction();
134
+ const result = await dubhe.query.game_system.get_state(tx, params);
135
+ const decodedState = dubhe.view(result);
209
136
  ```
210
137
 
138
+ #### Known Limitations
211
139
 
212
- #### Contain entity
140
+ ⚠️ **Important Note**:
213
141
 
214
- Determine if the entity exists
142
+ 1. The current implementation cannot automatically decode enum types due to limitations in Sui metadata.
143
+ 2. Some complex nested structures might require additional handling.
215
144
 
216
- ```typescript
217
- const metadata = await getMetadata(NETWORK, PACKAGE_ID);
218
- const obelisk = new Dubhe({
219
- networkType: NETWORK,
220
- packageId: PACKAGE_ID,
221
- metadata: metadata,
222
- });
145
+ ### Entity Key Generation
223
146
 
224
- const worldId = "0x1541f3a2e7ac48e3e68e60bb97a7cee94e16316cc3f9043a9c0f5e6790ea3af0";
147
+ Dubhe provides three methods for generating entity keys:
225
148
 
226
- // get schema entity data
227
- const schemaName = "simple_schema"
228
- const entityId = "0x00000000000000000000000000000000000000000000000000000000000003ed"
229
- const entities = await obelisk.containEntity(
230
- worldId,
231
- schemaName,
232
- entityId
233
- );
149
+ ```typescript
150
+ // From object ID
151
+ const objectKey = await dubhe.entity_key_from_object(objectId);
234
152
 
235
- // get singleton schema entity data
236
- const singletonSchemaName = "counter"
237
- const entities = await obelisk.containEntity(
238
- worldId,
239
- singletonSchemaName
240
- );
153
+ // From string data
154
+ const bytesKey = await dubhe.entity_key_from_bytes('hello');
241
155
 
156
+ // From number
157
+ const numberKey = await dubhe.entity_key_from_u256(123);
242
158
  ```
243
159
 
244
- #### Get owned objects
160
+ ### Query Owned Objects
245
161
 
246
- Query all the objects under the current worldId that are owned by a certain address.
162
+ To query objects owned by a specific address:
247
163
 
248
164
  ```typescript
249
- const metadata = await getMetadata(NETWORK, PACKAGE_ID);
250
- const obelisk = new Dubhe({
251
- networkType: NETWORK,
252
- packageId: PACKAGE_ID,
253
- metadata: metadata,
254
- });
255
-
256
165
  const owner = "0xfa99b5b0463fcfb7d0203c701a76da5eda21a96190eb1368ab36a437cc89195e";
257
- const owned_objects_value = await obelisk.getOwnedObjects(owner);
166
+ const ownedObjects = await dubhe.getOwnedObjects(owner);
258
167
  ```
259
168
 
260
- ### About entity key
261
-
262
- You can customize how the key is generated in the system, but I recommend that you generate the entity key using the user's address or objectId as the associative data, as this will help you associate the generated entity with address/objectId. This will help you associate the generated entity with the user's address, and then you can quickly determine the creator of the entity by the user's address or objectId.
263
-
264
- We provide three ways to convert entity keys, and of course you are welcome to contribute more entity key specifications.
169
+ ## Best Practices
265
170
 
171
+ 1. Use pre-saved metadata for better performance in production
172
+ 2. Implement proper error handling for BCS decoding
173
+ 3. Consider the limitations of enum type handling when designing your contract return types
266
174
 
267
- ```typescript
268
- // Create key based on objectId.
269
- // You can use the user's address as the entity key,
270
- // or you can use the Id of an object as the entity key.
271
- //
272
- // For example: using the objectId of the NFT as the key,
273
- // you can set the owner of the nft as the owner of the accessed entity.
274
- let objectAddress = await obelisk.entity_key_from_object(
275
- '0x1541f3a2e7ac48e3e68e60bb97a7cee94e16316cc3f9043a9c0f5e6790ea3af0'
276
- );
277
-
278
- // hexAddress(keccak256(inputStringData))
279
- let bytesAddress = await obelisk.entity_key_from_bytes('hello');
280
-
281
- // hexAddress(inputNumberData)
282
- let numberAddress = await obelisk.entity_key_from_u256(123);
283
- ```
175
+ ## Support
284
176
 
177
+ For more information or support, please visit our GitHub repository or join our community channels.
package/dist/dubhe.d.ts CHANGED
@@ -39,7 +39,7 @@ export declare class Dubhe {
39
39
  get query(): MapMoudleFuncQuery;
40
40
  get tx(): MapMoudleFuncTx;
41
41
  get object(): MapObjectStruct;
42
- view(dryResult: DevInspectResults): any[] | undefined;
42
+ view(dryResult: DevInspectResults): any[];
43
43
  /**
44
44
  * if derivePathParams is not provided or mnemonics is empty, it will return the keypair.
45
45
  * else:
@@ -0,0 +1,7 @@
1
+ export declare class ContractDataParsingError extends Error {
2
+ readonly errorType: string;
3
+ readonly functionName: string;
4
+ readonly moduleAddress: string;
5
+ readonly errorMessage: string;
6
+ constructor(dryResult: any);
7
+ }
package/dist/index.js CHANGED
@@ -946,6 +946,31 @@ function numberToAddressHex(num) {
946
946
 
947
947
  // src/dubhe.ts
948
948
  var import_bcs2 = require("@mysten/bcs");
949
+
950
+ // src/errors/index.ts
951
+ var ContractDataParsingError = class extends Error {
952
+ constructor(dryResult) {
953
+ const error = dryResult?.effects?.status?.error || "";
954
+ const functionMatch = error ? error.match(/function_name: Some\("([^"]+)"\)/) : null;
955
+ const moduleMatch = error ? error.match(/address: ([a-fA-F0-9]+)/) : null;
956
+ const functionName = functionMatch ? functionMatch[1] : "unknown";
957
+ const moduleAddress = moduleMatch ? "0x" + moduleMatch[1] : "unknown";
958
+ const errorMessage = dryResult.error ? dryResult.error : "UNKNOWN_ERROR";
959
+ const message = [
960
+ `
961
+ - Function: ${functionName}`,
962
+ `- Module Address: ${moduleAddress}`,
963
+ `- Error Message: ${errorMessage}`
964
+ ].join("\n");
965
+ super(message);
966
+ this.errorType = "ContractDataParsingError";
967
+ this.functionName = functionName;
968
+ this.moduleAddress = moduleAddress;
969
+ this.errorMessage = errorMessage;
970
+ }
971
+ };
972
+
973
+ // src/dubhe.ts
949
974
  function isUndefined(value) {
950
975
  return value === void 0;
951
976
  }
@@ -1376,7 +1401,7 @@ var Dubhe = class {
1376
1401
  }
1377
1402
  return returnValues;
1378
1403
  } else {
1379
- return void 0;
1404
+ throw new ContractDataParsingError(dryResult);
1380
1405
  }
1381
1406
  }
1382
1407
  /**