/ src / services / WalletBalanceService.ts
WalletBalanceService.ts
  1  import { ChainId, WalletBalanceProvider } from '@aave/contract-helpers';
  2  import { normalize } from '@aave/math-utils';
  3  import { Provider } from '@ethersproject/providers';
  4  import { formatUnits } from 'ethers/lib/utils';
  5  import { governanceV3Config } from 'src/ui-config/governanceConfig';
  6  import { MarketDataType } from 'src/ui-config/marketsConfig';
  7  
  8  export interface GovernanceTokensBalance {
  9    aave: string;
 10    stkAave: string;
 11    aAave: string;
 12  }
 13  
 14  export type UserPoolTokensBalances = {
 15    address: string;
 16    amount: string;
 17  };
 18  
 19  export class WalletBalanceService {
 20    constructor(private readonly getProvider: (chainId: number) => Provider) {}
 21  
 22    private getWalletBalanceService(chainId: ChainId, walletBalanceProviderAddress: string) {
 23      const provider = this.getProvider(chainId);
 24      return new WalletBalanceProvider({
 25        walletBalanceProviderAddress,
 26        provider,
 27      });
 28    }
 29  
 30    async getGovernanceTokensBalance(
 31      chainId: ChainId,
 32      walletBalanceProviderAddress: string,
 33      user: string,
 34      blockHash?: string
 35    ): Promise<GovernanceTokensBalance> {
 36      const walletBalanceService = this.getWalletBalanceService(
 37        chainId,
 38        walletBalanceProviderAddress
 39      );
 40  
 41      const options: { blockTag?: string } = {};
 42      if (blockHash) {
 43        options.blockTag = blockHash;
 44      }
 45      const balances = await walletBalanceService.batchBalanceOf(
 46        [user],
 47        [
 48          governanceV3Config.votingAssets.aaveTokenAddress,
 49          governanceV3Config.votingAssets.aAaveTokenAddress,
 50          governanceV3Config.votingAssets.stkAaveTokenAddress,
 51        ],
 52        options
 53      );
 54      return {
 55        aave: normalize(balances[0].toString(), 18),
 56        aAave: normalize(balances[1].toString(), 18),
 57        stkAave: normalize(balances[2].toString(), 18),
 58      };
 59    }
 60  
 61    async getPoolTokensBalances(
 62      marketData: MarketDataType,
 63      user: string
 64    ): Promise<UserPoolTokensBalances[]> {
 65      const walletBalanceService = this.getWalletBalanceService(
 66        marketData.chainId,
 67        marketData.addresses.WALLET_BALANCE_PROVIDER
 68      );
 69      const { 0: tokenAddresses, 1: balances } =
 70        await walletBalanceService.getUserWalletBalancesForLendingPoolProvider(
 71          user,
 72          marketData.addresses.LENDING_POOL_ADDRESS_PROVIDER
 73        );
 74      const mappedBalances = tokenAddresses.map((address, ix) => ({
 75        address: address.toLowerCase(),
 76        amount: balances[ix].toString(),
 77      }));
 78      return mappedBalances;
 79    }
 80  
 81    async getGhoBridgeBalancesTokenBalances(
 82      marketData: MarketDataType,
 83      user: string
 84    ): Promise<{
 85      bridgeTokenBalance: string;
 86      bridgeTokenBalanceFormatted: string;
 87      address: string;
 88    }> {
 89      const walletBalanceService = this.getWalletBalanceService(
 90        marketData.chainId,
 91        marketData.addresses.WALLET_BALANCE_PROVIDER
 92      );
 93  
 94      const balances = await walletBalanceService.batchBalanceOf(
 95        [user],
 96        [marketData.addresses.GHO_TOKEN_ADDRESS?.toLowerCase() as string] // GHO UNDERLYING
 97      );
 98  
 99      return {
100        bridgeTokenBalance: balances[0].toString(),
101        bridgeTokenBalanceFormatted: formatUnits(balances[0].toString(), 18),
102        address: marketData.addresses.GHO_TOKEN_ADDRESS as string,
103      };
104    }
105  }