pussy-ts/src/pages/teleport/hooks/useGetSendTxsByAddressByLcd.tsx

import { InfiniteData, useInfiniteQuery } from '@tanstack/react-query';
import BigNumber from 'bignumber.js';
import { getSendBySenderRecipient } from 'src/utils/search/utils';
import { Nullable, Option } from 'src/types';
import { AccountValue } from 'src/types/defaultAccount';
import { useCallback, useEffect, useState } from 'react';
import { TxsResponse } from '@cosmjs/launchpad';
import { PATTERN_CYBER } from 'src/constants/app';

const limit = 5;

const concatResponse = (arr: undefined | InfiniteData<{ data: any }>) => {
  return (
    arr?.pages?.reduce((acc, page) => {
      return acc.concat(page.data.tx_responses);
    }, []) || []
  );
};

function useGetSendBySenderRecipient(
  addressSender: Option<string>,
  addressRecipient: Option<string>,
  callBack?: React.Dispatch<React.SetStateAction<number>>
) {
  const data = useInfiniteQuery(
    ['getSendBySenderRecipient', addressSender, addressRecipient],
    async ({ pageParam = 0 }) => {
      const address = {
        sender: addressSender,
        recipient: addressRecipient,
      };

      const offset = new BigNumber(limit).multipliedBy(pageParam).toNumber();

      const response = await getSendBySenderRecipient(address, offset, limit);

      if (callBack && offset === 0 && response) {
        callBack(response.pagination.total);
      }

      return {
        data: response,
        page: pageParam,
      };
    },
    {
      enabled:
        Boolean(addressSender) &&
        Boolean(addressSender?.match(PATTERN_CYBER)) &&
        Boolean(addressRecipient) &&
        Boolean(addressRecipient?.match(PATTERN_CYBER)),
      getNextPageParam: (lastPage) => {
        const {
          page,
          data: {
            pagination: { total },
          },
        } = lastPage;

        if (!total || (page + 1) * limit >= total) {
          return undefined;
        }

        return page + 1;
      },
    }
  );

  return {
    data: data.data,
    fetchNextPage: data.fetchNextPage,
    refetch: data.refetch,
    hasNextPage: data.hasNextPage,
  };
}

function useGetSendTxsByAddressByLcd(
  sender: Nullable<AccountValue>,
  addressRecipient: Option<string>
) {
  const [addressSender, setAddressSender] = useState<Option<string>>();
  const [dataTsx, setDataTxs] = useState<Option<TxsResponse[]>>(undefined);

  const dataSend = useGetSendBySenderRecipient(addressSender, addressRecipient);
  const dataReceive = useGetSendBySenderRecipient(
    addressRecipient,
    addressSender
  );

  useEffect(() => {
    let firstSendItem = '0';
    let lastSendItem = '0';
    const dataSendArr: TxsResponse[] = concatResponse(dataSend.data);
    const dataReceiveArr: TxsResponse[] = concatResponse(dataReceive.data);

    let dataTxs: TxsResponse[] = [];

    if (dataSendArr.length) {
      lastSendItem = dataSendArr[dataSendArr.length - 1].height;
      firstSendItem = dataSendArr[0].height;
    }

    if (dataSendArr.length && dataReceiveArr.length) {
      dataReceiveArr.forEach((item) => {
        const height = parseFloat(item.height);
        if (height > parseFloat(firstSendItem)) {
          dataTxs.push(item);
        }

        if (
          height > parseFloat(lastSendItem) &&
          height < parseFloat(firstSendItem)
        ) {
          dataTxs.push(item);
        }

        if (height < parseFloat(lastSendItem)) {
          dataTxs.push(item);
        }
      });
      dataTxs = [...dataTxs, ...dataSendArr];
      dataTxs = dataTxs.sort(
        (itemA, itemB) => parseFloat(itemB.height) - parseFloat(itemA.height)
      );
    } else {
      dataTxs = [...dataSendArr, ...dataReceiveArr];
    }

    setDataTxs(dataTxs);
  }, [dataSend.data, dataReceive.data]);

  useEffect(() => {
    if (sender) {
      setAddressSender(sender.bech32);
    }
  }, [sender]);

  const fetchNextPage = useCallback(() => {
    dataReceive.fetchNextPage();
    dataSend.fetchNextPage();
  }, [dataReceive, dataSend]);

  const refetch = useCallback(() => {
    dataReceive.refetch();
    dataSend.refetch();
  }, [dataReceive, dataSend]);

  return {
    data: dataTsx,
    fetchNextPage,
    refetch,
    hasNextPage: Boolean(dataReceive.hasNextPage || dataSend.hasNextPage),
  };
}

export default useGetSendTxsByAddressByLcd;

Synonyms

cyb/src/pages/teleport/hooks/useGetSendTxsByAddressByLcd.tsx

Neighbours