From 0e7e98f46e00e80b9dcf66f57b0963ed82c654df Mon Sep 17 00:00:00 2001 From: babkenmes Date: Fri, 13 Dec 2024 19:05:59 +0400 Subject: [PATCH] Added wallet display names --- Models/WalletProvider.ts | 5 +- .../Address/AddressPicker/AddressWithIcon.tsx | 2 +- .../AddressPicker/ConnectedWallets/index.tsx | 53 ++--- .../Withdraw/Wallet/ZKsyncWalletWithdraw.tsx | 2 +- .../Swap/Withdraw/WalletTransferContent.tsx | 2 +- components/Wallet/ConnectedWallets.tsx | 4 +- components/Wallet/WalletsList.tsx | 9 +- lib/wallets/evm/useEVM.ts | 186 +++++++++++------- lib/wallets/fuel/useFuel.ts | 3 +- lib/wallets/solana/useSolana.tsx | 13 +- lib/wallets/starknet/useStarknet.ts | 3 +- lib/wallets/ton/useTON.ts | 10 +- stores/walletStore.ts | 4 +- 13 files changed, 165 insertions(+), 131 deletions(-) diff --git a/Models/WalletProvider.ts b/Models/WalletProvider.ts index 199d4ce02..a9c83f780 100644 --- a/Models/WalletProvider.ts +++ b/Models/WalletProvider.ts @@ -12,6 +12,8 @@ export type InternalConnector = { } export type Wallet = { + id: string; + displayName?: string; // TODO: might be unused and unnecessary check isActive: boolean; address: string | `0x${string}`; @@ -19,7 +21,6 @@ export type Wallet = { providerName: string icon: (props: any) => React.JSX.Element; //TODO: this is name of the connector, should be changed to connectorId - connector?: string; metadata?: { starknetAccount?: AccountInterface, wallet?: StarknetWindowObject @@ -27,7 +28,7 @@ export type Wallet = { chainId?: string | number, isLoading?: boolean, disconnect: () => Promise | undefined | void; - connect: () => Promise; + connect?: () => Promise; isNotAvailable?: boolean; //TODO: refactor withdrawalSupportedNetworks?: string[], diff --git a/components/Input/Address/AddressPicker/AddressWithIcon.tsx b/components/Input/Address/AddressPicker/AddressWithIcon.tsx index 61c28dfe9..875dca8ce 100644 --- a/components/Input/Address/AddressPicker/AddressWithIcon.tsx +++ b/components/Input/Address/AddressPicker/AddressWithIcon.tsx @@ -43,7 +43,7 @@ const AddressWithIcon: FC = ({ addressItem, connectedWallet, partner, net }, { group: AddressGroup.ConnectedWallet, - text:

{connectedWallet?.connector || 'Connected wallet'}

, + text:

{connectedWallet?.displayName || 'Connected wallet'}

, icon: connectedWallet?.icon || WalletIcon }, { diff --git a/components/Input/Address/AddressPicker/ConnectedWallets/index.tsx b/components/Input/Address/AddressPicker/ConnectedWallets/index.tsx index 0f9f69087..10adfee80 100644 --- a/components/Input/Address/AddressPicker/ConnectedWallets/index.tsx +++ b/components/Input/Address/AddressPicker/ConnectedWallets/index.tsx @@ -31,6 +31,7 @@ const ConnectedWallets: FC = ({ provider, wallets, onClick, onConnect, de setIsLoading(false) } + //TODO: should check for real compatibility, in the future network can have wallets from multiple providers const notCompatibleWallets = wallets.filter(wallet => wallet.providerName !== provider.name || wallet.isNotAvailable) return
@@ -64,7 +65,6 @@ const ConnectedWallets: FC = ({ provider, wallets, onClick, onConnect, de wallet={wallet} selectable network={destination} - provider={provider} onWalletSelect={onClick} selectedAddress={destination_address} /> @@ -109,25 +109,16 @@ const ConnectedWallets: FC = ({ provider, wallets, onClick, onConnect, de {showIncompatibleWallets && notCompatibleWallets.map((wallet, index) => ( - - {wallet.addresses?.map((address) => { - const addressItem = { - address: address, - group: AddressGroup.ConnectedWallet, - }; - - return ( -
-
- -
-
- ); - })} + +
+ +
))}
@@ -139,26 +130,16 @@ const ConnectedWallets: FC = ({ provider, wallets, onClick, onConnect, de
Not compatible with {destination.display_name}
- {notCompatibleWallets[0].addresses?.map((address) => { - const addressItem = { - address: address, - group: AddressGroup.ConnectedWallet, - }; - - return ( - - ); - })} + )) } - } diff --git a/components/Swap/Withdraw/Wallet/ZKsyncWalletWithdraw.tsx b/components/Swap/Withdraw/Wallet/ZKsyncWalletWithdraw.tsx index 9f41ffc3b..7cb09f668 100644 --- a/components/Swap/Withdraw/Wallet/ZKsyncWalletWithdraw.tsx +++ b/components/Swap/Withdraw/Wallet/ZKsyncWalletWithdraw.tsx @@ -123,7 +123,7 @@ const ZkSyncWalletWithdrawStep: FC = ({ amount, depositAddres } }, [syncWallet, swapId, depositAddress, token, amount, sequenceNumber]) - if (wallet && wallet?.connector?.toLowerCase() === 'argent') return ( + if (wallet && wallet?.id?.toLowerCase() === 'argent') return (
diff --git a/components/Swap/Withdraw/WalletTransferContent.tsx b/components/Swap/Withdraw/WalletTransferContent.tsx index 551384111..0b52641f1 100644 --- a/components/Swap/Withdraw/WalletTransferContent.tsx +++ b/components/Swap/Withdraw/WalletTransferContent.tsx @@ -29,7 +29,7 @@ const WalletTransferContent: FC = () => { const changeWallet = async (wallet: Wallet, address: string) => { const connections = getConnections(config) - const connector = connections?.find(c => c.connector.name === wallet.connector) + const connector = connections?.find(c => c.connector.name === wallet.id) if (!connector) return switchAccount({ connector: connector.connector }) setSelectedSourceAccount({ wallet, address }) diff --git a/components/Wallet/ConnectedWallets.tsx b/components/Wallet/ConnectedWallets.tsx index 56af29cc4..a4f8e822d 100644 --- a/components/Wallet/ConnectedWallets.tsx +++ b/components/Wallet/ConnectedWallets.tsx @@ -51,11 +51,11 @@ const WalletsIcons = ({ wallets }: { wallets: Wallet[] }) => { return (
{ - firstWallet?.connector && + firstWallet?.displayName && } { - secondWallet?.connector && + secondWallet?.displayName && } { diff --git a/components/Wallet/WalletsList.tsx b/components/Wallet/WalletsList.tsx index f3957deda..fca53772a 100644 --- a/components/Wallet/WalletsList.tsx +++ b/components/Wallet/WalletsList.tsx @@ -65,7 +65,6 @@ const WalletsList: FC = (props) => { selectable={selectable} token={token} network={network} - provider={provider} onWalletSelect={onSelect} selectedAddress={selectedSourceAccount?.address} />) @@ -80,7 +79,6 @@ type WalletItemProps = { selectable?: boolean, token?: Token; network?: Network; - provider?: WalletProvider; selectedAddress: string | undefined; onWalletSelect?: (wallet: Wallet, address: string) => void; } @@ -94,6 +92,7 @@ export const WalletItem: FC & WalletItemProps> = const isSelected = selectable && (wallet.addresses.length == 1 && wallet.address == selectedAddress) const walletBalanceAmount = walletBalance?.amount && truncateDecimals(walletBalance?.amount, token?.precision) + return (
& WalletItemProps> =
{ - wallet.connector && + wallet &&
& WalletItemProps> = { wallet.addresses.length > 1 ?
- {wallet.connector} + {wallet.displayName}
:
@@ -145,7 +144,7 @@ export const WalletItem: FC & WalletItemProps> = /> }

- {wallet.connector} + {wallet.displayName}

{ diff --git a/lib/wallets/evm/useEVM.ts b/lib/wallets/evm/useEVM.ts index 411662a87..022f2e324 100644 --- a/lib/wallets/evm/useEVM.ts +++ b/lib/wallets/evm/useEVM.ts @@ -1,5 +1,5 @@ import { useAccount, useConfig, useConnect, useConnectors, useDisconnect, useSwitchAccount, Connector } from "wagmi" -import { Network, NetworkType } from "../../../Models/Network" +import { Network, NetworkType, NetworkWithTokens } from "../../../Models/Network" import { useSettingsState } from "../../../context/settings" import KnownInternalNames from "../../knownIds" import { resolveWalletConnectorIcon, resolveWalletConnectorIndex } from "../utils/resolveWalletIcon" @@ -63,6 +63,30 @@ export default function useEVM({ network }: Props): WalletProvider { } } + const disconnectWallet = async (connectorName: string) => { + + try { + const connector = activeConnectors.find(w => w.name.toLowerCase() === connectorName.toLowerCase()) + await disconnectAsync({ + connector: connector + }) + } + catch (e) { + console.log(e) + } + } + + const disconnectWallets = () => { + try { + activeConnectors.forEach(async (connector) => { + disconnectWallet(connector.name) + }) + } + catch (e) { + console.log(e) + } + } + const connectConnector = async ({ connector }: { connector: InternalConnector & LSConnector }) => { try { @@ -91,25 +115,25 @@ export default function useEVM({ network }: Props): WalletProvider { }); const activeAccount = getAccount(config) - const address = activeAccount.address - - if (!activeAccount || !activeAccount.connector || !address) return undefined - - const wallet: Wallet = { - isActive: true, - address: address, - addresses: activeAccount.addresses as string[] || [address], - connector: activeAccount.connector?.name, - providerName: name, - icon: resolveWalletConnectorIcon({ connector: evmConnectorNameResolver(activeAccount.connector), address, iconUrl: activeAccount.connector?.icon }), - connect: connectWallet, - disconnect: () => disconnectWallet(activeAccount.connector?.name || ""), - isNotAvailable: isNotAvailable(activeAccount.connector, network), - asSourceSupportedNetworks: activeAccount.connector.id === "com.immutable.passport" ? asSourceSupportedNetworks.filter(n => n.toLowerCase().startsWith("immutable")) : asSourceSupportedNetworks, - autofillSupportedNetworks: activeAccount.connector.id === "com.immutable.passport" ? autofillSupportedNetworks.filter(n => n.toLowerCase().startsWith("immutable")) : autofillSupportedNetworks, - withdrawalSupportedNetworks: activeAccount.connector.id === "com.immutable.passport" ? withdrawalSupportedNetworks.filter(n => n.toLowerCase().startsWith("immutable")) : withdrawalSupportedNetworks, - networkIcon: networks.find(n => activeAccount?.connector?.id === "com.immutable.passport" ? immutableZKEvm.some(name => name === n.name) : ethereumNames.some(name => name === n.name))?.logo - } + const connections = getConnections(config) + const connection = connections.find(c => c.connector.id === activeAccount.connector?.id) + + const wallet = ResolveWallet({ + activeConnection: (activeAccount.connector && activeAccount.address) ? { + id: activeAccount.connector.id, + address: activeAccount.address + } : undefined, + connection, + discconnect: disconnectWallet, + networks, + network, + supportedNetworks: { + asSource: asSourceSupportedNetworks, + autofill: autofillSupportedNetworks, + withdrawal: withdrawalSupportedNetworks + }, + providerName: name + }) return wallet @@ -137,59 +161,30 @@ export default function useEVM({ network }: Props): WalletProvider { // } const connection = connections.find(c => c.connector.id === w.id) - const accountIsActive = activeAccount?.connector?.id === w.id - - const addresses = connection?.accounts as (string[] | undefined); - const activeAddress = activeAccount?.address - - const address = accountIsActive ? activeAddress : addresses?.[0] - if (!address) return undefined - return { - isActive: accountIsActive, - address, - addresses: addresses || [address], - connector: w.name, - providerName: name, - icon: resolveWalletConnectorIcon({ connector: evmConnectorNameResolver(w), address, iconUrl: w.icon }), - connect: connectWallet, - disconnect: () => disconnectWallet(w.name), - isNotAvailable: isNotAvailable(w, network), - //TODO:refactor this - asSourceSupportedNetworks: w.id === "com.immutable.passport" ? asSourceSupportedNetworks.filter(n => n.toLowerCase().startsWith("immutable")) : asSourceSupportedNetworks, - autofillSupportedNetworks: w.id === "com.immutable.passport" ? autofillSupportedNetworks.filter(n => n.toLowerCase().startsWith("immutable")) : autofillSupportedNetworks, - withdrawalSupportedNetworks: w.id === "com.immutable.passport" ? withdrawalSupportedNetworks.filter(n => n.toLowerCase().startsWith("immutable")) : withdrawalSupportedNetworks, - networkIcon: networks.find(n => w?.id === "com.immutable.passport" ? immutableZKEvm.some(name => name === n.name) : ethereumNames.some(name => name === n.name))?.logo - - } - }).filter(w => w !== undefined) as Wallet[] - }, [activeAccount, activeConnectors, config, network]) - - const disconnectWallet = async (connectorName: string) => { - try { - const connector = activeConnectors.find(w => w.name.toLowerCase() === connectorName.toLowerCase()) - await disconnectAsync({ - connector: connector + const wallet = ResolveWallet({ + activeConnection: (activeAccount.connector && activeAccount.address) ? { + id: activeAccount.connector.id, + address: activeAccount.address + } : undefined, + connection, + discconnect: disconnectWallet, + networks, + network, + supportedNetworks: { + asSource: asSourceSupportedNetworks, + autofill: autofillSupportedNetworks, + withdrawal: withdrawalSupportedNetworks + }, + providerName: name }) - } - catch (e) { - console.log(e) - } - } - const disconnectWallets = () => { - try { - activeConnectors.forEach(async (connector) => { - disconnectWallet(connector.name) - }) - } - catch (e) { - console.log(e) - } - } + return wallet + }).filter(w => w !== undefined) as Wallet[] + }, [activeAccount, activeConnectors, config, network]) const switchAccount = async (wallet: Wallet, address: string) => { - const connector = getConnections(config).find(c => c.connector.name === wallet.connector)?.connector + const connector = getConnections(config).find(c => c.connector.name === wallet.id)?.connector if (!connector) throw new Error("Connector not found") const { accounts } = await switchAccountAsync({ connector }) @@ -238,7 +233,60 @@ const getWalletConnectUri = async ( ); }; -const isNotAvailable = (connector: Connector, network: Network | undefined) => { +const isNotAvailable = (connector: Connector | undefined, network: Network | undefined) => { if (!network) return false + if (!connector) return true return connector.id === "com.immutable.passport" && !network.name.toLowerCase().startsWith("immutable") } + +type ResolveWalletProps = { + connection: { + accounts: readonly [`0x${string}`, ...`0x${string}`[]]; + chainId: number; + connector: Connector; + } | undefined, + networks: NetworkWithTokens[], + network: Network | undefined, + activeConnection: { + id: string, + address: string + } | undefined, + discconnect: (connectorName: string | undefined) => Promise, + supportedNetworks: { + asSource: string[], + autofill: string[], + withdrawal: string[] + }, + providerName: string +} +const ResolveWallet = (props: ResolveWalletProps): Wallet | undefined => { + const { activeConnection, connection, networks, discconnect, network, supportedNetworks, providerName } = props + const accountIsActive = activeConnection?.id === connection?.connector.id + + const addresses = connection?.accounts as (string[] | undefined); + const activeAddress = activeConnection?.address + const connector = connection?.connector + if (!connector) + return undefined + + const address = accountIsActive ? activeAddress : addresses?.[0] + if (!address) return undefined + + const walletname = `${connector?.name} - ${connector.id === "com.immutable.passport" ? "Immutable" : "EVM"}` + return { + id: connector.name, + isActive: accountIsActive, + address, + addresses: addresses || [address], + displayName: walletname, + providerName, + icon: resolveWalletConnectorIcon({ connector: evmConnectorNameResolver(connector), address, iconUrl: connector.icon }), + disconnect: () => discconnect(connector.name), + isNotAvailable: isNotAvailable(connector, network), + //TODO:refactor this + asSourceSupportedNetworks: connector.id === "com.immutable.passport" ? supportedNetworks.asSource.filter(n => n.toLowerCase().startsWith("immutable")) : supportedNetworks.asSource, + autofillSupportedNetworks: connector.id === "com.immutable.passport" ? supportedNetworks.autofill.filter(n => n.toLowerCase().startsWith("immutable")) : supportedNetworks.autofill, + withdrawalSupportedNetworks: connector.id === "com.immutable.passport" ? supportedNetworks.withdrawal.filter(n => n.toLowerCase().startsWith("immutable")) : supportedNetworks.withdrawal, + networkIcon: networks.find(n => connector?.id === "com.immutable.passport" ? immutableZKEvm.some(name => name === n.name) : ethereumNames.some(name => name === n.name))?.logo + } +} \ No newline at end of file diff --git a/lib/wallets/fuel/useFuel.ts b/lib/wallets/fuel/useFuel.ts index e4712e7f7..9941e393d 100644 --- a/lib/wallets/fuel/useFuel.ts +++ b/lib/wallets/fuel/useFuel.ts @@ -228,12 +228,13 @@ const resolveFuelWallet = ({ address, addresses, autofillSupportedNetworks, conn } const w: Wallet = { + id: fuelCurrentConnector || connector.name, address: address, addresses: addresses, isActive: true, connect: connectWallet, disconnect: () => disconnectWallet(connector.name), - connector: fuelCurrentConnector || connector.name, + displayName: `${fuelCurrentConnector || connector.name} - Fuel`, providerName: name, icon: resolveWalletConnectorIcon({ connector: customConnectorname || connector.name, address: address, iconUrl: typeof connector.metadata.image === 'string' ? connector.metadata.image : (connector.metadata.image?.light.startsWith('data:') ? connector.metadata.image.light : `data:image/svg+xml;base64,${connector.metadata.image && btoa(connector.metadata.image.light)}`) }), autofillSupportedNetworks, diff --git a/lib/wallets/solana/useSolana.tsx b/lib/wallets/solana/useSolana.tsx index 3ff507d9d..aa1127fc5 100644 --- a/lib/wallets/solana/useSolana.tsx +++ b/lib/wallets/solana/useSolana.tsx @@ -23,7 +23,6 @@ export default function useSolana({ network }: { network: Network | undefined }) const { disconnect, wallet: solanaWallet, select, wallets } = useWallet(); const { networks } = useSettingsState() - const connectedWallet = wallets.find(w => w.adapter.connected === true) const connectedAddress = connectedWallet?.adapter.publicKey?.toBase58() const connectedAdapterName = connectedWallet?.adapter.name @@ -34,9 +33,10 @@ export default function useSolana({ network }: { network: Network | undefined }) return undefined } - const wallet: Wallet | undefined = connectedAddress ? { + const wallet: Wallet | undefined = (connectedAddress && connectedAdapterName) ? { + id: connectedAdapterName, address: connectedAddress, - connector: connectedAdapterName, + displayName: `${connectedAdapterName} - Solana`, providerName: name, icon: resolveWalletConnectorIcon({ connector: String(connectedAdapterName), address: connectedAddress, iconUrl: connectedWallet?.adapter.icon }), disconnect, @@ -46,7 +46,7 @@ export default function useSolana({ network }: { network: Network | undefined }) withdrawalSupportedNetworks: commonSupportedNetworks, asSourceSupportedNetworks: commonSupportedNetworks, autofillSupportedNetworks: commonSupportedNetworks, - networkIcon: networks.find(n => solanaNames.some(name => name === n.name))?.logo + networkIcon: networks.find(n => solanaNames.some(name => name === n.name))?.logo, } : undefined if (wallet) { @@ -74,9 +74,10 @@ export default function useSolana({ network }: { network: Network | undefined }) const connectedWallet = wallets.find(w => w.adapter.connected === true) const connectedAddress = connectedWallet?.adapter.publicKey?.toBase58() - const wallet: Wallet | undefined = connectedAddress ? { + const wallet: Wallet | undefined = connectedAddress && connectedWallet ? { + id: connectedWallet.adapter.name, address: connectedAddress, - connector: connectedWallet?.adapter.name, + displayName: `${connectedWallet?.adapter.name} - Solana`, providerName: name, icon: resolveWalletConnectorIcon({ connector: String(connectedWallet?.adapter.name), address: connectedAddress, iconUrl: connectedWallet?.adapter.icon }), disconnect, diff --git a/lib/wallets/starknet/useStarknet.ts b/lib/wallets/starknet/useStarknet.ts index 441443892..730063116 100644 --- a/lib/wallets/starknet/useStarknet.ts +++ b/lib/wallets/starknet/useStarknet.ts @@ -87,11 +87,12 @@ export default function useStarknet(): WalletProvider { const starknetWalletAccount = new WalletAccount({ nodeUrl: starkent?.node_url }, (starknetConnector as any).wallet); const wallet: Wallet = { + id: connector.name, + displayName: `${connector.name} - Starknet`, address: result?.account, addresses: [result?.account], chainId: walletChain, icon: resolveWalletConnectorIcon({ connector: connector.name, address: result?.account }), - connector: connector.name, providerName: name, metadata: { starknetAccount: starknetWalletAccount, diff --git a/lib/wallets/ton/useTON.ts b/lib/wallets/ton/useTON.ts index 49a4b69d3..e8c4ba20e 100644 --- a/lib/wallets/ton/useTON.ts +++ b/lib/wallets/ton/useTON.ts @@ -23,11 +23,12 @@ export default function useTON(): WalletProvider { const address = tonWallet?.account && Address.parse(tonWallet.account.address).toString({ bounceable: false }) const iconUrl = tonWallet?.["imageUrl"] as string - + const wallet_id = tonWallet?.["name"] || tonWallet?.device.appName const wallet: Wallet | undefined = tonWallet && address ? { + id: wallet_id, + displayName: `${wallet_id} - Ton`, addresses: [address], address, - connector: tonWallet?.["name"] || tonWallet.device.appName, providerName: id, isActive: true, icon: resolveWalletConnectorIcon({ connector: name, address, iconUrl }), @@ -74,10 +75,11 @@ export default function useTON(): WalletProvider { .then((status: ConnectedWallet) => { const connectedAddress = Address.parse(status.account.address).toString({ bounceable: false }) const connectedName = status.device.appName - const wallet = status && connectedAddress ? { + const wallet: Wallet | undefined = status && connectedAddress ? { + id: connectedName, + displayName: `${connectedName} - Ton`, addresses: [connectedAddress], address: connectedAddress, - connector: connectedName, providerName: id, isActive: true, icon: resolveWalletConnectorIcon({ connector: connectedName, address: connectedAddress }), diff --git a/stores/walletStore.ts b/stores/walletStore.ts index 314e4f696..7fc06044d 100644 --- a/stores/walletStore.ts +++ b/stores/walletStore.ts @@ -17,7 +17,7 @@ export const useWalletStore = create()((set) => ({ // we check if the wallet is already connected do not modify the state // TODO: get rid of useEffect hooks and implement singelton pattern connectWallet: (wallet) => set((state) => { - if (state.connectedWallets.find(w => w.providerName == wallet.providerName && w.connector == wallet.connector && w.address == wallet.address)) { + if (state.connectedWallets.find(w => w.providerName == wallet.providerName && w.id == wallet.id && w.address == wallet.address)) { return state } return ({ @@ -28,6 +28,6 @@ export const useWalletStore = create()((set) => ({ }) }), disconnectWallet: (providerName, connectorName) => set((state) => ({ - connectedWallets: state.connectedWallets.filter(w => connectorName ? !(w.providerName == providerName && w.connector == connectorName) : w.providerName != providerName) + connectedWallets: state.connectedWallets.filter(w => connectorName ? !(w.providerName == providerName && w.id == connectorName) : w.providerName != providerName) })) })) \ No newline at end of file