UNPKG

@davidzwfu/wagmi-connector

Version:
124 lines (123 loc) 5.04 kB
import { ChainNotConfiguredError, createConnector, } from '@wagmi/core'; import { // type ProviderRpcError, SwitchChainError, UserRejectedRequestError, getAddress, numberToHex, } from 'viem'; import { VenlyProvider, CHAIN_CONFIGS, } from '@venly/web3-provider'; venly.type = 'venly'; export function venly(parameters) { let sdk = new VenlyProvider(); let walletProvider; return createConnector((config) => ({ id: 'venly', name: 'Venly', type: venly.type, async connect({ chainId } = {}) { try { const provider = await this.getProvider(); const accounts = (await provider.request({ method: 'eth_requestAccounts', })).map((x) => getAddress(x)); provider.on('accountsChanged', this.onAccountsChanged); provider.on('chainChanged', this.onChainChanged); provider.on('disconnect', this.onDisconnect.bind(this)); // Switch to chain if provided let currentChainId = await this.getChainId(); if (chainId && currentChainId !== chainId) { const chain = await this.switchChain({ chainId }); currentChainId = chain?.id ?? currentChainId; } return { accounts, chainId: currentChainId }; } catch (error) { if (/(user closed modal|accounts received is empty|user denied account)/i.test(error.message)) throw new UserRejectedRequestError(error); throw error; } }, async disconnect() { const provider = await this.getProvider(); if (!provider) return; provider.removeListener('accountsChanged', this.onAccountsChanged); provider.removeListener('chainChanged', this.onChainChanged); provider.removeListener('disconnect', this.onDisconnect.bind(this)); await sdk.logout(); }, async getAccounts() { const provider = await this.getProvider(); return (await provider.request({ method: 'eth_accounts', })).map((x) => getAddress(x)); }, async getChainId() { const provider = await this.getProvider(); const chainId = await provider.request({ method: 'eth_chainId', }); return Number(chainId); }, async getProvider() { if (!walletProvider) { const chain = config.chains.find((chain) => chain.id === parameters.chainId) || config.chains[0]; const chainId = parameters.chainId || chain?.id; const options = CHAIN_CONFIGS[chainId]; walletProvider = await sdk.createProvider({ ...parameters, skipAuthentication: true, environment: options.env, secretType: options.secretType, }); } return walletProvider; }, async isAuthorized() { try { walletProvider = await sdk.createProvider({ ...parameters, skipAuthentication: true, }); const authResult = await sdk.checkAuthenticated(); return authResult.isAuthenticated; } catch { return false; } }, async switchChain({ chainId }) { const chain = config.chains.find((chain) => chain.id === chainId); if (!chain) throw new SwitchChainError(new ChainNotConfiguredError()); const provider = await this.getProvider(); const chainId_ = numberToHex(chain.id); try { await provider.request({ method: 'wallet_switchEthereumChain', params: [{ chainId: chainId_ }], }); return chain; } catch (error) { throw new SwitchChainError(error); } }, onAccountsChanged(accounts) { if (accounts.length === 0) config.emitter.emit('disconnect'); else config.emitter.emit('change', { accounts: accounts.map((x) => getAddress(x)), }); }, onChainChanged(chain) { const chainId = Number(chain); config.emitter.emit('change', { chainId }); }, async onDisconnect(_error) { config.emitter.emit('disconnect'); const provider = await this.getProvider(); provider.removeListener('accountsChanged', this.onAccountsChanged); provider.removeListener('chainChanged', this.onChainChanged); provider.removeListener('disconnect', this.onDisconnect.bind(this)); }, })); }