Make wallet disconnect not hang

AppKit's modal.disconnect() can stall on the WalletConnect relay (mobile),
leaving the Disconnect button spinning forever ("just loads and says
disconnect") and never reaching the reload. Race the disconnect against a
1.2s timeout, and fire-and-forget from the button with a guaranteed reload
that drops in-memory wallet state so the picker returns.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-09-08 13:57:35 -05:00
parent 11011c6c51
commit 85532155a6
3 changed files with 10 additions and 7 deletions
+6 -5
View File
@@ -1429,11 +1429,12 @@
IAP.status('Faucet opened in a new tab. Choose Polygon Amoy, paste your address, and request test POL.', 'ok');
}));
if ($('wcDisconnect')) $('wcDisconnect').addEventListener('click', busy($('wcDisconnect'), async () => {
try { await IAPWallet.disconnect(); } catch (e) {}
$('wcDisconnectInfo').textContent = 'Disconnected. Reloading so you can pick a different wallet…';
IAP.status('Wallet disconnected. Reloading…', 'ok');
// reload to drop any in-memory WalletConnect state so the picker reappears
setTimeout(() => location.reload(), 700);
// fire-and-forget: don't gate the reload on disconnect resolving (it can
// stall). The reload drops all in-memory wallet state and the picker returns.
IAPWallet.disconnect().catch(() => {});
$('wcDisconnectInfo').textContent = 'Disconnecting — reloading so you can pick a different wallet…';
IAP.status('Disconnecting — reloading…', 'ok');
setTimeout(() => location.reload(), 900);
}));
$('activateBtn').addEventListener('click', busy($('activateBtn'), async () => {
const me = await (await fetch('/api/me')).json();
+3 -1
View File
@@ -186,7 +186,9 @@ window.IAPWallet = (function () {
}
async function disconnect() {
try { if (modal && modal.disconnect) await modal.disconnect(); } catch (e) {}
// AppKit's disconnect can hang on the WalletConnect relay (esp. mobile) —
// never block on it, so the UI can't get stuck "disconnecting".
try { if (modal && modal.disconnect) await Promise.race([modal.disconnect(), new Promise(r => setTimeout(r, 1200))]); } catch (e) {}
provider = null;
try { Object.keys(localStorage).forEach(k => { if (/wc@2|walletconnect|w3m|wcm|reown|wagmi|appkit/i.test(k)) localStorage.removeItem(k); }); } catch (e) {}
}
+1 -1
View File
@@ -696,7 +696,7 @@
</div>
<script src="/assets/common.js?v=20260908c"></script>
<script src="/assets/wallet.js?v=20260908r"></script>
<script src="/assets/my.js?v=20260908s"></script>
<script src="/assets/my.js?v=20260908t"></script>
<script src="/assets/chat.js?v=20260907l"></script>
</body>
</html>