@lifi/wallet-management
Version:
LI.FI Wallet Management solution.
120 lines (108 loc) • 4.06 kB
text/typescript
import { http, createClient } from 'viem'
import { mainnet } from 'viem/chains'
import type { Config, CreateConnectorFn } from 'wagmi'
import { createConfig } from 'wagmi'
import type {
CoinbaseWalletParameters,
MetaMaskParameters,
WalletConnectParameters,
} from 'wagmi/connectors'
import { safe } from 'wagmi/connectors'
import { createCoinbaseConnector } from './connectors/coinbase.js'
import { createMetaMaskConnector } from './connectors/metaMask.js'
import { createWalletConnectConnector } from './connectors/walletConnect.js'
import { isWalletInstalled } from './utils/isWalletInstalled.js'
export interface DefaultWagmiConfigProps {
walletConnect?: WalletConnectParameters
coinbase?: CoinbaseWalletParameters
metaMask?: MetaMaskParameters
wagmiConfig?: {
ssr?: boolean
multiInjectedProviderDiscovery?: boolean
}
connectors?: CreateConnectorFn[]
/**
* Load Wallet SDKs only if the wallet is the most recently connected wallet
*/
lazy?: boolean
}
export interface DefaultWagmiConfigResult {
config: Config
connectors: CreateConnectorFn[]
}
/**
* Creates default Wagmi config that can be later synced (via useSyncWagmiConfig) with chains fetched from LI.FI API.
* @param props Properties to setup connectors. {@link DefaultWagmiConfigProps}
* @returns Wagmi config and connectors. {@link DefaultWagmiConfigResult}
* @example
* const { config, connectors } = createDefaultWagmiConfig({
* walletConnect: {
* projectId: import.meta.env.VITE_WALLET_CONNECT,
* },
* coinbase: { appName: 'LI.FI Demo' },
* });
* export const WalletProvider: FC<PropsWithChildren> = ({ children }) => {
* const { chains } = useAvailableChains();
* useSyncWagmiConfig(config, connectors, chains);
* return (
* <WagmiProvider config={wagmi.config} reconnectOnMount={false}>
* {children}
* </WagmiProvider>
* );
* };
*/
export function createDefaultWagmiConfig(
props?: DefaultWagmiConfigProps
): DefaultWagmiConfigResult {
const connectors: CreateConnectorFn[] = [...(props?.connectors ?? [])]
const anyWindow = typeof window !== 'undefined' ? (window as any) : undefined
const localStorage = anyWindow?.localStorage
// in Multisig env, window.parent is not equal to window
const isIframeEnvironment = anyWindow && anyWindow.parent !== anyWindow
const multiInjectedProviderDiscovery = isIframeEnvironment
? false
: (props?.wagmiConfig?.multiInjectedProviderDiscovery ?? true)
const config = createConfig({
chains: [mainnet],
client({ chain }) {
return createClient({ chain, transport: http() })
},
...props?.wagmiConfig,
multiInjectedProviderDiscovery,
})
if (isIframeEnvironment) {
connectors.unshift(safe())
}
// Check if WalletConnect properties exist in the props
if (props?.walletConnect) {
// Retrieve the ID of the most recently connected wallet connector from storage
const recentConnectorId = localStorage?.getItem(
`${config.storage?.key}.recentConnectorId`
)
// If WalletConnect is the most recently connected wallet or lazy loading is disabled,
// add the WalletConnect connector to the beginning of the connectors list
if (recentConnectorId?.includes?.('walletConnect') || !props.lazy) {
connectors.unshift(createWalletConnectConnector(props.walletConnect))
}
}
if (props?.coinbase && !isWalletInstalled('coinbase')) {
const recentConnectorId = localStorage?.getItem(
`${config.storage?.key}.recentConnectorId`
)
if (recentConnectorId?.includes?.('coinbaseWalletSDK') || !props.lazy) {
connectors.unshift(createCoinbaseConnector(props.coinbase))
}
}
if (props?.metaMask && !isWalletInstalled('metaMask')) {
const recentConnectorId = localStorage?.getItem(
`${config.storage?.key}.recentConnectorId`
)
if (recentConnectorId?.includes?.('metaMaskSDK') || !props.lazy) {
connectors.unshift(createMetaMaskConnector(props.metaMask))
}
}
return {
config,
connectors,
}
}