fix(wallet): improve imtoken mobile login fallback
This commit is contained in:
@@ -175,6 +175,28 @@ export function logWalletProviders(): void {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function connectInjectedWallet(
|
||||||
|
kind?: WalletKind,
|
||||||
|
): Promise<string> {
|
||||||
|
/* eslint-disable no-console */
|
||||||
|
console.info("[wallet-login] start injected connect", { kind });
|
||||||
|
logWalletProviders();
|
||||||
|
const ethereum = getInjectedWallet(kind);
|
||||||
|
if (!ethereum) {
|
||||||
|
console.warn("[wallet-login] no injected provider found");
|
||||||
|
throw new Error("No injected wallet found");
|
||||||
|
}
|
||||||
|
|
||||||
|
console.info("[wallet-login] requesting BNB wallet account…");
|
||||||
|
const address = await requestInjectedAddress(ethereum);
|
||||||
|
console.info("[wallet-login] injected account", address);
|
||||||
|
|
||||||
|
console.info("[wallet-login] ensuring BNB Chain (0x38)…");
|
||||||
|
await ensureBnbChain(ethereum);
|
||||||
|
return address;
|
||||||
|
/* eslint-enable no-console */
|
||||||
|
}
|
||||||
|
|
||||||
export async function signInWithInjectedWallet(kind?: WalletKind): Promise<{
|
export async function signInWithInjectedWallet(kind?: WalletKind): Promise<{
|
||||||
token: string;
|
token: string;
|
||||||
wallet: string;
|
wallet: string;
|
||||||
|
|||||||
@@ -2,7 +2,11 @@ import { useCallback, useRef, useState } from "react";
|
|||||||
import { useConnect, useDisconnect } from "wagmi";
|
import { useConnect, useDisconnect } from "wagmi";
|
||||||
import { bsc } from "wagmi/chains";
|
import { bsc } from "wagmi/chains";
|
||||||
import { hasWalletConnectProjectId } from "./RainbowWalletProvider";
|
import { hasWalletConnectProjectId } from "./RainbowWalletProvider";
|
||||||
import type { WalletKind } from "./injected";
|
import {
|
||||||
|
connectInjectedWallet,
|
||||||
|
getInjectedWallet,
|
||||||
|
type WalletKind,
|
||||||
|
} from "./injected";
|
||||||
import { localWalletToken, useWallet } from "./WalletProvider";
|
import { localWalletToken, useWallet } from "./WalletProvider";
|
||||||
|
|
||||||
export type WalletConnectLoginState = "idle" | "connecting" | "signing";
|
export type WalletConnectLoginState = "idle" | "connecting" | "signing";
|
||||||
@@ -15,6 +19,11 @@ function isMobileDevice(): boolean {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function currentUrl(): string {
|
||||||
|
if (typeof window === "undefined") return "https://ark-library.com";
|
||||||
|
return window.location.href;
|
||||||
|
}
|
||||||
|
|
||||||
function walletConnectDeeplink(
|
function walletConnectDeeplink(
|
||||||
kind: WalletKind | undefined,
|
kind: WalletKind | undefined,
|
||||||
uri: string,
|
uri: string,
|
||||||
@@ -31,6 +40,27 @@ function walletConnectDeeplink(
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function inAppBrowserFallback(kind: WalletKind | undefined): string | null {
|
||||||
|
if (kind === "imToken") {
|
||||||
|
return `imtokenv2://navigate/DappView?url=${encodeURIComponent(currentUrl())}`;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function openWalletDeeplink(
|
||||||
|
kind: WalletKind | undefined,
|
||||||
|
deeplink: string,
|
||||||
|
): void {
|
||||||
|
window.location.href = deeplink;
|
||||||
|
const fallback = inAppBrowserFallback(kind);
|
||||||
|
if (!fallback) return;
|
||||||
|
window.setTimeout(() => {
|
||||||
|
if (document.visibilityState === "visible") {
|
||||||
|
window.location.href = fallback;
|
||||||
|
}
|
||||||
|
}, 1500);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MetaMask / imToken QR fallback via RainbowKit + WalletConnect.
|
* MetaMask / imToken QR fallback via RainbowKit + WalletConnect.
|
||||||
*
|
*
|
||||||
@@ -76,11 +106,28 @@ export function useWalletConnectLogin() {
|
|||||||
pendingRef.current = true;
|
pendingRef.current = true;
|
||||||
setState("connecting");
|
setState("connecting");
|
||||||
|
|
||||||
|
if (preferredWallet && getInjectedWallet(preferredWallet)) {
|
||||||
|
try {
|
||||||
|
const injectedAddress = await connectInjectedWallet(preferredWallet);
|
||||||
|
console.info("[wallet-login] injected connected", {
|
||||||
|
preferredWallet,
|
||||||
|
address: injectedAddress,
|
||||||
|
chain: "BNB Chain",
|
||||||
|
chainId: bsc.id,
|
||||||
|
});
|
||||||
|
completeLogin(localWalletToken(injectedAddress), injectedAddress);
|
||||||
|
setState("idle");
|
||||||
|
return;
|
||||||
|
} catch (err) {
|
||||||
|
console.info("[wallet-login] injected connect fallback to wc", {
|
||||||
|
preferredWallet,
|
||||||
|
message: err instanceof Error ? err.message : String(err),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This modal is QR/WalletConnect-only. RainbowKit also exposes wallet-
|
// This modal is QR/WalletConnect-only. RainbowKit also exposes wallet-
|
||||||
// specific injected connectors (for example `tokenPocket`) when an
|
// specific injected connectors (for example `tokenPocket`) when an
|
||||||
// extension is installed; using those here makes the click try the local
|
|
||||||
// browser extension and can fail with "wallet must has at least one
|
|
||||||
// account" before a QR is shown.
|
|
||||||
const connector =
|
const connector =
|
||||||
connectors.find((item) => item.type === "walletConnect") ??
|
connectors.find((item) => item.type === "walletConnect") ??
|
||||||
connectors.find((item) => item.id === "walletConnect");
|
connectors.find((item) => item.id === "walletConnect");
|
||||||
@@ -114,7 +161,7 @@ export function useWalletConnectLogin() {
|
|||||||
if (mode === "qr") setQrUri(message.data);
|
if (mode === "qr") setQrUri(message.data);
|
||||||
const deeplink = walletConnectDeeplink(preferredWallet, message.data);
|
const deeplink = walletConnectDeeplink(preferredWallet, message.data);
|
||||||
if (mode === "deeplink" && deeplink && isMobileDevice()) {
|
if (mode === "deeplink" && deeplink && isMobileDevice()) {
|
||||||
window.location.href = deeplink;
|
openWalletDeeplink(preferredWallet, deeplink);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user