tiwiflix-wallet-connector 1.5.5 → 1.5.6

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.esm.js CHANGED
@@ -7530,7 +7530,7 @@ const defaultStyles = {
7530
7530
  fontFamily: 'Lexend, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
7531
7531
  boxShadow: '0 4px 14px 0 rgba(51, 150, 255, 0.39)',
7532
7532
  }};
7533
- const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className, style, showBalance = false, modalPosition = 'center', theme = 'auto', buttonText = 'Connect Wallet', fetchTransactions, getExplorerUrl, fetchBalance: fetchBalanceProp, }) => {
7533
+ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className, style, showBalance = false, modalPosition = 'center', theme = 'auto', buttonText = 'Connect Wallet Now', fetchTransactions, getExplorerUrl, fetchBalance: fetchBalanceProp, }) => {
7534
7534
  // Provide a default fetchBalance if not passed
7535
7535
  const fetchBalance = fetchBalanceProp || (async (account) => {
7536
7536
  // Default: return zero balance with symbol based on chain
@@ -7662,12 +7662,15 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7662
7662
  });
7663
7663
  // Stable USD value updater - only updates if value changes significantly
7664
7664
  const setUsdValueStable = useCallback((newValue) => {
7665
- // Set USD value immediately - only skip if value is the same
7666
7665
  setUsdValue((prevValue) => {
7667
7666
  // If new value is null/undefined and we have a previous value, keep it
7668
7667
  if ((newValue === null || newValue === undefined) && prevValue !== null) {
7669
7668
  return prevValue;
7670
7669
  }
7670
+ // Only update if value actually changed
7671
+ if (prevValue === newValue) {
7672
+ return prevValue;
7673
+ }
7671
7674
  // Otherwise set the new value
7672
7675
  return newValue;
7673
7676
  });
@@ -7881,6 +7884,7 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7881
7884
  const walletsRef = useRef(null);
7882
7885
  // Initialize and subscribe to events
7883
7886
  useEffect(() => {
7887
+ let isMounted = true;
7884
7888
  // Get initial state
7885
7889
  const initialState = connector.getState();
7886
7890
  setStatus(initialState.status);
@@ -7902,6 +7906,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7902
7906
  setBalanceLoading(false);
7903
7907
  }, 2000);
7904
7908
  connector.getAccount().then(async (acc) => {
7909
+ if (!isMounted)
7910
+ return;
7905
7911
  setAccount(acc);
7906
7912
  // Load balance when account is available
7907
7913
  if (acc && acc.chainType === 'ton') {
@@ -7912,10 +7918,14 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7912
7918
  fetchTONBalance(acc),
7913
7919
  fetchTONNFTs(acc)
7914
7920
  ]);
7921
+ if (!isMounted)
7922
+ return;
7915
7923
  clearTimeout(safetyTimeout);
7916
7924
  setIsInitializing(false);
7917
7925
  }
7918
7926
  catch (err) {
7927
+ if (!isMounted)
7928
+ return;
7919
7929
  clearTimeout(safetyTimeout);
7920
7930
  setIsInitializing(false);
7921
7931
  }
@@ -7924,6 +7934,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7924
7934
  try {
7925
7935
  setBalanceLoading(true);
7926
7936
  const hasRealBalance = await loadBalance();
7937
+ if (!isMounted)
7938
+ return;
7927
7939
  // Always stop loading state after balance fetch
7928
7940
  setBalanceLoading(false);
7929
7941
  clearTimeout(safetyTimeout);
@@ -7931,6 +7943,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7931
7943
  setIsInitializing(false);
7932
7944
  }
7933
7945
  catch (err) {
7946
+ if (!isMounted)
7947
+ return;
7934
7948
  setBalanceLoading(false);
7935
7949
  clearTimeout(safetyTimeout);
7936
7950
  // Always stop initializing on error
@@ -7942,6 +7956,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7942
7956
  const state = connector.getState();
7943
7957
  const stateTwcBalance = state.twcBalance;
7944
7958
  if (acc && stateTwcBalance && stateTwcBalance !== '0' && stateTwcBalance !== '0.00') {
7959
+ if (!isMounted)
7960
+ return;
7945
7961
  setTwcBalance(stateTwcBalance);
7946
7962
  setUsdValueStable(state.usdValue ?? null);
7947
7963
  // Save to cache
@@ -7955,6 +7971,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7955
7971
  // Try to load from cache as fallback
7956
7972
  const cached = loadTWCBalanceFromCache(acc.address);
7957
7973
  if (cached?.balance && cached.balance !== '0' && cached.balance !== '0.00') {
7974
+ if (!isMounted)
7975
+ return;
7958
7976
  setTwcBalance(cached.balance);
7959
7977
  setUsdValueStable(cached.usdValue);
7960
7978
  clearTimeout(safetyTimeout);
@@ -7964,6 +7982,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7964
7982
  // No real balance yet, but for EVM wallets, proactively fetch with retries
7965
7983
  if (acc.chainType === 'evm') {
7966
7984
  fetchTWCBalanceWithRetry(2, 200).then((result) => {
7985
+ if (!isMounted)
7986
+ return;
7967
7987
  if (result) {
7968
7988
  setTwcBalance(result.balance);
7969
7989
  setUsdValueStable(result.usdValue);
@@ -7980,6 +8000,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7980
8000
  setIsInitializing(false);
7981
8001
  }
7982
8002
  }).catch((error) => {
8003
+ if (!isMounted)
8004
+ return;
7983
8005
  // On error - show connected button with 0 balance
7984
8006
  setTwcBalance('0');
7985
8007
  clearTimeout(safetyTimeout);
@@ -7995,9 +8017,13 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7995
8017
  fetchTONBalance(acc),
7996
8018
  fetchTONNFTs(acc)
7997
8019
  ]).then(() => {
8020
+ if (!isMounted)
8021
+ return;
7998
8022
  clearTimeout(safetyTimeout);
7999
8023
  setIsInitializing(false);
8000
8024
  }).catch((err) => {
8025
+ if (!isMounted)
8026
+ return;
8001
8027
  clearTimeout(safetyTimeout);
8002
8028
  setIsInitializing(false);
8003
8029
  });
@@ -8005,6 +8031,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8005
8031
  else if (fetchBalance) {
8006
8032
  // For other non-EVM chains: If fetchBalance is provided, load balance and then stop initializing
8007
8033
  fetchTWCBalanceWithRetry(1, 100).then((result) => {
8034
+ if (!isMounted)
8035
+ return;
8008
8036
  if (result) {
8009
8037
  setTwcBalance(result.balance);
8010
8038
  setUsdValueStable(result.usdValue);
@@ -8016,12 +8044,16 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8016
8044
  clearTimeout(safetyTimeout);
8017
8045
  setIsInitializing(false);
8018
8046
  }).catch(() => {
8047
+ if (!isMounted)
8048
+ return;
8019
8049
  // Stop initializing even on error
8020
8050
  clearTimeout(safetyTimeout);
8021
8051
  setIsInitializing(false);
8022
8052
  });
8023
8053
  }
8024
8054
  else {
8055
+ if (!isMounted)
8056
+ return;
8025
8057
  // No fetchBalance and no cached balance - stop initializing with 0 balance
8026
8058
  setTwcBalance('0');
8027
8059
  clearTimeout(safetyTimeout);
@@ -8032,6 +8064,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8032
8064
  }
8033
8065
  }
8034
8066
  }).catch((err) => {
8067
+ if (!isMounted)
8068
+ return;
8035
8069
  clearTimeout(safetyTimeout);
8036
8070
  setIsInitializing(false);
8037
8071
  // If we can't get account even though status is connected, disconnect
@@ -8044,9 +8078,13 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8044
8078
  setIsInitializing(true);
8045
8079
  // Set a shorter timeout to prevent stuck loading state
8046
8080
  initTimeout = setTimeout(() => {
8081
+ if (!isMounted)
8082
+ return;
8047
8083
  setIsInitializing(false);
8048
8084
  // If still no account after timeout, ensure we show connect button
8049
8085
  connector.getAccount().then((acc) => {
8086
+ if (!isMounted)
8087
+ return;
8050
8088
  if (!acc) {
8051
8089
  setAccount(null);
8052
8090
  // If status is disconnected and no account, ensure we're fully disconnected
@@ -8058,11 +8096,15 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8058
8096
  }
8059
8097
  }
8060
8098
  }).catch((err) => {
8099
+ if (!isMounted)
8100
+ return;
8061
8101
  setAccount(null);
8062
8102
  setStatus(ConnectionStatus.DISCONNECTED);
8063
8103
  });
8064
8104
  }, 1500); // Reduced to 1.5 second timeout to prevent stuck loading
8065
8105
  connector.getAccount().then((acc) => {
8106
+ if (!isMounted)
8107
+ return;
8066
8108
  if (initTimeout)
8067
8109
  clearTimeout(initTimeout);
8068
8110
  setAccount(acc);
@@ -8077,6 +8119,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8077
8119
  }
8078
8120
  }
8079
8121
  }).catch((err) => {
8122
+ if (!isMounted)
8123
+ return;
8080
8124
  if (initTimeout)
8081
8125
  clearTimeout(initTimeout);
8082
8126
  setIsInitializing(false);
@@ -8090,6 +8134,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8090
8134
  }
8091
8135
  // Subscribe to events
8092
8136
  const unsubscribeAccount = connector.on(WalletEvent.ACCOUNT_CHANGED, async (acc) => {
8137
+ if (!isMounted)
8138
+ return;
8093
8139
  setAccount(acc);
8094
8140
  // Clear isConnecting when account changes (connection succeeded)
8095
8141
  setIsConnecting(false);
@@ -8110,9 +8156,13 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8110
8156
  fetchTONBalance(acc),
8111
8157
  fetchTONNFTs(acc)
8112
8158
  ]);
8159
+ if (!isMounted)
8160
+ return;
8113
8161
  setIsInitializing(false);
8114
8162
  }
8115
8163
  catch (err) {
8164
+ if (!isMounted)
8165
+ return;
8116
8166
  setIsInitializing(false);
8117
8167
  }
8118
8168
  }
@@ -8120,9 +8170,13 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8120
8170
  setBalanceLoading(true);
8121
8171
  try {
8122
8172
  await loadBalance();
8173
+ if (!isMounted)
8174
+ return;
8123
8175
  setIsInitializing(false);
8124
8176
  }
8125
8177
  catch (err) {
8178
+ if (!isMounted)
8179
+ return;
8126
8180
  setIsInitializing(false);
8127
8181
  setBalanceLoading(false);
8128
8182
  }
@@ -8245,6 +8299,7 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8245
8299
  }
8246
8300
  });
8247
8301
  return () => {
8302
+ isMounted = false;
8248
8303
  clearTimeout(initTimeout);
8249
8304
  unsubscribeAccount();
8250
8305
  unsubscribeStatus();
@@ -8390,16 +8445,23 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8390
8445
  }, [connector]);
8391
8446
  // Load balance when account changes
8392
8447
  useEffect(() => {
8448
+ let isActive = true;
8393
8449
  if (account && fetchBalance) {
8394
8450
  setBalanceLoading(true);
8395
8451
  loadBalance()
8396
8452
  .then(() => {
8453
+ if (!isActive)
8454
+ return;
8397
8455
  // Always stop initializing once balance request completes
8398
8456
  })
8399
8457
  .catch(() => {
8458
+ if (!isActive)
8459
+ return;
8400
8460
  // Ignore errors, we still clear loading states
8401
8461
  })
8402
8462
  .finally(() => {
8463
+ if (!isActive)
8464
+ return;
8403
8465
  setBalanceLoading(false);
8404
8466
  setIsInitializing(false);
8405
8467
  });
@@ -8432,6 +8494,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8432
8494
  // Only fetch if we don't have a balance yet
8433
8495
  if (!hasBalance) {
8434
8496
  fetchTWCBalanceWithRetry(2, 200).then((result) => {
8497
+ if (!isActive)
8498
+ return;
8435
8499
  if (result) {
8436
8500
  setTwcBalance(result.balance);
8437
8501
  setUsdValueStable(result.usdValue);
@@ -8447,6 +8511,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8447
8511
  setIsInitializing(false);
8448
8512
  }
8449
8513
  }).catch(() => {
8514
+ if (!isActive)
8515
+ return;
8450
8516
  setIsInitializing(false);
8451
8517
  });
8452
8518
  }
@@ -8467,22 +8533,33 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8467
8533
  }
8468
8534
  }
8469
8535
  }
8536
+ return () => {
8537
+ isActive = false;
8538
+ };
8470
8539
  // eslint-disable-next-line react-hooks/exhaustive-deps
8471
8540
  }, [account?.address, fetchBalance]);
8472
8541
  // Polling mechanism as fallback to ensure TWC balance is always fetched
8473
8542
  useEffect(() => {
8474
- if (!account || account.chainType !== 'evm' || isInitializing) {
8543
+ if (!account || account.chainType !== 'evm') {
8475
8544
  return;
8476
8545
  }
8477
- // If we don't have a balance yet, start polling
8478
- const hasBalance = twcBalance && twcBalance !== '0' && twcBalance !== '0.00';
8479
- if (!hasBalance) {
8546
+ // Check if we already have a balance
8547
+ const currentBalance = twcBalance;
8548
+ const hasBalance = currentBalance && currentBalance !== '0' && currentBalance !== '0.00';
8549
+ if (!hasBalance && !isInitializing) {
8480
8550
  // Poll every 2 seconds, up to 3 times (6 seconds total) - faster polling
8481
8551
  let pollCount = 0;
8482
8552
  const maxPolls = 3;
8553
+ let isActive = true;
8483
8554
  const pollInterval = setInterval(() => {
8555
+ if (!isActive) {
8556
+ clearInterval(pollInterval);
8557
+ return;
8558
+ }
8484
8559
  pollCount++;
8485
8560
  fetchTWCBalanceWithRetry(2, 200).then((result) => {
8561
+ if (!isActive)
8562
+ return;
8486
8563
  if (result) {
8487
8564
  setTwcBalance(result.balance);
8488
8565
  setUsdValueStable(result.usdValue);
@@ -8495,17 +8572,22 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8495
8572
  clearInterval(pollInterval);
8496
8573
  }
8497
8574
  }).catch((error) => {
8575
+ if (!isActive)
8576
+ return;
8498
8577
  if (pollCount >= maxPolls) {
8499
8578
  clearInterval(pollInterval);
8500
8579
  }
8501
8580
  });
8502
8581
  }, 2000); // Poll every 2 seconds (faster)
8503
8582
  return () => {
8583
+ isActive = false;
8504
8584
  clearInterval(pollInterval);
8505
8585
  };
8506
8586
  }
8587
+ return undefined;
8588
+ // Only depend on account address - check balance inside effect
8507
8589
  // eslint-disable-next-line react-hooks/exhaustive-deps
8508
- }, [account?.address, twcBalance, isInitializing]);
8590
+ }, [account?.address]);
8509
8591
  // Load transactions when details modal opens
8510
8592
  useEffect(() => {
8511
8593
  if (showDetailsModal && account) {
package/dist/index.js CHANGED
@@ -7532,7 +7532,7 @@ const defaultStyles = {
7532
7532
  fontFamily: 'Lexend, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
7533
7533
  boxShadow: '0 4px 14px 0 rgba(51, 150, 255, 0.39)',
7534
7534
  }};
7535
- const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className, style, showBalance = false, modalPosition = 'center', theme = 'auto', buttonText = 'Connect Wallet', fetchTransactions, getExplorerUrl, fetchBalance: fetchBalanceProp, }) => {
7535
+ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className, style, showBalance = false, modalPosition = 'center', theme = 'auto', buttonText = 'Connect Wallet Now', fetchTransactions, getExplorerUrl, fetchBalance: fetchBalanceProp, }) => {
7536
7536
  // Provide a default fetchBalance if not passed
7537
7537
  const fetchBalance = fetchBalanceProp || (async (account) => {
7538
7538
  // Default: return zero balance with symbol based on chain
@@ -7664,12 +7664,15 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7664
7664
  });
7665
7665
  // Stable USD value updater - only updates if value changes significantly
7666
7666
  const setUsdValueStable = React.useCallback((newValue) => {
7667
- // Set USD value immediately - only skip if value is the same
7668
7667
  setUsdValue((prevValue) => {
7669
7668
  // If new value is null/undefined and we have a previous value, keep it
7670
7669
  if ((newValue === null || newValue === undefined) && prevValue !== null) {
7671
7670
  return prevValue;
7672
7671
  }
7672
+ // Only update if value actually changed
7673
+ if (prevValue === newValue) {
7674
+ return prevValue;
7675
+ }
7673
7676
  // Otherwise set the new value
7674
7677
  return newValue;
7675
7678
  });
@@ -7883,6 +7886,7 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7883
7886
  const walletsRef = React.useRef(null);
7884
7887
  // Initialize and subscribe to events
7885
7888
  React.useEffect(() => {
7889
+ let isMounted = true;
7886
7890
  // Get initial state
7887
7891
  const initialState = connector.getState();
7888
7892
  setStatus(initialState.status);
@@ -7904,6 +7908,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7904
7908
  setBalanceLoading(false);
7905
7909
  }, 2000);
7906
7910
  connector.getAccount().then(async (acc) => {
7911
+ if (!isMounted)
7912
+ return;
7907
7913
  setAccount(acc);
7908
7914
  // Load balance when account is available
7909
7915
  if (acc && acc.chainType === 'ton') {
@@ -7914,10 +7920,14 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7914
7920
  fetchTONBalance(acc),
7915
7921
  fetchTONNFTs(acc)
7916
7922
  ]);
7923
+ if (!isMounted)
7924
+ return;
7917
7925
  clearTimeout(safetyTimeout);
7918
7926
  setIsInitializing(false);
7919
7927
  }
7920
7928
  catch (err) {
7929
+ if (!isMounted)
7930
+ return;
7921
7931
  clearTimeout(safetyTimeout);
7922
7932
  setIsInitializing(false);
7923
7933
  }
@@ -7926,6 +7936,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7926
7936
  try {
7927
7937
  setBalanceLoading(true);
7928
7938
  const hasRealBalance = await loadBalance();
7939
+ if (!isMounted)
7940
+ return;
7929
7941
  // Always stop loading state after balance fetch
7930
7942
  setBalanceLoading(false);
7931
7943
  clearTimeout(safetyTimeout);
@@ -7933,6 +7945,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7933
7945
  setIsInitializing(false);
7934
7946
  }
7935
7947
  catch (err) {
7948
+ if (!isMounted)
7949
+ return;
7936
7950
  setBalanceLoading(false);
7937
7951
  clearTimeout(safetyTimeout);
7938
7952
  // Always stop initializing on error
@@ -7944,6 +7958,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7944
7958
  const state = connector.getState();
7945
7959
  const stateTwcBalance = state.twcBalance;
7946
7960
  if (acc && stateTwcBalance && stateTwcBalance !== '0' && stateTwcBalance !== '0.00') {
7961
+ if (!isMounted)
7962
+ return;
7947
7963
  setTwcBalance(stateTwcBalance);
7948
7964
  setUsdValueStable(state.usdValue ?? null);
7949
7965
  // Save to cache
@@ -7957,6 +7973,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7957
7973
  // Try to load from cache as fallback
7958
7974
  const cached = loadTWCBalanceFromCache(acc.address);
7959
7975
  if (cached?.balance && cached.balance !== '0' && cached.balance !== '0.00') {
7976
+ if (!isMounted)
7977
+ return;
7960
7978
  setTwcBalance(cached.balance);
7961
7979
  setUsdValueStable(cached.usdValue);
7962
7980
  clearTimeout(safetyTimeout);
@@ -7966,6 +7984,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7966
7984
  // No real balance yet, but for EVM wallets, proactively fetch with retries
7967
7985
  if (acc.chainType === 'evm') {
7968
7986
  fetchTWCBalanceWithRetry(2, 200).then((result) => {
7987
+ if (!isMounted)
7988
+ return;
7969
7989
  if (result) {
7970
7990
  setTwcBalance(result.balance);
7971
7991
  setUsdValueStable(result.usdValue);
@@ -7982,6 +8002,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7982
8002
  setIsInitializing(false);
7983
8003
  }
7984
8004
  }).catch((error) => {
8005
+ if (!isMounted)
8006
+ return;
7985
8007
  // On error - show connected button with 0 balance
7986
8008
  setTwcBalance('0');
7987
8009
  clearTimeout(safetyTimeout);
@@ -7997,9 +8019,13 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7997
8019
  fetchTONBalance(acc),
7998
8020
  fetchTONNFTs(acc)
7999
8021
  ]).then(() => {
8022
+ if (!isMounted)
8023
+ return;
8000
8024
  clearTimeout(safetyTimeout);
8001
8025
  setIsInitializing(false);
8002
8026
  }).catch((err) => {
8027
+ if (!isMounted)
8028
+ return;
8003
8029
  clearTimeout(safetyTimeout);
8004
8030
  setIsInitializing(false);
8005
8031
  });
@@ -8007,6 +8033,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8007
8033
  else if (fetchBalance) {
8008
8034
  // For other non-EVM chains: If fetchBalance is provided, load balance and then stop initializing
8009
8035
  fetchTWCBalanceWithRetry(1, 100).then((result) => {
8036
+ if (!isMounted)
8037
+ return;
8010
8038
  if (result) {
8011
8039
  setTwcBalance(result.balance);
8012
8040
  setUsdValueStable(result.usdValue);
@@ -8018,12 +8046,16 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8018
8046
  clearTimeout(safetyTimeout);
8019
8047
  setIsInitializing(false);
8020
8048
  }).catch(() => {
8049
+ if (!isMounted)
8050
+ return;
8021
8051
  // Stop initializing even on error
8022
8052
  clearTimeout(safetyTimeout);
8023
8053
  setIsInitializing(false);
8024
8054
  });
8025
8055
  }
8026
8056
  else {
8057
+ if (!isMounted)
8058
+ return;
8027
8059
  // No fetchBalance and no cached balance - stop initializing with 0 balance
8028
8060
  setTwcBalance('0');
8029
8061
  clearTimeout(safetyTimeout);
@@ -8034,6 +8066,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8034
8066
  }
8035
8067
  }
8036
8068
  }).catch((err) => {
8069
+ if (!isMounted)
8070
+ return;
8037
8071
  clearTimeout(safetyTimeout);
8038
8072
  setIsInitializing(false);
8039
8073
  // If we can't get account even though status is connected, disconnect
@@ -8046,9 +8080,13 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8046
8080
  setIsInitializing(true);
8047
8081
  // Set a shorter timeout to prevent stuck loading state
8048
8082
  initTimeout = setTimeout(() => {
8083
+ if (!isMounted)
8084
+ return;
8049
8085
  setIsInitializing(false);
8050
8086
  // If still no account after timeout, ensure we show connect button
8051
8087
  connector.getAccount().then((acc) => {
8088
+ if (!isMounted)
8089
+ return;
8052
8090
  if (!acc) {
8053
8091
  setAccount(null);
8054
8092
  // If status is disconnected and no account, ensure we're fully disconnected
@@ -8060,11 +8098,15 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8060
8098
  }
8061
8099
  }
8062
8100
  }).catch((err) => {
8101
+ if (!isMounted)
8102
+ return;
8063
8103
  setAccount(null);
8064
8104
  setStatus(exports.ConnectionStatus.DISCONNECTED);
8065
8105
  });
8066
8106
  }, 1500); // Reduced to 1.5 second timeout to prevent stuck loading
8067
8107
  connector.getAccount().then((acc) => {
8108
+ if (!isMounted)
8109
+ return;
8068
8110
  if (initTimeout)
8069
8111
  clearTimeout(initTimeout);
8070
8112
  setAccount(acc);
@@ -8079,6 +8121,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8079
8121
  }
8080
8122
  }
8081
8123
  }).catch((err) => {
8124
+ if (!isMounted)
8125
+ return;
8082
8126
  if (initTimeout)
8083
8127
  clearTimeout(initTimeout);
8084
8128
  setIsInitializing(false);
@@ -8092,6 +8136,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8092
8136
  }
8093
8137
  // Subscribe to events
8094
8138
  const unsubscribeAccount = connector.on(exports.WalletEvent.ACCOUNT_CHANGED, async (acc) => {
8139
+ if (!isMounted)
8140
+ return;
8095
8141
  setAccount(acc);
8096
8142
  // Clear isConnecting when account changes (connection succeeded)
8097
8143
  setIsConnecting(false);
@@ -8112,9 +8158,13 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8112
8158
  fetchTONBalance(acc),
8113
8159
  fetchTONNFTs(acc)
8114
8160
  ]);
8161
+ if (!isMounted)
8162
+ return;
8115
8163
  setIsInitializing(false);
8116
8164
  }
8117
8165
  catch (err) {
8166
+ if (!isMounted)
8167
+ return;
8118
8168
  setIsInitializing(false);
8119
8169
  }
8120
8170
  }
@@ -8122,9 +8172,13 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8122
8172
  setBalanceLoading(true);
8123
8173
  try {
8124
8174
  await loadBalance();
8175
+ if (!isMounted)
8176
+ return;
8125
8177
  setIsInitializing(false);
8126
8178
  }
8127
8179
  catch (err) {
8180
+ if (!isMounted)
8181
+ return;
8128
8182
  setIsInitializing(false);
8129
8183
  setBalanceLoading(false);
8130
8184
  }
@@ -8247,6 +8301,7 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8247
8301
  }
8248
8302
  });
8249
8303
  return () => {
8304
+ isMounted = false;
8250
8305
  clearTimeout(initTimeout);
8251
8306
  unsubscribeAccount();
8252
8307
  unsubscribeStatus();
@@ -8392,16 +8447,23 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8392
8447
  }, [connector]);
8393
8448
  // Load balance when account changes
8394
8449
  React.useEffect(() => {
8450
+ let isActive = true;
8395
8451
  if (account && fetchBalance) {
8396
8452
  setBalanceLoading(true);
8397
8453
  loadBalance()
8398
8454
  .then(() => {
8455
+ if (!isActive)
8456
+ return;
8399
8457
  // Always stop initializing once balance request completes
8400
8458
  })
8401
8459
  .catch(() => {
8460
+ if (!isActive)
8461
+ return;
8402
8462
  // Ignore errors, we still clear loading states
8403
8463
  })
8404
8464
  .finally(() => {
8465
+ if (!isActive)
8466
+ return;
8405
8467
  setBalanceLoading(false);
8406
8468
  setIsInitializing(false);
8407
8469
  });
@@ -8434,6 +8496,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8434
8496
  // Only fetch if we don't have a balance yet
8435
8497
  if (!hasBalance) {
8436
8498
  fetchTWCBalanceWithRetry(2, 200).then((result) => {
8499
+ if (!isActive)
8500
+ return;
8437
8501
  if (result) {
8438
8502
  setTwcBalance(result.balance);
8439
8503
  setUsdValueStable(result.usdValue);
@@ -8449,6 +8513,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8449
8513
  setIsInitializing(false);
8450
8514
  }
8451
8515
  }).catch(() => {
8516
+ if (!isActive)
8517
+ return;
8452
8518
  setIsInitializing(false);
8453
8519
  });
8454
8520
  }
@@ -8469,22 +8535,33 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8469
8535
  }
8470
8536
  }
8471
8537
  }
8538
+ return () => {
8539
+ isActive = false;
8540
+ };
8472
8541
  // eslint-disable-next-line react-hooks/exhaustive-deps
8473
8542
  }, [account?.address, fetchBalance]);
8474
8543
  // Polling mechanism as fallback to ensure TWC balance is always fetched
8475
8544
  React.useEffect(() => {
8476
- if (!account || account.chainType !== 'evm' || isInitializing) {
8545
+ if (!account || account.chainType !== 'evm') {
8477
8546
  return;
8478
8547
  }
8479
- // If we don't have a balance yet, start polling
8480
- const hasBalance = twcBalance && twcBalance !== '0' && twcBalance !== '0.00';
8481
- if (!hasBalance) {
8548
+ // Check if we already have a balance
8549
+ const currentBalance = twcBalance;
8550
+ const hasBalance = currentBalance && currentBalance !== '0' && currentBalance !== '0.00';
8551
+ if (!hasBalance && !isInitializing) {
8482
8552
  // Poll every 2 seconds, up to 3 times (6 seconds total) - faster polling
8483
8553
  let pollCount = 0;
8484
8554
  const maxPolls = 3;
8555
+ let isActive = true;
8485
8556
  const pollInterval = setInterval(() => {
8557
+ if (!isActive) {
8558
+ clearInterval(pollInterval);
8559
+ return;
8560
+ }
8486
8561
  pollCount++;
8487
8562
  fetchTWCBalanceWithRetry(2, 200).then((result) => {
8563
+ if (!isActive)
8564
+ return;
8488
8565
  if (result) {
8489
8566
  setTwcBalance(result.balance);
8490
8567
  setUsdValueStable(result.usdValue);
@@ -8497,17 +8574,22 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8497
8574
  clearInterval(pollInterval);
8498
8575
  }
8499
8576
  }).catch((error) => {
8577
+ if (!isActive)
8578
+ return;
8500
8579
  if (pollCount >= maxPolls) {
8501
8580
  clearInterval(pollInterval);
8502
8581
  }
8503
8582
  });
8504
8583
  }, 2000); // Poll every 2 seconds (faster)
8505
8584
  return () => {
8585
+ isActive = false;
8506
8586
  clearInterval(pollInterval);
8507
8587
  };
8508
8588
  }
8589
+ return undefined;
8590
+ // Only depend on account address - check balance inside effect
8509
8591
  // eslint-disable-next-line react-hooks/exhaustive-deps
8510
- }, [account?.address, twcBalance, isInitializing]);
8592
+ }, [account?.address]);
8511
8593
  // Load transactions when details modal opens
8512
8594
  React.useEffect(() => {
8513
8595
  if (showDetailsModal && account) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tiwiflix-wallet-connector",
3
- "version": "1.5.5",
3
+ "version": "1.5.6",
4
4
  "description": "Multi-chain wallet connector for Tiwiflix supporting EVM, TON, Solana, and Tron wallets",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",