@algobright/solana-connector 0.1.1 → 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.
@@ -869,12 +869,70 @@ import { ChevronDown } from "lucide-react";
869
869
 
870
870
  // src/components/WalletDropdown/WalletDropdown.tsx
871
871
  import { useEffect as useEffect2, useRef, useState as useState3 } from "react";
872
- import styles8 from "./WalletDropdown.module-A6KHWKGK.module.css";
872
+ import { isAddress } from "@solana/kit";
873
+ import styles8 from "./WalletDropdown.module-DOK7CUOQ.module.css";
873
874
  import { motion } from "motion/react";
874
875
  import { Check as Check2, ChevronLeft as ChevronLeft2, Copy as Copy2, Globe, LogOut, RefreshCw } from "lucide-react";
875
- import { address, ClusterElement, DisconnectElement, lamportsToSol, useConnectorClient } from "@solana/connector";
876
- import { createSolanaRpc } from "@solana/kit";
876
+ import { ClusterElement, DisconnectElement, useConnectorClient } from "@solana/connector";
877
877
  import { clsx as clsx3 } from "clsx";
878
+
879
+ // src/utils/fetchBalance.tsx
880
+ import { findAssociatedTokenPda } from "@solana-program/token";
881
+ import { address, lamportsToSol } from "@solana/connector";
882
+ import { createSolanaRpc } from "@solana/kit";
883
+ async function getSolBalance(client, pubkey) {
884
+ let balance = 0;
885
+ try {
886
+ const rpcUrl = client.getRpcUrl();
887
+ if (!rpcUrl) {
888
+ console.error("RPC URL is not available from the ConnectorClient.");
889
+ return 0;
890
+ }
891
+ const pubkeyAddress = address(pubkey);
892
+ const rpc = createSolanaRpc(rpcUrl);
893
+ const balanceResponse = await rpc.getBalance(pubkeyAddress).send();
894
+ balance = lamportsToSol(balanceResponse.value);
895
+ } catch (error) {
896
+ console.error("Error fetching SOL balance:", error);
897
+ } finally {
898
+ return balance;
899
+ }
900
+ }
901
+ async function getTokenBalance(client, pubkey, mintAddress) {
902
+ var _a;
903
+ let balance = 0;
904
+ try {
905
+ const rpcUrl = client.getRpcUrl();
906
+ if (!rpcUrl) {
907
+ console.error("RPC URL is not available from the ConnectorClient.");
908
+ return 0;
909
+ }
910
+ const pubkeyAddress = address(pubkey);
911
+ const mintPubkey = address(mintAddress);
912
+ const rpc = createSolanaRpc(rpcUrl);
913
+ const mintInfo = await rpc.getAccountInfo(mintPubkey).send();
914
+ const ownerProgram = (_a = mintInfo.value) == null ? void 0 : _a.owner;
915
+ if (!ownerProgram) {
916
+ throw new Error("Failed to fetch mint account info");
917
+ }
918
+ const tokenProgram = address(ownerProgram);
919
+ const [tokenPDA] = await findAssociatedTokenPda({
920
+ mint: mintPubkey,
921
+ owner: pubkeyAddress,
922
+ tokenProgram
923
+ });
924
+ const tokenBalance = await rpc.getTokenAccountBalance(tokenPDA).send();
925
+ if (tokenBalance.value) {
926
+ balance = parseFloat(tokenBalance.value.uiAmountString);
927
+ }
928
+ } catch (error) {
929
+ console.error("Error fetching token balance:", error);
930
+ } finally {
931
+ return balance;
932
+ }
933
+ }
934
+
935
+ // src/components/WalletDropdown/WalletDropdown.tsx
878
936
  import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
879
937
  var networkColor = {
880
938
  "solana:mainnet": "#00c950",
@@ -884,12 +942,24 @@ var networkColor = {
884
942
  };
885
943
  function WalletDropdown(props) {
886
944
  const client = useConnectorClient();
887
- const { CN_ConnectButton, selectedAccount, walletIcon, walletName, theme, allowNetworkSwitch, showSolBalance } = props;
945
+ const {
946
+ CN_ConnectButton,
947
+ selectedAccount,
948
+ walletIcon,
949
+ walletName,
950
+ theme,
951
+ allowNetworkSwitch,
952
+ showSolBalance,
953
+ showDefaultToken
954
+ } = props;
888
955
  const [view, setView] = useState3("wallet");
889
956
  const [copied, setCopied] = useState3(false);
890
- const fetching = useRef(false);
957
+ const fetchingSolBalance = useRef(false);
891
958
  const [isFetchingBalance, setIsFetchingBalance] = useState3(false);
959
+ const fetchingDefaultToken = useRef(false);
960
+ const [isFetchingDefaultTokenBalance, setIsFetchingDefaultTokenBalance] = useState3(false);
892
961
  const [solBalance, setSolBalance] = useState3(null);
962
+ const [defaultTokenBalance, setDefaultTokenBalance] = useState3(null);
893
963
  const shortAddress = `${selectedAccount.slice(0, 4)}...${selectedAccount.slice(-4)}`;
894
964
  async function handleCopy() {
895
965
  try {
@@ -902,29 +972,36 @@ function WalletDropdown(props) {
902
972
  }
903
973
  }
904
974
  async function fetchSolBalance() {
905
- if (!client || fetching.current) return;
975
+ if (!client || fetchingSolBalance.current) return;
906
976
  setIsFetchingBalance(true);
907
- fetching.current = true;
908
- try {
909
- const rpcUrl = client.getRpcUrl();
910
- const pubkey = address(selectedAccount);
911
- if (!rpcUrl) throw new Error("No RPC endpoint configured");
912
- const rpc = createSolanaRpc(rpcUrl);
913
- const solLamports = (await rpc.getBalance(pubkey).send()).value || 0;
914
- const sol = lamportsToSol(solLamports);
915
- setSolBalance(sol);
916
- } catch (error) {
917
- setSolBalance(0);
918
- } finally {
919
- setIsFetchingBalance(false);
920
- fetching.current = false;
977
+ fetchingSolBalance.current = true;
978
+ const solBalance2 = await getSolBalance(client, selectedAccount);
979
+ setSolBalance(solBalance2);
980
+ setIsFetchingBalance(false);
981
+ fetchingSolBalance.current = false;
982
+ }
983
+ async function fetchDefaultTokenBalance() {
984
+ if (!showDefaultToken || !showDefaultToken.address || !client || fetchingDefaultToken.current) return;
985
+ const isValidAddress = isAddress(showDefaultToken.address);
986
+ if (!isValidAddress) {
987
+ console.error("Invalid default token address:", showDefaultToken);
988
+ return;
921
989
  }
990
+ setIsFetchingDefaultTokenBalance(true);
991
+ fetchingDefaultToken.current = true;
992
+ const tokenBalance = await getTokenBalance(client, selectedAccount, showDefaultToken.address);
993
+ setDefaultTokenBalance(tokenBalance);
994
+ setIsFetchingDefaultTokenBalance(false);
995
+ fetchingDefaultToken.current = false;
922
996
  }
923
997
  useEffect2(() => {
924
998
  if (showSolBalance && selectedAccount && client) {
925
999
  fetchSolBalance();
926
1000
  }
927
- }, [selectedAccount, client, showSolBalance]);
1001
+ if (showDefaultToken && selectedAccount && client) {
1002
+ fetchDefaultTokenBalance();
1003
+ }
1004
+ }, [selectedAccount, client, showSolBalance, showDefaultToken]);
928
1005
  if (view === "wallet") {
929
1006
  return /* @__PURE__ */ jsxs4(
930
1007
  motion.div,
@@ -1018,7 +1095,35 @@ function WalletDropdown(props) {
1018
1095
  ]
1019
1096
  }
1020
1097
  ),
1021
- /* @__PURE__ */ jsx9("div", { className: styles8.balanceValue, children: isFetchingBalance ? /* @__PURE__ */ jsx9("div", { className: styles8.balanceLoading }) : solBalance !== null ? `${solBalance.toFixed(4)} SOL` : "-- SOL" })
1098
+ /* @__PURE__ */ jsx9("div", { className: styles8.balanceValue, title: String(solBalance) || "0", children: isFetchingBalance ? /* @__PURE__ */ jsx9("div", { className: styles8.balanceLoading }) : solBalance !== null ? `${solBalance.toFixed(4)} SOL` : "-- SOL" })
1099
+ ] }),
1100
+ showDefaultToken && /* @__PURE__ */ jsxs4("div", { className: styles8.balanceSection, children: [
1101
+ /* @__PURE__ */ jsxs4(
1102
+ "div",
1103
+ {
1104
+ className: styles8.balanceHeader,
1105
+ children: [
1106
+ /* @__PURE__ */ jsx9("span", { className: styles8.balanceLabel, children: "Balance" }),
1107
+ /* @__PURE__ */ jsx9(
1108
+ "button",
1109
+ {
1110
+ onClick: () => fetchDefaultTokenBalance(),
1111
+ disabled: isFetchingDefaultTokenBalance,
1112
+ title: "Refresh balance",
1113
+ className: styles8.refreshButton,
1114
+ "data-loading": isFetchingDefaultTokenBalance,
1115
+ children: /* @__PURE__ */ jsx9(
1116
+ RefreshCw,
1117
+ {
1118
+ className: styles8.refreshIcon
1119
+ }
1120
+ )
1121
+ }
1122
+ )
1123
+ ]
1124
+ }
1125
+ ),
1126
+ /* @__PURE__ */ jsx9("div", { className: styles8.balanceValue, title: String(defaultTokenBalance) || "0", children: isFetchingDefaultTokenBalance ? /* @__PURE__ */ jsx9("div", { className: styles8.balanceLoading }) : defaultTokenBalance !== null ? `${defaultTokenBalance.toFixed(4)} ${(showDefaultToken == null ? void 0 : showDefaultToken.symbol) || ""}` : `-- ${(showDefaultToken == null ? void 0 : showDefaultToken.symbol) || ""}` })
1022
1127
  ] }),
1023
1128
  /* @__PURE__ */ jsx9(
1024
1129
  DisconnectElement,
@@ -1043,7 +1148,6 @@ function WalletDropdown(props) {
1043
1148
  );
1044
1149
  }
1045
1150
  if (view === "network") {
1046
- console.count("Network view rendered");
1047
1151
  return /* @__PURE__ */ jsxs4(
1048
1152
  motion.div,
1049
1153
  {
@@ -1128,7 +1232,8 @@ function ConnectButton(props) {
1128
1232
  CN_ConnectButton,
1129
1233
  connectText = "Connect Wallet",
1130
1234
  connectingText = "Connecting...",
1131
- showSolBalance = false
1235
+ showSolBalance = false,
1236
+ showDefaultToken
1132
1237
  } = props;
1133
1238
  const [isModalOpen, setIsModalOpen] = useState4(false);
1134
1239
  const { isConnected, isConnecting, account, connector, walletConnectUri, clearWalletConnectUri } = useConnector2();
@@ -1168,7 +1273,8 @@ function ConnectButton(props) {
1168
1273
  walletName: connector.name,
1169
1274
  allowNetworkSwitch: true,
1170
1275
  theme,
1171
- showSolBalance
1276
+ showSolBalance,
1277
+ showDefaultToken
1172
1278
  }
1173
1279
  ) }) }) })
1174
1280
  ] });