From 8e1ddd12d912d685d59d65c30b959569b2ea676b Mon Sep 17 00:00:00 2001 From: chaitanyapotti Date: Tue, 29 Mar 2022 19:52:03 +0800 Subject: [PATCH 1/5] add wc initial adapters --- .../wallet-connect-v1-adapter/src/config.ts | 17 ++++++++++ .../src/walletConnectV1adapter.ts | 2 ++ packages/base/src/adapter/IAdapter.ts | 15 +++++++++ packages/ui/package.json | 3 +- .../ui/src/components/ExternalWallets.tsx | 7 ++-- packages/ui/src/components/Modal.tsx | 2 ++ packages/ui/src/components/WalletConnect.tsx | 32 +++++++++++++++---- packages/ui/src/interfaces.ts | 3 +- packages/ui/src/loginModal.tsx | 6 ++-- packages/ui/yarn.lock | 5 +++ 10 files changed, 79 insertions(+), 13 deletions(-) create mode 100644 packages/adapters/wallet-connect-v1-adapter/src/config.ts diff --git a/packages/adapters/wallet-connect-v1-adapter/src/config.ts b/packages/adapters/wallet-connect-v1-adapter/src/config.ts new file mode 100644 index 000000000..b3db194bf --- /dev/null +++ b/packages/adapters/wallet-connect-v1-adapter/src/config.ts @@ -0,0 +1,17 @@ +import { CHAIN_NAMESPACES, IWalletConnectExtensionAdapter } from "@web3auth/base"; + +export const WALLET_CONNECT_EXTENSION_ADAPTERS: IWalletConnectExtensionAdapter[] = [ + { + name: "Rainbow", + chains: [CHAIN_NAMESPACES.EIP155], + logo: "", + mobile: { + native: "rainbow:", + universal: "https://rnbwapp.com", + }, + desktop: { + native: "", + universal: "", + }, + }, +]; diff --git a/packages/adapters/wallet-connect-v1-adapter/src/walletConnectV1adapter.ts b/packages/adapters/wallet-connect-v1-adapter/src/walletConnectV1adapter.ts index 933fd06c7..0bfbcf644 100644 --- a/packages/adapters/wallet-connect-v1-adapter/src/walletConnectV1adapter.ts +++ b/packages/adapters/wallet-connect-v1-adapter/src/walletConnectV1adapter.ts @@ -25,6 +25,7 @@ import { } from "@web3auth/base"; import { WalletConnectProvider } from "@web3auth/ethereum-provider"; +import { WALLET_CONNECT_EXTENSION_ADAPTERS } from "./config"; import { WalletConnectV1AdapterOptions } from "./interface"; class WalletConnectV1Adapter extends BaseAdapter { @@ -42,6 +43,7 @@ class WalletConnectV1Adapter extends BaseAdapter { public adapterData: WalletConnectV1Data = { uri: "", + extensionAdapters: WALLET_CONNECT_EXTENSION_ADAPTERS, }; public connector: WalletConnect | null = null; diff --git a/packages/base/src/adapter/IAdapter.ts b/packages/base/src/adapter/IAdapter.ts index babf761c1..59164d4de 100644 --- a/packages/base/src/adapter/IAdapter.ts +++ b/packages/base/src/adapter/IAdapter.ts @@ -199,8 +199,23 @@ export type LoginMethodConfig = Record< } >; +export interface IWalletConnectExtensionAdapter { + name: string; + chains: ChainNamespaceType[]; + logo: string; + mobile: { + native: string; + universal: string; + }; + desktop: { + native: string; + universal: string; + }; +} + export interface WalletConnectV1Data { uri: string; + extensionAdapters: IWalletConnectExtensionAdapter[]; } export interface IAdapterDataEvent { diff --git a/packages/ui/package.json b/packages/ui/package.json index d78bf65ef..178529259 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -66,7 +66,8 @@ "lodash.merge": "^4.6.2", "react": "^17.0.2", "react-dom": "^17.0.2", - "react-qr-code": "^2.0.3" + "react-qr-code": "^2.0.3", + "bowser": "^2.11.0" }, "lint-staged": { "!(*d).ts": [ diff --git a/packages/ui/src/components/ExternalWallets.tsx b/packages/ui/src/components/ExternalWallets.tsx index 5e295f542..1d46a4bd5 100644 --- a/packages/ui/src/components/ExternalWallets.tsx +++ b/packages/ui/src/components/ExternalWallets.tsx @@ -1,4 +1,4 @@ -import { BaseAdapterConfig, log, WALLET_ADAPTERS } from "@web3auth/base"; +import { BaseAdapterConfig, IWalletConnectExtensionAdapter, log, WALLET_ADAPTERS } from "@web3auth/base"; import { useEffect, useState } from "react"; import { MODAL_STATUS, ModalStatusType } from "../interfaces"; @@ -14,9 +14,10 @@ interface ExternalWalletsProps { walletConnectUri: string | undefined; showBackButton: boolean; modalStatus: ModalStatusType; + wcAdapters: IWalletConnectExtensionAdapter[]; } export default function ExternalWallet(props: ExternalWalletsProps) { - const { hideExternalWallets, handleExternalWalletClick, config = {}, walletConnectUri, showBackButton, modalStatus } = props; + const { hideExternalWallets, handleExternalWalletClick, config = {}, walletConnectUri, showBackButton, modalStatus, wcAdapters } = props; const [isLoaded, setIsLoaded] = useState(false); useEffect(() => { @@ -42,7 +43,7 @@ export default function ExternalWallet(props: ExternalWalletsProps) { {/* */} {Object.keys(config).map((adapter) => { if (adapter === WALLET_ADAPTERS.WALLET_CONNECT_V1 || adapter === WALLET_ADAPTERS.WALLET_CONNECT_V2) { - return ; + return ; } return null; })} diff --git a/packages/ui/src/components/Modal.tsx b/packages/ui/src/components/Modal.tsx index 58d5b3526..49c8e8324 100644 --- a/packages/ui/src/components/Modal.tsx +++ b/packages/ui/src/components/Modal.tsx @@ -47,6 +47,7 @@ export default function Modal(props: ModalProps) { externalWalletsConfig: {}, detailedLoaderAdapter: "", showExternalWalletsOnly: false, + wcAdapters: [], }); const { stateListener, appLogo, version, handleSocialLoginClick, handleExternalWalletClick, handleShowExternalWallets, closeModal } = props; @@ -198,6 +199,7 @@ export default function Modal(props: ModalProps) { showBackButton={areSocialLoginsVisible} handleExternalWalletClick={(params: ExternalWalletEventType) => preHandleExternalWalletClick(params)} walletConnectUri={modalState.walletConnectUri} + wcAdapters={modalState.wcAdapters} config={modalState.externalWalletsConfig} hideExternalWallets={() => setModalState((prevState) => { diff --git a/packages/ui/src/components/WalletConnect.tsx b/packages/ui/src/components/WalletConnect.tsx index 7d71f3c4f..e0216dadb 100644 --- a/packages/ui/src/components/WalletConnect.tsx +++ b/packages/ui/src/components/WalletConnect.tsx @@ -1,4 +1,6 @@ -import { memo } from "react"; +import { IWalletConnectExtensionAdapter } from "@web3auth/base"; +import bowser, { PLATFORMS_MAP } from "bowser"; +import { memo, useMemo } from "react"; import QRCode from "react-qr-code"; import Image from "./Image"; @@ -7,18 +9,36 @@ const walletConnectIcon = ; interface WalletConnectProps { walletConnectUri: string; + wcAdapters: IWalletConnectExtensionAdapter[]; } function WalletConnect(props: WalletConnectProps) { - const { walletConnectUri } = props; + const { walletConnectUri, wcAdapters } = props; + const platform = useMemo(() => { + const browser = bowser.getParser(window.navigator.userAgent); + return browser.getPlatformType(); + }, []); + // TODO: show only wcAdapters of current chain return (
{walletConnectIcon}
-
Scan QR code with a WalletConnect-compatible wallet
-
- -
+ {platform === PLATFORMS_MAP.desktop ? ( + <> +
Scan QR code with a WalletConnect-compatible wallet
+
+ +
+ + ) : ( + <> + {wcAdapters.map((adapter) => { + // TODO: render logo and on click, + // https://github.com/WalletConnect/walletconnect-monorepo/blob/54f3ca0b1cd1ac24e8992a5a812fdfad01769abb/packages/helpers/browser-utils/src/registry.ts#L24 + // format and show + })} + + )}
); diff --git a/packages/ui/src/interfaces.ts b/packages/ui/src/interfaces.ts index 578b2b067..bd02ec7ea 100644 --- a/packages/ui/src/interfaces.ts +++ b/packages/ui/src/interfaces.ts @@ -1,5 +1,5 @@ import { SafeEventEmitter } from "@toruslabs/openlogin-jrpc"; -import { BaseAdapterConfig, LoginMethodConfig, WALLET_ADAPTER_TYPE } from "@web3auth/base"; +import { BaseAdapterConfig, IWalletConnectExtensionAdapter, LoginMethodConfig, WALLET_ADAPTER_TYPE } from "@web3auth/base"; export interface UIConfig { appLogo: string; @@ -43,6 +43,7 @@ export interface ModalState { externalWalletsConfig: Record; detailedLoaderAdapter: string; showExternalWalletsOnly: boolean; + wcAdapters: IWalletConnectExtensionAdapter[]; } export type SocialLoginEventType = { adapter: string; loginParams: { loginProvider: string; login_hint?: string } }; diff --git a/packages/ui/src/loginModal.tsx b/packages/ui/src/loginModal.tsx index e8504c2ba..cd33260fe 100644 --- a/packages/ui/src/loginModal.tsx +++ b/packages/ui/src/loginModal.tsx @@ -6,6 +6,7 @@ import { BaseAdapterConfig, CONNECTED_EVENT_DATA, IAdapterDataEvent, + IWalletConnectExtensionAdapter, log, LoginMethodConfig, WALLET_ADAPTER_TYPE, @@ -143,17 +144,18 @@ export default class LoginModal extends SafeEventEmitter { this.stateEmitter.emit("STATE_UPDATED", newState); }; - private updateWalletConnect = (walletConnectUri: string): void => { + private updateWalletConnect = (walletConnectUri: string, wcAdapters: IWalletConnectExtensionAdapter[]): void => { if (!walletConnectUri) return; this.setState({ walletConnectUri, + wcAdapters, }); }; private handleAdapterData = (adapterData: IAdapterDataEvent) => { if (adapterData.adapterName === WALLET_ADAPTERS.WALLET_CONNECT_V1) { const walletConnectData = adapterData.data as WalletConnectV1Data; - this.updateWalletConnect(walletConnectData.uri); + this.updateWalletConnect(walletConnectData.uri, walletConnectData.extensionAdapters); } }; diff --git a/packages/ui/yarn.lock b/packages/ui/yarn.lock index b00b4ad4e..fb80e52e3 100644 --- a/packages/ui/yarn.lock +++ b/packages/ui/yarn.lock @@ -1855,6 +1855,11 @@ boolbase@^1.0.0, boolbase@~1.0.0: resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24= +bowser@^2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" + integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" From 02ae3b289ad69c2d704832453e26810718d4d4b9 Mon Sep 17 00:00:00 2001 From: himanshuchawla009 Date: Wed, 30 Mar 2022 01:49:25 +0530 Subject: [PATCH 2/5] wc adapter on click hndler --- examples/vue-app/package-lock.json | 3 + .../src/walletConnectV1adapter.ts | 2 +- packages/ui/src/components/WalletConnect.tsx | 86 +++++++++++++++++-- 3 files changed, 84 insertions(+), 7 deletions(-) diff --git a/examples/vue-app/package-lock.json b/examples/vue-app/package-lock.json index 0085f1b7a..45766463a 100644 --- a/examples/vue-app/package-lock.json +++ b/examples/vue-app/package-lock.json @@ -58,6 +58,7 @@ } }, "../../packages/adapters/coinbase-adapter": { + "name": "@web3auth/coinbase-adapter", "version": "0.6.3", "license": "ISC", "dependencies": { @@ -332,6 +333,7 @@ "@toruslabs/openlogin": "^1.6.0", "@toruslabs/openlogin-jrpc": "^1.6.0", "@web3auth/base": "^0.6.3", + "bowser": "^2.11.0", "classnames": "^2.3.1", "lodash.clonedeep": "^4.5.0", "lodash.merge": "^4.6.2", @@ -19845,6 +19847,7 @@ "@types/react": "^17.0.40", "@types/react-dom": "^17.0.13", "@web3auth/base": "^0.6.3", + "bowser": "^2.11.0", "classnames": "^2.3.1", "css-loader": "^5.2.7", "eslint-plugin-import": "^2.25.4", diff --git a/packages/adapters/wallet-connect-v1-adapter/src/walletConnectV1adapter.ts b/packages/adapters/wallet-connect-v1-adapter/src/walletConnectV1adapter.ts index 0bfbcf644..5017e618c 100644 --- a/packages/adapters/wallet-connect-v1-adapter/src/walletConnectV1adapter.ts +++ b/packages/adapters/wallet-connect-v1-adapter/src/walletConnectV1adapter.ts @@ -180,7 +180,7 @@ class WalletConnectV1Adapter extends BaseAdapter { return reject(err); } const uri = payload.params[0]; - this.updateAdapterData({ uri } as WalletConnectV1Data); + this.updateAdapterData({ uri, extensionAdapters: WALLET_CONNECT_EXTENSION_ADAPTERS } as WalletConnectV1Data); this.connector?.off("display_uri"); return resolve(); diff --git a/packages/ui/src/components/WalletConnect.tsx b/packages/ui/src/components/WalletConnect.tsx index e0216dadb..25f2a2260 100644 --- a/packages/ui/src/components/WalletConnect.tsx +++ b/packages/ui/src/components/WalletConnect.tsx @@ -1,6 +1,6 @@ import { IWalletConnectExtensionAdapter } from "@web3auth/base"; -import bowser, { PLATFORMS_MAP } from "bowser"; -import { memo, useMemo } from "react"; +import bowser, { OS_MAP, PLATFORMS_MAP } from "bowser"; +import { memo, useEffect, useMemo, useState } from "react"; import QRCode from "react-qr-code"; import Image from "./Image"; @@ -12,18 +12,78 @@ interface WalletConnectProps { wcAdapters: IWalletConnectExtensionAdapter[]; } +interface IMobileRegistryEntry { + name: string; + logo: string; + universalLink: string; + deepLink: string; + href: string; +} +type platform = "mobile" | "desktop"; + +type os = "iOS" | "Android"; + +function formatIOSMobile(params: { uri: string; universalLink?: string; deepLink?: string }) { + const encodedUri: string = encodeURIComponent(params.uri); + if (params.universalLink) { + return `${params.universalLink}/wc?uri=${encodedUri}`; + } + if (params.deepLink) { + return `${params.deepLink}${params.deepLink.endsWith(":") ? "//" : "/"}wc?uri=${encodedUri}`; + } + return ""; +} + +function formatMobileRegistryEntry( + entry: IWalletConnectExtensionAdapter, + walletConnectUri: string, + os: os, + platform: "mobile" | "desktop" = "mobile" +): IMobileRegistryEntry { + const universalLink = entry[platform].universal || ""; + const deepLink = entry[platform].native || ""; + return { + name: entry.name || "", + logo: entry.logo || "", + universalLink, + deepLink, + href: os === OS_MAP.iOS ? formatIOSMobile({ uri: walletConnectUri, universalLink, deepLink }) : walletConnectUri, + }; +} + +function formatMobileRegistry( + registry: IWalletConnectExtensionAdapter[], + walletConnectUri: string, + os: os, + platform: platform = "mobile" +): IMobileRegistryEntry[] { + return Object.values(registry) + .filter((entry) => !!entry[platform].universal || !!entry[platform].native) + .map((entry) => formatMobileRegistryEntry(entry, walletConnectUri, os, platform)); +} + function WalletConnect(props: WalletConnectProps) { const { walletConnectUri, wcAdapters } = props; - const platform = useMemo(() => { + const [links, setLinks] = useState([]); + + const deviceDetails = useMemo<{ platform: platform; os: os }>(() => { const browser = bowser.getParser(window.navigator.userAgent); - return browser.getPlatformType(); + return { platform: browser.getPlatformType() as platform, os: browser.getOSName() as os }; }, []); + + useEffect(() => { + if (deviceDetails.platform === PLATFORMS_MAP.mobile) { + const mobileLinks = formatMobileRegistry(wcAdapters, walletConnectUri, deviceDetails.os, deviceDetails.platform); + setLinks(mobileLinks); + } + }, [wcAdapters, deviceDetails.os, deviceDetails.platform, walletConnectUri]); + // TODO: show only wcAdapters of current chain return (
{walletConnectIcon}
- {platform === PLATFORMS_MAP.desktop ? ( + {deviceDetails.platform === PLATFORMS_MAP.desktop ? ( <>
Scan QR code with a WalletConnect-compatible wallet
@@ -32,10 +92,24 @@ function WalletConnect(props: WalletConnectProps) { ) : ( <> - {wcAdapters.map((adapter) => { + {links.map((link) => { // TODO: render logo and on click, // https://github.com/WalletConnect/walletconnect-monorepo/blob/54f3ca0b1cd1ac24e8992a5a812fdfad01769abb/packages/helpers/browser-utils/src/registry.ts#L24 // format and show + return deviceDetails.os === OS_MAP.iOS ? ( + + +

{link.name}

+
+ ) : ( + + + + ); })} )} From 72b801cd9b97a28ba2e5fe348ef5b8c0b1a0dde7 Mon Sep 17 00:00:00 2001 From: Lionell Briones Date: Wed, 30 Mar 2022 15:06:25 +0800 Subject: [PATCH 3/5] Updated ios android ui --- .../wallet-connect-v1-adapter/src/config.ts | 2 +- packages/ui/css/web3auth.css | 33 ++++++++++++++-- packages/ui/src/components/WalletConnect.tsx | 38 +++++++++++-------- 3 files changed, 54 insertions(+), 19 deletions(-) diff --git a/packages/adapters/wallet-connect-v1-adapter/src/config.ts b/packages/adapters/wallet-connect-v1-adapter/src/config.ts index b3db194bf..b94fea5ae 100644 --- a/packages/adapters/wallet-connect-v1-adapter/src/config.ts +++ b/packages/adapters/wallet-connect-v1-adapter/src/config.ts @@ -4,7 +4,7 @@ export const WALLET_CONNECT_EXTENSION_ADAPTERS: IWalletConnectExtensionAdapter[] { name: "Rainbow", chains: [CHAIN_NAMESPACES.EIP155], - logo: "", + logo: "https://images.web3auth.io/login-rainbow.svg", mobile: { native: "rainbow:", universal: "https://rnbwapp.com", diff --git a/packages/ui/css/web3auth.css b/packages/ui/css/web3auth.css index be76052b7..1f6dac44d 100644 --- a/packages/ui/css/web3auth.css +++ b/packages/ui/css/web3auth.css @@ -503,21 +503,48 @@ } #w3a-modal .w3a-wallet-connect__container { - padding: 10px; background: #ffffff; border-radius: 10px; color: var(--text-color1); font-size: 10px; width: fit-content; margin: auto; + min-width: 250px; + padding: 16px 12px; } -.w3a-wallet-connect-qr { - width: 200px; +#w3a-modal .w3a-wallet-connect__container-desktop, +#w3a-modal .w3a-wallet-connect__container-android { + margin: auto; +} + +#w3a-modal .w3a-wallet-connect__container-ios { + display: flex; + grid-gap: 30px 20px; + padding: 0 0 28px; + box-sizing: border-box; + flex-wrap: wrap; +} + +#w3a-modal .w3a-wallet-connect-qr { margin: 16px 16px; padding: inherit; } +#w3a-modal .w3a-wallet-connect__container-android a { + text-decoration: none; +} + +#w3a-modal .w3a-wallet-connect__container-android .w3a-button { + background-color: rgb(64, 153, 255) !important; + color: #ffffff !important; + height: auto; + font-size: 14px; + padding: 8px 16px; + width: auto; + margin: auto; +} + #w3a-modal .w3a-wallet-connect__logo > img { text-align: center; width: 115px; diff --git a/packages/ui/src/components/WalletConnect.tsx b/packages/ui/src/components/WalletConnect.tsx index 25f2a2260..d582bb7d5 100644 --- a/packages/ui/src/components/WalletConnect.tsx +++ b/packages/ui/src/components/WalletConnect.tsx @@ -81,15 +81,19 @@ function WalletConnect(props: WalletConnectProps) { // TODO: show only wcAdapters of current chain return (
- {walletConnectIcon} -
+
+
{walletConnectIcon}
{deviceDetails.platform === PLATFORMS_MAP.desktop ? ( - <> +
Scan QR code with a WalletConnect-compatible wallet
- +
) : ( <> {links.map((link) => { @@ -97,18 +101,22 @@ function WalletConnect(props: WalletConnectProps) { // https://github.com/WalletConnect/walletconnect-monorepo/blob/54f3ca0b1cd1ac24e8992a5a812fdfad01769abb/packages/helpers/browser-utils/src/registry.ts#L24 // format and show return deviceDetails.os === OS_MAP.iOS ? ( - - -

{link.name}

-
+ ) : ( - - - + ); })} From 968ad57dcb85c2d7b02c1407d2b17ac6b7e70ae6 Mon Sep 17 00:00:00 2001 From: chaitanyapotti Date: Wed, 30 Mar 2022 20:39:34 +0800 Subject: [PATCH 4/5] Fix multiple wallet connect issues --- examples/vue-app/vue.config.js | 8 ++- .../src/walletConnectV1adapter.ts | 46 +++++++++-------- .../WalletConnectProvider.ts | 49 +++++++++++++------ packages/ui/src/interfaces.ts | 1 + packages/ui/src/loginModal.tsx | 20 +++++--- 5 files changed, 81 insertions(+), 43 deletions(-) diff --git a/examples/vue-app/vue.config.js b/examples/vue-app/vue.config.js index 965f2c5c9..93d84d39b 100644 --- a/examples/vue-app/vue.config.js +++ b/examples/vue-app/vue.config.js @@ -29,7 +29,13 @@ module.exports = { }, chainWebpack: (config) => { if (process.env.NODE_ENV !== "production") { - config.module.rule("sourcemap").test(/\.js$/).enforce("pre").use("source-map-loader").loader("source-map-loader").end(); + config.module + .rule("sourcemap") + .test(/\.${js,ts}$/) + .enforce("pre") + .use("source-map-loader") + .loader("source-map-loader") + .end(); } const svgRule = config.module.rule("svg"); diff --git a/packages/adapters/wallet-connect-v1-adapter/src/walletConnectV1adapter.ts b/packages/adapters/wallet-connect-v1-adapter/src/walletConnectV1adapter.ts index 5017e618c..2caac682d 100644 --- a/packages/adapters/wallet-connect-v1-adapter/src/walletConnectV1adapter.ts +++ b/packages/adapters/wallet-connect-v1-adapter/src/walletConnectV1adapter.ts @@ -13,7 +13,6 @@ import { CONNECTED_EVENT_DATA, CustomChainConfig, getChainConfig, - isHexStrict, log, SafeEventEmitterProvider, UserInfo, @@ -77,13 +76,13 @@ class WalletConnectV1Adapter extends BaseAdapter { } // Create a connector this.connector = this.getWalletConnectInstance(); - this.wcProvider = new WalletConnectProvider({ config: { chainConfig: this.chainConfig as CustomChainConfig } }); + this.wcProvider = new WalletConnectProvider({ config: { chainConfig: this.chainConfig as CustomChainConfig }, connector: this.connector }); this.emit(ADAPTER_EVENTS.READY, WALLET_ADAPTERS.WALLET_CONNECT_V1); this.status = ADAPTER_STATUS.READY; if (this.connector.connected) { this.rehydrated = true; - await this.onConnectHandler({ accounts: this.connector.accounts, chainId: this.connector.chainId.toString() }); + await this.onConnectHandler({ accounts: this.connector.accounts, chainId: this.connector.chainId }); } } @@ -92,7 +91,7 @@ class WalletConnectV1Adapter extends BaseAdapter { if (!this.connector) throw WalletInitializationError.notReady("Wallet adapter is not ready yet"); if (this.connected) { - await this.onConnectHandler({ accounts: this.connector.accounts, chainId: this.connector.chainId.toString() }); + await this.onConnectHandler({ accounts: this.connector.accounts, chainId: this.connector.chainId }); return this.provider; } @@ -116,7 +115,7 @@ class WalletConnectV1Adapter extends BaseAdapter { }); try { // Subscribe to session connection - this.connector.on("connect", async (error: Error | null, payload: { params: { accounts: string[]; chainId: string }[] }) => { + this.connector.on("connect", async (error: Error | null, payload: { params: { accounts: string[]; chainId: number }[] }) => { if (error) { this.emit(ADAPTER_EVENTS.ERRORED, error); } @@ -194,25 +193,32 @@ class WalletConnectV1Adapter extends BaseAdapter { }); } - private async onConnectHandler(params: { accounts: string[]; chainId: string }) { + private async onConnectHandler(params: { accounts: string[]; chainId: number }) { if (!this.connector || !this.wcProvider) throw WalletInitializationError.notReady("Wallet adapter is not ready yet"); if (!this.chainConfig) throw WalletInitializationError.invalidParams("Chain config is not set"); const { chainId } = params; - log.debug("connected chainId", chainId); - const connectedChainId = parseInt(chainId, isHexStrict(chainId) ? 16 : 10); - if (connectedChainId !== parseInt(this.chainConfig.chainId, 16)) { - // we need to create a new session since old session is already used and - // user needs to login again with correct chain with new qr code. - await this.createNewSession({ forceNewSession: true }); - this.emit( - ADAPTER_EVENTS.ERRORED, - WalletInitializationError.fromCode( - 5000, - `Not connected to correct chainId. Expected: ${this.chainConfig.chainId}, Current: ${connectedChainId}, Please switch to correct chain from wallet` - ) - ); - return; + log.debug("connected chainId in hex", chainId); + if (chainId !== parseInt(this.chainConfig.chainId, 16)) { + try { + await this.wcProvider.switchChain({ chainId: this.chainConfig.chainId, lookup: false }); + } catch (error) { + log.error(error); + // we need to create a new session since old session is already used and + // user needs to login again with correct chain with new qr code. + await this.createNewSession({ forceNewSession: true }); + const connectedChainConfig = getChainConfig(CHAIN_NAMESPACES.EIP155, chainId); + this.emit( + ADAPTER_EVENTS.ERRORED, + WalletInitializationError.fromCode( + 5000, + `Not connected to correct network. Expected: ${this.chainConfig.displayName}, Current: ${ + connectedChainConfig?.displayName || chainId + }, Please switch to correct network from wallet` + ) + ); + return; + } } await this.wcProvider.setupProvider(this.connector); this.subscribeEvents(this.connector); diff --git a/packages/providers/ethereum-provider/src/providers/injectedProviders/WalletConnectProvider.ts b/packages/providers/ethereum-provider/src/providers/injectedProviders/WalletConnectProvider.ts index 6dbbf0b4f..990c69691 100644 --- a/packages/providers/ethereum-provider/src/providers/injectedProviders/WalletConnectProvider.ts +++ b/packages/providers/ethereum-provider/src/providers/injectedProviders/WalletConnectProvider.ts @@ -1,7 +1,7 @@ import { providerFromEngine } from "@toruslabs/base-controllers"; import { JRPCEngine } from "@toruslabs/openlogin-jrpc"; import type { IConnector } from "@walletconnect/types"; -import { CHAIN_NAMESPACES, CustomChainConfig, isHexStrict, WalletInitializationError, WalletLoginError } from "@web3auth/base"; +import { CHAIN_NAMESPACES, CustomChainConfig, getChainConfig, isHexStrict, log, WalletInitializationError, WalletLoginError } from "@web3auth/base"; import { BaseProvider, BaseProviderConfig, BaseProviderState } from "@web3auth/base-provider"; import { ethErrors } from "eth-rpc-errors"; @@ -49,23 +49,39 @@ export class WalletConnectProvider extends BaseProvider { + public async switchChain({ chainId, lookup = true }: { chainId: string; lookup?: boolean }): Promise { + if (!this.connector) + throw ethErrors.provider.custom({ message: "Connector is not initialized, pass wallet connect connector in constructor", code: 4902 }); const currentChainConfig = this.getChainConfig(chainId); - const { ticker, tickerName, rpcTarget } = currentChainConfig; + const { rpcTarget, displayName } = currentChainConfig; this.update({ chainId: "loading", }); - await this.connector.updateChain({ - chainId: Number.parseInt(chainId, 16), - nativeCurrency: { - name: tickerName, - symbol: ticker, - }, - networkId: Number.parseInt(chainId, 10), - rpcUrl: rpcTarget, - }); + try { + await this.connector.sendCustomRequest({ + method: "wallet_addEthereumChain", + params: [{ chainId, chainName: displayName, rpcUrls: [rpcTarget] }], + }); + } catch (error) { + log.error(error); + } + + try { + await this.connector.sendCustomRequest({ + method: "wallet_switchEthereumChain", + params: [{ chainId }], + }); + } catch (error) { + log.error(error); + // ignore this error because metamask & others return provider.result as null + // wallet connect thinks this is wrong + if (error.message !== "JSON RPC response format is invalid") { + throw error; + } + } + this.configure({ chainConfig: currentChainConfig }); - await this.lookupNetwork(this.connector); + if (lookup) await this.lookupNetwork(this.connector); } protected async lookupNetwork(connector: IConnector): Promise { @@ -104,7 +120,7 @@ export class WalletConnectProvider extends BaseProvider { log.error("error", error, error.message); if (error.code === 5000) { - this.setState({ - modalVisibility: true, - postLoadingMessage: error.message || "Something went wrong!", - status: MODAL_STATUS.ERRORED, - }); + if (this.displayErrorsOnModal) + this.setState({ + modalVisibility: true, + postLoadingMessage: error.message || "Something went wrong!", + status: MODAL_STATUS.ERRORED, + }); + else + this.setState({ + modalVisibility: false, + }); } else { this.setState({ modalVisibility: true, From f8f2923cb03b2c21cce750c3f24524477692475d Mon Sep 17 00:00:00 2001 From: himanshuchawla009 Date: Wed, 30 Mar 2022 19:45:30 +0530 Subject: [PATCH 5/5] displayErrorsOnModal param added in web3auth --- examples/vue-app/src/chains/ethereum.vue | 7 ++++++- .../src/walletConnectV1adapter.ts | 2 ++ packages/modal/src/modalManager.ts | 8 ++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/examples/vue-app/src/chains/ethereum.vue b/examples/vue-app/src/chains/ethereum.vue index 0ce4a1949..84564a6db 100644 --- a/examples/vue-app/src/chains/ethereum.vue +++ b/examples/vue-app/src/chains/ethereum.vue @@ -113,7 +113,12 @@ export default Vue.extend({ try { this.parseConfig(); this.loading = true; - this.web3auth = new Web3Auth({ chainConfig: ethChainConfig, clientId: config.clientId, authMode: "DAPP", enableLogging: true }); + this.web3auth = new Web3Auth({ + chainConfig: ethChainConfig, + clientId: config.clientId, + authMode: "DAPP", + enableLogging: true, + }); const openloginAdapter = new OpenloginAdapter({ adapterSettings: { network: this.openloginNetwork as OPENLOGIN_NETWORK_TYPE, diff --git a/packages/adapters/wallet-connect-v1-adapter/src/walletConnectV1adapter.ts b/packages/adapters/wallet-connect-v1-adapter/src/walletConnectV1adapter.ts index 2caac682d..6bbfeb965 100644 --- a/packages/adapters/wallet-connect-v1-adapter/src/walletConnectV1adapter.ts +++ b/packages/adapters/wallet-connect-v1-adapter/src/walletConnectV1adapter.ts @@ -217,6 +217,8 @@ class WalletConnectV1Adapter extends BaseAdapter { }, Please switch to correct network from wallet` ) ); + this.status = ADAPTER_STATUS.READY; + this.rehydrated = true; return; } } diff --git a/packages/modal/src/modalManager.ts b/packages/modal/src/modalManager.ts index f72d86753..225b08ef6 100644 --- a/packages/modal/src/modalManager.ts +++ b/packages/modal/src/modalManager.ts @@ -59,6 +59,13 @@ export interface Web3AuthOptions extends Web3AuthCoreOptions { * Config for configuring modal ui display properties */ uiConfig?: UIConfig; + + /** + * Whether to show errors on Web3Auth modal. + * + * @defaultValue `true` + */ + displayErrorsOnModal?: boolean; } export class Web3Auth extends Web3AuthCore { public loginModal: LoginModal; @@ -95,6 +102,7 @@ export class Web3Auth extends Web3AuthCore { appLogo: this.options.uiConfig?.appLogo || "", version: "", adapterListener: this, + displayErrorsOnModal: this.options.displayErrorsOnModal, }); this.subscribeToLoginModalEvents(); }