suidouble 1.14.2 → 1.14.3-2
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/index.js +7 -1
- package/lib/SuiCoin.js +104 -15
- package/lib/SuiCoins.js +38 -0
- package/lib/SuiMaster.js +7 -0
- package/lib/SuiMemoryObjectStorage.js +47 -6
- package/lib/SuiPackage.js +1 -1
- package/package.json +3 -3
- package/test/coins.test.js +126 -8
package/index.js
CHANGED
|
@@ -4,7 +4,10 @@ import SuiTestScenario from './lib/SuiTestScenario.js';
|
|
|
4
4
|
import SuiObject from './lib/SuiObject.js';
|
|
5
5
|
import SuiUtils from './lib/SuiUtils.js';
|
|
6
6
|
import SuiLocalTestValidator from './lib/SuiLocalTestValidator.js';
|
|
7
|
-
import
|
|
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';
|
|
8
11
|
import { bcs } from '@mysten/sui/bcs';
|
|
9
12
|
|
|
10
13
|
const txInput = SuiUtils.txInput;
|
|
@@ -22,4 +25,7 @@ export {
|
|
|
22
25
|
SuiUtils,
|
|
23
26
|
txInput,
|
|
24
27
|
bcs,
|
|
28
|
+
SuiMemoryObjectStorage,
|
|
29
|
+
SuiCoin,
|
|
30
|
+
SuiCoins,
|
|
25
31
|
};
|
package/lib/SuiCoin.js
CHANGED
|
@@ -13,9 +13,18 @@ import { Commands, Transaction } from '@mysten/sui/transactions';
|
|
|
13
13
|
* @property {string} symbol - Symbol for the token
|
|
14
14
|
* @property {string} [id] - Meta id
|
|
15
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
|
+
*
|
|
16
26
|
*/
|
|
17
27
|
|
|
18
|
-
|
|
19
28
|
/** Coin metadata object */
|
|
20
29
|
export default class SuiCoin {
|
|
21
30
|
|
|
@@ -53,38 +62,94 @@ export default class SuiCoin {
|
|
|
53
62
|
|
|
54
63
|
/**
|
|
55
64
|
* Normalize amount based on .decimals. Pass a string with a dot ('5.22', '0.0005') to convert it to units. No worries about loading metadata first.
|
|
56
|
-
* @param {String|Number|
|
|
57
|
-
* @returns {
|
|
65
|
+
* @param {String|Number|bigint} amount
|
|
66
|
+
* @returns {Promise.<bigint>}
|
|
58
67
|
*/
|
|
59
68
|
async lazyNormalizeAmount(amount) {
|
|
60
69
|
await this.getMetadata();
|
|
61
70
|
return this.normalizeAmount(amount);
|
|
62
71
|
}
|
|
63
72
|
|
|
64
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Get readable representation of amount value (system one, bigint or converted from bigint, NOT the '1.99' etc)
|
|
75
|
+
* based on coin decimals metadata ( so it expects metadata to be loaded or set).
|
|
76
|
+
*
|
|
77
|
+
* @param {Object} params - format parameters
|
|
78
|
+
* @param {boolean} params.withAbbr - append K, M, B, T for large amounts. Suiet-style
|
|
79
|
+
* @param {boolean|string} params.separateThousands - separate thousands, by ',' or by specific delimeter
|
|
80
|
+
*
|
|
81
|
+
* @returns {string}
|
|
82
|
+
*/
|
|
83
|
+
amountToString(amount, options = {}) {
|
|
65
84
|
if (!this.decimals) {
|
|
66
85
|
throw new Error('Please load coin metadata first');
|
|
67
86
|
}
|
|
68
87
|
|
|
88
|
+
const withAbbr = !!options.withAbbr;
|
|
89
|
+
const separateThousands = options.separateThousands;
|
|
90
|
+
|
|
69
91
|
const str = (''+BigInt(amount)).padStart(this.decimals + 1,'0');
|
|
70
92
|
const ind = str.length - this.decimals;
|
|
71
93
|
let asFloatString = str.substring(0, ind) + '.' + str.substring(ind);
|
|
72
94
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
95
|
+
if (asFloatString.includes('.')) {
|
|
96
|
+
asFloatString = asFloatString.replace(/(\.\d*?)0+$/, '$1').replace(/\.$/, '');
|
|
97
|
+
if (!asFloatString.includes('.')) {
|
|
98
|
+
asFloatString = '' + asFloatString + '.0';
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (withAbbr) {
|
|
103
|
+
const asBig = BigInt(Math.floor(Number(asFloatString)));
|
|
104
|
+
|
|
105
|
+
if (asBig > 1000n) {
|
|
106
|
+
if (asBig < 1000000n) return this.formatWithAbbr(asBig, 1000n, 'K', separateThousands);
|
|
107
|
+
if (asBig >= 1000000n && asBig < 1000000000n) return this.formatWithAbbr(asBig, 1000000n, 'M', separateThousands);
|
|
108
|
+
if (asBig >= 1000000000n && asBig < 1000000000000n) return this.formatWithAbbr(asBig, 1000000000n, 'B', separateThousands);
|
|
109
|
+
if (asBig >= 1000000000000n) return this.formatWithAbbr(asBig, 1000000000000n, 'T', separateThousands);
|
|
81
110
|
}
|
|
82
|
-
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (separateThousands) {
|
|
114
|
+
// asFloatString has '.' anyway ( see above )
|
|
115
|
+
const [integerPart, decimalPart] = asFloatString.split('.'); // Split into integer and decimal parts
|
|
116
|
+
const separator = (typeof separateThousands === 'string') ? separateThousands : ',';
|
|
117
|
+
const formattedInteger = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, separator);
|
|
118
|
+
asFloatString = '' + formattedInteger + '.' + decimalPart;
|
|
83
119
|
}
|
|
84
120
|
|
|
85
121
|
return asFloatString;
|
|
86
122
|
}
|
|
87
123
|
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Format large amounts
|
|
127
|
+
*
|
|
128
|
+
* thanks @bruceeewong and @suiet
|
|
129
|
+
*
|
|
130
|
+
* @param {bigint} amount
|
|
131
|
+
* @param {bigint} measureUnit
|
|
132
|
+
* @param {string} abbrSymbol
|
|
133
|
+
*
|
|
134
|
+
* @returns {string}
|
|
135
|
+
*/
|
|
136
|
+
formatWithAbbr(amount, measureUnit, abbrSymbol, separateThousands = false) {
|
|
137
|
+
let showAmount = (''+Math.floor(Number(amount) / Number(measureUnit / 1000n)));
|
|
138
|
+
showAmount = showAmount.padEnd(4, '0');
|
|
139
|
+
|
|
140
|
+
const result = Intl.NumberFormat('en-US').format(Number(showAmount));
|
|
141
|
+
|
|
142
|
+
let separator = '';
|
|
143
|
+
if (separateThousands) {
|
|
144
|
+
separator = (typeof separateThousands === 'string') ? separateThousands : ',';
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const pcs = result.split(',');
|
|
148
|
+
const lastPc = pcs.pop();
|
|
149
|
+
return pcs.join( separator ) + '.' + lastPc + abbrSymbol;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
|
|
88
153
|
get suiMaster() {
|
|
89
154
|
return this._suiCoins.suiMaster;
|
|
90
155
|
}
|
|
@@ -140,6 +205,7 @@ export default class SuiCoin {
|
|
|
140
205
|
/**
|
|
141
206
|
* set predefined coin metadata so it will not be fetched from RPC
|
|
142
207
|
* @param {CoinMeta} meta
|
|
208
|
+
*
|
|
143
209
|
* @returns {boolean} if processed ok
|
|
144
210
|
*/
|
|
145
211
|
setMetadata(meta) {
|
|
@@ -152,11 +218,25 @@ export default class SuiCoin {
|
|
|
152
218
|
return false;
|
|
153
219
|
}
|
|
154
220
|
|
|
221
|
+
/**
|
|
222
|
+
* Load coin metadata from the blockchain. As a good pattern, it's better to have metadata hard-coded or cached
|
|
223
|
+
* and set via suiMaster.suiCoins.setCoinMetas(...)
|
|
224
|
+
*
|
|
225
|
+
* @returns {Promise.<boolean>}
|
|
226
|
+
*/
|
|
155
227
|
async getMetadata() {
|
|
156
228
|
if (this._metadata) {
|
|
157
229
|
return this._metadata;
|
|
158
230
|
}
|
|
159
231
|
|
|
232
|
+
if (this.__getMetadataPromise) {
|
|
233
|
+
return await this.__getMetadataPromise;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// be sure it asyncs in 1 thread
|
|
237
|
+
this.__getMetadataResolver = null;
|
|
238
|
+
this.__getMetadataPromise = new Promise((res)=>{ this.__getMetadataResolver = res; });
|
|
239
|
+
|
|
160
240
|
let result = null;
|
|
161
241
|
try {
|
|
162
242
|
result = await this.suiMaster.client.getCoinMetadata({
|
|
@@ -173,9 +253,17 @@ export default class SuiCoin {
|
|
|
173
253
|
this._exists = true;
|
|
174
254
|
}
|
|
175
255
|
|
|
176
|
-
|
|
256
|
+
this.__getMetadataResolver(true);
|
|
257
|
+
|
|
258
|
+
return true;
|
|
177
259
|
}
|
|
178
260
|
|
|
261
|
+
/**
|
|
262
|
+
* Get coin balance of the wallet
|
|
263
|
+
* @param {string} owner
|
|
264
|
+
*
|
|
265
|
+
* @returns {Promise.<bigint>}
|
|
266
|
+
*/
|
|
179
267
|
async getBalance(owner) {
|
|
180
268
|
const coins = [];
|
|
181
269
|
let result = null;
|
|
@@ -208,7 +296,8 @@ export default class SuiCoin {
|
|
|
208
296
|
* @param {string} owner - address of the owner
|
|
209
297
|
* @param {BigInt|string} amount - amount of coin. BigIng or String to be normalized via Coin decimals, "0.05" for 0.05 sui
|
|
210
298
|
* @param {boolean} addEmptyCoins - attach coins == 0 to the list
|
|
211
|
-
*
|
|
299
|
+
*
|
|
300
|
+
* @returns {Promise.<TransactionObjectArgument>}
|
|
212
301
|
*/
|
|
213
302
|
async coinOfAmountToTxCoin(txb, owner, amount, addEmptyCoins = false) {
|
|
214
303
|
const normalizedAmount = await this.lazyNormalizeAmount(amount);
|
package/lib/SuiCoins.js
CHANGED
|
@@ -5,6 +5,7 @@ import { normalizeStructTag } from "@mysten/sui/utils";
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @typedef {import("./SuiCoin.js").CoinMeta} CoinMeta
|
|
8
|
+
* @typedef {import("./SuiCoin.js").SuidoubleCoinBalance} SuidoubleCoinBalance
|
|
8
9
|
* @typedef {import("./SuiMaster.js").default} SuiMaster
|
|
9
10
|
*/
|
|
10
11
|
|
|
@@ -79,6 +80,42 @@ export default class SuiCoins extends SuiCommonMethods {
|
|
|
79
80
|
return processedCount;
|
|
80
81
|
}
|
|
81
82
|
|
|
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;
|
|
95
|
+
}
|
|
96
|
+
|
|
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
|
+
}
|
|
115
|
+
|
|
116
|
+
return ret;
|
|
117
|
+
}
|
|
118
|
+
|
|
82
119
|
/**
|
|
83
120
|
* normalize coinType string to sui's coin type. As extra, may take 'sui' or 'SUI' as the type and return type for it
|
|
84
121
|
* @param {string} coinType
|
|
@@ -106,6 +143,7 @@ export default class SuiCoins extends SuiCommonMethods {
|
|
|
106
143
|
* Return instance of SuiCoin of specific type
|
|
107
144
|
*
|
|
108
145
|
* @param {string} coinType - MoveType, or 'SUI' as helper
|
|
146
|
+
*
|
|
109
147
|
* @returns {SuiCoin}
|
|
110
148
|
*/
|
|
111
149
|
get(coinType) {
|
package/lib/SuiMaster.js
CHANGED
|
@@ -102,6 +102,7 @@ export default class SuiMaster extends SuiCommonMethods {
|
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
// we are differient single instances of object storage by provider name (so we can separate like devnet-testnet entities if needed)
|
|
105
|
+
/** @type {SuiMemoryObjectStorage} */
|
|
105
106
|
this._objectStorage = SuiMemoryObjectStorage.instanceOf(this._providerName, {
|
|
106
107
|
debug: this._debug,
|
|
107
108
|
suiMaster: this,
|
|
@@ -111,6 +112,7 @@ export default class SuiMaster extends SuiCommonMethods {
|
|
|
111
112
|
|
|
112
113
|
this._packages = {};
|
|
113
114
|
|
|
115
|
+
/** @type {SuiCoins} */
|
|
114
116
|
this._suiCoins = new SuiCoins({
|
|
115
117
|
suiMaster: this,
|
|
116
118
|
debug: this._debug,
|
|
@@ -161,6 +163,11 @@ export default class SuiMaster extends SuiCommonMethods {
|
|
|
161
163
|
return SuiEvent;
|
|
162
164
|
}
|
|
163
165
|
|
|
166
|
+
/**
|
|
167
|
+
* Storage storing all objects interacted by this suiMaster
|
|
168
|
+
*
|
|
169
|
+
* @type {SuiMemoryObjectStorage}
|
|
170
|
+
*/
|
|
164
171
|
get objectStorage() {
|
|
165
172
|
return this._objectStorage;
|
|
166
173
|
}
|
|
@@ -1,10 +1,29 @@
|
|
|
1
1
|
import SuiCommonMethods from './SuiCommonMethods.js';
|
|
2
|
-
|
|
2
|
+
import SuiObject from './SuiObject.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Class to work with SuiObject's in bulk
|
|
6
|
+
*
|
|
7
|
+
* Sample usage:
|
|
8
|
+
* ```
|
|
9
|
+
* suiMemoryObjectStorage.push(id);
|
|
10
|
+
* suiMemoryObjectStorage.push(suiObject);
|
|
11
|
+
* await suiMemoryObjectStorage.fetchObjects();
|
|
12
|
+
* suiMemoryObjectStorage.byAddress(id);
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
3
15
|
export default class SuiMemoryObjectStorage extends SuiCommonMethods {
|
|
16
|
+
/**
|
|
17
|
+
* SuiMemoryObjectStorage constructor
|
|
18
|
+
* @param {Object} params - Initialization parameters
|
|
19
|
+
* @param {SuiMaster} params.suiMaster - instance of SuiMaster
|
|
20
|
+
*/
|
|
4
21
|
constructor(params = {}) {
|
|
5
22
|
super(params);
|
|
6
23
|
|
|
7
24
|
this._suiMaster = params.suiMaster;
|
|
25
|
+
|
|
26
|
+
/** @type {Object.<string, SuiObject>} */
|
|
8
27
|
this._objects = {};
|
|
9
28
|
}
|
|
10
29
|
|
|
@@ -44,14 +63,29 @@ export default class SuiMemoryObjectStorage extends SuiCommonMethods {
|
|
|
44
63
|
return mostRecentObject;
|
|
45
64
|
}
|
|
46
65
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
66
|
+
/**
|
|
67
|
+
* @param {SuiObject | string} suiObjectOrId
|
|
68
|
+
*
|
|
69
|
+
* @returns {SuiObject | null}
|
|
70
|
+
*/
|
|
71
|
+
push(suiObjectOrId) {
|
|
72
|
+
if (suiObjectOrId && suiObjectOrId.address) {
|
|
73
|
+
const /** @type {SuiObject} */ obj = suiObjectOrId;
|
|
74
|
+
this._objects[obj.address] = obj;
|
|
75
|
+
|
|
76
|
+
return obj;
|
|
77
|
+
} else if (suiObjectOrId && (''+suiObjectOrId).indexOf('0x') === 0) {
|
|
78
|
+
if (this._objects[suiObjectOrId]) {
|
|
79
|
+
return this._objects[suiObjectOrId];
|
|
80
|
+
}
|
|
50
81
|
|
|
51
|
-
|
|
82
|
+
const obj = new SuiObject({id: suiObjectOrId, suiMaster: this._suiMaster});
|
|
83
|
+
this._objects[obj.address] = obj;
|
|
84
|
+
|
|
85
|
+
return obj;
|
|
52
86
|
}
|
|
53
87
|
|
|
54
|
-
return
|
|
88
|
+
return null;
|
|
55
89
|
}
|
|
56
90
|
|
|
57
91
|
byAddress(address) {
|
|
@@ -125,6 +159,13 @@ export default class SuiMemoryObjectStorage extends SuiCommonMethods {
|
|
|
125
159
|
|
|
126
160
|
static _instances = {};
|
|
127
161
|
|
|
162
|
+
/**
|
|
163
|
+
* @param {string} validatorId - just a string for single instance identifier
|
|
164
|
+
* @param {Object} params - Initialization parameters
|
|
165
|
+
* @param {SuiMaster} params.suiMaster - instance of SuiMaster
|
|
166
|
+
*
|
|
167
|
+
* @returns {SuiMemoryObjectStorage}
|
|
168
|
+
*/
|
|
128
169
|
static instanceOf(validatorId, params = {}) {
|
|
129
170
|
if (SuiMemoryObjectStorage._instances[validatorId]) {
|
|
130
171
|
return SuiMemoryObjectStorage._instances[validatorId];
|
package/lib/SuiPackage.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "suidouble",
|
|
3
|
-
"version": "1.14.2",
|
|
3
|
+
"version": "1.14.3-2",
|
|
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
|
"type": "module",
|
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
"author": "suidouble (https://github.com/suidouble)",
|
|
23
23
|
"license": "Apache-2.0",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@mysten/sui": "^1.14.
|
|
26
|
-
"@polymedia/coinmeta": "^0.0.
|
|
25
|
+
"@mysten/sui": "^1.14.3",
|
|
26
|
+
"@polymedia/coinmeta": "^0.0.17",
|
|
27
27
|
"@wallet-standard/core": "^1.0.3",
|
|
28
28
|
"websocket": "^1.0.35"
|
|
29
29
|
},
|
package/test/coins.test.js
CHANGED
|
@@ -5,6 +5,8 @@ import { SuiMaster, SuiLocalTestValidator, Transaction } from '../index.js';
|
|
|
5
5
|
const { test } = t;
|
|
6
6
|
|
|
7
7
|
let suiLocalTestValidator = null;
|
|
8
|
+
|
|
9
|
+
/** @type {SuiMaster} */
|
|
8
10
|
let suiMaster = null;
|
|
9
11
|
|
|
10
12
|
test('spawn local test node', async t => {
|
|
@@ -33,13 +35,6 @@ test('type is normalized for SUI', async t => {
|
|
|
33
35
|
const suiCoin5 = suiMaster.suiCoins.get('2::sui::SUI');
|
|
34
36
|
const suiCoin6 = suiMaster.suiCoins.get('0000000000000000000000000000000000000000000000000000000000000002::sui::SUI');
|
|
35
37
|
|
|
36
|
-
console.log(suiCoin1.coinType);
|
|
37
|
-
console.log(suiCoin2.coinType);
|
|
38
|
-
console.log(suiCoin3.coinType);
|
|
39
|
-
console.log(suiCoin4.coinType);
|
|
40
|
-
console.log(suiCoin5.coinType);
|
|
41
|
-
console.log(suiCoin6.coinType);
|
|
42
|
-
|
|
43
38
|
t.ok(suiCoin1.coinType == suiCoin2.coinType);
|
|
44
39
|
t.ok(suiCoin1.coinType == suiCoin3.coinType);
|
|
45
40
|
t.ok(suiCoin1.coinType == suiCoin4.coinType);
|
|
@@ -67,6 +62,9 @@ test('string representation works ok', async t => {
|
|
|
67
62
|
const toDisplay2 = suiCoin.amountToString(1); // 1 mist
|
|
68
63
|
t.equal(toDisplay2, '0.000000001');
|
|
69
64
|
|
|
65
|
+
const toDisplay1000 = suiCoin.amountToString(1000); // 1000 mist
|
|
66
|
+
t.equal(toDisplay1000, '0.000001');
|
|
67
|
+
|
|
70
68
|
const toDisplay3 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1000) + BigInt(1)); // 1000 SUI + 1 mist
|
|
71
69
|
t.equal(toDisplay3, '1000.000000001');
|
|
72
70
|
|
|
@@ -74,6 +72,111 @@ test('string representation works ok', async t => {
|
|
|
74
72
|
t.equal(toDisplay4, '999.999999999');
|
|
75
73
|
});
|
|
76
74
|
|
|
75
|
+
|
|
76
|
+
test('string representation (withAbbr) works ok', async t => {
|
|
77
|
+
const suiCoin = suiMaster.suiCoins.get('sui');
|
|
78
|
+
await suiCoin.getMetadata();
|
|
79
|
+
|
|
80
|
+
// it should dispaly the same on the low amounts:
|
|
81
|
+
|
|
82
|
+
const toDisplay1 = suiCoin.amountToString(suiMaster.MIST_PER_SUI, {withAbbr: true});
|
|
83
|
+
t.equal(toDisplay1, '1.0');
|
|
84
|
+
|
|
85
|
+
const toDisplay2 = suiCoin.amountToString(1, {withAbbr: true}); // 1 mist
|
|
86
|
+
t.equal(toDisplay2, '0.000000001');
|
|
87
|
+
|
|
88
|
+
const toDisplay1000 = suiCoin.amountToString(1000, {withAbbr: true}); // 1000 mist
|
|
89
|
+
t.equal(toDisplay1000, '0.000001');
|
|
90
|
+
|
|
91
|
+
const toDisplay3 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1000) + BigInt(1), {withAbbr: true}); // 1000 SUI + 1 mist
|
|
92
|
+
t.equal(toDisplay3, '1000.000000001');
|
|
93
|
+
|
|
94
|
+
const toDisplay4 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1000) - BigInt(1), {withAbbr: true}); // 1000 SUI - 1 mist
|
|
95
|
+
t.equal(toDisplay4, '999.999999999');
|
|
96
|
+
|
|
97
|
+
// things are getting interesting starting from '1001.0'
|
|
98
|
+
|
|
99
|
+
const toDisplayK1 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1001) + BigInt(1), {withAbbr: true}); // 1000 SUI + 1 mist
|
|
100
|
+
t.equal(toDisplayK1, '1.001K');
|
|
101
|
+
const toDisplayK2 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(2000), {withAbbr: true});
|
|
102
|
+
t.equal(toDisplayK2, '2.000K');
|
|
103
|
+
const toDisplayK3 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(999900), {withAbbr: true});
|
|
104
|
+
t.equal(toDisplayK3, '999.900K');
|
|
105
|
+
|
|
106
|
+
const toDisplayM1 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1000000) + BigInt(1), {withAbbr: true}); // 1000 SUI + 1 mist
|
|
107
|
+
t.equal(toDisplayM1, '1.000M');
|
|
108
|
+
const toDisplayM2 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(2000000) + BigInt(900), {withAbbr: true}); // 1000 SUI + 1 mist
|
|
109
|
+
t.equal(toDisplayM2, '2.000M');
|
|
110
|
+
|
|
111
|
+
const toDisplayM2spec = suiCoin.amountToString(148518424765531477n, {withAbbr: true}); // 1000 SUI + 1 mist
|
|
112
|
+
t.equal(toDisplayM2spec, '148.518M');
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
const toDisplayB1 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1000000000) + BigInt(1), {withAbbr: true}); // 1000 SUI + 1 mist
|
|
116
|
+
t.equal(toDisplayB1, '1.000B');
|
|
117
|
+
|
|
118
|
+
const toDisplayB2spec = suiCoin.amountToString(148518424765531477000n, {withAbbr: true}); // 1000 SUI + 1 mist
|
|
119
|
+
t.equal(toDisplayB2spec, '148.518B');
|
|
120
|
+
|
|
121
|
+
const toDisplayT1 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1000000000000) + BigInt(1), {withAbbr: true}); // 1000 SUI + 1 mist
|
|
122
|
+
t.equal(toDisplayT1, '1.000T');
|
|
123
|
+
|
|
124
|
+
const toDisplayT2spec = suiCoin.amountToString(148518424765531477000000n, {withAbbr: true}); // 1000 SUI + 1 mist
|
|
125
|
+
t.equal(toDisplayT2spec, '148.518T');
|
|
126
|
+
|
|
127
|
+
const toDisplayT20spec = suiCoin.amountToString(148518424765531477000000000n, {withAbbr: true}); // 1000 SUI + 1 mist
|
|
128
|
+
t.equal(toDisplayT20spec, '148518.424T');
|
|
129
|
+
|
|
130
|
+
const toDisplayT20spec2 = suiCoin.amountToString(148518424765531477000000000n, {withAbbr: true, separateThousands: true}); // 1000 SUI + 1 mist
|
|
131
|
+
t.equal(toDisplayT20spec2, '148,518.424T');
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
test('string representation (separateThousands) works ok', async t => {
|
|
136
|
+
const suiCoin = suiMaster.suiCoins.get('sui');
|
|
137
|
+
await suiCoin.getMetadata();
|
|
138
|
+
|
|
139
|
+
// it should dispaly the same on the low amounts:
|
|
140
|
+
|
|
141
|
+
const toDisplay1 = suiCoin.amountToString(suiMaster.MIST_PER_SUI, {separateThousands: true});
|
|
142
|
+
t.equal(toDisplay1, '1.0');
|
|
143
|
+
|
|
144
|
+
const toDisplay2 = suiCoin.amountToString(1, {separateThousands: true}); // 1 mist
|
|
145
|
+
t.equal(toDisplay2, '0.000000001');
|
|
146
|
+
|
|
147
|
+
const toDisplay1000 = suiCoin.amountToString(1000, {separateThousands: true}); // 1000 mist
|
|
148
|
+
t.equal(toDisplay1000, '0.000001');
|
|
149
|
+
|
|
150
|
+
const toDisplay3 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1000) + BigInt(1), {separateThousands: true}); // 1000 SUI + 1 mist
|
|
151
|
+
t.equal(toDisplay3, '1,000.000000001');
|
|
152
|
+
|
|
153
|
+
const toDisplay4 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1000) - BigInt(1), {separateThousands: true}); // 1000 SUI - 1 mist
|
|
154
|
+
t.equal(toDisplay4, '999.999999999');
|
|
155
|
+
|
|
156
|
+
// things are getting interesting starting from '1001.0'
|
|
157
|
+
|
|
158
|
+
const toDisplayK1 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1001) + BigInt(1), {separateThousands: true});
|
|
159
|
+
t.equal(toDisplayK1, '1,001.000000001');
|
|
160
|
+
const toDisplayK2 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(2000), {separateThousands: true});
|
|
161
|
+
t.equal(toDisplayK2, '2,000.0');
|
|
162
|
+
const toDisplayK3 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(999900), {separateThousands: true});
|
|
163
|
+
t.equal(toDisplayK3, '999,900.0');
|
|
164
|
+
|
|
165
|
+
const toDisplayM1 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1000000) + BigInt(1), {separateThousands: true});
|
|
166
|
+
t.equal(toDisplayM1, '1,000,000.000000001');
|
|
167
|
+
const toDisplayM2 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(2000000) + BigInt(900), {separateThousands: true});
|
|
168
|
+
t.equal(toDisplayM2, '2,000,000.0000009');
|
|
169
|
+
|
|
170
|
+
const toDisplayB1 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1000000000) + BigInt(1), {separateThousands: true});
|
|
171
|
+
t.equal(toDisplayB1, '1,000,000,000.000000001');
|
|
172
|
+
|
|
173
|
+
const toDisplayT1 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1000000000000) + BigInt(1), {separateThousands: true});
|
|
174
|
+
t.equal(toDisplayT1, '1,000,000,000,000.000000001');
|
|
175
|
+
|
|
176
|
+
const toDisplayT1q = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1000000000000) + BigInt(1), {separateThousands: ' '});
|
|
177
|
+
t.equal(toDisplayT1q, '1 000 000 000 000.000000001');
|
|
178
|
+
});
|
|
179
|
+
|
|
77
180
|
test('you have no SUI on the fresh node', async t => {
|
|
78
181
|
const suiCoin = suiMaster.suiCoins.get('sui');
|
|
79
182
|
const balance = await suiCoin.getBalance(suiMaster.address);
|
|
@@ -88,6 +191,22 @@ test('have some after requesting from faucet', async t => {
|
|
|
88
191
|
t.ok(balance > BigInt(0));
|
|
89
192
|
});
|
|
90
193
|
|
|
194
|
+
test('have some in balance query', async t => {
|
|
195
|
+
const balances = await suiMaster.suiCoins.getAllBalances();
|
|
196
|
+
|
|
197
|
+
let ok = false;
|
|
198
|
+
for (const balance of balances) {
|
|
199
|
+
if (balance.coin.isSUI()) {
|
|
200
|
+
if (balance.totalBalance > 0n) {
|
|
201
|
+
ok = true;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
t.ok(ok);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
|
|
91
210
|
test('getting coin objects for a transaction', async t => {
|
|
92
211
|
const suiCoin = suiMaster.suiCoins.get('sui');
|
|
93
212
|
|
|
@@ -111,7 +230,6 @@ test('getting coin objects for a transaction', async t => {
|
|
|
111
230
|
});
|
|
112
231
|
|
|
113
232
|
|
|
114
|
-
|
|
115
233
|
test('stops local test node', async t => {
|
|
116
234
|
await SuiLocalTestValidator.stop();
|
|
117
235
|
});
|