@@ -11,9 +11,10 @@ import { JwtPayload } from 'src/shared/auth/jwt-payload.interface';
1111import { Asset } from 'src/shared/models/asset/asset.entity' ;
1212import { AssetService } from 'src/shared/models/asset/asset.service' ;
1313import { FiatService } from 'src/shared/models/fiat/fiat.service' ;
14+ import { User } from 'src/subdomains/generic/user/models/user/user.entity' ;
1415import { UserService } from 'src/subdomains/generic/user/models/user/user.service' ;
1516import { TransactionRequest } from 'src/subdomains/supporting/payment/entities/transaction-request.entity' ;
16- import { Equal } from 'typeorm' ;
17+ import { Equal , In , Not } from 'typeorm' ;
1718import { BuyCrypto } from '../../buy-crypto/process/entities/buy-crypto.entity' ;
1819import { BuyService } from '../../buy-crypto/routes/buy/buy.service' ;
1920import { SwapService } from '../../buy-crypto/routes/swap/swap.service' ;
@@ -23,12 +24,18 @@ import { OrderConfig } from '../config/order-config';
2324import { CreateCustodyOrderInternalDto } from '../dto/input/create-custody-order.dto' ;
2425import { GetCustodyInfoDto } from '../dto/input/get-custody-info.dto' ;
2526import { UpdateCustodyOrderInternalDto } from '../dto/input/update-custody-order.dto' ;
27+ import { CustodyOrderHistoryDto } from '../dto/output/custody-order-history.dto' ;
2628import { CustodyOrderResponseDto } from '../dto/output/custody-order-response.dto' ;
2729import { CustodyOrderDto } from '../dto/output/custody-order.dto' ;
28- import { CustodyBalance } from '../entities/custody-balance.entity' ;
2930import { CustodyOrderStep } from '../entities/custody-order-step.entity' ;
3031import { CustodyOrder } from '../entities/custody-order.entity' ;
31- import { CustodyOrderStepCommand , CustodyOrderStepContext , CustodyOrderType } from '../enums/custody' ;
32+ import {
33+ CustodyOrderStatus ,
34+ CustodyOrderStepCommand ,
35+ CustodyOrderStepContext ,
36+ CustodyOrderType ,
37+ } from '../enums/custody' ;
38+ import { CustodyOrderHistoryDtoMapper } from '../mappers/custody-order-history-dto.mapper' ;
3239import { CustodyOrderResponseDtoMapper } from '../mappers/custody-order-response-dto.mapper' ;
3340import { GetCustodyOrderDtoMapper } from '../mappers/get-custody-order-dto.mapper' ;
3441import { CustodyOrderStepRepository } from '../repositories/custody-order-step.repository' ;
@@ -81,14 +88,15 @@ export class CustodyOrderService {
8188 paymentInfo = CustodyOrderResponseDtoMapper . mapBuyPaymentInfo ( buyPaymentInfo ) ;
8289 break ;
8390 }
91+
8492 case CustodyOrderType . WITHDRAWAL : {
8593 const sourceAsset = await this . getCustodyAsset ( dto . sourceAsset ) ;
8694 if ( ! sourceAsset ) throw new NotFoundException ( 'Source asset not found' ) ;
8795
8896 const targetCurrency = await this . fiatService . getFiatByName ( dto . targetAsset ) ;
8997 if ( ! targetCurrency ) throw new NotFoundException ( 'Target currency not found' ) ;
9098
91- this . checkBalance ( sourceAsset , dto . sourceAmount , user . custodyBalances ) ;
99+ await this . checkBalance ( sourceAsset , dto . sourceAmount , user ) ;
92100
93101 const sellPaymentInfo = await this . sellService . createSellPaymentInfo (
94102 jwt . user ,
@@ -102,14 +110,15 @@ export class CustodyOrderService {
102110 paymentInfo = CustodyOrderResponseDtoMapper . mapSellPaymentInfo ( sellPaymentInfo ) ;
103111 break ;
104112 }
113+
105114 case CustodyOrderType . SWAP : {
106115 const sourceAsset = await this . getCustodyAsset ( dto . sourceAsset ) ;
107116 if ( ! sourceAsset ) throw new NotFoundException ( 'Source asset not found' ) ;
108117
109118 const targetAsset = await this . getCustodyAsset ( dto . targetAsset ) ;
110119 if ( ! targetAsset ) throw new NotFoundException ( 'Target asset not found' ) ;
111120
112- this . checkBalance ( sourceAsset , dto . sourceAmount , user . custodyBalances ) ;
121+ await this . checkBalance ( sourceAsset , dto . sourceAmount , user ) ;
113122
114123 const swapPaymentInfo = await this . swapService . createSwapPaymentInfo (
115124 jwt . user ,
@@ -123,6 +132,7 @@ export class CustodyOrderService {
123132 paymentInfo = CustodyOrderResponseDtoMapper . mapSwapPaymentInfo ( swapPaymentInfo ) ;
124133 break ;
125134 }
135+
126136 case CustodyOrderType . SEND : {
127137 const sourceAsset = await this . getCustodyAsset ( dto . sourceAsset ) ;
128138 if ( ! sourceAsset ) throw new NotFoundException ( 'Source asset not found' ) ;
@@ -134,7 +144,7 @@ export class CustodyOrderService {
134144 } ) ;
135145 if ( ! targetAsset ) throw new NotFoundException ( 'Target asset not found' ) ;
136146
137- this . checkBalance ( sourceAsset , dto . sourceAmount , user . custodyBalances ) ;
147+ await this . checkBalance ( sourceAsset , dto . sourceAmount , user ) ;
138148
139149 const targetUser = await this . userService . getUserByAddress ( dto . targetAddress , { userData : true } ) ;
140150 if ( ! targetUser || targetUser . userData . id !== user . userData . id )
@@ -152,6 +162,7 @@ export class CustodyOrderService {
152162 paymentInfo = CustodyOrderResponseDtoMapper . mapSwapPaymentInfo ( swapPaymentInfo ) ;
153163 break ;
154164 }
165+
155166 case CustodyOrderType . RECEIVE : {
156167 const sourceAsset = await this . getCustodyAsset ( dto . sourceAsset ) ;
157168 if ( ! sourceAsset ) throw new NotFoundException ( 'Asset not found' ) ;
@@ -181,6 +192,17 @@ export class CustodyOrderService {
181192 } ;
182193 }
183194
195+ async getOrdersByUserData ( userDataId : number ) : Promise < CustodyOrderHistoryDto [ ] > {
196+ const orders = await this . custodyOrderRepo . find ( {
197+ where : { user : { userData : { id : userDataId } } , status : Not ( CustodyOrderStatus . CREATED ) } ,
198+ relations : { inputAsset : true , outputAsset : true , transactionRequest : true } ,
199+ order : { created : 'DESC' } ,
200+ take : 100 ,
201+ } ) ;
202+
203+ return CustodyOrderHistoryDtoMapper . mapList ( orders ) ;
204+ }
205+
184206 async createOrderInternal ( dto : CreateCustodyOrderInternalDto ) : Promise < CustodyOrder > {
185207 const order = this . custodyOrderRepo . create ( dto ) ;
186208
@@ -265,9 +287,17 @@ export class CustodyOrderService {
265287 . sort ( ( a , b ) => this . CustodyChains . indexOf ( a . blockchain ) - this . CustodyChains . indexOf ( b . blockchain ) ) [ 0 ] ;
266288 }
267289
268- private checkBalance ( asset : Asset , amount : number , custodyBalances : CustodyBalance [ ] ) : void {
269- const assetBalance = custodyBalances . find ( ( a ) => a . asset . id === asset . id ) ;
270- if ( ! assetBalance || assetBalance . balance < amount )
290+ private async checkBalance ( asset : Asset , amount : number , user : User ) : Promise < void > {
291+ const assetBalance = user . custodyBalances . find ( ( a ) => a . asset . id === asset . id ) ;
292+ const balance = assetBalance ?. balance ?? 0 ;
293+
294+ const pendingAmount = await this . custodyOrderRepo . sum ( 'outputAmount' , {
295+ user : { id : user . id } ,
296+ outputAsset : { id : asset . id } ,
297+ status : In ( [ CustodyOrderStatus . CONFIRMED , CustodyOrderStatus . APPROVED , CustodyOrderStatus . IN_PROGRESS ] ) ,
298+ } ) ;
299+
300+ if ( balance < pendingAmount + amount )
271301 throw new BadRequestException ( 'This transaction can only be created manually by support' ) ;
272302 }
273303}
0 commit comments