11import {
22 type AddEthereumChainParameter ,
33 createMetamaskConnectEVM ,
4+ type EIP1193Provider ,
45 type MetamaskConnectEVM ,
56} from '@metamask/connect-evm' ;
67
@@ -13,7 +14,7 @@ import {
1314import type { OneOf } from '@wagmi/core/internal' ;
1415
1516import {
16- type EIP1193Provider ,
17+ type Address ,
1718 getAddress ,
1819 type ProviderConnectInfo ,
1920 ResourceUnavailableRpcError ,
@@ -80,30 +81,83 @@ export function metaMask(parameters: MetaMaskParameters = {}) {
8081 } ) ;
8182 } ,
8283
83- async connect < withCapabilities extends boolean = false > ( parameters ?: {
84+ async connect < withCapabilities extends boolean = false > ( connectParams ?: {
8485 chainId ?: number | undefined ;
8586 isReconnecting ?: boolean | undefined ;
8687 withCapabilities ?: withCapabilities | boolean | undefined ;
8788 } ) {
88- const chainId = parameters ?. chainId ?? DEFAULT_CHAIN_ID ;
89- const withCapabilities = parameters ?. withCapabilities ;
90-
91- // TODO: Add connectAndSign and connectWith support, including events
89+ const chainId = connectParams ?. chainId ?? DEFAULT_CHAIN_ID ;
90+ const withCapabilities = connectParams ?. withCapabilities ;
91+
92+ let accounts : readonly string [ ] = [ ] ;
93+ if ( connectParams ?. isReconnecting ) {
94+ accounts = ( await this . getAccounts ( ) . catch ( ( ) => [ ] ) ) . map ( ( account ) =>
95+ getAddress ( account ) ,
96+ ) ;
97+ }
9298
9399 try {
94- const result = await metamask . connect ( {
95- chainId,
96- account : undefined ,
97- } ) ;
100+ let signResponse : string | undefined ;
101+ let connectWithResponse : unknown | undefined ;
102+
103+ if ( ! accounts ?. length ) {
104+ if ( parameters . connectAndSign || parameters . connectWith ) {
105+ if ( parameters . connectAndSign ) {
106+ signResponse = await ( metamask as any ) . connectAndSign ( {
107+ msg : parameters . connectAndSign ,
108+ } ) ;
109+ } else if ( parameters . connectWith ) {
110+ connectWithResponse = await ( metamask as any ) . connectWith ( {
111+ method : parameters . connectWith . method ,
112+ params : parameters . connectWith . params ,
113+ } ) ;
114+ }
115+
116+ accounts = ( await this . getAccounts ( ) ) . map ( ( account ) =>
117+ getAddress ( account ) ,
118+ ) ;
119+ } else {
120+ const result = await metamask . connect ( {
121+ chainId,
122+ account : undefined ,
123+ } ) ;
124+ accounts = result . accounts . map ( ( account ) => getAddress ( account ) ) ;
125+ }
126+ }
127+
128+ // Switch to chain if provided
129+ let currentChainId = ( await this . getChainId ( ) ) as number ;
130+ if ( chainId && currentChainId !== chainId ) {
131+ const chain = await this . switchChain ! ( { chainId } ) . catch ( ( error ) => {
132+ if ( error . code === UserRejectedRequestError . code ) throw error ;
133+ return { id : currentChainId } ;
134+ } ) ;
135+ currentChainId = chain ?. id ?? currentChainId ;
136+ }
137+
138+ // Emit events for connectAndSign and connectWith
139+ const provider = await this . getProvider ( ) ;
140+ if ( signResponse )
141+ provider . emit ( 'connectAndSign' , {
142+ accounts : accounts as Address [ ] ,
143+ chainId : currentChainId ,
144+ signResponse,
145+ } ) ;
146+ else if ( connectWithResponse )
147+ provider . emit ( 'connectWith' , {
148+ accounts : accounts as Address [ ] ,
149+ chainId : currentChainId ,
150+ connectWithResponse,
151+ } ) ;
98152
99153 return {
100154 accounts : ( withCapabilities
101- ? result . accounts . map ( ( account ) => ( {
155+ ? accounts . map ( ( account ) => ( {
102156 address : account ,
103157 capabilities : { } ,
104158 } ) )
105- : result . accounts ) as never ,
106- chainId : result . chainId ?? chainId ,
159+ : accounts ) as never ,
160+ chainId : currentChainId ,
107161 } ;
108162 } catch ( err ) {
109163 const error = err as RpcError ;
@@ -199,15 +253,6 @@ export function metaMask(parameters: MetaMaskParameters = {}) {
199253 } ,
200254
201255 async onAccountsChanged ( accounts ) {
202- // TODO: verify if this is needed or if we can just rely on the
203- // existing disconnect event instead
204- // Disconnect if there are no accounts
205- if ( accounts . length === 0 ) {
206- this . onDisconnect ( ) ;
207- return ;
208- }
209- // Regular change event
210-
211256 config . emitter . emit ( 'change' , {
212257 accounts : accounts . map ( ( account ) => getAddress ( account ) ) ,
213258 } ) ;
@@ -231,7 +276,7 @@ export function metaMask(parameters: MetaMaskParameters = {}) {
231276 // https://github.com/MetaMask/providers/pull/120
232277 if ( error && ( error as unknown as RpcError < 1013 > ) . code === 1013 ) {
233278 const provider = await this . getProvider ( ) ;
234- if ( provider && ( await this . getAccounts ( ) ) . length > 0 ) return ;
279+ if ( provider && ! ! ( await this . getAccounts ( ) ) . length ) return ;
235280 }
236281
237282 config . emitter . emit ( 'disconnect' ) ;
0 commit comments