import {reactive, ref, markRaw, Ref} from 'vue'; import { ethers } from "ethers"; export interface ReturnConnect { getAccount: () => Promise | undefined> getChainId: () => Promise | undefined> getSigner: () => Promise chainId: Ref connect: () => Promise | void> disconnect: () => Promise | void> switchChain: (localChainId: string) => Promise account: Ref data: Record } export function useConnect(): ReturnConnect { if(!window.ethereum) { throw 'No provider' } const provider = reactive(window.ethereum); const account = ref(null); const chainId = ref(null); const data = reactive<{signer: ethers.providers.JsonRpcSigner | null}>({ signer: null }) const getAccount = async () => { if (!provider.request) return const accounts = await provider.request({ method: 'eth_requestAccounts', }) account.value = ethers.utils.getAddress(accounts[0]) return account; } const getChainId = async () => { if (!provider.request) return chainId.value = await provider.request({ method: 'eth_chainId', }) return chainId } const getSigner = async (): Promise => { const localProvider = new ethers.providers.Web3Provider(provider); data.signer = markRaw(localProvider.getSigner(account.value)); return data.signer; } const accountsChanged = (accounts: string[]) => { if (accounts.length === 0) disconnect() else account.value = ethers.utils.getAddress(accounts[0]) } const chainChanged = (localChainId: string) => { chainId.value = localChainId; } const switchChain = async (localChainId: string) => { if (!provider.request) return try { await provider.request({ method: 'wallet_switchEthereumChain', params: [{ chainId: localChainId }], }) } catch (error) { throw error; } } const connect = async () => { if (provider.on) { provider.on('accountsChanged', accountsChanged) provider.on('chainChanged', chainChanged) provider.on('disconnect', disconnect) } await getAccount(); await getChainId(); await getSigner(); return {account, chainId, data}; } const disconnect = async () => { if (!provider.removeListener) return provider.removeListener('accountsChanged', accountsChanged) provider.removeListener('chainChanged', chainChanged) provider.removeListener('disconnect', disconnect) account.value = null; chainId.value = null; data.signer = null; return {account, chainId, data}; } return {account, chainId, data, connect, switchChain, disconnect, getSigner, getAccount, getChainId} }