diff --git a/app/globals.css b/app/globals.css index e489c6f4..39abb59a 100644 --- a/app/globals.css +++ b/app/globals.css @@ -94,3 +94,20 @@ textarea { html { scroll-behavior: smooth; } + +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + } + + body::before, + body::after { + animation: none !important; + transition: none !important; + } +} + diff --git a/features/freighter-connect/lib/freighter.ts b/features/freighter-connect/lib/freighter.ts index 63fe8751..491479b3 100644 --- a/features/freighter-connect/lib/freighter.ts +++ b/features/freighter-connect/lib/freighter.ts @@ -6,6 +6,18 @@ import type { WalletSnapshot } from "@/features/freighter-connect/types"; +const CONNECTION_TIMEOUT_MS = 15_000; + +function withTimeout(promise: Promise, ms = CONNECTION_TIMEOUT_MS): Promise { + let timer: ReturnType; + const timeoutPromise = new Promise((_, reject) => { + timer = setTimeout(() => reject(new Error("TIMEOUT")), ms); + }); + return Promise.race([promise, timeoutPromise]).finally(() => { + clearTimeout(timer); + }); +} + /** * Reads the wallet's current state. * @@ -20,15 +32,15 @@ export async function readWallet( if (!api.ok) return api; try { - const allowed = (await api.value.isAllowed?.()) ?? false; + const allowed = (await withTimeout(api.value.isAllowed?.() ?? Promise.resolve(false))) ?? false; if (!allowed) { return ok({ installed: true, allowed: false, network: "unknown" }); } const [publicKey, rawNetwork] = await Promise.all([ - api.value.getPublicKey!(), - api.value.getNetwork!() + withTimeout(api.value.getPublicKey!()), + withTimeout(api.value.getNetwork!()) ]); return ok({ @@ -51,7 +63,7 @@ export async function requestAccess( if (!api.ok) return api; try { - await api.value.setAllowed?.(); + await withTimeout(api.value.setAllowed?.() ?? Promise.resolve(false)); } catch { return err("not_allowed"); }