Skip to content

Commit

Permalink
feat: propagate transport rpc urls to connectors (#4162)
Browse files Browse the repository at this point in the history
* feat: propagate transport rpc urls to connectors

* tests: update snaps
  • Loading branch information
jxom authored Jul 23, 2024
1 parent 361fd58 commit a73a773
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 9 deletions.
8 changes: 8 additions & 0 deletions .changeset/real-squids-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@wagmi/connectors": minor
"@wagmi/core": minor
"wagmi": minor
"@wagmi/vue": minor
---

Added functionality for consumer-defined RPC URLs (`config.transports`) to be propagated to the WalletConnect & MetaMask Connectors.
12 changes: 8 additions & 4 deletions packages/connectors/src/metaMask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
ChainNotConfiguredError,
type Connector,
createConnector,
extractRpcUrls,
} from '@wagmi/core'
import type {
Compute,
Expand Down Expand Up @@ -175,10 +176,13 @@ export function metaMask(parameters: MetaMaskParameters = {}) {
// Workaround cast since MetaMask SDK does not support `'exactOptionalPropertyTypes'`
...(parameters as RemoveUndefined<typeof parameters>),
readonlyRPCMap: Object.fromEntries(
config.chains.map((chain) => [
chain.id,
chain.rpcUrls.default.http[0]!,
]),
config.chains.map((chain) => {
const [url] = extractRpcUrls({
chain,
transports: config.transports,
})
return [chain.id, url]
}),
),
dappMetadata: parameters.dappMetadata ?? {},
useDeeplink: parameters.useDeeplink ?? true,
Expand Down
12 changes: 8 additions & 4 deletions packages/connectors/src/walletConnect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
type Connector,
ProviderNotFoundError,
createConnector,
extractRpcUrls,
} from '@wagmi/core'
import type { Compute, ExactPartial, Omit } from '@wagmi/core/internal'
import type { EthereumProvider } from '@walletconnect/ethereum-provider'
Expand Down Expand Up @@ -249,10 +250,13 @@ export function walletConnect(parameters: WalletConnectParameters) {
optionalChains,
projectId: parameters.projectId,
rpcMap: Object.fromEntries(
config.chains.map((chain) => [
chain.id,
chain.rpcUrls.default.http[0]!,
]),
config.chains.map((chain) => {
const [url] = extractRpcUrls({
chain,
transports: config.transports,
})
return [chain.id, url]
}),
),
showQrModal: parameters.showQrModal ?? true,
})
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/connectors/createConnector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type {
ProviderMessage,
} from 'viem'

import type { Transport } from '../createConfig.js'
import type { Emitter } from '../createEmitter.js'
import type { Storage } from '../createStorage.js'
import type { Compute, ExactPartial, StrictOmit } from '../types/utils.js'
Expand All @@ -30,6 +31,7 @@ export type CreateConnectorFn<
chains: readonly [Chain, ...Chain[]]
emitter: Emitter<ConnectorEventMap>
storage?: Compute<Storage<storageItem>> | null | undefined
transports?: Record<number, Transport> | undefined
}) => Compute<
{
readonly icon?: string | undefined
Expand Down
7 changes: 6 additions & 1 deletion packages/core/src/createConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,12 @@ export function createConfig<
// Set up emitter with uid and add to connector so they are "linked" together.
const emitter = createEmitter<ConnectorEventMap>(uid())
const connector = {
...connectorFn({ emitter, chains: chains.getState(), storage }),
...connectorFn({
emitter,
chains: chains.getState(),
storage,
transports: rest.transports,
}),
emitter,
uid: emitter.uid,
}
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/exports/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ test('exports', () => {
"parseCookie",
"deepEqual",
"deserialize",
"extractRpcUrls",
"normalizeChainId",
"serialize",
"version",
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/exports/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,8 @@ export { deepEqual } from '../utils/deepEqual.js'

export { deserialize } from '../utils/deserialize.js'

export { extractRpcUrls } from '../utils/extractRpcUrls.js'

export { normalizeChainId } from '../utils/normalizeChainId.js'

export { serialize } from '../utils/serialize.js'
Expand Down
73 changes: 73 additions & 0 deletions packages/core/src/utils/extractRpcUrls.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { http } from 'viem'
import { mainnet, optimism, sepolia } from 'viem/chains'
import { expect, test } from 'vitest'

import { fallback } from '../transports/fallback.js'
import { extractRpcUrls } from './extractRpcUrls.js'

test('default', () => {
expect(
extractRpcUrls({
chain: mainnet,
transports: {
[mainnet.id]: fallback([
http('https://wagmi.com'),
http('https://lol.com'),
]),
[sepolia.id]: http('https://sepoliarocks.com'),
[optimism.id]: http(),
},
}),
).toMatchInlineSnapshot(`
[
"https://wagmi.com",
"https://lol.com",
]
`)

expect(
extractRpcUrls({
chain: sepolia,
transports: {
[mainnet.id]: fallback([
http('https://wagmi.com'),
http('https://lol.com'),
]),
[sepolia.id]: http('https://sepoliarocks.com'),
[optimism.id]: http(),
},
}),
).toMatchInlineSnapshot(`
[
"https://sepoliarocks.com",
]
`)

expect(
extractRpcUrls({
chain: optimism,
transports: {
[mainnet.id]: fallback([
http('https://wagmi.com'),
http('https://lol.com'),
]),
[sepolia.id]: http('https://sepoliarocks.com'),
[optimism.id]: http(),
},
}),
).toMatchInlineSnapshot(`
[
"https://mainnet.optimism.io",
]
`)

expect(
extractRpcUrls({
chain: mainnet,
}),
).toMatchInlineSnapshot(`
[
"https://cloudflare-eth.com",
]
`)
})
19 changes: 19 additions & 0 deletions packages/core/src/utils/extractRpcUrls.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { Chain, Transport } from 'viem'

type ExtractRpcUrlsParameters = {
transports?: Record<string, Transport> | undefined
chain: Chain
}

export function extractRpcUrls(parameters: ExtractRpcUrlsParameters) {
const { chain } = parameters
const fallbackUrl = chain.rpcUrls.default.http[0]

if (!parameters.transports) return [fallbackUrl]

const transport = parameters.transports?.[chain.id]?.({ chain })
const transports = transport?.value?.transports || [transport]
return transports.map(
({ value }: { value: { url: string } }) => value.url || fallbackUrl,
)
}

0 comments on commit a73a773

Please sign in to comment.