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 +4 -0
- package/dist/index.esm.js +211 -21
- package/dist/index.js +211 -21
- package/package.json +1 -1
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:
|
|
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
|
-
|
|
7773
|
-
|
|
7774
|
-
|
|
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
|
-
|
|
7788
|
-
|
|
7789
|
-
|
|
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
|
|
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
|
-
},
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
7775
|
-
|
|
7776
|
-
|
|
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
|
-
|
|
7790
|
-
|
|
7791
|
-
|
|
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
|
|
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
|
-
},
|
|
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
|
-
|
|
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