Skip to content
Closed
49 changes: 28 additions & 21 deletions demo/vue-app-new/src/MainView.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
<script setup lang="ts">

import { CHAIN_NAMESPACES, coinbaseConnector, ConnectorFn, CustomChainConfig, getChainConfig, nftCheckoutPlugin, PluginFn, storageAvailable, WALLET_CONNECTORS, walletConnectV2Connector, walletServicesPlugin, type Web3AuthOptions } from "@web3auth/modal";
import { AccountAbstractionMultiChainConfig, CHAIN_NAMESPACES, coinbaseConnector, ConnectorFn, CustomChainConfig, getChainConfig, nftCheckoutPlugin, PluginFn, storageAvailable, WALLET_CONNECTORS, walletServicesPlugin, type Web3AuthOptions } from "@web3auth/modal";
import { Web3AuthContextConfig, Web3AuthProvider } from "@web3auth/modal/vue";
import { WalletServicesProvider } from "@web3auth/no-modal/vue";
import { computed, onBeforeMount, ref, watch } from "vue";

import { LOGIN_PROVIDER_TYPE } from "@web3auth/auth";
import AppDashboard from "./components/AppDashboard.vue";
import AppHeader from "./components/AppHeader.vue";
import AppSettings from "./components/AppSettings.vue";
import { chainConfigs, clientIds, getDefaultBundlerUrl, NFT_CHECKOUT_CLIENT_ID } from "./config";
import { clientIds, NFT_CHECKOUT_CLIENT_ID } from "./config";
import { FormConfigSettings } from "./interfaces";
import { formDataStore } from "./store/form";

const formData = formDataStore;
Expand All @@ -20,29 +22,34 @@ const showAAProviderSettings = computed(() => formData.chainNamespaces.includes(
// Options for reinitializing the web3Auth object
const options = computed((): Web3AuthOptions => {
const { config: whiteLabel, enable: enabledWhiteLabel } = formData.whiteLabel;
// TODO: AA config need multi chain support
const evmChainIds = chainConfigs[CHAIN_NAMESPACES.EIP155].filter((x) => formData.chains.includes(x));
const firstEvmChainId = evmChainIds[0];

// Account Abstraction
const { useAccountAbstractionProvider } = formData;
let accountAbstractionConfig: Web3AuthOptions["accountAbstractionConfig"];
if (showAAProviderSettings.value && useAccountAbstractionProvider) {
const chains: AccountAbstractionMultiChainConfig["chains"] = {};
Object.entries(formData.smartAccountChainsConfig).forEach(([chainId, { bundlerUrl, paymasterUrl }]) => {
if (formData.chains.includes(chainId)) {
chains[chainId] = {
bundlerConfig: { url: bundlerUrl },
paymasterConfig: paymasterUrl ? { url: paymasterUrl } : undefined,
smartAccountConfig: undefined,
}
}
});
accountAbstractionConfig = {
smartAccountType: formData.smartAccountType as string,
smartAccountConfig: undefined,
bundlerConfig: { url: formData.bundlerUrl ?? getDefaultBundlerUrl(firstEvmChainId) },
paymasterConfig: formData.paymasterUrl ? { url: formData.paymasterUrl } : undefined,
chains,
}
}

// Wallet services settings
let walletServicesConfig: Web3AuthOptions["walletServicesConfig"] = {
// walletUrls: {
// production: {
// url: "http://localhost:4050",
// }
// }
walletUrls: {
production: {
url: "http://localhost:4050",
}
}
};
if (formData.walletPlugin.enable) {
const { confirmationStrategy } = formData.walletPlugin;
Expand Down Expand Up @@ -111,11 +118,13 @@ const options = computed((): Web3AuthOptions => {
const loginMethodsConfig = computed(() => {
if (formData.loginProviders.length === 0) return undefined;

if (!Object.values(formData.loginMethods).some((x) => x.showOnModal)) {
return undefined;
}
// only show login methods that are configured
const config = formData.loginProviders.reduce((acc, provider) => {
acc[provider] = formData.loginMethods[provider];
return acc;
}, {} as Record<LOGIN_PROVIDER_TYPE, FormConfigSettings>);

const loginMethods = JSON.parse(JSON.stringify(formData.loginMethods));
const loginMethods = JSON.parse(JSON.stringify(config));
return loginMethods;
});

Expand All @@ -133,8 +142,6 @@ const getExternalAdapterByName = (name: string): ConnectorFn[] => {
switch (name) {
case "coinbase":
return [coinbaseConnector()];
case "wallet-connect-v2":
return [walletConnectV2Connector({ walletConnectInitOptions: { projectId: "d3c63f19f9582f8ba48e982057eb096b" } })];
default:
return [];
}
Expand All @@ -159,8 +166,8 @@ onBeforeMount(() => {
formData.nftCheckoutPlugin = json.nftCheckoutPlugin || {};
formData.useAccountAbstractionProvider = json.useAccountAbstractionProvider;
formData.smartAccountType = json.smartAccountType;
formData.bundlerUrl = json.bundlerUrl;
formData.paymasterUrl = json.paymasterUrl;
formData.smartAccountChains = json.smartAccountChains;
formData.smartAccountChainsConfig = json.smartAccountChainsConfig;
}
} catch (error) { }
}
Expand Down
2 changes: 1 addition & 1 deletion demo/vue-app-new/src/components/AppDashboard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const props = defineProps<{
}>();

const { userInfo, isConnected, provider, switchChain, web3Auth } = useWeb3Auth();
const currentChainId = ref<string | undefined>(web3Auth.value?.currentChain.chainId);
const currentChainId = ref<string | undefined>(web3Auth.value?.currentChain?.chainId);
const currentChainConfig = computed(() => supportedNetworks[currentChainId.value as keyof typeof supportedNetworks]);
const currentChainNamespace = computed(() => currentChainConfig.value?.chainNamespace);
const connection = computed(() => {
Expand Down
77 changes: 63 additions & 14 deletions demo/vue-app-new/src/components/AppSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
chainNamespaceOptions,
clientIds,
confirmationStrategyOptions,
getDefaultBundlerUrl,
languageOptions,
loginProviderOptions,
networkOptions,
Expand Down Expand Up @@ -41,6 +42,12 @@ const defaultChainOptions = computed(() => {
return formData.chains.map((chain) => ({ name: chain, value: chain }));
});

const aaSupportedChains = computed(() => {
return formData.chains.map((chainId) => {
return getChainConfig(CHAIN_NAMESPACES.EIP155, chainId, clientIds[formData.network]);
}).filter((chainConfig) => chainConfig).map((chainConfig) => ({ name: `${chainConfig!.chainId} ${chainConfig!.displayName}`, value: chainConfig!.chainId }));
});

const adapterOptions = computed(() =>
formData.chainNamespaces.includes(CHAIN_NAMESPACES.EIP155)
? [
Expand Down Expand Up @@ -71,6 +78,7 @@ const isDisabled = (name: string): boolean => {
return !isInitialized.value;

case "smartAccountType":
case "smartAccountChains":
case "bundlerUrl":
case "paymasterUrl":
case "useAAWithExternalWallet":
Expand All @@ -94,9 +102,32 @@ const isActiveTab = (index: number) => activeTab.value === index;
const onChainNamespaceChange = (value: string[]) => {
log.info("onChainNamespaceChange", value);
formData.chains = value.map((namespace) => chainConfigs[namespace as ChainNamespaceType][0]);
formData.defaultChainId = formData.chains[0];
onChainChange(formData.chains);
formData.connectors = [];
};

const onChainChange = (chainIds: string[]) => {
log.info("onChainChange", chainIds);
// update default chain Id if not found in the new chains
if (formData.defaultChainId && chainIds.includes(formData.defaultChainId)) {
formData.defaultChainId = chainIds[0];
}
// update smart account chains if not found in the new chains
formData.smartAccountChains = formData.smartAccountChains.filter((chain) => chainIds.includes(chain));
};

const onSmartAccountChainChange = (chainIds: string[]) => {
log.info("onSmartAccountChainChange", chainIds);
formData.smartAccountChainsConfig = {};
for (const chainId of chainIds) {
if (!formData.smartAccountChainsConfig[chainId]) {
formData.smartAccountChainsConfig[chainId] = {
bundlerUrl: getDefaultBundlerUrl(chainId),
paymasterUrl: "",
};
}
}
};
</script>

<template>
Expand Down Expand Up @@ -159,6 +190,7 @@ const onChainNamespaceChange = (value: string[]) => {
:placeholder="$t('app.chains')"
:multiple="true"
:options="chainOptions"
@update:model-value="onChainChange"
/>
<Select
v-model="formData.defaultChainId"
Expand All @@ -167,6 +199,7 @@ const onChainNamespaceChange = (value: string[]) => {
:aria-label="$t('app.defaultChainId')"
:placeholder="$t('app.defaultChainId')"
:options="defaultChainOptions"
:disable-deselect="false"
/>
<Select
v-model="formData.connectors"
Expand Down Expand Up @@ -433,20 +466,36 @@ const onChainNamespaceChange = (value: string[]) => {
:options="SmartAccountOptions"
:disabled="isDisabled('smartAccountType')"
/>
<TextField
v-model="formData.bundlerUrl"
:label="$t('app.accountAbstractionProvider.bundlerUrl')"
:aria-label="$t('app.accountAbstractionProvider.bundlerUrl')"
:placeholder="$t('app.accountAbstractionProvider.bundlerUrl')"
:disabled="isDisabled('bundlerUrl')"
/>
<TextField
v-model="formData.paymasterUrl"
:label="$t('app.accountAbstractionProvider.paymasterUrl')"
:aria-label="$t('app.accountAbstractionProvider.paymasterUrl')"
:placeholder="$t('app.accountAbstractionProvider.paymasterUrl')"
:disabled="isDisabled('paymasterUrl')"
<Select
v-model="formData.smartAccountChains"
data-testid="selectSmartAccountChains"
:label="$t('app.chains')"
:aria-label="$t('app.chains')"
:placeholder="$t('app.chains')"
:options="aaSupportedChains"
multiple
:disabled="isDisabled('smartAccountChains')"
@update:model-value="onSmartAccountChainChange"
/>
<Card v-for="c in formData.smartAccountChains" :key="c" :shadow="false" class="gap-2 px-4 py-4">
<div class="font-bold leading-tight text-left sm:col-span-2">{{ c }}</div>
<TextField
class="mt-3"
v-model="formData.smartAccountChainsConfig[c].bundlerUrl"
:label="$t('app.accountAbstractionProvider.bundlerUrl')"
:aria-label="$t('app.accountAbstractionProvider.bundlerUrl')"
:placeholder="$t('app.accountAbstractionProvider.bundlerUrl')"
:disabled="isDisabled('bundlerUrl')"
/>
<TextField
class="mt-3"
v-model="formData.smartAccountChainsConfig[c].paymasterUrl"
:label="$t('app.accountAbstractionProvider.paymasterUrl')"
:aria-label="$t('app.accountAbstractionProvider.paymasterUrl')"
:placeholder="$t('app.accountAbstractionProvider.paymasterUrl')"
:disabled="isDisabled('paymasterUrl')"
/>
</Card>
</Card>
<div class="flex justify-center mt-5">
<Button
Expand Down
6 changes: 3 additions & 3 deletions demo/vue-app-new/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export type FormData = {
network: WEB3AUTH_NETWORK_TYPE;
chainNamespaces: ChainNamespaceType[];
chains: string[];
defaultChainId: string;
defaultChainId?: string;
whiteLabel: {
enable: boolean;
config: WhiteLabelData;
Expand All @@ -122,8 +122,8 @@ export type FormData = {
useAccountAbstractionProvider: boolean;
useAAWithExternalWallet?: boolean;
smartAccountType?: SmartAccountType;
bundlerUrl?: string;
paymasterUrl?: string;
smartAccountChains: string[];
smartAccountChainsConfig: Record<string, { bundlerUrl: string; paymasterUrl: string }>;
};

export const getV4TypedData = (chainId: string): SignTypedDataMessageV4 => ({
Expand Down
4 changes: 3 additions & 1 deletion demo/vue-app-new/src/store/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const formDataStore = reactive<FormData>({
network: WEB3AUTH_NETWORK.TESTNET,
chainNamespaces: [CHAIN_NAMESPACES.EIP155],
chains: [chainConfigs[CHAIN_NAMESPACES.EIP155][0], chainConfigs[CHAIN_NAMESPACES.EIP155][1]],
defaultChainId: chainConfigs[CHAIN_NAMESPACES.EIP155][0],
defaultChainId: undefined,
whiteLabel: {
enable: false,
config: initWhiteLabel,
Expand All @@ -29,4 +29,6 @@ export const formDataStore = reactive<FormData>({
useAccountAbstractionProvider: false,
useAAWithExternalWallet: true,
smartAccountType: "safe", // default smart account type to safe
smartAccountChains: [],
smartAccountChainsConfig: {},
});
Loading
Loading