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

APT-1608: Claiming implemented #14

Merged
merged 2 commits into from
Dec 12, 2024
Merged
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
4 changes: 2 additions & 2 deletions src/components/stakingPoolDetailsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,14 @@ const StakingPoolDetailsView: React.FC<StakingPoolDetailsViewProps> = ({
const pendingUnstakesValue = userUnstakingPoolData?.filter(
(item) => item.availableAt > DateTime.now()
).reduce(
(acc, item) => acc + item.unstakingTokenAmount,
(acc, item) => acc + item.zilAmount,
0n
);

const availableToClaim = userUnstakingPoolData?.filter(
(item) => item.availableAt <= DateTime.now()
).reduce(
(acc, item) => acc + item.unstakingTokenAmount,
(acc, item) => acc + item.zilAmount,
0n
);

Expand Down
35 changes: 28 additions & 7 deletions src/components/withdrawUnstakedZilPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { AppConfigStorage } from "@/contexts/appConfigStorage";
import { StakingOperations } from "@/contexts/stakingOperations";
import { convertTokenToZil, getHumanFormDuration } from "@/misc/formatting";
import { formatAddress, getHumanFormDuration, getTxExplorerUrl } from "@/misc/formatting";
import { StakingPool } from "@/misc/stakingPoolsConfig";
import { UserUnstakingPoolData } from "@/misc/walletsConfig";
import { Button } from "antd";
import { DateTime } from "luxon";
import Link from "next/link";
import { formatUnits } from "viem";

interface WithdrawZilPanelProps {
stakingPoolData: StakingPool;
Expand All @@ -15,9 +18,15 @@ const WithdrawZilPanel: React.FC<WithdrawZilPanelProps> = ({
stakingPoolData,
}) => {
const {
claim
claim,
isClaimingInProgress,
claimCallTxHash,
} = StakingOperations.useContainer();

const {
appConfig
} = AppConfigStorage.useContainer();

const pendingUnstake = userUnstakingPoolData?.filter(
(claim) => claim.availableAt > DateTime.now()
).toSorted((claimA, claimB) => claimA.availableAt.diff(claimB.availableAt).milliseconds)
Expand All @@ -28,6 +37,17 @@ const WithdrawZilPanel: React.FC<WithdrawZilPanelProps> = ({

return (
<div>

{
claimCallTxHash !== undefined && (
<div className="text-center gradient-bg-1 py-2">
<Link rel="noopener noreferrer" target="_blank" href={getTxExplorerUrl(claimCallTxHash, appConfig.chainId)} passHref={true}>
Last staking transaction: {formatAddress(claimCallTxHash)}
</Link>
</div>
)
}

{
!!availableUnstake?.length ? (
availableUnstake.map(
Expand All @@ -36,12 +56,13 @@ const WithdrawZilPanel: React.FC<WithdrawZilPanelProps> = ({
<div className="flex justify-between items-center">
{
stakingPoolData.data ? <div>
~{convertTokenToZil(item.unstakingTokenAmount, stakingPoolData.data.zilToTokenRate)} ZIL
{parseFloat(formatUnits(item.zilAmount, 18)).toFixed(3)} ZIL
</div> : <div className="w-[4em] h-[1em] animated-gradient" />
}
<Button
className='btn-primary-cyan text-2xl'
onClick={() => claim(item.unstakingTokenAmount)}
onClick={() => claim(item.address)}
loading={isClaimingInProgress}
>
Claim
</Button>
Expand All @@ -60,7 +81,7 @@ const WithdrawZilPanel: React.FC<WithdrawZilPanelProps> = ({
</div>
{
stakingPoolData.data ? <div>
~{convertTokenToZil(pendingUnstake[0].unstakingTokenAmount, stakingPoolData.data.zilToTokenRate)} ZIL
{parseFloat(formatUnits(pendingUnstake[0].zilAmount, 18)).toFixed(3)} ZIL
</div> : <div className="w-[4em] h-[1em] animated-gradient" />
}
</div>
Expand All @@ -76,7 +97,7 @@ const WithdrawZilPanel: React.FC<WithdrawZilPanelProps> = ({
!!pendingUnstake?.length && (
<div className="mt-4">
<div className="font-bold text-gray-500">
Pending requests
All pending requests
</div>

{
Expand All @@ -85,7 +106,7 @@ const WithdrawZilPanel: React.FC<WithdrawZilPanelProps> = ({

{
stakingPoolData.data ? <div>
{claim.unstakingTokenAmount} {stakingPoolData.definition.tokenSymbol} ~= {convertTokenToZil(claim.unstakingTokenAmount, stakingPoolData.data.zilToTokenRate)} ZILs
{parseFloat(formatUnits(claim.zilAmount, 18)).toFixed(3)} ZIL
</div> : <div className="w-[4em] h-[1em] animated-gradient" />
}
<div>
Expand Down
34 changes: 22 additions & 12 deletions src/components/withdrawZilView.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { StakingOperations } from "@/contexts/stakingOperations";
import { StakingPoolsStorage } from "@/contexts/stakingPoolsStorage";
import { convertTokenToZil, formatUnitsToHumanReadable } from "@/misc/formatting";
import { convertTokenToZil, formatUnitsToHumanReadable, getHumanFormDuration } from "@/misc/formatting";
import { Button } from "antd";
import Image from 'next/image';

const WithdrawZilView: React.FC = () => {
const {
availableForUnstaking,
pendingUnstaking,
selectStakingPoolForView,
isUnstakingDataLoading
} = StakingPoolsStorage.useContainer();

const {
Expand Down Expand Up @@ -61,7 +63,7 @@ const WithdrawZilView: React.FC = () => {
item.stakingPool.data ? <>
{
formatUnitsToHumanReadable(
convertTokenToZil(item.unstakeInfo.unstakingTokenAmount, item.stakingPool.data!.zilToTokenRate),
convertTokenToZil(item.unstakeInfo.zilAmount, item.stakingPool.data!.zilToTokenRate),
18
)
} ZIL
Expand All @@ -73,34 +75,42 @@ const WithdrawZilView: React.FC = () => {
}

</div>
<div className="body1-s max-lg:mr-2.5 lg:ml-2.5 max-lg:order-1">{item.unstakeInfo.unstakingTokenAmount} {item.stakingPool.definition.tokenSymbol}</div>
<div className="body1-s max-lg:mr-2.5 lg:ml-2.5 max-lg:order-1">{item.unstakeInfo.zilAmount} {item.stakingPool.definition.tokenSymbol}</div>
</div>
</div>
<div className="max-lg:gap-2.5 max-lg:flex lg:w-1/3 lg:max-w-[218px]">
<div className="max-lg:w-1/2">
<Button
className="btn-primary-gradient-aqua"
disabled={!item.available}
onClick={() => claim(item.unstakeInfo.unstakingTokenAmount)}
onClick={() => claim(item.unstakeInfo.address)}
>
{item.available ? 'Claim' : item.unstakeInfo.availableAt.diffNow("days").days.toFixed(0) + ' days left'}
{item.available ? 'Claim' : getHumanFormDuration(item.unstakeInfo.availableAt) + ' left'}
</Button>
</div>
<div className="max-lg:w-1/2 lg:mt-2.5">
<Button
className="btn-primary-white2"
>
View
</Button></div>
<Button
className="btn-primary-white2"
onClick={() => selectStakingPoolForView(item.stakingPool.definition.id)}
>
View
</Button>
</div>
</div>

</div>
))
}
</div>
) : (
<div className="text-center">
WoW such empty
<div className="text-center w-full">
{
isUnstakingDataLoading ? (
<div className="animated-gradient h-[2em] w-full"></div>
) : (
<span>WoW such empty</span>
)
}
</div>
)
}
Expand Down
83 changes: 77 additions & 6 deletions src/contexts/stakingOperations.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { notification } from "antd";
import { useEffect, useState } from "react";
import { useWaitForTransactionReceipt, useWriteContract } from "wagmi";
import { useWaitForTransactionReceipt } from "wagmi";
import { createContainer } from "./context";
import { WalletConnector } from "./walletConnector";
import { StakingPoolsStorage } from "./stakingPoolsStorage";
Expand Down Expand Up @@ -125,6 +125,14 @@ const useStakingOperations = () => {
(txHash) => {
setUnstakingCallTxHash(txHash);
}
).catch(
(error) => {
notification.error({
message: "Unstaking failed",
description: error?.message || "There was an error while unstaking ZIL",
placement: "topRight"
});
}
)
}
}
Expand Down Expand Up @@ -153,11 +161,66 @@ const useStakingOperations = () => {
* CLAIMING
*/

const claim = (zilToStake: bigint) => {
setDummyWalletPopupContent(`Now User gonna approve the wallet transaction for withdrawing/claiming ${zilToStake} ZIL`);
setIsDummyWalletPopupOpen(true);
const [claimCallTxHash, setClaimCallTxHash] = useState<Address | undefined>(undefined);

const {
isLoading: isClaimingInProgress,
error: claimContractCallError,
status: claimCallReceiptStatus,
} = useWaitForTransactionReceipt({
hash: claimCallTxHash,
})

const claim = (delegatorAddress: string) => {
if (isDummyWalletConnected) {
setDummyWalletPopupContent(`Now User gonna approve the wallet transaction for withdrawing/claiming ZIL`);
setIsDummyWalletPopupOpen(true);
setClaimCallTxHash("0x1234567890234567890234567890234567890" as Address);
} else {
writeContract(
wagmiConfig,
{
address: delegatorAddress as Address,
abi: delegatorAbi,
functionName: 'claim',
args: []
}
).then(
(txHash) => {
setClaimCallTxHash(txHash);
}
).catch(
(error) => {
notification.error({
message: "Claiming failed",
description: error?.message || "There was an error while claiming ZIL",
placement: "topRight"
});
}
)
}
}

useEffect(
() => {
if (claimCallReceiptStatus === "success") {
notification.success({
message: "Claiming successful",
description: `You have successfully claimed ZIL`,
placement: "topRight"
});
reloadUserStakingPoolsData();
updateWalletBalance();
} else if (claimCallReceiptStatus === "error") {
notification.error({
message: "Claiming failed",
description: `There was an error while claiming ZIL`,
placement: "topRight"
});
}
}, [claimCallReceiptStatus]
)

/**
* OTHER
*/
Expand All @@ -166,6 +229,7 @@ const useStakingOperations = () => {
function clearStateOnDelegatorChange() {
setStakingCallTxHash(undefined);
setUnstakingCallTxHash(undefined);
setClaimCallTxHash(undefined);
},
[stakingPoolId]
)
Expand All @@ -174,14 +238,21 @@ const useStakingOperations = () => {
isDummyWalletPopupOpen,
dummyWalletPopupContent,
setIsDummyWalletPopupOpen,

stake,
unstake,
claim,
isStakingInProgress,
stakingCallTxHash,
stakeContractCallError,

unstake,
isUnstakingInProgress,
unstakingCallTxHash,
unstakeContractCallError,

claim,
isClaimingInProgress,
claimCallTxHash,
claimContractCallError,
}

};
Expand Down
9 changes: 8 additions & 1 deletion src/contexts/stakingPoolsStorage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,20 @@ const useStakingPoolsStorage = () => {
const [stakingPoolForStaking, setStakingPoolForStaking] = useState<StakingPool | null>(null);
const [stakingPoolForUnstaking, setStakingPoolForUnstaking] = useState<StakingPool | null>(null);

const [isUnstakingDataLoading, setIsUnstakingDataLoading] = useState(false);

const reloadUserStakingPoolsData = () => {
if (!walletAddress) {
setUserStakingPoolsData([]);
return
}

getWalletStakingData(walletAddress, appConfig!.chainId).then(setUserStakingPoolsData).catch(console.error);
getWalletUnstakingData(walletAddress).then(setUserUnstakesData).catch(console.error);
setIsUnstakingDataLoading(true);
getWalletUnstakingData(walletAddress, appConfig!.chainId)
.then(setUserUnstakesData)
.catch(console.error)
.finally(() => setIsUnstakingDataLoading(false));
}

useEffect(
Expand Down Expand Up @@ -192,6 +198,7 @@ const useStakingPoolsStorage = () => {
availableForUnstaking,
pendingUnstaking,
reloadUserStakingPoolsData,
isUnstakingDataLoading,
};
};

Expand Down
Loading