tiwiflix-wallet-connector 1.6.5 → 1.6.7
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 +182 -43
- package/dist/index.js +182 -43
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ethers } from 'ethers';
|
|
1
2
|
import React, { useMemo, useState, useEffect, useRef, useCallback } from 'react';
|
|
2
3
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
4
|
import ReactDOM from 'react-dom';
|
|
@@ -2552,13 +2553,9 @@ class WalletConnector {
|
|
|
2552
2553
|
if (account && adapter.chainType === ChainType.TON) {
|
|
2553
2554
|
try {
|
|
2554
2555
|
const nftResult = await this.checkNFTOwnership([
|
|
2555
|
-
// New collection - user-friendly format
|
|
2556
2556
|
'EQDVaDCso_2LRTkc8WrT9A4bVO5BG_PZ8313BC_lOO8XW1T8',
|
|
2557
|
-
// New collection - raw format
|
|
2558
2557
|
'0:d56830aca3fd8b45391cf16ad3f40e1b54ee411bf3d9f37d77042fe538ef175b',
|
|
2559
|
-
// Legacy collection - user-friendly format
|
|
2560
2558
|
'EQDKfA87JVnBJXsBVfzjIfbhr3bmTTdouUP31Szgm_Lw0v-J',
|
|
2561
|
-
// Legacy collection - raw format
|
|
2562
2559
|
'0:ca7c0f3b2559c1257b0155fce321f6e1af76e64d3768b943f7d52ce09bf2f0d2'
|
|
2563
2560
|
]);
|
|
2564
2561
|
accountWithNFTs = {
|
|
@@ -2569,7 +2566,6 @@ class WalletConnector {
|
|
|
2569
2566
|
hasRequiredNFTs: nftResult.hasNFTs,
|
|
2570
2567
|
ownedCount: nftResult.ownedNFTs.length
|
|
2571
2568
|
});
|
|
2572
|
-
// Update state with NFT count and data
|
|
2573
2569
|
this.updateState({
|
|
2574
2570
|
account: accountWithNFTs,
|
|
2575
2571
|
nftCount: nftResult.ownedNFTs.length,
|
|
@@ -2578,36 +2574,40 @@ class WalletConnector {
|
|
|
2578
2574
|
}
|
|
2579
2575
|
catch (nftError) {
|
|
2580
2576
|
this.debugTools.warn('WALLET_CONNECTOR', 'NFT check failed during account change', nftError);
|
|
2581
|
-
// Continue with account change even if NFT check fails
|
|
2582
2577
|
this.updateState({ account: accountWithNFTs });
|
|
2583
2578
|
}
|
|
2584
2579
|
}
|
|
2585
2580
|
else {
|
|
2586
2581
|
this.updateState({ account: accountWithNFTs });
|
|
2587
2582
|
}
|
|
2583
|
+
// Always update chainId in state after account change (for EVM wallets)
|
|
2584
|
+
if (account && adapter.chainType === ChainType.EVM && typeof adapter.getChainId === 'function') {
|
|
2585
|
+
try {
|
|
2586
|
+
const chainId = await adapter.getChainId();
|
|
2587
|
+
this.updateState({ chainId });
|
|
2588
|
+
}
|
|
2589
|
+
catch (e) {
|
|
2590
|
+
this.updateState({ chainId: null });
|
|
2591
|
+
}
|
|
2592
|
+
}
|
|
2588
2593
|
this.eventEmitter.emit(WalletEvent.ACCOUNT_CHANGED, accountWithNFTs);
|
|
2589
2594
|
if (account) {
|
|
2590
2595
|
this.eventEmitter.emit(WalletEvent.CONNECTED, account);
|
|
2591
|
-
// Automatically fetch new balance and price when account changes
|
|
2592
2596
|
try {
|
|
2593
2597
|
this.debugTools.info('WALLET_CONNECTOR', 'Account changed, fetching new balance and price', {
|
|
2594
2598
|
account: account.address,
|
|
2595
2599
|
wallet: walletType
|
|
2596
2600
|
});
|
|
2597
|
-
// Clear price cache for new account
|
|
2598
2601
|
priceService.clearCache();
|
|
2599
|
-
// Fetch TWC balance and price
|
|
2600
2602
|
if (adapter.chainType === ChainType.EVM) {
|
|
2601
2603
|
try {
|
|
2602
2604
|
const twcBalance = await this.getTWCBalance();
|
|
2603
|
-
// Persist in state for exportability
|
|
2604
2605
|
this.updateState({ twcBalance: twcBalance.amount, usdValue: twcBalance.usdValue ?? null });
|
|
2605
2606
|
this.debugTools.info('WALLET_CONNECTOR', 'TWC balance updated for new account', {
|
|
2606
2607
|
balance: twcBalance.amount,
|
|
2607
2608
|
usdValue: twcBalance.usdValue,
|
|
2608
2609
|
account: account.address
|
|
2609
2610
|
});
|
|
2610
|
-
// Emit balance update event
|
|
2611
2611
|
this.eventEmitter.emit(WalletEvent.BALANCE_UPDATED, {
|
|
2612
2612
|
type: 'TWC',
|
|
2613
2613
|
balance: twcBalance.amount,
|
|
@@ -2619,7 +2619,6 @@ class WalletConnector {
|
|
|
2619
2619
|
}
|
|
2620
2620
|
catch (twcError) {
|
|
2621
2621
|
this.debugTools.warn('WALLET_CONNECTOR', 'Failed to fetch TWC balance for new account', twcError);
|
|
2622
|
-
// Fallback to native balance
|
|
2623
2622
|
try {
|
|
2624
2623
|
const nativeBalance = await this.getNativeBalance();
|
|
2625
2624
|
this.debugTools.info('WALLET_CONNECTOR', 'Native balance updated for new account', {
|
|
@@ -2627,7 +2626,6 @@ class WalletConnector {
|
|
|
2627
2626
|
symbol: nativeBalance.symbol,
|
|
2628
2627
|
account: account.address
|
|
2629
2628
|
});
|
|
2630
|
-
// Emit balance update event
|
|
2631
2629
|
this.eventEmitter.emit(WalletEvent.BALANCE_UPDATED, {
|
|
2632
2630
|
type: 'NATIVE',
|
|
2633
2631
|
balance: nativeBalance.amount,
|
|
@@ -2646,7 +2644,6 @@ class WalletConnector {
|
|
|
2646
2644
|
}
|
|
2647
2645
|
}
|
|
2648
2646
|
else if (this.state.wallet) {
|
|
2649
|
-
// Account removed/disconnected from wallet app
|
|
2650
2647
|
this.storage.clearWallet();
|
|
2651
2648
|
this.updateState({ wallet: null, account: null, status: ConnectionStatus.DISCONNECTED, twcBalance: null, usdValue: null, nftCount: 0, nftData: null });
|
|
2652
2649
|
this.eventEmitter.emit(WalletEvent.DISCONNECTED, undefined);
|
|
@@ -2692,13 +2689,9 @@ class WalletConnector {
|
|
|
2692
2689
|
if (adapter.chainType === ChainType.TON) {
|
|
2693
2690
|
try {
|
|
2694
2691
|
const nftResult = await this.checkNFTOwnership([
|
|
2695
|
-
// New collection - user-friendly format
|
|
2696
2692
|
'EQDVaDCso_2LRTkc8WrT9A4bVO5BG_PZ8313BC_lOO8XW1T8',
|
|
2697
|
-
// New collection - raw format
|
|
2698
2693
|
'0:d56830aca3fd8b45391cf16ad3f40e1b54ee411bf3d9f37d77042fe538ef175b',
|
|
2699
|
-
// Legacy collection - user-friendly format
|
|
2700
2694
|
'EQDKfA87JVnBJXsBVfzjIfbhr3bmTTdouUP31Szgm_Lw0v-J',
|
|
2701
|
-
// Legacy collection - raw format
|
|
2702
2695
|
'0:ca7c0f3b2559c1257b0155fce321f6e1af76e64d3768b943f7d52ce09bf2f0d2'
|
|
2703
2696
|
]);
|
|
2704
2697
|
accountWithNFTs = {
|
|
@@ -2712,7 +2705,6 @@ class WalletConnector {
|
|
|
2712
2705
|
}
|
|
2713
2706
|
catch (nftError) {
|
|
2714
2707
|
this.debugTools.warn('WALLET_CONNECTOR', 'NFT check failed, proceeding without NFT info', nftError);
|
|
2715
|
-
// Continue with connection even if NFT check fails
|
|
2716
2708
|
}
|
|
2717
2709
|
}
|
|
2718
2710
|
this.storage.saveWallet(walletType);
|
|
@@ -2722,6 +2714,39 @@ class WalletConnector {
|
|
|
2722
2714
|
error: null,
|
|
2723
2715
|
});
|
|
2724
2716
|
this.eventEmitter.emit(WalletEvent.CONNECTED, accountWithNFTs);
|
|
2717
|
+
// Immediately fetch TWC balance after initial connection (not just on reconnect or refresh)
|
|
2718
|
+
if (adapter.chainType === ChainType.EVM) {
|
|
2719
|
+
try {
|
|
2720
|
+
// Update chainId in state if possible
|
|
2721
|
+
if (typeof adapter.getChainId === 'function') {
|
|
2722
|
+
try {
|
|
2723
|
+
const chainId = await adapter.getChainId();
|
|
2724
|
+
this.updateState({ chainId });
|
|
2725
|
+
}
|
|
2726
|
+
catch (e) {
|
|
2727
|
+
this.updateState({ chainId: null });
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
const twcBalance = await this.getTWCBalance();
|
|
2731
|
+
this.updateState({ twcBalance: twcBalance.amount, usdValue: twcBalance.usdValue ?? null });
|
|
2732
|
+
this.debugTools.info('WALLET_CONNECTOR', 'TWC balance updated after initial connect', {
|
|
2733
|
+
balance: twcBalance.amount,
|
|
2734
|
+
usdValue: twcBalance.usdValue,
|
|
2735
|
+
account: accountWithNFTs.address
|
|
2736
|
+
});
|
|
2737
|
+
this.eventEmitter.emit(WalletEvent.BALANCE_UPDATED, {
|
|
2738
|
+
type: 'TWC',
|
|
2739
|
+
balance: twcBalance.amount,
|
|
2740
|
+
symbol: twcBalance.symbol,
|
|
2741
|
+
usdValue: twcBalance.usdValue,
|
|
2742
|
+
usdFormatted: twcBalance.usdFormatted,
|
|
2743
|
+
account: accountWithNFTs.address
|
|
2744
|
+
});
|
|
2745
|
+
}
|
|
2746
|
+
catch (twcError) {
|
|
2747
|
+
this.debugTools.warn('WALLET_CONNECTOR', 'Failed to fetch TWC balance after initial connect', twcError);
|
|
2748
|
+
}
|
|
2749
|
+
}
|
|
2725
2750
|
}
|
|
2726
2751
|
else {
|
|
2727
2752
|
// Connection failed - reset state properly
|
|
@@ -3102,14 +3127,21 @@ class WalletConnector {
|
|
|
3102
3127
|
}
|
|
3103
3128
|
async getTWCBalance() {
|
|
3104
3129
|
if (!this.state.account) {
|
|
3130
|
+
if (typeof window !== 'undefined')
|
|
3131
|
+
window.showDebugLog?.('[getTWCBalance] No wallet connected');
|
|
3105
3132
|
throw new Error('No wallet connected');
|
|
3106
3133
|
}
|
|
3107
3134
|
const accountAddress = this.state.account.address;
|
|
3135
|
+
const chainId = this.state.chainId;
|
|
3108
3136
|
performance.now();
|
|
3137
|
+
if (typeof window !== 'undefined')
|
|
3138
|
+
window.showDebugLog?.(`[getTWCBalance] Called for account=${accountAddress}, chainId=${chainId}`);
|
|
3109
3139
|
// Check cache first
|
|
3110
3140
|
if (this.twcBalanceCache &&
|
|
3111
3141
|
this.twcBalanceCache.address === accountAddress &&
|
|
3112
3142
|
Date.now() - this.twcBalanceCache.timestamp < this.TWC_CACHE_TTL) {
|
|
3143
|
+
if (typeof window !== 'undefined')
|
|
3144
|
+
window.showDebugLog?.(`[getTWCBalance] Using cache for ${accountAddress}: ${JSON.stringify(this.twcBalanceCache)}`);
|
|
3113
3145
|
return {
|
|
3114
3146
|
amount: this.twcBalanceCache.balance,
|
|
3115
3147
|
symbol: 'TWC',
|
|
@@ -3126,26 +3158,86 @@ class WalletConnector {
|
|
|
3126
3158
|
// Use the currently connected wallet's adapter
|
|
3127
3159
|
const currentWallet = this.state.wallet;
|
|
3128
3160
|
if (!currentWallet) {
|
|
3161
|
+
if (typeof window !== 'undefined')
|
|
3162
|
+
window.showDebugLog?.('[getTWCBalance] No wallet connected (no currentWallet)');
|
|
3129
3163
|
throw new Error('No wallet connected');
|
|
3130
3164
|
}
|
|
3131
3165
|
const adapter = this.adapters.get(currentWallet);
|
|
3132
3166
|
if (!adapter || adapter.chainType !== ChainType.EVM) {
|
|
3167
|
+
if (typeof window !== 'undefined')
|
|
3168
|
+
window.showDebugLog?.('[getTWCBalance] No EVM adapter available');
|
|
3133
3169
|
throw new Error('No EVM adapter available');
|
|
3134
3170
|
}
|
|
3135
|
-
//
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3171
|
+
// Debug: log adapter type and available methods
|
|
3172
|
+
if (typeof window !== 'undefined') {
|
|
3173
|
+
window.showDebugLog?.(`[getTWCBalance] Using adapter: ${adapter.constructor?.name || typeof adapter}`);
|
|
3174
|
+
window.showDebugLog?.(`[getTWCBalance] Adapter keys: ${Object.keys(adapter).join(', ')}`);
|
|
3175
|
+
window.showDebugLog?.(`[getTWCBalance] typeof getTokenBalance: ${typeof adapter.getTokenBalance}`);
|
|
3176
|
+
}
|
|
3177
|
+
let balance;
|
|
3178
|
+
// Always use ethers fallback if EVM is connected, regardless of chainId
|
|
3179
|
+
if (this.state.chainId !== 56) {
|
|
3180
|
+
if (typeof window !== 'undefined')
|
|
3181
|
+
window.showDebugLog?.(`[getTWCBalance] Warning: Not on BSC (chainId=${this.state.chainId}), but fetching TWC balance using ethers fallback.`);
|
|
3182
|
+
// Fallback: use ethers.js to fetch balance from chain
|
|
3183
|
+
let provider = adapter.provider || this.getProvider();
|
|
3184
|
+
if (!provider) {
|
|
3185
|
+
if (typeof window !== 'undefined')
|
|
3186
|
+
window.showDebugLog?.('[getTWCBalance] No provider available for ethers fallback');
|
|
3187
|
+
throw new Error('No provider available for ethers fallback');
|
|
3188
|
+
}
|
|
3189
|
+
if (!provider._isProvider) {
|
|
3190
|
+
provider = new ethers.BrowserProvider(provider);
|
|
3191
|
+
}
|
|
3192
|
+
const erc20Abi = ["function balanceOf(address) view returns (uint256)"];
|
|
3193
|
+
const contract = new ethers.Contract(TWC_CONTRACT, erc20Abi, provider);
|
|
3194
|
+
const rawBalance = await contract.balanceOf(accountAddress);
|
|
3195
|
+
if (typeof window !== 'undefined')
|
|
3196
|
+
window.showDebugLog?.(`[getTWCBalance] [ethers fallback] rawBalance (BigInt) for ${accountAddress}: ${rawBalance?.toString?.()}`);
|
|
3197
|
+
balance = ethers.formatUnits(rawBalance, TWC_DECIMALS);
|
|
3198
|
+
if (typeof window !== 'undefined')
|
|
3199
|
+
window.showDebugLog?.(`[getTWCBalance] Raw balance for ${accountAddress} (ethers): ${balance}`);
|
|
3200
|
+
}
|
|
3201
|
+
else if (typeof adapter.getTokenBalance === 'function') {
|
|
3202
|
+
// Use adapter method if available and on BSC
|
|
3203
|
+
const balancePromise = adapter.getTokenBalance(TWC_CONTRACT, TWC_DECIMALS, true);
|
|
3204
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
3205
|
+
setTimeout(() => reject(new Error('Balance fetch timeout after 10 seconds')), 10000);
|
|
3206
|
+
});
|
|
3207
|
+
balance = await Promise.race([balancePromise, timeoutPromise]);
|
|
3208
|
+
if (typeof window !== 'undefined')
|
|
3209
|
+
window.showDebugLog?.(`[getTWCBalance] Raw balance for ${accountAddress} (adapter): ${balance}`);
|
|
3210
|
+
}
|
|
3211
|
+
else {
|
|
3212
|
+
// Fallback: use ethers.js to fetch balance from chain (should not happen, but for safety)
|
|
3213
|
+
if (typeof window !== 'undefined')
|
|
3214
|
+
window.showDebugLog?.('[getTWCBalance] Fallback to ethers.js for TWC balance (on BSC)');
|
|
3215
|
+
let provider = adapter.provider || this.getProvider();
|
|
3216
|
+
if (!provider) {
|
|
3217
|
+
if (typeof window !== 'undefined')
|
|
3218
|
+
window.showDebugLog?.('[getTWCBalance] No provider available for ethers fallback');
|
|
3219
|
+
throw new Error('No provider available for ethers fallback');
|
|
3220
|
+
}
|
|
3221
|
+
if (!provider._isProvider) {
|
|
3222
|
+
provider = new ethers.BrowserProvider(provider);
|
|
3223
|
+
}
|
|
3224
|
+
const erc20Abi = ["function balanceOf(address) view returns (uint256)"];
|
|
3225
|
+
const contract = new ethers.Contract(TWC_CONTRACT, erc20Abi, provider);
|
|
3226
|
+
const rawBalance = await contract.balanceOf(accountAddress);
|
|
3227
|
+
if (typeof window !== 'undefined')
|
|
3228
|
+
window.showDebugLog?.(`[getTWCBalance] [ethers fallback] rawBalance (BigInt) for ${accountAddress}: ${rawBalance?.toString?.()}`);
|
|
3229
|
+
balance = ethers.formatUnits(rawBalance, TWC_DECIMALS);
|
|
3230
|
+
if (typeof window !== 'undefined')
|
|
3231
|
+
window.showDebugLog?.(`[getTWCBalance] Raw balance for ${accountAddress} (ethers): ${balance}`);
|
|
3232
|
+
}
|
|
3143
3233
|
// Calculate USD value with 5 second timeout
|
|
3144
3234
|
const usdPromise = priceService.calculateTWCValue(balance);
|
|
3145
3235
|
const usdTimeoutPromise = new Promise((resolve) => {
|
|
3146
3236
|
setTimeout(() => resolve(0), 5000); // Default to 0 on timeout
|
|
3147
3237
|
});
|
|
3148
3238
|
const usdValue = await Promise.race([usdPromise, usdTimeoutPromise]);
|
|
3239
|
+
if (typeof window !== 'undefined')
|
|
3240
|
+
window.showDebugLog?.(`[getTWCBalance] USD value for ${accountAddress}: ${usdValue}`);
|
|
3149
3241
|
// Update cache
|
|
3150
3242
|
this.twcBalanceCache = {
|
|
3151
3243
|
balance,
|
|
@@ -3161,10 +3253,14 @@ class WalletConnector {
|
|
|
3161
3253
|
};
|
|
3162
3254
|
// Keep state in sync
|
|
3163
3255
|
this.updateState({ twcBalance: result.amount, usdValue: result.usdValue ?? null });
|
|
3256
|
+
if (typeof window !== 'undefined')
|
|
3257
|
+
window.showDebugLog?.(`[getTWCBalance] Final result for ${accountAddress}: ${JSON.stringify(result)}`);
|
|
3164
3258
|
return result;
|
|
3165
3259
|
}
|
|
3166
3260
|
catch (error) {
|
|
3167
3261
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
3262
|
+
if (typeof window !== 'undefined')
|
|
3263
|
+
window.showDebugLog?.(`[getTWCBalance] ERROR: ${errorMsg}`);
|
|
3168
3264
|
// Track error
|
|
3169
3265
|
this.balanceFetchErrors.push({
|
|
3170
3266
|
endpoint: 'wallet-provider',
|
|
@@ -7517,6 +7613,41 @@ const TWCBalanceModal = ({ isOpen, onClose, twcBalance, usdValue, colors, isDark
|
|
|
7517
7613
|
}, children: "Learn More" })] })] }) }));
|
|
7518
7614
|
};
|
|
7519
7615
|
|
|
7616
|
+
// Debug log overlay for mobile
|
|
7617
|
+
function showDebugLog(msg) {
|
|
7618
|
+
if (typeof window === 'undefined')
|
|
7619
|
+
return;
|
|
7620
|
+
let logDiv = document.getElementById('twc-debug-log');
|
|
7621
|
+
if (!logDiv) {
|
|
7622
|
+
logDiv = document.createElement('div');
|
|
7623
|
+
logDiv.id = 'twc-debug-log';
|
|
7624
|
+
logDiv.style.position = 'fixed';
|
|
7625
|
+
logDiv.style.bottom = '10px';
|
|
7626
|
+
logDiv.style.left = '10px';
|
|
7627
|
+
logDiv.style.right = '10px';
|
|
7628
|
+
logDiv.style.maxHeight = '40vh';
|
|
7629
|
+
logDiv.style.overflowY = 'auto';
|
|
7630
|
+
logDiv.style.background = 'rgba(0,0,0,0.85)';
|
|
7631
|
+
logDiv.style.color = '#fff';
|
|
7632
|
+
logDiv.style.fontSize = '12px';
|
|
7633
|
+
logDiv.style.zIndex = '99999';
|
|
7634
|
+
logDiv.style.padding = '8px 12px';
|
|
7635
|
+
logDiv.style.borderRadius = '8px';
|
|
7636
|
+
logDiv.style.pointerEvents = 'auto';
|
|
7637
|
+
logDiv.style.fontFamily = 'monospace';
|
|
7638
|
+
logDiv.style.boxShadow = '0 2px 12px rgba(0,0,0,0.3)';
|
|
7639
|
+
logDiv.innerHTML = '';
|
|
7640
|
+
document.body.appendChild(logDiv);
|
|
7641
|
+
}
|
|
7642
|
+
const now = new Date();
|
|
7643
|
+
const time = now.toLocaleTimeString();
|
|
7644
|
+
logDiv.innerHTML = `<div>[${time}] ${msg}</div>` + logDiv.innerHTML;
|
|
7645
|
+
// Limit to 30 log lines
|
|
7646
|
+
const lines = logDiv.innerHTML.split('<div>');
|
|
7647
|
+
if (lines.length > 30) {
|
|
7648
|
+
logDiv.innerHTML = lines.slice(0, 30).join('<div>');
|
|
7649
|
+
}
|
|
7650
|
+
}
|
|
7520
7651
|
const tonApiCache = new Map();
|
|
7521
7652
|
const CACHE_DURATION = 30000; // 30 seconds
|
|
7522
7653
|
const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className, style, showBalance = false, modalPosition = 'center', theme = 'auto', buttonText = 'Connect Wallet', getExplorerUrl, }) => {
|
|
@@ -7822,12 +7953,20 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
7822
7953
|
return;
|
|
7823
7954
|
}
|
|
7824
7955
|
try {
|
|
7825
|
-
|
|
7956
|
+
let chainId = await connector.getCurrentChain();
|
|
7826
7957
|
setCurrentChainId(chainId);
|
|
7827
7958
|
if (chainId !== 56) {
|
|
7828
7959
|
// Automatically switch to BSC
|
|
7829
7960
|
try {
|
|
7830
7961
|
await connector.switchChain(56);
|
|
7962
|
+
// After switching, re-fetch chainId and update state
|
|
7963
|
+
chainId = await connector.getCurrentChain();
|
|
7964
|
+
setCurrentChainId(chainId);
|
|
7965
|
+
// Optionally, trigger TWC balance fetch here if needed
|
|
7966
|
+
if (chainId === 56) {
|
|
7967
|
+
// Force a state update to trigger TWC balance fetch effect
|
|
7968
|
+
setTimeout(() => setCurrentChainId(56), 100); // small delay to ensure state update
|
|
7969
|
+
}
|
|
7831
7970
|
}
|
|
7832
7971
|
catch (err) {
|
|
7833
7972
|
// Optionally handle error (user rejected, etc.)
|
|
@@ -8389,13 +8528,15 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8389
8528
|
}
|
|
8390
8529
|
}, [account]);
|
|
8391
8530
|
const fetchTWCBalanceWithRetry = useCallback(async (maxRetries = 3, initialDelay = 200) => {
|
|
8392
|
-
//
|
|
8531
|
+
// Fetch TWC balance for all EVM chains (for debugging)
|
|
8393
8532
|
try {
|
|
8394
8533
|
const state = connector.getState();
|
|
8395
|
-
if (state.account?.chainType !== 'evm'
|
|
8396
|
-
// Not
|
|
8534
|
+
if (state.account?.chainType !== 'evm') {
|
|
8535
|
+
// Not EVM, do not fetch TWC balance
|
|
8397
8536
|
return null;
|
|
8398
8537
|
}
|
|
8538
|
+
// Log chainId for debug
|
|
8539
|
+
showDebugLog?.(`[fetchTWCBalanceWithRetry] Fetching TWC for chainId=${state.chainId}`);
|
|
8399
8540
|
const twcBalance = await connector.getTWCBalance();
|
|
8400
8541
|
return {
|
|
8401
8542
|
balance: twcBalance.amount || '0',
|
|
@@ -8430,6 +8571,7 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8430
8571
|
// Fetch TWC balance immediately after connection
|
|
8431
8572
|
const cacheKey = `tiwiflix_twc_balance_cache_${account.address}`;
|
|
8432
8573
|
fetchTWCBalanceWithRetry(2, 200).then((result) => {
|
|
8574
|
+
showDebugLog(`[ConnectButton] TWC balance fetch after WalletConnect connect: status=${status}, account=${account?.address}, chainId=${chainId}, result=${JSON.stringify(result)}`);
|
|
8433
8575
|
if (result && result.balance !== '0' && result.balance !== '0.00') {
|
|
8434
8576
|
setTwcBalance(result.balance);
|
|
8435
8577
|
setUsdValueStable(result.usdValue);
|
|
@@ -8437,7 +8579,6 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8437
8579
|
localStorage.setItem(cacheKey, JSON.stringify({ balance: result.balance, usdValue: result.usdValue, timestamp: Date.now() }));
|
|
8438
8580
|
}
|
|
8439
8581
|
setIsInitializing(false);
|
|
8440
|
-
console.log('[ConnectButton] TWC balance fetched after WalletConnect connect:', result);
|
|
8441
8582
|
}
|
|
8442
8583
|
});
|
|
8443
8584
|
}
|
|
@@ -8468,7 +8609,7 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8468
8609
|
setTwcBalance(cache.balance);
|
|
8469
8610
|
setUsdValueStable(cache.usdValue);
|
|
8470
8611
|
setIsInitializing(false);
|
|
8471
|
-
|
|
8612
|
+
showDebugLog(`[ConnectButton] Using localStorage cached TWC balance: ${JSON.stringify(cache)}`);
|
|
8472
8613
|
// Fetch in background to update cache, but don't reset UI while fetching
|
|
8473
8614
|
fetchTWCBalanceWithRetry(2, 200).then((result) => {
|
|
8474
8615
|
if (!isActive)
|
|
@@ -8481,7 +8622,7 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8481
8622
|
localStorage.setItem(cacheKey, JSON.stringify({ balance: result.balance, usdValue: result.usdValue, timestamp: Date.now() }));
|
|
8482
8623
|
}
|
|
8483
8624
|
setIsInitializing(false);
|
|
8484
|
-
|
|
8625
|
+
showDebugLog(`[ConnectButton] TWC balance updated after background fetch: ${JSON.stringify(result)}`);
|
|
8485
8626
|
}
|
|
8486
8627
|
}).catch(() => {
|
|
8487
8628
|
// Ignore errors in background fetch
|
|
@@ -8501,19 +8642,19 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8501
8642
|
localStorage.setItem(cacheKey, JSON.stringify({ balance: result.balance, usdValue: result.usdValue, timestamp: Date.now() }));
|
|
8502
8643
|
}
|
|
8503
8644
|
setIsInitializing(false);
|
|
8504
|
-
|
|
8645
|
+
showDebugLog(`[ConnectButton] TWC balance fetched and cached: ${JSON.stringify(result)}`);
|
|
8505
8646
|
}
|
|
8506
8647
|
else {
|
|
8507
8648
|
setTwcBalance('0');
|
|
8508
8649
|
setUsdValueStable(null);
|
|
8509
8650
|
setIsInitializing(false);
|
|
8510
|
-
|
|
8651
|
+
showDebugLog(`[ConnectButton] No TWC balance found for BSC wallet: ${account.address}`);
|
|
8511
8652
|
}
|
|
8512
8653
|
}).catch(() => {
|
|
8513
8654
|
if (!isActive)
|
|
8514
8655
|
return;
|
|
8515
8656
|
setIsInitializing(false);
|
|
8516
|
-
|
|
8657
|
+
showDebugLog(`[ConnectButton] Error fetching TWC balance for BSC wallet: ${account.address}`);
|
|
8517
8658
|
});
|
|
8518
8659
|
}
|
|
8519
8660
|
}
|
|
@@ -8737,8 +8878,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8737
8878
|
}, [connector, account]);
|
|
8738
8879
|
// Render button based on connection status
|
|
8739
8880
|
const renderButton = () => {
|
|
8740
|
-
// Only show connect button if we are fully initialized and truly disconnected
|
|
8741
|
-
if (!isInitializing && (!account
|
|
8881
|
+
// Only show connect button if we are fully initialized and truly disconnected (no account and status is DISCONNECTED)
|
|
8882
|
+
if (!isInitializing && (!account && status === ConnectionStatus.DISCONNECTED)) {
|
|
8742
8883
|
// Wallet icon SVG component
|
|
8743
8884
|
const WalletIcon = () => (jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: { display: 'block' }, children: [jsx("path", { d: "M19 7V4a1 1 0 0 0-1-1H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v4h-3a2 2 0 0 0 0 4h3a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1" }), jsx("path", { d: "M3 5v14a2 2 0 0 0 2 2h15a1 1 0 0 0 1-1v-4" })] }));
|
|
8744
8885
|
return (jsxs("button", { onClick: () => handleOpenModal(), style: {
|
|
@@ -8767,16 +8908,14 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8767
8908
|
e.currentTarget.style.boxShadow = '0 2px 8px rgba(255, 152, 20, 0.3)';
|
|
8768
8909
|
}, children: [jsx("span", { style: { color: '#000000', display: 'flex', alignItems: 'center' }, children: jsx(WalletIcon, {}) }), jsx("span", { style: { color: '#000000', fontWeight: '500', fontSize: '14px' }, children: buttonText })] }));
|
|
8769
8910
|
}
|
|
8770
|
-
// ...existing code...
|
|
8771
8911
|
// All other states (including loading, connecting, connected) should only show the connected button or loading spinner if account is present or initializing is true
|
|
8772
8912
|
// If initializing, show nothing (or a spinner if desired)
|
|
8773
8913
|
if (isInitializing) {
|
|
8774
8914
|
// Optionally, you can show a spinner or skeleton here, but do not show connect/disconnect buttons
|
|
8775
8915
|
return null;
|
|
8776
8916
|
}
|
|
8777
|
-
//
|
|
8778
|
-
|
|
8779
|
-
if (account) {
|
|
8917
|
+
// Show connected button for any state where account is present and status is not DISCONNECTED or CONNECTING
|
|
8918
|
+
if (account && status !== ConnectionStatus.DISCONNECTED && status !== ConnectionStatus.CONNECTING) {
|
|
8780
8919
|
// ...existing code...
|
|
8781
8920
|
// Show normal connected button - styled to match design
|
|
8782
8921
|
// Parse balance amount and symbol separately
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var ethers = require('ethers');
|
|
3
4
|
var React = require('react');
|
|
4
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
6
|
var ReactDOM = require('react-dom');
|
|
@@ -2554,13 +2555,9 @@ class WalletConnector {
|
|
|
2554
2555
|
if (account && adapter.chainType === exports.ChainType.TON) {
|
|
2555
2556
|
try {
|
|
2556
2557
|
const nftResult = await this.checkNFTOwnership([
|
|
2557
|
-
// New collection - user-friendly format
|
|
2558
2558
|
'EQDVaDCso_2LRTkc8WrT9A4bVO5BG_PZ8313BC_lOO8XW1T8',
|
|
2559
|
-
// New collection - raw format
|
|
2560
2559
|
'0:d56830aca3fd8b45391cf16ad3f40e1b54ee411bf3d9f37d77042fe538ef175b',
|
|
2561
|
-
// Legacy collection - user-friendly format
|
|
2562
2560
|
'EQDKfA87JVnBJXsBVfzjIfbhr3bmTTdouUP31Szgm_Lw0v-J',
|
|
2563
|
-
// Legacy collection - raw format
|
|
2564
2561
|
'0:ca7c0f3b2559c1257b0155fce321f6e1af76e64d3768b943f7d52ce09bf2f0d2'
|
|
2565
2562
|
]);
|
|
2566
2563
|
accountWithNFTs = {
|
|
@@ -2571,7 +2568,6 @@ class WalletConnector {
|
|
|
2571
2568
|
hasRequiredNFTs: nftResult.hasNFTs,
|
|
2572
2569
|
ownedCount: nftResult.ownedNFTs.length
|
|
2573
2570
|
});
|
|
2574
|
-
// Update state with NFT count and data
|
|
2575
2571
|
this.updateState({
|
|
2576
2572
|
account: accountWithNFTs,
|
|
2577
2573
|
nftCount: nftResult.ownedNFTs.length,
|
|
@@ -2580,36 +2576,40 @@ class WalletConnector {
|
|
|
2580
2576
|
}
|
|
2581
2577
|
catch (nftError) {
|
|
2582
2578
|
this.debugTools.warn('WALLET_CONNECTOR', 'NFT check failed during account change', nftError);
|
|
2583
|
-
// Continue with account change even if NFT check fails
|
|
2584
2579
|
this.updateState({ account: accountWithNFTs });
|
|
2585
2580
|
}
|
|
2586
2581
|
}
|
|
2587
2582
|
else {
|
|
2588
2583
|
this.updateState({ account: accountWithNFTs });
|
|
2589
2584
|
}
|
|
2585
|
+
// Always update chainId in state after account change (for EVM wallets)
|
|
2586
|
+
if (account && adapter.chainType === exports.ChainType.EVM && typeof adapter.getChainId === 'function') {
|
|
2587
|
+
try {
|
|
2588
|
+
const chainId = await adapter.getChainId();
|
|
2589
|
+
this.updateState({ chainId });
|
|
2590
|
+
}
|
|
2591
|
+
catch (e) {
|
|
2592
|
+
this.updateState({ chainId: null });
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2590
2595
|
this.eventEmitter.emit(exports.WalletEvent.ACCOUNT_CHANGED, accountWithNFTs);
|
|
2591
2596
|
if (account) {
|
|
2592
2597
|
this.eventEmitter.emit(exports.WalletEvent.CONNECTED, account);
|
|
2593
|
-
// Automatically fetch new balance and price when account changes
|
|
2594
2598
|
try {
|
|
2595
2599
|
this.debugTools.info('WALLET_CONNECTOR', 'Account changed, fetching new balance and price', {
|
|
2596
2600
|
account: account.address,
|
|
2597
2601
|
wallet: walletType
|
|
2598
2602
|
});
|
|
2599
|
-
// Clear price cache for new account
|
|
2600
2603
|
priceService.clearCache();
|
|
2601
|
-
// Fetch TWC balance and price
|
|
2602
2604
|
if (adapter.chainType === exports.ChainType.EVM) {
|
|
2603
2605
|
try {
|
|
2604
2606
|
const twcBalance = await this.getTWCBalance();
|
|
2605
|
-
// Persist in state for exportability
|
|
2606
2607
|
this.updateState({ twcBalance: twcBalance.amount, usdValue: twcBalance.usdValue ?? null });
|
|
2607
2608
|
this.debugTools.info('WALLET_CONNECTOR', 'TWC balance updated for new account', {
|
|
2608
2609
|
balance: twcBalance.amount,
|
|
2609
2610
|
usdValue: twcBalance.usdValue,
|
|
2610
2611
|
account: account.address
|
|
2611
2612
|
});
|
|
2612
|
-
// Emit balance update event
|
|
2613
2613
|
this.eventEmitter.emit(exports.WalletEvent.BALANCE_UPDATED, {
|
|
2614
2614
|
type: 'TWC',
|
|
2615
2615
|
balance: twcBalance.amount,
|
|
@@ -2621,7 +2621,6 @@ class WalletConnector {
|
|
|
2621
2621
|
}
|
|
2622
2622
|
catch (twcError) {
|
|
2623
2623
|
this.debugTools.warn('WALLET_CONNECTOR', 'Failed to fetch TWC balance for new account', twcError);
|
|
2624
|
-
// Fallback to native balance
|
|
2625
2624
|
try {
|
|
2626
2625
|
const nativeBalance = await this.getNativeBalance();
|
|
2627
2626
|
this.debugTools.info('WALLET_CONNECTOR', 'Native balance updated for new account', {
|
|
@@ -2629,7 +2628,6 @@ class WalletConnector {
|
|
|
2629
2628
|
symbol: nativeBalance.symbol,
|
|
2630
2629
|
account: account.address
|
|
2631
2630
|
});
|
|
2632
|
-
// Emit balance update event
|
|
2633
2631
|
this.eventEmitter.emit(exports.WalletEvent.BALANCE_UPDATED, {
|
|
2634
2632
|
type: 'NATIVE',
|
|
2635
2633
|
balance: nativeBalance.amount,
|
|
@@ -2648,7 +2646,6 @@ class WalletConnector {
|
|
|
2648
2646
|
}
|
|
2649
2647
|
}
|
|
2650
2648
|
else if (this.state.wallet) {
|
|
2651
|
-
// Account removed/disconnected from wallet app
|
|
2652
2649
|
this.storage.clearWallet();
|
|
2653
2650
|
this.updateState({ wallet: null, account: null, status: exports.ConnectionStatus.DISCONNECTED, twcBalance: null, usdValue: null, nftCount: 0, nftData: null });
|
|
2654
2651
|
this.eventEmitter.emit(exports.WalletEvent.DISCONNECTED, undefined);
|
|
@@ -2694,13 +2691,9 @@ class WalletConnector {
|
|
|
2694
2691
|
if (adapter.chainType === exports.ChainType.TON) {
|
|
2695
2692
|
try {
|
|
2696
2693
|
const nftResult = await this.checkNFTOwnership([
|
|
2697
|
-
// New collection - user-friendly format
|
|
2698
2694
|
'EQDVaDCso_2LRTkc8WrT9A4bVO5BG_PZ8313BC_lOO8XW1T8',
|
|
2699
|
-
// New collection - raw format
|
|
2700
2695
|
'0:d56830aca3fd8b45391cf16ad3f40e1b54ee411bf3d9f37d77042fe538ef175b',
|
|
2701
|
-
// Legacy collection - user-friendly format
|
|
2702
2696
|
'EQDKfA87JVnBJXsBVfzjIfbhr3bmTTdouUP31Szgm_Lw0v-J',
|
|
2703
|
-
// Legacy collection - raw format
|
|
2704
2697
|
'0:ca7c0f3b2559c1257b0155fce321f6e1af76e64d3768b943f7d52ce09bf2f0d2'
|
|
2705
2698
|
]);
|
|
2706
2699
|
accountWithNFTs = {
|
|
@@ -2714,7 +2707,6 @@ class WalletConnector {
|
|
|
2714
2707
|
}
|
|
2715
2708
|
catch (nftError) {
|
|
2716
2709
|
this.debugTools.warn('WALLET_CONNECTOR', 'NFT check failed, proceeding without NFT info', nftError);
|
|
2717
|
-
// Continue with connection even if NFT check fails
|
|
2718
2710
|
}
|
|
2719
2711
|
}
|
|
2720
2712
|
this.storage.saveWallet(walletType);
|
|
@@ -2724,6 +2716,39 @@ class WalletConnector {
|
|
|
2724
2716
|
error: null,
|
|
2725
2717
|
});
|
|
2726
2718
|
this.eventEmitter.emit(exports.WalletEvent.CONNECTED, accountWithNFTs);
|
|
2719
|
+
// Immediately fetch TWC balance after initial connection (not just on reconnect or refresh)
|
|
2720
|
+
if (adapter.chainType === exports.ChainType.EVM) {
|
|
2721
|
+
try {
|
|
2722
|
+
// Update chainId in state if possible
|
|
2723
|
+
if (typeof adapter.getChainId === 'function') {
|
|
2724
|
+
try {
|
|
2725
|
+
const chainId = await adapter.getChainId();
|
|
2726
|
+
this.updateState({ chainId });
|
|
2727
|
+
}
|
|
2728
|
+
catch (e) {
|
|
2729
|
+
this.updateState({ chainId: null });
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
const twcBalance = await this.getTWCBalance();
|
|
2733
|
+
this.updateState({ twcBalance: twcBalance.amount, usdValue: twcBalance.usdValue ?? null });
|
|
2734
|
+
this.debugTools.info('WALLET_CONNECTOR', 'TWC balance updated after initial connect', {
|
|
2735
|
+
balance: twcBalance.amount,
|
|
2736
|
+
usdValue: twcBalance.usdValue,
|
|
2737
|
+
account: accountWithNFTs.address
|
|
2738
|
+
});
|
|
2739
|
+
this.eventEmitter.emit(exports.WalletEvent.BALANCE_UPDATED, {
|
|
2740
|
+
type: 'TWC',
|
|
2741
|
+
balance: twcBalance.amount,
|
|
2742
|
+
symbol: twcBalance.symbol,
|
|
2743
|
+
usdValue: twcBalance.usdValue,
|
|
2744
|
+
usdFormatted: twcBalance.usdFormatted,
|
|
2745
|
+
account: accountWithNFTs.address
|
|
2746
|
+
});
|
|
2747
|
+
}
|
|
2748
|
+
catch (twcError) {
|
|
2749
|
+
this.debugTools.warn('WALLET_CONNECTOR', 'Failed to fetch TWC balance after initial connect', twcError);
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
2727
2752
|
}
|
|
2728
2753
|
else {
|
|
2729
2754
|
// Connection failed - reset state properly
|
|
@@ -3104,14 +3129,21 @@ class WalletConnector {
|
|
|
3104
3129
|
}
|
|
3105
3130
|
async getTWCBalance() {
|
|
3106
3131
|
if (!this.state.account) {
|
|
3132
|
+
if (typeof window !== 'undefined')
|
|
3133
|
+
window.showDebugLog?.('[getTWCBalance] No wallet connected');
|
|
3107
3134
|
throw new Error('No wallet connected');
|
|
3108
3135
|
}
|
|
3109
3136
|
const accountAddress = this.state.account.address;
|
|
3137
|
+
const chainId = this.state.chainId;
|
|
3110
3138
|
performance.now();
|
|
3139
|
+
if (typeof window !== 'undefined')
|
|
3140
|
+
window.showDebugLog?.(`[getTWCBalance] Called for account=${accountAddress}, chainId=${chainId}`);
|
|
3111
3141
|
// Check cache first
|
|
3112
3142
|
if (this.twcBalanceCache &&
|
|
3113
3143
|
this.twcBalanceCache.address === accountAddress &&
|
|
3114
3144
|
Date.now() - this.twcBalanceCache.timestamp < this.TWC_CACHE_TTL) {
|
|
3145
|
+
if (typeof window !== 'undefined')
|
|
3146
|
+
window.showDebugLog?.(`[getTWCBalance] Using cache for ${accountAddress}: ${JSON.stringify(this.twcBalanceCache)}`);
|
|
3115
3147
|
return {
|
|
3116
3148
|
amount: this.twcBalanceCache.balance,
|
|
3117
3149
|
symbol: 'TWC',
|
|
@@ -3128,26 +3160,86 @@ class WalletConnector {
|
|
|
3128
3160
|
// Use the currently connected wallet's adapter
|
|
3129
3161
|
const currentWallet = this.state.wallet;
|
|
3130
3162
|
if (!currentWallet) {
|
|
3163
|
+
if (typeof window !== 'undefined')
|
|
3164
|
+
window.showDebugLog?.('[getTWCBalance] No wallet connected (no currentWallet)');
|
|
3131
3165
|
throw new Error('No wallet connected');
|
|
3132
3166
|
}
|
|
3133
3167
|
const adapter = this.adapters.get(currentWallet);
|
|
3134
3168
|
if (!adapter || adapter.chainType !== exports.ChainType.EVM) {
|
|
3169
|
+
if (typeof window !== 'undefined')
|
|
3170
|
+
window.showDebugLog?.('[getTWCBalance] No EVM adapter available');
|
|
3135
3171
|
throw new Error('No EVM adapter available');
|
|
3136
3172
|
}
|
|
3137
|
-
//
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3173
|
+
// Debug: log adapter type and available methods
|
|
3174
|
+
if (typeof window !== 'undefined') {
|
|
3175
|
+
window.showDebugLog?.(`[getTWCBalance] Using adapter: ${adapter.constructor?.name || typeof adapter}`);
|
|
3176
|
+
window.showDebugLog?.(`[getTWCBalance] Adapter keys: ${Object.keys(adapter).join(', ')}`);
|
|
3177
|
+
window.showDebugLog?.(`[getTWCBalance] typeof getTokenBalance: ${typeof adapter.getTokenBalance}`);
|
|
3178
|
+
}
|
|
3179
|
+
let balance;
|
|
3180
|
+
// Always use ethers fallback if EVM is connected, regardless of chainId
|
|
3181
|
+
if (this.state.chainId !== 56) {
|
|
3182
|
+
if (typeof window !== 'undefined')
|
|
3183
|
+
window.showDebugLog?.(`[getTWCBalance] Warning: Not on BSC (chainId=${this.state.chainId}), but fetching TWC balance using ethers fallback.`);
|
|
3184
|
+
// Fallback: use ethers.js to fetch balance from chain
|
|
3185
|
+
let provider = adapter.provider || this.getProvider();
|
|
3186
|
+
if (!provider) {
|
|
3187
|
+
if (typeof window !== 'undefined')
|
|
3188
|
+
window.showDebugLog?.('[getTWCBalance] No provider available for ethers fallback');
|
|
3189
|
+
throw new Error('No provider available for ethers fallback');
|
|
3190
|
+
}
|
|
3191
|
+
if (!provider._isProvider) {
|
|
3192
|
+
provider = new ethers.ethers.BrowserProvider(provider);
|
|
3193
|
+
}
|
|
3194
|
+
const erc20Abi = ["function balanceOf(address) view returns (uint256)"];
|
|
3195
|
+
const contract = new ethers.ethers.Contract(TWC_CONTRACT, erc20Abi, provider);
|
|
3196
|
+
const rawBalance = await contract.balanceOf(accountAddress);
|
|
3197
|
+
if (typeof window !== 'undefined')
|
|
3198
|
+
window.showDebugLog?.(`[getTWCBalance] [ethers fallback] rawBalance (BigInt) for ${accountAddress}: ${rawBalance?.toString?.()}`);
|
|
3199
|
+
balance = ethers.ethers.formatUnits(rawBalance, TWC_DECIMALS);
|
|
3200
|
+
if (typeof window !== 'undefined')
|
|
3201
|
+
window.showDebugLog?.(`[getTWCBalance] Raw balance for ${accountAddress} (ethers): ${balance}`);
|
|
3202
|
+
}
|
|
3203
|
+
else if (typeof adapter.getTokenBalance === 'function') {
|
|
3204
|
+
// Use adapter method if available and on BSC
|
|
3205
|
+
const balancePromise = adapter.getTokenBalance(TWC_CONTRACT, TWC_DECIMALS, true);
|
|
3206
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
3207
|
+
setTimeout(() => reject(new Error('Balance fetch timeout after 10 seconds')), 10000);
|
|
3208
|
+
});
|
|
3209
|
+
balance = await Promise.race([balancePromise, timeoutPromise]);
|
|
3210
|
+
if (typeof window !== 'undefined')
|
|
3211
|
+
window.showDebugLog?.(`[getTWCBalance] Raw balance for ${accountAddress} (adapter): ${balance}`);
|
|
3212
|
+
}
|
|
3213
|
+
else {
|
|
3214
|
+
// Fallback: use ethers.js to fetch balance from chain (should not happen, but for safety)
|
|
3215
|
+
if (typeof window !== 'undefined')
|
|
3216
|
+
window.showDebugLog?.('[getTWCBalance] Fallback to ethers.js for TWC balance (on BSC)');
|
|
3217
|
+
let provider = adapter.provider || this.getProvider();
|
|
3218
|
+
if (!provider) {
|
|
3219
|
+
if (typeof window !== 'undefined')
|
|
3220
|
+
window.showDebugLog?.('[getTWCBalance] No provider available for ethers fallback');
|
|
3221
|
+
throw new Error('No provider available for ethers fallback');
|
|
3222
|
+
}
|
|
3223
|
+
if (!provider._isProvider) {
|
|
3224
|
+
provider = new ethers.ethers.BrowserProvider(provider);
|
|
3225
|
+
}
|
|
3226
|
+
const erc20Abi = ["function balanceOf(address) view returns (uint256)"];
|
|
3227
|
+
const contract = new ethers.ethers.Contract(TWC_CONTRACT, erc20Abi, provider);
|
|
3228
|
+
const rawBalance = await contract.balanceOf(accountAddress);
|
|
3229
|
+
if (typeof window !== 'undefined')
|
|
3230
|
+
window.showDebugLog?.(`[getTWCBalance] [ethers fallback] rawBalance (BigInt) for ${accountAddress}: ${rawBalance?.toString?.()}`);
|
|
3231
|
+
balance = ethers.ethers.formatUnits(rawBalance, TWC_DECIMALS);
|
|
3232
|
+
if (typeof window !== 'undefined')
|
|
3233
|
+
window.showDebugLog?.(`[getTWCBalance] Raw balance for ${accountAddress} (ethers): ${balance}`);
|
|
3234
|
+
}
|
|
3145
3235
|
// Calculate USD value with 5 second timeout
|
|
3146
3236
|
const usdPromise = priceService.calculateTWCValue(balance);
|
|
3147
3237
|
const usdTimeoutPromise = new Promise((resolve) => {
|
|
3148
3238
|
setTimeout(() => resolve(0), 5000); // Default to 0 on timeout
|
|
3149
3239
|
});
|
|
3150
3240
|
const usdValue = await Promise.race([usdPromise, usdTimeoutPromise]);
|
|
3241
|
+
if (typeof window !== 'undefined')
|
|
3242
|
+
window.showDebugLog?.(`[getTWCBalance] USD value for ${accountAddress}: ${usdValue}`);
|
|
3151
3243
|
// Update cache
|
|
3152
3244
|
this.twcBalanceCache = {
|
|
3153
3245
|
balance,
|
|
@@ -3163,10 +3255,14 @@ class WalletConnector {
|
|
|
3163
3255
|
};
|
|
3164
3256
|
// Keep state in sync
|
|
3165
3257
|
this.updateState({ twcBalance: result.amount, usdValue: result.usdValue ?? null });
|
|
3258
|
+
if (typeof window !== 'undefined')
|
|
3259
|
+
window.showDebugLog?.(`[getTWCBalance] Final result for ${accountAddress}: ${JSON.stringify(result)}`);
|
|
3166
3260
|
return result;
|
|
3167
3261
|
}
|
|
3168
3262
|
catch (error) {
|
|
3169
3263
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
3264
|
+
if (typeof window !== 'undefined')
|
|
3265
|
+
window.showDebugLog?.(`[getTWCBalance] ERROR: ${errorMsg}`);
|
|
3170
3266
|
// Track error
|
|
3171
3267
|
this.balanceFetchErrors.push({
|
|
3172
3268
|
endpoint: 'wallet-provider',
|
|
@@ -7519,6 +7615,41 @@ const TWCBalanceModal = ({ isOpen, onClose, twcBalance, usdValue, colors, isDark
|
|
|
7519
7615
|
}, children: "Learn More" })] })] }) }));
|
|
7520
7616
|
};
|
|
7521
7617
|
|
|
7618
|
+
// Debug log overlay for mobile
|
|
7619
|
+
function showDebugLog(msg) {
|
|
7620
|
+
if (typeof window === 'undefined')
|
|
7621
|
+
return;
|
|
7622
|
+
let logDiv = document.getElementById('twc-debug-log');
|
|
7623
|
+
if (!logDiv) {
|
|
7624
|
+
logDiv = document.createElement('div');
|
|
7625
|
+
logDiv.id = 'twc-debug-log';
|
|
7626
|
+
logDiv.style.position = 'fixed';
|
|
7627
|
+
logDiv.style.bottom = '10px';
|
|
7628
|
+
logDiv.style.left = '10px';
|
|
7629
|
+
logDiv.style.right = '10px';
|
|
7630
|
+
logDiv.style.maxHeight = '40vh';
|
|
7631
|
+
logDiv.style.overflowY = 'auto';
|
|
7632
|
+
logDiv.style.background = 'rgba(0,0,0,0.85)';
|
|
7633
|
+
logDiv.style.color = '#fff';
|
|
7634
|
+
logDiv.style.fontSize = '12px';
|
|
7635
|
+
logDiv.style.zIndex = '99999';
|
|
7636
|
+
logDiv.style.padding = '8px 12px';
|
|
7637
|
+
logDiv.style.borderRadius = '8px';
|
|
7638
|
+
logDiv.style.pointerEvents = 'auto';
|
|
7639
|
+
logDiv.style.fontFamily = 'monospace';
|
|
7640
|
+
logDiv.style.boxShadow = '0 2px 12px rgba(0,0,0,0.3)';
|
|
7641
|
+
logDiv.innerHTML = '';
|
|
7642
|
+
document.body.appendChild(logDiv);
|
|
7643
|
+
}
|
|
7644
|
+
const now = new Date();
|
|
7645
|
+
const time = now.toLocaleTimeString();
|
|
7646
|
+
logDiv.innerHTML = `<div>[${time}] ${msg}</div>` + logDiv.innerHTML;
|
|
7647
|
+
// Limit to 30 log lines
|
|
7648
|
+
const lines = logDiv.innerHTML.split('<div>');
|
|
7649
|
+
if (lines.length > 30) {
|
|
7650
|
+
logDiv.innerHTML = lines.slice(0, 30).join('<div>');
|
|
7651
|
+
}
|
|
7652
|
+
}
|
|
7522
7653
|
const tonApiCache = new Map();
|
|
7523
7654
|
const CACHE_DURATION = 30000; // 30 seconds
|
|
7524
7655
|
const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className, style, showBalance = false, modalPosition = 'center', theme = 'auto', buttonText = 'Connect Wallet', getExplorerUrl, }) => {
|
|
@@ -7824,12 +7955,20 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
7824
7955
|
return;
|
|
7825
7956
|
}
|
|
7826
7957
|
try {
|
|
7827
|
-
|
|
7958
|
+
let chainId = await connector.getCurrentChain();
|
|
7828
7959
|
setCurrentChainId(chainId);
|
|
7829
7960
|
if (chainId !== 56) {
|
|
7830
7961
|
// Automatically switch to BSC
|
|
7831
7962
|
try {
|
|
7832
7963
|
await connector.switchChain(56);
|
|
7964
|
+
// After switching, re-fetch chainId and update state
|
|
7965
|
+
chainId = await connector.getCurrentChain();
|
|
7966
|
+
setCurrentChainId(chainId);
|
|
7967
|
+
// Optionally, trigger TWC balance fetch here if needed
|
|
7968
|
+
if (chainId === 56) {
|
|
7969
|
+
// Force a state update to trigger TWC balance fetch effect
|
|
7970
|
+
setTimeout(() => setCurrentChainId(56), 100); // small delay to ensure state update
|
|
7971
|
+
}
|
|
7833
7972
|
}
|
|
7834
7973
|
catch (err) {
|
|
7835
7974
|
// Optionally handle error (user rejected, etc.)
|
|
@@ -8391,13 +8530,15 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8391
8530
|
}
|
|
8392
8531
|
}, [account]);
|
|
8393
8532
|
const fetchTWCBalanceWithRetry = React.useCallback(async (maxRetries = 3, initialDelay = 200) => {
|
|
8394
|
-
//
|
|
8533
|
+
// Fetch TWC balance for all EVM chains (for debugging)
|
|
8395
8534
|
try {
|
|
8396
8535
|
const state = connector.getState();
|
|
8397
|
-
if (state.account?.chainType !== 'evm'
|
|
8398
|
-
// Not
|
|
8536
|
+
if (state.account?.chainType !== 'evm') {
|
|
8537
|
+
// Not EVM, do not fetch TWC balance
|
|
8399
8538
|
return null;
|
|
8400
8539
|
}
|
|
8540
|
+
// Log chainId for debug
|
|
8541
|
+
showDebugLog?.(`[fetchTWCBalanceWithRetry] Fetching TWC for chainId=${state.chainId}`);
|
|
8401
8542
|
const twcBalance = await connector.getTWCBalance();
|
|
8402
8543
|
return {
|
|
8403
8544
|
balance: twcBalance.amount || '0',
|
|
@@ -8432,6 +8573,7 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8432
8573
|
// Fetch TWC balance immediately after connection
|
|
8433
8574
|
const cacheKey = `tiwiflix_twc_balance_cache_${account.address}`;
|
|
8434
8575
|
fetchTWCBalanceWithRetry(2, 200).then((result) => {
|
|
8576
|
+
showDebugLog(`[ConnectButton] TWC balance fetch after WalletConnect connect: status=${status}, account=${account?.address}, chainId=${chainId}, result=${JSON.stringify(result)}`);
|
|
8435
8577
|
if (result && result.balance !== '0' && result.balance !== '0.00') {
|
|
8436
8578
|
setTwcBalance(result.balance);
|
|
8437
8579
|
setUsdValueStable(result.usdValue);
|
|
@@ -8439,7 +8581,6 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8439
8581
|
localStorage.setItem(cacheKey, JSON.stringify({ balance: result.balance, usdValue: result.usdValue, timestamp: Date.now() }));
|
|
8440
8582
|
}
|
|
8441
8583
|
setIsInitializing(false);
|
|
8442
|
-
console.log('[ConnectButton] TWC balance fetched after WalletConnect connect:', result);
|
|
8443
8584
|
}
|
|
8444
8585
|
});
|
|
8445
8586
|
}
|
|
@@ -8470,7 +8611,7 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8470
8611
|
setTwcBalance(cache.balance);
|
|
8471
8612
|
setUsdValueStable(cache.usdValue);
|
|
8472
8613
|
setIsInitializing(false);
|
|
8473
|
-
|
|
8614
|
+
showDebugLog(`[ConnectButton] Using localStorage cached TWC balance: ${JSON.stringify(cache)}`);
|
|
8474
8615
|
// Fetch in background to update cache, but don't reset UI while fetching
|
|
8475
8616
|
fetchTWCBalanceWithRetry(2, 200).then((result) => {
|
|
8476
8617
|
if (!isActive)
|
|
@@ -8483,7 +8624,7 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8483
8624
|
localStorage.setItem(cacheKey, JSON.stringify({ balance: result.balance, usdValue: result.usdValue, timestamp: Date.now() }));
|
|
8484
8625
|
}
|
|
8485
8626
|
setIsInitializing(false);
|
|
8486
|
-
|
|
8627
|
+
showDebugLog(`[ConnectButton] TWC balance updated after background fetch: ${JSON.stringify(result)}`);
|
|
8487
8628
|
}
|
|
8488
8629
|
}).catch(() => {
|
|
8489
8630
|
// Ignore errors in background fetch
|
|
@@ -8503,19 +8644,19 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8503
8644
|
localStorage.setItem(cacheKey, JSON.stringify({ balance: result.balance, usdValue: result.usdValue, timestamp: Date.now() }));
|
|
8504
8645
|
}
|
|
8505
8646
|
setIsInitializing(false);
|
|
8506
|
-
|
|
8647
|
+
showDebugLog(`[ConnectButton] TWC balance fetched and cached: ${JSON.stringify(result)}`);
|
|
8507
8648
|
}
|
|
8508
8649
|
else {
|
|
8509
8650
|
setTwcBalance('0');
|
|
8510
8651
|
setUsdValueStable(null);
|
|
8511
8652
|
setIsInitializing(false);
|
|
8512
|
-
|
|
8653
|
+
showDebugLog(`[ConnectButton] No TWC balance found for BSC wallet: ${account.address}`);
|
|
8513
8654
|
}
|
|
8514
8655
|
}).catch(() => {
|
|
8515
8656
|
if (!isActive)
|
|
8516
8657
|
return;
|
|
8517
8658
|
setIsInitializing(false);
|
|
8518
|
-
|
|
8659
|
+
showDebugLog(`[ConnectButton] Error fetching TWC balance for BSC wallet: ${account.address}`);
|
|
8519
8660
|
});
|
|
8520
8661
|
}
|
|
8521
8662
|
}
|
|
@@ -8739,8 +8880,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8739
8880
|
}, [connector, account]);
|
|
8740
8881
|
// Render button based on connection status
|
|
8741
8882
|
const renderButton = () => {
|
|
8742
|
-
// Only show connect button if we are fully initialized and truly disconnected
|
|
8743
|
-
if (!isInitializing && (!account
|
|
8883
|
+
// Only show connect button if we are fully initialized and truly disconnected (no account and status is DISCONNECTED)
|
|
8884
|
+
if (!isInitializing && (!account && status === exports.ConnectionStatus.DISCONNECTED)) {
|
|
8744
8885
|
// Wallet icon SVG component
|
|
8745
8886
|
const WalletIcon = () => (jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: { display: 'block' }, children: [jsxRuntime.jsx("path", { d: "M19 7V4a1 1 0 0 0-1-1H5a2 2 0 0 0 0 4h15a1 1 0 0 1 1 1v4h-3a2 2 0 0 0 0 4h3a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1" }), jsxRuntime.jsx("path", { d: "M3 5v14a2 2 0 0 0 2 2h15a1 1 0 0 0 1-1v-4" })] }));
|
|
8746
8887
|
return (jsxRuntime.jsxs("button", { onClick: () => handleOpenModal(), style: {
|
|
@@ -8769,16 +8910,14 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8769
8910
|
e.currentTarget.style.boxShadow = '0 2px 8px rgba(255, 152, 20, 0.3)';
|
|
8770
8911
|
}, children: [jsxRuntime.jsx("span", { style: { color: '#000000', display: 'flex', alignItems: 'center' }, children: jsxRuntime.jsx(WalletIcon, {}) }), jsxRuntime.jsx("span", { style: { color: '#000000', fontWeight: '500', fontSize: '14px' }, children: buttonText })] }));
|
|
8771
8912
|
}
|
|
8772
|
-
// ...existing code...
|
|
8773
8913
|
// All other states (including loading, connecting, connected) should only show the connected button or loading spinner if account is present or initializing is true
|
|
8774
8914
|
// If initializing, show nothing (or a spinner if desired)
|
|
8775
8915
|
if (isInitializing) {
|
|
8776
8916
|
// Optionally, you can show a spinner or skeleton here, but do not show connect/disconnect buttons
|
|
8777
8917
|
return null;
|
|
8778
8918
|
}
|
|
8779
|
-
//
|
|
8780
|
-
|
|
8781
|
-
if (account) {
|
|
8919
|
+
// Show connected button for any state where account is present and status is not DISCONNECTED or CONNECTING
|
|
8920
|
+
if (account && status !== exports.ConnectionStatus.DISCONNECTED && status !== exports.ConnectionStatus.CONNECTING) {
|
|
8782
8921
|
// ...existing code...
|
|
8783
8922
|
// Show normal connected button - styled to match design
|
|
8784
8923
|
// Parse balance amount and symbol separately
|
package/package.json
CHANGED