/* eslint-disable no-restricted-syntax */
import { Decimal } from '@cosmjs/math';
import { useQuery } from '@tanstack/react-query';
import BigNumber from 'bignumber.js';

import { BASE_DENOM, BECH32_PREFIX_VALOPER } from 'src/constants/config';
import { useQueryClient } from 'src/contexts/queryClient';
import { useCyberClient } from 'src/contexts/queryCyberClient';
import { CYBERVER_CONTRACTS } from 'src/features/cybernet/constants';
import { useStake as useVerseStake } from 'src/features/cybernet/ui/hooks/useCurrentAccountStake';

import { getDelegatorDelegations } from 'src/features/staking/delegation/getDelegatorDelegations';
import { isPussyChain } from 'src/utils/chains/pussy';
import { fromBech32 } from '../../../utils/utils';

const initValue = {
  denom: BASE_DENOM,
  amount: '0',
};

export const initValueMainToken = {
  liquid: { ...initValue },
  frozen: { ...initValue },
  melting: { ...initValue },
  growth: { ...initValue },
  total: { ...initValue },
};

if (isPussyChain) {
  initValueMainToken.cyberver = { ...initValue };
}

const initValueResponseFunc = (denom = '', amount = 0) => {
  return { denom, amount };
};

const getDelegationsAmount = (data) => {
  let delegationsAmount = new BigNumber(0);
  if (data.length) {
    data.forEach((itemDelegation) => {
      delegationsAmount = delegationsAmount.plus(itemDelegation.balance.amount);
    });
  }
  return initValueResponseFunc(BASE_DENOM, delegationsAmount.toString());
};

const getUnbondingAmount = (data) => {
  let unbondingAmount = new BigNumber(0);
  const { unbondingResponses } = data;
  if (unbondingResponses && Object.keys(unbondingResponses).length > 0) {
    unbondingResponses.forEach((unbond) => {
      unbond.entries.forEach((entry) => {
        unbondingAmount = unbondingAmount.plus(entry.balance);
      });
    });
  }
  return initValueResponseFunc(BASE_DENOM, unbondingAmount.toString());
};

const getRewardsAmount = (data) => {
  let rewardsAmount = new BigNumber(0);
  const { total } = data;
  if (total && total.length > 0) {
    const [{ amount }] = total;
    rewardsAmount = rewardsAmount.plus(Decimal.fromAtomics(amount, 18).floor().toString());
  }
  return initValueResponseFunc(BASE_DENOM, rewardsAmount.toString());
};

const getCommissionAmount = (data) => {
  let commissionAmount = new BigNumber(0);

  if (data.commission.commission.length > 0) {
    const { commission } = data;
    const [{ amount }] = commission.commission;
    commissionAmount = commissionAmount.plus(Decimal.fromAtomics(amount, 18).floor().toString());
  }
  return initValueResponseFunc(BASE_DENOM, commissionAmount.toString());
};

function useCyberverBalance({ address }) {
  const skip = !address || !isPussyChain;
  // will be refactored to loop
  const s1 = useVerseStake({
    address,
    contractAddress: CYBERVER_CONTRACTS[0],
    skip,
  });

  const s2 = useVerseStake({
    address,
    contractAddress: CYBERVER_CONTRACTS[1],
    skip,
  });

  const total1 = s1.data?.reduce((acc, { stake }) => acc + stake, 0) || 0;
  const total2 = s2.data?.reduce((acc, { stake }) => acc + stake, 0) || 0;

  const total = total1 + total2;

  if (total === 0) {
    return null;
  }

  return total.toString();
}

export const useGetBalance = (addressBech32) => {
  const client = useQueryClient();
  const { rpc } = useCyberClient();

  const { data, isFetching, refetch } = useQuery(
    ['getBalance', addressBech32],
    async () => {
      const responsegetBalance = await client.getBalance(addressBech32, BASE_DENOM);

      const responsedelegatorDelegations = await getDelegatorDelegations(rpc, addressBech32);

      const delegationsAmount = getDelegationsAmount(responsedelegatorDelegations);

      const responsedelegatorUnbondingDelegations =
        await client.delegatorUnbondingDelegations(addressBech32);

      const unbondingAmount = getUnbondingAmount(responsedelegatorUnbondingDelegations);

      const responsedelegationTotalRewards = await client.delegationTotalRewards(addressBech32);

      const rewardsAmount = getRewardsAmount(responsedelegationTotalRewards);

      const dataValidatorAddress = fromBech32(addressBech32, BECH32_PREFIX_VALOPER);

      const responsevalidatorCommission = await client.validatorCommission(dataValidatorAddress);

      const commissionAmount = getCommissionAmount(responsevalidatorCommission);

      const resultBalance = {
        liquid: responsegetBalance,
        frozen: delegationsAmount,
        melting: unbondingAmount,
        growth: rewardsAmount,
      };

      if (commissionAmount.amount > 0) {
        resultBalance.commission = commissionAmount;
      }

      return resultBalance;
    },
    {
      enabled: Boolean(client && addressBech32 && rpc),
    }
  );

  const totalCyberver = useCyberverBalance({ address: addressBech32 });

  // TODO: refactor below
  if (isFetching) {
    return { data: initValueMainToken, refetch, isFetching };
  }

  const result = {
    ...initValueMainToken,
    ...data,
  };

  if (data && totalCyberver) {
    result.cyberver = {
      denom: BASE_DENOM,
      amount: totalCyberver,
    };
  }

  const total = Object.values(result).reduce((acc, item) => {
    return new BigNumber(acc).plus(item.amount).toString();
  }, 0);

  result.total = {
    denom: BASE_DENOM,
    amount: total,
  };

  return {
    data: result,
    refetch,
    isFetching,
  };
};

Synonyms

soft3.js/examples/utils.ts
cyb/src/utils/utils.ts
pussy-ts/src/utils/utils.ts
bostrom.network/src/lib/utils.ts
pussy-ts/src/services/ibc-history/utils.ts
cyb/src/services/CozoDb/utils.ts
cyb/src/features/ibc-history/utils.ts
cyb/src/containers/mint/utils.ts
cyb/src/containers/portal/utils.ts
pussy-ts/src/containers/portal/utils.ts
cyb/src/utils/search/utils.ts
pussy-ts/src/services/CozoDb/utils.ts
pussy-ts/src/utils/search/utils.ts
cyb/src/containers/warp/utils.ts
cyb/src/components/time/utils.ts
pussy-ts/src/containers/warp/utils.ts
cyb/src/pages/teleport/swap/utils.ts
pussy-ts/src/pages/teleport/swap/utils.ts
cyb/src/features/studio/utils/utils.ts
cyb/src/pages/robot/Brain/utils.ts
cyb/src/services/backend/services/sync/utils.ts
pussy-ts/src/services/backend/services/sync/utils.ts
cyb/src/pages/teleport/components/Inputs/utils.ts
pussy-ts/src/services/backend/services/indexer/utils.ts
pussy-ts/src/services/backend/services/lcd/utils.ts
pussy-ts/src/pages/teleport/components/Inputs/utils.ts
cyb/src/features/studio/components/Editor/utils/utils.ts
cyb/src/pages/robot/_refactor/account/tabs/feeds/utils.ts

Neighbours