idquia
Version:
Web3-Onboard makes it simple to connect Ethereum hardware and software wallets to your dapp. Features standardised spec compliant web3 providers for all supported wallets, framework agnostic modern javascript UI with code splitting, CSS customization, mul
112 lines (92 loc) • 3.2 kB
text/typescript
import type { WalletInit } from '@web3-onboard/common'
import type { MetaMaskSDK, MetaMaskSDKOptions } from '@metamask/sdk'
import type { createEIP1193Provider } from '@web3-onboard/common'
type ImportSDK = {
createEIP1193Provider: typeof createEIP1193Provider
MetaMaskSDKConstructor: typeof MetaMaskSDK
}
const loadImports = async () => {
if (importPromise) {
return await importPromise
}
const { createEIP1193Provider } = await import('@web3-onboard/common')
const importedSDK = await import('@metamask/sdk')
const MetaMaskSDKConstructor =
// @ts-ignore
importedSDK.MetaMaskSDK || importedSDK.default.MetaMaskSDK
if (!MetaMaskSDKConstructor) {
throw new Error('Error importing and initializing MetaMask SDK')
}
return { createEIP1193Provider, MetaMaskSDKConstructor }
}
let importPromise: Promise<ImportSDK> | null = null
let sdk: MetaMaskSDK | null = null
let createInstance: typeof createEIP1193Provider
function metamask({
options
}: {
options: Partial<MetaMaskSDKOptions>
}): WalletInit {
return () => {
importPromise = loadImports().catch(error => {
throw error
})
const getProvider = (_sdk: MetaMaskSDK) => {
const provider = createInstance(_sdk.getProvider(), {})
provider.disconnect = () => {
sdk?.terminate()
}
return provider
}
return {
label: 'MetaMask',
getIcon: async () => (await import('./icon.js')).default,
getInterface: async ({ appMetadata }) => {
sdk = (window as any).mmsdk || sdk; // Prevent conflict with existing mmsdk instances
if (sdk) {
// Prevent re-initializing instance as it causes issues with MetaMask sdk mobile provider.
return {
provider: sdk.getProvider() as any,
instance: sdk
}
}
const { name, icon } = appMetadata || {}
const base64 = window.btoa(icon || '')
const appLogoUrl = `data:image/svg+xml;base64,${base64}`
const imports = await importPromise
// Patch issue with MetaMask SDK, remove after SDK is fixed
localStorage.removeItem('providerType')
if (
!imports?.MetaMaskSDKConstructor ||
!imports?.createEIP1193Provider
) {
throw new Error('Error importing and initializing MetaMask SDK')
}
const { createEIP1193Provider, MetaMaskSDKConstructor } = imports
createInstance = createEIP1193Provider
sdk = new MetaMaskSDKConstructor({
...options,
dappMetadata: {
name: options.dappMetadata?.name || name || '',
base64Icon: appLogoUrl
},
_source: 'web3-onboard'
})
await sdk.init()
const provider = getProvider(sdk)
const _request = provider.request
provider.request = async ({ method, params }) => {
if (sdk?.isExtensionActive()) {
return (window.extension as any).request({ method, params })
}
return _request({ method, params }) as Promise<any>
}
return {
provider,
instance: sdk
}
}
}
}
}
export default metamask