vega-frontend-monorepo/apps/token/src/hooks/use-get-association-breakdown.ts
Matthew Russell e463bbe238
feat(#495): get smart contracts addresses from network params
* feat: unhardcode contract addresses

* fix: linting and tests

* feat: switch contract usage in token app to use unhardcoded addresses

* chore: remove other usage of hard coded contract addresses

* feat: convert contracts to classes, update claim contract to fix circular dependency

* feat: add hard coded contract addresses to contracts page

* fix: misc tidy up

* chore: rename ethers big num conversion func

* fix: remove pending transactions modal

* chore: add single toBigNum function that can accept number string or EthersBignNumber

* chore: delete unused tranche helpers and decimals functions from smart contracts lib

* feat: add faucetable token class

* fix: reset tx state after early exit from approve tx

* feat: re add transaction modal using zustand store

* fix: loader colors for eth wallet

* fix: pass ethereum config to gurantee existence before tx execution

* chore: lint smart contracts lib

* chore: fix web3container to use children and not render prop

* chore: lint

* fix: use background to mock ethereum wallet to avoid mocking globally for every test

* chore: move web3 mock to common steps and call from withdrawals feature tests
2022-06-07 15:08:40 -07:00

99 lines
2.8 KiB
TypeScript

import React from 'react';
import type { ethers } from 'ethers';
import * as Sentry from '@sentry/react';
import { addDecimal } from '@vegaprotocol/react-helpers';
import type {
StakingBridge,
TokenVesting,
} from '@vegaprotocol/smart-contracts';
import {
AppStateActionType,
useAppState,
} from '../contexts/app-state/app-state-context';
import BigNumber from 'bignumber.js';
export function useGetAssociationBreakdown(
ethAddress: string,
staking: StakingBridge,
vesting: TokenVesting
): () => Promise<void> {
const {
appState: { decimals },
appDispatch,
} = useAppState();
const getAssociationBreakdown = React.useCallback(async () => {
try {
const [stakingAssociations, vestingAssociations] = await Promise.all([
userTotalStakedByVegaKey(staking, ethAddress, decimals),
userTotalStakedByVegaKey(vesting, ethAddress, decimals),
]);
appDispatch({
type: AppStateActionType.SET_ASSOCIATION_BREAKDOWN,
breakdown: {
stakingAssociations,
vestingAssociations,
},
});
} catch (err) {
Sentry.captureException(err);
}
}, [ethAddress, staking, vesting, decimals, appDispatch]);
return getAssociationBreakdown;
}
async function userTotalStakedByVegaKey(
contract: StakingBridge | TokenVesting,
ethereumAccount: string,
decimals: number
): Promise<{ [vegaKey: string]: BigNumber }> {
const addFilter = contract.contract.filters.Stake_Deposited(ethereumAccount);
const removeFilter = contract.contract.filters.Stake_Removed(ethereumAccount);
const addEvents = await contract.contract.queryFilter(addFilter);
const removeEvents = await contract.contract.queryFilter(removeFilter);
const res = combineStakeEventsByVegaKey(
[...addEvents, ...removeEvents],
decimals
);
return res;
}
function combineStakeEventsByVegaKey(
events: ethers.Event[],
decimals: number
): { [vegaKey: string]: BigNumber } {
const res = events.reduce((obj, e) => {
const vegaKey = e.args?.vega_public_key;
const amount = parseEventAmount(e, decimals);
const isDeposit = e.event === 'Stake_Deposited';
const isRemove = e.event === 'Stake_Removed';
if (!isDeposit && !isRemove) return obj;
if (Object.prototype.hasOwnProperty.call(obj, vegaKey)) {
if (isDeposit) {
obj[vegaKey] = obj[vegaKey].plus(amount);
} else {
obj[vegaKey] = obj[vegaKey].minus(amount);
}
} else {
if (isDeposit) {
obj[vegaKey] = amount;
} else {
obj[vegaKey] = new BigNumber(0);
}
}
return obj;
}, {} as { [vegaKey: string]: BigNumber });
return res;
}
function parseEventAmount(e: ethers.Event, decimals: number) {
const rawAmount = new BigNumber(e.args?.amount.toString() || 0);
return new BigNumber(addDecimal(rawAmount.toString(), decimals));
}