Skip to content

Commit 681b0f1

Browse files
committed
refactor: decouple EVM connectors from app env — accept metadata via factory params
1 parent f56c340 commit 681b0f1

8 files changed

Lines changed: 137 additions & 113 deletions

File tree

src/sdk/react/evm/connectors/connectkit.tsx

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ import { ConnectKitProvider, getDefaultConfig, useModal } from 'connectkit'
22
import type { FC, ReactNode } from 'react'
33
import type { Chain, Transport } from 'viem'
44
import { createConfig } from 'wagmi'
5-
import { env } from '@/src/env'
65

7-
import type { EvmConnectorConfig } from '../types'
6+
import type { ConnectorAppMetadata, EvmConnectorConfig } from '../types'
87

98
const WalletProvider: FC<{ children: ReactNode }> = ({ children }) => (
109
<ConnectKitProvider
@@ -22,20 +21,22 @@ function useConnectModal() {
2221
return { open: () => setOpen(true) }
2322
}
2423

25-
/** ConnectKit-backed EVM connector. */
26-
export const connectkitConnector: EvmConnectorConfig = {
27-
createConfig(chains: Chain[], transports: Record<number, Transport>) {
28-
const connectkitParams = getDefaultConfig({
29-
chains: chains as [Chain, ...Chain[]],
30-
transports,
31-
walletConnectProjectId: env.PUBLIC_WALLETCONNECT_PROJECT_ID,
32-
appName: env.PUBLIC_APP_NAME,
33-
appDescription: env.PUBLIC_APP_DESCRIPTION,
34-
appUrl: env.PUBLIC_APP_URL,
35-
appIcon: env.PUBLIC_APP_LOGO,
36-
})
37-
return createConfig(connectkitParams)
38-
},
39-
WalletProvider,
40-
useConnectModal,
24+
/** Creates a ConnectKit-backed EVM connector from app metadata. */
25+
export function createConnectkitConnector(metadata: ConnectorAppMetadata): EvmConnectorConfig {
26+
return {
27+
createConfig(chains: Chain[], transports: Record<number, Transport>) {
28+
const connectkitParams = getDefaultConfig({
29+
chains: chains as [Chain, ...Chain[]],
30+
transports,
31+
walletConnectProjectId: metadata.walletConnectProjectId,
32+
appName: metadata.appName,
33+
appDescription: metadata.appDescription,
34+
appUrl: metadata.appUrl,
35+
appIcon: metadata.appIcon,
36+
})
37+
return createConfig(connectkitParams)
38+
},
39+
WalletProvider,
40+
useConnectModal,
41+
}
4142
}

src/sdk/react/evm/connectors/connectors.test.ts

Lines changed: 37 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,57 @@ import { http } from 'viem'
22
import { mainnet } from 'viem/chains'
33
import { describe, expect, it } from 'vitest'
44

5-
import { connectkitConnector } from './connectkit'
6-
import { rainbowkitConnector } from './rainbowkit'
7-
import { reownConnector } from './reown'
5+
import type { ConnectorAppMetadata } from '../types'
6+
import { createConnectkitConnector } from './connectkit'
7+
import { createRainbowkitConnector } from './rainbowkit'
8+
import { createReownConnector } from './reown'
89

9-
describe('connectkitConnector', () => {
10-
it('createConfig returns a wagmi Config containing the supplied chain', () => {
11-
const config = connectkitConnector.createConfig([mainnet], { [mainnet.id]: http() })
12-
expect(config.chains).toContain(mainnet)
13-
})
14-
15-
it('WalletProvider is a function', () => {
16-
expect(typeof connectkitConnector.WalletProvider).toBe('function')
17-
})
10+
const testMetadata: ConnectorAppMetadata = {
11+
appName: 'Test App',
12+
walletConnectProjectId: 'test-project-id',
13+
}
1814

19-
it('useConnectModal is a function', () => {
20-
expect(typeof connectkitConnector.useConnectModal).toBe('function')
15+
describe('createConnectkitConnector', () => {
16+
it('returns an EvmConnectorConfig with createConfig, WalletProvider, useConnectModal', () => {
17+
const connector = createConnectkitConnector(testMetadata)
18+
expect(typeof connector.createConfig).toBe('function')
19+
expect(typeof connector.WalletProvider).toBe('function')
20+
expect(typeof connector.useConnectModal).toBe('function')
2121
})
22-
})
2322

24-
describe('rainbowkitConnector', () => {
2523
it('createConfig returns a wagmi Config containing the supplied chain', () => {
26-
const config = rainbowkitConnector.createConfig([mainnet], { [mainnet.id]: http() })
24+
const connector = createConnectkitConnector(testMetadata)
25+
const config = connector.createConfig([mainnet], { [mainnet.id]: http() })
2726
expect(config.chains).toContain(mainnet)
2827
})
28+
})
2929

30-
it('WalletProvider is a function', () => {
31-
expect(typeof rainbowkitConnector.WalletProvider).toBe('function')
30+
describe('createRainbowkitConnector', () => {
31+
it('returns an EvmConnectorConfig with createConfig, WalletProvider, useConnectModal', () => {
32+
const connector = createRainbowkitConnector(testMetadata)
33+
expect(typeof connector.createConfig).toBe('function')
34+
expect(typeof connector.WalletProvider).toBe('function')
35+
expect(typeof connector.useConnectModal).toBe('function')
3236
})
3337

34-
it('useConnectModal is a function', () => {
35-
expect(typeof rainbowkitConnector.useConnectModal).toBe('function')
38+
it('createConfig returns a wagmi Config containing the supplied chain', () => {
39+
const connector = createRainbowkitConnector(testMetadata)
40+
const config = connector.createConfig([mainnet], { [mainnet.id]: http() })
41+
expect(config.chains).toContain(mainnet)
3642
})
3743
})
3844

39-
describe('reownConnector', () => {
40-
it('createConfig returns a wagmi Config containing the supplied chain id', () => {
41-
const config = reownConnector.createConfig([mainnet], { [mainnet.id]: http() })
42-
// Reown's WagmiAdapter wraps chains with extra fields (chainNamespace, caipNetworkId, assets),
43-
// so reference equality fails — assert by chain id instead.
44-
expect(config.chains).toContainEqual(expect.objectContaining({ id: mainnet.id }))
45+
describe('createReownConnector', () => {
46+
it('returns an EvmConnectorConfig with createConfig, WalletProvider, useConnectModal', () => {
47+
const connector = createReownConnector(testMetadata)
48+
expect(typeof connector.createConfig).toBe('function')
49+
expect(typeof connector.WalletProvider).toBe('function')
50+
expect(typeof connector.useConnectModal).toBe('function')
4551
})
4652

47-
it('WalletProvider is a function', () => {
48-
expect(typeof reownConnector.WalletProvider).toBe('function')
49-
})
50-
51-
it('useConnectModal is a function', () => {
52-
expect(typeof reownConnector.useConnectModal).toBe('function')
53+
it('createConfig returns a wagmi Config containing the supplied chain id', () => {
54+
const connector = createReownConnector(testMetadata)
55+
const config = connector.createConfig([mainnet], { [mainnet.id]: http() })
56+
expect(config.chains).toContainEqual(expect.objectContaining({ id: mainnet.id }))
5357
})
5458
})
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
export { connectkitConnector } from './connectkit'
2-
export { rainbowkitConnector } from './rainbowkit'
3-
export { reownConnector } from './reown'
1+
export { createConnectkitConnector } from './connectkit'
2+
export { createRainbowkitConnector } from './rainbowkit'
3+
export { createReownConnector } from './reown'

src/sdk/react/evm/connectors/rainbowkit.tsx

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,11 @@ import {
44
useAccountModal as useRainbowAccountModal,
55
useConnectModal as useRainbowConnectModal,
66
} from '@rainbow-me/rainbowkit'
7-
import { env } from '@/src/env'
87
import '@rainbow-me/rainbowkit/styles.css'
98
import type { FC, ReactNode } from 'react'
109
import type { Chain, Transport } from 'viem'
1110

12-
import type { EvmConnectorConfig } from '../types'
11+
import type { ConnectorAppMetadata, EvmConnectorConfig } from '../types'
1312

1413
const WalletProvider: FC<{ children: ReactNode }> = ({ children }) => (
1514
<RainbowKitProvider>{children}</RainbowKitProvider>
@@ -24,19 +23,21 @@ function useConnectModal() {
2423
}
2524
}
2625

27-
/** RainbowKit-backed EVM connector. */
28-
export const rainbowkitConnector: EvmConnectorConfig = {
29-
createConfig(chains: Chain[], transports: Record<number, Transport>) {
30-
return getDefaultConfig({
31-
chains: chains as [Chain, ...Chain[]],
32-
transports,
33-
projectId: env.PUBLIC_WALLETCONNECT_PROJECT_ID,
34-
appName: env.PUBLIC_APP_NAME,
35-
appDescription: env.PUBLIC_APP_DESCRIPTION,
36-
appUrl: env.PUBLIC_APP_URL,
37-
appIcon: env.PUBLIC_APP_LOGO,
38-
})
39-
},
40-
WalletProvider,
41-
useConnectModal,
26+
/** Creates a RainbowKit-backed EVM connector from app metadata. */
27+
export function createRainbowkitConnector(metadata: ConnectorAppMetadata): EvmConnectorConfig {
28+
return {
29+
createConfig(chains: Chain[], transports: Record<number, Transport>) {
30+
return getDefaultConfig({
31+
chains: chains as [Chain, ...Chain[]],
32+
transports,
33+
projectId: metadata.walletConnectProjectId,
34+
appName: metadata.appName,
35+
appDescription: metadata.appDescription,
36+
appUrl: metadata.appUrl,
37+
appIcon: metadata.appIcon,
38+
})
39+
},
40+
WalletProvider,
41+
useConnectModal,
42+
}
4243
}

src/sdk/react/evm/connectors/reown.tsx

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@ import { createAppKit, useAppKit } from '@reown/appkit/react'
22
import { WagmiAdapter } from '@reown/appkit-adapter-wagmi'
33
import type { FC, PropsWithChildren } from 'react'
44
import type { Chain, Transport } from 'viem'
5-
import { env } from '@/src/env'
65

7-
import type { EvmConnectorConfig } from '../types'
6+
import type { ConnectorAppMetadata, EvmConnectorConfig } from '../types'
87

98
const WalletProvider: FC<PropsWithChildren> = ({ children }) => <>{children}</>
109

@@ -13,36 +12,34 @@ function useConnectModal() {
1312
return { open }
1413
}
1514

16-
/** Reown/AppKit-backed EVM connector. */
17-
export const reownConnector: EvmConnectorConfig = {
18-
createConfig(chains: Chain[], transports: Record<number, Transport>) {
19-
const projectId = env.PUBLIC_WALLETCONNECT_PROJECT_ID
20-
21-
const metadata = {
22-
name: env.PUBLIC_APP_NAME,
23-
description: env.PUBLIC_APP_DESCRIPTION ?? '',
24-
url: env.PUBLIC_APP_URL ?? '',
25-
icons: [env.PUBLIC_APP_LOGO ?? ''],
26-
}
27-
28-
const wagmiAdapter = new WagmiAdapter({
29-
networks: chains as unknown as Chain[],
30-
transports,
31-
projectId,
32-
})
33-
34-
createAppKit({
35-
adapters: [wagmiAdapter],
36-
networks: chains as unknown as [Chain, ...Chain[]],
37-
metadata,
38-
projectId,
39-
features: {
40-
analytics: true,
41-
},
42-
})
43-
44-
return wagmiAdapter.wagmiConfig
45-
},
46-
WalletProvider,
47-
useConnectModal,
15+
/** Creates a Reown/AppKit-backed EVM connector from app metadata. */
16+
export function createReownConnector(metadata: ConnectorAppMetadata): EvmConnectorConfig {
17+
return {
18+
createConfig(chains: Chain[], transports: Record<number, Transport>) {
19+
const wagmiAdapter = new WagmiAdapter({
20+
networks: chains as unknown as Chain[],
21+
transports,
22+
projectId: metadata.walletConnectProjectId,
23+
})
24+
25+
createAppKit({
26+
adapters: [wagmiAdapter],
27+
networks: chains as unknown as [Chain, ...Chain[]],
28+
metadata: {
29+
name: metadata.appName,
30+
description: metadata.appDescription ?? '',
31+
url: metadata.appUrl ?? '',
32+
icons: [metadata.appIcon ?? ''],
33+
},
34+
projectId: metadata.walletConnectProjectId,
35+
features: {
36+
analytics: true,
37+
},
38+
})
39+
40+
return wagmiAdapter.wagmiConfig
41+
},
42+
WalletProvider,
43+
useConnectModal,
44+
}
4845
}

src/sdk/react/evm/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1-
export { connectkitConnector, rainbowkitConnector, reownConnector } from './connectors'
1+
export {
2+
createConnectkitConnector,
3+
createRainbowkitConnector,
4+
createReownConnector,
5+
} from './connectors'
26
export type { UseEvmReadOnlyOptions } from './read-only'
37
export { useEvmReadOnly } from './read-only'
4-
export type { EvmConnectorConfig } from './types'
8+
export type { ConnectorAppMetadata, EvmConnectorConfig } from './types'
59
export type { EvmWalletBundleConfig } from './wallet-bundle'
610
export { createEvmWalletBundle } from './wallet-bundle'

src/sdk/react/evm/types.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@ import type { FC, ReactNode } from 'react'
22

33
import type { EvmCoreConnectorConfig } from '../../core/evm/types'
44

5+
/** App metadata passed to connector factories. Decouples SDK from app env config. */
6+
export interface ConnectorAppMetadata {
7+
appName: string
8+
appDescription?: string
9+
appUrl?: string
10+
appIcon?: string
11+
walletConnectProjectId: string
12+
}
13+
514
/** React-layer EVM connector config — extends core with UI components. */
615
export interface EvmConnectorConfig extends EvmCoreConnectorConfig {
716
WalletProvider: FC<{ children: ReactNode }>

src/wallet/connectors/wagmi.config.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,21 @@
22
* Shared wagmi Config and connector — the single place to choose which EVM connector to use.
33
* Both the SDK adapter (in __root.tsx) and generated contract hooks reference this file.
44
*
5-
* To switch connectors, change the import below:
6-
* import { connectkitConnector as connector } from '@/src/sdk/react/evm'
7-
* import { rainbowkitConnector as connector } from '@/src/sdk/react/evm'
8-
* import { reownConnector as connector } from '@/src/sdk/react/evm'
5+
* To switch connectors, change the factory call below:
6+
* createConnectkitConnector(metadata)
7+
* createRainbowkitConnector(metadata)
8+
* createReownConnector(metadata)
99
*/
1010
import { chains, transports } from '@/src/core/types'
11-
import { connectkitConnector as connector } from '@/src/sdk/react/evm'
11+
import { env } from '@/src/env'
12+
import { createConnectkitConnector } from '@/src/sdk/react/evm'
13+
14+
export const connector = createConnectkitConnector({
15+
appName: env.PUBLIC_APP_NAME,
16+
appDescription: env.PUBLIC_APP_DESCRIPTION,
17+
appUrl: env.PUBLIC_APP_URL,
18+
appIcon: env.PUBLIC_APP_LOGO,
19+
walletConnectProjectId: env.PUBLIC_WALLETCONNECT_PROJECT_ID,
20+
})
1221

13-
export { connector }
1422
export const config = connector.createConfig([...chains], transports)

0 commit comments

Comments
 (0)