## Environment
- `@web3auth/modal` v10.13.1 (UMD via unpkg)
- `web3AuthNetwork`: `sapphire_devnet`
- Browser: Chrome (latest)
- Platform: Web (vanilla JS, no React)
## Problem
After a user logs in with one provider (e.g., Google), logs out, and opens the login popup again, `connect()` either:
1. Auto-connects to the previously used provider without showing the modal, OR
2. Shows the modal but auto-connects before the user clicks anything, OR
3. Shows the modal, user clicks a **different** provider (e.g., Twitter), but the SDK connects with the **previous** provider (Google)
The user cannot switch between providers without manually clearing site data for `wallet.web3auth.io` in browser settings.
## Root cause identified
The iframe at `wallet.web3auth.io/v5/frame` maintains its own cross-origin session/OAuth token cache. This cache persists independently of the parent page’s `localStorage`, `sessionStorage`, and `IndexedDB`. After logout, the SDK reports `connected: false`, but the iframe still holds cached OAuth tokens. When `connect()` or `connectTo()` is called, the iframe auto-reconnects using those cached tokens, ignoring the requested provider.
## Why `logout({ cleanup: true })` doesn’t fix it
`logout({ cleanup: true })` requires `connected === true` to send a cleanup message to the iframe. But after a session expires (or `localStorage` is cleared), `init()` reports `connected: false`, so `logout()` cannot be called. This creates a deadlock:
- Can’t `logout()` because not connected
- Can’t `connect()` fresh because iframe auto-reconnects
- Can’t access iframe storage because it’s cross-origin
## Diagnostic evidence
After `init()`, `localStorage` state shows:
```json
{
“connectedConnectorName”: null,
“cachedConnector”: null,
“currentChainId”: “0xaa36a7”,
“idToken”: null
}
```
SDK state: `connected: false`, `status: “ready”`
Yet `connect()` still auto-connects to the previous provider.
## What we tried (none worked)
1. `logout({ cleanup: true })` — SDK never reaches `connected: true` so this never runs
2. Clearing all `localStorage` keys matching `Web3Auth|torus|openlogin|plink|w3a` before and after `init()`
3. Deleting IndexedDB databases (`torus_default`, `openlogin_store`, `web3auth_store`, `plink_store`, `w3a_default`)
4. `sessionTime: 1` — iframe still caches OAuth tokens independently
5. `storageType: ‘session’` — iframe cache is unaffected
6. Two-phase init: first instance for `logout({ cleanup: true })`, fresh instance for `connect()` — first instance also sees `connected: false`
7. Polling `web3auth.connected` for 3 seconds after `init()` to catch async iframe reconnection — stays `false`
8. `connectTo(‘auth’, { authConnection: ‘google’ })` to explicitly specify provider — iframe ignores the `authConnection` parameter and returns the cached provider’s session
## Console logs
```
[W3A] init done: status=ready, connected=false
```
When `connect()` is called after the above, the modal either doesn’t appear (auto-connects silently) or appears and auto-connects before user interaction. If the previous session was with Google and user selects Twitter:
```
[web3auth-popup] userInfo for auth: {typeOfLogin: “google”, verifier: “…”, aggregateVerifier: “…”, hasIdToken: true}
```
When `connectTo()` is attempted while the iframe has auto-reconnected:
```
Uncaught (in promise) WalletLoginError: Failed to connect with wallet. Already connected
at fromCode (modal.umd.min.js:2)
at connectionError (modal.umd.min.js:2)
at checkConnectionRequirements (modal.umd.min.js:2)
at connect (modal.umd.min.js:2)
at connectTo (modal.umd.min.js:2)
```
Failed analytics fetch (non-blocking, but present on every load):
```
modal.umd.min.js:2 Failed to fetch
modal.umd.min.js:2 Error: Failed to fetch
at s (modal.umd.min.js:2:3210228)
at d.error (modal.umd.min.js:2:3210868)
'Failed to initialize Analytics'
```
## Package details
| Package | Version | Source |
|---------|---------|--------|
| `@web3auth/modal` | 10.13.1 | `https://unpkg.com/@web3auth/modal@10.13.1/dist/modal.umd.min.js\` |
| `web3` | 1.10.0 | `https://cdn.jsdelivr.net/npm/web3@1.10.0/dist/web3.min.js\` |
No other Web3Auth packages are used. The integration is vanilla JavaScript (no React, no bundler) loading the UMD build via `` tags.
## Minimal reproduction code
```javascript
const web3auth = new Web3Auth({
clientId: ‘YOUR_CLIENT_ID’,
web3AuthNetwork: ‘sapphire_devnet’,
chainConfig: {
chainNamespace: ‘eip155’,
chainId: ‘0x1’,
rpcTarget: ‘https://rpc.ankr.com/eth’,
},
});
await web3auth.init();
// connected is false, but iframe has cached session
const provider = await web3auth.connect();
// Auto-connects to previously cached provider without showing modal
// OR shows modal but ignores user’s provider selection
const userInfo = await web3auth.getUserInfo();
// Returns previous provider’s identity, not the one the user selected
```
## Steps to reproduce
1. Call `init()` + `connect()` — log in with Google
2. Call `logout({ cleanup: true })`
3. Call `init()` + `connect()` again — expect modal to show and let user pick a different provider
4. **Actual:** Auto-connects to Google without showing modal, or shows modal but still connects as Google regardless of selection
## Expected behavior
After `logout({ cleanup: true })`, the iframe’s cached OAuth session should be fully cleared so that the next `connect()` shows a fresh modal and honors the user’s provider selection.
## Question
Is there a way to force-clear the `wallet.web3auth.io` iframe’s cached session from the parent page? Or a constructor/init parameter that prevents the iframe from auto-reconnecting with cached OAuth tokens?