@leather.io/utils 0.15.0 → 0.16.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
 
2
- > @leather.io/utils@0.15.0 build /home/runner/work/mono/mono/packages/utils
2
+ > @leather.io/utils@0.16.1 build /home/runner/work/mono/mono/packages/utils
3
3
  > tsup
4
4
 
5
5
  CLI Building entry: src/index.ts
@@ -8,9 +8,9 @@ CLI tsup v8.1.0
8
8
  CLI Using tsup config: /home/runner/work/mono/mono/packages/utils/tsup.config.ts
9
9
  CLI Target: es2022
10
10
  ESM Build start
11
- ESM dist/index.js 14.37 KB
12
- ESM dist/index.js.map 27.63 KB
13
- ESM ⚡️ Build success in 20ms
11
+ ESM dist/index.js 15.70 KB
12
+ ESM dist/index.js.map 30.37 KB
13
+ ESM ⚡️ Build success in 21ms
14
14
  DTS Build start
15
- DTS ⚡️ Build success in 1477ms
16
- DTS dist/index.d.ts 7.11 KB
15
+ DTS ⚡️ Build success in 1829ms
16
+ DTS dist/index.d.ts 7.56 KB
package/CHANGELOG.md CHANGED
@@ -85,6 +85,36 @@
85
85
  * dependencies
86
86
  * @leather.io/constants bumped to 0.9.2
87
87
 
88
+ ### Dependencies
89
+
90
+ * The following workspace dependencies were updated
91
+ * dependencies
92
+ * @leather.io/constants bumped to 0.12.0
93
+ * @leather.io/models bumped to 0.16.0
94
+ * @leather.io/rpc bumped to 2.1.9
95
+
96
+ ## [0.16.0](https://github.com/leather-io/mono/compare/@leather.io/utils-v0.15.0...@leather.io/utils-v0.16.0) (2024-09-20)
97
+
98
+
99
+ ### Features
100
+
101
+ * add tokens widget, ref leather-io/issues[#221](https://github.com/leather-io/mono/issues/221) ([69e4377](https://github.com/leather-io/mono/commit/69e43770969d549f296c98d24ba3dc58b12b938d))
102
+ * **bitcoin:** signer logic ([811c15c](https://github.com/leather-io/mono/commit/811c15cd6d4105b07dd89595f136703fd3defd4d))
103
+
104
+
105
+ ### Bug Fixes
106
+
107
+ * update btc-signer ([714fff0](https://github.com/leather-io/mono/commit/714fff083a581726feceab291d442997aabc9859))
108
+
109
+
110
+ ### Dependencies
111
+
112
+ * The following workspace dependencies were updated
113
+ * dependencies
114
+ * @leather.io/constants bumped to 0.11.0
115
+ * @leather.io/models bumped to 0.15.0
116
+ * @leather.io/rpc bumped to 2.1.8
117
+
88
118
  ## [0.15.0](https://github.com/leather-io/mono/compare/@leather.io/utils-v0.14.0...@leather.io/utils-v0.15.0) (2024-09-17)
89
119
 
90
120
 
package/dist/index.d.ts CHANGED
@@ -72,6 +72,18 @@ declare function extractPhraseFromString(value: string): string;
72
72
 
73
73
  declare function pxStringToNumber(pxString: string): number;
74
74
 
75
+ /**
76
+ * TODO: investigate improving
77
+ * @param amount is a string
78
+ * in the extension we pre-convert it from Money with formatMoneyWithoutSymbol
79
+ */
80
+ declare function formatBalance(amount: string): {
81
+ isAbbreviated: boolean;
82
+ value: string;
83
+ };
84
+
85
+ declare function abbreviateNumber(n: number): string;
86
+
75
87
  declare function isNumber(value: unknown): value is number;
76
88
  declare function isString(value: unknown): value is string;
77
89
  declare function isEmptyString(value: unknown): value is '';
@@ -109,11 +121,13 @@ declare function propIfDefined(prop: string, value: any): {
109
121
  };
110
122
  declare function isHexString(value: string): boolean;
111
123
  declare function toHexString(value: number): string;
124
+ declare function hexToNumber(hex: string): number;
112
125
  type MapFunction<T, U> = (value: T[keyof T], key: string) => U;
113
126
  declare function mapObject<T extends object, U>(obj: T, mapFn: MapFunction<T, U>): {
114
127
  [K in keyof T]: U;
115
128
  };
116
129
  declare function assertIsTruthy<T>(val: T): asserts val is NonNullable<T>;
117
130
  declare function capitalize(val: string): string;
131
+ declare function uniqueArray<T>(arr: T[]): T[];
118
132
 
119
- export { assertIsTruthy, baseCurrencyAmountInQuote, btcToSat, calculateMeanAverage, capitalize, convertAmountToBaseUnit, convertAmountToFractionalUnit, convertToMoneyTypeWithDefaultOfZero, countDecimals, createCounter, createMoney, createMoneyFromDecimal, createNullArrayOfLength, createNumArrayOfRange, defaultWalletKeyId, delay, ensureArray, extractPhraseFromString, fibonacciGenerator, fiveMinInMs, formatContractId, formatDustUsdAmounts, formatMoney, formatMoneyPadded, formatMoneyWithoutSymbol, getPrincipalFromContractId, getTicker, i18nFormatCurrency, increaseValueByOneMicroStx, initBigNumber, isBigInt, isBoolean, isDefined, isEmpty, isEmptyArray, isEmptyString, isError, isEven, isFulfilled, isFunction, isHexString, isMoney, isMoneyGreaterThanZero, isNumber, isObject, isRejected, isString, isTypedArray, isUndefined, makeNumberRange, mapObject, microStxToStx, migratePositiveAssetBalancesToTop, moneyToBaseUnit, noop, oneDayInMs, oneMonthInMs, oneWeekInMs, propIfDefined, pxStringToNumber, reverseBytes, safelyFormatHexTxid, satToBtc, sortAssetsByName, spamFilter, stxToMicroStx, subtractMoney, sumMoney, sumNumbers, toHexString, truncateMiddle, undefinedIfLengthZero, unitToFractionalUnit, whenNetwork };
133
+ export { abbreviateNumber, assertIsTruthy, baseCurrencyAmountInQuote, btcToSat, calculateMeanAverage, capitalize, convertAmountToBaseUnit, convertAmountToFractionalUnit, convertToMoneyTypeWithDefaultOfZero, countDecimals, createCounter, createMoney, createMoneyFromDecimal, createNullArrayOfLength, createNumArrayOfRange, defaultWalletKeyId, delay, ensureArray, extractPhraseFromString, fibonacciGenerator, fiveMinInMs, formatBalance, formatContractId, formatDustUsdAmounts, formatMoney, formatMoneyPadded, formatMoneyWithoutSymbol, getPrincipalFromContractId, getTicker, hexToNumber, i18nFormatCurrency, increaseValueByOneMicroStx, initBigNumber, isBigInt, isBoolean, isDefined, isEmpty, isEmptyArray, isEmptyString, isError, isEven, isFulfilled, isFunction, isHexString, isMoney, isMoneyGreaterThanZero, isNumber, isObject, isRejected, isString, isTypedArray, isUndefined, makeNumberRange, mapObject, microStxToStx, migratePositiveAssetBalancesToTop, moneyToBaseUnit, noop, oneDayInMs, oneMonthInMs, oneWeekInMs, propIfDefined, pxStringToNumber, reverseBytes, safelyFormatHexTxid, satToBtc, sortAssetsByName, spamFilter, stxToMicroStx, subtractMoney, sumMoney, sumNumbers, toHexString, truncateMiddle, undefinedIfLengthZero, uniqueArray, unitToFractionalUnit, whenNetwork };
package/dist/index.js CHANGED
@@ -286,6 +286,37 @@ function pxStringToNumber(pxString) {
286
286
  return +pxString.replace("px", "");
287
287
  }
288
288
 
289
+ // src/abbreviate-number/abbreviate-number.ts
290
+ function abbreviateNumber(n) {
291
+ if (n < 1e3) return n.toString();
292
+ if (n >= 1e3 && n < 1e6) return +(n / 1e3).toFixed(2) + "K";
293
+ if (n >= 1e6 && n < 1e9) return +(n / 1e6).toFixed(2) + "M";
294
+ if (n >= 1e9 && n < 1e12) return +(n / 1e9).toFixed(2) + "B";
295
+ if (n >= 1e12) return +(n / 1e12).toFixed(2) + "T";
296
+ return n.toString();
297
+ }
298
+
299
+ // src/money/format-balance/remove-commas.ts
300
+ function removeCommas(amountWithCommas) {
301
+ if (typeof amountWithCommas !== "string") {
302
+ throw new Error("Amount with commas must be a string");
303
+ }
304
+ return amountWithCommas.replace(/,/g, "");
305
+ }
306
+
307
+ // src/money/format-balance/format-balance.ts
308
+ function formatBalance(amount) {
309
+ if (typeof amount !== "string" || amount.trim() === "" || isNaN(Number(removeCommas(amount)))) {
310
+ throw new Error("Invalid input: amount must be a non-empty string representing a valid number");
311
+ }
312
+ const noCommas = removeCommas(amount);
313
+ const number = noCommas.includes(".") ? parseFloat(noCommas) : parseInt(noCommas);
314
+ return number > 1e4 ? {
315
+ isAbbreviated: true,
316
+ value: abbreviateNumber(number)
317
+ } : { isAbbreviated: false, value: amount };
318
+ }
319
+
289
320
  // src/index.ts
290
321
  function isNumber(value) {
291
322
  return typeof value === "number";
@@ -408,6 +439,9 @@ function isHexString(value) {
408
439
  function toHexString(value) {
409
440
  return value.toString(16);
410
441
  }
442
+ function hexToNumber(hex) {
443
+ return parseInt(hex, 16);
444
+ }
411
445
  function mapObject(obj, mapFn) {
412
446
  const result = {};
413
447
  for (const key in obj) {
@@ -423,7 +457,11 @@ function assertIsTruthy(val) {
423
457
  function capitalize(val) {
424
458
  return val.charAt(0).toUpperCase() + val.slice(1);
425
459
  }
460
+ function uniqueArray(arr) {
461
+ return Array.from(new Set(arr));
462
+ }
426
463
  export {
464
+ abbreviateNumber,
427
465
  assertIsTruthy,
428
466
  baseCurrencyAmountInQuote,
429
467
  btcToSat,
@@ -444,6 +482,7 @@ export {
444
482
  extractPhraseFromString,
445
483
  fibonacciGenerator,
446
484
  fiveMinInMs,
485
+ formatBalance,
447
486
  formatContractId,
448
487
  formatDustUsdAmounts,
449
488
  formatMoney,
@@ -451,6 +490,7 @@ export {
451
490
  formatMoneyWithoutSymbol,
452
491
  getPrincipalFromContractId,
453
492
  getTicker,
493
+ hexToNumber,
454
494
  i18nFormatCurrency,
455
495
  increaseValueByOneMicroStx,
456
496
  initBigNumber,
@@ -496,6 +536,7 @@ export {
496
536
  toHexString,
497
537
  truncateMiddle,
498
538
  undefinedIfLengthZero,
539
+ uniqueArray,
499
540
  unitToFractionalUnit,
500
541
  whenNetwork
501
542
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/counter.ts","../src/math/calculate-averages.ts","../src/math/helpers.ts","../src/math/fibonacci.ts","../src/money/calculate-money.ts","../src/money/format-money.ts","../src/money/is-money.ts","../src/money/unit-conversion.ts","../src/sort-assets.ts","../src/truncate-middle.ts","../src/time.ts","../src/spam-filter/spam-filter.ts","../src/extract-phrase-from-string/extract-phrase-from-string.ts","../src/px-string-to-number/px-string-to-number.ts"],"sourcesContent":["import { BigNumber } from 'bignumber.js';\n\nimport { KEBAB_REGEX } from '@leather.io/constants';\nimport type { NetworkModes } from '@leather.io/models';\n\nexport { createCounter } from './counter';\nexport * from './math';\nexport * from './money';\nexport * from './sort-assets';\nexport * from './truncate-middle';\nexport * from './time';\n\nexport { spamFilter } from './spam-filter/spam-filter';\nexport { extractPhraseFromString } from './extract-phrase-from-string/extract-phrase-from-string';\nexport { pxStringToNumber } from './px-string-to-number/px-string-to-number';\n\nexport function isNumber(value: unknown): value is number {\n return typeof value === 'number';\n}\n\nexport function isString(value: unknown): value is string {\n return typeof value === 'string';\n}\n\nexport function isEmptyString(value: unknown): value is '' {\n return isString(value) && value === '';\n}\n\nexport function isBigInt(value: unknown): value is bigint {\n return typeof value === 'bigint';\n}\n\nexport function isUndefined(value: unknown): value is undefined {\n return typeof value === 'undefined';\n}\n\nexport function isFunction(value: unknown): value is () => void {\n return typeof value === 'function';\n}\n\nexport function isBoolean(value: unknown): value is boolean {\n return typeof value === 'boolean';\n}\n\nexport function isObject(value: unknown): value is object {\n return typeof value === 'object';\n}\n\nexport function isError(value: unknown): value is Error {\n return value instanceof Error;\n}\n\nexport function isEmpty(value: object) {\n return Object.keys(value).length === 0;\n}\n\nexport function isDefined<T>(argument: T | undefined): argument is T {\n return !isUndefined(argument);\n}\n\nexport function isTypedArray(val: unknown): val is Uint8Array {\n const TypedArray = Object.getPrototypeOf(Uint8Array);\n return val instanceof TypedArray;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nexport function noop() {}\n\nexport function ensureArray<T>(value: T | T[]): T[] {\n return Array.isArray(value) ? value : [value];\n}\n\nexport function undefinedIfLengthZero<T extends any[]>(arr: T) {\n return arr.length ? arr : undefined;\n}\n\ntype NetworkMap<T> = Record<NetworkModes, T>;\n\nexport function whenNetwork(mode: NetworkModes) {\n return <T extends NetworkMap<unknown>>(networkMap: T) => networkMap[mode] as T[NetworkModes];\n}\n\nexport function isEmptyArray(data: unknown[]) {\n return data.length === 0;\n}\n\n// TODO: extension concept, remove remove from utils\nexport const defaultWalletKeyId = 'default' as const;\n\nexport function reverseBytes(bytes: Buffer): Buffer;\nexport function reverseBytes(bytes: Uint8Array): Uint8Array;\nexport function reverseBytes(bytes: Buffer | Uint8Array) {\n if (Buffer.isBuffer(bytes)) return Buffer.from(bytes).reverse();\n return new Uint8Array(bytes.slice().reverse());\n}\n\nexport function makeNumberRange(num: number) {\n return [...Array(num).keys()];\n}\n\nexport function createNumArrayOfRange(fromIndex: number, toIndex: number) {\n const result = [];\n for (let i = fromIndex; i <= toIndex; i++) {\n result.push(i);\n }\n return result;\n}\n\nexport async function delay(ms: number) {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nexport function sumNumbers(nums: number[]) {\n return nums.reduce((acc, num) => acc.plus(num), new BigNumber(0));\n}\n\nexport function isFulfilled<T>(p: PromiseSettledResult<T>): p is PromiseFulfilledResult<T> {\n return p.status === 'fulfilled';\n}\n\nexport function isRejected<T>(p: PromiseSettledResult<T>): p is PromiseRejectedResult {\n return p.status === 'rejected';\n}\n\n// TODO: Move to @leather.io/stacks\nexport function getPrincipalFromContractId(identifier: string) {\n return identifier.split('::')[0];\n}\n\n// TODO: Move to @leather.io/stacks\nexport function formatContractId(address: string, name: string) {\n return `${address}.${name}`;\n}\n\nexport function createNullArrayOfLength(length: number) {\n return new Array(length).fill(null);\n}\n\nexport function safelyFormatHexTxid(id: string) {\n const prefix = '0x';\n if (id.startsWith(prefix)) return id;\n return prefix + id;\n}\n\nfunction kebabCase(str: string) {\n return str.replace(KEBAB_REGEX, match => '-' + match.toLowerCase());\n}\n\nfunction getLetters(string: string, offset = 1) {\n return string.slice(0, offset);\n}\n\nexport function getTicker(value: string) {\n let name = kebabCase(value);\n if (name.includes('-')) {\n const words = name.split('-');\n if (words.length >= 3) {\n name = `${getLetters(words[0])}${getLetters(words[1])}${getLetters(words[2])}`;\n } else {\n name = `${getLetters(words[0])}${getLetters(words[1], 2)}`;\n }\n } else if (name.length >= 3) {\n name = `${getLetters(name, 3)}`;\n }\n return name.toUpperCase();\n}\n\nexport function propIfDefined(prop: string, value: any) {\n return isBoolean(value) ? { [prop]: value } : {};\n}\n\nexport function isHexString(value: string) {\n return /^[0-9a-fA-F]+$/.test(value);\n}\n\nexport function toHexString(value: number) {\n return value.toString(16);\n}\n\ntype MapFunction<T, U> = (value: T[keyof T], key: string) => U;\n\nexport function mapObject<T extends object, U>(\n obj: T,\n mapFn: MapFunction<T, U>\n): { [K in keyof T]: U } {\n const result: Partial<{ [K in keyof T]: U }> = {};\n\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n result[key] = mapFn(obj[key], key);\n }\n }\n\n return result as { [K in keyof T]: U };\n}\n\nexport function assertIsTruthy<T>(val: T): asserts val is NonNullable<T> {\n if (!val) throw new Error(`expected: true, actual: ${val}`);\n}\n\nexport function capitalize(val: string) {\n return val.charAt(0).toUpperCase() + val.slice(1);\n}\n","export function createCounter(startPosition = 0) {\n let count = startPosition;\n return {\n getValue() {\n return count;\n },\n increment() {\n return (count += 1);\n },\n incrementBy(amount: number) {\n return (count += amount);\n },\n decrement() {\n return (count -= 1);\n },\n };\n}\n","import BigNumber from 'bignumber.js';\n\nimport { initBigNumber } from './helpers';\n\nexport function calculateMeanAverage(numbers: BigNumber[] | number[]) {\n if (numbers.length === 0) return new BigNumber(0);\n return numbers\n .map(initBigNumber)\n .reduce((acc, price) => acc.plus(price), new BigNumber(0))\n .dividedBy(numbers.length);\n}\n","import BigNumber from 'bignumber.js';\n\nimport { isBigInt } from '..';\n\nexport function initBigNumber(num: string | number | BigNumber | bigint) {\n if (BigNumber.isBigNumber(num)) return num;\n return isBigInt(num) ? new BigNumber(num.toString()) : new BigNumber(num);\n}\n\nexport function sumNumbers(nums: number[]) {\n return nums.reduce((acc, num) => acc.plus(num), new BigNumber(0));\n}\n\nfunction isMultipleOf(multiple: number) {\n return (num: number) => num % multiple === 0;\n}\n\nexport function isEven(num: number) {\n return isMultipleOf(2)(num);\n}\n\nexport function countDecimals(num: string | number | BigNumber) {\n const LARGE_NUMBER_OF_DECIMALS = 100;\n BigNumber.config({ DECIMAL_PLACES: LARGE_NUMBER_OF_DECIMALS });\n const amount = initBigNumber(num);\n const decimals = amount.toString(10).split('.')[1];\n return decimals ? decimals.length : 0;\n}\n\nexport function increaseValueByOneMicroStx(value: string | number | BigNumber) {\n return new BigNumber(value).plus(0.000001).toNumber();\n}\n","function fibonacci(n = 0): number {\n if (n < 0) throw 'Cannot calculate from negative number';\n if (n < 2) return n;\n return fibonacci(n - 1) + fibonacci(n - 2);\n}\n\nexport function* fibonacciGenerator(startIndex = 0): IterableIterator<number> {\n let index = startIndex;\n while (index < Infinity) yield fibonacci(index++);\n return Infinity;\n}\n","import { BigNumber } from 'bignumber.js';\n\nimport { type MarketData, type Money, type NumType, formatMarketPair } from '@leather.io/models';\n\nimport { isNumber } from '..';\nimport { initBigNumber, sumNumbers } from '../math/helpers';\nimport { createMoney, formatMoney } from './format-money';\nimport { isMoney } from './is-money';\n\nexport function baseCurrencyAmountInQuote(quantity: Money, { pair, price }: MarketData) {\n if (quantity.symbol !== pair.base)\n throw new Error(\n `Cannot calculate value of ${formatMoney(quantity)} with market pair of ${formatMarketPair(\n pair\n )}`\n );\n\n return createMoney(\n convertAmountToFractionalUnit(\n convertAmountToBaseUnit(quantity).times(convertAmountToBaseUnit(price)),\n price.decimals\n ),\n pair.quote\n );\n}\n\nexport function convertAmountToFractionalUnit(num: Money | BigNumber, decimals?: number) {\n if (isMoney(num)) return num.amount.shiftedBy(num.decimals);\n if (!isNumber(decimals)) throw new Error('Must define decimal of given currency');\n return num.shiftedBy(decimals);\n}\n\nexport function convertToMoneyTypeWithDefaultOfZero(\n symbol: string,\n num?: NumType,\n decimals?: number\n) {\n return createMoney(initBigNumber(num ?? 0), symbol.toUpperCase(), decimals);\n}\n\n// ts-unused-exports:disable-next-line\nexport function convertAmountToBaseUnit(num: Money | BigNumber, decimals?: number) {\n if (isMoney(num)) return num.amount.shiftedBy(-num.decimals);\n if (!isNumber(decimals)) throw new Error('Must define decimal of given currency');\n return num.shiftedBy(-decimals);\n}\n\nexport function subtractMoney(xAmount: Money, yAmount: Money) {\n if (xAmount.symbol !== yAmount.symbol) throw new Error('Cannot subtract different currencies');\n return createMoney(xAmount.amount.minus(yAmount.amount), xAmount.symbol, xAmount.decimals);\n}\n\nexport function sumMoney(moneysArr: Money[]) {\n if (moneysArr.some(item => item.symbol !== moneysArr[0].symbol))\n throw new Error('Cannot sum different currencies');\n\n const sum = sumNumbers(moneysArr.map(item => item.amount.toNumber()));\n return createMoney(sum, moneysArr[0].symbol, moneysArr[0].decimals);\n}\n","import BigNumber from 'bignumber.js';\n\nimport { currencyDecimalsMap } from '@leather.io/constants';\nimport type { Currency, Money, NumType } from '@leather.io/models';\n\nimport { isBigInt, isUndefined } from '..';\n\ntype KnownCurrencyDecimals = keyof typeof currencyDecimalsMap;\n\nfunction isResolutionOfCurrencyKnown(symbol: Currency): symbol is KnownCurrencyDecimals {\n return symbol in currencyDecimalsMap;\n}\n\nfunction getDecimalsOfSymbolIfKnown(symbol: Currency) {\n if (isResolutionOfCurrencyKnown(symbol)) return currencyDecimalsMap[symbol];\n return null;\n}\n\nfunction throwWhenDecimalUnknown(symbol: Currency, decimals?: number): asserts decimals is number {\n if (isUndefined(decimals) && isUndefined(getDecimalsOfSymbolIfKnown(symbol)))\n throw new Error(`Resolution of currency ${symbol} is unknown, must be described`);\n}\n\n/**\n * @param value Amount described in currency's primary unit\n * @param symbol Identifying letter code, e.g. EUR\n * @param resolution Optional, required if value not known at build-time\n */\nexport function createMoneyFromDecimal(\n value: NumType,\n symbol: Currency,\n resolution?: number\n): Money {\n throwWhenDecimalUnknown(symbol, resolution);\n const decimals = getDecimalsOfSymbolIfKnown(symbol) ?? resolution;\n const amount = new BigNumber(isBigInt(value) ? value.toString() : value).shiftedBy(decimals);\n return Object.freeze({ amount, symbol, decimals });\n}\n\n/**\n * @param value Amount described in currency's fractional base unit, e.g. cents for USD amounts\n * @param symbol Identifying letter code, e.g. EUR\n * @param resolution Optional, required if value not known at build-time\n */\nexport function createMoney(value: NumType, symbol: Currency, resolution?: number): Money {\n throwWhenDecimalUnknown(symbol, resolution);\n const decimals = getDecimalsOfSymbolIfKnown(symbol) ?? resolution;\n const amount = new BigNumber(isBigInt(value) ? value.toString() : value);\n return Object.freeze({ amount, symbol, decimals });\n}\n\nconst thinSpace = ' ';\n\nexport function formatMoney({ amount, symbol, decimals }: Money) {\n return `${amount.shiftedBy(-decimals).toString()} ${symbol}`;\n}\n\nexport function formatMoneyWithoutSymbol({ amount, decimals }: Money) {\n return `${amount.shiftedBy(-decimals).toString()}`;\n}\n\nexport function formatMoneyPadded({ amount, symbol, decimals }: Money) {\n return `${amount.shiftedBy(-decimals).toFormat(decimals)} ${symbol}`;\n}\n\nexport function i18nFormatCurrency(quantity: Money, decimals: number = 2) {\n if (quantity.symbol !== 'USD') throw new Error('Cannot format non-USD amounts');\n const currencyFormatter = new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD',\n maximumFractionDigits: decimals,\n });\n\n const formatted = currencyFormatter.format(\n quantity.amount.shiftedBy(-quantity.decimals).toNumber()\n );\n\n if (quantity.amount.isGreaterThan(0) && formatted === '$0.00')\n return '<' + thinSpace + formatted.replace('0.00', '0.01');\n\n return formatted;\n}\n\nexport function formatDustUsdAmounts(value: string) {\n return value.endsWith('0.00') ? '<' + thinSpace + value.replace('0.00', '0.01') : value;\n}\n","import BigNumber from 'bignumber.js';\n\nimport { Money } from '@leather.io/models';\n\nimport { isObject } from '..';\n\nexport function isMoney(val: unknown): val is Money {\n if (!isObject(val)) return false;\n return 'amount' in val && 'symbol' in val && 'decimals' in val;\n}\n\nexport function isMoneyGreaterThanZero(money: Money) {\n if (!BigNumber.isBigNumber(money.amount)) return;\n return !(money.amount.isNaN() || money.amount.isZero());\n}\n","import BigNumber from 'bignumber.js';\n\nimport { BTC_DECIMALS, STX_DECIMALS } from '@leather.io/constants';\nimport { Money } from '@leather.io/models';\n\nimport { initBigNumber } from '../math/helpers';\n\nfunction fractionalUnitToUnit(decimals: number) {\n return (unit: number | string | BigNumber) => {\n const unitBigNumber = initBigNumber(unit);\n return unitBigNumber.shiftedBy(-decimals);\n };\n}\n\nexport function unitToFractionalUnit(decimals: number) {\n return (unit: number | string | BigNumber) => {\n const unitBigNumber = initBigNumber(unit);\n return unitBigNumber.shiftedBy(decimals);\n };\n}\n\nexport const satToBtc = fractionalUnitToUnit(BTC_DECIMALS);\nexport const btcToSat = unitToFractionalUnit(BTC_DECIMALS);\n\nexport const microStxToStx = fractionalUnitToUnit(STX_DECIMALS);\nexport const stxToMicroStx = unitToFractionalUnit(STX_DECIMALS);\n\nexport function moneyToBaseUnit(sum: Money) {\n return fractionalUnitToUnit(sum.decimals)(sum.amount);\n}\n","import type { Money } from '@leather.io/models';\n\nexport function sortAssetsByName<T extends { name: string }[]>(assets: T) {\n return assets\n .sort((a, b) => {\n if (a.name < b.name) return -1;\n if (a.name > b.name) return 1;\n return 0;\n })\n .sort((a, b) => {\n if (a.name === 'STX') return -1;\n if (b.name !== 'STX') return 1;\n return 0;\n })\n .sort((a, b) => {\n if (a.name === 'BTC') return -1;\n if (b.name !== 'BTC') return 1;\n return 0;\n });\n}\n\nexport function migratePositiveAssetBalancesToTop<T extends { balance: Money }[]>(assets: T) {\n const assetsWithPositiveBalance = assets.filter(asset => asset.balance.amount.isGreaterThan(0));\n const assetsWithZeroBalance = assets.filter(asset => asset.balance.amount.isEqualTo(0));\n return [...assetsWithPositiveBalance, ...assetsWithZeroBalance] as T;\n}\n","function truncateHex(hex: string, offset = 5): string {\n return `${hex.substring(0, offset + 2)}…${hex.substring(hex.length - offset)}`;\n}\n\nexport function truncateMiddle(input: string, offset = 5): string {\n if (!input) return '';\n // Hex\n if (input.startsWith('0x')) {\n return truncateHex(input, offset);\n }\n // For contracts\n if (input.includes('.')) {\n const parts = input.split('.');\n const start = parts[0]?.substring(0, offset);\n const end = parts[0]?.substring(parts[0].length - offset, parts[0].length);\n return `${start}…${end}.${parts[1]}`;\n } else {\n // Everything else\n const start = input?.substring(0, offset);\n const end = input?.substring(input.length - offset, input.length);\n return `${start}…${end}`;\n }\n}\n","export const fiveMinInMs = 5 * 60 * 1000;\nexport const oneDayInMs = 24 * 60 * 60 * 1000;\nexport const oneWeekInMs = 7 * oneDayInMs;\nexport const oneMonthInMs = 30 * oneDayInMs;\n","const urlRegex =\n /(http|https|ftp)|(((http|ftp|https):\\/\\/)?(((http|ftp|https):\\/\\/)?(([\\w.-]*)\\.([\\w]*))))/g;\nconst spamWords = ['won', 'win', 'click'];\nexport const spamReplacement = 'Suspicious token';\n\nfunction spamUrlFilter(input: string) {\n return input.match(urlRegex);\n}\n\nfunction spamWordFilter(input: string): boolean {\n const containsSpam = (element: string) => input.toLowerCase().includes(element);\n return spamWords.some(containsSpam);\n}\n\nexport function spamFilter(input: string): string {\n const urlFound = spamUrlFilter(input);\n const spamWordsFound = spamWordFilter(input);\n\n if (urlFound || spamWordsFound) {\n return spamReplacement;\n }\n\n return input;\n}\n","export function extractPhraseFromString(value: string) {\n const clean = value.trim();\n const words = clean.match(/\\S+/g);\n if (words?.length) {\n return words\n .map(word => (word.match(/[^0-9]+/g) ? word : null))\n .filter(Boolean)\n .join(' ');\n } else {\n return clean;\n }\n}\n","export function pxStringToNumber(pxString: string): number {\n if (!/^\\d+px$/.test(pxString)) {\n throw new Error('Invalid pixel string format');\n }\n return +pxString.replace('px', '');\n}\n"],"mappings":"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","names":["BigNumber","BigNumber","BigNumber","BigNumber","BigNumber","BigNumber","BigNumber","sumNumbers","BigNumber"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/counter.ts","../src/math/calculate-averages.ts","../src/math/helpers.ts","../src/math/fibonacci.ts","../src/money/calculate-money.ts","../src/money/format-money.ts","../src/money/is-money.ts","../src/money/unit-conversion.ts","../src/sort-assets.ts","../src/truncate-middle.ts","../src/time.ts","../src/spam-filter/spam-filter.ts","../src/extract-phrase-from-string/extract-phrase-from-string.ts","../src/px-string-to-number/px-string-to-number.ts","../src/abbreviate-number/abbreviate-number.ts","../src/money/format-balance/remove-commas.ts","../src/money/format-balance/format-balance.ts"],"sourcesContent":["import { BigNumber } from 'bignumber.js';\n\nimport { KEBAB_REGEX } from '@leather.io/constants';\nimport type { NetworkModes } from '@leather.io/models';\n\nexport { createCounter } from './counter';\nexport * from './math';\nexport * from './money';\nexport * from './sort-assets';\nexport * from './truncate-middle';\nexport * from './time';\n\nexport { spamFilter } from './spam-filter/spam-filter';\nexport { extractPhraseFromString } from './extract-phrase-from-string/extract-phrase-from-string';\nexport { pxStringToNumber } from './px-string-to-number/px-string-to-number';\nexport { formatBalance } from './money/format-balance/format-balance';\nexport { abbreviateNumber } from './abbreviate-number/abbreviate-number';\n\nexport function isNumber(value: unknown): value is number {\n return typeof value === 'number';\n}\n\nexport function isString(value: unknown): value is string {\n return typeof value === 'string';\n}\n\nexport function isEmptyString(value: unknown): value is '' {\n return isString(value) && value === '';\n}\n\nexport function isBigInt(value: unknown): value is bigint {\n return typeof value === 'bigint';\n}\n\nexport function isUndefined(value: unknown): value is undefined {\n return typeof value === 'undefined';\n}\n\nexport function isFunction(value: unknown): value is () => void {\n return typeof value === 'function';\n}\n\nexport function isBoolean(value: unknown): value is boolean {\n return typeof value === 'boolean';\n}\n\nexport function isObject(value: unknown): value is object {\n return typeof value === 'object';\n}\n\nexport function isError(value: unknown): value is Error {\n return value instanceof Error;\n}\n\nexport function isEmpty(value: object) {\n return Object.keys(value).length === 0;\n}\n\nexport function isDefined<T>(argument: T | undefined): argument is T {\n return !isUndefined(argument);\n}\n\nexport function isTypedArray(val: unknown): val is Uint8Array {\n const TypedArray = Object.getPrototypeOf(Uint8Array);\n return val instanceof TypedArray;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-function\nexport function noop() {}\n\nexport function ensureArray<T>(value: T | T[]): T[] {\n return Array.isArray(value) ? value : [value];\n}\n\nexport function undefinedIfLengthZero<T extends any[]>(arr: T) {\n return arr.length ? arr : undefined;\n}\n\ntype NetworkMap<T> = Record<NetworkModes, T>;\n\nexport function whenNetwork(mode: NetworkModes) {\n return <T extends NetworkMap<unknown>>(networkMap: T) => networkMap[mode] as T[NetworkModes];\n}\n\nexport function isEmptyArray(data: unknown[]) {\n return data.length === 0;\n}\n\n// TODO: extension concept, remove remove from utils\nexport const defaultWalletKeyId = 'default' as const;\n\nexport function reverseBytes(bytes: Buffer): Buffer;\nexport function reverseBytes(bytes: Uint8Array): Uint8Array;\nexport function reverseBytes(bytes: Buffer | Uint8Array) {\n if (Buffer.isBuffer(bytes)) return Buffer.from(bytes).reverse();\n return new Uint8Array(bytes.slice().reverse());\n}\n\nexport function makeNumberRange(num: number) {\n return [...Array(num).keys()];\n}\n\nexport function createNumArrayOfRange(fromIndex: number, toIndex: number) {\n const result = [];\n for (let i = fromIndex; i <= toIndex; i++) {\n result.push(i);\n }\n return result;\n}\n\nexport async function delay(ms: number) {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\nexport function sumNumbers(nums: number[]) {\n return nums.reduce((acc, num) => acc.plus(num), new BigNumber(0));\n}\n\nexport function isFulfilled<T>(p: PromiseSettledResult<T>): p is PromiseFulfilledResult<T> {\n return p.status === 'fulfilled';\n}\n\nexport function isRejected<T>(p: PromiseSettledResult<T>): p is PromiseRejectedResult {\n return p.status === 'rejected';\n}\n\n// TODO: Move to @leather.io/stacks\nexport function getPrincipalFromContractId(identifier: string) {\n return identifier.split('::')[0];\n}\n\n// TODO: Move to @leather.io/stacks\nexport function formatContractId(address: string, name: string) {\n return `${address}.${name}`;\n}\n\nexport function createNullArrayOfLength(length: number) {\n return new Array(length).fill(null);\n}\n\nexport function safelyFormatHexTxid(id: string) {\n const prefix = '0x';\n if (id.startsWith(prefix)) return id;\n return prefix + id;\n}\n\nfunction kebabCase(str: string) {\n return str.replace(KEBAB_REGEX, match => '-' + match.toLowerCase());\n}\n\nfunction getLetters(string: string, offset = 1) {\n return string.slice(0, offset);\n}\n\nexport function getTicker(value: string) {\n let name = kebabCase(value);\n if (name.includes('-')) {\n const words = name.split('-');\n if (words.length >= 3) {\n name = `${getLetters(words[0])}${getLetters(words[1])}${getLetters(words[2])}`;\n } else {\n name = `${getLetters(words[0])}${getLetters(words[1], 2)}`;\n }\n } else if (name.length >= 3) {\n name = `${getLetters(name, 3)}`;\n }\n return name.toUpperCase();\n}\n\nexport function propIfDefined(prop: string, value: any) {\n return isBoolean(value) ? { [prop]: value } : {};\n}\n\nexport function isHexString(value: string) {\n return /^[0-9a-fA-F]+$/.test(value);\n}\n\nexport function toHexString(value: number) {\n return value.toString(16);\n}\n\nexport function hexToNumber(hex: string) {\n return parseInt(hex, 16);\n}\n\ntype MapFunction<T, U> = (value: T[keyof T], key: string) => U;\n\nexport function mapObject<T extends object, U>(\n obj: T,\n mapFn: MapFunction<T, U>\n): { [K in keyof T]: U } {\n const result: Partial<{ [K in keyof T]: U }> = {};\n\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n result[key] = mapFn(obj[key], key);\n }\n }\n\n return result as { [K in keyof T]: U };\n}\n\nexport function assertIsTruthy<T>(val: T): asserts val is NonNullable<T> {\n if (!val) throw new Error(`expected: true, actual: ${val}`);\n}\n\nexport function capitalize(val: string) {\n return val.charAt(0).toUpperCase() + val.slice(1);\n}\n\nexport function uniqueArray<T>(arr: T[]) {\n return Array.from(new Set(arr));\n}\n","export function createCounter(startPosition = 0) {\n let count = startPosition;\n return {\n getValue() {\n return count;\n },\n increment() {\n return (count += 1);\n },\n incrementBy(amount: number) {\n return (count += amount);\n },\n decrement() {\n return (count -= 1);\n },\n };\n}\n","import BigNumber from 'bignumber.js';\n\nimport { initBigNumber } from './helpers';\n\nexport function calculateMeanAverage(numbers: BigNumber[] | number[]) {\n if (numbers.length === 0) return new BigNumber(0);\n return numbers\n .map(initBigNumber)\n .reduce((acc, price) => acc.plus(price), new BigNumber(0))\n .dividedBy(numbers.length);\n}\n","import BigNumber from 'bignumber.js';\n\nimport { isBigInt } from '..';\n\nexport function initBigNumber(num: string | number | BigNumber | bigint) {\n if (BigNumber.isBigNumber(num)) return num;\n return isBigInt(num) ? new BigNumber(num.toString()) : new BigNumber(num);\n}\n\nexport function sumNumbers(nums: number[]) {\n return nums.reduce((acc, num) => acc.plus(num), new BigNumber(0));\n}\n\nfunction isMultipleOf(multiple: number) {\n return (num: number) => num % multiple === 0;\n}\n\nexport function isEven(num: number) {\n return isMultipleOf(2)(num);\n}\n\nexport function countDecimals(num: string | number | BigNumber) {\n const LARGE_NUMBER_OF_DECIMALS = 100;\n BigNumber.config({ DECIMAL_PLACES: LARGE_NUMBER_OF_DECIMALS });\n const amount = initBigNumber(num);\n const decimals = amount.toString(10).split('.')[1];\n return decimals ? decimals.length : 0;\n}\n\nexport function increaseValueByOneMicroStx(value: string | number | BigNumber) {\n return new BigNumber(value).plus(0.000001).toNumber();\n}\n","function fibonacci(n = 0): number {\n if (n < 0) throw 'Cannot calculate from negative number';\n if (n < 2) return n;\n return fibonacci(n - 1) + fibonacci(n - 2);\n}\n\nexport function* fibonacciGenerator(startIndex = 0): IterableIterator<number> {\n let index = startIndex;\n while (index < Infinity) yield fibonacci(index++);\n return Infinity;\n}\n","import { BigNumber } from 'bignumber.js';\n\nimport { type MarketData, type Money, type NumType, formatMarketPair } from '@leather.io/models';\n\nimport { isNumber } from '..';\nimport { initBigNumber, sumNumbers } from '../math/helpers';\nimport { createMoney, formatMoney } from './format-money';\nimport { isMoney } from './is-money';\n\nexport function baseCurrencyAmountInQuote(quantity: Money, { pair, price }: MarketData) {\n if (quantity.symbol !== pair.base)\n throw new Error(\n `Cannot calculate value of ${formatMoney(quantity)} with market pair of ${formatMarketPair(\n pair\n )}`\n );\n\n return createMoney(\n convertAmountToFractionalUnit(\n convertAmountToBaseUnit(quantity).times(convertAmountToBaseUnit(price)),\n price.decimals\n ),\n pair.quote\n );\n}\n\nexport function convertAmountToFractionalUnit(num: Money | BigNumber, decimals?: number) {\n if (isMoney(num)) return num.amount.shiftedBy(num.decimals);\n if (!isNumber(decimals)) throw new Error('Must define decimal of given currency');\n return num.shiftedBy(decimals);\n}\n\nexport function convertToMoneyTypeWithDefaultOfZero(\n symbol: string,\n num?: NumType,\n decimals?: number\n) {\n return createMoney(initBigNumber(num ?? 0), symbol.toUpperCase(), decimals);\n}\n\n// ts-unused-exports:disable-next-line\nexport function convertAmountToBaseUnit(num: Money | BigNumber, decimals?: number) {\n if (isMoney(num)) return num.amount.shiftedBy(-num.decimals);\n if (!isNumber(decimals)) throw new Error('Must define decimal of given currency');\n return num.shiftedBy(-decimals);\n}\n\nexport function subtractMoney(xAmount: Money, yAmount: Money) {\n if (xAmount.symbol !== yAmount.symbol) throw new Error('Cannot subtract different currencies');\n return createMoney(xAmount.amount.minus(yAmount.amount), xAmount.symbol, xAmount.decimals);\n}\n\nexport function sumMoney(moneysArr: Money[]) {\n if (moneysArr.some(item => item.symbol !== moneysArr[0].symbol))\n throw new Error('Cannot sum different currencies');\n\n const sum = sumNumbers(moneysArr.map(item => item.amount.toNumber()));\n return createMoney(sum, moneysArr[0].symbol, moneysArr[0].decimals);\n}\n","import BigNumber from 'bignumber.js';\n\nimport { currencyDecimalsMap } from '@leather.io/constants';\nimport type { Currency, Money, NumType } from '@leather.io/models';\n\nimport { isBigInt, isUndefined } from '..';\n\ntype KnownCurrencyDecimals = keyof typeof currencyDecimalsMap;\n\nfunction isResolutionOfCurrencyKnown(symbol: Currency): symbol is KnownCurrencyDecimals {\n return symbol in currencyDecimalsMap;\n}\n\nfunction getDecimalsOfSymbolIfKnown(symbol: Currency) {\n if (isResolutionOfCurrencyKnown(symbol)) return currencyDecimalsMap[symbol];\n return null;\n}\n\nfunction throwWhenDecimalUnknown(symbol: Currency, decimals?: number): asserts decimals is number {\n if (isUndefined(decimals) && isUndefined(getDecimalsOfSymbolIfKnown(symbol)))\n throw new Error(`Resolution of currency ${symbol} is unknown, must be described`);\n}\n\n/**\n * @param value Amount described in currency's primary unit\n * @param symbol Identifying letter code, e.g. EUR\n * @param resolution Optional, required if value not known at build-time\n */\nexport function createMoneyFromDecimal(\n value: NumType,\n symbol: Currency,\n resolution?: number\n): Money {\n throwWhenDecimalUnknown(symbol, resolution);\n const decimals = getDecimalsOfSymbolIfKnown(symbol) ?? resolution;\n const amount = new BigNumber(isBigInt(value) ? value.toString() : value).shiftedBy(decimals);\n return Object.freeze({ amount, symbol, decimals });\n}\n\n/**\n * @param value Amount described in currency's fractional base unit, e.g. cents for USD amounts\n * @param symbol Identifying letter code, e.g. EUR\n * @param resolution Optional, required if value not known at build-time\n */\nexport function createMoney(value: NumType, symbol: Currency, resolution?: number): Money {\n throwWhenDecimalUnknown(symbol, resolution);\n const decimals = getDecimalsOfSymbolIfKnown(symbol) ?? resolution;\n const amount = new BigNumber(isBigInt(value) ? value.toString() : value);\n return Object.freeze({ amount, symbol, decimals });\n}\n\nconst thinSpace = ' ';\n\nexport function formatMoney({ amount, symbol, decimals }: Money) {\n return `${amount.shiftedBy(-decimals).toString()} ${symbol}`;\n}\n\nexport function formatMoneyWithoutSymbol({ amount, decimals }: Money) {\n return `${amount.shiftedBy(-decimals).toString()}`;\n}\n\nexport function formatMoneyPadded({ amount, symbol, decimals }: Money) {\n return `${amount.shiftedBy(-decimals).toFormat(decimals)} ${symbol}`;\n}\n\nexport function i18nFormatCurrency(quantity: Money, decimals: number = 2) {\n if (quantity.symbol !== 'USD') throw new Error('Cannot format non-USD amounts');\n const currencyFormatter = new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency: 'USD',\n maximumFractionDigits: decimals,\n });\n\n const formatted = currencyFormatter.format(\n quantity.amount.shiftedBy(-quantity.decimals).toNumber()\n );\n\n if (quantity.amount.isGreaterThan(0) && formatted === '$0.00')\n return '<' + thinSpace + formatted.replace('0.00', '0.01');\n\n return formatted;\n}\n\nexport function formatDustUsdAmounts(value: string) {\n return value.endsWith('0.00') ? '<' + thinSpace + value.replace('0.00', '0.01') : value;\n}\n","import BigNumber from 'bignumber.js';\n\nimport { Money } from '@leather.io/models';\n\nimport { isObject } from '..';\n\nexport function isMoney(val: unknown): val is Money {\n if (!isObject(val)) return false;\n return 'amount' in val && 'symbol' in val && 'decimals' in val;\n}\n\nexport function isMoneyGreaterThanZero(money: Money) {\n if (!BigNumber.isBigNumber(money.amount)) return;\n return !(money.amount.isNaN() || money.amount.isZero());\n}\n","import BigNumber from 'bignumber.js';\n\nimport { BTC_DECIMALS, STX_DECIMALS } from '@leather.io/constants';\nimport { Money } from '@leather.io/models';\n\nimport { initBigNumber } from '../math/helpers';\n\nfunction fractionalUnitToUnit(decimals: number) {\n return (unit: number | string | BigNumber) => {\n const unitBigNumber = initBigNumber(unit);\n return unitBigNumber.shiftedBy(-decimals);\n };\n}\n\nexport function unitToFractionalUnit(decimals: number) {\n return (unit: number | string | BigNumber) => {\n const unitBigNumber = initBigNumber(unit);\n return unitBigNumber.shiftedBy(decimals);\n };\n}\n\nexport const satToBtc = fractionalUnitToUnit(BTC_DECIMALS);\nexport const btcToSat = unitToFractionalUnit(BTC_DECIMALS);\n\nexport const microStxToStx = fractionalUnitToUnit(STX_DECIMALS);\nexport const stxToMicroStx = unitToFractionalUnit(STX_DECIMALS);\n\nexport function moneyToBaseUnit(sum: Money) {\n return fractionalUnitToUnit(sum.decimals)(sum.amount);\n}\n","import type { Money } from '@leather.io/models';\n\nexport function sortAssetsByName<T extends { name: string }[]>(assets: T) {\n return assets\n .sort((a, b) => {\n if (a.name < b.name) return -1;\n if (a.name > b.name) return 1;\n return 0;\n })\n .sort((a, b) => {\n if (a.name === 'STX') return -1;\n if (b.name !== 'STX') return 1;\n return 0;\n })\n .sort((a, b) => {\n if (a.name === 'BTC') return -1;\n if (b.name !== 'BTC') return 1;\n return 0;\n });\n}\n\nexport function migratePositiveAssetBalancesToTop<T extends { balance: Money }[]>(assets: T) {\n const assetsWithPositiveBalance = assets.filter(asset => asset.balance.amount.isGreaterThan(0));\n const assetsWithZeroBalance = assets.filter(asset => asset.balance.amount.isEqualTo(0));\n return [...assetsWithPositiveBalance, ...assetsWithZeroBalance] as T;\n}\n","function truncateHex(hex: string, offset = 5): string {\n return `${hex.substring(0, offset + 2)}…${hex.substring(hex.length - offset)}`;\n}\n\nexport function truncateMiddle(input: string, offset = 5): string {\n if (!input) return '';\n // Hex\n if (input.startsWith('0x')) {\n return truncateHex(input, offset);\n }\n // For contracts\n if (input.includes('.')) {\n const parts = input.split('.');\n const start = parts[0]?.substring(0, offset);\n const end = parts[0]?.substring(parts[0].length - offset, parts[0].length);\n return `${start}…${end}.${parts[1]}`;\n } else {\n // Everything else\n const start = input?.substring(0, offset);\n const end = input?.substring(input.length - offset, input.length);\n return `${start}…${end}`;\n }\n}\n","export const fiveMinInMs = 5 * 60 * 1000;\nexport const oneDayInMs = 24 * 60 * 60 * 1000;\nexport const oneWeekInMs = 7 * oneDayInMs;\nexport const oneMonthInMs = 30 * oneDayInMs;\n","const urlRegex =\n /(http|https|ftp)|(((http|ftp|https):\\/\\/)?(((http|ftp|https):\\/\\/)?(([\\w.-]*)\\.([\\w]*))))/g;\nconst spamWords = ['won', 'win', 'click'];\nexport const spamReplacement = 'Suspicious token';\n\nfunction spamUrlFilter(input: string) {\n return input.match(urlRegex);\n}\n\nfunction spamWordFilter(input: string): boolean {\n const containsSpam = (element: string) => input.toLowerCase().includes(element);\n return spamWords.some(containsSpam);\n}\n\nexport function spamFilter(input: string): string {\n const urlFound = spamUrlFilter(input);\n const spamWordsFound = spamWordFilter(input);\n\n if (urlFound || spamWordsFound) {\n return spamReplacement;\n }\n\n return input;\n}\n","export function extractPhraseFromString(value: string) {\n const clean = value.trim();\n const words = clean.match(/\\S+/g);\n if (words?.length) {\n return words\n .map(word => (word.match(/[^0-9]+/g) ? word : null))\n .filter(Boolean)\n .join(' ');\n } else {\n return clean;\n }\n}\n","export function pxStringToNumber(pxString: string): number {\n if (!/^\\d+px$/.test(pxString)) {\n throw new Error('Invalid pixel string format');\n }\n return +pxString.replace('px', '');\n}\n","export function abbreviateNumber(n: number) {\n if (n < 1e3) return n.toString();\n if (n >= 1e3 && n < 1e6) return +(n / 1e3).toFixed(2) + 'K';\n if (n >= 1e6 && n < 1e9) return +(n / 1e6).toFixed(2) + 'M';\n if (n >= 1e9 && n < 1e12) return +(n / 1e9).toFixed(2) + 'B';\n if (n >= 1e12) return +(n / 1e12).toFixed(2) + 'T';\n return n.toString();\n}\n","export function removeCommas(amountWithCommas: string) {\n if (typeof amountWithCommas !== 'string') {\n throw new Error('Amount with commas must be a string');\n }\n return amountWithCommas.replace(/,/g, '');\n}\n","import { abbreviateNumber } from '../../abbreviate-number/abbreviate-number';\nimport { removeCommas } from './remove-commas';\n\n/**\n * TODO: investigate improving\n * @param amount is a string\n * in the extension we pre-convert it from Money with formatMoneyWithoutSymbol\n */\nexport function formatBalance(amount: string) {\n if (typeof amount !== 'string' || amount.trim() === '' || isNaN(Number(removeCommas(amount)))) {\n throw new Error('Invalid input: amount must be a non-empty string representing a valid number');\n }\n\n const noCommas = removeCommas(amount);\n const number = noCommas.includes('.') ? parseFloat(noCommas) : parseInt(noCommas);\n return number > 10000\n ? {\n isAbbreviated: true,\n value: abbreviateNumber(number),\n }\n : { isAbbreviated: false, value: amount };\n}\n"],"mappings":";AAAA,SAAS,aAAAA,kBAAiB;AAE1B,SAAS,mBAAmB;;;ACFrB,SAAS,cAAc,gBAAgB,GAAG;AAC/C,MAAI,QAAQ;AACZ,SAAO;AAAA,IACL,WAAW;AACT,aAAO;AAAA,IACT;AAAA,IACA,YAAY;AACV,aAAQ,SAAS;AAAA,IACnB;AAAA,IACA,YAAY,QAAgB;AAC1B,aAAQ,SAAS;AAAA,IACnB;AAAA,IACA,YAAY;AACV,aAAQ,SAAS;AAAA,IACnB;AAAA,EACF;AACF;;;AChBA,OAAOC,gBAAe;;;ACAtB,OAAO,eAAe;AAIf,SAAS,cAAc,KAA2C;AACvE,MAAI,UAAU,YAAY,GAAG,EAAG,QAAO;AACvC,SAAO,SAAS,GAAG,IAAI,IAAI,UAAU,IAAI,SAAS,CAAC,IAAI,IAAI,UAAU,GAAG;AAC1E;AAEO,SAAS,WAAW,MAAgB;AACzC,SAAO,KAAK,OAAO,CAAC,KAAK,QAAQ,IAAI,KAAK,GAAG,GAAG,IAAI,UAAU,CAAC,CAAC;AAClE;AAEA,SAAS,aAAa,UAAkB;AACtC,SAAO,CAAC,QAAgB,MAAM,aAAa;AAC7C;AAEO,SAAS,OAAO,KAAa;AAClC,SAAO,aAAa,CAAC,EAAE,GAAG;AAC5B;AAEO,SAAS,cAAc,KAAkC;AAC9D,QAAM,2BAA2B;AACjC,YAAU,OAAO,EAAE,gBAAgB,yBAAyB,CAAC;AAC7D,QAAM,SAAS,cAAc,GAAG;AAChC,QAAM,WAAW,OAAO,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AACjD,SAAO,WAAW,SAAS,SAAS;AACtC;AAEO,SAAS,2BAA2B,OAAoC;AAC7E,SAAO,IAAI,UAAU,KAAK,EAAE,KAAK,IAAQ,EAAE,SAAS;AACtD;;;AD3BO,SAAS,qBAAqB,SAAiC;AACpE,MAAI,QAAQ,WAAW,EAAG,QAAO,IAAIC,WAAU,CAAC;AAChD,SAAO,QACJ,IAAI,aAAa,EACjB,OAAO,CAAC,KAAK,UAAU,IAAI,KAAK,KAAK,GAAG,IAAIA,WAAU,CAAC,CAAC,EACxD,UAAU,QAAQ,MAAM;AAC7B;;;AEVA,SAAS,UAAU,IAAI,GAAW;AAChC,MAAI,IAAI,EAAG,OAAM;AACjB,MAAI,IAAI,EAAG,QAAO;AAClB,SAAO,UAAU,IAAI,CAAC,IAAI,UAAU,IAAI,CAAC;AAC3C;AAEO,UAAU,mBAAmB,aAAa,GAA6B;AAC5E,MAAI,QAAQ;AACZ,SAAO,QAAQ,SAAU,OAAM,UAAU,OAAO;AAChD,SAAO;AACT;;;ACRA,SAAoD,wBAAwB;;;ACF5E,OAAOC,gBAAe;AAEtB,SAAS,2BAA2B;AAOpC,SAAS,4BAA4B,QAAmD;AACtF,SAAO,UAAU;AACnB;AAEA,SAAS,2BAA2B,QAAkB;AACpD,MAAI,4BAA4B,MAAM,EAAG,QAAO,oBAAoB,MAAM;AAC1E,SAAO;AACT;AAEA,SAAS,wBAAwB,QAAkB,UAA+C;AAChG,MAAI,YAAY,QAAQ,KAAK,YAAY,2BAA2B,MAAM,CAAC;AACzE,UAAM,IAAI,MAAM,0BAA0B,MAAM,gCAAgC;AACpF;AAOO,SAAS,uBACd,OACA,QACA,YACO;AACP,0BAAwB,QAAQ,UAAU;AAC1C,QAAM,WAAW,2BAA2B,MAAM,KAAK;AACvD,QAAM,SAAS,IAAIC,WAAU,SAAS,KAAK,IAAI,MAAM,SAAS,IAAI,KAAK,EAAE,UAAU,QAAQ;AAC3F,SAAO,OAAO,OAAO,EAAE,QAAQ,QAAQ,SAAS,CAAC;AACnD;AAOO,SAAS,YAAY,OAAgB,QAAkB,YAA4B;AACxF,0BAAwB,QAAQ,UAAU;AAC1C,QAAM,WAAW,2BAA2B,MAAM,KAAK;AACvD,QAAM,SAAS,IAAIA,WAAU,SAAS,KAAK,IAAI,MAAM,SAAS,IAAI,KAAK;AACvE,SAAO,OAAO,OAAO,EAAE,QAAQ,QAAQ,SAAS,CAAC;AACnD;AAEA,IAAM,YAAY;AAEX,SAAS,YAAY,EAAE,QAAQ,QAAQ,SAAS,GAAU;AAC/D,SAAO,GAAG,OAAO,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,MAAM;AAC5D;AAEO,SAAS,yBAAyB,EAAE,QAAQ,SAAS,GAAU;AACpE,SAAO,GAAG,OAAO,UAAU,CAAC,QAAQ,EAAE,SAAS,CAAC;AAClD;AAEO,SAAS,kBAAkB,EAAE,QAAQ,QAAQ,SAAS,GAAU;AACrE,SAAO,GAAG,OAAO,UAAU,CAAC,QAAQ,EAAE,SAAS,QAAQ,CAAC,IAAI,MAAM;AACpE;AAEO,SAAS,mBAAmB,UAAiB,WAAmB,GAAG;AACxE,MAAI,SAAS,WAAW,MAAO,OAAM,IAAI,MAAM,+BAA+B;AAC9E,QAAM,oBAAoB,IAAI,KAAK,aAAa,SAAS;AAAA,IACvD,OAAO;AAAA,IACP,UAAU;AAAA,IACV,uBAAuB;AAAA,EACzB,CAAC;AAED,QAAM,YAAY,kBAAkB;AAAA,IAClC,SAAS,OAAO,UAAU,CAAC,SAAS,QAAQ,EAAE,SAAS;AAAA,EACzD;AAEA,MAAI,SAAS,OAAO,cAAc,CAAC,KAAK,cAAc;AACpD,WAAO,MAAM,YAAY,UAAU,QAAQ,QAAQ,MAAM;AAE3D,SAAO;AACT;AAEO,SAAS,qBAAqB,OAAe;AAClD,SAAO,MAAM,SAAS,MAAM,IAAI,MAAM,YAAY,MAAM,QAAQ,QAAQ,MAAM,IAAI;AACpF;;;ACrFA,OAAOC,gBAAe;AAMf,SAAS,QAAQ,KAA4B;AAClD,MAAI,CAAC,SAAS,GAAG,EAAG,QAAO;AAC3B,SAAO,YAAY,OAAO,YAAY,OAAO,cAAc;AAC7D;AAEO,SAAS,uBAAuB,OAAc;AACnD,MAAI,CAACC,WAAU,YAAY,MAAM,MAAM,EAAG;AAC1C,SAAO,EAAE,MAAM,OAAO,MAAM,KAAK,MAAM,OAAO,OAAO;AACvD;;;AFLO,SAAS,0BAA0B,UAAiB,EAAE,MAAM,MAAM,GAAe;AACtF,MAAI,SAAS,WAAW,KAAK;AAC3B,UAAM,IAAI;AAAA,MACR,6BAA6B,YAAY,QAAQ,CAAC,wBAAwB;AAAA,QACxE;AAAA,MACF,CAAC;AAAA,IACH;AAEF,SAAO;AAAA,IACL;AAAA,MACE,wBAAwB,QAAQ,EAAE,MAAM,wBAAwB,KAAK,CAAC;AAAA,MACtE,MAAM;AAAA,IACR;AAAA,IACA,KAAK;AAAA,EACP;AACF;AAEO,SAAS,8BAA8B,KAAwB,UAAmB;AACvF,MAAI,QAAQ,GAAG,EAAG,QAAO,IAAI,OAAO,UAAU,IAAI,QAAQ;AAC1D,MAAI,CAAC,SAAS,QAAQ,EAAG,OAAM,IAAI,MAAM,uCAAuC;AAChF,SAAO,IAAI,UAAU,QAAQ;AAC/B;AAEO,SAAS,oCACd,QACA,KACA,UACA;AACA,SAAO,YAAY,cAAc,OAAO,CAAC,GAAG,OAAO,YAAY,GAAG,QAAQ;AAC5E;AAGO,SAAS,wBAAwB,KAAwB,UAAmB;AACjF,MAAI,QAAQ,GAAG,EAAG,QAAO,IAAI,OAAO,UAAU,CAAC,IAAI,QAAQ;AAC3D,MAAI,CAAC,SAAS,QAAQ,EAAG,OAAM,IAAI,MAAM,uCAAuC;AAChF,SAAO,IAAI,UAAU,CAAC,QAAQ;AAChC;AAEO,SAAS,cAAc,SAAgB,SAAgB;AAC5D,MAAI,QAAQ,WAAW,QAAQ,OAAQ,OAAM,IAAI,MAAM,sCAAsC;AAC7F,SAAO,YAAY,QAAQ,OAAO,MAAM,QAAQ,MAAM,GAAG,QAAQ,QAAQ,QAAQ,QAAQ;AAC3F;AAEO,SAAS,SAAS,WAAoB;AAC3C,MAAI,UAAU,KAAK,UAAQ,KAAK,WAAW,UAAU,CAAC,EAAE,MAAM;AAC5D,UAAM,IAAI,MAAM,iCAAiC;AAEnD,QAAM,MAAM,WAAW,UAAU,IAAI,UAAQ,KAAK,OAAO,SAAS,CAAC,CAAC;AACpE,SAAO,YAAY,KAAK,UAAU,CAAC,EAAE,QAAQ,UAAU,CAAC,EAAE,QAAQ;AACpE;;;AGxDA,SAAS,cAAc,oBAAoB;AAK3C,SAAS,qBAAqB,UAAkB;AAC9C,SAAO,CAAC,SAAsC;AAC5C,UAAM,gBAAgB,cAAc,IAAI;AACxC,WAAO,cAAc,UAAU,CAAC,QAAQ;AAAA,EAC1C;AACF;AAEO,SAAS,qBAAqB,UAAkB;AACrD,SAAO,CAAC,SAAsC;AAC5C,UAAM,gBAAgB,cAAc,IAAI;AACxC,WAAO,cAAc,UAAU,QAAQ;AAAA,EACzC;AACF;AAEO,IAAM,WAAW,qBAAqB,YAAY;AAClD,IAAM,WAAW,qBAAqB,YAAY;AAElD,IAAM,gBAAgB,qBAAqB,YAAY;AACvD,IAAM,gBAAgB,qBAAqB,YAAY;AAEvD,SAAS,gBAAgB,KAAY;AAC1C,SAAO,qBAAqB,IAAI,QAAQ,EAAE,IAAI,MAAM;AACtD;;;AC3BO,SAAS,iBAA+C,QAAW;AACxE,SAAO,OACJ,KAAK,CAAC,GAAG,MAAM;AACd,QAAI,EAAE,OAAO,EAAE,KAAM,QAAO;AAC5B,QAAI,EAAE,OAAO,EAAE,KAAM,QAAO;AAC5B,WAAO;AAAA,EACT,CAAC,EACA,KAAK,CAAC,GAAG,MAAM;AACd,QAAI,EAAE,SAAS,MAAO,QAAO;AAC7B,QAAI,EAAE,SAAS,MAAO,QAAO;AAC7B,WAAO;AAAA,EACT,CAAC,EACA,KAAK,CAAC,GAAG,MAAM;AACd,QAAI,EAAE,SAAS,MAAO,QAAO;AAC7B,QAAI,EAAE,SAAS,MAAO,QAAO;AAC7B,WAAO;AAAA,EACT,CAAC;AACL;AAEO,SAAS,kCAAkE,QAAW;AAC3F,QAAM,4BAA4B,OAAO,OAAO,WAAS,MAAM,QAAQ,OAAO,cAAc,CAAC,CAAC;AAC9F,QAAM,wBAAwB,OAAO,OAAO,WAAS,MAAM,QAAQ,OAAO,UAAU,CAAC,CAAC;AACtF,SAAO,CAAC,GAAG,2BAA2B,GAAG,qBAAqB;AAChE;;;ACzBA,SAAS,YAAY,KAAa,SAAS,GAAW;AACpD,SAAO,GAAG,IAAI,UAAU,GAAG,SAAS,CAAC,CAAC,SAAI,IAAI,UAAU,IAAI,SAAS,MAAM,CAAC;AAC9E;AAEO,SAAS,eAAe,OAAe,SAAS,GAAW;AAChE,MAAI,CAAC,MAAO,QAAO;AAEnB,MAAI,MAAM,WAAW,IAAI,GAAG;AAC1B,WAAO,YAAY,OAAO,MAAM;AAAA,EAClC;AAEA,MAAI,MAAM,SAAS,GAAG,GAAG;AACvB,UAAM,QAAQ,MAAM,MAAM,GAAG;AAC7B,UAAM,QAAQ,MAAM,CAAC,GAAG,UAAU,GAAG,MAAM;AAC3C,UAAM,MAAM,MAAM,CAAC,GAAG,UAAU,MAAM,CAAC,EAAE,SAAS,QAAQ,MAAM,CAAC,EAAE,MAAM;AACzE,WAAO,GAAG,KAAK,SAAI,GAAG,IAAI,MAAM,CAAC,CAAC;AAAA,EACpC,OAAO;AAEL,UAAM,QAAQ,OAAO,UAAU,GAAG,MAAM;AACxC,UAAM,MAAM,OAAO,UAAU,MAAM,SAAS,QAAQ,MAAM,MAAM;AAChE,WAAO,GAAG,KAAK,SAAI,GAAG;AAAA,EACxB;AACF;;;ACtBO,IAAM,cAAc,IAAI,KAAK;AAC7B,IAAM,aAAa,KAAK,KAAK,KAAK;AAClC,IAAM,cAAc,IAAI;AACxB,IAAM,eAAe,KAAK;;;ACHjC,IAAM,WACJ;AACF,IAAM,YAAY,CAAC,OAAO,OAAO,OAAO;AACjC,IAAM,kBAAkB;AAE/B,SAAS,cAAc,OAAe;AACpC,SAAO,MAAM,MAAM,QAAQ;AAC7B;AAEA,SAAS,eAAe,OAAwB;AAC9C,QAAM,eAAe,CAAC,YAAoB,MAAM,YAAY,EAAE,SAAS,OAAO;AAC9E,SAAO,UAAU,KAAK,YAAY;AACpC;AAEO,SAAS,WAAW,OAAuB;AAChD,QAAM,WAAW,cAAc,KAAK;AACpC,QAAM,iBAAiB,eAAe,KAAK;AAE3C,MAAI,YAAY,gBAAgB;AAC9B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;ACvBO,SAAS,wBAAwB,OAAe;AACrD,QAAM,QAAQ,MAAM,KAAK;AACzB,QAAM,QAAQ,MAAM,MAAM,MAAM;AAChC,MAAI,OAAO,QAAQ;AACjB,WAAO,MACJ,IAAI,UAAS,KAAK,MAAM,UAAU,IAAI,OAAO,IAAK,EAClD,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,EACb,OAAO;AACL,WAAO;AAAA,EACT;AACF;;;ACXO,SAAS,iBAAiB,UAA0B;AACzD,MAAI,CAAC,UAAU,KAAK,QAAQ,GAAG;AAC7B,UAAM,IAAI,MAAM,6BAA6B;AAAA,EAC/C;AACA,SAAO,CAAC,SAAS,QAAQ,MAAM,EAAE;AACnC;;;ACLO,SAAS,iBAAiB,GAAW;AAC1C,MAAI,IAAI,IAAK,QAAO,EAAE,SAAS;AAC/B,MAAI,KAAK,OAAO,IAAI,IAAK,QAAO,EAAE,IAAI,KAAK,QAAQ,CAAC,IAAI;AACxD,MAAI,KAAK,OAAO,IAAI,IAAK,QAAO,EAAE,IAAI,KAAK,QAAQ,CAAC,IAAI;AACxD,MAAI,KAAK,OAAO,IAAI,KAAM,QAAO,EAAE,IAAI,KAAK,QAAQ,CAAC,IAAI;AACzD,MAAI,KAAK,KAAM,QAAO,EAAE,IAAI,MAAM,QAAQ,CAAC,IAAI;AAC/C,SAAO,EAAE,SAAS;AACpB;;;ACPO,SAAS,aAAa,kBAA0B;AACrD,MAAI,OAAO,qBAAqB,UAAU;AACxC,UAAM,IAAI,MAAM,qCAAqC;AAAA,EACvD;AACA,SAAO,iBAAiB,QAAQ,MAAM,EAAE;AAC1C;;;ACGO,SAAS,cAAc,QAAgB;AAC5C,MAAI,OAAO,WAAW,YAAY,OAAO,KAAK,MAAM,MAAM,MAAM,OAAO,aAAa,MAAM,CAAC,CAAC,GAAG;AAC7F,UAAM,IAAI,MAAM,8EAA8E;AAAA,EAChG;AAEA,QAAM,WAAW,aAAa,MAAM;AACpC,QAAM,SAAS,SAAS,SAAS,GAAG,IAAI,WAAW,QAAQ,IAAI,SAAS,QAAQ;AAChF,SAAO,SAAS,MACZ;AAAA,IACE,eAAe;AAAA,IACf,OAAO,iBAAiB,MAAM;AAAA,EAChC,IACA,EAAE,eAAe,OAAO,OAAO,OAAO;AAC5C;;;AjBHO,SAAS,SAAS,OAAiC;AACxD,SAAO,OAAO,UAAU;AAC1B;AAEO,SAAS,SAAS,OAAiC;AACxD,SAAO,OAAO,UAAU;AAC1B;AAEO,SAAS,cAAc,OAA6B;AACzD,SAAO,SAAS,KAAK,KAAK,UAAU;AACtC;AAEO,SAAS,SAAS,OAAiC;AACxD,SAAO,OAAO,UAAU;AAC1B;AAEO,SAAS,YAAY,OAAoC;AAC9D,SAAO,OAAO,UAAU;AAC1B;AAEO,SAAS,WAAW,OAAqC;AAC9D,SAAO,OAAO,UAAU;AAC1B;AAEO,SAAS,UAAU,OAAkC;AAC1D,SAAO,OAAO,UAAU;AAC1B;AAEO,SAAS,SAAS,OAAiC;AACxD,SAAO,OAAO,UAAU;AAC1B;AAEO,SAAS,QAAQ,OAAgC;AACtD,SAAO,iBAAiB;AAC1B;AAEO,SAAS,QAAQ,OAAe;AACrC,SAAO,OAAO,KAAK,KAAK,EAAE,WAAW;AACvC;AAEO,SAAS,UAAa,UAAwC;AACnE,SAAO,CAAC,YAAY,QAAQ;AAC9B;AAEO,SAAS,aAAa,KAAiC;AAC5D,QAAM,aAAa,OAAO,eAAe,UAAU;AACnD,SAAO,eAAe;AACxB;AAGO,SAAS,OAAO;AAAC;AAEjB,SAAS,YAAe,OAAqB;AAClD,SAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAC9C;AAEO,SAAS,sBAAuC,KAAQ;AAC7D,SAAO,IAAI,SAAS,MAAM;AAC5B;AAIO,SAAS,YAAY,MAAoB;AAC9C,SAAO,CAAgC,eAAkB,WAAW,IAAI;AAC1E;AAEO,SAAS,aAAa,MAAiB;AAC5C,SAAO,KAAK,WAAW;AACzB;AAGO,IAAM,qBAAqB;AAI3B,SAAS,aAAa,OAA4B;AACvD,MAAI,OAAO,SAAS,KAAK,EAAG,QAAO,OAAO,KAAK,KAAK,EAAE,QAAQ;AAC9D,SAAO,IAAI,WAAW,MAAM,MAAM,EAAE,QAAQ,CAAC;AAC/C;AAEO,SAAS,gBAAgB,KAAa;AAC3C,SAAO,CAAC,GAAG,MAAM,GAAG,EAAE,KAAK,CAAC;AAC9B;AAEO,SAAS,sBAAsB,WAAmB,SAAiB;AACxE,QAAM,SAAS,CAAC;AAChB,WAAS,IAAI,WAAW,KAAK,SAAS,KAAK;AACzC,WAAO,KAAK,CAAC;AAAA,EACf;AACA,SAAO;AACT;AAEA,eAAsB,MAAM,IAAY;AACtC,SAAO,IAAI,QAAQ,aAAW,WAAW,SAAS,EAAE,CAAC;AACvD;AAEO,SAASC,YAAW,MAAgB;AACzC,SAAO,KAAK,OAAO,CAAC,KAAK,QAAQ,IAAI,KAAK,GAAG,GAAG,IAAIC,WAAU,CAAC,CAAC;AAClE;AAEO,SAAS,YAAe,GAA4D;AACzF,SAAO,EAAE,WAAW;AACtB;AAEO,SAAS,WAAc,GAAwD;AACpF,SAAO,EAAE,WAAW;AACtB;AAGO,SAAS,2BAA2B,YAAoB;AAC7D,SAAO,WAAW,MAAM,IAAI,EAAE,CAAC;AACjC;AAGO,SAAS,iBAAiB,SAAiB,MAAc;AAC9D,SAAO,GAAG,OAAO,IAAI,IAAI;AAC3B;AAEO,SAAS,wBAAwB,QAAgB;AACtD,SAAO,IAAI,MAAM,MAAM,EAAE,KAAK,IAAI;AACpC;AAEO,SAAS,oBAAoB,IAAY;AAC9C,QAAM,SAAS;AACf,MAAI,GAAG,WAAW,MAAM,EAAG,QAAO;AAClC,SAAO,SAAS;AAClB;AAEA,SAAS,UAAU,KAAa;AAC9B,SAAO,IAAI,QAAQ,aAAa,WAAS,MAAM,MAAM,YAAY,CAAC;AACpE;AAEA,SAAS,WAAW,QAAgB,SAAS,GAAG;AAC9C,SAAO,OAAO,MAAM,GAAG,MAAM;AAC/B;AAEO,SAAS,UAAU,OAAe;AACvC,MAAI,OAAO,UAAU,KAAK;AAC1B,MAAI,KAAK,SAAS,GAAG,GAAG;AACtB,UAAM,QAAQ,KAAK,MAAM,GAAG;AAC5B,QAAI,MAAM,UAAU,GAAG;AACrB,aAAO,GAAG,WAAW,MAAM,CAAC,CAAC,CAAC,GAAG,WAAW,MAAM,CAAC,CAAC,CAAC,GAAG,WAAW,MAAM,CAAC,CAAC,CAAC;AAAA,IAC9E,OAAO;AACL,aAAO,GAAG,WAAW,MAAM,CAAC,CAAC,CAAC,GAAG,WAAW,MAAM,CAAC,GAAG,CAAC,CAAC;AAAA,IAC1D;AAAA,EACF,WAAW,KAAK,UAAU,GAAG;AAC3B,WAAO,GAAG,WAAW,MAAM,CAAC,CAAC;AAAA,EAC/B;AACA,SAAO,KAAK,YAAY;AAC1B;AAEO,SAAS,cAAc,MAAc,OAAY;AACtD,SAAO,UAAU,KAAK,IAAI,EAAE,CAAC,IAAI,GAAG,MAAM,IAAI,CAAC;AACjD;AAEO,SAAS,YAAY,OAAe;AACzC,SAAO,iBAAiB,KAAK,KAAK;AACpC;AAEO,SAAS,YAAY,OAAe;AACzC,SAAO,MAAM,SAAS,EAAE;AAC1B;AAEO,SAAS,YAAY,KAAa;AACvC,SAAO,SAAS,KAAK,EAAE;AACzB;AAIO,SAAS,UACd,KACA,OACuB;AACvB,QAAM,SAAyC,CAAC;AAEhD,aAAW,OAAO,KAAK;AACrB,QAAI,OAAO,UAAU,eAAe,KAAK,KAAK,GAAG,GAAG;AAClD,aAAO,GAAG,IAAI,MAAM,IAAI,GAAG,GAAG,GAAG;AAAA,IACnC;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,eAAkB,KAAuC;AACvE,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,2BAA2B,GAAG,EAAE;AAC5D;AAEO,SAAS,WAAW,KAAa;AACtC,SAAO,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC;AAClD;AAEO,SAAS,YAAe,KAAU;AACvC,SAAO,MAAM,KAAK,IAAI,IAAI,GAAG,CAAC;AAChC;","names":["BigNumber","BigNumber","BigNumber","BigNumber","BigNumber","BigNumber","BigNumber","sumNumbers","BigNumber"]}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@leather.io/utils",
3
3
  "author": "Leather.io contact@leather.io",
4
4
  "description": "Shared bitcoin utilities",
5
- "version": "0.15.0",
5
+ "version": "0.16.1",
6
6
  "license": "MIT",
7
7
  "homepage": "https://github.com/leather-io/mono/tree/dev/packages/utils",
8
8
  "repository": {
@@ -17,12 +17,11 @@
17
17
  "bugs": "https://github.com/leather-io/mono/issues",
18
18
  "dependencies": {
19
19
  "bignumber.js": "9.1.2",
20
- "@leather.io/constants": "0.10.0",
21
- "@leather.io/models": "0.14.0",
22
- "@leather.io/rpc": "2.1.7"
20
+ "@leather.io/models": "0.16.0",
21
+ "@leather.io/constants": "0.12.0",
22
+ "@leather.io/rpc": "2.1.9"
23
23
  },
24
24
  "devDependencies": {
25
- "@vitest/coverage-istanbul": "0.34.6",
26
25
  "eslint": "8.53.0",
27
26
  "prettier": "3.3.3",
28
27
  "tsup": "8.1.0",
@@ -0,0 +1,37 @@
1
+ import { abbreviateNumber } from './abbreviate-number';
2
+
3
+ describe('abbreviateNumber', () => {
4
+ test('abbreviates numbers less than 1 thousand', () => {
5
+ expect(abbreviateNumber(0)).toBe('0');
6
+ expect(abbreviateNumber(999)).toBe('999');
7
+ });
8
+
9
+ test('abbreviates numbers between 1 thousand and 1 million', () => {
10
+ expect(abbreviateNumber(1000)).toBe('1K');
11
+ expect(abbreviateNumber(1500)).toBe('1.5K');
12
+ expect(abbreviateNumber(999999)).toBe('1000K');
13
+ });
14
+
15
+ test('abbreviates numbers between 1 million and 1 billion', () => {
16
+ expect(abbreviateNumber(1000000)).toBe('1M');
17
+ expect(abbreviateNumber(1500000)).toBe('1.5M');
18
+ expect(abbreviateNumber(999999999)).toBe('1000M');
19
+ });
20
+
21
+ test('abbreviates numbers 1 billion and above', () => {
22
+ expect(abbreviateNumber(1000000000)).toBe('1B');
23
+ expect(abbreviateNumber(1500000000)).toBe('1.5B');
24
+ expect(abbreviateNumber(1000000000000)).toBe('1T');
25
+ });
26
+
27
+ test('handles decimal numbers', () => {
28
+ expect(abbreviateNumber(1234.56)).toBe('1.23K');
29
+ expect(abbreviateNumber(1234567.89)).toBe('1.23M');
30
+ });
31
+
32
+ test('handles edge cases', () => {
33
+ expect(abbreviateNumber(999.9)).toBe('999.9');
34
+ expect(abbreviateNumber(999999.9)).toBe('1000K');
35
+ expect(abbreviateNumber(999999999.9)).toBe('1000M');
36
+ });
37
+ });
@@ -0,0 +1,8 @@
1
+ export function abbreviateNumber(n: number) {
2
+ if (n < 1e3) return n.toString();
3
+ if (n >= 1e3 && n < 1e6) return +(n / 1e3).toFixed(2) + 'K';
4
+ if (n >= 1e6 && n < 1e9) return +(n / 1e6).toFixed(2) + 'M';
5
+ if (n >= 1e9 && n < 1e12) return +(n / 1e9).toFixed(2) + 'B';
6
+ if (n >= 1e12) return +(n / 1e12).toFixed(2) + 'T';
7
+ return n.toString();
8
+ }
package/src/index.ts CHANGED
@@ -13,6 +13,8 @@ export * from './time';
13
13
  export { spamFilter } from './spam-filter/spam-filter';
14
14
  export { extractPhraseFromString } from './extract-phrase-from-string/extract-phrase-from-string';
15
15
  export { pxStringToNumber } from './px-string-to-number/px-string-to-number';
16
+ export { formatBalance } from './money/format-balance/format-balance';
17
+ export { abbreviateNumber } from './abbreviate-number/abbreviate-number';
16
18
 
17
19
  export function isNumber(value: unknown): value is number {
18
20
  return typeof value === 'number';
@@ -177,6 +179,10 @@ export function toHexString(value: number) {
177
179
  return value.toString(16);
178
180
  }
179
181
 
182
+ export function hexToNumber(hex: string) {
183
+ return parseInt(hex, 16);
184
+ }
185
+
180
186
  type MapFunction<T, U> = (value: T[keyof T], key: string) => U;
181
187
 
182
188
  export function mapObject<T extends object, U>(
@@ -201,3 +207,7 @@ export function assertIsTruthy<T>(val: T): asserts val is NonNullable<T> {
201
207
  export function capitalize(val: string) {
202
208
  return val.charAt(0).toUpperCase() + val.slice(1);
203
209
  }
210
+
211
+ export function uniqueArray<T>(arr: T[]) {
212
+ return Array.from(new Set(arr));
213
+ }
@@ -0,0 +1,31 @@
1
+ import { formatBalance } from './format-balance';
2
+
3
+ // TODO: revise this behaviour and make sure it's intentional
4
+ describe('formatBalance', () => {
5
+ test('handles string inputs correctly', () => {
6
+ expect(formatBalance('1,000').value).toBe('1,000');
7
+ expect(formatBalance('1,000.5').value).toBe('1,000.5');
8
+ expect(formatBalance('1000.5').value).toBe('1000.5');
9
+ expect(formatBalance('1000000').value).toBe('1M');
10
+ expect(formatBalance('1000000000').value).toBe('1B');
11
+ expect(formatBalance('1000000000000').value).toBe('1T');
12
+ });
13
+
14
+ test('throws error for invalid inputs', () => {
15
+ expect(() => formatBalance('invalid')).toThrow(
16
+ 'Invalid input: amount must be a non-empty string representing a valid number'
17
+ );
18
+ expect(() => formatBalance(null as any)).toThrow(
19
+ 'Invalid input: amount must be a non-empty string representing a valid number'
20
+ );
21
+ expect(() => formatBalance(undefined as any)).toThrow(
22
+ 'Invalid input: amount must be a non-empty string representing a valid number'
23
+ );
24
+ expect(() => formatBalance({} as any)).toThrow(
25
+ 'Invalid input: amount must be a non-empty string representing a valid number'
26
+ );
27
+ expect(() => formatBalance([] as any)).toThrow(
28
+ 'Invalid input: amount must be a non-empty string representing a valid number'
29
+ );
30
+ });
31
+ });
@@ -0,0 +1,22 @@
1
+ import { abbreviateNumber } from '../../abbreviate-number/abbreviate-number';
2
+ import { removeCommas } from './remove-commas';
3
+
4
+ /**
5
+ * TODO: investigate improving
6
+ * @param amount is a string
7
+ * in the extension we pre-convert it from Money with formatMoneyWithoutSymbol
8
+ */
9
+ export function formatBalance(amount: string) {
10
+ if (typeof amount !== 'string' || amount.trim() === '' || isNaN(Number(removeCommas(amount)))) {
11
+ throw new Error('Invalid input: amount must be a non-empty string representing a valid number');
12
+ }
13
+
14
+ const noCommas = removeCommas(amount);
15
+ const number = noCommas.includes('.') ? parseFloat(noCommas) : parseInt(noCommas);
16
+ return number > 10000
17
+ ? {
18
+ isAbbreviated: true,
19
+ value: abbreviateNumber(number),
20
+ }
21
+ : { isAbbreviated: false, value: amount };
22
+ }
@@ -0,0 +1,41 @@
1
+ import { removeCommas } from './remove-commas';
2
+
3
+ describe('removeCommas', () => {
4
+ test('removes commas from a string with commas', () => {
5
+ expect(removeCommas('1,000,000')).toBe('1000000');
6
+ });
7
+
8
+ test('returns the same string if there are no commas', () => {
9
+ expect(removeCommas('1000000')).toBe('1000000');
10
+ });
11
+
12
+ test('handles decimal numbers correctly', () => {
13
+ expect(removeCommas('1,234,567.89')).toBe('1234567.89');
14
+ });
15
+
16
+ test('handles string with only commas', () => {
17
+ expect(removeCommas(',,,,')).toBe('');
18
+ });
19
+
20
+ test('handles empty string', () => {
21
+ expect(removeCommas('')).toBe('');
22
+ });
23
+ test('throws an error if input is not a string', () => {
24
+ expect(() => removeCommas(123 as any)).toThrow('Amount with commas must be a string');
25
+ expect(() => removeCommas(null as any)).toThrow('Amount with commas must be a string');
26
+ expect(() => removeCommas(undefined as any)).toThrow('Amount with commas must be a string');
27
+ expect(() => removeCommas({} as any)).toThrow('Amount with commas must be a string');
28
+ });
29
+
30
+ test('handles string with commas in different positions', () => {
31
+ expect(removeCommas('1,00,0,00')).toBe('100000');
32
+ });
33
+
34
+ test('handles string with spaces and commas', () => {
35
+ expect(removeCommas('1, 000, 000')).toBe('1 000 000');
36
+ });
37
+
38
+ test('handles string with non-numeric characters', () => {
39
+ expect(removeCommas('1,000,abc,123')).toBe('1000abc123');
40
+ });
41
+ });
@@ -0,0 +1,6 @@
1
+ export function removeCommas(amountWithCommas: string) {
2
+ if (typeof amountWithCommas !== 'string') {
3
+ throw new Error('Amount with commas must be a string');
4
+ }
5
+ return amountWithCommas.replace(/,/g, '');
6
+ }