Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions demo/vue-app-new/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion demo/vue-app-new/src/components/AppSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
} from "../config";
import { formDataStore } from "../store/form";
import { getChainConfig } from "../utils/chainconfig";
import ExternalWalletOnlyTest from "./ExternalWalletOnlyTest.vue";

const formData = formDataStore;

Expand Down Expand Up @@ -170,6 +171,7 @@ const onSmartAccountChainChange = (chainIds: string[]) => {
<Tab v-if="formData.chainNamespaces.includes(CHAIN_NAMESPACES.EIP155)" variant="underline" :active="isActiveTab(4)" @click="onTabChange(4)">
Account Abstraction Provider
</Tab>
<Tab variant="underline" :active="isActiveTab(5)" @click="onTabChange(5)">External Wallet Only</Tab>
</Tabs>
<Card v-if="isActiveTab(0)" class="grid grid-cols-1 gap-2 px-4 py-4" :shadow="false">
<Select
Expand Down Expand Up @@ -501,7 +503,10 @@ const onSmartAccountChainChange = (chainIds: string[]) => {
/>
</Card>
</Card>
<div class="flex justify-center mt-5">
<Card v-if="isActiveTab(5)" class="px-4 py-4" :shadow="false">
<ExternalWalletOnlyTest />
</Card>
<div v-if="!isActiveTab(5)" class="flex justify-center mt-5">
<Button
v-if="formData.widget === 'modal'"
:class="['w-full !h-auto group py-3 rounded-full flex items-center justify-center']"
Expand Down
111 changes: 111 additions & 0 deletions demo/vue-app-new/src/components/ExternalWalletOnlyTest.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<script setup lang="ts">
import { Button, Card } from "@toruslabs/vue-components";
import { Web3Auth } from "@web3auth/modal";
import { CHAIN_NAMESPACES, WALLET_CONNECTORS } from "@web3auth/no-modal";
import { ref } from "vue";

const web3auth = ref<Web3Auth | null>(null);
const isConnected = ref(false);
const address = ref("");
const balance = ref("");
const connectorName = ref("");

const connect = async () => {
web3auth.value = new Web3Auth({
clientId: "BPi5PB_UiIZ-cPz1GtV5i1I2iOSOHuimiXBI0e-Oe_u6X3oVAbCiAZOTEBtTXw4tsluTITPqA8zMsfxIKMjiqNQ",
web3AuthNetwork: "sapphire_mainnet",
chains: [
{
chainNamespace: CHAIN_NAMESPACES.EIP155,
chainId: "0x1",
rpcTarget: "https://rpc.ankr.com/eth",
displayName: "Ethereum Mainnet",
blockExplorerUrl: "https://etherscan.io",
ticker: "ETH",
tickerName: "Ethereum",
logo: "https://images.toruswallet.io/eth.svg",
},
],
multiInjectedProviderDiscovery: true,
modalConfig: {
hideWalletDiscovery: false,
connectors: {
[WALLET_CONNECTORS.AUTH]: {
label: "Auth",
showOnModal: false,
},
},
},
uiConfig: {
primaryButton: "externalLogin",
},
});

await web3auth.value.init();
const provider = await web3auth.value.connect();

if (provider) {
isConnected.value = true;
connectorName.value = web3auth.value.connectedConnectorName || "Unknown";

// Get address
const accounts = (await provider.request({ method: "eth_accounts" })) as string[];
address.value = accounts?.[0] || "";

// Get balance
if (address.value) {
const balanceHex = (await provider.request({
method: "eth_getBalance",
params: [address.value, "latest"],
})) as string;
const balanceWei = BigInt(balanceHex);
const balanceEth = Number(balanceWei) / 1e18;
balance.value = balanceEth.toFixed(4) + " ETH";
}
}
};

const disconnect = async () => {
if (web3auth.value) {
await web3auth.value.logout();
isConnected.value = false;
address.value = "";
balance.value = "";
connectorName.value = "";
web3auth.value = null;
}
};

const truncateAddress = (addr: string) => {
if (!addr) return "";
return `${addr.slice(0, 6)}...${addr.slice(-4)}`;
};
</script>

<template>
<div class="grid grid-cols-1 gap-2">
<!-- Connect Button -->
<div v-if="!isConnected">
<p class="text-sm text-app-gray-500 dark:text-app-gray-400 mb-3">
Test external wallet connection (isolated instance with AUTH hidden).
</p>
<Button block size="xs" pill @click="connect">Connect External Wallet Only</Button>
</div>

<!-- Dashboard after connection -->
<div v-else class="grid grid-cols-1 gap-2">
<Card class="px-4 py-4" :shadow="false">
<div class="mb-2 text-xl font-bold leading-tight text-left text-app-gray-900 dark:text-app-white">Connected Wallet</div>
<div class="grid grid-cols-2 gap-2 text-sm">
<div class="text-app-gray-500 dark:text-app-gray-400">Connector:</div>
<div class="font-medium text-app-gray-900 dark:text-app-white">{{ connectorName }}</div>
<div class="text-app-gray-500 dark:text-app-gray-400">Address:</div>
<div class="font-medium font-mono text-app-gray-900 dark:text-app-white">{{ truncateAddress(address) }}</div>
<div class="text-app-gray-500 dark:text-app-gray-400">Balance:</div>
<div class="font-medium text-app-gray-900 dark:text-app-white">{{ balance }}</div>
</div>
</Card>
<Button block size="xs" pill variant="tertiary" @click="disconnect">Disconnect</Button>
</div>
</div>
</template>
11 changes: 9 additions & 2 deletions packages/modal/src/ui/components/Loader/Loader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,15 +148,22 @@ function Loader(props: LoaderProps) {
[modalStatus, isConnectAndSignAuthenticationMode]
);

// Check if connector is an external wallet
const isExternalWallet = useMemo(() => {
return connector && externalWalletsConfig && connector in externalWalletsConfig;
}, [connector, externalWalletsConfig]);

useEffect(() => {
if (isConnectedAccordingToAuthenticationMode) {
// Skip success screen for external wallets, show for 1 second for social logins
const delay = isExternalWallet ? 0 : 1000;
const timeout = setTimeout(() => {
onClose();
}, 1000);
}, delay);

return () => clearTimeout(timeout);
}
}, [isConnectedAccordingToAuthenticationMode, onClose]);
}, [isConnectedAccordingToAuthenticationMode, isExternalWallet, onClose]);

return (
<div className="w3a--flex w3a--h-full w3a--flex-1 w3a--flex-col w3a--items-center w3a--justify-center w3a--gap-y-4">
Expand Down
40 changes: 21 additions & 19 deletions packages/modal/src/ui/components/Root/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -505,25 +505,27 @@ function Root(props: RootProps) {
/>
)}
{/* Connect Wallet Screen */}
{modalState.currentPage === PAGES.CONNECT_WALLET && !showExternalWalletPage && modalState.status === MODAL_STATUS.INITIALIZED && (
<ConnectWallet
isDark={isDark}
walletConnectUri={modalState.walletConnectUri}
metamaskConnectUri={modalState.metamaskConnectUri}
config={modalState.externalWalletsConfig}
walletRegistry={walletRegistry}
allRegistryButtons={allRegistryButtons}
connectorVisibilityMap={connectorVisibilityMap}
customConnectorButtons={customConnectorButtons}
deviceDetails={deviceDetails}
chainNamespace={chainNamespaces}
buttonRadius={buttonRadiusType}
handleWalletDetailsHeight={handleWalletDetailsHeight}
isExternalWalletModeOnly={isExternalWalletModeOnly}
onBackClick={onBackClick}
handleExternalWalletClick={preHandleExternalWalletClick}
/>
)}
{modalState.currentPage === PAGES.CONNECT_WALLET &&
(!showExternalWalletPage || isExternalWalletModeOnly) &&
modalState.status === MODAL_STATUS.INITIALIZED && (
<ConnectWallet
isDark={isDark}
walletConnectUri={modalState.walletConnectUri}
metamaskConnectUri={modalState.metamaskConnectUri}
config={modalState.externalWalletsConfig}
walletRegistry={walletRegistry}
allRegistryButtons={allRegistryButtons}
connectorVisibilityMap={connectorVisibilityMap}
customConnectorButtons={customConnectorButtons}
deviceDetails={deviceDetails}
chainNamespace={chainNamespaces}
buttonRadius={buttonRadiusType}
handleWalletDetailsHeight={handleWalletDetailsHeight}
isExternalWalletModeOnly={isExternalWalletModeOnly}
onBackClick={onBackClick}
handleExternalWalletClick={preHandleExternalWalletClick}
/>
)}
</>
)}
</>
Expand Down