suidouble 0.0.3

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,284 @@
1
+ const SuiCommonMethods = require('./SuiCommonMethods.js');
2
+ const SuiInBrowserAdapter = require('./SuiInBrowserAdapter.js');
3
+ const WalletsStandardCore = require('@wallet-standard/core');
4
+ const icons = require('./data/icons.json');
5
+ const { JsonRpcProvider } = require('@mysten/sui.js');
6
+ const SuiMaster = require('./SuiMaster.js');
7
+
8
+ class SuiInBrowser extends SuiCommonMethods {
9
+ constructor(params = {}) {
10
+ super(params);
11
+
12
+ this._adapters = {};
13
+
14
+ this._defaultChain = 'sui:devnet';
15
+
16
+ this._activeAdapter = null;
17
+ this._connectedAddress = null;
18
+ this._connectedChain = null;
19
+ this._isConnected = false;
20
+ this._isConnecting = false;
21
+
22
+ this._provider = null;
23
+ this._suiMaster = null;
24
+
25
+ setTimeout(()=>{
26
+ this.initialize();
27
+ }, 50);
28
+ }
29
+
30
+ getAddress() {
31
+ return this._connectedAddress;
32
+ }
33
+
34
+ async signAndExecuteTransactionBlock(params) {
35
+ return await this._activeAdapter.signAndExecuteTransactionBlock(params);
36
+ }
37
+
38
+ get provider() {
39
+ return this._provider;
40
+ }
41
+
42
+ async getProvider() {
43
+ await this.initProvider();
44
+ return this._provider;
45
+ }
46
+
47
+ async getSuiMaster() {
48
+ await this.initProvider();
49
+ return this._suiMaster;
50
+ }
51
+
52
+ get suiMaster() {
53
+ return this._suiMaster;
54
+ }
55
+
56
+ get isConnected() {
57
+ return this._isConnected;
58
+ }
59
+
60
+ get connectedAddress() {
61
+ return this._connectedAddress;
62
+ }
63
+
64
+ get connectedChain() {
65
+ return this._connectedChain;
66
+ }
67
+
68
+ static _singleInstance = null;
69
+ static getSingleton(params = {}) {
70
+ if (SuiInBrowser._singleInstance) {
71
+ return SuiInBrowser._singleInstance;
72
+ }
73
+
74
+ SuiInBrowser._singleInstance = new SuiInBrowser(params);
75
+ return SuiInBrowser._singleInstance;
76
+ }
77
+
78
+ get adapters() {
79
+ return this._adapters;
80
+ }
81
+
82
+ async connect(adapterOrAdapterName) {
83
+ let adapterName = adapterOrAdapterName;
84
+ if (adapterOrAdapterName.name) {
85
+ adapterName = adapterOrAdapterName.name;
86
+ }
87
+
88
+ if (!this._adapters[adapterName]) {
89
+ return false;
90
+ }
91
+ this._activeAdapter = this._adapters[adapterName];
92
+
93
+ this._isConnecting = true;
94
+ try {
95
+ await this._activeAdapter.connect();
96
+ } catch (e) {
97
+ this.log('error', e);
98
+ }
99
+ this._isConnecting = false;
100
+ }
101
+
102
+ adapterConnected(suiInBrowserAdapter) {
103
+ this._activeAdapter = suiInBrowserAdapter;
104
+ this._isConnected = suiInBrowserAdapter.isConnected;
105
+ this._connectedAddress = suiInBrowserAdapter.connectedAddress;
106
+ const wasConnectedToChain = this._connectedChain;
107
+ this._connectedChain = suiInBrowserAdapter.connectedChain;
108
+
109
+ if (this._connectedChain != wasConnectedToChain) {
110
+ this.log('chain was switched');
111
+ this._provider = null;
112
+ this._suiMaster = null;
113
+ }
114
+
115
+ this.initProvider();
116
+
117
+ this.emit('connected');
118
+ }
119
+
120
+ adapterDisconnected(suiInBrowserAdapter) {
121
+ this._isConnected = false;
122
+ this._connectedAddress = null;
123
+
124
+ this.emit('disconnected');
125
+ }
126
+
127
+ attachAdapter(adapterParams) {
128
+ let adapterName = adapterParams.name;
129
+ if (adapterParams.standartAdapter && adapterParams.standartAdapter.name) {
130
+ adapterName = adapterParams.standartAdapter.name;
131
+ }
132
+
133
+ if (!adapterName) {
134
+ return false;
135
+ }
136
+
137
+ const adapter = new SuiInBrowserAdapter({
138
+ ...adapterParams,
139
+ debug: this._debug,
140
+ });
141
+ if (this._adapters[adapterName]) {
142
+ // already attached
143
+ if (adapterParams.standartAdapter) {
144
+ this._adapters[adapterName].setStandartAdapter(adapterParams.standartAdapter);
145
+ }
146
+ } else {
147
+ this._adapters[adapterName] = adapter;
148
+ this._adapters[adapterName].addEventListener('connected', (e)=>{
149
+ this.adapterConnected(e.detail);
150
+ });
151
+ this._adapters[adapterName].addEventListener('disconnected', (e)=>{
152
+ this.adapterDisconnected(e.detail);
153
+ });
154
+ this.emit('adapter', adapter);
155
+ }
156
+ }
157
+
158
+ getCurrentChain() {
159
+ return this._connectedChain ? this._connectedChain : this._defaultChain;
160
+ }
161
+
162
+ async initProvider() {
163
+ if (this._provider) {
164
+ return true;
165
+ }
166
+
167
+ let chainName = this.getCurrentChain();
168
+ const chainSettings = SuiInBrowser.getChainsSettings();
169
+ // https://github.com/MystenLabs/sui/blob/827f1138a09190975172ec99389751ca95cce5df/sdk/typescript/src/rpc/connection.ts#L32
170
+
171
+ if (!chainSettings[chainName]) {
172
+ this.log('error', 'invalid chain', chainName);
173
+ throw new Error('invalid chain: '+chainName);
174
+ }
175
+
176
+ this._provider = new JsonRpcProvider(chainSettings[chainName]);
177
+ this._suiMaster = new SuiMaster({
178
+ debug: this._debug,
179
+ signer: this,
180
+ provider: this._provider,
181
+ });
182
+ }
183
+
184
+ async initialize() {
185
+ await this.initProvider(); // set default provider
186
+
187
+ // create empty adapters (we need instances even if they are not installed)
188
+ for (const possibleAdapterParams of SuiInBrowser.getPossibleWallets()) {
189
+ this.attachAdapter(possibleAdapterParams);
190
+ }
191
+
192
+ const walletsCore = WalletsStandardCore.getWallets();
193
+ const standartAdapters = walletsCore.get();
194
+ for (const standartAdapter of standartAdapters) {
195
+ this.attachAdapter({
196
+ standartAdapter: standartAdapter,
197
+ });
198
+ }
199
+ walletsCore.on('register', (what)=>{
200
+ const adapterName = what.name;
201
+ if (adapterName) {
202
+ this.attachAdapter({
203
+ standartAdapter: what,
204
+ });
205
+ }
206
+ });
207
+
208
+
209
+ }
210
+
211
+ static getChainsSettings() {
212
+ return {
213
+ 'sui:devnet': {
214
+ fullnode: 'https://fullnode.devnet.sui.io:443/',
215
+ websocket: 'https://fullnode.devnet.sui.io:443/',
216
+ faucet: 'https://faucet.devnet.sui.io/gas',
217
+ },
218
+ 'sui:testnet': {
219
+ fullnode: 'https://fullnode.testnet.sui.io:443/',
220
+ websocket: 'https://fullnode.testnet.sui.io:443/',
221
+ faucet: 'https://faucet.testnet.sui.io/gas',
222
+ },
223
+ 'sui:mainnet': {
224
+ fullnode: 'https://fullnode.mainnet.sui.io:443/',
225
+ websocket: 'https://fullnode.mainnet.sui.io:443/',
226
+ },
227
+ 'sui:localnet': {
228
+ websocket: 'http://127.0.0.1:9000',
229
+ fullnode: 'http://127.0.0.1:9000',
230
+ websocket: 'http://127.0.0.1:9000',
231
+ faucet: 'http://127.0.0.1:9123/gas',
232
+ },
233
+ };
234
+ }
235
+
236
+ static getPossibleWallets() {
237
+ return [
238
+ {
239
+ name: 'Sui Wallet',
240
+ icon: icons['SUI'],
241
+ downloadUrls: {
242
+ chrome: 'https://chrome.google.com/webstore/detail/sui-wallet/opcgpfmipidbgpenhmajoajpbobppdil',
243
+ },
244
+ },
245
+ {
246
+ name: 'Suiet',
247
+ icon: icons['SUIET'],
248
+ downloadUrls: {
249
+ chrome: 'https://chrome.google.com/webstore/detail/suiet-sui-wallet/khpkpbbcccdmmclmpigdgddabeilkdpd',
250
+ },
251
+ },
252
+ {
253
+ name: 'GlassWallet',
254
+ icon: icons['GLASS'],
255
+ downloadUrls: {
256
+ chrome: 'https://chrome.google.com/webstore/detail/glass-wallet-sui-wallet/loinekcabhlmhjjbocijdoimmejangoa',
257
+ },
258
+ },
259
+ {
260
+ name: 'Ethos Wallet',
261
+ icon: icons['ETHOS'],
262
+ downloadUrls: {
263
+ chrome: 'https://chrome.google.com/webstore/detail/ethos-sui-wallet/mcbigmjiafegjnnogedioegffbooigli',
264
+ },
265
+ },
266
+ {
267
+ name: 'Surf Wallet',
268
+ icon: icons['SURF'],
269
+ downloadUrls: {
270
+ chrome: 'https://chrome.google.com/webstore/detail/surf-wallet/emeeapjkbcbpbpgaagfchmcgglmebnen',
271
+ },
272
+ },
273
+ {
274
+ name: 'Nightly Wallet',
275
+ icon: icons['NIGHTLY'],
276
+ downloadUrls: {
277
+ chrome: 'https://chrome.google.com/webstore/detail/nightly/fiikommddbeccaoicoejoniammnalkfa',
278
+ },
279
+ },
280
+ ];
281
+ }
282
+ };
283
+
284
+ module.exports = SuiInBrowser;
@@ -0,0 +1,181 @@
1
+ const SuiCommonMethods = require('./SuiCommonMethods.js');
2
+ // const WalletsStandardCore = require('@wallet-standard/core');
3
+ // const icons = require('./data/icons.json');
4
+
5
+ const Feature = {
6
+ DISCONNECT: 'standard:disconnect',
7
+ CONNECT: 'standard:connect',
8
+ EVENTS: 'standard:events',
9
+ SUI_SIGN_AND_EXECUTE_TX_BLOCK: 'sui:signAndExecuteTransactionBlock',
10
+ SUI_SIGN_TX_BLOCK: 'sui:signTransactionBlock',
11
+ SUI_SIGN_MESSAGE: 'sui:signMessage'
12
+ };
13
+
14
+ class SuiInBrowserAdapter extends SuiCommonMethods {
15
+ constructor(params = {}) {
16
+ super(params);
17
+
18
+ this._standartAdapter = null;
19
+ // params.standartAdapter || null; // instance returned from '@wallet-standard/core'
20
+ if (params.standartAdapter) {
21
+ this.setStandartAdapter(params.standartAdapter);
22
+ }
23
+
24
+ this._name = params.name || null;
25
+ this._icon = params.icon || null;
26
+ this._downloadUrls = params.downloadUrls || {};
27
+
28
+ this._connectedAddress = null;
29
+ this._connectedChain = null;
30
+ this._isConnected = false;
31
+ }
32
+
33
+ getDownloadURL() {
34
+ if (this._downloadUrls && this._downloadUrls.chrome) {
35
+ return this._downloadUrls.chrome;
36
+ }
37
+ return null;
38
+ }
39
+
40
+ get isDefault() {
41
+ if (!this._standartAdapter) {
42
+ return true;
43
+ }
44
+ return false;
45
+ }
46
+
47
+ get connectedAddress() {
48
+ return this._connectedAddress;
49
+ }
50
+
51
+ get connectedChain() {
52
+ return this._connectedChain;
53
+ }
54
+
55
+ get isConnected() {
56
+ return this._isConnected;
57
+ }
58
+
59
+ async connect() {
60
+ try {
61
+ await this.getFeature(Feature.CONNECT).connect();
62
+ } catch (e) {
63
+ console.error(e);
64
+ }
65
+
66
+ this.connectionUpdated();
67
+ }
68
+
69
+ connectionUpdated() {
70
+ const wasConnectedAddress = ''+this._connectedAddress;
71
+ const wasConnectedChain = ''+this._connectedChain;
72
+
73
+ try {
74
+ if (this._standartAdapter && this._standartAdapter.accounts && this._standartAdapter.accounts.length) {
75
+ this._connectedAddress = this._standartAdapter.accounts[0].address;
76
+ this._connectedChain = this._standartAdapter.accounts[0].chains[0];
77
+ } else {
78
+ this._connectedAddress = null;
79
+ this._connectedChain = null;
80
+ }
81
+ } catch (e) {
82
+ this._connectedAddress = null;
83
+ this._connectedChain = null;
84
+ }
85
+
86
+ if ((''+this._connectedAddress) != wasConnectedAddress || (''+this._connectedChain) != wasConnectedChain) {
87
+ if (this._connectedAddress && this._connectedChain) {
88
+ this._isConnected = true;
89
+ this.emit('connected', this);
90
+ } else {
91
+ this._isConnected = false;
92
+ this.emit('disconnected', this);
93
+ }
94
+ }
95
+ }
96
+
97
+
98
+ setStandartAdapter(standartAdapter) {
99
+ if (this._standartAdapter) {
100
+ // no need to re-attach
101
+ return true;
102
+ }
103
+
104
+ this._standartAdapter = standartAdapter;
105
+ if (!this.__standartAdapterChangeListener) {
106
+ this.__standartAdapterChangeListener = (e) => {
107
+ this.connectionUpdated();
108
+ };
109
+ }
110
+ this.getFeature(Feature.EVENTS).on('change', this.__standartAdapterChangeListener);
111
+
112
+ this.connectionUpdated();
113
+ }
114
+
115
+ async signAndExecuteTransactionBlock(params) {
116
+ return await this.getFeature(Feature.SUI_SIGN_AND_EXECUTE_TX_BLOCK).signAndExecuteTransactionBlock(params);
117
+ // console.log(this.getFeature(Feature.SUI_SIGN_AND_EXECUTE_TX_BLOCK));
118
+ }
119
+
120
+ get okForSui() {
121
+ if (!this.isInstalled) {
122
+ return false;
123
+ }
124
+
125
+ return this.hasFeature(Feature.SUI_SIGN_AND_EXECUTE_TX_BLOCK) && this.hasFeature(Feature.EVENTS);
126
+ }
127
+
128
+ get isInstalled() {
129
+ if (this._standartAdapter) {
130
+ return true;
131
+ }
132
+ return false;
133
+ }
134
+
135
+ get features() {
136
+ if (this._standartAdapter) {
137
+ return this._standartAdapter.features;
138
+ }
139
+ return {};
140
+ }
141
+
142
+ get name() {
143
+ if (this._standartAdapter) {
144
+ return this._standartAdapter.name;
145
+ } else {
146
+ return this._name;
147
+ }
148
+ }
149
+
150
+ get icon() {
151
+ if (this._standartAdapter) {
152
+ return this._standartAdapter.icon;
153
+ } else {
154
+ return this._icon;
155
+ }
156
+ }
157
+
158
+ get version() {
159
+ if (this._standartAdapter) {
160
+ return this._standartAdapter.version;
161
+ }
162
+ }
163
+
164
+ hasFeature(featureName) {
165
+ return (!!this.getFeature(featureName));
166
+ }
167
+
168
+ getFeature(featureName) {
169
+ const features = this.features;
170
+
171
+ if (features && features[Feature[featureName]]) {
172
+ return features[Feature[featureName]];
173
+ }
174
+ if (features && features[featureName]) {
175
+ return features[featureName];
176
+ }
177
+ return null;
178
+ }
179
+ };
180
+
181
+ module.exports = SuiInBrowserAdapter;
@@ -0,0 +1,93 @@
1
+ // const { spawn } = require('child_process');
2
+ const SuiCliCommands = require('./SuiCliCommands.js');
3
+ const SuiCommonMethods = require('./SuiCommonMethods.js');
4
+
5
+ class SuiLocalTestValidator extends SuiCommonMethods {
6
+ constructor(params = {}) {
7
+ super(params);
8
+
9
+ this._child = null;
10
+ this._active = false;
11
+ }
12
+
13
+ static async launch(params = {}) {
14
+ if (SuiLocalTestValidator.__instance) {
15
+ return await SuiLocalTestValidator.__instance.launch();
16
+ }
17
+
18
+ SuiLocalTestValidator.__instance = new SuiLocalTestValidator(params);
19
+ return await SuiLocalTestValidator.__instance.launch();
20
+ }
21
+
22
+ static async stop() {
23
+ if (SuiLocalTestValidator.__instance) {
24
+ return await SuiLocalTestValidator.__instance.stop();
25
+ }
26
+ }
27
+
28
+ async launch() {
29
+ if (this._child && this._active) {
30
+ return true;
31
+ }
32
+
33
+ this.log('launching sui-test-validator ...');
34
+
35
+ this._child = await SuiCliCommands.spawn('sui-test-validator', { RUST_LOG: 'consensus=off' });
36
+
37
+ // spawn('sui-test-validator', [], {
38
+ // env: {
39
+ // ...process.env,
40
+ // RUST_LOG: 'consensus=off',
41
+ // }
42
+ // });
43
+
44
+ this.__readyLaunchedPromiseResolver = null;
45
+ this.__readyLaunchedPromise = new Promise((res)=>{
46
+ this.__readyLaunchedPromiseResolver = res;
47
+ });
48
+
49
+ this._child.stdout.on('data', (data) => {
50
+ this.log(`stdout:\n${data}`);
51
+ if ((`${data}`).indexOf('Fullnode RPC URL') !== -1) {
52
+ this._active = true;
53
+
54
+ this.log('sui-test-validator launched');
55
+ this.__readyLaunchedPromiseResolver();
56
+ }
57
+ });
58
+
59
+ this._child.stderr.on('data', (data) => {
60
+ this.log(`stderr: ${data}`);
61
+ });
62
+
63
+ this._child.on('error', (error) => {
64
+ this.log(`error: ${error.message}`);
65
+ });
66
+
67
+ this._child.on('close', (code) => {
68
+ this._active = false;
69
+ this.log(`child process exited with code ${code}`);
70
+ });
71
+
72
+ process.on('exit', ()=>{
73
+ if (this._child) {
74
+ this._child.kill();
75
+ }
76
+ });
77
+ const cleanExit = function() { process.exit() };
78
+ process.on('SIGINT', cleanExit); // catch ctrl-c
79
+ process.on('SIGTERM', cleanExit); // catch kill
80
+
81
+ await this.__readyLaunchedPromise;
82
+
83
+ return this;
84
+ }
85
+
86
+ async stop() {
87
+ if (this._child) {
88
+ await this._child.kill();
89
+ }
90
+ }
91
+ }
92
+
93
+ module.exports = SuiLocalTestValidator;