Skip to content

Commit

Permalink
Merge pull request #2003 from Web3Auth/feat/wallet-service-aa
Browse files Browse the repository at this point in the history
Feat/wallet service aa
chaitanyapotti authored Dec 3, 2024
2 parents 9a71c71 + 55ca5ad commit 15e3d60
Showing 12 changed files with 737 additions and 181 deletions.
627 changes: 473 additions & 154 deletions demo/vue-app-new/package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions demo/vue-app-new/package.json
Original file line number Diff line number Diff line change
@@ -36,6 +36,7 @@
"@web3auth/torus-solana-adapter": "file:../../packages/adapters/torus-solana-adapter",
"@web3auth/wallet-connect-v2-adapter": "file:../../packages/adapters/wallet-connect-v2-adapter",
"@web3auth/wallet-services-plugin": "file:../../packages/plugins/wallet-services-plugin",
"@web3auth/ws-embed": "^3.2.1",
"bs58": "^5.0.0",
"ethers": "^6.13.3",
"vue": "^3.5.11",
7 changes: 5 additions & 2 deletions demo/vue-app-new/src/MainView.vue
Original file line number Diff line number Diff line change
@@ -36,9 +36,12 @@ const externalAdapters = ref<IAdapter<unknown>[]>([]);
const walletPlugins = computed(() => {
if (formData.chainNamespace !== CHAIN_NAMESPACES.EIP155 || !formData.walletPlugin.enable) return [];
const { logoDark, logoLight } = formData.walletPlugin;
const { logoDark, logoLight, confirmationStrategy } = formData.walletPlugin;
const walletServicesPlugin = new WalletServicesPlugin({
walletInitOptions: { whiteLabel: { showWidgetButton: true, logoDark: logoDark || "logo", logoLight: logoLight || "logo" } },
walletInitOptions: {
whiteLabel: { showWidgetButton: true, logoDark: logoDark || "logo", logoLight: logoLight || "logo" },
confirmationStrategy,
},
});
return [walletServicesPlugin];
});
53 changes: 40 additions & 13 deletions demo/vue-app-new/src/components/AppDashboard.vue
Original file line number Diff line number Diff line change
@@ -16,6 +16,12 @@ import {
signTypedMessage,
} from "../services/ethHandlers";
import { signAllTransactions, signAndSendTransaction, signMessage, signTransaction as signSolTransaction } from "../services/solHandlers";
import {
walletSendEth,
walletSignPersonalMessage,
walletSignTransaction as walletSignEthTransaction,
walletSignTypedMessage,
} from "../services/walletServiceHandlers";
import { formDataStore } from "../store/form";
const { t } = useI18n({ useScope: "global" });
@@ -48,19 +54,6 @@ const isDisplay = (name: string): boolean => {
}
};
const showWalletUI = async () => {
const walletPlugin = web3Auth.value?.getPlugin(WALLET_PLUGINS.WALLET_SERVICES) as WalletServicesPlugin;
await walletPlugin.showWalletUi();
};
const showCheckout = async () => {
const walletPlugin = web3Auth.value?.getPlugin(WALLET_PLUGINS.WALLET_SERVICES) as WalletServicesPlugin;
await walletPlugin.showCheckout();
};
const showWalletConnectScanner = async () => {
const walletPlugin = web3Auth.value?.getPlugin(WALLET_PLUGINS.WALLET_SERVICES) as WalletServicesPlugin;
await walletPlugin.showWalletConnectScanner();
};
const clearConsole = () => {
const el = document.querySelector("#console>pre");
const h1 = document.querySelector("#console>h1");
@@ -91,6 +84,33 @@ const printToConsole = (...args: unknown[]) => {
}
};
// Wallet Services
const showWalletUI = async () => {
const walletPlugin = web3Auth.value?.getPlugin(WALLET_PLUGINS.WALLET_SERVICES) as WalletServicesPlugin;
await walletPlugin.showWalletUi();
};
const showCheckout = async () => {
const walletPlugin = web3Auth.value?.getPlugin(WALLET_PLUGINS.WALLET_SERVICES) as WalletServicesPlugin;
await walletPlugin.showCheckout();
};
const showWalletConnectScanner = async () => {
const walletPlugin = web3Auth.value?.getPlugin(WALLET_PLUGINS.WALLET_SERVICES) as WalletServicesPlugin;
await walletPlugin.showWalletConnectScanner();
};
const onWalletSignPersonalMessage = async () => {
const walletPlugin = web3Auth.value?.getPlugin(WALLET_PLUGINS.WALLET_SERVICES) as WalletServicesPlugin;
await walletSignPersonalMessage(walletPlugin.wsEmbedInstance.provider, printToConsole);
};
const onWalletSignTypedData_v4 = async () => {
const walletPlugin = web3Auth.value?.getPlugin(WALLET_PLUGINS.WALLET_SERVICES) as WalletServicesPlugin;
await walletSignTypedMessage(walletPlugin.wsEmbedInstance.provider, printToConsole);
};
const onWalletSendEth = async () => {
const walletPlugin = web3Auth.value?.getPlugin(WALLET_PLUGINS.WALLET_SERVICES) as WalletServicesPlugin;
await walletSendEth(walletPlugin.wsEmbedInstance.provider, printToConsole);
};
// Ethereum Provider
const onGetUserInfo = async () => {
printToConsole("User Info", userInfo.value);
};
@@ -206,6 +226,13 @@ const onSignPersonalMsg = async () => {
<Button block size="xs" pill class="mb-2" @click="showCheckout">
{{ $t("app.buttons.btnShowCheckout") }}
</Button>
<Button block size="xs" pill class="mb-2" @click="onWalletSignPersonalMessage">
{{ t("app.buttons.btnSignPersonalMsg") }}
</Button>
<Button block size="xs" pill class="mb-2" @click="onWalletSignTypedData_v4">
{{ t("app.buttons.btnSignTypedData_v4") }}
</Button>
<Button block size="xs" pill class="mb-2" @click="onWalletSendEth">{{ t("app.buttons.btnSendEth") }}</Button>
</Card>
<Card v-if="isDisplay('ethServices')" class="px-4 py-4 gap-4 !h-auto lg:!h-[calc(100dvh_-_240px)]" :shadow="false">
<div class="mb-2 text-xl font-bold leading-tight text-left">Sample Transaction</div>
19 changes: 18 additions & 1 deletion demo/vue-app-new/src/components/AppSettings.vue
Original file line number Diff line number Diff line change
@@ -4,7 +4,15 @@ import { ADAPTER_STATUS, CHAIN_NAMESPACES, ChainNamespaceType, log } from "@web3
import { useWeb3Auth } from "@web3auth/modal-vue-composables";
import { computed, InputHTMLAttributes, ref } from "vue";
import { chainConfigs, chainNamespaceOptions, languageOptions, loginProviderOptions, networkOptions, SmartAccountOptions } from "../config";
import {
chainConfigs,
chainNamespaceOptions,
confirmationStrategyOptions,
languageOptions,
loginProviderOptions,
networkOptions,
SmartAccountOptions,
} from "../config";
import { formDataStore } from "../store/form";
const formData = formDataStore;
@@ -350,6 +358,15 @@ const onChainNamespaceChange = (value: string) => {
:placeholder="$t('app.walletPlugin.logoDark')"
class="sm:col-span-2"
/>
<Select
v-model="formData.walletPlugin.confirmationStrategy"
data-testid="selectLoginProviders"
:label="$t('app.walletPlugin.confirmationStrategy')"
:aria-label="$t('app.walletPlugin.confirmationStrategy')"
:placeholder="$t('app.walletPlugin.confirmationStrategy')"
:options="confirmationStrategyOptions"
class=""
/>
</Card>
<Card v-if="isActiveTab(4)" class="grid grid-cols-1 gap-2 px-4 py-4" :shadow="false">
<Toggle
8 changes: 8 additions & 0 deletions demo/vue-app-new/src/config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { LANGUAGE_TYPE, LANGUAGES, LOGIN_PROVIDER, LOGIN_PROVIDER_TYPE, WhiteLabelData } from "@web3auth/auth";
import { CHAIN_NAMESPACES, ChainNamespaceType, CustomChainConfig, WEB3AUTH_NETWORK, WEB3AUTH_NETWORK_TYPE } from "@web3auth/base";
import { SignTypedDataMessageV4 } from "@web3auth/ethereum-provider";
import { CONFIRMATION_STRATEGY, CONFIRMATION_STRATEGY_TYPE } from "@web3auth/wallet-services-plugin";

import { FormConfigSettings } from "./interfaces";

@@ -184,6 +185,7 @@ export type FormData = {
enable: boolean;
logoDark: string;
logoLight: string;
confirmationStrategy: Exclude<CONFIRMATION_STRATEGY_TYPE, "popup">;
};
useAccountAbstractionProvider: boolean;
useAAWithExternalWallet?: boolean;
@@ -240,3 +242,9 @@ export const getV4TypedData = (chainId: string): SignTypedDataMessageV4 => ({
contents: "Hello, Bob!",
},
});

export const confirmationStrategyOptions: { name: string; value: string }[] = [
{ name: "Modal", value: CONFIRMATION_STRATEGY.MODAL },
{ name: "Auto Approve", value: CONFIRMATION_STRATEGY.AUTO_APPROVE },
{ name: "Default", value: CONFIRMATION_STRATEGY.DEFAULT },
];
96 changes: 96 additions & 0 deletions demo/vue-app-new/src/services/walletServiceHandlers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { log } from "@web3auth/base";
import { verifyMessage as eipVerifyMessage } from "@web3auth/sign-in-with-ethereum";
import { WalletServicesPlugin } from "@web3auth/wallet-services-plugin";
import { BrowserProvider, parseEther } from "ethers";

import { getV4TypedData } from "../config";

export const walletSignPersonalMessage = async (provider: WalletServicesPlugin["provider"], uiConsole: any) => {
try {
const ethProvider = new BrowserProvider(provider);
const signer = await ethProvider.getSigner();
const account = await signer.getAddress();
const from = account;

const originalMessage = "Example `personal_sign` messages";

// Sign the message
const signedMessage = await signer.signMessage(originalMessage);

const valid = await eipVerifyMessage({
provider: ethProvider,
message: originalMessage,
signature: signedMessage,
signer: from,
});

uiConsole(`Success`, { signedMessage, verify: valid });
} catch (error) {
log.error("Error", error);
uiConsole("Error", error instanceof Error ? error.message : error);
}
};

export const walletSignTypedMessage = async (provider: WalletServicesPlugin["provider"], uiConsole: any) => {
try {
const ethProvider = new BrowserProvider(provider);
const signer = await ethProvider.getSigner();
const account = await signer.getAddress();
const from = account;
const typedData = getV4TypedData(provider.chainId);

const signedMessage = await signer.signTypedData(typedData.domain, typedData.types, typedData.message);

const valid = await eipVerifyMessage({
provider: ethProvider,
typedData,
signature: signedMessage,
signer: from,
});

uiConsole(`Success`, { signedMessage, verify: valid });
} catch (error) {
log.error("Error", error);
uiConsole("Error", error instanceof Error ? error.message : error);
}
};

export const walletSendEth = async (provider: WalletServicesPlugin["provider"], uiConsole: any) => {
try {
const ethProvider = new BrowserProvider(provider);
const signer = await ethProvider.getSigner();
const account = await signer.getAddress();
const txRes = await signer.sendTransaction({
from: account,
to: account,
value: parseEther("0.01"),
});
// check for big int before logging to not break the stringify
uiConsole("txRes", txRes.toJSON());
} catch (error) {
log.info("error", error);
uiConsole("error", error instanceof Error ? error.message : error);
}
};

export const walletSignTransaction = async (provider: WalletServicesPlugin["provider"], uiConsole: any) => {
try {
const ethProvider = new BrowserProvider(provider);
const accounts = await provider.request({ method: "eth_accounts" });
const smartAccountAddress = accounts[0];
const signer = await ethProvider.getSigner(smartAccountAddress);
const account = await signer.getAddress();
// only supported with social logins (openlogin adapter)
const serializedTx = await signer.signTransaction({
from: account,
to: account,
value: parseEther("0.01"),
});

uiConsole("serialized user operation", serializedTx);
} catch (error) {
log.info("error", error);
uiConsole("error", error instanceof Error ? error.message : error);
}
};
1 change: 1 addition & 0 deletions demo/vue-app-new/src/store/form.ts
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@ export const formDataStore = reactive<FormData>({
enable: false,
logoLight: "",
logoDark: "",
confirmationStrategy: "default",
},
useAccountAbstractionProvider: false,
useAAWithExternalWallet: true,
4 changes: 2 additions & 2 deletions demo/vue-app-new/src/translations/en.json
Original file line number Diff line number Diff line change
@@ -14,7 +14,8 @@
"walletPlugin": {
"title": "Wallet Service Plugin",
"logoLight": "Logo Light",
"logoDark": "Logo Dark"
"logoDark": "Logo Dark",
"confirmationStrategy": "Confirmation Strategy"
},
"accountAbstractionProvider": {
"title": "Account Abstraction Provider",
@@ -49,7 +50,6 @@
"sessionTime": "Session Time"
},
"chainNamespace": "Chain namespace",

"w3aStatus": "Web3Auth status ::::: {status}",
"isConnected": "Is connected ::::: {isConnected}",
"isInitialized": "Is initialized ::::: {isInitialized}",
73 changes: 66 additions & 7 deletions package-lock.json

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

Loading

0 comments on commit 15e3d60

Please sign in to comment.