Skip to content

Commit 4933621

Browse files
Merge pull request #2129 from Web3Auth/fix/v10-ui-p2
Fix/v10 UI p2
2 parents bf100ac + f19bd67 commit 4933621

File tree

10 files changed

+264
-231
lines changed

10 files changed

+264
-231
lines changed

demo/vue-app-new/package-lock.json

Lines changed: 193 additions & 164 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
coinbaseConnector,
66
type ConnectorFn,
77
type CustomChainConfig,
8-
getChainConfig,
98
nftCheckoutPlugin,
109
type PluginFn,
1110
storageAvailable,
@@ -27,6 +26,7 @@ import AppSettings from "./components/AppSettings.vue";
2726
import { clientIds, NFT_CHECKOUT_CLIENT_ID } from "./config";
2827
import { FormConfigSettings } from "./interfaces";
2928
import { formDataStore } from "./store/form";
29+
import { getChainConfig } from "./utils/chainconfig";
3030
3131
const formData = formDataStore;
3232

packages/modal/src/interface.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { BaseConnectorConfig, IProvider, IWeb3Auth, LoginMethodConfig, WALLET_CONNECTOR_TYPE } from "@web3auth/no-modal";
22

3-
export interface ModalConfig extends Omit<BaseConnectorConfig, "isInjected"> {
3+
export interface ModalConfig extends Omit<BaseConnectorConfig, "isInjected" | "chainNamespaces"> {
44
loginMethods?: LoginMethodConfig;
55
}
66

packages/modal/src/modalManager.ts

Lines changed: 36 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
CONNECTOR_CATEGORY,
99
CONNECTOR_EVENTS,
1010
CONNECTOR_NAMES,
11+
CONNECTOR_NAMESPACES,
1112
CONNECTOR_STATUS,
1213
fetchProjectConfig,
1314
fetchWalletRegistry,
@@ -80,7 +81,7 @@ export class Web3Auth extends Web3AuthNoModal implements IWeb3AuthModal {
8081
connectorListener: this,
8182
web3authClientId: this.options.clientId,
8283
web3authNetwork: this.options.web3AuthNetwork,
83-
chainNamespaces: [...new Set(this.coreOptions.chains?.map((x) => x.chainNamespace) || [])],
84+
chainNamespaces: this.getChainNamespaces(),
8485
walletRegistry: filteredWalletRegistry,
8586
},
8687
{
@@ -422,38 +423,47 @@ export class Web3Auth extends Web3AuthNoModal implements IWeb3AuthModal {
422423
options: { externalWalletsInitialized: boolean; showExternalWalletsOnly?: boolean; externalWalletsVisibility?: boolean }
423424
): Promise<void> {
424425
const connectorsConfig: Record<string, BaseConnectorConfig> = {};
426+
const connectorChainNamespaceMap: Record<string, Set<ChainNamespaceType>> = {};
427+
425428
// we do it like this because we don't want one slow connector to delay the load of the entire external wallet section.
426429
externalConnectors.forEach(async (connector) => {
427430
const connectorName = connector.name;
428431
log.debug("init external wallet", this.cachedConnector, connectorName, connector.status);
429-
if (connector.status === CONNECTOR_STATUS.NOT_READY) {
430-
// we are not initializing cached connector here as it is already being initialized in initModal before.
431-
if (this.cachedConnector === connectorName) return;
432+
433+
// a wallet can support multiple chain namespaces e.g. Phantom has EvmInjected connector and WalletStandard connector.
434+
if (!connectorChainNamespaceMap[connectorName]) connectorChainNamespaceMap[connectorName] = new Set();
435+
if (connector.connectorNamespace === CONNECTOR_NAMESPACES.MULTICHAIN) {
436+
this.getChainNamespaces().forEach((x) => connectorChainNamespaceMap[connectorName].add(x));
437+
} else {
438+
connectorChainNamespaceMap[connectorName].add(connector.connectorNamespace as ChainNamespaceType);
439+
}
440+
441+
// initialize connectors
442+
// skip initializing cached connector here as it is already being initialized in initModal before.
443+
if (connector.status === CONNECTOR_STATUS.NOT_READY && this.cachedConnector !== connectorName) {
432444
try {
433445
this.subscribeToConnectorEvents(connector);
434446
const initialChain = this.getInitialChainIdForConnector(connector);
435447
await connector.init({ autoConnect: this.cachedConnector === connectorName, chainId: initialChain.chainId });
436-
const connectorModalConfig = (this.modalConfig.connectors as Record<WALLET_CONNECTOR_TYPE, ModalConfig>)[connectorName];
437-
connectorsConfig[connectorName] = { ...connectorModalConfig, isInjected: connector.isInjected, icon: connector.icon };
438-
this.loginModal.addWalletLogins(connectorsConfig, {
439-
showExternalWalletsOnly: !!options.showExternalWalletsOnly,
440-
externalWalletsVisibility: !!options.externalWalletsVisibility,
441-
externalWalletsInitialized: !!options.externalWalletsInitialized,
442-
});
443448
} catch (error) {
444449
log.error(error, "error while initializing connector", connectorName);
445450
}
446-
} else {
447-
if (connector.status === CONNECTOR_STATUS.READY || connector.status === CONNECTOR_STATUS.CONNECTING) {
448-
// we use connecting status for wallet connect
449-
const connectorModalConfig = (this.modalConfig.connectors as Record<WALLET_CONNECTOR_TYPE, ModalConfig>)[connectorName];
450-
connectorsConfig[connectorName] = { ...connectorModalConfig, isInjected: connector.isInjected, icon: connector.icon };
451-
this.loginModal.addWalletLogins(connectorsConfig, {
452-
showExternalWalletsOnly: !!options.showExternalWalletsOnly,
453-
externalWalletsVisibility: !!options.externalWalletsVisibility,
454-
externalWalletsInitialized: !!options.externalWalletsInitialized,
455-
});
456-
}
451+
}
452+
453+
// update connector config
454+
if (([CONNECTOR_STATUS.NOT_READY, CONNECTOR_STATUS.READY, CONNECTOR_STATUS.CONNECTING] as string[]).includes(connector.status)) {
455+
const connectorModalConfig = (this.modalConfig.connectors as Record<WALLET_CONNECTOR_TYPE, ModalConfig>)[connectorName];
456+
connectorsConfig[connectorName] = {
457+
...connectorModalConfig,
458+
isInjected: connector.isInjected,
459+
icon: connector.icon,
460+
chainNamespaces: Array.from(connectorChainNamespaceMap[connectorName]),
461+
};
462+
this.loginModal.addWalletLogins(connectorsConfig, {
463+
showExternalWalletsOnly: !!options.showExternalWalletsOnly,
464+
externalWalletsVisibility: !!options.externalWalletsVisibility,
465+
externalWalletsInitialized: !!options.externalWalletsInitialized,
466+
});
457467
}
458468
});
459469
}
@@ -514,4 +524,8 @@ export class Web3Auth extends Web3AuthNoModal implements IWeb3AuthModal {
514524
}
515525
}
516526
};
527+
528+
private getChainNamespaces = (): ChainNamespaceType[] => {
529+
return [...new Set(this.coreOptions.chains?.map((x) => x.chainNamespace) || [])];
530+
};
517531
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { BottomSheetProps } from "./BottomSheet.type";
55
* @returns BottomSheet component
66
*/
77
function BottomSheet({ isShown, onClose, children, uiConfig }: BottomSheetProps) {
8-
const { borderRadiusType } = uiConfig;
8+
const { borderRadiusType = "large" } = uiConfig;
99
return (
1010
<>
1111
{/* Backdrop */}
@@ -23,7 +23,7 @@ function BottomSheet({ isShown, onClose, children, uiConfig }: BottomSheetProps)
2323
<div
2424
className={cn(
2525
`w3a--fixed w3a--bottom-2 w3a--left-2 w3a--mx-auto w3a--flex w3a--w-[96%] w3a--flex-col
26-
w3a--gap-y-2 w3a--rounded-3xl w3a--border w3a--border-app-gray-100 w3a--bg-app-white w3a--p-4 w3a--shadow-lg w3a--transition-transform w3a--duration-500
26+
w3a--gap-y-2 w3a--border w3a--border-app-gray-100 w3a--bg-app-white w3a--p-4 w3a--shadow-lg w3a--transition-transform w3a--duration-500
2727
w3a--ease-out dark:w3a--border-app-gray-600 dark:w3a--bg-app-dark-surface-main
2828
${isShown ? "w3a--translate-y-0 w3a--delay-700" : "w3a--translate-y-full"}`,
2929
{

packages/modal/src/ui/components/ConnectWallet/ConnectWalletChainFilter/ConnectWalletChainFilter.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@ function ConnectWalletChainFilter(props: ConnectWalletChainFilterProps) {
4141
type="button"
4242
key={chain.id}
4343
className={cn(
44-
"w3a--flex w3a--items-center w3a--justify-center w3a--gap-x-1 w3a--text-xs w3a--font-medium w3a--px-4 w3a--py-3 w3a--text-app-gray-500 dark:w3a--text-app-gray-300 w3a--h-12",
44+
"w3a--flex w3a--items-center w3a--justify-center w3a--gap-x-1 w3a--text-xs w3a--font-medium w3a--px-4 w3a--py-3 w3a--text-app-gray-500 dark:w3a--text-app-gray-300 hover:w3a--bg-app-gray-200 dark:hover:w3a--bg-app-gray-700 w3a--h-12 w3a--rounded-2xl",
4545
{
46-
"w3a--bg-app-gray-100 dark:w3a--bg-app-gray-800 w3a--border w3a--border-app-gray-200 dark:w3a--border-app-gray-700 w3a--rounded-2xl hover:w3a--bg-app-gray-200 dark:hover:w3a--bg-app-gray-700 w3a--text-app-gray-900 dark:w3a--text-app-white":
46+
"w3a--bg-app-gray-100 dark:w3a--bg-app-gray-800 w3a--border w3a--border-app-gray-200 dark:w3a--border-app-gray-700 w3a--text-app-gray-900 dark:w3a--text-app-white":
4747
selectedChain === chain.id,
4848
}
4949
)}
@@ -52,7 +52,7 @@ function ConnectWalletChainFilter(props: ConnectWalletChainFilterProps) {
5252
{chain.icon && (
5353
<img src={getIcons(isDark ? `${chain.icon}-dark` : `${chain.icon}-light`)} alt={chain.name} className="w3a--size-5 w3a--object-contain" />
5454
)}
55-
{t(chain.name)}
55+
<span className="first-letter:w3a--capitalize">{t(chain.name)}</span>
5656
</button>
5757
))}
5858
</div>

packages/modal/src/ui/components/ConnectWallet/ConnectWalletChainNamespaceSelect/ConnectWalletChainNamespaceSelect.tsx

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,20 +23,6 @@ const ConnectWalletChainNamespaceSelect = (props: ConnectWalletChainNamespaceSel
2323
<div>
2424
{/* Header */}
2525
<div className="w3a--flex w3a--items-center w3a--justify-center">
26-
{/* <button
27-
type="button"
28-
className="w3a--z-20 w3a--flex w3a--size-5 w3a--cursor-pointer w3a--items-center w3a--justify-center w3a--rounded-full"
29-
onClick={handleBack}
30-
>
31-
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20" className="w3a--text-app-gray-900 dark:w3a--text-app-white">
32-
<path
33-
fill="currentColor"
34-
fillRule="evenodd"
35-
d="M9.707 16.707a1 1 0 0 1-1.414 0l-6-6a1 1 0 0 1 0-1.414l6-6a1 1 0 0 1 1.414 1.414L5.414 9H17a1 1 0 1 1 0 2H5.414l4.293 4.293a1 1 0 0 1 0 1.414"
36-
clipRule="evenodd"
37-
/>
38-
</svg>
39-
</button> */}
4026
<p className="w3a--text-base w3a--font-medium w3a--text-app-gray-900 dark:w3a--text-app-white">{t("modal.external.select-chain")}</p>
4127
</div>
4228

@@ -64,14 +50,19 @@ const ConnectWalletChainNamespaceSelect = (props: ConnectWalletChainNamespaceSel
6450
<li key={chainNamespace}>
6551
<button
6652
type="button"
67-
className="w3a--btn w3a--size-xl w3a--w-full w3a--items-center !w3a--justify-between w3a--rounded-full"
53+
className="w3a--btn w3a-external-wallet-btn w3a--h-12 w3a--w-full w3a--items-center !w3a--justify-between w3a--rounded-full"
6854
onClick={() => handleExternalWalletClick({ connector: wallet.name, chainNamespace })}
6955
>
7056
<div className="w3a--flex w3a--items-center">
7157
<Image imageId={imageId} hoverImageId={imageId} fallbackImageId="wallet" height="24" width="24" isButton extension="svg" />
7258
<p className="w3a--ml-2 w3a--text-left w3a--text-sm first-letter:w3a--capitalize">{displayName}</p>
7359
</div>
74-
<img id="external-wallet-arrow" src={getIcons(isDark ? "chevron-right-dark" : "chevron-right-light")} alt="arrow" />
60+
<img
61+
id="external-wallet-arrow"
62+
className="w3a--icon-animation"
63+
src={getIcons(isDark ? "chevron-right-dark" : "chevron-right-light")}
64+
alt="arrow"
65+
/>
7566
</button>
7667
</li>
7768
))}

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

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -256,20 +256,25 @@ function Root(props: RootProps) {
256256
href = universalLink || deepLink;
257257
}
258258

259+
// determine the chain namespaces supported by the wallet
260+
const connectorConfig = config[wallet];
261+
const connectorChainNamespaces = connectorConfig?.chainNamespaces || [];
259262
const registryNamespaces = new Set(walletRegistryItem.chains?.map((chain) => chain.split(":")[0]));
260263
const injectedChainNamespaces = new Set(walletRegistryItem.injected?.map((injected) => injected.namespace));
261-
const availableChainNamespaces = chainNamespaces.filter((x) => registryNamespaces.has(x) || injectedChainNamespaces.has(x));
262-
const connector = config[wallet];
264+
const availableChainNamespaces = chainNamespaces.filter(
265+
(x) => registryNamespaces.has(x) || injectedChainNamespaces.has(x) || connectorChainNamespaces.includes(x)
266+
);
267+
263268
const button: ExternalButton = {
264269
name: wallet,
265270
displayName: walletRegistryItem.name,
266271
href,
267-
hasInjectedWallet: connector?.isInjected || false,
272+
hasInjectedWallet: connectorConfig?.isInjected || false,
268273
hasWalletConnect: isWalletConnectConnectorIncluded && walletRegistryItem.walletConnect?.sdks?.includes("sign_v2"),
269274
hasInstallLinks: Object.keys(walletRegistryItem.app || {}).length > 0,
270275
walletRegistryItem,
271276
imgExtension: walletRegistryItem.imgExtension || "svg",
272-
icon: connector?.icon,
277+
icon: connectorConfig?.icon,
273278
chainNamespaces: availableChainNamespaces,
274279
};
275280

@@ -286,29 +291,22 @@ function Root(props: RootProps) {
286291
const installedConnectorButtons = useMemo(() => {
287292
const installedConnectors = Object.keys(config).reduce((acc, connector) => {
288293
if ([WALLET_CONNECTORS.WALLET_CONNECT_V2].includes(connector) || !connectorVisibilityMap[connector]) return acc;
289-
290-
// determine chain namespaces based on wallet registry
291-
const walletRegistryItem = walletRegistry.default[connector];
292-
const registryNamespaces = new Set(walletRegistryItem?.chains?.map((chain) => chain.split(":")[0]));
293-
const injectedChainNamespaces = new Set(walletRegistryItem?.injected?.map((injected) => injected.namespace));
294-
const availableChainNamespaces = chainNamespaces.filter((x) => registryNamespaces.has(x) || injectedChainNamespaces.has(x));
295-
294+
const connectorConfig = config[connector];
296295
acc.push({
297296
name: connector,
298-
displayName: config[connector].label || connector,
299-
hasInjectedWallet: config[connector]?.isInjected || false,
297+
displayName: connectorConfig?.label || connector,
298+
hasInjectedWallet: connectorConfig?.isInjected || false,
300299
hasWalletConnect: false,
301300
hasInstallLinks: false,
302-
walletRegistryItem,
303-
icon: config[connector]?.icon,
304-
chainNamespaces: availableChainNamespaces,
301+
icon: connectorConfig?.icon,
302+
chainNamespaces: connectorConfig?.chainNamespaces || [],
305303
});
306304
return acc;
307305
}, [] as ExternalButton[]);
308306

309307
// make metamask the first button and limit the number of buttons
310308
return installedConnectors;
311-
}, [config, connectorVisibilityMap, walletRegistry.default, chainNamespaces]);
309+
}, [config, connectorVisibilityMap]);
312310

313311
const customConnectorButtons = useMemo(() => {
314312
return installedConnectorButtons.filter((button) => !button.hasInjectedWallet);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ function Widget(props: WidgetProps) {
6161
log.debug("state updated", newModalState);
6262

6363
setModalState((prevState) => {
64-
const mergedState = cloneDeep(deepmerge(prevState, newModalState));
64+
const mergedState = cloneDeep(deepmerge(prevState, newModalState, { arrayMerge: (_prevState, newState) => newState }));
6565
return mergedState;
6666
});
6767
});

packages/no-modal/src/base/connector/interfaces.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ import {
1414
type WEB3AUTH_NETWORK_TYPE,
1515
} from "@web3auth/auth";
1616

17-
import { ConnectorNamespaceType, CustomChainConfig } from "../chain/IChainInterface";
18-
import { IWeb3AuthCoreOptions } from "../core/IWeb3Auth";
17+
import type { ChainNamespaceType, ConnectorNamespaceType, CustomChainConfig } from "../chain/IChainInterface";
18+
import type { IWeb3AuthCoreOptions } from "../core/IWeb3Auth";
1919
import { Web3AuthError } from "../errors";
20-
import { ProjectConfig } from "../interfaces";
21-
import { ProviderEvents, SafeEventEmitterProvider } from "../provider/IProvider";
20+
import type { ProjectConfig } from "../interfaces";
21+
import type { ProviderEvents, SafeEventEmitterProvider } from "../provider/IProvider";
2222
import { CONNECTOR_CATEGORY, CONNECTOR_EVENTS, CONNECTOR_STATUS } from "./constants";
2323

2424
export type UserInfo = AuthUserInfo;
@@ -113,6 +113,7 @@ export interface BaseConnectorConfig {
113113
label: string;
114114
icon?: string;
115115
isInjected?: boolean;
116+
chainNamespaces?: ChainNamespaceType[];
116117
showOnModal?: boolean;
117118
showOnMobile?: boolean;
118119
showOnDesktop?: boolean;

0 commit comments

Comments
 (0)