import type { WalletInit, APIKey, EIP1193Provider } from '@web3-onboard/common' function fortmatic(options: APIKey): WalletInit { const { apiKey } = options return () => { return { label: 'Fortmatic', getIcon: async () => (await import('./icon.js')).default, getInterface: async ({ EventEmitter, BigNumber, chains }) => { const { default: Fortmatic } = await import('fortmatic') const { createEIP1193Provider, ProviderRpcErrorCode, ProviderRpcError } = await import('@web3-onboard/common') const emitter = new EventEmitter() let instance = new Fortmatic(apiKey, { chainId: parseInt(chains[0].id), rpcUrl: chains[0].rpcUrl }) let fortmaticProvider = instance.getProvider() let provider: EIP1193Provider function patchProvider(): EIP1193Provider { const patchedProvider = createEIP1193Provider(fortmaticProvider, { eth_requestAccounts: async () => { try { const accounts = await instance.user.login() return accounts } catch (error) { const { code } = error as { code: number } if (code === -32603) { throw new ProviderRpcError({ code: ProviderRpcErrorCode.ACCOUNT_ACCESS_REJECTED, message: 'Account access rejected' }) } return [] } }, eth_selectAccounts: null, eth_getBalance: async () => { const [balance] = await instance.user.getBalances() return balance ? BigNumber.from(balance.crypto_amount) .mul('1000000000000000000') .toString() : '0' }, wallet_switchEthereumChain: async ({ params }) => { const chain = chains.find(({ id }) => id === params[0].chainId) if (!chain) throw new Error('chain must be set before switching') // re-instantiate instance with new network instance = new Fortmatic(apiKey, { chainId: parseInt(chain.id), rpcUrl: chain.rpcUrl }) // get the provider again fortmaticProvider = instance.getProvider() emitter.emit('chainChanged', chain.id) // patch the provider patchProvider() return null } }) if (!provider) { patchedProvider.on = emitter.on.bind(emitter) patchedProvider.disconnect = () => () => instance.user.logout() return patchedProvider } else { provider.request = patchedProvider.request.bind(patchedProvider) // @ts-ignore - bind old methods for backwards compat provider.send = patchedProvider.send.bind(patchedProvider) // @ts-ignore - bind old methods for backwards compat provider.sendAsync = patchedProvider.sendAsync.bind(patchedProvider) return provider } } provider = patchProvider() return { provider, instance } } } } } export default fortmatic