nexushub-commands 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/Client.d.ts +20 -0
- package/lib/Client.js +28 -0
- package/lib/commands/CheckPaidOrder.command.d.ts +4 -0
- package/lib/commands/CheckPaidOrder.command.js +31 -0
- package/lib/commands/Deposit.command.d.ts +5 -0
- package/lib/commands/Deposit.command.js +208 -0
- package/lib/commands/GetDepositOrder.command.d.ts +5 -0
- package/lib/commands/GetDepositOrder.command.js +92 -0
- package/lib/commands/Withdrawal.command.d.ts +0 -0
- package/lib/commands/Withdrawal.command.js +1 -0
- package/lib/commands/index.d.ts +3 -0
- package/lib/commands/index.js +6 -0
- package/lib/convert.d.ts +17 -0
- package/lib/convert.js +64 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +4 -0
- package/lib/utils/CoinBase.service.d.ts +33 -0
- package/lib/utils/CoinBase.service.js +113 -0
- package/lib/utils/formatMessage.d.ts +8 -0
- package/lib/utils/formatMessage.js +46 -0
- package/package.json +16 -0
- package/src/Client.ts +49 -0
- package/src/commands/CheckPaidOrder.command.ts +16 -0
- package/src/commands/Deposit.command.ts +243 -0
- package/src/commands/GetDepositOrder.command.ts +88 -0
- package/src/commands/Withdrawal.command.ts +0 -0
- package/src/commands/index.ts +3 -0
- package/src/convert.ts +91 -0
- package/src/index.ts +1 -0
- package/src/utils/CoinBase.service.ts +129 -0
- package/src/utils/formatMessage.ts +43 -0
- package/tsconfig.json +15 -0
package/lib/Client.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { AxiosInstance } from 'axios';
|
|
2
|
+
import { Evogram } from 'evogram';
|
|
3
|
+
import { CommandContext } from 'evogram/lib/migrated';
|
|
4
|
+
export interface DepositConfig {
|
|
5
|
+
API: AxiosInstance;
|
|
6
|
+
currency: string;
|
|
7
|
+
images: {
|
|
8
|
+
deposit: string;
|
|
9
|
+
depositCard: string;
|
|
10
|
+
depositCrypto: string;
|
|
11
|
+
[key: string]: string;
|
|
12
|
+
};
|
|
13
|
+
support: {
|
|
14
|
+
username: string;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export declare class Client {
|
|
18
|
+
static config: (context: CommandContext) => DepositConfig;
|
|
19
|
+
static init(client: Evogram): Promise<void>;
|
|
20
|
+
}
|
package/lib/Client.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Client = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const axios_1 = tslib_1.__importDefault(require("axios"));
|
|
6
|
+
const Deposit_command_1 = require("./commands/Deposit.command");
|
|
7
|
+
const GetDepositOrder_command_1 = require("./commands/GetDepositOrder.command");
|
|
8
|
+
// Значения по умолчанию для конфигурации
|
|
9
|
+
const defaultConfig = {
|
|
10
|
+
API: axios_1.default.create(),
|
|
11
|
+
currency: 'RUB',
|
|
12
|
+
images: {
|
|
13
|
+
deposit: 'deposit',
|
|
14
|
+
depositCard: 'deposit-card',
|
|
15
|
+
depositCrypto: 'deposit-crypto',
|
|
16
|
+
},
|
|
17
|
+
support: {
|
|
18
|
+
username: 'support',
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
class Client {
|
|
22
|
+
static init(client) {
|
|
23
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
24
|
+
client.commands.commands.push(new Deposit_command_1.DepositCommand(client), new GetDepositOrder_command_1.GetDepositOrderCommand(client));
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.Client = Client;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CheckPaidOrderCommand = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const evogram_1 = require("evogram");
|
|
6
|
+
const migrated_1 = require("evogram/lib/migrated");
|
|
7
|
+
const Client_1 = require("../Client");
|
|
8
|
+
let CheckPaidOrderCommand = class CheckPaidOrderCommand extends migrated_1.Command {
|
|
9
|
+
execute(context, orderId) {
|
|
10
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
11
|
+
var _a;
|
|
12
|
+
const config = Client_1.Client.config(context);
|
|
13
|
+
yield config.API.get(`/orders/${orderId}/checkPaid`).catch(() => { });
|
|
14
|
+
const order = yield config.API.get(`/orders/${orderId}`);
|
|
15
|
+
if (order.data.status !== 'paid' && order.data.status !== 'fakepaid')
|
|
16
|
+
throw new Error('Счет еще не оплачен');
|
|
17
|
+
else
|
|
18
|
+
(_a = context.callbackQuery) === null || _a === void 0 ? void 0 : _a.answer({ text: 'Счет оплачен', show_alert: true });
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
exports.CheckPaidOrderCommand = CheckPaidOrderCommand;
|
|
23
|
+
tslib_1.__decorate([
|
|
24
|
+
tslib_1.__param(1, (0, evogram_1.CommandArgument)('orderId')),
|
|
25
|
+
tslib_1.__metadata("design:type", Function),
|
|
26
|
+
tslib_1.__metadata("design:paramtypes", [migrated_1.CommandContext, String]),
|
|
27
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
28
|
+
], CheckPaidOrderCommand.prototype, "execute", null);
|
|
29
|
+
exports.CheckPaidOrderCommand = CheckPaidOrderCommand = tslib_1.__decorate([
|
|
30
|
+
(0, evogram_1.CommandD)({ name: 'checkPaidOrder', backButton: 'К пополнению' })
|
|
31
|
+
], CheckPaidOrderCommand);
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DepositCommand = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const evogram_1 = require("evogram");
|
|
6
|
+
const migrated_1 = require("evogram/lib/migrated");
|
|
7
|
+
const Client_1 = require("../Client");
|
|
8
|
+
const GetDepositOrder_command_1 = require("./GetDepositOrder.command");
|
|
9
|
+
const formatMessage_1 = require("../utils/formatMessage");
|
|
10
|
+
let DepositCommand = class DepositCommand extends evogram_1.Command {
|
|
11
|
+
execute(context, method, coin, deposit) {
|
|
12
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
13
|
+
const config = Client_1.Client.config(context);
|
|
14
|
+
let interval;
|
|
15
|
+
if (method !== 'cryptoWallet') {
|
|
16
|
+
if (['card', 'qrcode'].includes(method)) {
|
|
17
|
+
const message = yield context.sendFormatted({
|
|
18
|
+
photo: config.images.deposit,
|
|
19
|
+
body: [
|
|
20
|
+
{
|
|
21
|
+
title: 'ℹ️ Подождите, идет обработка заявки',
|
|
22
|
+
data: [['Создаем заявку на пополнение...']],
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
});
|
|
26
|
+
const startTime = Date.now();
|
|
27
|
+
interval = setInterval(() => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
yield message.edit({
|
|
29
|
+
text: (0, formatMessage_1.formatMessage)({
|
|
30
|
+
body: [
|
|
31
|
+
{
|
|
32
|
+
title: 'ℹ️ Подождите, идет обработка заявки',
|
|
33
|
+
data: [[`Создаем заявку на пополнение...`]],
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
footer: `<i>⏳ Прошло {{ ${Math.floor((Date.now() - startTime) / 1000)} }} сек.</i>`,
|
|
37
|
+
}),
|
|
38
|
+
parse_mode: 'HTML',
|
|
39
|
+
});
|
|
40
|
+
}), 1000);
|
|
41
|
+
}
|
|
42
|
+
const order = yield config.API.post(`orders`, {
|
|
43
|
+
mirrorId: context.mammoth.mirror.mirror.id,
|
|
44
|
+
mammothId: context.user.id,
|
|
45
|
+
method,
|
|
46
|
+
amount: Number(deposit),
|
|
47
|
+
currency: config.currency,
|
|
48
|
+
})
|
|
49
|
+
.then((x) => x.data)
|
|
50
|
+
.catch(() => null);
|
|
51
|
+
//@ts-ignore
|
|
52
|
+
if (interval)
|
|
53
|
+
clearInterval(interval);
|
|
54
|
+
this.logger.log(`Запрос на пополнение: ${JSON.stringify(order, null, 2)}`);
|
|
55
|
+
if (!order) {
|
|
56
|
+
context.user.log(0, `Не удалось получить реквизиты для пополнения на сумму ${Number(deposit).toLocaleString('ru')} ${config.currency}`);
|
|
57
|
+
return context.sendFormatted({
|
|
58
|
+
photo: config.images.deposit,
|
|
59
|
+
header: '<b>❗️К сожалению, сейчас нет доступных реквизитов для оплаты.</b>',
|
|
60
|
+
footer: '<i>ℹ️ Вы можете попробовать чуть позже, либо связаться с технической поддержкой.</i>',
|
|
61
|
+
}, {
|
|
62
|
+
reply_markup: {
|
|
63
|
+
inline_keyboard: [[{ text: '👩💻 Поддержка', url: `t.me/${config.support.username}` }]],
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
if (!order.isRepeat)
|
|
68
|
+
yield context.user.log(0, `Запросил пополнение на ${Number(order.amount).toLocaleString('ru')} ${order.currency} (${yield order.amount.convert({
|
|
69
|
+
from: order.currency,
|
|
70
|
+
to: 'RUB',
|
|
71
|
+
ceiled: true,
|
|
72
|
+
})})`, {
|
|
73
|
+
keyboard: [[{ text: '🚀 Оплатить счет', callback_data: `paidOrder?orderId=${order.id}` }]],
|
|
74
|
+
});
|
|
75
|
+
return context.redirect(GetDepositOrder_command_1.GetDepositOrderCommand, { orderId: order.id });
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
const wallets = (yield config.API.get('/crypto/wallets')).data.filter((x) => x.isActive);
|
|
79
|
+
return context.sendFormatted({
|
|
80
|
+
photo: config.images.depositCrypto,
|
|
81
|
+
header: '<b>Создана заявка на оплату</b>',
|
|
82
|
+
body: [
|
|
83
|
+
{
|
|
84
|
+
title: 'ℹ️ Информация о реквизитах',
|
|
85
|
+
data: [
|
|
86
|
+
['Адрес кошелька', `{{ ${wallets.find((x) => x.name === coin).address} }}`],
|
|
87
|
+
['Криптовалюта', `{{ ${coin} }}`],
|
|
88
|
+
],
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
footer: '<i>Это Ваш постоянный адрес для пополнения.</i>',
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
exports.DepositCommand = DepositCommand;
|
|
98
|
+
tslib_1.__decorate([
|
|
99
|
+
tslib_1.__param(1, (0, evogram_1.CommandArgument)('method', (_a) => tslib_1.__awaiter(void 0, [_a], void 0, function* ({ value, context }) {
|
|
100
|
+
const config = Client_1.Client.config(context);
|
|
101
|
+
if (value) {
|
|
102
|
+
const paymentMethods = (yield config.API.get('/payments')).data;
|
|
103
|
+
if (!paymentMethods.find((x) => x.isEnabled && x.type.toLowerCase() === value.toLowerCase()))
|
|
104
|
+
throw new Error('К сожалению, данный метод пополнения временно недоступен');
|
|
105
|
+
if (value !== 'cryptowallet')
|
|
106
|
+
return value;
|
|
107
|
+
}
|
|
108
|
+
if (!value) {
|
|
109
|
+
const allowedMethods = (yield config.API.get('/orders/allowedMethods', { params: { currency: config.currency } })).data;
|
|
110
|
+
yield context.sendFormatted({
|
|
111
|
+
photo: config.images.deposit,
|
|
112
|
+
header: '<b>📤 Выберите удобный для Вас метод пополнения.</b>',
|
|
113
|
+
}, {
|
|
114
|
+
reply_markup: {
|
|
115
|
+
inline_keyboard: [
|
|
116
|
+
...(allowedMethods.includes('card') ? [[{ text: '💳 Банковская карта', command: DepositCommand, payload: { method: 'card' } }]] : []),
|
|
117
|
+
...(allowedMethods.includes('qrcode') ? [[{ text: '📸 QR-код (СБП)', command: DepositCommand, payload: { method: 'qrcode' } }]] : []),
|
|
118
|
+
[{ text: '🪙 Криптовалюта', command: DepositCommand, payload: { method: 'cryptowallet' } }],
|
|
119
|
+
],
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
else if (value === 'cryptowallet') {
|
|
124
|
+
yield context.sendFormatted({
|
|
125
|
+
photo: config.images.depositCrypto,
|
|
126
|
+
header: '<b>🪙 Выберите удобный для вас метод пополнения.</b>',
|
|
127
|
+
}, {
|
|
128
|
+
reply_markup: {
|
|
129
|
+
inline_keyboard: [
|
|
130
|
+
[
|
|
131
|
+
{ text: '🤖 CryptoBot', command: DepositCommand, payload: { method: 'cryptoBot' } },
|
|
132
|
+
{ text: '🌐 По кошельку', command: DepositCommand, payload: { method: 'cryptoWallet' } },
|
|
133
|
+
],
|
|
134
|
+
],
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}))),
|
|
139
|
+
tslib_1.__param(2, (0, evogram_1.CommandArgument)('coin', (_a) => tslib_1.__awaiter(void 0, [_a], void 0, function* ({ value, args, context }) {
|
|
140
|
+
if (value)
|
|
141
|
+
return value;
|
|
142
|
+
else if (args.method !== 'cryptoWallet')
|
|
143
|
+
return true;
|
|
144
|
+
const config = Client_1.Client.config(context);
|
|
145
|
+
const wallets = yield config.API.get('/crypto/wallets').then((x) => x.data.filter((x) => x.isActive));
|
|
146
|
+
context.sendFormatted({
|
|
147
|
+
header: '<b>🪙 Доступные криптовалюты для пополнения:</b>',
|
|
148
|
+
photo: config.images.depositCrypto,
|
|
149
|
+
}, {
|
|
150
|
+
reply_markup: {
|
|
151
|
+
inline_keyboard: wallets.map((x) => [
|
|
152
|
+
{
|
|
153
|
+
text: x.name,
|
|
154
|
+
command: DepositCommand,
|
|
155
|
+
payload: Object.assign(Object.assign({}, args), { coin: x.name }),
|
|
156
|
+
},
|
|
157
|
+
]),
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
}))),
|
|
161
|
+
tslib_1.__param(3, (0, evogram_1.CommandArgument)({
|
|
162
|
+
name: 'deposit',
|
|
163
|
+
question: (_a) => tslib_1.__awaiter(void 0, [_a], void 0, function* ({ context, error, args, validateArgs }) {
|
|
164
|
+
var _b;
|
|
165
|
+
if (args.method === 'cryptoWallet')
|
|
166
|
+
return 1;
|
|
167
|
+
const config = Client_1.Client.config(context);
|
|
168
|
+
let minAmountSetting = JSON.parse(context.state.settings.find((x) => x.name === 'minDeposit').value);
|
|
169
|
+
let minAmount = (_b = minAmountSetting[config.currency]) !== null && _b !== void 0 ? _b : (yield minAmountSetting['RUB'].convert({ from: 'RUB', to: config.currency }));
|
|
170
|
+
const minDepositByMethod = yield config.API.get('/config/minDepositByMethod').then((x) => x.data);
|
|
171
|
+
// prettier-ignore
|
|
172
|
+
if (minDepositByMethod && minDepositByMethod[args.method] !== undefined && (yield minAmount.convert({ from: config.currency, to: 'RUB' })) < minDepositByMethod[args.method])
|
|
173
|
+
minAmount = yield minDepositByMethod[args.method].convert({ from: 'RUB', to: config.currency });
|
|
174
|
+
validateArgs.minAmount = minAmount;
|
|
175
|
+
return (yield context.sendFormattedQuestion({
|
|
176
|
+
photo: ['card', 'qrcode'].includes(args.method) ? config.images.deposit : config.images.depositCrypto,
|
|
177
|
+
body: [
|
|
178
|
+
{
|
|
179
|
+
title: '💰 Сумма пополнения',
|
|
180
|
+
data: [['Введите сумму пополнения']],
|
|
181
|
+
},
|
|
182
|
+
],
|
|
183
|
+
footer: `<i>Минимальная сумма пополнения: {{ ${Number(minAmount).toLocaleString('ru')} ${config.currency} }}</i>`,
|
|
184
|
+
error: error === null || error === void 0 ? void 0 : error.message,
|
|
185
|
+
})).text;
|
|
186
|
+
}),
|
|
187
|
+
}, (0, evogram_1.numberValidator)({ allowFloat: true, min: 0 }), (_a) => tslib_1.__awaiter(void 0, [_a], void 0, function* ({ value, context, args }) {
|
|
188
|
+
if (args.method === 'cryptoWallet')
|
|
189
|
+
return 0;
|
|
190
|
+
const config = Client_1.Client.config(context);
|
|
191
|
+
const maxDeposit = yield config.API.get('/config/maxDepositInService').then((x) => x.data);
|
|
192
|
+
const depositAmount = yield value.convert({ from: config.currency, to: 'RUB' });
|
|
193
|
+
if (depositAmount > maxDeposit)
|
|
194
|
+
throw new Error(`Пополнение, более чем на ${yield maxDeposit.convert({ from: 'RUB', to: config.currency })}, доступно только через <a href="t.me/{{ ${config.support.username} }}">тех. поддержку</a>`);
|
|
195
|
+
return value;
|
|
196
|
+
}), (_a) => tslib_1.__awaiter(void 0, [_a], void 0, function* ({ value, context, validateArgs }) {
|
|
197
|
+
const config = Client_1.Client.config(context);
|
|
198
|
+
if (Number(value) < Number(validateArgs.minAmount))
|
|
199
|
+
throw new Error(`Минимальная сумма пополнения: ${Number(validateArgs.minAmount).toLocaleString('ru')} ${config.currency}`);
|
|
200
|
+
return value;
|
|
201
|
+
}))),
|
|
202
|
+
tslib_1.__metadata("design:type", Function),
|
|
203
|
+
tslib_1.__metadata("design:paramtypes", [migrated_1.CommandContext, String, Object, Number]),
|
|
204
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
205
|
+
], DepositCommand.prototype, "execute", null);
|
|
206
|
+
exports.DepositCommand = DepositCommand = tslib_1.__decorate([
|
|
207
|
+
(0, evogram_1.CommandD)({ name: 'deposit', description: [{ text: 'Пополнение' }, { language: 'en', text: 'Deposit' }] })
|
|
208
|
+
], DepositCommand);
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GetDepositOrderCommand = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const evogram_1 = require("evogram");
|
|
6
|
+
const migrated_1 = require("evogram/lib/migrated");
|
|
7
|
+
const Client_1 = require("../Client");
|
|
8
|
+
const CheckPaidOrder_command_1 = require("./CheckPaidOrder.command");
|
|
9
|
+
let GetDepositOrderCommand = class GetDepositOrderCommand extends evogram_1.Command {
|
|
10
|
+
execute(context, orderId) {
|
|
11
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
12
|
+
const config = Client_1.Client.config(context);
|
|
13
|
+
const order = yield config.API.get(`/orders/deposit/${orderId}`)
|
|
14
|
+
.then((x) => x.data)
|
|
15
|
+
.catch(() => null);
|
|
16
|
+
if (!order)
|
|
17
|
+
throw new Error('Заявка на оплату не найдена');
|
|
18
|
+
switch (order.method) {
|
|
19
|
+
case 'cryptoBot':
|
|
20
|
+
return context.sendFormatted({
|
|
21
|
+
photo: config.images.depositCrypto,
|
|
22
|
+
header: '<b>Создана заявка на оплату</b>',
|
|
23
|
+
body: [
|
|
24
|
+
{
|
|
25
|
+
title: 'ℹ️ Информация о счете',
|
|
26
|
+
data: [
|
|
27
|
+
['Сумма', `{{ ${Number(order.amount).toLocaleString('ru')} ${order.currency} }}`],
|
|
28
|
+
['Дата', `{{ ${new Date().toLocaleString('ru')} }}`],
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
title: '📎 Ваша ссылка для оплаты',
|
|
33
|
+
data: [[`{{ ${order.cryptoBot.url} }}`]],
|
|
34
|
+
},
|
|
35
|
+
],
|
|
36
|
+
footer: '<i>Ссылка действительна 10 минут.</i>',
|
|
37
|
+
}, {
|
|
38
|
+
reply_markup: {
|
|
39
|
+
inline_keyboard: [
|
|
40
|
+
[{ text: '🔗 Перейти к оплате', url: order.cryptoBot.url }],
|
|
41
|
+
[{ text: '🔄 Проверить оплату', command: CheckPaidOrder_command_1.CheckPaidOrderCommand, payload: { orderId: order.id } }],
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
case 'card':
|
|
46
|
+
return context.sendFormatted({
|
|
47
|
+
photo: config.images.deposit,
|
|
48
|
+
header: order.isRepeat ? '<b>❗️У вас уже есть заявка на пополнение, сначала оплатите ёё</b>' : '<b>Создана заявка на оплату</b>',
|
|
49
|
+
body: [
|
|
50
|
+
{
|
|
51
|
+
title: 'ℹ️ Информация о реквизитах',
|
|
52
|
+
data: [
|
|
53
|
+
['Реквизиты', `{{ ${order.card.requisites} }}`],
|
|
54
|
+
order.card.bank && ['Банк', `{{ ${order.card.bank} }}`],
|
|
55
|
+
order.card.holder && ['Получатель', `{{ ${order.card.holder} }}`],
|
|
56
|
+
['Сумма оплаты', `{{ ${Number(order.amount).toLocaleString('ru')} ${order.currency} }}`],
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
footer: '<i>Реквизиты действительны 10 минут.</i>',
|
|
61
|
+
}, {
|
|
62
|
+
reply_markup: {
|
|
63
|
+
inline_keyboard: [[{ text: '🔄 Проверить оплату', command: CheckPaidOrder_command_1.CheckPaidOrderCommand, payload: { orderId: order.id } }]],
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
case 'qrcode':
|
|
67
|
+
return context.sendFormatted({
|
|
68
|
+
photo: config.images.deposit,
|
|
69
|
+
header: '<b>Создана заявка на оплату</b>',
|
|
70
|
+
footer: `<i>Ссылка действительна ${Math.ceil((new Date(order.expiresAt).getTime() - new Date().getTime()) / 60000)} минут.</i>`,
|
|
71
|
+
}, {
|
|
72
|
+
reply_markup: {
|
|
73
|
+
inline_keyboard: [
|
|
74
|
+
[{ text: '🔗 Перейти к оплате', url: order.qrcode.link }],
|
|
75
|
+
[{ text: '🔄 Проверить оплату', command: CheckPaidOrder_command_1.CheckPaidOrderCommand, payload: { orderId: order.id } }],
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
exports.GetDepositOrderCommand = GetDepositOrderCommand;
|
|
84
|
+
tslib_1.__decorate([
|
|
85
|
+
tslib_1.__param(1, (0, evogram_1.CommandArgument)('orderId')),
|
|
86
|
+
tslib_1.__metadata("design:type", Function),
|
|
87
|
+
tslib_1.__metadata("design:paramtypes", [migrated_1.CommandContext, String]),
|
|
88
|
+
tslib_1.__metadata("design:returntype", Promise)
|
|
89
|
+
], GetDepositOrderCommand.prototype, "execute", null);
|
|
90
|
+
exports.GetDepositOrderCommand = GetDepositOrderCommand = tslib_1.__decorate([
|
|
91
|
+
(0, evogram_1.CommandD)({ name: 'getDepositOrder', backButton: 'К пополнению' })
|
|
92
|
+
], GetDepositOrderCommand);
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./Deposit.command"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./GetDepositOrder.command"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./CheckPaidOrder.command"), exports);
|
package/lib/convert.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
interface ConvertParams {
|
|
2
|
+
from?: string;
|
|
3
|
+
to: string;
|
|
4
|
+
round?: boolean;
|
|
5
|
+
ceiled?: boolean;
|
|
6
|
+
}
|
|
7
|
+
interface CurrencyConverter {
|
|
8
|
+
convert(params: ConvertParams): Promise<number>;
|
|
9
|
+
}
|
|
10
|
+
declare global {
|
|
11
|
+
interface String extends CurrencyConverter {
|
|
12
|
+
translate(language: string, ...args: any[]): Promise<string>;
|
|
13
|
+
}
|
|
14
|
+
interface Number extends CurrencyConverter {
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export {};
|
package/lib/convert.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const CoinBase_service_1 = require("./utils/CoinBase.service");
|
|
5
|
+
class ConvertedNumber {
|
|
6
|
+
constructor(value, stringValue) {
|
|
7
|
+
this.value = value;
|
|
8
|
+
this.stringValue = stringValue;
|
|
9
|
+
}
|
|
10
|
+
// Переопределяем метод toString
|
|
11
|
+
toString() {
|
|
12
|
+
return this.stringValue;
|
|
13
|
+
}
|
|
14
|
+
// Добавляем valueOf для корректного сравнения
|
|
15
|
+
valueOf() {
|
|
16
|
+
return this.value;
|
|
17
|
+
}
|
|
18
|
+
convert(params) {
|
|
19
|
+
return this.value.convert(params);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
Number.prototype.convert = function (params) {
|
|
23
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
24
|
+
const { to = 'RUB', from = 'RUB', round, ceiled } = params;
|
|
25
|
+
const fromCurrency = from.toUpperCase();
|
|
26
|
+
const currency = to.toUpperCase();
|
|
27
|
+
if (currency === 'RUB' && fromCurrency === 'RUB') {
|
|
28
|
+
const value = round ? Math.round(this) : ceiled ? Math.ceil(this) : this;
|
|
29
|
+
//@ts-ignore
|
|
30
|
+
return new ConvertedNumber(value, `${value.toLocaleString('ru', { maximumFractionDigits: 2 })} RUB`);
|
|
31
|
+
}
|
|
32
|
+
else if (currency === 'RUB') {
|
|
33
|
+
const rates = yield CoinBase_service_1.CoinBaseService.getInstance().getRates('RUB');
|
|
34
|
+
const targetRate = 1 / Number(rates[fromCurrency]);
|
|
35
|
+
let convertedAmount = this * Number(targetRate);
|
|
36
|
+
if (!convertedAmount)
|
|
37
|
+
convertedAmount = this;
|
|
38
|
+
if (round) {
|
|
39
|
+
convertedAmount = Math.round(convertedAmount);
|
|
40
|
+
}
|
|
41
|
+
else if (ceiled) {
|
|
42
|
+
convertedAmount = Math.ceil(convertedAmount);
|
|
43
|
+
}
|
|
44
|
+
//@ts-ignore
|
|
45
|
+
return new ConvertedNumber(convertedAmount, `${convertedAmount.toLocaleString('ru', { maximumFractionDigits: 2 })} ${currency}`);
|
|
46
|
+
}
|
|
47
|
+
const rates = yield CoinBase_service_1.CoinBaseService.getInstance().getRates(fromCurrency);
|
|
48
|
+
const targetRate = rates[currency];
|
|
49
|
+
let convertedAmount = this * Number(targetRate);
|
|
50
|
+
if (!convertedAmount)
|
|
51
|
+
convertedAmount = this;
|
|
52
|
+
if (round) {
|
|
53
|
+
convertedAmount = Math.round(convertedAmount);
|
|
54
|
+
}
|
|
55
|
+
else if (ceiled) {
|
|
56
|
+
convertedAmount = Math.ceil(convertedAmount);
|
|
57
|
+
}
|
|
58
|
+
//@ts-ignore
|
|
59
|
+
return new ConvertedNumber(convertedAmount, `${convertedAmount.toLocaleString('ru', { maximumFractionDigits: 2 })} ${targetRate ? currency : 'RUB'}`);
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
String.prototype.convert = function (params) {
|
|
63
|
+
return Number(this).convert(params);
|
|
64
|
+
};
|
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './Client';
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare class CoinBaseService {
|
|
2
|
+
private readonly UPDATE_INTERVAL_MS;
|
|
3
|
+
private readonly CACHE_LIFETIME_MS;
|
|
4
|
+
private ratesCache;
|
|
5
|
+
static instance: CoinBaseService;
|
|
6
|
+
static getInstance(): CoinBaseService;
|
|
7
|
+
/**
|
|
8
|
+
* Проверяет актуальность кэша
|
|
9
|
+
*/
|
|
10
|
+
private isCacheValid;
|
|
11
|
+
/**
|
|
12
|
+
* Получает курсы из кэша
|
|
13
|
+
*/
|
|
14
|
+
getRates(currency?: string): Promise<{
|
|
15
|
+
[key: string]: string;
|
|
16
|
+
}>;
|
|
17
|
+
/**
|
|
18
|
+
* Запускает автоматическое обновление курсов для конкретной валюты
|
|
19
|
+
*/
|
|
20
|
+
private startUpdates;
|
|
21
|
+
/**
|
|
22
|
+
* Останавливает обновление для указанной валюты или всех валют
|
|
23
|
+
*/
|
|
24
|
+
stopUpdates(currency?: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* Обновляет курсы криптовалют в кэше
|
|
27
|
+
*/
|
|
28
|
+
private updateRates;
|
|
29
|
+
/**
|
|
30
|
+
* Очищает кэш для указанной валюты или весь кэш
|
|
31
|
+
*/
|
|
32
|
+
clearCache(currency?: string): void;
|
|
33
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CoinBaseService = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const axios_1 = tslib_1.__importDefault(require("axios"));
|
|
6
|
+
class CoinBaseService {
|
|
7
|
+
constructor() {
|
|
8
|
+
this.UPDATE_INTERVAL_MS = 300000; // 5 минут
|
|
9
|
+
this.CACHE_LIFETIME_MS = 300000; // Время жизни кэша - 5 минут
|
|
10
|
+
this.ratesCache = new Map();
|
|
11
|
+
}
|
|
12
|
+
static getInstance() {
|
|
13
|
+
if (!CoinBaseService.instance)
|
|
14
|
+
CoinBaseService.instance = new CoinBaseService();
|
|
15
|
+
return CoinBaseService.instance;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Проверяет актуальность кэша
|
|
19
|
+
*/
|
|
20
|
+
isCacheValid(currency) {
|
|
21
|
+
const cachedData = this.ratesCache.get(currency);
|
|
22
|
+
if (!cachedData)
|
|
23
|
+
return false;
|
|
24
|
+
const now = Date.now();
|
|
25
|
+
return now - cachedData.timestamp < this.CACHE_LIFETIME_MS;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Получает курсы из кэша
|
|
29
|
+
*/
|
|
30
|
+
getRates() {
|
|
31
|
+
return tslib_1.__awaiter(this, arguments, void 0, function* (currency = 'USD') {
|
|
32
|
+
// Если валюта не кэширована или кэш устарел, начинаем обновление
|
|
33
|
+
if (!this.isCacheValid(currency))
|
|
34
|
+
yield this.startUpdates(currency);
|
|
35
|
+
const cachedData = this.ratesCache.get(currency);
|
|
36
|
+
return cachedData.rates;
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Запускает автоматическое обновление курсов для конкретной валюты
|
|
41
|
+
*/
|
|
42
|
+
startUpdates(currency) {
|
|
43
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
44
|
+
var _a;
|
|
45
|
+
// Проверяем, не запущено ли уже обновление для этой валюты
|
|
46
|
+
const existingCache = this.ratesCache.get(currency);
|
|
47
|
+
if (existingCache === null || existingCache === void 0 ? void 0 : existingCache.updateInterval)
|
|
48
|
+
return;
|
|
49
|
+
// Первое обновление сразу
|
|
50
|
+
yield this.updateRates(currency);
|
|
51
|
+
// Создаем новый интервал обновления
|
|
52
|
+
const updateInterval = setInterval(() => {
|
|
53
|
+
this.updateRates(currency);
|
|
54
|
+
}, this.UPDATE_INTERVAL_MS);
|
|
55
|
+
// Сохраняем или обновляем информацию в кэше
|
|
56
|
+
this.ratesCache.set(currency, Object.assign(Object.assign({}, this.ratesCache.get(currency)), { updateInterval, timestamp: Date.now(), rates: ((_a = this.ratesCache.get(currency)) === null || _a === void 0 ? void 0 : _a.rates) || {} }));
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Останавливает обновление для указанной валюты или всех валют
|
|
61
|
+
*/
|
|
62
|
+
stopUpdates(currency) {
|
|
63
|
+
if (currency) {
|
|
64
|
+
const cachedData = this.ratesCache.get(currency);
|
|
65
|
+
if (cachedData === null || cachedData === void 0 ? void 0 : cachedData.updateInterval) {
|
|
66
|
+
clearInterval(cachedData.updateInterval);
|
|
67
|
+
cachedData.updateInterval = null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// Останавливаем все обновления
|
|
72
|
+
for (const [, data] of this.ratesCache) {
|
|
73
|
+
if (data.updateInterval) {
|
|
74
|
+
clearInterval(data.updateInterval);
|
|
75
|
+
data.updateInterval = null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Обновляет курсы криптовалют в кэше
|
|
82
|
+
*/
|
|
83
|
+
updateRates(currency) {
|
|
84
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
85
|
+
try {
|
|
86
|
+
const response = yield axios_1.default.get(`https://api.coinbase.com/v2/exchange-rates?currency=${currency}`);
|
|
87
|
+
const rates = response.data.data.rates;
|
|
88
|
+
// Обновляем кэш
|
|
89
|
+
const existingCache = this.ratesCache.get(currency);
|
|
90
|
+
this.ratesCache.set(currency, Object.assign(Object.assign({}, existingCache), { rates, timestamp: Date.now() }));
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
console.error('Ошибка при обновлении курсов криптовалют:', error);
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Очищает кэш для указанной валюты или весь кэш
|
|
99
|
+
*/
|
|
100
|
+
clearCache(currency) {
|
|
101
|
+
if (currency) {
|
|
102
|
+
// Останавливаем обновления перед удалением
|
|
103
|
+
this.stopUpdates(currency);
|
|
104
|
+
this.ratesCache.delete(currency);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
// Останавливаем все обновления перед очисткой
|
|
108
|
+
this.stopUpdates();
|
|
109
|
+
this.ratesCache.clear();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
exports.CoinBaseService = CoinBaseService;
|