@@ -540,6 +540,41 @@ export default class TransactionDbRepository implements TransactionRepository {
540540 return totalCount ;
541541 }
542542
543+ private getHeightChange (
544+ counters : { chainId : number ; counter : number } [ ] ,
545+ minHeight : number | null ,
546+ maxHeight : number | null ,
547+ ) {
548+ // If no height constraints, return the sum of all counters
549+ if ( ! minHeight && ! maxHeight ) {
550+ return counters . reduce ( ( acc , curr ) => acc + curr . counter , 0 ) ;
551+ }
552+
553+ let totalCount = 0 ;
554+ for ( const { chainId, counter } of counters ) {
555+ // Determine starting height for each chain
556+ const chainStartHeight = chainId >= 10 ? 852054 : 0 ;
557+
558+ // If no maxHeight provided, use counter - 1 (since height 0 is valid)
559+ const chainMaxHeight = maxHeight !== null ? maxHeight : counter - 1 ;
560+
561+ // Calculate the effective height range for this chain
562+ const effectiveMinHeight = Math . max ( minHeight || 0 , chainStartHeight ) ;
563+ const effectiveMaxHeight = chainMaxHeight ;
564+
565+ // If the range is invalid (min > max), skip this chain
566+ if ( effectiveMinHeight > effectiveMaxHeight ) {
567+ continue ;
568+ }
569+
570+ // Calculate how many blocks are included in the range [effectiveMinHeight, effectiveMaxHeight]
571+ const includedBlocks = Math . max ( 0 , effectiveMaxHeight - effectiveMinHeight + 1 ) ;
572+
573+ totalCount += includedBlocks ;
574+ }
575+
576+ return totalCount ;
577+ }
543578 /**
544579 * Counts transactions matching the specified filter parameters.
545580 * This method efficiently counts matching transactions without retrieving full data.
@@ -552,72 +587,53 @@ export default class TransactionDbRepository implements TransactionRepository {
552587 isCoinbase : isCoinbaseParam ,
553588 chainId : chainIdParam ,
554589 minimumDepth : minimumDepthParam ,
590+ minHeight : minHeightParam ,
591+ maxHeight : maxHeightParam ,
555592 ...rest
556593 } = params ;
594+
557595 const hasNoOtherParams = Object . values ( rest ) . every ( v => v === undefined || v === null ) ;
558596 if ( hasNoOtherParams ) {
559597 const query = `
560- SELECT sum(" canonicalTransactions") as "totalTransactionsCount ", sum( "canonicalBlocks") as "totalBlocksCount "
598+ SELECT "chainId", " canonicalTransactions" as "transactionsCount ", "canonicalBlocks" as "blocksCount "
561599 FROM "Counters"
562- ${ chainIdParam ? `WHERE "chainId" = $1` : '' }
563600 ` ;
564601
565- const { rows } = await rootPgPool . query ( query , chainIdParam ? [ chainIdParam ] : [ ] ) ;
566-
567- const totalTransactionsCount = parseInt ( rows ?. [ 0 ] ?. totalTransactionsCount ?? '0' , 10 ) ;
568- const totalBlocksCount = parseInt ( rows ?. [ 0 ] ?. totalBlocksCount ?? '0' , 10 ) ;
569- const totalCount = totalTransactionsCount + ( params . isCoinbase ? totalBlocksCount : 0 ) ;
602+ const { rows } = await rootPgPool . query ( query ) ;
603+
604+ const counters = rows
605+ . map ( r => {
606+ const { chainId, transactionsCount, blocksCount } = r ;
607+ const counter =
608+ parseInt ( transactionsCount , 10 ) + ( params . isCoinbase ? parseInt ( blocksCount , 10 ) : 0 ) ;
609+ return {
610+ chainId,
611+ counter,
612+ } ;
613+ } )
614+ . filter ( c => ( chainIdParam ? c . chainId . toString ( ) === chainIdParam : true ) ) ;
615+
616+ const counterConsideringHeight = this . getHeightChange (
617+ counters ,
618+ minHeightParam ?? null ,
619+ maxHeightParam ?? null ,
620+ ) ;
570621
571622 const depthDecrement = ( minimumDepthParam ?? 0 ) * ( isNullOrUndefined ( chainIdParam ) ? 20 : 1 ) ;
572- return Math . max ( totalCount - depthDecrement , 0 ) ;
573- }
574-
575- const {
576- accountName : accountNameParam ,
577- fungibleName : fungibleNameParam ,
578- chainId : chainIdParamTwo ,
579- ...rest2
580- } = params ;
581- const hasNoOtherParams2 = Object . values ( rest2 ) . every ( v => v === undefined || v === null ) ;
582- if ( accountNameParam && fungibleNameParam && hasNoOtherParams2 ) {
583- let query = `
584- SELECT COUNT(*) as count
585- FROM "Transactions" t
586- JOIN "Events" e ON e."transactionId" = t.id
587- WHERE t.sender = $1 AND e.module = $2
588- ` ;
589-
590- if ( chainIdParamTwo ) {
591- query += `\nAND EXISTS (
592- SELECT 1
593- FROM "Blocks" b
594- WHERE b.id = t."blockId"
595- AND b."chainId" = $3
596- AND b.canonical = true
597- )` ;
598- }
599-
600- const { rows : countResult } = await rootPgPool . query ( query , [
601- accountNameParam ,
602- fungibleNameParam ,
603- chainIdParamTwo ,
604- ] ) ;
605-
606- const totalCount = parseInt ( countResult [ 0 ] . count , 10 ) ;
607- const depthDecrement =
608- ( minimumDepthParam ?? 0 ) * ( isNullOrUndefined ( chainIdParamTwo ) ? 20 : 1 ) ;
609- return Math . max ( totalCount - depthDecrement , 0 ) ;
623+ return counterConsideringHeight - depthDecrement ;
610624 }
611625
612626 const {
613627 blockHash,
614628 accountName,
615- chainId,
616629 requestKey,
617630 fungibleName,
618- minHeight,
619- maxHeight,
620631 hasTokenId,
632+ chainId,
633+ isCoinbase,
634+ maxHeight,
635+ minHeight,
636+ minimumDepth,
621637 } = params ;
622638 const transactionsParams : ( string | number ) [ ] = [ ] ;
623639 const blockParams : ( string | number | boolean ) [ ] = [ ] ;
@@ -630,18 +646,12 @@ export default class TransactionDbRepository implements TransactionRepository {
630646 transactionsParams . push ( accountName ) ;
631647 const op = localOperator ( transactionsParams . length ) ;
632648 transactionsConditions += `${ op } t.sender = $${ transactionsParams . length } ` ;
633- } else if ( ! isCoinbaseParam ) {
649+ } else if ( ! isCoinbase ) {
634650 transactionsParams . push ( 'coinbase' ) ;
635651 const op = localOperator ( transactionsParams . length ) ;
636652 transactionsConditions += `${ op } t.sender != $${ transactionsParams . length } ` ;
637653 }
638654
639- if ( requestKey ) {
640- transactionsParams . push ( requestKey ) ;
641- const op = localOperator ( transactionsParams . length ) ;
642- transactionsConditions += `${ op } t."requestkey" = $${ transactionsParams . length } ` ;
643- }
644-
645655 if ( fungibleName ) {
646656 transactionsParams . push ( fungibleName ) ;
647657 const op = localOperator ( transactionsParams . length ) ;
@@ -655,19 +665,23 @@ export default class TransactionDbRepository implements TransactionRepository {
655665 )` ;
656666 }
657667
658- if ( accountName && hasTokenId ) {
659- transactionsParams . push ( accountName ) ;
668+ if ( hasTokenId ) {
660669 const op = localOperator ( transactionsParams . length ) ;
661670 transactionsConditions += `
662671 ${ op } EXISTS
663672 (
664673 SELECT 1
665674 FROM "Transfers" t
666- WHERE t."from_acct" = $${ transactionsParams . length }
667- AND t."hasTokenId" = true
675+ WHERE t."hasTokenId" = true
668676 )` ;
669677 }
670678
679+ if ( requestKey ) {
680+ transactionsParams . push ( requestKey ) ;
681+ const op = localOperator ( transactionsParams . length ) ;
682+ transactionsConditions += `${ op } t."requestkey" = $${ transactionsParams . length } ` ;
683+ }
684+
671685 const paramsOffset = transactionsParams . length ;
672686
673687 blockParams . push ( true ) ;
@@ -698,16 +712,16 @@ export default class TransactionDbRepository implements TransactionRepository {
698712 }
699713
700714 const totalCountQuery = `
701- WITH filtered_transactions AS (
702- SELECT id, "blockId"
703- FROM "Transactions" t
704- ${ transactionsConditions }
715+ WITH filtered_transactions AS (
716+ SELECT id, "blockId"
717+ FROM "Transactions" t
718+ ${ transactionsConditions }
705719 )
706720 SELECT COUNT(*) as count
707721 FROM filtered_transactions t
708722 ${ blocksConditions ? `JOIN "Blocks" b ON b.id = t."blockId"` : '' }
709723 ${ blocksConditions }
710- ` ;
724+ ` ;
711725
712726 const { rows : countResult } = await rootPgPool . query ( totalCountQuery , [
713727 ...transactionsParams ,
0 commit comments