-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathuseIsMiniPay.ts
More file actions
55 lines (51 loc) · 1.95 KB
/
Copy pathuseIsMiniPay.ts
File metadata and controls
55 lines (51 loc) · 1.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
"use client";
import { useEffect, useState } from "react";
/**
* MiniPay injects an EIP-1193 provider flagged with `isMiniPay`.
* Unlike Farcaster's async `sdk.isInMiniApp()`, detection is synchronous off `window.ethereum`.
*/
export function detectMiniPay(): boolean {
if (typeof window === "undefined") return false;
const eth = (window as unknown as { ethereum?: { isMiniPay?: boolean } }).ethereum;
return Boolean(eth?.isMiniPay);
}
/** React hook form. Returns false during SSR/first paint, then resolves on mount. */
export function useIsMiniPay(): boolean {
const [isMiniPay, setIsMiniPay] = useState(false);
useEffect(() => {
setIsMiniPay(detectMiniPay());
}, []);
return isMiniPay;
}
/**
* Three-state host resolution for the provider switch: `null` while resolving,
* then true (MiniPay webview) / false (regular browser). Unlike useIsMiniPay
* (which flips false→true), this never mounts Dynamic prematurely: we poll
* briefly because MiniPay's WKWebView injects `window.ethereum` slightly late.
* If a provider shows up without `isMiniPay`, or ~1.2s pass with none at all,
* we resolve "browser". Worst case (an unusually slow MiniPay injection) the
* Dynamic tree mounts but never connects, and useWalletSession still reaches
* the wallet through the wagmi fallback — degraded, not broken.
*/
export function useMiniPayHost(): boolean | null {
const [host, setHost] = useState<boolean | null>(null);
useEffect(() => {
let stopped = false;
let polls = 0;
let timer: ReturnType<typeof setTimeout> | undefined;
const tick = () => {
if (stopped) return;
const eth = (window as unknown as { ethereum?: { isMiniPay?: boolean } }).ethereum;
if (eth?.isMiniPay) return setHost(true);
if (eth || polls >= 4) return setHost(false);
polls++;
timer = setTimeout(tick, 300);
};
tick();
return () => {
stopped = true;
if (timer) clearTimeout(timer);
};
}, []);
return host;
}