diff --git a/providers/ethereum-provider/src/EthereumProvider.ts b/providers/ethereum-provider/src/EthereumProvider.ts index 46e85179dc..1ec1b5a94c 100644 --- a/providers/ethereum-provider/src/EthereumProvider.ts +++ b/providers/ethereum-provider/src/EthereumProvider.ts @@ -336,7 +336,7 @@ export class EthereumProvider implements IEthereumProvider { this.signer.logger.error(error); throw error; } finally { - if (this.modal) this.modal.closeModal(); + if (this.rpc.showQrModal) this.modal?.closeModal(); } } @@ -394,7 +394,7 @@ export class EthereumProvider implements IEthereumProvider { this.signer.logger.error(error); throw error; } finally { - if (this.modal) this.modal.closeModal(); + if (this.rpc.showQrModal) this.modal?.closeModal(); } } @@ -433,6 +433,18 @@ export class EthereumProvider implements IEthereumProvider { return this.signer.session; } + public updateConfigOptions(opts: Partial) { + const chains = opts.chains?.map((chain) => this.formatChainId(chain)) || this.rpc.chains; + const optionalChains = + opts.optionalChains?.map((chain) => this.formatChainId(chain)) || this.rpc.optionalChains; + this.rpc = { + ...this.rpc, + ...opts, + chains, + optionalChains, + }; + } + // ---------- Protected --------------------------------------------- // protected registerEventListeners() { @@ -597,24 +609,28 @@ export class EthereumProvider implements IEthereumProvider { }); this.registerEventListeners(); await this.loadPersistedSession(); - if (this.rpc.showQrModal) { - let WalletConnectModalClass; + await this.loadWalletConnectModal(); + } + + protected async loadWalletConnectModal() { + if (this.modal) return; + // old try catch block from the time the modal was optional + let WalletConnectModalClass; + try { + const { WalletConnectModal } = await import("@walletconnect/modal"); + WalletConnectModalClass = WalletConnectModal; + } catch { + throw new Error("To use QR modal, please install @walletconnect/modal package"); + } + if (WalletConnectModalClass) { try { - const { WalletConnectModal } = await import("@walletconnect/modal"); - WalletConnectModalClass = WalletConnectModal; - } catch { - throw new Error("To use QR modal, please install @walletconnect/modal package"); - } - if (WalletConnectModalClass) { - try { - this.modal = new WalletConnectModalClass({ - projectId: this.rpc.projectId, - ...this.rpc.qrModalOptions, - }); - } catch (e) { - this.signer.logger.error(e); - throw new Error("Could not generate WalletConnectModal Instance"); - } + this.modal = new WalletConnectModalClass({ + projectId: this.rpc.projectId, + ...this.rpc.qrModalOptions, + }); + } catch (e) { + this.signer.logger.error(e); + throw new Error("Could not generate WalletConnectModal Instance"); } } } diff --git a/providers/ethereum-provider/test/index.spec.ts b/providers/ethereum-provider/test/index.spec.ts index 4db3d518c3..fd48cdf82f 100644 --- a/providers/ethereum-provider/test/index.spec.ts +++ b/providers/ethereum-provider/test/index.spec.ts @@ -74,6 +74,56 @@ describe("EthereumProvider", function () { await walletClient.client?.core.relayer.transportClose(); }); + describe("config options", () => { + it("should set options", () => { + const cacheConfig = provider.rpc; + // validate that we can update individual options + provider.updateConfigOptions({ showQrModal: true }); + expect(provider.rpc.showQrModal).to.be.true; + provider.updateConfigOptions({ showQrModal: false }); + expect(provider.rpc.showQrModal).to.be.false; + provider.updateConfigOptions({ + chains: [42], + }); + expect(provider.rpc.chains).to.be.eql(["eip155:42"]); + provider.updateConfigOptions({ + optionalChains: [3, 1], + }); + expect(provider.rpc.optionalChains).to.be.eql(["eip155:3", "eip155:1"]); + provider.updateConfigOptions({ + methods: ["eth_sendTransaction"], + }); + expect(provider.rpc.methods).to.be.eql(["eth_sendTransaction"]); + provider.updateConfigOptions({ + optionalMethods: ["eth_sendTransaction"], + }); + expect(provider.rpc.optionalMethods).to.be.eql(["eth_sendTransaction"]); + provider.updateConfigOptions({ + events: ["accountsChanged"], + }); + expect(provider.rpc.events).to.be.eql(["accountsChanged"]); + provider.updateConfigOptions({ + optionalEvents: ["accountsChanged"], + }); + expect(provider.rpc.optionalEvents).to.be.eql(["accountsChanged"]); + provider.updateConfigOptions({ + rpcMap: { + 42: "https://kovan.poa.network", + }, + }); + // validate updating individual options doesn't affect other options + expect(provider.rpc.rpcMap).to.be.eql({ 42: "https://kovan.poa.network" }); + expect(provider.rpc.chains).to.be.eql(["eip155:42"]); + expect(provider.rpc.optionalChains).to.be.eql(["eip155:3", "eip155:1"]); + expect(provider.rpc.methods).to.be.eql(["eth_sendTransaction"]); + expect(provider.rpc.optionalMethods).to.be.eql(["eth_sendTransaction"]); + expect(provider.rpc.events).to.be.eql(["accountsChanged"]); + expect(provider.rpc.optionalEvents).to.be.eql(["accountsChanged"]); + expect(provider.rpc.rpcMap).to.be.eql({ 42: "https://kovan.poa.network" }); + provider.rpc = cacheConfig; + }); + }); + it("chainChanged", async () => { await new Promise((resolve) => setTimeout(resolve, 1000)); // change to Kovan