2022-04-20 19:37:44 +00:00
|
|
|
import React from 'react';
|
2022-06-07 22:08:40 +00:00
|
|
|
import type { ethers } from 'ethers';
|
2022-04-20 19:37:44 +00:00
|
|
|
import * as Sentry from '@sentry/react';
|
2022-06-07 22:08:40 +00:00
|
|
|
import { addDecimal } from '@vegaprotocol/react-helpers';
|
|
|
|
import type {
|
|
|
|
StakingBridge,
|
|
|
|
TokenVesting,
|
|
|
|
} from '@vegaprotocol/smart-contracts';
|
2022-04-20 19:37:44 +00:00
|
|
|
|
|
|
|
import {
|
|
|
|
AppStateActionType,
|
|
|
|
useAppState,
|
|
|
|
} from '../contexts/app-state/app-state-context';
|
2022-06-07 22:08:40 +00:00
|
|
|
import BigNumber from 'bignumber.js';
|
2022-04-20 19:37:44 +00:00
|
|
|
|
|
|
|
export function useGetAssociationBreakdown(
|
|
|
|
ethAddress: string,
|
2022-06-07 22:08:40 +00:00
|
|
|
staking: StakingBridge,
|
|
|
|
vesting: TokenVesting
|
2022-04-20 19:37:44 +00:00
|
|
|
): () => Promise<void> {
|
2022-06-07 22:08:40 +00:00
|
|
|
const {
|
|
|
|
appState: { decimals },
|
|
|
|
appDispatch,
|
|
|
|
} = useAppState();
|
2022-04-20 19:37:44 +00:00
|
|
|
|
|
|
|
const getAssociationBreakdown = React.useCallback(async () => {
|
|
|
|
try {
|
|
|
|
const [stakingAssociations, vestingAssociations] = await Promise.all([
|
2022-06-07 22:08:40 +00:00
|
|
|
userTotalStakedByVegaKey(staking, ethAddress, decimals),
|
|
|
|
userTotalStakedByVegaKey(vesting, ethAddress, decimals),
|
2022-04-20 19:37:44 +00:00
|
|
|
]);
|
|
|
|
|
|
|
|
appDispatch({
|
|
|
|
type: AppStateActionType.SET_ASSOCIATION_BREAKDOWN,
|
|
|
|
breakdown: {
|
|
|
|
stakingAssociations,
|
|
|
|
vestingAssociations,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
} catch (err) {
|
|
|
|
Sentry.captureException(err);
|
|
|
|
}
|
2022-06-07 22:08:40 +00:00
|
|
|
}, [ethAddress, staking, vesting, decimals, appDispatch]);
|
2022-04-20 19:37:44 +00:00
|
|
|
|
|
|
|
return getAssociationBreakdown;
|
|
|
|
}
|
2022-06-07 22:08:40 +00:00
|
|
|
|
|
|
|
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));
|
|
|
|
}
|