suidouble 1.14.2 → 1.14.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.
- package/index.js +7 -1
- package/lib/SuiCoin.js +96 -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 +110 -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,86 @@ 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');
|
|
107
|
+
if (asBig >= 1000000n && asBig < 1000000000n) return this.formatWithAbbr(asBig, 1000000n, 'M');
|
|
108
|
+
if (asBig >= 1000000000n && asBig < 1000000000000n) return this.formatWithAbbr(asBig, 1000000000n, 'B');
|
|
109
|
+
if (asBig >= 1000000000000n) return this.formatWithAbbr(asBig, 1000000000000n, 'T');
|
|
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) {
|
|
137
|
+
let showAmount = (''+(Number(amount) / Number(measureUnit / 1000n)));
|
|
138
|
+
showAmount = showAmount.padEnd(4, '0');
|
|
139
|
+
|
|
140
|
+
const result = Intl.NumberFormat('en-US').format(Number(showAmount));
|
|
141
|
+
return result.replace(',', '.') + abbrSymbol;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
|
|
88
145
|
get suiMaster() {
|
|
89
146
|
return this._suiCoins.suiMaster;
|
|
90
147
|
}
|
|
@@ -140,6 +197,7 @@ export default class SuiCoin {
|
|
|
140
197
|
/**
|
|
141
198
|
* set predefined coin metadata so it will not be fetched from RPC
|
|
142
199
|
* @param {CoinMeta} meta
|
|
200
|
+
*
|
|
143
201
|
* @returns {boolean} if processed ok
|
|
144
202
|
*/
|
|
145
203
|
setMetadata(meta) {
|
|
@@ -152,11 +210,25 @@ export default class SuiCoin {
|
|
|
152
210
|
return false;
|
|
153
211
|
}
|
|
154
212
|
|
|
213
|
+
/**
|
|
214
|
+
* Load coin metadata from the blockchain. As a good pattern, it's better to have metadata hard-coded or cached
|
|
215
|
+
* and set via suiMaster.suiCoins.setCoinMetas(...)
|
|
216
|
+
*
|
|
217
|
+
* @returns {Promise.<boolean>}
|
|
218
|
+
*/
|
|
155
219
|
async getMetadata() {
|
|
156
220
|
if (this._metadata) {
|
|
157
221
|
return this._metadata;
|
|
158
222
|
}
|
|
159
223
|
|
|
224
|
+
if (this.__getMetadataPromise) {
|
|
225
|
+
return await this.__getMetadataPromise();
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// be sure it asyncs in 1 thread
|
|
229
|
+
this.__getMetadataResolver = null;
|
|
230
|
+
this.__getMetadataPromise = new Promise((res)=>{ this.__getMetadataResolver = res; });
|
|
231
|
+
|
|
160
232
|
let result = null;
|
|
161
233
|
try {
|
|
162
234
|
result = await this.suiMaster.client.getCoinMetadata({
|
|
@@ -173,9 +245,17 @@ export default class SuiCoin {
|
|
|
173
245
|
this._exists = true;
|
|
174
246
|
}
|
|
175
247
|
|
|
176
|
-
|
|
248
|
+
this.__getMetadataResolver(true);
|
|
249
|
+
|
|
250
|
+
return true;
|
|
177
251
|
}
|
|
178
252
|
|
|
253
|
+
/**
|
|
254
|
+
* Get coin balance of the wallet
|
|
255
|
+
* @param {string} owner
|
|
256
|
+
*
|
|
257
|
+
* @returns {Promise.<bigint>}
|
|
258
|
+
*/
|
|
179
259
|
async getBalance(owner) {
|
|
180
260
|
const coins = [];
|
|
181
261
|
let result = null;
|
|
@@ -208,7 +288,8 @@ export default class SuiCoin {
|
|
|
208
288
|
* @param {string} owner - address of the owner
|
|
209
289
|
* @param {BigInt|string} amount - amount of coin. BigIng or String to be normalized via Coin decimals, "0.05" for 0.05 sui
|
|
210
290
|
* @param {boolean} addEmptyCoins - attach coins == 0 to the list
|
|
211
|
-
*
|
|
291
|
+
*
|
|
292
|
+
* @returns {Promise.<TransactionObjectArgument>}
|
|
212
293
|
*/
|
|
213
294
|
async coinOfAmountToTxCoin(txb, owner, amount, addEmptyCoins = false) {
|
|
214
295
|
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.
|
|
3
|
+
"version": "1.14.3",
|
|
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,95 @@ 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 toDisplayB1 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1000000000) + BigInt(1), {withAbbr: true}); // 1000 SUI + 1 mist
|
|
112
|
+
t.equal(toDisplayB1, '1.000B');
|
|
113
|
+
|
|
114
|
+
const toDisplayT1 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1000000000000) + BigInt(1), {withAbbr: true}); // 1000 SUI + 1 mist
|
|
115
|
+
t.equal(toDisplayT1, '1.000T');
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
test('string representation (separateThousands) works ok', async t => {
|
|
120
|
+
const suiCoin = suiMaster.suiCoins.get('sui');
|
|
121
|
+
await suiCoin.getMetadata();
|
|
122
|
+
|
|
123
|
+
// it should dispaly the same on the low amounts:
|
|
124
|
+
|
|
125
|
+
const toDisplay1 = suiCoin.amountToString(suiMaster.MIST_PER_SUI, {separateThousands: true});
|
|
126
|
+
t.equal(toDisplay1, '1.0');
|
|
127
|
+
|
|
128
|
+
const toDisplay2 = suiCoin.amountToString(1, {separateThousands: true}); // 1 mist
|
|
129
|
+
t.equal(toDisplay2, '0.000000001');
|
|
130
|
+
|
|
131
|
+
const toDisplay1000 = suiCoin.amountToString(1000, {separateThousands: true}); // 1000 mist
|
|
132
|
+
t.equal(toDisplay1000, '0.000001');
|
|
133
|
+
|
|
134
|
+
const toDisplay3 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1000) + BigInt(1), {separateThousands: true}); // 1000 SUI + 1 mist
|
|
135
|
+
t.equal(toDisplay3, '1,000.000000001');
|
|
136
|
+
|
|
137
|
+
const toDisplay4 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1000) - BigInt(1), {separateThousands: true}); // 1000 SUI - 1 mist
|
|
138
|
+
t.equal(toDisplay4, '999.999999999');
|
|
139
|
+
|
|
140
|
+
// things are getting interesting starting from '1001.0'
|
|
141
|
+
|
|
142
|
+
const toDisplayK1 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1001) + BigInt(1), {separateThousands: true});
|
|
143
|
+
t.equal(toDisplayK1, '1,001.000000001');
|
|
144
|
+
const toDisplayK2 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(2000), {separateThousands: true});
|
|
145
|
+
t.equal(toDisplayK2, '2,000.0');
|
|
146
|
+
const toDisplayK3 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(999900), {separateThousands: true});
|
|
147
|
+
t.equal(toDisplayK3, '999,900.0');
|
|
148
|
+
|
|
149
|
+
const toDisplayM1 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1000000) + BigInt(1), {separateThousands: true});
|
|
150
|
+
t.equal(toDisplayM1, '1,000,000.000000001');
|
|
151
|
+
const toDisplayM2 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(2000000) + BigInt(900), {separateThousands: true});
|
|
152
|
+
t.equal(toDisplayM2, '2,000,000.0000009');
|
|
153
|
+
|
|
154
|
+
const toDisplayB1 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1000000000) + BigInt(1), {separateThousands: true});
|
|
155
|
+
t.equal(toDisplayB1, '1,000,000,000.000000001');
|
|
156
|
+
|
|
157
|
+
const toDisplayT1 = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1000000000000) + BigInt(1), {separateThousands: true});
|
|
158
|
+
t.equal(toDisplayT1, '1,000,000,000,000.000000001');
|
|
159
|
+
|
|
160
|
+
const toDisplayT1q = suiCoin.amountToString(suiMaster.MIST_PER_SUI * BigInt(1000000000000) + BigInt(1), {separateThousands: ' '});
|
|
161
|
+
t.equal(toDisplayT1q, '1 000 000 000 000.000000001');
|
|
162
|
+
});
|
|
163
|
+
|
|
77
164
|
test('you have no SUI on the fresh node', async t => {
|
|
78
165
|
const suiCoin = suiMaster.suiCoins.get('sui');
|
|
79
166
|
const balance = await suiCoin.getBalance(suiMaster.address);
|
|
@@ -88,6 +175,22 @@ test('have some after requesting from faucet', async t => {
|
|
|
88
175
|
t.ok(balance > BigInt(0));
|
|
89
176
|
});
|
|
90
177
|
|
|
178
|
+
test('have some in balance query', async t => {
|
|
179
|
+
const balances = await suiMaster.suiCoins.getAllBalances();
|
|
180
|
+
|
|
181
|
+
let ok = false;
|
|
182
|
+
for (const balance of balances) {
|
|
183
|
+
if (balance.coin.isSUI()) {
|
|
184
|
+
if (balance.totalBalance > 0n) {
|
|
185
|
+
ok = true;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
t.ok(ok);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
|
|
91
194
|
test('getting coin objects for a transaction', async t => {
|
|
92
195
|
const suiCoin = suiMaster.suiCoins.get('sui');
|
|
93
196
|
|
|
@@ -111,7 +214,6 @@ test('getting coin objects for a transaction', async t => {
|
|
|
111
214
|
});
|
|
112
215
|
|
|
113
216
|
|
|
114
|
-
|
|
115
217
|
test('stops local test node', async t => {
|
|
116
218
|
await SuiLocalTestValidator.stop();
|
|
117
219
|
});
|