diff --git a/packages/provider/src/client.ts b/packages/provider/src/client.ts index 00bd04543..d2883ec1c 100644 --- a/packages/provider/src/client.ts +++ b/packages/provider/src/client.ts @@ -54,10 +54,14 @@ export class SequenceClientSession { } getSession(): WalletSession | undefined { - const session = this.store.getItem(SequenceClientSession.SESSION_LOCALSTORE_KEY) + try { + const session = this.store.getItem(SequenceClientSession.SESSION_LOCALSTORE_KEY) - if (session) { - return JSON.parse(session) + if (session) { + return JSON.parse(session) + } + } catch (err) { + console.error('Error parsing session', err) } return undefined diff --git a/packages/provider/src/init.ts b/packages/provider/src/init.ts index 92fca0b9c..c84ed3e68 100644 --- a/packages/provider/src/init.ts +++ b/packages/provider/src/init.ts @@ -84,58 +84,31 @@ export const initWallet = (projectAccessKey: string, partialConfig?: Partial = {} - - // Find any new networks that aren't already defined in sequence.js - // and add them to the list of networks, (they must have a rpcUrl and chainId) - const newNetworks = (config.networks?.filter(n => { - // eslint-disable-next-line - n.rpcUrl !== undefined && n.chainId !== undefined && !allNetworks.find(an => an.chainId === n.chainId) - }) ?? []) as NetworkConfig[] - - // Override any information about the networks using the config - const combinedNetworks = allNetworks - .map(n => { - const network = config.networks?.find(cn => cn.chainId === n.chainId) - return network ? { ...n, ...network } : n - }) - .concat(newNetworks) - .map(network => { - // don't double-append in the case the user has already included their access key in the rpc URL + let networks: NetworkConfig[] = [] + + const updateNetworks = (connectedNetworks: NetworkConfig[] = []) => { + networks = mergeNetworks(allNetworks, connectedNetworks, config.networks ?? []) + + // Append projectAccessKey to network rpcUrls + networks = networks.map(network => { + // Don't double-append in the case the user has already included their access key in the rpc URL if (network.rpcUrl.includes(projectAccessKey)) { return network } - // this will probably break non-sequence RPC provider URLs. + // XXX: This will probably break non-sequence RPC provider URLs. network.rpcUrl = network.rpcUrl + `/${projectAccessKey}` + return network }) - - // This builds a "public rpc" on demand, we build them on demand because we don't want to - // generate a bunch of providers for networks that aren't used. - const providerForChainId = (chainId: number) => { - if (!rpcProviders[chainId]) { - const rpcUrl = combinedNetworks.find(n => n.chainId === chainId)?.rpcUrl - if (!rpcUrl) { - throw new Error(`no rpcUrl found for chainId: ${chainId}`) - } - - rpcProviders[chainId] = new JsonRpcProvider( - rpcUrl, - { - middlewares: [loggingProviderMiddleware, exceptionProviderMiddleware, new CachedProvider()] - }, - { cacheTimeout: -1 } - ) - } - - return rpcProviders[chainId] } + updateNetworks() + // This is the starting default network (as defined by the config) // it can be later be changed using `wallet_switchEthereumChain` or some // of the other methods on the provider. - const defaultNetwork = config.defaultNetwork ? findNetworkConfig(combinedNetworks, config.defaultNetwork)?.chainId : undefined + const defaultNetwork = config.defaultNetwork ? findNetworkConfig(networks, config.defaultNetwork)?.chainId : undefined if (!defaultNetwork && config.defaultNetwork) { throw new Error(`defaultNetwork not found for chainId: ${config.defaultNetwork}`) } @@ -151,6 +124,39 @@ export const initWallet = (projectAccessKey: string, partialConfig?: Partial { + updateNetworks(ev.session?.networks) + }) + + const rpcProviders: Record = {} + + // This builds a "public rpc" on demand, we build them on demand because we don't want to + // generate a bunch of providers for networks that aren't used. + const providerForChainId = (chainId: number) => { + const network = findNetworkConfig(networks, chainId) + + if (!network) { + throw new Error(`no network config found for chainId: ${chainId}`) + } + + const { rpcUrl } = network + + // Cache providers by rpc url + if (!rpcProviders[rpcUrl]) { + rpcProviders[rpcUrl] = new JsonRpcProvider( + rpcUrl, + { + middlewares: [loggingProviderMiddleware, exceptionProviderMiddleware, new CachedProvider()] + }, + { cacheTimeout: -1 } + ) + } + + return rpcProviders[rpcUrl] + } + sequenceWalletProvider = new SequenceProvider(client, providerForChainId) return sequenceWalletProvider } @@ -168,3 +174,18 @@ export const getWallet = () => { } return sequenceWalletProvider } + +// allNetworks <- connectedNetworks <- config.networks +const mergeNetworks = (...networks: Partial[][]) => { + const networkMap = new Map() + + for (const network of networks.flat()) { + if (network.chainId && network.rpcUrl) { + const existingNetwork = networkMap.get(network.chainId) + + networkMap.set(network.chainId, { ...existingNetwork, ...network } as NetworkConfig) + } + } + + return Array.from(networkMap.values()) +}