@@ -285,6 +285,108 @@ export class DepositsService {
285285 return result ;
286286 }
287287
288+ public async getDeposit ( params : DepositParams ) {
289+ // in the validation rules each of these params are marked as optional
290+ // but we need to check that at least one of them is present
291+ if (
292+ ! (
293+ ( params . depositId && params . originChainId ) ||
294+ params . depositTxHash ||
295+ params . relayDataHash
296+ )
297+ ) {
298+ throw new IncorrectQueryParamsException ( ) ;
299+ }
300+
301+ // construct cache key
302+ const cacheKey = this . getDepositCacheKey ( params ) ;
303+ const cachedData = await this . redis . get ( cacheKey ) ;
304+
305+ if ( cachedData ) {
306+ return JSON . parse ( cachedData ) ;
307+ }
308+
309+ // no cached data, so we need to query the database
310+ const repo = this . db . getRepository ( entities . RelayHashInfo ) ;
311+ const queryBuilder = repo . createQueryBuilder ( "rhi" ) ;
312+
313+ queryBuilder . leftJoinAndSelect (
314+ entities . V3FundsDeposited ,
315+ "deposit" ,
316+ "rhi.depositEventId = deposit.id" ,
317+ ) ;
318+ queryBuilder . leftJoinAndSelect (
319+ entities . SwapBeforeBridge ,
320+ "swap" ,
321+ "swap.id = rhi.swapBeforeBridgeEventId" ,
322+ ) ;
323+ queryBuilder . leftJoinAndSelect (
324+ entities . FilledV3Relay ,
325+ "fill" ,
326+ "fill.id = rhi.fillEventId" ,
327+ ) ;
328+
329+ if ( params . depositId && params . originChainId ) {
330+ queryBuilder . andWhere (
331+ "rhi.depositId = :depositId AND rhi.originChainId = :originChainId" ,
332+ {
333+ depositId : params . depositId ,
334+ originChainId : params . originChainId ,
335+ } ,
336+ ) ;
337+ }
338+
339+ if ( params . depositTxHash ) {
340+ queryBuilder . andWhere ( "rhi.depositTxHash = :depositTxHash" , {
341+ depositTxHash : params . depositTxHash ,
342+ } ) ;
343+ }
344+
345+ if ( params . relayDataHash ) {
346+ queryBuilder . andWhere ( "rhi.relayHash = :relayDataHash" , {
347+ relayDataHash : params . relayDataHash ,
348+ } ) ;
349+ }
350+
351+ const matchingRelays = await queryBuilder
352+ . orderBy ( "rhi.depositEventId" , "ASC" )
353+ . select ( [
354+ ...DepositFields ,
355+ ...RelayHashInfoFields ,
356+ ...SwapBeforeBridgeFields ,
357+ ...FilledRelayFields ,
358+ ] )
359+ . execute ( ) ;
360+ const numberMatchingRelays = matchingRelays . length ;
361+ if ( numberMatchingRelays === 0 ) throw new DepositNotFoundException ( ) ;
362+ const relay = matchingRelays [ params . index ] ;
363+ if ( ! relay ) {
364+ throw new IndexParamOutOfRangeException (
365+ `Index ${ params . index } out of range. Index must be between 0 and ${ numberMatchingRelays - 1 } ` ,
366+ ) ;
367+ }
368+
369+ const result = {
370+ deposit : {
371+ ...relay ,
372+ } ,
373+ pagination : {
374+ currentIndex : params . index ,
375+ maxIndex : numberMatchingRelays - 1 ,
376+ } ,
377+ } ;
378+
379+ if ( this . shouldCacheDepositResponse ( relay ) ) {
380+ await this . redis . set (
381+ cacheKey ,
382+ JSON . stringify ( result ) ,
383+ "EX" ,
384+ this . getDepositCacheTTLSeconds ( relay ) ,
385+ ) ;
386+ }
387+ return result ;
388+ }
389+
288390 public async getUnfilledDeposits (
289391 params : FilterDepositsParams ,
290392 ) : Promise < ParsedDepositReturnType [ ] > {
@@ -493,6 +595,27 @@ export class DepositsService {
493595 }
494596 }
495597
598+ private getDepositCacheTTLSeconds ( deposit : DepositReturnType ) {
599+ const minute = 60 ;
600+ const hour = 60 * minute ;
601+ const day = 24 * hour ;
602+
603+ if (
604+ deposit . status === entities . RelayStatus . Filled &&
605+ deposit . depositBlockTimestamp &&
606+ deposit . fillBlockTimestamp &&
607+ deposit . bridgeFeeUsd
608+ ) {
609+ return hour ;
610+ }
611+
612+ if ( deposit . status === entities . RelayStatus . Refunded ) {
613+ return hour ;
614+ }
615+
616+ return 0 ;
617+ }
618+
496619 private shouldCacheDepositStatusResponse ( status : entities . RelayStatus ) {
497620 return [
498621 entities . RelayStatus . Expired ,
@@ -502,6 +625,23 @@ export class DepositsService {
502625 ] . includes ( status ) ;
503626 }
504627
628+ private shouldCacheDepositResponse ( deposit : DepositReturnType ) {
629+ if (
630+ deposit . status === entities . RelayStatus . Filled &&
631+ deposit . depositBlockTimestamp &&
632+ deposit . fillBlockTimestamp &&
633+ deposit . bridgeFeeUsd
634+ ) {
635+ return true ;
636+ }
637+
638+ if ( deposit . status === entities . RelayStatus . Refunded ) {
639+ return true ;
640+ }
641+
642+ return false ;
643+ }
644+
505645 private getDepositStatusCacheKey ( params : DepositParams ) {
506646 if ( params . depositId && params . originChainId ) {
507647 return `depositStatus-${ params . depositId } -${ params . originChainId } -${ params . index } ` ;
@@ -519,4 +659,20 @@ export class DepositsService {
519659 "Could not get deposit status: could not locate cache data" ,
520660 ) ;
521661 }
662+
663+ private getDepositCacheKey ( params : DepositParams ) {
664+ if ( params . depositId && params . originChainId ) {
665+ return `deposit-${ params . depositId } -${ params . originChainId } -${ params . index } ` ;
666+ }
667+ if ( params . depositTxHash ) {
668+ return `deposit-${ params . depositTxHash } -${ params . index } ` ;
669+ }
670+ if ( params . relayDataHash ) {
671+ return `deposit-${ params . relayDataHash } -${ params . index } ` ;
672+ }
673+
674+ // in theory this should never happen because we have already checked
675+ // that at least one of the params is present
676+ throw new Error ( "Could not get deposit: could not locate cache data" ) ;
677+ }
522678}
0 commit comments