* fix: fixed the wallet auto connection * tidy: refactor * fix: re-enabled account change support * tidy: refactor
192 lines
5.9 KiB
TypeScript
192 lines
5.9 KiB
TypeScript
import { useShuttle } from '@delphi-labs/shuttle-react'
|
|
import Image from 'next/image'
|
|
import React, { useEffect, useState } from 'react'
|
|
import QRCode from 'react-qr-code'
|
|
|
|
import Button from 'components/Button'
|
|
import FullOverlayContent from 'components/FullOverlayContent'
|
|
import { ChevronLeft, ChevronRight } from 'components/Icons'
|
|
import Text from 'components/Text'
|
|
import WalletConnecting from 'components/Wallet/WalletConnecting'
|
|
import { CHAINS } from 'constants/chains'
|
|
import { ENV } from 'constants/env'
|
|
import { WALLETS } from 'constants/wallets'
|
|
import useStore from 'store'
|
|
import { WalletID } from 'types/enums/wallet'
|
|
import { isAndroid, isIOS, isMobile } from 'utils/mobile'
|
|
|
|
interface Props {
|
|
error?: ErrorObject
|
|
}
|
|
|
|
interface ErrorObject {
|
|
title: string
|
|
message: string
|
|
}
|
|
|
|
interface WalletOptionProps {
|
|
name: string
|
|
imageSrc: string
|
|
handleClick: () => void
|
|
}
|
|
|
|
const currentChainId = ENV.CHAIN_ID
|
|
const currentChain = CHAINS[currentChainId]
|
|
|
|
function WalletOption(props: WalletOptionProps) {
|
|
return (
|
|
<Button
|
|
color='tertiary'
|
|
className='flex w-full !justify-start px-4 py-3'
|
|
onClick={props.handleClick}
|
|
>
|
|
<Image
|
|
className='rounded-full'
|
|
width={20}
|
|
height={20}
|
|
src={props.imageSrc}
|
|
alt={props.name}
|
|
/>
|
|
<Text className='ml-2 flex-1 text-left'>{props.name}</Text>
|
|
<ChevronRight className='h-4 w-4' />
|
|
</Button>
|
|
)
|
|
}
|
|
|
|
export default function WalletSelect(props: Props) {
|
|
const { extensionProviders, mobileProviders, mobileConnect } = useShuttle()
|
|
const [qrCodeUrl, setQRCodeUrl] = useState('')
|
|
const [error, setError] = useState(props.error)
|
|
const sortedExtensionProviders = extensionProviders.sort((a, b) => +b - +a)
|
|
|
|
const handleConnectClick = (extensionProviderId: string) => {
|
|
useStore.setState({
|
|
focusComponent: <WalletConnecting providerId={extensionProviderId} />,
|
|
})
|
|
}
|
|
|
|
const handleMobileConnectClick = async (mobileProviderId: string, chainId: string) => {
|
|
try {
|
|
const urls = await mobileConnect({
|
|
mobileProviderId,
|
|
chainId,
|
|
})
|
|
|
|
if (isMobile()) {
|
|
if (isAndroid()) {
|
|
window.location.href = urls.androidUrl
|
|
} else if (isIOS()) {
|
|
window.location.href = urls.iosUrl
|
|
} else {
|
|
window.location.href = urls.androidUrl
|
|
}
|
|
} else {
|
|
setQRCodeUrl(urls.qrCodeUrl)
|
|
}
|
|
} catch (error) {
|
|
if (error instanceof Error) {
|
|
setError({ title: 'Failed to connect to wallet', message: error.message })
|
|
}
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (error?.message && error?.title) {
|
|
useStore.setState({
|
|
toast: {
|
|
isError: true,
|
|
title: error.title,
|
|
message: error.message,
|
|
},
|
|
})
|
|
}
|
|
}, [error?.message, error?.title])
|
|
|
|
if (qrCodeUrl)
|
|
return (
|
|
<FullOverlayContent
|
|
title={'Scan the QR Code'}
|
|
copy={
|
|
'Open your mobile wallet App and use the QR Scan function to connect via WalletConnect v2'
|
|
}
|
|
button={{
|
|
color: 'secondary',
|
|
leftIcon: <ChevronLeft />,
|
|
iconClassName: 'w-3',
|
|
onClick: () => setQRCodeUrl(''),
|
|
text: 'Back',
|
|
}}
|
|
>
|
|
<div className='mb-4 rounded-sm bg-white p-2'>
|
|
<QRCode value={qrCodeUrl} />
|
|
</div>
|
|
</FullOverlayContent>
|
|
)
|
|
|
|
return (
|
|
<FullOverlayContent
|
|
title={'Connect your wallet'}
|
|
copy={`Deposit assets from your ${currentChain.name} address to your Mars credit account.`}
|
|
docs='wallet'
|
|
>
|
|
<div className='flex w-full flex-wrap gap-3'>
|
|
{!isMobile() && (
|
|
<>
|
|
{sortedExtensionProviders.map((provider) => {
|
|
const walletId = provider.id as WalletID
|
|
return (
|
|
<React.Fragment key={walletId}>
|
|
{Array.from(provider.networks.values())
|
|
.filter((network) => network.chainId === currentChainId)
|
|
.map((network) => {
|
|
if (!provider.initialized && !provider.initializing) {
|
|
return (
|
|
<WalletOption
|
|
key={`${walletId}-${network.chainId}`}
|
|
handleClick={() => {
|
|
window.open(WALLETS[walletId].installURL ?? '/', '_blank')
|
|
}}
|
|
imageSrc={WALLETS[walletId].imageURL}
|
|
name={WALLETS[walletId].install ?? 'Install Wallet'}
|
|
/>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<WalletOption
|
|
key={`${walletId}-${network.chainId}`}
|
|
handleClick={() => handleConnectClick(walletId)}
|
|
imageSrc={WALLETS[walletId].imageURL}
|
|
name={WALLETS[walletId].name ?? 'Conenct Wallet'}
|
|
/>
|
|
)
|
|
})}
|
|
</React.Fragment>
|
|
)
|
|
})}
|
|
</>
|
|
)}
|
|
{mobileProviders.map((provider) => {
|
|
const walletId = provider.id as WalletID
|
|
return (
|
|
<React.Fragment key={walletId}>
|
|
{Array.from(provider.networks.values())
|
|
.filter((network) => network.chainId === currentChainId)
|
|
.map((network) => {
|
|
return (
|
|
<WalletOption
|
|
key={`${walletId}-${network.chainId}`}
|
|
name={WALLETS[walletId].walletConnect ?? 'WalletConnect'}
|
|
imageSrc={WALLETS[walletId].mobileImageURL ?? '/'}
|
|
handleClick={() => handleMobileConnectClick(walletId, network.chainId)}
|
|
/>
|
|
)
|
|
})}
|
|
</React.Fragment>
|
|
)
|
|
})}
|
|
</div>
|
|
</FullOverlayContent>
|
|
)
|
|
}
|