1818 </button >
1919 <button
2020 v-if =" !address"
21- title =" Connect with paymaster sponsorship "
21+ title =" Connect with paymaster sponsoring gas (no session) "
2222 class =" bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded mr-4"
2323 @click =" connectWallet('paymaster')"
2424 >
4444 >
4545 <p >Balance: {{ balance ? `${balance.formatted} ${balance.symbol}` : '...' }}</p >
4646 </div >
47+ <div
48+ v-if =" address"
49+ class =" mt-4"
50+ >
51+ <p >Connection Mode: {{ connectionMode }} {{ isPaymasterEnabled ? '(Gas Sponsored ✨)' : '' }}</p >
52+ </div >
4753 <button
4854 v-if =" address"
49- class =" bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded mt-3 mr-4 disabled:bg-slate-300"
55+ :class =" isPaymasterEnabled ? 'bg-green-500 hover:bg-green-700' : 'bg-blue-500 hover:bg-blue-700'"
56+ class =" text-white font-bold py-2 px-4 rounded mt-3 mr-4 disabled:bg-slate-300"
5057 :disabled =" isSendingEth"
5158 @click =" sendTokens()"
5259 >
53- Send 0.1 ETH
60+ Send 0.1 ETH{{ isPaymasterEnabled ? ' (Paymaster)' : '' }}
5461 </button >
5562
5663 <!-- <div
112119</template >
113120
114121<script lang="ts" setup>
115- import { disconnect , getBalance , watchAccount , sendTransaction , createConfig , connect , waitForTransactionReceipt , type GetBalanceReturnType , signTypedData , readContract } from " @wagmi/core" ;
116- import { createWalletClient , createPublicClient , http , parseEther , type Address , type Hash } from " viem" ;
117- import { zksyncSsoConnector } from " zksync-sso-4337/connector" ;
122+ import { disconnect , getBalance , watchAccount , createConfig , connect , waitForTransactionReceipt , type GetBalanceReturnType , signTypedData , readContract , getConnectorClient } from " @wagmi/core" ;
123+ import { createWalletClient , createPublicClient , http , parseEther , toHex , type Address , type Hash } from " viem" ;
124+ import { zksyncSsoConnector , getConnectedSsoSessionClient , isSsoSessionClientConnected } from " zksync-sso-4337/connector" ;
118125import { privateKeyToAccount } from " viem/accounts" ;
119126import { localhost } from " viem/chains" ;
120127import { onMounted } from " vue" ;
@@ -160,7 +167,15 @@ const sessionConfig = {
160167
161168const buildConnector = (mode : " regular" | " session" | " paymaster" | " session-paymaster" ) => {
162169 const baseConfig: Parameters <typeof zksyncSsoConnector >[0 ] = {
163- authServerUrl: " http://localhost:3003/confirm" ,
170+ authServerUrl: " http://localhost:3002/confirm" ,
171+ // Add unique timestamp to ensure each connector is truly fresh
172+ // This prevents Wagmi from reusing cached connector instances
173+ connectorMetadata: {
174+ id: ` zksync-sso-${mode }-${Date .now ()} ` ,
175+ name: " ZKsync" ,
176+ icon: " https://zksync.io/favicon.ico" ,
177+ type: " zksync-sso" ,
178+ },
164179 };
165180
166181 if (mode === " session" || mode === " session-paymaster" ) {
@@ -189,6 +204,8 @@ const wagmiConfig = createConfig({
189204const address = ref <Address | null >(null );
190205const balance = ref <GetBalanceReturnType | null >(null );
191206const errorMessage = ref <string | null >(null );
207+ const connectionMode = ref <string >(" Not connected" );
208+ const isPaymasterEnabled = computed (() => connectionMode .value === " paymaster" || connectionMode .value === " session-paymaster" );
192209const isInitializing = ref (true );
193210
194211// Ensure fresh, unauthenticated state on page load so the connect buttons render
@@ -270,6 +287,9 @@ const connectWallet = async (mode: "regular" | "session" | "paymaster" | "sessio
270287 return ;
271288 }
272289
290+ // Track which mode was used for connection
291+ connectionMode .value = mode ;
292+
273293 connect (wagmiConfig , {
274294 connector ,
275295 chainId: chain .id ,
@@ -283,7 +303,16 @@ const connectWallet = async (mode: "regular" | "session" | "paymaster" | "sessio
283303
284304const disconnectWallet = async () => {
285305 errorMessage .value = " " ;
286- await disconnect (wagmiConfig );
306+ try {
307+ await disconnect (wagmiConfig );
308+ } catch (error ) {
309+ // If connector doesn't have disconnect method, manually reset state
310+ // eslint-disable-next-line no-console
311+ console .warn (" Disconnect failed, manually resetting state:" , error );
312+ address .value = null ;
313+ balance .value = null ;
314+ }
315+ connectionMode .value = " Not connected" ;
287316};
288317
289318/* Send ETH */
@@ -295,18 +324,29 @@ const sendTokens = async () => {
295324 errorMessage .value = " " ;
296325 isSendingEth .value = true ;
297326 try {
298- let transactionHash;
299-
300- transactionHash = await sendTransaction (wagmiConfig , {
301- to: testTransferTarget ,
302- value: parseEther (" 0.1" ),
303- });
304-
305- // FIXME: When not using sessions, sendTransaction returns a map and not a string
306- // eslint-disable-next-line @typescript-eslint/no-explicit-any
307- if ((transactionHash as any ).value !== undefined ) {
308- // eslint-disable-next-line @typescript-eslint/no-explicit-any
309- transactionHash = (transactionHash as any ).value ;
327+ let transactionHash: Hash ;
328+
329+ // Check if we're using a session client
330+ const isSession = await isSsoSessionClientConnected (wagmiConfig );
331+
332+ if (isSession ) {
333+ // Use session client's sendTransaction which routes through bundler
334+ const sessionClient = await getConnectedSsoSessionClient (wagmiConfig );
335+ transactionHash = await sessionClient .sendTransaction ({
336+ to: testTransferTarget ,
337+ value: parseEther (" 0.1" ),
338+ });
339+ } else {
340+ // Use regular connector client for non-session (passkey) transactions
341+ const connectorClient = await getConnectorClient (wagmiConfig );
342+ transactionHash = await connectorClient .request ({
343+ method: " eth_sendTransaction" ,
344+ params: [{
345+ from: address .value ,
346+ to: testTransferTarget ,
347+ value: toHex (parseEther (" 0.1" )),
348+ }],
349+ }) as Hash ;
310350 }
311351
312352 const receipt = await waitForTransactionReceipt (wagmiConfig , {
0 commit comments