diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cdc087..381ace8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # @magiclabs/wagmi-magic-connector +## 2.0.0 + +### Major Changes + +- Update to support WAGMI v2 + ## 1.1.6 ### Patch Changes diff --git a/README.md b/README.md index 5d02641..e4ee6f2 100644 --- a/README.md +++ b/README.md @@ -29,16 +29,27 @@ Special thanks to the [Everipedia](https://github.com/EveripediaNetwork) team fo - [**Example repositories:**](#example-repositories) # ⬇️ Install +Two versions of the `wagmi-magic-connector` are available, each designed to support different WAGMI versions. -```bash -npm install @magiclabs/wagmi-connector -``` +Note: **It is crucial not to mix up these versions to ensure compatibility and functionality.** + +**V1** +This version utilizes WAGMI version 1. To install, use the following command: +`npm install @magiclabs/wagmi-connector@1.1.5` or +`yarn install @magiclabs/wagmi-connector@1.1.5` -```bash -yarn add @magiclabs/wagmi-connector -``` +**V2 (Beta)** +This version utilizes and includes the latest WAGMI v2 features. + +To install, use the following command: + +`npm install @magiclabs/wagmi-connector` +or +`yarn install @magiclabs/wagmi-connector` + +We actively encourage the community to participate in testing the versions of `wagmi-magic-connector` and to report [any issues or suggestions](https://github.com/magiclabs/wagmi-magic-connector/issues/new/choose) for improvement. Your feedback is invaluable in helping us enhance the quality and stability of the connector. # 🔎 Package TL;DR diff --git a/package.json b/package.json index eae8616..9b57303 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@magiclabs/wagmi-connector", - "version": "1.1.6", + "version": "2.0.0", "description": "wagmi connector to connect with Magic SDK", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -27,18 +27,20 @@ "@changesets/cli": "^2.24.0", "@magic-ext/oauth": "^12.3.0", "@magic-sdk/provider": "^18.3.0", - "@wagmi/core": "^1.4.12", + "@wagmi/connectors": "^4.1.14", + "@wagmi/core": "^2.6.5", "magic-sdk": "^18.3.0", "tsc-esm-fix": "^2.20.10" }, "devDependencies": { + "@types/node": "^20.11.24", "changeset": "^0.2.6", "rome": "12.0.0", "typescript": "^5.0.4", - "viem": "^1.2.10" + "viem": "2.x" }, "peerDependencies": { - "viem": "^1.2.10" + "viem": "2.x" }, "files": [ "dist", diff --git a/src/lib/connectors/dedicatedWalletConnector.ts b/src/lib/connectors/dedicatedWalletConnector.ts index 7aeaf0e..1de9a20 100644 --- a/src/lib/connectors/dedicatedWalletConnector.ts +++ b/src/lib/connectors/dedicatedWalletConnector.ts @@ -1,15 +1,17 @@ -import { OAuthExtension, OAuthProvider } from '@magic-ext/oauth' +import type { OAuthExtension, OAuthProvider } from '@magic-ext/oauth' import type { InstanceWithExtensions, MagicSDKAdditionalConfiguration, - MagicSDKExtensionsOption, SDKBase, } from '@magic-sdk/provider' -import type { Chain } from '@wagmi/core' -import { Magic } from 'magic-sdk' +import { createConnector, normalizeChainId } from '@wagmi/core' +import { + type MagicConnectorParams, + type MagicOptions, + magicConnector, +} from './magicConnector' +import { UserRejectedRequestError, getAddress } from 'viem' import { createModal } from '../modal/view' -import { MagicConnector, MagicOptions } from './magicConnector' -import { UserRejectedRequestError } from 'viem' interface UserDetails { email: string @@ -17,19 +19,6 @@ interface UserDetails { oauthProvider: OAuthProvider } -interface DedicatedWalletOptions extends MagicOptions { - enableEmailLogin?: boolean - enableSMSLogin?: boolean - oauthOptions?: { - providers: OAuthProvider[] - callbackUrl?: string - } - magicSdkConfiguration?: MagicSDKAdditionalConfiguration< - string, - OAuthExtension[] - > -} - /** * Dedicated Wallet Connector class used to connect to wallet using Dedicated Wallet. * It uses modal UI defined in our package which also takes in various styling options @@ -49,162 +38,212 @@ interface DedicatedWalletOptions extends MagicOptions { * @see https://magic.link/docs/dedicated/overview */ -export class DedicatedWalletConnector extends MagicConnector { - magicSDK?: InstanceWithExtensions +interface DedicatedWalletOptions extends MagicOptions { + enableEmailLogin?: boolean + enableSMSLogin?: boolean + oauthOptions?: { + providers: OAuthProvider[] + callbackUrl?: string + } magicSdkConfiguration?: MagicSDKAdditionalConfiguration< string, - MagicSDKExtensionsOption + OAuthExtension[] > - enableSMSLogin: boolean - enableEmailLogin: boolean - oauthProviders: OAuthProvider[] - oauthCallbackUrl?: string - magicOptions: MagicOptions - - constructor(config: { chains?: Chain[]; options: DedicatedWalletOptions }) { - super(config) - this.magicSdkConfiguration = config.options.magicSdkConfiguration - this.oauthProviders = config.options.oauthOptions?.providers || [] - this.oauthCallbackUrl = config.options.oauthOptions?.callbackUrl - this.enableSMSLogin = config.options.enableSMSLogin || false - this.enableEmailLogin = config.options.enableEmailLogin || true - this.magicOptions = config.options - } - - /** - * Get the Magic Instance - * @throws {Error} if Magic API Key is not provided - */ - getMagicSDK(): InstanceWithExtensions { - if (!this.magicSDK) { - this.magicSDK = new Magic(this.magicOptions.apiKey, { - ...this.magicSdkConfiguration, - extensions: [new OAuthExtension()], - }) - } - return this.magicSDK - } - - /** - * Connect method attempts to connects to wallet using Dedicated Wallet modal - * this will open a modal for the user to select their wallet - */ - async connect() { - if (!this.magicOptions.apiKey) - throw new Error('Magic API Key is not provided.') - - const provider = await this.getProvider() - - if (provider?.on) { - provider.on('accountsChanged', this.onAccountsChanged) - provider.on('chainChanged', this.onChainChanged) - provider.on('disconnect', this.onDisconnect) - } - - // Check if we have a chainId, in case of error just assign 0 for legacy - let chainId: number - try { - chainId = await this.getChainId() - } catch { - chainId = 0 - } - - // if there is a user logged in, return the user - if (await this.isAuthorized()) { - return { - provider, - chain: { - id: chainId, - unsupported: false, - }, - account: await this.getAccount(), - } - } - - // open the modal and process the magic login steps - if (!this.isModalOpen) { - const modalOutput = await this.getUserDetailsByForm( - this.enableSMSLogin, - this.enableEmailLogin, - this.oauthProviders, - ) - - const magic = this.getMagicSDK() - - // LOGIN WITH MAGIC USING OAUTH PROVIDER - if (modalOutput.oauthProvider) - await magic.oauth.loginWithRedirect({ - provider: modalOutput.oauthProvider, - redirectURI: this.oauthCallbackUrl || window.location.href, - }) - - // LOGIN WITH MAGIC USING EMAIL - if (modalOutput.email) - await magic.auth.loginWithEmailOTP({ - email: modalOutput.email, - }) - - // LOGIN WITH MAGIC USING PHONE NUMBER - if (modalOutput.phoneNumber) - await magic.auth.loginWithSMS({ - phoneNumber: modalOutput.phoneNumber, - }) - - if (await magic.user.isLoggedIn()) - return { - account: await this.getAccount(), - chain: { - id: chainId, - unsupported: false, - }, - provider, - } - } - throw new UserRejectedRequestError(Error('User Rejected Request')) - } - - /** - * checks if user is authorized with Magic. - * It also checks for oauth redirect result incase user - * comes from OAuth flow redirect. - * (without this check, user will not be logged in after oauth redirect) - */ - async isAuthorized() { - try { - const magic = this.getMagicSDK() +} - const isLoggedIn = await magic.user.isLoggedIn() - if (isLoggedIn) return true +export interface DedicatedWalletConnectorParams extends MagicConnectorParams { + options: DedicatedWalletOptions +} - const result = await magic.oauth.getRedirectResult() - return result !== null - } catch {} - return false - } +export function dedicatedWalletConnector({ + chains, + options, +}: DedicatedWalletConnectorParams) { + let { + id, + name, + type, + isModalOpen, + getAccount, + getMagicSDK, + getProvider, + onAccountsChanged, + } = magicConnector({ + chains, + options: { ...options, connectorType: 'dedicated' }, + }) + + const oauthProviders = options.oauthOptions?.providers ?? [] + const oauthCallbackUrl = options.oauthOptions?.callbackUrl + const enableSMSLogin = options.enableSMSLogin ?? false + const enableEmailLogin = options.enableEmailLogin ?? true /** * This method is used to get user details from the modal UI * It first creates the modal UI and then waits for the user to * fill in the details and submit the form. */ - async getUserDetailsByForm( + const getUserDetailsByForm = async ( enableSMSLogin: boolean, enableEmailLogin: boolean, oauthProviders: OAuthProvider[], - ): Promise { + ): Promise => { const output: UserDetails = (await createModal({ - accentColor: this.magicOptions.accentColor, - isDarkMode: this.magicOptions.isDarkMode, - customLogo: this.magicOptions.customLogo, - customHeaderText: this.magicOptions.customHeaderText, + accentColor: options.accentColor, + isDarkMode: options.isDarkMode, + customLogo: options.customLogo, + customHeaderText: options.customHeaderText, enableSMSLogin: enableSMSLogin, enableEmailLogin: enableEmailLogin, oauthProviders, })) as UserDetails - this.isModalOpen = false + isModalOpen = false return output } -} -export class MagicAuthConnector extends DedicatedWalletConnector {} + return createConnector((config) => ({ + id, + type, + name, + getProvider, + connect: async function () { + if (!options.apiKey) { + throw new Error('Magic API Key is not provided.') + } + + const provider = await getProvider() + + if (provider?.on) { + provider.on('accountsChanged', this.onAccountsChanged.bind(this)) + provider.on('chainChanged', this.onChainChanged.bind(this)) + provider.on('disconnect', this.onDisconnect.bind(this)) + } + + let chainId: number + try { + chainId = await this.getChainId() + } catch { + chainId = 0 + } + + if (await this.isAuthorized()) { + return { + chainId, + accounts: [await getAccount()], + } + } + + if (!isModalOpen) { + const modalOutput = await getUserDetailsByForm( + enableSMSLogin, + enableEmailLogin, + oauthProviders, + ) + + const magic = getMagicSDK() as InstanceWithExtensions< + SDKBase, + OAuthExtension[] + > + + // LOGIN WITH MAGIC USING OAUTH PROVIDER + if (modalOutput.oauthProvider) + await magic.oauth.loginWithRedirect({ + provider: modalOutput.oauthProvider, + redirectURI: oauthCallbackUrl ?? window.location.href, + }) + + // LOGIN WITH MAGIC USING EMAIL + if (modalOutput.email) + await magic.auth.loginWithEmailOTP({ + email: modalOutput.email, + }) + + // LOGIN WITH MAGIC USING PHONE NUMBER + if (modalOutput.phoneNumber) + await magic.auth.loginWithSMS({ + phoneNumber: modalOutput.phoneNumber, + }) + + if (await magic.user.isLoggedIn()) + return { + accounts: [await getAccount()], + chainId, + } + } + throw new UserRejectedRequestError(Error('User Rejected Request')) + }, + + disconnect: async () => { + try { + const magic = getMagicSDK() + await magic?.wallet.disconnect() + config.emitter.emit('disconnect') + } catch (error) { + console.error('Error disconnecting from Magic SDK:', error) + } + }, + + getAccounts: async () => { + const provider = await getProvider() + const accounts = (await provider?.request({ + method: 'eth_accounts', + })) as string[] + return accounts.map((x) => getAddress(x)) + }, + + getChainId: async (): Promise => { + const provider = await getProvider() + if (provider) { + const chainId = await provider.request({ + method: 'eth_chainId', + params: [], + }) + return normalizeChainId(chainId) + } + const networkOptions = options.magicSdkConfiguration?.network + if (typeof networkOptions === 'object') { + const chainID = networkOptions.chainId + if (chainID) return normalizeChainId(chainID) + } + throw new Error('Chain ID is not defined') + }, + + isAuthorized: async () => { + try { + const magic = getMagicSDK() as InstanceWithExtensions< + SDKBase, + OAuthExtension[] + > + + if (!magic) { + return false + } + + const isLoggedIn = await magic.user.isLoggedIn() + if (isLoggedIn) return true + + const result = await magic.oauth.getRedirectResult() + return result !== null + } catch {} + return false + }, + + onAccountsChanged, + + onChainChanged(chain) { + const chainId = normalizeChainId(chain) + config.emitter.emit('change', { chainId }) + }, + + async onConnect(connectInfo) { + const chainId = normalizeChainId(connectInfo.chainId) + const accounts = await this.getAccounts() + config.emitter.emit('connect', { accounts, chainId }) + }, + + onDisconnect: () => { + config.emitter.emit('disconnect') + }, + })) +} diff --git a/src/lib/connectors/magicConnector.ts b/src/lib/connectors/magicConnector.ts index 5921d63..6fdbdb6 100644 --- a/src/lib/connectors/magicConnector.ts +++ b/src/lib/connectors/magicConnector.ts @@ -1,12 +1,12 @@ -import type { OAuthExtension } from '@magic-ext/oauth' +import { OAuthExtension } from '@magic-ext/oauth' import type { InstanceWithExtensions, + MagicSDKAdditionalConfiguration, MagicSDKExtensionsOption, SDKBase, } from '@magic-sdk/provider' -import { Chain, Connector } from '@wagmi/core' -import { createWalletClient, custom, getAddress } from 'viem' -import { normalizeChainId } from '../utils' +import { type EthNetworkConfiguration, Magic } from 'magic-sdk' +import { type Chain, createWalletClient, custom, getAddress } from 'viem' const IS_SERVER = typeof window === 'undefined' @@ -16,6 +16,9 @@ export interface MagicOptions { isDarkMode?: boolean customLogo?: string customHeaderText?: string + connectorType?: 'dedicated' | 'universal' + magicSdkConfiguration?: MagicSDKAdditionalConfiguration + networks?: EthNetworkConfiguration[] } /** @@ -25,23 +28,47 @@ export interface MagicOptions { * Dedicated Wallet Connector and Universal Wallet Connector are the two connectors provided by this library * And both of them extend this class. */ -export abstract class MagicConnector extends Connector { - ready = !IS_SERVER - readonly id = 'magic' - readonly name = 'Magic' - isModalOpen = false - protected constructor(config: { chains?: Chain[]; options: MagicOptions }) { - super(config) - if (!config.options.apiKey) { - throw new Error( - 'Magic API Key is required. Get one at https://dashboard.magic.link/', - ) +export interface MagicConnectorParams { + chains: readonly Chain[] + options: MagicOptions +} + +export function magicConnector({ chains = [], options }: MagicConnectorParams) { + if (!options.apiKey) { + throw new Error( + 'Magic API Key is required. Get one at https://dashboard.magic.link/', + ) + } + + const getMagicSDK = (): + | InstanceWithExtensions + | InstanceWithExtensions> + | null => { + if (options.connectorType === 'dedicated') { + return new Magic(options.apiKey, { + ...options.magicSdkConfiguration, + extensions: [new OAuthExtension()], + }) } + if (options.connectorType === 'universal') { + return new Magic(options.apiKey, { + ...options.magicSdkConfiguration, + network: + options.magicSdkConfiguration?.network ?? options?.networks?.[0], + }) + } + return null + } + + const getProvider = async () => { + const magic = getMagicSDK() + if (!magic) return null + return magic.rpcProvider } - async getAccount() { - const provider = await this.getProvider() + const getAccount = async () => { + const provider = await getProvider() const accounts = await provider?.request({ method: 'eth_accounts', }) @@ -49,10 +76,10 @@ export abstract class MagicConnector extends Connector { return account } - async getWalletClient({ chainId }: { chainId?: number } = {}): Promise { - const provider = await this.getProvider() - const account = await this.getAccount() - const chain = this.chains.find((x) => x.id === chainId) || this.chains[0] + const getWalletClient = async ({ chainId }: { chainId?: number } = {}) => { + const provider = await getProvider() + const account = await getAccount() + const chain = chains.find((x) => x.id === chainId) ?? chains[0] if (!provider) throw new Error('provider is required.') return createWalletClient({ account, @@ -61,55 +88,22 @@ export abstract class MagicConnector extends Connector { }) } - async getProvider() { - const magic = this.getMagicSDK() - return magic?.rpcProvider - } - - protected onAccountsChanged(accounts: string[]): void { - if (accounts.length === 0 || !accounts[0]) this.emit('disconnect') - else this.emit('change', { account: getAddress(accounts[0]) }) + const onAccountsChanged = async (accounts: string[]) => { + const provider = await getProvider() + if (accounts.length === 0 || !accounts[0]) provider?.emit('disconnect') + else provider?.emit('change', { account: getAddress(accounts[0]) }) } - protected onChainChanged(chainId: string | number): void { - const id = normalizeChainId(chainId) - const unsupported = this.isChainUnsupported(id) - this.emit('change', { chain: { id, unsupported } }) + return { + id: 'magic', + name: 'Magic', + type: 'Magic', + isModalOpen: false, + isReady: IS_SERVER, + getProvider, + getMagicSDK, + getAccount, + getWalletClient, + onAccountsChanged, } - - async getChainId(): Promise { - const provider = await this.getProvider() - if (provider) { - const chainId = await provider.request({ - method: 'eth_chainId', - params: [], - }) - return normalizeChainId(chainId) - } - const networkOptions = this.options.magicSdkConfiguration?.network - if (typeof networkOptions === 'object') { - const chainID = networkOptions.chainId - if (chainID) return normalizeChainId(chainID) - } - throw new Error('Chain ID is not defined') - } - - protected onDisconnect(): void { - this.emit('disconnect') - } - - async disconnect(): Promise { - try { - const magic = this.getMagicSDK() - await magic?.wallet.disconnect() - this.emit('disconnect') - } catch (error) { - console.error('Error disconnecting from Magic SDK:', error) - } - } - - abstract getMagicSDK(): - | InstanceWithExtensions - | InstanceWithExtensions> - | null } diff --git a/src/lib/connectors/universalWalletConnector.ts b/src/lib/connectors/universalWalletConnector.ts index a1ec234..f1a88d5 100644 --- a/src/lib/connectors/universalWalletConnector.ts +++ b/src/lib/connectors/universalWalletConnector.ts @@ -1,15 +1,10 @@ -import type { - InstanceWithExtensions, - MagicSDKAdditionalConfiguration, - MagicSDKExtensionsOption, - SDKBase, -} from '@magic-sdk/provider' +import type { MagicSDKAdditionalConfiguration } from '@magic-sdk/provider' import type { RPCProviderModule } from '@magic-sdk/provider/dist/types/modules/rpc-provider' import type { EthNetworkConfiguration } from '@magic-sdk/types' -import type { Chain } from '@wagmi/core' -import { Magic } from 'magic-sdk' +import { createConnector } from '@wagmi/core' import { normalizeChainId } from '../utils' -import { MagicConnector } from './magicConnector' +import { magicConnector } from './magicConnector' +import { type Chain, getAddress } from 'viem' export interface UniversalWalletOptions { apiKey: string @@ -36,127 +31,119 @@ export interface UniversalWalletOptions { * @see https://magic.link/docs/universal/overview */ -export class UniversalWalletConnector extends MagicConnector { - magic: InstanceWithExtensions< - SDKBase, - MagicSDKExtensionsOption - > | null - - constructor(config: { chains?: Chain[]; options: UniversalWalletOptions }) { - super(config) - this.magic = this.getMagicSDK() - } - - /** - * Get the Magic Instance - * @throws {Error} if Magic API Key is not provided - */ - getMagicSDK() { - const { apiKey, magicSdkConfiguration, networks } = this.options - if (typeof window === 'undefined') { - return null - } - if (this.magic) return this.magic - this.magic = new Magic(apiKey, { - ...magicSdkConfiguration, - network: magicSdkConfiguration?.network || networks?.[0], - }) - return this.magic - } - - /** - * Connect method attempts to connects to wallet using Universal Wallet modal - * this will open a modal for the user to select their wallet - */ - async connect() { - await this.magic?.wallet.connectWithUI() - const provider = await this.getProvider() - const chainId = await this.getChainId() - - provider && this.registerProviderEventListeners(provider) - - const account = await this.getAccount() - - return { - account, - chain: { - id: chainId, - unsupported: false, - }, - provider, - } - } +interface UniversalWalletConnectorParams { + chains: readonly Chain[] + options: UniversalWalletOptions +} - /** - * Provider events to run methods on various events - * on user session - */ - private registerProviderEventListeners(provider: RPCProviderModule) { +export function universalWalletConnector({ + chains, + options, +}: UniversalWalletConnectorParams) { + const { + id, + name, + type, + getAccount, + getMagicSDK, + getProvider, + onAccountsChanged, + } = magicConnector({ + chains, + options: { ...options, connectorType: 'universal' }, + }) + + const magic = getMagicSDK() + + const registerProviderEventListeners = ( + provider: RPCProviderModule, + onChainChanged: (chain: string) => void, + onDisconnect: () => void, + ) => { if (provider.on) { - provider.on('accountsChanged', this.onAccountsChanged) - provider.on('chainChanged', this.onChainChanged) - provider.on('disconnect', this.onDisconnect) + provider.on('accountsChanged', onAccountsChanged) + provider.on('chainChanged', (chain) => onChainChanged(chain)) + provider.on('disconnect', onDisconnect) } } - /** - * checks if user is authorized with Universal Wallet - */ - async isAuthorized() { - try { - const walletInfo = await this.magic?.wallet.getInfo() - return !!walletInfo - } catch { - return false - } - } - - /** - * method that switches chains given a chainId. - * This only works when user provides multiple networks in options - * @param chainId - * @throws {Error} if chainId is not supported - */ - async switchChain(chainId: number): Promise { - if (!this.options.networks) { - throw new Error( - 'switch chain not supported: please provide networks in options', - ) - } - - const normalizedChainId = normalizeChainId(chainId) - const chain = this.chains.find((x) => x.id === normalizedChainId) - if (!chain) throw new Error(`Unsupported chainId: ${chainId}`) - - const network = this.options.networks.find( - (x: string | { chainId: string }) => - typeof x === 'object' && x.chainId - ? normalizeChainId(x.chainId) === normalizedChainId - : normalizeChainId(x as string) === normalizedChainId, - ) - - if (!network) throw new Error(`Unsupported chainId: ${chainId}`) - - const account = await this.getAccount() - const provider = await this.getProvider() - - if (provider?.off) { - provider.off('accountsChanged', this.onAccountsChanged) - provider.off('chainChanged', this.onChainChanged) - provider.off('disconnect', this.onDisconnect) - } - - this.magic = new Magic(this.options.apiKey, { - ...this.options.magicSdkConfiguration, - network: network, - }) - - this.registerProviderEventListeners(this.magic.rpcProvider) - this.onChainChanged(chain.id) - this.onAccountsChanged([account]) - - return chain - } + return createConnector((config) => ({ + id, + name, + type, + getProvider, + connect: async function () { + await magic?.wallet.connectWithUI() + const provider = await getProvider() + const chainId = await this.getChainId() + provider && + registerProviderEventListeners( + provider, + (chain) => { + const chainId = normalizeChainId(chain) + config.emitter.emit('change', { chainId }) + }, + this.onDisconnect, + ) + const account = await getAccount() + return { + accounts: [account], + chainId, + } + }, + onAccountsChanged, + getAccounts: async () => { + const provider = await getProvider() + const accounts = (await provider?.request({ + method: 'eth_accounts', + })) as string[] + return accounts.map((x) => getAddress(x)) + }, + + onChainChanged: (chain) => { + const chainId = normalizeChainId(chain) + config.emitter.emit('change', { chainId }) + }, + async onConnect(connectInfo) { + const chainId = normalizeChainId(connectInfo.chainId) + const accounts = await this.getAccounts() + config.emitter.emit('connect', { accounts, chainId }) + }, + disconnect: async () => { + try { + await magic?.wallet.disconnect() + config.emitter.emit('disconnect') + } catch (error) { + console.error('Error disconnecting from Magic SDK:', error) + } + }, + isAuthorized: async () => { + try { + const walletInfo = await magic?.wallet.getInfo() + return !!walletInfo + } catch { + return false + } + }, + getChainId: async (): Promise => { + const provider = await getProvider() + if (provider) { + const chainId = await provider.request({ + method: 'eth_chainId', + params: [], + }) + return normalizeChainId(chainId) + } + const networkOptions = options.magicSdkConfiguration?.network + if (typeof networkOptions === 'object') { + const chainID = networkOptions.chainId + if (chainID) return normalizeChainId(chainID) + } + throw new Error('Chain ID is not defined') + }, + + onDisconnect: () => { + config.emitter.emit('disconnect') + }, + })) } - -export class MagicConnectConnector extends UniversalWalletConnector {} diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 7f625bb..dee6622 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -2,7 +2,7 @@ export function normalizeChainId(chainId: string | number | bigint) { if (typeof chainId === 'string') return Number.parseInt( chainId, - chainId.trim().substring(0, 2) === '0x' ? 16 : 10, + chainId.trim().startsWith('0x') ? 16 : 10, ) if (typeof chainId === 'bigint') return Number(chainId) return chainId