@pioneer-platform/helpers 4.0.4 → 4.0.6
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/__tests__/test-module.js +25 -8
- package/lib/modules/assetValue.d.ts +9 -9
- package/lib/modules/assetValue.js +254 -208
- package/lib/modules/bigIntArithmetics.d.ts +2 -6
- package/lib/modules/bigIntArithmetics.js +509 -210
- package/lib/modules/swapKitNumber.js +2 -1
- package/package.json +1 -1
- package/src/modules/assetValue.ts +273 -263
- package/src/modules/bigIntArithmetics.ts +520 -264
- package/src/modules/swapKitNumber.ts +3 -3
@@ -1,6 +1,8 @@
|
|
1
1
|
import { BaseDecimal } from '@coinmasters/types';
|
2
2
|
import type { SwapKitNumber } from './swapKitNumber';
|
3
3
|
|
4
|
+
const TAG = " | BigIntArithmetics | ";
|
5
|
+
|
4
6
|
type NumberPrimitivesType = {
|
5
7
|
bigint: bigint;
|
6
8
|
number: number;
|
@@ -15,259 +17,458 @@ type AllowedNumberTypes = 'bigint' | 'number' | 'string';
|
|
15
17
|
const DEFAULT_DECIMAL = 8;
|
16
18
|
|
17
19
|
const bigintPow = (base: bigint, exponent: number): bigint => {
|
18
|
-
let
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
let tag = TAG + " | bigintPow | ";
|
21
|
+
try {
|
22
|
+
let result = BigInt(1);
|
23
|
+
while (exponent > 0) {
|
24
|
+
if (exponent % 2 === 1) {
|
25
|
+
result *= base;
|
26
|
+
}
|
27
|
+
base *= base;
|
28
|
+
exponent = Math.floor(exponent / 2);
|
22
29
|
}
|
23
|
-
|
24
|
-
|
30
|
+
return result;
|
31
|
+
} catch (error) {
|
32
|
+
console.error(tag + 'Error in bigintPow:', error);
|
33
|
+
return BigInt(1);
|
25
34
|
}
|
26
|
-
return result;
|
27
35
|
};
|
28
36
|
|
29
|
-
const toMultiplier = (decimal: number): bigint => {
|
30
|
-
|
37
|
+
export const toMultiplier = (decimal: number): bigint => {
|
38
|
+
let tag = TAG + " | toMultiplier | ";
|
39
|
+
console.log(tag + 'input decimal:', decimal);
|
31
40
|
try {
|
32
|
-
|
33
|
-
|
41
|
+
if (decimal < 0) {
|
42
|
+
throw new Error("Decimal must be non-negative");
|
43
|
+
}
|
44
|
+
let result = BigInt(1);
|
45
|
+
for (let i = 0; i < decimal; i++) {
|
46
|
+
result *= BigInt(10);
|
47
|
+
}
|
48
|
+
console.log(tag + 'result:', result);
|
34
49
|
return result;
|
35
50
|
} catch (error) {
|
36
|
-
console.error('Error in toMultiplier:', error);
|
51
|
+
console.error(tag + 'Error in toMultiplier:', error);
|
37
52
|
return BigInt(10);
|
38
53
|
}
|
39
54
|
};
|
40
55
|
|
41
|
-
const decimalFromMultiplier = (multiplier: bigint): number =>
|
56
|
+
const decimalFromMultiplier = (multiplier: bigint): number => {
|
57
|
+
let tag = TAG + " | decimalFromMultiplier | ";
|
58
|
+
try {
|
59
|
+
return Math.log10(Number(multiplier));
|
60
|
+
} catch (error) {
|
61
|
+
console.error(tag + 'Error in decimalFromMultiplier:', error);
|
62
|
+
return 0;
|
63
|
+
}
|
64
|
+
};
|
42
65
|
|
43
66
|
export function formatBigIntToSafeValue({
|
44
67
|
value,
|
45
|
-
bigIntDecimal
|
46
|
-
decimal
|
68
|
+
bigIntDecimal,
|
69
|
+
decimal,
|
47
70
|
}: {
|
48
71
|
value: bigint;
|
49
|
-
bigIntDecimal?:
|
72
|
+
bigIntDecimal?: bigint;
|
50
73
|
decimal?: number;
|
51
74
|
}): string {
|
52
|
-
const
|
53
|
-
|
75
|
+
const tag = TAG+" | BigIntArithmetics | ";
|
76
|
+
try {
|
77
|
+
console.log(tag,'value:',value,'bigIntDecimal:',bigIntDecimal,'decimal:',decimal);
|
78
|
+
if(!decimal) decimal = DEFAULT_DECIMAL;
|
79
|
+
if(!bigIntDecimal) bigIntDecimal = toMultiplier(decimal);
|
54
80
|
|
55
|
-
|
81
|
+
// Check if the value is negative and throw an error if true
|
82
|
+
if (value < BigInt(0)) {
|
83
|
+
throw new Error(TAG + 'Negative value is not allowed');
|
84
|
+
}
|
56
85
|
|
57
|
-
|
58
|
-
valueString =
|
59
|
-
|
86
|
+
// Convert bigint to string and then to number
|
87
|
+
let valueString = value.toString();
|
88
|
+
console.log(tag,'valueString:',valueString);
|
89
|
+
console.log(tag,'valueString:',valueString.length);
|
60
90
|
|
61
|
-
|
62
|
-
|
91
|
+
console.log(tag,'decimal:',decimal);
|
92
|
+
// Ensure the valueString has enough length for the decimal places
|
93
|
+
if (valueString.length <= decimal) {
|
94
|
+
valueString = '0'.repeat(decimal - valueString.length + 1) + valueString;
|
95
|
+
}
|
63
96
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
}
|
97
|
+
// Determine the integer and decimal parts
|
98
|
+
const integerPart = valueString.slice(0, valueString.length - decimal) || '0';
|
99
|
+
const decimalPart = valueString.slice(valueString.length - decimal).padEnd(decimal, '0');
|
100
|
+
|
101
|
+
// Construct the final formatted value
|
102
|
+
const formattedValue = `${integerPart}.${decimalPart}`;
|
71
103
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
104
|
+
console.log(tag,"formattedValue:", formattedValue);
|
105
|
+
return formattedValue;
|
106
|
+
} catch (error) {
|
107
|
+
console.error(TAG + 'Error in formatBigIntToSafeValue:', error);
|
108
|
+
return '';
|
109
|
+
}
|
76
110
|
}
|
77
111
|
|
78
112
|
export class BigIntArithmetics {
|
79
|
-
private decimalMultiplier:
|
80
|
-
|
113
|
+
private decimalMultiplier: any;
|
114
|
+
//@ts-ignore
|
115
|
+
private bigIntValue: bigint;
|
81
116
|
private decimal?: number;
|
82
117
|
|
83
118
|
static fromBigInt(value: bigint, decimal?: number): BigIntArithmetics {
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
119
|
+
let tag = TAG + " | fromBigInt | ";
|
120
|
+
try {
|
121
|
+
console.log(tag,"Decimal: ", decimal);
|
122
|
+
|
123
|
+
return new BigIntArithmetics({
|
124
|
+
decimal,
|
125
|
+
value: formatBigIntToSafeValue({ value, bigIntDecimal: toMultiplier(decimal || DEFAULT_DECIMAL), decimal }),
|
126
|
+
});
|
127
|
+
} catch (error) {
|
128
|
+
console.error(tag + 'Error in fromBigInt:', error);
|
129
|
+
return new BigIntArithmetics(0);
|
130
|
+
}
|
88
131
|
}
|
89
132
|
|
90
|
-
static shiftDecimals({
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
}): BigIntArithmetics {
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
133
|
+
// static shiftDecimals({
|
134
|
+
// value,
|
135
|
+
// from,
|
136
|
+
// to,
|
137
|
+
// }: {
|
138
|
+
// value: InstanceType<typeof SwapKitNumber>;
|
139
|
+
// from: number;
|
140
|
+
// to: number;
|
141
|
+
// }): BigIntArithmetics {
|
142
|
+
// let tag = TAG + " | shiftDecimals | ";
|
143
|
+
// try {
|
144
|
+
// return this.fromBigInt(
|
145
|
+
// (value.getBaseValue('bigint') * toMultiplier(to)) / toMultiplier(from),
|
146
|
+
// to,
|
147
|
+
// );
|
148
|
+
// } catch (error) {
|
149
|
+
// console.error(tag + 'Error in shiftDecimals:', error);
|
150
|
+
// return new BigIntArithmetics(0);
|
151
|
+
// }
|
152
|
+
// }
|
153
|
+
|
154
|
+
/*
|
155
|
+
AssetValue
|
156
|
+
{
|
157
|
+
decimalMultiplier: 1000000000000000000n,
|
158
|
+
bigIntValue: 62128120000000000n,
|
159
|
+
decimal: 18,
|
160
|
+
isGasAsset: true,
|
161
|
+
isSynthetic: false,
|
162
|
+
type: 'Native',
|
163
|
+
chain: 'BASE',
|
164
|
+
ticker: 'ETH',
|
165
|
+
symbol: 'ETH',
|
166
|
+
address: undefined,
|
167
|
+
tax: undefined,
|
168
|
+
caip: 'eip155:8453/slip44:60'
|
169
|
+
}
|
170
|
+
*/
|
104
171
|
|
105
172
|
constructor(params: SKBigIntParams) {
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
173
|
+
let tag = TAG + " | constructor | ";
|
174
|
+
try {
|
175
|
+
console.log(tag + 'Constructor Params:', params);
|
176
|
+
const value = getStringValue(params);
|
177
|
+
console.log(tag + 'String Value:', value);
|
178
|
+
const isComplex = typeof params === 'object' && params !== null;
|
179
|
+
this.decimal = isComplex ? (params as { decimal?: number }).decimal : undefined;
|
180
|
+
console.log(tag , 'Decimal:', this.decimal);
|
181
|
+
console.log(tag , 'isComplex:', isComplex);
|
182
|
+
if (isComplex) {
|
183
|
+
this.decimalMultiplier = toMultiplier(this.decimal || DEFAULT_DECIMAL);
|
184
|
+
} else {
|
185
|
+
const maxDecimals = Math.max(getFloatDecimals(toSafeValue(value)), this.decimal || 0);
|
186
|
+
this.decimalMultiplier = toMultiplier(maxDecimals);
|
187
|
+
}
|
188
|
+
console.log(tag + 'Decimal Multiplier:', this.decimalMultiplier);
|
189
|
+
|
190
|
+
this.setValue(value);
|
191
|
+
//@ts-ignore
|
192
|
+
console.log(tag + 'BigInt Value:', this.bigIntValue);
|
193
|
+
} catch (error) {
|
194
|
+
console.error(tag + 'Error in constructor:', error);
|
195
|
+
this.decimalMultiplier = BigInt(1);
|
196
|
+
this.bigIntValue = BigInt(0);
|
118
197
|
}
|
119
|
-
console.log('Decimal Multiplier:', this.decimalMultiplier);
|
120
|
-
|
121
|
-
this.setValue(value);
|
122
|
-
console.log('BigInt Value:', this.bigIntValue);
|
123
198
|
}
|
199
|
+
|
200
|
+
// constructor(params: SKBigIntParams) {
|
201
|
+
// let tag = TAG + " | constructor | ";
|
202
|
+
// try {
|
203
|
+
// console.log(tag + 'Constructor Params:', params);
|
204
|
+
// const value = getStringValue(params);
|
205
|
+
// console.log(tag + 'String Value:', value);
|
206
|
+
// const isComplex = typeof params === 'object' && params !== null;
|
207
|
+
// this.decimal = isComplex ? (params as { decimal?: number }).decimal : undefined;
|
208
|
+
// console.log(tag , 'Decimal:', this.decimal);
|
209
|
+
// console.log(tag , 'isComplex:', isComplex);
|
210
|
+
// if (isComplex) {
|
211
|
+
// this.decimalMultiplier = this.decimal;
|
212
|
+
// } else {
|
213
|
+
// const maxDecimals = Math.max(getFloatDecimals(toSafeValue(value)), this.decimal || 0);
|
214
|
+
// this.decimalMultiplier = toMultiplier(maxDecimals);
|
215
|
+
// }
|
216
|
+
// console.log(tag + 'Decimal Multiplier:', this.decimalMultiplier);
|
217
|
+
//
|
218
|
+
// this.setValue(value);
|
219
|
+
// //@ts-ignore
|
220
|
+
// console.log(tag + 'BigInt Value:', this.bigIntValue);
|
221
|
+
// } catch (error) {
|
222
|
+
// console.error(tag + 'Error in constructor:', error);
|
223
|
+
// this.decimalMultiplier = BigInt(1);
|
224
|
+
// this.bigIntValue = BigInt(0);
|
225
|
+
// }
|
226
|
+
// }
|
124
227
|
|
125
228
|
set(value: SKBigIntParams): this {
|
126
|
-
|
127
|
-
|
229
|
+
let tag = TAG + " | set | ";
|
230
|
+
try {
|
231
|
+
// @ts-ignore
|
232
|
+
return new BigIntArithmetics({ decimal: this.decimal, value }) as this;
|
233
|
+
} catch (error) {
|
234
|
+
console.error(tag + 'Error in set:', error);
|
235
|
+
return this;
|
236
|
+
}
|
128
237
|
}
|
129
238
|
|
130
239
|
add(...args: InitialisationValueType[]): this {
|
131
|
-
|
240
|
+
let tag = TAG + " | add | ";
|
241
|
+
try {
|
242
|
+
return this.arithmetics('add', ...args);
|
243
|
+
} catch (error) {
|
244
|
+
console.error(tag + 'Error in add:', error);
|
245
|
+
return this;
|
246
|
+
}
|
132
247
|
}
|
133
248
|
|
134
249
|
sub(...args: InitialisationValueType[]): this {
|
135
|
-
|
250
|
+
let tag = TAG + " | sub | ";
|
251
|
+
try {
|
252
|
+
return this.arithmetics('sub', ...args);
|
253
|
+
} catch (error) {
|
254
|
+
console.error(tag + 'Error in sub:', error);
|
255
|
+
return this;
|
256
|
+
}
|
136
257
|
}
|
137
258
|
|
138
259
|
mul(...args: InitialisationValueType[]): this {
|
139
|
-
|
260
|
+
let tag = TAG + " | mul | ";
|
261
|
+
try {
|
262
|
+
return this.arithmetics('mul', ...args);
|
263
|
+
} catch (error) {
|
264
|
+
console.error(tag + 'Error in mul:', error);
|
265
|
+
return this;
|
266
|
+
}
|
140
267
|
}
|
141
268
|
|
142
269
|
div(...args: InitialisationValueType[]): this {
|
143
|
-
|
270
|
+
let tag = TAG + " | div | ";
|
271
|
+
try {
|
272
|
+
return this.arithmetics('div', ...args);
|
273
|
+
} catch (error) {
|
274
|
+
console.error(tag + 'Error in div:', error);
|
275
|
+
return this;
|
276
|
+
}
|
144
277
|
}
|
145
278
|
|
146
279
|
gt(value: InitialisationValueType): boolean {
|
147
|
-
|
280
|
+
let tag = TAG + " | gt | ";
|
281
|
+
try {
|
282
|
+
return this.comparison('gt', value);
|
283
|
+
} catch (error) {
|
284
|
+
console.error(tag + 'Error in gt:', error);
|
285
|
+
return false;
|
286
|
+
}
|
148
287
|
}
|
149
288
|
|
150
289
|
gte(value: InitialisationValueType): boolean {
|
151
|
-
|
290
|
+
let tag = TAG + " | gte | ";
|
291
|
+
try {
|
292
|
+
return this.comparison('gte', value);
|
293
|
+
} catch (error) {
|
294
|
+
console.error(tag + 'Error in gte:', error);
|
295
|
+
return false;
|
296
|
+
}
|
152
297
|
}
|
153
298
|
|
154
299
|
lt(value: InitialisationValueType): boolean {
|
155
|
-
|
300
|
+
let tag = TAG + " | lt | ";
|
301
|
+
try {
|
302
|
+
return this.comparison('lt', value);
|
303
|
+
} catch (error) {
|
304
|
+
console.error(tag + 'Error in lt:', error);
|
305
|
+
return false;
|
306
|
+
}
|
156
307
|
}
|
157
308
|
|
158
309
|
lte(value: InitialisationValueType): boolean {
|
159
|
-
|
310
|
+
let tag = TAG + " | lte | ";
|
311
|
+
try {
|
312
|
+
return this.comparison('lte', value);
|
313
|
+
} catch (error) {
|
314
|
+
console.error(tag + 'Error in lte:', error);
|
315
|
+
return false;
|
316
|
+
}
|
160
317
|
}
|
161
318
|
|
162
319
|
eqValue(value: InitialisationValueType): boolean {
|
163
|
-
|
320
|
+
let tag = TAG + " | eqValue | ";
|
321
|
+
try {
|
322
|
+
return this.comparison('eqValue', value);
|
323
|
+
} catch (error) {
|
324
|
+
console.error(tag + 'Error in eqValue:', error);
|
325
|
+
return false;
|
326
|
+
}
|
164
327
|
}
|
165
|
-
|
166
|
-
// @ts-ignore
|
328
|
+
//@ts-ignore
|
167
329
|
getValue<T extends AllowedNumberTypes>(type: T): NumberPrimitivesType[T] {
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
330
|
+
let tag = TAG + " | getValue | ";
|
331
|
+
try {
|
332
|
+
console.log(tag,'getValue type:', type);
|
333
|
+
console.log(tag,'decimalMultiplier: ', this.decimalMultiplier);
|
334
|
+
const value = formatBigIntToSafeValue({
|
335
|
+
value: this.bigIntValue,
|
336
|
+
bigIntDecimal: toMultiplier(this.decimal || DEFAULT_DECIMAL),
|
337
|
+
decimal: this.decimal || DEFAULT_DECIMAL,
|
338
|
+
});
|
339
|
+
console.log(tag,'value:', value);
|
340
|
+
switch (type) {
|
341
|
+
case 'number':
|
342
|
+
return Number(value) as NumberPrimitivesType[T];
|
343
|
+
case 'string':
|
344
|
+
return value as NumberPrimitivesType[T];
|
345
|
+
case 'bigint':
|
346
|
+
return ((this.bigIntValue * bigintPow(BigInt(10), this.decimal || 8)) /
|
347
|
+
this.decimalMultiplier) as NumberPrimitivesType[T];
|
348
|
+
}
|
349
|
+
} catch (error) {
|
350
|
+
console.error(tag + 'Error in getValue:', error);
|
351
|
+
return null as any;
|
181
352
|
}
|
182
353
|
}
|
183
354
|
|
184
355
|
// @ts-ignore
|
185
356
|
getBaseValue<T extends AllowedNumberTypes>(type: T): NumberPrimitivesType[T] {
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
357
|
+
let tag = TAG + " | getBaseValue | ";
|
358
|
+
try {
|
359
|
+
const divisor = this.decimalMultiplier / toMultiplier(this.decimal || BaseDecimal.THOR);
|
360
|
+
const baseValue = this.bigIntValue / divisor;
|
361
|
+
|
362
|
+
switch (type) {
|
363
|
+
case 'number':
|
364
|
+
return Number(baseValue) as NumberPrimitivesType[T];
|
365
|
+
case 'string':
|
366
|
+
return baseValue.toString() as NumberPrimitivesType[T];
|
367
|
+
case 'bigint':
|
368
|
+
return baseValue as NumberPrimitivesType[T];
|
369
|
+
}
|
370
|
+
} catch (error) {
|
371
|
+
console.error(tag + 'Error in getBaseValue:', error);
|
372
|
+
return null as any;
|
196
373
|
}
|
197
374
|
}
|
198
375
|
|
199
376
|
getBigIntValue(value: InitialisationValueType, decimal?: number): bigint {
|
200
|
-
|
201
|
-
|
377
|
+
let tag = TAG + " | getBigIntValue | ";
|
378
|
+
try {
|
379
|
+
if (!decimal && typeof value === 'object' && value !== null) {
|
380
|
+
return (value as BigIntArithmetics).bigIntValue;
|
381
|
+
}
|
382
|
+
|
383
|
+
const stringValue = getStringValue(value);
|
384
|
+
const safeValue = toSafeValue(stringValue);
|
385
|
+
|
386
|
+
if (safeValue === '0' || safeValue === 'undefined') return BigInt(0);
|
387
|
+
return this.toBigInt(safeValue, decimal);
|
388
|
+
} catch (error) {
|
389
|
+
console.error(tag + 'Error in getBigIntValue:', error);
|
390
|
+
return BigInt(0);
|
202
391
|
}
|
203
|
-
|
204
|
-
const stringValue = getStringValue(value);
|
205
|
-
const safeValue = toSafeValue(stringValue);
|
206
|
-
|
207
|
-
if (safeValue === '0' || safeValue === 'undefined') return BigInt(0);
|
208
|
-
return this.toBigInt(safeValue, decimal);
|
209
392
|
}
|
210
393
|
|
211
394
|
toSignificant(significantDigits: number = 6): string {
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
395
|
+
let tag = TAG + " | toSignificant | ";
|
396
|
+
try {
|
397
|
+
const [int, dec] = this.getValue('string').split('.');
|
398
|
+
const integer = int || '';
|
399
|
+
const decimal = dec || '';
|
400
|
+
const valueLength = parseInt(integer) ? integer.length + decimal.length : decimal.length;
|
401
|
+
|
402
|
+
if (valueLength <= significantDigits) {
|
403
|
+
return this.getValue('string');
|
404
|
+
}
|
405
|
+
|
406
|
+
if (integer.length >= significantDigits) {
|
407
|
+
return integer.slice(0, significantDigits).padEnd(integer.length, '0');
|
408
|
+
}
|
409
|
+
|
410
|
+
if (parseInt(integer)) {
|
411
|
+
return `${integer}.${decimal.slice(0, significantDigits - integer.length)}`.padEnd(
|
412
|
+
significantDigits - integer.length,
|
413
|
+
'0',
|
414
|
+
);
|
415
|
+
}
|
416
|
+
|
417
|
+
const trimmedDecimal = parseInt(decimal);
|
418
|
+
const slicedDecimal = `${trimmedDecimal}`.slice(0, significantDigits);
|
419
|
+
|
420
|
+
return `0.${slicedDecimal.padStart(
|
421
|
+
decimal.length - `${trimmedDecimal}`.length + slicedDecimal.length,
|
228
422
|
'0',
|
229
|
-
)
|
423
|
+
)}`;
|
424
|
+
} catch (error) {
|
425
|
+
console.error(tag + 'Error in toSignificant:', error);
|
426
|
+
return '';
|
230
427
|
}
|
231
|
-
|
232
|
-
const trimmedDecimal = parseInt(decimal);
|
233
|
-
const slicedDecimal = `${trimmedDecimal}`.slice(0, significantDigits);
|
234
|
-
|
235
|
-
return `0.${slicedDecimal.padStart(
|
236
|
-
decimal.length - `${trimmedDecimal}`.length + slicedDecimal.length,
|
237
|
-
'0',
|
238
|
-
)}`;
|
239
428
|
}
|
240
429
|
|
241
430
|
toFixed(fixedDigits: number = 6): string {
|
242
|
-
|
243
|
-
|
244
|
-
|
431
|
+
let tag = TAG + " | toFixed | ";
|
432
|
+
try {
|
433
|
+
const [int, dec] = this.getValue('string').split('.');
|
434
|
+
const integer = int || '';
|
435
|
+
const decimal = dec || '';
|
245
436
|
|
246
|
-
|
247
|
-
|
248
|
-
|
437
|
+
if (parseInt(integer)) {
|
438
|
+
return `${integer}.${decimal.slice(0, fixedDigits)}`.padEnd(fixedDigits, '0');
|
439
|
+
}
|
249
440
|
|
250
|
-
|
251
|
-
|
441
|
+
const trimmedDecimal = parseInt(decimal);
|
442
|
+
const slicedDecimal = `${trimmedDecimal}`.slice(0, fixedDigits);
|
252
443
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
444
|
+
return `0.${slicedDecimal.padStart(
|
445
|
+
decimal.length - `${trimmedDecimal}`.length + slicedDecimal.length,
|
446
|
+
'0',
|
447
|
+
)}`;
|
448
|
+
} catch (error) {
|
449
|
+
console.error(tag + 'Error in toFixed:', error);
|
450
|
+
return '';
|
451
|
+
}
|
257
452
|
}
|
258
453
|
|
259
454
|
toAbbreviation(digits = 2): string {
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
455
|
+
let tag = TAG + " | toAbbreviation | ";
|
456
|
+
try {
|
457
|
+
const value = this.getValue('number');
|
458
|
+
const abbreviations = ['', 'K', 'M', 'B', 'T', 'Q', 'Qi', 'S'];
|
459
|
+
const tier = Math.floor(Math.log10(Math.abs(value)) / 3);
|
460
|
+
const suffix = abbreviations[tier];
|
461
|
+
|
462
|
+
if (!suffix) return this.getValue('string');
|
463
|
+
|
464
|
+
const scale = 10 ** (tier * 3);
|
465
|
+
const scaled = value / scale;
|
466
|
+
|
467
|
+
return `${scaled.toFixed(digits)}${suffix}`;
|
468
|
+
} catch (error) {
|
469
|
+
console.error(tag + 'Error in toAbbreviation:', error);
|
470
|
+
return '';
|
471
|
+
}
|
271
472
|
}
|
272
473
|
|
273
474
|
toCurrency(
|
@@ -279,107 +480,144 @@ export class BigIntArithmetics {
|
|
279
480
|
thousandSeparator = ',',
|
280
481
|
} = {},
|
281
482
|
): string {
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
483
|
+
let tag = TAG + " | toCurrency | ";
|
484
|
+
try {
|
485
|
+
const value = this.getValue('number');
|
486
|
+
const [int, dec = ''] = value.toFixed(6).split('.');
|
487
|
+
const integer = int.replace(/\B(?=(\d{3})+(?!\d))/g, thousandSeparator);
|
488
|
+
|
489
|
+
const parsedValue =
|
490
|
+
!int && !dec
|
491
|
+
? '0.00'
|
492
|
+
: int === '0'
|
493
|
+
? `${parseFloat(`0.${dec}`)}`.replace('.', decimalSeparator)
|
494
|
+
: `${integer}${parseInt(dec) ? `${decimalSeparator}${dec.slice(0, decimal)}` : ''}`;
|
495
|
+
|
496
|
+
return `${currencyPosition === 'start' ? currency : ''}${parsedValue}${currencyPosition === 'end' ? currency : ''
|
497
|
+
}`;
|
498
|
+
} catch (error) {
|
499
|
+
console.error(tag + 'Error in toCurrency:', error);
|
500
|
+
return '';
|
501
|
+
}
|
296
502
|
}
|
297
503
|
|
298
504
|
private arithmetics(method: 'add' | 'sub' | 'mul' | 'div', ...args: InitialisationValueType[]): this {
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
505
|
+
let tag = TAG + " | arithmetics | ";
|
506
|
+
try {
|
507
|
+
const precisionDecimal = this.retrievePrecisionDecimal(this, ...args);
|
508
|
+
const decimal = Math.max(precisionDecimal, decimalFromMultiplier(this.decimalMultiplier));
|
509
|
+
const precisionDecimalMultiplier = toMultiplier(decimal);
|
510
|
+
|
511
|
+
const result = args.reduce(
|
512
|
+
(acc: bigint, arg) => {
|
513
|
+
const value = this.getBigIntValue(arg, decimal);
|
514
|
+
|
515
|
+
switch (method) {
|
516
|
+
case 'add':
|
517
|
+
return acc + value;
|
518
|
+
case 'sub':
|
519
|
+
return acc - value;
|
520
|
+
case 'mul':
|
521
|
+
return (acc * value) / precisionDecimalMultiplier;
|
522
|
+
case 'div': {
|
523
|
+
if (value === BigInt(0)) throw new RangeError('Division by zero');
|
524
|
+
return (acc * precisionDecimalMultiplier) / value;
|
525
|
+
}
|
526
|
+
default:
|
527
|
+
return acc;
|
317
528
|
}
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
529
|
+
},
|
530
|
+
(this.bigIntValue * precisionDecimalMultiplier) / this.decimalMultiplier,
|
531
|
+
);
|
532
|
+
|
533
|
+
const formattedValue = formatBigIntToSafeValue({
|
534
|
+
bigIntDecimal: toMultiplier(decimal),
|
535
|
+
decimal,
|
536
|
+
value: result,
|
537
|
+
});
|
538
|
+
|
539
|
+
return new BigIntArithmetics({
|
540
|
+
decimalMultiplier: toMultiplier(decimal),
|
541
|
+
decimal: this.decimal,
|
542
|
+
value: formattedValue,
|
543
|
+
}) as this;
|
544
|
+
} catch (error) {
|
545
|
+
console.error(tag + 'Error in arithmetics:', error);
|
546
|
+
return this;
|
547
|
+
}
|
336
548
|
}
|
337
549
|
|
338
550
|
private comparison(method: 'gt' | 'gte' | 'lt' | 'lte' | 'eqValue', ...args: InitialisationValueType[]): boolean {
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
551
|
+
let tag = TAG + " | comparison | ";
|
552
|
+
try {
|
553
|
+
const decimal = this.retrievePrecisionDecimal(this, ...args);
|
554
|
+
const value = this.getBigIntValue(args[0], decimal);
|
555
|
+
const compareToValue = this.getBigIntValue(this, decimal);
|
556
|
+
|
557
|
+
switch (method) {
|
558
|
+
case 'gt':
|
559
|
+
return compareToValue > value;
|
560
|
+
case 'gte':
|
561
|
+
return compareToValue >= value;
|
562
|
+
case 'lt':
|
563
|
+
return compareToValue < value;
|
564
|
+
case 'lte':
|
565
|
+
return compareToValue <= value;
|
566
|
+
case 'eqValue':
|
567
|
+
return compareToValue === value;
|
568
|
+
}
|
569
|
+
} catch (error) {
|
570
|
+
console.error(tag + 'Error in comparison:', error);
|
571
|
+
return false;
|
354
572
|
}
|
355
573
|
}
|
356
574
|
|
357
|
-
private setValue(value:
|
358
|
-
|
359
|
-
|
575
|
+
private setValue(value: any): void {
|
576
|
+
let tag = TAG + " | setValue | ";
|
577
|
+
try {
|
578
|
+
console.log(tag, 'value:', value);
|
579
|
+
console.log(tag, ' this.decimal:', this.decimal);
|
580
|
+
const safeValue = formatBigIntToSafeValue({value:value, decimal: this.decimal})
|
581
|
+
console.log(tag, 'safeValue:', safeValue);
|
582
|
+
this.bigIntValue = this.toBigInt(safeValue);
|
583
|
+
} catch (error) {
|
584
|
+
console.error(tag + 'Error in setValue:', error);
|
585
|
+
}
|
360
586
|
}
|
361
587
|
|
362
588
|
private retrievePrecisionDecimal(...args: InitialisationValueType[]): number {
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
589
|
+
let tag = TAG + " | retrievePrecisionDecimal | ";
|
590
|
+
try {
|
591
|
+
const decimals = args
|
592
|
+
.map((arg) => {
|
593
|
+
const isObject = typeof arg === 'object' && arg !== null;
|
594
|
+
const value = isObject
|
595
|
+
? (arg as any).decimal || decimalFromMultiplier((arg as any).decimalMultiplier)
|
596
|
+
: getFloatDecimals(toSafeValue(arg));
|
597
|
+
|
598
|
+
return value;
|
599
|
+
})
|
600
|
+
.filter(Boolean) as number[];
|
601
|
+
|
602
|
+
return Math.max(...decimals, DEFAULT_DECIMAL);
|
603
|
+
} catch (error) {
|
604
|
+
console.error(tag + 'Error in retrievePrecisionDecimal:', error);
|
605
|
+
return DEFAULT_DECIMAL;
|
606
|
+
}
|
375
607
|
}
|
376
608
|
|
377
609
|
private toBigInt(value: string, decimal?: number): bigint {
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
610
|
+
let tag = TAG + " | toBigInt | ";
|
611
|
+
try {
|
612
|
+
const multiplier = decimal ? toMultiplier(decimal) : this.decimalMultiplier;
|
613
|
+
const padDecimal = decimalFromMultiplier(multiplier);
|
614
|
+
const [integerPart = '', decimalPart = ''] = value.split('.');
|
615
|
+
|
616
|
+
return BigInt(`${integerPart}${decimalPart.padEnd(padDecimal, '0')}`);
|
617
|
+
} catch (error) {
|
618
|
+
console.error(tag + 'Error in toBigInt:', error);
|
619
|
+
return BigInt(0);
|
620
|
+
}
|
383
621
|
}
|
384
622
|
}
|
385
623
|
|
@@ -389,28 +627,46 @@ const numberFormatter = Intl.NumberFormat('fullwide', {
|
|
389
627
|
});
|
390
628
|
|
391
629
|
function toSafeValue(value: InitialisationValueType): string {
|
392
|
-
|
393
|
-
|
394
|
-
|
630
|
+
let tag = TAG + " | toSafeValue | ";
|
631
|
+
try {
|
632
|
+
const parsedValue =
|
633
|
+
typeof value === 'number' ? numberFormatter.format(value) : getStringValue(value);
|
634
|
+
const splitValue = `${parsedValue}`.replace(/,/g, '.').split('.');
|
395
635
|
|
396
|
-
|
397
|
-
|
398
|
-
|
636
|
+
return splitValue.length > 1
|
637
|
+
? `${splitValue.slice(0, -1).join('')}.${splitValue.at(-1)}`
|
638
|
+
: splitValue[0];
|
639
|
+
} catch (error) {
|
640
|
+
console.error(tag + 'Error in toSafeValue:', error);
|
641
|
+
return '0';
|
642
|
+
}
|
399
643
|
}
|
400
644
|
|
401
645
|
function getFloatDecimals(value: string): number {
|
402
|
-
let
|
403
|
-
|
404
|
-
|
405
|
-
|
646
|
+
let tag = TAG + " | getFloatDecimals | ";
|
647
|
+
try {
|
648
|
+
let decimals = 0;
|
649
|
+
const parts = value.split('.');
|
650
|
+
if (parts.length > 1 && parts[1].length > 0) {
|
651
|
+
decimals = parts[1].length;
|
652
|
+
}
|
653
|
+
return Math.max(decimals, DEFAULT_DECIMAL);
|
654
|
+
} catch (error) {
|
655
|
+
console.error(tag + 'Error in getFloatDecimals:', error);
|
656
|
+
return DEFAULT_DECIMAL;
|
406
657
|
}
|
407
|
-
return Math.max(decimals, DEFAULT_DECIMAL);
|
408
658
|
}
|
409
659
|
|
410
660
|
function getStringValue(param: SKBigIntParams): string {
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
661
|
+
let tag = TAG + " | getStringValue | ";
|
662
|
+
try {
|
663
|
+
return typeof param === 'object' && param !== null
|
664
|
+
? 'getValue' in param
|
665
|
+
? (param as SwapKitNumber).getValue('string')
|
666
|
+
: (param as any).value
|
667
|
+
: (param as string);
|
668
|
+
} catch (error) {
|
669
|
+
console.error(tag + 'Error in getStringValue:', error);
|
670
|
+
return '';
|
671
|
+
}
|
416
672
|
}
|