@syncswap/sdk
Version:
SyncSwap TypeScript SDK for building DeFi applications
312 lines • 11.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Numbers = void 0;
const ethers_1 = require("ethers");
const constants_1 = require("./constants");
// import { getTokenDisplayDecimals } from '../../components/SwapBox/SwapInput/TokenBox/swapInputInfo';
const NUMBER_SPLIT_REGEX = /\B(?=(\d{3})+(?!\d))/g;
const STRING_DOT = '.';
const STRING_COMMA = ',';
//const STRING_SPACE = ' ';
class Numbers {
static numberWithCommas(s) {
const len = s.length;
if (len <= 3) {
return s;
}
const dotIndex = s.indexOf(STRING_DOT);
if (dotIndex === -1) {
return s.replace(NUMBER_SPLIT_REGEX, STRING_COMMA);
}
else {
const integer = s.slice(0, dotIndex);
const decimal = s.slice(dotIndex);
return integer.replace(NUMBER_SPLIT_REGEX, STRING_COMMA) + decimal;
}
}
/*
public static numberWithSpaces(s: string) {
const parts = s.split(STRING_DOT);
parts[0] = parts[0].replace(NUMBER_SPLIT_REGEX, STRING_SPACE);
return parts.join(STRING_DOT);
}
*/
// NO trimTailingZeros, NO ICS
static formatInput(value, decimals, fractions) {
const maxDecimals = 18;
const formatted = ethers_1.ethers.utils.formatUnits(value, decimals);
const fixed = this.fixPoints(formatted, fractions, maxDecimals);
return fixed;
}
// NO ICS
static formatPrice(value, decimals, fractions) {
const maxDecimals = 18;
const formatted = ethers_1.ethers.utils.formatUnits(value, decimals);
const fixed = this.fixPoints(formatted, fractions, maxDecimals);
return this.trimTailingZeros(fixed);
}
static formatPercent(numerator, denominator, fractions, capped = true, space = false, maxDecimals = 4) {
if (numerator.isZero()) {
return space ? '0 %' : '0%';
}
if (denominator.isZero()) {
return space ? '100 %' : '100%';
}
const percentValue = numerator.mul(constants_1.ETHER).div(denominator);
if (capped && percentValue.gte(constants_1.ETHER)) {
return space ? '100 %' : '100%';
}
else {
const text = Numbers.format(percentValue, 16, fractions, {
disableICS: true,
maxDecimals: maxDecimals,
});
return space ? `${text} %` : `${text}%`;
}
}
static formatPercentBy(percentValue, fractions, capped = true, maxDecimals = 4) {
if (percentValue.isZero()) {
return '0%';
}
if (capped && percentValue.gte(constants_1.ETHER)) {
return '100%';
}
else {
return `${Numbers.format(percentValue, 16, fractions, {
disableICS: true,
maxDecimals: maxDecimals,
})}%`;
}
}
static formatWithCommas(value, decimals, fractions, options) {
return this.numberWithCommas(this.format(value, decimals, fractions, options));
}
// public static formatWithToken(
// value: BigNumber,
// token: Token,
// commas = true,
//
// options?: {
// allowTailingZero?: boolean,
// disableICS?: boolean,
// disableOverflow?: boolean,
// maxDecimals?: number,
// //compensateDecimals?: number,
// minimumICSValue?: BigNumber,
// }
// ): string {
// const formatted: string = this.format(value, token.decimals, getTokenDisplayDecimals(token), options);
// if (commas) {
// return this.numberWithCommas(formatted);
// } else {
// return formatted;
// }
// }
static format(value, decimals, fractions, options) {
if (!value || value.isZero()) {
return '0';
}
const maxDecimals = options?.maxDecimals ?? 18;
if (!options || (!options.disableICS)) {
const BIG_VALUE = this.pow(decimals).mul(options && options.minimumICSValue ? options.minimumICSValue : constants_1.DECIMALS_9); // 1b
//console.log('format value', value.toString(), 'ICS', value.gte(BIG_VALUE), 'BIG_VALUE', BIG_VALUE.toString(), 'decimals', decimals, 'this.power(decimals)', this.power(decimals).toString());
if (value.gte(BIG_VALUE)) {
return this.formatICS(value, decimals, fractions, maxDecimals, options?.disableOverflow ? {
disableOverflow: options.disableOverflow
} : undefined);
}
}
const formatted = ethers_1.ethers.utils.formatUnits(value, decimals);
const fixed = this.fixPoints(formatted, fractions, maxDecimals);
if (options?.allowTailingZero) {
return fixed;
}
else {
return this.trimTailingZeros(fixed);
}
}
static trimTailingZeros(s) {
const i = s.indexOf('.');
if (i === -1) {
return s;
}
let trim = s;
// Removes all zeros after the dot.
while (trim.endsWith('0')) {
trim = trim.substring(0, trim.length - 1);
}
// Removes the dot at the end if it has.
if (trim.endsWith('.')) {
trim = trim.substring(0, trim.length - 1);
}
return trim;
}
static fixPoints(formatted, fixPoints, maxDecimals) {
//console.log('fixPoints', formatted);
const dotIndex = formatted.indexOf('.');
if (dotIndex === -1) {
return formatted;
}
if (formatted === '0.0' || formatted.replaceAll('.', '').replaceAll('0', '') === '') {
return formatted; // 0.0
}
const fractionStartIndex = dotIndex + 1;
for (let i = 0; i <= 18; i++) {
// length of current testing fraction
const curFractionLen = fixPoints + i;
// index of end position of current fraction
const curEndAt = fractionStartIndex + curFractionLen;
const slice = formatted.slice(0, curEndAt);
// whether current fraction has a number
if (slice.replaceAll('.', '').replaceAll('0', '') !== '') {
// deciamls of current slice
const decimals = slice.length - dotIndex;
// if decimals exceeds max
if (decimals > maxDecimals) {
const sliceOfMaxDecimals = slice.substring(0, dotIndex + maxDecimals);
// limit decimals if possible
if (sliceOfMaxDecimals.replaceAll('.', '').replaceAll('0', '') !== '') {
// compensate one if reach
//if (compensateDecimals !== -1 && decimals > compensateDecimals) {
// return slice.substring(0, dotIndex + maxDecimals + 1);
//}
return sliceOfMaxDecimals;
}
}
return slice;
}
if (curFractionLen >= maxDecimals) {
return '<' + formatted.slice(0, curEndAt - 1) + '1';
}
}
return '0';
}
static formatICS(value, valueDecimals, fixPoints, maxDecimals = 4, options) {
const oneToken = Numbers.pow(valueDecimals);
const b = constants_1.DECIMALS_9;
const m = constants_1.DECIMALS_6;
const k = constants_1.DECIMALS_3;
//console.log('formatICS', value.toString(), valueDecimals);
if ((!options || !options.disableOverflow) && value.gte(constants_1.NINE_MILLION_BILLION.mul(Numbers.pow(valueDecimals)).mul(oneToken))) {
return '>9,000,000B';
}
let s;
if (value.gte(b.mul(oneToken))) {
s = ethers_1.ethers.utils.formatUnits(value.div(b), valueDecimals);
return this.fixPoints(s, fixPoints, maxDecimals) + 'B';
}
else if (value.gte(m.mul(oneToken))) {
s = ethers_1.ethers.utils.formatUnits(value.div(m), valueDecimals);
return this.fixPoints(s, fixPoints, maxDecimals) + 'M';
}
else if (value.gte(k.mul(oneToken))) {
s = ethers_1.ethers.utils.formatUnits(value.div(k), valueDecimals);
return this.fixPoints(s, fixPoints, maxDecimals) + 'K';
}
else {
s = ethers_1.ethers.utils.formatUnits(value, valueDecimals);
return this.fixPoints(s, fixPoints, maxDecimals);
}
}
/**
* Reduce decimals from given number
* @param num number
* @param decimals decimals of number
* @returns number after decimals reduced
*/
static reduceDecimals(num, decimals) {
return (decimals === 0 || num.isZero()) ? constants_1.ZERO : num.div(Numbers.pow(decimals));
}
/**
* Compare two numbers with their decimals deduced
* @param a number A
* @param decimalsA decimals of number A
* @param b number B
* @param decimalsB decimals of number B
* @returns whether number A is greater than number B
*/
static compareWithDecimals(a, decimalsA, b, decimalsB) {
const wadA = this.reduceDecimals(a, decimalsA);
const wadB = this.reduceDecimals(b, decimalsB);
return wadA.gt(wadB);
}
static pow(pow) {
if (pow === 18) {
return constants_1.ETHER;
}
else if (pow === 6) {
return constants_1.DECIMALS_6;
}
else if (pow === 8) {
return constants_1.DECIMALS_8;
}
else if (pow === 18) {
return constants_1.DECIMALS_18;
}
else if (pow === 17) {
return constants_1.DECIMALS_17;
}
else if (pow === 16) {
return constants_1.DECIMALS_16;
}
else if (pow === 15) {
return constants_1.DECIMALS_15;
//} else if (pow === 3) {
// return DECIMALS_3;
}
else if (pow === 9) {
return constants_1.DECIMALS_9;
}
else if (pow === 10) {
return constants_1.DECIMALS_10;
}
else if (pow === 24) {
return constants_1.DECIMALS_24;
}
else if (pow === 20) {
return constants_1.DECIMALS_20;
}
else if (pow === 36) {
return constants_1.DECIMALS_36;
}
else {
//console.log('Numbers: power uncached', pow);
return constants_1.TEN.pow(pow);
}
}
static convertAmount(amount, fromDecimals, toDecimals) {
if (fromDecimals === toDecimals) {
return amount;
}
else {
return amount.mul(this.pow(toDecimals)).div(this.pow(fromDecimals));
}
}
static asPercentDisplay(sample, sampleDecimals, total, totalDecimals) {
if (sample.isZero() || total.isZero()) {
return '0.0';
}
const sampleAdjusted = this.convertAmount(sample, sampleDecimals, totalDecimals);
const percent = sampleAdjusted.mul(constants_1.ETHER) // precision
.div(total);
const percentAdjusted = percent.lt(constants_1.DECIMALS_15) ? '<0.01' : Numbers.format(percent, 18 - 2, 2);
return percentAdjusted;
}
static asPercentFloat(numerator, denominator, capped = true) {
if (numerator.isZero()) {
return 0.0;
}
if (denominator.isZero()) {
return 1.0;
}
const percentValue = numerator.mul(constants_1.ETHER).div(denominator);
if (capped && percentValue.gte(constants_1.ETHER)) {
return 1.0;
}
else {
return Number(percentValue.div(constants_1.DECIMALS_12)) / 1000000;
}
}
}
exports.Numbers = Numbers;
//# sourceMappingURL=numbers.js.map