Skip to content

Commit

Permalink
fix(unisat): wait for extension to load (#174)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nanosync authored Nov 29, 2023
1 parent 33eae8b commit 6957b57
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 2 deletions.
13 changes: 11 additions & 2 deletions packages/ord-connect/src/components/SelectWalletModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import CloseModalIcon from "../../assets/close-modal.svg";
import UnisatWalletIcon from "../../assets/unisat-wallet.svg";
import XverseWalletIcon from "../../assets/xverse-wallet.svg";
import { useOrdContext, Wallet } from "../../providers/OrdContext";
import { isMobileDevice } from "../../utils/mobile-detector.ts";
import { isMobileDevice } from "../../utils/mobile-detector";
import { waitForUnisatExtensionReady } from "../../utils/unisat";

import { WalletButton } from "./WalletButton";

Expand Down Expand Up @@ -153,7 +154,15 @@ export function SelectWalletModal({
// Reconnect address change listener if there there is already a connected wallet
useEffect(() => {
if (wallet === Wallet.UNISAT && address && publicKey && format) {
onConnectUnisatWallet(true);
const connectToUnisatWalletOnLoad = async () => {
const isUnisatExtensionReady = await waitForUnisatExtensionReady();
if (!isUnisatExtensionReady) {
disconnectWallet();
return;
}
onConnectUnisatWallet(true);
};
connectToUnisatWalletOnLoad();
}
}, []);

Check warning on line 167 in packages/ord-connect/src/components/SelectWalletModal/index.tsx

View workflow job for this annotation

GitHub Actions / Build (Apps & Packages)

React Hook useEffect has missing dependencies: 'address', 'disconnectWallet', 'format', 'onConnectUnisatWallet', 'publicKey', and 'wallet'. Either include them or remove the dependency array

Check warning on line 167 in packages/ord-connect/src/components/SelectWalletModal/index.tsx

View workflow job for this annotation

GitHub Actions / Lint - Typescript and ESLint

React Hook useEffect has missing dependencies: 'address', 'disconnectWallet', 'format', 'onConnectUnisatWallet', 'publicKey', and 'wallet'. Either include them or remove the dependency array

Check warning on line 167 in packages/ord-connect/src/components/SelectWalletModal/index.tsx

View workflow job for this annotation

GitHub Actions / NPM

React Hook useEffect has missing dependencies: 'address', 'disconnectWallet', 'format', 'onConnectUnisatWallet', 'publicKey', and 'wallet'. Either include them or remove the dependency array

Expand Down
1 change: 1 addition & 0 deletions packages/ord-connect/src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ type Unisat = {
getNetwork: () => Promise<UnisatNetwork>;
switchNetwork: (targetNetwork: UnisatNetwork) => Promise<void>;
requestAccounts: () => Promise<string[]>;
getAccounts: () => Promise<string[]>;
getPublicKey: () => Promise<string>;
signPsbt: (hex: string) => Promise<string>;
signMessage: (message: string) => Promise<string>;
Expand Down
32 changes: 32 additions & 0 deletions packages/ord-connect/src/utils/unisat.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Continuously checks if the unisat extension and all related unisat APIs are ready, timing out after 2 seconds.
*
* @returns true if extension is ready, false otherwise
*/
export async function waitForUnisatExtensionReady() {
let attempts = 0;
const MAX_ATTEMPTS = 20;

// Wait for extension to be loaded. On average, it takes 1-2 attempts. At maximum, timeout after two seconds.
while (attempts < MAX_ATTEMPTS) {
if (typeof window !== "undefined" && window.unisat) {
try {
// eslint-disable-next-line no-await-in-loop
const accounts = await window.unisat.getAccounts();
// Accounts may be empty even though extension is loaded - we need to wait until this API is ready.
return !!accounts && accounts.length > 0;
} catch (_) {
// If we reach here, getAccounts never existed. This should never happen.
break;
}
}

attempts += 1;
// eslint-disable-next-line no-await-in-loop
await new Promise<void>((resolve) => {
setTimeout(resolve, 100);
});
}

return false;
}

0 comments on commit 6957b57

Please sign in to comment.