Skip to content

Commit b15697e

Browse files
committed
feat: initial setup for connect sign on injected evm connectors
1 parent 344746d commit b15697e

File tree

14 files changed

+110
-52
lines changed

14 files changed

+110
-52
lines changed

demo/vue-app-new/src/MainView.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ const options = computed((): Web3AuthOptions => {
139139
connectors: modalParams.value,
140140
hideWalletDiscovery: !formData.showWalletDiscovery,
141141
},
142+
initialAuthenticationMode: "connect-and-sign",
142143
};
143144
});
144145

packages/modal/src/modalManager.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ export class Web3Auth extends Web3AuthNoModal implements IWeb3AuthModal {
116116
chainNamespaces: this.getChainNamespaces(),
117117
walletRegistry: filteredWalletRegistry,
118118
analytics: this.analytics,
119+
initialAuthenticationMode: this.options.initialAuthenticationMode,
119120
},
120121
{
121122
onInitExternalWallets: this.onInitExternalWallets,

packages/modal/src/ui/components/Loader/Loader.tsx

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { useTranslation } from "react-i18next";
33

44
import { MODAL_STATUS } from "../../interfaces";
55
import i18n from "../../localeImport";
6+
import CircularLoader from "../CircularLoader";
67
import Image from "../Image";
78
import PulseLoader from "../PulseLoader";
89
import { ConnectedStatusType, ConnectingStatusType, ErroredStatusType, LoaderProps } from "./Loader.type";
@@ -88,29 +89,65 @@ function ErroredStatus(props: ErroredStatusType) {
8889
);
8990
}
9091

92+
function AuthorizingStatus() {
93+
return (
94+
<div className="w3a--flex w3a--size-full w3a--flex-col w3a--items-center w3a--justify-center w3a--gap-y-6">
95+
<p className="w3a--p-2 w3a--text-center w3a--text-base w3a--font-semibold w3a--text-app-gray-900 dark:w3a--text-app-white">
96+
Verify on MetaMask
97+
</p>
98+
<div className="w3a--flex w3a--justify-center">
99+
<CircularLoader width={95} height={95} thickness={6} arcSizeDeg={100}>
100+
<Image
101+
imageId={`login-metamask`}
102+
hoverImageId={`login-metamask`}
103+
fallbackImageId="wallet"
104+
height="45"
105+
width="45"
106+
isButton
107+
extension="svg"
108+
/>
109+
</CircularLoader>
110+
</div>
111+
<p className="w3a--text-center w3a--text-sm w3a--text-app-gray-500 dark:w3a--text-app-gray-400">
112+
We’ve sent a request to your wallet. Verify on your wallet to confirm that you own this wallet.
113+
</p>
114+
<button className="w3a--w-full w3a--rounded-xl w3a--bg-app-gray-100 w3a--p-2 w3a--py-3 w3a--text-sm w3a--text-app-gray-900 dark:w3a--bg-app-gray-800 dark:w3a--text-app-white">
115+
Click here to verify
116+
</button>
117+
</div>
118+
);
119+
}
120+
91121
/**
92122
* Loader component
93123
* @param props - LoaderProps
94124
* @returns Loader component
95125
*/
96126
function Loader(props: LoaderProps) {
97-
const { connector, connectorName, modalStatus, onClose, appLogo, message } = props;
127+
const { connector, connectorName, modalStatus, onClose, appLogo, message, isConnectAndSignAuthenticationMode } = props;
98128

99129
useEffect(() => {
100130
if (modalStatus === MODAL_STATUS.CONNECTED) {
101131
setTimeout(() => {
102132
onClose();
103133
}, 1000);
104134
}
105-
}, [modalStatus, onClose]);
135+
if (isConnectAndSignAuthenticationMode && modalStatus === MODAL_STATUS.AUTHORIZED) {
136+
setTimeout(() => {
137+
onClose();
138+
}, 1000);
139+
}
140+
}, [modalStatus, onClose, isConnectAndSignAuthenticationMode]);
106141

107142
return (
108143
<div className="w3a--flex w3a--h-full w3a--flex-1 w3a--flex-col w3a--items-center w3a--justify-center w3a--gap-y-4">
109144
{modalStatus === MODAL_STATUS.CONNECTING && <ConnectingStatus connector={connector} connectorName={connectorName} appLogo={appLogo} />}
110145

111-
{modalStatus === MODAL_STATUS.CONNECTED && <ConnectedStatus message={message} />}
146+
{(modalStatus === MODAL_STATUS.CONNECTED || modalStatus === MODAL_STATUS.AUTHORIZED) && <ConnectedStatus message={message} />}
112147

113148
{modalStatus === MODAL_STATUS.ERRORED && <ErroredStatus message={message} />}
149+
150+
{modalStatus === MODAL_STATUS.AUTHORIZING && <AuthorizingStatus />}
114151
</div>
115152
);
116153
}

packages/modal/src/ui/components/Loader/Loader.type.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export interface LoaderProps {
77
connectorName: string;
88
modalStatus: ModalStatusType;
99
onClose: () => void;
10+
isConnectAndSignAuthenticationMode: boolean;
1011
}
1112

1213
export type ConnectingStatusType = Pick<LoaderProps, "connectorName" | "appLogo" | "connector">;

packages/modal/src/ui/components/Root/Root.tsx

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { ExternalButton, mobileOs, MODAL_STATUS, TOAST_TYPE, ToastType } from ".
99
import i18n from "../../localeImport";
1010
import { cn, getBrowserExtensionUrl, getBrowserName, getIcons, getMobileInstallLink, getOsName } from "../../utils";
1111
import BottomSheet from "../BottomSheet";
12-
import CircularLoader from "../CircularLoader";
1312
import ConnectWallet from "../ConnectWallet";
1413
import ConnectWalletChainNamespaceSelect from "../ConnectWallet/ConnectWalletChainNamespaceSelect";
1514
import ConnectWalletHeader from "../ConnectWallet/ConnectWalletHeader";
@@ -43,6 +42,7 @@ function Root(props: RootProps) {
4342
preHandleExternalWalletClick,
4443
uiConfig,
4544
deviceDetails,
45+
isConnectAndSignAuthenticationMode,
4646
} = props;
4747

4848
const {
@@ -441,6 +441,7 @@ function Root(props: RootProps) {
441441
modalStatus={modalState.status}
442442
onClose={onCloseLoader}
443443
appLogo={appLogo}
444+
isConnectAndSignAuthenticationMode={isConnectAndSignAuthenticationMode}
444445
/>
445446
) : (
446447
<>
@@ -564,41 +565,6 @@ function Root(props: RootProps) {
564565
</ul>
565566
</BottomSheet>
566567
)}
567-
568-
{
569-
<BottomSheet
570-
uiConfig={uiConfig}
571-
isShown={true}
572-
onClose={() => setBodyState({ ...bodyState, installLinks: { show: false, wallet: null } })}
573-
sheetClassName="!w3a--px-8 !w3a--py-4"
574-
showCloseButton={false}
575-
>
576-
<div className="w3a--flex w3a--size-full w3a--flex-col w3a--items-center w3a--justify-center w3a--gap-y-6">
577-
<p className="w3a--p-2 w3a--text-center w3a--text-base w3a--font-semibold w3a--text-app-gray-900 dark:w3a--text-app-white">
578-
Verify on MetaMask
579-
</p>
580-
<div className="w3a--flex w3a--justify-center">
581-
<CircularLoader width={95} height={95} thickness={6} arcSizeDeg={100}>
582-
<Image
583-
imageId={`login-metamask`}
584-
hoverImageId={`login-metamask`}
585-
fallbackImageId="wallet"
586-
height="45"
587-
width="45"
588-
isButton
589-
extension="svg"
590-
/>
591-
</CircularLoader>
592-
</div>
593-
<p className="w3a--text-center w3a--text-sm w3a--text-app-gray-500 dark:w3a--text-app-gray-400">
594-
We’ve sent a request to your wallet. Verify on your wallet to confirm that you own this wallet.
595-
</p>
596-
<button className="w3a--w-full w3a--rounded-xl w3a--bg-app-gray-100 w3a--p-2 w3a--py-3 w3a--text-sm w3a--text-app-gray-900 dark:w3a--bg-app-gray-800 dark:w3a--text-app-white">
597-
Click here to verify
598-
</button>
599-
</div>
600-
</BottomSheet>
601-
}
602568
</div>
603569
</div>
604570
<Toast />

packages/modal/src/ui/components/Root/Root.type.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ export interface RootProps {
2424
preHandleExternalWalletClick: (params: { connector: string; chainNamespace?: ChainNamespaceType }) => void;
2525
setModalState: (state: ModalState) => void;
2626
onCloseLoader: () => void;
27+
isConnectAndSignAuthenticationMode: boolean;
2728
}

packages/modal/src/ui/components/Widget/Widget.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ function Widget(props: WidgetProps) {
2323
walletRegistry,
2424
uiConfig,
2525
deviceDetails,
26+
initialAuthenticationMode,
2627
} = props;
2728

2829
const { widgetType } = uiConfig;
@@ -55,6 +56,8 @@ function Widget(props: WidgetProps) {
5556
authBuildEnv: BUILD_ENV.PRODUCTION,
5657
});
5758

59+
const isConnectAndSignAuthenticationMode = useMemo(() => initialAuthenticationMode === "connect-and-sign", [initialAuthenticationMode]);
60+
5861
useEffect(() => {
5962
setModalState((prev) => ({ ...prev, modalVisibility: visible }));
6063
}, [visible]);
@@ -162,6 +165,13 @@ function Widget(props: WidgetProps) {
162165
externalWalletsVisibility: false,
163166
});
164167
}
168+
if (isConnectAndSignAuthenticationMode && modalState.status === MODAL_STATUS.AUTHORIZED) {
169+
setModalState({
170+
...modalState,
171+
modalVisibility: false,
172+
externalWalletsVisibility: false,
173+
});
174+
}
165175
if (modalState.status === MODAL_STATUS.ERRORED) {
166176
setModalState({
167177
...modalState,
@@ -223,6 +233,7 @@ function Widget(props: WidgetProps) {
223233
isSmsPasswordLessLoginVisible={isSmsPasswordLessLoginVisible}
224234
uiConfig={uiConfig}
225235
deviceDetails={deviceDetails}
236+
isConnectAndSignAuthenticationMode={isConnectAndSignAuthenticationMode}
226237
/>
227238
)}
228239
</Modal>
@@ -255,6 +266,7 @@ function Widget(props: WidgetProps) {
255266
isSmsPasswordLessLoginVisible={isSmsPasswordLessLoginVisible}
256267
uiConfig={uiConfig}
257268
deviceDetails={deviceDetails}
269+
isConnectAndSignAuthenticationMode={isConnectAndSignAuthenticationMode}
258270
/>
259271
)}
260272
</Embed>

packages/modal/src/ui/components/Widget/Widget.type.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { SafeEventEmitter } from "@web3auth/auth";
2-
import { ChainNamespaceType, WalletRegistry } from "@web3auth/no-modal";
2+
import { ChainNamespaceType, InitialAuthenticationModeType, WalletRegistry } from "@web3auth/no-modal";
33

44
import { browser, ExternalWalletEventType, os, platform, SocialLoginEventType, StateEmitterEvents, UIConfig } from "../../interfaces";
55

@@ -10,6 +10,7 @@ export interface WidgetProps {
1010
chainNamespaces: ChainNamespaceType[];
1111
walletRegistry?: WalletRegistry;
1212
uiConfig: UIConfig;
13+
initialAuthenticationMode: InitialAuthenticationModeType;
1314
deviceDetails: { platform: platform; browser: browser; os: os };
1415
handleSocialLoginClick: (params: SocialLoginEventType) => void;
1516
handleExternalWalletClick: (params: ExternalWalletEventType) => void;

packages/modal/src/ui/interfaces.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
type AuthLoginParams,
1414
type BaseConnectorConfig,
1515
type ChainNamespaceType,
16+
InitialAuthenticationModeType,
1617
type LoginMethodConfig,
1718
type LoginModalConfig,
1819
type UIConfig as CoreUIConfig,
@@ -76,6 +77,7 @@ export type ModalLoginParams = Pick<
7677
};
7778

7879
export interface LoginModalProps extends UIConfig {
80+
initialAuthenticationMode: InitialAuthenticationModeType;
7981
chainNamespaces: ChainNamespaceType[];
8082
walletRegistry: WalletRegistry;
8183
web3authClientId: string;
@@ -109,6 +111,8 @@ export const MODAL_STATUS = {
109111
CONNECTED: "connected",
110112
CONNECTING: "connecting",
111113
ERRORED: "errored",
114+
AUTHORIZING: "authorizing",
115+
AUTHORIZED: "authorized",
112116
} as const;
113117
export type ModalStatusType = (typeof MODAL_STATUS)[keyof typeof MODAL_STATUS];
114118

packages/modal/src/ui/loginModal.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ export class LoginModal {
9898
if (!uiConfig.primaryButton) this.uiConfig.primaryButton = "socialLogin";
9999
if (!uiConfig.defaultLanguage) this.uiConfig.defaultLanguage = getUserLanguage(uiConfig.defaultLanguage);
100100
if (!uiConfig.widgetType) this.uiConfig.widgetType = WIDGET_TYPE.MODAL;
101+
if (!uiConfig.initialAuthenticationMode) this.uiConfig.initialAuthenticationMode = "connect-only";
101102

102103
if (uiConfig.widgetType === WIDGET_TYPE.EMBED && !uiConfig.targetId) {
103104
log.error("targetId is required for embed widget");
@@ -269,6 +270,7 @@ export class LoginModal {
269270
handleSocialLoginClick={this.handleSocialLoginClick}
270271
closeModal={this.closeModal}
271272
uiConfig={this.uiConfig}
273+
initialAuthenticationMode={this.uiConfig.initialAuthenticationMode}
272274
/>
273275
</AnalyticsContext.Provider>
274276
</ThemedContext.Provider>
@@ -458,5 +460,11 @@ export class LoginModal {
458460
listener.on(CONNECTOR_EVENTS.CONNECTOR_DATA_UPDATED, (connectorData: IConnectorDataEvent) => {
459461
this.handleConnectorData(connectorData);
460462
});
463+
listener.on(CONNECTOR_EVENTS.AUTHORIZING, () => {
464+
this.setState({ status: MODAL_STATUS.AUTHORIZING });
465+
});
466+
listener.on(CONNECTOR_EVENTS.AUTHORIZED, () => {
467+
this.setState({ status: MODAL_STATUS.AUTHORIZED });
468+
});
461469
};
462470
}

0 commit comments

Comments
 (0)