suidouble 0.0.17 → 0.0.19

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
@@ -9,6 +9,7 @@ Set of provider, package and object classes for javascript representation of Sui
9
9
  - [Interacting with smart contract](#interacting-with-smart-contract)
10
10
  - [SuiObject](#suiobject)
11
11
  - [Fetching Events](#fetching-events)
12
+ - [Subscribe to Events](#subscribing-to-events)
12
13
  - [Executing smart contract method](#executing-smart-contract-method)
13
14
  - [Fetching objects](#fetching-objects)
14
15
  - [Publishing the package](#publishing-the-package)
@@ -138,6 +139,35 @@ while (events.hasNextPage) {
138
139
  // const events = await contract.fetchEvents('modulename', {order: 'descending'}); // or all module events
139
140
  ```
140
141
 
142
+ ##### subscribing to events
143
+
144
+ You can subscribe to Sui's contract events on package's module level. No types-etc filters for now ( @todo? )
145
+
146
+ ```javascript
147
+ const module = await contract.getModule('suidouble_chat');
148
+ await module.subscribeEvents();
149
+ module.addEventListener('ChatResponseCreated', (suiEvent)=>{
150
+ // received message emited by
151
+ // emit(ChatResponseCreated { id: object::uid_to_inner(&chat_response_id), top_message_id: object::uid_to_inner(&id), seq_n: 0 });
152
+ // in suidouble_chat 's smart contract
153
+ console.log(suiEvent.typeName); // == 'ChatResponseCreated'
154
+ console.log(suiEvent.parsedJson);
155
+ });
156
+ module.addEventListener('ChatTopMessageCreated', (suiEvent)=>{
157
+ // received message emited by
158
+ // emit(ChatTopMessageCreated { id: object::uid_to_inner(&id), top_response_id: object::uid_to_inner(&chat_response_id), });
159
+ // in suidouble_chat 's smart contract
160
+ console.log(suiEvent.typeName); // == 'ChatTopMessageCreated'
161
+ console.log(suiEvent.parsedJson);
162
+ });
163
+ ```
164
+
165
+ Don't forget to unsubscribe from events when you don't need them anymore:
166
+
167
+ ```javascript
168
+ await module.unsubscribeEvents();
169
+ ```
170
+
141
171
  ##### executing smart contract method
142
172
 
143
173
  ```javascript
@@ -34,7 +34,11 @@ class SuiCommonMethods extends EventTarget {
34
34
 
35
35
  emit(eventType, data) {
36
36
  try {
37
- this.dispatchEvent(new CustomEvent(eventType, { detail: data }));
37
+ if (data && data.isSuiEvent) {
38
+ this.dispatchEvent(data);
39
+ } else {
40
+ this.dispatchEvent(new CustomEvent(eventType, { detail: data }));
41
+ }
38
42
  } catch (e) {
39
43
  console.error(e);
40
44
  }
package/lib/SuiEvent.js CHANGED
@@ -1,15 +1,36 @@
1
1
  const SuiCommonMethods = require('./SuiCommonMethods.js');
2
2
 
3
- class SuiEvent extends SuiCommonMethods {
3
+ class SuiEvent extends Event {
4
4
  constructor(params = {}) {
5
- super(params);
5
+ const typeName = params.data ? (params.data.type.split('::').pop()) : null;
6
+ super(typeName, {});
6
7
 
8
+ this._debug = !!params.debug;
7
9
  this._suiMaster = params.suiMaster;
8
10
  if (!this._suiMaster) {
9
11
  throw new Error('suiMaster is requried for suiPackage');
10
12
  }
11
13
 
12
14
  this._data = params.data || {};
15
+
16
+ this.detail = this; // quick backward support as this is the instance of CustomEvent
17
+ }
18
+
19
+ log(...args) {
20
+ if (!this._debug) {
21
+ return;
22
+ }
23
+
24
+ let prefix = (this._suiMaster ? (''+this._suiMaster.instanceN+' |') : (this.instanceN ? ''+this.instanceN+' |' : '') );
25
+ // prefix += this.constructor.name+' | ';
26
+
27
+ args.unshift(this.constructor.name+' |');
28
+ args.unshift(prefix);
29
+ console.info.apply(null, args);
30
+ }
31
+
32
+ get isSuiEvent() {
33
+ return true;
13
34
  }
14
35
 
15
36
  /**
@@ -105,7 +105,6 @@ class SuiLocalTestValidator extends SuiCommonMethods {
105
105
  });
106
106
 
107
107
  process.on('exit', ()=>{
108
- console.log('this._testFallbackEnabled', this._testFallbackEnabled);
109
108
  if (this._child) {
110
109
  this._child.kill();
111
110
  }
@@ -3,6 +3,7 @@ const SuiObject = require('./SuiObject.js');
3
3
 
4
4
  const SuiCommonMethods = require('./SuiCommonMethods.js');
5
5
  const SuiPaginatedResponse = require('./SuiPaginatedResponse.js');
6
+ const SuiEvent = require('./SuiEvent.js');
6
7
  // fromB64, toB64
7
8
 
8
9
  class SuiPackageModule extends SuiCommonMethods {
@@ -28,6 +29,43 @@ class SuiPackageModule extends SuiCommonMethods {
28
29
  // we need to get very first version's address of this package to use for types, so we are doing this in separate call
29
30
  this._checkedOnChain = false;
30
31
  this._normalizedMoveModule = {};
32
+
33
+ this._unsubscribeFunction = null;
34
+ }
35
+
36
+ async subscribeEvents() {
37
+ this.log('subscribing to events of module', this._moduleName);
38
+
39
+ // we need very first package version's id here. So we are getting it from normalized data
40
+ const normalizedPackageAddress = await this.getNormalizedPackageAddress();
41
+
42
+ const onMessage = (rawEvent) => {
43
+ const suiEvent = new SuiEvent({
44
+ suiMaster: this._suiMaster,
45
+ debug: this._debug,
46
+ data: rawEvent,
47
+ });
48
+
49
+ const eventTypeName = suiEvent.typeName;
50
+ this.log('got event', eventTypeName);
51
+ this.emit(eventTypeName, suiEvent);
52
+ };
53
+
54
+ this._unsubscribeFunction = await this._suiMaster._provider.subscribeEvent({
55
+ filter: {"MoveModule": {"package": normalizedPackageAddress, "module": this._moduleName} },
56
+ onMessage: onMessage,
57
+ });
58
+ }
59
+
60
+ async unsubscribeEvents() {
61
+ if (this._unsubscribeFunction) {
62
+ await this._unsubscribeFunction();
63
+ this._unsubscribeFunction = null;
64
+
65
+ return true;
66
+ }
67
+
68
+ return false;
31
69
  }
32
70
 
33
71
  get objectStorage() {
@@ -181,8 +219,15 @@ class SuiPackageModule extends SuiCommonMethods {
181
219
  const eventType = event.type;
182
220
  const eventTypeName = eventType.split(':').pop(); // last name, without package and module names
183
221
 
184
- const eventData = event.parsedJson;
185
- this.emit(eventTypeName, eventData);
222
+ // const eventData = event.parsedJson;
223
+
224
+ const suiEvent = new SuiEvent({
225
+ suiMaster: this._suiMaster,
226
+ debug: this._debug,
227
+ data: event,
228
+ });
229
+
230
+ this.emit(eventTypeName, suiEvent);
186
231
  }
187
232
  }
188
233
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "suidouble",
3
- "version": "0.0.17",
3
+ "version": "0.0.19",
4
4
  "description": "Set of provider, package and object classes for javascript representation of Sui Move smart contracts. Use same code for publishing, upgrading, integration testing, interaction with smart contracts and integration in browser web3 dapps",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -21,7 +21,7 @@
21
21
  "author": "Jeka Kiselyov <jeka911@gmail.com> (https://github.com/jeka-kiselyov)",
22
22
  "license": "Apache-2.0",
23
23
  "dependencies": {
24
- "@mysten/sui.js": "^0.34.0",
24
+ "@mysten/sui.js": "^0.35.1",
25
25
  "@wallet-standard/core": "^1.0.3"
26
26
  },
27
27
  "devDependencies": {
@@ -25,7 +25,7 @@ test('spawn local test node', async t => {
25
25
  });
26
26
 
27
27
  test('init suiMaster and connect it to local test validator', async t => {
28
- suiMaster = new SuiMaster({provider: suiLocalTestValidator, as: 'somebody', debug: false});
28
+ suiMaster = new SuiMaster({provider: suiLocalTestValidator, as: 'somebody', debug: true});
29
29
  await suiMaster.initialize();
30
30
 
31
31
  t.ok(suiMaster.address); // there should be some address
@@ -150,6 +150,34 @@ test('can find a package on the blockchain by expected module name (in owned)',
150
150
  t.equal(contract.version, 2);
151
151
  });
152
152
 
153
+ test('subscribe to module events', async t => {
154
+ const module = await contract.getModule('suidouble_chat');
155
+ await module.subscribeEvents();
156
+
157
+ let gotEventChatTopMessageCreated = false;
158
+ let gotEventChatResponseCreated = false;
159
+
160
+ module.addEventListener('ChatTopMessageCreated', (event)=>{
161
+ gotEventChatTopMessageCreated = event;
162
+ });
163
+ module.addEventListener('ChatResponseCreated', (event)=>{
164
+ gotEventChatResponseCreated = event.detail; // .detail is reference to event itself. To support CustomEvent pattern
165
+ });
166
+
167
+ await contract.moveCall('suidouble_chat', 'post', [chatShopObjectId, 'the message', 'metadata']);
168
+ await new Promise((res)=>setTimeout(res, 300)); // got events without timeout, but just to be sure.
169
+
170
+ t.ok(gotEventChatTopMessageCreated);
171
+ t.ok(gotEventChatResponseCreated);
172
+
173
+ // just some checks that events have data by contract's architecture
174
+ t.ok(gotEventChatResponseCreated.parsedJson.top_message_id == gotEventChatTopMessageCreated.parsedJson.id);
175
+ t.ok(gotEventChatTopMessageCreated.parsedJson.top_response_id == gotEventChatResponseCreated.parsedJson.id);
176
+
177
+ // unsubscribing from events, to close websocket
178
+ await module.unsubscribeEvents();
179
+ });
180
+
153
181
  test('execute contract methods', async t => {
154
182
  const moveCallResult = await contract.moveCall('suidouble_chat', 'post', [chatShopObjectId, 'the message', 'metadata']);
155
183
 
@@ -290,5 +318,5 @@ test('testing move call with coins', async t => {
290
318
  });
291
319
 
292
320
  test('stops local test node', async t => {
293
- SuiLocalTestValidator.stop();
321
+ await SuiLocalTestValidator.stop();
294
322
  });