src/orderbook/settlement.service.ts
Properties |
|
Methods |
|
constructor(settlementModel: Model<SettlementDocument>, allowanceModel: Model<AllowanceDocument>)
|
|||||||||
|
Defined in src/orderbook/settlement.service.ts:31
|
|||||||||
|
Parameters :
|
| Async approveSettlement | |||||
approveSettlement(undefined: IApproveSettlement)
|
|||||
|
Defined in src/orderbook/settlement.service.ts:119
|
|||||
|
Parameters :
Returns :
Promise<literal type>
|
| Async authenticateFundAdmin | |||||||||
authenticateFundAdmin(userJwt: UserJwtPayload, fundId: string)
|
|||||||||
|
Defined in src/orderbook/settlement.service.ts:170
|
|||||||||
|
Parameters :
Returns :
any
|
| Async create | ||||
create(createSettlementDto)
|
||||
|
Defined in src/orderbook/settlement.service.ts:40
|
||||
|
Parameters :
Returns :
unknown
|
| Async getAllSettlements | |||
getAllSettlements(undefined)
|
|||
|
Defined in src/orderbook/settlement.service.ts:57
|
|||
|
Parameters :
Returns :
unknown
|
| Async getSettlementByOrderBookId | |||||
getSettlementByOrderBookId(undefined: IGetSettlementApproval)
|
|||||
|
Defined in src/orderbook/settlement.service.ts:107
|
|||||
|
Parameters :
Returns :
unknown
|
| Async resetVote | ||||||
resetVote(orderbookId: string)
|
||||||
|
Defined in src/orderbook/settlement.service.ts:49
|
||||||
|
Parameters :
Returns :
unknown
|
| Private Readonly userService |
Type : UserService
|
Decorators :
@Inject(UserService)
|
|
Defined in src/orderbook/settlement.service.ts:31
|
import { UserJwtPayload } from "./../common/interfaces/SharedTypes";
import {
BadRequestException,
Inject,
Injectable,
ServiceUnavailableException,
UnauthorizedException,
} from "@nestjs/common";
import { UserService } from "src/user/user.service";
import { Settlement } from "./entities/settlement.entity";
import { InjectModel } from "@nestjs/mongoose";
import { Model } from "mongoose";
import { SettlementDocument } from "./schemas/settlement.schema";
import { CreateSettlementDto } from "./dto/create-settlement.dto";
import {
IApproveSettlement,
IGetSettlementApproval,
} from "./orderbook.interface";
import { decodeBytes32String, encodeBytes32String } from "ethers";
import { Allowance } from "./entities/allowance.entity";
import { AllowanceDocument } from "./schemas/allowance.schema";
import { FilterPaginationDto } from "src/shared/dto/filter-pagination.dto";
import { ApolloQueryResult } from "@apollo/client";
import { IGetOrderBooksByFundIdsQuery } from "src/common/interfaces";
import { apolloClient, getOrderBooksByFundIdsQuery } from "src/common/provider";
@Injectable()
export class SettlementService {
@Inject(UserService)
private readonly userService: UserService;
constructor(
@InjectModel(Settlement.name)
private readonly settlementModel: Model<SettlementDocument>,
@InjectModel(Allowance.name)
private readonly allowanceModel: Model<AllowanceDocument>,
) {}
async create(
createSettlementDto: CreateSettlementDto & { orderbookId: string },
) {
return this.settlementModel.create({
...createSettlementDto,
currentApprovalNo: 0,
});
}
async resetVote(orderbookId: string) {
return this.settlementModel.findOneAndUpdate(
{ orderbookId },
{
currentApprovalNo: 0,
},
);
}
async getAllSettlements({
userJwt,
skip,
limit,
orderDirection,
}: FilterPaginationDto & { userJwt: UserJwtPayload }) {
if (userJwt.role === "admin") {
return await this.settlementModel
.find()
.limit(limit)
.skip(skip * limit)
.sort({ created: orderDirection })
.lean()
.exec();
}
const user = await this.userService.findUserByProperty({
email: userJwt.email,
});
const encodedFundsId = user.subscribedFunds.map((fund) =>
encodeBytes32String(fund._id.toString()),
);
const orderBooks: ApolloQueryResult<IGetOrderBooksByFundIdsQuery> =
await apolloClient.query({
query: getOrderBooksByFundIdsQuery,
variables: {
orderBookId: encodedFundsId,
},
});
if (orderBooks.errors) {
console.error(orderBooks.errors[0]);
throw new ServiceUnavailableException(orderBooks.error);
}
if (!orderBooks.data.getOrderBooksByFundIdsQuery.length) {
return [];
}
return await this.settlementModel
.find({
orderbookId: {
$in: orderBooks.data.getOrderBooksByFundIdsQuery.map(
(orderBook) => orderBook.id,
),
},
})
.limit(limit)
.skip(skip * limit)
.sort({ created: orderDirection })
.lean()
.exec();
}
async getSettlementByOrderBookId({
orderbookId,
fundId,
userJwt,
}: IGetSettlementApproval) {
if (userJwt.role === "admin") {
return await this.settlementModel.findOne({ orderbookId }).lean().exec();
}
await this.authenticateFundAdmin(userJwt, fundId);
return await this.settlementModel.findOne({ orderbookId }).lean().exec();
}
async approveSettlement({
orderbookId,
fundId,
userJwt,
orderId,
}: IApproveSettlement): Promise<{
isAllowed: boolean;
requiredApprovalNo: number;
currentApprovalNo: number;
}> {
const [, settlement, isAlreadyVoted] = await Promise.all([
this.authenticateFundAdmin(userJwt, fundId),
this.settlementModel.findOne({ orderbookId }).lean().exec(),
this.allowanceModel.findOne({
orderbookId,
fundId,
userEmail: userJwt.email,
orderId,
}),
]);
if (isAlreadyVoted) {
throw new BadRequestException("User already voted");
}
if (settlement.requiredApprovalNo <= settlement.currentApprovalNo) {
return {
isAllowed: true,
requiredApprovalNo: settlement.requiredApprovalNo,
currentApprovalNo: settlement.currentApprovalNo,
};
}
const updatedSettlement = await this.settlementModel
.findOneAndUpdate(
{ orderbookId },
{ $inc: { currentApprovalNo: 1 } },
{ new: true },
)
.exec();
await this.allowanceModel.create({
orderbookId,
fundId,
userEmail: userJwt.email,
orderId,
});
return {
isAllowed:
settlement.requiredApprovalNo <= updatedSettlement.currentApprovalNo,
requiredApprovalNo: settlement.requiredApprovalNo,
currentApprovalNo: updatedSettlement.currentApprovalNo,
};
}
async authenticateFundAdmin(userJwt: UserJwtPayload, fundId: string) {
const fundAdmin = await this.userService.findUserByProperty({
email: userJwt.email,
});
const decodedFundId = decodeBytes32String(fundId);
const isSubscribed = fundAdmin.subscribedFunds.map(
(fund) => fund._id.toString() === decodedFundId,
);
if (!isSubscribed) {
throw new UnauthorizedException(
"Fund admin is not subscribed to this fund",
);
}
}
}