@algobright/solana-connector-kit 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/Avatar.module-P7KEBP7R.module.css +42 -0
  2. package/dist/Button.module-7TPMDOJN.module.css +145 -0
  3. package/dist/Collapsible.module-NXSN3MGI.module.css +24 -0
  4. package/dist/ConnectButton.d.mts +14 -0
  5. package/dist/ConnectButton.d.ts +14 -0
  6. package/dist/ConnectButton.js +1248 -0
  7. package/dist/ConnectButton.js.map +1 -0
  8. package/dist/ConnectButton.mjs +1216 -0
  9. package/dist/ConnectButton.mjs.map +1 -0
  10. package/dist/ConnectButton.module-UWQKSVTP.module.css +8 -0
  11. package/dist/CustomQRCode.module-FOXENMZG.module.css +176 -0
  12. package/dist/Dialog.module-HCRT743N.module.css +136 -0
  13. package/dist/Menu.module-GV627ZLI.module.css +79 -0
  14. package/dist/Spinner.module-G7GUQJZJ.module.css +16 -0
  15. package/dist/WalletDropdown.d.mts +14 -0
  16. package/dist/WalletDropdown.d.ts +14 -0
  17. package/dist/WalletDropdown.js +346 -0
  18. package/dist/WalletDropdown.js.map +1 -0
  19. package/dist/WalletDropdown.mjs +314 -0
  20. package/dist/WalletDropdown.mjs.map +1 -0
  21. package/dist/WalletDropdown.module-342MM7XM.module.css +220 -0
  22. package/dist/WalletModal.d.mts +13 -0
  23. package/dist/WalletModal.d.ts +13 -0
  24. package/dist/WalletModal.js +838 -0
  25. package/dist/WalletModal.js.map +1 -0
  26. package/dist/WalletModal.mjs +806 -0
  27. package/dist/WalletModal.mjs.map +1 -0
  28. package/dist/WalletModal.module-PVV5PRXU.module.css +341 -0
  29. package/dist/index.d.mts +70 -0
  30. package/dist/index.d.ts +70 -0
  31. package/dist/index.js +242 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/index.mjs +222 -0
  34. package/dist/index.mjs.map +1 -0
  35. package/package.json +70 -0
@@ -0,0 +1,806 @@
1
+ "use client";
2
+
3
+ // src/components/WalletModal/WalletModal.tsx
4
+ import { useConnector } from "@solana/connector";
5
+ import { Check, ChevronLeft, Copy, ExternalLink, Wallet as Wallet2, X as X2 } from "lucide-react";
6
+ import { useEffect, useState as useState2, useSyncExternalStore } from "react";
7
+ import styles6 from "./WalletModal.module-PVV5PRXU.module.css";
8
+
9
+ // src/components/shared/Dialog/Dialog.tsx
10
+ import * as React from "react";
11
+ import { Dialog as BaseDialog } from "@base-ui/react/dialog";
12
+ import { X } from "lucide-react";
13
+ import styles from "./Dialog.module-HCRT743N.module.css";
14
+ import clsx from "clsx";
15
+ import { jsx, jsxs } from "react/jsx-runtime";
16
+ var Dialog = BaseDialog.Root;
17
+ var DialogTrigger = BaseDialog.Trigger;
18
+ var DialogPortal = BaseDialog.Portal;
19
+ var DialogClose = BaseDialog.Close;
20
+ var DialogBackdrop = React.forwardRef(
21
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
22
+ BaseDialog.Backdrop,
23
+ {
24
+ ref,
25
+ className: `${styles.backdrop} ${className || ""}`,
26
+ ...props
27
+ }
28
+ )
29
+ );
30
+ DialogBackdrop.displayName = "DialogBackdrop";
31
+ var DialogContent = React.forwardRef(
32
+ ({ className, children, theme, showCloseButton = true, ...props }, ref) => /* @__PURE__ */ jsxs(DialogPortal, { children: [
33
+ /* @__PURE__ */ jsx(DialogBackdrop, { "data-theme": theme }),
34
+ /* @__PURE__ */ jsxs(
35
+ BaseDialog.Popup,
36
+ {
37
+ ref,
38
+ "data-theme": theme,
39
+ className: clsx(styles.content, className),
40
+ ...props,
41
+ children: [
42
+ children,
43
+ showCloseButton && /* @__PURE__ */ jsx(DialogClose, { className: styles.closeButton, children: /* @__PURE__ */ jsx(X, {}) })
44
+ ]
45
+ }
46
+ )
47
+ ] })
48
+ );
49
+ DialogContent.displayName = "DialogContent";
50
+ var DialogHeader = ({ className, ...props }) => /* @__PURE__ */ jsx("div", { className: `${styles.header} ${className || ""}`, ...props });
51
+ DialogHeader.displayName = "DialogHeader";
52
+ var DialogFooter = ({ className, ...props }) => /* @__PURE__ */ jsx("div", { className: `${styles.footer} ${className || ""}`, ...props });
53
+ DialogFooter.displayName = "DialogFooter";
54
+ var DialogTitle = React.forwardRef(
55
+ ({ className, ...props }, ref) => /* @__PURE__ */ jsx(
56
+ BaseDialog.Title,
57
+ {
58
+ ref,
59
+ className: `${styles.title} ${className || ""}`,
60
+ ...props
61
+ }
62
+ )
63
+ );
64
+ DialogTitle.displayName = "DialogTitle";
65
+ var DialogDescription = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
66
+ BaseDialog.Description,
67
+ {
68
+ ref,
69
+ className: `${styles.description} ${className || ""}`,
70
+ ...props
71
+ }
72
+ ));
73
+ DialogDescription.displayName = "DialogDescription";
74
+
75
+ // src/components/shared/Button/Button.tsx
76
+ import * as React2 from "react";
77
+ import { Button as BaseButton } from "@base-ui/react/button";
78
+ import styles2 from "./Button.module-7TPMDOJN.module.css";
79
+ import { jsx as jsx2 } from "react/jsx-runtime";
80
+ var Button = React2.forwardRef(
81
+ ({ className, variant = "default", size = "default", ...props }, ref) => {
82
+ return /* @__PURE__ */ jsx2(
83
+ BaseButton,
84
+ {
85
+ ref,
86
+ className: `${styles2.button} ${className || ""}`,
87
+ "data-variant": variant,
88
+ "data-size": size,
89
+ ...props
90
+ }
91
+ );
92
+ }
93
+ );
94
+ Button.displayName = "Button";
95
+ var Button_default = Button;
96
+
97
+ // src/components/shared/Button/index.ts
98
+ var Button_default2 = Button_default;
99
+
100
+ // src/components/shared/CustomQRCode/CustomQRCode.tsx
101
+ import { useMemo } from "react";
102
+ import QRCodeUtil from "qrcode";
103
+ import styles3 from "./CustomQRCode.module-FOXENMZG.module.css";
104
+ import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
105
+ function generateMatrix(value, errorCorrectionLevel) {
106
+ const arr = Array.prototype.slice.call(QRCodeUtil.create(value, { errorCorrectionLevel }).modules.data, 0);
107
+ const sqrt = Math.sqrt(arr.length);
108
+ return arr.reduce(
109
+ (rows, key, index) => (index % sqrt === 0 ? rows.push([key]) : rows[rows.length - 1].push(key)) && rows,
110
+ []
111
+ );
112
+ }
113
+ function QRCodeSVG({
114
+ value,
115
+ size: sizeProp = 200,
116
+ ecl = "M",
117
+ clearArea = false,
118
+ dotColor = "currentColor",
119
+ backgroundColor = "#ffffff"
120
+ }) {
121
+ const logoSize = clearArea ? 76 : 0;
122
+ const size = sizeProp - 10 * 2;
123
+ const dots = useMemo(() => {
124
+ const dots2 = [];
125
+ const matrix = generateMatrix(value, ecl);
126
+ const cellSize = size / matrix.length;
127
+ const qrList = [
128
+ { x: 0, y: 0 },
129
+ { x: 1, y: 0 },
130
+ { x: 0, y: 1 }
131
+ ];
132
+ qrList.forEach(({ x, y }) => {
133
+ const x1 = (matrix.length - 7) * cellSize * x;
134
+ const y1 = (matrix.length - 7) * cellSize * y;
135
+ for (let i = 0; i < 3; i++) {
136
+ dots2.push(
137
+ /* @__PURE__ */ jsx3(
138
+ "rect",
139
+ {
140
+ fill: i % 2 !== 0 ? backgroundColor : dotColor,
141
+ rx: (i - 2) * -5 + (i === 0 ? 2 : 3),
142
+ ry: (i - 2) * -5 + (i === 0 ? 2 : 3),
143
+ width: cellSize * (7 - i * 2),
144
+ height: cellSize * (7 - i * 2),
145
+ x: x1 + cellSize * i,
146
+ y: y1 + cellSize * i
147
+ },
148
+ `finder-${i}-${x}-${y}`
149
+ )
150
+ );
151
+ }
152
+ });
153
+ const clearArenaSize = Math.floor((logoSize + 25) / cellSize);
154
+ const matrixMiddleStart = matrix.length / 2 - clearArenaSize / 2;
155
+ const matrixMiddleEnd = matrix.length / 2 + clearArenaSize / 2 - 1;
156
+ matrix.forEach((row, i) => {
157
+ row.forEach((_, j) => {
158
+ if (matrix[i][j]) {
159
+ if (!(i < 7 && j < 7 || i > matrix.length - 8 && j < 7 || i < 7 && j > matrix.length - 8)) {
160
+ if (!clearArea || !(i > matrixMiddleStart && i < matrixMiddleEnd && j > matrixMiddleStart && j < matrixMiddleEnd)) {
161
+ dots2.push(
162
+ /* @__PURE__ */ jsx3(
163
+ "circle",
164
+ {
165
+ cx: j * cellSize + cellSize / 2,
166
+ cy: i * cellSize + cellSize / 2,
167
+ fill: dotColor,
168
+ r: cellSize / 3
169
+ },
170
+ `dot-${i}-${j}`
171
+ )
172
+ );
173
+ }
174
+ }
175
+ }
176
+ });
177
+ });
178
+ return dots2;
179
+ }, [value, ecl, size, clearArea, logoSize, dotColor, backgroundColor]);
180
+ return /* @__PURE__ */ jsxs2(
181
+ "svg",
182
+ {
183
+ height: size,
184
+ width: size,
185
+ viewBox: `0 0 ${size} ${size}`,
186
+ className: styles3.svgFull,
187
+ style: { maxWidth: size, maxHeight: size },
188
+ children: [
189
+ /* @__PURE__ */ jsx3("rect", { fill: "transparent", height: size, width: size }),
190
+ dots
191
+ ]
192
+ }
193
+ );
194
+ }
195
+ function ViewfinderFrame({
196
+ size,
197
+ color = "#2D2D2D",
198
+ opacity = 0.01
199
+ }) {
200
+ return /* @__PURE__ */ jsx3(
201
+ "svg",
202
+ {
203
+ width: size,
204
+ height: size,
205
+ viewBox: "0 0 283 283",
206
+ fill: "none",
207
+ xmlns: "http://www.w3.org/2000/svg",
208
+ className: styles3.viewfinder,
209
+ children: /* @__PURE__ */ jsx3(
210
+ "path",
211
+ {
212
+ d: "M3.5 264.06C3.5 272.587 10.4127 279.5 18.9399 279.5H32.8799C33.7083 279.5 34.3799 280.172 34.3799 281V281C34.3799 281.828 33.7083 282.5 32.8799 282.5H17.4399C8.08427 282.5 0.5 274.916 0.5 265.56V250.12C0.5 249.292 1.17157 248.62 2 248.62V248.62C2.82843 248.62 3.5 249.292 3.5 250.12V264.06ZM282.5 266.058C282.5 275.139 275.139 282.5 266.058 282.5H251.116C250.288 282.5 249.616 281.828 249.616 281V281C249.616 280.172 250.288 279.5 251.116 279.5H264.558C272.81 279.5 279.5 272.81 279.5 264.558V250.12C279.5 249.292 280.172 248.62 281 248.62V248.62C281.828 248.62 282.5 249.292 282.5 250.12V266.058ZM34.3799 2C34.3799 2.82843 33.7083 3.5 32.8799 3.5H18.9399C10.4127 3.5 3.5 10.4127 3.5 18.9399V32.8799C3.5 33.7083 2.82843 34.3799 2 34.3799V34.3799C1.17157 34.3799 0.5 33.7083 0.5 32.8799V17.4399C0.5 8.08427 8.08427 0.5 17.4399 0.5H32.8799C33.7083 0.5 34.3799 1.17157 34.3799 2V2ZM282.5 32.8799C282.5 33.7083 281.828 34.3799 281 34.3799V34.3799C280.172 34.3799 279.5 33.7083 279.5 32.8799V18.4419C279.5 10.1897 272.81 3.5 264.558 3.5H251.116C250.288 3.5 249.616 2.82843 249.616 2V2C249.616 1.17157 250.288 0.5 251.116 0.5H266.058C275.139 0.5 282.5 7.86129 282.5 16.9419V32.8799Z",
213
+ fill: color,
214
+ fillOpacity: opacity
215
+ }
216
+ )
217
+ }
218
+ );
219
+ }
220
+ function CustomQRCode({
221
+ value,
222
+ size = 280,
223
+ ecl = "M",
224
+ clearArea = false,
225
+ image,
226
+ imageBackground = "transparent",
227
+ dotColor,
228
+ backgroundColor,
229
+ className,
230
+ style,
231
+ loading = false,
232
+ scanning = true,
233
+ error = false,
234
+ frameColor
235
+ }) {
236
+ const showPlaceholder = loading || !value;
237
+ const resolvedBackground = backgroundColor || "#ffffff";
238
+ const resolvedDotColor = dotColor || "#000000";
239
+ const resolvedFrameColor = error ? "#FF0000" : frameColor || "#2D2D2D";
240
+ const frameOpacity = error ? 0.56 : 0.01;
241
+ return /* @__PURE__ */ jsxs2(
242
+ "div",
243
+ {
244
+ className: `${styles3.container} ${className || ""}`,
245
+ style: {
246
+ width: size,
247
+ height: size,
248
+ ...style
249
+ },
250
+ children: [
251
+ /* @__PURE__ */ jsx3(ViewfinderFrame, { size, color: resolvedFrameColor, opacity: frameOpacity }),
252
+ /* @__PURE__ */ jsxs2(
253
+ "div",
254
+ {
255
+ className: styles3.contentArea,
256
+ style: { background: resolvedBackground },
257
+ "data-error": error,
258
+ children: [
259
+ /* @__PURE__ */ jsx3("div", { className: styles3.glow, "data-error": error }),
260
+ scanning && !showPlaceholder && !error && /* @__PURE__ */ jsx3("div", { className: styles3.shine }),
261
+ /* @__PURE__ */ jsx3("div", { className: styles3.qrWrapper, children: showPlaceholder ? /* @__PURE__ */ jsx3(QRPlaceholder, { size, dotColor: resolvedDotColor, backgroundColor: resolvedBackground }) : /* @__PURE__ */ jsxs2(Fragment, { children: [
262
+ /* @__PURE__ */ jsx3(
263
+ QRCodeSVG,
264
+ {
265
+ value,
266
+ size: size - 40,
267
+ ecl,
268
+ clearArea: clearArea || !!image,
269
+ dotColor: resolvedDotColor,
270
+ backgroundColor: resolvedBackground
271
+ }
272
+ ),
273
+ image && /* @__PURE__ */ jsx3(
274
+ "div",
275
+ {
276
+ className: styles3.logoWrapper,
277
+ style: {
278
+ width: "28%",
279
+ height: "28%",
280
+ background: imageBackground || resolvedBackground
281
+ },
282
+ children: image
283
+ }
284
+ )
285
+ ] }) })
286
+ ]
287
+ }
288
+ )
289
+ ]
290
+ }
291
+ );
292
+ }
293
+ function QRPlaceholder({
294
+ size,
295
+ dotColor,
296
+ backgroundColor
297
+ }) {
298
+ return /* @__PURE__ */ jsxs2("div", { className: styles3.placeholderContainer, style: { width: size - 40, height: size - 40 }, children: [
299
+ /* @__PURE__ */ jsx3(
300
+ "div",
301
+ {
302
+ className: styles3.placeholderPattern,
303
+ style: {
304
+ backgroundImage: `radial-gradient(${dotColor} 41%, transparent 41%)`
305
+ }
306
+ }
307
+ ),
308
+ [
309
+ { top: 0, left: 0 },
310
+ { top: 0, right: 0 },
311
+ { bottom: 0, left: 0 }
312
+ ].map((pos, i) => /* @__PURE__ */ jsx3(
313
+ "span",
314
+ {
315
+ className: styles3.cornerSquare,
316
+ style: {
317
+ ...pos,
318
+ background: dotColor
319
+ }
320
+ },
321
+ i
322
+ )),
323
+ /* @__PURE__ */ jsx3(
324
+ "div",
325
+ {
326
+ className: styles3.centerArea,
327
+ style: {
328
+ background: backgroundColor,
329
+ boxShadow: `0 0 0 7px ${backgroundColor}`
330
+ }
331
+ }
332
+ ),
333
+ /* @__PURE__ */ jsxs2("div", { className: styles3.loaderWrapper, children: [
334
+ /* @__PURE__ */ jsx3(
335
+ "div",
336
+ {
337
+ className: styles3.spinner,
338
+ style: { color: `${dotColor}40` }
339
+ }
340
+ ),
341
+ /* @__PURE__ */ jsx3("span", { className: styles3.loadingText, style: { color: `${dotColor}70` }, children: "Generating QR code..." })
342
+ ] })
343
+ ] });
344
+ }
345
+ CustomQRCode.displayName = "CustomQRCode";
346
+
347
+ // src/components/shared/CustomQRCode/index.ts
348
+ var CustomQRCode_default = CustomQRCode;
349
+
350
+ // src/components/shared/Spinner/Spinner.tsx
351
+ import classes from "./Spinner.module-G7GUQJZJ.module.css";
352
+ import { jsx as jsx4 } from "react/jsx-runtime";
353
+ var Spinner = () => {
354
+ return /* @__PURE__ */ jsx4("div", { className: classes.spinner });
355
+ };
356
+ var Spinner_default = Spinner;
357
+
358
+ // src/components/shared/Spinner/index.ts
359
+ var Spinner_default2 = Spinner_default;
360
+
361
+ // src/components/WalletModal/WalletModal.tsx
362
+ import { SiWalletconnect } from "react-icons/si";
363
+
364
+ // src/components/shared/Collapsible/Collapsible.tsx
365
+ import * as React3 from "react";
366
+ import { Collapsible as BaseCollapsible } from "@base-ui/react/collapsible";
367
+ import styles4 from "./Collapsible.module-NXSN3MGI.module.css";
368
+ import { jsx as jsx5 } from "react/jsx-runtime";
369
+ var Collapsible = BaseCollapsible.Root;
370
+ var CollapsibleTrigger = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx5(
371
+ BaseCollapsible.Trigger,
372
+ {
373
+ ref,
374
+ className: `${styles4.trigger} ${className || ""}`,
375
+ ...props
376
+ }
377
+ ));
378
+ CollapsibleTrigger.displayName = "CollapsibleTrigger";
379
+ var CollapsibleContent = React3.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx5(
380
+ BaseCollapsible.Panel,
381
+ {
382
+ ref,
383
+ className: `${styles4.content} ${className || ""}`,
384
+ ...props
385
+ }
386
+ ));
387
+ CollapsibleContent.displayName = "CollapsibleContent";
388
+
389
+ // src/components/shared/Avatar/Avatar.tsx
390
+ import { useState } from "react";
391
+ import styles5 from "./Avatar.module-P7KEBP7R.module.css";
392
+ import { Wallet } from "lucide-react";
393
+ import { jsx as jsx6 } from "react/jsx-runtime";
394
+ function Avatar({
395
+ height,
396
+ width,
397
+ src,
398
+ alt,
399
+ theme = "light"
400
+ }) {
401
+ const [hasError, setHasError] = useState(false);
402
+ return /* @__PURE__ */ jsx6("div", { className: styles5.avatar, "data-theme": theme, children: src && !hasError ? /* @__PURE__ */ jsx6(
403
+ "img",
404
+ {
405
+ height,
406
+ width,
407
+ src,
408
+ alt: alt || "Avatar",
409
+ onError: () => setHasError(true)
410
+ }
411
+ ) : /* @__PURE__ */ jsx6("div", { className: styles5.fallback, style: { height, width }, children: /* @__PURE__ */ jsx6(Wallet, {}) }) });
412
+ }
413
+
414
+ // src/components/shared/Avatar/index.ts
415
+ var Avatar_default = Avatar;
416
+
417
+ // src/components/WalletModal/WalletModal.tsx
418
+ import { clsx as clsx2 } from "clsx";
419
+ import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
420
+ function WalletModal(props) {
421
+ var _a;
422
+ const {
423
+ CN_Modal,
424
+ theme = "light",
425
+ open,
426
+ onOpenChange,
427
+ walletConnectUri,
428
+ onClearWalletConnectUri
429
+ } = props;
430
+ const { walletStatus: { status }, isConnecting, connectorId, connectors, connectWallet, disconnectWallet } = useConnector();
431
+ const [connectingConnectorId, setConnectingConnectorId] = useState2(null);
432
+ const [isOtherWalletsOpen, setIsOtherWalletsOpen] = useState2(false);
433
+ const [errorConnectorId, setErrorConnectorId] = useState2(null);
434
+ const [errorMessage, setErrorMessage] = useState2(null);
435
+ const [copied, setCopied] = useState2(false);
436
+ const isClient = useSyncExternalStore(
437
+ () => () => {
438
+ },
439
+ () => true,
440
+ () => false
441
+ );
442
+ const recentlyConnectedConnectorId = useSyncExternalStore(
443
+ () => () => {
444
+ },
445
+ () => localStorage.getItem("recentlyConnectedConnectorId"),
446
+ () => null
447
+ );
448
+ useEffect(() => {
449
+ if (status === "connected" && connectorId) {
450
+ localStorage.setItem("recentlyConnectedConnectorId", connectorId);
451
+ }
452
+ }, [status, connectorId]);
453
+ const walletConnectConnector = (_a = connectors.find((c) => c.name === "WalletConnect")) != null ? _a : null;
454
+ const isWalletConnectFlow = !!walletConnectConnector && (connectingConnectorId === walletConnectConnector.id || status === "connecting" && connectorId === walletConnectConnector.id) || !!walletConnectUri;
455
+ function cancelConnection() {
456
+ onClearWalletConnectUri == null ? void 0 : onClearWalletConnectUri();
457
+ setConnectingConnectorId(null);
458
+ disconnectWallet().catch(() => {
459
+ });
460
+ }
461
+ const clearError = () => {
462
+ setErrorConnectorId(null);
463
+ setErrorMessage(null);
464
+ };
465
+ const handleSelectWallet = async (connector) => {
466
+ clearError();
467
+ setConnectingConnectorId(connector.id);
468
+ try {
469
+ if (connector.name === "WalletConnect") {
470
+ onClearWalletConnectUri == null ? void 0 : onClearWalletConnectUri();
471
+ }
472
+ await connectWallet(connector.id);
473
+ localStorage.setItem("recentlyConnectedConnectorId", connector.id);
474
+ if (connector.name !== "WalletConnect") {
475
+ onOpenChange(false);
476
+ }
477
+ } catch (error) {
478
+ const message = error instanceof Error ? error.message : "An unexpected error occurred";
479
+ if (message.includes("Connection cancelled")) return;
480
+ setErrorConnectorId(connector.id);
481
+ setErrorMessage(message);
482
+ console.error("Failed to connect wallet:", {
483
+ wallet: connector.name,
484
+ connectorId: connector.id,
485
+ error,
486
+ message,
487
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
488
+ });
489
+ } finally {
490
+ setConnectingConnectorId(null);
491
+ }
492
+ };
493
+ const handleCopyUri = async () => {
494
+ if (!walletConnectUri) return;
495
+ try {
496
+ await navigator.clipboard.writeText(walletConnectUri);
497
+ setCopied(true);
498
+ setTimeout(() => setCopied(false), 2e3);
499
+ } catch (err) {
500
+ console.error("Failed to copy URI:", err);
501
+ }
502
+ };
503
+ const handleBackFromWalletConnect = () => {
504
+ cancelConnection();
505
+ };
506
+ const readyConnectors = connectors.filter((c) => c.ready);
507
+ const notReadyConnectors = connectors.filter((c) => !c.ready);
508
+ const sortedReadyConnectors = [...readyConnectors].sort((a, b) => {
509
+ const aIsRecent = recentlyConnectedConnectorId === a.id;
510
+ const bIsRecent = recentlyConnectedConnectorId === b.id;
511
+ if (aIsRecent && !bIsRecent) return -1;
512
+ if (!aIsRecent && bIsRecent) return 1;
513
+ return 0;
514
+ });
515
+ const primaryWallets = sortedReadyConnectors.slice(0, 3);
516
+ const otherWallets = sortedReadyConnectors.slice(3);
517
+ const primayOuterHr = otherWallets.length > 0 && primaryWallets.length > 0;
518
+ const getInstallUrl = (walletName, walletUrl) => {
519
+ if (walletUrl) return walletUrl;
520
+ const name = walletName.toLowerCase();
521
+ if (name.includes("phantom")) return "https://phantom.app";
522
+ if (name.includes("solflare")) return "https://solflare.com";
523
+ if (name.includes("backpack")) return "https://backpack.app";
524
+ if (name.includes("glow")) return "https://glow.app";
525
+ if (name.includes("coinbase")) return "https://www.coinbase.com/wallet";
526
+ if (name.includes("ledger")) return "https://www.ledger.com";
527
+ if (name.includes("trust")) return "https://trustwallet.com";
528
+ if (name.includes("exodus")) return "https://www.exodus.com";
529
+ return void 0;
530
+ };
531
+ const handleOpenChange = (isOpen) => {
532
+ if (!isOpen) {
533
+ clearError();
534
+ if (isConnecting || connectingConnectorId || walletConnectUri) {
535
+ cancelConnection();
536
+ }
537
+ }
538
+ onOpenChange(isOpen);
539
+ };
540
+ const walletLinkOpen = (walletName) => {
541
+ const installUrl = getInstallUrl(walletName);
542
+ if (installUrl) {
543
+ window.open(installUrl, "_blank");
544
+ }
545
+ };
546
+ return /* @__PURE__ */ jsx7(Dialog, { open, onOpenChange: handleOpenChange, children: /* @__PURE__ */ jsxs3(
547
+ DialogContent,
548
+ {
549
+ showCloseButton: false,
550
+ className: clsx2(styles6.dialogContent, CN_Modal),
551
+ theme,
552
+ children: [
553
+ /* @__PURE__ */ jsxs3("div", { className: styles6.dialogHeader, children: [
554
+ isWalletConnectFlow ? /* @__PURE__ */ jsx7(
555
+ "button",
556
+ {
557
+ onClick: handleBackFromWalletConnect,
558
+ className: styles6.iconButton,
559
+ children: /* @__PURE__ */ jsx7(ChevronLeft, {})
560
+ }
561
+ ) : null,
562
+ /* @__PURE__ */ jsx7(DialogTitle, { className: styles6.dialogTitle, children: isWalletConnectFlow ? "WalletConnect" : "Connect your wallet" }),
563
+ /* @__PURE__ */ jsx7(DialogClose, { className: styles6.iconButton, children: /* @__PURE__ */ jsx7(X2, {}) })
564
+ ] }),
565
+ isWalletConnectFlow && /* @__PURE__ */ jsxs3("div", { className: styles6.walletsContainer, children: [
566
+ /* @__PURE__ */ jsxs3("div", { className: styles6.tooltipBubble, children: [
567
+ /* @__PURE__ */ jsx7("span", { children: "Use a WalletConnect" }),
568
+ /* @__PURE__ */ jsxs3("div", { className: styles6.tooltipIconWrapper, children: [
569
+ /* @__PURE__ */ jsx7(SiWalletconnect, { className: styles6.tooltipIcon }),
570
+ /* @__PURE__ */ jsx7("div", { className: styles6.tooltipCaret })
571
+ ] }),
572
+ /* @__PURE__ */ jsx7("span", { children: "supported wallet to scan" })
573
+ ] }),
574
+ /* @__PURE__ */ jsx7("div", { className: styles6.qrWrapper, children: /* @__PURE__ */ jsx7(
575
+ CustomQRCode_default,
576
+ {
577
+ value: walletConnectUri != null ? walletConnectUri : "",
578
+ size: 280,
579
+ ecl: "M",
580
+ loading: !walletConnectUri,
581
+ scanning: !!walletConnectUri
582
+ }
583
+ ) }),
584
+ /* @__PURE__ */ jsx7(
585
+ Button_default2,
586
+ {
587
+ variant: "outline",
588
+ onClick: handleCopyUri,
589
+ disabled: !walletConnectUri,
590
+ className: styles6.copyButton,
591
+ "data-theme": theme,
592
+ children: copied ? /* @__PURE__ */ jsxs3(Fragment2, { children: [
593
+ /* @__PURE__ */ jsx7(Check, { className: `${styles6.icon} ${styles6.successIcon}` }),
594
+ "Copy to Clipboard"
595
+ ] }) : /* @__PURE__ */ jsxs3(Fragment2, { children: [
596
+ /* @__PURE__ */ jsx7(Copy, { className: styles6.icon }),
597
+ "Copy to Clipboard"
598
+ ] })
599
+ }
600
+ )
601
+ ] }),
602
+ !isWalletConnectFlow && /* @__PURE__ */ jsxs3("div", { className: styles6.walletsContainer, children: [
603
+ !isClient && /* @__PURE__ */ jsxs3("div", { className: styles6.detectingWallets, children: [
604
+ /* @__PURE__ */ jsx7(Spinner_default2, {}),
605
+ /* @__PURE__ */ jsx7("p", { children: "Detecting wallets..." })
606
+ ] }),
607
+ connectors.length === 0 && /* @__PURE__ */ jsxs3("div", { className: styles6.emptyStateContainer, children: [
608
+ /* @__PURE__ */ jsx7(Wallet2, { className: styles6.emptyStateIcon }),
609
+ /* @__PURE__ */ jsx7("h3", { className: styles6.emptyStateTitle, children: "No Wallets Detected" }),
610
+ /* @__PURE__ */ jsx7("p", { className: styles6.emptyStateDesc, children: "Install a Solana wallet extension to get started" }),
611
+ /* @__PURE__ */ jsxs3("div", { className: styles6.emptyStateActions, children: [
612
+ /* @__PURE__ */ jsx7(
613
+ Button_default2,
614
+ {
615
+ variant: "outline",
616
+ "data-theme": theme,
617
+ onClick: () => walletLinkOpen("Phantom"),
618
+ children: "Get Phantom"
619
+ }
620
+ ),
621
+ /* @__PURE__ */ jsx7(
622
+ Button_default2,
623
+ {
624
+ "data-theme": theme,
625
+ variant: "outline",
626
+ onClick: () => walletLinkOpen("Backpack"),
627
+ children: "Get Backpack"
628
+ }
629
+ )
630
+ ] })
631
+ ] }),
632
+ /* @__PURE__ */ jsx7("div", { className: styles6.allWallets, children: primaryWallets.map((connector) => /* @__PURE__ */ jsx7(
633
+ WalletButton,
634
+ {
635
+ theme,
636
+ connector,
637
+ isThisConnecting: isConnecting && connectingConnectorId === connector.id,
638
+ hasError: errorConnectorId === connector.id,
639
+ isRecent: recentlyConnectedConnectorId === connector.id,
640
+ onSelect: () => handleSelectWallet(connector),
641
+ getInstallUrl
642
+ },
643
+ connector.id
644
+ )) }),
645
+ otherWallets.length > 0 && /* @__PURE__ */ jsxs3(Fragment2, { children: [
646
+ primayOuterHr && /* @__PURE__ */ jsx7("div", { className: styles6.seprator }),
647
+ /* @__PURE__ */ jsxs3(
648
+ Collapsible,
649
+ {
650
+ open: isOtherWalletsOpen,
651
+ onOpenChange: setIsOtherWalletsOpen,
652
+ className: styles6.Collapsible,
653
+ children: [
654
+ /* @__PURE__ */ jsxs3(CollapsibleTrigger, { className: styles6.hiddenExpand, children: [
655
+ /* @__PURE__ */ jsx7("span", { className: styles6.textContainer, children: "Other Wallets" }),
656
+ /* @__PURE__ */ jsx7(HiddenWalletIcons, { wallets: otherWallets, className: "shrink-0" })
657
+ ] }),
658
+ /* @__PURE__ */ jsx7(CollapsibleContent, { className: styles6.allWallets, children: otherWallets.map((connector) => /* @__PURE__ */ jsx7(
659
+ WalletButton,
660
+ {
661
+ theme,
662
+ connector,
663
+ isThisConnecting: isConnecting && connectingConnectorId === connector.id,
664
+ hasError: errorConnectorId === connector.id,
665
+ isRecent: recentlyConnectedConnectorId === connector.id,
666
+ onSelect: () => handleSelectWallet(connector),
667
+ getInstallUrl
668
+ },
669
+ connector.id
670
+ )) })
671
+ ]
672
+ }
673
+ )
674
+ ] }),
675
+ notReadyConnectors.length > 0 && /* @__PURE__ */ jsxs3(Fragment2, { children: [
676
+ (primaryWallets.length > 0 || otherWallets.length > 0) && /* @__PURE__ */ jsx7("div", { className: styles6.seprator }),
677
+ /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
678
+ /* @__PURE__ */ jsx7("h3", { className: styles6.sectionHeader, children: readyConnectors.length > 0 ? "Unavailable Wallets" : "Wallets" }),
679
+ /* @__PURE__ */ jsx7("div", { className: styles6.grid, children: notReadyConnectors.slice(0, 3).map((connector) => {
680
+ const installUrl = getInstallUrl(connector.name);
681
+ return /* @__PURE__ */ jsxs3("div", { className: styles6.unavailableRow, children: [
682
+ /* @__PURE__ */ jsxs3("div", { className: styles6.walletInfo, children: [
683
+ /* @__PURE__ */ jsx7(
684
+ Avatar_default,
685
+ {
686
+ width: 40,
687
+ height: 40,
688
+ src: connector.icon,
689
+ alt: connector.name,
690
+ theme
691
+ }
692
+ ),
693
+ /* @__PURE__ */ jsxs3("div", { className: "text-left", children: [
694
+ /* @__PURE__ */ jsx7("div", { className: styles6.walletName, children: connector.name }),
695
+ /* @__PURE__ */ jsx7("div", { className: styles6.unavailableLabel, children: "Not available" })
696
+ ] })
697
+ ] }),
698
+ installUrl && /* @__PURE__ */ jsx7(
699
+ Button_default2,
700
+ {
701
+ "data-theme": theme,
702
+ variant: "ghost",
703
+ size: "sm",
704
+ className: styles6.installButton,
705
+ onClick: () => window.open(installUrl, "_blank"),
706
+ children: /* @__PURE__ */ jsx7(ExternalLink, {})
707
+ }
708
+ )
709
+ ] }, connector.id);
710
+ }) })
711
+ ] })
712
+ ] })
713
+ ] })
714
+ ]
715
+ }
716
+ ) });
717
+ }
718
+ var WalletModal_default = WalletModal;
719
+ function WalletButton(props) {
720
+ const { connector, isThisConnecting, hasError, isRecent, theme, onSelect, getInstallUrl } = props;
721
+ const handleSelectWallet = () => {
722
+ onSelect();
723
+ };
724
+ return /* @__PURE__ */ jsxs3(
725
+ Button_default2,
726
+ {
727
+ variant: "outline",
728
+ "data-error": hasError,
729
+ "data-theme": theme,
730
+ className: styles6.walletButton,
731
+ onClick: handleSelectWallet,
732
+ disabled: isThisConnecting,
733
+ children: [
734
+ /* @__PURE__ */ jsxs3("div", { className: styles6.textContainer, children: [
735
+ /* @__PURE__ */ jsxs3("div", { className: styles6.nameRow, children: [
736
+ /* @__PURE__ */ jsx7("span", { children: connector.name }),
737
+ isRecent && /* @__PURE__ */ jsx7("span", { className: styles6.recentBadge, children: "Recent" })
738
+ ] }),
739
+ isThisConnecting && /* @__PURE__ */ jsx7("div", { className: styles6.statusText, children: "Connecting..." }),
740
+ hasError && !isThisConnecting && /* @__PURE__ */ jsx7("div", { className: styles6.statusText, "data-type": "error", children: "Click to retry" })
741
+ ] }),
742
+ /* @__PURE__ */ jsxs3("div", { className: styles6.iconContainer, children: [
743
+ isThisConnecting && /* @__PURE__ */ jsx7(Spinner_default2, {}),
744
+ /* @__PURE__ */ jsx7(
745
+ Avatar_default,
746
+ {
747
+ width: 40,
748
+ height: 40,
749
+ src: connector.icon,
750
+ alt: connector.name,
751
+ theme
752
+ }
753
+ )
754
+ ] })
755
+ ]
756
+ },
757
+ connector.id
758
+ );
759
+ }
760
+ function HiddenWalletIcons({ wallets, maxIcons = 4, className }) {
761
+ const previewWallets = wallets.slice(0, maxIcons);
762
+ const placeholderCount = Math.max(0, maxIcons - previewWallets.length);
763
+ return /* @__PURE__ */ jsxs3(
764
+ "div",
765
+ {
766
+ className: `${styles6.hiddenWalletGrid} ${className || ""}`,
767
+ "aria-hidden": "true",
768
+ children: [
769
+ previewWallets.map((wallet) => /* @__PURE__ */ jsx7(
770
+ "div",
771
+ {
772
+ className: styles6.hiddenWalletIconWrapper,
773
+ children: wallet.icon && /* @__PURE__ */ jsx7(
774
+ "img",
775
+ {
776
+ height: 10,
777
+ width: 10,
778
+ src: wallet.icon,
779
+ alt: wallet.name,
780
+ draggable: false,
781
+ onError: (e) => {
782
+ e.currentTarget.style.display = "none";
783
+ }
784
+ }
785
+ )
786
+ },
787
+ wallet.id
788
+ )),
789
+ Array.from({ length: placeholderCount }).map((_, index) => /* @__PURE__ */ jsx7(
790
+ "div",
791
+ {
792
+ className: styles6.hiddenWalletIconWrapper
793
+ },
794
+ `placeholder-${index}`
795
+ ))
796
+ ]
797
+ }
798
+ );
799
+ }
800
+
801
+ // src/components/WalletModal/index.ts
802
+ var WalletModal_default2 = WalletModal_default;
803
+ export {
804
+ WalletModal_default2 as default
805
+ };
806
+ //# sourceMappingURL=WalletModal.mjs.map