diff --git a/src/components/LoadingSpinner.tsx b/src/components/LoadingSpinner.tsx index 3bcbf1e..501e3b8 100644 --- a/src/components/LoadingSpinner.tsx +++ b/src/components/LoadingSpinner.tsx @@ -1,6 +1,6 @@ const LoadingSpinner = () => { return ( -
+
{ return (
-

+

Claim Vesting + {isBalanceLoading ? : null}

{!selectedAccount ? ( @@ -253,8 +254,6 @@ const Claim = () => {
) : null} - {isBalanceLoading ? : null} - {!isBalanceLoading && selectedAccount && vestingSummary ? (
diff --git a/src/routes/overview.tsx b/src/routes/overview.tsx index 3dbc0aa..7f11c45 100644 --- a/src/routes/overview.tsx +++ b/src/routes/overview.tsx @@ -20,6 +20,7 @@ import { loadProjectCores, loadStakedDaos } from '../utils/stakingServices'; import { StakingCore, CoreEraStakedInfoType, UserStakedInfoType, ChainPropertiesType, TotalUserStakedData, StakedType, BalanceType, LockedType, CoreEraStakeType, LedgerType, TotalRewardsClaimedSubscription, TotalRewardsClaimedQuery, RewardQueryType, getCoreInfo, getTotalUserStaked } from "./staking"; import { calculateVestingData, fetchSystemData } from "../utils/vestingServices"; import OnOffSwitch from "../components/Switch"; +import { formatBalance } from "@polkadot/util"; export type StakedDaoType = StakingCore & { members?: AnyJson; }; @@ -337,7 +338,7 @@ const Overview = () => { }); }; - const handleAutoRestake = (bool: boolean) => { + const handleAutoRestakeSwitch = (bool: boolean) => { // use toasts to show if auto-restake is enabled or disabled if (bool) { toast.success("Auto-restake enabled"); @@ -348,6 +349,33 @@ const Overview = () => { localStorage.setItem("autoRestake", JSON.stringify(bool)); }; + const handleRestakingLogic = () => { + // grab the total unclaimed rewards and account for the existential deposit + const unclaimedMinusED = new BigNumber(totalUnclaimed); + + // Check if unclaimedMinusED is a valid number + if (isNaN(unclaimedMinusED.toNumber())) { + console.error("Invalid unclaimedMinusED"); + return; + } + + if (unclaimedMinusED.toNumber() <= 0) { + console.error("unclaimedMinusED must be greater than 0"); + return; + } + + // Check if stakedDaos.length is a valid number and not zero to avoid division by zero + if (isNaN(stakedDaos.length) || stakedDaos.length === 0) { + console.error("Invalid stakedDaos.length"); + return; + } + + // divide unclaimedMinusED by the number of stakedDaos the user is part of + const unclaimedPerCore = unclaimedMinusED.div(stakedDaos.length); + + return unclaimedPerCore; + }; + const handleClaimAll = async () => { if (!selectedAccount) return; @@ -367,28 +395,38 @@ const Overview = () => { const uniqueCores = [ ...new Map(unclaimedEras.cores.map((x) => [x.coreId, x])).values(), ]; - + console.log("uniqueCores", uniqueCores); for (const core of uniqueCores) { if (!core?.earliestEra) continue; - if (typeof currentStakingEra === 'number' && core && typeof core.earliestEra === 'number') { - if (core.earliestEra <= currentStakingEra) { - const iterations = currentStakingEra - core.earliestEra; - for (let i = 0; i < iterations; i++) { - batch.push(api.tx.ocifStaking.stakerClaimRewards(core.coreId)); - console.log("pushed core: ", core.coreId); - } - } else { - console.error("core.earliestEra is greater than currentStakingEra"); + const localEarliestEra = core.earliestEra; // Create a local copy of core.earliestEra + + if (typeof currentStakingEra === 'number' && core && typeof localEarliestEra === 'number') { + for (let i = 0; i < currentStakingEra - localEarliestEra; i++) { + batch.push(api.tx.ocifStaking.stakerClaimRewards(core.coreId)); } } else { - console.error("currentStakingEra, core, or core.earliestEra is undefined or not a number"); + console.error("currentStakingEra, core, or localEarliestEra is undefined or not a number"); } + + console.log("utility.batch", batch); } - console.log("batch: ", batch); - console.log("uniqueCores: ", uniqueCores); - console.log("unclaimedEras: ", unclaimedEras); + if (enableAutoRestake) { + for (const core of uniqueCores) { + if (!core?.earliestEra) continue; + + // using the restaking logic, calculate the amount to restake + const restakeAmount = handleRestakingLogic(); + // Check if restakeAmount is not zero + if (restakeAmount && !restakeAmount.isZero()) { + // Convert restakeAmount to an integer string + const restakeAmountInteger = restakeAmount.integerValue().toString(); + // push restake tx to the batch + batch.push(api.tx.ocifStaking.stake(core.coreId, restakeAmountInteger)); + } + } + } await api.tx.utility.batch(batch).signAndSend( selectedAccount.address, @@ -581,20 +619,14 @@ const Overview = () => { setTotalUnclaimed(totalUnclaimed); }, [selectedAccount, rewardsClaimedQuery]); - if (isLoading) { - return ( -
- -
- ); - } - return (
-

+

Account Overview + {isLoading || !isDataLoaded ? : null}

+ {selectedAccount &&
- handleAutoRestake(bool)} /> + handleAutoRestakeSwitch(bool)} />
Auto-Restake
diff --git a/src/routes/staking.tsx b/src/routes/staking.tsx index 8b0370a..760113e 100644 --- a/src/routes/staking.tsx +++ b/src/routes/staking.tsx @@ -635,21 +635,15 @@ const Staking = () => { setTotalClaimed(rewardsClaimed); }, [selectedAccount, rewardsClaimedQuery]); - if (isLoading) { - return ( -
- -
- ); - } - return (
-

+

DAO Staking + {isLoading || !isDataLoaded ? : null}

+ {selectedAccount ? ( <> { return (
-

+

Asset Transfers + {isLoading ? : null}

{!selectedAccount ? ( @@ -430,12 +431,6 @@ const Transfer = () => {
) : null} - {isLoading ? ( -
- -
- ) : null} - {!isLoading && selectedAccount ? (