tiwiflix-wallet-connector 1.6.6 → 1.6.8
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 +171 -38
- package/dist/index.js +171 -38
- package/package.json +2 -2
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';
|
|
@@ -2424,13 +2425,38 @@ class WalletConnector {
|
|
|
2424
2425
|
* Connect to a wallet
|
|
2425
2426
|
*/
|
|
2426
2427
|
async connect(walletType) {
|
|
2428
|
+
// Only allow EVM wallet connections on BSC (chainId 56)
|
|
2429
|
+
let adapter = this.adapters.get(walletType);
|
|
2430
|
+
if (adapter && adapter.chainType === ChainType.EVM && typeof adapter.getChainId === 'function') {
|
|
2431
|
+
try {
|
|
2432
|
+
const chainId = await adapter.getChainId();
|
|
2433
|
+
if (chainId !== 56) {
|
|
2434
|
+
const error = new Error('Only Binance Smart Chain (BSC) is supported for EVM wallet connections. Please switch your wallet to BSC and try again.');
|
|
2435
|
+
this.updateState({
|
|
2436
|
+
status: ConnectionStatus.ERROR,
|
|
2437
|
+
error,
|
|
2438
|
+
});
|
|
2439
|
+
this.eventEmitter.emit(WalletEvent.ERROR, error);
|
|
2440
|
+
throw error;
|
|
2441
|
+
}
|
|
2442
|
+
}
|
|
2443
|
+
catch (e) {
|
|
2444
|
+
const error = new Error('Failed to detect EVM chain. Please ensure your wallet is connected to BSC.');
|
|
2445
|
+
this.updateState({
|
|
2446
|
+
status: ConnectionStatus.ERROR,
|
|
2447
|
+
error,
|
|
2448
|
+
});
|
|
2449
|
+
this.eventEmitter.emit(WalletEvent.ERROR, error);
|
|
2450
|
+
throw error;
|
|
2451
|
+
}
|
|
2452
|
+
}
|
|
2427
2453
|
// Prevent duplicate connection requests
|
|
2428
2454
|
if (this.state.status === ConnectionStatus.CONNECTING) {
|
|
2429
2455
|
const error = new Error('Connection already in progress. Please wait...');
|
|
2430
2456
|
console.warn('Duplicate connection attempt blocked:', walletType);
|
|
2431
2457
|
throw error;
|
|
2432
2458
|
}
|
|
2433
|
-
|
|
2459
|
+
// adapter already declared above
|
|
2434
2460
|
if (!adapter) {
|
|
2435
2461
|
const error = new Error(`Wallet ${walletType} is not registered`);
|
|
2436
2462
|
this.updateState({
|
|
@@ -2552,13 +2578,9 @@ class WalletConnector {
|
|
|
2552
2578
|
if (account && adapter.chainType === ChainType.TON) {
|
|
2553
2579
|
try {
|
|
2554
2580
|
const nftResult = await this.checkNFTOwnership([
|
|
2555
|
-
// New collection - user-friendly format
|
|
2556
2581
|
'EQDVaDCso_2LRTkc8WrT9A4bVO5BG_PZ8313BC_lOO8XW1T8',
|
|
2557
|
-
// New collection - raw format
|
|
2558
2582
|
'0:d56830aca3fd8b45391cf16ad3f40e1b54ee411bf3d9f37d77042fe538ef175b',
|
|
2559
|
-
// Legacy collection - user-friendly format
|
|
2560
2583
|
'EQDKfA87JVnBJXsBVfzjIfbhr3bmTTdouUP31Szgm_Lw0v-J',
|
|
2561
|
-
// Legacy collection - raw format
|
|
2562
2584
|
'0:ca7c0f3b2559c1257b0155fce321f6e1af76e64d3768b943f7d52ce09bf2f0d2'
|
|
2563
2585
|
]);
|
|
2564
2586
|
accountWithNFTs = {
|
|
@@ -2569,7 +2591,6 @@ class WalletConnector {
|
|
|
2569
2591
|
hasRequiredNFTs: nftResult.hasNFTs,
|
|
2570
2592
|
ownedCount: nftResult.ownedNFTs.length
|
|
2571
2593
|
});
|
|
2572
|
-
// Update state with NFT count and data
|
|
2573
2594
|
this.updateState({
|
|
2574
2595
|
account: accountWithNFTs,
|
|
2575
2596
|
nftCount: nftResult.ownedNFTs.length,
|
|
@@ -2578,36 +2599,40 @@ class WalletConnector {
|
|
|
2578
2599
|
}
|
|
2579
2600
|
catch (nftError) {
|
|
2580
2601
|
this.debugTools.warn('WALLET_CONNECTOR', 'NFT check failed during account change', nftError);
|
|
2581
|
-
// Continue with account change even if NFT check fails
|
|
2582
2602
|
this.updateState({ account: accountWithNFTs });
|
|
2583
2603
|
}
|
|
2584
2604
|
}
|
|
2585
2605
|
else {
|
|
2586
2606
|
this.updateState({ account: accountWithNFTs });
|
|
2587
2607
|
}
|
|
2608
|
+
// Always update chainId in state after account change (for EVM wallets)
|
|
2609
|
+
if (account && adapter.chainType === ChainType.EVM && typeof adapter.getChainId === 'function') {
|
|
2610
|
+
try {
|
|
2611
|
+
const chainId = await adapter.getChainId();
|
|
2612
|
+
this.updateState({ chainId });
|
|
2613
|
+
}
|
|
2614
|
+
catch (e) {
|
|
2615
|
+
this.updateState({ chainId: null });
|
|
2616
|
+
}
|
|
2617
|
+
}
|
|
2588
2618
|
this.eventEmitter.emit(WalletEvent.ACCOUNT_CHANGED, accountWithNFTs);
|
|
2589
2619
|
if (account) {
|
|
2590
2620
|
this.eventEmitter.emit(WalletEvent.CONNECTED, account);
|
|
2591
|
-
// Automatically fetch new balance and price when account changes
|
|
2592
2621
|
try {
|
|
2593
2622
|
this.debugTools.info('WALLET_CONNECTOR', 'Account changed, fetching new balance and price', {
|
|
2594
2623
|
account: account.address,
|
|
2595
2624
|
wallet: walletType
|
|
2596
2625
|
});
|
|
2597
|
-
// Clear price cache for new account
|
|
2598
2626
|
priceService.clearCache();
|
|
2599
|
-
// Fetch TWC balance and price
|
|
2600
2627
|
if (adapter.chainType === ChainType.EVM) {
|
|
2601
2628
|
try {
|
|
2602
2629
|
const twcBalance = await this.getTWCBalance();
|
|
2603
|
-
// Persist in state for exportability
|
|
2604
2630
|
this.updateState({ twcBalance: twcBalance.amount, usdValue: twcBalance.usdValue ?? null });
|
|
2605
2631
|
this.debugTools.info('WALLET_CONNECTOR', 'TWC balance updated for new account', {
|
|
2606
2632
|
balance: twcBalance.amount,
|
|
2607
2633
|
usdValue: twcBalance.usdValue,
|
|
2608
2634
|
account: account.address
|
|
2609
2635
|
});
|
|
2610
|
-
// Emit balance update event
|
|
2611
2636
|
this.eventEmitter.emit(WalletEvent.BALANCE_UPDATED, {
|
|
2612
2637
|
type: 'TWC',
|
|
2613
2638
|
balance: twcBalance.amount,
|
|
@@ -2619,7 +2644,6 @@ class WalletConnector {
|
|
|
2619
2644
|
}
|
|
2620
2645
|
catch (twcError) {
|
|
2621
2646
|
this.debugTools.warn('WALLET_CONNECTOR', 'Failed to fetch TWC balance for new account', twcError);
|
|
2622
|
-
// Fallback to native balance
|
|
2623
2647
|
try {
|
|
2624
2648
|
const nativeBalance = await this.getNativeBalance();
|
|
2625
2649
|
this.debugTools.info('WALLET_CONNECTOR', 'Native balance updated for new account', {
|
|
@@ -2627,7 +2651,6 @@ class WalletConnector {
|
|
|
2627
2651
|
symbol: nativeBalance.symbol,
|
|
2628
2652
|
account: account.address
|
|
2629
2653
|
});
|
|
2630
|
-
// Emit balance update event
|
|
2631
2654
|
this.eventEmitter.emit(WalletEvent.BALANCE_UPDATED, {
|
|
2632
2655
|
type: 'NATIVE',
|
|
2633
2656
|
balance: nativeBalance.amount,
|
|
@@ -2646,7 +2669,6 @@ class WalletConnector {
|
|
|
2646
2669
|
}
|
|
2647
2670
|
}
|
|
2648
2671
|
else if (this.state.wallet) {
|
|
2649
|
-
// Account removed/disconnected from wallet app
|
|
2650
2672
|
this.storage.clearWallet();
|
|
2651
2673
|
this.updateState({ wallet: null, account: null, status: ConnectionStatus.DISCONNECTED, twcBalance: null, usdValue: null, nftCount: 0, nftData: null });
|
|
2652
2674
|
this.eventEmitter.emit(WalletEvent.DISCONNECTED, undefined);
|
|
@@ -2692,13 +2714,9 @@ class WalletConnector {
|
|
|
2692
2714
|
if (adapter.chainType === ChainType.TON) {
|
|
2693
2715
|
try {
|
|
2694
2716
|
const nftResult = await this.checkNFTOwnership([
|
|
2695
|
-
// New collection - user-friendly format
|
|
2696
2717
|
'EQDVaDCso_2LRTkc8WrT9A4bVO5BG_PZ8313BC_lOO8XW1T8',
|
|
2697
|
-
// New collection - raw format
|
|
2698
2718
|
'0:d56830aca3fd8b45391cf16ad3f40e1b54ee411bf3d9f37d77042fe538ef175b',
|
|
2699
|
-
// Legacy collection - user-friendly format
|
|
2700
2719
|
'EQDKfA87JVnBJXsBVfzjIfbhr3bmTTdouUP31Szgm_Lw0v-J',
|
|
2701
|
-
// Legacy collection - raw format
|
|
2702
2720
|
'0:ca7c0f3b2559c1257b0155fce321f6e1af76e64d3768b943f7d52ce09bf2f0d2'
|
|
2703
2721
|
]);
|
|
2704
2722
|
accountWithNFTs = {
|
|
@@ -2712,7 +2730,6 @@ class WalletConnector {
|
|
|
2712
2730
|
}
|
|
2713
2731
|
catch (nftError) {
|
|
2714
2732
|
this.debugTools.warn('WALLET_CONNECTOR', 'NFT check failed, proceeding without NFT info', nftError);
|
|
2715
|
-
// Continue with connection even if NFT check fails
|
|
2716
2733
|
}
|
|
2717
2734
|
}
|
|
2718
2735
|
this.storage.saveWallet(walletType);
|
|
@@ -2722,6 +2739,39 @@ class WalletConnector {
|
|
|
2722
2739
|
error: null,
|
|
2723
2740
|
});
|
|
2724
2741
|
this.eventEmitter.emit(WalletEvent.CONNECTED, accountWithNFTs);
|
|
2742
|
+
// Immediately fetch TWC balance after initial connection (not just on reconnect or refresh)
|
|
2743
|
+
if (adapter.chainType === ChainType.EVM) {
|
|
2744
|
+
try {
|
|
2745
|
+
// Update chainId in state if possible
|
|
2746
|
+
if (typeof adapter.getChainId === 'function') {
|
|
2747
|
+
try {
|
|
2748
|
+
const chainId = await adapter.getChainId();
|
|
2749
|
+
this.updateState({ chainId });
|
|
2750
|
+
}
|
|
2751
|
+
catch (e) {
|
|
2752
|
+
this.updateState({ chainId: null });
|
|
2753
|
+
}
|
|
2754
|
+
}
|
|
2755
|
+
const twcBalance = await this.getTWCBalance();
|
|
2756
|
+
this.updateState({ twcBalance: twcBalance.amount, usdValue: twcBalance.usdValue ?? null });
|
|
2757
|
+
this.debugTools.info('WALLET_CONNECTOR', 'TWC balance updated after initial connect', {
|
|
2758
|
+
balance: twcBalance.amount,
|
|
2759
|
+
usdValue: twcBalance.usdValue,
|
|
2760
|
+
account: accountWithNFTs.address
|
|
2761
|
+
});
|
|
2762
|
+
this.eventEmitter.emit(WalletEvent.BALANCE_UPDATED, {
|
|
2763
|
+
type: 'TWC',
|
|
2764
|
+
balance: twcBalance.amount,
|
|
2765
|
+
symbol: twcBalance.symbol,
|
|
2766
|
+
usdValue: twcBalance.usdValue,
|
|
2767
|
+
usdFormatted: twcBalance.usdFormatted,
|
|
2768
|
+
account: accountWithNFTs.address
|
|
2769
|
+
});
|
|
2770
|
+
}
|
|
2771
|
+
catch (twcError) {
|
|
2772
|
+
this.debugTools.warn('WALLET_CONNECTOR', 'Failed to fetch TWC balance after initial connect', twcError);
|
|
2773
|
+
}
|
|
2774
|
+
}
|
|
2725
2775
|
}
|
|
2726
2776
|
else {
|
|
2727
2777
|
// Connection failed - reset state properly
|
|
@@ -3102,14 +3152,21 @@ class WalletConnector {
|
|
|
3102
3152
|
}
|
|
3103
3153
|
async getTWCBalance() {
|
|
3104
3154
|
if (!this.state.account) {
|
|
3155
|
+
if (typeof window !== 'undefined')
|
|
3156
|
+
window.showDebugLog?.('[getTWCBalance] No wallet connected');
|
|
3105
3157
|
throw new Error('No wallet connected');
|
|
3106
3158
|
}
|
|
3107
3159
|
const accountAddress = this.state.account.address;
|
|
3160
|
+
const chainId = this.state.chainId;
|
|
3108
3161
|
performance.now();
|
|
3162
|
+
if (typeof window !== 'undefined')
|
|
3163
|
+
window.showDebugLog?.(`[getTWCBalance] Called for account=${accountAddress}, chainId=${chainId}`);
|
|
3109
3164
|
// Check cache first
|
|
3110
3165
|
if (this.twcBalanceCache &&
|
|
3111
3166
|
this.twcBalanceCache.address === accountAddress &&
|
|
3112
3167
|
Date.now() - this.twcBalanceCache.timestamp < this.TWC_CACHE_TTL) {
|
|
3168
|
+
if (typeof window !== 'undefined')
|
|
3169
|
+
window.showDebugLog?.(`[getTWCBalance] Using cache for ${accountAddress}: ${JSON.stringify(this.twcBalanceCache)}`);
|
|
3113
3170
|
return {
|
|
3114
3171
|
amount: this.twcBalanceCache.balance,
|
|
3115
3172
|
symbol: 'TWC',
|
|
@@ -3126,26 +3183,87 @@ class WalletConnector {
|
|
|
3126
3183
|
// Use the currently connected wallet's adapter
|
|
3127
3184
|
const currentWallet = this.state.wallet;
|
|
3128
3185
|
if (!currentWallet) {
|
|
3186
|
+
if (typeof window !== 'undefined')
|
|
3187
|
+
window.showDebugLog?.('[getTWCBalance] No wallet connected (no currentWallet)');
|
|
3129
3188
|
throw new Error('No wallet connected');
|
|
3130
3189
|
}
|
|
3131
3190
|
const adapter = this.adapters.get(currentWallet);
|
|
3132
3191
|
if (!adapter || adapter.chainType !== ChainType.EVM) {
|
|
3192
|
+
if (typeof window !== 'undefined')
|
|
3193
|
+
window.showDebugLog?.('[getTWCBalance] No EVM adapter available');
|
|
3133
3194
|
throw new Error('No EVM adapter available');
|
|
3134
3195
|
}
|
|
3135
|
-
//
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3196
|
+
// Debug: log adapter type and available methods
|
|
3197
|
+
if (typeof window !== 'undefined') {
|
|
3198
|
+
window.showDebugLog?.(`[getTWCBalance] Using adapter: ${adapter.constructor?.name || typeof adapter}`);
|
|
3199
|
+
window.showDebugLog?.(`[getTWCBalance] Adapter keys: ${Object.keys(adapter).join(', ')}`);
|
|
3200
|
+
window.showDebugLog?.(`[getTWCBalance] typeof getTokenBalance: ${typeof adapter.getTokenBalance}`);
|
|
3201
|
+
}
|
|
3202
|
+
let balance;
|
|
3203
|
+
// Always use ethers fallback if EVM is connected, regardless of chainId
|
|
3204
|
+
if (this.state.chainId !== 56) {
|
|
3205
|
+
if (typeof window !== 'undefined')
|
|
3206
|
+
window.showDebugLog?.(`[getTWCBalance] Warning: Not on BSC (chainId=${this.state.chainId}), but fetching TWC balance using ethers fallback.`);
|
|
3207
|
+
// Fallback: use ethers.js to fetch balance from chain
|
|
3208
|
+
let provider = adapter.provider || this.getProvider();
|
|
3209
|
+
if (!provider) {
|
|
3210
|
+
if (typeof window !== 'undefined')
|
|
3211
|
+
window.showDebugLog?.('[getTWCBalance] No provider available for ethers fallback');
|
|
3212
|
+
throw new Error('No provider available for ethers fallback');
|
|
3213
|
+
}
|
|
3214
|
+
// Use ethers.BrowserProvider for ethers v6 compatibility
|
|
3215
|
+
if (!provider._isProvider) {
|
|
3216
|
+
provider = new ethers.BrowserProvider(provider);
|
|
3217
|
+
}
|
|
3218
|
+
const erc20Abi = ["function balanceOf(address) view returns (uint256)"];
|
|
3219
|
+
const contract = new ethers.Contract(TWC_CONTRACT, erc20Abi, provider);
|
|
3220
|
+
const rawBalance = await contract.balanceOf(accountAddress);
|
|
3221
|
+
if (typeof window !== 'undefined')
|
|
3222
|
+
window.showDebugLog?.(`[getTWCBalance] [ethers fallback] rawBalance (BigInt) for ${accountAddress}: ${rawBalance?.toString?.()}`);
|
|
3223
|
+
balance = ethers.formatUnits(rawBalance, TWC_DECIMALS);
|
|
3224
|
+
if (typeof window !== 'undefined')
|
|
3225
|
+
window.showDebugLog?.(`[getTWCBalance] Raw balance for ${accountAddress} (ethers): ${balance}`);
|
|
3226
|
+
}
|
|
3227
|
+
else if (typeof adapter.getTokenBalance === 'function') {
|
|
3228
|
+
// Use adapter method if available and on BSC
|
|
3229
|
+
const balancePromise = adapter.getTokenBalance(TWC_CONTRACT, TWC_DECIMALS, true);
|
|
3230
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
3231
|
+
setTimeout(() => reject(new Error('Balance fetch timeout after 10 seconds')), 10000);
|
|
3232
|
+
});
|
|
3233
|
+
balance = await Promise.race([balancePromise, timeoutPromise]);
|
|
3234
|
+
if (typeof window !== 'undefined')
|
|
3235
|
+
window.showDebugLog?.(`[getTWCBalance] Raw balance for ${accountAddress} (adapter): ${balance}`);
|
|
3236
|
+
}
|
|
3237
|
+
else {
|
|
3238
|
+
// Fallback: use ethers.js to fetch balance from chain (should not happen, but for safety)
|
|
3239
|
+
if (typeof window !== 'undefined')
|
|
3240
|
+
window.showDebugLog?.('[getTWCBalance] Fallback to ethers.js for TWC balance (on BSC)');
|
|
3241
|
+
let provider = adapter.provider || this.getProvider();
|
|
3242
|
+
if (!provider) {
|
|
3243
|
+
if (typeof window !== 'undefined')
|
|
3244
|
+
window.showDebugLog?.('[getTWCBalance] No provider available for ethers fallback');
|
|
3245
|
+
throw new Error('No provider available for ethers fallback');
|
|
3246
|
+
}
|
|
3247
|
+
if (!provider._isProvider) {
|
|
3248
|
+
provider = new ethers.BrowserProvider(provider);
|
|
3249
|
+
}
|
|
3250
|
+
const erc20Abi = ["function balanceOf(address) view returns (uint256)"];
|
|
3251
|
+
const contract = new ethers.Contract(TWC_CONTRACT, erc20Abi, provider);
|
|
3252
|
+
const rawBalance = await contract.balanceOf(accountAddress);
|
|
3253
|
+
if (typeof window !== 'undefined')
|
|
3254
|
+
window.showDebugLog?.(`[getTWCBalance] [ethers fallback] rawBalance (BigInt) for ${accountAddress}: ${rawBalance?.toString?.()}`);
|
|
3255
|
+
balance = ethers.formatUnits(rawBalance, TWC_DECIMALS);
|
|
3256
|
+
if (typeof window !== 'undefined')
|
|
3257
|
+
window.showDebugLog?.(`[getTWCBalance] Raw balance for ${accountAddress} (ethers): ${balance}`);
|
|
3258
|
+
}
|
|
3143
3259
|
// Calculate USD value with 5 second timeout
|
|
3144
3260
|
const usdPromise = priceService.calculateTWCValue(balance);
|
|
3145
3261
|
const usdTimeoutPromise = new Promise((resolve) => {
|
|
3146
3262
|
setTimeout(() => resolve(0), 5000); // Default to 0 on timeout
|
|
3147
3263
|
});
|
|
3148
3264
|
const usdValue = await Promise.race([usdPromise, usdTimeoutPromise]);
|
|
3265
|
+
if (typeof window !== 'undefined')
|
|
3266
|
+
window.showDebugLog?.(`[getTWCBalance] USD value for ${accountAddress}: ${usdValue}`);
|
|
3149
3267
|
// Update cache
|
|
3150
3268
|
this.twcBalanceCache = {
|
|
3151
3269
|
balance,
|
|
@@ -3161,10 +3279,14 @@ class WalletConnector {
|
|
|
3161
3279
|
};
|
|
3162
3280
|
// Keep state in sync
|
|
3163
3281
|
this.updateState({ twcBalance: result.amount, usdValue: result.usdValue ?? null });
|
|
3282
|
+
if (typeof window !== 'undefined')
|
|
3283
|
+
window.showDebugLog?.(`[getTWCBalance] Final result for ${accountAddress}: ${JSON.stringify(result)}`);
|
|
3164
3284
|
return result;
|
|
3165
3285
|
}
|
|
3166
3286
|
catch (error) {
|
|
3167
3287
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
3288
|
+
if (typeof window !== 'undefined')
|
|
3289
|
+
window.showDebugLog?.(`[getTWCBalance] ERROR: ${errorMsg}`);
|
|
3168
3290
|
// Track error
|
|
3169
3291
|
this.balanceFetchErrors.push({
|
|
3170
3292
|
endpoint: 'wallet-provider',
|
|
@@ -7857,12 +7979,20 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
7857
7979
|
return;
|
|
7858
7980
|
}
|
|
7859
7981
|
try {
|
|
7860
|
-
|
|
7982
|
+
let chainId = await connector.getCurrentChain();
|
|
7861
7983
|
setCurrentChainId(chainId);
|
|
7862
7984
|
if (chainId !== 56) {
|
|
7863
7985
|
// Automatically switch to BSC
|
|
7864
7986
|
try {
|
|
7865
7987
|
await connector.switchChain(56);
|
|
7988
|
+
// After switching, re-fetch chainId and update state
|
|
7989
|
+
chainId = await connector.getCurrentChain();
|
|
7990
|
+
setCurrentChainId(chainId);
|
|
7991
|
+
// Optionally, trigger TWC balance fetch here if needed
|
|
7992
|
+
if (chainId === 56) {
|
|
7993
|
+
// Force a state update to trigger TWC balance fetch effect
|
|
7994
|
+
setTimeout(() => setCurrentChainId(56), 100); // small delay to ensure state update
|
|
7995
|
+
}
|
|
7866
7996
|
}
|
|
7867
7997
|
catch (err) {
|
|
7868
7998
|
// Optionally handle error (user rejected, etc.)
|
|
@@ -8424,13 +8554,18 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8424
8554
|
}
|
|
8425
8555
|
}, [account]);
|
|
8426
8556
|
const fetchTWCBalanceWithRetry = useCallback(async (maxRetries = 3, initialDelay = 200) => {
|
|
8427
|
-
//
|
|
8557
|
+
// Fetch TWC balance for all EVM chains (for debugging)
|
|
8428
8558
|
try {
|
|
8429
8559
|
const state = connector.getState();
|
|
8430
|
-
if (state.
|
|
8431
|
-
|
|
8560
|
+
if (state.status !== 'connected' ||
|
|
8561
|
+
!state.account ||
|
|
8562
|
+
state.account.chainType !== 'evm') {
|
|
8563
|
+
// Not connected, no account, or not EVM, do not fetch TWC balance
|
|
8432
8564
|
return null;
|
|
8433
8565
|
}
|
|
8566
|
+
// Allow fetching even if chainId is null, as long as account exists and is EVM
|
|
8567
|
+
// Log chainId for debug
|
|
8568
|
+
showDebugLog?.(`[fetchTWCBalanceWithRetry] Fetching TWC for chainId=${state.chainId}`);
|
|
8434
8569
|
const twcBalance = await connector.getTWCBalance();
|
|
8435
8570
|
return {
|
|
8436
8571
|
balance: twcBalance.amount || '0',
|
|
@@ -8772,8 +8907,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8772
8907
|
}, [connector, account]);
|
|
8773
8908
|
// Render button based on connection status
|
|
8774
8909
|
const renderButton = () => {
|
|
8775
|
-
// Only show connect button if we are fully initialized and truly disconnected
|
|
8776
|
-
if (!isInitializing && (!account
|
|
8910
|
+
// Only show connect button if we are fully initialized and truly disconnected (no account and status is DISCONNECTED)
|
|
8911
|
+
if (!isInitializing && (!account && status === ConnectionStatus.DISCONNECTED)) {
|
|
8777
8912
|
// Wallet icon SVG component
|
|
8778
8913
|
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" })] }));
|
|
8779
8914
|
return (jsxs("button", { onClick: () => handleOpenModal(), style: {
|
|
@@ -8802,16 +8937,14 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8802
8937
|
e.currentTarget.style.boxShadow = '0 2px 8px rgba(255, 152, 20, 0.3)';
|
|
8803
8938
|
}, children: [jsx("span", { style: { color: '#000000', display: 'flex', alignItems: 'center' }, children: jsx(WalletIcon, {}) }), jsx("span", { style: { color: '#000000', fontWeight: '500', fontSize: '14px' }, children: buttonText })] }));
|
|
8804
8939
|
}
|
|
8805
|
-
// ...existing code...
|
|
8806
8940
|
// All other states (including loading, connecting, connected) should only show the connected button or loading spinner if account is present or initializing is true
|
|
8807
8941
|
// If initializing, show nothing (or a spinner if desired)
|
|
8808
8942
|
if (isInitializing) {
|
|
8809
8943
|
// Optionally, you can show a spinner or skeleton here, but do not show connect/disconnect buttons
|
|
8810
8944
|
return null;
|
|
8811
8945
|
}
|
|
8812
|
-
//
|
|
8813
|
-
|
|
8814
|
-
if (account) {
|
|
8946
|
+
// Show connected button for any state where account is present and status is not DISCONNECTED or CONNECTING
|
|
8947
|
+
if (account && status !== ConnectionStatus.DISCONNECTED && status !== ConnectionStatus.CONNECTING) {
|
|
8815
8948
|
// ...existing code...
|
|
8816
8949
|
// Show normal connected button - styled to match design
|
|
8817
8950
|
// 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');
|
|
@@ -2426,13 +2427,38 @@ class WalletConnector {
|
|
|
2426
2427
|
* Connect to a wallet
|
|
2427
2428
|
*/
|
|
2428
2429
|
async connect(walletType) {
|
|
2430
|
+
// Only allow EVM wallet connections on BSC (chainId 56)
|
|
2431
|
+
let adapter = this.adapters.get(walletType);
|
|
2432
|
+
if (adapter && adapter.chainType === exports.ChainType.EVM && typeof adapter.getChainId === 'function') {
|
|
2433
|
+
try {
|
|
2434
|
+
const chainId = await adapter.getChainId();
|
|
2435
|
+
if (chainId !== 56) {
|
|
2436
|
+
const error = new Error('Only Binance Smart Chain (BSC) is supported for EVM wallet connections. Please switch your wallet to BSC and try again.');
|
|
2437
|
+
this.updateState({
|
|
2438
|
+
status: exports.ConnectionStatus.ERROR,
|
|
2439
|
+
error,
|
|
2440
|
+
});
|
|
2441
|
+
this.eventEmitter.emit(exports.WalletEvent.ERROR, error);
|
|
2442
|
+
throw error;
|
|
2443
|
+
}
|
|
2444
|
+
}
|
|
2445
|
+
catch (e) {
|
|
2446
|
+
const error = new Error('Failed to detect EVM chain. Please ensure your wallet is connected to BSC.');
|
|
2447
|
+
this.updateState({
|
|
2448
|
+
status: exports.ConnectionStatus.ERROR,
|
|
2449
|
+
error,
|
|
2450
|
+
});
|
|
2451
|
+
this.eventEmitter.emit(exports.WalletEvent.ERROR, error);
|
|
2452
|
+
throw error;
|
|
2453
|
+
}
|
|
2454
|
+
}
|
|
2429
2455
|
// Prevent duplicate connection requests
|
|
2430
2456
|
if (this.state.status === exports.ConnectionStatus.CONNECTING) {
|
|
2431
2457
|
const error = new Error('Connection already in progress. Please wait...');
|
|
2432
2458
|
console.warn('Duplicate connection attempt blocked:', walletType);
|
|
2433
2459
|
throw error;
|
|
2434
2460
|
}
|
|
2435
|
-
|
|
2461
|
+
// adapter already declared above
|
|
2436
2462
|
if (!adapter) {
|
|
2437
2463
|
const error = new Error(`Wallet ${walletType} is not registered`);
|
|
2438
2464
|
this.updateState({
|
|
@@ -2554,13 +2580,9 @@ class WalletConnector {
|
|
|
2554
2580
|
if (account && adapter.chainType === exports.ChainType.TON) {
|
|
2555
2581
|
try {
|
|
2556
2582
|
const nftResult = await this.checkNFTOwnership([
|
|
2557
|
-
// New collection - user-friendly format
|
|
2558
2583
|
'EQDVaDCso_2LRTkc8WrT9A4bVO5BG_PZ8313BC_lOO8XW1T8',
|
|
2559
|
-
// New collection - raw format
|
|
2560
2584
|
'0:d56830aca3fd8b45391cf16ad3f40e1b54ee411bf3d9f37d77042fe538ef175b',
|
|
2561
|
-
// Legacy collection - user-friendly format
|
|
2562
2585
|
'EQDKfA87JVnBJXsBVfzjIfbhr3bmTTdouUP31Szgm_Lw0v-J',
|
|
2563
|
-
// Legacy collection - raw format
|
|
2564
2586
|
'0:ca7c0f3b2559c1257b0155fce321f6e1af76e64d3768b943f7d52ce09bf2f0d2'
|
|
2565
2587
|
]);
|
|
2566
2588
|
accountWithNFTs = {
|
|
@@ -2571,7 +2593,6 @@ class WalletConnector {
|
|
|
2571
2593
|
hasRequiredNFTs: nftResult.hasNFTs,
|
|
2572
2594
|
ownedCount: nftResult.ownedNFTs.length
|
|
2573
2595
|
});
|
|
2574
|
-
// Update state with NFT count and data
|
|
2575
2596
|
this.updateState({
|
|
2576
2597
|
account: accountWithNFTs,
|
|
2577
2598
|
nftCount: nftResult.ownedNFTs.length,
|
|
@@ -2580,36 +2601,40 @@ class WalletConnector {
|
|
|
2580
2601
|
}
|
|
2581
2602
|
catch (nftError) {
|
|
2582
2603
|
this.debugTools.warn('WALLET_CONNECTOR', 'NFT check failed during account change', nftError);
|
|
2583
|
-
// Continue with account change even if NFT check fails
|
|
2584
2604
|
this.updateState({ account: accountWithNFTs });
|
|
2585
2605
|
}
|
|
2586
2606
|
}
|
|
2587
2607
|
else {
|
|
2588
2608
|
this.updateState({ account: accountWithNFTs });
|
|
2589
2609
|
}
|
|
2610
|
+
// Always update chainId in state after account change (for EVM wallets)
|
|
2611
|
+
if (account && adapter.chainType === exports.ChainType.EVM && typeof adapter.getChainId === 'function') {
|
|
2612
|
+
try {
|
|
2613
|
+
const chainId = await adapter.getChainId();
|
|
2614
|
+
this.updateState({ chainId });
|
|
2615
|
+
}
|
|
2616
|
+
catch (e) {
|
|
2617
|
+
this.updateState({ chainId: null });
|
|
2618
|
+
}
|
|
2619
|
+
}
|
|
2590
2620
|
this.eventEmitter.emit(exports.WalletEvent.ACCOUNT_CHANGED, accountWithNFTs);
|
|
2591
2621
|
if (account) {
|
|
2592
2622
|
this.eventEmitter.emit(exports.WalletEvent.CONNECTED, account);
|
|
2593
|
-
// Automatically fetch new balance and price when account changes
|
|
2594
2623
|
try {
|
|
2595
2624
|
this.debugTools.info('WALLET_CONNECTOR', 'Account changed, fetching new balance and price', {
|
|
2596
2625
|
account: account.address,
|
|
2597
2626
|
wallet: walletType
|
|
2598
2627
|
});
|
|
2599
|
-
// Clear price cache for new account
|
|
2600
2628
|
priceService.clearCache();
|
|
2601
|
-
// Fetch TWC balance and price
|
|
2602
2629
|
if (adapter.chainType === exports.ChainType.EVM) {
|
|
2603
2630
|
try {
|
|
2604
2631
|
const twcBalance = await this.getTWCBalance();
|
|
2605
|
-
// Persist in state for exportability
|
|
2606
2632
|
this.updateState({ twcBalance: twcBalance.amount, usdValue: twcBalance.usdValue ?? null });
|
|
2607
2633
|
this.debugTools.info('WALLET_CONNECTOR', 'TWC balance updated for new account', {
|
|
2608
2634
|
balance: twcBalance.amount,
|
|
2609
2635
|
usdValue: twcBalance.usdValue,
|
|
2610
2636
|
account: account.address
|
|
2611
2637
|
});
|
|
2612
|
-
// Emit balance update event
|
|
2613
2638
|
this.eventEmitter.emit(exports.WalletEvent.BALANCE_UPDATED, {
|
|
2614
2639
|
type: 'TWC',
|
|
2615
2640
|
balance: twcBalance.amount,
|
|
@@ -2621,7 +2646,6 @@ class WalletConnector {
|
|
|
2621
2646
|
}
|
|
2622
2647
|
catch (twcError) {
|
|
2623
2648
|
this.debugTools.warn('WALLET_CONNECTOR', 'Failed to fetch TWC balance for new account', twcError);
|
|
2624
|
-
// Fallback to native balance
|
|
2625
2649
|
try {
|
|
2626
2650
|
const nativeBalance = await this.getNativeBalance();
|
|
2627
2651
|
this.debugTools.info('WALLET_CONNECTOR', 'Native balance updated for new account', {
|
|
@@ -2629,7 +2653,6 @@ class WalletConnector {
|
|
|
2629
2653
|
symbol: nativeBalance.symbol,
|
|
2630
2654
|
account: account.address
|
|
2631
2655
|
});
|
|
2632
|
-
// Emit balance update event
|
|
2633
2656
|
this.eventEmitter.emit(exports.WalletEvent.BALANCE_UPDATED, {
|
|
2634
2657
|
type: 'NATIVE',
|
|
2635
2658
|
balance: nativeBalance.amount,
|
|
@@ -2648,7 +2671,6 @@ class WalletConnector {
|
|
|
2648
2671
|
}
|
|
2649
2672
|
}
|
|
2650
2673
|
else if (this.state.wallet) {
|
|
2651
|
-
// Account removed/disconnected from wallet app
|
|
2652
2674
|
this.storage.clearWallet();
|
|
2653
2675
|
this.updateState({ wallet: null, account: null, status: exports.ConnectionStatus.DISCONNECTED, twcBalance: null, usdValue: null, nftCount: 0, nftData: null });
|
|
2654
2676
|
this.eventEmitter.emit(exports.WalletEvent.DISCONNECTED, undefined);
|
|
@@ -2694,13 +2716,9 @@ class WalletConnector {
|
|
|
2694
2716
|
if (adapter.chainType === exports.ChainType.TON) {
|
|
2695
2717
|
try {
|
|
2696
2718
|
const nftResult = await this.checkNFTOwnership([
|
|
2697
|
-
// New collection - user-friendly format
|
|
2698
2719
|
'EQDVaDCso_2LRTkc8WrT9A4bVO5BG_PZ8313BC_lOO8XW1T8',
|
|
2699
|
-
// New collection - raw format
|
|
2700
2720
|
'0:d56830aca3fd8b45391cf16ad3f40e1b54ee411bf3d9f37d77042fe538ef175b',
|
|
2701
|
-
// Legacy collection - user-friendly format
|
|
2702
2721
|
'EQDKfA87JVnBJXsBVfzjIfbhr3bmTTdouUP31Szgm_Lw0v-J',
|
|
2703
|
-
// Legacy collection - raw format
|
|
2704
2722
|
'0:ca7c0f3b2559c1257b0155fce321f6e1af76e64d3768b943f7d52ce09bf2f0d2'
|
|
2705
2723
|
]);
|
|
2706
2724
|
accountWithNFTs = {
|
|
@@ -2714,7 +2732,6 @@ class WalletConnector {
|
|
|
2714
2732
|
}
|
|
2715
2733
|
catch (nftError) {
|
|
2716
2734
|
this.debugTools.warn('WALLET_CONNECTOR', 'NFT check failed, proceeding without NFT info', nftError);
|
|
2717
|
-
// Continue with connection even if NFT check fails
|
|
2718
2735
|
}
|
|
2719
2736
|
}
|
|
2720
2737
|
this.storage.saveWallet(walletType);
|
|
@@ -2724,6 +2741,39 @@ class WalletConnector {
|
|
|
2724
2741
|
error: null,
|
|
2725
2742
|
});
|
|
2726
2743
|
this.eventEmitter.emit(exports.WalletEvent.CONNECTED, accountWithNFTs);
|
|
2744
|
+
// Immediately fetch TWC balance after initial connection (not just on reconnect or refresh)
|
|
2745
|
+
if (adapter.chainType === exports.ChainType.EVM) {
|
|
2746
|
+
try {
|
|
2747
|
+
// Update chainId in state if possible
|
|
2748
|
+
if (typeof adapter.getChainId === 'function') {
|
|
2749
|
+
try {
|
|
2750
|
+
const chainId = await adapter.getChainId();
|
|
2751
|
+
this.updateState({ chainId });
|
|
2752
|
+
}
|
|
2753
|
+
catch (e) {
|
|
2754
|
+
this.updateState({ chainId: null });
|
|
2755
|
+
}
|
|
2756
|
+
}
|
|
2757
|
+
const twcBalance = await this.getTWCBalance();
|
|
2758
|
+
this.updateState({ twcBalance: twcBalance.amount, usdValue: twcBalance.usdValue ?? null });
|
|
2759
|
+
this.debugTools.info('WALLET_CONNECTOR', 'TWC balance updated after initial connect', {
|
|
2760
|
+
balance: twcBalance.amount,
|
|
2761
|
+
usdValue: twcBalance.usdValue,
|
|
2762
|
+
account: accountWithNFTs.address
|
|
2763
|
+
});
|
|
2764
|
+
this.eventEmitter.emit(exports.WalletEvent.BALANCE_UPDATED, {
|
|
2765
|
+
type: 'TWC',
|
|
2766
|
+
balance: twcBalance.amount,
|
|
2767
|
+
symbol: twcBalance.symbol,
|
|
2768
|
+
usdValue: twcBalance.usdValue,
|
|
2769
|
+
usdFormatted: twcBalance.usdFormatted,
|
|
2770
|
+
account: accountWithNFTs.address
|
|
2771
|
+
});
|
|
2772
|
+
}
|
|
2773
|
+
catch (twcError) {
|
|
2774
|
+
this.debugTools.warn('WALLET_CONNECTOR', 'Failed to fetch TWC balance after initial connect', twcError);
|
|
2775
|
+
}
|
|
2776
|
+
}
|
|
2727
2777
|
}
|
|
2728
2778
|
else {
|
|
2729
2779
|
// Connection failed - reset state properly
|
|
@@ -3104,14 +3154,21 @@ class WalletConnector {
|
|
|
3104
3154
|
}
|
|
3105
3155
|
async getTWCBalance() {
|
|
3106
3156
|
if (!this.state.account) {
|
|
3157
|
+
if (typeof window !== 'undefined')
|
|
3158
|
+
window.showDebugLog?.('[getTWCBalance] No wallet connected');
|
|
3107
3159
|
throw new Error('No wallet connected');
|
|
3108
3160
|
}
|
|
3109
3161
|
const accountAddress = this.state.account.address;
|
|
3162
|
+
const chainId = this.state.chainId;
|
|
3110
3163
|
performance.now();
|
|
3164
|
+
if (typeof window !== 'undefined')
|
|
3165
|
+
window.showDebugLog?.(`[getTWCBalance] Called for account=${accountAddress}, chainId=${chainId}`);
|
|
3111
3166
|
// Check cache first
|
|
3112
3167
|
if (this.twcBalanceCache &&
|
|
3113
3168
|
this.twcBalanceCache.address === accountAddress &&
|
|
3114
3169
|
Date.now() - this.twcBalanceCache.timestamp < this.TWC_CACHE_TTL) {
|
|
3170
|
+
if (typeof window !== 'undefined')
|
|
3171
|
+
window.showDebugLog?.(`[getTWCBalance] Using cache for ${accountAddress}: ${JSON.stringify(this.twcBalanceCache)}`);
|
|
3115
3172
|
return {
|
|
3116
3173
|
amount: this.twcBalanceCache.balance,
|
|
3117
3174
|
symbol: 'TWC',
|
|
@@ -3128,26 +3185,87 @@ class WalletConnector {
|
|
|
3128
3185
|
// Use the currently connected wallet's adapter
|
|
3129
3186
|
const currentWallet = this.state.wallet;
|
|
3130
3187
|
if (!currentWallet) {
|
|
3188
|
+
if (typeof window !== 'undefined')
|
|
3189
|
+
window.showDebugLog?.('[getTWCBalance] No wallet connected (no currentWallet)');
|
|
3131
3190
|
throw new Error('No wallet connected');
|
|
3132
3191
|
}
|
|
3133
3192
|
const adapter = this.adapters.get(currentWallet);
|
|
3134
3193
|
if (!adapter || adapter.chainType !== exports.ChainType.EVM) {
|
|
3194
|
+
if (typeof window !== 'undefined')
|
|
3195
|
+
window.showDebugLog?.('[getTWCBalance] No EVM adapter available');
|
|
3135
3196
|
throw new Error('No EVM adapter available');
|
|
3136
3197
|
}
|
|
3137
|
-
//
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3198
|
+
// Debug: log adapter type and available methods
|
|
3199
|
+
if (typeof window !== 'undefined') {
|
|
3200
|
+
window.showDebugLog?.(`[getTWCBalance] Using adapter: ${adapter.constructor?.name || typeof adapter}`);
|
|
3201
|
+
window.showDebugLog?.(`[getTWCBalance] Adapter keys: ${Object.keys(adapter).join(', ')}`);
|
|
3202
|
+
window.showDebugLog?.(`[getTWCBalance] typeof getTokenBalance: ${typeof adapter.getTokenBalance}`);
|
|
3203
|
+
}
|
|
3204
|
+
let balance;
|
|
3205
|
+
// Always use ethers fallback if EVM is connected, regardless of chainId
|
|
3206
|
+
if (this.state.chainId !== 56) {
|
|
3207
|
+
if (typeof window !== 'undefined')
|
|
3208
|
+
window.showDebugLog?.(`[getTWCBalance] Warning: Not on BSC (chainId=${this.state.chainId}), but fetching TWC balance using ethers fallback.`);
|
|
3209
|
+
// Fallback: use ethers.js to fetch balance from chain
|
|
3210
|
+
let provider = adapter.provider || this.getProvider();
|
|
3211
|
+
if (!provider) {
|
|
3212
|
+
if (typeof window !== 'undefined')
|
|
3213
|
+
window.showDebugLog?.('[getTWCBalance] No provider available for ethers fallback');
|
|
3214
|
+
throw new Error('No provider available for ethers fallback');
|
|
3215
|
+
}
|
|
3216
|
+
// Use ethers.BrowserProvider for ethers v6 compatibility
|
|
3217
|
+
if (!provider._isProvider) {
|
|
3218
|
+
provider = new ethers.ethers.BrowserProvider(provider);
|
|
3219
|
+
}
|
|
3220
|
+
const erc20Abi = ["function balanceOf(address) view returns (uint256)"];
|
|
3221
|
+
const contract = new ethers.ethers.Contract(TWC_CONTRACT, erc20Abi, provider);
|
|
3222
|
+
const rawBalance = await contract.balanceOf(accountAddress);
|
|
3223
|
+
if (typeof window !== 'undefined')
|
|
3224
|
+
window.showDebugLog?.(`[getTWCBalance] [ethers fallback] rawBalance (BigInt) for ${accountAddress}: ${rawBalance?.toString?.()}`);
|
|
3225
|
+
balance = ethers.ethers.formatUnits(rawBalance, TWC_DECIMALS);
|
|
3226
|
+
if (typeof window !== 'undefined')
|
|
3227
|
+
window.showDebugLog?.(`[getTWCBalance] Raw balance for ${accountAddress} (ethers): ${balance}`);
|
|
3228
|
+
}
|
|
3229
|
+
else if (typeof adapter.getTokenBalance === 'function') {
|
|
3230
|
+
// Use adapter method if available and on BSC
|
|
3231
|
+
const balancePromise = adapter.getTokenBalance(TWC_CONTRACT, TWC_DECIMALS, true);
|
|
3232
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
3233
|
+
setTimeout(() => reject(new Error('Balance fetch timeout after 10 seconds')), 10000);
|
|
3234
|
+
});
|
|
3235
|
+
balance = await Promise.race([balancePromise, timeoutPromise]);
|
|
3236
|
+
if (typeof window !== 'undefined')
|
|
3237
|
+
window.showDebugLog?.(`[getTWCBalance] Raw balance for ${accountAddress} (adapter): ${balance}`);
|
|
3238
|
+
}
|
|
3239
|
+
else {
|
|
3240
|
+
// Fallback: use ethers.js to fetch balance from chain (should not happen, but for safety)
|
|
3241
|
+
if (typeof window !== 'undefined')
|
|
3242
|
+
window.showDebugLog?.('[getTWCBalance] Fallback to ethers.js for TWC balance (on BSC)');
|
|
3243
|
+
let provider = adapter.provider || this.getProvider();
|
|
3244
|
+
if (!provider) {
|
|
3245
|
+
if (typeof window !== 'undefined')
|
|
3246
|
+
window.showDebugLog?.('[getTWCBalance] No provider available for ethers fallback');
|
|
3247
|
+
throw new Error('No provider available for ethers fallback');
|
|
3248
|
+
}
|
|
3249
|
+
if (!provider._isProvider) {
|
|
3250
|
+
provider = new ethers.ethers.BrowserProvider(provider);
|
|
3251
|
+
}
|
|
3252
|
+
const erc20Abi = ["function balanceOf(address) view returns (uint256)"];
|
|
3253
|
+
const contract = new ethers.ethers.Contract(TWC_CONTRACT, erc20Abi, provider);
|
|
3254
|
+
const rawBalance = await contract.balanceOf(accountAddress);
|
|
3255
|
+
if (typeof window !== 'undefined')
|
|
3256
|
+
window.showDebugLog?.(`[getTWCBalance] [ethers fallback] rawBalance (BigInt) for ${accountAddress}: ${rawBalance?.toString?.()}`);
|
|
3257
|
+
balance = ethers.ethers.formatUnits(rawBalance, TWC_DECIMALS);
|
|
3258
|
+
if (typeof window !== 'undefined')
|
|
3259
|
+
window.showDebugLog?.(`[getTWCBalance] Raw balance for ${accountAddress} (ethers): ${balance}`);
|
|
3260
|
+
}
|
|
3145
3261
|
// Calculate USD value with 5 second timeout
|
|
3146
3262
|
const usdPromise = priceService.calculateTWCValue(balance);
|
|
3147
3263
|
const usdTimeoutPromise = new Promise((resolve) => {
|
|
3148
3264
|
setTimeout(() => resolve(0), 5000); // Default to 0 on timeout
|
|
3149
3265
|
});
|
|
3150
3266
|
const usdValue = await Promise.race([usdPromise, usdTimeoutPromise]);
|
|
3267
|
+
if (typeof window !== 'undefined')
|
|
3268
|
+
window.showDebugLog?.(`[getTWCBalance] USD value for ${accountAddress}: ${usdValue}`);
|
|
3151
3269
|
// Update cache
|
|
3152
3270
|
this.twcBalanceCache = {
|
|
3153
3271
|
balance,
|
|
@@ -3163,10 +3281,14 @@ class WalletConnector {
|
|
|
3163
3281
|
};
|
|
3164
3282
|
// Keep state in sync
|
|
3165
3283
|
this.updateState({ twcBalance: result.amount, usdValue: result.usdValue ?? null });
|
|
3284
|
+
if (typeof window !== 'undefined')
|
|
3285
|
+
window.showDebugLog?.(`[getTWCBalance] Final result for ${accountAddress}: ${JSON.stringify(result)}`);
|
|
3166
3286
|
return result;
|
|
3167
3287
|
}
|
|
3168
3288
|
catch (error) {
|
|
3169
3289
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
3290
|
+
if (typeof window !== 'undefined')
|
|
3291
|
+
window.showDebugLog?.(`[getTWCBalance] ERROR: ${errorMsg}`);
|
|
3170
3292
|
// Track error
|
|
3171
3293
|
this.balanceFetchErrors.push({
|
|
3172
3294
|
endpoint: 'wallet-provider',
|
|
@@ -7859,12 +7981,20 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
7859
7981
|
return;
|
|
7860
7982
|
}
|
|
7861
7983
|
try {
|
|
7862
|
-
|
|
7984
|
+
let chainId = await connector.getCurrentChain();
|
|
7863
7985
|
setCurrentChainId(chainId);
|
|
7864
7986
|
if (chainId !== 56) {
|
|
7865
7987
|
// Automatically switch to BSC
|
|
7866
7988
|
try {
|
|
7867
7989
|
await connector.switchChain(56);
|
|
7990
|
+
// After switching, re-fetch chainId and update state
|
|
7991
|
+
chainId = await connector.getCurrentChain();
|
|
7992
|
+
setCurrentChainId(chainId);
|
|
7993
|
+
// Optionally, trigger TWC balance fetch here if needed
|
|
7994
|
+
if (chainId === 56) {
|
|
7995
|
+
// Force a state update to trigger TWC balance fetch effect
|
|
7996
|
+
setTimeout(() => setCurrentChainId(56), 100); // small delay to ensure state update
|
|
7997
|
+
}
|
|
7868
7998
|
}
|
|
7869
7999
|
catch (err) {
|
|
7870
8000
|
// Optionally handle error (user rejected, etc.)
|
|
@@ -8426,13 +8556,18 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8426
8556
|
}
|
|
8427
8557
|
}, [account]);
|
|
8428
8558
|
const fetchTWCBalanceWithRetry = React.useCallback(async (maxRetries = 3, initialDelay = 200) => {
|
|
8429
|
-
//
|
|
8559
|
+
// Fetch TWC balance for all EVM chains (for debugging)
|
|
8430
8560
|
try {
|
|
8431
8561
|
const state = connector.getState();
|
|
8432
|
-
if (state.
|
|
8433
|
-
|
|
8562
|
+
if (state.status !== 'connected' ||
|
|
8563
|
+
!state.account ||
|
|
8564
|
+
state.account.chainType !== 'evm') {
|
|
8565
|
+
// Not connected, no account, or not EVM, do not fetch TWC balance
|
|
8434
8566
|
return null;
|
|
8435
8567
|
}
|
|
8568
|
+
// Allow fetching even if chainId is null, as long as account exists and is EVM
|
|
8569
|
+
// Log chainId for debug
|
|
8570
|
+
showDebugLog?.(`[fetchTWCBalanceWithRetry] Fetching TWC for chainId=${state.chainId}`);
|
|
8436
8571
|
const twcBalance = await connector.getTWCBalance();
|
|
8437
8572
|
return {
|
|
8438
8573
|
balance: twcBalance.amount || '0',
|
|
@@ -8774,8 +8909,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8774
8909
|
}, [connector, account]);
|
|
8775
8910
|
// Render button based on connection status
|
|
8776
8911
|
const renderButton = () => {
|
|
8777
|
-
// Only show connect button if we are fully initialized and truly disconnected
|
|
8778
|
-
if (!isInitializing && (!account
|
|
8912
|
+
// Only show connect button if we are fully initialized and truly disconnected (no account and status is DISCONNECTED)
|
|
8913
|
+
if (!isInitializing && (!account && status === exports.ConnectionStatus.DISCONNECTED)) {
|
|
8779
8914
|
// Wallet icon SVG component
|
|
8780
8915
|
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" })] }));
|
|
8781
8916
|
return (jsxRuntime.jsxs("button", { onClick: () => handleOpenModal(), style: {
|
|
@@ -8804,16 +8939,14 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8804
8939
|
e.currentTarget.style.boxShadow = '0 2px 8px rgba(255, 152, 20, 0.3)';
|
|
8805
8940
|
}, 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 })] }));
|
|
8806
8941
|
}
|
|
8807
|
-
// ...existing code...
|
|
8808
8942
|
// All other states (including loading, connecting, connected) should only show the connected button or loading spinner if account is present or initializing is true
|
|
8809
8943
|
// If initializing, show nothing (or a spinner if desired)
|
|
8810
8944
|
if (isInitializing) {
|
|
8811
8945
|
// Optionally, you can show a spinner or skeleton here, but do not show connect/disconnect buttons
|
|
8812
8946
|
return null;
|
|
8813
8947
|
}
|
|
8814
|
-
//
|
|
8815
|
-
|
|
8816
|
-
if (account) {
|
|
8948
|
+
// Show connected button for any state where account is present and status is not DISCONNECTED or CONNECTING
|
|
8949
|
+
if (account && status !== exports.ConnectionStatus.DISCONNECTED && status !== exports.ConnectionStatus.CONNECTING) {
|
|
8817
8950
|
// ...existing code...
|
|
8818
8951
|
// Show normal connected button - styled to match design
|
|
8819
8952
|
// Parse balance amount and symbol separately
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tiwiflix-wallet-connector",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.8",
|
|
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",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"@tonconnect/ui": "^2.3.1",
|
|
61
61
|
"@walletconnect/ethereum-provider": "^2.13.0",
|
|
62
62
|
"@walletconnect/universal-provider": "^2.21.10",
|
|
63
|
-
"ethers": "^6.
|
|
63
|
+
"ethers": "^6.16.0",
|
|
64
64
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
|
65
65
|
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
|
66
66
|
"viem": "^2.42.1",
|