Skip to content

Commit a73a773

Browse files
authoredJul 23, 2024··
feat: propagate transport rpc urls to connectors (#4162)
* feat: propagate transport rpc urls to connectors * tests: update snaps
1 parent 361fd58 commit a73a773

File tree

9 files changed

+127
-9
lines changed

9 files changed

+127
-9
lines changed
 

‎.changeset/real-squids-add.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@wagmi/connectors": minor
3+
"@wagmi/core": minor
4+
"wagmi": minor
5+
"@wagmi/vue": minor
6+
---
7+
8+
Added functionality for consumer-defined RPC URLs (`config.transports`) to be propagated to the WalletConnect & MetaMask Connectors.

‎packages/connectors/src/metaMask.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
ChainNotConfiguredError,
88
type Connector,
99
createConnector,
10+
extractRpcUrls,
1011
} from '@wagmi/core'
1112
import type {
1213
Compute,
@@ -175,10 +176,13 @@ export function metaMask(parameters: MetaMaskParameters = {}) {
175176
// Workaround cast since MetaMask SDK does not support `'exactOptionalPropertyTypes'`
176177
...(parameters as RemoveUndefined<typeof parameters>),
177178
readonlyRPCMap: Object.fromEntries(
178-
config.chains.map((chain) => [
179-
chain.id,
180-
chain.rpcUrls.default.http[0]!,
181-
]),
179+
config.chains.map((chain) => {
180+
const [url] = extractRpcUrls({
181+
chain,
182+
transports: config.transports,
183+
})
184+
return [chain.id, url]
185+
}),
182186
),
183187
dappMetadata: parameters.dappMetadata ?? {},
184188
useDeeplink: parameters.useDeeplink ?? true,

‎packages/connectors/src/walletConnect.ts

+8-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
type Connector,
44
ProviderNotFoundError,
55
createConnector,
6+
extractRpcUrls,
67
} from '@wagmi/core'
78
import type { Compute, ExactPartial, Omit } from '@wagmi/core/internal'
89
import type { EthereumProvider } from '@walletconnect/ethereum-provider'
@@ -249,10 +250,13 @@ export function walletConnect(parameters: WalletConnectParameters) {
249250
optionalChains,
250251
projectId: parameters.projectId,
251252
rpcMap: Object.fromEntries(
252-
config.chains.map((chain) => [
253-
chain.id,
254-
chain.rpcUrls.default.http[0]!,
255-
]),
253+
config.chains.map((chain) => {
254+
const [url] = extractRpcUrls({
255+
chain,
256+
transports: config.transports,
257+
})
258+
return [chain.id, url]
259+
}),
256260
),
257261
showQrModal: parameters.showQrModal ?? true,
258262
})

‎packages/core/src/connectors/createConnector.ts

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type {
77
ProviderMessage,
88
} from 'viem'
99

10+
import type { Transport } from '../createConfig.js'
1011
import type { Emitter } from '../createEmitter.js'
1112
import type { Storage } from '../createStorage.js'
1213
import type { Compute, ExactPartial, StrictOmit } from '../types/utils.js'
@@ -30,6 +31,7 @@ export type CreateConnectorFn<
3031
chains: readonly [Chain, ...Chain[]]
3132
emitter: Emitter<ConnectorEventMap>
3233
storage?: Compute<Storage<storageItem>> | null | undefined
34+
transports?: Record<number, Transport> | undefined
3335
}) => Compute<
3436
{
3537
readonly icon?: string | undefined

‎packages/core/src/createConfig.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,12 @@ export function createConfig<
103103
// Set up emitter with uid and add to connector so they are "linked" together.
104104
const emitter = createEmitter<ConnectorEventMap>(uid())
105105
const connector = {
106-
...connectorFn({ emitter, chains: chains.getState(), storage }),
106+
...connectorFn({
107+
emitter,
108+
chains: chains.getState(),
109+
storage,
110+
transports: rest.transports,
111+
}),
107112
emitter,
108113
uid: emitter.uid,
109114
}

‎packages/core/src/exports/index.test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ test('exports', () => {
102102
"parseCookie",
103103
"deepEqual",
104104
"deserialize",
105+
"extractRpcUrls",
105106
"normalizeChainId",
106107
"serialize",
107108
"version",

‎packages/core/src/exports/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,8 @@ export { deepEqual } from '../utils/deepEqual.js'
543543

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

546+
export { extractRpcUrls } from '../utils/extractRpcUrls.js'
547+
546548
export { normalizeChainId } from '../utils/normalizeChainId.js'
547549

548550
export { serialize } from '../utils/serialize.js'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { http } from 'viem'
2+
import { mainnet, optimism, sepolia } from 'viem/chains'
3+
import { expect, test } from 'vitest'
4+
5+
import { fallback } from '../transports/fallback.js'
6+
import { extractRpcUrls } from './extractRpcUrls.js'
7+
8+
test('default', () => {
9+
expect(
10+
extractRpcUrls({
11+
chain: mainnet,
12+
transports: {
13+
[mainnet.id]: fallback([
14+
http('https://wagmi.com'),
15+
http('https://lol.com'),
16+
]),
17+
[sepolia.id]: http('https://sepoliarocks.com'),
18+
[optimism.id]: http(),
19+
},
20+
}),
21+
).toMatchInlineSnapshot(`
22+
[
23+
"https://wagmi.com",
24+
"https://lol.com",
25+
]
26+
`)
27+
28+
expect(
29+
extractRpcUrls({
30+
chain: sepolia,
31+
transports: {
32+
[mainnet.id]: fallback([
33+
http('https://wagmi.com'),
34+
http('https://lol.com'),
35+
]),
36+
[sepolia.id]: http('https://sepoliarocks.com'),
37+
[optimism.id]: http(),
38+
},
39+
}),
40+
).toMatchInlineSnapshot(`
41+
[
42+
"https://sepoliarocks.com",
43+
]
44+
`)
45+
46+
expect(
47+
extractRpcUrls({
48+
chain: optimism,
49+
transports: {
50+
[mainnet.id]: fallback([
51+
http('https://wagmi.com'),
52+
http('https://lol.com'),
53+
]),
54+
[sepolia.id]: http('https://sepoliarocks.com'),
55+
[optimism.id]: http(),
56+
},
57+
}),
58+
).toMatchInlineSnapshot(`
59+
[
60+
"https://mainnet.optimism.io",
61+
]
62+
`)
63+
64+
expect(
65+
extractRpcUrls({
66+
chain: mainnet,
67+
}),
68+
).toMatchInlineSnapshot(`
69+
[
70+
"https://cloudflare-eth.com",
71+
]
72+
`)
73+
})
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import type { Chain, Transport } from 'viem'
2+
3+
type ExtractRpcUrlsParameters = {
4+
transports?: Record<string, Transport> | undefined
5+
chain: Chain
6+
}
7+
8+
export function extractRpcUrls(parameters: ExtractRpcUrlsParameters) {
9+
const { chain } = parameters
10+
const fallbackUrl = chain.rpcUrls.default.http[0]
11+
12+
if (!parameters.transports) return [fallbackUrl]
13+
14+
const transport = parameters.transports?.[chain.id]?.({ chain })
15+
const transports = transport?.value?.transports || [transport]
16+
return transports.map(
17+
({ value }: { value: { url: string } }) => value.url || fallbackUrl,
18+
)
19+
}

0 commit comments

Comments
 (0)
Please sign in to comment.