UNPKG

@web3-onboard/wagmi

Version:

Module to configure, connect and return web3-onboard wallets as wagmi wallets and wagmi-config to be used with wagmi-core methods

210 lines (209 loc) 8.08 kB
import { createConfig, createConnector, getConnectors } from '@wagmi/core'; import { createWagmiChains, createWalletId } from './utils'; import { connect as wagmiConnect } from '@wagmi/core'; import { validateWagmiInit } from './validation'; import EventEmitter from 'eventemitter3'; import { toHex, fromHex, UserRejectedRequestError, ResourceUnavailableRpcError } from 'viem'; import { ProviderRpcErrorCode } from '@web3-onboard/common'; export * from '@wagmi/core'; const wagmiConnectorFn = {}; const transports = {}; let chainsList; let wagmiConfig; let providerMethods; function wagmiInit(initOptions) { if (initOptions) { const error = validateWagmiInit(initOptions); if (error) { throw error; } } providerMethods = initOptions; return { buildWagmiConfig, createWagmiConnector, connectWalletToWagmi, wagmiConnect, wagmiDisconnectWallet, getWagmiConnector }; } async function buildWagmiConfig(chains, wallet) { if (wallet && (!wallet.provider || !wallet.label)) { throw new Error('Provider and wallet label are required to initialize WAGMI with a new connector'); } chainsList = chains !== null && chains !== void 0 ? chains : chainsList; try { if (wallet) { const { label, provider } = wallet; const latestWallet = await createWagmiConnector(label, provider); if (latestWallet) { wagmiConnectorFn[createWalletId(label)] = latestWallet; } else { console.error(`Failed to initialize Web3-Onboard WAGMI instance because of error from creating wallet connector - Label: ${label}`); return undefined; } } const connectors = [...Object.values(wagmiConnectorFn)]; const viemChains = await createWagmiChains(chainsList || [], transports); wagmiConfig = createConfig({ chains: [...viemChains], transports, multiInjectedProviderDiscovery: false, connectors }); return wagmiConfig; } catch (e) { console.error(`Failed to initialize Web3-Onboard WAGMI instance - Error: ${e}`); return undefined; } } async function createWagmiConnector(label, provider) { try { if (!providerMethods) { throw new Error('WAGMI config not initialized'); } return createConnector(() => convertW3OToWagmiWallet(label, provider, providerMethods)); } catch (e) { console.error('Error creating wagmi connector', e); return undefined; } } async function connectWalletToWagmi(label, provider) { try { if (!wagmiConfig || !providerMethods) { throw new Error('WAGMI connectWalletToWagmi could not be completed'); } return await wagmiConnect(wagmiConfig, { connector: convertW3OToWagmiWallet(label, provider, providerMethods) }); } catch (e) { console.error('Error connecting wallet to wagmi', e); return undefined; } } async function wagmiDisconnectWallet(label) { try { delete wagmiConnectorFn[createWalletId(label)]; wagmiConfig = await buildWagmiConfig(); return wagmiConfig; } catch (e) { console.error('error disconnecting wallet from wagmi', e); } } function getWagmiConnector(label) { try { const wagmiConnectors = getConnectors(wagmiConfig); if (!(wagmiConnectors === null || wagmiConnectors === void 0 ? void 0 : wagmiConnectors.length)) return undefined; return wagmiConnectors.find(connector => connector.name === label); } catch (e) { console.error('error disconnecting wallet from wagmi', e); } } const convertW3OToWagmiWallet = (label, provider, coreProviderMethods) => { if (!coreProviderMethods || typeof coreProviderMethods === undefined) { console.error('Required provider methods not defined for Wagmi Module API'); return {}; } else { return { name: label, id: createWalletId(label), connect: ({ chainId }) => { try { return Promise.resolve(coreProviderMethods .requestAccounts(provider) .then((accounts) => { const acc = accounts; if (chainId) { return { chainId, accounts: acc }; } return coreProviderMethods .getChainId(provider) .then((id) => { return { chainId: fromHex(id, 'number'), accounts: acc }; }); })); } catch (err) { const error = err; if (error.code === UserRejectedRequestError.code) throw new UserRejectedRequestError(error); if (error.code === ResourceUnavailableRpcError.code) throw new ResourceUnavailableRpcError(error); throw error; } }, disconnect: () => { wagmiDisconnectWallet(label); coreProviderMethods.disconnect({ label }); }, getAccounts: () => coreProviderMethods.requestAccounts(provider).then((acc) => { return acc; }), getChainId: () => coreProviderMethods.getChainId(provider).then((chainId) => { return fromHex(chainId, 'number'); }), getProvider: () => Promise.resolve(provider), isAuthorized: () => coreProviderMethods .requestAccounts(provider) .then((accounts) => { return !!accounts.length; }), switchChain: ({ chainId }) => { const hexChainId = toHex(chainId); try { coreProviderMethods.switchChain(provider, hexChainId).then(() => { return chainId; }); } catch (error) { const { code } = error; if (code === ProviderRpcErrorCode.CHAIN_NOT_ADDED || code === ProviderRpcErrorCode.UNRECOGNIZED_CHAIN_ID) { if (!chainsList) throw new Error('Chains list not defined'); // chain has not been added to wallet const targetChain = chainsList.find(({ id }) => id === hexChainId); if (!targetChain) throw new Error('Chain not found in chains list'); coreProviderMethods.updateChain(targetChain); // add chain to wallet coreProviderMethods .addOrSwitchChain(provider, targetChain) .then((id) => { return fromHex(id, 'number'); }); } } }, onAccountsChanged: (accounts) => { // Disconnect if there are no accounts if (accounts.length === 0) coreProviderMethods.disconnect({ label }); }, onChainChanged: (chainId) => { coreProviderMethods.switchChain(provider, toHex(chainId)); }, onDisconnect: () => { wagmiDisconnectWallet(label); coreProviderMethods.disconnect({ label }); }, emitter: new EventEmitter() }; } }; export default wagmiInit;