Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ledger): improve ledger connect flow #44

Merged
merged 16 commits into from
Mar 7, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion components/screens/AddWallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export default function AddWallet() {
<button
className="flex w-full items-center justify-between rounded-xl border border-daintree-700 bg-[#1E343D] p-5 hover:border-white"
onClick={() => {
browser.tabs.create({ url: "/popup.html#/import-ledger-start" });
browser.tabs.create({ url: "/popup.html#/import-ledger" });
}}
>
<span className="text-base">Import with Ledger</span>
Expand Down
46 changes: 0 additions & 46 deletions components/screens/full-pages/ledger/ImportLedgerStart.tsx

This file was deleted.

137 changes: 70 additions & 67 deletions components/screens/full-pages/ledger/LedgerConnectForImport.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import useLedgerTransport from "@/hooks/useLedgerTransport";
import { useNavigate, useSearchParams } from "react-router-dom";
import { useEffect, useRef } from "react";

Check warning on line 3 in components/screens/full-pages/ledger/LedgerConnectForImport.tsx

View workflow job for this annotation

GitHub Actions / submit

'useRef' is defined but never used
import Header from "@/components/GeneralHeader";
import { twMerge } from "tailwind-merge";
import ledgerConnectingImage from "@/assets/images/ledger-connecting.png";
Expand All @@ -10,9 +10,8 @@
const [searchParams] = useSearchParams();
const navigate = useNavigate();
const redirect = searchParams.get("redirect");
const calledConnectOnce = useRef(false);
const callCheckNeedRetryOnce = useRef(false);
const [showRetry, setShowRetry] = useState(false);
const [showConnect, setShowConnect] = useState(true);
const [isPreviousConnected, setIsPreviousConnected] = useState(false);

const connectDevice = async () => {
if (isConnecting) {
Expand All @@ -21,28 +20,23 @@

try {
await connect();
} catch (error) {

Check warning on line 23 in components/screens/full-pages/ledger/LedgerConnectForImport.tsx

View workflow job for this annotation

GitHub Actions / submit

'error' is defined but never used
navigate("/ledger-connect-for-import-failed?redirect=" + redirect);
}
};

const retry = () => {
setShowRetry(false);
const tryConnect = () => {
setShowConnect(false);
connectDevice();
setTimeout(() => {
setShowRetry(true);
}, 2000); // Show retry button after 2 seconds
setShowConnect(true);
}, 1000); // Show retry button after 1 seconds
};

useEffect(() => {
if (!calledConnectOnce.current) {
calledConnectOnce.current = true;
return;
}

if (!transport) {
connectDevice();
}
return () => {
setIsPreviousConnected(!!transport);
};
}, [transport]);

useEffect(() => {
Expand All @@ -51,77 +45,86 @@
}

if (transport && isAppOpen) {
setTimeout(() => {
navigate(redirect);
}, 1000); // Delay to prevent the page from flickering
return;
}

if (!callCheckNeedRetryOnce.current) {
callCheckNeedRetryOnce.current = true;
navigate(redirect);
return;
}

const timeout = setTimeout(() => {
if (!transport || !isAppOpen) {
setShowRetry(true);
}
}, 500); // Wait for the first attempt to connect
return () => clearTimeout(timeout);
}, [transport, isAppOpen]);

const isLedgerConnected = !!transport || isPreviousConnected;

return (
<div className="flex h-[39rem] w-[41rem] flex-col items-stretch justify-between rounded-3xl bg-icy-blue-950 p-4 pb-6">
<div className="space-y-4">
<Header title="Connect Ledger" showClose={false} showPrevious={false} />

<div className="space-y-2">
<img
alt="ledger connecting"
className="mx-auto"
src={ledgerConnectingImage}
/>
<div className="space-y-2 text-center">
<h1 className="text-xl font-semibold">
Please connect your Ledger device and open Kaspa app
</h1>
<p className="text-sm text-[#7b9aaa]"> Waiting for connection...</p>
<div className="space-y-10">
<div className="space-y-2">
<img
alt="ledger connecting"
className="mx-auto"
src={ledgerConnectingImage}
/>
<div className="space-y-2 text-center">
<h1 className="text-xl font-semibold">
Please connect your Ledger device and open Kaspa app
</h1>
</div>
</div>

<div className="flex justify-center gap-4 text-center text-sm">
<div className="flex items-center gap-1">
<i
className={twMerge(
"hn text-sm",
transport
? "hn-check-circle text-green-200"
: "hn-exclamation-triangle text-red-400",
)}
></i>
Ledger connected
</div>
<div className="flex flex-col items-center justify-center gap-4 text-xs">
<div
className={twMerge(
"flex items-center gap-2 rounded-md p-2",
isLedgerConnected
? "bg-[#115E59] bg-opacity-30 text-[#14B8A6]"
: "bg-[#122932]",
)}
>
{isLedgerConnected ? (
<i className="hn hn-check-circle text-xs text-[#14B8A6]"></i>
) : (
<div
className="border-3 inline-block size-3 animate-spin rounded-full border-current border-t-transparent text-blue-600 dark:text-blue-500"
role="status"
aria-label="loading"
>
<span className="sr-only">Loading...</span>
</div>
)}
Connect Ledger
</div>

<div className="flex items-center gap-1">
<i
className={twMerge(
"hn text-sm",
isAppOpen
? "hn-check-circle text-green-200"
: "hn-exclamation-triangle text-red-400",
)}
></i>
Kaspa app open
</div>
<div
className={twMerge(
"flex items-center gap-2 rounded-md p-2",
isAppOpen
? "bg-[#115E59] bg-opacity-30 text-[#14B8A6]"
: "bg-[#122932]",
)}
>
{isAppOpen ? (
<i className="hn hn-check-circle text-xs text-[#14B8A6]"></i>
) : (
<div
className="border-3 inline-block size-3 animate-spin rounded-full border-current border-t-transparent text-blue-600 dark:text-blue-500"
role="status"
aria-label="loading"
>
<span className="sr-only">Loading...</span>
</div>
)}
Open Kaspa app
</div>
</div>
</div>
</div>

{showRetry && (
{showConnect && (
<button
onClick={retry}
onClick={tryConnect}
className="items-center rounded-full bg-icy-blue-400 p-5 text-base font-semibold hover:bg-icy-blue-600"
>
Retry
Try Connect
</button>
)}
</div>
Expand Down
4 changes: 2 additions & 2 deletions components/screens/full-pages/ledger/LedgerManageAccounts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@
}

return accounts;
} catch (error) {

Check warning on line 47 in components/screens/full-pages/ledger/LedgerManageAccounts.tsx

View workflow job for this annotation

GitHub Actions / submit

'error' is defined but never used
navigate("/ledger-connect-failed");
navigate("/ledger-connect-for-import-failed");
throw new Error(
"Failed to list accounts, please unlock and open Kaspa app and try again",
);
Expand All @@ -56,7 +56,7 @@
useEffect(() => {
if (!transport && !calledOnce.current) {
const currentUrl = window.location.hash.replace("#", "");
navigate("/connect-ledger?redirect=" + currentUrl);
navigate("/ledger-connect-for-import?redirect=" + currentUrl);
}
}, [transport]);

Expand Down
Loading
Loading