/* * Copyright (c) 2022 @automata-network/wallet-sdk authors and contributors. * This software may be modified and distributed under the terms of UNLICENSED * license. Refer to the LICENSE file for details. */ import React, { useEffect, useState } from 'react' import { Injected } from '@polkadot/extension-inject/types' import { WalletReadyState } from '@solana/wallet-adapter-base' import { useWallet as useSolanaAdapterReactWallet } from '@solana/wallet-adapter-react' import { useSolanaConnectorContext } from '../../store/solana-connector/hook' import { userCanceledError } from '../../utils' import { Connector, ConnectorItem } from '../Connector/Connector' interface ConnectorContextData { loading: boolean injected?: Injected error?: Error } const initialConnectorContextData = { loading: false, error: undefined } export const SolanaConnector: React.FC = () => { const { visible, setVisible, connectionPromise } = useSolanaConnectorContext() const { select, wallets, wallet, connect } = useSolanaAdapterReactWallet() const [data, setData] = useState(initialConnectorContextData) const [walletConnecting, setWalletConnecting] = useState(false) const [walletWaitingResolve, setWalletWaitingResolve] = useState(false) async function getAdapter(index: number) { setData({ loading: true }) try { select(wallets[index].adapter.name) setWalletConnecting(true) } catch (e) { if (connectionPromise) { connectionPromise.reject(e as Error) } setData({ loading: false, error: e as Error }) throw e } } async function connectWallet() { if (walletConnecting) { setWalletConnecting(false) try { await connect() } catch (e) { if (connectionPromise) { connectionPromise.reject(e as Error) } setData({ loading: false, error: e as Error }) throw e } setWalletWaitingResolve(true) } } useEffect(() => { connectWallet() }, [connect, walletConnecting]) useEffect(() => { if (walletWaitingResolve && wallet) { setWalletWaitingResolve(false) if (connectionPromise) { const { name, icon } = wallet.adapter connectionPromise.resolve({ label: name, icon, adapter: wallet.adapter, accounts: wallet.adapter.publicKey ? [wallet.adapter.publicKey.toString()] : [] }) } setVisible(false) setData(initialConnectorContextData) } }, [walletWaitingResolve, wallet]) return visible ? ( { const { url, icon, name, readyState } = item.adapter const enabled = readyState === WalletReadyState.Installed || readyState === WalletReadyState.Loadable return enabled || url ? { enabled, link: url, icon, label: name } : undefined }) .filter((item) => item != null) as ConnectorItem[] } onSelect={(index) => { getAdapter(index) }} onClose={() => { setVisible(false) connectionPromise?.reject(userCanceledError) }} /> ) : null }