Skip to content

Commit

Permalink
feat: Extend formatAmount to support bigint and string values. Add mo…
Browse files Browse the repository at this point in the history
…re format amount unit tests.
  • Loading branch information
msarcev committed Mar 6, 2024
1 parent 8655797 commit cb4bbd2
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const buildShimmerClaimedStats = (claimed: string, supply: string, tokenI

const formatFull = bigInt < Math.pow(10, tokenInfo.decimals - 3);
const decimals = bigInt < Math.pow(10, tokenInfo.decimals) ? 3 : bigInt < Math.pow(10, tokenInfo.decimals + 2) ? 2 : 0;
claimedFinal = formatAmount(Number(claimedFinal), tokenInfo, formatFull, decimals);
claimedFinal = formatAmount(claimedFinal, tokenInfo, formatFull, decimals);
claimedFinal = claimedFinal.replaceAll(COMMAS_REGEX, ",");

const claimedPercentBd = new BigDecimal("100", 2).multiply(claimedBd.toString()).divide(supply);
Expand Down
28 changes: 28 additions & 0 deletions client/src/helpers/stardust/valueFormatHelper.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,31 @@ test("formatAmount should honour precision 0", () => {
test("formatAmount should format big values properly", () => {
expect(formatAmount(1450896407249092, tokenInfo)).toBe("1450896407.24 IOTA");
});

test("formatAmount should format bigint values properly", () => {
expect(formatAmount(BigInt(1450896407249092), tokenInfo)).toBe("1450896407.24 IOTA");
});

test("formatAmount should format bigint subunit values properly", () => {
expect(formatAmount(BigInt(123), tokenInfo)).toBe("0.000123 IOTA");
});

test("formatAmount should format string values properly", () => {
expect(formatAmount("1450896407249092", tokenInfo)).toBe("1450896407.24 IOTA");
});

test("formatAmount should format string subunit values properly", () => {
expect(formatAmount("1", tokenInfo)).toBe("0.000001 IOTA");
});

test("formatAmount should honour format full (number)", () => {
expect(formatAmount(1, tokenInfo, true)).toBe("1 micro");
});

test("formatAmount should honour format full (bigint)", () => {
expect(formatAmount(1n, tokenInfo, true)).toBe("1 micro");
});

test("formatAmount should honour format full (string)", () => {
expect(formatAmount("1", tokenInfo, true)).toBe("1 micro");
});
18 changes: 11 additions & 7 deletions client/src/helpers/stardust/valueFormatHelper.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { UnitsHelper } from "@iota/iota.js";
import { INodeInfoBaseToken } from "@iota/sdk-wasm/web";
import React from "react";
import Tooltip from "~app/components/Tooltip";
import BigDecimal from "../bigDecimal";

/**
* The id of the Genesis block.
Expand All @@ -17,7 +17,7 @@ const GENESIS_BLOCK_ID = "0x0000000000000000000000000000000000000000000000000000
* @returns The formatted string.
*/
export function formatAmount(
value: number,
value: number | bigint | string,
tokenInfo: INodeInfoBaseToken,
formatFull: boolean = false,
decimalPlaces: number = 2,
Expand All @@ -27,12 +27,16 @@ export function formatAmount(
return `${value} ${tokenInfo.subunit ?? tokenInfo.unit}`;
}

const baseTokenValue = value / Math.pow(10, tokenInfo.decimals);
const formattedAmount = toFixedNoRound(baseTokenValue, decimalPlaces, trailingDecimals);
const valueBigDecimal =
typeof value === "string"
? new BigDecimal(value, tokenInfo.decimals, false)
: new BigDecimal(value.toString(), tokenInfo.decimals, false);

const baseTokenValue = valueBigDecimal.divide(Math.pow(10, tokenInfo.decimals).toString());
const formattedAmount = toFixedNoRound(baseTokenValue.toString(), decimalPlaces, trailingDecimals);

// useMetricPrefix is broken cause it passes a float value to formatBest
const amount = tokenInfo.useMetricPrefix ? UnitsHelper.formatBest(baseTokenValue) : `${formattedAmount} `;
return `${amount}${tokenInfo.unit}`;
return `${formattedAmount} ${tokenInfo.unit}`;
}

/**
Expand All @@ -50,7 +54,7 @@ export function formatNumberWithCommas(value: bigint): string {
* @param precision The decimal places to show.
* @returns The formatted amount.
*/
function toFixedNoRound(value: number, precision: number = 2, trailingDecimals?: boolean): string {
function toFixedNoRound(value: number | string, precision: number = 2, trailingDecimals?: boolean): string {
const defaultDecimals = "0".repeat(precision);
const valueString = `${value}`;
const [integer, fraction = defaultDecimals] = valueString.split(".");
Expand Down

0 comments on commit cb4bbd2

Please sign in to comment.