Skip to content

Commit

Permalink
refactor: handle custom transport objects for wagmi adapter (#3072)
Browse files Browse the repository at this point in the history
  • Loading branch information
enesozturk authored Oct 11, 2024
1 parent 6cf5745 commit e4adf06
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 32 deletions.
23 changes: 23 additions & 0 deletions .changeset/warm-toes-unite.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
'@reown/appkit-adapter-wagmi': patch
'@reown/appkit-utils': patch
'@apps/demo': patch
'@apps/gallery': patch
'@apps/laboratory': patch
'@reown/appkit-adapter-ethers': patch
'@reown/appkit-adapter-ethers5': patch
'@reown/appkit-adapter-polkadot': patch
'@reown/appkit-adapter-solana': patch
'@reown/appkit': patch
'@reown/appkit-cdn': patch
'@reown/appkit-common': patch
'@reown/appkit-core': patch
'@reown/appkit-experimental': patch
'@reown/appkit-polyfills': patch
'@reown/appkit-scaffold-ui': patch
'@reown/appkit-siwe': patch
'@reown/appkit-ui': patch
'@reown/appkit-wallet': patch
---

Refactors wagmi constructor to handle custom transpor objects
14 changes: 11 additions & 3 deletions packages/adapters/wagmi/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import type {
WriteContractArgs
} from '@reown/appkit-core'
import { formatUnits, parseUnits } from 'viem'
import type { Hex } from 'viem'
import type { Hex, HttpTransport } from 'viem'
import {
ConstantsUtil,
PresetsUtil,
Expand All @@ -59,7 +59,6 @@ import {
import { isReownName, SafeLocalStorage, SafeLocalStorageKeys } from '@reown/appkit-common'
import {
getEmailCaipNetworks,
getTransport,
getWalletConnectCaipNetworks,
parseWalletCapabilities,
requireCaipAddress
Expand Down Expand Up @@ -169,9 +168,18 @@ export class WagmiAdapter implements ChainAdapter {

const transportsArr = this.wagmiChains.map(chain => [
chain.id,
getTransport({ chain: chain as Chain, projectId: configParams.projectId })
CaipNetworksUtil.getViemTransport(chain as CaipNetwork)
])

Object.entries(configParams.transports ?? {}).forEach(([chainId, transport]) => {
const index = transportsArr.findIndex(([id]) => id === Number(chainId))
if (index === -1) {
transportsArr.push([Number(chainId), transport as HttpTransport])
} else {
transportsArr[index] = [Number(chainId), transport as HttpTransport]
}
})

const transports = Object.fromEntries(transportsArr)
const connectors: CreateConnectorFn[] = [...(configParams.connectors ?? [])]

Expand Down
65 changes: 65 additions & 0 deletions packages/adapters/wagmi/src/tests/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
import { connect, disconnect, getAccount, getChainId, getEnsName, getBalance } from '@wagmi/core'
import { CaipNetworksUtil, ConstantsUtil } from '@reown/appkit-utils'
import type { CaipNetwork } from '@reown/appkit-common'
import { http } from 'viem'
import { WagmiAdapter } from '../client'

const [mainnet, arbitrum] = CaipNetworksUtil.extendCaipNetworks(
[AppkitMainnet, AppkitArbitrum, AppkitPolygon, AppkitOptimism, AppkitBsc],
Expand Down Expand Up @@ -495,4 +497,67 @@ describe('Wagmi Client', () => {
expect(mockAppKit.redirect).toHaveBeenCalledWith('ApproveTransaction')
})
})

describe('Wagmi Client - Transports', () => {
it('should use default transports for networks without custom transports', () => {
const client = new WagmiAdapter({
projectId: '123',
networks: [mainnet, arbitrum]
})

expect(client.wagmiConfig._internal.transports).toBeDefined()
expect(client.wagmiConfig._internal.transports[mainnet.id as number]).toBeDefined()
expect(client.wagmiConfig._internal.transports[arbitrum.id as number]).toBeDefined()
})

it('should merge user-provided transports with default transports', () => {
const customTransport = http('https://custom-rpc.example.com')
const client = new WagmiAdapter({
projectId: '123',
networks: [mainnet, arbitrum],
transports: {
[mainnet.id]: customTransport
}
})

expect(client.wagmiConfig._internal.transports).toBeDefined()
expect(client.wagmiConfig._internal.transports[mainnet.id as number]).toBe(customTransport)
expect(client.wagmiConfig._internal.transports[arbitrum.id as number]).toBeDefined()
expect(client.wagmiConfig._internal.transports[arbitrum.id as number]).not.toBe(
customTransport
)
})

it('should prioritize user-provided transports over default ones', () => {
const customTransport1 = http('https://custom-rpc1.example.com')
const customTransport2 = http('https://custom-rpc2.example.com')
const client = new WagmiAdapter({
projectId: '123',
networks: [mainnet, arbitrum],
transports: {
[mainnet.id]: customTransport1,
[arbitrum.id]: customTransport2
}
})

expect(client.wagmiConfig._internal.transports).toBeDefined()
expect(client.wagmiConfig._internal.transports[mainnet.id as number]).toBe(customTransport1)
expect(client.wagmiConfig._internal.transports[arbitrum.id as number]).toBe(customTransport2)
})

it('should handle transports for networks not in the provided networks array', () => {
const customTransport = http('https://custom-rpc.example.com')
const client = new WagmiAdapter({
projectId: '123',
networks: [mainnet],
transports: {
[arbitrum.id]: customTransport
}
})

expect(client.wagmiConfig._internal.transports).toBeDefined()
expect(client.wagmiConfig._internal.transports[mainnet.id as number]).toBeDefined()
expect(client.wagmiConfig._internal.transports[arbitrum.id as number]).toBe(customTransport)
})
})
})
28 changes: 1 addition & 27 deletions packages/adapters/wagmi/src/utils/helpers.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import { type CaipNetworkId } from '@reown/appkit-common'
import { ConstantsUtil, PresetsUtil } from '@reown/appkit-utils'
import { UniversalProvider } from '@walletconnect/universal-provider'
import { fallback, http, type Hex } from 'viem'
import { type Hex } from 'viem'

import type { Chain } from '@wagmi/core/chains'
import type { Connector } from '@wagmi/core'
import { CoreHelperUtil } from '@reown/appkit-core'
import { WcHelpersUtil } from '@reown/appkit'

export async function getWalletConnectCaipNetworks(connector?: Connector) {
Expand Down Expand Up @@ -35,30 +33,6 @@ export function getEmailCaipNetworks() {
}
}

export function getTransport({ chain, projectId }: { chain: Chain; projectId: string }) {
const RPC_URL = CoreHelperUtil.getBlockchainApiUrl()
const chainDefaultUrl = chain.rpcUrls.default.http?.[0]

if (!PresetsUtil.WalletConnectRpcChainIds.includes(chain.id)) {
return http(chainDefaultUrl)
}

return fallback([
http(`${RPC_URL}/v1/?chainId=${ConstantsUtil.EIP155}:${chain.id}&projectId=${projectId}`, {
/*
* The Blockchain API uses "Content-Type: text/plain" to avoid OPTIONS preflight requests
* It will only work for viem >= 2.17.7
*/
fetchOptions: {
headers: {
'Content-Type': 'text/plain'
}
}
}),
http(chainDefaultUrl)
])
}

export function requireCaipAddress(caipAddress: string) {
if (!caipAddress) {
throw new Error('No CAIP address provided')
Expand Down
3 changes: 2 additions & 1 deletion packages/appkit-utils/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@
"@reown/appkit-wallet": "workspace:*",
"@walletconnect/logger": "2.1.2",
"@walletconnect/universal-provider": "2.17.0",
"valtio": "1.11.2"
"valtio": "1.11.2",
"viem": "2.x"
},
"devDependencies": {
"@coinbase/wallet-sdk": "4.0.3",
Expand Down
24 changes: 24 additions & 0 deletions packages/appkit-utils/src/CaipNetworkUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
type CaipNetworkId
} from '@reown/appkit-common'
import { PresetsUtil } from './PresetsUtil.js'
import { fallback, http } from 'viem'

const RPC_URL_HOST = 'rpc.walletconnect.org'

Expand Down Expand Up @@ -170,5 +171,28 @@ export const CaipNetworksUtil = {
projectId
})
) as [CaipNetwork, ...CaipNetwork[]]
},

getViemTransport(caipNetwork: CaipNetwork) {
const chainDefaultUrl = caipNetwork.rpcUrls.default.http?.[0]

if (!WC_HTTP_RPC_SUPPORTED_CHAINS.includes(caipNetwork.caipNetworkId)) {
return http(chainDefaultUrl)
}

return fallback([
http(chainDefaultUrl, {
/*
* The Blockchain API uses "Content-Type: text/plain" to avoid OPTIONS preflight requests
* It will only work for viem >= 2.17.7
*/
fetchOptions: {
headers: {
'Content-Type': 'text/plain'
}
}
}),
http(chainDefaultUrl)
])
}
}
5 changes: 4 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit e4adf06

Please sign in to comment.