src/profile/profile.service.ts
Properties |
|
Methods |
|
| Async createRole | ||||
createRole(createRoleDto)
|
||||
|
Defined in src/profile/profile.service.ts:350
|
||||
|
Parameters :
Returns :
unknown
|
| Async getMyProfile | ||||||
getMyProfile(userJwtPayload: UserJwtPayload)
|
||||||
|
Defined in src/profile/profile.service.ts:69
|
||||||
|
Parameters :
Returns :
Promise<IUserProfile>
|
| Async grantRole | ||||
grantRole(grantRoleDto)
|
||||
|
Defined in src/profile/profile.service.ts:369
|
||||
|
Parameters :
Returns :
unknown
|
| Async manageRoleAccess | |||||||||
manageRoleAccess(action: "revoke" | "grant", manageRoleAccessDto)
|
|||||||||
|
Defined in src/profile/profile.service.ts:389
|
|||||||||
|
Parameters :
Returns :
unknown
|
| Async resetAccess | ||||
resetAccess(restRoleDto)
|
||||
|
Defined in src/profile/profile.service.ts:418
|
||||
|
Parameters :
Returns :
unknown
|
| Async setInvestorRestriction | |||||
setInvestorRestriction(undefined: ISetInvestorRestriction)
|
|||||
|
Defined in src/profile/profile.service.ts:153
|
|||||
|
Parameters :
Returns :
unknown
|
| Async setSanction | ||||||
setSanction(investorSanctionDto: ISetSanction)
|
||||||
|
Defined in src/profile/profile.service.ts:257
|
||||||
|
Parameters :
Returns :
unknown
|
| Async userDeleteModule | |||||
userDeleteModule(undefined: IUserModule)
|
|||||
|
Defined in src/profile/profile.service.ts:331
|
|||||
|
Parameters :
Returns :
unknown
|
| Async userEnableDisableModule | |||||
userEnableDisableModule(undefined: IUserModuleEnableDisable)
|
|||||
|
Defined in src/profile/profile.service.ts:307
|
|||||
|
Parameters :
Returns :
unknown
|
| Async userRegisterModule | |||||
userRegisterModule(undefined: IUserModule)
|
|||||
|
Defined in src/profile/profile.service.ts:288
|
|||||
|
Parameters :
Returns :
unknown
|
| Async verifyInvestor | |||||
verifyInvestor(undefined: Omit<ISetInvestorRestriction | "isRestricted" | "userJwtPayload">)
|
|||||
|
Defined in src/profile/profile.service.ts:231
|
|||||
|
Parameters :
Returns :
unknown
|
| Private Readonly adminProfileService |
Type : AdminProfileService
|
Decorators :
@Inject(AdminProfileService)
|
|
Defined in src/profile/profile.service.ts:67
|
| Private Readonly emailService |
Type : EmailService
|
Decorators :
@Inject(EmailService)
|
|
Defined in src/profile/profile.service.ts:59
|
| Private Readonly fundService |
Type : FundService
|
Decorators :
@Inject(FundService)
|
|
Defined in src/profile/profile.service.ts:57
|
| Private Readonly instrumentService |
Type : InstrumentService
|
Decorators :
@Inject(InstrumentService)
|
|
Defined in src/profile/profile.service.ts:63
|
| Private Readonly internalCustodialService |
Type : InternalCustodialService
|
Decorators :
@Inject(InternalCustodialService)
|
|
Defined in src/profile/profile.service.ts:65
|
| Private Readonly userService |
Type : UserService
|
Decorators :
@Inject(UserService)
|
|
Defined in src/profile/profile.service.ts:61
|
import { CustodialDocument } from "./../shared/custodial/schemas/custodial.schema";
import {
BatchRegistry,
ContractName,
EndUserRoles,
IGetOrdersQuery,
QueryNames,
RegistryName,
TransactionNames,
UserJwtPayload,
} from "src/common/interfaces";
import { Inject, Injectable } from "@nestjs/common";
import { FundService } from "src/security/fund.service";
import { UserService } from "src/user/user.service";
import type {
IUserModule,
IDealerModuleEnableDisable as IUserModuleEnableDisable,
IOrderWithDbFundInstrument,
ISetInvestorRestriction,
ISetSanction,
IUserProfile,
} from "./profile.interface";
import { ApolloQueryResult } from "@apollo/client";
import { encodeBytes32String } from "ethers";
import {
apolloClient,
getAllOrdersByDealerIdQuery,
getAllOrdersByInvestorIdQuery,
getAllOrdersBySubscribedFundsIdQuery,
getAllOrdersByTypeQuery,
getContractByName,
getRoleAndContractAddressByNameOrAddress,
getTxSelector,
transactionQuery,
transactionSubmitter,
} from "src/common/provider";
import { UserDocument } from "src/user/schemas/user.schema";
import { InternalCustodialService } from "src/shared/custodial/internalCustodial.service";
import { JurisdictionDefaultValues, Roles } from "src/common/constants";
import { RoleRegistry } from "src/shared/artifacts/RoleRegistry";
import { CreateRoleDto } from "./dto/create-role.dto";
import { GrantRoleDto } from "./dto/grant-role.dto";
import { ResetRoleDto } from "./dto/reset-role.dto";
import { ManageRoleAccessDto } from "./dto/manage-role.dto";
import { OnChainDataField } from "src/shared/onchainDataFields/entities/onChainDataField.entity";
import { LeanDocument } from "mongoose";
import { InstrumentDocument } from "src/security/schemas/instrument.schema";
import { InstrumentService } from "src/security/instrument.service";
import { EmailService } from "src/common/provider/mail/email.service";
import { AllowInstrumentAccessTemplate } from "src/common/provider/mail/templates/allowInstrumentAccess";
import { RejectInstrumentAccessTemplate } from "src/common/provider/mail/templates/rejectInstrumentAccess";
import { AdminProfileService } from "src/admin-profile/admin-profile.service";
@Injectable()
export class ProfileService {
@Inject(FundService)
private readonly fundService: FundService;
@Inject(EmailService)
private readonly emailService: EmailService;
@Inject(UserService)
private readonly userService: UserService;
@Inject(InstrumentService)
private readonly instrumentService: InstrumentService;
@Inject(InternalCustodialService)
private readonly internalCustodialService: InternalCustodialService;
@Inject(AdminProfileService)
private readonly adminProfileService: AdminProfileService;
async getMyProfile(userJwtPayload: UserJwtPayload): Promise<IUserProfile> {
const { email, role } = userJwtPayload;
const user: LeanDocument<UserDocument> =
await this.userService.findUserByProperty({
email,
});
const funds = await this.fundService.findByIdsAndInstrument({
ids: user.subscribedFunds.map((currentFund) => currentFund.toString()),
});
let subgraphOrderBook: ApolloQueryResult<IGetOrdersQuery>;
if (role === EndUserRoles.dealer) {
subgraphOrderBook = await apolloClient.query({
query: getAllOrdersByDealerIdQuery,
variables: {
dealerId: encodeBytes32String(user._id.toString()),
type: "",
},
});
}
if (role === EndUserRoles.investor) {
subgraphOrderBook = await apolloClient.query({
query: getAllOrdersByInvestorIdQuery,
variables: {
investorId: encodeBytes32String(user._id.toString()),
type: "",
},
});
}
if (role === EndUserRoles.fundAdmin) {
subgraphOrderBook = await apolloClient.query({
query: getAllOrdersBySubscribedFundsIdQuery,
variables: {
fundsId: user.subscribedFunds.map((subscribedFund) =>
encodeBytes32String(String(subscribedFund)),
),
type: "",
},
});
}
if (role === "admin") {
subgraphOrderBook = await apolloClient.query({
query: getAllOrdersByTypeQuery,
variables: {
type: "",
},
});
}
if (!subgraphOrderBook.data) {
return {
...user,
orders: [],
};
}
const orders: IOrderWithDbFundInstrument[] = subgraphOrderBook.data.orders
.map((order) => {
const fund = funds.find((currentFund) => {
return (
encodeBytes32String(currentFund._id.toString()) ===
order.orderBook.fund.id
);
});
if (!fund) {
return null;
}
const instrument = fund.instruments.find(
(currentInstrument) =>
currentInstrument.subgraphInstrument.id ===
order.orderBook.instrument.id,
);
return {
...order,
orderBook: {
...order.orderBook,
fund: { ...fund, instruments: [] },
instrument,
},
};
})
.filter((orderBook) => orderBook);
return { ...user, orders };
}
async setInvestorRestriction({
investorId,
instrumentId,
isRestricted,
userJwtPayload,
}: ISetInvestorRestriction) {
const isPlatformAdmin = userJwtPayload.role === "admin";
let signerKey: CustodialDocument;
let dealer: LeanDocument<UserDocument>;
if (isPlatformAdmin) {
signerKey = await this.adminProfileService.getCustodial(
userJwtPayload.email,
);
} else {
dealer = await this.userService.findUserByProperty({
email: userJwtPayload.email,
});
signerKey = await this.internalCustodialService.findOne(
dealer.wallets[0].address,
);
}
const { contractAddress, role } =
await getRoleAndContractAddressByNameOrAddress({
contractName: ContractName.InvestorRegistry,
transactionName: TransactionNames.setInvestorRestriction,
userAddress:
userJwtPayload.role !== "admin"
? dealer.wallets[0].address
: signerKey.address,
});
const txResponse = await transactionSubmitter({
signerKey: signerKey.privateKey,
contractAddress,
contractName: ContractName.InvestorRegistry,
transactionName: TransactionNames.setInvestorRestriction,
args: [
role,
encodeBytes32String(investorId),
encodeBytes32String(instrumentId),
isRestricted,
],
});
const [instrument, investor]: [
LeanDocument<InstrumentDocument>,
LeanDocument<UserDocument>,
] = await Promise.all([
this.instrumentService.findOne(instrumentId),
this.userService.findOne(investorId),
]);
let subject;
let htmlTemplate;
if (isRestricted) {
subject = `Access to ${instrument.name} is denied for the investor ${investor.name}`;
htmlTemplate = RejectInstrumentAccessTemplate({
instrumentName: instrument.name,
investor: investor,
});
} else {
subject = `Access to ${instrument.name} is approved for the investor ${investor.name}`;
htmlTemplate = AllowInstrumentAccessTemplate({
instrumentName: instrument.name,
investor: investor,
});
}
await this.emailService.sendEmail({
from: "yehia@nethermind.io",
to: [investor.email],
subject,
html: htmlTemplate,
});
return txResponse;
}
async verifyInvestor({
investorId,
instrumentId,
}: Omit<ISetInvestorRestriction, "isRestricted" | "userJwtPayload">) {
try {
await transactionQuery({
contractAddress: getContractByName["InvestorRegistry"].address,
contractName: ContractName.InvestorRegistry,
queryName: QueryNames.checkInvestorAllowed,
args: [
encodeBytes32String(investorId),
encodeBytes32String(instrumentId),
],
});
return {
isAllowed: true,
message: "Investor is allowed to use this instrument",
};
} catch (error) {
return {
isAllowed: false,
message: error.toString(),
};
}
}
async setSanction(investorSanctionDto: ISetSanction) {
const { investorSanction, userJwtPayload } = investorSanctionDto;
const onchainFields: OnChainDataField[] = [];
const investorIdInBytes = encodeBytes32String(
investorSanctionDto.investorId,
);
const sanctionRegistriesToSet: BatchRegistry[] = Object.keys(
investorSanction,
).map((investor) => {
onchainFields.push({
name: JurisdictionDefaultValues[investor].dataFieldCol,
hash: JurisdictionDefaultValues[investor].dataFieldColHash,
linkedName: "",
linkedHash: "",
linkedType: JurisdictionDefaultValues[investor].type,
});
return {
id: investorIdInBytes,
dataFieldType: JurisdictionDefaultValues[investor].type,
dataFieldName: JurisdictionDefaultValues[investor].dataFieldCol,
dataFieldValue: investorSanction[investor],
};
});
return await this.userService.setRegistryData({
registries: sanctionRegistriesToSet,
registryName: RegistryName.InvestorRegistry,
userJwtPayload,
onchainFields,
});
}
async userRegisterModule({ contractAddress, userJwtPayload }: IUserModule) {
const user = await this.userService.findUserByProperty({
email: userJwtPayload.email,
});
const signerKey = (
await this.internalCustodialService.findOne(user.wallets[0].address)
).privateKey;
return await transactionSubmitter({
signerKey,
contractName: ContractName.DealerRulesEngine,
contractAddress:
userJwtPayload.role === EndUserRoles.dealer
? getContractByName["DealerRulesEngine"].address
: getContractByName["RulesEngine"].address,
transactionName: TransactionNames.registerModule,
args: [contractAddress],
});
}
async userEnableDisableModule({
contractAddress,
userJwtPayload,
status,
}: IUserModuleEnableDisable) {
const user = await this.userService.findUserByProperty({
email: userJwtPayload.email,
});
const signerKey = (
await this.internalCustodialService.findOne(user.wallets[0].address)
).privateKey;
return await transactionSubmitter({
signerKey,
contractName: ContractName.DealerRulesEngine,
contractAddress:
userJwtPayload.role === EndUserRoles.dealer
? getContractByName["DealerRulesEngine"].address
: getContractByName["RulesEngine"].address,
transactionName: TransactionNames.editModule,
args: [contractAddress, status],
});
}
async userDeleteModule({ contractAddress, userJwtPayload }: IUserModule) {
const dealer = await this.userService.findUserByProperty({
email: userJwtPayload.email,
});
const signerKey = (
await this.internalCustodialService.findOne(dealer.wallets[0].address)
).privateKey;
return await transactionSubmitter({
signerKey,
contractName: ContractName.DealerRulesEngine,
contractAddress:
userJwtPayload.role === EndUserRoles.dealer
? getContractByName["DealerRulesEngine"].address
: getContractByName["RulesEngine"].address,
transactionName: TransactionNames.deleteModule,
args: [contractAddress],
});
}
async createRole(createRoleDto: CreateRoleDto & { user: UserJwtPayload }) {
const { user } = createRoleDto;
const signerKey =
user.role === "admin"
? (await this.adminProfileService.getCustodial(user.email)).privateKey
: (await this.userService.getCustodial(user.email)).privateKey;
const createdRole = encodeBytes32String(createRoleDto.newRoleName);
await transactionSubmitter({
signerKey,
contractAddress: RoleRegistry.address,
transactionName: TransactionNames.createRole,
contractName: ContractName.RoleRegistry,
args: [Roles.Admin, createdRole],
});
return {
createdRole,
};
}
async grantRole(grantRoleDto: GrantRoleDto & { user: UserJwtPayload }) {
const roleBytes = encodeBytes32String(grantRoleDto.roleName);
const userWithGrantedRole = await this.userService.findOne(
grantRoleDto.userId,
);
const { user } = grantRoleDto;
const signerKey =
user.role === "admin"
? (await this.adminProfileService.getCustodial(user.email)).privateKey
: (await this.userService.getCustodial(user.email)).privateKey;
return await transactionSubmitter({
signerKey,
contractAddress: RoleRegistry.address,
transactionName: TransactionNames.grantRole,
contractName: ContractName.RoleRegistry,
args: [roleBytes, userWithGrantedRole.wallets[0].address],
});
}
async manageRoleAccess(
action: "revoke" | "grant",
manageRoleAccessDto: ManageRoleAccessDto & { user: UserJwtPayload },
) {
const { contractName, transactionName, user } = manageRoleAccessDto;
const selector = getTxSelector({ contractName, transactionName });
const transactionNameToSubmit =
action === "revoke"
? TransactionNames.revokeAccess
: TransactionNames.grantAccess;
const signerKey =
user.role === "admin"
? (await this.adminProfileService.getCustodial(user.email)).privateKey
: (await this.userService.getCustodial(user.email)).privateKey;
return transactionSubmitter({
signerKey,
contractAddress: RoleRegistry.address,
transactionName: transactionNameToSubmit,
contractName: ContractName.RoleRegistry,
args: [
getContractByName[contractName].address,
selector,
encodeBytes32String(manageRoleAccessDto.roleName),
],
});
}
async resetAccess(restRoleDto: ResetRoleDto & { user: UserJwtPayload }) {
const { contractName, transactionName, user } = restRoleDto;
const selector = getTxSelector({ contractName, transactionName });
const signerKey =
user.role === "admin"
? (await this.adminProfileService.getCustodial(user.email)).privateKey
: (await this.userService.getCustodial(user.email)).privateKey;
return transactionSubmitter({
signerKey,
contractAddress: RoleRegistry.address,
transactionName: TransactionNames.resetAccess,
contractName: ContractName.RoleRegistry,
args: [
restRoleDto.contractAddress || getContractByName[contractName].address,
selector,
],
});
}
}