Skip to content
This repository has been archived by the owner on Jul 16, 2024. It is now read-only.

Commit

Permalink
fix: add buildPrice
Browse files Browse the repository at this point in the history
Create buildPrice utility function
  • Loading branch information
lightwalker-eth authored Apr 19, 2024
2 parents 699e711 + c01794e commit dd3f84e
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 6 deletions.
4 changes: 2 additions & 2 deletions src/currency.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,13 @@ describe("parseStringToCurrency() function", () => {

it("should throw an error for invalid currency string", () => {
expect(() => parseStringToCurrency("invalid")).toThrow(
"Input string is not a valid currency"
"Cannot convert: \"invalid\" to a recognized Currency"
);
});

it("should throw an error for empty string", () => {
expect(() => parseStringToCurrency("")).toThrow(
"Input string is not a valid currency"
"Cannot convert: \"\" to a recognized Currency"
);
});
});
2 changes: 1 addition & 1 deletion src/currency.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ export const parseStringToCurrency = (str: string): Currency => {
const curatedStr = str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
const currency = Currency[curatedStr as keyof typeof Currency];

if (!currency) throw new Error("Input string is not a valid currency");
if (!currency) throw new Error(`Cannot convert: "${str}" to a recognized Currency`);

return currency;
};
44 changes: 43 additions & 1 deletion src/price.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,50 @@
import { describe, it, expect } from "vitest";

import { Price, convertCurrencyWithRates, formattedPrice } from "./price";
import { Price, buildPrice, convertCurrencyWithRates, formattedPrice } from "./price";
import { Currency, PriceCurrencyFormat } from "./currency";

describe("buildPrice() function", () => {

it("Build from string values", () => {
const value = "100";
const currency = "USD";

const result = buildPrice(value, currency);

expect(result).toStrictEqual({
value: 100n,
currency: Currency.Usd,
});
});

it("Build from non-string values", () => {
const value = 100n;
const currency = Currency.Usd;

const result = buildPrice(value, currency);

expect(result).toStrictEqual({
value: 100n,
currency: Currency.Usd,
});
});

it("Invalid value", () => {
const value = "abc";
const currency = "USD";

expect(() => buildPrice(value, currency)).toThrow(`Cannot convert string: ${value} to BigInt`);
});

it("Invalid currency", () => {
const value = "100";
const currency = "invalid";

expect(() => buildPrice(value, currency)).toThrow(`Cannot convert: "${currency}" to a recognized Currency`);
});

});

enum CurrencyTestScenario {
"UNDERFLOW",
"MIN",
Expand Down
42 changes: 40 additions & 2 deletions src/price.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import { Currency, PriceCurrencyFormat } from "./currency";
import { approxScaleBigInt } from "./number";
import { Currency, PriceCurrencyFormat, parseStringToCurrency } from "./currency";
import { approxScaleBigInt, stringToBigInt } from "./number";

export interface Price {

// TODO: consider adding a constraint where value is never negative
/**
* The value of the price. This is a BigInt to avoid floating point math issues when working with prices.
* For example, a price of 1.23 USD would be represented as 123n with a currency of USD.
* Note that the value is always in the smallest unit of the currency (e.g. cents for USD, wei for ETH).
* See the CurrencyConfig for the related currency for the number of decimals to use when converting the value to a human-readable format.
*/
value: bigint;

currency: Currency;
}

Expand All @@ -11,6 +20,35 @@ export interface Price {
// { ETH: 1737.16, DAI: 0.99999703, USDC: 1, WETH: 1737.16, USD: 1 }
export interface ExchangeRates extends Partial<Record<Currency, number>> {}

/**
* Builds a Price object.
* @param value the value of the price. This is a BigInt to avoid floating point math issues when working with prices.
* For example, a price of 1.23 USD would be represented as 123n with a currency of USD.
* Note that the value is always in the smallest unit of the currency (e.g. cents for USD, wei for ETH).
* See the CurrencyConfig for the related currency for the number of decimals to use when converting the value to a human-readable format.
* @param currency
* @returns
*/
export const buildPrice = (value: bigint | string, currency: Currency | string): Price => {

let priceValue : bigint;
let priceCurrency : Currency;

if (typeof value === "string") {
priceValue = stringToBigInt(value)
} else {
priceValue = value;
}

if (typeof currency === "string") {
priceCurrency = parseStringToCurrency(currency);
} else {
priceCurrency = currency;
}

return { value: priceValue, currency: priceCurrency };
}

export const priceAsNumber = (price: Price): number => {
return (
Number(price.value) /
Expand Down

0 comments on commit dd3f84e

Please sign in to comment.