optimization & tx cancel fix
This commit is contained in:
parent
739afd03cd
commit
95ca3a9642
6 changed files with 113 additions and 19 deletions
|
|
@ -8,6 +8,7 @@ import {
|
|||
OrderWithUser,
|
||||
} from '@/interfaces/database/modifiedRequests';
|
||||
import User from '@/schemes/User.js';
|
||||
import CancelTransactionBody from '@/interfaces/bodies/exchange-transactions/CancelTransactionBody.js';
|
||||
import exchangeModel from '../models/ExchangeTransactions.js';
|
||||
import ConfirmTransactionBody from '../interfaces/bodies/exchange-transactions/ConfirmTransactionBody.js';
|
||||
import GetActiveTxByOrdersIdsBody from '../interfaces/bodies/exchange-transactions/GetActiveTxByOrdersIdsBody.js';
|
||||
|
|
@ -208,7 +209,9 @@ class TransactionsController {
|
|||
.flat()
|
||||
.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime());
|
||||
|
||||
const connectedOrdersIDs = flatTxs.map((tx) => tx.creator === 'buy' ? tx.sell_order_id : tx.buy_order_id);
|
||||
const connectedOrdersIDs = flatTxs.map((tx) =>
|
||||
tx.creator === 'buy' ? tx.sell_order_id : tx.buy_order_id,
|
||||
);
|
||||
|
||||
const uniqueConnectedOrdersIDs = [...new Set(connectedOrdersIDs)];
|
||||
|
||||
|
|
@ -266,6 +269,21 @@ class TransactionsController {
|
|||
return res.status(500).send({ success: false, data: 'Unhandled error' });
|
||||
}
|
||||
}
|
||||
|
||||
async cancelTransaction(req: Request, res: Response) {
|
||||
try {
|
||||
if (!(req.body as CancelTransactionBody).transactionId) {
|
||||
return res.status(400).json({ success: false, data: 'Invalid transaction data' });
|
||||
}
|
||||
|
||||
const result = await exchangeModel.cancelTransaction(req.body as CancelTransactionBody);
|
||||
|
||||
return res.status(200).send(result);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return res.status(500).send({ success: false, data: 'Unhandled error' });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const transactionsController = new TransactionsController();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
import UserData from '../../common/UserData';
|
||||
|
||||
interface CancelTransactionBody {
|
||||
transactionId: string;
|
||||
userData: UserData;
|
||||
}
|
||||
|
||||
export default CancelTransactionBody;
|
||||
|
|
@ -20,3 +20,15 @@ export interface PairWithFirstCurrency extends Pair {
|
|||
export interface OrderWithUser extends Order {
|
||||
user: User;
|
||||
}
|
||||
|
||||
export interface OrderWithPair extends Order {
|
||||
pair: Pair;
|
||||
}
|
||||
export interface PairWithCurrencies extends Pair {
|
||||
first_currency: Currency;
|
||||
second_currency: Currency;
|
||||
}
|
||||
|
||||
export interface OrderWithPairAndCurrencies extends Order {
|
||||
pair: PairWithCurrencies;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import Decimal from 'decimal.js';
|
||||
import { Op } from 'sequelize';
|
||||
import type { Transaction as SequelizeTransaction } from 'sequelize';
|
||||
import CancelTransactionBody from '@/interfaces/bodies/exchange-transactions/CancelTransactionBody.js';
|
||||
import sequelize from '@/sequelize.js';
|
||||
import { sendDeleteOrderMessage, sendUpdatePairStatsMessage } from '../socket/main.js';
|
||||
import ordersModel from './Orders.js';
|
||||
import userModel from './User.js';
|
||||
|
|
@ -444,6 +446,56 @@ class ExchangeModel {
|
|||
}
|
||||
}
|
||||
|
||||
async cancelTransaction(body: CancelTransactionBody) {
|
||||
try {
|
||||
return await sequelize.transaction(async (t) => {
|
||||
const { userData } = body;
|
||||
const { transactionId } = body;
|
||||
|
||||
const userRow = await userModel.getUserRow(userData.address);
|
||||
|
||||
if (!userRow) {
|
||||
throw new Error('User not found.');
|
||||
}
|
||||
|
||||
const transaction = await Transaction.findByPk(transactionId);
|
||||
|
||||
if (!transaction) {
|
||||
return { success: false, data: "Transaction doesn't exist." };
|
||||
}
|
||||
|
||||
const transactionOwnerOrder =
|
||||
transaction.creator === 'buy'
|
||||
? transaction.buy_order_id
|
||||
: transaction.sell_order_id;
|
||||
|
||||
const ownerOrder = await Order.findByPk(transactionOwnerOrder, {
|
||||
transaction: t,
|
||||
lock: t.LOCK.UPDATE,
|
||||
});
|
||||
|
||||
if (!ownerOrder) {
|
||||
throw new Error('Owner order not found.');
|
||||
}
|
||||
|
||||
if (ownerOrder.user_id !== userRow.id) {
|
||||
return { success: false, data: 'You are not the creator of this transaction' };
|
||||
}
|
||||
|
||||
if (transaction.status !== 'pending') {
|
||||
return { success: false, data: 'Transaction is not pending' };
|
||||
}
|
||||
|
||||
await this.returnTransactionAmount(transaction.id, t);
|
||||
|
||||
return { success: true };
|
||||
});
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return { success: false, data: 'Internal error' };
|
||||
}
|
||||
}
|
||||
|
||||
async getActiveTxByOrdersIds(firstOrderId: number, secondOrderId: number) {
|
||||
const txRow = await Transaction.findOne({
|
||||
where: {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,11 @@ import { Op } from 'sequelize';
|
|||
import Decimal from 'decimal.js';
|
||||
import TransactionWithOrders from '@/interfaces/common/Transaction.js';
|
||||
import Currency from '@/schemes/Currency.js';
|
||||
import {
|
||||
OrderWithAllTransactions,
|
||||
OrderWithPair,
|
||||
OrderWithPairAndCurrencies,
|
||||
} from '@/interfaces/database/modifiedRequests.js';
|
||||
import configModel from './Config.js';
|
||||
import dexModel from './Dex.js';
|
||||
import userModel from './User.js';
|
||||
|
|
@ -337,29 +342,26 @@ class OrdersModel {
|
|||
|
||||
if (!userRow) throw new Error('Invalid address from token.');
|
||||
|
||||
const orders = await Order.findAll({
|
||||
const orders = (await Order.findAll({
|
||||
where: {
|
||||
user_id: userRow.id,
|
||||
},
|
||||
order: [['timestamp', 'DESC']],
|
||||
});
|
||||
include: [
|
||||
{
|
||||
model: Pair,
|
||||
as: 'pair',
|
||||
include: ['first_currency', 'second_currency'],
|
||||
},
|
||||
],
|
||||
})) as OrderWithPairAndCurrencies[];
|
||||
|
||||
const ordersWithCurrencies: Order[] = orders;
|
||||
|
||||
const result = [];
|
||||
|
||||
for (let i = 0; i < orders.length; i++) {
|
||||
const pairData = await dexModel.getPairRow(orders[i].pair_id);
|
||||
|
||||
if (!pairData) throw new Error('Invalid pair id in order row.');
|
||||
|
||||
result.push({
|
||||
...(ordersWithCurrencies[i]?.toJSON() || {}),
|
||||
first_currency: await configModel.getCurrencyRow(pairData.first_currency_id),
|
||||
second_currency: await configModel.getCurrencyRow(pairData.second_currency_id),
|
||||
isInstant: dexModel.isBotActive(ordersWithCurrencies[i].id),
|
||||
});
|
||||
}
|
||||
const result = orders.map((e) => ({
|
||||
...e.toJSON(),
|
||||
first_currency: e.pair.first_currency,
|
||||
second_currency: e.pair.second_currency,
|
||||
isInstant: dexModel.isBotActive(e.id),
|
||||
}));
|
||||
|
||||
return { success: true, data: result };
|
||||
} catch (err) {
|
||||
|
|
|
|||
|
|
@ -22,4 +22,6 @@ transactionsRouter.post(
|
|||
transactionsController.getPendingTransactions,
|
||||
);
|
||||
|
||||
transactionsRouter.post('/transactions/cancel', transactionsController.cancelTransaction);
|
||||
|
||||
export default transactionsRouter;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue