From 06c9f6df04d365177d7888b5da7a7fd78b09ff10 Mon Sep 17 00:00:00 2001 From: michael1011 Date: Tue, 10 Oct 2023 01:50:30 +0200 Subject: [PATCH] feat: use satcomma to format notification amounts --- lib/DenominationConverter.ts | 31 ++- lib/data/Stats.ts | 4 +- lib/notifications/BalanceChecker.ts | 18 +- lib/notifications/CommandHandler.ts | 14 +- lib/notifications/NotificationProvider.ts | 36 +--- package-lock.json | 176 +++++++++--------- package.json | 6 +- test/unit/DenominationConverter.spec.ts | 33 ++++ .../unit/notifications/BalanceChecker.spec.ts | 22 +-- .../unit/notifications/CommandHandler.spec.ts | 24 +-- .../NotificationProvider.spec.ts | 73 ++++---- 11 files changed, 232 insertions(+), 205 deletions(-) diff --git a/lib/DenominationConverter.ts b/lib/DenominationConverter.ts index dce19b65..2766f75c 100644 --- a/lib/DenominationConverter.ts +++ b/lib/DenominationConverter.ts @@ -1,22 +1,41 @@ -const decimals = 100_000_000; +const decimals = 8; +const satFactor = 100_000_000; + +/** + * Round a number to a specific amount of decimals + */ +const roundToDecimals = (number: number, decimals: number): number => { + return Number(number.toFixed(decimals)); +}; /** * Convert whole coins to satoshis */ export const coinsToSatoshis = (coins: number): number => { - return coins * decimals; + return coins * satFactor; }; /** * Convert satoshis to whole coins and remove trailing zeros */ export const satoshisToCoins = (satoshis: number): number => { - return roundToDecimals(satoshis / decimals, 8); + return roundToDecimals(satoshis / satFactor, decimals); }; /** - * Round a number to a specific amount of decimals + * Convert satoshis to whole coins with trailing zeros */ -const roundToDecimals = (number: number, decimals: number): number => { - return Number(number.toFixed(decimals)); +export const satoshisToPaddedCoins = (satoshis: number): string => { + return (satoshis / satFactor).toFixed(decimals); +}; + +export const satoshisToSatcomma = (satoshis: number): string => { + let coins = (satoshis / satFactor).toFixed(decimals); + for (const [num, index] of [3, 6].entries()) { + coins = `${coins.substring( + 0, + coins.length - index - num, + )},${coins.substring(coins.length - index - num)}`; + } + return coins; }; diff --git a/lib/data/Stats.ts b/lib/data/Stats.ts index 067ad4a3..8043217f 100644 --- a/lib/data/Stats.ts +++ b/lib/data/Stats.ts @@ -1,5 +1,5 @@ import { getNestedObject } from './Utils'; -import { satoshisToCoins } from '../DenominationConverter'; +import { satoshisToPaddedCoins } from '../DenominationConverter'; import StatsRepository, { StatsDate } from '../db/repositories/StatsRepository'; type MonthStats = { @@ -32,7 +32,7 @@ class Stats { volumes.forEach((volume) => { const obj = getNestedObject(getMonthObj(volume), 'volume'); - obj[volume.pair || Stats.totalString] = satoshisToCoins(volume.sum); + obj[volume.pair || Stats.totalString] = satoshisToPaddedCoins(volume.sum); }); tradeCounts.forEach((counts) => { diff --git a/lib/notifications/BalanceChecker.ts b/lib/notifications/BalanceChecker.ts index 91ae15e6..b7a7ccd2 100644 --- a/lib/notifications/BalanceChecker.ts +++ b/lib/notifications/BalanceChecker.ts @@ -4,8 +4,8 @@ import Service from '../service/Service'; import DiscordClient from './DiscordClient'; import { Balances } from '../proto/boltzrpc_pb'; import { liquidSymbol } from '../consts/LiquidTypes'; -import { satoshisToCoins } from '../DenominationConverter'; import { BaseCurrencyConfig, TokenConfig } from '../Config'; +import { satoshisToSatcomma } from '../DenominationConverter'; enum BalanceType { Wallet, @@ -152,7 +152,7 @@ class BalanceChecker { if (type === BalanceType.Wallet) { message = `${ Emojis.Checkmark - } ${name} wallet balance of ${satoshisToCoins( + } ${name} wallet balance of ${satoshisToSatcomma( balance, )} is in bounds again ${Emojis.Checkmark}`; } else { @@ -160,8 +160,8 @@ class BalanceChecker { `${Emojis.Checkmark} ${name} ${ type === BalanceType.ChannelLocal ? 'local' : 'remote' } channel balance ` + - `of ${satoshisToCoins(balance)} is more than expected ` + - `${satoshisToCoins( + `of ${satoshisToSatcomma(balance)} is more than expected ` + + `${satoshisToSatcomma( type === BalanceType.ChannelLocal ? currency.minLocalBalance! : currency.minRemoteBalance!, @@ -171,20 +171,20 @@ class BalanceChecker { if (type === BalanceType.Wallet) { message = `${Emojis.RotatingLight} **${name} wallet balance is out of bounds** ${Emojis.RotatingLight}\n` + - ` Balance: ${satoshisToCoins(balance)}\n` + + ` Balance: ${satoshisToSatcomma(balance)}\n` + `${ currency.maxWalletBalance - ? ` Max: ${satoshisToCoins(currency.maxWalletBalance)}\n` + ? ` Max: ${satoshisToSatcomma(currency.maxWalletBalance)}\n` : '' }` + - ` Min: ${satoshisToCoins(currency.minWalletBalance)}`; + ` Min: ${satoshisToSatcomma(currency.minWalletBalance)}`; } else { message = `${Emojis.RotatingLight} **${name} ${ type === BalanceType.ChannelLocal ? 'local' : 'remote' } channel balance ` + - `of ${satoshisToCoins(balance)} is less than expected ` + - `${satoshisToCoins( + `of ${satoshisToSatcomma(balance)} is less than expected ` + + `${satoshisToSatcomma( type === BalanceType.ChannelLocal ? currency.minLocalBalance! : currency.minRemoteBalance!, diff --git a/lib/notifications/CommandHandler.ts b/lib/notifications/CommandHandler.ts index acf13a8d..6935ef69 100644 --- a/lib/notifications/CommandHandler.ts +++ b/lib/notifications/CommandHandler.ts @@ -14,8 +14,8 @@ import BackupScheduler from '../backup/BackupScheduler'; import ChannelCreation from '../db/models/ChannelCreation'; import FeeRepository from '../db/repositories/FeeRepository'; import SwapRepository from '../db/repositories/SwapRepository'; -import { coinsToSatoshis, satoshisToCoins } from '../DenominationConverter'; import ReverseSwapRepository from '../db/repositories/ReverseSwapRepository'; +import { coinsToSatoshis, satoshisToSatcomma } from '../DenominationConverter'; import ChannelCreationRepository from '../db/repositories/ChannelCreationRepository'; import { stringify, @@ -257,7 +257,7 @@ class CommandHandler { private getFees = async () => { let message = 'Fees:\n'; (await FeeRepository.getFees()).forEach(({ asset, sum }) => { - message += `\n**${asset}**: ${satoshisToCoins(sum)} ${asset}`; + message += `\n**${asset}**: ${satoshisToSatcomma(sum)} ${asset}`; }); await this.discord.sendMessage(message); @@ -350,7 +350,7 @@ class CommandHandler { message += `\n\n**${symbol}**\n`; bals.walletsMap.forEach(([service, walletBals]) => { - message += `\n${service} Wallet: ${satoshisToCoins( + message += `\n${service} Wallet: ${satoshisToSatcomma( walletBals.confirmed + walletBals.unconfirmed, )} ${symbol}`; }); @@ -362,8 +362,8 @@ class CommandHandler { bals.lightningMap.forEach(([service, lightningBals]) => { message += `\n${service}:\n` + - ` Local: ${satoshisToCoins(lightningBals.local)} ${symbol}\n` + - ` Remote: ${satoshisToCoins(lightningBals.remote)} ${symbol}`; + ` Local: ${satoshisToSatcomma(lightningBals.local)} ${symbol}\n` + + ` Remote: ${satoshisToSatcomma(lightningBals.remote)} ${symbol}`; }); }); @@ -410,12 +410,12 @@ class CommandHandler { for (const pendingReverseSwap of chainArray) { symbolTotal += pendingReverseSwap.onchainAmount; - message += `\n - \`${pendingReverseSwap.id}\`: ${satoshisToCoins( + message += `\n - \`${pendingReverseSwap.id}\`: ${satoshisToSatcomma( pendingReverseSwap.onchainAmount, )}`; } - message += `\n\nTotal: ${satoshisToCoins(symbolTotal)}\n`; + message += `\n\nTotal: ${satoshisToSatcomma(symbolTotal)}\n`; } await this.discord.sendMessage(message); diff --git a/lib/notifications/NotificationProvider.ts b/lib/notifications/NotificationProvider.ts index 2687bd6b..50a9fc6b 100644 --- a/lib/notifications/NotificationProvider.ts +++ b/lib/notifications/NotificationProvider.ts @@ -11,7 +11,7 @@ import DiskUsageChecker from './DiskUsageChecker'; import ReverseSwap from '../db/models/ReverseSwap'; import BackupScheduler from '../backup/BackupScheduler'; import { CurrencyType, OrderSide } from '../consts/Enums'; -import { satoshisToCoins } from '../DenominationConverter'; +import { satoshisToSatcomma } from '../DenominationConverter'; import { ChainInfo, LightningInfo } from '../proto/boltzrpc_pb'; import { TokenConfig, BaseCurrencyConfig, NotificationConfig } from '../Config'; import { @@ -192,12 +192,12 @@ class NotificationProvider { message += `${ swap.onchainAmount - ? `\nOnchain amount: ${satoshisToCoins( + ? `\nOnchain amount: ${satoshisToSatcomma( swap.onchainAmount, )} ${onchainSymbol}` : '' }` + - `\nLightning amount: ${satoshisToCoins( + `\nLightning amount: ${satoshisToSatcomma( lightningAmount, )} ${lightningSymbol}`; } @@ -250,12 +250,10 @@ class NotificationProvider { hasChannelCreation ? ' :construction_site:' : '' }**\n` + `${getBasicSwapInfo(swap, onchainSymbol, lightningSymbol)}\n` + - `Fees earned: ${this.numberToDecimal( - satoshisToCoins(swap.fee!), - )} ${onchainSymbol}\n` + - `Miner fees: ${satoshisToCoins(swap.minerFee!)} ${getMinerFeeSymbol( - onchainSymbol, - )}`; + `Fees earned: ${satoshisToSatcomma(swap.fee!)} ${onchainSymbol}\n` + + `Miner fees: ${satoshisToSatcomma( + swap.minerFee!, + )} ${getMinerFeeSymbol(onchainSymbol)}`; if (!isReverse) { // The routing fees are denominated in millisatoshi @@ -300,7 +298,7 @@ class NotificationProvider { if (isReverse) { if (swap.minerFee) { - message += `\nMiner fees: ${satoshisToCoins( + message += `\nMiner fees: ${satoshisToSatcomma( swap.minerFee, )} ${onchainSymbol}`; } @@ -350,24 +348,6 @@ class NotificationProvider { return 'satoshi'; } }; - - private numberToDecimal = (toFormat: number) => { - // Numbers smaller 1e-6 are formatted in the scientific notation when converted to a string - if (toFormat < 1e-6) { - let format = toFormat.toFixed(8); - - // Trim the trailing zeros if they exist - const lastZero = format.lastIndexOf('0'); - - if (lastZero === format.length - 1) { - format = format.slice(0, format.length - 1); - } - - return format; - } else { - return toFormat.toString(); - } - }; } export default NotificationProvider; diff --git a/package-lock.json b/package-lock.json index b72e0f09..053f24cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,12 +54,12 @@ "@types/cors": "^2.8.14", "@types/express": "^4.17.18", "@types/jest": "^29.5.5", - "@types/node-forge": "^1.3.6", + "@types/node-forge": "^1.3.7", "@types/node-schedule": "^2.1.1", "@types/yargs": "^17.0.28", "@types/zeromq": "^5.2.3", - "@typescript-eslint/eslint-plugin": "^6.7.4", - "@typescript-eslint/parser": "^6.7.4", + "@typescript-eslint/eslint-plugin": "^6.7.5", + "@typescript-eslint/parser": "^6.7.5", "eslint": "^8.51.0", "eslint-plugin-import": "^2.28.1", "eslint-plugin-jest": "^27.4.2", @@ -2355,9 +2355,9 @@ "integrity": "sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==" }, "node_modules/@types/node-forge": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.6.tgz", - "integrity": "sha512-rOLL54+BcPO1BV0ogdKCtfmohdL3WW3ODCbnh8gA8ZWPYfHM0aVFyXQljme5DoICH29/2JZOXqgkS9CEd/NmSQ==", + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.7.tgz", + "integrity": "sha512-uWvTDObXqNQPVprvvm7FCS/B0qexgRMmNCJCRETywf7cBm3C7uGRtGfaSqCoUlksrmY5Yn3++fvA7awBE5lAzw==", "dev": true, "dependencies": { "@types/node": "*" @@ -2450,16 +2450,16 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.4.tgz", - "integrity": "sha512-DAbgDXwtX+pDkAHwiGhqP3zWUGpW49B7eqmgpPtg+BKJXwdct79ut9+ifqOFPJGClGKSHXn2PTBatCnldJRUoA==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.5.tgz", + "integrity": "sha512-JhtAwTRhOUcP96D0Y6KYnwig/MRQbOoLGXTON2+LlyB/N35SP9j1boai2zzwXb7ypKELXMx3DVk9UTaEq1vHEw==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.7.4", - "@typescript-eslint/type-utils": "6.7.4", - "@typescript-eslint/utils": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4", + "@typescript-eslint/scope-manager": "6.7.5", + "@typescript-eslint/type-utils": "6.7.5", + "@typescript-eslint/utils": "6.7.5", + "@typescript-eslint/visitor-keys": "6.7.5", "debug": "^4.3.4", "graphemer": "^1.4.0", "ignore": "^5.2.4", @@ -2485,13 +2485,13 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.4.tgz", - "integrity": "sha512-SdGqSLUPTXAXi7c3Ob7peAGVnmMoGzZ361VswK2Mqf8UOYcODiYvs8rs5ILqEdfvX1lE7wEZbLyELCW+Yrql1A==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.5.tgz", + "integrity": "sha512-GAlk3eQIwWOJeb9F7MKQ6Jbah/vx1zETSDw8likab/eFcqkjSD7BI75SDAeC5N2L0MmConMoPvTsmkrg71+B1A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4" + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/visitor-keys": "6.7.5" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2502,9 +2502,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", - "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.5.tgz", + "integrity": "sha512-WboQBlOXtdj1tDFPyIthpKrUb+kZf2VroLZhxKa/VlwLlLyqv/PwUNgL30BlTVZV1Wu4Asu2mMYPqarSO4L5ZQ==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2515,13 +2515,13 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.4.tgz", - "integrity": "sha512-ty8b5qHKatlNYd9vmpHooQz3Vki3gG+3PchmtsA4TgrZBKWHNjWfkQid7K7xQogBqqc7/BhGazxMD5vr6Ha+iQ==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.5.tgz", + "integrity": "sha512-NhJiJ4KdtwBIxrKl0BqG1Ur+uw7FiOnOThcYx9DpOGJ/Abc9z2xNzLeirCG02Ig3vkvrc2qFLmYSSsaITbKjlg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4", + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/visitor-keys": "6.7.5", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2542,17 +2542,17 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.4.tgz", - "integrity": "sha512-PRQAs+HUn85Qdk+khAxsVV+oULy3VkbH3hQ8hxLRJXWBEd7iI+GbQxH5SEUSH7kbEoTp6oT1bOwyga24ELALTA==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.5.tgz", + "integrity": "sha512-pfRRrH20thJbzPPlPc4j0UNGvH1PjPlhlCMq4Yx7EGjV7lvEeGX0U6MJYe8+SyFutWgSHsdbJ3BXzZccYggezA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.4", - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/typescript-estree": "6.7.4", + "@typescript-eslint/scope-manager": "6.7.5", + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/typescript-estree": "6.7.5", "semver": "^7.5.4" }, "engines": { @@ -2567,12 +2567,12 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", - "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.5.tgz", + "integrity": "sha512-3MaWdDZtLlsexZzDSdQWsFQ9l9nL8B80Z4fImSpyllFC/KLqWQRdEcB+gGGO+N3Q2uL40EsG66wZLsohPxNXvg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/types": "6.7.5", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -2599,15 +2599,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.4.tgz", - "integrity": "sha512-I5zVZFY+cw4IMZUeNCU7Sh2PO5O57F7Lr0uyhgCJmhN/BuTlnc55KxPonR4+EM3GBdfiCyGZye6DgMjtubQkmA==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.5.tgz", + "integrity": "sha512-bIZVSGx2UME/lmhLcjdVc7ePBwn7CLqKarUBL4me1C5feOd663liTGjMBGVcGr+BhnSLeP4SgwdvNnnkbIdkCw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "6.7.4", - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/typescript-estree": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4", + "@typescript-eslint/scope-manager": "6.7.5", + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/typescript-estree": "6.7.5", + "@typescript-eslint/visitor-keys": "6.7.5", "debug": "^4.3.4" }, "engines": { @@ -2627,13 +2627,13 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.4.tgz", - "integrity": "sha512-SdGqSLUPTXAXi7c3Ob7peAGVnmMoGzZ361VswK2Mqf8UOYcODiYvs8rs5ILqEdfvX1lE7wEZbLyELCW+Yrql1A==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.5.tgz", + "integrity": "sha512-GAlk3eQIwWOJeb9F7MKQ6Jbah/vx1zETSDw8likab/eFcqkjSD7BI75SDAeC5N2L0MmConMoPvTsmkrg71+B1A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4" + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/visitor-keys": "6.7.5" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2644,9 +2644,9 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", - "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.5.tgz", + "integrity": "sha512-WboQBlOXtdj1tDFPyIthpKrUb+kZf2VroLZhxKa/VlwLlLyqv/PwUNgL30BlTVZV1Wu4Asu2mMYPqarSO4L5ZQ==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2657,13 +2657,13 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.4.tgz", - "integrity": "sha512-ty8b5qHKatlNYd9vmpHooQz3Vki3gG+3PchmtsA4TgrZBKWHNjWfkQid7K7xQogBqqc7/BhGazxMD5vr6Ha+iQ==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.5.tgz", + "integrity": "sha512-NhJiJ4KdtwBIxrKl0BqG1Ur+uw7FiOnOThcYx9DpOGJ/Abc9z2xNzLeirCG02Ig3vkvrc2qFLmYSSsaITbKjlg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4", + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/visitor-keys": "6.7.5", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2684,12 +2684,12 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", - "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.5.tgz", + "integrity": "sha512-3MaWdDZtLlsexZzDSdQWsFQ9l9nL8B80Z4fImSpyllFC/KLqWQRdEcB+gGGO+N3Q2uL40EsG66wZLsohPxNXvg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/types": "6.7.5", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -2733,13 +2733,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.4.tgz", - "integrity": "sha512-n+g3zi1QzpcAdHFP9KQF+rEFxMb2KxtnJGID3teA/nxKHOVi3ylKovaqEzGBbVY2pBttU6z85gp0D00ufLzViQ==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.5.tgz", + "integrity": "sha512-Gs0qos5wqxnQrvpYv+pf3XfcRXW6jiAn9zE/K+DlmYf6FcpxeNYN0AIETaPR7rHO4K2UY+D0CIbDP9Ut0U4m1g==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "6.7.4", - "@typescript-eslint/utils": "6.7.4", + "@typescript-eslint/typescript-estree": "6.7.5", + "@typescript-eslint/utils": "6.7.5", "debug": "^4.3.4", "ts-api-utils": "^1.0.1" }, @@ -2760,13 +2760,13 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.4.tgz", - "integrity": "sha512-SdGqSLUPTXAXi7c3Ob7peAGVnmMoGzZ361VswK2Mqf8UOYcODiYvs8rs5ILqEdfvX1lE7wEZbLyELCW+Yrql1A==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.5.tgz", + "integrity": "sha512-GAlk3eQIwWOJeb9F7MKQ6Jbah/vx1zETSDw8likab/eFcqkjSD7BI75SDAeC5N2L0MmConMoPvTsmkrg71+B1A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4" + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/visitor-keys": "6.7.5" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2777,9 +2777,9 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.4.tgz", - "integrity": "sha512-o9XWK2FLW6eSS/0r/tgjAGsYasLAnOWg7hvZ/dGYSSNjCh+49k5ocPN8OmG5aZcSJ8pclSOyVKP2x03Sj+RrCA==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.5.tgz", + "integrity": "sha512-WboQBlOXtdj1tDFPyIthpKrUb+kZf2VroLZhxKa/VlwLlLyqv/PwUNgL30BlTVZV1Wu4Asu2mMYPqarSO4L5ZQ==", "dev": true, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2790,13 +2790,13 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.4.tgz", - "integrity": "sha512-ty8b5qHKatlNYd9vmpHooQz3Vki3gG+3PchmtsA4TgrZBKWHNjWfkQid7K7xQogBqqc7/BhGazxMD5vr6Ha+iQ==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.5.tgz", + "integrity": "sha512-NhJiJ4KdtwBIxrKl0BqG1Ur+uw7FiOnOThcYx9DpOGJ/Abc9z2xNzLeirCG02Ig3vkvrc2qFLmYSSsaITbKjlg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/visitor-keys": "6.7.4", + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/visitor-keys": "6.7.5", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2817,17 +2817,17 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.4.tgz", - "integrity": "sha512-PRQAs+HUn85Qdk+khAxsVV+oULy3VkbH3hQ8hxLRJXWBEd7iI+GbQxH5SEUSH7kbEoTp6oT1bOwyga24ELALTA==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.5.tgz", + "integrity": "sha512-pfRRrH20thJbzPPlPc4j0UNGvH1PjPlhlCMq4Yx7EGjV7lvEeGX0U6MJYe8+SyFutWgSHsdbJ3BXzZccYggezA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", "@types/json-schema": "^7.0.12", "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.7.4", - "@typescript-eslint/types": "6.7.4", - "@typescript-eslint/typescript-estree": "6.7.4", + "@typescript-eslint/scope-manager": "6.7.5", + "@typescript-eslint/types": "6.7.5", + "@typescript-eslint/typescript-estree": "6.7.5", "semver": "^7.5.4" }, "engines": { @@ -2842,12 +2842,12 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.4.tgz", - "integrity": "sha512-pOW37DUhlTZbvph50x5zZCkFn3xzwkGtNoJHzIM3svpiSkJzwOYr/kVBaXmf+RAQiUDs1AHEZVNPg6UJCJpwRA==", + "version": "6.7.5", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.5.tgz", + "integrity": "sha512-3MaWdDZtLlsexZzDSdQWsFQ9l9nL8B80Z4fImSpyllFC/KLqWQRdEcB+gGGO+N3Q2uL40EsG66wZLsohPxNXvg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "6.7.4", + "@typescript-eslint/types": "6.7.5", "eslint-visitor-keys": "^3.4.1" }, "engines": { diff --git a/package.json b/package.json index f683e364..632fa630 100644 --- a/package.json +++ b/package.json @@ -100,12 +100,12 @@ "@types/cors": "^2.8.14", "@types/express": "^4.17.18", "@types/jest": "^29.5.5", - "@types/node-forge": "^1.3.6", + "@types/node-forge": "^1.3.7", "@types/node-schedule": "^2.1.1", "@types/yargs": "^17.0.28", "@types/zeromq": "^5.2.3", - "@typescript-eslint/eslint-plugin": "^6.7.4", - "@typescript-eslint/parser": "^6.7.4", + "@typescript-eslint/eslint-plugin": "^6.7.5", + "@typescript-eslint/parser": "^6.7.5", "eslint": "^8.51.0", "eslint-plugin-import": "^2.28.1", "eslint-plugin-jest": "^27.4.2", diff --git a/test/unit/DenominationConverter.spec.ts b/test/unit/DenominationConverter.spec.ts index 8456e102..c7aa85e5 100644 --- a/test/unit/DenominationConverter.spec.ts +++ b/test/unit/DenominationConverter.spec.ts @@ -2,6 +2,8 @@ import { randomRange } from '../Utils'; import { coinsToSatoshis, satoshisToCoins, + satoshisToPaddedCoins, + satoshisToSatcomma, } from '../../lib/DenominationConverter'; describe('DenominationConverter', () => { @@ -13,6 +15,23 @@ describe('DenominationConverter', () => { expect(satoshisToCoins(1000)).toEqual(0.00001); }); + test.each` + sats | expected + ${100_000_000} | ${'1.00000000'} + ${103_050_087} | ${'1.03050087'} + ${0} | ${'0.00000000'} + ${1} | ${'0.00000001'} + ${1_000} | ${'0.00001000'} + ${10_000} | ${'0.00010000'} + ${34_578_934_789} | ${'345.78934789'} + ${2_868_926} | ${'0.02868926'} + `( + 'should convert $sats satoshis to whole padded coins', + ({ sats, expected }) => { + expect(satoshisToPaddedCoins(sats)).toEqual(expected); + }, + ); + test('should convert whole coins to satoshis', () => { const randomCoins = randomRange(1000); const sats = Number((randomCoins * 100000000).toFixed(8)); @@ -20,4 +39,18 @@ describe('DenominationConverter', () => { expect(coinsToSatoshis(randomCoins)).toEqual(sats); expect(coinsToSatoshis(100)).toEqual(10000000000); }); + + test.each` + sats | expected + ${100_000_000} | ${'1.00,000,000'} + ${103_050_087} | ${'1.03,050,087'} + ${0} | ${'0.00,000,000'} + ${1} | ${'0.00,000,001'} + ${1_000} | ${'0.00,001,000'} + ${10_000} | ${'0.00,010,000'} + ${34_578_934_789} | ${'345.78,934,789'} + ${2_868_926} | ${'0.02,868,926'} + `('should convert $sats satoshis to satcomma', ({ sats, expected }) => { + expect(satoshisToSatcomma(sats)).toEqual(expected); + }); }); diff --git a/test/unit/notifications/BalanceChecker.spec.ts b/test/unit/notifications/BalanceChecker.spec.ts index 0dbd6170..a979a53d 100644 --- a/test/unit/notifications/BalanceChecker.spec.ts +++ b/test/unit/notifications/BalanceChecker.spec.ts @@ -335,7 +335,7 @@ describe('BalanceChecker', () => { await sendAlert(btcCurrency, BalanceType.Wallet, service, true, 999999999); expect(mockSendMessage).toHaveBeenNthCalledWith( 1, - `:white_check_mark: BTC ${service} wallet balance of 9.99999999 is in bounds again :white_check_mark:`, + `:white_check_mark: BTC ${service} wallet balance of 9.99,999,999 is in bounds again :white_check_mark:`, true, ); @@ -343,8 +343,8 @@ describe('BalanceChecker', () => { expect(mockSendMessage).toHaveBeenNthCalledWith( 2, `:rotating_light: **BTC ${service} wallet balance is out of bounds** :rotating_light:\n` + - ' Balance: 0.99999999\n' + - ' Min: 0.1', + ' Balance: 0.99,999,999\n' + + ' Min: 0.10,000,000', true, ); @@ -357,7 +357,7 @@ describe('BalanceChecker', () => { ); expect(mockSendMessage).toHaveBeenNthCalledWith( 3, - `:white_check_mark: USDT ${service} wallet balance of 1500 is in bounds again :white_check_mark:`, + `:white_check_mark: USDT ${service} wallet balance of 1500.00,000,000 is in bounds again :white_check_mark:`, true, ); @@ -371,9 +371,9 @@ describe('BalanceChecker', () => { expect(mockSendMessage).toHaveBeenNthCalledWith( 4, `:rotating_light: **USDT ${service} wallet balance is out of bounds** :rotating_light:\n` + - ' Balance: 100\n' + - ' Max: 2000\n' + - ' Min: 1000', + ' Balance: 100.00,000,000\n' + + ' Max: 2000.00,000,000\n' + + ' Min: 1000.00,000,000', true, ); @@ -387,7 +387,7 @@ describe('BalanceChecker', () => { ); expect(mockSendMessage).toHaveBeenNthCalledWith( 5, - `:white_check_mark: BTC ${service} local channel balance of 0.25000001 is more than expected 0.25 again :white_check_mark:`, + `:white_check_mark: BTC ${service} local channel balance of 0.25,000,001 is more than expected 0.25,000,000 again :white_check_mark:`, true, ); @@ -400,7 +400,7 @@ describe('BalanceChecker', () => { ); expect(mockSendMessage).toHaveBeenNthCalledWith( 6, - `:white_check_mark: BTC ${service} remote channel balance of 0.25000001 is more than expected 0.24 again :white_check_mark:`, + `:white_check_mark: BTC ${service} remote channel balance of 0.25,000,001 is more than expected 0.24,000,000 again :white_check_mark:`, true, ); @@ -413,7 +413,7 @@ describe('BalanceChecker', () => { ); expect(mockSendMessage).toHaveBeenNthCalledWith( 7, - `:rotating_light: **BTC ${service} local channel balance of 0.2 is less than expected 0.25** :rotating_light:`, + `:rotating_light: **BTC ${service} local channel balance of 0.20,000,000 is less than expected 0.25,000,000** :rotating_light:`, true, ); @@ -426,7 +426,7 @@ describe('BalanceChecker', () => { ); expect(mockSendMessage).toHaveBeenNthCalledWith( 8, - `:rotating_light: **BTC ${service} remote channel balance of 0.2 is less than expected 0.24** :rotating_light:`, + `:rotating_light: **BTC ${service} remote channel balance of 0.20,000,000 is less than expected 0.24,000,000** :rotating_light:`, true, ); }); diff --git a/test/unit/notifications/CommandHandler.spec.ts b/test/unit/notifications/CommandHandler.spec.ts index 4557284f..03742f03 100644 --- a/test/unit/notifications/CommandHandler.spec.ts +++ b/test/unit/notifications/CommandHandler.spec.ts @@ -14,16 +14,16 @@ import { Balances, GetBalanceResponse } from '../../../lib/proto/boltzrpc_pb'; import ReverseSwapRepository from '../../../lib/db/repositories/ReverseSwapRepository'; import ChannelCreationRepository from '../../../lib/db/repositories/ChannelCreationRepository'; import { - satoshisToCoins, coinsToSatoshis, + satoshisToSatcomma, } from '../../../lib/DenominationConverter'; import { - swapExample, + channelCreationExample, channelSwapExample, + pendingReverseSwapExample, pendingSwapExample, reverseSwapExample, - channelCreationExample, - pendingReverseSwapExample, + swapExample, } from './ExampleSwaps'; import Stats from '../../../lib/data/Stats'; @@ -264,7 +264,7 @@ describe('CommandHandler', () => { expect(mockSendMessage).toHaveBeenCalledTimes(1); expect(mockSendMessage).toHaveBeenLastCalledWith( - `Fees:\n\n**BTC**: ${satoshisToCoins( + `Fees:\n\n**BTC**: ${satoshisToSatcomma( swapExample.fee! + reverseSwapExample.fee, )} BTC`, ); @@ -342,8 +342,8 @@ describe('CommandHandler', () => { [new Date().getFullYear()]: { [new Date().getMonth() + 1]: { volume: { - total: 0.03, - 'LTC/BTC': 0.03, + total: (0.03).toFixed(8), + 'LTC/BTC': (0.03).toFixed(8), }, trades: { total: 3, @@ -394,12 +394,12 @@ describe('CommandHandler', () => { expect(mockSendMessage).toHaveBeenCalledTimes(1); expect(mockSendMessage).toHaveBeenCalledWith( 'Balances:\n\n' + - `**BTC**\n\nCore Wallet: ${satoshisToCoins( + `**BTC**\n\nCore Wallet: ${satoshisToSatcomma( wallet.getConfirmed() + wallet.getUnconfirmed(), )} BTC\n\n` + 'LND:\n' + - ` Local: ${satoshisToCoins(lightning.getLocal())} BTC\n` + - ` Remote: ${satoshisToCoins(lightning.getRemote())} BTC`, + ` Local: ${satoshisToSatcomma(lightning.getLocal())} BTC\n` + + ` Remote: ${satoshisToSatcomma(lightning.getRemote())} BTC`, ); }); @@ -411,8 +411,8 @@ describe('CommandHandler', () => { expect(mockSendMessage).toHaveBeenCalledWith( '**Locked up funds:**\n\n' + '**BTC**\n' + - ' - `r654321`: 0.01\n' + - '\nTotal: 0.01\n', + ' - `r654321`: 0.01,000,000\n' + + '\nTotal: 0.01,000,000\n', ); }); diff --git a/test/unit/notifications/NotificationProvider.spec.ts b/test/unit/notifications/NotificationProvider.spec.ts index cf0ff8bb..75c850db 100644 --- a/test/unit/notifications/NotificationProvider.spec.ts +++ b/test/unit/notifications/NotificationProvider.spec.ts @@ -1,5 +1,5 @@ import { join } from 'path'; -import { unlinkSync, existsSync } from 'fs'; +import { existsSync, unlinkSync } from 'fs'; import { wait } from '../../Utils'; import Logger from '../../../lib/Logger'; import Swap from '../../../lib/db/models/Swap'; @@ -8,14 +8,14 @@ import { decodeInvoice } from '../../../lib/Utils'; import { CurrencyType } from '../../../lib/consts/Enums'; import ReverseSwap from '../../../lib/db/models/ReverseSwap'; import BackupScheduler from '../../../lib/backup/BackupScheduler'; -import DiscordClient from '../../../lib/notifications/DiscordClient'; -import { satoshisToCoins } from '../../../lib/DenominationConverter'; import ChannelCreation from '../../../lib/db/models/ChannelCreation'; +import DiscordClient from '../../../lib/notifications/DiscordClient'; +import { satoshisToSatcomma } from '../../../lib/DenominationConverter'; import NotificationProvider from '../../../lib/notifications/NotificationProvider'; import { - swapExample, - reverseSwapExample, channelCreationExample, + reverseSwapExample, + swapExample, } from './ExampleSwaps'; type successCallback = ( @@ -148,12 +148,12 @@ describe('NotificationProvider', () => { `ID: ${swap.id}\n` + `Pair: ${swap.pair}\n` + 'Order side: buy\n' + - `Onchain amount: ${satoshisToCoins(swap.onchainAmount!)} BTC\n` + - `Lightning amount: ${satoshisToCoins( + `Onchain amount: ${satoshisToSatcomma(swap.onchainAmount!)} BTC\n` + + `Lightning amount: ${satoshisToSatcomma( decodeInvoice(swap.invoice!).satoshis, )} LTC\n` + - `Fees earned: ${satoshisToCoins(swap.fee!)} BTC\n` + - `Miner fees: ${satoshisToCoins(swap.minerFee!)} BTC\n` + + `Fees earned: ${satoshisToSatcomma(swap.fee!)} BTC\n` + + `Miner fees: ${satoshisToSatcomma(swap.minerFee!)} BTC\n` + `Routing fees: ${swap.routingFee! / 1000} litoshi` + NotificationProvider['trailingWhitespace'], ); @@ -171,8 +171,8 @@ describe('NotificationProvider', () => { `ID: ${swap.id}\n` + `Pair: ${swap.pair}\n` + 'Order side: buy\n' + - `Onchain amount: ${satoshisToCoins(swap.onchainAmount!)} BTC\n` + - `Lightning amount: ${satoshisToCoins( + `Onchain amount: ${satoshisToSatcomma(swap.onchainAmount!)} BTC\n` + + `Lightning amount: ${satoshisToSatcomma( decodeInvoice(swap.invoice!).satoshis, )} LTC\n` + `Invoice: ${swap.invoice}` + @@ -190,12 +190,14 @@ describe('NotificationProvider', () => { `ID: ${reverseSwap.id}\n` + `Pair: ${reverseSwap.pair}\n` + 'Order side: sell\n' + - `Onchain amount: ${satoshisToCoins(reverseSwap.onchainAmount!)} BTC\n` + - `Lightning amount: ${satoshisToCoins( + `Onchain amount: ${satoshisToSatcomma( + reverseSwap.onchainAmount!, + )} BTC\n` + + `Lightning amount: ${satoshisToSatcomma( decodeInvoice(reverseSwap.invoice).satoshis, )} LTC\n` + - `Fees earned: ${satoshisToCoins(reverseSwap.fee)} BTC\n` + - `Miner fees: ${satoshisToCoins(reverseSwap.minerFee!)} BTC` + + `Fees earned: ${satoshisToSatcomma(reverseSwap.fee)} BTC\n` + + `Miner fees: ${satoshisToSatcomma(reverseSwap.minerFee!)} BTC` + NotificationProvider['trailingWhitespace'], ); }); @@ -213,11 +215,13 @@ describe('NotificationProvider', () => { `ID: ${reverseSwap.id}\n` + `Pair: ${reverseSwap.pair}\n` + 'Order side: sell\n' + - `Onchain amount: ${satoshisToCoins(reverseSwap.onchainAmount!)} BTC\n` + - `Lightning amount: ${satoshisToCoins( + `Onchain amount: ${satoshisToSatcomma( + reverseSwap.onchainAmount!, + )} BTC\n` + + `Lightning amount: ${satoshisToSatcomma( decodeInvoice(reverseSwap.invoice).satoshis, )} LTC\n` + - `Miner fees: ${satoshisToCoins(reverseSwap.minerFee)} BTC` + + `Miner fees: ${satoshisToSatcomma(reverseSwap.minerFee)} BTC` + NotificationProvider['trailingWhitespace'], ); @@ -238,8 +242,10 @@ describe('NotificationProvider', () => { `ID: ${reverseSwap.id}\n` + `Pair: ${reverseSwap.pair}\n` + 'Order side: sell\n' + - `Onchain amount: ${satoshisToCoins(reverseSwap.onchainAmount!)} BTC\n` + - `Lightning amount: ${satoshisToCoins( + `Onchain amount: ${satoshisToSatcomma( + reverseSwap.onchainAmount!, + )} BTC\n` + + `Lightning amount: ${satoshisToSatcomma( decodeInvoice(reverseSwap.invoice).satoshis, )} LTC` + NotificationProvider['trailingWhitespace'], @@ -256,12 +262,12 @@ describe('NotificationProvider', () => { `ID: ${swap.id}\n` + `Pair: ${swap.pair}\n` + 'Order side: buy\n' + - `Onchain amount: ${satoshisToCoins(swap.onchainAmount!)} BTC\n` + - `Lightning amount: ${satoshisToCoins( + `Onchain amount: ${satoshisToSatcomma(swap.onchainAmount!)} BTC\n` + + `Lightning amount: ${satoshisToSatcomma( decodeInvoice(swap.invoice!).satoshis, )} LTC\n` + - `Fees earned: ${satoshisToCoins(swap.fee!)} BTC\n` + - `Miner fees: ${satoshisToCoins(swap.minerFee!)} BTC\n` + + `Fees earned: ${satoshisToSatcomma(swap.fee!)} BTC\n` + + `Miner fees: ${satoshisToSatcomma(swap.minerFee!)} BTC\n` + `Routing fees: ${swap.routingFee! / 1000} litoshi\n\n` + '**Channel Creation:**\n' + `Private: ${channelCreation.private}\n` + @@ -286,12 +292,12 @@ describe('NotificationProvider', () => { `ID: ${swap.id}\n` + `Pair: ${swap.pair}\n` + 'Order side: buy\n' + - `Onchain amount: ${satoshisToCoins(swap.onchainAmount!)} BTC\n` + - `Lightning amount: ${satoshisToCoins( + `Onchain amount: ${satoshisToSatcomma(swap.onchainAmount!)} BTC\n` + + `Lightning amount: ${satoshisToSatcomma( decodeInvoice(swap.invoice!).satoshis, )} LTC\n` + - `Fees earned: ${satoshisToCoins(swap.fee!)} BTC\n` + - `Miner fees: ${satoshisToCoins(swap.minerFee!)} BTC\n` + + `Fees earned: ${satoshisToSatcomma(swap.fee!)} BTC\n` + + `Miner fees: ${satoshisToSatcomma(swap.minerFee!)} BTC\n` + `Routing fees: ${swap.routingFee! / 1000} litoshi` + NotificationProvider['trailingWhitespace'], ); @@ -318,17 +324,6 @@ describe('NotificationProvider', () => { ); }); - test('should format numbers to strings in decimal notation', () => { - const numberToDecimal = notificationProvider['numberToDecimal']; - - expect(numberToDecimal(1)).toEqual('1'); - expect(numberToDecimal(0.0001)).toEqual('0.0001'); - expect(numberToDecimal(1e-6)).toEqual('0.000001'); - expect(numberToDecimal(1e-7)).toEqual('0.0000001'); - expect(numberToDecimal(10e-8)).toEqual('0.0000001'); - expect(numberToDecimal(12e-8)).toEqual('0.00000012'); - }); - afterAll(() => { notificationProvider.disconnect();