Skip to content

Commit

Permalink
Merge pull request #476 from valory-xyz/tanya/needs-funds-main
Browse files Browse the repository at this point in the history
Tanya/needs funds main
  • Loading branch information
Tanya-atatakai authored Nov 21, 2024
2 parents 9e4f2da + 2157686 commit 96cafe0
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 68 deletions.
11 changes: 8 additions & 3 deletions frontend/components/MainPage/sections/NeedsFundsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { CustomAlert } from '@/components/Alert';
import { UNICODE_SYMBOLS } from '@/constants/symbols';
import { useElectronApi } from '@/hooks/useElectronApi';
import { useNeedsFunds } from '@/hooks/useNeedsFunds';
import { useServices } from '@/hooks/useServices';

import { CardSection } from '../../styled/CardSection';

Expand All @@ -28,6 +29,9 @@ export const MainNeedsFunds = () => {
needsInitialFunding,
} = useNeedsFunds();

const { selectedAgentConfig } = useServices();
const { homeChainId } = selectedAgentConfig;

const electronApi = useElectronApi();

const message: ReactNode = useMemo(
Expand All @@ -37,14 +41,14 @@ export const MainNeedsFunds = () => {
<Flex gap={24}>
{!hasEnoughOlasForInitialFunding && (
<div>
<FundingValue>{`${UNICODE_SYMBOLS.OLAS}${serviceFundRequirements.olas} OLAS `}</FundingValue>
<FundingValue>{`${UNICODE_SYMBOLS.OLAS}${serviceFundRequirements[homeChainId].olas} OLAS `}</FundingValue>
<span className="text-sm">for staking</span>
</div>
)}
{!hasEnoughEthForInitialFunding && (
<div>
<FundingValue>
{`$${serviceFundRequirements.eth} XDAI `}
{`$${serviceFundRequirements[homeChainId].eth} XDAI `}
</FundingValue>
<span className="text-sm">for trading</span>
</div>
Expand All @@ -56,9 +60,10 @@ export const MainNeedsFunds = () => {
</Flex>
),
[
hasEnoughOlasForInitialFunding,
serviceFundRequirements,
homeChainId,
hasEnoughEthForInitialFunding,
hasEnoughOlasForInitialFunding,
],
);

Expand Down
141 changes: 76 additions & 65 deletions frontend/hooks/useNeedsFunds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,20 @@ import { formatEther, formatUnits } from 'ethers/lib/utils';
import { useMemo } from 'react';

import { ServiceTemplate } from '@/client';
import { CHAIN_CONFIG } from '@/config/chains';
import { STAKING_PROGRAMS } from '@/config/stakingPrograms';
import { getNativeTokenSymbol } from '@/config/tokens';
import { getServiceTemplate } from '@/constants/serviceTemplates';
import { TokenSymbol } from '@/enums/Token';

import { useBalanceContext } from './useBalanceContext';
import { useBalanceContext, useMasterBalances } from './useBalanceContext';
import { useService } from './useService';
import { useStore } from './useStore';
import { TokenSymbol } from '@/enums/Token';
import { getNativeTokenSymbol, NATIVE_TOKEN_CONFIG } from '@/config/tokens';
import { useMasterWalletContext } from './useWallet';

export const useNeedsFunds = (serviceConfigId: string) => {
export const useNeedsFunds = (serviceConfigId?: string) => {
const { storeState } = useStore();
const { service } = useService({ serviceConfigId });
const { masterSafes } = useMasterWalletContext();
const { isLoaded: isBalanceLoaded, walletBalances } =
useBalanceContext();

const { isLoaded: isBalanceLoaded, walletBalances } = useBalanceContext();
const { masterSafeBalances } = useMasterBalances();

const isInitialFunded = storeState?.isInitialFunded;

Expand All @@ -28,35 +24,38 @@ export const useNeedsFunds = (serviceConfigId: string) => {
[service],
);

const serviceFundRequirements = useMemo< {
const serviceFundRequirements = useMemo<{
[chainId: number]: {
[tokenSymbol: string]: number;
}
[tokenSymbol: string]: number;
};
}>(() => {
if (!serviceTemplate) return {};

const results: {
[chainId: number]: {
[tokenSymbol: string]: number;
}
[tokenSymbol: string]: number;
};
} = {};

Object.entries(serviceTemplate.configurations).forEach(
([chainId, config]) => {
const serviceTemplateDefault = serviceTemplate.configurations[+chainId].staking_program_id
const serviceCurrent = service?.chain_configs[+chainId]?.chain_data?.user_params?.staking_program_id

if (!serviceCurrent && !serviceTemplateDefault) return;

const templateStakingProgramId =
serviceTemplate.configurations[+chainId].staking_program_id;
const serviceStakingProgramId =
service?.chain_configs[+chainId]?.chain_data?.user_params
?.staking_program_id;
const stakingProgramId =
serviceStakingProgramId ?? templateStakingProgramId;

if (!stakingProgramId) return;
if (!service?.chain_configs[+chainId]) return;

const gasEstimate = config.monthly_gas_estimate;
const monthlyGasEstimate = Number(formatUnits(`${gasEstimate}`, 18));
const minimumStakedAmountRequired =
STAKING_PROGRAMS[+chainId][
service?.chain_configs[+chainId]?.chain_data?.user_params
?.staking_program_id ??
serviceTemplate.configurations[+chainId].staking_program_id
].stakingRequirements.OLAS;
STAKING_PROGRAMS[+chainId]?.[stakingProgramId]?.stakingRequirements?.[
TokenSymbol.OLAS
] || 0;

const nativeTokenSymbol = getNativeTokenSymbol(+chainId);

Expand All @@ -69,48 +68,60 @@ export const useNeedsFunds = (serviceConfigId: string) => {
);

return results;
}, [serviceTemplate]);

const hasEnoughEthForInitialFunding = useMemo(
() => {
if (!serviceFundRequirements) return ;
if (!walletBalances) return ;

const nativeBalancesByChain = walletBalances.reduce<{[chainId: number]: number}>((acc, {symbol, balance, chainId}) => {
if (getNativeTokenSymbol(chainId) !== symbol) return acc;

if (!acc[chainId]) acc[chainId] = 0;
acc[chainId] += balance;

return acc;
}, {});

const chainIds = Object.keys(serviceFundRequirements).map(Number);

return chainIds.every(chainId => {
const nativeTokenSymbol = getNativeTokenSymbol(chainId);
const nativeTokenBalance = nativeBalancesByChain[chainId] || 0;
const nativeTokenRequired = serviceFundRequirements[chainId]?.[nativeTokenSymbol] || 0;

return nativeTokenBalance >= nativeTokenRequired;
});

},
[],
);
}, [service?.chain_configs, serviceTemplate]);

const hasEnoughEthForInitialFunding = useMemo(() => {
if (!serviceFundRequirements) return;
if (!walletBalances) return;

const nativeBalancesByChain = walletBalances.reduce<{
[chainId: number]: number;
}>((acc, { symbol, balance, chainId }) => {
if (getNativeTokenSymbol(chainId) !== symbol) return acc;

if (!acc[chainId]) acc[chainId] = 0;
acc[chainId] += balance;

return acc;
}, {});

const chainIds = Object.keys(serviceFundRequirements).map(Number);

return chainIds.every((chainId) => {
const nativeTokenSymbol = getNativeTokenSymbol(chainId);
const nativeTokenBalance = nativeBalancesByChain[chainId] || 0;
const nativeTokenRequired =
serviceFundRequirements[chainId]?.[nativeTokenSymbol] || 0;

return nativeTokenBalance >= nativeTokenRequired;
});
}, [serviceFundRequirements, walletBalances]);

// TODO: refactor this to use the new balance context
const hasEnoughOlasForInitialFunding = useMemo(() => {
const olasInSafe = safeBalance?.OLAS || 0;
const olasStakedBySafe = totalStakedOlasBalance || 0;
const olasRequiredToFundService = serviceFundRequirements.olas || 0;
const olasInSafeAndStaked = olasInSafe + olasStakedBySafe;
return olasInSafeAndStaked >= olasRequiredToFundService;
}, [
safeBalance?.OLAS,
totalStakedOlasBalance,
serviceFundRequirements?.olas,
]);
if (!serviceFundRequirements) return;
if (!masterSafeBalances) return;

const olasBalancesByChain = masterSafeBalances.reduce<{
[chainId: number]: number;
}>((acc, { symbol, balance, chainId }) => {
if (TokenSymbol.OLAS !== symbol) return acc;

if (!acc[chainId]) acc[chainId] = 0;
acc[chainId] += balance;

return acc;
}, {});

const chainIds = Object.keys(serviceFundRequirements).map(Number);

return chainIds.every((chainId) => {
const olasBalance = olasBalancesByChain[chainId] || 0;
const olasRequired =
serviceFundRequirements[chainId]?.[TokenSymbol.OLAS] || 0;

return olasBalance >= olasRequired;
});
}, [masterSafeBalances, serviceFundRequirements]);

const needsInitialFunding: boolean = useMemo(() => {
if (isInitialFunded) return false;
Expand Down

0 comments on commit 96cafe0

Please sign in to comment.