Skip to content

Commit 15e3d60

Browse files
Merge pull request #2003 from Web3Auth/feat/wallet-service-aa
Feat/wallet service aa
2 parents 9a71c71 + 55ca5ad commit 15e3d60

File tree

12 files changed

+737
-181
lines changed

12 files changed

+737
-181
lines changed

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

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

demo/vue-app-new/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"@web3auth/torus-solana-adapter": "file:../../packages/adapters/torus-solana-adapter",
3737
"@web3auth/wallet-connect-v2-adapter": "file:../../packages/adapters/wallet-connect-v2-adapter",
3838
"@web3auth/wallet-services-plugin": "file:../../packages/plugins/wallet-services-plugin",
39+
"@web3auth/ws-embed": "^3.2.1",
3940
"bs58": "^5.0.0",
4041
"ethers": "^6.13.3",
4142
"vue": "^3.5.11",

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,12 @@ const externalAdapters = ref<IAdapter<unknown>[]>([]);
3636
3737
const walletPlugins = computed(() => {
3838
if (formData.chainNamespace !== CHAIN_NAMESPACES.EIP155 || !formData.walletPlugin.enable) return [];
39-
const { logoDark, logoLight } = formData.walletPlugin;
39+
const { logoDark, logoLight, confirmationStrategy } = formData.walletPlugin;
4040
const walletServicesPlugin = new WalletServicesPlugin({
41-
walletInitOptions: { whiteLabel: { showWidgetButton: true, logoDark: logoDark || "logo", logoLight: logoLight || "logo" } },
41+
walletInitOptions: {
42+
whiteLabel: { showWidgetButton: true, logoDark: logoDark || "logo", logoLight: logoLight || "logo" },
43+
confirmationStrategy,
44+
},
4245
});
4346
return [walletServicesPlugin];
4447
});

demo/vue-app-new/src/components/AppDashboard.vue

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ import {
1616
signTypedMessage,
1717
} from "../services/ethHandlers";
1818
import { signAllTransactions, signAndSendTransaction, signMessage, signTransaction as signSolTransaction } from "../services/solHandlers";
19+
import {
20+
walletSendEth,
21+
walletSignPersonalMessage,
22+
walletSignTransaction as walletSignEthTransaction,
23+
walletSignTypedMessage,
24+
} from "../services/walletServiceHandlers";
1925
import { formDataStore } from "../store/form";
2026
2127
const { t } = useI18n({ useScope: "global" });
@@ -48,19 +54,6 @@ const isDisplay = (name: string): boolean => {
4854
}
4955
};
5056
51-
const showWalletUI = async () => {
52-
const walletPlugin = web3Auth.value?.getPlugin(WALLET_PLUGINS.WALLET_SERVICES) as WalletServicesPlugin;
53-
await walletPlugin.showWalletUi();
54-
};
55-
const showCheckout = async () => {
56-
const walletPlugin = web3Auth.value?.getPlugin(WALLET_PLUGINS.WALLET_SERVICES) as WalletServicesPlugin;
57-
await walletPlugin.showCheckout();
58-
};
59-
const showWalletConnectScanner = async () => {
60-
const walletPlugin = web3Auth.value?.getPlugin(WALLET_PLUGINS.WALLET_SERVICES) as WalletServicesPlugin;
61-
await walletPlugin.showWalletConnectScanner();
62-
};
63-
6457
const clearConsole = () => {
6558
const el = document.querySelector("#console>pre");
6659
const h1 = document.querySelector("#console>h1");
@@ -91,6 +84,33 @@ const printToConsole = (...args: unknown[]) => {
9184
}
9285
};
9386
87+
// Wallet Services
88+
const showWalletUI = async () => {
89+
const walletPlugin = web3Auth.value?.getPlugin(WALLET_PLUGINS.WALLET_SERVICES) as WalletServicesPlugin;
90+
await walletPlugin.showWalletUi();
91+
};
92+
const showCheckout = async () => {
93+
const walletPlugin = web3Auth.value?.getPlugin(WALLET_PLUGINS.WALLET_SERVICES) as WalletServicesPlugin;
94+
await walletPlugin.showCheckout();
95+
};
96+
const showWalletConnectScanner = async () => {
97+
const walletPlugin = web3Auth.value?.getPlugin(WALLET_PLUGINS.WALLET_SERVICES) as WalletServicesPlugin;
98+
await walletPlugin.showWalletConnectScanner();
99+
};
100+
const onWalletSignPersonalMessage = async () => {
101+
const walletPlugin = web3Auth.value?.getPlugin(WALLET_PLUGINS.WALLET_SERVICES) as WalletServicesPlugin;
102+
await walletSignPersonalMessage(walletPlugin.wsEmbedInstance.provider, printToConsole);
103+
};
104+
const onWalletSignTypedData_v4 = async () => {
105+
const walletPlugin = web3Auth.value?.getPlugin(WALLET_PLUGINS.WALLET_SERVICES) as WalletServicesPlugin;
106+
await walletSignTypedMessage(walletPlugin.wsEmbedInstance.provider, printToConsole);
107+
};
108+
const onWalletSendEth = async () => {
109+
const walletPlugin = web3Auth.value?.getPlugin(WALLET_PLUGINS.WALLET_SERVICES) as WalletServicesPlugin;
110+
await walletSendEth(walletPlugin.wsEmbedInstance.provider, printToConsole);
111+
};
112+
113+
// Ethereum Provider
94114
const onGetUserInfo = async () => {
95115
printToConsole("User Info", userInfo.value);
96116
};
@@ -206,6 +226,13 @@ const onSignPersonalMsg = async () => {
206226
<Button block size="xs" pill class="mb-2" @click="showCheckout">
207227
{{ $t("app.buttons.btnShowCheckout") }}
208228
</Button>
229+
<Button block size="xs" pill class="mb-2" @click="onWalletSignPersonalMessage">
230+
{{ t("app.buttons.btnSignPersonalMsg") }}
231+
</Button>
232+
<Button block size="xs" pill class="mb-2" @click="onWalletSignTypedData_v4">
233+
{{ t("app.buttons.btnSignTypedData_v4") }}
234+
</Button>
235+
<Button block size="xs" pill class="mb-2" @click="onWalletSendEth">{{ t("app.buttons.btnSendEth") }}</Button>
209236
</Card>
210237
<Card v-if="isDisplay('ethServices')" class="px-4 py-4 gap-4 !h-auto lg:!h-[calc(100dvh_-_240px)]" :shadow="false">
211238
<div class="mb-2 text-xl font-bold leading-tight text-left">Sample Transaction</div>

demo/vue-app-new/src/components/AppSettings.vue

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,15 @@ import { ADAPTER_STATUS, CHAIN_NAMESPACES, ChainNamespaceType, log } from "@web3
44
import { useWeb3Auth } from "@web3auth/modal-vue-composables";
55
import { computed, InputHTMLAttributes, ref } from "vue";
66
7-
import { chainConfigs, chainNamespaceOptions, languageOptions, loginProviderOptions, networkOptions, SmartAccountOptions } from "../config";
7+
import {
8+
chainConfigs,
9+
chainNamespaceOptions,
10+
confirmationStrategyOptions,
11+
languageOptions,
12+
loginProviderOptions,
13+
networkOptions,
14+
SmartAccountOptions,
15+
} from "../config";
816
import { formDataStore } from "../store/form";
917
1018
const formData = formDataStore;
@@ -350,6 +358,15 @@ const onChainNamespaceChange = (value: string) => {
350358
:placeholder="$t('app.walletPlugin.logoDark')"
351359
class="sm:col-span-2"
352360
/>
361+
<Select
362+
v-model="formData.walletPlugin.confirmationStrategy"
363+
data-testid="selectLoginProviders"
364+
:label="$t('app.walletPlugin.confirmationStrategy')"
365+
:aria-label="$t('app.walletPlugin.confirmationStrategy')"
366+
:placeholder="$t('app.walletPlugin.confirmationStrategy')"
367+
:options="confirmationStrategyOptions"
368+
class=""
369+
/>
353370
</Card>
354371
<Card v-if="isActiveTab(4)" class="grid grid-cols-1 gap-2 px-4 py-4" :shadow="false">
355372
<Toggle

demo/vue-app-new/src/config.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { LANGUAGE_TYPE, LANGUAGES, LOGIN_PROVIDER, LOGIN_PROVIDER_TYPE, WhiteLabelData } from "@web3auth/auth";
22
import { CHAIN_NAMESPACES, ChainNamespaceType, CustomChainConfig, WEB3AUTH_NETWORK, WEB3AUTH_NETWORK_TYPE } from "@web3auth/base";
33
import { SignTypedDataMessageV4 } from "@web3auth/ethereum-provider";
4+
import { CONFIRMATION_STRATEGY, CONFIRMATION_STRATEGY_TYPE } from "@web3auth/wallet-services-plugin";
45

56
import { FormConfigSettings } from "./interfaces";
67

@@ -184,6 +185,7 @@ export type FormData = {
184185
enable: boolean;
185186
logoDark: string;
186187
logoLight: string;
188+
confirmationStrategy: Exclude<CONFIRMATION_STRATEGY_TYPE, "popup">;
187189
};
188190
useAccountAbstractionProvider: boolean;
189191
useAAWithExternalWallet?: boolean;
@@ -240,3 +242,9 @@ export const getV4TypedData = (chainId: string): SignTypedDataMessageV4 => ({
240242
contents: "Hello, Bob!",
241243
},
242244
});
245+
246+
export const confirmationStrategyOptions: { name: string; value: string }[] = [
247+
{ name: "Modal", value: CONFIRMATION_STRATEGY.MODAL },
248+
{ name: "Auto Approve", value: CONFIRMATION_STRATEGY.AUTO_APPROVE },
249+
{ name: "Default", value: CONFIRMATION_STRATEGY.DEFAULT },
250+
];
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/* eslint-disable @typescript-eslint/no-explicit-any */
2+
import { log } from "@web3auth/base";
3+
import { verifyMessage as eipVerifyMessage } from "@web3auth/sign-in-with-ethereum";
4+
import { WalletServicesPlugin } from "@web3auth/wallet-services-plugin";
5+
import { BrowserProvider, parseEther } from "ethers";
6+
7+
import { getV4TypedData } from "../config";
8+
9+
export const walletSignPersonalMessage = async (provider: WalletServicesPlugin["provider"], uiConsole: any) => {
10+
try {
11+
const ethProvider = new BrowserProvider(provider);
12+
const signer = await ethProvider.getSigner();
13+
const account = await signer.getAddress();
14+
const from = account;
15+
16+
const originalMessage = "Example `personal_sign` messages";
17+
18+
// Sign the message
19+
const signedMessage = await signer.signMessage(originalMessage);
20+
21+
const valid = await eipVerifyMessage({
22+
provider: ethProvider,
23+
message: originalMessage,
24+
signature: signedMessage,
25+
signer: from,
26+
});
27+
28+
uiConsole(`Success`, { signedMessage, verify: valid });
29+
} catch (error) {
30+
log.error("Error", error);
31+
uiConsole("Error", error instanceof Error ? error.message : error);
32+
}
33+
};
34+
35+
export const walletSignTypedMessage = async (provider: WalletServicesPlugin["provider"], uiConsole: any) => {
36+
try {
37+
const ethProvider = new BrowserProvider(provider);
38+
const signer = await ethProvider.getSigner();
39+
const account = await signer.getAddress();
40+
const from = account;
41+
const typedData = getV4TypedData(provider.chainId);
42+
43+
const signedMessage = await signer.signTypedData(typedData.domain, typedData.types, typedData.message);
44+
45+
const valid = await eipVerifyMessage({
46+
provider: ethProvider,
47+
typedData,
48+
signature: signedMessage,
49+
signer: from,
50+
});
51+
52+
uiConsole(`Success`, { signedMessage, verify: valid });
53+
} catch (error) {
54+
log.error("Error", error);
55+
uiConsole("Error", error instanceof Error ? error.message : error);
56+
}
57+
};
58+
59+
export const walletSendEth = async (provider: WalletServicesPlugin["provider"], uiConsole: any) => {
60+
try {
61+
const ethProvider = new BrowserProvider(provider);
62+
const signer = await ethProvider.getSigner();
63+
const account = await signer.getAddress();
64+
const txRes = await signer.sendTransaction({
65+
from: account,
66+
to: account,
67+
value: parseEther("0.01"),
68+
});
69+
// check for big int before logging to not break the stringify
70+
uiConsole("txRes", txRes.toJSON());
71+
} catch (error) {
72+
log.info("error", error);
73+
uiConsole("error", error instanceof Error ? error.message : error);
74+
}
75+
};
76+
77+
export const walletSignTransaction = async (provider: WalletServicesPlugin["provider"], uiConsole: any) => {
78+
try {
79+
const ethProvider = new BrowserProvider(provider);
80+
const accounts = await provider.request({ method: "eth_accounts" });
81+
const smartAccountAddress = accounts[0];
82+
const signer = await ethProvider.getSigner(smartAccountAddress);
83+
const account = await signer.getAddress();
84+
// only supported with social logins (openlogin adapter)
85+
const serializedTx = await signer.signTransaction({
86+
from: account,
87+
to: account,
88+
value: parseEther("0.01"),
89+
});
90+
91+
uiConsole("serialized user operation", serializedTx);
92+
} catch (error) {
93+
log.info("error", error);
94+
uiConsole("error", error instanceof Error ? error.message : error);
95+
}
96+
};

demo/vue-app-new/src/store/form.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export const formDataStore = reactive<FormData>({
2121
enable: false,
2222
logoLight: "",
2323
logoDark: "",
24+
confirmationStrategy: "default",
2425
},
2526
useAccountAbstractionProvider: false,
2627
useAAWithExternalWallet: true,

demo/vue-app-new/src/translations/en.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
"walletPlugin": {
1515
"title": "Wallet Service Plugin",
1616
"logoLight": "Logo Light",
17-
"logoDark": "Logo Dark"
17+
"logoDark": "Logo Dark",
18+
"confirmationStrategy": "Confirmation Strategy"
1819
},
1920
"accountAbstractionProvider": {
2021
"title": "Account Abstraction Provider",
@@ -49,7 +50,6 @@
4950
"sessionTime": "Session Time"
5051
},
5152
"chainNamespace": "Chain namespace",
52-
5353
"w3aStatus": "Web3Auth status ::::: {status}",
5454
"isConnected": "Is connected ::::: {isConnected}",
5555
"isInitialized": "Is initialized ::::: {isInitialized}",

package-lock.json

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

0 commit comments

Comments
 (0)