@bze/bze-ui-kit 0.4.1 → 0.4.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.
package/dist/index.mjs CHANGED
@@ -3913,9 +3913,104 @@ var useTx = (chainName, isCosmos, isIBC) => {
3913
3913
  };
3914
3914
  };
3915
3915
 
3916
+ // src/hooks/useValidatorLogos.ts
3917
+ import { useCallback as useCallback12, useEffect as useEffect3, useRef as useRef2, useState as useState4 } from "react";
3918
+ var KEYBASE_API_URL = "https://keybase.io/_/api/1.0/user/lookup.json";
3919
+ var LOGOS_STORAGE_KEY = "validator_logos";
3920
+ var LOGOS_TTL = 24 * 60 * 60 * 1e3;
3921
+ var useValidatorLogos = (validators) => {
3922
+ const [logos, setLogos] = useState4({});
3923
+ const [isLoading, setIsLoading] = useState4(false);
3924
+ const fetchedRef = useRef2(false);
3925
+ const validatorCountRef = useRef2(0);
3926
+ const fetchLogos = useCallback12(async (identities) => {
3927
+ if (identities.length === 0) return {};
3928
+ let cached = null;
3929
+ try {
3930
+ const raw = typeof window !== "undefined" ? localStorage.getItem(LOGOS_STORAGE_KEY) : null;
3931
+ if (raw) {
3932
+ const parsed = JSON.parse(raw);
3933
+ if (parsed && typeof parsed === "object" && parsed.data && (!parsed.expiry || Date.now() < parsed.expiry)) {
3934
+ cached = parsed.data;
3935
+ }
3936
+ }
3937
+ } catch (e) {
3938
+ }
3939
+ if (cached) {
3940
+ const allCached = identities.every(
3941
+ (v) => v.operatorAddress in cached
3942
+ );
3943
+ if (allCached) {
3944
+ return cached;
3945
+ }
3946
+ }
3947
+ const result = cached != null ? cached : {};
3948
+ const toFetch = identities.filter((v) => !(v.operatorAddress in result));
3949
+ if (toFetch.length === 0) return result;
3950
+ const chunkSize = 20;
3951
+ for (let i = 0; i < toFetch.length; i += chunkSize) {
3952
+ const chunk = toFetch.slice(i, i + chunkSize);
3953
+ const chunkResults = await Promise.all(
3954
+ chunk.map(async ({ operatorAddress, identity }) => {
3955
+ var _a2, _b2, _c, _d, _e;
3956
+ if (!identity) {
3957
+ return { operatorAddress, url: "" };
3958
+ }
3959
+ try {
3960
+ const resp = await fetch(
3961
+ `${KEYBASE_API_URL}?key_suffix=${encodeURIComponent(identity)}&fields=pictures`
3962
+ );
3963
+ const data = await resp.json();
3964
+ const url = (_e = (_d = (_c = (_b2 = (_a2 = data == null ? void 0 : data.them) == null ? void 0 : _a2[0]) == null ? void 0 : _b2.pictures) == null ? void 0 : _c.primary) == null ? void 0 : _d.url) != null ? _e : "";
3965
+ return { operatorAddress, url };
3966
+ } catch (e) {
3967
+ return { operatorAddress, url: "" };
3968
+ }
3969
+ })
3970
+ );
3971
+ for (const { operatorAddress, url } of chunkResults) {
3972
+ result[operatorAddress] = url;
3973
+ }
3974
+ if (i + chunkSize < toFetch.length) {
3975
+ await new Promise((resolve) => setTimeout(resolve, 500));
3976
+ }
3977
+ }
3978
+ try {
3979
+ if (typeof window !== "undefined") {
3980
+ localStorage.setItem(LOGOS_STORAGE_KEY, JSON.stringify({
3981
+ data: result,
3982
+ expiry: Date.now() + LOGOS_TTL
3983
+ }));
3984
+ }
3985
+ } catch (e) {
3986
+ }
3987
+ return result;
3988
+ }, []);
3989
+ useEffect3(() => {
3990
+ if (!validators || validators.length === 0) return;
3991
+ if (fetchedRef.current && validatorCountRef.current === validators.length) return;
3992
+ const identities = validators.map((v) => {
3993
+ var _a2, _b2;
3994
+ return {
3995
+ operatorAddress: v.operator_address,
3996
+ identity: (_b2 = (_a2 = v.description) == null ? void 0 : _a2.identity) != null ? _b2 : ""
3997
+ };
3998
+ });
3999
+ setIsLoading(true);
4000
+ fetchedRef.current = true;
4001
+ validatorCountRef.current = validators.length;
4002
+ fetchLogos(identities).then((result) => {
4003
+ setLogos(result);
4004
+ }).catch(console.error).finally(() => {
4005
+ setIsLoading(false);
4006
+ });
4007
+ }, [validators, fetchLogos]);
4008
+ return { logos, isLoading };
4009
+ };
4010
+
3916
4011
  // src/components/highlight.tsx
3917
4012
  import { Text } from "@chakra-ui/react";
3918
- import { useEffect as useEffect3, useRef as useRef2, useState as useState4 } from "react";
4013
+ import { useEffect as useEffect4, useRef as useRef3, useState as useState5 } from "react";
3919
4014
  import { jsx as jsx2 } from "react/jsx-runtime";
3920
4015
  var HighlightText = (_a2) => {
3921
4016
  var _b2 = _a2, {
@@ -3931,14 +4026,14 @@ var HighlightText = (_a2) => {
3931
4026
  "highlightIntensity",
3932
4027
  "children"
3933
4028
  ]);
3934
- const [isHighlighted, setIsHighlighted] = useState4(false);
3935
- const isMountedRef = useRef2(false);
3936
- const timeoutRef = useRef2(void 0);
4029
+ const [isHighlighted, setIsHighlighted] = useState5(false);
4030
+ const isMountedRef = useRef3(false);
4031
+ const timeoutRef = useRef3(void 0);
3937
4032
  const childrenString = String(children);
3938
- const previousValueRef = useRef2(childrenString);
4033
+ const previousValueRef = useRef3(childrenString);
3939
4034
  const highlightOpacity = highlightIntensity === "subtle" ? "15" : "50";
3940
4035
  const boxShadowStrength = highlightIntensity === "subtle" ? "10" : "25";
3941
- useEffect3(() => {
4036
+ useEffect4(() => {
3942
4037
  if (!isMountedRef.current) {
3943
4038
  isMountedRef.current = true;
3944
4039
  if (highlightOnMount) {
@@ -3984,10 +4079,10 @@ var HighlightText = (_a2) => {
3984
4079
  // src/components/sidebar/sidebar.tsx
3985
4080
  import { Icon, IconButton, Portal as Portal2 } from "@chakra-ui/react";
3986
4081
  import { LuX } from "react-icons/lu";
3987
- import { useState as useState5 } from "react";
4082
+ import { useState as useState6 } from "react";
3988
4083
  import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
3989
4084
  var Sidebar = ({ children, trigger, ariaLabel }) => {
3990
- const [isOpen, setIsOpen] = useState5(false);
4085
+ const [isOpen, setIsOpen] = useState6(false);
3991
4086
  const handleTriggerClick = () => {
3992
4087
  setIsOpen(true);
3993
4088
  };
@@ -4111,7 +4206,7 @@ import {
4111
4206
  } from "@chakra-ui/react";
4112
4207
  import { Select, Portal as Portal3 } from "@chakra-ui/react";
4113
4208
  import { useTheme } from "next-themes";
4114
- import { useState as useState6, useEffect as useEffect4, useMemo as useMemo13, useCallback as useCallback12 } from "react";
4209
+ import { useState as useState7, useEffect as useEffect5, useMemo as useMemo13, useCallback as useCallback13 } from "react";
4115
4210
  import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
4116
4211
  var SettingsSidebarContent = ({ accentColor = "blue" }) => {
4117
4212
  const { setTheme, resolvedTheme } = useTheme();
@@ -4119,19 +4214,19 @@ var SettingsSidebarContent = ({ accentColor = "blue" }) => {
4119
4214
  const { settings, isLoaded, updateEndpoints, updatePreferredFeeDenom, defaultSettings } = useSettings();
4120
4215
  const { connectionType } = useConnectionType();
4121
4216
  const { feeTokens, isLoading: feeTokensLoading } = useFeeTokens();
4122
- const [restEndpoint, setRestEndpoint] = useState6("");
4123
- const [rpcEndpoint, setRpcEndpoint] = useState6("");
4124
- const [isValidating, setIsValidating] = useState6(false);
4125
- const [validationResults, setValidationResults] = useState6({});
4126
- const [preferredFeeDenom, setPreferredFeeDenom] = useState6(void 0);
4127
- useEffect4(() => {
4217
+ const [restEndpoint, setRestEndpoint] = useState7("");
4218
+ const [rpcEndpoint, setRpcEndpoint] = useState7("");
4219
+ const [isValidating, setIsValidating] = useState7(false);
4220
+ const [validationResults, setValidationResults] = useState7({});
4221
+ const [preferredFeeDenom, setPreferredFeeDenom] = useState7(void 0);
4222
+ useEffect5(() => {
4128
4223
  if (isLoaded) {
4129
4224
  setRestEndpoint(settings.endpoints.restEndpoint);
4130
4225
  setRpcEndpoint(settings.endpoints.rpcEndpoint);
4131
4226
  setPreferredFeeDenom(settings.preferredFeeDenom || getChainNativeAssetDenom());
4132
4227
  }
4133
4228
  }, [isLoaded, settings]);
4134
- const handleValidateEndpoints = useCallback12(async (rest, rpc) => {
4229
+ const handleValidateEndpoints = useCallback13(async (rest, rpc) => {
4135
4230
  setIsValidating(true);
4136
4231
  setValidationResults({});
4137
4232
  try {
@@ -4151,7 +4246,7 @@ var SettingsSidebarContent = ({ accentColor = "blue" }) => {
4151
4246
  setTimeout(() => setValidationResults({}), 1e4);
4152
4247
  }
4153
4248
  }, []);
4154
- const handleSaveSettings = useCallback12(async (rest, rpc, feeDenom) => {
4249
+ const handleSaveSettings = useCallback13(async (rest, rpc, feeDenom) => {
4155
4250
  setValidationResults({});
4156
4251
  const results = await validateEndpoints(rest, rpc);
4157
4252
  if (!results.isValid) {
@@ -4171,7 +4266,7 @@ var SettingsSidebarContent = ({ accentColor = "blue" }) => {
4171
4266
  toast.success("Success!", "Settings have been saved.");
4172
4267
  }
4173
4268
  }, []);
4174
- const handleResetToDefaults = useCallback12(() => {
4269
+ const handleResetToDefaults = useCallback13(() => {
4175
4270
  setRestEndpoint(defaultSettings.endpoints.restEndpoint);
4176
4271
  setRpcEndpoint(defaultSettings.endpoints.rpcEndpoint);
4177
4272
  setPreferredFeeDenom(defaultSettings.preferredFeeDenom);
@@ -4204,7 +4299,7 @@ var SettingsSidebarContent = ({ accentColor = "blue" }) => {
4204
4299
  name: token.ticker || token.name
4205
4300
  }))
4206
4301
  }), [feeTokens]);
4207
- const handleFeeTokenChange = useCallback12((denom) => {
4302
+ const handleFeeTokenChange = useCallback13((denom) => {
4208
4303
  setPreferredFeeDenom(denom || void 0);
4209
4304
  }, []);
4210
4305
  const hasUnsavedChanges = restEndpoint !== settings.endpoints.restEndpoint || rpcEndpoint !== settings.endpoints.rpcEndpoint || preferredFeeDenom !== settings.preferredFeeDenom;
@@ -4380,7 +4475,7 @@ import {
4380
4475
  VStack as VStack2
4381
4476
  } from "@chakra-ui/react";
4382
4477
  import { LuCopy, LuExternalLink, LuX as LuX2 } from "react-icons/lu";
4383
- import { useCallback as useCallback13, useEffect as useEffect5, useMemo as useMemo14, useRef as useRef3, useState as useState7 } from "react";
4478
+ import { useCallback as useCallback14, useEffect as useEffect6, useMemo as useMemo14, useRef as useRef4, useState as useState8 } from "react";
4384
4479
  import { WalletState } from "@interchain-kit/core";
4385
4480
  import BigNumber14 from "bignumber.js";
4386
4481
  import { cosmos } from "@bze/bzejs";
@@ -4401,7 +4496,7 @@ var validateAmount = (amount, coin, onError) => {
4401
4496
  }
4402
4497
  };
4403
4498
  var BalanceItem = ({ asset, onClick, accentColor }) => {
4404
- const [showSendButton, setShowSendButton] = useState7(false);
4499
+ const [showSendButton, setShowSendButton] = useState8(false);
4405
4500
  const formattedBalanceAmount = useMemo14(() => {
4406
4501
  var _a2;
4407
4502
  return prettyAmount(uAmountToBigNumberAmount(asset.amount, (_a2 = asset.decimals) != null ? _a2 : 0));
@@ -4458,14 +4553,14 @@ var BalanceItem = ({ asset, onClick, accentColor }) => {
4458
4553
  );
4459
4554
  };
4460
4555
  var SendForm = ({ balances, onClose, selectedTicker, accentColor }) => {
4461
- const [isLoading, setIsLoading] = useState7(false);
4462
- const [selectedCoin, setSelectedCoin] = useState7();
4463
- const [sendAmount, setSendAmount] = useState7("");
4464
- const [sendAmountError, setSendAmountError] = useState7("");
4465
- const [recipient, setRecipient] = useState7("");
4466
- const [recipientError, setRecipientError] = useState7("");
4467
- const [memo, setMemo] = useState7("");
4468
- const [memoError, setMemoError] = useState7("");
4556
+ const [isLoading, setIsLoading] = useState8(false);
4557
+ const [selectedCoin, setSelectedCoin] = useState8();
4558
+ const [sendAmount, setSendAmount] = useState8("");
4559
+ const [sendAmountError, setSendAmountError] = useState8("");
4560
+ const [recipient, setRecipient] = useState8("");
4561
+ const [recipientError, setRecipientError] = useState8("");
4562
+ const [memo, setMemo] = useState8("");
4563
+ const [memoError, setMemoError] = useState8("");
4469
4564
  const { toast } = useToast();
4470
4565
  const { status, address } = useChain3(getChainName());
4471
4566
  const { tx } = useSDKTx(getChainName());
@@ -4482,13 +4577,13 @@ var SendForm = ({ balances, onClose, selectedTicker, accentColor }) => {
4482
4577
  const isValidForm = useMemo14(() => {
4483
4578
  return selectedCoin && memoError === "" && recipientError === "" && sendAmountError === "" && sendAmount !== "" && recipient !== "";
4484
4579
  }, [selectedCoin, memoError, recipientError, sendAmountError, sendAmount, recipient]);
4485
- const resetSendForm = useCallback13(() => {
4580
+ const resetSendForm = useCallback14(() => {
4486
4581
  setSelectedCoin(void 0);
4487
4582
  setSendAmount("");
4488
4583
  setRecipient("");
4489
4584
  setMemo("");
4490
4585
  }, []);
4491
- const handleSend = useCallback13(async () => {
4586
+ const handleSend = useCallback14(async () => {
4492
4587
  var _a2, _b2;
4493
4588
  if (!isValidForm) {
4494
4589
  toast.error("Can not send coins!", "Please check the input data.");
@@ -4513,11 +4608,11 @@ var SendForm = ({ balances, onClose, selectedTicker, accentColor }) => {
4513
4608
  setIsLoading(false);
4514
4609
  onClose();
4515
4610
  }, [address, memo, onClose, recipient, selectedCoin, sendAmount, status]);
4516
- const handleCancel = useCallback13(() => {
4611
+ const handleCancel = useCallback14(() => {
4517
4612
  resetSendForm();
4518
4613
  onClose();
4519
4614
  }, [onClose, resetSendForm]);
4520
- const onRecipientChange = useCallback13((recipient2) => {
4615
+ const onRecipientChange = useCallback14((recipient2) => {
4521
4616
  setRecipient(recipient2);
4522
4617
  if (recipient2.length === 0) {
4523
4618
  setRecipientError("");
@@ -4530,11 +4625,11 @@ var SendForm = ({ balances, onClose, selectedTicker, accentColor }) => {
4530
4625
  setRecipientError(validate.message);
4531
4626
  }
4532
4627
  }, []);
4533
- const onAmountChange = useCallback13((amount) => {
4628
+ const onAmountChange = useCallback14((amount) => {
4534
4629
  setSendAmount(sanitizeNumberInput(amount));
4535
4630
  setSendAmountError("");
4536
4631
  }, []);
4537
- const onCoinSelectChange = useCallback13((ticker) => {
4632
+ const onCoinSelectChange = useCallback14((ticker) => {
4538
4633
  if (ticker === "") return;
4539
4634
  const selectedCoin2 = balances.find((item) => item.ticker === ticker);
4540
4635
  if (selectedCoin2) {
@@ -4542,13 +4637,13 @@ var SendForm = ({ balances, onClose, selectedTicker, accentColor }) => {
4542
4637
  validateAmount(sendAmount, selectedCoin2, setSendAmountError);
4543
4638
  }
4544
4639
  }, [sendAmount, balances]);
4545
- const setMaxAmount = useCallback13(() => {
4640
+ const setMaxAmount = useCallback14(() => {
4546
4641
  if (!selectedCoin) return;
4547
4642
  const maxAmount = uAmountToBigNumberAmount(selectedCoin.amount, selectedCoin.decimals);
4548
4643
  onAmountChange(maxAmount.toString());
4549
4644
  validateAmount(maxAmount.toString(), selectedCoin, setSendAmountError);
4550
4645
  }, [selectedCoin, onAmountChange]);
4551
- const onMemoChange = useCallback13((memo2) => {
4646
+ const onMemoChange = useCallback14((memo2) => {
4552
4647
  setMemo(memo2);
4553
4648
  if (memo2.length > 256) {
4554
4649
  setMemoError("Memo must be less than or equal to 256 characters");
@@ -4556,7 +4651,7 @@ var SendForm = ({ balances, onClose, selectedTicker, accentColor }) => {
4556
4651
  setMemoError("");
4557
4652
  }
4558
4653
  }, []);
4559
- useEffect5(() => {
4654
+ useEffect6(() => {
4560
4655
  if (selectedTicker !== "") {
4561
4656
  onCoinSelectChange(selectedTicker);
4562
4657
  }
@@ -4719,11 +4814,11 @@ var SendForm = ({ balances, onClose, selectedTicker, accentColor }) => {
4719
4814
  ] });
4720
4815
  };
4721
4816
  var WalletSidebarContent = ({ accentColor = "blue" }) => {
4722
- const [viewState, setViewState] = useState7("balances");
4723
- const [isDisconnecting, setIsDisconnecting] = useState7(false);
4724
- const [showCopiedTooltip, setShowCopiedTooltip] = useState7(false);
4725
- const [clickedBalance, setClickedBalance] = useState7("");
4726
- const copyButtonRef = useRef3(null);
4817
+ const [viewState, setViewState] = useState8("balances");
4818
+ const [isDisconnecting, setIsDisconnecting] = useState8(false);
4819
+ const [showCopiedTooltip, setShowCopiedTooltip] = useState8(false);
4820
+ const [clickedBalance, setClickedBalance] = useState8("");
4821
+ const copyButtonRef = useRef4(null);
4727
4822
  const {
4728
4823
  status,
4729
4824
  username,
@@ -4759,15 +4854,15 @@ var WalletSidebarContent = ({ accentColor = "blue" }) => {
4759
4854
  setShowCopiedTooltip(true);
4760
4855
  setTimeout(() => setShowCopiedTooltip(false), 2e3);
4761
4856
  };
4762
- const handleCancel = useCallback13(() => {
4857
+ const handleCancel = useCallback14(() => {
4763
4858
  setViewState("balances");
4764
4859
  setClickedBalance("");
4765
4860
  }, []);
4766
- const onBalanceClick = useCallback13((ticker) => {
4861
+ const onBalanceClick = useCallback14((ticker) => {
4767
4862
  setClickedBalance(ticker);
4768
4863
  setViewState("send");
4769
4864
  }, []);
4770
- const handleDisconnectAll = useCallback13(async () => {
4865
+ const handleDisconnectAll = useCallback14(async () => {
4771
4866
  setIsDisconnecting(true);
4772
4867
  try {
4773
4868
  console.log("Disconnected from all chains");
@@ -5219,6 +5314,7 @@ export {
5219
5314
  useSettings,
5220
5315
  useSigningClient,
5221
5316
  useToast,
5317
+ useValidatorLogos,
5222
5318
  validateBZEBech32Address,
5223
5319
  validateBech32Address,
5224
5320
  validateEndpoints,