Skip to content

Commit 8172ce1

Browse files
committed
feat: improve keystore connect dialog (#1587)
* fix: resolve missing dependencies issue, set exact=true in bunfig.toml * feat: set up the dialog components for keystore * feat: add tabs from shadcn/ui, improve dialog footer layout * feat: restore and refactor some of the keystore connect implementation * feat: add shadcn/ui components for implementing rich forms * feat: move keystore connection state outside of swapkit context, use react-hook-form for WalletKeystoreConnectDialog * feat: add loading states, move file input onChange handler outside of jsx * chore: reorder imports * feat: show new keystore connect dialog on keystore click * chore: remove old keystore dialog, remove dialog components outside of the scope * chore: update bun.lock * feat: tweak dialog styles to handle edge cases * feat: add missing variables, handle styling edge cases
1 parent 42a0f64 commit 8172ce1

File tree

18 files changed

+624
-90
lines changed

18 files changed

+624
-90
lines changed

bun.lock

Lines changed: 73 additions & 13 deletions
Large diffs are not rendered by default.

packages/helpers/package.json

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,16 @@
66
"@swapkit/tokens": "workspace:*",
77
"@swapkit/types": "workspace:*",
88
"ethers": "^6.14.0",
9-
"ts-pattern": "^5.9.0",
9+
"ts-pattern": "5.9.0",
1010
"zod": "3.25.74",
11-
"zustand": "^5.0.0"
11+
"zustand": "5.0.8"
1212
},
1313
"description": "SwapKit - Helpers",
1414
"devDependencies": {
1515
"@near-js/providers": "2.5.0",
1616
"@swapkit/toolboxes": "workspace:*",
1717
"ethers": "6.15.0",
18-
"tronweb": "6.1.0",
19-
"ts-pattern": "5.9.0",
20-
"zod": "3.25.74",
21-
"zustand": "5.0.8"
18+
"tronweb": "6.1.0"
2219
},
2320
"exports": {
2421
".": {

packages/ui/package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"author": "swapkit-oss",
33
"dependencies": {
4+
"@hookform/resolvers": "5.2.2",
45
"@radix-ui/react-accordion": "1.2.12",
56
"@radix-ui/react-alert-dialog": "1.1.15",
67
"@radix-ui/react-checkbox": "1.3.3",
@@ -23,15 +24,16 @@
2324
"clsx": "2.1.1",
2425
"lucide-react": "0.552.0",
2526
"react": "19.1.1",
27+
"react-hook-form": "7.65.0",
2628
"sonner": "2.0.7",
2729
"tailwind-merge": "3.3.1",
2830
"tailwindcss": "3.4.18",
2931
"tailwindcss-animate": "1.0.7",
30-
"ts-pattern": "^5.9.0",
31-
"zustand": "^5.0.0"
32+
"ts-pattern": "5.9.0",
33+
"zod": "3.25.74",
34+
"zustand": "5.0.8"
3235
},
3336
"description": "SwapKit - UI",
34-
"devDependencies": { "ts-pattern": "5.9.0", "zustand": "5.0.8" },
3537
"exports": {
3638
".": {
3739
"bun": "./src/index.ts",

packages/ui/src/react/components/chain-icon.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export function ChainIcon({ chain, className }: ChainIconProps) {
1616

1717
if (!iconUrl) {
1818
return (
19-
<div className={cn("flex items-center justify-center rounded-full bg-accent font-medium text-xs", className)}>
19+
<div className={cn("flex items-center justify-center rounded-full bg-card font-medium text-xs", className)}>
2020
{chain?.slice(0, 2)}
2121
</div>
2222
);

packages/ui/src/react/components/composable/swap-asset-select.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ export function SwapAssetSelect({
136136
</div>
137137
</div>
138138

139-
<DialogFooter className="mt-2 flex max-h-[clamp(16rem,50svh,32rem)] flex-col">
139+
<DialogFooter className="mt-2 max-h-[clamp(16rem,50svh,32rem)] overflow-y-auto overflow-x-hidden">
140140
{match({ assets, isWalletConnected })
141141
.with({ isWalletConnected: false }, () => (
142142
<div className="flex h-40 flex-col items-center justify-center gap-1">
@@ -158,7 +158,7 @@ export function SwapAssetSelect({
158158
),
159159
)
160160
.otherwise(() => (
161-
<div className="-mx-6 flex flex-col overflow-y-auto overflow-x-hidden px-6">
161+
<div className="flex w-auto flex-1 flex-col">
162162
{assets?.slice(0, 100)?.map((asset) => {
163163
const assetIdentifier = asset.toString();
164164

packages/ui/src/react/components/dialogs/wallet-connect-dialog.tsx

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ import { SearchIcon, WalletMinimalIcon } from "lucide-react";
77
import { useCallback, useMemo, useState } from "react";
88
import { toast } from "sonner";
99
import { match, P } from "ts-pattern";
10-
import { useModal } from "../../hooks/use-modal";
10+
import { showModal, useModal } from "../../hooks/use-modal";
1111
import { useSwapKit } from "../../swapkit-context";
1212
import { Button } from "../ui/button";
1313
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "../ui/dialog";
1414
import { Input } from "../ui/input";
1515
import { SWAPKIT_WIDGET_TOASTER_ID } from "../ui/sonner";
1616
import { WalletIcon } from "../wallet-icon";
17+
import { WalletKeystoreConnectDialog } from "./wallet-keystore-connect-dialog";
1718

1819
const WALLET_GROUPS = {
1920
"Browser Extensions": [
@@ -190,7 +191,7 @@ const FEATURED_WALLETS = [
190191
WalletOption.METAMASK,
191192
WalletOption.CTRL,
192193
WalletOption.COINBASE_WEB,
193-
WalletOption.PHANTOM,
194+
WalletOption.KEYSTORE,
194195
WalletOption.LEDGER,
195196
WalletOption.TREZOR,
196197
WalletOption.BRAVE,
@@ -200,7 +201,6 @@ const FEATURED_WALLETS = [
200201
export function WalletConnectDialog() {
201202
const modal = useModal();
202203
const [isShowingAllWallets, setIsShowingAllWallets] = useState(false);
203-
204204
const [searchQuery, setSearchQuery] = useState("");
205205

206206
const filteredWalletGroups = useMemo(() => {
@@ -292,11 +292,31 @@ function WalletConnectButton({ wallet }: { wallet: WalletOption }) {
292292
const { connectWallet, isConnectingWallet, walletType } = useSwapKit();
293293
const modal = useModal();
294294

295-
const handleButtonClick = useCallback(async () => {
295+
const handleWalletClick = useCallback(async () => {
296296
try {
297-
await connectWallet(wallet, [Chain.Cosmos, Chain.Maya, Chain.THORChain, Chain.Kujira] as Chain[]);
297+
const chainsForWallet = availableChainsByWallet?.[wallet] as Chain[];
298+
299+
if (!chainsForWallet || chainsForWallet?.length === 0) {
300+
toast.error("This wallet does not support any chains", {
301+
description: "Please try a different wallet.",
302+
toasterId: SWAPKIT_WIDGET_TOASTER_ID,
303+
});
304+
return;
305+
}
306+
307+
await match(wallet)
308+
.with(WalletOption.KEYSTORE, async () => {
309+
const { confirmed } = await showModal(<WalletKeystoreConnectDialog />);
310+
311+
if (!confirmed) return;
312+
313+
modal.resolve({ confirmed: true, data: wallet });
314+
})
315+
.otherwise(async () => {
316+
await connectWallet(wallet, chainsForWallet);
298317

299-
modal.resolve({ confirmed: true, data: wallet });
318+
modal.resolve({ confirmed: true, data: wallet });
319+
});
300320
} catch {
301321
toast.error("Failed to connect your wallet", {
302322
description: "Make sure your wallet is connected and accessible by the browser.",
@@ -315,7 +335,7 @@ function WalletConnectButton({ wallet }: { wallet: WalletOption }) {
315335
className="flex aspect-[1.525/1] h-full w-full flex-col items-center justify-center gap-1"
316336
isLoading={isConnectingWallet && walletType === wallet}
317337
key={`wallet-connect-button-${wallet}`}
318-
onClick={handleButtonClick}>
338+
onClick={handleWalletClick}>
319339
<WalletIcon className="size-5" wallet={wallet} />
320340

321341
<span className="text-foreground text-sm">{walletName}</span>

0 commit comments

Comments
 (0)