Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: integrate authz with staking and overview (backport #1092) #1107

Open
wants to merge 1 commit into
base: release/v2.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import { RootState } from '@/store/store';
import { CircularProgress, Tooltip } from '@mui/material';
import { setError } from '@/store/features/common/commonSlice';
import { capitalize } from 'lodash';
import useGetChainInfo from '@/custom-hooks/useGetChainInfo';
import { DelegationsPairs } from '@/types/distribution';
import useAuthzStakingExecHelper from '@/custom-hooks/useAuthzStakingExecHelper';

const Asset = ({
asset,
Expand All @@ -27,11 +30,38 @@ const Asset = ({
(state: RootState) =>
state.staking.chains[asset.chainID]?.reStakeTxStatus || TxStatus.IDLE
);
const authzRewards = useAppSelector(
(state) => state.distribution.authzChains
);
const isAuthzMode = useAppSelector((state) => state.authz.authzModeEnabled);
const authzAddress = useAppSelector((state) => state.authz.authzAddress);
const { getChainInfo } = useGetChainInfo();

const dispatch = useAppDispatch();
const { txWithdrawAllRewardsInputs, txRestakeInputs } = useGetTxInputs();
const { txWithdrawAllRewardsInputs, txRestakeInputs, txAuthzRestakeMsgs } =
useGetTxInputs();
const { txAuthzClaim, txAuthzRestake } = useAuthzStakingExecHelper();

const claim = (chainID: string) => {
if (isAuthzMode) {
const { address } = getChainInfo(chainID);
const pairs: DelegationsPairs[] = (
authzRewards[chainID]?.delegatorRewards?.list || []
).map((reward) => {
const pair = {
delegator: authzAddress,
validator: reward.validator_address,
};
return pair;
});
txAuthzClaim({
grantee: address,
granter: authzAddress,
pairs: pairs,
chainID: chainID,
});
return;
}
if (txClaimStatus === TxStatus.PENDING) {
dispatch(
setError({
Expand All @@ -58,6 +88,17 @@ const Asset = ({
};

const claimAndStake = (chainID: string) => {
if (isAuthzMode) {
const { address } = getChainInfo(chainID);
const msgs = txAuthzRestakeMsgs(chainID);
txAuthzRestake({
grantee: address,
granter: authzAddress,
msgs: msgs,
chainID: chainID,
});
return;
}
if (txRestakeStatus === TxStatus.PENDING) {
dispatch(
setError({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,37 @@ import { CircularProgress } from '@mui/material';
import NoAssets from '@/components/illustrations/NoAssets';

const AssetsTable = ({ chainIDs }: { chainIDs: string[] }) => {
const [sortedAssets] = useSortedAssets(chainIDs, {
const isAuthzMode = useAppSelector((state) => state.authz.authzModeEnabled);
const [sortedAssets, authzSortedAssets] = useSortedAssets(chainIDs, {
showAvailable: true,
showRewards: true,
showStaked: true,
});

const assets = isAuthzMode ? authzSortedAssets : sortedAssets;

const balancesLoading = useAppSelector(
(state) => state.bank.balancesLoading > 0
);
const delegationsLoading = useAppSelector(
(state) => state.staking.delegationsLoading > 0
);
const authzBalanceLoading = useAppSelector(
(state) => state.bank.authz.balancesLoading > 0
);
const authzDelegationsLoading = useAppSelector(
(state) => state.staking.authz.delegationsLoading > 0
);

const loading = !isAuthzMode && (balancesLoading || delegationsLoading);
const authzLoading =
isAuthzMode && (authzBalanceLoading || authzDelegationsLoading);

return (
<div className="flex flex-col flex-1 overflow-y-scroll">
<div className="assets-table bg-[#1a1a1b] px-8 py-8">
<div className="flex flex-col flex-1">
{sortedAssets.length ? (
{assets.length ? (
<div className="flex-1">
<table className="w-full text-sm leading-normal">
<thead className="border-b-[0.5px] border-[#B0B0B033] relative">
Expand Down Expand Up @@ -60,7 +74,7 @@ const AssetsTable = ({ chainIDs }: { chainIDs: string[] }) => {
</tr>
</thead>
<tbody className="flex-1">
{sortedAssets.map((asset) => (
{assets.map((asset) => (
<Asset
asset={asset}
key={asset.chainID + asset.denom}
Expand All @@ -72,7 +86,7 @@ const AssetsTable = ({ chainIDs }: { chainIDs: string[] }) => {
</div>
) : (
<div className="w-full flex flex-col flex-1 items-center justify-center text-white">
{balancesLoading || delegationsLoading ? (
{loading || authzLoading ? (
<CircularProgress size={32} />
) : (
<NoAssets />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useAppSelector } from '@/custom-hooks/StateHooks';
import { RootState } from '@/store/store';
import { useRouter } from 'next/navigation';
import NoTransactions from '@/components/illustrations/NoTransactions';
import useGetAuthzAssetsAmount from '../../../../custom-hooks/useGetAuthzAssetsAmount';

const History = ({ chainIDs }: { chainIDs: string[] }) => {
return (
Expand All @@ -32,6 +33,7 @@ export default History;
const Balance = ({ chainIDs }: { chainIDs: string[] }) => {
const router = useRouter();
const nameToChainIDs = useAppSelector((state) => state.wallet.nameToChainIDs);
const isAuthzMode = useAppSelector((state) => state.authz.authzModeEnabled);
const getPath = (chainIDs: string[], module: string) => {
if (chainIDs.length !== 1) {
return '/' + module;
Expand All @@ -42,7 +44,14 @@ const Balance = ({ chainIDs }: { chainIDs: string[] }) => {
});
return '/' + module + '/' + curChainName;
};
const [staked, available, rewards] = useGetAssetsAmount(chainIDs);

const [myStaked, myAvailable, myRewards] = useGetAssetsAmount(chainIDs);
const [authzStaked, authzAvailable, authzRewards] =
useGetAuthzAssetsAmount(chainIDs);
const staked = isAuthzMode ? authzStaked : myStaked;
const available = isAuthzMode ? authzAvailable : myAvailable;
const rewards = isAuthzMode ? authzRewards : myRewards;

return (
<div>
<div className="text-white text-center mt-10 mb-6">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,15 @@ import AssetsTable from './AssetsTable';
import AccountSummery from './AccountSummary';
import { getAccountInfo } from '@/store/features/auth/authSlice';
import { getDelegatorTotalRewards } from '@/store/features/distribution/distributionSlice';
import useInitAuthzForOverview from '@/custom-hooks/useInitAuthzForOverview';
import AuthzToast from '@/components/AuthzToast';

const OverviewPage = ({ chainIDs }: { chainIDs: string[] }) => {
const dispatch = useAppDispatch();
const networks = useAppSelector((state: RootState) => state.wallet.networks);
const isAuthzMode = useAppSelector((state) => state.authz.authzModeEnabled);

useInitAuthzForOverview(chainIDs);
useEffect(() => {
chainIDs.forEach((chainID) => {
const allChainInfo = networks[chainID];
Expand Down Expand Up @@ -66,8 +70,17 @@ const OverviewPage = ({ chainIDs }: { chainIDs: string[] }) => {
<div className="w-full flex justify-between">
<div className="flex flex-col w-full px-10 py-6 space-y-6 min-h-screen max-h-screen">
<TopNav />
{isAuthzMode && (
<div>
<div className="h-4"></div>
<AuthzToast chainIDs={chainIDs} margins="" />
<div className="h-4"></div>
</div>
)}
<WalletSummery chainIDs={chainIDs} />
{chainIDs.length === 1 && <AccountSummery chainID={chainIDs[0]} />}
{!isAuthzMode && chainIDs.length === 1 && (
<AccountSummery chainID={chainIDs[0]} />
)}
<PageAd />
<div className="flex items-center min-h-[36px] h-8">
<h2 className="text-xl not-italic font-normal leading-[normal]">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,19 @@ import {
resetError,
resetTxAndHash,
} from '@/store/features/common/commonSlice';
<<<<<<< HEAD
=======
import { resetState as bankReset } from '@/store/features/bank/bankSlice';
import { resetState as rewardsReset } from '@/store/features/distribution/distributionSlice';
import { resetCompleteState as stakingReset } from '@/store/features/staking/stakeSlice';
import { resetState as authzReset } from '@/store/features/authz/authzSlice';
import useAuthzGrants from '@/custom-hooks/useAuthzGrants';

>>>>>>> a885705 (feat: integrate authz with staking and overview (#1092))
const Profile = () => {
const profileName = useAppSelector((state) => state.wallet.name);
const dispatch = useAppDispatch();
const { disableAuthzMode } = useAuthzGrants();

return (
<div className="flex items-center gap-1">
Expand All @@ -34,6 +44,14 @@ const Profile = () => {
dispatch(resetWallet());
dispatch(resetError());
dispatch(resetTxAndHash());
<<<<<<< HEAD
=======
dispatch(bankReset());
dispatch(rewardsReset());
dispatch(stakingReset());
dispatch(authzReset());
disableAuthzMode();
>>>>>>> a885705 (feat: integrate authz with staking and overview (#1092))
logout();
}}
className="cursor-pointer"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
import { useAppSelector } from '@/custom-hooks/StateHooks';
import useGetAssetsAmount from '@/custom-hooks/useGetAssetsAmount';
import { formatDollarAmount } from '@/utils/util';
import Image from 'next/image';
import React from 'react';
import useGetAuthzAssetsAmount from '../../../../custom-hooks/useGetAuthzAssetsAmount';
type AssetSummary = { icon: string; alt: string; type: string; amount: string };

const WalletSummery = ({ chainIDs }: { chainIDs: string[] }) => {
const [stakedAmount, availableAmount, rewardsAmount] =
useGetAssetsAmount(chainIDs);
const isAuthzMode = useAppSelector((state) => state.authz.authzModeEnabled);
const [myStaked, myAvailable, myRewards] = useGetAssetsAmount(chainIDs);
const [authzStaked, authzAvailable, authzRewards] =
useGetAuthzAssetsAmount(chainIDs);
const stakedAmount = isAuthzMode ? authzStaked : myStaked;
const availableAmount = isAuthzMode ? authzAvailable : myAvailable;
const rewardsAmount = isAuthzMode ? authzRewards : myRewards;

const available = formatDollarAmount(availableAmount);
const staked = formatDollarAmount(stakedAmount);
const rewards = formatDollarAmount(rewardsAmount);
Expand Down
13 changes: 12 additions & 1 deletion frontend/src/app/(routes)/governance/DepositPopup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,18 @@ const DepositPopup = ({
const handleDeposit = (data: { amount: number }) => {
const { aminoConfig, prefix, rest, feeAmount, address, rpc, minimalDenom } =
getVoteTxInputs(chainID);
console.log(data);

if (isAuthzMode) {
txAuthzDeposit({
grantee: address,
proposalId: proposalId,
amount: Number(data.amount) * 10 ** currency.coinDecimals,
granter: authzGranter,
chainID: chainID,
metaData: '',
});
return;
}

dispatch(
txDeposit({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import DialogRedelegate from './DialogRedelegate';
import useGetChainInfo from '@/custom-hooks/useGetChainInfo';
import { parseDenomAmount } from '@/utils/util';
import { TxStatus } from '@/types/enums';
import useAuthzStakingExecHelper from '@/custom-hooks/useAuthzStakingExecHelper';

const ChainDelegations = ({
chainID,
Expand All @@ -38,6 +39,8 @@ const ChainDelegations = ({
const router = useRouter();
const dispatch = useAppDispatch();
const { getChainInfo } = useGetChainInfo();
const { txAuthzDelegate, txAuthzReDelegate, txAuthzUnDelegate } =
useAuthzStakingExecHelper();

const networks = useAppSelector((state: RootState) => state.wallet.networks);
const networkLogo = networks[chainID]?.network.logos.menu;
Expand All @@ -55,6 +58,8 @@ const ChainDelegations = ({
const stakingParams = useAppSelector(
(state: RootState) => state.staking.chains[chainID]?.params
);
const authzAddress = useAppSelector((state) => state.authz.authzAddress);
const isAuthzMode = useAppSelector((state) => state.authz.authzModeEnabled);

const [availableBalance, setAvailableBalance] = useState(0);
const [delegateOpen, setDelegateOpen] = useState(false);
Expand Down Expand Up @@ -108,9 +113,21 @@ const ChainDelegations = ({
);

const onDelegateTx = (data: DelegateTxInputs) => {
const basicChainInfo = getChainInfo(chainID);
if (isAuthzMode) {
txAuthzDelegate({
grantee: address,
granter: authzAddress,
validator: data.validator,
amount: data.amount * 10 ** currency.coinDecimals,
denom: currency.coinMinimalDenom,
chainID: basicChainInfo.chainID,
});
return;
}
dispatch(
txDelegate({
basicChainInfo: getChainInfo(chainID),
basicChainInfo: basicChainInfo,
delegator: address,
validator: data.validator,
amount: data.amount * 10 ** currency.coinDecimals,
Expand All @@ -122,6 +139,18 @@ const ChainDelegations = ({
};

const onUndelegateTx = (data: UndelegateTxInputs) => {
const basicChainInfo = getChainInfo(chainID);
if (isAuthzMode) {
txAuthzUnDelegate({
grantee: address,
granter: authzAddress,
validator: data.validator,
amount: data.amount * 10 ** currency.coinDecimals,
denom: currency.coinMinimalDenom,
chainID: basicChainInfo.chainID,
});
return;
}
dispatch(
txUnDelegate({
basicChainInfo: getChainInfo(chainID),
Expand All @@ -136,6 +165,19 @@ const ChainDelegations = ({
};

const onRedelegateTx = (data: RedelegateTxInputs) => {
const basicChainInfo = getChainInfo(chainID);
if (isAuthzMode) {
txAuthzReDelegate({
grantee: address,
granter: authzAddress,
srcValidator: data.src,
validator: data.dest,
amount: data.amount * 10 ** currency.coinDecimals,
denom: currency.coinMinimalDenom,
chainID: basicChainInfo.chainID,
});
return;
}
dispatch(
txReDelegate({
basicChainInfo: getChainInfo(chainID),
Expand Down
Loading
Loading