From 8ba8ba20d37be224c87dde1e0a8d8411953297a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Calder=C3=B3n?= Date: Thu, 29 Aug 2024 11:02:26 -0300 Subject: [PATCH] Revert "Convert JS to TS (commits 7-13 of PR435) (#557)" This reverts commit a31ab63ffa9908c12c7833fc499f12c8dd3ed3ae. --- bot/start.ts | 75 +++---- bot/{validations.ts => validations.js} | 131 +++++------- ...ngs.ts => calculate_community_earnings.js} | 13 +- jobs/{cancel_orders.ts => cancel_orders.js} | 19 +- jobs/{communities.ts => communities.js} | 15 +- ...d_orders.ts => delete_published_orders.js} | 15 +- jobs/index.js | 19 ++ jobs/index.ts | 19 -- jobs/{node_info.ts => node_info.js} | 13 +- jobs/pending_payments.ts | 27 +-- lnurl/{lnurl-pay.ts => lnurl-pay.js} | 15 +- package-lock.json | 10 - package.json | 1 - tsconfig.json | 2 - util/fiatModel.ts | 4 - util/{index.ts => index.js} | 199 ++++++++---------- util/languagesModel.ts | 9 - 17 files changed, 240 insertions(+), 346 deletions(-) rename bot/{validations.ts => validations.js} (76%) rename jobs/{calculate_community_earnings.ts => calculate_community_earnings.js} (77%) rename jobs/{cancel_orders.ts => cancel_orders.js} (86%) rename jobs/{communities.ts => communities.js} (70%) rename jobs/{delete_published_orders.ts => delete_published_orders.js} (73%) create mode 100644 jobs/index.js delete mode 100644 jobs/index.ts rename jobs/{node_info.ts => node_info.js} (62%) rename lnurl/{lnurl-pay.ts => lnurl-pay.js} (76%) rename util/{index.ts => index.js} (70%) delete mode 100644 util/languagesModel.ts diff --git a/bot/start.ts b/bot/start.ts index 25984393..fe7a1013 100644 --- a/bot/start.ts +++ b/bot/start.ts @@ -4,17 +4,18 @@ import { Message } from 'typegram' import { UserDocument } from '../models/user' import { FilterQuery } from 'mongoose'; const OrderEvents = require('./modules/events/orders'); -import { limit } from "@grammyjs/ratelimiter" + +const { limit } = require('@grammyjs/ratelimiter'); const schedule = require('node-schedule'); -import { +const { Order, User, PendingPayment, Community, Dispute, Config, -} from '../models'; -import { getCurrenciesWithPrice, deleteOrderFromChannel, removeAtSymbol } from '../util'; +} = require('../models'); +const { getCurrenciesWithPrice, deleteOrderFromChannel, removeAtSymbol } = require('../util'); const { commandArgsMiddleware, stageMiddleware, @@ -54,7 +55,7 @@ const { validateLightningAddress, } = require('./validations'); import * as messages from './messages'; -import { +const { attemptPendingPayments, cancelOrders, deleteOrders, @@ -62,10 +63,8 @@ import { attemptCommunitiesPendingPayments, deleteCommunity, nodeInfo, -} from '../jobs'; -import { logger } from "../logger"; -import { ICommunity, IUsernameId } from '../models/community'; - +} = require('../jobs'); +const { logger } = require('../logger'); export interface MainContext extends Context { match: Array | null; i18n: I18nContext; @@ -73,7 +72,7 @@ export interface MainContext extends Context { admin: UserDocument; } -export interface OrderQuery { +interface OrderQuery { status?: string; buyer_id?: string; seller_id?: string; @@ -81,7 +80,7 @@ export interface OrderQuery { const askForConfirmation = async (user: UserDocument, command: string) => { try { - let orders: any[] = []; + let orders = []; if (command === '/cancel') { const where: FilterQuery = { $and: [ @@ -134,7 +133,6 @@ const askForConfirmation = async (user: UserDocument, command: string) => { return orders; } catch (error) { logger.error(error); - return null; } }; @@ -147,7 +145,7 @@ has the same condition. The problem mentioned above is similar to this issue: https://github.com/telegraf/telegraf/issues/1319#issuecomment-766360594 */ -export const ctxUpdateAssertMsg = "ctx.update.message.text is not available."; +const ctxUpdateAssertMsg = "ctx.update.message.text is not available."; const initialize = (botToken: string, options: Partial>): Telegraf => { const i18n = new I18n({ @@ -217,7 +215,7 @@ const initialize = (botToken: string, options: Partial'); if (!val) return; let config = await Config.findOne(); - if (config === null) { + if (!config) { config = new Config(); } config.maintenance = false; @@ -264,11 +262,11 @@ const initialize = (botToken: string, options: Partial el); + const [command, orderId] = params.filter((el) => el); if (!orderId) { const orders = await askForConfirmation(ctx.user, command); - if (orders === null || orders.length === 0) return await ctx.reply(`${command} `); + if (!orders.length) return await ctx.reply(`${command} `); return await messages.showConfirmationButtons(ctx, orders, command); } else if (!(await validateObjectId(ctx, orderId))) { @@ -327,7 +325,7 @@ const initialize = (botToken: string, options: Partial el); + const [command, orderId] = params.filter((el) => el); if (!orderId) { const orders = await askForConfirmation(ctx.user, command); - if (orders === null || orders.length === 0) return await ctx.reply(`${command} `); + if (!orders.length) return await ctx.reply(`${command} `); return await messages.showConfirmationButtons(ctx, orders, command); } else if (!(await validateObjectId(ctx, orderId))) { @@ -448,7 +445,7 @@ const initialize = (botToken: string, options: Partial el); + const [command, orderId] = params.filter((el) => el); if (!orderId) { const orders = await askForConfirmation(ctx.user, command); - if (orders === null || orders.length === 0) return await ctx.reply(`${command} `); + if (!orders.length) return await ctx.reply(`${command} `); return await messages.showConfirmationButtons(ctx, orders, command); } else if (!(await validateObjectId(ctx, orderId))) { @@ -641,7 +637,7 @@ const initialize = (botToken: string, options: Partial el.id !== user.id + community.banned_users = community.banned_users.filter( + (el: any) => el.id !== user.id ); await community.save(); } else { @@ -745,7 +739,7 @@ const initialize = (botToken: string, options: Partial { try { const config = await Config.findOne({}); - if (config === null) throw Error("Config was not found in DB"); await messages.showInfoMessage(ctx, ctx.user, config); } catch (error) { logger.error(error); diff --git a/bot/validations.ts b/bot/validations.js similarity index 76% rename from bot/validations.ts rename to bot/validations.js index 36e1734a..781622b9 100644 --- a/bot/validations.ts +++ b/bot/validations.js @@ -1,32 +1,18 @@ -import { MainContext, OrderQuery, ctxUpdateAssertMsg } from "./start"; -import { ICommunity } from "../models/community"; -import { FilterQuery } from "mongoose"; -import { UserDocument } from "../models/user"; -import { IOrder } from "../models/order"; -import { Telegraf } from "telegraf"; - const { parsePaymentRequest } = require('invoices'); const { ObjectId } = require('mongoose').Types; -import * as messages from './messages'; -import { Order, User, Community } from '../models'; -import { isIso4217, isDisputeSolver } from '../util'; +const messages = require('./messages'); +const { Order, User, Community } = require('../models'); +const { isIso4217, isDisputeSolver } = require('../util'); const { existLightningAddress } = require('../lnurl/lnurl-pay'); -import { logger } from '../logger'; +const { logger } = require('../logger'); // We look in database if the telegram user exists, // if not, it creates a new user -const validateUser = async (ctx: MainContext, start: boolean) => { +const validateUser = async (ctx, start) => { try { - let tgUser = null; - if (("callback_query" in ctx.update) && ctx.update.callback_query) { - tgUser = ctx.update.callback_query.from; - } - else if (("message" in ctx.update) && ctx.update.message) { - tgUser = ctx.update.message.from; - } - else { - throw new Error(ctxUpdateAssertMsg); - } + const tgUser = ctx.update.callback_query + ? ctx.update.callback_query.from + : ctx.update.message.from; // We need to make sure the user has a username if (!tgUser.username) { await ctx.telegram.sendMessage(tgUser.id, ctx.i18n.t('non_handle_error')); @@ -61,18 +47,15 @@ const validateUser = async (ctx: MainContext, start: boolean) => { } }; -const validateSuperAdmin = async (ctx: MainContext, id?: string) => { +const validateSuperAdmin = async (ctx, id) => { try { - if (!('message' in ctx.update) || !('text' in ctx.update.message)) { - throw new Error(ctxUpdateAssertMsg); - } const tgUserId = id || ctx.update.message.from.id; const user = await User.findOne({ tg_id: tgUserId }); // If the user never started the bot we can't send messages // to that user, so we do nothing - if (user === null) return; + if (!user) return; - if (!user.admin) return await messages.notAuthorized(ctx, tgUserId.toString()); + if (!user.admin) return await messages.notAuthorized(ctx, tgUserId); return user; } catch (error) { @@ -81,26 +64,22 @@ const validateSuperAdmin = async (ctx: MainContext, id?: string) => { } }; -const validateAdmin = async (ctx: MainContext, id?: string) => { +const validateAdmin = async (ctx, id) => { try { - if (!('message' in ctx.update) || !('text' in ctx.update.message)) { - throw new Error(ctxUpdateAssertMsg); - } const tgUserId = id || ctx.update.message.from.id; const user = await User.findOne({ tg_id: tgUserId }); // If the user never started the bot we can't send messages // to that user, so we do nothing - if (user === null) return; + if (!user) return; let community = null; if (user.default_community_id) community = await Community.findOne({ _id: user.default_community_id }); - if (community === null) throw Error("Community was not found in DB"); const isSolver = isDisputeSolver(community, user); if (!user.admin && !isSolver) - return await messages.notAuthorized(ctx, tgUserId.toString()); + return await messages.notAuthorized(ctx, tgUserId); return user; } catch (error) { @@ -109,7 +88,7 @@ const validateAdmin = async (ctx: MainContext, id?: string) => { } }; -const processParameters = (args: string[]) => { +const processParameters = args => { const correctedArgs = []; let isGrouping = false; let groupedString = ''; @@ -141,7 +120,7 @@ const processParameters = (args: string[]) => { return correctedArgs; }; -const validateSellOrder = async (ctx: MainContext) => { +const validateSellOrder = async ctx => { try { let args = ctx.state.command.args; if (args.length < 4) { @@ -186,11 +165,11 @@ const validateSellOrder = async (ctx: MainContext) => { return false; } - if (amount !== 0 && amount < Number(process.env.MIN_PAYMENT_AMT)) { + if (amount !== 0 && amount < process.env.MIN_PAYMENT_AMT) { await messages.mustBeGreatherEqThan( ctx, 'monto_en_sats', - Number(process.env.MIN_PAYMENT_AMT) + process.env.MIN_PAYMENT_AMT ); return false; } @@ -205,7 +184,7 @@ const validateSellOrder = async (ctx: MainContext) => { return false; } - if (fiatAmount.some((x: number) => x < 1)) { + if (fiatAmount.some(x => x < 1)) { await messages.mustBeGreatherEqThan(ctx, 'monto_en_fiat', 1); return false; } @@ -230,7 +209,7 @@ const validateSellOrder = async (ctx: MainContext) => { } }; -const validateBuyOrder = async (ctx: MainContext) => { +const validateBuyOrder = async ctx => { try { let args = ctx.state.command.args; if (args.length < 4) { @@ -274,11 +253,11 @@ const validateBuyOrder = async (ctx: MainContext) => { return false; } - if (amount !== 0 && amount < Number(process.env.MIN_PAYMENT_AMT)) { + if (amount !== 0 && amount < process.env.MIN_PAYMENT_AMT) { await messages.mustBeGreatherEqThan( ctx, 'monto_en_sats', - Number(process.env.MIN_PAYMENT_AMT) + process.env.MIN_PAYMENT_AMT ); return false; } @@ -293,7 +272,7 @@ const validateBuyOrder = async (ctx: MainContext) => { return false; } - if (fiatAmount.some((x: number) => x < 1)) { + if (fiatAmount.some(x => x < 1)) { await messages.mustBeGreatherEqThan(ctx, 'monto_en_fiat', 1); return false; } @@ -317,21 +296,20 @@ const validateBuyOrder = async (ctx: MainContext) => { return false; } }; -const validateLightningAddress = async (lightningAddress: string) => { +const validateLightningAddress = async lightningAddress => { const pattern = /^[\w-.]+@(?:[\w-]+(? { +const validateInvoice = async (ctx, lnInvoice) => { try { const invoice = parsePaymentRequest({ request: lnInvoice }); const latestDate = new Date( - Date.now() + Number(process.env.INVOICE_EXPIRATION_WINDOW) - ); - if (!("MAIN_PAYMENT_AMT" in process.env)) throw Error("MIN_PAYMENT_AMT not found, please check .env file"); - if (!!invoice.tokens && invoice.tokens < Number(process.env.MIN_PAYMENT_AMT)) { + Date.now() + parseInt(process.env.INVOICE_EXPIRATION_WINDOW) + ).toISOString(); + if (!!invoice.tokens && invoice.tokens < process.env.MIN_PAYMENT_AMT) { await messages.minimunAmountInvoiceMessage(ctx); return false; } @@ -364,20 +342,20 @@ const validateInvoice = async (ctx: MainContext, lnInvoice: string) => { } }; -const isValidInvoice = async (ctx: MainContext, lnInvoice: string) => { +const isValidInvoice = async (ctx, lnInvoice) => { try { const invoice = parsePaymentRequest({ request: lnInvoice }); const latestDate = new Date( - Date.now() + Number(process.env.INVOICE_EXPIRATION_WINDOW) + Date.now() + parseInt(process.env.INVOICE_EXPIRATION_WINDOW) ).toISOString(); - if (!!invoice.tokens && invoice.tokens < Number(process.env.MIN_PAYMENT_AMT)) { + if (!!invoice.tokens && invoice.tokens < process.env.MIN_PAYMENT_AMT) { await messages.invoiceMustBeLargerMessage(ctx); return { success: false, }; } - if (new Date(invoice.expires_at).toISOString() < latestDate) { + if (new Date(invoice.expires_at) < latestDate) { await messages.invoiceExpiryTooShortMessage(ctx); return { success: false, @@ -417,7 +395,7 @@ const isValidInvoice = async (ctx: MainContext, lnInvoice: string) => { } }; -const isOrderCreator = (user: UserDocument, order: IOrder) => { +const isOrderCreator = (user, order) => { try { return user._id == order.creator_id; } catch (error) { @@ -426,7 +404,7 @@ const isOrderCreator = (user: UserDocument, order: IOrder) => { } }; -const validateTakeSellOrder = async (ctx: MainContext, bot: Telegraf, user: UserDocument, order: IOrder) => { +const validateTakeSellOrder = async (ctx, bot, user, order) => { try { if (!order) { await messages.invalidOrderMessage(ctx, bot, user); @@ -455,10 +433,10 @@ const validateTakeSellOrder = async (ctx: MainContext, bot: Telegraf, user: UserDocument, order: IOrder) => { +const validateTakeBuyOrder = async (ctx, bot, user, order) => { try { if (!order) { - await messages.invalidOrderMessage(ctx, bot, user); + await messages.invalidOrderMessage(bot, user); return false; } if (isOrderCreator(user, order) && process.env.NODE_ENV === 'production') { @@ -480,9 +458,9 @@ const validateTakeBuyOrder = async (ctx: MainContext, bot: Telegraf } }; -const validateReleaseOrder = async (ctx: MainContext, user: UserDocument, orderId: string) => { +const validateReleaseOrder = async (ctx, user, orderId) => { try { - let where: FilterQuery = { + let where = { seller_id: user._id, status: 'WAITING_BUYER_INVOICE', _id: orderId, @@ -511,7 +489,7 @@ const validateReleaseOrder = async (ctx: MainContext, user: UserDocument, orderI } order = await Order.findOne(where); - if (order === null) { + if (!order) { await messages.notActiveOrderMessage(ctx); return false; } @@ -523,7 +501,7 @@ const validateReleaseOrder = async (ctx: MainContext, user: UserDocument, orderI } }; -const validateDisputeOrder = async (ctx: MainContext, user: UserDocument, orderId: string) => { +const validateDisputeOrder = async (ctx, user, orderId) => { try { const where = { $and: [ @@ -535,7 +513,7 @@ const validateDisputeOrder = async (ctx: MainContext, user: UserDocument, orderI const order = await Order.findOne(where); - if (order === null) { + if (!order) { await messages.notActiveOrderMessage(ctx); return false; } @@ -547,9 +525,9 @@ const validateDisputeOrder = async (ctx: MainContext, user: UserDocument, orderI } }; -const validateFiatSentOrder = async (ctx: MainContext, user: UserDocument, orderId: string) => { +const validateFiatSentOrder = async (ctx, user, orderId) => { try { - const where: FilterQuery = { + const where = { $and: [ { buyer_id: user._id }, { $or: [{ status: 'ACTIVE' }, { status: 'PAID_HOLD_INVOICE' }] }, @@ -560,7 +538,7 @@ const validateFiatSentOrder = async (ctx: MainContext, user: UserDocument, order where._id = orderId; } const order = await Order.findOne(where); - if (order === null) { + if (!order) { await messages.notActiveOrderMessage(ctx); return false; } @@ -583,7 +561,7 @@ const validateFiatSentOrder = async (ctx: MainContext, user: UserDocument, order }; // If a seller have an order with status FIAT_SENT, return false -const validateSeller = async (ctx: MainContext, user: UserDocument) => { +const validateSeller = async (ctx, user) => { try { const where = { seller_id: user._id, @@ -604,13 +582,10 @@ const validateSeller = async (ctx: MainContext, user: UserDocument) => { } }; -const validateParams = async (ctx: MainContext, paramNumber: number, errOutputString: string): Promise> => { +const validateParams = async (ctx, paramNumber, errOutputString) => { try { - if (!('message' in ctx.update) || !('text' in ctx.update.message)) { - throw new Error(ctxUpdateAssertMsg); - } const paramsArray = ctx.update.message.text.split(' '); - const params = paramsArray.filter((el: string) => el !== ''); + const params = paramsArray.filter(el => el !== ''); if (params.length !== paramNumber) { await messages.customMessage( ctx, @@ -623,11 +598,11 @@ const validateParams = async (ctx: MainContext, paramNumber: number, errOutputSt return params.slice(1); } catch (error) { logger.error(error); - return null; + return false; } }; -const validateObjectId = async (ctx: MainContext, id: string) => { +const validateObjectId = async (ctx, id) => { try { if (!ObjectId.isValid(id)) { await messages.notValidIdMessage(ctx); @@ -641,10 +616,10 @@ const validateObjectId = async (ctx: MainContext, id: string) => { } }; -const validateUserWaitingOrder = async (ctx: MainContext, bot: Telegraf, user: UserDocument) => { +const validateUserWaitingOrder = async (ctx, bot, user) => { try { // If is a seller - let where: FilterQuery = { + let where = { seller_id: user._id, status: 'WAITING_PAYMENT', }; @@ -671,12 +646,12 @@ const validateUserWaitingOrder = async (ctx: MainContext, bot: Telegraf { +const isBannedFromCommunity = async (user, communityId) => { try { if (!communityId) return false; const community = await Community.findOne({ _id: communityId }); if (!community) return false; - return community.banned_users.toObject().some((buser: ICommunity) => buser.id == user._id); + return community.banned_users.some(buser => buser.id == user._id); } catch (error) { logger.error(error); return false; diff --git a/jobs/calculate_community_earnings.ts b/jobs/calculate_community_earnings.js similarity index 77% rename from jobs/calculate_community_earnings.ts rename to jobs/calculate_community_earnings.js index 3ccc7b39..87eb3e28 100644 --- a/jobs/calculate_community_earnings.ts +++ b/jobs/calculate_community_earnings.js @@ -1,5 +1,5 @@ -import { Order, Community } from '../models'; -import { logger } from "../logger"; +const { Order, Community } = require('../models'); +const { logger } = require('../logger'); const calculateEarnings = async () => { try { @@ -12,9 +12,9 @@ const calculateEarnings = async () => { for (const order of orders) { const amount = order.amount; const fee = order.fee; - const botFee = order.bot_fee || Number(process.env.MAX_FEE); + const botFee = order.bot_fee || parseFloat(process.env.MAX_FEE); const communityFeePercent = - order.community_fee || Number(process.env.FEE_PERCENT); + order.community_fee || parseFloat(process.env.FEE_PERCENT); const maxFee = amount * botFee; const communityFee = fee - maxFee * communityFeePercent; const earnings = earningsMap.get(order.community_id) || [0, 0]; @@ -27,7 +27,6 @@ const calculateEarnings = async () => { } for (const [communityId, earnings] of earningsMap) { const community = await Community.findById(communityId); - if (community === null) throw Error("Community was not found in DB"); const amount = Math.round(earnings[0]); community.earnings = community.earnings + amount; community.orders_to_redeem = community.orders_to_redeem + earnings[1]; @@ -37,9 +36,9 @@ const calculateEarnings = async () => { ); } } catch (error) { - const message = String(error); + const message = error.toString(); logger.error(`calculateEarnings catch error: ${message}`); } }; -export default calculateEarnings; +module.exports = calculateEarnings; diff --git a/jobs/cancel_orders.ts b/jobs/cancel_orders.js similarity index 86% rename from jobs/cancel_orders.ts rename to jobs/cancel_orders.js index 686b3dec..4cce5064 100644 --- a/jobs/cancel_orders.ts +++ b/jobs/cancel_orders.js @@ -1,18 +1,16 @@ -import { Telegraf } from "telegraf"; -import { MainContext } from "../bot/start"; -import { User, Order } from "../models"; +const { User, Order } = require('../models'); const { cancelShowHoldInvoice, cancelAddInvoice } = require('../bot/commands'); -import * as messages from "../bot/messages"; -import { getUserI18nContext, holdInvoiceExpirationInSecs } from '../util'; -import { logger } from "../logger"; +const messages = require('../bot/messages'); +const { getUserI18nContext, holdInvoiceExpirationInSecs } = require('../util'); +const { logger } = require('../logger'); const OrderEvents = require('../bot/modules/events/orders'); -const cancelOrders = async (bot: Telegraf) => { +const cancelOrders = async bot => { try { const holdInvoiceTime = new Date(); holdInvoiceTime.setSeconds( holdInvoiceTime.getSeconds() - - Number(process.env.HOLD_INVOICE_EXPIRATION_WINDOW) + parseInt(process.env.HOLD_INVOICE_EXPIRATION_WINDOW) ); // We get the orders where the seller didn't pay the hold invoice before expired // or where the buyer didn't add the invoice @@ -56,7 +54,6 @@ const cancelOrders = async (bot: Telegraf) => { for (const order of activeOrders) { const buyerUser = await User.findOne({ _id: order.buyer_id }); const sellerUser = await User.findOne({ _id: order.seller_id }); - if (buyerUser === null || sellerUser === null) return; const i18nCtxBuyer = await getUserI18nContext(buyerUser); const i18nCtxSeller = await getUserI18nContext(sellerUser); // Instead of cancel this order we should send this to the admins @@ -82,7 +79,7 @@ const cancelOrders = async (bot: Telegraf) => { // Now we cancel orders expired // ============================== orderTime = new Date(); - let orderExpirationTime = Number( + let orderExpirationTime = parseInt( process.env.ORDER_PUBLISHED_EXPIRATION_WINDOW ); orderExpirationTime = orderExpirationTime + orderExpirationTime * 0.2; @@ -109,4 +106,4 @@ const cancelOrders = async (bot: Telegraf) => { } }; -export default cancelOrders; +module.exports = cancelOrders; diff --git a/jobs/communities.ts b/jobs/communities.js similarity index 70% rename from jobs/communities.ts rename to jobs/communities.js index a3599506..4d28409e 100644 --- a/jobs/communities.ts +++ b/jobs/communities.js @@ -1,15 +1,12 @@ -import { Telegraf } from "telegraf"; -import { MainContext } from "../bot/start"; +const { Order, Community } = require('../models'); +const { logger } = require('../logger'); -import { Order, Community } from '../models'; -import { logger } from "../logger"; - -const deleteCommunity = async (bot: Telegraf) => { +const deleteCommunity = async bot => { try { const communities = await Community.find(); for (const community of communities) { // Delete communities with COMMUNITY_TTL days without a successful order - const days = 86400 * Number(process.env.COMMUNITY_TTL); + const days = 86400 * parseInt(process.env.COMMUNITY_TTL); const time = new Date(); time.setSeconds(time.getSeconds() - days); // If is a new community we don't do anything @@ -29,9 +26,9 @@ const deleteCommunity = async (bot: Telegraf) => { } } } catch (error) { - const message = String(error); + const message = error.toString(); logger.error(`deleteCommunity catch error: ${message}`); } }; -export default deleteCommunity; +module.exports = deleteCommunity; diff --git a/jobs/delete_published_orders.ts b/jobs/delete_published_orders.js similarity index 73% rename from jobs/delete_published_orders.ts rename to jobs/delete_published_orders.js index 4182840d..bec2af2f 100644 --- a/jobs/delete_published_orders.ts +++ b/jobs/delete_published_orders.js @@ -1,16 +1,13 @@ -import { Telegraf } from "telegraf"; -import { MainContext } from "../bot/start"; - -import { Order } from '../models'; +const { Order } = require('../models'); const { deleteOrderFromChannel } = require('../util'); -import { logger } from '../logger'; +const { logger } = require('../logger'); -const deleteOrders = async (bot: Telegraf) => { +const deleteOrders = async bot => { try { const windowTime = new Date(); windowTime.setSeconds( windowTime.getSeconds() - - Number(process.env.ORDER_PUBLISHED_EXPIRATION_WINDOW) + parseInt(process.env.ORDER_PUBLISHED_EXPIRATION_WINDOW) ); // We get the pending orders where time is expired const pendingOrders = await Order.find({ @@ -28,9 +25,9 @@ const deleteOrders = async (bot: Telegraf) => { await deleteOrderFromChannel(orderCloned, bot.telegram); } } catch (error) { - const message = String(error); + const message = error.toString(); logger.error(`deleteOrders catch error: ${message}`); } }; -export default deleteOrders; +module.exports = deleteOrders; diff --git a/jobs/index.js b/jobs/index.js new file mode 100644 index 00000000..b784f178 --- /dev/null +++ b/jobs/index.js @@ -0,0 +1,19 @@ +const { + attemptPendingPayments, + attemptCommunitiesPendingPayments, +} = require('./pending_payments'); +const cancelOrders = require('./cancel_orders'); +const deleteOrders = require('./delete_published_orders'); +const calculateEarnings = require('./calculate_community_earnings'); +const deleteCommunity = require('./communities'); +const nodeInfo = require('./node_info'); + +module.exports = { + attemptPendingPayments, + cancelOrders, + deleteOrders, + calculateEarnings, + attemptCommunitiesPendingPayments, + deleteCommunity, + nodeInfo, +}; diff --git a/jobs/index.ts b/jobs/index.ts deleted file mode 100644 index 281f16f6..00000000 --- a/jobs/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { - attemptPendingPayments, - attemptCommunitiesPendingPayments, -} from "./pending_payments"; -import cancelOrders from "./cancel_orders"; -import deleteOrders from "./delete_published_orders"; -import calculateEarnings from './calculate_community_earnings' -import deleteCommunity from './communities' -import nodeInfo from './node_info' - -export { - attemptPendingPayments, - cancelOrders, - deleteOrders, - calculateEarnings, - attemptCommunitiesPendingPayments, - deleteCommunity, - nodeInfo, -}; diff --git a/jobs/node_info.ts b/jobs/node_info.js similarity index 62% rename from jobs/node_info.ts rename to jobs/node_info.js index 22e82eb3..94c994d0 100644 --- a/jobs/node_info.ts +++ b/jobs/node_info.js @@ -1,14 +1,11 @@ -import { Telegraf } from "telegraf"; -import { MainContext } from "../bot/start"; - -import { Config } from '../models'; +const { Config } = require('../models'); const { getInfo } = require('../ln'); const { logger } = require('../logger'); -const info = async (bot: Telegraf) => { +const info = async bot => { try { let config = await Config.findOne({}); - if (config === null) { + if (!config) { config = new Config(); } const info = await getInfo(); @@ -18,9 +15,9 @@ const info = async (bot: Telegraf) => { config.node_uri = info.uris[0]; await config.save(); } catch (error) { - const message = String(error); + const message = error.toString(); logger.error(`node info catch error: ${message}`); } }; -export default info; +module.exports = info; diff --git a/jobs/pending_payments.ts b/jobs/pending_payments.ts index b3b9a091..90bdfff7 100644 --- a/jobs/pending_payments.ts +++ b/jobs/pending_payments.ts @@ -1,14 +1,14 @@ -import { PendingPayment, Order, User, Community } from '../models'; +const { payRequest, isPendingPayment } = require('../ln'); +const { PendingPayment, Order, User, Community } = require('../models'); import * as messages from '../bot/messages'; -import { logger } from "../logger"; +const { getUserI18nContext } = require('../util'); +const { logger } = require('../logger'); import { Telegraf } from 'telegraf'; import { I18nContext } from '@grammyjs/i18n'; import { MainContext } from '../bot/start'; -const { payRequest, isPendingPayment } = require('../ln'); -import { getUserI18nContext } from '../util'; const { orderUpdated } = require('../bot/modules/events/orders'); -export const attemptPendingPayments = async (bot: Telegraf): Promise => { +exports.attemptPendingPayments = async (bot: Telegraf): Promise => { const pendingPayments = await PendingPayment.find({ paid: false, attempts: { $lt: process.env.PAYMENT_ATTEMPTS }, @@ -18,7 +18,6 @@ export const attemptPendingPayments = async (bot: Telegraf): Promis for (const pending of pendingPayments) { const order = await Order.findOne({ _id: pending.order_id }); try { - if (order === null) throw Error("Order was not found in DB"); pending.attempts++; if (order.status === 'SUCCESS') { pending.paid = true; @@ -40,7 +39,6 @@ export const attemptPendingPayments = async (bot: Telegraf): Promis request: pending.payment_request, }); const buyerUser = await User.findOne({ _id: order.buyer_id }); - if (buyerUser === null) throw Error("buyerUser was not found in DB"); const i18nCtx: I18nContext = await getUserI18nContext(buyerUser); // If the buyer's invoice is expired we let it know and don't try to pay again if (!!payment && payment.is_expired) { @@ -58,13 +56,12 @@ export const attemptPendingPayments = async (bot: Telegraf): Promis order.status = 'SUCCESS'; order.routing_fee = payment.fee; pending.paid = true; - pending.paid_at = new Date(); + pending.paid_at = new Date().toISOString(); // We add a new completed trade for the buyer buyerUser.trades_completed++; await buyerUser.save(); // We add a new completed trade for the seller const sellerUser = await User.findOne({ _id: order.seller_id }); - if (sellerUser === null) throw Error("sellerUser was not found in DB"); sellerUser.trades_completed++; sellerUser.save(); logger.info(`Invoice with hash: ${pending.hash} paid`); @@ -109,16 +106,14 @@ export const attemptPendingPayments = async (bot: Telegraf): Promis const message: string = error.toString(); logger.error(`attemptPendingPayments catch error: ${message}`); } finally { - if (order !== null) { - await order.save(); - orderUpdated(order); - } + await order.save(); + orderUpdated(order); await pending.save(); } } }; -export const attemptCommunitiesPendingPayments = async (bot: Telegraf): Promise => { +exports.attemptCommunitiesPendingPayments = async (bot: Telegraf): Promise => { const pendingPayments = await PendingPayment.find({ paid: false, attempts: { $lt: process.env.PAYMENT_ATTEMPTS }, @@ -141,7 +136,6 @@ export const attemptCommunitiesPendingPayments = async (bot: Telegraf { +const resolvLightningAddress = async (address, amountMsat) => { const [user, domain] = address.split('@'); const lnAddressQuery = `https://${domain}/.well-known/lnurlp/${user}`; @@ -17,7 +17,7 @@ const resolvLightningAddress = async (address: string, amountMsat: number) => { } if ( - (lnAddressRes.minSendable > amountMsat) || + (lnAddressRes.minSendable > amountMsat) | (lnAddressRes.maxSendable < amountMsat) ) { logger.info('lnAddress invalid amount'); @@ -31,7 +31,7 @@ const resolvLightningAddress = async (address: string, amountMsat: number) => { return res; }; -const existLightningAddress = async (address: string) => { +const existLightningAddress = async address => { const [user, domain] = address.split('@'); const lnAddressQuery = `https://${domain}/.well-known/lnurlp/${user}`; @@ -48,4 +48,7 @@ const existLightningAddress = async (address: string) => { } }; -export { resolvLightningAddress, existLightningAddress } +module.exports = { + resolvLightningAddress, + existLightningAddress, +}; diff --git a/package-lock.json b/package-lock.json index 9b99bdb9..139aee65 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,6 @@ }, "devDependencies": { "@types/node": "^20.5.0", - "@types/node-schedule": "^2.1.0", "@types/qrcode": "^1.5.2", "chai": "^4.3.4", "chokidar": "^3.5.3", @@ -1774,15 +1773,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.5.0.tgz", "integrity": "sha512-Mgq7eCtoTjT89FqNoTzzXg2XvCi5VMhRV6+I2aYanc6kQCBImeNaAYRs/DyoVqk1YEUJK5gN9VO7HRIdz4Wo3Q==" }, - "node_modules/@types/node-schedule": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/node-schedule/-/node-schedule-2.1.0.tgz", - "integrity": "sha512-NiTwl8YN3v/1YCKrDFSmCTkVxFDylueEqsOFdgF+vPsm+AlyJKGAo5yzX1FiOxPsZiN6/r8gJitYx2EaSuBmmg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/qrcode": { "version": "1.5.5", "resolved": "https://registry.npmjs.org/@types/qrcode/-/qrcode-1.5.5.tgz", diff --git a/package.json b/package.json index 7706079a..b622708c 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,6 @@ "devDependencies": { "@types/node": "^20.5.0", "@types/qrcode": "^1.5.2", - "@types/node-schedule": "^2.1.0", "chai": "^4.3.4", "chokidar": "^3.5.3", "eslint": "^8.15.0", diff --git a/tsconfig.json b/tsconfig.json index 7b8d0663..f2c464b6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,5 @@ "compilerOptions": { "strict": true, "esModuleInterop": true, - "resolveJsonModule": true, - "downlevelIteration": true } } diff --git a/util/fiatModel.ts b/util/fiatModel.ts index cc8d22e8..a722adc0 100644 --- a/util/fiatModel.ts +++ b/util/fiatModel.ts @@ -10,7 +10,3 @@ export interface IFiat { price?: boolean; locale?: string; } - -export interface IFiatCurrencies { - [key: string]: IFiat; -} diff --git a/util/index.ts b/util/index.js similarity index 70% rename from util/index.ts rename to util/index.js index 8d0f2da5..628b2117 100644 --- a/util/index.ts +++ b/util/index.js @@ -1,29 +1,20 @@ -import { I18nContext } from "@grammyjs/i18n"; -import { ICommunity, IOrderChannel } from "../models/community"; -import { IOrder } from "../models/order"; -import { UserDocument } from "../models/user"; -import { IFiatCurrencies, IFiat } from "./fiatModel"; -import { ILanguage, ILanguages } from "./languagesModel"; -import { Telegram } from "telegraf"; -import axios from "axios"; -import fiatJson from './fiat.json'; -import languagesJson from './languages.json'; -import { Order, Community } from "../models"; -import { logger } from "../logger"; +const axios = require('axios'); const { I18n } = require('@grammyjs/i18n'); +const currencies = require('./fiat.json'); // ISO 639-1 language codes - -const languages: ILanguages = languagesJson; -const currencies: IFiatCurrencies = fiatJson; +const languages = require('./languages.json'); +const { Order, Community } = require('../models'); +const { logger } = require('../logger'); // ISO 4217, all ISO currency codes are 3 letters but users can trade shitcoins -const isIso4217 = (code: string): boolean => { + +const isIso4217 = code => { if (code.length < 3 || code.length > 5) { return false; } const alphabet = 'abcdefghijklmnopqrstuvwxyz'.split(''); - code = code.toLowerCase() - return code.split('').every(letter => { + code = code.toLowerCase().split(''); + return code.every(letter => { if (alphabet.indexOf(letter) == -1) { return false; } @@ -31,16 +22,19 @@ const isIso4217 = (code: string): boolean => { }); }; -const getCurrency = (code: string): (IFiat | null) => { - if (!isIso4217(code)) return null; +exports.isIso4217 = isIso4217; + +const getCurrency = code => { + if (!isIso4217(code)) return false; const currency = currencies[code]; - if (!currency) return null; + if (!currency) return false; return currency; }; -const plural = (n: number): string => { +exports.getCurrency = getCurrency; +const plural = n => { if (n === 1) { return ''; } @@ -51,7 +45,8 @@ exports.plural = plural; // This function formats a number to locale strings. // If Iso code or locale code doesn´t exist, the function will return a number without format. -const numberFormat = (code: string, number: number) => { + +exports.numberFormat = (code, number) => { if (!isIso4217(code)) return false; if (!currencies[code]) return number; @@ -67,7 +62,8 @@ const numberFormat = (code: string, number: number) => { // This function checks if the current buyer and seller were doing circular operations // In order to increase their trades_completed and volume_traded. // If we found those trades in the last 24 hours we decrease both variables to both users -const handleReputationItems = async (buyer: UserDocument, seller: UserDocument, amount: number) => { + +exports.handleReputationItems = async (buyer, seller, amount) => { try { const yesterday = new Date(Date.now() - 86400000).toISOString(); const orders = await Order.find({ @@ -78,7 +74,7 @@ const handleReputationItems = async (buyer: UserDocument, seller: UserDocument, }); if (orders.length > 0) { let totalAmount = 0; - orders.forEach((order: IOrder) => { + orders.forEach(order => { totalAmount += order.amount; }); const lastAmount = orders[orders.length - 1].amount; @@ -132,10 +128,9 @@ const handleReputationItems = async (buyer: UserDocument, seller: UserDocument, } }; -const getBtcFiatPrice = async (fiatCode: string, fiatAmount: number) => { +exports.getBtcFiatPrice = async (fiatCode, fiatAmount) => { try { const currency = getCurrency(fiatCode); - if (currency === null) throw Error("Currency not found"); if (!currency.price) return; // Before hit the endpoint we make sure the code have only 3 chars const code = currency.code.substring(0, 3); @@ -145,13 +140,13 @@ const getBtcFiatPrice = async (fiatCode: string, fiatAmount: number) => { } const sats = (fiatAmount / response.data.btc) * 100000000; - return Number(sats); + return parseInt(sats); } catch (error) { logger.error(error); } }; -const getBtcExchangePrice = (fiatAmount: number, satsAmount: number) => { +exports.getBtcExchangePrice = (fiatAmount, satsAmount) => { try { const satsPerBtc = 1e8; const feeRate = (satsPerBtc * fiatAmount) / satsAmount; @@ -162,8 +157,8 @@ const getBtcExchangePrice = (fiatAmount: number, satsAmount: number) => { } }; -const objectToArray = (object: any): any[] => { - const array: any[] = []; +const objectToArray = object => { + const array = []; for (const i in object) array.push(object[i]); @@ -172,20 +167,20 @@ const objectToArray = (object: any): any[] => { exports.objectToArray = objectToArray; -const getCurrenciesWithPrice = () => { +exports.getCurrenciesWithPrice = () => { const currenciesArr = objectToArray(currencies); const withPrice = currenciesArr.filter(currency => currency.price); return withPrice; }; -const toKebabCase = (string: string) => +exports.toKebabCase = string => string .replace(/([a-z])([A-Z])/g, '$1-$2') .replace(/[\s_]+/g, '-') .toLowerCase(); -const getEmojiRate = (rate: number) => { +const getEmojiRate = rate => { const star = '⭐'; const roundedRate = Math.round(rate); const output = []; @@ -194,9 +189,12 @@ const getEmojiRate = (rate: number) => { return output.join(''); }; +exports.getEmojiRate = getEmojiRate; + // Round number to exp decimal digits // Source: https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Math/round#redondeo_decimal -const decimalRound = (value: number, exp: number): number => { + +const decimalRound = (value, exp) => { if (typeof exp === 'undefined' || +exp === 0) { return Math.round(value); } @@ -207,29 +205,32 @@ const decimalRound = (value: number, exp: number): number => { return NaN; } // Shift - let valueArr = value.toString().split('e'); - value = Math.round(+(valueArr[0] + 'e' + (valueArr[1] ? +valueArr[1] - exp : -exp))); + value = value.toString().split('e'); + value = Math.round(+(value[0] + 'e' + (value[1] ? +value[1] - exp : -exp))); // Shift back - valueArr = value.toString().split('e'); - return +(valueArr[0] + 'e' + (valueArr[1] ? +valueArr[1] + exp : exp)); + value = value.toString().split('e'); + return +(value[0] + 'e' + (value[1] ? +value[1] + exp : exp)); }; -const extractId = (text: string): (string | null) => { +exports.decimalRound = decimalRound; + +exports.extractId = text => { const matches = text.match(/:([a-f0-9]{24}):$/); - if (matches !== null){ - return matches?.[1]; - } - return null; + + return matches[1]; }; // Clean strings that are going to be rendered with markdown -const sanitizeMD = (text: any) => { + +const sanitizeMD = text => { if (!text) return ''; - return String(text).replace(/(?=[|<>(){}[\]\-_!#.`=+])/g, '\\'); + return text.toString().replace(/(?=[|<>(){}[\]\-_!#.`=+])/g, '\\'); }; -const secondsToTime = (secs: number) => { +exports.sanitizeMD = sanitizeMD; + +exports.secondsToTime = secs => { const hours = Math.floor(secs / (60 * 60)); const divisor = secs % (60 * 60); @@ -241,9 +242,9 @@ const secondsToTime = (secs: number) => { }; }; -const isGroupAdmin = async (groupId: string, user: UserDocument, telegram: Telegram) => { +exports.isGroupAdmin = async (groupId, user, telegram) => { try { - const member = await telegram.getChatMember(groupId, Number(user.tg_id)); + const member = await telegram.getChatMember(groupId, user.tg_id); if ( member && (member.status === 'creator' || member.status === 'administrator') @@ -267,12 +268,12 @@ const isGroupAdmin = async (groupId: string, user: UserDocument, telegram: Teleg logger.error(error); return { success: false, - message: String(error), + message: error.toString(), }; } }; -const deleteOrderFromChannel = async (order: IOrder, telegram: Telegram) => { +exports.deleteOrderFromChannel = async (order, telegram) => { try { let channel = process.env.CHANNEL; if (order.community_id) { @@ -290,13 +291,13 @@ const deleteOrderFromChannel = async (order: IOrder, telegram: Telegram) => { } } } - await telegram.deleteMessage(channel!, Number(order.tg_channel_message1!)); + await telegram.deleteMessage(channel, order.tg_channel_message1); } catch (error) { logger.error(error); } }; -const getOrderChannel = async (order: IOrder) => { +exports.getOrderChannel = async order => { let channel = process.env.CHANNEL; if (order.community_id) { const community = await Community.findOne({ _id: order.community_id }); @@ -306,7 +307,7 @@ const getOrderChannel = async (order: IOrder) => { if (community.order_channels.length === 1) { channel = community.order_channels[0].name; } else { - community.order_channels.forEach(async (c: IOrderChannel) => { + community.order_channels.forEach(async c => { if (c.type === order.type) { channel = c.name; } @@ -317,11 +318,10 @@ const getOrderChannel = async (order: IOrder) => { return channel; }; -const getDisputeChannel = async (order: IOrder) => { +exports.getDisputeChannel = async order => { let channel = process.env.DISPUTE_CHANNEL; if (order.community_id) { const community = await Community.findOne({ _id: order.community_id }); - if (community === null) throw Error("Community was not found in DB"); channel = community.dispute_channel; } @@ -333,13 +333,8 @@ const getDisputeChannel = async (order: IOrder) => { * @param {*} user * @returns i18n context */ -const getUserI18nContext = async (user: UserDocument) => { - let language = null; - if (!('language' in user)) { - language = 'en'; - } else { - language = user.language; - } +exports.getUserI18nContext = async user => { + const language = user.language || 'en'; const i18n = new I18n({ locale: language, defaultLanguageOnMissing: true, @@ -349,7 +344,7 @@ const getUserI18nContext = async (user: UserDocument) => { return i18n.createContext(user.lang); }; -const getDetailedOrder = (i18n: I18nContext, order: IOrder, buyer: UserDocument, seller: UserDocument) => { +exports.getDetailedOrder = (i18n, order, buyer, seller) => { try { const buyerUsername = buyer ? sanitizeMD(buyer.username) : ''; const buyerReputation = buyer @@ -368,7 +363,7 @@ const getDetailedOrder = (i18n: I18nContext, order: IOrder, buyer: UserDocument, takenAt = sanitizeMD(takenAt); const previousDisputeStatus = sanitizeMD(order.previous_dispute_status); const status = sanitizeMD(order.status); - const fee = order.fee ? Number(order.fee) : ''; + const fee = order.fee ? parseInt(order.fee) : ''; const creator = order.creator_id === buyerId ? buyerUsername : sellerUsername; const buyerAge = getUserAge(buyer); @@ -402,7 +397,7 @@ const getDetailedOrder = (i18n: I18nContext, order: IOrder, buyer: UserDocument, }; // We need to know if this user is a dispute solver for this community -const isDisputeSolver = (community: ICommunity, user: UserDocument) => { +exports.isDisputeSolver = (community, user) => { if (!community || !user) { return false; } @@ -412,45 +407,49 @@ const isDisputeSolver = (community: ICommunity, user: UserDocument) => { // Return the fee the bot will charge to the seller // this fee is a combination from the global bot fee and the community fee -const getFee = async (amount: number, communityId: string) => { - const maxFee = Math.round(amount * Number(process.env.MAX_FEE)); +exports.getFee = async (amount, communityId) => { + const maxFee = Math.round(amount * parseFloat(process.env.MAX_FEE)); if (!communityId) return maxFee; - const botFee = maxFee * Number(process.env.FEE_PERCENT); + const botFee = maxFee * parseFloat(process.env.FEE_PERCENT); let communityFee = Math.round(maxFee - botFee); const community = await Community.findOne({ _id: communityId }); - if (community === null) throw Error("Community was not found in DB"); communityFee = communityFee * (community.fee / 100); return botFee + communityFee; }; -const itemsFromMessage = (str: string) => { +exports.itemsFromMessage = str => { return str .split(' ') .map(e => e.trim()) .filter(e => !!e); }; +// Check if a number is int +const isInt = n => parseInt(n) === n; + +exports.isInt = isInt; + // Check if a number is float -const isFloat = (n: number) => typeof n === 'number' && !Number.isInteger(n); +exports.isFloat = n => typeof n === 'number' && !isInt(n); // Returns an emoji flag for a language -const getLanguageFlag = (code: string): ILanguage => { +exports.getLanguageFlag = code => { return languages[code]; }; -const delay = (time: number) => { +exports.delay = time => { return new Promise(resolve => setTimeout(resolve, time)); }; // Returns the hold invoice expiration time in seconds, // and the hold invoice safety window in seconds -const holdInvoiceExpirationInSecs = () => { +exports.holdInvoiceExpirationInSecs = () => { const expirationTimeInSecs = - Number(process.env.HOLD_INVOICE_CLTV_DELTA) * 10 * 60; + parseInt(process.env.HOLD_INVOICE_CLTV_DELTA) * 10 * 60; const safetyWindowInSecs = - Number(process.env.HOLD_INVOICE_CLTV_DELTA_SAFETY_WINDOW) * 10 * 60; + parseInt(process.env.HOLD_INVOICE_CLTV_DELTA_SAFETY_WINDOW) * 10 * 60; return { expirationTimeInSecs, safetyWindowInSecs, @@ -458,7 +457,7 @@ const holdInvoiceExpirationInSecs = () => { }; // Returns the user age in days -const getUserAge = (user: UserDocument) => { +const getUserAge = user => { const userCreationDate = new Date(user.created_at); const today = new Date(); const ageInDays = Math.floor( @@ -467,19 +466,21 @@ const getUserAge = (user: UserDocument) => { return ageInDays; }; +exports.getUserAge = getUserAge; + /** * Returns order expiration time text * @param {*} order order object * @param {*} i18n context * @returns String with the remaining time to expiration in format '1 hours 30 minutes' */ -const getTimeToExpirationOrder = (order: IOrder, i18n: I18nContext) => { +exports.getTimeToExpirationOrder = (order, i18n) => { const initialDateObj = new Date(order.created_at); - const timeToExpire = Number(process.env.ORDER_PUBLISHED_EXPIRATION_WINDOW); + const timeToExpire = parseInt(process.env.ORDER_PUBLISHED_EXPIRATION_WINDOW); initialDateObj.setSeconds(initialDateObj.getSeconds() + timeToExpire); const currentDateObj = new Date(); - const timeDifferenceMs = initialDateObj.valueOf() - currentDateObj.valueOf(); + const timeDifferenceMs = initialDateObj - currentDateObj; const totalSecondsRemaining = Math.floor(timeDifferenceMs / 1000); const textHour = i18n.t('hours'); const textMin = i18n.t('minutes'); @@ -493,45 +494,13 @@ const getTimeToExpirationOrder = (order: IOrder, i18n: I18nContext) => { return `${hours} ${textHour} ${minutes} ${textMin}`; }; -export const getStars = (rate: number, totalReviews: number) => { +exports.getStars = (rate, totalReviews) => { const stars = getEmojiRate(rate); const roundedRating = decimalRound(rate, -1); return `${roundedRating} ${stars} (${totalReviews})`; }; -export const removeAtSymbol = (text: string) => { +exports.removeAtSymbol = text => { return text[0] === '@' ? text.slice(1) : text; -} - -export { - isIso4217, - plural, - getCurrency, - handleReputationItems, - getBtcFiatPrice, - getBtcExchangePrice, - getCurrenciesWithPrice, - getEmojiRate, - decimalRound, - extractId, - sanitizeMD, - secondsToTime, - isGroupAdmin, - deleteOrderFromChannel, - getOrderChannel, - getUserI18nContext, - numberFormat, - getDisputeChannel, - getDetailedOrder, - isDisputeSolver, - getFee, - itemsFromMessage, - isFloat, - getLanguageFlag, - delay, - holdInvoiceExpirationInSecs, - getUserAge, - getTimeToExpirationOrder, - toKebabCase }; diff --git a/util/languagesModel.ts b/util/languagesModel.ts deleted file mode 100644 index fa159815..00000000 --- a/util/languagesModel.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface ILanguage { - name: string; - emoji: string; - code: string; -} - -export interface ILanguages { - [key: string]: ILanguage; -}