dydx-v4-web/src/lib/numbers.ts
Jared Vu f7d052f52e
Abacus Transactions Protocol (#38)
* Merge main

* MarketLinks: add key to map

* Merge stashed changes

* fix callback usage to fulfill success/error cbs

* Add Abacus analytics class

* Bump Abacus 0.4.27, Update cancelOrder to use Abacus

* Cancel order loading states

* Use latestOrderChanged to determine whether an order has been committed

* nits

* restore uncommittedOrderClientIds

* bump abacus@0.5.0

* fix for handling null testMarket
2023-09-21 09:19:01 -07:00

83 lines
2.6 KiB
TypeScript

import { BigNumber } from 'bignumber.js';
export type BigNumberish = BigNumber | string | number;
export type LocaleSeparators = { group?: string; decimal?: string };
export const BIG_NUMBERS = {
ZERO: new BigNumber(0),
ONE: new BigNumber(1),
};
export const MustBigNumber = (amount?: BigNumberish | null) => new BigNumber(amount || 0);
/**
* @description Rounds the input to the nearest multiple of `factor`, which must be non-zero.
*/
export const roundToNearestFactor = ({
number,
factor,
roundingMode = BigNumber.ROUND_UP,
}: {
number: BigNumberish;
factor: number;
roundingMode: BigNumber.RoundingMode;
}): BigNumber => {
if (factor === 0) throw Error('Invalid dividend');
return MustBigNumber(number).div(factor).decimalPlaces(0, roundingMode).times(factor);
};
export const getFractionDigits = (unit?: BigNumber | number | string | null) =>
// n?.toString().match(/[.](\d*)/)?.[1].length ?? 0
unit ? Math.max(Math.ceil(-Math.log10(Math.abs(+unit))), 0) : 0;
/**
* @description Rounds the input to the nearest multiple of `tick`, which must be non-zero.
*/
export const roundToTick = ({ num, tick }: { num: number; tick: number }): number => {
if (tick === 0) {
throw Error('Invalid dividend');
}
const absTick: number = Math.abs(tick);
return Math.round(num / absTick) * absTick;
};
export const isNumber = (value: any): value is number =>
typeof value === 'number' && !Number.isNaN(value);
/**
* @description Returns null if input is 0 or null, '99+' if input is greater than 99, otherwise original input number
*/
export const shortenNumberForDisplay = (num?: number) =>
MustBigNumber(num).eq(0) ? null : MustBigNumber(num).gt(99) ? '99+' : num;
/**
* @param locale - locale to use for formatting (optional)
* @param separatorType - type of separator to get (group or decimal)
* @returns separator for the given locale and separator type
*/
export const getSeparator = ({
browserLanguage = navigator.language || 'en-US',
separatorType,
}: {
browserLanguage?: string;
separatorType: Intl.NumberFormatPartTypes;
}) =>
Intl.NumberFormat(browserLanguage)
.formatToParts(1000.1)
.find?.((part) => part.type === separatorType)?.value;
/**
* Converts a byte array (representing an arbitrary-size signed integer) into a bigint.
* @param u Array of bytes represented as a Uint8Array.
*/
export function bytesToBigInt(u: Uint8Array): bigint {
if (u.length <= 1) {
return BigInt(0);
}
const negated: boolean = (u[0] & 1) === 1;
const hex: string = Buffer.from(u.slice(1)).toString('hex');
const abs: bigint = BigInt(`0x${hex}`);
return negated ? -abs : abs;
}