tiwiflix-wallet-connector 1.4.7 → 1.5.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.
package/dist/index.d.ts CHANGED
@@ -855,6 +855,10 @@ declare abstract class TONBaseAdapter extends BaseWalletAdapter {
855
855
  private checkForTonWalletExtensions;
856
856
  connect(): Promise<ConnectionResult>;
857
857
  disconnect(): Promise<void>;
858
+ /**
859
+ * Clear all TON-related storage (localStorage and cookies)
860
+ */
861
+ private clearAllTONStorage;
858
862
  getAccount(): Promise<Account | null>;
859
863
  /**
860
864
  * Get TON balance with caching
package/dist/index.esm.js CHANGED
@@ -5446,12 +5446,84 @@ class TONBaseAdapter extends BaseWalletAdapter {
5446
5446
  this.performanceMetrics.lastError = error;
5447
5447
  }
5448
5448
  }
5449
+ // Clear all TON-related storage (localStorage and cookies)
5450
+ this.clearAllTONStorage();
5449
5451
  // Clear local state
5450
5452
  this.currentAccount = null;
5451
5453
  this.notifyStatusChanged(ConnectionStatus.DISCONNECTED);
5452
5454
  this.notifyAccountChanged(null);
5453
5455
  this.debugLog('TON wallet disconnected');
5454
5456
  }
5457
+ /**
5458
+ * Clear all TON-related storage (localStorage and cookies)
5459
+ */
5460
+ clearAllTONStorage() {
5461
+ if (typeof window === 'undefined')
5462
+ return;
5463
+ try {
5464
+ // Clear localStorage
5465
+ if (window.localStorage) {
5466
+ const keysToRemove = [];
5467
+ // Find all TON-related keys
5468
+ for (let i = 0; i < window.localStorage.length; i++) {
5469
+ const key = window.localStorage.key(i);
5470
+ if (key) {
5471
+ // Check for TON-related patterns
5472
+ if (key.includes('ton') ||
5473
+ key.includes('TON') ||
5474
+ key.includes('tonconnect') ||
5475
+ key.includes('TonConnect') ||
5476
+ key.includes('tonkeeper') ||
5477
+ key.includes('mytonwallet') ||
5478
+ key.includes('tonhub') ||
5479
+ key.toLowerCase().includes('wallet')) {
5480
+ keysToRemove.push(key);
5481
+ }
5482
+ }
5483
+ }
5484
+ // Remove found keys
5485
+ keysToRemove.forEach(key => {
5486
+ try {
5487
+ window.localStorage.removeItem(key);
5488
+ this.debugLog(`Cleared localStorage key: ${key}`);
5489
+ }
5490
+ catch (error) {
5491
+ this.debugLog(`Failed to remove localStorage item: ${key}`, error);
5492
+ }
5493
+ });
5494
+ }
5495
+ // Clear cookies
5496
+ if (document && document.cookie) {
5497
+ const cookies = document.cookie.split(';');
5498
+ cookies.forEach(cookie => {
5499
+ const eqPos = cookie.indexOf('=');
5500
+ const name = eqPos > -1 ? cookie.substr(0, eqPos).trim() : cookie.trim();
5501
+ // Check if cookie is TON-related
5502
+ if (name.includes('ton') ||
5503
+ name.includes('TON') ||
5504
+ name.includes('tonconnect') ||
5505
+ name.includes('tonkeeper') ||
5506
+ name.includes('mytonwallet') ||
5507
+ name.includes('tonhub') ||
5508
+ name.toLowerCase().includes('wallet')) {
5509
+ // Clear cookie for current domain
5510
+ document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
5511
+ // Also try to clear for parent domains
5512
+ const hostname = window.location.hostname;
5513
+ const parts = hostname.split('.');
5514
+ for (let i = 0; i < parts.length; i++) {
5515
+ const domain = parts.slice(i).join('.');
5516
+ document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.${domain};`;
5517
+ }
5518
+ this.debugLog(`Cleared cookie: ${name}`);
5519
+ }
5520
+ });
5521
+ }
5522
+ }
5523
+ catch (error) {
5524
+ this.debugLog('Error clearing TON storage', error);
5525
+ }
5526
+ }
5455
5527
  async getAccount() {
5456
5528
  if (!this.currentAccount || !this.connector) {
5457
5529
  return null;
@@ -6392,6 +6464,10 @@ const AccountDetailsModal = ({ isOpen, onClose, account, onDisconnect, onCopyAdd
6392
6464
  // State for TWC price - hooks must be called before any conditional returns
6393
6465
  const [twcPrice, setTwcPrice] = useState(null);
6394
6466
  const [priceLoading, setPriceLoading] = useState(false);
6467
+ // State for TP Points
6468
+ const [tpPoints, setTpPoints] = useState(null);
6469
+ const [tpLoading, setTpLoading] = useState(false);
6470
+ const [tpError, setTpError] = useState(null);
6395
6471
  // Fetch TWC price when modal opens and twcBalance is available
6396
6472
  useEffect(() => {
6397
6473
  if (isOpen && twcBalance && twcBalance !== '0' && twcBalance !== '0.00') {
@@ -6408,6 +6484,32 @@ const AccountDetailsModal = ({ isOpen, onClose, account, onDisconnect, onCopyAdd
6408
6484
  });
6409
6485
  }
6410
6486
  }, [isOpen, twcBalance]);
6487
+ // Fetch TP Points when modal opens
6488
+ useEffect(() => {
6489
+ if (isOpen && account?.address) {
6490
+ setTpLoading(true);
6491
+ setTpError(null);
6492
+ fetch(`http://localhost:3090/api/v2/user/leaderboard/points/${account.address}`)
6493
+ .then(response => {
6494
+ if (!response.ok) {
6495
+ throw new Error(`HTTP error! status: ${response.status}`);
6496
+ }
6497
+ return response.json();
6498
+ })
6499
+ .then(responseData => {
6500
+ // Handle nested response structure: { success, statusCode, data: { points, ... } }
6501
+ const points = responseData.data?.points ?? responseData.points ?? responseData.data?.totalPoints ?? 0;
6502
+ setTpPoints(points);
6503
+ setTpLoading(false);
6504
+ })
6505
+ .catch(error => {
6506
+ console.error('Failed to fetch TP points:', error);
6507
+ setTpError('Failed to load');
6508
+ setTpPoints(0);
6509
+ setTpLoading(false);
6510
+ });
6511
+ }
6512
+ }, [isOpen, account?.address]);
6411
6513
  // Early return AFTER hooks
6412
6514
  if (!isOpen || !account)
6413
6515
  return null;
@@ -6774,7 +6876,13 @@ const AccountDetailsModal = ({ isOpen, onClose, account, onDisconnect, onCopyAdd
6774
6876
  fontFamily: 'Lexend, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
6775
6877
  fontSize: '12px',
6776
6878
  letterSpacing: '-0.1px',
6777
- }, children: "0 TP" })] })] }) }), jsxs("div", { onClick: handleBuyTWC, style: {
6879
+ }, children: tpLoading
6880
+ ? 'Loading...'
6881
+ : tpError
6882
+ ? tpError
6883
+ : tpPoints !== null
6884
+ ? `${tpPoints.toLocaleString()} TP`
6885
+ : '0 TP' })] })] }) }), jsxs("div", { onClick: handleBuyTWC, style: {
6778
6886
  background: 'rgb(29, 31, 35)',
6779
6887
  border: '1px solid rgba(113, 122, 140, 0.08)',
6780
6888
  borderRadius: '12px',
@@ -7746,6 +7854,11 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7746
7854
  if (initialState.status === ConnectionStatus.CONNECTED) {
7747
7855
  // Set isInitializing to true initially, will be set to false once balance loads
7748
7856
  setIsInitializing(true);
7857
+ // Safety timeout - ensure we NEVER stay in loading state for more than 2 seconds
7858
+ const safetyTimeout = setTimeout(() => {
7859
+ setIsInitializing(false);
7860
+ setBalanceLoading(false);
7861
+ }, 2000);
7749
7862
  connector.getAccount().then(async (acc) => {
7750
7863
  setAccount(acc);
7751
7864
  // Load balance when account is available
@@ -7757,9 +7870,11 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7757
7870
  fetchTONBalance(acc),
7758
7871
  fetchTONNFTs(acc)
7759
7872
  ]);
7873
+ clearTimeout(safetyTimeout);
7760
7874
  setIsInitializing(false);
7761
7875
  }
7762
7876
  catch (err) {
7877
+ clearTimeout(safetyTimeout);
7763
7878
  setIsInitializing(false);
7764
7879
  }
7765
7880
  }
@@ -7769,25 +7884,15 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7769
7884
  const hasRealBalance = await loadBalance();
7770
7885
  // Always stop loading state after balance fetch
7771
7886
  setBalanceLoading(false);
7772
- // Only stop initializing if we got a real (non-zero) balance
7773
- if (hasRealBalance) {
7774
- setIsInitializing(false);
7775
- }
7776
- else {
7777
- // For TON and other non-EVM chains, stop initializing even if balance is 0
7778
- // This allows the connected button to show with 0 balance
7779
- if (acc.chainType !== 'evm') {
7780
- setIsInitializing(false);
7781
- }
7782
- // Keep loading state if balance is 0 for EVM chains only
7783
- }
7887
+ clearTimeout(safetyTimeout);
7888
+ // Always stop initializing after balance fetch completes, regardless of result
7889
+ setIsInitializing(false);
7784
7890
  }
7785
7891
  catch (err) {
7786
7892
  setBalanceLoading(false);
7787
- // On error, stop initializing for non-EVM chains
7788
- if (acc && acc.chainType !== 'evm') {
7789
- setIsInitializing(false);
7790
- }
7893
+ clearTimeout(safetyTimeout);
7894
+ // Always stop initializing on error
7895
+ setIsInitializing(false);
7791
7896
  }
7792
7897
  }
7793
7898
  else {
@@ -7801,6 +7906,7 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7801
7906
  if (acc.address) {
7802
7907
  saveTWCBalanceToCache(acc.address, stateTwcBalance, state.usdValue ?? null);
7803
7908
  }
7909
+ clearTimeout(safetyTimeout);
7804
7910
  setIsInitializing(false);
7805
7911
  }
7806
7912
  else if (acc) {
@@ -7809,6 +7915,7 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7809
7915
  if (cached?.balance && cached.balance !== '0' && cached.balance !== '0.00') {
7810
7916
  setTwcBalance(cached.balance);
7811
7917
  setUsdValueStable(cached.usdValue);
7918
+ clearTimeout(safetyTimeout);
7812
7919
  setIsInitializing(false);
7813
7920
  }
7814
7921
  else {
@@ -7821,16 +7928,19 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7821
7928
  if (acc.address) {
7822
7929
  saveTWCBalanceToCache(acc.address, result.balance, result.usdValue);
7823
7930
  }
7931
+ clearTimeout(safetyTimeout);
7824
7932
  setIsInitializing(false);
7825
7933
  }
7826
7934
  else {
7827
7935
  // Fetch failed - show connected button with 0 balance
7828
7936
  setTwcBalance('0');
7937
+ clearTimeout(safetyTimeout);
7829
7938
  setIsInitializing(false);
7830
7939
  }
7831
7940
  }).catch((error) => {
7832
7941
  // On error - show connected button with 0 balance
7833
7942
  setTwcBalance('0');
7943
+ clearTimeout(safetyTimeout);
7834
7944
  setIsInitializing(false);
7835
7945
  });
7836
7946
  }
@@ -7843,8 +7953,10 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7843
7953
  fetchTONBalance(acc),
7844
7954
  fetchTONNFTs(acc)
7845
7955
  ]).then(() => {
7956
+ clearTimeout(safetyTimeout);
7846
7957
  setIsInitializing(false);
7847
7958
  }).catch((err) => {
7959
+ clearTimeout(safetyTimeout);
7848
7960
  setIsInitializing(false);
7849
7961
  });
7850
7962
  }
@@ -7859,15 +7971,18 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7859
7971
  }
7860
7972
  }
7861
7973
  // Always stop initializing after attempting to fetch
7974
+ clearTimeout(safetyTimeout);
7862
7975
  setIsInitializing(false);
7863
7976
  }).catch(() => {
7864
7977
  // Stop initializing even on error
7978
+ clearTimeout(safetyTimeout);
7865
7979
  setIsInitializing(false);
7866
7980
  });
7867
7981
  }
7868
7982
  else {
7869
7983
  // No fetchBalance and no cached balance - stop initializing with 0 balance
7870
7984
  setTwcBalance('0');
7985
+ clearTimeout(safetyTimeout);
7871
7986
  setIsInitializing(false);
7872
7987
  }
7873
7988
  }
@@ -7875,6 +7990,7 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7875
7990
  }
7876
7991
  }
7877
7992
  }).catch((err) => {
7993
+ clearTimeout(safetyTimeout);
7878
7994
  setIsInitializing(false);
7879
7995
  // If we can't get account even though status is connected, disconnect
7880
7996
  setAccount(null);
@@ -7884,7 +8000,7 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7884
8000
  else {
7885
8001
  // Only set isInitializing if we're not already connected
7886
8002
  setIsInitializing(true);
7887
- // Set a timeout to prevent infinite loading (if connection can't be restored)
8003
+ // Set a shorter timeout to prevent stuck loading state
7888
8004
  initTimeout = setTimeout(() => {
7889
8005
  setIsInitializing(false);
7890
8006
  // If still no account after timeout, ensure we show connect button
@@ -7903,7 +8019,7 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7903
8019
  setAccount(null);
7904
8020
  setStatus(ConnectionStatus.DISCONNECTED);
7905
8021
  });
7906
- }, 3000); // 3 second timeout
8022
+ }, 1500); // Reduced to 1.5 second timeout to prevent stuck loading
7907
8023
  connector.getAccount().then((acc) => {
7908
8024
  if (initTimeout)
7909
8025
  clearTimeout(initTimeout);
@@ -8006,6 +8122,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8006
8122
  const prevAccount = account;
8007
8123
  setAccount(null);
8008
8124
  setIsInitializing(false);
8125
+ setIsConnecting(false);
8126
+ setStatus(ConnectionStatus.DISCONNECTED);
8009
8127
  // Clear cached balance when disconnecting
8010
8128
  if (prevAccount?.address) {
8011
8129
  clearTWCBalanceCache(prevAccount.address);
@@ -8014,6 +8132,39 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8014
8132
  balanceCache.current.clear();
8015
8133
  transactionsCache.current.clear();
8016
8134
  txDetailsCache.current.clear();
8135
+ tonApiCache.clear();
8136
+ // Reset all state
8137
+ setTwcBalance(null);
8138
+ setUsdValue(null);
8139
+ setBalance({ amount: '', symbol: '' });
8140
+ setTxs([]);
8141
+ setNftCount(0);
8142
+ nftCountRef.current = 0;
8143
+ setTonBalance(null);
8144
+ setTonUsdValue(null);
8145
+ // Clear all localStorage items related to TWC balance cache
8146
+ if (typeof window !== 'undefined' && window.localStorage) {
8147
+ try {
8148
+ const keysToRemove = [];
8149
+ for (let i = 0; i < window.localStorage.length; i++) {
8150
+ const key = window.localStorage.key(i);
8151
+ if (key && key.includes(TWC_BALANCE_CACHE_KEY)) {
8152
+ keysToRemove.push(key);
8153
+ }
8154
+ }
8155
+ keysToRemove.forEach(key => {
8156
+ try {
8157
+ window.localStorage.removeItem(key);
8158
+ }
8159
+ catch (error) {
8160
+ // Ignore errors
8161
+ }
8162
+ });
8163
+ }
8164
+ catch (error) {
8165
+ // Ignore errors
8166
+ }
8167
+ }
8017
8168
  if (onDisconnect) {
8018
8169
  onDisconnect();
8019
8170
  }
@@ -8381,12 +8532,51 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8381
8532
  }, [connector, fetchBalance, loadBalance]);
8382
8533
  const handleDisconnect = useCallback(async () => {
8383
8534
  try {
8384
- await connector.disconnect();
8535
+ // Close all modals first
8385
8536
  setShowDetailsModal(false);
8537
+ setShowModal(false);
8538
+ setShowSwapModal(false);
8539
+ setShowSendModal(false);
8540
+ setShowActivityModal(false);
8541
+ setShowTWCBalanceModal(false);
8542
+ // Clear current account address before disconnect
8543
+ const currentAddress = account?.address;
8544
+ // Disconnect from connector
8545
+ await connector.disconnect();
8546
+ // Additional cleanup - clear all TWC balance cache entries
8547
+ if (currentAddress) {
8548
+ clearTWCBalanceCache(currentAddress);
8549
+ }
8550
+ // Clear all localStorage items related to TWC and wallets
8551
+ if (typeof window !== 'undefined' && window.localStorage) {
8552
+ try {
8553
+ const keysToRemove = [];
8554
+ for (let i = 0; i < window.localStorage.length; i++) {
8555
+ const key = window.localStorage.key(i);
8556
+ if (key && (key.includes(TWC_BALANCE_CACHE_KEY) || key.toLowerCase().includes('wallet'))) {
8557
+ keysToRemove.push(key);
8558
+ }
8559
+ }
8560
+ keysToRemove.forEach(key => {
8561
+ try {
8562
+ window.localStorage.removeItem(key);
8563
+ }
8564
+ catch (error) {
8565
+ // Ignore errors
8566
+ }
8567
+ });
8568
+ }
8569
+ catch (error) {
8570
+ // Ignore errors
8571
+ }
8572
+ }
8386
8573
  }
8387
8574
  catch (err) {
8575
+ // Even on error, ensure modals are closed
8576
+ setShowDetailsModal(false);
8577
+ setShowModal(false);
8388
8578
  }
8389
- }, [connector]);
8579
+ }, [connector, account?.address]);
8390
8580
  const handleCopyAddress = useCallback(() => {
8391
8581
  if (account?.address) {
8392
8582
  navigator.clipboard.writeText(account.address);
package/dist/index.js CHANGED
@@ -5448,12 +5448,84 @@ class TONBaseAdapter extends BaseWalletAdapter {
5448
5448
  this.performanceMetrics.lastError = error;
5449
5449
  }
5450
5450
  }
5451
+ // Clear all TON-related storage (localStorage and cookies)
5452
+ this.clearAllTONStorage();
5451
5453
  // Clear local state
5452
5454
  this.currentAccount = null;
5453
5455
  this.notifyStatusChanged(exports.ConnectionStatus.DISCONNECTED);
5454
5456
  this.notifyAccountChanged(null);
5455
5457
  this.debugLog('TON wallet disconnected');
5456
5458
  }
5459
+ /**
5460
+ * Clear all TON-related storage (localStorage and cookies)
5461
+ */
5462
+ clearAllTONStorage() {
5463
+ if (typeof window === 'undefined')
5464
+ return;
5465
+ try {
5466
+ // Clear localStorage
5467
+ if (window.localStorage) {
5468
+ const keysToRemove = [];
5469
+ // Find all TON-related keys
5470
+ for (let i = 0; i < window.localStorage.length; i++) {
5471
+ const key = window.localStorage.key(i);
5472
+ if (key) {
5473
+ // Check for TON-related patterns
5474
+ if (key.includes('ton') ||
5475
+ key.includes('TON') ||
5476
+ key.includes('tonconnect') ||
5477
+ key.includes('TonConnect') ||
5478
+ key.includes('tonkeeper') ||
5479
+ key.includes('mytonwallet') ||
5480
+ key.includes('tonhub') ||
5481
+ key.toLowerCase().includes('wallet')) {
5482
+ keysToRemove.push(key);
5483
+ }
5484
+ }
5485
+ }
5486
+ // Remove found keys
5487
+ keysToRemove.forEach(key => {
5488
+ try {
5489
+ window.localStorage.removeItem(key);
5490
+ this.debugLog(`Cleared localStorage key: ${key}`);
5491
+ }
5492
+ catch (error) {
5493
+ this.debugLog(`Failed to remove localStorage item: ${key}`, error);
5494
+ }
5495
+ });
5496
+ }
5497
+ // Clear cookies
5498
+ if (document && document.cookie) {
5499
+ const cookies = document.cookie.split(';');
5500
+ cookies.forEach(cookie => {
5501
+ const eqPos = cookie.indexOf('=');
5502
+ const name = eqPos > -1 ? cookie.substr(0, eqPos).trim() : cookie.trim();
5503
+ // Check if cookie is TON-related
5504
+ if (name.includes('ton') ||
5505
+ name.includes('TON') ||
5506
+ name.includes('tonconnect') ||
5507
+ name.includes('tonkeeper') ||
5508
+ name.includes('mytonwallet') ||
5509
+ name.includes('tonhub') ||
5510
+ name.toLowerCase().includes('wallet')) {
5511
+ // Clear cookie for current domain
5512
+ document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
5513
+ // Also try to clear for parent domains
5514
+ const hostname = window.location.hostname;
5515
+ const parts = hostname.split('.');
5516
+ for (let i = 0; i < parts.length; i++) {
5517
+ const domain = parts.slice(i).join('.');
5518
+ document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; domain=.${domain};`;
5519
+ }
5520
+ this.debugLog(`Cleared cookie: ${name}`);
5521
+ }
5522
+ });
5523
+ }
5524
+ }
5525
+ catch (error) {
5526
+ this.debugLog('Error clearing TON storage', error);
5527
+ }
5528
+ }
5457
5529
  async getAccount() {
5458
5530
  if (!this.currentAccount || !this.connector) {
5459
5531
  return null;
@@ -6394,6 +6466,10 @@ const AccountDetailsModal = ({ isOpen, onClose, account, onDisconnect, onCopyAdd
6394
6466
  // State for TWC price - hooks must be called before any conditional returns
6395
6467
  const [twcPrice, setTwcPrice] = React.useState(null);
6396
6468
  const [priceLoading, setPriceLoading] = React.useState(false);
6469
+ // State for TP Points
6470
+ const [tpPoints, setTpPoints] = React.useState(null);
6471
+ const [tpLoading, setTpLoading] = React.useState(false);
6472
+ const [tpError, setTpError] = React.useState(null);
6397
6473
  // Fetch TWC price when modal opens and twcBalance is available
6398
6474
  React.useEffect(() => {
6399
6475
  if (isOpen && twcBalance && twcBalance !== '0' && twcBalance !== '0.00') {
@@ -6410,6 +6486,32 @@ const AccountDetailsModal = ({ isOpen, onClose, account, onDisconnect, onCopyAdd
6410
6486
  });
6411
6487
  }
6412
6488
  }, [isOpen, twcBalance]);
6489
+ // Fetch TP Points when modal opens
6490
+ React.useEffect(() => {
6491
+ if (isOpen && account?.address) {
6492
+ setTpLoading(true);
6493
+ setTpError(null);
6494
+ fetch(`http://localhost:3090/api/v2/user/leaderboard/points/${account.address}`)
6495
+ .then(response => {
6496
+ if (!response.ok) {
6497
+ throw new Error(`HTTP error! status: ${response.status}`);
6498
+ }
6499
+ return response.json();
6500
+ })
6501
+ .then(responseData => {
6502
+ // Handle nested response structure: { success, statusCode, data: { points, ... } }
6503
+ const points = responseData.data?.points ?? responseData.points ?? responseData.data?.totalPoints ?? 0;
6504
+ setTpPoints(points);
6505
+ setTpLoading(false);
6506
+ })
6507
+ .catch(error => {
6508
+ console.error('Failed to fetch TP points:', error);
6509
+ setTpError('Failed to load');
6510
+ setTpPoints(0);
6511
+ setTpLoading(false);
6512
+ });
6513
+ }
6514
+ }, [isOpen, account?.address]);
6413
6515
  // Early return AFTER hooks
6414
6516
  if (!isOpen || !account)
6415
6517
  return null;
@@ -6776,7 +6878,13 @@ const AccountDetailsModal = ({ isOpen, onClose, account, onDisconnect, onCopyAdd
6776
6878
  fontFamily: 'Lexend, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
6777
6879
  fontSize: '12px',
6778
6880
  letterSpacing: '-0.1px',
6779
- }, children: "0 TP" })] })] }) }), jsxRuntime.jsxs("div", { onClick: handleBuyTWC, style: {
6881
+ }, children: tpLoading
6882
+ ? 'Loading...'
6883
+ : tpError
6884
+ ? tpError
6885
+ : tpPoints !== null
6886
+ ? `${tpPoints.toLocaleString()} TP`
6887
+ : '0 TP' })] })] }) }), jsxRuntime.jsxs("div", { onClick: handleBuyTWC, style: {
6780
6888
  background: 'rgb(29, 31, 35)',
6781
6889
  border: '1px solid rgba(113, 122, 140, 0.08)',
6782
6890
  borderRadius: '12px',
@@ -7748,6 +7856,11 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7748
7856
  if (initialState.status === exports.ConnectionStatus.CONNECTED) {
7749
7857
  // Set isInitializing to true initially, will be set to false once balance loads
7750
7858
  setIsInitializing(true);
7859
+ // Safety timeout - ensure we NEVER stay in loading state for more than 2 seconds
7860
+ const safetyTimeout = setTimeout(() => {
7861
+ setIsInitializing(false);
7862
+ setBalanceLoading(false);
7863
+ }, 2000);
7751
7864
  connector.getAccount().then(async (acc) => {
7752
7865
  setAccount(acc);
7753
7866
  // Load balance when account is available
@@ -7759,9 +7872,11 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7759
7872
  fetchTONBalance(acc),
7760
7873
  fetchTONNFTs(acc)
7761
7874
  ]);
7875
+ clearTimeout(safetyTimeout);
7762
7876
  setIsInitializing(false);
7763
7877
  }
7764
7878
  catch (err) {
7879
+ clearTimeout(safetyTimeout);
7765
7880
  setIsInitializing(false);
7766
7881
  }
7767
7882
  }
@@ -7771,25 +7886,15 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7771
7886
  const hasRealBalance = await loadBalance();
7772
7887
  // Always stop loading state after balance fetch
7773
7888
  setBalanceLoading(false);
7774
- // Only stop initializing if we got a real (non-zero) balance
7775
- if (hasRealBalance) {
7776
- setIsInitializing(false);
7777
- }
7778
- else {
7779
- // For TON and other non-EVM chains, stop initializing even if balance is 0
7780
- // This allows the connected button to show with 0 balance
7781
- if (acc.chainType !== 'evm') {
7782
- setIsInitializing(false);
7783
- }
7784
- // Keep loading state if balance is 0 for EVM chains only
7785
- }
7889
+ clearTimeout(safetyTimeout);
7890
+ // Always stop initializing after balance fetch completes, regardless of result
7891
+ setIsInitializing(false);
7786
7892
  }
7787
7893
  catch (err) {
7788
7894
  setBalanceLoading(false);
7789
- // On error, stop initializing for non-EVM chains
7790
- if (acc && acc.chainType !== 'evm') {
7791
- setIsInitializing(false);
7792
- }
7895
+ clearTimeout(safetyTimeout);
7896
+ // Always stop initializing on error
7897
+ setIsInitializing(false);
7793
7898
  }
7794
7899
  }
7795
7900
  else {
@@ -7803,6 +7908,7 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7803
7908
  if (acc.address) {
7804
7909
  saveTWCBalanceToCache(acc.address, stateTwcBalance, state.usdValue ?? null);
7805
7910
  }
7911
+ clearTimeout(safetyTimeout);
7806
7912
  setIsInitializing(false);
7807
7913
  }
7808
7914
  else if (acc) {
@@ -7811,6 +7917,7 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7811
7917
  if (cached?.balance && cached.balance !== '0' && cached.balance !== '0.00') {
7812
7918
  setTwcBalance(cached.balance);
7813
7919
  setUsdValueStable(cached.usdValue);
7920
+ clearTimeout(safetyTimeout);
7814
7921
  setIsInitializing(false);
7815
7922
  }
7816
7923
  else {
@@ -7823,16 +7930,19 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7823
7930
  if (acc.address) {
7824
7931
  saveTWCBalanceToCache(acc.address, result.balance, result.usdValue);
7825
7932
  }
7933
+ clearTimeout(safetyTimeout);
7826
7934
  setIsInitializing(false);
7827
7935
  }
7828
7936
  else {
7829
7937
  // Fetch failed - show connected button with 0 balance
7830
7938
  setTwcBalance('0');
7939
+ clearTimeout(safetyTimeout);
7831
7940
  setIsInitializing(false);
7832
7941
  }
7833
7942
  }).catch((error) => {
7834
7943
  // On error - show connected button with 0 balance
7835
7944
  setTwcBalance('0');
7945
+ clearTimeout(safetyTimeout);
7836
7946
  setIsInitializing(false);
7837
7947
  });
7838
7948
  }
@@ -7845,8 +7955,10 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7845
7955
  fetchTONBalance(acc),
7846
7956
  fetchTONNFTs(acc)
7847
7957
  ]).then(() => {
7958
+ clearTimeout(safetyTimeout);
7848
7959
  setIsInitializing(false);
7849
7960
  }).catch((err) => {
7961
+ clearTimeout(safetyTimeout);
7850
7962
  setIsInitializing(false);
7851
7963
  });
7852
7964
  }
@@ -7861,15 +7973,18 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7861
7973
  }
7862
7974
  }
7863
7975
  // Always stop initializing after attempting to fetch
7976
+ clearTimeout(safetyTimeout);
7864
7977
  setIsInitializing(false);
7865
7978
  }).catch(() => {
7866
7979
  // Stop initializing even on error
7980
+ clearTimeout(safetyTimeout);
7867
7981
  setIsInitializing(false);
7868
7982
  });
7869
7983
  }
7870
7984
  else {
7871
7985
  // No fetchBalance and no cached balance - stop initializing with 0 balance
7872
7986
  setTwcBalance('0');
7987
+ clearTimeout(safetyTimeout);
7873
7988
  setIsInitializing(false);
7874
7989
  }
7875
7990
  }
@@ -7877,6 +7992,7 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7877
7992
  }
7878
7993
  }
7879
7994
  }).catch((err) => {
7995
+ clearTimeout(safetyTimeout);
7880
7996
  setIsInitializing(false);
7881
7997
  // If we can't get account even though status is connected, disconnect
7882
7998
  setAccount(null);
@@ -7886,7 +8002,7 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7886
8002
  else {
7887
8003
  // Only set isInitializing if we're not already connected
7888
8004
  setIsInitializing(true);
7889
- // Set a timeout to prevent infinite loading (if connection can't be restored)
8005
+ // Set a shorter timeout to prevent stuck loading state
7890
8006
  initTimeout = setTimeout(() => {
7891
8007
  setIsInitializing(false);
7892
8008
  // If still no account after timeout, ensure we show connect button
@@ -7905,7 +8021,7 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
7905
8021
  setAccount(null);
7906
8022
  setStatus(exports.ConnectionStatus.DISCONNECTED);
7907
8023
  });
7908
- }, 3000); // 3 second timeout
8024
+ }, 1500); // Reduced to 1.5 second timeout to prevent stuck loading
7909
8025
  connector.getAccount().then((acc) => {
7910
8026
  if (initTimeout)
7911
8027
  clearTimeout(initTimeout);
@@ -8008,6 +8124,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8008
8124
  const prevAccount = account;
8009
8125
  setAccount(null);
8010
8126
  setIsInitializing(false);
8127
+ setIsConnecting(false);
8128
+ setStatus(exports.ConnectionStatus.DISCONNECTED);
8011
8129
  // Clear cached balance when disconnecting
8012
8130
  if (prevAccount?.address) {
8013
8131
  clearTWCBalanceCache(prevAccount.address);
@@ -8016,6 +8134,39 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8016
8134
  balanceCache.current.clear();
8017
8135
  transactionsCache.current.clear();
8018
8136
  txDetailsCache.current.clear();
8137
+ tonApiCache.clear();
8138
+ // Reset all state
8139
+ setTwcBalance(null);
8140
+ setUsdValue(null);
8141
+ setBalance({ amount: '', symbol: '' });
8142
+ setTxs([]);
8143
+ setNftCount(0);
8144
+ nftCountRef.current = 0;
8145
+ setTonBalance(null);
8146
+ setTonUsdValue(null);
8147
+ // Clear all localStorage items related to TWC balance cache
8148
+ if (typeof window !== 'undefined' && window.localStorage) {
8149
+ try {
8150
+ const keysToRemove = [];
8151
+ for (let i = 0; i < window.localStorage.length; i++) {
8152
+ const key = window.localStorage.key(i);
8153
+ if (key && key.includes(TWC_BALANCE_CACHE_KEY)) {
8154
+ keysToRemove.push(key);
8155
+ }
8156
+ }
8157
+ keysToRemove.forEach(key => {
8158
+ try {
8159
+ window.localStorage.removeItem(key);
8160
+ }
8161
+ catch (error) {
8162
+ // Ignore errors
8163
+ }
8164
+ });
8165
+ }
8166
+ catch (error) {
8167
+ // Ignore errors
8168
+ }
8169
+ }
8019
8170
  if (onDisconnect) {
8020
8171
  onDisconnect();
8021
8172
  }
@@ -8383,12 +8534,51 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
8383
8534
  }, [connector, fetchBalance, loadBalance]);
8384
8535
  const handleDisconnect = React.useCallback(async () => {
8385
8536
  try {
8386
- await connector.disconnect();
8537
+ // Close all modals first
8387
8538
  setShowDetailsModal(false);
8539
+ setShowModal(false);
8540
+ setShowSwapModal(false);
8541
+ setShowSendModal(false);
8542
+ setShowActivityModal(false);
8543
+ setShowTWCBalanceModal(false);
8544
+ // Clear current account address before disconnect
8545
+ const currentAddress = account?.address;
8546
+ // Disconnect from connector
8547
+ await connector.disconnect();
8548
+ // Additional cleanup - clear all TWC balance cache entries
8549
+ if (currentAddress) {
8550
+ clearTWCBalanceCache(currentAddress);
8551
+ }
8552
+ // Clear all localStorage items related to TWC and wallets
8553
+ if (typeof window !== 'undefined' && window.localStorage) {
8554
+ try {
8555
+ const keysToRemove = [];
8556
+ for (let i = 0; i < window.localStorage.length; i++) {
8557
+ const key = window.localStorage.key(i);
8558
+ if (key && (key.includes(TWC_BALANCE_CACHE_KEY) || key.toLowerCase().includes('wallet'))) {
8559
+ keysToRemove.push(key);
8560
+ }
8561
+ }
8562
+ keysToRemove.forEach(key => {
8563
+ try {
8564
+ window.localStorage.removeItem(key);
8565
+ }
8566
+ catch (error) {
8567
+ // Ignore errors
8568
+ }
8569
+ });
8570
+ }
8571
+ catch (error) {
8572
+ // Ignore errors
8573
+ }
8574
+ }
8388
8575
  }
8389
8576
  catch (err) {
8577
+ // Even on error, ensure modals are closed
8578
+ setShowDetailsModal(false);
8579
+ setShowModal(false);
8390
8580
  }
8391
- }, [connector]);
8581
+ }, [connector, account?.address]);
8392
8582
  const handleCopyAddress = React.useCallback(() => {
8393
8583
  if (account?.address) {
8394
8584
  navigator.clipboard.writeText(account.address);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tiwiflix-wallet-connector",
3
- "version": "1.4.7",
3
+ "version": "1.5.0",
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",