import { IntPretty , IntPrettyOptions } from "./int-pretty" ; import { Dec } from "./decimal" ; import { AppCurrency } from "@keplr-wallet/types" ; import { DeepReadonly } from "utility-types" ; import { DecUtils } from "./dec-utils" ; import bigInteger from "big-integer" ; export type CoinPrettyOptions = { separator : string ; upperCase : boolean ; lowerCase : boolean ; hideDenom : boolean ; } ; export class CoinPretty { protected intPretty : IntPretty ; protected _options : CoinPrettyOptions = { separator : " " , upperCase : false , lowerCase : false , hideDenom : false , } ; constructor ( protected _currency , protected amount ) { if ( typeof this . amount === "object" && "toDec" in this . amount ) { this . amount = this . amount . toDec ( ) ; } else if ( ! ( this . amount instanceof Dec ) ) { this . amount = new Dec ( this . amount ) ; } this . intPretty = new IntPretty ( this . amount . quoTruncate ( DecUtils . getTenExponentNInPrecisionRange ( _currency . coinDecimals ) ) ) . maxDecimals ( _currency . coinDecimals ) ; } get options ( ) : DeepReadonly < IntPrettyOptions & CoinPrettyOptions > { return { ... this . _options , ... this . intPretty . options , } ; } get denom ( ) : string { return this . currency . coinDenom ; } get currency ( ) : AppCurrency { return this . _currency ; } setCurrency ( currency ) { const pretty = this . clone ( ) ; pretty . intPretty = this . intPretty . moveDecimalPointRight ( this . _currency . coinDecimals - currency . coinDecimals ) ; pretty . _currency = currency ; return pretty ; } separator ( str ) { const pretty = this . clone ( ) ; pretty . _options . separator = str ; return pretty ; } upperCase ( bool ) { const pretty = this . clone ( ) ; pretty . _options . upperCase = bool ; pretty . _options . lowerCase = ! bool ; return pretty ; } lowerCase ( bool ) { const pretty = this . clone ( ) ; pretty . _options . lowerCase = bool ; pretty . _options . upperCase = ! bool ; return pretty ; } hideDenom ( bool ) { const pretty = this . clone ( ) ; pretty . _options . hideDenom = bool ; return pretty ; } moveDecimalPointLeft ( delta ) { const pretty = this . clone ( ) ; pretty . intPretty = pretty . intPretty . moveDecimalPointLeft ( delta ) ; return pretty ; } moveDecimalPointRight ( delta ) { const pretty = this . clone ( ) ; pretty . intPretty = pretty . intPretty . moveDecimalPointRight ( delta ) ; return pretty ; } deprecated increasePrecision ( delta ) { return this . moveDecimalPointLeft ( delta ) ; } deprecated decreasePrecision ( delta ) { return this . moveDecimalPointRight ( delta ) ; } maxDecimals ( max ) { const pretty = this . clone ( ) ; pretty . intPretty = pretty . intPretty . maxDecimals ( max ) ; return pretty ; } inequalitySymbol ( bool ) { const pretty = this . clone ( ) ; pretty . intPretty = pretty . intPretty . inequalitySymbol ( bool ) ; return pretty ; } inequalitySymbolSeparator ( str ) { const pretty = this . clone ( ) ; pretty . intPretty = pretty . intPretty . inequalitySymbolSeparator ( str ) ; return pretty ; } trim ( bool ) { const pretty = this . clone ( ) ; pretty . intPretty = pretty . intPretty . trim ( bool ) ; return pretty ; } shrink ( bool ) { const pretty = this . clone ( ) ; pretty . intPretty = pretty . intPretty . shrink ( bool ) ; return pretty ; } locale ( locale ) { const pretty = this . clone ( ) ; pretty . intPretty = pretty . intPretty . locale ( locale ) ; return pretty ; } param bool ready ( bool ) { const pretty = this . clone ( ) ; pretty . intPretty = pretty . intPretty . ready ( bool ) ; return pretty ; } get isReady ( ) : boolean { return this . intPretty . isReady ; } add ( target ) { const isCoinPretty = target instanceof CoinPretty ; if ( isCoinPretty ) { if ( "currency" in target && this . currency . coinMinimalDenom !== target . currency . coinMinimalDenom ) { return this . clone ( ) ; } } if ( "toDec" in target ) { target = target . toDec ( ) ; } const pretty = this . clone ( ) ; pretty . intPretty = pretty . intPretty . add ( isCoinPretty ? target : target . mul ( DecUtils . getTenExponentNInPrecisionRange ( - this . _currency . coinDecimals ) ) ) ; return pretty ; } sub ( target ) { const isCoinPretty = target instanceof CoinPretty ; if ( isCoinPretty ) { if ( "currency" in target && this . currency . coinMinimalDenom !== target . currency . coinMinimalDenom ) { return this . clone ( ) ; } } if ( "toDec" in target ) { target = target . toDec ( ) ; } const pretty = this . clone ( ) ; pretty . intPretty = pretty . intPretty . sub ( isCoinPretty ? target : target . mul ( DecUtils . getTenExponentNInPrecisionRange ( - this . _currency . coinDecimals ) ) ) ; return pretty ; } mul ( target ) { const pretty = this . clone ( ) ; pretty . intPretty = pretty . intPretty . mul ( target ) ; return pretty ; } quo ( target ) { const pretty = this . clone ( ) ; pretty . intPretty = pretty . intPretty . quo ( target ) ; return pretty ; } toDec ( ) { return this . intPretty . toDec ( ) ; } toCoin ( ) { const amount = this . toDec ( ) . mulTruncate ( DecUtils . getTenExponentNInPrecisionRange ( this . currency . coinDecimals ) ) . truncate ( ) ; return { denom : this . currency . coinMinimalDenom , amount : amount . toString ( ) , } ; } toString ( ) { let denom = this . denom ; if ( this . _options . upperCase ) { denom = denom . toUpperCase ( ) ; } if ( this . _options . lowerCase ) { denom = denom . toLowerCase ( ) ; } let separator = this . _options . separator ; if ( this . _options . hideDenom ) { denom = "" ; separator = "" ; } return this . intPretty . toStringWithSymbols ( "" , `${ separator }${ denom }` ) ; } clone ( ) { const pretty = new CoinPretty ( this . _currency , this . amount ) ; pretty . _options = { ... this . _options , } ; pretty . intPretty = this . intPretty . clone ( ) ; return pretty ; } }