import { AccountId } from 'caip'
import { Box, Button, Heading, Layer, Text } from 'grommet'
import React from 'react'
import type { ReactElement, ReactNode } from 'react'
import { useAuthState } from '../hooks'
import type { AuthAccount, AuthenticatedState, AuthMethod, NetworkConfig } from '../types'
import { deferred } from '../utils'
import { ModalItem } from './ModalItem'
type ModalGridProps = {
children: ReactNode
}
function ModalGrid({ children }: ModalGridProps) {
return
{children}
}
const defaultCloseIconSrc = new URL('../images/icon-close.svg', import.meta.url).href
export type ModalConfig = {
closeIcon?: string | ReactElement
selectedIcon?: string | ReactElement
text?: string
title?: string
}
export type ModalProps = ModalConfig & {
networks: Array
}
export function Modal({
closeIcon,
networks,
selectedIcon,
text,
title,
}: ModalProps): ReactElement | null {
const [authState, setAuthState] = useAuthState()
if (authState.status !== 'authenticating' || !authState.modal) {
return null
}
const ethereumConfig = networks.find((p) => p.key === 'ethereum')
if (ethereumConfig == null) {
console.warn('Ethereum provider missing in config')
return null
}
const ethereumWallets = ethereumConfig.connectors.map((connector) => {
type Provider = typeof connector.providerKey
const key = 'ethereum'
const method: AuthMethod = { key, connector }
const onClick = () => {
if (authState.status === 'authenticating') {
if (authState.method == null) {
setAuthState({ ...authState, method })
}
} else {
setAuthState({
status: 'authenticating',
promise: deferred | null>(),
method,
modal: true,
})
}
connector
.getProvider(connector.providerKey, connector.params)
.then((provider) => ethereumConfig.getState(connector.providerKey, provider))
.then(
(state) => {
if (state.account == null) {
if (authState.status === 'authenticating') {
authState.promise.resolve(null)
}
setAuthState({ status: 'idle' })
} else {
const accountID = new AccountId({ address: state.account, chainId: state.chainID })
const auth: AuthAccount = {
accountID,
method,
state: state as AuthenticatedState,
}
if (authState.status === 'authenticating') {
authState.promise.resolve(auth)
}
setAuthState({ status: 'authenticated', auth })
}
},
(error: Error) => {
if (authState.status === 'authenticating') {
authState.promise.reject(error)
}
setAuthState({ status: 'failed', error })
}
)
}
return (
)
})
const closeIconElement =
typeof closeIcon === 'string' ? (
) : closeIcon == null ? (
) : (
closeIcon
)
const onCloseModal = () => {
if (authState.status === 'authenticating') {
if (authState.method == null) {
authState.promise.resolve(null)
setAuthState({ status: 'idle' })
} else {
setAuthState({ ...authState, modal: false })
}
}
}
return (
{title ?? 'Connect wallet'}
{text ? {text} : null}
1. Choose network
{
// Only option, no effect
}}
selected
selectedIcon={selectedIcon}
/>
2. Choose wallet
{ethereumWallets}
)
}