@algobright/solana-connector 0.1.0 → 0.1.2

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 (29) hide show
  1. package/dist/{Avatar.module-P7KEBP7R.module.css → Avatar.module-AACAT34D.module.css} +42 -42
  2. package/dist/{Button.module-7TPMDOJN.module.css → Button.module-HQNNX6IB.module.css} +145 -145
  3. package/dist/{Collapsible.module-NXSN3MGI.module.css → Collapsible.module-F4VIL5FH.module.css} +24 -24
  4. package/dist/ConnectButton.d.mts +4 -0
  5. package/dist/ConnectButton.d.ts +4 -0
  6. package/dist/ConnectButton.js +145 -39
  7. package/dist/ConnectButton.js.map +1 -1
  8. package/dist/ConnectButton.mjs +140 -34
  9. package/dist/ConnectButton.mjs.map +1 -1
  10. package/dist/{ConnectButton.module-UWQKSVTP.module.css → ConnectButton.module-O3M32YJK.module.css} +8 -8
  11. package/dist/{CustomQRCode.module-FOXENMZG.module.css → CustomQRCode.module-JW3JU3FX.module.css} +176 -176
  12. package/dist/{Dialog.module-HCRT743N.module.css → Dialog.module-AYJTMDAD.module.css} +136 -136
  13. package/dist/{Menu.module-GV627ZLI.module.css → Menu.module-6ATSLATI.module.css} +79 -79
  14. package/dist/{Spinner.module-G7GUQJZJ.module.css → Spinner.module-BLSWZSIL.module.css} +16 -16
  15. package/dist/WalletDropdown.d.mts +4 -0
  16. package/dist/WalletDropdown.d.ts +4 -0
  17. package/dist/WalletDropdown.js +132 -28
  18. package/dist/WalletDropdown.js.map +1 -1
  19. package/dist/WalletDropdown.mjs +129 -25
  20. package/dist/WalletDropdown.mjs.map +1 -1
  21. package/dist/{WalletDropdown.module-342MM7XM.module.css → WalletDropdown.module-DOK7CUOQ.module.css} +223 -220
  22. package/dist/WalletModal.js +7 -7
  23. package/dist/WalletModal.js.map +1 -1
  24. package/dist/WalletModal.mjs +7 -7
  25. package/dist/WalletModal.mjs.map +1 -1
  26. package/dist/{WalletModal.module-PVV5PRXU.module.css → WalletModal.module-ZRTJGOQY.module.css} +341 -341
  27. package/dist/index.js.map +1 -1
  28. package/dist/index.mjs.map +1 -1
  29. package/package.json +11 -9
@@ -2,12 +2,13 @@
2
2
 
3
3
  // src/components/WalletDropdown/WalletDropdown.tsx
4
4
  import { useEffect, useRef, useState as useState2 } from "react";
5
- import styles3 from "./WalletDropdown.module-342MM7XM.module.css";
5
+ import { isAddress } from "@solana/kit";
6
+ import styles3 from "./WalletDropdown.module-DOK7CUOQ.module.css";
6
7
  import { motion } from "motion/react";
7
8
 
8
9
  // src/components/shared/Avatar/Avatar.tsx
9
10
  import { useState } from "react";
10
- import styles from "./Avatar.module-P7KEBP7R.module.css";
11
+ import styles from "./Avatar.module-AACAT34D.module.css";
11
12
  import { Wallet } from "lucide-react";
12
13
  import { jsx } from "react/jsx-runtime";
13
14
  function Avatar({
@@ -39,7 +40,7 @@ import { Check, ChevronLeft, Copy, Globe, LogOut, RefreshCw } from "lucide-react
39
40
  // src/components/shared/Button/Button.tsx
40
41
  import * as React from "react";
41
42
  import { Button as BaseButton } from "@base-ui/react/button";
42
- import styles2 from "./Button.module-7TPMDOJN.module.css";
43
+ import styles2 from "./Button.module-HQNNX6IB.module.css";
43
44
  import { jsx as jsx2 } from "react/jsx-runtime";
44
45
  var Button = React.forwardRef(
45
46
  ({ className, variant = "default", size = "default", ...props }, ref) => {
@@ -62,9 +63,66 @@ var Button_default = Button;
62
63
  var Button_default2 = Button_default;
63
64
 
64
65
  // src/components/WalletDropdown/WalletDropdown.tsx
65
- import { address, ClusterElement, DisconnectElement, lamportsToSol, useConnectorClient } from "@solana/connector";
66
- import { createSolanaRpc } from "@solana/kit";
66
+ import { ClusterElement, DisconnectElement, useConnectorClient } from "@solana/connector";
67
67
  import { clsx } from "clsx";
68
+
69
+ // src/utils/fetchBalance.tsx
70
+ import { findAssociatedTokenPda } from "@solana-program/token";
71
+ import { address, lamportsToSol } from "@solana/connector";
72
+ import { createSolanaRpc } from "@solana/kit";
73
+ async function getSolBalance(client, pubkey) {
74
+ let balance = 0;
75
+ try {
76
+ const rpcUrl = client.getRpcUrl();
77
+ if (!rpcUrl) {
78
+ console.error("RPC URL is not available from the ConnectorClient.");
79
+ return 0;
80
+ }
81
+ const pubkeyAddress = address(pubkey);
82
+ const rpc = createSolanaRpc(rpcUrl);
83
+ const balanceResponse = await rpc.getBalance(pubkeyAddress).send();
84
+ balance = lamportsToSol(balanceResponse.value);
85
+ } catch (error) {
86
+ console.error("Error fetching SOL balance:", error);
87
+ } finally {
88
+ return balance;
89
+ }
90
+ }
91
+ async function getTokenBalance(client, pubkey, mintAddress) {
92
+ var _a;
93
+ let balance = 0;
94
+ try {
95
+ const rpcUrl = client.getRpcUrl();
96
+ if (!rpcUrl) {
97
+ console.error("RPC URL is not available from the ConnectorClient.");
98
+ return 0;
99
+ }
100
+ const pubkeyAddress = address(pubkey);
101
+ const mintPubkey = address(mintAddress);
102
+ const rpc = createSolanaRpc(rpcUrl);
103
+ const mintInfo = await rpc.getAccountInfo(mintPubkey).send();
104
+ const ownerProgram = (_a = mintInfo.value) == null ? void 0 : _a.owner;
105
+ if (!ownerProgram) {
106
+ throw new Error("Failed to fetch mint account info");
107
+ }
108
+ const tokenProgram = address(ownerProgram);
109
+ const [tokenPDA] = await findAssociatedTokenPda({
110
+ mint: mintPubkey,
111
+ owner: pubkeyAddress,
112
+ tokenProgram
113
+ });
114
+ const tokenBalance = await rpc.getTokenAccountBalance(tokenPDA).send();
115
+ if (tokenBalance.value) {
116
+ balance = parseFloat(tokenBalance.value.uiAmountString);
117
+ }
118
+ } catch (error) {
119
+ console.error("Error fetching token balance:", error);
120
+ } finally {
121
+ return balance;
122
+ }
123
+ }
124
+
125
+ // src/components/WalletDropdown/WalletDropdown.tsx
68
126
  import { jsx as jsx3, jsxs } from "react/jsx-runtime";
69
127
  var networkColor = {
70
128
  "solana:mainnet": "#00c950",
@@ -74,12 +132,24 @@ var networkColor = {
74
132
  };
75
133
  function WalletDropdown(props) {
76
134
  const client = useConnectorClient();
77
- const { CN_ConnectButton, selectedAccount, walletIcon, walletName, theme, allowNetworkSwitch, showSolBalance } = props;
135
+ const {
136
+ CN_ConnectButton,
137
+ selectedAccount,
138
+ walletIcon,
139
+ walletName,
140
+ theme,
141
+ allowNetworkSwitch,
142
+ showSolBalance,
143
+ showDefaultToken
144
+ } = props;
78
145
  const [view, setView] = useState2("wallet");
79
146
  const [copied, setCopied] = useState2(false);
80
- const fetching = useRef(false);
147
+ const fetchingSolBalance = useRef(false);
81
148
  const [isFetchingBalance, setIsFetchingBalance] = useState2(false);
149
+ const fetchingDefaultToken = useRef(false);
150
+ const [isFetchingDefaultTokenBalance, setIsFetchingDefaultTokenBalance] = useState2(false);
82
151
  const [solBalance, setSolBalance] = useState2(null);
152
+ const [defaultTokenBalance, setDefaultTokenBalance] = useState2(null);
83
153
  const shortAddress = `${selectedAccount.slice(0, 4)}...${selectedAccount.slice(-4)}`;
84
154
  async function handleCopy() {
85
155
  try {
@@ -92,29 +162,36 @@ function WalletDropdown(props) {
92
162
  }
93
163
  }
94
164
  async function fetchSolBalance() {
95
- if (!client || fetching.current) return;
165
+ if (!client || fetchingSolBalance.current) return;
96
166
  setIsFetchingBalance(true);
97
- fetching.current = true;
98
- try {
99
- const rpcUrl = client.getRpcUrl();
100
- const pubkey = address(selectedAccount);
101
- if (!rpcUrl) throw new Error("No RPC endpoint configured");
102
- const rpc = createSolanaRpc(rpcUrl);
103
- const solLamports = (await rpc.getBalance(pubkey).send()).value || 0;
104
- const sol = lamportsToSol(solLamports);
105
- setSolBalance(sol);
106
- } catch (error) {
107
- setSolBalance(0);
108
- } finally {
109
- setIsFetchingBalance(false);
110
- fetching.current = false;
167
+ fetchingSolBalance.current = true;
168
+ const solBalance2 = await getSolBalance(client, selectedAccount);
169
+ setSolBalance(solBalance2);
170
+ setIsFetchingBalance(false);
171
+ fetchingSolBalance.current = false;
172
+ }
173
+ async function fetchDefaultTokenBalance() {
174
+ if (!showDefaultToken || !showDefaultToken.address || !client || fetchingDefaultToken.current) return;
175
+ const isValidAddress = isAddress(showDefaultToken.address);
176
+ if (!isValidAddress) {
177
+ console.error("Invalid default token address:", showDefaultToken);
178
+ return;
111
179
  }
180
+ setIsFetchingDefaultTokenBalance(true);
181
+ fetchingDefaultToken.current = true;
182
+ const tokenBalance = await getTokenBalance(client, selectedAccount, showDefaultToken.address);
183
+ setDefaultTokenBalance(tokenBalance);
184
+ setIsFetchingDefaultTokenBalance(false);
185
+ fetchingDefaultToken.current = false;
112
186
  }
113
187
  useEffect(() => {
114
188
  if (showSolBalance && selectedAccount && client) {
115
189
  fetchSolBalance();
116
190
  }
117
- }, [selectedAccount, client, showSolBalance]);
191
+ if (showDefaultToken && selectedAccount && client) {
192
+ fetchDefaultTokenBalance();
193
+ }
194
+ }, [selectedAccount, client, showSolBalance, showDefaultToken]);
118
195
  if (view === "wallet") {
119
196
  return /* @__PURE__ */ jsxs(
120
197
  motion.div,
@@ -208,7 +285,35 @@ function WalletDropdown(props) {
208
285
  ]
209
286
  }
210
287
  ),
211
- /* @__PURE__ */ jsx3("div", { className: styles3.balanceValue, children: isFetchingBalance ? /* @__PURE__ */ jsx3("div", { className: styles3.balanceLoading }) : solBalance !== null ? `${solBalance.toFixed(4)} SOL` : "-- SOL" })
288
+ /* @__PURE__ */ jsx3("div", { className: styles3.balanceValue, title: String(solBalance) || "0", children: isFetchingBalance ? /* @__PURE__ */ jsx3("div", { className: styles3.balanceLoading }) : solBalance !== null ? `${solBalance.toFixed(4)} SOL` : "-- SOL" })
289
+ ] }),
290
+ showDefaultToken && /* @__PURE__ */ jsxs("div", { className: styles3.balanceSection, children: [
291
+ /* @__PURE__ */ jsxs(
292
+ "div",
293
+ {
294
+ className: styles3.balanceHeader,
295
+ children: [
296
+ /* @__PURE__ */ jsx3("span", { className: styles3.balanceLabel, children: "Balance" }),
297
+ /* @__PURE__ */ jsx3(
298
+ "button",
299
+ {
300
+ onClick: () => fetchDefaultTokenBalance(),
301
+ disabled: isFetchingDefaultTokenBalance,
302
+ title: "Refresh balance",
303
+ className: styles3.refreshButton,
304
+ "data-loading": isFetchingDefaultTokenBalance,
305
+ children: /* @__PURE__ */ jsx3(
306
+ RefreshCw,
307
+ {
308
+ className: styles3.refreshIcon
309
+ }
310
+ )
311
+ }
312
+ )
313
+ ]
314
+ }
315
+ ),
316
+ /* @__PURE__ */ jsx3("div", { className: styles3.balanceValue, title: String(defaultTokenBalance) || "0", children: isFetchingDefaultTokenBalance ? /* @__PURE__ */ jsx3("div", { className: styles3.balanceLoading }) : defaultTokenBalance !== null ? `${defaultTokenBalance.toFixed(4)} ${(showDefaultToken == null ? void 0 : showDefaultToken.symbol) || ""}` : `-- ${(showDefaultToken == null ? void 0 : showDefaultToken.symbol) || ""}` })
212
317
  ] }),
213
318
  /* @__PURE__ */ jsx3(
214
319
  DisconnectElement,
@@ -233,7 +338,6 @@ function WalletDropdown(props) {
233
338
  );
234
339
  }
235
340
  if (view === "network") {
236
- console.count("Network view rendered");
237
341
  return /* @__PURE__ */ jsxs(
238
342
  motion.div,
239
343
  {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/WalletDropdown/WalletDropdown.tsx","../src/components/shared/Avatar/Avatar.tsx","../src/components/shared/Avatar/index.ts","../src/components/shared/Button/Button.tsx","../src/components/shared/Button/index.ts","../src/components/WalletDropdown/index.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react'\r\nimport styles from './WalletDropdown.module.css'\r\nimport { motion } from 'motion/react';\r\nimport Avatar from '@shared/Avatar';\r\nimport { Check, ChevronLeft, Copy, Globe, LogOut, RefreshCw } from 'lucide-react';\r\nimport Button from '@shared/Button';\r\nimport { address, BalanceElement, ClusterElement, DisconnectElement, lamportsToSol, useCluster, useConnectorClient } from '@solana/connector';\r\nimport { createSolanaRpc } from '@solana/kit';\r\nimport { clsx } from 'clsx';\r\n\r\ninterface WalletDropdownProps {\r\n CN_ConnectButton?: string;\r\n selectedAccount: string;\r\n walletIcon?: string;\r\n walletName: string;\r\n theme?: 'light' | 'dark';\r\n\r\n allowNetworkSwitch?: boolean;\r\n showSolBalance?: boolean;\r\n}\r\n\r\ntype DropdownView = 'wallet' | 'network';\r\n\r\nconst networkColor: Record<string, string> = {\r\n 'solana:mainnet': '#00c950',\r\n 'solana:devnet': '#2b7fff',\r\n 'solana:testnet': '#f0b100',\r\n 'solana:localnet': '#ff3b3b',\r\n};\r\n\r\nexport function WalletDropdown(props: WalletDropdownProps) {\r\n const client = useConnectorClient();\r\n\r\n const { CN_ConnectButton, selectedAccount, walletIcon, walletName, theme, allowNetworkSwitch, showSolBalance } = props\r\n\r\n const [view, setView] = useState<DropdownView>('wallet');\r\n const [copied, setCopied] = useState(false);\r\n\r\n const fetching = useRef(false);\r\n const [isFetchingBalance, setIsFetchingBalance] = useState(false);\r\n const [solBalance, setSolBalance] = useState<number | null>(null);\r\n\r\n const shortAddress = `${selectedAccount.slice(0, 4)}...${selectedAccount.slice(-4)}`;\r\n\r\n async function handleCopy() {\r\n try {\r\n await navigator.clipboard.writeText(selectedAccount);\r\n setCopied(true);\r\n setTimeout(() => setCopied(false), 2000);\r\n } catch (error) {\r\n setCopied(false);\r\n console.error('Failed to copy to clipboard:', error);\r\n }\r\n }\r\n\r\n async function fetchSolBalance() {\r\n if (!client || fetching.current) return;\r\n setIsFetchingBalance(true);\r\n fetching.current = true;\r\n try {\r\n const rpcUrl = client.getRpcUrl();\r\n const pubkey = address(selectedAccount);\r\n if (!rpcUrl) throw new Error('No RPC endpoint configured');\r\n const rpc = createSolanaRpc(rpcUrl);\r\n const solLamports = (await rpc.getBalance(pubkey).send()).value || 0;\r\n const sol = lamportsToSol(solLamports);\r\n setSolBalance(sol);\r\n\r\n } catch (error) {\r\n setSolBalance(0);\r\n } finally {\r\n setIsFetchingBalance(false);\r\n fetching.current = false;\r\n }\r\n }\r\n\r\n useEffect(() => {\r\n if (showSolBalance && selectedAccount && client) {\r\n fetchSolBalance();\r\n }\r\n }, [selectedAccount, client, showSolBalance]);\r\n\r\n if (view === 'wallet') {\r\n return (\r\n <motion.div\r\n initial={{ opacity: 0 }}\r\n animate={{ opacity: 1 }}\r\n exit={{ opacity: 0 }}\r\n transition={{ duration: 0.2 }}\r\n className={clsx(styles.WalletDropdown, CN_ConnectButton)}\r\n data-theme={theme}\r\n >\r\n {/* Header with Avatar and Address */}\r\n <div className={styles.Header}>\r\n <div className={styles.addressAndAvatar}>\r\n <Avatar\r\n width={48}\r\n height={48}\r\n src={walletIcon}\r\n alt={walletName}\r\n />\r\n <div className={styles.address}>\r\n <span className={styles.shortAddress}>{shortAddress}</span>\r\n <span className={styles.walletName}>{walletName}</span>\r\n </div>\r\n </div>\r\n\r\n <div className={styles.actions}>\r\n <Button\r\n type=\"button\"\r\n onClick={handleCopy}\r\n variant=\"outline\"\r\n size=\"icon\"\r\n className=\"rounded-full\"\r\n title={copied ? 'Copied!' : 'Copy address'}\r\n >\r\n {copied ?\r\n <Check className={styles.checkIcon} /> :\r\n <Copy />\r\n }\r\n </Button>\r\n\r\n {/* Network Selector Globe Button */}\r\n {allowNetworkSwitch && (\r\n <ClusterElement\r\n render={({ cluster }) => (\r\n <Button\r\n type=\"button\"\r\n variant=\"outline\"\r\n size=\"icon\"\r\n onClick={() => setView('network')}\r\n title={`Network: ${cluster?.label || 'Unknown'}`}\r\n >\r\n <Globe />\r\n <span\r\n className={styles.networkIndicator}\r\n style={{ background: networkColor[cluster?.id || 'solana:mainnet'] }}\r\n />\r\n </Button>\r\n )}\r\n />\r\n )}\r\n </div>\r\n </div>\r\n\r\n {showSolBalance && (\r\n <div className={styles.balanceSection}>\r\n <div\r\n className={styles.balanceHeader}\r\n >\r\n <span className={styles.balanceLabel}>Balance</span>\r\n <button\r\n onClick={() => fetchSolBalance()}\r\n disabled={isFetchingBalance}\r\n title=\"Refresh balance\"\r\n className={styles.refreshButton}\r\n data-loading={isFetchingBalance}\r\n >\r\n <RefreshCw\r\n className={styles.refreshIcon}\r\n />\r\n </button>\r\n </div>\r\n <div className={styles.balanceValue}>\r\n {isFetchingBalance ? (\r\n <div className={styles.balanceLoading} />\r\n ) : solBalance !== null ? (\r\n `${solBalance.toFixed(4)} SOL`\r\n ) : (\r\n '-- SOL'\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n\r\n <DisconnectElement\r\n render={({ disconnect, disconnecting }) => (\r\n <Button\r\n variant=\"default\"\r\n className={styles.disconnectButton}\r\n onClick={disconnect}\r\n disabled={disconnecting}\r\n >\r\n <LogOut className={styles.disconnectIcon} />\r\n {disconnecting ? 'Disconnecting...' : 'Disconnect'}\r\n </Button>\r\n )}\r\n />\r\n </motion.div>\r\n )\r\n }\r\n\r\n //network switch view\r\n if (view === 'network') {\r\n console.count('Network view rendered');\r\n return (\r\n <motion.div\r\n initial={{ opacity: 0 }}\r\n animate={{ opacity: 1 }}\r\n exit={{ opacity: 0 }}\r\n transition={{ duration: 0.2 }}\r\n className={clsx(styles.WalletDropdown, CN_ConnectButton)}\r\n data-theme={theme}\r\n >\r\n {/* Header */}\r\n <div className={styles.NetworkHeader}>\r\n <Button\r\n type=\"button\"\r\n variant=\"outline\"\r\n size=\"icon\"\r\n onClick={() => setView('wallet')}\r\n title={`Network: Back to Wallet`}\r\n className={styles.backButton}\r\n >\r\n <ChevronLeft />\r\n </Button>\r\n <span>Network Settings</span>\r\n </div>\r\n\r\n {/* Network Options */}\r\n <ClusterElement\r\n render={({ cluster, clusters, setCluster }) => {\r\n const currentClusterId = (cluster as { id?: string })?.id || 'solana:mainnet';\r\n return (\r\n <div className={styles.networkOptions}>\r\n {clusters.map((network, index) => {\r\n const isSelected = currentClusterId === network.id;\r\n return (\r\n <div\r\n key={network.id}\r\n role=\"button\"\r\n tabIndex={0}\r\n onClick={() => setCluster(network.id)}\r\n onKeyDown={e => {\r\n if (e.key === 'Enter' || e.key === ' ') {\r\n e.preventDefault();\r\n setCluster(network.id);\r\n }\r\n }}\r\n className={styles.networkButton}\r\n >\r\n <div className={styles.networkName}>\r\n <span\r\n className={styles.networkColor}\r\n style={{ background: networkColor[network.id] }}\r\n />\r\n <span className={styles.networkLabel}>{network.label}</span>\r\n </div>\r\n <div className={styles.checkMark} data-selected={isSelected}>\r\n {isSelected && <Check />}\r\n </div>\r\n </div>\r\n );\r\n })}\r\n </div>\r\n );\r\n }}\r\n />\r\n </motion.div>\r\n )\r\n }\r\n}\r\n\r\nexport default WalletDropdown","import { useState } from 'react';\r\nimport styles from './Avatar.module.css';\r\nimport { Wallet } from 'lucide-react';\r\ninterface AvatarProps {\r\n height?: number | string;\r\n width?: number | string;\r\n src?: string;\r\n alt?: string;\r\n theme?: 'light' | 'dark';\r\n}\r\nexport function Avatar({\r\n height,\r\n width,\r\n src,\r\n alt,\r\n theme = 'light',\r\n}: AvatarProps) {\r\n const [hasError, setHasError] = useState(false);\r\n return (\r\n <div className={styles.avatar} data-theme={theme}>\r\n {src && !hasError ? (\r\n <img\r\n height={height}\r\n width={width}\r\n src={src}\r\n alt={alt || \"Avatar\"}\r\n onError={() => setHasError(true)}\r\n />\r\n ) : (\r\n <div className={styles.fallback} style={{ height, width }}>\r\n <Wallet />\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","import { Avatar } from './Avatar';\r\n\r\nexport default Avatar;","'use client';\r\n\r\nimport * as React from 'react';\r\nimport { Button as BaseButton } from '@base-ui/react/button';\r\nimport styles from './Button.module.css';\r\n\r\n// 1. Define Types\r\ntype ButtonVariant = 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link';\r\ntype ButtonSize = 'default' | 'sm' | 'lg' | 'icon';\r\n\r\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\r\n variant?: ButtonVariant;\r\n size?: ButtonSize;\r\n}\r\n\r\n// 2. The Component\r\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\r\n ({ className, variant = 'default', size = 'default', ...props }, ref) => {\r\n return (\r\n <BaseButton\r\n ref={ref}\r\n\r\n className={`${styles.button} ${className || ''}`}\r\n data-variant={variant}\r\n data-size={size}\r\n\r\n {...props}\r\n />\r\n );\r\n }\r\n);\r\nButton.displayName = 'Button';\r\n\r\nexport default Button;","import Button from \"./Button\";\r\n\r\nexport default Button;","import WalletDropdown from './WalletDropdown';\r\n\r\n\r\nexport default WalletDropdown"],"mappings":"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","names":["useState","styles","styles","jsx","Button_default","jsx","useState","styles","Button_default","WalletDropdown_default"]}
1
+ {"version":3,"sources":["../src/components/WalletDropdown/WalletDropdown.tsx","../src/components/shared/Avatar/Avatar.tsx","../src/components/shared/Avatar/index.ts","../src/components/shared/Button/Button.tsx","../src/components/shared/Button/index.ts","../src/utils/fetchBalance.tsx","../src/components/WalletDropdown/index.ts"],"sourcesContent":["import { useEffect, useRef, useState } from 'react'\nimport { createSolanaRpc, isAddress } from '@solana/kit';\nimport { findAssociatedTokenPda, TOKEN_PROGRAM_ADDRESS } from '@solana-program/token';\nimport { TOKEN_2022_PROGRAM_ADDRESS } from '@solana-program/token-2022';\nimport styles from './WalletDropdown.module.css'\nimport { motion } from 'motion/react';\nimport Avatar from '@shared/Avatar';\nimport { Check, ChevronLeft, Copy, Globe, LogOut, RefreshCw } from 'lucide-react';\nimport Button from '@shared/Button';\nimport { address, ClusterElement, DisconnectElement, lamportsToSol, useConnectorClient } from '@solana/connector';\nimport { clsx } from 'clsx';\nimport { getSolBalance, getTokenBalance } from 'src/utils/fetchBalance';\n\ninterface WalletDropdownProps {\n CN_ConnectButton?: string;\n selectedAccount: string;\n walletIcon?: string;\n walletName: string;\n theme?: 'light' | 'dark';\n\n allowNetworkSwitch?: boolean;\n showSolBalance?: boolean;\n showDefaultToken?: {\n address: string;\n symbol: string;\n }\n}\n\ntype DropdownView = 'wallet' | 'network';\n\nconst networkColor: Record<string, string> = {\n 'solana:mainnet': '#00c950',\n 'solana:devnet': '#2b7fff',\n 'solana:testnet': '#f0b100',\n 'solana:localnet': '#ff3b3b',\n};\n\nexport function WalletDropdown(props: WalletDropdownProps) {\n const client = useConnectorClient();\n\n const { CN_ConnectButton,\n selectedAccount,\n walletIcon,\n walletName,\n theme,\n allowNetworkSwitch,\n showSolBalance,\n showDefaultToken\n } = props\n\n const [view, setView] = useState<DropdownView>('wallet');\n const [copied, setCopied] = useState(false);\n\n const fetchingSolBalance = useRef(false);\n const [isFetchingBalance, setIsFetchingBalance] = useState(false);\n\n const fetchingDefaultToken = useRef(false);\n const [isFetchingDefaultTokenBalance, setIsFetchingDefaultTokenBalance] = useState(false);\n\n const [solBalance, setSolBalance] = useState<number | null>(null);\n const [defaultTokenBalance, setDefaultTokenBalance] = useState<number | null>(null);\n\n const shortAddress = `${selectedAccount.slice(0, 4)}...${selectedAccount.slice(-4)}`;\n\n async function handleCopy() {\n try {\n await navigator.clipboard.writeText(selectedAccount);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch (error) {\n setCopied(false);\n console.error('Failed to copy to clipboard:', error);\n }\n }\n\n async function fetchSolBalance() {\n if (!client || fetchingSolBalance.current) return;\n setIsFetchingBalance(true);\n fetchingSolBalance.current = true;\n\n const solBalance = await getSolBalance(client, selectedAccount);\n setSolBalance(solBalance);\n\n setIsFetchingBalance(false);\n fetchingSolBalance.current = false;\n }\n\n async function fetchDefaultTokenBalance() {\n if (!showDefaultToken || !showDefaultToken.address || !client || fetchingDefaultToken.current) return;\n\n const isValidAddress = isAddress(showDefaultToken.address);\n if (!isValidAddress) {\n console.error('Invalid default token address:', showDefaultToken);\n return\n }\n\n setIsFetchingDefaultTokenBalance(true);\n fetchingDefaultToken.current = true;\n\n const tokenBalance = await getTokenBalance(client, selectedAccount, showDefaultToken.address);\n setDefaultTokenBalance(tokenBalance);\n\n setIsFetchingDefaultTokenBalance(false);\n fetchingDefaultToken.current = false;\n }\n\n useEffect(() => {\n if (showSolBalance && selectedAccount && client) {\n fetchSolBalance();\n }\n if (showDefaultToken && selectedAccount && client) {\n fetchDefaultTokenBalance();\n }\n }, [selectedAccount, client, showSolBalance, showDefaultToken]);\n\n if (view === 'wallet') {\n return (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.2 }}\n className={clsx(styles.WalletDropdown, CN_ConnectButton)}\n data-theme={theme}\n >\n {/* Header with Avatar and Address */}\n <div className={styles.Header}>\n <div className={styles.addressAndAvatar}>\n <Avatar\n width={48}\n height={48}\n src={walletIcon}\n alt={walletName}\n />\n <div className={styles.address}>\n <span className={styles.shortAddress}>{shortAddress}</span>\n <span className={styles.walletName}>{walletName}</span>\n </div>\n </div>\n\n <div className={styles.actions}>\n <Button\n type=\"button\"\n onClick={handleCopy}\n variant=\"outline\"\n size=\"icon\"\n className=\"rounded-full\"\n title={copied ? 'Copied!' : 'Copy address'}\n >\n {copied ?\n <Check className={styles.checkIcon} /> :\n <Copy />\n }\n </Button>\n\n {/* Network Selector Globe Button */}\n {allowNetworkSwitch && (\n <ClusterElement\n render={({ cluster }) => (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setView('network')}\n title={`Network: ${cluster?.label || 'Unknown'}`}\n >\n <Globe />\n <span\n className={styles.networkIndicator}\n style={{ background: networkColor[cluster?.id || 'solana:mainnet'] }}\n />\n </Button>\n )}\n />\n )}\n </div>\n </div>\n\n {showSolBalance && (\n <div className={styles.balanceSection}>\n <div\n className={styles.balanceHeader}\n >\n <span className={styles.balanceLabel}>Balance</span>\n <button\n onClick={() => fetchSolBalance()}\n disabled={isFetchingBalance}\n title=\"Refresh balance\"\n className={styles.refreshButton}\n data-loading={isFetchingBalance}\n >\n <RefreshCw\n className={styles.refreshIcon}\n />\n </button>\n </div>\n <div className={styles.balanceValue} title={String(solBalance) || \"0\"}>\n {isFetchingBalance ? (\n <div className={styles.balanceLoading} />\n ) : solBalance !== null ? (\n `${solBalance.toFixed(4)} SOL`\n ) : (\n '-- SOL'\n )}\n </div>\n </div>\n )}\n\n {showDefaultToken && (\n <div className={styles.balanceSection}>\n <div\n className={styles.balanceHeader}\n >\n <span className={styles.balanceLabel}>Balance</span>\n <button\n onClick={() => fetchDefaultTokenBalance()}\n disabled={isFetchingDefaultTokenBalance}\n title=\"Refresh balance\"\n className={styles.refreshButton}\n data-loading={isFetchingDefaultTokenBalance}\n >\n <RefreshCw\n className={styles.refreshIcon}\n />\n </button>\n </div>\n <div className={styles.balanceValue} title={String(defaultTokenBalance) || \"0\"}>\n {isFetchingDefaultTokenBalance ? (\n <div className={styles.balanceLoading} />\n ) : defaultTokenBalance !== null ? (\n `${defaultTokenBalance.toFixed(4)} ${showDefaultToken?.symbol || ''}`\n ) : (\n `-- ${showDefaultToken?.symbol || ''}`\n )}\n </div>\n </div>\n )}\n\n <DisconnectElement\n render={({ disconnect, disconnecting }) => (\n <Button\n variant=\"default\"\n className={styles.disconnectButton}\n onClick={disconnect}\n disabled={disconnecting}\n >\n <LogOut className={styles.disconnectIcon} />\n {disconnecting ? 'Disconnecting...' : 'Disconnect'}\n </Button>\n )}\n />\n </motion.div>\n )\n }\n\n //network switch view\n if (view === 'network') {\n return (\n <motion.div\n initial={{ opacity: 0 }}\n animate={{ opacity: 1 }}\n exit={{ opacity: 0 }}\n transition={{ duration: 0.2 }}\n className={clsx(styles.WalletDropdown, CN_ConnectButton)}\n data-theme={theme}\n >\n {/* Header */}\n <div className={styles.NetworkHeader}>\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"icon\"\n onClick={() => setView('wallet')}\n title={`Network: Back to Wallet`}\n className={styles.backButton}\n >\n <ChevronLeft />\n </Button>\n <span>Network Settings</span>\n </div>\n\n {/* Network Options */}\n <ClusterElement\n render={({ cluster, clusters, setCluster }) => {\n const currentClusterId = (cluster as { id?: string })?.id || 'solana:mainnet';\n return (\n <div className={styles.networkOptions}>\n {clusters.map((network, index) => {\n const isSelected = currentClusterId === network.id;\n return (\n <div\n key={network.id}\n role=\"button\"\n tabIndex={0}\n onClick={() => setCluster(network.id)}\n onKeyDown={e => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n setCluster(network.id);\n }\n }}\n className={styles.networkButton}\n >\n <div className={styles.networkName}>\n <span\n className={styles.networkColor}\n style={{ background: networkColor[network.id] }}\n />\n <span className={styles.networkLabel}>{network.label}</span>\n </div>\n <div className={styles.checkMark} data-selected={isSelected}>\n {isSelected && <Check />}\n </div>\n </div>\n );\n })}\n </div>\n );\n }}\n />\n </motion.div>\n )\n }\n}\n\nexport default WalletDropdown","import { useState } from 'react';\nimport styles from './Avatar.module.css';\nimport { Wallet } from 'lucide-react';\ninterface AvatarProps {\n height?: number | string;\n width?: number | string;\n src?: string;\n alt?: string;\n theme?: 'light' | 'dark';\n}\nexport function Avatar({\n height,\n width,\n src,\n alt,\n theme = 'light',\n}: AvatarProps) {\n const [hasError, setHasError] = useState(false);\n return (\n <div className={styles.avatar} data-theme={theme}>\n {src && !hasError ? (\n <img\n height={height}\n width={width}\n src={src}\n alt={alt || \"Avatar\"}\n onError={() => setHasError(true)}\n />\n ) : (\n <div className={styles.fallback} style={{ height, width }}>\n <Wallet />\n </div>\n )}\n </div>\n );\n}\n","import { Avatar } from './Avatar';\n\nexport default Avatar;","'use client';\n\nimport * as React from 'react';\nimport { Button as BaseButton } from '@base-ui/react/button';\nimport styles from './Button.module.css';\n\n// 1. Define Types\ntype ButtonVariant = 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link';\ntype ButtonSize = 'default' | 'sm' | 'lg' | 'icon';\n\nexport interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n}\n\n// 2. The Component\nconst Button = React.forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant = 'default', size = 'default', ...props }, ref) => {\n return (\n <BaseButton\n ref={ref}\n\n className={`${styles.button} ${className || ''}`}\n data-variant={variant}\n data-size={size}\n\n {...props}\n />\n );\n }\n);\nButton.displayName = 'Button';\n\nexport default Button;","import Button from \"./Button\";\n\nexport default Button;","import { findAssociatedTokenPda } from \"@solana-program/token\";\nimport { address, ConnectorClient, lamportsToSol } from \"@solana/connector\";\nimport { createSolanaRpc } from \"@solana/kit\";\n\nexport async function getSolBalance(\n client: ConnectorClient,\n pubkey: string\n): Promise<number> {\n let balance = 0;\n try {\n const rpcUrl = client.getRpcUrl();\n if (!rpcUrl) {\n console.error(\"RPC URL is not available from the ConnectorClient.\");\n return 0;\n }\n const pubkeyAddress = address(pubkey);\n const rpc = createSolanaRpc(rpcUrl);\n const balanceResponse = await rpc.getBalance(pubkeyAddress).send();\n balance = lamportsToSol(balanceResponse.value);\n } catch (error) {\n console.error(\"Error fetching SOL balance:\", error);\n } finally {\n return balance;\n }\n}\n\nexport async function getTokenBalance(\n client: ConnectorClient,\n pubkey: string,\n mintAddress: string\n): Promise<number> {\n let balance = 0;\n try {\n const rpcUrl = client.getRpcUrl();\n if (!rpcUrl) {\n console.error(\"RPC URL is not available from the ConnectorClient.\");\n return 0;\n }\n const pubkeyAddress = address(pubkey);\n const mintPubkey = address(mintAddress);\n const rpc = createSolanaRpc(rpcUrl);\n\n const mintInfo = await rpc.getAccountInfo(mintPubkey).send();\n const ownerProgram = mintInfo.value?.owner;\n if (!ownerProgram) {\n throw new Error('Failed to fetch mint account info');\n }\n const tokenProgram = address(ownerProgram)\n const [tokenPDA] = await findAssociatedTokenPda({\n mint: mintPubkey,\n owner: pubkeyAddress,\n tokenProgram: tokenProgram\n });\n const tokenBalance = await rpc.getTokenAccountBalance(tokenPDA).send();\n\n if (tokenBalance.value) {\n balance = parseFloat(tokenBalance.value.uiAmountString);\n }\n } catch (error) {\n console.error(\"Error fetching token balance:\", error);\n } finally {\n return balance;\n }\n}","import WalletDropdown from './WalletDropdown';\n\n\nexport default WalletDropdown"],"mappings":"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","names":["useState","styles","styles","jsx","Button_default","jsx","useState","solBalance","styles","Button_default","WalletDropdown_default"]}