2edf99c323
* chore: deps and react-script update * ci: bump node version to 18 * ci: depscheck * docs: mention minimal npm required version * chore: feedback Co-authored-by: Vojtech Simetka <vojtech@simetka.cz> Co-authored-by: Vojtech Simetka <vojtech@simetka.cz>
91 lines
2.5 KiB
TypeScript
91 lines
2.5 KiB
TypeScript
import { BigNumber } from 'bignumber.js'
|
|
import { isInteger, makeBigNumber } from '../utils'
|
|
|
|
const POSSIBLE_DECIMALS = [18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
|
|
type digits = typeof POSSIBLE_DECIMALS[number]
|
|
|
|
const BZZ_DECIMALS = 16
|
|
|
|
export class Token {
|
|
private amount: BigNumber // Represented in the base units, so it is always an integer value
|
|
private readonly decimals: digits
|
|
|
|
constructor(amount: BigNumber | string | bigint, decimals: digits = BZZ_DECIMALS) {
|
|
const a = makeBigNumber(amount)
|
|
|
|
if (!isInteger(a) || !POSSIBLE_DECIMALS.includes(decimals)) {
|
|
throw new TypeError(`Not a valid token values: ${amount} ${decimals}`)
|
|
}
|
|
|
|
this.amount = a
|
|
this.decimals = decimals
|
|
}
|
|
|
|
/**
|
|
* Construct new Token from a digit representation
|
|
*
|
|
* @param amount Amount of a token in the digits (1 token = 10^decimals)
|
|
* @param decimals Number of decimals for the token (must be integer)
|
|
*
|
|
* @throws {TypeError} If the decimals is not an integer or the amount after conversion is not an integer
|
|
*
|
|
* @returns new Token
|
|
*/
|
|
static fromDecimal(amount: BigNumber | string | bigint, decimals: digits = BZZ_DECIMALS): Token | never {
|
|
const a = makeBigNumber(amount)
|
|
|
|
// No need to do any validation here, it is done when the new token is created
|
|
const t = a.multipliedBy(new BigNumber(10).pow(decimals))
|
|
|
|
return new Token(t, decimals)
|
|
}
|
|
|
|
get toBigInt(): bigint {
|
|
return BigInt(this.amount.toFixed(0))
|
|
}
|
|
|
|
get toString(): string {
|
|
return this.amount.toFixed(0)
|
|
}
|
|
|
|
get toBigNumber(): BigNumber {
|
|
return new BigNumber(this.amount)
|
|
}
|
|
|
|
get toDecimal(): BigNumber {
|
|
return this.amount.dividedBy(new BigNumber(10).pow(this.decimals))
|
|
}
|
|
|
|
toFixedDecimal(digits = 7): string {
|
|
return this.toDecimal.toFixed(digits)
|
|
}
|
|
|
|
toSignificantDigits(digits = 4): string {
|
|
const asString = this.toDecimal.toFixed(this.decimals)
|
|
|
|
let indexOfSignificantDigit = -1
|
|
let reachedDecimalPoint = false
|
|
|
|
for (let i = 0; i < asString.length; i++) {
|
|
const char = asString[i]
|
|
|
|
if (char === '.') {
|
|
reachedDecimalPoint = true
|
|
indexOfSignificantDigit = i + 1
|
|
} else if (reachedDecimalPoint && char !== '0') {
|
|
indexOfSignificantDigit = i
|
|
break
|
|
}
|
|
}
|
|
|
|
return asString.slice(0, indexOfSignificantDigit + digits)
|
|
}
|
|
|
|
minusBaseUnits(amount: string): Token {
|
|
return new Token(
|
|
this.toBigNumber.minus(new BigNumber(amount).multipliedBy(new BigNumber(10).pow(this.decimals))),
|
|
this.decimals,
|
|
)
|
|
}
|
|
}
|