suidouble 1.13.0 → 1.14.2-1
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 +8 -33
- package/index.js +23 -14
- package/lib/SuiCliCommands.js +80 -20
- package/lib/SuiCoin.js +47 -56
- package/lib/SuiCoins.js +111 -62
- package/lib/SuiCommonMethods.js +2 -4
- package/lib/SuiEvent.js +2 -4
- package/lib/SuiInBrowser.js +18 -15
- package/lib/SuiInBrowserAdapter.js +14 -6
- package/lib/SuiLocalTestValidator.js +7 -37
- package/lib/SuiMaster.js +93 -53
- package/lib/SuiMemoryObjectStorage.js +49 -10
- package/lib/SuiObject.js +4 -6
- package/lib/SuiPackage.js +9 -14
- package/lib/SuiPackageModule.js +11 -16
- package/lib/SuiPaginatedResponse.js +4 -6
- package/lib/SuiPseudoRandomAddress.js +4 -6
- package/lib/SuiTestScenario.js +6 -7
- package/lib/SuiTransaction.js +3 -5
- package/lib/SuiUtils.js +20 -15
- package/lib/data/{icons.json → icons.js} +5 -2
- package/package.json +5 -3
- package/test/coins.test.js +28 -5
- package/test/different_types_args.test.js +8 -4
- package/test/rpc.test.js +8 -2
- package/test/sui_in_browser.test.js +8 -2
- package/test/sui_master_basic.test.js +9 -2
- package/test/sui_master_onlocal.test.js +9 -4
- package/test/sui_test_scenario.test.js +8 -4
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ npm install suidouble --save
|
|
|
43
43
|
Main class to interact with blockchain is SuiMaster:
|
|
44
44
|
|
|
45
45
|
```javascript
|
|
46
|
-
|
|
46
|
+
import { SuiMaster } from 'suidouble';
|
|
47
47
|
```
|
|
48
48
|
|
|
49
49
|
You can initialize it directly, if you have keypair, secret phrase, or privateKey and can use it in code (so on node.js side - server side or CLI apps):
|
|
@@ -85,7 +85,7 @@ const suiMasterAsUser = new SuiMaster({ as: 'user', client: 'dev', });
|
|
|
85
85
|
|
|
86
86
|
On browser side, you'd probably want to use Sui wallets extensions adapters to sign message and don't store any keypairs or secret phrases in your code. So there's SuiInBrowser class for this, which can setup suiMaster instance for you. See 'Sui Move Connect in browser' section or sample UI application's code for more details.
|
|
87
87
|
```javascript
|
|
88
|
-
|
|
88
|
+
import { SuiInBrowser } from 'suidouble';
|
|
89
89
|
const suiInBrowser = SuiInBrowser.getSingleton(); // you probably don't want to keep few connections, so there's singleton
|
|
90
90
|
/// ...
|
|
91
91
|
suiInBrowser.addEventListener('connected', async()=>{
|
|
@@ -175,32 +175,6 @@ while (events.hasNextPage) {
|
|
|
175
175
|
|
|
176
176
|
*** Subscribe to Events is deprecated in Sui SDK *** You should plan to use different architecture in your application.
|
|
177
177
|
|
|
178
|
-
You can subscribe to Sui's contract events on package's module level.
|
|
179
|
-
|
|
180
|
-
```javascript
|
|
181
|
-
const module = await contract.getModule('suidouble_chat');
|
|
182
|
-
await module.subscribeEvents();
|
|
183
|
-
module.addEventListener('ChatResponseCreated', (suiEvent)=>{
|
|
184
|
-
// received message emited by
|
|
185
|
-
// emit(ChatResponseCreated { id: object::uid_to_inner(&chat_response_id), top_message_id: object::uid_to_inner(&id), seq_n: 0 });
|
|
186
|
-
// in suidouble_chat 's smart contract
|
|
187
|
-
console.log(suiEvent.typeName); // == 'ChatResponseCreated'
|
|
188
|
-
console.log(suiEvent.parsedJson);
|
|
189
|
-
});
|
|
190
|
-
module.addEventListener('ChatTopMessageCreated', (suiEvent)=>{
|
|
191
|
-
// received message emited by
|
|
192
|
-
// emit(ChatTopMessageCreated { id: object::uid_to_inner(&id), top_response_id: object::uid_to_inner(&chat_response_id), });
|
|
193
|
-
// in suidouble_chat 's smart contract
|
|
194
|
-
console.log(suiEvent.typeName); // == 'ChatTopMessageCreated'
|
|
195
|
-
console.log(suiEvent.parsedJson);
|
|
196
|
-
});
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
Don't forget to unsubscribe from events when you don't need them anymore:
|
|
200
|
-
|
|
201
|
-
```javascript
|
|
202
|
-
await module.unsubscribeEvents();
|
|
203
|
-
```
|
|
204
178
|
|
|
205
179
|
##### executing smart contract method
|
|
206
180
|
|
|
@@ -302,7 +276,7 @@ Don't forget to test transactions sending real money on devnet/testnet first!
|
|
|
302
276
|
If you need more flexebility, there's always an option to construct the transaction yourself:
|
|
303
277
|
|
|
304
278
|
```javascript
|
|
305
|
-
|
|
279
|
+
import { Transaction, txInput } from 'suidouble';
|
|
306
280
|
|
|
307
281
|
const tx = new Transaction();
|
|
308
282
|
tx.moveCall({
|
|
@@ -348,7 +322,8 @@ await paginatedResponse.forEach(async(suiObject)=>{
|
|
|
348
322
|
Builds a package and publish it to blockchain. CLI thing, as it needs `execSync` to run `sui move build`. Tested on Ubuntu, works good. If you have some issues with other platforms - please feel free to let me know or post Pull Request.
|
|
349
323
|
|
|
350
324
|
```javascript
|
|
351
|
-
|
|
325
|
+
import { SuiMaster } from 'suidouble';
|
|
326
|
+
|
|
352
327
|
|
|
353
328
|
const client = 'dev';
|
|
354
329
|
const suiMaster = new SuiMaster({ debug: true, as: 'admin', client: client, });
|
|
@@ -369,7 +344,7 @@ console.log('published as', package.address);
|
|
|
369
344
|
Same, it's for CLI as it re-builds the package.
|
|
370
345
|
|
|
371
346
|
```javascript
|
|
372
|
-
|
|
347
|
+
import { SuiMaster } from 'suidouble';
|
|
373
348
|
|
|
374
349
|
const client = 'local';// or await SuiLocalTestValidator.launch({debug: true, epochDuration: 30000});
|
|
375
350
|
|
|
@@ -394,7 +369,7 @@ CLI integration tests, it runs local testing node (has to be installed), build a
|
|
|
394
369
|
suidouble try to mimic Sui Move's testing framework:
|
|
395
370
|
|
|
396
371
|
```javascript
|
|
397
|
-
|
|
372
|
+
import { SuiTestScenario } from 'suidouble';
|
|
398
373
|
|
|
399
374
|
const testScenario = new SuiTestScenario({
|
|
400
375
|
path: '../path_to_move_project_root/',
|
|
@@ -432,7 +407,7 @@ Check out [suidouble Vue component](https://www.npmjs.com/package/vue-sui) to co
|
|
|
432
407
|
Or write the one manually, code is framework independed:
|
|
433
408
|
|
|
434
409
|
```javascript
|
|
435
|
-
|
|
410
|
+
import { SuiInBrowser } from 'suidouble';
|
|
436
411
|
|
|
437
412
|
const suiInBrowser = SuiInBrowser.getSingleton();
|
|
438
413
|
const suiMaster = await suiInBrowser.getSuiMaster(); // not yet connected, works in read-only mode (no signing-posting txs).
|
package/index.js
CHANGED
|
@@ -1,22 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import SuiMaster from './lib/SuiMaster.js';
|
|
2
|
+
import SuiInBrowser from './lib/SuiInBrowser.js';
|
|
3
|
+
import SuiTestScenario from './lib/SuiTestScenario.js';
|
|
4
|
+
import SuiObject from './lib/SuiObject.js';
|
|
5
|
+
import SuiUtils from './lib/SuiUtils.js';
|
|
6
|
+
import SuiLocalTestValidator from './lib/SuiLocalTestValidator.js';
|
|
7
|
+
import SuiMemoryObjectStorage from './lib/SuiMemoryObjectStorage.js';
|
|
8
|
+
import SuiCoin from './lib/SuiCoin.js';
|
|
9
|
+
import SuiCoins from './lib/SuiCoins.js';
|
|
10
|
+
import { Transaction, Commands } from '@mysten/sui/transactions';
|
|
11
|
+
import { bcs } from '@mysten/sui/bcs';
|
|
9
12
|
|
|
10
|
-
|
|
13
|
+
const txInput = SuiUtils.txInput;
|
|
14
|
+
const MIST_PER_SUI = SuiMaster.MIST_PER_SUI;
|
|
15
|
+
|
|
16
|
+
export {
|
|
11
17
|
SuiMaster,
|
|
12
18
|
SuiObject,
|
|
13
19
|
SuiInBrowser,
|
|
14
20
|
SuiTestScenario,
|
|
15
21
|
SuiLocalTestValidator,
|
|
16
|
-
MIST_PER_SUI
|
|
17
|
-
Transaction
|
|
18
|
-
Commands
|
|
19
|
-
SuiUtils
|
|
20
|
-
txInput
|
|
22
|
+
MIST_PER_SUI,
|
|
23
|
+
Transaction,
|
|
24
|
+
Commands,
|
|
25
|
+
SuiUtils,
|
|
26
|
+
txInput,
|
|
21
27
|
bcs,
|
|
28
|
+
SuiMemoryObjectStorage,
|
|
29
|
+
SuiCoin,
|
|
30
|
+
SuiCoins,
|
|
22
31
|
};
|
package/lib/SuiCliCommands.js
CHANGED
|
@@ -1,23 +1,80 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const fs = require('fs');
|
|
11
|
-
const path = require('path');
|
|
12
|
-
|
|
13
|
-
doFs = fs;
|
|
14
|
-
doPath = path;
|
|
15
|
-
} catch (e) {
|
|
16
|
-
console.log('looks we are in browser');
|
|
1
|
+
class ImportError extends Error {}
|
|
2
|
+
|
|
3
|
+
const loadModule = async (modulePath) => {
|
|
4
|
+
try {
|
|
5
|
+
return await import(modulePath)
|
|
6
|
+
} catch (e) {
|
|
7
|
+
throw new ImportError(`Unable to import module ${modulePath}`)
|
|
8
|
+
}
|
|
17
9
|
}
|
|
18
10
|
|
|
19
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Wrapper to get system function available on node.js side only, returning null on the browser side
|
|
13
|
+
* @param {string} name - execSync, spawn, fs, path, net
|
|
14
|
+
* @returns {(function | null)}
|
|
15
|
+
*/
|
|
16
|
+
const getSystemFunction = async (name) => {
|
|
17
|
+
try {
|
|
18
|
+
if (name == 'execSync' || name == 'spawn') {
|
|
19
|
+
const { default: myDefault } = await loadModule('child_process');
|
|
20
|
+
return myDefault[name];
|
|
21
|
+
}
|
|
22
|
+
if (name == 'fs') {
|
|
23
|
+
const { default: myDefault } = await loadModule('fs');
|
|
24
|
+
return myDefault;
|
|
25
|
+
}
|
|
26
|
+
if (name == 'path') {
|
|
27
|
+
const { default: myDefault } = await loadModule('path');
|
|
28
|
+
return myDefault;
|
|
29
|
+
}
|
|
30
|
+
if (name == 'net') {
|
|
31
|
+
const { default: myDefault } = await loadModule('net');
|
|
32
|
+
return myDefault;
|
|
33
|
+
}
|
|
34
|
+
} catch (e) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default class SuiCliCommands {
|
|
40
|
+
static async isPortThere(port) {
|
|
41
|
+
const net = await getSystemFunction('net');
|
|
42
|
+
if (!net) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const Socket = net.Socket;
|
|
47
|
+
const socket = new Socket();
|
|
48
|
+
|
|
49
|
+
let __waitPortPromiseResolver = null;
|
|
50
|
+
const __waitPortPromise = new Promise((res)=>{ __waitPortPromiseResolver = res; });
|
|
51
|
+
|
|
52
|
+
setTimeout(()=>{
|
|
53
|
+
socket.destroy();
|
|
54
|
+
__waitPortPromiseResolver(false);
|
|
55
|
+
}, 3000);
|
|
56
|
+
socket.on("connect", () => {
|
|
57
|
+
__waitPortPromiseResolver(true);
|
|
58
|
+
});
|
|
59
|
+
socket.on("error", () =>
|
|
60
|
+
{
|
|
61
|
+
__waitPortPromiseResolver(false);
|
|
62
|
+
});
|
|
63
|
+
socket.on("timeout", () => {
|
|
64
|
+
__waitPortPromiseResolver(false);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
socket.connect(port, "0.0.0.0");
|
|
68
|
+
|
|
69
|
+
const portIsThere = await __waitPortPromise;
|
|
70
|
+
socket.destroy();
|
|
71
|
+
|
|
72
|
+
return portIsThere;
|
|
73
|
+
}
|
|
74
|
+
|
|
20
75
|
static async spawn(command, params = [], envVars = {}) {
|
|
76
|
+
const doSpawn = await getSystemFunction('spawn');
|
|
77
|
+
|
|
21
78
|
if (!doSpawn) {
|
|
22
79
|
throw new Error('can not spawn a proccess in this env');
|
|
23
80
|
}
|
|
@@ -59,6 +116,8 @@ class SuiCliCommands {
|
|
|
59
116
|
}
|
|
60
117
|
|
|
61
118
|
static async exec(command) {
|
|
119
|
+
const doExecSync = await getSystemFunction('execSync');
|
|
120
|
+
|
|
62
121
|
if (!doExecSync) {
|
|
63
122
|
throw new Error('can not exec a proccess in this env');
|
|
64
123
|
}
|
|
@@ -70,6 +129,9 @@ class SuiCliCommands {
|
|
|
70
129
|
}
|
|
71
130
|
|
|
72
131
|
static async getModulesNamesFromPackagePath(path) {
|
|
132
|
+
const doPath = await getSystemFunction('path');
|
|
133
|
+
const doFs = await getSystemFunction('fs');
|
|
134
|
+
|
|
73
135
|
if (!doPath || !doFs) {
|
|
74
136
|
throw new Error('can not access path in this env');
|
|
75
137
|
}
|
|
@@ -90,6 +152,4 @@ class SuiCliCommands {
|
|
|
90
152
|
throw new Error('can not get modules names from local package path');
|
|
91
153
|
}
|
|
92
154
|
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
module.exports = SuiCliCommands;
|
|
155
|
+
};
|
package/lib/SuiCoin.js
CHANGED
|
@@ -1,31 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
1
|
+
import { Commands, Transaction } from '@mysten/sui/transactions';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef {import("@mysten/sui/transactions").TransactionObjectArgument} TransactionObjectArgument
|
|
5
|
+
*
|
|
6
|
+
*
|
|
7
|
+
* @typedef CoinMeta
|
|
8
|
+
* @type {object}
|
|
9
|
+
* @property {number} decimals - Number of decimal places the coin uses.
|
|
10
|
+
* @property {string} description - Description of the token
|
|
11
|
+
* @property {string} iconUrl - URL for the token logo
|
|
12
|
+
* @property {string} name - Name for the token
|
|
13
|
+
* @property {string} symbol - Symbol for the token
|
|
14
|
+
* @property {string} [id] - Meta id
|
|
15
|
+
* @property {string} [type] - Coin type string
|
|
16
|
+
*
|
|
17
|
+
*
|
|
18
|
+
* @typedef SuidoubleCoinBalance
|
|
19
|
+
* @type {object}
|
|
20
|
+
* @property {SuiCoin} coin
|
|
21
|
+
* @property {string} coinType
|
|
22
|
+
* @property {number} coinObjectCount
|
|
23
|
+
* @property {bigint} totalBalance
|
|
24
|
+
* @property {Object.<string,string>} lockedBalance
|
|
25
|
+
*
|
|
26
|
+
*/
|
|
27
|
+
|
|
26
28
|
|
|
27
29
|
/** Coin metadata object */
|
|
28
|
-
class SuiCoin {
|
|
30
|
+
export default class SuiCoin {
|
|
29
31
|
|
|
30
32
|
/**
|
|
31
33
|
* SuiCoin constructor
|
|
@@ -97,10 +99,6 @@ class SuiCoin {
|
|
|
97
99
|
return this._suiCoins.suiMaster;
|
|
98
100
|
}
|
|
99
101
|
|
|
100
|
-
static safeList(connectedChain) {
|
|
101
|
-
return safeList[connectedChain];
|
|
102
|
-
}
|
|
103
|
-
|
|
104
102
|
get coinType() {
|
|
105
103
|
if (this._coinType.indexOf('0x') === 0) {
|
|
106
104
|
return this._coinType;
|
|
@@ -129,29 +127,7 @@ class SuiCoin {
|
|
|
129
127
|
return this._metadata;
|
|
130
128
|
}
|
|
131
129
|
|
|
132
|
-
get safeList() {
|
|
133
|
-
if (this.suiMaster && this.suiMaster.connectedChain) {
|
|
134
|
-
if (safeList[this.suiMaster.connectedChain]) {
|
|
135
|
-
return safeList[this.suiMaster.connectedChain];
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
return {};
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
get isSafe() {
|
|
143
|
-
if (this.safeList[this.coinType]) {
|
|
144
|
-
return true;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return false;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
130
|
get symbol() {
|
|
151
|
-
if (this.safeList[this.coinType]) {
|
|
152
|
-
return this.safeList[this.coinType];
|
|
153
|
-
}
|
|
154
|
-
|
|
155
131
|
if (this.metadata) {
|
|
156
132
|
return this.metadata.symbol;
|
|
157
133
|
}
|
|
@@ -165,9 +141,24 @@ class SuiCoin {
|
|
|
165
141
|
|
|
166
142
|
isSUI() {
|
|
167
143
|
const lc = this._coinType.toLowerCase();
|
|
168
|
-
if (lc == 'sui
|
|
144
|
+
if (lc == '0x0000000000000000000000000000000000000000000000000000000000000002::sui::sui') { // as it's normalized
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* set predefined coin metadata so it will not be fetched from RPC
|
|
152
|
+
* @param {CoinMeta} meta
|
|
153
|
+
* @returns {boolean} if processed ok
|
|
154
|
+
*/
|
|
155
|
+
setMetadata(meta) {
|
|
156
|
+
if (meta && meta.decimals && meta.decimals > 0 && meta.name && meta.symbol) {
|
|
157
|
+
this._metadata = meta;
|
|
158
|
+
this._exists = true;
|
|
169
159
|
return true;
|
|
170
160
|
}
|
|
161
|
+
|
|
171
162
|
return false;
|
|
172
163
|
}
|
|
173
164
|
|
|
@@ -189,6 +180,7 @@ class SuiCoin {
|
|
|
189
180
|
this._exists = false;
|
|
190
181
|
} else {
|
|
191
182
|
this._metadata = result;
|
|
183
|
+
this._exists = true;
|
|
192
184
|
}
|
|
193
185
|
|
|
194
186
|
return this._metadata;
|
|
@@ -218,6 +210,7 @@ class SuiCoin {
|
|
|
218
210
|
return totalAmount;
|
|
219
211
|
}
|
|
220
212
|
|
|
213
|
+
|
|
221
214
|
/**
|
|
222
215
|
* Returns TransactionObjectArgument with Coin of amount to be used in tranasctions
|
|
223
216
|
*
|
|
@@ -300,6 +293,4 @@ class SuiCoin {
|
|
|
300
293
|
|
|
301
294
|
return null;
|
|
302
295
|
}
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
module.exports = SuiCoin;
|
|
296
|
+
};
|
package/lib/SuiCoins.js
CHANGED
|
@@ -1,17 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import SuiCoin from './SuiCoin.js';
|
|
2
|
+
import SuiCommonMethods from './SuiCommonMethods.js';
|
|
3
|
+
import { allCoinMetas } from '@polymedia/coinmeta';
|
|
4
|
+
import { normalizeStructTag } from "@mysten/sui/utils";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {import("./SuiCoin.js").CoinMeta} CoinMeta
|
|
8
|
+
* @typedef {import("./SuiCoin.js").SuidoubleCoinBalance} SuidoubleCoinBalance
|
|
9
|
+
* @typedef {import("./SuiMaster.js").default} SuiMaster
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Common class to work with Coins and Coin objects. Expected to have single instance per SuiMaster instance
|
|
14
|
+
* @class
|
|
15
|
+
* @constructor
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
export default class SuiCoins extends SuiCommonMethods {
|
|
3
19
|
|
|
4
|
-
|
|
20
|
+
/**
|
|
21
|
+
* SuiCoins constructor
|
|
22
|
+
* @param {Object} params - Initialization parameters
|
|
23
|
+
* @param {SuiMaster} params.suiMaster - instance of SuiMaster
|
|
24
|
+
*/
|
|
5
25
|
constructor(params = {}) {
|
|
6
26
|
super(params);
|
|
7
27
|
|
|
28
|
+
/** @type {SuiMaster} */
|
|
8
29
|
this._suiMaster = params.suiMaster;
|
|
9
30
|
if (!this._suiMaster) {
|
|
10
31
|
throw new Error('suiMaster is required');
|
|
11
32
|
}
|
|
33
|
+
|
|
34
|
+
/** @type {Object.<string, SuiCoin>} */
|
|
12
35
|
this._coins = {};
|
|
13
36
|
|
|
14
|
-
this.
|
|
37
|
+
if (this._suiMaster.onMainnet) {
|
|
38
|
+
// pre-cached coins metadata
|
|
39
|
+
this.setCoinMetas(allCoinMetas);
|
|
40
|
+
}
|
|
15
41
|
}
|
|
16
42
|
|
|
17
43
|
get suiMaster() {
|
|
@@ -23,84 +49,101 @@ class SuiCoins extends SuiCommonMethods {
|
|
|
23
49
|
}
|
|
24
50
|
|
|
25
51
|
/**
|
|
26
|
-
*
|
|
52
|
+
* set predefined coin metas so they will not be fetched from RPC
|
|
53
|
+
* @param {(Object.<string, CoinMeta> | Array.<CoinMeta>)}
|
|
54
|
+
* @returns {number} count of processed items
|
|
27
55
|
*/
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
56
|
+
setCoinMetas(coinMetas) {
|
|
57
|
+
let processedCount = 0;
|
|
58
|
+
if (Array.isArray(coinMetas)) {
|
|
59
|
+
// [CoinMeta, CoinMeta]
|
|
60
|
+
for (const coinMeta of coinMetas) {
|
|
61
|
+
if (coinMeta.type) {
|
|
62
|
+
const suiCoin = this.get(coinMeta.type);
|
|
63
|
+
const ok = suiCoin.setMetadata(coinMeta);
|
|
64
|
+
if (ok) {
|
|
65
|
+
processedCount++;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
} else {
|
|
70
|
+
// {type: CoinMeta, type: CoinMeta}
|
|
71
|
+
for (const coinType in coinMetas) {
|
|
72
|
+
const suiCoin = this.get(coinType);
|
|
73
|
+
const ok = suiCoin.setMetadata(coinMetas[coinType]);
|
|
74
|
+
if (ok) {
|
|
75
|
+
processedCount++;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
31
78
|
}
|
|
32
79
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
for (const coinType in safeList) {
|
|
36
|
-
const normalizedCoinType = this.normalizeCoinType(coinType);
|
|
37
|
-
if (!this._coins[normalizedCoinType]) {
|
|
38
|
-
const suiCoin = new SuiCoin({
|
|
39
|
-
coinType: normalizedCoinType,
|
|
40
|
-
suiCoins: this,
|
|
41
|
-
});
|
|
42
|
-
console.log('adding coin with type', normalizedCoinType);
|
|
43
|
-
this._coins[normalizedCoinType] = suiCoin;
|
|
44
|
-
|
|
45
|
-
const metadataPromise = new Promise(async(res)=>{
|
|
46
|
-
try {
|
|
47
|
-
await suiCoin.getMetadata();
|
|
48
|
-
} catch (e) {
|
|
49
|
-
console.error(e);
|
|
50
|
-
}
|
|
80
|
+
return processedCount;
|
|
81
|
+
}
|
|
51
82
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Get all CoinBalance[] for the specific address or connected address
|
|
85
|
+
*
|
|
86
|
+
* @param {Object} params
|
|
87
|
+
* @param {string?} params.owner - owner address, if skipped - will query for connected wallet address
|
|
88
|
+
*
|
|
89
|
+
* @returns {Promise.<Array.<SuidoubleCoinBalance>>}
|
|
90
|
+
*/
|
|
91
|
+
async getAllBalances(params = {}) {
|
|
92
|
+
let owner = params.owner;
|
|
93
|
+
if (!owner) {
|
|
94
|
+
owner = this._suiMaster.address;
|
|
56
95
|
}
|
|
57
96
|
|
|
58
|
-
|
|
97
|
+
/** @type {Array.<SuidoubleCoinBalance>} */
|
|
98
|
+
const ret = [];
|
|
99
|
+
|
|
100
|
+
const nativeCoinBalances = await this._suiMaster.client.getAllBalances({
|
|
101
|
+
owner,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
for (const nativeCoinBalance of nativeCoinBalances) {
|
|
105
|
+
/** @type {SuidoubleCoinBalance} */
|
|
106
|
+
const coinBalance = {
|
|
107
|
+
coin: this.get(nativeCoinBalance.coinType),
|
|
108
|
+
coinType: nativeCoinBalance.coinType,
|
|
109
|
+
coinObjectCount: nativeCoinBalance.coinObjectCount,
|
|
110
|
+
totalBalance: BigInt(nativeCoinBalance.totalBalance),
|
|
111
|
+
lockedBalance: nativeCoinBalance.lockedBalance,
|
|
112
|
+
};
|
|
113
|
+
ret.push(coinBalance);
|
|
114
|
+
}
|
|
59
115
|
|
|
60
|
-
|
|
116
|
+
return ret;
|
|
61
117
|
}
|
|
62
118
|
|
|
119
|
+
/**
|
|
120
|
+
* normalize coinType string to sui's coin type. As extra, may take 'sui' or 'SUI' as the type and return type for it
|
|
121
|
+
* @param {string} coinType
|
|
122
|
+
* @returns {string} normalized coin type
|
|
123
|
+
*/
|
|
63
124
|
normalizeCoinType(coinType) {
|
|
64
|
-
|
|
65
|
-
if (coinType.toLowerCase() == 'sui') {
|
|
66
|
-
return '0x2::sui::SUI';
|
|
67
|
-
} else {
|
|
68
|
-
for (const key in this._coins) {
|
|
69
|
-
if (key == coinType) {
|
|
70
|
-
return this._coins[key].coinType;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const safeList = SuiCoin.safeList(this._suiMaster.connectedChain);
|
|
75
|
-
for (const key in safeList) {
|
|
76
|
-
if (safeList[key] == coinType) {
|
|
77
|
-
return key;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
125
|
+
let nCoinType = (''+coinType);
|
|
81
126
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
return ''+coinType+'::coin::COIN';
|
|
127
|
+
if (nCoinType.indexOf('::') == -1) {
|
|
128
|
+
if (nCoinType.toLowerCase() == 'sui') {
|
|
129
|
+
nCoinType = '0x2::sui::SUI';
|
|
86
130
|
}
|
|
87
131
|
}
|
|
88
132
|
|
|
89
|
-
if (
|
|
90
|
-
|
|
133
|
+
if (nCoinType.indexOf('0x') == -1) {
|
|
134
|
+
nCoinType = '0x'+nCoinType;
|
|
91
135
|
}
|
|
92
136
|
|
|
93
|
-
|
|
94
|
-
return '0x2::sui::SUI';
|
|
95
|
-
}
|
|
137
|
+
nCoinType = normalizeStructTag(nCoinType);
|
|
96
138
|
|
|
97
|
-
return
|
|
139
|
+
return nCoinType;
|
|
98
140
|
}
|
|
99
141
|
|
|
100
142
|
/**
|
|
101
143
|
* Return instance of SuiCoin of specific type
|
|
102
144
|
*
|
|
103
145
|
* @param {string} coinType - MoveType, or 'SUI' as helper
|
|
146
|
+
*
|
|
104
147
|
* @returns {SuiCoin}
|
|
105
148
|
*/
|
|
106
149
|
get(coinType) {
|
|
@@ -121,6 +164,14 @@ class SuiCoins extends SuiCommonMethods {
|
|
|
121
164
|
}
|
|
122
165
|
|
|
123
166
|
static _singleInstances = {};
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Return singleton instance of the SuiCoins object for the specific chain
|
|
170
|
+
*
|
|
171
|
+
* @param {Object} params - parameters
|
|
172
|
+
* @param {SuiMaster} params.suiMaster - instance of SuiMaster
|
|
173
|
+
* @returns {SuiCoins}
|
|
174
|
+
*/
|
|
124
175
|
static getSingleton(params = {}) {
|
|
125
176
|
const suiMaster = params.suiMaster;
|
|
126
177
|
const connectedChain = suiMaster.connectedChain;
|
|
@@ -133,6 +184,4 @@ class SuiCoins extends SuiCommonMethods {
|
|
|
133
184
|
return SuiCoins._singleInstances[connectedChain];
|
|
134
185
|
}
|
|
135
186
|
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
module.exports = SuiCoins;
|
|
187
|
+
};
|
package/lib/SuiCommonMethods.js
CHANGED
|
@@ -12,7 +12,7 @@ class CustomEvent extends Event {
|
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
class SuiCommonMethods extends EventTarget {
|
|
15
|
+
export default class SuiCommonMethods extends EventTarget {
|
|
16
16
|
constructor(params = {}) {
|
|
17
17
|
super();
|
|
18
18
|
|
|
@@ -42,6 +42,4 @@ class SuiCommonMethods extends EventTarget {
|
|
|
42
42
|
console.error(e);
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
module.exports = SuiCommonMethods;
|
|
45
|
+
};
|
package/lib/SuiEvent.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
2
|
|
|
3
|
-
class SuiEvent extends Event {
|
|
3
|
+
export default class SuiEvent extends Event {
|
|
4
4
|
constructor(params = {}) {
|
|
5
5
|
const typeName = params.data ? ((''+params.data.type).split('<')[0].split('::').pop()) : null;
|
|
6
6
|
super(typeName, {});
|
|
@@ -58,6 +58,4 @@ class SuiEvent extends Event {
|
|
|
58
58
|
return null;
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
module.exports = SuiEvent;
|
|
61
|
+
};
|