tiwiflix-wallet-connector 1.6.7 → 1.6.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +0 -6
- package/dist/index.esm.js +157 -250
- package/dist/index.js +157 -250
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -418,8 +418,6 @@ declare class WalletConnector {
|
|
|
418
418
|
* Get TWC token balance for EVM wallets
|
|
419
419
|
* TWC is ONLY available on BSC (chainId 56)
|
|
420
420
|
*/
|
|
421
|
-
private twcBalanceCache;
|
|
422
|
-
private readonly TWC_CACHE_TTL;
|
|
423
421
|
private balanceFetchErrors;
|
|
424
422
|
getTWCBalance(): Promise<{
|
|
425
423
|
amount: string;
|
|
@@ -492,10 +490,6 @@ declare class WalletConnector {
|
|
|
492
490
|
* Can optionally filter by collection addresses
|
|
493
491
|
*/
|
|
494
492
|
private queryAllTONNFTs;
|
|
495
|
-
/**
|
|
496
|
-
* Query TON API for NFTs owned by an address in a specific collection
|
|
497
|
-
*/
|
|
498
|
-
private queryTONNFTs;
|
|
499
493
|
}
|
|
500
494
|
|
|
501
495
|
/**
|
package/dist/index.esm.js
CHANGED
|
@@ -1907,7 +1907,7 @@ const defaultMultiChainConfig = {
|
|
|
1907
1907
|
{
|
|
1908
1908
|
chainId: 56,
|
|
1909
1909
|
name: 'BNB Smart Chain',
|
|
1910
|
-
rpcUrl: 'https://bsc
|
|
1910
|
+
rpcUrl: 'https://bsc.publicnode.com',
|
|
1911
1911
|
blockExplorerUrl: 'https://bscscan.com',
|
|
1912
1912
|
nativeCurrency: {
|
|
1913
1913
|
name: 'BNB',
|
|
@@ -2312,6 +2312,7 @@ class WalletConnector {
|
|
|
2312
2312
|
error: null,
|
|
2313
2313
|
twcBalance: null,
|
|
2314
2314
|
usdValue: null,
|
|
2315
|
+
chainId: null,
|
|
2315
2316
|
};
|
|
2316
2317
|
// Performance monitoring
|
|
2317
2318
|
this.performanceMetrics = {
|
|
@@ -2325,8 +2326,6 @@ class WalletConnector {
|
|
|
2325
2326
|
* TWC is ONLY available on BSC (chainId 56)
|
|
2326
2327
|
*/
|
|
2327
2328
|
// Cache for TWC balance to avoid redundant fetches
|
|
2328
|
-
this.twcBalanceCache = null;
|
|
2329
|
-
this.TWC_CACHE_TTL = 30000; // 30 seconds cache
|
|
2330
2329
|
// Error tracking for balance fetching
|
|
2331
2330
|
this.balanceFetchErrors = [];
|
|
2332
2331
|
this.config = config;
|
|
@@ -2425,13 +2424,38 @@ class WalletConnector {
|
|
|
2425
2424
|
* Connect to a wallet
|
|
2426
2425
|
*/
|
|
2427
2426
|
async connect(walletType) {
|
|
2427
|
+
// Only allow EVM wallet connections on BSC (chainId 56)
|
|
2428
|
+
let adapter = this.adapters.get(walletType);
|
|
2429
|
+
if (adapter && adapter.chainType === ChainType.EVM && typeof adapter.getChainId === 'function') {
|
|
2430
|
+
try {
|
|
2431
|
+
const chainId = await adapter.getChainId();
|
|
2432
|
+
if (chainId !== 56) {
|
|
2433
|
+
const error = new Error('Only Binance Smart Chain (BSC) is supported for EVM wallet connections. Please switch your wallet to BSC and try again.');
|
|
2434
|
+
this.updateState({
|
|
2435
|
+
status: ConnectionStatus.ERROR,
|
|
2436
|
+
error,
|
|
2437
|
+
});
|
|
2438
|
+
this.eventEmitter.emit(WalletEvent.ERROR, error);
|
|
2439
|
+
throw error;
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
catch (e) {
|
|
2443
|
+
const error = new Error('Failed to detect EVM chain. Please ensure your wallet is connected to BSC.');
|
|
2444
|
+
this.updateState({
|
|
2445
|
+
status: ConnectionStatus.ERROR,
|
|
2446
|
+
error,
|
|
2447
|
+
});
|
|
2448
|
+
this.eventEmitter.emit(WalletEvent.ERROR, error);
|
|
2449
|
+
throw error;
|
|
2450
|
+
}
|
|
2451
|
+
}
|
|
2428
2452
|
// Prevent duplicate connection requests
|
|
2429
2453
|
if (this.state.status === ConnectionStatus.CONNECTING) {
|
|
2430
2454
|
const error = new Error('Connection already in progress. Please wait...');
|
|
2431
2455
|
console.warn('Duplicate connection attempt blocked:', walletType);
|
|
2432
2456
|
throw error;
|
|
2433
2457
|
}
|
|
2434
|
-
|
|
2458
|
+
// adapter already declared above
|
|
2435
2459
|
if (!adapter) {
|
|
2436
2460
|
const error = new Error(`Wallet ${walletType} is not registered`);
|
|
2437
2461
|
this.updateState({
|
|
@@ -2668,7 +2692,7 @@ class WalletConnector {
|
|
|
2668
2692
|
clearTimeout(safetyTimeout);
|
|
2669
2693
|
clearTimeout(connectionTimeout);
|
|
2670
2694
|
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
|
2671
|
-
|
|
2695
|
+
// removed unused errorMsg
|
|
2672
2696
|
this.debugTools.error('WALLET_CONNECTOR', 'Connection error caught', error);
|
|
2673
2697
|
// Reset state on connection error
|
|
2674
2698
|
this.updateState({
|
|
@@ -2750,7 +2774,7 @@ class WalletConnector {
|
|
|
2750
2774
|
}
|
|
2751
2775
|
else {
|
|
2752
2776
|
// Connection failed - reset state properly
|
|
2753
|
-
|
|
2777
|
+
// removed unused errorMsg
|
|
2754
2778
|
this.debugTools.error('WALLET_CONNECTOR', 'Connection failed', result.error);
|
|
2755
2779
|
this.updateState({
|
|
2756
2780
|
status: ConnectionStatus.DISCONNECTED,
|
|
@@ -3126,153 +3150,29 @@ class WalletConnector {
|
|
|
3126
3150
|
this.sdkLoader.clearCache();
|
|
3127
3151
|
}
|
|
3128
3152
|
async getTWCBalance() {
|
|
3129
|
-
if (!this.state.account) {
|
|
3130
|
-
|
|
3131
|
-
window.showDebugLog?.('[getTWCBalance] No wallet connected');
|
|
3132
|
-
throw new Error('No wallet connected');
|
|
3153
|
+
if (!this.state.account || this.state.account.chainType !== 'evm') {
|
|
3154
|
+
throw new Error('No EVM account connected');
|
|
3133
3155
|
}
|
|
3134
3156
|
const accountAddress = this.state.account.address;
|
|
3135
|
-
const chainId = this.state.chainId;
|
|
3136
|
-
performance.now();
|
|
3137
|
-
if (typeof window !== 'undefined')
|
|
3138
|
-
window.showDebugLog?.(`[getTWCBalance] Called for account=${accountAddress}, chainId=${chainId}`);
|
|
3139
|
-
// Check cache first
|
|
3140
|
-
if (this.twcBalanceCache &&
|
|
3141
|
-
this.twcBalanceCache.address === accountAddress &&
|
|
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)}`);
|
|
3145
|
-
return {
|
|
3146
|
-
amount: this.twcBalanceCache.balance,
|
|
3147
|
-
symbol: 'TWC',
|
|
3148
|
-
usdValue: this.twcBalanceCache.usdValue,
|
|
3149
|
-
usdFormatted: priceService.formatUSDValue(this.twcBalanceCache.usdValue)
|
|
3150
|
-
};
|
|
3151
|
-
}
|
|
3152
|
-
// TWC contract on BSC
|
|
3153
3157
|
const TWC_CONTRACT = '0xDA1060158F7D593667cCE0a15DB346BB3FfB3596';
|
|
3154
3158
|
const TWC_DECIMALS = 9;
|
|
3155
3159
|
const TWC_SYMBOL = 'TWC';
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
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
|
-
}
|
|
3233
|
-
// Calculate USD value with 5 second timeout
|
|
3234
|
-
const usdPromise = priceService.calculateTWCValue(balance);
|
|
3235
|
-
const usdTimeoutPromise = new Promise((resolve) => {
|
|
3236
|
-
setTimeout(() => resolve(0), 5000); // Default to 0 on timeout
|
|
3237
|
-
});
|
|
3238
|
-
const usdValue = await Promise.race([usdPromise, usdTimeoutPromise]);
|
|
3239
|
-
if (typeof window !== 'undefined')
|
|
3240
|
-
window.showDebugLog?.(`[getTWCBalance] USD value for ${accountAddress}: ${usdValue}`);
|
|
3241
|
-
// Update cache
|
|
3242
|
-
this.twcBalanceCache = {
|
|
3243
|
-
balance,
|
|
3244
|
-
usdValue,
|
|
3245
|
-
timestamp: Date.now(),
|
|
3246
|
-
address: accountAddress
|
|
3247
|
-
};
|
|
3248
|
-
const result = {
|
|
3249
|
-
amount: balance,
|
|
3250
|
-
symbol: TWC_SYMBOL,
|
|
3251
|
-
usdValue,
|
|
3252
|
-
usdFormatted: priceService.formatUSDValue(usdValue)
|
|
3253
|
-
};
|
|
3254
|
-
// Keep state in sync
|
|
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)}`);
|
|
3258
|
-
return result;
|
|
3259
|
-
}
|
|
3260
|
-
catch (error) {
|
|
3261
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
3262
|
-
if (typeof window !== 'undefined')
|
|
3263
|
-
window.showDebugLog?.(`[getTWCBalance] ERROR: ${errorMsg}`);
|
|
3264
|
-
// Track error
|
|
3265
|
-
this.balanceFetchErrors.push({
|
|
3266
|
-
endpoint: 'wallet-provider',
|
|
3267
|
-
error: errorMsg,
|
|
3268
|
-
timestamp: Date.now()
|
|
3269
|
-
});
|
|
3270
|
-
// Keep only last 10 errors
|
|
3271
|
-
if (this.balanceFetchErrors.length > 10) {
|
|
3272
|
-
this.balanceFetchErrors = this.balanceFetchErrors.slice(-10);
|
|
3273
|
-
}
|
|
3274
|
-
throw error;
|
|
3275
|
-
}
|
|
3160
|
+
let provider = this.getProvider();
|
|
3161
|
+
// If provider is missing or not a valid ethers.js provider, use a public BSC provider
|
|
3162
|
+
if (!provider || typeof provider.call !== 'function') {
|
|
3163
|
+
provider = new ethers.JsonRpcProvider('https://bsc.publicnode.com', 56);
|
|
3164
|
+
}
|
|
3165
|
+
const erc20Abi = ["function balanceOf(address) view returns (uint256)"];
|
|
3166
|
+
const contract = new ethers.Contract(TWC_CONTRACT, erc20Abi, provider);
|
|
3167
|
+
const rawBalance = await contract.balanceOf(accountAddress);
|
|
3168
|
+
const balance = ethers.formatUnits(rawBalance, TWC_DECIMALS);
|
|
3169
|
+
const usdValue = await priceService.calculateTWCValue(balance);
|
|
3170
|
+
return {
|
|
3171
|
+
amount: balance,
|
|
3172
|
+
symbol: TWC_SYMBOL,
|
|
3173
|
+
usdValue,
|
|
3174
|
+
usdFormatted: priceService.formatUSDValue(usdValue)
|
|
3175
|
+
};
|
|
3276
3176
|
}
|
|
3277
3177
|
/**
|
|
3278
3178
|
* Get balance fetch error history (for debugging)
|
|
@@ -3534,73 +3434,6 @@ class WalletConnector {
|
|
|
3534
3434
|
return [];
|
|
3535
3435
|
}
|
|
3536
3436
|
}
|
|
3537
|
-
/**
|
|
3538
|
-
* Query TON API for NFTs owned by an address in a specific collection
|
|
3539
|
-
*/
|
|
3540
|
-
async queryTONNFTs(ownerAddress, collectionAddress) {
|
|
3541
|
-
// TON API endpoints to try
|
|
3542
|
-
const endpoints = [
|
|
3543
|
-
'https://tonapi.io/v1',
|
|
3544
|
-
'https://testnet.tonapi.io/v1'
|
|
3545
|
-
];
|
|
3546
|
-
for (const baseUrl of endpoints) {
|
|
3547
|
-
try {
|
|
3548
|
-
// First, get NFT items for the collection
|
|
3549
|
-
const collectionResponse = await fetch(`${baseUrl}/nft/getItems?collection=${collectionAddress}&limit=1000`, {
|
|
3550
|
-
method: 'GET',
|
|
3551
|
-
headers: {
|
|
3552
|
-
'Accept': 'application/json'
|
|
3553
|
-
}
|
|
3554
|
-
});
|
|
3555
|
-
if (!collectionResponse.ok) {
|
|
3556
|
-
continue; // Try next endpoint
|
|
3557
|
-
}
|
|
3558
|
-
const collectionData = await collectionResponse.json();
|
|
3559
|
-
const nftItems = collectionData.nft_items || [];
|
|
3560
|
-
// Filter NFTs owned by the specified address
|
|
3561
|
-
const ownedNFTs = [];
|
|
3562
|
-
for (const nft of nftItems) {
|
|
3563
|
-
if (nft.owner?.address === ownerAddress) {
|
|
3564
|
-
ownedNFTs.push({
|
|
3565
|
-
collection: collectionAddress,
|
|
3566
|
-
nftAddress: nft.address,
|
|
3567
|
-
name: nft.metadata?.name,
|
|
3568
|
-
description: nft.metadata?.description
|
|
3569
|
-
});
|
|
3570
|
-
}
|
|
3571
|
-
}
|
|
3572
|
-
return ownedNFTs;
|
|
3573
|
-
}
|
|
3574
|
-
catch (error) {
|
|
3575
|
-
this.debugTools.warn('WALLET_CONNECTOR', `TON API call failed for ${baseUrl}`, error);
|
|
3576
|
-
continue; // Try next endpoint
|
|
3577
|
-
}
|
|
3578
|
-
}
|
|
3579
|
-
// If all endpoints fail, try a simpler approach using getAccountNftItems
|
|
3580
|
-
try {
|
|
3581
|
-
const accountResponse = await fetch(`${endpoints[0]}/account/getNftItems?account=${ownerAddress}&collection=${collectionAddress}&limit=100`, {
|
|
3582
|
-
method: 'GET',
|
|
3583
|
-
headers: {
|
|
3584
|
-
'Accept': 'application/json'
|
|
3585
|
-
}
|
|
3586
|
-
});
|
|
3587
|
-
if (accountResponse.ok) {
|
|
3588
|
-
const accountData = await accountResponse.json();
|
|
3589
|
-
const nftItems = accountData.nft_items || [];
|
|
3590
|
-
return nftItems.map((nft) => ({
|
|
3591
|
-
collection: collectionAddress,
|
|
3592
|
-
nftAddress: nft.address,
|
|
3593
|
-
name: nft.metadata?.name,
|
|
3594
|
-
description: nft.metadata?.description
|
|
3595
|
-
}));
|
|
3596
|
-
}
|
|
3597
|
-
}
|
|
3598
|
-
catch (error) {
|
|
3599
|
-
this.debugTools.warn('WALLET_CONNECTOR', 'Fallback NFT query also failed', error);
|
|
3600
|
-
}
|
|
3601
|
-
// Return empty array if all queries fail
|
|
3602
|
-
return [];
|
|
3603
|
-
}
|
|
3604
3437
|
}
|
|
3605
3438
|
|
|
3606
3439
|
/**
|
|
@@ -7651,8 +7484,41 @@ function showDebugLog(msg) {
|
|
|
7651
7484
|
const tonApiCache = new Map();
|
|
7652
7485
|
const CACHE_DURATION = 30000; // 30 seconds
|
|
7653
7486
|
const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className, style, showBalance = false, modalPosition = 'center', theme = 'auto', buttonText = 'Connect Wallet', getExplorerUrl, }) => {
|
|
7487
|
+
// Move all state hooks that are referenced early to the top to avoid use-before-init errors
|
|
7488
|
+
const [isInitializing, setIsInitializing] = useState(true);
|
|
7489
|
+
const [isConnecting, setIsConnecting] = useState(false);
|
|
7490
|
+
const [balanceLoading, setBalanceLoading] = useState(false);
|
|
7654
7491
|
// Always fetch balance automatically when wallet is connected
|
|
7655
7492
|
// Balance is always fetched automatically from the chain
|
|
7493
|
+
// Helper: get the best available TWC balance (cached or real)
|
|
7494
|
+
const getDisplayBalance = () => {
|
|
7495
|
+
// Prefer real fetched balance if available and non-zero
|
|
7496
|
+
if (twcBalance && twcBalance !== '0' && twcBalance !== '0.00')
|
|
7497
|
+
return twcBalance;
|
|
7498
|
+
// Fallback to cached balance if available and non-zero
|
|
7499
|
+
if (account?.address) {
|
|
7500
|
+
const cached = loadTWCBalanceFromCache(account.address);
|
|
7501
|
+
if (cached?.balance && cached.balance !== '0' && cached.balance !== '0.00')
|
|
7502
|
+
return cached.balance;
|
|
7503
|
+
}
|
|
7504
|
+
// If loading, keep showing last known value (even if zero)
|
|
7505
|
+
if (isInitializing || isConnecting) {
|
|
7506
|
+
if (twcBalance)
|
|
7507
|
+
return twcBalance;
|
|
7508
|
+
if (account?.address) {
|
|
7509
|
+
const cached = loadTWCBalanceFromCache(account.address);
|
|
7510
|
+
if (cached?.balance)
|
|
7511
|
+
return cached.balance;
|
|
7512
|
+
}
|
|
7513
|
+
}
|
|
7514
|
+
// Otherwise, show 0
|
|
7515
|
+
return '0';
|
|
7516
|
+
};
|
|
7517
|
+
// ...existing code...
|
|
7518
|
+
// ...existing code...
|
|
7519
|
+
// Helper: show spinner if loading/connecting
|
|
7520
|
+
// Show spinner if initializing, connecting, or balance is loading
|
|
7521
|
+
const showSpinner = Boolean(isInitializing || isConnecting || balanceLoading);
|
|
7656
7522
|
// Detect dark mode
|
|
7657
7523
|
const [isDarkMode, setIsDarkMode] = useState(false);
|
|
7658
7524
|
useEffect(() => {
|
|
@@ -7670,7 +7536,6 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
7670
7536
|
}, [theme]);
|
|
7671
7537
|
const [account, setAccount] = useState(null);
|
|
7672
7538
|
const [status, setStatus] = useState(ConnectionStatus.DISCONNECTED);
|
|
7673
|
-
const [isInitializing, setIsInitializing] = useState(true);
|
|
7674
7539
|
const [showModal, setShowModal] = useState(false);
|
|
7675
7540
|
// Preload Reown SDK when modal opens for faster connection
|
|
7676
7541
|
React.useEffect(() => {
|
|
@@ -7692,7 +7557,6 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
7692
7557
|
const [showActivityModal, setShowActivityModal] = useState(false);
|
|
7693
7558
|
const [showTWCBalanceModal, setShowTWCBalanceModal] = useState(false);
|
|
7694
7559
|
const [availableWallets, setAvailableWallets] = useState([]);
|
|
7695
|
-
const [isConnecting, setIsConnecting] = useState(false);
|
|
7696
7560
|
const [error, setError] = useState(null);
|
|
7697
7561
|
const [nftCount, setNftCount] = useState(0);
|
|
7698
7562
|
const [nftLoading, setNftLoading] = useState(false);
|
|
@@ -7703,7 +7567,6 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
7703
7567
|
const [txsLoading, setTxsLoading] = useState(false);
|
|
7704
7568
|
const [txsError, setTxsError] = useState(null);
|
|
7705
7569
|
const [balance, setBalance] = useState({ amount: '', symbol: '' });
|
|
7706
|
-
const [balanceLoading, setBalanceLoading] = useState(false);
|
|
7707
7570
|
const [currentChainId, setCurrentChainId] = useState(null);
|
|
7708
7571
|
const [isWrongNetwork, setIsWrongNetwork] = useState(false);
|
|
7709
7572
|
// TWC Balance cache key prefix
|
|
@@ -8531,10 +8394,13 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8531
8394
|
// Fetch TWC balance for all EVM chains (for debugging)
|
|
8532
8395
|
try {
|
|
8533
8396
|
const state = connector.getState();
|
|
8534
|
-
if (state.
|
|
8535
|
-
|
|
8397
|
+
if (state.status !== 'connected' ||
|
|
8398
|
+
!state.account ||
|
|
8399
|
+
state.account.chainType !== 'evm') {
|
|
8400
|
+
// Not connected, no account, or not EVM, do not fetch TWC balance
|
|
8536
8401
|
return null;
|
|
8537
8402
|
}
|
|
8403
|
+
// Allow fetching even if chainId is null, as long as account exists and is EVM
|
|
8538
8404
|
// Log chainId for debug
|
|
8539
8405
|
showDebugLog?.(`[fetchTWCBalanceWithRetry] Fetching TWC for chainId=${state.chainId}`);
|
|
8540
8406
|
const twcBalance = await connector.getTWCBalance();
|
|
@@ -8878,8 +8744,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8878
8744
|
}, [connector, account]);
|
|
8879
8745
|
// Render button based on connection status
|
|
8880
8746
|
const renderButton = () => {
|
|
8881
|
-
//
|
|
8882
|
-
if (!
|
|
8747
|
+
// Always show connect button for first-time visitors or when not connected
|
|
8748
|
+
if (!account && status === ConnectionStatus.DISCONNECTED) {
|
|
8883
8749
|
// Wallet icon SVG component
|
|
8884
8750
|
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" })] }));
|
|
8885
8751
|
return (jsxs("button", { onClick: () => handleOpenModal(), style: {
|
|
@@ -9053,34 +8919,75 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
9053
8919
|
}
|
|
9054
8920
|
// Wallet icon SVG component
|
|
9055
8921
|
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" })] }));
|
|
9056
|
-
//
|
|
9057
|
-
|
|
9058
|
-
|
|
9059
|
-
|
|
9060
|
-
|
|
9061
|
-
|
|
9062
|
-
|
|
9063
|
-
|
|
9064
|
-
|
|
9065
|
-
|
|
9066
|
-
|
|
9067
|
-
|
|
9068
|
-
|
|
9069
|
-
|
|
9070
|
-
|
|
9071
|
-
|
|
9072
|
-
|
|
9073
|
-
|
|
9074
|
-
|
|
9075
|
-
|
|
9076
|
-
|
|
9077
|
-
|
|
9078
|
-
|
|
9079
|
-
|
|
9080
|
-
|
|
9081
|
-
|
|
9082
|
-
|
|
9083
|
-
|
|
8922
|
+
// Always show the button, but change content based on connection state
|
|
8923
|
+
const displayBalance = getDisplayBalance();
|
|
8924
|
+
const isConnected = !!account && status === ConnectionStatus.CONNECTED;
|
|
8925
|
+
// Helper for details modal open
|
|
8926
|
+
const handleOpenDetailsModal = () => setShowDetailsModal(true);
|
|
8927
|
+
// Wallet icon for display
|
|
8928
|
+
const walletIcon = account ? getWalletIcon(connector.getState().wallet || '') : jsx("span", { children: "\uD83D\uDCBC" });
|
|
8929
|
+
// Current wallet type
|
|
8930
|
+
const currentWalletType = connector.getState().wallet;
|
|
8931
|
+
return (jsxs(React.Fragment, { children: [jsx("style", { children: `
|
|
8932
|
+
@import url('https://fonts.googleapis.com/css2?family=Lexend:wght@300;400;500;600;700&display=swap');
|
|
8933
|
+
.tiwiflix-scrollbar-hide::-webkit-scrollbar {
|
|
8934
|
+
display: none;
|
|
8935
|
+
}
|
|
8936
|
+
.twc-balance-spinner {
|
|
8937
|
+
display: inline-block;
|
|
8938
|
+
width: 16px;
|
|
8939
|
+
height: 16px;
|
|
8940
|
+
border: 2px solid #FF9814;
|
|
8941
|
+
border-top: 2px solid #fff;
|
|
8942
|
+
border-radius: 50%;
|
|
8943
|
+
animation: spin 0.7s linear infinite;
|
|
8944
|
+
margin-left: 6px;
|
|
8945
|
+
vertical-align: middle;
|
|
8946
|
+
}
|
|
8947
|
+
@keyframes spin {
|
|
8948
|
+
0% { transform: rotate(0deg); }
|
|
8949
|
+
100% { transform: rotate(360deg); }
|
|
8950
|
+
}
|
|
8951
|
+
` }), jsxs("button", { onClick: () => (isConnected ? handleOpenDetailsModal() : handleOpenModal()), style: {
|
|
8952
|
+
display: 'flex',
|
|
8953
|
+
alignItems: 'center',
|
|
8954
|
+
gap: '10px',
|
|
8955
|
+
padding: '12px 12px',
|
|
8956
|
+
borderRadius: '12px',
|
|
8957
|
+
border: 'none',
|
|
8958
|
+
backgroundColor: isConnected ? '#0A0A0A' : '#FF9814',
|
|
8959
|
+
color: isConnected ? '#FF9814' : '#000000',
|
|
8960
|
+
fontWeight: '700',
|
|
8961
|
+
fontSize: '15px',
|
|
8962
|
+
cursor: showSpinner ? 'wait' : 'pointer',
|
|
8963
|
+
transition: 'all 0.15s ease',
|
|
8964
|
+
fontFamily: 'Lexend, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
8965
|
+
boxShadow: isConnected ? '0 2px 8px rgba(10,10,10,0.3)' : '0 2px 8px rgba(255, 152, 20, 0.3)',
|
|
8966
|
+
opacity: showSpinner ? 0.85 : 1,
|
|
8967
|
+
pointerEvents: showSpinner ? 'none' : 'auto',
|
|
8968
|
+
...style,
|
|
8969
|
+
}, className: className, disabled: showSpinner, onMouseEnter: (e) => {
|
|
8970
|
+
if (!isConnected) {
|
|
8971
|
+
e.currentTarget.style.backgroundColor = '#E8870F';
|
|
8972
|
+
e.currentTarget.style.transform = 'translateY(-1px)';
|
|
8973
|
+
e.currentTarget.style.boxShadow = '0 4px 12px rgba(255, 152, 20, 0.4)';
|
|
8974
|
+
}
|
|
8975
|
+
}, onMouseLeave: (e) => {
|
|
8976
|
+
if (!isConnected) {
|
|
8977
|
+
e.currentTarget.style.backgroundColor = '#FF9814';
|
|
8978
|
+
e.currentTarget.style.transform = 'translateY(0)';
|
|
8979
|
+
e.currentTarget.style.boxShadow = '0 2px 8px rgba(255, 152, 20, 0.3)';
|
|
8980
|
+
}
|
|
8981
|
+
}, children: [jsx("span", { style: { color: isConnected ? '#FF9814' : '#000000', display: 'flex', alignItems: 'center' }, children: jsx(WalletIcon, {}) }), jsx("span", { style: { color: isConnected ? '#FF9814' : '#000000', fontWeight: '500', fontSize: '14px' }, children: isConnected ? (jsxs(Fragment, { children: [twcIconMemoized, jsx("span", { style: { marginLeft: 6, fontWeight: 600, fontFamily: 'SF Mono, Monaco, Inconsolata, Roboto Mono, monospace' }, children: displayBalance }), showSpinner && jsx("span", { className: "twc-balance-spinner" })] })) : (jsxs(Fragment, { children: [buttonText, showSpinner && jsx("span", { className: "twc-balance-spinner" })] })) })] }), jsx(AccountDetailsModal, { isOpen: showDetailsModal, onClose: () => setShowDetailsModal(false), account: account, onDisconnect: handleDisconnect, onCopyAddress: handleCopyAddress, onOpenSwap: () => setShowSwapModal(true), onOpenSend: () => setShowSendModal(true), onOpenActivity: () => setShowActivityModal(true), balance: balance, balanceLoading: balanceLoading, twcBalance: twcBalance, usdValue: usdValue, nftCount: nftCount, nftLoading: nftLoading, tonBalance: balance.amount || tonBalance, tonUsdValue: balance.usdValue ?? tonUsdValue, walletIcon: walletIcon, colors: colors, isDarkMode: isDarkMode, modalPosition: modalPosition,
|
|
8982
|
+
// Add a Switch Wallet button to allow explicit wallet switching
|
|
8983
|
+
onSwitchWallet: () => handleOpenModal(true) }), jsx(ActivityModal, { isOpen: showActivityModal, onClose: () => setShowActivityModal(false), transactions: txs, loading: txsLoading, error: txsError, colors: colors, isDarkMode: isDarkMode, modalPosition: modalPosition }), jsx(SwapModal, { isOpen: showSwapModal && account?.chainType !== 'ton', onClose: () => setShowSwapModal(false), colors: colors, isDarkMode: isDarkMode, modalPosition: modalPosition }), jsx(SendModal, { isOpen: showSendModal, onClose: () => setShowSendModal(false), balance: balance, colors: colors, isDarkMode: isDarkMode, modalPosition: modalPosition, onSend: async () => {
|
|
8984
|
+
alert('Send functionality coming soon');
|
|
8985
|
+
setShowSendModal(false);
|
|
8986
|
+
} }), jsx(TWCBalanceModal, { isOpen: showTWCBalanceModal, onClose: () => setShowTWCBalanceModal(false), twcBalance: twcBalance, usdValue: usdValue, colors: colors, isDarkMode: isDarkMode, modalPosition: modalPosition, onBuyTWC: () => {
|
|
8987
|
+
// Handle Buy TWC action
|
|
8988
|
+
}, onLearnMore: () => {
|
|
8989
|
+
// Handle Learn More action
|
|
8990
|
+
} }), jsx(WalletSelectModal, { isOpen: showModal, onClose: () => setShowModal(false), onSelectWallet: handleConnect, availableWallets: availableWallets, currentWalletType: currentWalletType, isConnecting: isConnecting, error: error, colors: colors, isDarkMode: isDarkMode, modalPosition: modalPosition })] }));
|
|
9084
8991
|
};
|
|
9085
8992
|
// Group wallets by chain
|
|
9086
8993
|
availableWallets.reduce((acc, wallet) => {
|
package/dist/index.js
CHANGED
|
@@ -1909,7 +1909,7 @@ const defaultMultiChainConfig = {
|
|
|
1909
1909
|
{
|
|
1910
1910
|
chainId: 56,
|
|
1911
1911
|
name: 'BNB Smart Chain',
|
|
1912
|
-
rpcUrl: 'https://bsc
|
|
1912
|
+
rpcUrl: 'https://bsc.publicnode.com',
|
|
1913
1913
|
blockExplorerUrl: 'https://bscscan.com',
|
|
1914
1914
|
nativeCurrency: {
|
|
1915
1915
|
name: 'BNB',
|
|
@@ -2314,6 +2314,7 @@ class WalletConnector {
|
|
|
2314
2314
|
error: null,
|
|
2315
2315
|
twcBalance: null,
|
|
2316
2316
|
usdValue: null,
|
|
2317
|
+
chainId: null,
|
|
2317
2318
|
};
|
|
2318
2319
|
// Performance monitoring
|
|
2319
2320
|
this.performanceMetrics = {
|
|
@@ -2327,8 +2328,6 @@ class WalletConnector {
|
|
|
2327
2328
|
* TWC is ONLY available on BSC (chainId 56)
|
|
2328
2329
|
*/
|
|
2329
2330
|
// Cache for TWC balance to avoid redundant fetches
|
|
2330
|
-
this.twcBalanceCache = null;
|
|
2331
|
-
this.TWC_CACHE_TTL = 30000; // 30 seconds cache
|
|
2332
2331
|
// Error tracking for balance fetching
|
|
2333
2332
|
this.balanceFetchErrors = [];
|
|
2334
2333
|
this.config = config;
|
|
@@ -2427,13 +2426,38 @@ class WalletConnector {
|
|
|
2427
2426
|
* Connect to a wallet
|
|
2428
2427
|
*/
|
|
2429
2428
|
async connect(walletType) {
|
|
2429
|
+
// Only allow EVM wallet connections on BSC (chainId 56)
|
|
2430
|
+
let adapter = this.adapters.get(walletType);
|
|
2431
|
+
if (adapter && adapter.chainType === exports.ChainType.EVM && typeof adapter.getChainId === 'function') {
|
|
2432
|
+
try {
|
|
2433
|
+
const chainId = await adapter.getChainId();
|
|
2434
|
+
if (chainId !== 56) {
|
|
2435
|
+
const error = new Error('Only Binance Smart Chain (BSC) is supported for EVM wallet connections. Please switch your wallet to BSC and try again.');
|
|
2436
|
+
this.updateState({
|
|
2437
|
+
status: exports.ConnectionStatus.ERROR,
|
|
2438
|
+
error,
|
|
2439
|
+
});
|
|
2440
|
+
this.eventEmitter.emit(exports.WalletEvent.ERROR, error);
|
|
2441
|
+
throw error;
|
|
2442
|
+
}
|
|
2443
|
+
}
|
|
2444
|
+
catch (e) {
|
|
2445
|
+
const error = new Error('Failed to detect EVM chain. Please ensure your wallet is connected to BSC.');
|
|
2446
|
+
this.updateState({
|
|
2447
|
+
status: exports.ConnectionStatus.ERROR,
|
|
2448
|
+
error,
|
|
2449
|
+
});
|
|
2450
|
+
this.eventEmitter.emit(exports.WalletEvent.ERROR, error);
|
|
2451
|
+
throw error;
|
|
2452
|
+
}
|
|
2453
|
+
}
|
|
2430
2454
|
// Prevent duplicate connection requests
|
|
2431
2455
|
if (this.state.status === exports.ConnectionStatus.CONNECTING) {
|
|
2432
2456
|
const error = new Error('Connection already in progress. Please wait...');
|
|
2433
2457
|
console.warn('Duplicate connection attempt blocked:', walletType);
|
|
2434
2458
|
throw error;
|
|
2435
2459
|
}
|
|
2436
|
-
|
|
2460
|
+
// adapter already declared above
|
|
2437
2461
|
if (!adapter) {
|
|
2438
2462
|
const error = new Error(`Wallet ${walletType} is not registered`);
|
|
2439
2463
|
this.updateState({
|
|
@@ -2670,7 +2694,7 @@ class WalletConnector {
|
|
|
2670
2694
|
clearTimeout(safetyTimeout);
|
|
2671
2695
|
clearTimeout(connectionTimeout);
|
|
2672
2696
|
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
|
2673
|
-
|
|
2697
|
+
// removed unused errorMsg
|
|
2674
2698
|
this.debugTools.error('WALLET_CONNECTOR', 'Connection error caught', error);
|
|
2675
2699
|
// Reset state on connection error
|
|
2676
2700
|
this.updateState({
|
|
@@ -2752,7 +2776,7 @@ class WalletConnector {
|
|
|
2752
2776
|
}
|
|
2753
2777
|
else {
|
|
2754
2778
|
// Connection failed - reset state properly
|
|
2755
|
-
|
|
2779
|
+
// removed unused errorMsg
|
|
2756
2780
|
this.debugTools.error('WALLET_CONNECTOR', 'Connection failed', result.error);
|
|
2757
2781
|
this.updateState({
|
|
2758
2782
|
status: exports.ConnectionStatus.DISCONNECTED,
|
|
@@ -3128,153 +3152,29 @@ class WalletConnector {
|
|
|
3128
3152
|
this.sdkLoader.clearCache();
|
|
3129
3153
|
}
|
|
3130
3154
|
async getTWCBalance() {
|
|
3131
|
-
if (!this.state.account) {
|
|
3132
|
-
|
|
3133
|
-
window.showDebugLog?.('[getTWCBalance] No wallet connected');
|
|
3134
|
-
throw new Error('No wallet connected');
|
|
3155
|
+
if (!this.state.account || this.state.account.chainType !== 'evm') {
|
|
3156
|
+
throw new Error('No EVM account connected');
|
|
3135
3157
|
}
|
|
3136
3158
|
const accountAddress = this.state.account.address;
|
|
3137
|
-
const chainId = this.state.chainId;
|
|
3138
|
-
performance.now();
|
|
3139
|
-
if (typeof window !== 'undefined')
|
|
3140
|
-
window.showDebugLog?.(`[getTWCBalance] Called for account=${accountAddress}, chainId=${chainId}`);
|
|
3141
|
-
// Check cache first
|
|
3142
|
-
if (this.twcBalanceCache &&
|
|
3143
|
-
this.twcBalanceCache.address === accountAddress &&
|
|
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)}`);
|
|
3147
|
-
return {
|
|
3148
|
-
amount: this.twcBalanceCache.balance,
|
|
3149
|
-
symbol: 'TWC',
|
|
3150
|
-
usdValue: this.twcBalanceCache.usdValue,
|
|
3151
|
-
usdFormatted: priceService.formatUSDValue(this.twcBalanceCache.usdValue)
|
|
3152
|
-
};
|
|
3153
|
-
}
|
|
3154
|
-
// TWC contract on BSC
|
|
3155
3159
|
const TWC_CONTRACT = '0xDA1060158F7D593667cCE0a15DB346BB3FfB3596';
|
|
3156
3160
|
const TWC_DECIMALS = 9;
|
|
3157
3161
|
const TWC_SYMBOL = 'TWC';
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
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
|
-
}
|
|
3235
|
-
// Calculate USD value with 5 second timeout
|
|
3236
|
-
const usdPromise = priceService.calculateTWCValue(balance);
|
|
3237
|
-
const usdTimeoutPromise = new Promise((resolve) => {
|
|
3238
|
-
setTimeout(() => resolve(0), 5000); // Default to 0 on timeout
|
|
3239
|
-
});
|
|
3240
|
-
const usdValue = await Promise.race([usdPromise, usdTimeoutPromise]);
|
|
3241
|
-
if (typeof window !== 'undefined')
|
|
3242
|
-
window.showDebugLog?.(`[getTWCBalance] USD value for ${accountAddress}: ${usdValue}`);
|
|
3243
|
-
// Update cache
|
|
3244
|
-
this.twcBalanceCache = {
|
|
3245
|
-
balance,
|
|
3246
|
-
usdValue,
|
|
3247
|
-
timestamp: Date.now(),
|
|
3248
|
-
address: accountAddress
|
|
3249
|
-
};
|
|
3250
|
-
const result = {
|
|
3251
|
-
amount: balance,
|
|
3252
|
-
symbol: TWC_SYMBOL,
|
|
3253
|
-
usdValue,
|
|
3254
|
-
usdFormatted: priceService.formatUSDValue(usdValue)
|
|
3255
|
-
};
|
|
3256
|
-
// Keep state in sync
|
|
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)}`);
|
|
3260
|
-
return result;
|
|
3261
|
-
}
|
|
3262
|
-
catch (error) {
|
|
3263
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
3264
|
-
if (typeof window !== 'undefined')
|
|
3265
|
-
window.showDebugLog?.(`[getTWCBalance] ERROR: ${errorMsg}`);
|
|
3266
|
-
// Track error
|
|
3267
|
-
this.balanceFetchErrors.push({
|
|
3268
|
-
endpoint: 'wallet-provider',
|
|
3269
|
-
error: errorMsg,
|
|
3270
|
-
timestamp: Date.now()
|
|
3271
|
-
});
|
|
3272
|
-
// Keep only last 10 errors
|
|
3273
|
-
if (this.balanceFetchErrors.length > 10) {
|
|
3274
|
-
this.balanceFetchErrors = this.balanceFetchErrors.slice(-10);
|
|
3275
|
-
}
|
|
3276
|
-
throw error;
|
|
3277
|
-
}
|
|
3162
|
+
let provider = this.getProvider();
|
|
3163
|
+
// If provider is missing or not a valid ethers.js provider, use a public BSC provider
|
|
3164
|
+
if (!provider || typeof provider.call !== 'function') {
|
|
3165
|
+
provider = new ethers.ethers.JsonRpcProvider('https://bsc.publicnode.com', 56);
|
|
3166
|
+
}
|
|
3167
|
+
const erc20Abi = ["function balanceOf(address) view returns (uint256)"];
|
|
3168
|
+
const contract = new ethers.ethers.Contract(TWC_CONTRACT, erc20Abi, provider);
|
|
3169
|
+
const rawBalance = await contract.balanceOf(accountAddress);
|
|
3170
|
+
const balance = ethers.ethers.formatUnits(rawBalance, TWC_DECIMALS);
|
|
3171
|
+
const usdValue = await priceService.calculateTWCValue(balance);
|
|
3172
|
+
return {
|
|
3173
|
+
amount: balance,
|
|
3174
|
+
symbol: TWC_SYMBOL,
|
|
3175
|
+
usdValue,
|
|
3176
|
+
usdFormatted: priceService.formatUSDValue(usdValue)
|
|
3177
|
+
};
|
|
3278
3178
|
}
|
|
3279
3179
|
/**
|
|
3280
3180
|
* Get balance fetch error history (for debugging)
|
|
@@ -3536,73 +3436,6 @@ class WalletConnector {
|
|
|
3536
3436
|
return [];
|
|
3537
3437
|
}
|
|
3538
3438
|
}
|
|
3539
|
-
/**
|
|
3540
|
-
* Query TON API for NFTs owned by an address in a specific collection
|
|
3541
|
-
*/
|
|
3542
|
-
async queryTONNFTs(ownerAddress, collectionAddress) {
|
|
3543
|
-
// TON API endpoints to try
|
|
3544
|
-
const endpoints = [
|
|
3545
|
-
'https://tonapi.io/v1',
|
|
3546
|
-
'https://testnet.tonapi.io/v1'
|
|
3547
|
-
];
|
|
3548
|
-
for (const baseUrl of endpoints) {
|
|
3549
|
-
try {
|
|
3550
|
-
// First, get NFT items for the collection
|
|
3551
|
-
const collectionResponse = await fetch(`${baseUrl}/nft/getItems?collection=${collectionAddress}&limit=1000`, {
|
|
3552
|
-
method: 'GET',
|
|
3553
|
-
headers: {
|
|
3554
|
-
'Accept': 'application/json'
|
|
3555
|
-
}
|
|
3556
|
-
});
|
|
3557
|
-
if (!collectionResponse.ok) {
|
|
3558
|
-
continue; // Try next endpoint
|
|
3559
|
-
}
|
|
3560
|
-
const collectionData = await collectionResponse.json();
|
|
3561
|
-
const nftItems = collectionData.nft_items || [];
|
|
3562
|
-
// Filter NFTs owned by the specified address
|
|
3563
|
-
const ownedNFTs = [];
|
|
3564
|
-
for (const nft of nftItems) {
|
|
3565
|
-
if (nft.owner?.address === ownerAddress) {
|
|
3566
|
-
ownedNFTs.push({
|
|
3567
|
-
collection: collectionAddress,
|
|
3568
|
-
nftAddress: nft.address,
|
|
3569
|
-
name: nft.metadata?.name,
|
|
3570
|
-
description: nft.metadata?.description
|
|
3571
|
-
});
|
|
3572
|
-
}
|
|
3573
|
-
}
|
|
3574
|
-
return ownedNFTs;
|
|
3575
|
-
}
|
|
3576
|
-
catch (error) {
|
|
3577
|
-
this.debugTools.warn('WALLET_CONNECTOR', `TON API call failed for ${baseUrl}`, error);
|
|
3578
|
-
continue; // Try next endpoint
|
|
3579
|
-
}
|
|
3580
|
-
}
|
|
3581
|
-
// If all endpoints fail, try a simpler approach using getAccountNftItems
|
|
3582
|
-
try {
|
|
3583
|
-
const accountResponse = await fetch(`${endpoints[0]}/account/getNftItems?account=${ownerAddress}&collection=${collectionAddress}&limit=100`, {
|
|
3584
|
-
method: 'GET',
|
|
3585
|
-
headers: {
|
|
3586
|
-
'Accept': 'application/json'
|
|
3587
|
-
}
|
|
3588
|
-
});
|
|
3589
|
-
if (accountResponse.ok) {
|
|
3590
|
-
const accountData = await accountResponse.json();
|
|
3591
|
-
const nftItems = accountData.nft_items || [];
|
|
3592
|
-
return nftItems.map((nft) => ({
|
|
3593
|
-
collection: collectionAddress,
|
|
3594
|
-
nftAddress: nft.address,
|
|
3595
|
-
name: nft.metadata?.name,
|
|
3596
|
-
description: nft.metadata?.description
|
|
3597
|
-
}));
|
|
3598
|
-
}
|
|
3599
|
-
}
|
|
3600
|
-
catch (error) {
|
|
3601
|
-
this.debugTools.warn('WALLET_CONNECTOR', 'Fallback NFT query also failed', error);
|
|
3602
|
-
}
|
|
3603
|
-
// Return empty array if all queries fail
|
|
3604
|
-
return [];
|
|
3605
|
-
}
|
|
3606
3439
|
}
|
|
3607
3440
|
|
|
3608
3441
|
/**
|
|
@@ -7653,8 +7486,41 @@ function showDebugLog(msg) {
|
|
|
7653
7486
|
const tonApiCache = new Map();
|
|
7654
7487
|
const CACHE_DURATION = 30000; // 30 seconds
|
|
7655
7488
|
const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className, style, showBalance = false, modalPosition = 'center', theme = 'auto', buttonText = 'Connect Wallet', getExplorerUrl, }) => {
|
|
7489
|
+
// Move all state hooks that are referenced early to the top to avoid use-before-init errors
|
|
7490
|
+
const [isInitializing, setIsInitializing] = React.useState(true);
|
|
7491
|
+
const [isConnecting, setIsConnecting] = React.useState(false);
|
|
7492
|
+
const [balanceLoading, setBalanceLoading] = React.useState(false);
|
|
7656
7493
|
// Always fetch balance automatically when wallet is connected
|
|
7657
7494
|
// Balance is always fetched automatically from the chain
|
|
7495
|
+
// Helper: get the best available TWC balance (cached or real)
|
|
7496
|
+
const getDisplayBalance = () => {
|
|
7497
|
+
// Prefer real fetched balance if available and non-zero
|
|
7498
|
+
if (twcBalance && twcBalance !== '0' && twcBalance !== '0.00')
|
|
7499
|
+
return twcBalance;
|
|
7500
|
+
// Fallback to cached balance if available and non-zero
|
|
7501
|
+
if (account?.address) {
|
|
7502
|
+
const cached = loadTWCBalanceFromCache(account.address);
|
|
7503
|
+
if (cached?.balance && cached.balance !== '0' && cached.balance !== '0.00')
|
|
7504
|
+
return cached.balance;
|
|
7505
|
+
}
|
|
7506
|
+
// If loading, keep showing last known value (even if zero)
|
|
7507
|
+
if (isInitializing || isConnecting) {
|
|
7508
|
+
if (twcBalance)
|
|
7509
|
+
return twcBalance;
|
|
7510
|
+
if (account?.address) {
|
|
7511
|
+
const cached = loadTWCBalanceFromCache(account.address);
|
|
7512
|
+
if (cached?.balance)
|
|
7513
|
+
return cached.balance;
|
|
7514
|
+
}
|
|
7515
|
+
}
|
|
7516
|
+
// Otherwise, show 0
|
|
7517
|
+
return '0';
|
|
7518
|
+
};
|
|
7519
|
+
// ...existing code...
|
|
7520
|
+
// ...existing code...
|
|
7521
|
+
// Helper: show spinner if loading/connecting
|
|
7522
|
+
// Show spinner if initializing, connecting, or balance is loading
|
|
7523
|
+
const showSpinner = Boolean(isInitializing || isConnecting || balanceLoading);
|
|
7658
7524
|
// Detect dark mode
|
|
7659
7525
|
const [isDarkMode, setIsDarkMode] = React.useState(false);
|
|
7660
7526
|
React.useEffect(() => {
|
|
@@ -7672,7 +7538,6 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
7672
7538
|
}, [theme]);
|
|
7673
7539
|
const [account, setAccount] = React.useState(null);
|
|
7674
7540
|
const [status, setStatus] = React.useState(exports.ConnectionStatus.DISCONNECTED);
|
|
7675
|
-
const [isInitializing, setIsInitializing] = React.useState(true);
|
|
7676
7541
|
const [showModal, setShowModal] = React.useState(false);
|
|
7677
7542
|
// Preload Reown SDK when modal opens for faster connection
|
|
7678
7543
|
React.useEffect(() => {
|
|
@@ -7694,7 +7559,6 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
7694
7559
|
const [showActivityModal, setShowActivityModal] = React.useState(false);
|
|
7695
7560
|
const [showTWCBalanceModal, setShowTWCBalanceModal] = React.useState(false);
|
|
7696
7561
|
const [availableWallets, setAvailableWallets] = React.useState([]);
|
|
7697
|
-
const [isConnecting, setIsConnecting] = React.useState(false);
|
|
7698
7562
|
const [error, setError] = React.useState(null);
|
|
7699
7563
|
const [nftCount, setNftCount] = React.useState(0);
|
|
7700
7564
|
const [nftLoading, setNftLoading] = React.useState(false);
|
|
@@ -7705,7 +7569,6 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
7705
7569
|
const [txsLoading, setTxsLoading] = React.useState(false);
|
|
7706
7570
|
const [txsError, setTxsError] = React.useState(null);
|
|
7707
7571
|
const [balance, setBalance] = React.useState({ amount: '', symbol: '' });
|
|
7708
|
-
const [balanceLoading, setBalanceLoading] = React.useState(false);
|
|
7709
7572
|
const [currentChainId, setCurrentChainId] = React.useState(null);
|
|
7710
7573
|
const [isWrongNetwork, setIsWrongNetwork] = React.useState(false);
|
|
7711
7574
|
// TWC Balance cache key prefix
|
|
@@ -8533,10 +8396,13 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8533
8396
|
// Fetch TWC balance for all EVM chains (for debugging)
|
|
8534
8397
|
try {
|
|
8535
8398
|
const state = connector.getState();
|
|
8536
|
-
if (state.
|
|
8537
|
-
|
|
8399
|
+
if (state.status !== 'connected' ||
|
|
8400
|
+
!state.account ||
|
|
8401
|
+
state.account.chainType !== 'evm') {
|
|
8402
|
+
// Not connected, no account, or not EVM, do not fetch TWC balance
|
|
8538
8403
|
return null;
|
|
8539
8404
|
}
|
|
8405
|
+
// Allow fetching even if chainId is null, as long as account exists and is EVM
|
|
8540
8406
|
// Log chainId for debug
|
|
8541
8407
|
showDebugLog?.(`[fetchTWCBalanceWithRetry] Fetching TWC for chainId=${state.chainId}`);
|
|
8542
8408
|
const twcBalance = await connector.getTWCBalance();
|
|
@@ -8880,8 +8746,8 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
8880
8746
|
}, [connector, account]);
|
|
8881
8747
|
// Render button based on connection status
|
|
8882
8748
|
const renderButton = () => {
|
|
8883
|
-
//
|
|
8884
|
-
if (!
|
|
8749
|
+
// Always show connect button for first-time visitors or when not connected
|
|
8750
|
+
if (!account && status === exports.ConnectionStatus.DISCONNECTED) {
|
|
8885
8751
|
// Wallet icon SVG component
|
|
8886
8752
|
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" })] }));
|
|
8887
8753
|
return (jsxRuntime.jsxs("button", { onClick: () => handleOpenModal(), style: {
|
|
@@ -9055,34 +8921,75 @@ const ConnectButton = ({ connector, onConnect, onDisconnect, onError, className,
|
|
|
9055
8921
|
}
|
|
9056
8922
|
// Wallet icon SVG component
|
|
9057
8923
|
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" })] }));
|
|
9058
|
-
//
|
|
9059
|
-
|
|
9060
|
-
|
|
9061
|
-
|
|
9062
|
-
|
|
9063
|
-
|
|
9064
|
-
|
|
9065
|
-
|
|
9066
|
-
|
|
9067
|
-
|
|
9068
|
-
|
|
9069
|
-
|
|
9070
|
-
|
|
9071
|
-
|
|
9072
|
-
|
|
9073
|
-
|
|
9074
|
-
|
|
9075
|
-
|
|
9076
|
-
|
|
9077
|
-
|
|
9078
|
-
|
|
9079
|
-
|
|
9080
|
-
|
|
9081
|
-
|
|
9082
|
-
|
|
9083
|
-
|
|
9084
|
-
|
|
9085
|
-
|
|
8924
|
+
// Always show the button, but change content based on connection state
|
|
8925
|
+
const displayBalance = getDisplayBalance();
|
|
8926
|
+
const isConnected = !!account && status === exports.ConnectionStatus.CONNECTED;
|
|
8927
|
+
// Helper for details modal open
|
|
8928
|
+
const handleOpenDetailsModal = () => setShowDetailsModal(true);
|
|
8929
|
+
// Wallet icon for display
|
|
8930
|
+
const walletIcon = account ? getWalletIcon(connector.getState().wallet || '') : jsxRuntime.jsx("span", { children: "\uD83D\uDCBC" });
|
|
8931
|
+
// Current wallet type
|
|
8932
|
+
const currentWalletType = connector.getState().wallet;
|
|
8933
|
+
return (jsxRuntime.jsxs(React.Fragment, { children: [jsxRuntime.jsx("style", { children: `
|
|
8934
|
+
@import url('https://fonts.googleapis.com/css2?family=Lexend:wght@300;400;500;600;700&display=swap');
|
|
8935
|
+
.tiwiflix-scrollbar-hide::-webkit-scrollbar {
|
|
8936
|
+
display: none;
|
|
8937
|
+
}
|
|
8938
|
+
.twc-balance-spinner {
|
|
8939
|
+
display: inline-block;
|
|
8940
|
+
width: 16px;
|
|
8941
|
+
height: 16px;
|
|
8942
|
+
border: 2px solid #FF9814;
|
|
8943
|
+
border-top: 2px solid #fff;
|
|
8944
|
+
border-radius: 50%;
|
|
8945
|
+
animation: spin 0.7s linear infinite;
|
|
8946
|
+
margin-left: 6px;
|
|
8947
|
+
vertical-align: middle;
|
|
8948
|
+
}
|
|
8949
|
+
@keyframes spin {
|
|
8950
|
+
0% { transform: rotate(0deg); }
|
|
8951
|
+
100% { transform: rotate(360deg); }
|
|
8952
|
+
}
|
|
8953
|
+
` }), jsxRuntime.jsxs("button", { onClick: () => (isConnected ? handleOpenDetailsModal() : handleOpenModal()), style: {
|
|
8954
|
+
display: 'flex',
|
|
8955
|
+
alignItems: 'center',
|
|
8956
|
+
gap: '10px',
|
|
8957
|
+
padding: '12px 12px',
|
|
8958
|
+
borderRadius: '12px',
|
|
8959
|
+
border: 'none',
|
|
8960
|
+
backgroundColor: isConnected ? '#0A0A0A' : '#FF9814',
|
|
8961
|
+
color: isConnected ? '#FF9814' : '#000000',
|
|
8962
|
+
fontWeight: '700',
|
|
8963
|
+
fontSize: '15px',
|
|
8964
|
+
cursor: showSpinner ? 'wait' : 'pointer',
|
|
8965
|
+
transition: 'all 0.15s ease',
|
|
8966
|
+
fontFamily: 'Lexend, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
8967
|
+
boxShadow: isConnected ? '0 2px 8px rgba(10,10,10,0.3)' : '0 2px 8px rgba(255, 152, 20, 0.3)',
|
|
8968
|
+
opacity: showSpinner ? 0.85 : 1,
|
|
8969
|
+
pointerEvents: showSpinner ? 'none' : 'auto',
|
|
8970
|
+
...style,
|
|
8971
|
+
}, className: className, disabled: showSpinner, onMouseEnter: (e) => {
|
|
8972
|
+
if (!isConnected) {
|
|
8973
|
+
e.currentTarget.style.backgroundColor = '#E8870F';
|
|
8974
|
+
e.currentTarget.style.transform = 'translateY(-1px)';
|
|
8975
|
+
e.currentTarget.style.boxShadow = '0 4px 12px rgba(255, 152, 20, 0.4)';
|
|
8976
|
+
}
|
|
8977
|
+
}, onMouseLeave: (e) => {
|
|
8978
|
+
if (!isConnected) {
|
|
8979
|
+
e.currentTarget.style.backgroundColor = '#FF9814';
|
|
8980
|
+
e.currentTarget.style.transform = 'translateY(0)';
|
|
8981
|
+
e.currentTarget.style.boxShadow = '0 2px 8px rgba(255, 152, 20, 0.3)';
|
|
8982
|
+
}
|
|
8983
|
+
}, children: [jsxRuntime.jsx("span", { style: { color: isConnected ? '#FF9814' : '#000000', display: 'flex', alignItems: 'center' }, children: jsxRuntime.jsx(WalletIcon, {}) }), jsxRuntime.jsx("span", { style: { color: isConnected ? '#FF9814' : '#000000', fontWeight: '500', fontSize: '14px' }, children: isConnected ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [twcIconMemoized, jsxRuntime.jsx("span", { style: { marginLeft: 6, fontWeight: 600, fontFamily: 'SF Mono, Monaco, Inconsolata, Roboto Mono, monospace' }, children: displayBalance }), showSpinner && jsxRuntime.jsx("span", { className: "twc-balance-spinner" })] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [buttonText, showSpinner && jsxRuntime.jsx("span", { className: "twc-balance-spinner" })] })) })] }), jsxRuntime.jsx(AccountDetailsModal, { isOpen: showDetailsModal, onClose: () => setShowDetailsModal(false), account: account, onDisconnect: handleDisconnect, onCopyAddress: handleCopyAddress, onOpenSwap: () => setShowSwapModal(true), onOpenSend: () => setShowSendModal(true), onOpenActivity: () => setShowActivityModal(true), balance: balance, balanceLoading: balanceLoading, twcBalance: twcBalance, usdValue: usdValue, nftCount: nftCount, nftLoading: nftLoading, tonBalance: balance.amount || tonBalance, tonUsdValue: balance.usdValue ?? tonUsdValue, walletIcon: walletIcon, colors: colors, isDarkMode: isDarkMode, modalPosition: modalPosition,
|
|
8984
|
+
// Add a Switch Wallet button to allow explicit wallet switching
|
|
8985
|
+
onSwitchWallet: () => handleOpenModal(true) }), jsxRuntime.jsx(ActivityModal, { isOpen: showActivityModal, onClose: () => setShowActivityModal(false), transactions: txs, loading: txsLoading, error: txsError, colors: colors, isDarkMode: isDarkMode, modalPosition: modalPosition }), jsxRuntime.jsx(SwapModal, { isOpen: showSwapModal && account?.chainType !== 'ton', onClose: () => setShowSwapModal(false), colors: colors, isDarkMode: isDarkMode, modalPosition: modalPosition }), jsxRuntime.jsx(SendModal, { isOpen: showSendModal, onClose: () => setShowSendModal(false), balance: balance, colors: colors, isDarkMode: isDarkMode, modalPosition: modalPosition, onSend: async () => {
|
|
8986
|
+
alert('Send functionality coming soon');
|
|
8987
|
+
setShowSendModal(false);
|
|
8988
|
+
} }), jsxRuntime.jsx(TWCBalanceModal, { isOpen: showTWCBalanceModal, onClose: () => setShowTWCBalanceModal(false), twcBalance: twcBalance, usdValue: usdValue, colors: colors, isDarkMode: isDarkMode, modalPosition: modalPosition, onBuyTWC: () => {
|
|
8989
|
+
// Handle Buy TWC action
|
|
8990
|
+
}, onLearnMore: () => {
|
|
8991
|
+
// Handle Learn More action
|
|
8992
|
+
} }), jsxRuntime.jsx(WalletSelectModal, { isOpen: showModal, onClose: () => setShowModal(false), onSelectWallet: handleConnect, availableWallets: availableWallets, currentWalletType: currentWalletType, isConnecting: isConnecting, error: error, colors: colors, isDarkMode: isDarkMode, modalPosition: modalPosition })] }));
|
|
9086
8993
|
};
|
|
9087
8994
|
// Group wallets by chain
|
|
9088
8995
|
availableWallets.reduce((acc, wallet) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tiwiflix-wallet-connector",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.9",
|
|
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",
|