) => {
- const { value: inputValue } = e.target;
- const reg = /^-?\d*(\.\d*)?$/;
- if (
- reg.test(inputValue) ||
- inputValue === '' ||
- inputValue === '-'
- ) {
- setZilToStake(inputValue);
+ const { value: inputValue } = e.target
+ const reg = /^-?\d*(\.\d*)?$/
+ if (reg.test(inputValue) || inputValue === "" || inputValue === "-") {
+ setZilToStake(inputValue)
}
- };
+ }
const handleFocus = () => {
- if (zilToStake === '') onMinClick();
- };
+ if (zilToStake === "") onMinClick()
+ }
const handleBlur = () => {
- let valueTemp = zilToStake;
-
+ let valueTemp = zilToStake
+
if (
- zilToStake.charAt(zilToStake.length - 1) === '.' ||
- zilToStake === '-'
+ zilToStake.charAt(zilToStake.length - 1) === "." ||
+ zilToStake === "-"
) {
- valueTemp = zilToStake.slice(0, -1);
+ valueTemp = zilToStake.slice(0, -1)
}
- setZilToStake(valueTemp.replace(/0*(\d+)/, '$1'));
+ setZilToStake(valueTemp.replace(/0*(\d+)/, "$1"))
- if (zilToStake === '') onMinClick();
- };
+ if (zilToStake === "") onMinClick()
+ }
+
+ const zilToStakeNumber = parseFloat(zilToStake)
- const zilToStakeNumber = parseFloat(zilToStake);
-
- const zilInWei = parseEther(zilToStake);
- const zilToStakeOk = !isNaN(zilToStakeNumber) && zilToStakeNumber <= (zilAvailable || 0n);
- const canStake = stakingPoolForView?.stakingPool.data && zilToStakeNumber > 0 && zilToStakeNumber <= (zilAvailable || 0n);
+ const zilInWei = parseEther(zilToStake)
+ const zilToStakeOk =
+ !isNaN(zilToStakeNumber) && zilToStakeNumber <= (zilAvailable || 0n)
+ const canStake =
+ stakingPoolForView?.stakingPool.data &&
+ zilToStakeNumber > 0 &&
+ zilToStakeNumber <= (zilAvailable || 0n)
const onMinClick = () => {
- setZilToStake(`${formatUnits(stakingPoolForView?.stakingPool.definition.minimumStake || 0n, 18) }`)
+ setZilToStake(
+ `${formatUnits(stakingPoolForView?.stakingPool.definition.minimumStake || 0n, 18)}`
+ )
}
const onMaxClick = () => {
- setZilToStake(`${formatUnits(zilAvailable || 0n, 18) }`)
+ setZilToStake(`${formatUnits(zilAvailable || 0n, 18)}`)
}
-
return (
stakingPoolForView && (
@@ -87,35 +91,31 @@ const StakingCalculator: React.FC = () => {
{stakingPoolForView!.stakingPool.data ? (
<>
~
- {
- !isNaN(zilToStakeNumber) && !isNaN(stakingPoolForView.stakingPool.data
- .zilToTokenRate)
- ? convertZilValueInToken(zilToStakeNumber, stakingPoolForView.stakingPool.data
- .zilToTokenRate)
- : ""
- }
- {' '}
- {
- stakingPoolForView.stakingPool.definition
- .tokenSymbol
- }{' '}
+ {!isNaN(zilToStakeNumber) &&
+ !isNaN(stakingPoolForView.stakingPool.data.zilToTokenRate)
+ ? convertZilValueInToken(
+ zilToStakeNumber,
+ stakingPoolForView.stakingPool.data.zilToTokenRate
+ )
+ : ""}{" "}
+ {stakingPoolForView.stakingPool.definition.tokenSymbol}{" "}
~
@@ -150,7 +150,7 @@ const StakingCalculator: React.FC = () => {
- Commission Fee:{' '}
+ Commission Fee:{" "}
{stakingPoolForView!.stakingPool.data ? (
<>
{formatPercentage(
@@ -162,25 +162,30 @@ const StakingCalculator: React.FC = () => {
)}
- Max transaction cost: {zilToStake ? '0.01' : '0'}$
+ Max transaction cost: {zilToStake ? "0.01" : "0"}$
Rate
- {stakingPoolForView!.stakingPool.data && (
-
{`1 ZIL = ~${ stakingPoolForView.stakingPool.data.zilToTokenRate} ${stakingPoolForView.stakingPool.definition.tokenSymbol}`}
- )}
+ {stakingPoolForView!.stakingPool.data && (
+
{`1 ZIL = ~${stakingPoolForView.stakingPool.data.zilToTokenRate} ${stakingPoolForView.stakingPool.definition.tokenSymbol}`}
+ )}
-
- APR
-
+
+ APR
+
{stakingPoolForView!.stakingPool.data ? (
<>
- ~{formatPercentage(
- stakingPoolForView!.stakingPool.data.apr
- )}
+ ~
+ {formatPercentage(stakingPoolForView!.stakingPool.data.apr)}
>
) : (
@@ -195,31 +200,40 @@ const StakingCalculator: React.FC = () => {
size="large"
className="btn-primary-gradient-aqua-lg lg:btn-primary-gradient-aqua"
disabled={!canStake}
- onClick={() => stake(stakingPoolForView.stakingPool.definition.address, zilInWei)}
- loading={isStakingInProgress} >
+ onClick={() =>
+ stake(
+ stakingPoolForView.stakingPool.definition.address,
+ zilInWei
+ )
+ }
+ loading={isStakingInProgress}
+ >
STAKE
- {
- stakingCallTxHash !== undefined && (
-
-
- Last staking transaction: {formatAddress(stakingCallTxHash)}
-
-
- )
- }
+ {stakingCallTxHash !== undefined && (
+
+
+ Last staking transaction: {formatAddress(stakingCallTxHash)}
+
+
+ )}
{stakeContractCallError && (
{stakeContractCallError.message}
)}
- >
+ >
)
- );
-};
+ )
+}
-export default StakingCalculator;
\ No newline at end of file
+export default StakingCalculator
diff --git a/src/components/stakingPoolCard.tsx b/src/components/stakingPoolCard.tsx
index 1ae8a0f..2afcad3 100644
--- a/src/components/stakingPoolCard.tsx
+++ b/src/components/stakingPoolCard.tsx
@@ -1,17 +1,14 @@
-import {
- formatPercentage,
- formatUnitsToHumanReadable,
-} from '@/misc/formatting';
-import { StakingPool } from '@/misc/stakingPoolsConfig';
-import { UserStakingPoolData } from '@/misc/walletsConfig';
-import { Tooltip } from 'antd';
-import Image from 'next/image';
+import { formatPercentage, formatUnitsToHumanReadable } from "@/misc/formatting"
+import { StakingPool } from "@/misc/stakingPoolsConfig"
+import { UserStakingPoolData } from "@/misc/walletsConfig"
+import { Tooltip } from "antd"
+import Image from "next/image"
interface StakingPoolCardProps {
- stakingPoolData: StakingPool;
- userStakingPoolData?: UserStakingPoolData;
- isStakingPoolSelected?: boolean;
- onClick: () => void;
+ stakingPoolData: StakingPool
+ userStakingPoolData?: UserStakingPoolData
+ isStakingPoolSelected?: boolean
+ onClick: () => void
}
const StakingPoolCard: React.FC
= ({
@@ -24,16 +21,14 @@ const StakingPoolCard: React.FC = ({
= ({
= 50
- ? 'text-red2'
+ ? "text-red2"
: stakingPoolData.data.votingPower * 100 >= 30
- ? 'text-orange1'
- : ''
+ ? "text-orange1"
+ : ""
}`}
>
- VP{' '}
- {(
- stakingPoolData.data.votingPower * 100
- ).toPrecision(3)}
+ VP {(stakingPoolData.data.votingPower * 100).toPrecision(3)}
%
) : (
@@ -84,14 +76,9 @@ const StakingPoolCard: React.FC = ({
>
)}
- Commission{' '}
+ Commission{" "}
{stakingPoolData.data ? (
- <>
- {Math.floor(
- stakingPoolData.data.commission * 100
- )}
- %
- >
+ <>{Math.floor(stakingPoolData.data.commission * 100)}%>
) : (
)}
@@ -115,7 +102,7 @@ const StakingPoolCard: React.FC = ({
)}
-
+
{userStakingPoolData &&
userStakingPoolData.stakingTokenAmount ? (
@@ -130,9 +117,7 @@ const StakingPoolCard: React.FC = ({
-
)}
-
- {stakingPoolData.definition.tokenSymbol}
-
+
{stakingPoolData.definition.tokenSymbol}
@@ -155,7 +140,7 @@ const StakingPoolCard: React.FC = ({
- );
-};
+ )
+}
-export default StakingPoolCard;
+export default StakingPoolCard
diff --git a/src/components/stakingPoolDetailsView.tsx b/src/components/stakingPoolDetailsView.tsx
index b50a288..ff9d7dd 100644
--- a/src/components/stakingPoolDetailsView.tsx
+++ b/src/components/stakingPoolDetailsView.tsx
@@ -1,54 +1,46 @@
-import StakingCalculator from '@/components/stakingCalculator';
-import UnstakingCalculator from '@/components/unstakingCalculator';
-import WithdrawZilPanel from '@/components/withdrawUnstakedZilPanel';
-import { WalletConnector } from '@/contexts/walletConnector';
-import { getViemClient } from '@/misc/chainConfig';
-import {
- formatPercentage,
- formatUnitsToHumanReadable,
-} from '@/misc/formatting';
-import { StakingPool } from '@/misc/stakingPoolsConfig';
+import StakingCalculator from "@/components/stakingCalculator"
+import UnstakingCalculator from "@/components/unstakingCalculator"
+import WithdrawZilPanel from "@/components/withdrawUnstakedZilPanel"
+import { WalletConnector } from "@/contexts/walletConnector"
+import { getViemClient } from "@/misc/chainConfig"
+import { formatPercentage, formatUnitsToHumanReadable } from "@/misc/formatting"
+import { StakingPool } from "@/misc/stakingPoolsConfig"
import {
UserStakingPoolData,
UserUnstakingPoolData,
-} from '@/misc/walletsConfig';
-import { Button } from 'antd';
-import { DateTime } from 'luxon';
-import { useState } from 'react';
-import { useWatchAsset } from 'wagmi';
-import { useWalletClient } from 'wagmi';
-import Plus from '../assets/svgs/plus.svg'
-import Image from 'next/image';
+} from "@/misc/walletsConfig"
+import { Button } from "antd"
+import { DateTime } from "luxon"
+import { useState } from "react"
+import { useWatchAsset } from "wagmi"
+import { useWalletClient } from "wagmi"
+import Plus from "../assets/svgs/plus.svg"
+import Image from "next/image"
interface StakingPoolDetailsViewProps {
- stakingPoolData: StakingPool;
- userStakingPoolData?: UserStakingPoolData;
- userUnstakingPoolData?: Array;
- selectStakingPoolForStaking: (stakingPoolId: string) => void;
+ stakingPoolData: StakingPool
+ userStakingPoolData?: UserStakingPoolData
+ userUnstakingPoolData?: Array
+ selectStakingPoolForStaking: (stakingPoolId: string) => void
}
-const StakingPoolDetailsView: React.FC<
- StakingPoolDetailsViewProps
-> = ({
+const StakingPoolDetailsView: React.FC = ({
stakingPoolData,
userStakingPoolData,
userUnstakingPoolData,
}) => {
- const { zilAvailable } = WalletConnector.useContainer();
+ const { zilAvailable } = WalletConnector.useContainer()
- const [selectedPane, setSelectedPane] = useState('Stake');
+ const [selectedPane, setSelectedPane] = useState("Stake")
const colorInfoEntry = (title: string, value: string | null) => (
- );
+ )
- const greyInfoEntry = (
- title: string,
- value: string | JSX.Element | null
- ) => (
+ const greyInfoEntry = (title: string, value: string | JSX.Element | null) => (
{value ? (
@@ -57,38 +49,33 @@ const StakingPoolDetailsView: React.FC<
) : (
)}
-
- {title}
-
+
{title}
- );
+ )
const pendingUnstakesValue = userUnstakingPoolData
?.filter((item) => item.availableAt > DateTime.now())
- .reduce((acc, item) => acc + item.zilAmount, 0n);
+ .reduce((acc, item) => acc + item.zilAmount, 0n)
const availableToClaim = userUnstakingPoolData
?.filter((item) => item.availableAt <= DateTime.now())
- .reduce((acc, item) => acc + item.zilAmount, 0n);
+ .reduce((acc, item) => acc + item.zilAmount, 0n)
const doesUserHoldAnyFundsInThisPool = !!(
userStakingPoolData?.stakingTokenAmount ||
pendingUnstakesValue ||
availableToClaim
- );
+ )
const humanReadableStakingToken = (value: bigint) =>
- formatUnitsToHumanReadable(
- value,
- stakingPoolData.definition.tokenDecimals
- );
+ formatUnitsToHumanReadable(value, stakingPoolData.definition.tokenDecimals)
+
+ const { watchAsset } = useWatchAsset()
- const { watchAsset } = useWatchAsset();
-
const handleClickAaddToken = () =>
watchAsset(
{
- type: 'ERC20',
+ type: "ERC20",
options: {
address: stakingPoolData.definition.tokenAddress,
symbol: stakingPoolData.definition.tokenSymbol,
@@ -97,13 +84,13 @@ const StakingPoolDetailsView: React.FC<
},
{
onSuccess: (data) => {
- console.log('Asset watched successfully:', data);
+ console.log("Asset watched successfully:", data)
},
onError: (error) => {
- console.error('Failed to watch the asset:', error);
+ console.error("Failed to watch the asset:", error)
},
}
- );
+ )
return (
-
Add Token
+ />
+
+ Add Token
+
@@ -141,62 +130,57 @@ const StakingPoolDetailsView: React.FC<
{doesUserHoldAnyFundsInThisPool && (
{colorInfoEntry(
- 'Available to stake',
- `${formatUnitsToHumanReadable(
- zilAvailable || 0n,
- 18
- )} ZIL`
+ "Available to stake",
+ `${formatUnitsToHumanReadable(zilAvailable || 0n, 18)} ZIL`
)}
{colorInfoEntry(
- 'Staked',
+ "Staked",
`${humanReadableStakingToken(
userStakingPoolData?.stakingTokenAmount || 0n
)} ${stakingPoolData.definition.tokenSymbol}`
)}
{colorInfoEntry(
- 'Unstake',
+ "Unstake",
pendingUnstakesValue
? `${humanReadableStakingToken(
pendingUnstakesValue
)} ${stakingPoolData.definition.tokenSymbol}`
- : '-'
+ : "-"
)}
{colorInfoEntry(
- 'Available to claim',
+ "Available to claim",
availableToClaim
? `${humanReadableStakingToken(availableToClaim)} ${
stakingPoolData.definition.tokenSymbol
}`
- : '-'
+ : "-"
)}
)}
{greyInfoEntry(
- 'Voting power',
+ "Voting power",
stakingPoolData.data &&
formatPercentage(stakingPoolData.data.votingPower)
)}
{greyInfoEntry(
- 'Total supply',
+ "Total supply",
stakingPoolData.data &&
`${humanReadableStakingToken(
stakingPoolData.data.tvl
)} ${stakingPoolData.definition.tokenSymbol}`
)}
{greyInfoEntry(
- 'Commission',
+ "Commission",
stakingPoolData.data &&
formatPercentage(stakingPoolData.data.commission)
)}
{greyInfoEntry(
- '',
+ "",
stakingPoolData.data && (
<>
1 ZIL ~
- {stakingPoolData.data.zilToTokenRate.toPrecision(
- 3
- )}{' '}
+ {stakingPoolData.data.zilToTokenRate.toPrecision(3)}{" "}
{stakingPoolData.definition.tokenSymbol}
>
)
@@ -204,13 +188,13 @@ const StakingPoolDetailsView: React.FC<
- {['Stake', 'Unstake', 'Claim'].map((pane) => (
+ {["Stake", "Unstake", "Claim"].map((pane) => (
setSelectedPane(pane)}
>
@@ -219,9 +203,9 @@ const StakingPoolDetailsView: React.FC<
))}
- {selectedPane === 'Stake' ? (
+ {selectedPane === "Stake" ? (
- ) : selectedPane === 'Unstake' ? (
+ ) : selectedPane === "Unstake" ? (
) : (
)}
- );
-};
+ )
+}
-export default StakingPoolDetailsView;
+export default StakingPoolDetailsView
diff --git a/src/components/stakingPoolsList.tsx b/src/components/stakingPoolsList.tsx
index 4bf6aad..2a224ea 100644
--- a/src/components/stakingPoolsList.tsx
+++ b/src/components/stakingPoolsList.tsx
@@ -1,131 +1,134 @@
-import { StakingPoolsStorage } from '@/contexts/stakingPoolsStorage';
-import StakingPoolCard from './stakingPoolCard';
-import SortBtn from './sortBtn';
-import { useState } from 'react';
+import { StakingPoolsStorage } from "@/contexts/stakingPoolsStorage"
+import StakingPoolCard from "./stakingPoolCard"
+import SortBtn from "./sortBtn"
+import { useState } from "react"
const StakingPoolsList: React.FC = () => {
const {
combinedStakingPoolsData,
selectStakingPoolForView,
stakingPoolForView,
- } = StakingPoolsStorage.useContainer();
+ } = StakingPoolsStorage.useContainer()
- const [sortCriteria, setSortCriteria] = useState< 'APR' | 'VP' | 'Commission' | null >(null);
+ const [sortCriteria, setSortCriteria] = useState<
+ "APR" | "VP" | "Commission" | null
+ >(null)
- const [isAscending, setIsAscending] = useState(true);
+ const [isAscending, setIsAscending] = useState(true)
// Function to get the value to sort by based on the criteria
const getSortValue = (data: any, criteria: string | null) => {
- if (!data) return 0;
+ if (!data) return 0
switch (criteria) {
- case 'APR':
- return data.apr || 0;
- case 'VP':
- return (data.votingPower || 0) * 100;
- case 'Commission':
- return (data.commission || 0) * 100;
+ case "APR":
+ return data.apr || 0
+ case "VP":
+ return (data.votingPower || 0) * 100
+ case "Commission":
+ return (data.commission || 0) * 100
default:
- return 0;
+ return 0
}
- };
+ }
// Sort the staking pools based on the selected criteria
- const sortedStakingPoolsData = [...combinedStakingPoolsData].sort(
- (a, b) => {
- const aValue = getSortValue(a.stakingPool.data, sortCriteria);
- const bValue = getSortValue(b.stakingPool.data, sortCriteria);
- return isAscending ? aValue - bValue : bValue - aValue;
- }
- );
-
- const handleSortClick = (criteria: 'APR' | 'VP' | 'Commission') => {
+ const sortedStakingPoolsData = [...combinedStakingPoolsData].sort((a, b) => {
+ const aValue = getSortValue(a.stakingPool.data, sortCriteria)
+ const bValue = getSortValue(b.stakingPool.data, sortCriteria)
+ return isAscending ? aValue - bValue : bValue - aValue
+ })
+
+ const handleSortClick = (criteria: "APR" | "VP" | "Commission") => {
if (sortCriteria === criteria) {
- setIsAscending(!isAscending);
+ setIsAscending(!isAscending)
} else {
- setSortCriteria(criteria);
- setIsAscending(true);
+ setSortCriteria(criteria)
+ setIsAscending(true)
}
- };
+ }
const tabs = [
{
- name: 'Liquid staking',
+ name: "Liquid staking",
},
{
- name: 'Normal Staking ',
- },
- ];
+ name: "Normal Staking ",
+ },
+ ]
- const [activeTab, setActiveTab] = useState(0);
+ const [activeTab, setActiveTab] = useState(0)
return (
<>
{/*
Liquid Validators
*/}
-
- {activeTab === 0 && (
-<>
-
- handleSortClick('APR')}
- />
- handleSortClick('VP')}
- />
- handleSortClick('Commission')}
- />
-
-
-
- {sortedStakingPoolsData.map(({ stakingPool, userData }) => (
-
- selectStakingPoolForView(stakingPool.definition.id)
- }
- />
+ activeTab === index
+ ? "border-aqua1"
+ : "border-transparent"
+ }`}
+ onClick={() => {
+ setActiveTab(index)
+ }}
+ >
+ {tab.name}
+
))}
-
>)}
+
+ {activeTab === 0 && (
+ <>
+
+ handleSortClick("APR")}
+ />
+ handleSortClick("VP")}
+ />
+ handleSortClick("Commission")}
+ />
+
+
+
+ {sortedStakingPoolsData.map(({ stakingPool, userData }) => (
+
+ selectStakingPoolForView(stakingPool.definition.id)
+ }
+ />
+ ))}
+
+ >
+ )}
>
- );
-};
+ )
+}
-export default StakingPoolsList;
+export default StakingPoolsList
diff --git a/src/components/unstakingCalculator.tsx b/src/components/unstakingCalculator.tsx
index 9ef317e..7933316 100644
--- a/src/components/unstakingCalculator.tsx
+++ b/src/components/unstakingCalculator.tsx
@@ -1,82 +1,79 @@
-import { StakingPoolsStorage } from '@/contexts/stakingPoolsStorage';
-import { useEffect, useState } from 'react';
-import { Button, Input, Tooltip } from 'antd';
+import { StakingPoolsStorage } from "@/contexts/stakingPoolsStorage"
+import { useEffect, useState } from "react"
+import { Button, Input, Tooltip } from "antd"
import {
formatPercentage,
convertTokenToZil,
formatUnitsToHumanReadable,
getHumanFormDuration,
-} from '@/misc/formatting';
-import { formatUnits, parseEther } from 'viem';
-import { StakingOperations } from '@/contexts/stakingOperations';
-import { DateTime } from 'luxon';
+} from "@/misc/formatting"
+import { formatUnits, parseEther } from "viem"
+import { StakingOperations } from "@/contexts/stakingOperations"
+import { DateTime } from "luxon"
const UnstakingCalculator: React.FC = () => {
- const { stakingPoolForView } = StakingPoolsStorage.useContainer();
+ const { stakingPoolForView } = StakingPoolsStorage.useContainer()
const { unstake, isUnstakingInProgress, unstakeContractCallError } =
- StakingOperations.useContainer();
+ StakingOperations.useContainer()
- const [zilToUnstake, setZilToUnstake] = useState('0');
+ const [zilToUnstake, setZilToUnstake] = useState("0")
const handleChange = (e: React.ChangeEvent) => {
- const { value: inputValue } = e.target;
- const reg = /^-?\d*(\.\d*)?$/;
- if (
- reg.test(inputValue) ||
- inputValue === '' ||
- inputValue === '-'
- ) {
- setZilToUnstake(inputValue);
+ const { value: inputValue } = e.target
+ const reg = /^-?\d*(\.\d*)?$/
+ if (reg.test(inputValue) || inputValue === "" || inputValue === "-") {
+ setZilToUnstake(inputValue)
}
- };
+ }
const handleFocus = () => {
- if (zilToUnstake === '') onMaxClick();
- };
+ if (zilToUnstake === "") onMaxClick()
+ }
const handleBlur = () => {
- let valueTemp = zilToUnstake;
+ let valueTemp = zilToUnstake
if (
- zilToUnstake.charAt(zilToUnstake.length - 1) === '.' ||
- zilToUnstake === '-'
+ zilToUnstake.charAt(zilToUnstake.length - 1) === "." ||
+ zilToUnstake === "-"
) {
- valueTemp = zilToUnstake.slice(0, -1);
+ valueTemp = zilToUnstake.slice(0, -1)
}
- setZilToUnstake(valueTemp.replace(/0*(\d+)/, '$1'));
- if (zilToUnstake === '') onMaxClick();
- };
+ setZilToUnstake(valueTemp.replace(/0*(\d+)/, "$1"))
+ if (zilToUnstake === "") onMaxClick()
+ }
useEffect(() => {
- setZilToUnstake('1');
- }, [stakingPoolForView]);
+ setZilToUnstake("1")
+ }, [stakingPoolForView])
const stakedTokenAvailable =
- stakingPoolForView?.userData?.staked?.stakingTokenAmount || 0;
+ stakingPoolForView?.userData?.staked?.stakingTokenAmount || 0
- const zilToUnstakeNumber = parseFloat(zilToUnstake);
- const zilInWei = parseEther(zilToUnstake);
+ const zilToUnstakeNumber = parseFloat(zilToUnstake)
+ const zilInWei = parseEther(zilToUnstake)
const zilToUnstakeOk =
- !isNaN(zilToUnstakeNumber) &&
- zilToUnstakeNumber <= stakedTokenAvailable;
+ !isNaN(zilToUnstakeNumber) && zilToUnstakeNumber <= stakedTokenAvailable
const canUnstake =
stakingPoolForView?.stakingPool.data &&
zilToUnstakeNumber > 0 &&
- zilToUnstakeNumber <= stakedTokenAvailable;
+ zilToUnstakeNumber <= stakedTokenAvailable
const onMaxClick = () => {
setZilToUnstake(
`${formatUnits(
- stakingPoolForView?.userData?.staked?.stakingTokenAmount ||
- 0n,
+ stakingPoolForView?.userData?.staked?.stakingTokenAmount || 0n,
stakingPoolForView?.stakingPool.definition.tokenDecimals || 18
)}`
- );
- };
+ )
+ }
- const unboudingPeriod = getHumanFormDuration((
- DateTime.now().plus({ minutes: stakingPoolForView?.stakingPool.definition.withdrawPeriodInMinutes || 0 })
- ));
+ const unboudingPeriod = getHumanFormDuration(
+ DateTime.now().plus({
+ minutes:
+ stakingPoolForView?.stakingPool.definition.withdrawPeriodInMinutes || 0,
+ })
+ )
return (
stakingPoolForView && (
@@ -85,7 +82,7 @@ const UnstakingCalculator: React.FC = () => {
@@ -130,7 +123,7 @@ const UnstakingCalculator: React.FC = () => {
setZilToUnstake('0')}
+ onClick={() => setZilToUnstake("0")}
>
MIN
@@ -140,23 +133,23 @@ const UnstakingCalculator: React.FC = () => {
- Commission Fee:{' '}
+ Commission Fee:{" "}
{stakingPoolForView!.stakingPool.data ? (
<>
- {' '}
+ {" "}
{formatPercentage(
stakingPoolForView!.stakingPool.data.commission
- )}{' '}
+ )}{" "}
>
) : (
)}
- Max transaction cost: {zilToUnstake ? '0.01' : '0'}$
+ Max transaction cost: {zilToUnstake ? "0.01" : "0"}$
- Unbonding Period: { unboudingPeriod }
+ Unbonding Period: {unboudingPeriod}
@@ -165,22 +158,16 @@ const UnstakingCalculator: React.FC = () => {
{stakingPoolForView!.stakingPool.data ? (
<>
- 1{' '}
- {
- stakingPoolForView.stakingPool.definition
- .tokenSymbol
- }{' '}
+ 1 {stakingPoolForView.stakingPool.definition.tokenSymbol}{" "}
= ~
{formatUnitsToHumanReadable(
convertTokenToZil(
- parseEther('1'),
- stakingPoolForView.stakingPool.data
- .zilToTokenRate
+ parseEther("1"),
+ stakingPoolForView.stakingPool.data.zilToTokenRate
),
18
)}
-
- >
+ >
) : (
)}
@@ -188,15 +175,19 @@ const UnstakingCalculator: React.FC = () => {
-
- APR
-
+
+ APR
+
{stakingPoolForView!.stakingPool.data ? (
<>
~
- {formatPercentage(
- stakingPoolForView!.stakingPool.data.apr
- )}
+ {formatPercentage(stakingPoolForView!.stakingPool.data.apr)}
>
) : (
@@ -230,7 +221,7 @@ const UnstakingCalculator: React.FC = () => {
)
- );
-};
+ )
+}
-export default UnstakingCalculator;
+export default UnstakingCalculator
diff --git a/src/components/withdrawUnstakedZilPanel.tsx b/src/components/withdrawUnstakedZilPanel.tsx
index 00c49d8..a87754f 100644
--- a/src/components/withdrawUnstakedZilPanel.tsx
+++ b/src/components/withdrawUnstakedZilPanel.tsx
@@ -1,20 +1,20 @@
-import { AppConfigStorage } from '@/contexts/appConfigStorage';
-import { StakingOperations } from '@/contexts/stakingOperations';
+import { AppConfigStorage } from "@/contexts/appConfigStorage"
+import { StakingOperations } from "@/contexts/stakingOperations"
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';
+} 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;
- userUnstakingPoolData?: Array
;
+ stakingPoolData: StakingPool
+ userUnstakingPoolData?: Array
}
const WithdrawZilPanel: React.FC = ({
@@ -22,23 +22,23 @@ const WithdrawZilPanel: React.FC = ({
stakingPoolData,
}) => {
const { claim, isClaimingInProgress, claimCallTxHash } =
- StakingOperations.useContainer();
+ StakingOperations.useContainer()
- const { appConfig } = AppConfigStorage.useContainer();
+ const { appConfig } = AppConfigStorage.useContainer()
const pendingUnstake = userUnstakingPoolData
?.filter((claim) => claim.availableAt > DateTime.now())
.toSorted(
(claimA, claimB) =>
claimA.availableAt.diff(claimB.availableAt).milliseconds
- );
+ )
const availableUnstake = userUnstakingPoolData
?.filter((claim) => claim.availableAt <= DateTime.now())
.toSorted(
(claimA, claimB) =>
claimA.availableAt.diff(claimB.availableAt).milliseconds
- );
+ )
return (
@@ -47,10 +47,7 @@ const WithdrawZilPanel: React.FC
= ({
Last staking transaction: {formatAddress(claimCallTxHash)}
@@ -60,57 +57,50 @@ const WithdrawZilPanel: React.FC = ({
{!!availableUnstake?.length ? (
availableUnstake.map((item, claimIdx) => (
-
{stakingPoolData.data ? (
-
-
- {parseFloat(
- formatUnits(item.zilAmount, 18)
- ).toFixed(3)}{' '}
- ZIL
-
-
avZIL
-
-
+
+
+ {parseFloat(formatUnits(item.zilAmount, 18)).toFixed(3)} ZIL
+
+
avZIL
+
) : (
)}
-
+
claim(item.address)}
loading={isClaimingInProgress}
- >
- Claim
+ >
+ Claim
-
+
))
) : !!pendingUnstake?.length ? (
-
- Next available reward
-
-
- {stakingPoolData.data ? (
-
- {parseFloat(
- formatUnits(pendingUnstake[0].zilAmount, 18)
- ).toFixed(3)}{' '}
- ZIL
-
- ) : (
-
- )}
+
Next available reward
+
+ {stakingPoolData.data ? (
- {getHumanFormDuration(pendingUnstake[0].availableAt)}
+ {parseFloat(
+ formatUnits(pendingUnstake[0].zilAmount, 18)
+ ).toFixed(3)}{" "}
+ ZIL
-
-
+ ) : (
+
+ )}
+
{getHumanFormDuration(pendingUnstake[0].availableAt)}
+
+
) : (
No available Claims
@@ -119,31 +109,32 @@ const WithdrawZilPanel: React.FC
= ({
{!!pendingUnstake?.length && (
-
- Pending Requests
-
+
Pending Requests
{pendingUnstake?.map((claim, claimIdx) => (
-
+
{stakingPoolData.data ? (
-
-
- {parseFloat(
- formatUnits(claim.zilAmount, 18)
- ).toFixed(3)}{' '}
- ZIL
-
+
+
+ {parseFloat(formatUnits(claim.zilAmount, 18)).toFixed(3)}{" "}
+ ZIL
+
) : (
)}
-
{getHumanFormDuration(claim.availableAt)}
+
+ {getHumanFormDuration(claim.availableAt)}
+
))}
)}
- );
-};
+ )
+}
-export default WithdrawZilPanel;
+export default WithdrawZilPanel
diff --git a/src/components/withdrawZilView.tsx b/src/components/withdrawZilView.tsx
index ab50b5a..4072221 100644
--- a/src/components/withdrawZilView.tsx
+++ b/src/components/withdrawZilView.tsx
@@ -1,130 +1,135 @@
-import { StakingOperations } from "@/contexts/stakingOperations";
-import { StakingPoolsStorage } from "@/contexts/stakingPoolsStorage";
-import { convertTokenToZil, formatUnitsToHumanReadable, getHumanFormDuration } from "@/misc/formatting";
-import { Button } from "antd";
-import Image from 'next/image';
+import { StakingOperations } from "@/contexts/stakingOperations"
+import { StakingPoolsStorage } from "@/contexts/stakingPoolsStorage"
+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();
+ isUnstakingDataLoading,
+ } = StakingPoolsStorage.useContainer()
- const {
- claim,
- } = StakingOperations.useContainer();
+ const { claim } = StakingOperations.useContainer()
const unstakingItems = [
...availableForUnstaking.map((item) => ({ ...item, available: true })),
- ...pendingUnstaking.map((item) => ({ ...item, available: false }))
+ ...pendingUnstaking.map((item) => ({ ...item, available: false })),
]
return (
-
+ flex flex-col gap-2"
+ >
Staking Portal
Claims
- Below are withdrawal claims waiting for you
+ Below are withdrawal claims waiting for you
- {
- unstakingItems.length > 0 ? (
-
-
- {
- unstakingItems.map((item, claimIdx) => (
-
-
-
-
-
- {item.stakingPool.definition.name}
-
-
-
-
- {
- item.stakingPool.data ? <>
- {
- formatUnitsToHumanReadable(
- convertTokenToZil(item.unstakeInfo.zilAmount, item.stakingPool.data!.zilToTokenRate),
- 18
- )
- } ZIL
-
- > :
- <>
-
- >
- }
-
-
-
{item.unstakeInfo.zilAmount} {item.stakingPool.definition.tokenSymbol}
-
+ "
+ >
+ {unstakingItems.map((item, claimIdx) => (
+
+
+
+
+
+ {item.stakingPool.definition.name}
-
-
- claim(item.unstakeInfo.address)}
- >
- {item.available ? 'Claim' : getHumanFormDuration(item.unstakeInfo.availableAt) + ' left'}
-
-
-
- selectStakingPoolForView(item.stakingPool.definition.id)}
- >
- View
-
-
+
+
+
+ {item.stakingPool.data ? (
+ <>
+ {formatUnitsToHumanReadable(
+ convertTokenToZil(
+ item.unstakeInfo.zilAmount,
+ item.stakingPool.data!.zilToTokenRate
+ ),
+ 18
+ )}{" "}
+ ZIL
+ >
+ ) : (
+ <>
+
+ >
+ )}
-
+
+ {item.unstakeInfo.zilAmount}{" "}
+ {item.stakingPool.definition.tokenSymbol}
+
+
+
+
+
+ claim(item.unstakeInfo.address)}
+ >
+ {item.available
+ ? "Claim"
+ : getHumanFormDuration(item.unstakeInfo.availableAt) +
+ " left"}
+
- ))
- }
-
- ) : (
-
- {
- isUnstakingDataLoading ? (
-
- ) : (
-
- Here is the testing ground for the new Zilliqa portal.
- Explore and give us you feedback.
-
- )
- }
-
- )
- }
+
+
+ selectStakingPoolForView(item.stakingPool.definition.id)
+ }
+ >
+ View
+
+
+
+
+ ))}
+
+ ) : (
+
+ {isUnstakingDataLoading ? (
+
+ ) : (
+
+ Here is the testing ground for the new Zilliqa portal. Explore and
+ give us you feedback.
+
+ )}
+
+ )}
)
-
}
-export default WithdrawZilView;
\ No newline at end of file
+export default WithdrawZilView
diff --git a/src/contexts/appConfigStorage.tsx b/src/contexts/appConfigStorage.tsx
index 8e35ac7..01cac41 100644
--- a/src/contexts/appConfigStorage.tsx
+++ b/src/contexts/appConfigStorage.tsx
@@ -1,12 +1,12 @@
-"use client";
+"use client"
-import { AppConfig } from "@/pages/api/config";
-import { createContainer } from "./context";
+import { AppConfig } from "@/pages/api/config"
+import { createContainer } from "./context"
const useAppConfigStorage = (initialState?: { appConfig: AppConfig }) => {
return {
- appConfig: initialState!.appConfig
- };
-};
+ appConfig: initialState!.appConfig,
+ }
+}
-export const AppConfigStorage = createContainer(useAppConfigStorage);
+export const AppConfigStorage = createContainer(useAppConfigStorage)
diff --git a/src/contexts/context.tsx b/src/contexts/context.tsx
index 432eb30..c6b0e87 100644
--- a/src/contexts/context.tsx
+++ b/src/contexts/context.tsx
@@ -1,4 +1,4 @@
-"use client";
+"use client"
/**
* This file is a copy of https://github.com/jamiebuilds/unstated-next/blob/master/src/unstated-next.tsx
* The reason it is the copy is that the project is no longer maintained and we are using new version of React
@@ -6,49 +6,49 @@
* In theory, this should land in the "@zilliqa/zilliqa-ui" but then you need to set up jsx transpilation
* if you are reading that and have time to do it, please do!
*/
-import React from "react";
+import React from "react"
-const EMPTY: unique symbol = Symbol();
+const EMPTY: unique symbol = Symbol()
export interface ContainerProviderProps
{
- initialState?: State;
- children: React.ReactNode;
+ initialState?: State
+ children: React.ReactNode
}
export interface Container {
- Provider: React.ComponentType>;
- useContainer: () => Value;
- MockProvider: React.ComponentType>>;
+ Provider: React.ComponentType>
+ useContainer: () => Value
+ MockProvider: React.ComponentType>>
}
export function createContainer(
useHook: (initialState?: State) => Value,
- mockkContextCreator?: (overrides: Partial) => Value,
+ mockkContextCreator?: (overrides: Partial) => Value
): Container {
- let Context = React.createContext(EMPTY);
+ let Context = React.createContext(EMPTY)
function Provider(props: ContainerProviderProps) {
- let value = useHook(props.initialState);
- return {props.children};
+ let value = useHook(props.initialState)
+ return {props.children}
}
function MockProvider(props: ContainerProviderProps>) {
if (!mockkContextCreator) {
throw new Error(
- "MockProvider can only be used when mockkContextCreator is provided",
- );
+ "MockProvider can only be used when mockkContextCreator is provided"
+ )
}
- let value = mockkContextCreator(props.initialState || {});
- return {props.children};
+ let value = mockkContextCreator(props.initialState || {})
+ return {props.children}
}
function useContainer(): Value {
- let value = React.useContext(Context);
+ let value = React.useContext(Context)
if (value === EMPTY) {
- throw new Error("Component must be wrapped with ");
+ throw new Error("Component must be wrapped with ")
}
- return value;
+ return value
}
- return { Provider, useContainer, MockProvider };
+ return { Provider, useContainer, MockProvider }
}
diff --git a/src/contexts/stakingOperations.tsx b/src/contexts/stakingOperations.tsx
index 5ec74e3..473af99 100644
--- a/src/contexts/stakingOperations.tsx
+++ b/src/contexts/stakingOperations.tsx
@@ -1,39 +1,38 @@
-import { notification } from "antd";
-import { useEffect, useState } from "react";
-import { useWaitForTransactionReceipt } from "wagmi";
-import { createContainer } from "./context";
-import { WalletConnector } from "./walletConnector";
-import { StakingPoolsStorage } from "./stakingPoolsStorage";
-import { Address } from "viem";
-import { delegatorAbi } from "@/misc/stakingAbis";
-import { writeContract } from "wagmi/actions";
-import { useConfig } from 'wagmi'
+import { notification } from "antd"
+import { useEffect, useState } from "react"
+import { useWaitForTransactionReceipt } from "wagmi"
+import { createContainer } from "./context"
+import { WalletConnector } from "./walletConnector"
+import { StakingPoolsStorage } from "./stakingPoolsStorage"
+import { Address } from "viem"
+import { delegatorAbi } from "@/misc/stakingAbis"
+import { writeContract } from "wagmi/actions"
+import { useConfig } from "wagmi"
const useStakingOperations = () => {
+ const { isDummyWalletConnected, updateWalletBalance } =
+ WalletConnector.useContainer()
- const {
- isDummyWalletConnected,
- updateWalletBalance,
- } = WalletConnector.useContainer();
-
- const {
- reloadUserStakingPoolsData,
- stakingPoolForView,
- } = StakingPoolsStorage.useContainer();
+ const { reloadUserStakingPoolsData, stakingPoolForView } =
+ StakingPoolsStorage.useContainer()
const wagmiConfig = useConfig()
- const [isDummyWalletPopupOpen, setIsDummyWalletPopupOpen] = useState(false);
- const [dummyWalletPopupContent, setDummyWalletPopupContent] = useState(null);
+ const [isDummyWalletPopupOpen, setIsDummyWalletPopupOpen] = useState(false)
+ const [dummyWalletPopupContent, setDummyWalletPopupContent] = useState<
+ string | null
+ >(null)
- const stakingPoolId = stakingPoolForView?.stakingPool.definition.id;
+ const stakingPoolId = stakingPoolForView?.stakingPool.definition.id
/**
* STAKING
*/
- const [stakingCallTxHash, setStakingCallTxHash] = useState(undefined);
- const [preparingStakingTx, setPreparingStakingTx] = useState(false);
+ const [stakingCallTxHash, setStakingCallTxHash] = useState<
+ Address | undefined
+ >(undefined)
+ const [preparingStakingTx, setPreparingStakingTx] = useState(false)
const {
isLoading: submittingStakingTx,
@@ -44,67 +43,64 @@ const useStakingOperations = () => {
})
const stake = (delegatorAddress: string, weiToStake: bigint) => {
- setPreparingStakingTx(true);
+ setPreparingStakingTx(true)
if (isDummyWalletConnected) {
- setDummyWalletPopupContent(`Now User gonna approve the wallet transaction for staking ZIL`);
- setIsDummyWalletPopupOpen(true);
- setStakingCallTxHash("0x1234567890234567890234567890234567890" as Address);
- setPreparingStakingTx(false);
+ setDummyWalletPopupContent(
+ "Now User gonna approve the wallet transaction for staking ZIL"
+ )
+ setIsDummyWalletPopupOpen(true)
+ setStakingCallTxHash("0x1234567890234567890234567890234567890" as Address)
+ setPreparingStakingTx(false)
} else {
- writeContract(
- wagmiConfig,
- {
- address: delegatorAddress as Address,
- abi: delegatorAbi,
- functionName: 'stake',
- args: [],
- value: weiToStake
- }
- ).then(
- (txHash) => {
- setStakingCallTxHash(txHash);
- }
- ).catch(
- (error) => {
+ writeContract(wagmiConfig, {
+ address: delegatorAddress as Address,
+ abi: delegatorAbi,
+ functionName: "stake",
+ args: [],
+ value: weiToStake,
+ })
+ .then((txHash) => {
+ setStakingCallTxHash(txHash)
+ })
+ .catch((error) => {
notification.error({
message: "Staking failed",
- description: error?.message || "There was an error while staking ZIL",
- placement: "topRight"
- });
- }
- ).finally(
- () => setPreparingStakingTx(false)
- )
+ description:
+ error?.message || "There was an error while staking ZIL",
+ placement: "topRight",
+ })
+ })
+ .finally(() => setPreparingStakingTx(false))
}
}
- useEffect(
- () => {
- if (stakingCallReceiptStatus === "success") {
- notification.success({
- message: "Staking successful",
- description: `You have successfully staked ZIL`,
- placement: "topRight"
- });
- reloadUserStakingPoolsData();
- updateWalletBalance();
- } else if (stakingCallReceiptStatus === "error") {
- notification.error({
- message: "Staking failed",
- description: `There was an error while staking ZIL`,
- placement: "topRight"
- });
- }
- }, [stakingCallReceiptStatus]
- )
+ useEffect(() => {
+ if (stakingCallReceiptStatus === "success") {
+ notification.success({
+ message: "Staking successful",
+ description: "You have successfully staked ZIL",
+ placement: "topRight",
+ })
+ reloadUserStakingPoolsData()
+ updateWalletBalance()
+ } else if (stakingCallReceiptStatus === "error") {
+ notification.error({
+ message: "Staking failed",
+ description: "There was an error while staking ZIL",
+ placement: "topRight",
+ })
+ }
+ }, [stakingCallReceiptStatus])
/**
* UNSTAKING
*/
- const [unstakingCallTxHash, setUnstakingCallTxHash] = useState(undefined);
- const [preparingUnstakingTx, setPreparingUnstakingTx] = useState(false);
+ const [unstakingCallTxHash, setUnstakingCallTxHash] = useState<
+ Address | undefined
+ >(undefined)
+ const [preparingUnstakingTx, setPreparingUnstakingTx] = useState(false)
const {
isLoading: submittingUnstakingTx,
@@ -115,65 +111,64 @@ const useStakingOperations = () => {
})
const unstake = (delegatorAddress: string, tokensToUnstake: bigint) => {
- setPreparingUnstakingTx(true);
+ setPreparingUnstakingTx(true)
if (isDummyWalletConnected) {
- setDummyWalletPopupContent(`Now User gonna approve the wallet transaction for unstaking ${tokensToUnstake} staked tokens`);
- setIsDummyWalletPopupOpen(true);
- setUnstakingCallTxHash("0x1234567890234567890234567890234567890" as Address);
- setPreparingUnstakingTx(false);
+ setDummyWalletPopupContent(
+ `Now User gonna approve the wallet transaction for unstaking ${tokensToUnstake} staked tokens`
+ )
+ setIsDummyWalletPopupOpen(true)
+ setUnstakingCallTxHash(
+ "0x1234567890234567890234567890234567890" as Address
+ )
+ setPreparingUnstakingTx(false)
} else {
- writeContract(
- wagmiConfig,
- {
- address: delegatorAddress as Address,
- abi: delegatorAbi,
- functionName: 'unstake',
- args: [tokensToUnstake]
- }
- ).then(
- (txHash) => {
- setUnstakingCallTxHash(txHash);
- }
- ).catch(
- (error) => {
+ writeContract(wagmiConfig, {
+ address: delegatorAddress as Address,
+ abi: delegatorAbi,
+ functionName: "unstake",
+ args: [tokensToUnstake],
+ })
+ .then((txHash) => {
+ setUnstakingCallTxHash(txHash)
+ })
+ .catch((error) => {
notification.error({
message: "Unstaking failed",
- description: error?.message || "There was an error while unstaking ZIL",
- placement: "topRight"
- });
- }
- ).finally(
- () => setPreparingUnstakingTx(false)
- )
+ description:
+ error?.message || "There was an error while unstaking ZIL",
+ placement: "topRight",
+ })
+ })
+ .finally(() => setPreparingUnstakingTx(false))
}
}
- useEffect(
- () => {
- if (unstakeCallReceiptStatus === "success") {
- notification.success({
- message: "Unstaking successful",
- description: `You have successfully unstaked ZIL`,
- placement: "topRight"
- });
- reloadUserStakingPoolsData();
- updateWalletBalance();
- } else if (unstakeCallReceiptStatus === "error") {
- notification.error({
- message: "Unstaking failed",
- description: `There was an error while unstaking ZIL`,
- placement: "topRight"
- });
- }
- }, [unstakeCallReceiptStatus]
- )
+ useEffect(() => {
+ if (unstakeCallReceiptStatus === "success") {
+ notification.success({
+ message: "Unstaking successful",
+ description: "You have successfully unstaked ZIL",
+ placement: "topRight",
+ })
+ reloadUserStakingPoolsData()
+ updateWalletBalance()
+ } else if (unstakeCallReceiptStatus === "error") {
+ notification.error({
+ message: "Unstaking failed",
+ description: "There was an error while unstaking ZIL",
+ placement: "topRight",
+ })
+ }
+ }, [unstakeCallReceiptStatus])
/**
* CLAIMING
*/
- const [claimCallTxHash, setClaimCallTxHash] = useState(undefined);
- const [preparingClaimTx, setPreparingClaimTx] = useState(false);
+ const [claimCallTxHash, setClaimCallTxHash] = useState(
+ undefined
+ )
+ const [preparingClaimTx, setPreparingClaimTx] = useState(false)
const {
isLoading: submittingClaimTx,
@@ -184,58 +179,53 @@ const useStakingOperations = () => {
})
const claim = (delegatorAddress: string) => {
- setPreparingClaimTx(true);
+ setPreparingClaimTx(true)
if (isDummyWalletConnected) {
- setDummyWalletPopupContent(`Now User gonna approve the wallet transaction for withdrawing/claiming ZIL`);
- setIsDummyWalletPopupOpen(true);
- setClaimCallTxHash("0x1234567890234567890234567890234567890" as Address);
- setPreparingClaimTx(false);
+ setDummyWalletPopupContent(
+ "Now User gonna approve the wallet transaction for withdrawing/claiming ZIL"
+ )
+ setIsDummyWalletPopupOpen(true)
+ setClaimCallTxHash("0x1234567890234567890234567890234567890" as Address)
+ setPreparingClaimTx(false)
} else {
- writeContract(
- wagmiConfig,
- {
- address: delegatorAddress as Address,
- abi: delegatorAbi,
- functionName: 'claim',
- args: []
- }
- ).then(
- (txHash) => {
- setClaimCallTxHash(txHash);
- }
- ).catch(
- (error) => {
+ 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"
- });
- }
- ).finally(
- () => setPreparingClaimTx(false)
- )
+ description:
+ error?.message || "There was an error while claiming ZIL",
+ placement: "topRight",
+ })
+ })
+ .finally(() => setPreparingClaimTx(false))
}
}
- 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]
- )
+ 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
@@ -243,9 +233,9 @@ const useStakingOperations = () => {
useEffect(
function clearStateOnDelegatorChange() {
- setStakingCallTxHash(undefined);
- setUnstakingCallTxHash(undefined);
- setClaimCallTxHash(undefined);
+ setStakingCallTxHash(undefined)
+ setUnstakingCallTxHash(undefined)
+ setClaimCallTxHash(undefined)
},
[stakingPoolId]
)
@@ -270,7 +260,6 @@ const useStakingOperations = () => {
claimCallTxHash,
claimContractCallError,
}
+}
-};
-
-export const StakingOperations = createContainer(useStakingOperations);
\ No newline at end of file
+export const StakingOperations = createContainer(useStakingOperations)
diff --git a/src/contexts/stakingPoolsStorage.tsx b/src/contexts/stakingPoolsStorage.tsx
index 8779a89..f6ee606 100644
--- a/src/contexts/stakingPoolsStorage.tsx
+++ b/src/contexts/stakingPoolsStorage.tsx
@@ -1,66 +1,86 @@
-"use client";
-
-import { useEffect, useState } from "react";
-import { createContainer } from "./context";
-import { WalletConnector } from "./walletConnector";
-import { DateTime } from "luxon";
-import { StakingPool, stakingPoolsConfigForChainId } from "@/misc/stakingPoolsConfig";
-import { getWalletStakingData, getWalletUnstakingData, UserStakingPoolData, UserUnstakingPoolData } from "@/misc/walletsConfig";
-import { AppConfigStorage } from "./appConfigStorage";
+"use client"
+
+import { useEffect, useState } from "react"
+import { createContainer } from "./context"
+import { WalletConnector } from "./walletConnector"
+import { DateTime } from "luxon"
+import {
+ StakingPool,
+ stakingPoolsConfigForChainId,
+} from "@/misc/stakingPoolsConfig"
+import {
+ getWalletStakingData,
+ getWalletUnstakingData,
+ UserStakingPoolData,
+ UserUnstakingPoolData,
+} from "@/misc/walletsConfig"
+import { AppConfigStorage } from "./appConfigStorage"
const useStakingPoolsStorage = () => {
- const {
- walletAddress,
- } = WalletConnector.useContainer();
+ const { walletAddress } = WalletConnector.useContainer()
- const {
- appConfig
- } = AppConfigStorage.useContainer();
+ const { appConfig } = AppConfigStorage.useContainer()
- const [availableStakingPoolsData, setAvailableStakingPoolsData] = useState([]);
+ const [availableStakingPoolsData, setAvailableStakingPoolsData] = useState<
+ StakingPool[]
+ >([])
- const [userStakingPoolsData, setUserStakingPoolsData] = useState([]);
- const [userUnstakesData, setUserUnstakesData] = useState([]);
+ const [userStakingPoolsData, setUserStakingPoolsData] = useState<
+ UserStakingPoolData[]
+ >([])
+ const [userUnstakesData, setUserUnstakesData] = useState<
+ UserUnstakingPoolData[]
+ >([])
- const [stakingPoolForView, setSelectedStakingPool] = useState(null);
+ const [stakingPoolForView, setSelectedStakingPool] =
+ useState(null)
- const [stakingPoolForStaking, setStakingPoolForStaking] = useState(null);
- const [stakingPoolForUnstaking, setStakingPoolForUnstaking] = useState(null);
+ const [stakingPoolForStaking, setStakingPoolForStaking] =
+ useState(null)
+ const [stakingPoolForUnstaking, setStakingPoolForUnstaking] =
+ useState(null)
- const [isUnstakingDataLoading, setIsUnstakingDataLoading] = useState(false);
+ const [isUnstakingDataLoading, setIsUnstakingDataLoading] = useState(false)
const reloadUserStakingPoolsData = () => {
if (!walletAddress) {
- setUserStakingPoolsData([]);
+ setUserStakingPoolsData([])
return
}
- getWalletStakingData(walletAddress, appConfig!.chainId).then(setUserStakingPoolsData).catch(console.error);
- setIsUnstakingDataLoading(true);
+ getWalletStakingData(walletAddress, appConfig!.chainId)
+ .then(setUserStakingPoolsData)
+ .catch(console.error)
+ setIsUnstakingDataLoading(true)
getWalletUnstakingData(walletAddress, appConfig!.chainId)
.then(setUserUnstakesData)
.catch(console.error)
- .finally(() => setIsUnstakingDataLoading(false));
+ .finally(() => setIsUnstakingDataLoading(false))
}
useEffect(
function triggerUserDataLoadingOnWalletConnect() {
- reloadUserStakingPoolsData();
+ reloadUserStakingPoolsData()
},
[walletAddress]
- );
+ )
- useEffect(
- function populateStakingPoolsDefinitionsAndTriggerDataLoading () {
- const stakingPoolsConfig = stakingPoolsConfigForChainId[appConfig.chainId];
+ useEffect(function populateStakingPoolsDefinitionsAndTriggerDataLoading() {
+ const stakingPoolsConfig = stakingPoolsConfigForChainId[appConfig.chainId]
- setAvailableStakingPoolsData(stakingPoolsConfig.map((configEntry) => ({
+ setAvailableStakingPoolsData(
+ stakingPoolsConfig.map((configEntry) => ({
definition: configEntry.definition,
data: null,
- })));
+ }))
+ )
- Promise.all(stakingPoolsConfig.map(async (config) => {
- const data = await config.delegatorDataProvider(config.definition, appConfig.chainId);
+ Promise.all(
+ stakingPoolsConfig.map(async (config) => {
+ const data = await config.delegatorDataProvider(
+ config.definition,
+ appConfig.chainId
+ )
setAvailableStakingPoolsData((prev) => {
const updated = prev.map((entry) => {
@@ -68,122 +88,159 @@ const useStakingPoolsStorage = () => {
return {
...entry,
data,
- };
+ }
}
- return entry;
- });
+ return entry
+ })
- return updated;
- }
- )
- }));
- }, []); // eslint-disable-line react-hooks/exhaustive-deps
+ return updated
+ })
+ })
+ )
+ }, []) // eslint-disable-line react-hooks/exhaustive-deps
useEffect(
- function updateStakingForViewOnStakingPoolsDataChange () {
+ function updateStakingForViewOnStakingPoolsDataChange() {
if (stakingPoolForView) {
- const updatedStakingPool = availableStakingPoolsData.find((pool) => pool.definition.id === stakingPoolForView.definition.id);
+ const updatedStakingPool = availableStakingPoolsData.find(
+ (pool) => pool.definition.id === stakingPoolForView.definition.id
+ )
if (updatedStakingPool) {
- setSelectedStakingPool(updatedStakingPool);
+ setSelectedStakingPool(updatedStakingPool)
}
}
},
[availableStakingPoolsData]
- );
+ )
const selectStakingPoolForView = (stakingPoolId: string | null) => {
if (!stakingPoolId) {
- setSelectedStakingPool(null);
- return;
+ setSelectedStakingPool(null)
+ return
}
- const selectedPool = availableStakingPoolsData.find((pool) => pool.definition.id === stakingPoolId);
+ const selectedPool = availableStakingPoolsData.find(
+ (pool) => pool.definition.id === stakingPoolId
+ )
if (selectedPool) {
if (selectedPool?.definition.id === stakingPoolForView?.definition.id) {
- setSelectedStakingPool(null);
+ setSelectedStakingPool(null)
} else {
- setSelectedStakingPool(selectedPool);
+ setSelectedStakingPool(selectedPool)
}
}
- setStakingPoolForStaking(null);
+ setStakingPoolForStaking(null)
}
const selectStakingPoolForStaking = (stakingPoolId: string | null) => {
if (!stakingPoolId) {
- setStakingPoolForStaking(null);
- return;
+ setStakingPoolForStaking(null)
+ return
}
-
- const selectedPool = availableStakingPoolsData.find((pool) => pool.definition.id === stakingPoolId);
+
+ const selectedPool = availableStakingPoolsData.find(
+ (pool) => pool.definition.id === stakingPoolId
+ )
if (selectedPool) {
- setStakingPoolForStaking(selectedPool);
+ setStakingPoolForStaking(selectedPool)
}
}
const selectStakingPoolForUnstaking = (stakingPoolId: string | null) => {
if (!stakingPoolId) {
- setStakingPoolForUnstaking(null);
- return;
+ setStakingPoolForUnstaking(null)
+ return
}
-
- const selectedPool = availableStakingPoolsData.find((pool) => pool.definition.id === stakingPoolId);
+
+ const selectedPool = availableStakingPoolsData.find(
+ (pool) => pool.definition.id === stakingPoolId
+ )
if (selectedPool) {
- setStakingPoolForUnstaking(selectedPool);
+ setStakingPoolForUnstaking(selectedPool)
}
}
- const combinedStakingPoolsData = availableStakingPoolsData.map((stakingPool) => {
- const userStakingPoolData = userStakingPoolsData.find((userPool) => userPool.address === stakingPool.definition.address);
+ const combinedStakingPoolsData = availableStakingPoolsData
+ .map((stakingPool) => {
+ const userStakingPoolData = userStakingPoolsData.find(
+ (userPool) => userPool.address === stakingPool.definition.address
+ )
- return {
- stakingPool,
- userData: userStakingPoolData,
- }
- }).toSorted(
- (a, b) => {
- const diff = (b.userData?.stakingTokenAmount || 0n) - (a.userData?.stakingTokenAmount || 0n);
+ return {
+ stakingPool,
+ userData: userStakingPoolData,
+ }
+ })
+ .toSorted((a, b) => {
+ const diff =
+ (b.userData?.stakingTokenAmount || 0n) -
+ (a.userData?.stakingTokenAmount || 0n)
if (diff === 0n) {
- return a.stakingPool.definition.name.localeCompare(b.stakingPool.definition.name);
+ return a.stakingPool.definition.name.localeCompare(
+ b.stakingPool.definition.name
+ )
}
- return diff > 0 ? 1 : -1;
- }
- );
-
- const combinedSelectedStakingPoolForViewData = stakingPoolForView ? {
- stakingPool: stakingPoolForView,
- userData: {
- staked: userStakingPoolsData.find((userPoolData) => userPoolData.address === stakingPoolForView.definition.address),
- unstaked: userUnstakesData.filter((userPoolData) => userPoolData.address === stakingPoolForView.definition.address)
- }
- } : null;
-
- const combinedSelectedStakingPoolForStakingData = stakingPoolForStaking ? {
- stakingPool: stakingPoolForStaking,
- userData: userStakingPoolsData.find((userPool) => userPool.address === stakingPoolForStaking.definition.address),
- } : null;
+ return diff > 0 ? 1 : -1
+ })
- const combinedSelectedStakingPoolForUnstakingData = stakingPoolForUnstaking ? {
- stakingPool: stakingPoolForUnstaking,
- userData: userStakingPoolsData.find((userPool) => userPool.address === stakingPoolForUnstaking.definition.address),
- } : null;
+ const combinedSelectedStakingPoolForViewData = stakingPoolForView
+ ? {
+ stakingPool: stakingPoolForView,
+ userData: {
+ staked: userStakingPoolsData.find(
+ (userPoolData) =>
+ userPoolData.address === stakingPoolForView.definition.address
+ ),
+ unstaked: userUnstakesData.filter(
+ (userPoolData) =>
+ userPoolData.address === stakingPoolForView.definition.address
+ ),
+ },
+ }
+ : null
+
+ const combinedSelectedStakingPoolForStakingData = stakingPoolForStaking
+ ? {
+ stakingPool: stakingPoolForStaking,
+ userData: userStakingPoolsData.find(
+ (userPool) =>
+ userPool.address === stakingPoolForStaking.definition.address
+ ),
+ }
+ : null
+
+ const combinedSelectedStakingPoolForUnstakingData = stakingPoolForUnstaking
+ ? {
+ stakingPool: stakingPoolForUnstaking,
+ userData: userStakingPoolsData.find(
+ (userPool) =>
+ userPool.address === stakingPoolForUnstaking.definition.address
+ ),
+ }
+ : null
- const combinedUserUnstakesData = userUnstakesData?.map(
- (unstakeInfo) => ({
+ const combinedUserUnstakesData =
+ userUnstakesData?.map((unstakeInfo) => ({
unstakeInfo,
- stakingPool: availableStakingPoolsData.find((pool) => pool.definition.address === unstakeInfo.address)!,
- })
- ) || [];
-
- const availableForUnstaking = combinedUserUnstakesData.filter((unstakeData) => unstakeData.unstakeInfo.availableAt <= DateTime.now());
- const pendingUnstaking = combinedUserUnstakesData.filter((unstakeData) => unstakeData.unstakeInfo.availableAt > DateTime.now());
+ stakingPool: availableStakingPoolsData.find(
+ (pool) => pool.definition.address === unstakeInfo.address
+ )!,
+ })) || []
+
+ const availableForUnstaking = combinedUserUnstakesData.filter(
+ (unstakeData) => unstakeData.unstakeInfo.availableAt <= DateTime.now()
+ )
+ const pendingUnstaking = combinedUserUnstakesData.filter(
+ (unstakeData) => unstakeData.unstakeInfo.availableAt > DateTime.now()
+ )
return {
availableStakingPools: availableStakingPoolsData,
@@ -199,7 +256,7 @@ const useStakingPoolsStorage = () => {
pendingUnstaking,
reloadUserStakingPoolsData,
isUnstakingDataLoading,
- };
-};
+ }
+}
-export const StakingPoolsStorage = createContainer(useStakingPoolsStorage);
+export const StakingPoolsStorage = createContainer(useStakingPoolsStorage)
diff --git a/src/contexts/walletConnector.tsx b/src/contexts/walletConnector.tsx
index 3042374..cf7c2e3 100644
--- a/src/contexts/walletConnector.tsx
+++ b/src/contexts/walletConnector.tsx
@@ -1,97 +1,94 @@
-"use client";
+"use client"
-import { useEffect, useState } from "react";
-import { createContainer } from "./context";
-import { DummyWallet } from "@/misc/walletsConfig";
-import { useWalletClient } from "wagmi";
-import { getBalance } from "viem/actions";
-import { Address } from "viem";
-import { getViemClient } from "@/misc/chainConfig";
-import { AppConfigStorage } from "./appConfigStorage";
+import { useEffect, useState } from "react"
+import { createContainer } from "./context"
+import { DummyWallet } from "@/misc/walletsConfig"
+import { useWalletClient } from "wagmi"
+import { getBalance } from "viem/actions"
+import { Address } from "viem"
+import { getViemClient } from "@/misc/chainConfig"
+import { AppConfigStorage } from "./appConfigStorage"
export enum ConnectedWalletType {
None,
MockWallet,
- RealWallet
+ RealWallet,
}
const useWalletConnector = () => {
- const [zilAvailable, setZilAvailable] = useState(null);
+ const [zilAvailable, setZilAvailable] = useState(null)
- const {
- appConfig
- } = AppConfigStorage.useContainer();
+ const { appConfig } = AppConfigStorage.useContainer()
/**
* Dummy Wallet section
*/
- const [isDummyWalletConnected, setIsDummyWalletConnected] = useState(false);
- const [isDummyWalletConnecting, setIsDummyWalletConnecting] = useState(false);
- const [isDummyWalletSelectorOpen, setIsDummyWalletSelectorOpen] = useState(false);
- const [dummyWallet, setDummyWallet] = useState(null);
+ const [isDummyWalletConnected, setIsDummyWalletConnected] = useState(false)
+ const [isDummyWalletConnecting, setIsDummyWalletConnecting] = useState(false)
+ const [isDummyWalletSelectorOpen, setIsDummyWalletSelectorOpen] =
+ useState(false)
+ const [dummyWallet, setDummyWallet] = useState(null)
const connectDummyWallet = () => {
- setIsDummyWalletConnecting(true);
- setIsDummyWalletSelectorOpen(true);
+ setIsDummyWalletConnecting(true)
+ setIsDummyWalletSelectorOpen(true)
}
const selectDummyWallet = (wallet: DummyWallet) => {
- setDummyWallet(wallet);
- setTimeout(
- () => {
- setZilAvailable(wallet.currentZil);
- },
- 1500
- )
-
- setIsDummyWalletConnected(true);
- setIsDummyWalletSelectorOpen(false);
- setIsDummyWalletConnecting(false);
+ setDummyWallet(wallet)
+ setTimeout(() => {
+ setZilAvailable(wallet.currentZil)
+ }, 1500)
+
+ setIsDummyWalletConnected(true)
+ setIsDummyWalletSelectorOpen(false)
+ setIsDummyWalletConnecting(false)
}
const disconnectDummyWallet = () => {
- setIsDummyWalletConnected(false);
- setDummyWallet(null);
- setIsDummyWalletConnecting(false);
- setIsDummyWalletSelectorOpen(false);
- setZilAvailable(0n);
- };
+ setIsDummyWalletConnected(false)
+ setDummyWallet(null)
+ setIsDummyWalletConnecting(false)
+ setIsDummyWalletSelectorOpen(false)
+ setZilAvailable(0n)
+ }
/**
* Rainbow wallet section
*/
- const {
- data: walletClient,
- } = useWalletClient();
+ const { data: walletClient } = useWalletClient()
/**
* Wallet data
*/
- const isWalletConnected = walletClient || isDummyWalletConnected;
- const connectedWalletType = walletClient ? ConnectedWalletType.RealWallet : isDummyWalletConnected ? ConnectedWalletType.MockWallet : ConnectedWalletType.None;
- const walletAddress = walletClient ? walletClient.account.address : isDummyWalletConnected ? dummyWallet!.address : null;
+ const isWalletConnected = walletClient || isDummyWalletConnected
+ const connectedWalletType = walletClient
+ ? ConnectedWalletType.RealWallet
+ : isDummyWalletConnected
+ ? ConnectedWalletType.MockWallet
+ : ConnectedWalletType.None
+ const walletAddress = walletClient
+ ? walletClient.account.address
+ : isDummyWalletConnected
+ ? dummyWallet!.address
+ : null
const updateWalletBalance = () => {
if (!walletAddress) {
- setZilAvailable(null);
- return;
+ setZilAvailable(null)
+ return
}
getBalance(getViemClient(appConfig.chainId), {
address: walletAddress as Address,
- }).then(
- (balanceInWei) => {
- setZilAvailable(balanceInWei);
- }
- );
+ }).then((balanceInWei) => {
+ setZilAvailable(balanceInWei)
+ })
}
- useEffect(
- updateWalletBalance,
- [walletAddress]
- );
+ useEffect(updateWalletBalance, [walletAddress])
return {
isWalletConnected,
@@ -105,7 +102,7 @@ const useWalletConnector = () => {
selectDummyWallet,
connectedWalletType,
updateWalletBalance,
- };
-};
+ }
+}
-export const WalletConnector = createContainer(useWalletConnector);
+export const WalletConnector = createContainer(useWalletConnector)
diff --git a/src/misc/chainConfig.ts b/src/misc/chainConfig.ts
index d467fd7..fbec6b4 100644
--- a/src/misc/chainConfig.ts
+++ b/src/misc/chainConfig.ts
@@ -1,90 +1,98 @@
-import { connectorsForWallets } from '@rainbow-me/rainbowkit';
-import { coinbaseWallet, ledgerWallet, metaMaskWallet, phantomWallet, rabbyWallet, rainbowWallet, trustWallet, walletConnectWallet } from '@rainbow-me/rainbowkit/wallets';
-import { createClient, createPublicClient, defineChain, http } from 'viem';
-import { createConfig } from 'wagmi';
-
+import { connectorsForWallets } from "@rainbow-me/rainbowkit"
+import {
+ coinbaseWallet,
+ ledgerWallet,
+ metaMaskWallet,
+ phantomWallet,
+ rabbyWallet,
+ rainbowWallet,
+ trustWallet,
+ walletConnectWallet,
+} from "@rainbow-me/rainbowkit/wallets"
+import { createClient, createPublicClient, defineChain, http } from "viem"
+import { createConfig } from "wagmi"
export const CHAIN_ZQ2_DEVNET = defineChain({
id: 33469,
- name: 'Zq2 Devnet',
- nativeCurrency: { name: 'ZIL', symbol: 'ZIL', decimals: 18 },
+ name: "Zq2 Devnet",
+ nativeCurrency: { name: "ZIL", symbol: "ZIL", decimals: 18 },
rpcUrls: {
default: {
- http: ['https://api.zq2-devnet.zilliqa.com'],
+ http: ["https://api.zq2-devnet.zilliqa.com"],
},
},
blockExplorers: {
default: {
- name: 'Otterscan',
- url: 'https://explorer.zq2-devnet.zilliqa.com',
+ name: "Otterscan",
+ url: "https://explorer.zq2-devnet.zilliqa.com",
},
},
})
export const CHAIN_ZQ2_PROTOTESTNET = defineChain({
id: 33103,
- name: 'Zq2 ProtoTestnet',
- nativeCurrency: { name: 'ZIL', symbol: 'ZIL', decimals: 18 },
+ name: "Zq2 ProtoTestnet",
+ nativeCurrency: { name: "ZIL", symbol: "ZIL", decimals: 18 },
rpcUrls: {
default: {
- http: ['https://api.zq2-prototestnet.zilliqa.com'],
+ http: ["https://api.zq2-prototestnet.zilliqa.com"],
},
},
blockExplorers: {
default: {
- name: 'Otterscan',
- url: 'https://explorer.zq2-prototestnet.zilliqa.com',
+ name: "Otterscan",
+ url: "https://explorer.zq2-prototestnet.zilliqa.com",
},
},
})
export const CHAIN_ZQ2_PROTOMAINNET = defineChain({
id: 32770,
- name: 'Zq2 ProtoMainnet',
- nativeCurrency: { name: 'ZIL', symbol: 'ZIL', decimals: 18 },
+ name: "Zq2 ProtoMainnet",
+ nativeCurrency: { name: "ZIL", symbol: "ZIL", decimals: 18 },
rpcUrls: {
default: {
- http: ['https://api.zq2-protomainnet.zilliqa.com'],
+ http: ["https://api.zq2-protomainnet.zilliqa.com"],
},
},
blockExplorers: {
default: {
- name: 'Otterscan',
- url: 'https://explorer.zq2-protomainnet.zilliqa.com',
+ name: "Otterscan",
+ url: "https://explorer.zq2-protomainnet.zilliqa.com",
},
},
})
export const CHAIN_ZQ2_DOCKERCOMPOSE = defineChain({
id: 87362,
- name: 'Zq2 Dockercompose',
- nativeCurrency: { name: 'ZIL', symbol: 'ZIL', decimals: 18 },
+ name: "Zq2 Dockercompose",
+ nativeCurrency: { name: "ZIL", symbol: "ZIL", decimals: 18 },
rpcUrls: {
default: {
- http: ['http://localhost:4201'],
+ http: ["http://localhost:4201"],
},
},
blockExplorers: {
default: {
- name: 'Otterscan',
- url: 'http://localhost:5100/',
+ name: "Otterscan",
+ url: "http://localhost:5100/",
},
},
})
export const MOCK_CHAIN = defineChain({
id: 9999999,
- name: 'Mock Chain',
- nativeCurrency: { name: 'ZIL', symbol: 'ZIL', decimals: 18 },
+ name: "Mock Chain",
+ nativeCurrency: { name: "ZIL", symbol: "ZIL", decimals: 18 },
rpcUrls: {
default: {
- http: ['NOT_USED'],
+ http: ["NOT_USED"],
},
},
blockExplorers: {
default: {
- name: 'NOT_USED',
- url: 'NOT_USED',
+ name: "NOT_USED",
+ url: "NOT_USED",
},
},
})
@@ -93,7 +101,7 @@ function getConnectorsForWallets(walletConnectApiKey: string) {
return connectorsForWallets(
[
{
- groupName: 'Recommended',
+ groupName: "Recommended",
wallets: [
metaMaskWallet,
walletConnectWallet,
@@ -102,13 +110,13 @@ function getConnectorsForWallets(walletConnectApiKey: string) {
trustWallet,
ledgerWallet,
rainbowWallet,
- phantomWallet
+ phantomWallet,
],
},
],
{
- appName: 'ZQ2 Staking',
- projectId: walletConnectApiKey
+ appName: "ZQ2 Staking",
+ projectId: walletConnectApiKey,
}
)
}
@@ -120,15 +128,13 @@ export function getChain(chainId: number) {
CHAIN_ZQ2_PROTOMAINNET,
CHAIN_ZQ2_DOCKERCOMPOSE,
MOCK_CHAIN,
- ].find(
- (chain) => chain.id === chainId
- );
+ ].find((chain) => chain.id === chainId)
if (!chain) {
- throw new Error(`Active chain [${chainId}] is not defined`);
+ throw new Error(`Active chain [${chainId}] is not defined`)
}
- return chain;
+ return chain
}
export function getWagmiConfig(chainId: number, walletConnectApiKey: string) {
@@ -138,12 +144,12 @@ export function getWagmiConfig(chainId: number, walletConnectApiKey: string) {
return createClient({ chain, transport: http() })
},
connectors: getConnectorsForWallets(walletConnectApiKey),
- });
+ })
}
export function getViemClient(chainId: number) {
return createPublicClient({
chain: getChain(chainId),
transport: http(),
- });
-}
\ No newline at end of file
+ })
+}
diff --git a/src/misc/formatting.ts b/src/misc/formatting.ts
index a317f4c..e747efc 100644
--- a/src/misc/formatting.ts
+++ b/src/misc/formatting.ts
@@ -1,63 +1,75 @@
-import { DateTime } from "luxon";
-import { formatUnits } from "viem";
-import { getChain } from "./chainConfig";
+import { DateTime } from "luxon"
+import { formatUnits } from "viem"
+import { getChain } from "./chainConfig"
export function formatPercentage(value: number) {
- return `${parseFloat((value * 100).toFixed(2))}%`;
+ return `${parseFloat((value * 100).toFixed(2))}%`
}
export function formatAddress(address: string) {
- return `${address.slice(0, 5)}...${address.slice(-3)}`;
+ return `${address.slice(0, 5)}...${address.slice(-3)}`
}
export function getHumanFormDuration(availableAt: DateTime) {
- const units = availableAt.diff(DateTime.now()).shiftTo('days', 'hours', 'minutes').toHuman({
- unitDisplay: 'long',
- listStyle: 'narrow',
- maximumFractionDigits: 0,
- })
+ const units = availableAt
+ .diff(DateTime.now())
+ .shiftTo("days", "hours", "minutes")
+ .toHuman({
+ unitDisplay: "long",
+ listStyle: "narrow",
+ maximumFractionDigits: 0,
+ })
const mostSignificantUnit = units
- .split(',')
- .map(units => units.trim())
+ .split(",")
+ .map((units) => units.trim())
.reduce((acc, unit) => {
- if (acc !== '') {
+ if (acc !== "") {
return acc
}
// check if unit starts with smh different that 0
// e.g., 0 days 2 hours 5 minutes should return "2 hours"
- if (unit[0] !== '0') {
+ if (unit[0] !== "0") {
return unit
}
return acc
- }, '')
+ }, "")
- return `~${mostSignificantUnit || '< 1 minute'}`
+ return `~${mostSignificantUnit || "< 1 minute"}`
}
-export function convertTokenToZil(tokenAmount: bigint, zilToTokenRate: number): bigint {
- const rate = BigInt(Math.round((1 / zilToTokenRate) * 100));
- const amount = (tokenAmount * rate) / 100n;
- return amount;
+export function convertTokenToZil(
+ tokenAmount: bigint,
+ zilToTokenRate: number
+): bigint {
+ const rate = BigInt(Math.round((1 / zilToTokenRate) * 100))
+ const amount = (tokenAmount * rate) / 100n
+ return amount
}
-export function convertZilValueInToken(zilAmount: number, zilToTokenRate: number) {
- return `${(zilAmount * zilToTokenRate).toFixed(2)}`
+export function convertZilValueInToken(
+ zilAmount: number,
+ zilToTokenRate: number
+) {
+ return `${(zilAmount * zilToTokenRate).toFixed(2)}`
}
-export function formatUnitsToHumanReadable(value: bigint, decimals: number): string {
- const raw = parseFloat(formatUnits(value, decimals));
+export function formatUnitsToHumanReadable(
+ value: bigint,
+ decimals: number
+): string {
+ const raw = parseFloat(formatUnits(value, decimals))
- const formatter = new Intl.NumberFormat('en-US', {
- notation: 'compact',
- compactDisplay: 'short',
- });
+ const formatter = new Intl.NumberFormat("en-US", {
+ notation: "compact",
+ compactDisplay: "short",
+ })
- return formatter.format(raw);
+ return formatter.format(raw)
}
export function getTxExplorerUrl(txHash: string, chainId: number) {
- return `${getChain(chainId).blockExplorers.default.url}/tx/${txHash}`;
-}
\ No newline at end of file
+ return `${getChain(chainId).blockExplorers.default.url}/tx/${txHash}`
+}
diff --git a/src/misc/stakingAbis.ts b/src/misc/stakingAbis.ts
index b403fb4..edbaf06 100644
--- a/src/misc/stakingAbis.ts
+++ b/src/misc/stakingAbis.ts
@@ -1,30 +1,30 @@
export const depositAbi = [
{
- "inputs": [],
- "name": "getFutureTotalStake",
- "outputs": [
+ inputs: [],
+ name: "getFutureTotalStake",
+ outputs: [
{
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
+ internalType: "uint256",
+ name: "",
+ type: "uint256",
+ },
],
- "stateMutability": "view",
- "type": "function"
+ stateMutability: "view",
+ type: "function",
},
{
- "inputs": [],
- "name": "withdrawalPeriod",
- "outputs": [
+ inputs: [],
+ name: "withdrawalPeriod",
+ outputs: [
{
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
+ internalType: "uint256",
+ name: "",
+ type: "uint256",
+ },
],
- "stateMutability": "view",
- "type": "function"
- }
+ stateMutability: "view",
+ type: "function",
+ },
]
export const delegatorAbi = [
@@ -32,129 +32,129 @@ export const delegatorAbi = [
* from Delegation.sol
*/
{
- "inputs": [],
- "name": "stake",
- "outputs": [],
- "stateMutability": "payable",
- "type": "function"
+ inputs: [],
+ name: "stake",
+ outputs: [],
+ stateMutability: "payable",
+ type: "function",
},
{
- "inputs": [
+ inputs: [
{
- "internalType": "uint256",
- "name": "shares",
- "type": "uint256"
- }
+ internalType: "uint256",
+ name: "shares",
+ type: "uint256",
+ },
],
- "name": "unstake",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
+ name: "unstake",
+ outputs: [],
+ stateMutability: "nonpayable",
+ type: "function",
},
{
- "inputs": [],
- "name": "claim",
- "outputs": [],
- "stateMutability": "nonpayable",
- "type": "function"
+ inputs: [],
+ name: "claim",
+ outputs: [],
+ stateMutability: "nonpayable",
+ type: "function",
},
{
- "inputs": [],
- "name": "getPendingClaims",
- "outputs": [
+ inputs: [],
+ name: "getPendingClaims",
+ outputs: [
{
- "internalType": "uint256[2][]",
- "name": "claims",
- "type": "uint256[2][]"
- }
+ internalType: "uint256[2][]",
+ name: "claims",
+ type: "uint256[2][]",
+ },
],
- "stateMutability": "view",
- "type": "function"
+ stateMutability: "view",
+ type: "function",
},
{
- "inputs": [],
- "name": "getMinDelegation",
- "outputs": [
+ inputs: [],
+ name: "getMinDelegation",
+ outputs: [
{
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
+ internalType: "uint256",
+ name: "",
+ type: "uint256",
+ },
],
- "stateMutability": "view",
- "type": "function"
+ stateMutability: "view",
+ type: "function",
},
{
- "inputs": [],
- "name": "getCommission",
- "outputs": [
+ inputs: [],
+ name: "getCommission",
+ outputs: [
{
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
+ internalType: "uint256",
+ name: "",
+ type: "uint256",
},
{
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
+ internalType: "uint256",
+ name: "",
+ type: "uint256",
+ },
],
- "stateMutability": "view",
- "type": "function"
+ stateMutability: "view",
+ type: "function",
},
{
- "inputs": [],
- "name": "getStake",
- "outputs": [
+ inputs: [],
+ name: "getStake",
+ outputs: [
{
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
+ internalType: "uint256",
+ name: "",
+ type: "uint256",
+ },
],
- "stateMutability": "view",
- "type": "function"
+ stateMutability: "view",
+ type: "function",
},
{
- "inputs": [],
- "name": "getClaimable",
- "outputs": [
+ inputs: [],
+ name: "getClaimable",
+ outputs: [
{
- "internalType": "uint256",
- "name": "",
- "type": "uint256"
- }
+ internalType: "uint256",
+ name: "",
+ type: "uint256",
+ },
],
- "stateMutability": "view",
- "type": "function"
+ stateMutability: "view",
+ type: "function",
},
/**
* From ILiquidDelegation.sol
*/
{
- "inputs": [],
- "name": "getLST",
- "outputs": [
+ inputs: [],
+ name: "getLST",
+ outputs: [
{
- "internalType": "address",
- "name": "",
- "type": "address"
- }
+ internalType: "address",
+ name: "",
+ type: "address",
+ },
],
- "stateMutability": "view",
- "type": "function"
+ stateMutability: "view",
+ type: "function",
},
{
- "inputs": [],
- "name": "getPrice",
- "outputs": [
+ inputs: [],
+ name: "getPrice",
+ outputs: [
{
- "internalType": "uint256",
- "name": "amount",
- "type": "uint256"
- }
+ internalType: "uint256",
+ name: "amount",
+ type: "uint256",
+ },
],
- "stateMutability": "view",
- "type": "function"
+ stateMutability: "view",
+ type: "function",
},
-]
\ No newline at end of file
+]
diff --git a/src/misc/stakingPoolsConfig.ts b/src/misc/stakingPoolsConfig.ts
index ecb318d..0036c11 100644
--- a/src/misc/stakingPoolsConfig.ts
+++ b/src/misc/stakingPoolsConfig.ts
@@ -1,54 +1,71 @@
-import { Address, erc20Abi, formatUnits, parseUnits } from "viem";
-import { CHAIN_ZQ2_PROTOTESTNET, CHAIN_ZQ2_DOCKERCOMPOSE, getViemClient, MOCK_CHAIN, CHAIN_ZQ2_DEVNET, CHAIN_ZQ2_PROTOMAINNET } from "./chainConfig";
-import { readContract } from "viem/actions";
-import { delegatorAbi, depositAbi } from "./stakingAbis";
+import { Address, erc20Abi, formatUnits, parseUnits } from "viem"
+import {
+ CHAIN_ZQ2_PROTOTESTNET,
+ CHAIN_ZQ2_DOCKERCOMPOSE,
+ getViemClient,
+ MOCK_CHAIN,
+ CHAIN_ZQ2_DEVNET,
+ CHAIN_ZQ2_PROTOMAINNET,
+} from "./chainConfig"
+import { readContract } from "viem/actions"
+import { delegatorAbi, depositAbi } from "./stakingAbis"
/**
* Deposit address is always the same
*/
-const DEPOSIT_ADDRESS = "0x00000000005a494c4445504f53495450524f5859" as Address;
+const DEPOSIT_ADDRESS = "0x00000000005a494c4445504f53495450524f5859" as Address
export interface StakingPoolDefinition {
- id: string;
- name: string;
- address: string;
- tokenAddress: string;
- tokenDecimals: number;
- tokenSymbol: string;
- iconUrl: string;
- minimumStake: bigint;
- withdrawPeriodInMinutes: number;
+ id: string
+ name: string
+ address: string
+ tokenAddress: string
+ tokenDecimals: number
+ tokenSymbol: string
+ iconUrl: string
+ minimumStake: bigint
+ withdrawPeriodInMinutes: number
}
export interface StakingPoolData {
- tvl: bigint;
- apr: number;
- commission: number;
- votingPower: number;
- zilToTokenRate: number;
+ tvl: bigint
+ apr: number
+ commission: number
+ votingPower: number
+ zilToTokenRate: number
}
export interface StakingPool {
- definition: StakingPoolDefinition;
- data: StakingPoolData | null;
+ definition: StakingPoolDefinition
+ data: StakingPoolData | null
}
export interface StakingPoolConfig {
- definition: StakingPoolDefinition;
- delegatorDataProvider: (definition: StakingPoolDefinition, chainId: number) => Promise;
+ definition: StakingPoolDefinition
+ delegatorDataProvider: (
+ definition: StakingPoolDefinition,
+ chainId: number
+ ) => Promise
}
-async function mockDelegatorDataProvider(mockData: StakingPoolData, loadingMiliseconds: number, definition: StakingPoolDefinition, chainId: number): Promise {
+async function mockDelegatorDataProvider(
+ mockData: StakingPoolData,
+ loadingMiliseconds: number,
+ definition: StakingPoolDefinition,
+ chainId: number
+): Promise {
return new Promise((resolve) => {
setTimeout(() => {
- resolve(mockData);
- }, loadingMiliseconds);
- });
+ resolve(mockData)
+ }, loadingMiliseconds)
+ })
}
-async function fetchDelegatorDataFromNetwork(definition: StakingPoolDefinition, chainId: number): Promise {
-
- const viemClient = getViemClient(chainId);
+async function fetchDelegatorDataFromNetwork(
+ definition: StakingPoolDefinition,
+ chainId: number
+): Promise {
+ const viemClient = getViemClient(chainId)
const readDelegatorContract = async (functionName: string): Promise => {
return (await readContract(viemClient, {
@@ -58,8 +75,16 @@ async function fetchDelegatorDataFromNetwork(definition: StakingPoolDefinition,
})) as T
}
- const readTokenContract = async (functionName: "symbol" | "name" | "totalSupply" | "allowance" | "balanceOf" | "decimals"): Promise => {
- return await (readContract(viemClient, {
+ const readTokenContract = async (
+ functionName:
+ | "symbol"
+ | "name"
+ | "totalSupply"
+ | "allowance"
+ | "balanceOf"
+ | "decimals"
+ ): Promise => {
+ return (await readContract(viemClient, {
address: definition.tokenAddress as Address,
abi: erc20Abi,
functionName,
@@ -67,7 +92,7 @@ async function fetchDelegatorDataFromNetwork(definition: StakingPoolDefinition,
}
const readDepositContract = async (functionName: string): Promise => {
- return await (readContract(viemClient, {
+ return (await readContract(viemClient, {
address: DEPOSIT_ADDRESS,
abi: depositAbi,
functionName,
@@ -80,45 +105,53 @@ async function fetchDelegatorDataFromNetwork(definition: StakingPoolDefinition,
zilToTokenRateWei,
delegatorStake,
depositTotalStake,
- [commissionNumerator, commissionDenominator]
+ [commissionNumerator, commissionDenominator],
] = await Promise.all([
readTokenContract("totalSupply"),
readDelegatorContract("getPrice"),
readDelegatorContract("getStake"),
readDepositContract("getFutureTotalStake"),
readDelegatorContract<[bigint, bigint]>("getCommission"),
- ]);
+ ])
- const zilToTokenRate = 1 / parseFloat(formatUnits(zilToTokenRateWei, 18));
+ const zilToTokenRate = 1 / parseFloat(formatUnits(zilToTokenRateWei, 18))
- const bigintDivisionPrecision = 1000000n;
+ const bigintDivisionPrecision = 1000000n
- const commission = Number((commissionNumerator * bigintDivisionPrecision) / commissionDenominator) / Number(bigintDivisionPrecision);
- const votingPower = Number(((delegatorStake * bigintDivisionPrecision) / depositTotalStake)) / Number(bigintDivisionPrecision);
- const rewardsPerYearInZil = 51000 * 24 * 365;
+ const commission =
+ Number(
+ (commissionNumerator * bigintDivisionPrecision) / commissionDenominator
+ ) / Number(bigintDivisionPrecision)
+ const votingPower =
+ Number((delegatorStake * bigintDivisionPrecision) / depositTotalStake) /
+ Number(bigintDivisionPrecision)
+ const rewardsPerYearInZil = 51000 * 24 * 365
- const delegatorYearReward = votingPower * rewardsPerYearInZil;
- const delegatorRewardForShare = delegatorYearReward * (1 - commission);
- const apr = delegatorRewardForShare / parseFloat(formatUnits(delegatorStake, 18));
+ const delegatorYearReward = votingPower * rewardsPerYearInZil
+ const delegatorRewardForShare = delegatorYearReward * (1 - commission)
+ const apr =
+ delegatorRewardForShare / parseFloat(formatUnits(delegatorStake, 18))
return {
tvl: totalSupply,
commission,
zilToTokenRate,
votingPower,
- apr: apr
-
+ apr: apr,
}
} catch (error) {
- console.error("Error fetching total supply:", error);
- throw error;
+ console.error("Error fetching total supply:", error)
+ throw error
}
}
-const twoWeeksInMinutes = 60 * 24 * 14;
-const fiveMinutesInMinutes = 5;
+const twoWeeksInMinutes = 60 * 24 * 14
+const fiveMinutesInMinutes = 5
-export const stakingPoolsConfigForChainId: Record> = {
+export const stakingPoolsConfigForChainId: Record<
+ string,
+ Array
+> = {
[MOCK_CHAIN.id]: [
{
definition: {
@@ -133,7 +166,8 @@ export const stakingPoolsConfigForChainId: Record;
- zilAmount: Array;
- currentZil: bigint;
+ name: string
+ address: string
+ stakingTokenAmount: Array
+ zilAmount: Array
+ currentZil: bigint
}
export const dummyWallets: Array = [
@@ -66,12 +66,12 @@ export const dummyWallets: Array = [
{
address: "0x1234567890234567890234567890234567890",
stakingTokenAmount: parseUnits("1000.50", 18),
- rewardAcumulated: 10
+ rewardAcumulated: 10,
},
{
address: "0x96525678902345678902345678918278372212",
stakingTokenAmount: parseUnits("60.50", 18),
- rewardAcumulated: 50
+ rewardAcumulated: 50,
},
],
zilAmount: [],
@@ -84,12 +84,12 @@ export const dummyWallets: Array = [
{
address: "0x1234567890234567890234567890234567890",
stakingTokenAmount: parseUnits("1000", 18),
- rewardAcumulated: 10
+ rewardAcumulated: 10,
},
{
address: "0x96525678902345678902345678918278372212",
stakingTokenAmount: parseUnits("9991119", 18),
- rewardAcumulated: 50
+ rewardAcumulated: 50,
},
],
zilAmount: [
@@ -128,116 +128,121 @@ export const dummyWallets: Array = [
{
address: "0x96525678902345678902345678918278372212",
stakingTokenAmount: parseUnits("123.522039320", 18),
- rewardAcumulated: 40
+ rewardAcumulated: 40,
},
{
address: "0x82245678902345678902345678918278372382",
stakingTokenAmount: parseUnits("99999", 18),
- rewardAcumulated: 0
+ rewardAcumulated: 0,
},
],
zilAmount: [],
},
]
-export async function getWalletStakingData(wallet: string, chainId: number): Promise {
+export async function getWalletStakingData(
+ wallet: string,
+ chainId: number
+): Promise {
if (chainId === MOCK_CHAIN.id) {
return new Promise((resolve) => {
setTimeout(() => {
- resolve(dummyWallets.find((dw) => dw.address === wallet)?.stakingTokenAmount || []);
- }, 1000);
- });
+ resolve(
+ dummyWallets.find((dw) => dw.address === wallet)
+ ?.stakingTokenAmount || []
+ )
+ }, 1000)
+ })
} else {
const stakingData: UserStakingPoolData[] = await Promise.all(
- stakingPoolsConfigForChainId[chainId].map(
- async (pool) => {
- return {
- address: pool.definition.address,
- stakingTokenAmount: await readContract(getViemClient(chainId), {
- address: pool.definition.tokenAddress as Address,
- abi: erc20Abi,
- functionName: "balanceOf",
- args: [wallet as Address],
- }),
- rewardAcumulated: 0,
- }
+ stakingPoolsConfigForChainId[chainId].map(async (pool) => {
+ return {
+ address: pool.definition.address,
+ stakingTokenAmount: await readContract(getViemClient(chainId), {
+ address: pool.definition.tokenAddress as Address,
+ abi: erc20Abi,
+ functionName: "balanceOf",
+ args: [wallet as Address],
+ }),
+ rewardAcumulated: 0,
}
- )
+ })
)
- return stakingData;
+ return stakingData
}
}
-export async function getWalletUnstakingData(wallet: string, chainId: number): Promise {
+export async function getWalletUnstakingData(
+ wallet: string,
+ chainId: number
+): Promise {
if (chainId === MOCK_CHAIN.id) {
return new Promise((resolve) => {
setTimeout(() => {
- resolve(dummyWallets.find((dw) => dw.address === wallet)?.zilAmount || []);
- }, 1000);
- });
+ resolve(
+ dummyWallets.find((dw) => dw.address === wallet)?.zilAmount || []
+ )
+ }, 1000)
+ })
} else {
- const currentBlockNumber = await getViemClient(chainId).getBlockNumber();
+ const currentBlockNumber = await getViemClient(chainId).getBlockNumber()
// get unstaking data from contracts
- const unstakingWalletData = await Promise.all(
- stakingPoolsConfigForChainId[chainId].map(
- async (pool) => {
- return {
- address: pool.definition.address,
- blockNumberAndAmount: (await readContract(getViemClient(chainId), {
- address: pool.definition.address as Address,
- abi: delegatorAbi,
- functionName: "getPendingClaims",
- account: wallet as Address,
- })) as bigint[][],
- claimableNow: await readContract(getViemClient(chainId), {
- address: pool.definition.address as Address,
- abi: delegatorAbi,
- functionName: "getClaimable",
- account: wallet as Address,
- }) as bigint
- }
+ const unstakingWalletData = await Promise.all(
+ stakingPoolsConfigForChainId[chainId].map(async (pool) => {
+ return {
+ address: pool.definition.address,
+ blockNumberAndAmount: (await readContract(getViemClient(chainId), {
+ address: pool.definition.address as Address,
+ abi: delegatorAbi,
+ functionName: "getPendingClaims",
+ account: wallet as Address,
+ })) as bigint[][],
+ claimableNow: (await readContract(getViemClient(chainId), {
+ address: pool.definition.address as Address,
+ abi: delegatorAbi,
+ functionName: "getClaimable",
+ account: wallet as Address,
+ })) as bigint,
}
- )
+ })
)
// convert contracts raw data into application data
- const result: UserUnstakingPoolData[] = unstakingWalletData.filter(
- (uwd) => uwd.blockNumberAndAmount.length > 0 || uwd.claimableNow > 0
- ).map(
- (uwd) => {
-
- const claims: UserUnstakingPoolData[] = [];
+ const result: UserUnstakingPoolData[] = unstakingWalletData
+ .filter(
+ (uwd) => uwd.blockNumberAndAmount.length > 0 || uwd.claimableNow > 0
+ )
+ .map((uwd) => {
+ const claims: UserUnstakingPoolData[] = []
if (uwd.claimableNow > 0) {
claims.push({
zilAmount: uwd.claimableNow,
availableAt: DateTime.now().minus({ days: 1 }), // just to make sure it displays
address: uwd.address,
- });
+ })
}
if (uwd.blockNumberAndAmount.length > 0) {
claims.push(
- ...uwd.blockNumberAndAmount.map(
- (bna) => {
- const blocksRemaining = Number(bna[0] - currentBlockNumber);
+ ...uwd.blockNumberAndAmount.map((bna) => {
+ const blocksRemaining = Number(bna[0] - currentBlockNumber)
- return {
- zilAmount: bna[1],
- availableAt: DateTime.now().plus({ seconds: blocksRemaining }), // we assume block takes a second
- address: uwd.address,
- }
+ return {
+ zilAmount: bna[1],
+ availableAt: DateTime.now().plus({ seconds: blocksRemaining }), // we assume block takes a second
+ address: uwd.address,
}
- )
- );
+ })
+ )
}
- return claims;
- }
- ).flat();
+ return claims
+ })
+ .flat()
- return result;
+ return result
}
}
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index f51cfaa..6e03782 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -1,103 +1,103 @@
-import "@/styles/globals.css";
-import 'tailwindcss/tailwind.css';
-import '@rainbow-me/rainbowkit/styles.css';
-import { StakingPoolsStorage } from "@/contexts/stakingPoolsStorage";
-import type { AppProps } from "next/app";
-import { WalletConnector } from "@/contexts/walletConnector";
-import DummyWalletSelector from "@/components/dummyWalletSelector";
-import { ConfigProvider } from 'antd';
-import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
-import { WagmiProvider } from "wagmi";
-import { RainbowKitProvider } from "@rainbow-me/rainbowkit";
-import { StakingOperations } from "@/contexts/stakingOperations";
-import { getWagmiConfig } from "@/misc/chainConfig";
-import { useEffect, useState } from "react";
-import { AppConfig } from "./api/config";
-import { AppConfigStorage } from "@/contexts/appConfigStorage";
+import "@/styles/globals.css"
+import "tailwindcss/tailwind.css"
+import "@rainbow-me/rainbowkit/styles.css"
+import { StakingPoolsStorage } from "@/contexts/stakingPoolsStorage"
+import type { AppProps } from "next/app"
+import { WalletConnector } from "@/contexts/walletConnector"
+import DummyWalletSelector from "@/components/dummyWalletSelector"
+import { ConfigProvider } from "antd"
+import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
+import { WagmiProvider } from "wagmi"
+import { RainbowKitProvider } from "@rainbow-me/rainbowkit"
+import { StakingOperations } from "@/contexts/stakingOperations"
+import { getWagmiConfig } from "@/misc/chainConfig"
+import { useEffect, useState } from "react"
+import { AppConfig } from "./api/config"
+import { AppConfigStorage } from "@/contexts/appConfigStorage"
export default function App({ Component, pageProps }: AppProps) {
- const queryClient = new QueryClient();
- const [appConfig, setAppConfig] = useState(null);
- const [loadingPercentage, setLoadingPercentage] = useState(0);
- const [displayedPercentage, setDisplayedPercentage] = useState(0);
- const [fadeOut, setFadeOut] = useState(false);
+ const queryClient = new QueryClient()
+ const [appConfig, setAppConfig] = useState(null)
+ const [loadingPercentage, setLoadingPercentage] = useState(0)
+ const [displayedPercentage, setDisplayedPercentage] = useState(0)
+ const [fadeOut, setFadeOut] = useState(false)
useEffect(() => {
const fetchConfig = async () => {
- const startTime = Date.now();
- let progress = 0;
+ const startTime = Date.now()
+ let progress = 0
- const interval = setInterval(() => {
- progress += 10;
- setLoadingPercentage(progress);
+ const interval = setInterval(() => {
+ progress += 10
+ setLoadingPercentage(progress)
if (progress >= 100) {
- clearInterval(interval);
+ clearInterval(interval)
}
- }, 50);
+ }, 50)
try {
- const res = await fetch("/api/config");
- const data = await res.json();
- const elapsedTime = Date.now() - startTime;
+ const res = await fetch("/api/config")
+ const data = await res.json()
+ const elapsedTime = Date.now() - startTime
- const remainingTime = Math.max(1000 - elapsedTime, 0);
+ const remainingTime = Math.max(1000 - elapsedTime, 0)
setTimeout(() => {
- clearInterval(interval);
- setLoadingPercentage(100);
+ clearInterval(interval)
+ setLoadingPercentage(100)
setTimeout(() => {
- setAppConfig(data);
- }, 500);
- setFadeOut(true);
- }, remainingTime);
+ setAppConfig(data)
+ }, 500)
+ setFadeOut(true)
+ }, remainingTime)
} catch (error) {
- console.error("Error loading config:", error);
+ console.error("Error loading config:", error)
}
- };
+ }
- fetchConfig();
- }, []);
+ fetchConfig()
+ }, [])
useEffect(() => {
- const duration = 500;
- const frameRate = 16;
- const totalFrames = duration / frameRate;
- const increment = (loadingPercentage - displayedPercentage) / totalFrames;
+ const duration = 500
+ const frameRate = 16
+ const totalFrames = duration / frameRate
+ const increment = (loadingPercentage - displayedPercentage) / totalFrames
if (increment !== 0) {
- let currentFrame = 0;
+ let currentFrame = 0
const easingInterval = setInterval(() => {
setDisplayedPercentage((prev) => {
- currentFrame += 1;
- const next = prev + increment;
+ currentFrame += 1
+ const next = prev + increment
if (
currentFrame >= totalFrames ||
(increment > 0 && next >= loadingPercentage) ||
(increment < 0 && next <= loadingPercentage)
) {
- clearInterval(easingInterval);
- return loadingPercentage;
+ clearInterval(easingInterval)
+ return loadingPercentage
}
- return next;
- });
- }, frameRate);
+ return next
+ })
+ }, frameRate)
- return () => clearInterval(easingInterval);
+ return () => clearInterval(easingInterval)
}
- }, [loadingPercentage]);
+ }, [loadingPercentage])
if (!appConfig) {
return (
-
+ className={`h-screen bg-black text-white transition-opacity duration-500 ${
+ fadeOut ? "opacity-0" : "opacity-100"
+ }`}
+ >
+
@@ -106,13 +106,18 @@ export default function App({ Component, pageProps }: AppProps) {
- );
+ )
}
return (
-
+
@@ -128,5 +133,5 @@ export default function App({ Component, pageProps }: AppProps) {
- );
+ )
}
diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx
index e2b4f05..aa815db 100644
--- a/src/pages/_document.tsx
+++ b/src/pages/_document.tsx
@@ -1,4 +1,4 @@
-import { Html, Head, Main, NextScript } from 'next/document';
+import { Html, Head, Main, NextScript } from "next/document"
export default function Document() {
return (
@@ -15,5 +15,5 @@ export default function Document() {