@leather.io/utils 0.9.0

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.
package/dist/index.js ADDED
@@ -0,0 +1,453 @@
1
+ // src/index.ts
2
+ import { BigNumber as BigNumber5 } from "bignumber.js";
3
+ import { KEBAB_REGEX } from "@leather.io/constants";
4
+
5
+ // src/counter.ts
6
+ function createCounter(startPosition = 0) {
7
+ let count = startPosition;
8
+ return {
9
+ getValue() {
10
+ return count;
11
+ },
12
+ increment() {
13
+ return count += 1;
14
+ },
15
+ incrementBy(amount) {
16
+ return count += amount;
17
+ },
18
+ decrement() {
19
+ return count -= 1;
20
+ }
21
+ };
22
+ }
23
+
24
+ // src/math/calculate-averages.ts
25
+ import BigNumber2 from "bignumber.js";
26
+
27
+ // src/math/helpers.ts
28
+ import BigNumber from "bignumber.js";
29
+ function initBigNumber(num) {
30
+ if (BigNumber.isBigNumber(num)) return num;
31
+ return isBigInt(num) ? new BigNumber(num.toString()) : new BigNumber(num);
32
+ }
33
+ function sumNumbers(nums) {
34
+ return nums.reduce((acc, num) => acc.plus(num), new BigNumber(0));
35
+ }
36
+ function isMultipleOf(multiple) {
37
+ return (num) => num % multiple === 0;
38
+ }
39
+ function isEven(num) {
40
+ return isMultipleOf(2)(num);
41
+ }
42
+ function countDecimals(num) {
43
+ const LARGE_NUMBER_OF_DECIMALS = 100;
44
+ BigNumber.config({ DECIMAL_PLACES: LARGE_NUMBER_OF_DECIMALS });
45
+ const amount = initBigNumber(num);
46
+ const decimals = amount.toString(10).split(".")[1];
47
+ return decimals ? decimals.length : 0;
48
+ }
49
+ function increaseValueByOneMicroStx(value) {
50
+ return new BigNumber(value).plus(1e-6).toNumber();
51
+ }
52
+
53
+ // src/math/calculate-averages.ts
54
+ function calculateMeanAverage(numbers) {
55
+ if (numbers.length === 0) return new BigNumber2(0);
56
+ return numbers.map(initBigNumber).reduce((acc, price) => acc.plus(price), new BigNumber2(0)).dividedBy(numbers.length);
57
+ }
58
+
59
+ // src/math/fibonacci.ts
60
+ function fibonacci(n = 0) {
61
+ if (n < 0) throw "Cannot calculate from negative number";
62
+ if (n < 2) return n;
63
+ return fibonacci(n - 1) + fibonacci(n - 2);
64
+ }
65
+ function* fibonacciGenerator(startIndex = 0) {
66
+ let index = startIndex;
67
+ while (index < Infinity) yield fibonacci(index++);
68
+ return Infinity;
69
+ }
70
+
71
+ // src/money/calculate-money.ts
72
+ import { formatMarketPair } from "@leather.io/models";
73
+
74
+ // src/money/format-money.ts
75
+ import BigNumber3 from "bignumber.js";
76
+ import { currencyDecimalsMap } from "@leather.io/constants";
77
+ function isResolutionOfCurrencyKnown(symbol) {
78
+ return symbol in currencyDecimalsMap;
79
+ }
80
+ function getDecimalsOfSymbolIfKnown(symbol) {
81
+ if (isResolutionOfCurrencyKnown(symbol)) return currencyDecimalsMap[symbol];
82
+ return null;
83
+ }
84
+ function throwWhenDecimalUnknown(symbol, decimals) {
85
+ if (isUndefined(decimals) && isUndefined(getDecimalsOfSymbolIfKnown(symbol)))
86
+ throw new Error(`Resolution of currency ${symbol} is unknown, must be described`);
87
+ }
88
+ function createMoneyFromDecimal(value, symbol, resolution) {
89
+ throwWhenDecimalUnknown(symbol, resolution);
90
+ const decimals = getDecimalsOfSymbolIfKnown(symbol) ?? resolution;
91
+ const amount = new BigNumber3(isBigInt(value) ? value.toString() : value).shiftedBy(decimals);
92
+ return Object.freeze({ amount, symbol, decimals });
93
+ }
94
+ function createMoney(value, symbol, resolution) {
95
+ throwWhenDecimalUnknown(symbol, resolution);
96
+ const decimals = getDecimalsOfSymbolIfKnown(symbol) ?? resolution;
97
+ const amount = new BigNumber3(isBigInt(value) ? value.toString() : value);
98
+ return Object.freeze({ amount, symbol, decimals });
99
+ }
100
+ var thinSpace = "\u2009";
101
+ function formatMoney({ amount, symbol, decimals }) {
102
+ return `${amount.shiftedBy(-decimals).toString()} ${symbol}`;
103
+ }
104
+ function formatMoneyWithoutSymbol({ amount, decimals }) {
105
+ return `${amount.shiftedBy(-decimals).toString()}`;
106
+ }
107
+ function formatMoneyPadded({ amount, symbol, decimals }) {
108
+ return `${amount.shiftedBy(-decimals).toFormat(decimals)} ${symbol}`;
109
+ }
110
+ function i18nFormatCurrency(quantity, decimals = 2) {
111
+ if (quantity.symbol !== "USD") throw new Error("Cannot format non-USD amounts");
112
+ const currencyFormatter = new Intl.NumberFormat("en-US", {
113
+ style: "currency",
114
+ currency: "USD",
115
+ maximumFractionDigits: decimals
116
+ });
117
+ const formatted = currencyFormatter.format(
118
+ quantity.amount.shiftedBy(-quantity.decimals).toNumber()
119
+ );
120
+ if (quantity.amount.isGreaterThan(0) && formatted === "$0.00")
121
+ return "<" + thinSpace + formatted.replace("0.00", "0.01");
122
+ return formatted;
123
+ }
124
+ function formatDustUsdAmounts(value) {
125
+ return value.endsWith("0.00") ? "<" + thinSpace + value.replace("0.00", "0.01") : value;
126
+ }
127
+
128
+ // src/money/is-money.ts
129
+ import BigNumber4 from "bignumber.js";
130
+ function isMoney(val) {
131
+ if (!isObject(val)) return false;
132
+ return "amount" in val && "symbol" in val && "decimals" in val;
133
+ }
134
+ function isMoneyGreaterThanZero(money) {
135
+ if (!BigNumber4.isBigNumber(money.amount)) return;
136
+ return !(money.amount.isNaN() || money.amount.isZero());
137
+ }
138
+
139
+ // src/money/calculate-money.ts
140
+ function baseCurrencyAmountInQuote(quantity, { pair, price }) {
141
+ if (quantity.symbol !== pair.base)
142
+ throw new Error(
143
+ `Cannot calculate value of ${formatMoney(quantity)} with market pair of ${formatMarketPair(
144
+ pair
145
+ )}`
146
+ );
147
+ return createMoney(
148
+ convertAmountToFractionalUnit(
149
+ convertAmountToBaseUnit(quantity).times(convertAmountToBaseUnit(price)),
150
+ price.decimals
151
+ ),
152
+ pair.quote
153
+ );
154
+ }
155
+ function convertAmountToFractionalUnit(num, decimals) {
156
+ if (isMoney(num)) return num.amount.shiftedBy(num.decimals);
157
+ if (!isNumber(decimals)) throw new Error("Must define decimal of given currency");
158
+ return num.shiftedBy(decimals);
159
+ }
160
+ function convertToMoneyTypeWithDefaultOfZero(symbol, num, decimals) {
161
+ return createMoney(initBigNumber(num ?? 0), symbol.toUpperCase(), decimals);
162
+ }
163
+ function convertAmountToBaseUnit(num, decimals) {
164
+ if (isMoney(num)) return num.amount.shiftedBy(-num.decimals);
165
+ if (!isNumber(decimals)) throw new Error("Must define decimal of given currency");
166
+ return num.shiftedBy(-decimals);
167
+ }
168
+ function subtractMoney(xAmount, yAmount) {
169
+ if (xAmount.symbol !== yAmount.symbol) throw new Error("Cannot subtract different currencies");
170
+ return createMoney(xAmount.amount.minus(yAmount.amount), xAmount.symbol, xAmount.decimals);
171
+ }
172
+ function sumMoney(moneysArr) {
173
+ if (moneysArr.some((item) => item.symbol !== moneysArr[0].symbol))
174
+ throw new Error("Cannot sum different currencies");
175
+ const sum = sumNumbers(moneysArr.map((item) => item.amount.toNumber()));
176
+ return createMoney(sum, moneysArr[0].symbol, moneysArr[0].decimals);
177
+ }
178
+
179
+ // src/money/unit-conversion.ts
180
+ import { BTC_DECIMALS, STX_DECIMALS } from "@leather.io/constants";
181
+ function fractionalUnitToUnit(decimals) {
182
+ return (unit) => {
183
+ const unitBigNumber = initBigNumber(unit);
184
+ return unitBigNumber.shiftedBy(-decimals);
185
+ };
186
+ }
187
+ function unitToFractionalUnit(decimals) {
188
+ return (unit) => {
189
+ const unitBigNumber = initBigNumber(unit);
190
+ return unitBigNumber.shiftedBy(decimals);
191
+ };
192
+ }
193
+ var satToBtc = fractionalUnitToUnit(BTC_DECIMALS);
194
+ var btcToSat = unitToFractionalUnit(BTC_DECIMALS);
195
+ var microStxToStx = fractionalUnitToUnit(STX_DECIMALS);
196
+ var stxToMicroStx = unitToFractionalUnit(STX_DECIMALS);
197
+ function moneyToBaseUnit(sum) {
198
+ return fractionalUnitToUnit(sum.decimals)(sum.amount);
199
+ }
200
+
201
+ // src/sort-assets.ts
202
+ function sortAssetsByName(assets) {
203
+ return assets.sort((a, b) => {
204
+ if (a.name < b.name) return -1;
205
+ if (a.name > b.name) return 1;
206
+ return 0;
207
+ }).sort((a, b) => {
208
+ if (a.name === "STX") return -1;
209
+ if (b.name !== "STX") return 1;
210
+ return 0;
211
+ }).sort((a, b) => {
212
+ if (a.name === "BTC") return -1;
213
+ if (b.name !== "BTC") return 1;
214
+ return 0;
215
+ });
216
+ }
217
+ function migratePositiveAssetBalancesToTop(assets) {
218
+ const assetsWithPositiveBalance = assets.filter((asset) => asset.balance.amount.isGreaterThan(0));
219
+ const assetsWithZeroBalance = assets.filter((asset) => asset.balance.amount.isEqualTo(0));
220
+ return [...assetsWithPositiveBalance, ...assetsWithZeroBalance];
221
+ }
222
+
223
+ // src/truncate-middle.ts
224
+ function truncateHex(hex, offset = 5) {
225
+ return `${hex.substring(0, offset + 2)}\u2026${hex.substring(hex.length - offset)}`;
226
+ }
227
+ function truncateMiddle(input, offset = 5) {
228
+ if (!input) return "";
229
+ if (input.startsWith("0x")) {
230
+ return truncateHex(input, offset);
231
+ }
232
+ if (input.includes(".")) {
233
+ const parts = input.split(".");
234
+ const start = parts[0]?.substring(0, offset);
235
+ const end = parts[0]?.substring(parts[0].length - offset, parts[0].length);
236
+ return `${start}\u2026${end}.${parts[1]}`;
237
+ } else {
238
+ const start = input?.substring(0, offset);
239
+ const end = input?.substring(input.length - offset, input.length);
240
+ return `${start}\u2026${end}`;
241
+ }
242
+ }
243
+
244
+ // src/spam-filter/spam-filter.ts
245
+ var urlRegex = /(http|https|ftp)|(((http|ftp|https):\/\/)?(((http|ftp|https):\/\/)?(([\w.-]*)\.([\w]*))))/g;
246
+ var spamWords = ["won", "win", "click"];
247
+ var spamReplacement = "Unknown token";
248
+ function spamUrlFilter(input) {
249
+ return input.match(urlRegex);
250
+ }
251
+ function spamWordFilter(input) {
252
+ const containsSpam = (element) => input.toLowerCase().includes(element);
253
+ return spamWords.some(containsSpam);
254
+ }
255
+ function spamFilter(input) {
256
+ const urlFound = spamUrlFilter(input);
257
+ const spamWordsFound = spamWordFilter(input);
258
+ if (urlFound || spamWordsFound) {
259
+ return spamReplacement;
260
+ }
261
+ return input;
262
+ }
263
+
264
+ // src/extract-phrase-from-string/extract-phrase-from-string.ts
265
+ function extractPhraseFromString(value) {
266
+ const clean = value.trim();
267
+ const words = clean.match(/\S+/g);
268
+ if (words?.length) {
269
+ return words.map((word) => word.match(/[^0-9]+/g) ? word : null).filter(Boolean).join(" ");
270
+ } else {
271
+ return clean;
272
+ }
273
+ }
274
+
275
+ // src/index.ts
276
+ function isNumber(value) {
277
+ return typeof value === "number";
278
+ }
279
+ function isString(value) {
280
+ return typeof value === "string";
281
+ }
282
+ function isBigInt(value) {
283
+ return typeof value === "bigint";
284
+ }
285
+ function isUndefined(value) {
286
+ return typeof value === "undefined";
287
+ }
288
+ function isFunction(value) {
289
+ return typeof value === "function";
290
+ }
291
+ function isBoolean(value) {
292
+ return typeof value === "boolean";
293
+ }
294
+ function isObject(value) {
295
+ return typeof value === "object";
296
+ }
297
+ function isError(value) {
298
+ return value instanceof Error;
299
+ }
300
+ function isEmpty(value) {
301
+ return Object.keys(value).length === 0;
302
+ }
303
+ function isDefined(argument) {
304
+ return !isUndefined(argument);
305
+ }
306
+ function isTypedArray(val) {
307
+ const TypedArray = Object.getPrototypeOf(Uint8Array);
308
+ return val instanceof TypedArray;
309
+ }
310
+ function noop() {
311
+ }
312
+ function ensureArray(value) {
313
+ return Array.isArray(value) ? value : [value];
314
+ }
315
+ function undefinedIfLengthZero(arr) {
316
+ return arr.length ? arr : void 0;
317
+ }
318
+ function whenNetwork(mode) {
319
+ return (networkMap) => networkMap[mode];
320
+ }
321
+ function isEmptyArray(data) {
322
+ return data.length === 0;
323
+ }
324
+ var defaultWalletKeyId = "default";
325
+ function reverseBytes(bytes) {
326
+ if (Buffer.isBuffer(bytes)) return Buffer.from(bytes).reverse();
327
+ return new Uint8Array(bytes.slice().reverse());
328
+ }
329
+ function makeNumberRange(num) {
330
+ return [...Array(num).keys()];
331
+ }
332
+ function createNumArrayOfRange(fromIndex, toIndex) {
333
+ const result = [];
334
+ for (let i = fromIndex; i <= toIndex; i++) {
335
+ result.push(i);
336
+ }
337
+ return result;
338
+ }
339
+ async function delay(ms) {
340
+ return new Promise((resolve) => setTimeout(resolve, ms));
341
+ }
342
+ function sumNumbers2(nums) {
343
+ return nums.reduce((acc, num) => acc.plus(num), new BigNumber5(0));
344
+ }
345
+ function isFulfilled(p) {
346
+ return p.status === "fulfilled";
347
+ }
348
+ function isRejected(p) {
349
+ return p.status === "rejected";
350
+ }
351
+ function getPrincipalFromContractId(identifier) {
352
+ return identifier.split("::")[0];
353
+ }
354
+ function formatContractId(address, name) {
355
+ return `${address}.${name}`;
356
+ }
357
+ function createNullArrayOfLength(length) {
358
+ return new Array(length).fill(null);
359
+ }
360
+ function safelyFormatHexTxid(id) {
361
+ const prefix = "0x";
362
+ if (id.startsWith(prefix)) return id;
363
+ return prefix + id;
364
+ }
365
+ function kebabCase(str) {
366
+ return str.replace(KEBAB_REGEX, (match) => "-" + match.toLowerCase());
367
+ }
368
+ function getLetters(string, offset = 1) {
369
+ return string.slice(0, offset);
370
+ }
371
+ function getTicker(value) {
372
+ let name = kebabCase(value);
373
+ if (name.includes("-")) {
374
+ const words = name.split("-");
375
+ if (words.length >= 3) {
376
+ name = `${getLetters(words[0])}${getLetters(words[1])}${getLetters(words[2])}`;
377
+ } else {
378
+ name = `${getLetters(words[0])}${getLetters(words[1], 2)}`;
379
+ }
380
+ } else if (name.length >= 3) {
381
+ name = `${getLetters(name, 3)}`;
382
+ }
383
+ return name.toUpperCase();
384
+ }
385
+ function propIfDefined(prop, value) {
386
+ return isBoolean(value) ? { [prop]: value } : {};
387
+ }
388
+ export {
389
+ baseCurrencyAmountInQuote,
390
+ btcToSat,
391
+ calculateMeanAverage,
392
+ convertAmountToBaseUnit,
393
+ convertAmountToFractionalUnit,
394
+ convertToMoneyTypeWithDefaultOfZero,
395
+ countDecimals,
396
+ createCounter,
397
+ createMoney,
398
+ createMoneyFromDecimal,
399
+ createNullArrayOfLength,
400
+ createNumArrayOfRange,
401
+ defaultWalletKeyId,
402
+ delay,
403
+ ensureArray,
404
+ extractPhraseFromString,
405
+ fibonacciGenerator,
406
+ formatContractId,
407
+ formatDustUsdAmounts,
408
+ formatMoney,
409
+ formatMoneyPadded,
410
+ formatMoneyWithoutSymbol,
411
+ getPrincipalFromContractId,
412
+ getTicker,
413
+ i18nFormatCurrency,
414
+ increaseValueByOneMicroStx,
415
+ initBigNumber,
416
+ isBigInt,
417
+ isBoolean,
418
+ isDefined,
419
+ isEmpty,
420
+ isEmptyArray,
421
+ isError,
422
+ isEven,
423
+ isFulfilled,
424
+ isFunction,
425
+ isMoney,
426
+ isMoneyGreaterThanZero,
427
+ isNumber,
428
+ isObject,
429
+ isRejected,
430
+ isString,
431
+ isTypedArray,
432
+ isUndefined,
433
+ makeNumberRange,
434
+ microStxToStx,
435
+ migratePositiveAssetBalancesToTop,
436
+ moneyToBaseUnit,
437
+ noop,
438
+ propIfDefined,
439
+ reverseBytes,
440
+ safelyFormatHexTxid,
441
+ satToBtc,
442
+ sortAssetsByName,
443
+ spamFilter,
444
+ stxToMicroStx,
445
+ subtractMoney,
446
+ sumMoney,
447
+ sumNumbers2 as sumNumbers,
448
+ truncateMiddle,
449
+ undefinedIfLengthZero,
450
+ unitToFractionalUnit,
451
+ whenNetwork
452
+ };
453
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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/spam-filter/spam-filter.ts","../src/extract-phrase-from-string/extract-phrase-from-string.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 { spamFilter } from './spam-filter/spam-filter';\nexport { extractPhraseFromString } from './extract-phrase-from-string/extract-phrase-from-string';\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 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\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\nexport function getPrincipalFromContractId(identifier: string) {\n return identifier.split('::')[0];\n}\n\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","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, Money, NumType } from '@leather.io/models';\nimport { 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 { Currencies, Money, NumType } from '@leather.io/models';\n\nimport { isBigInt, isUndefined } from '..';\n\ntype KnownCurrencyDecimals = keyof typeof currencyDecimalsMap;\n\nfunction isResolutionOfCurrencyKnown(symbol: Currencies): symbol is KnownCurrencyDecimals {\n return symbol in currencyDecimalsMap;\n}\n\nfunction getDecimalsOfSymbolIfKnown(symbol: Currencies) {\n if (isResolutionOfCurrencyKnown(symbol)) return currencyDecimalsMap[symbol];\n return null;\n}\n\nfunction throwWhenDecimalUnknown(\n symbol: Currencies,\n decimals?: number\n): 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: Currencies,\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: Currencies, 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","const urlRegex =\n /(http|https|ftp)|(((http|ftp|https):\\/\\/)?(((http|ftp|https):\\/\\/)?(([\\w.-]*)\\.([\\w]*))))/g;\nconst spamWords = ['won', 'win', 'click'];\nexport const spamReplacement = 'Unknown 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"],"mappings":"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","names":["BigNumber","BigNumber","BigNumber","BigNumber","BigNumber","BigNumber","BigNumber","sumNumbers","BigNumber"]}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@leather.io/utils",
3
+ "author": "Leather.io contact@leather.io",
4
+ "description": "Shared bitcoin utilities",
5
+ "version": "0.9.0",
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/leather-io/mono/tree/dev/packages/utils",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git@github.com:leather-io/mono.git",
11
+ "directory": "packages/utils"
12
+ },
13
+ "type": "module",
14
+ "exports": {
15
+ ".": "./dist/index.js"
16
+ },
17
+ "bugs": "https://github.com/leather-io/mono/issues",
18
+ "dependencies": {
19
+ "bignumber.js": "9.1.2",
20
+ "@leather.io/constants": "0.8.0",
21
+ "@leather.io/models": "0.10.0",
22
+ "@leather.io/rpc": "2.0.0"
23
+ },
24
+ "devDependencies": {
25
+ "@vitest/coverage-istanbul": "0.34.6",
26
+ "eslint": "8.53.0",
27
+ "prettier": "3.3.0",
28
+ "tsup": "8.1.0",
29
+ "typescript": "5.4.5",
30
+ "vitest": "0.34.6",
31
+ "@leather.io/eslint-config": "0.6.0",
32
+ "@leather.io/prettier-config": "0.5.0",
33
+ "@leather.io/tsconfig-config": "0.5.0"
34
+ },
35
+ "keywords": [
36
+ "leather",
37
+ "leather wallet",
38
+ "utils"
39
+ ],
40
+ "prettier": "@leather.io/prettier-config",
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "scripts": {
45
+ "build": "tsup",
46
+ "build:watch": "tsup --watch",
47
+ "format": "prettier . --write --ignore-path ../../.prettierignore",
48
+ "format:check": "prettier . --check --ignore-path ../../.prettierignore",
49
+ "lint": "eslint . --ignore-path ../../.eslintignore",
50
+ "lint:fix": "eslint . --fix --ignore-path ../../.eslintignore",
51
+ "test:coverage": "vitest run --coverage",
52
+ "test:unit": "vitest run",
53
+ "typecheck": "tsc --noEmit"
54
+ }
55
+ }
package/src/counter.ts ADDED
@@ -0,0 +1,17 @@
1
+ export function createCounter(startPosition = 0) {
2
+ let count = startPosition;
3
+ return {
4
+ getValue() {
5
+ return count;
6
+ },
7
+ increment() {
8
+ return (count += 1);
9
+ },
10
+ incrementBy(amount: number) {
11
+ return (count += amount);
12
+ },
13
+ decrement() {
14
+ return (count -= 1);
15
+ },
16
+ };
17
+ }
@@ -0,0 +1,79 @@
1
+ import { extractPhraseFromString } from './extract-phrase-from-string';
2
+
3
+ const SECRET_KEY_FORMATTED_POORLY = `1 balance
4
+ 2 adult
5
+ 3 board
6
+ 4 true
7
+ 5 diary
8
+ pear banana olympic street enhance
9
+
10
+ gift rely account patient stereo one
11
+
12
+ during banner shift globe romance
13
+
14
+ arrange dolphin disease`;
15
+
16
+ const SECRET_KEY_FORMATTED_CORRECTLY = `balance adult board true diary pear banana olympic street enhance gift rely account patient stereo one during banner shift globe romance arrange dolphin disease`;
17
+
18
+ const SECRET_KEY_COPIED_FROM_v3 = `1
19
+ almost
20
+ 2
21
+ dumb
22
+ 3
23
+ wave
24
+ 4
25
+ rude
26
+ 5
27
+ surround
28
+ 6
29
+ jealous
30
+ 7
31
+ shine
32
+ 8
33
+ fruit
34
+ 9
35
+ toward
36
+ 10
37
+ method
38
+ 11
39
+ yard
40
+ 12
41
+ ribbon
42
+ 13
43
+ gold
44
+ 14
45
+ acid
46
+ 15
47
+ cute
48
+ 16
49
+ police
50
+ 17
51
+ team
52
+ 18
53
+ time
54
+ 19
55
+ this
56
+ 20
57
+ easy
58
+ 21
59
+ heavy
60
+ 22
61
+ fuel
62
+ 23
63
+ trash
64
+ 24
65
+ swing`;
66
+
67
+ const SECRET_KEY_COPIED_FROM_V3_FORMATTED = `almost dumb wave rude surround jealous shine fruit toward method yard ribbon gold acid cute police team time this easy heavy fuel trash swing`;
68
+
69
+ describe(extractPhraseFromString.name, () => {
70
+ test('Extract secret key from poorly formatted string', () => {
71
+ const key = extractPhraseFromString(SECRET_KEY_FORMATTED_POORLY);
72
+ expect(key).toEqual(SECRET_KEY_FORMATTED_CORRECTLY);
73
+ });
74
+
75
+ test('Extract secret key from seed copied from v3 wallet', () => {
76
+ const key = extractPhraseFromString(SECRET_KEY_COPIED_FROM_v3);
77
+ expect(key).toEqual(SECRET_KEY_COPIED_FROM_V3_FORMATTED);
78
+ });
79
+ });
@@ -0,0 +1,12 @@
1
+ export function extractPhraseFromString(value: string) {
2
+ const clean = value.trim();
3
+ const words = clean.match(/\S+/g);
4
+ if (words?.length) {
5
+ return words
6
+ .map(word => (word.match(/[^0-9]+/g) ? word : null))
7
+ .filter(Boolean)
8
+ .join(' ');
9
+ } else {
10
+ return clean;
11
+ }
12
+ }