From 1243e2e14b01bc8c53fcf44cece079e894af61b2 Mon Sep 17 00:00:00 2001 From: mohandast52 Date: Wed, 18 Dec 2024 16:44:55 +0530 Subject: [PATCH 1/7] feat: enhance wallet page components with middleware chain support --- frontend/components/YourWalletPage/Titles.tsx | 15 +++- frontend/components/YourWalletPage/index.tsx | 82 +++++++++---------- frontend/hooks/useFeatureFlag.ts | 2 +- 3 files changed, 54 insertions(+), 45 deletions(-) diff --git a/frontend/components/YourWalletPage/Titles.tsx b/frontend/components/YourWalletPage/Titles.tsx index c5f46af9b..7a6cb8e93 100644 --- a/frontend/components/YourWalletPage/Titles.tsx +++ b/frontend/components/YourWalletPage/Titles.tsx @@ -1,5 +1,6 @@ import { Flex, Typography } from 'antd'; +import { MiddlewareChain } from '@/client'; import { InfoTooltip } from '@/components/InfoTooltip'; import { TokenSymbol } from '@/enums/Token'; import { Address } from '@/types/Address'; @@ -8,11 +9,16 @@ import { AddressLink } from '../AddressLink'; const { Paragraph, Text, Title } = Typography; -type SignerTitleProps = { signerText: string; signerAddress?: Address }; +type SignerTitleProps = { + signerText: string; + signerAddress: Address; + middlewareChain: MiddlewareChain; +}; export const SignerTitle = ({ signerText, signerAddress, + middlewareChain, }: SignerTitleProps) => ( <> Signer  @@ -28,7 +34,10 @@ export const SignerTitle = ({ {signerText} - + @@ -58,7 +67,7 @@ export const NativeTokenTitle = ({ symbol }: { symbol: TokenSymbol }) => (   - {/* TODO: address multi-agent tooltip, specfic to agent config */} + {/* TODO: address multi-agent tooltip, specific to agent config */} {symbol} is used by the agent to engage in prediction markets. This amount will fluctuate based on your agent's performance. diff --git a/frontend/components/YourWalletPage/index.tsx b/frontend/components/YourWalletPage/index.tsx index 3a221f407..e487405c3 100644 --- a/frontend/components/YourWalletPage/index.tsx +++ b/frontend/components/YourWalletPage/index.tsx @@ -7,7 +7,7 @@ import { ThemeConfig, Typography, } from 'antd'; -import { isEmpty, isNil } from 'lodash'; +import { isNil } from 'lodash'; import { useMemo } from 'react'; import { AddressLink } from '@/components/AddressLink'; @@ -15,7 +15,6 @@ import { CardTitle } from '@/components/Card/CardTitle'; import { InfoBreakdownList } from '@/components/InfoBreakdown'; import { CardFlex } from '@/components/styled/CardFlex'; import { getNativeTokenSymbol } from '@/config/tokens'; -import { EvmChainId } from '@/enums/Chain'; import { Pages } from '@/enums/Pages'; import { TokenSymbol } from '@/enums/Token'; import { @@ -43,13 +42,26 @@ const yourWalletTheme: ThemeConfig = { }, }; -const Address = () => { - const { masterSafes } = useMasterWalletContext(); +const useYourWallet = () => { + const { selectedAgentConfig } = useServices(); + const { isLoading: isMasterSafeLoading, masterSafes } = + useMasterWalletContext(); + + return { + middlewareChain: selectedAgentConfig?.middlewareHomeChainId, + evmHomeChainId: selectedAgentConfig?.evmHomeChainId, + isMasterSafeLoading, + masterSafeAddress: masterSafes?.find( + ({ evmChainId }) => evmChainId === selectedAgentConfig?.evmHomeChainId, + )?.address, + }; +}; - if (!masterSafes) return ; - if (isEmpty(masterSafes)) return null; +const Address = () => { + const { isMasterSafeLoading, masterSafeAddress, middlewareChain } = + useYourWallet(); - const masterSafeAddress = masterSafes[0].address; // TODO: handle multiple safes in future + if (isMasterSafeLoading) return ; return ( @@ -58,7 +70,12 @@ const Address = () => { { left: 'Address', leftClassName: 'text-light', - right: , + right: ( + + ), rightClassName: 'font-normal', }, ]} @@ -107,49 +124,34 @@ const OlasBalance = () => { }; const MasterSafeNativeBalance = () => { - const { selectedAgentConfig } = useServices(); - const { masterSafes } = useMasterWalletContext(); + const { evmHomeChainId, masterSafeAddress } = useYourWallet(); const { masterSafeBalances } = useMasterBalances(); - const selectedMasterSafe = useMemo(() => { - if (!masterSafes) return; - if (!selectedAgentConfig) return; + const nativeTokenSymbol = getNativeTokenSymbol(evmHomeChainId); - return masterSafes.find( - (masterSafe) => - masterSafe.evmChainId === selectedAgentConfig.evmHomeChainId, - ); - }, [masterSafes, selectedAgentConfig]); - - const selectedMasterSafeNativeBalance: Optional = useMemo(() => { - if (isNil(selectedMasterSafe)) return; + const masterSafeNativeBalance: Optional = useMemo(() => { + if (isNil(masterSafeAddress)) return; if (isNil(masterSafeBalances)) return; return masterSafeBalances .filter(({ walletAddress, evmChainId, isNative }) => { return ( - evmChainId === selectedAgentConfig?.evmHomeChainId && // TODO: address multi chain, need to refactor as per product requirement + evmChainId === evmHomeChainId && // TODO: address multi chain, need to refactor as per product requirement isNative && - walletAddress === selectedMasterSafe.address + walletAddress === masterSafeAddress ); }) .reduce((acc, { balance }) => acc + balance, 0); - }, [ - masterSafeBalances, - selectedAgentConfig?.evmHomeChainId, - selectedMasterSafe, - ]); - - const nativeTokenSymbol = getNativeTokenSymbol(EvmChainId.Gnosis); + }, [masterSafeBalances, masterSafeAddress, evmHomeChainId]); return ( {getNativeTokenSymbol(EvmChainId.Gnosis)}, + left: {nativeTokenSymbol}, leftClassName: 'text-light', - right: `${balanceFormat(selectedMasterSafeNativeBalance, 2)} ${nativeTokenSymbol}`, + right: `${balanceFormat(masterSafeNativeBalance, 2)} ${nativeTokenSymbol}`, }, ]} parentStyle={infoBreakdownParentStyle} @@ -161,7 +163,9 @@ const MasterSafeNativeBalance = () => { const MasterEoaSignerNativeBalance = () => { const { masterEoa } = useMasterWalletContext(); const { masterWalletBalances } = useMasterBalances(); - const { selectedAgentConfig } = useServices(); + const { evmHomeChainId, middlewareChain } = useYourWallet(); + + const nativeTokenSymbol = getNativeTokenSymbol(evmHomeChainId); const masterEoaBalance: Optional = useMemo(() => { if (isNil(masterEoa)) return; @@ -172,25 +176,21 @@ const MasterEoaSignerNativeBalance = () => { ({ walletAddress, isNative, evmChainId }) => walletAddress === masterEoa.address && isNative && - selectedAgentConfig?.evmHomeChainId === evmChainId, // TODO: address multi chain, need to refactor as per product requirement + evmHomeChainId === evmChainId, // TODO: address multi chain, need to refactor as per product requirement ) .reduce((acc, { balance }) => acc + balance, 0); - }, [masterEoa, masterWalletBalances, selectedAgentConfig?.evmHomeChainId]); - - const nativeTokenSymbol = useMemo( - () => getNativeTokenSymbol(EvmChainId.Gnosis), // TODO: support multi chain - [], - ); + }, [masterEoa, masterWalletBalances, evmHomeChainId]); return ( ), leftClassName: 'text-light', diff --git a/frontend/hooks/useFeatureFlag.ts b/frontend/hooks/useFeatureFlag.ts index bfd9ec18d..684a3afd0 100644 --- a/frontend/hooks/useFeatureFlag.ts +++ b/frontend/hooks/useFeatureFlag.ts @@ -33,7 +33,7 @@ const FEATURES_CONFIG = FeaturesConfigSchema.parse({ 'low-funds': true, }, [AgentType.Memeooorr]: { - 'manage-wallet': false, + 'manage-wallet': true, 'last-transactions': false, 'rewards-streak': false, 'staking-contract-section': false, From f1bb7c4592eb121b6503364e1e4e2b6cf8af3c7e Mon Sep 17 00:00:00 2001 From: mohandast52 Date: Wed, 18 Dec 2024 16:52:03 +0530 Subject: [PATCH 2/7] feat: add feature flag for conditional rendering of WithdrawFunds component --- .../components/YourWalletPage/YourAgent.tsx | 17 +++++++++++------ frontend/hooks/useFeatureFlag.ts | 5 ++++- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/frontend/components/YourWalletPage/YourAgent.tsx b/frontend/components/YourWalletPage/YourAgent.tsx index 271cfa809..5c753f190 100644 --- a/frontend/components/YourWalletPage/YourAgent.tsx +++ b/frontend/components/YourWalletPage/YourAgent.tsx @@ -14,6 +14,7 @@ import { useBalanceContext, useServiceBalances, } from '@/hooks/useBalanceContext'; +import { useFeatureFlag } from '@/hooks/useFeatureFlag'; import { useReward } from '@/hooks/useReward'; import { useService } from '@/hooks/useService'; import { useServices } from '@/hooks/useServices'; @@ -273,9 +274,13 @@ const YourAgentWalletBreakdown = () => { ); }; -export const YourAgentWallet = () => ( - <> - - - -); +export const YourAgentWallet = () => { + const isWithdrawFundsEnabled = useFeatureFlag('withdraw-funds'); + + return ( + <> + + {isWithdrawFundsEnabled && } + + ); +}; diff --git a/frontend/hooks/useFeatureFlag.ts b/frontend/hooks/useFeatureFlag.ts index 684a3afd0..cba253631 100644 --- a/frontend/hooks/useFeatureFlag.ts +++ b/frontend/hooks/useFeatureFlag.ts @@ -6,8 +6,9 @@ import { assertRequired } from '@/types/Util'; import { useServices } from './useServices'; const FeatureFlagsSchema = z.enum([ - 'last-transactions', 'manage-wallet', + 'withdraw-funds', + 'last-transactions', 'rewards-streak', 'staking-contract-section', 'low-funds', @@ -27,6 +28,7 @@ const FeaturesConfigSchema = z.record( const FEATURES_CONFIG = FeaturesConfigSchema.parse({ [AgentType.PredictTrader]: { 'manage-wallet': true, + 'withdraw-funds': true, 'last-transactions': true, 'rewards-streak': true, 'staking-contract-section': true, @@ -34,6 +36,7 @@ const FEATURES_CONFIG = FeaturesConfigSchema.parse({ }, [AgentType.Memeooorr]: { 'manage-wallet': true, + 'withdraw-funds': false, 'last-transactions': false, 'rewards-streak': false, 'staking-contract-section': false, From 437ab496797db3710d702b1749b90ed01d542dbd Mon Sep 17 00:00:00 2001 From: mohandast52 Date: Wed, 18 Dec 2024 16:53:50 +0530 Subject: [PATCH 3/7] feat: disable withdrawal for mememooorr --- frontend/components/YourWalletPage/WithdrawFunds.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frontend/components/YourWalletPage/WithdrawFunds.tsx b/frontend/components/YourWalletPage/WithdrawFunds.tsx index b268b8807..28f1ced3f 100644 --- a/frontend/components/YourWalletPage/WithdrawFunds.tsx +++ b/frontend/components/YourWalletPage/WithdrawFunds.tsx @@ -5,6 +5,7 @@ import React, { useCallback, useMemo, useState } from 'react'; import { COLOR } from '@/constants/colors'; import { useBalanceContext } from '@/hooks/useBalanceContext'; +import { useFeatureFlag } from '@/hooks/useFeatureFlag'; import { useService } from '@/hooks/useService'; import { useServices } from '@/hooks/useServices'; import { useStakingContractCountdown } from '@/hooks/useStakingContractCountdown'; @@ -14,6 +15,7 @@ import { ServicesService } from '@/service/Services'; import { Address } from '@/types/Address'; import { CustomAlert } from '../Alert'; +import { FeatureNotEnabled } from '../FeatureNotEnabled'; const { Text } = Typography; @@ -54,7 +56,6 @@ const CompatibleMessage = () => ( export const WithdrawFunds = () => { const { selectedService, refetch: refetchServices } = useServices(); const { refetch: refetchMasterWallets } = useMasterWalletContext(); - const { updateBalances } = useBalanceContext(); const { service, isServiceRunning } = useService( @@ -64,6 +65,7 @@ export const WithdrawFunds = () => { const { isServiceStakedForMinimumDuration, selectedStakingContractDetails } = useActiveStakingContractDetails(); + // state const [isModalVisible, setIsModalVisible] = useState(false); const [withdrawAddress, setWithdrawAddress] = useState(''); const [isWithdrawalLoading, setIsWithdrawalLoading] = useState(false); @@ -148,6 +150,9 @@ export const WithdrawFunds = () => { [service, isServiceStakedForMinimumDuration, showModal], ); + const isWithdrawFundsEnabled = useFeatureFlag('withdraw-funds'); + if (!isWithdrawFundsEnabled) return ; + return ( <> {isServiceStakedForMinimumDuration ? ( From e98877cc0e7a46460405366931327209a65c05fb Mon Sep 17 00:00:00 2001 From: mohandast52 Date: Wed, 18 Dec 2024 17:47:00 +0530 Subject: [PATCH 4/7] feat: add BlockScout URL mapping and refactor wallet hooks for improved state management --- frontend/components/AddressLink.tsx | 7 +- .../components/YourWalletPage/YourAgent.tsx | 117 +++++++++++------- frontend/components/YourWalletPage/index.tsx | 18 +-- .../YourWalletPage/useYourWallet.ts | 34 +++++ frontend/constants/urls.ts | 8 ++ 5 files changed, 115 insertions(+), 69 deletions(-) create mode 100644 frontend/components/YourWalletPage/useYourWallet.ts diff --git a/frontend/components/AddressLink.tsx b/frontend/components/AddressLink.tsx index 3f005a59f..9f8c56c6c 100644 --- a/frontend/components/AddressLink.tsx +++ b/frontend/components/AddressLink.tsx @@ -7,16 +7,13 @@ import { truncateAddress } from '@/utils/truncate'; type AddressLinkProps = { address?: Address; hideLinkArrow?: boolean; - - // TODO: mark as required once balance breakdown is updated. - // and remove the default value - middlewareChain?: MiddlewareChain; + middlewareChain: MiddlewareChain; }; export const AddressLink = ({ address, hideLinkArrow = false, - middlewareChain = MiddlewareChain.GNOSIS, + middlewareChain, }: AddressLinkProps) => { if (!address) return null; if (!middlewareChain) return null; diff --git a/frontend/components/YourWalletPage/YourAgent.tsx b/frontend/components/YourWalletPage/YourAgent.tsx index 5c753f190..c92027d24 100644 --- a/frontend/components/YourWalletPage/YourAgent.tsx +++ b/frontend/components/YourWalletPage/YourAgent.tsx @@ -4,12 +4,12 @@ import Image from 'next/image'; import { useMemo } from 'react'; import styled from 'styled-components'; +import { MiddlewareChain } from '@/client'; import { OLAS_CONTRACTS } from '@/config/olasContracts'; -import { UNICODE_SYMBOLS } from '@/constants/symbols'; -import { EvmChainId } from '@/enums/Chain'; +import { NA, UNICODE_SYMBOLS } from '@/constants/symbols'; +import { BLOCKSCOUT_URL_BY_MIDDLEWARE_CHAIN } from '@/constants/urls'; import { ContractType } from '@/enums/Contract'; import { TokenSymbol } from '@/enums/Token'; -import { AgentSafe, Safe } from '@/enums/Wallet'; import { useBalanceContext, useServiceBalances, @@ -27,6 +27,7 @@ import { AddressLink } from '../AddressLink'; import { InfoBreakdownList } from '../InfoBreakdown'; import { Container, infoBreakdownParentStyle } from './styles'; import { OlasTitle, OwnershipNftTitle, ServiceNftIdTitle } from './Titles'; +import { useYourWallet } from './useYourWallet'; import { WithdrawFunds } from './WithdrawFunds'; const { Text, Paragraph } = Typography; @@ -40,8 +41,8 @@ const NftCard = styled(Card)` } `; -const SafeAddress = ({ serviceSafe }: { serviceSafe: Safe }) => { - const multisigAddress = serviceSafe.address; +const SafeAddress = ({ address }: { address: Address }) => { + const { middlewareChain } = useYourWallet(); return ( @@ -50,7 +51,12 @@ const SafeAddress = ({ serviceSafe }: { serviceSafe: Safe }) => { { left: 'Wallet Address', leftClassName: 'text-light text-sm', - right: , + right: ( + + ), rightClassName: 'font-normal text-sm', }, ]} @@ -60,11 +66,16 @@ const SafeAddress = ({ serviceSafe }: { serviceSafe: Safe }) => { ); }; -const AgentTitle = ({ serviceSafe }: { serviceSafe: AgentSafe }) => { - const agentName = useMemo( - () => (serviceSafe ? generateName(serviceSafe.address) : '--'), - [serviceSafe], - ); +const AgentTitle = ({ address }: { address: Address }) => { + const { middlewareChain } = useYourWallet(); + + const agentProfileLink = useMemo(() => { + if (!address) return null; + if (middlewareChain === MiddlewareChain.GNOSIS) { + return `https://predict.olas.network/agents/${address}`; + } + return null; + }, [address, middlewareChain]); return ( @@ -90,16 +101,14 @@ const AgentTitle = ({ serviceSafe }: { serviceSafe: AgentSafe }) => { } placement="top" > - {agentName} + {address ? generateName(address) : NA} - {/* TODO: address multi-agent at later point */} - - Agent profile {UNICODE_SYMBOLS.EXTERNAL_LINK} - + + {agentProfileLink && ( + + Agent profile {UNICODE_SYMBOLS.EXTERNAL_LINK} + + )} @@ -107,13 +116,14 @@ const AgentTitle = ({ serviceSafe }: { serviceSafe: AgentSafe }) => { ); }; +type ServiceAndNftDetailsProps = { serviceNftTokenId: number }; const ServiceAndNftDetails = ({ serviceNftTokenId, -}: { - serviceNftTokenId: number; -}) => { +}: ServiceAndNftDetailsProps) => { + const { middlewareChain, evmHomeChainId } = useYourWallet(); + const serviceRegistryL2ContractAddress = - OLAS_CONTRACTS[EvmChainId.Gnosis][ContractType.ServiceRegistryL2].address; + OLAS_CONTRACTS[evmHomeChainId][ContractType.ServiceRegistryL2].address; return ( @@ -130,7 +140,7 @@ const ServiceAndNftDetails = ({ {truncateAddress(serviceRegistryL2ContractAddress as Address)}{' '} @@ -141,7 +151,7 @@ const ServiceAndNftDetails = ({ {serviceNftTokenId} {UNICODE_SYMBOLS.EXTERNAL_LINK} @@ -156,12 +166,13 @@ const ServiceAndNftDetails = ({ const YourAgentWalletBreakdown = () => { const { isLoaded } = useBalanceContext(); const { selectedService } = useServices(); - const { serviceSafes, serviceNftTokenId, serviceEoa } = useService( + const { serviceNftTokenId, serviceEoa } = useService( selectedService?.service_config_id, ); const { serviceSafeBalances, serviceEoaBalances } = useServiceBalances( selectedService?.service_config_id, ); + const { serviceSafe, middlewareChain, evmHomeChainId } = useYourWallet(); const { availableRewardsForEpochEth, @@ -171,23 +182,27 @@ const YourAgentWalletBreakdown = () => { const reward = useMemo(() => { if (!isLoaded) return ; - if (!isEligibleForRewards) return 'Not yet earned'; - return `~${balanceFormat(availableRewardsForEpochEth, 2)} OLAS`; + if (isEligibleForRewards) { + return `~${balanceFormat(availableRewardsForEpochEth, 2)} OLAS`; + } + + return 'Not yet earned'; }, [isLoaded, isEligibleForRewards, availableRewardsForEpochEth]); - const serviceSafeOlasBalances = useMemo( + const serviceSafeOlas = useMemo( () => - serviceSafeBalances?.filter( - (walletBalance) => walletBalance.symbol === TokenSymbol.OLAS, + serviceSafeBalances?.find( + ({ symbol, evmChainId }) => + symbol === TokenSymbol.OLAS && evmChainId === evmHomeChainId, ), - [serviceSafeBalances], + [serviceSafeBalances, evmHomeChainId], ); const serviceSafeRewards = useMemo( () => [ { title: 'Claimed rewards', - value: `${balanceFormat(serviceSafeOlasBalances?.[0]?.balance ?? 0, 2)} OLAS`, + value: `${balanceFormat(serviceSafeOlas?.balance ?? 0, 2)} OLAS`, }, { title: 'Unclaimed rewards', @@ -198,30 +213,31 @@ const YourAgentWalletBreakdown = () => { value: reward, }, ], - [accruedServiceStakingRewards, reward, serviceSafeOlasBalances], + [accruedServiceStakingRewards, reward, serviceSafeOlas], ); const serviceSafeNativeBalances = useMemo( - () => serviceSafeBalances?.filter((balance) => balance.isNative), - [serviceSafeBalances], + () => + serviceSafeBalances?.filter( + ({ isNative, evmChainId }) => isNative && evmChainId === evmHomeChainId, + ), + [serviceSafeBalances, evmHomeChainId], ); const serviceEoaNativeBalances = useMemo( - () => serviceEoaBalances?.filter((balance) => balance.isNative), - [serviceEoaBalances], + () => + serviceEoaBalances?.filter( + ({ isNative, evmChainId }) => isNative && evmChainId === evmHomeChainId, + ), + [serviceEoaBalances, evmHomeChainId], ); - const serviceSafe = useMemo(() => { - if (isNil(serviceSafes) || isEmpty(serviceSafes)) return null; - return serviceSafes[0]; - }, [serviceSafes]); - - if (isNil(serviceSafe)) return null; + if (!serviceSafe) return null; return ( - }> + }> - + {!isEmpty(serviceSafeRewards) && ( @@ -256,7 +272,12 @@ const YourAgentWalletBreakdown = () => { { left: 'Signer', leftClassName: 'text-sm', - right: , + right: ( + + ), rightClassName: 'font-normal text-sm', }, ]} diff --git a/frontend/components/YourWalletPage/index.tsx b/frontend/components/YourWalletPage/index.tsx index e487405c3..6d9e1c31b 100644 --- a/frontend/components/YourWalletPage/index.tsx +++ b/frontend/components/YourWalletPage/index.tsx @@ -32,6 +32,7 @@ import { balanceFormat } from '@/utils/numberFormatters'; import { FeatureNotEnabled } from '../FeatureNotEnabled'; import { Container, infoBreakdownParentStyle } from './styles'; import { SignerTitle } from './Titles'; +import { useYourWallet } from './useYourWallet'; import { YourAgentWallet } from './YourAgent'; const { Text } = Typography; @@ -42,21 +43,6 @@ const yourWalletTheme: ThemeConfig = { }, }; -const useYourWallet = () => { - const { selectedAgentConfig } = useServices(); - const { isLoading: isMasterSafeLoading, masterSafes } = - useMasterWalletContext(); - - return { - middlewareChain: selectedAgentConfig?.middlewareHomeChainId, - evmHomeChainId: selectedAgentConfig?.evmHomeChainId, - isMasterSafeLoading, - masterSafeAddress: masterSafes?.find( - ({ evmChainId }) => evmChainId === selectedAgentConfig?.evmHomeChainId, - )?.address, - }; -}; - const Address = () => { const { isMasterSafeLoading, masterSafeAddress, middlewareChain } = useYourWallet(); @@ -227,7 +213,7 @@ export const YourWalletPage = () => { - {selectedService && } + {!selectedService && } ) : ( diff --git a/frontend/components/YourWalletPage/useYourWallet.ts b/frontend/components/YourWalletPage/useYourWallet.ts new file mode 100644 index 000000000..51469e05f --- /dev/null +++ b/frontend/components/YourWalletPage/useYourWallet.ts @@ -0,0 +1,34 @@ +import { useMemo } from 'react'; + +import { useService } from '@/hooks/useService'; +import { useServices } from '@/hooks/useServices'; +import { useMasterWalletContext } from '@/hooks/useWallet'; + +export const useYourWallet = () => { + const { selectedAgentConfig, selectedService } = useServices(); + const { serviceSafes } = useService(selectedService?.service_config_id); + const { isLoading: isMasterSafeLoading, masterSafes } = + useMasterWalletContext(); + + const evmHomeChainId = selectedAgentConfig?.evmHomeChainId; + + // master safe + const masterSafe = useMemo(() => { + return masterSafes?.find(({ evmChainId }) => evmChainId === evmHomeChainId); + }, [masterSafes, evmHomeChainId]); + + // agent safe + const serviceSafe = useMemo(() => { + return serviceSafes?.find( + ({ evmChainId }) => evmChainId === evmHomeChainId, + ); + }, [serviceSafes, evmHomeChainId]); + + return { + middlewareChain: selectedAgentConfig?.middlewareHomeChainId, + evmHomeChainId, + isMasterSafeLoading, + masterSafeAddress: masterSafe?.address, + serviceSafe, + }; +}; diff --git a/frontend/constants/urls.ts b/frontend/constants/urls.ts index 581b4e962..2847cd214 100644 --- a/frontend/constants/urls.ts +++ b/frontend/constants/urls.ts @@ -52,6 +52,14 @@ export const EXPLORER_URL_BY_MIDDLEWARE_CHAIN: Record< [MiddlewareChain.BASE]: BASE_EXPLORER_URL, }; +export const BLOCKSCOUT_URL_BY_MIDDLEWARE_CHAIN: Record< + string | MiddlewareChain, + Url +> = { + [MiddlewareChain.GNOSIS]: 'https://gnosis.blockscout.com', + [MiddlewareChain.BASE]: 'https://base.blockscout.com', +}; + export const SWAP_URL_BY_EVM_CHAIN: Record = { [EvmChainId.Gnosis]: COW_SWAP_GNOSIS_XDAI_OLAS_URL, // [EvmChainId.OPTIMISM]: COW_SWAP_GNOSIS_XDAI_OLAS_URL, From c8f0f3caed778ec3f937ab5f3bacb0ab8044d925 Mon Sep 17 00:00:00 2001 From: mohandast52 Date: Wed, 18 Dec 2024 17:52:10 +0530 Subject: [PATCH 5/7] feat: enhance OlasBalance and MasterSafeNativeBalance components with middlewareChain display and update balanceFormat default decimals --- frontend/components/YourWalletPage/index.tsx | 18 +++++++++++++----- frontend/utils/numberFormatters.ts | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/frontend/components/YourWalletPage/index.tsx b/frontend/components/YourWalletPage/index.tsx index 6d9e1c31b..240ad7c97 100644 --- a/frontend/components/YourWalletPage/index.tsx +++ b/frontend/components/YourWalletPage/index.tsx @@ -7,7 +7,7 @@ import { ThemeConfig, Typography, } from 'antd'; -import { isNil } from 'lodash'; +import { capitalize, isNil } from 'lodash'; import { useMemo } from 'react'; import { AddressLink } from '@/components/AddressLink'; @@ -74,6 +74,7 @@ const Address = () => { const OlasBalance = () => { const { totalStakedOlasBalance } = useBalanceContext(); const { masterWalletBalances } = useMasterBalances(); + const { middlewareChain } = useYourWallet(); const masterSafeOlasBalance = masterWalletBalances ?.filter((walletBalance) => walletBalance.symbol === TokenSymbol.OLAS) @@ -96,7 +97,9 @@ const OlasBalance = () => { return ( - {TokenSymbol.OLAS} + + {TokenSymbol.OLAS} ({capitalize(middlewareChain)}) + ({ left: item.title, @@ -110,7 +113,8 @@ const OlasBalance = () => { }; const MasterSafeNativeBalance = () => { - const { evmHomeChainId, masterSafeAddress } = useYourWallet(); + const { evmHomeChainId, masterSafeAddress, middlewareChain } = + useYourWallet(); const { masterSafeBalances } = useMasterBalances(); const nativeTokenSymbol = getNativeTokenSymbol(evmHomeChainId); @@ -135,7 +139,11 @@ const MasterSafeNativeBalance = () => { {nativeTokenSymbol}, + left: ( + + {nativeTokenSymbol} ({capitalize(middlewareChain)}) + + ), leftClassName: 'text-light', right: `${balanceFormat(masterSafeNativeBalance, 2)} ${nativeTokenSymbol}`, }, @@ -180,7 +188,7 @@ const MasterEoaSignerNativeBalance = () => { /> ), leftClassName: 'text-light', - right: `${balanceFormat(masterEoaBalance, 2)} ${nativeTokenSymbol}`, + right: `${balanceFormat(masterEoaBalance, 3)} ${nativeTokenSymbol}`, }, ]} parentStyle={infoBreakdownParentStyle} diff --git a/frontend/utils/numberFormatters.ts b/frontend/utils/numberFormatters.ts index 06a2ba047..c7eb43f8d 100644 --- a/frontend/utils/numberFormatters.ts +++ b/frontend/utils/numberFormatters.ts @@ -5,7 +5,7 @@ import { BigNumberish, ethers } from 'ethers'; */ export const balanceFormat = ( balance: number | undefined, - decimals: 2, + decimals = 2, ): string => { if (balance === undefined) return '--'; return Intl.NumberFormat('en-US', { From cba71fb52575890734c592c4371ad9bcf4e3463f Mon Sep 17 00:00:00 2001 From: mohandast52 Date: Wed, 18 Dec 2024 17:53:11 +0530 Subject: [PATCH 6/7] feat: remove DebugInfoSection from SettingsPage for cleaner UI --- frontend/components/SettingsPage/index.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/frontend/components/SettingsPage/index.tsx b/frontend/components/SettingsPage/index.tsx index 06061043c..528470485 100644 --- a/frontend/components/SettingsPage/index.tsx +++ b/frontend/components/SettingsPage/index.tsx @@ -18,7 +18,6 @@ import { CustomAlert } from '../Alert'; import { CardTitle } from '../Card/CardTitle'; import { CardSection } from '../styled/CardSection'; import { AddBackupWalletPage } from './AddBackupWalletPage'; -import { DebugInfoSection } from './DebugInfoSection'; const { Text, Paragraph } = Typography; @@ -161,9 +160,6 @@ const SettingsMain = () => { Backup wallet {walletBackup} - - {/* Debug info */} - ); }; From 32f3d0202c8519e5f12db3d834b2f70100a88188 Mon Sep 17 00:00:00 2001 From: mohandast52 Date: Wed, 18 Dec 2024 17:57:08 +0530 Subject: [PATCH 7/7] feat: update OlasBalance filtering logic to include evmChainId and adjust conditional rendering of YourAgentWallet --- frontend/components/YourWalletPage/index.tsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/frontend/components/YourWalletPage/index.tsx b/frontend/components/YourWalletPage/index.tsx index 240ad7c97..137e5c260 100644 --- a/frontend/components/YourWalletPage/index.tsx +++ b/frontend/components/YourWalletPage/index.tsx @@ -74,10 +74,13 @@ const Address = () => { const OlasBalance = () => { const { totalStakedOlasBalance } = useBalanceContext(); const { masterWalletBalances } = useMasterBalances(); - const { middlewareChain } = useYourWallet(); + const { middlewareChain, evmHomeChainId } = useYourWallet(); const masterSafeOlasBalance = masterWalletBalances - ?.filter((walletBalance) => walletBalance.symbol === TokenSymbol.OLAS) + ?.filter( + ({ symbol, evmChainId }) => + symbol === TokenSymbol.OLAS && evmChainId === evmHomeChainId, + ) .reduce((acc, balance) => acc + balance.balance, 0); const olasBalances = useMemo(() => { @@ -221,7 +224,7 @@ export const YourWalletPage = () => { - {!selectedService && } + {selectedService && } ) : (