import { decode } from '@findeth/abi'; import { BATCH_SIZE, CONTRACT_ADDRESS } from './constants'; import { call, ProviderLike } from './providers'; import { BalanceMap, EthScanOptions } from './types'; import { batch } from './utils'; /** * Get a balance map from an array of addresses and an array of balances. * * @param {string[]} addresses * @param {bigint[]} balances * @return {BalanceMap} */ export const toBalanceMap = (addresses: string[] | number[], balances: Array): BalanceMap => { return balances.reduce((current, next, index) => { return { ...current, [addresses[index]]: next }; }, {}); }; /** * Get a nested balance map from an array of addresses, token addresses, and balances. * * @param {string[]} addresses * @param {bigint[]} tokenAddresses * @param {BalanceMap} balances */ export const toNestedBalanceMap = ( addresses: string[], tokenAddresses: string[] | number[], balances: Array> ): BalanceMap => { return balances.reduce>((current, next, index) => { return { ...current, [addresses[index]]: toBalanceMap(tokenAddresses, next) }; }, {}); }; /** * Low level API function to send a contract call that returns a single uint256 array. * * @param {ProviderLike} provider * @param {string[]} addresses * @param {Function} encodeData * @param {EthScanOptions} options * @return {Promise} */ export const callSingle = async ( provider: ProviderLike, addresses: string[] | number[], encodeData: (addresses: string[] | number[]) => string, options?: EthScanOptions ): Promise => { const contractAddress = options?.contractAddress ?? CONTRACT_ADDRESS; const batchSize = options?.batchSize ?? BATCH_SIZE; const result = await batch( async (batchedAddresses: string[] | number[]) => { const data = encodeData(batchedAddresses); return decode(['uint256[]'], await call(provider, contractAddress, data))[0]; }, batchSize, addresses ); return toBalanceMap(addresses, result); }; export const callMultiple = async ( provider: ProviderLike, addresses: string[], otherAddresses: string[], encodeData: (addresses: string[] | number[], otherAddresses: string[]) => string, options?: EthScanOptions ): Promise> => { const contractAddress = options?.contractAddress ?? CONTRACT_ADDRESS; const batchSize = options?.batchSize ?? BATCH_SIZE; const result = await batch( async (batchedAddresses: string[] | number[]) => { const data = encodeData(batchedAddresses, otherAddresses); return decode(['uint256[][]'], await call(provider, contractAddress, data))[0] as Array>; }, batchSize, addresses ); return toNestedBalanceMap(addresses, otherAddresses, result); };