Skip to content

Commit

Permalink
Continue JS -> TS conversion (lnp2pBot#435)
Browse files Browse the repository at this point in the history
* logger: convert js to ts

* db_connect: convert js to ts

* models: convert index.js to index.ts

Also replace "require" with "import" and
"module.exports" with "export".

* app: convert js to ts

We need to enable esModuleInterop to solve error TS1192:
```
error TS1192: Module '"tls"' has no default export.
```

* bot/messages: fixing types & import/exports

* ln: convert js to ts

* util/index: convert js to ts

The languageModel & fiatModel interface created to type-check
the data and ensure that it conforms to
the expected structure and format.
This can help you avoid errors and bugs when
working with the data in your code.
This commit enables resolveJsonModule to import module
with '.json' extension.

* jobs: convert js to ts

The --downlevelIteration flag is a TypeScript compiler
option that enables support for iterating over new
concepts like Map, Set, or Generator in older JavaScript
runtimes. By default, TypeScript targets ES3, which does
not support these features. If you use a for...of loop or
a spread operator on an iterable object, you may get an error.
Use Date instead of Date.toISOString cause paid_at has type
Date and during the conversion from js to ts,
we got compilation errors.

* bot/start: fixing types & import/exports

* bot/validation: convert js to ts

Using null instead of a boolean/undefined type is better.

* lnurl/lnurl-pay: convert js to ts

I had to change the '|', otherwise typescript would
complain this error msg:
```
The '|' operator is not allowed for boolean types.
Consider using '||' instead.
```

* refactor: correcting a bad practice

* refactor: there's no need for isInt()
  • Loading branch information
Mersho authored Oct 9, 2023
1 parent a6dcb61 commit c4b2406
Show file tree
Hide file tree
Showing 37 changed files with 441 additions and 312 deletions.
19 changes: 11 additions & 8 deletions app.js → app.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
require('dotenv').config();
const { SocksProxyAgent } = require('socks-proxy-agent');
const { start } = require('./bot');
const mongoConnect = require('./db_connect');
import * as dotenv from "dotenv";
dotenv.config()
import { SocksProxyAgent } from "socks-proxy-agent";
import { MainContext, start } from "./bot/start";
import mongoConnect from './db_connect'
const { resubscribeInvoices } = require('./ln');
const logger = require('./logger');
import logger from "./logger";
import { Telegraf } from "telegraf";
const { delay } = require('./util');

(async () => {
Expand All @@ -23,7 +25,7 @@ const { delay } = require('./util');
mongoose.connection
.once('open', async () => {
logger.info('Connected to Mongo instance.');
let options = { handlerTimeout: 60000 };
let options: Partial<Telegraf.Options<MainContext>> = { handlerTimeout: 60000 };
if (process.env.SOCKS_PROXY_HOST) {
const agent = new SocksProxyAgent(process.env.SOCKS_PROXY_HOST);
options = {
Expand All @@ -32,10 +34,11 @@ const { delay } = require('./util');
},
};
}
const bot = start(process.env.BOT_TOKEN, options);
const bot = start(String(process.env.BOT_TOKEN), options);
// Wait 1 seconds before try to resubscribe hold invoices
await delay(1000);
await resubscribeInvoices(bot);
})
.on('error', error => logger.error(`Error connecting to Mongo: ${error}`));
.on('error', (error: Error) => logger.error(`Error connecting to Mongo: ${error}`));
})();

14 changes: 7 additions & 7 deletions bot/messages.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { TelegramError } = require('telegraf');
const QR = require('qrcode');
import { TelegramError } from 'telegraf'
import QR from 'qrcode';
const {
getCurrency,
numberFormat,
Expand All @@ -12,7 +12,7 @@ const {
decimalRound,
getUserAge,
} = require('../util');
const logger = require('../logger');
import logger from "../logger";
import { MainContext } from './start';
import { UserDocument } from '../models/user'
import { IOrder } from '../models/order'
Expand Down Expand Up @@ -109,7 +109,7 @@ const invoicePaymentRequestMessage = async (
}
};

const pendingSellMessage = async (ctx: MainContext, user: UserDocument, order: IOrder, channel: string, i18n: I18nContext) => {
const pendingSellMessage = async (ctx: Telegraf<MainContext>, user: UserDocument, order: IOrder, channel: string, i18n: I18nContext) => {
try {
const orderExpirationWindow =
Number(process.env.ORDER_PUBLISHED_EXPIRATION_WINDOW) / 60 / 60;
Expand Down Expand Up @@ -618,7 +618,7 @@ const publishBuyOrderMessage = async (
};

const publishSellOrderMessage = async (
ctx: MainContext,
ctx: Telegraf<MainContext>,
user: UserDocument,
order: IOrder,
i18n: I18nContext,
Expand Down Expand Up @@ -1549,7 +1549,7 @@ const currencyNotSupportedMessage = async (ctx: MainContext, currencies: Array<s
}
};

const notAuthorized = async (ctx: MainContext, tgId: string) => {
const notAuthorized = async (ctx: MainContext, tgId?: string) => {
try {
if (tgId) {
await ctx.telegram.sendMessage(tgId, ctx.i18n.t('not_authorized'));
Expand Down Expand Up @@ -1606,7 +1606,7 @@ const showConfirmationButtons = async (ctx: MainContext, orders: Array<IOrder>,
}
};

module.exports = {
export {
startMessage,
initBotErrorMessage,
invoicePaymentRequestMessage,
Expand Down
62 changes: 34 additions & 28 deletions bot/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,16 @@ import { I18n, I18nContext } from '@grammyjs/i18n';
import { Message } from 'typegram'
import { UserDocument } from '../models/user'
import { FilterQuery } from 'mongoose';

const { limit } = require('@grammyjs/ratelimiter');
const schedule = require('node-schedule');
const {
import { limit } from "@grammyjs/ratelimiter"
import schedule from 'node-schedule';
import {
Order,
User,
PendingPayment,
Community,
Dispute,
Config,
} = require('../models');
} from '../models';
const { getCurrenciesWithPrice, deleteOrderFromChannel } = require('../util');
const {
commandArgsMiddleware,
Expand Down Expand Up @@ -56,7 +55,7 @@ const {
validateInvoice,
validateLightningAddress,
} = require('./validations');
const messages = require('./messages');
import * as messages from './messages';
const {
attemptPendingPayments,
cancelOrders,
Expand All @@ -66,7 +65,8 @@ const {
deleteCommunity,
nodeInfo,
} = require('../jobs');
const logger = require('../logger');
import logger from "../logger";
import { ICommunity, IUsernameId } from '../models/community';

export interface MainContext extends Context {
match: Array<string> | null;
Expand All @@ -75,7 +75,7 @@ export interface MainContext extends Context {
admin: UserDocument;
}

interface OrderQuery {
export interface OrderQuery {
status?: string;
buyer_id?: string;
seller_id?: string;
Expand Down Expand Up @@ -125,6 +125,7 @@ const askForConfirmation = async (user: UserDocument, command: string) => {
return [];
} catch (error) {
logger.error(error);
return null;
}
};

Expand All @@ -137,7 +138,7 @@ has the same condition.
The problem mentioned above is similar to this issue:
https://github.com/telegraf/telegraf/issues/1319#issuecomment-766360594
*/
const ctxUpdateAssertMsg = "ctx.update.message.text is not available.";
export const ctxUpdateAssertMsg = "ctx.update.message.text is not available.";

const initialize = (botToken: string, options: Partial<Telegraf.Options<MainContext>>): Telegraf<MainContext> => {
const i18n = new I18n({
Expand Down Expand Up @@ -209,7 +210,7 @@ const initialize = (botToken: string, options: Partial<Telegraf.Options<MainCont
const [val] = await validateParams(ctx, 2, '\\<_on/off_\\>');
if (!val) return;
let config = await Config.findOne();
if (!config) {
if (config === null) {
config = new Config();
}
config.maintenance = false;
Expand Down Expand Up @@ -256,11 +257,11 @@ const initialize = (botToken: string, options: Partial<Telegraf.Options<MainCont
throw new Error(ctxUpdateAssertMsg);
}
const params = ctx.update.message.text.split(' ');
const [command, orderId] = params.filter((el) => el);
const [command, orderId] = params.filter((el: string) => el);

if (!orderId) {
const orders = await askForConfirmation(ctx.user, command);
if (!orders.length) return await ctx.reply(`${command} <order Id>`);
if (orders === null || orders.length === 0) return await ctx.reply(`${command} <order Id>`);

return await messages.showConfirmationButtons(ctx, orders, command);
} else if (!(await validateObjectId(ctx, orderId))) {
Expand All @@ -283,7 +284,7 @@ const initialize = (botToken: string, options: Partial<Telegraf.Options<MainCont
if (!(await validateObjectId(ctx, orderId))) return;
const order = await Order.findOne({ _id: orderId });

if (!order) return;
if (order === null) return;

// We look for a dispute for this order
const dispute = await Dispute.findOne({ order_id: order._id });
Expand Down Expand Up @@ -325,9 +326,10 @@ const initialize = (botToken: string, options: Partial<Telegraf.Options<MainCont

order.status = 'CANCELED_BY_ADMIN';
order.canceled_by = ctx.admin._id;
await order.save();
const buyer = await User.findOne({ _id: order.buyer_id });
const seller = await User.findOne({ _id: order.seller_id });
await order.save();
if (buyer === null || seller === null) throw Error("buyer and/or seller were not found in DB");
// we sent a private message to the admin
await messages.successCancelOrderMessage(ctx, ctx.admin, order, ctx.i18n);
// we sent a private message to the seller
Expand All @@ -347,11 +349,11 @@ const initialize = (botToken: string, options: Partial<Telegraf.Options<MainCont
throw new Error(ctxUpdateAssertMsg);
}
const params = ctx.update.message.text.split(' ');
const [command, orderId] = params.filter((el) => el);
const [command, orderId] = params.filter((el: string) => el);

if (!orderId) {
const orders = await askForConfirmation(ctx.user, command);
if (!orders.length) return await ctx.reply(`${command} <order Id>`);
if (orders === null || orders.length === 0) return await ctx.reply(`${command} <order Id>`);

return await messages.showConfirmationButtons(ctx, orders, command);
} else if (!(await validateObjectId(ctx, orderId))) {
Expand Down Expand Up @@ -394,7 +396,7 @@ const initialize = (botToken: string, options: Partial<Telegraf.Options<MainCont
if (!(await validateObjectId(ctx, orderId))) return;

const order = await Order.findOne({ _id: orderId });
if (!order) return;
if (order === null) return;

// We look for a dispute for this order
const dispute = await Dispute.findOne({ order_id: order._id });
Expand Down Expand Up @@ -424,9 +426,10 @@ const initialize = (botToken: string, options: Partial<Telegraf.Options<MainCont
}

order.status = 'COMPLETED_BY_ADMIN';
await order.save();
const buyer = await User.findOne({ _id: order.buyer_id });
const seller = await User.findOne({ _id: order.seller_id });
await order.save();
if (buyer === null || seller === null) throw Error("buyer and/or seller were not found in DB");
// we sent a private message to the admin
await messages.successCompleteOrderMessage(ctx, order);
// we sent a private message to the seller
Expand All @@ -450,11 +453,11 @@ const initialize = (botToken: string, options: Partial<Telegraf.Options<MainCont
if (!(await validateObjectId(ctx, orderId))) return;
const order = await Order.findOne({ _id: orderId });

if (!order) return;
if (order === null) return;

const buyer = await User.findOne({ _id: order.buyer_id });
const seller = await User.findOne({ _id: order.seller_id });

if (buyer === null || seller === null) throw Error("buyer and/or seller were not found in DB");
await messages.checkOrderMessage(ctx, order, buyer, seller);
} catch (error) {
logger.error(error);
Expand All @@ -468,7 +471,7 @@ const initialize = (botToken: string, options: Partial<Telegraf.Options<MainCont
if (!(await validateObjectId(ctx, orderId))) return;
const order = await Order.findOne({ _id: orderId });

if (!order) return;
if (order === null) return;
if (!order.hash) return;

const invoice = await getInvoice({ hash: order.hash });
Expand All @@ -492,7 +495,7 @@ const initialize = (botToken: string, options: Partial<Telegraf.Options<MainCont

const order = await Order.findOne({ hash });

if (!order) return;
if (order === null) return;
await subscribeInvoice(bot, hash, true);
ctx.reply(`hash resubscribed`);
} catch (error: any) {
Expand Down Expand Up @@ -523,11 +526,11 @@ const initialize = (botToken: string, options: Partial<Telegraf.Options<MainCont
throw new Error(ctxUpdateAssertMsg);
}
const params = ctx.update.message.text.split(' ');
const [command, orderId] = params.filter((el) => el);
const [command, orderId] = params.filter((el: string) => el);

if (!orderId) {
const orders = await askForConfirmation(ctx.user, command);
if (!orders.length) return await ctx.reply(`${command} <order Id>`);
if (orders === null || orders.length === 0) return await ctx.reply(`${command} <order Id>`);

return await messages.showConfirmationButtons(ctx, orders, command);
} else if (!(await validateObjectId(ctx, orderId))) {
Expand All @@ -554,7 +557,7 @@ const initialize = (botToken: string, options: Partial<Telegraf.Options<MainCont
const user = await User.findOne({
$or: [{ username }, { tg_id: username }],
});
if (!user) {
if (user === null) {
await messages.notFoundUserMessage(ctx);
return;
}
Expand All @@ -565,6 +568,7 @@ const initialize = (botToken: string, options: Partial<Telegraf.Options<MainCont
const community = await Community.findById(
ctx.admin.default_community_id
);
if (community === null) throw Error("Community was not found in DB");
community.banned_users.push({
id: user._id,
username: user.username,
Expand Down Expand Up @@ -597,7 +601,7 @@ const initialize = (botToken: string, options: Partial<Telegraf.Options<MainCont
const user = await User.findOne({
$or: [{ username }, { tg_id: username }],
});
if (!user) {
if (user === null) {
await messages.notFoundUserMessage(ctx);
return;
}
Expand All @@ -608,8 +612,9 @@ const initialize = (botToken: string, options: Partial<Telegraf.Options<MainCont
const community = await Community.findById(
ctx.admin.default_community_id
);
community.banned_users = community.banned_users.filter(
(el: any) => el.id !== user.id
if (community === null) throw Error("Community was not found in DB");
community.banned_users = community.banned_users.toObject().filter(
(el: IUsernameId) => el.id !== user.id
);
await community.save();
} else {
Expand Down Expand Up @@ -821,6 +826,7 @@ const initialize = (botToken: string, options: Partial<Telegraf.Options<MainCont
bot.command('info', userMiddleware, async (ctx: MainContext) => {
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);
Expand Down
Loading

0 comments on commit c4b2406

Please sign in to comment.