diff --git a/package.json b/package.json index fac0292..5217efe 100644 --- a/package.json +++ b/package.json @@ -17,30 +17,31 @@ "format": "rome format . --write", "lint": "rome check .", "lint:fix": "yarn lint --apply", - "watch:build": "tsc -p tsconfig.json -w", - "release": "yarn build && changeset publish" + "watch:build": "tsc -p tsconfig.json -w" }, "engines": { "node": ">=10" }, "dependencies": { "@changesets/cli": "^2.24.0", - "@magic-ext/oauth": "^12.3.0", + "@magic-ext/oauth": "^22.0.3", "@magic-sdk/provider": "^28.6.0", - "@wagmi/connectors": "^4.1.14", - "@wagmi/core": "^2.6.5", + "@wagmi/connectors": "^5.0.6", + "@wagmi/core": "^2.10.4", "magic-sdk": "^28.6.0", - "tsc-esm-fix": "^2.20.10" + "tsc-esm-fix": "^2.20.27" }, "devDependencies": { "@types/node": "^20.11.24", "changeset": "^0.2.6", + "localforage": "^1.10.0", "rome": "12.0.0", "typescript": "^5.0.4", "viem": "2.x" }, "peerDependencies": { - "viem": "2.x" + "viem": "2.x", + "localforage": ">=1.7.4" }, "files": [ "dist", diff --git a/src/lib/connectors/universalWalletConnector.ts b/src/lib/connectors/universalWalletConnector.ts index f1a88d5..66288a0 100644 --- a/src/lib/connectors/universalWalletConnector.ts +++ b/src/lib/connectors/universalWalletConnector.ts @@ -3,7 +3,7 @@ import type { RPCProviderModule } from '@magic-sdk/provider/dist/types/modules/r import type { EthNetworkConfiguration } from '@magic-sdk/types' import { createConnector } from '@wagmi/core' import { normalizeChainId } from '../utils' -import { magicConnector } from './magicConnector' +import { MagicOptions, magicConnector } from './magicConnector' import { type Chain, getAddress } from 'viem' export interface UniversalWalletOptions { @@ -71,10 +71,14 @@ export function universalWalletConnector({ id, name, type, + magic, getProvider, - connect: async function () { - await magic?.wallet.connectWithUI() - const provider = await getProvider() + getAccount, + onAccountsChanged, + + async connect() { + await this.magic?.wallet.connectWithUI() + const provider = await this.getProvider() as RPCProviderModule const chainId = await this.getChainId() provider && registerProviderEventListeners( @@ -85,15 +89,15 @@ export function universalWalletConnector({ }, this.onDisconnect, ) - const account = await getAccount() + const account: any = await this.getAccount() return { accounts: [account], chainId, } }, - onAccountsChanged, - getAccounts: async () => { - const provider = await getProvider() + + async getAccounts() { + const provider: any = await this.getProvider() const accounts = (await provider?.request({ method: 'eth_accounts', })) as string[] @@ -109,17 +113,17 @@ export function universalWalletConnector({ const accounts = await this.getAccounts() config.emitter.emit('connect', { accounts, chainId }) }, - disconnect: async () => { + async disconnect() { try { - await magic?.wallet.disconnect() + await this.magic?.user.logout() config.emitter.emit('disconnect') } catch (error) { console.error('Error disconnecting from Magic SDK:', error) } }, - isAuthorized: async () => { + async isAuthorized() { try { - const walletInfo = await magic?.wallet.getInfo() + const walletInfo = await (this.magic as any)?.user.getInfo() return !!walletInfo } catch { return false @@ -141,7 +145,50 @@ export function universalWalletConnector({ } throw new Error('Chain ID is not defined') }, + switchChain: async function ({ chainId }: { chainId: number }) { + if (!options.networks) { + throw new Error('switch chain not supported: please provide networks in options') + } + const normalizedChainId = normalizeChainId(chainId) + const chain = chains.find((x) => x.id === normalizedChainId) + + if (!chain) + throw new Error(`Unsupported chainId: ${chainId}`) + + const network = options.networks.find((x) => typeof x === 'object' && x.chainId + ? normalizeChainId(x.chainId) === normalizedChainId + : normalizeChainId(x as bigint | number | string) === normalizedChainId) + + if (!network) + throw new Error(`Unsupported chainId: ${chainId}`) + + const account = await this.getAccount() + const provider = await this.getProvider() as RPCProviderModule + + if (provider?.off) { + provider.off('accountsChanged', this.onAccountsChanged) + provider.off('chainChanged', this.onChainChanged) + provider.off('disconnect', this.onDisconnect) + } + + const newOptions: MagicOptions = {...options, connectorType: 'universal'} + newOptions.magicSdkConfiguration!.network = network + + const { getAccount, getMagicSDK, getProvider, onAccountsChanged, } = magicConnector({ + chains, + options: newOptions, + }) + this.getAccount = getAccount + this.magic = getMagicSDK() + this.getProvider = getProvider + this.onAccountsChanged = onAccountsChanged + + registerProviderEventListeners(this.magic!.rpcProvider, this.onChainChanged, this.onDisconnect) + this.onChainChanged(chain.id.toString()) + this.onAccountsChanged([account]) + return chain + }, onDisconnect: () => { config.emitter.emit('disconnect') },