tiwiflix-wallet-connector
v1.7.18
Published
Multi-chain wallet connector for Tiwiflix supporting EVM, TON, Solana, and Tron wallets
Maintainers
Readme
@tiwiflix/wallet-connector
A comprehensive multi-chain wallet connector for Tiwiflix, supporting EVM, Solana, TON, and Tron wallets with a unified API.
Features
- 🌐 Multi-Chain Support: EVM, Solana, TON, and Tron
- 🔌 16 Wallet Integrations: MetaMask, Trust Wallet, Bitget, Base, Phantom, Solflare, Tonkeeper, TronLink, and more
- 🎯 Unified API: Single interface for all wallet interactions
- 🔄 Auto-Connect: Automatically reconnect to previously used wallet
- 📦 TypeScript: Full TypeScript support with type definitions
- 🎨 Flexible: Easy to add custom wallet adapters
- ⚡ Lightweight: Optional peer dependencies for unused chains
- 🖼️ NFT Checking: Verify NFT ownership for TON wallets
Supported Wallets
EVM Wallets
- MetaMask
- Trust Wallet
- Bitget Wallet
- Base Wallet (formerly Coinbase Wallet)
- Atomic Wallet
- SafePal
- Rabby
- Exodus
- WalletConnect
Solana Wallets
- Solflare
- Phantom
TON Wallets
- Tonkeeper
- Ton Hub
- MyTonWallet
Tron Wallets
- TronLink
- Klever
Installation
npm install @tiwiflix/wallet-connectorPeer Dependencies
Install only the dependencies for the chains you need:
# For EVM wallets
npm install ethers
# For WalletConnect
npm install @walletconnect/ethereum-provider
# For Solana wallets
npm install @solana/web3.js @solana/wallet-adapter-base
# For TON wallets
npm install @tonconnect/ui
# All chains
npm install ethers @walletconnect/ethereum-provider @solana/web3.js @solana/wallet-adapter-base @tonconnect/uiQuick Start
Basic Usage
import {
WalletConnector,
MetamaskAdapter,
TrustWalletAdapter,
PhantomAdapter,
TonkeeperAdapter,
WalletType
} from '@tiwiflix/wallet-connector';
// Initialize connector with desired wallets
const connector = new WalletConnector({
adapters: [
new MetamaskAdapter(),
new TrustWalletAdapter(),
new PhantomAdapter(),
new TonkeeperAdapter(),
],
autoConnect: true, // Auto-connect to previously connected wallet
storageKey: 'tiwiflix_wallet', // Custom storage key
});
// Get available wallets (installed)
const availableWallets = connector.getAvailableWallets();
console.log('Available wallets:', availableWallets);
// Connect to a wallet
try {
await connector.connect(WalletType.METAMASK);
console.log('Connected!');
} catch (error) {
console.error('Connection failed:', error);
}
// Get current account
const account = await connector.getAccount();
console.log('Account:', account);
// Sign a message
const signature = await connector.signMessage('Hello, Tiwiflix!');
console.log('Signature:', signature);
// Disconnect
await connector.disconnect();React Example
import { useState, useEffect } from 'react';
import {
WalletConnector,
MetamaskAdapter,
PhantomAdapter,
TonkeeperAdapter,
WalletType,
WalletEvent,
Account
} from '@tiwiflix/wallet-connector';
// Initialize connector once
const connector = new WalletConnector({
adapters: [
new MetamaskAdapter(),
new PhantomAdapter(),
new TonkeeperAdapter(),
],
autoConnect: true,
});
function WalletButton() {
const [account, setAccount] = useState<Account | null>(null);
const [isConnecting, setIsConnecting] = useState(false);
useEffect(() => {
// Subscribe to account changes
const unsubscribe = connector.on(WalletEvent.ACCOUNT_CHANGED, (acc) => {
setAccount(acc);
});
// Get initial account
connector.getAccount().then(setAccount);
return () => unsubscribe();
}, []);
const handleConnect = async (walletType: WalletType) => {
setIsConnecting(true);
try {
await connector.connect(walletType);
} catch (error) {
console.error('Connection failed:', error);
} finally {
setIsConnecting(false);
}
};
const handleDisconnect = async () => {
await connector.disconnect();
};
if (account) {
return (
<div>
<p>Connected: {account.address.slice(0, 6)}...{account.address.slice(-4)}</p>
<button onClick={handleDisconnect}>Disconnect</button>
</div>
);
}
return (
<div>
<h3>Select Wallet</h3>
{connector.getAvailableWallets().map((wallet) => (
<button
key={wallet.type}
onClick={() => handleConnect(wallet.type)}
disabled={isConnecting}
>
{wallet.name}
</button>
))}
</div>
);
}WalletConnect Example
WalletConnect requires a project ID from WalletConnect Cloud.
import {
WalletConnector,
WalletConnectAdapter,
MetamaskAdapter,
WalletType
} from '@tiwiflix/wallet-connector';
const connector = new WalletConnector({
adapters: [
new MetamaskAdapter(),
new WalletConnectAdapter('YOUR_PROJECT_ID'), // Get from WalletConnect Cloud
],
walletConnectProjectId: 'YOUR_PROJECT_ID',
});
// Connect via WalletConnect (shows QR code modal)
await connector.connect(WalletType.WALLETCONNECT);All Wallets Example
import {
WalletConnector,
// EVM
MetamaskAdapter,
TrustWalletAdapter,
BitgetAdapter,
BaseAdapter,
AtomicAdapter,
SafePalAdapter,
RabbyAdapter,
ExodusAdapter,
WalletConnectAdapter,
// Solana
PhantomAdapter,
SolflareAdapter,
// TON
TonkeeperAdapter,
TonHubAdapter,
MyTonWalletAdapter,
// Tron
TronLinkAdapter,
KleverAdapter,
} from '@tiwiflix/wallet-connector';
const connector = new WalletConnector({
adapters: [
// EVM wallets
new MetamaskAdapter(),
new TrustWalletAdapter(),
new BitgetAdapter(),
new BaseAdapter(),
new AtomicAdapter(),
new SafePalAdapter(),
new RabbyAdapter(),
new ExodusAdapter(),
new WalletConnectAdapter('YOUR_WALLETCONNECT_PROJECT_ID'),
// Solana wallets
new PhantomAdapter(),
new SolflareAdapter(),
// TON wallets
new TonkeeperAdapter(),
new TonHubAdapter(),
new MyTonWalletAdapter(),
// Tron wallets
new TronLinkAdapter(),
new KleverAdapter(),
],
autoConnect: true,
});API Reference
WalletConnector
Constructor
new WalletConnector(config: WalletConnectorConfig)Config Options:
adapters: Array of wallet adapters to useautoConnect?: Auto-connect to previously connected wallet (default: false)storageKey?: Local storage key for persistence (default: 'tiwiflix_wallet')walletConnectProjectId?: WalletConnect project ID (required for WalletConnect)
Methods
getAvailableWallets(): Get list of installed/available walletsgetAllWallets(): Get list of all registered walletsgetWallet(type: WalletType): Get specific wallet adapterconnect(walletType: WalletType): Connect to a walletdisconnect(): Disconnect from current walletgetAccount(): Get current accountsignMessage(message: string): Sign a messagesignTransaction(transaction: any): Sign a transactioncheckNFTOwnership(collectionAddresses: string[]): Check NFT ownership for TON walletsgetState(): Get current connection stateon(event: WalletEvent, listener): Subscribe to eventsoff(event: WalletEvent, listener): Unsubscribe from eventsdestroy(): Clean up resources
Events
Subscribe to wallet events:
// Account changed
connector.on(WalletEvent.ACCOUNT_CHANGED, (account) => {
console.log('Account changed:', account);
});
// Connected
connector.on(WalletEvent.CONNECTED, (account) => {
console.log('Connected:', account);
});
// Disconnected
connector.on(WalletEvent.DISCONNECTED, () => {
console.log('Disconnected');
});
// Connection status changed
connector.on(WalletEvent.STATUS_CHANGED, (status) => {
console.log('Status:', status);
});
// Error
connector.on(WalletEvent.ERROR, (error) => {
console.error('Error:', error);
});NFT Checking
For TON wallets, you can check if a user owns NFTs from specific collections:
// Check NFT ownership
const nftResult = await connector.checkNFTOwnership([
'EQD8rUZqR_pWV1BylWUlPNBzyiTYVoBEmQkMIQDZXICfnuRr',
'EQB2fNcjH2tppC1cO1R4W1qYdYdP5zAQy9y1k5z6b0p'
]);
if (nftResult.hasNFTs) {
console.log('User has required NFTs!');
console.log('Owned NFTs:', nftResult.ownedNFTs);
} else {
console.log('User does not have required NFTs');
}The checkNFTOwnership method returns:
hasNFTs: Boolean indicating if user owns NFTs from any of the collectionscollections: Array of collection informationownedNFTs: Array of owned NFT details
Types
ChainType
enum ChainType {
EVM = 'evm',
SOLANA = 'solana',
TON = 'ton',
TRON = 'tron',
}WalletType
enum WalletType {
METAMASK = 'metamask',
TRUST_WALLET = 'trustwallet',
BITGET = 'bitget',
BASE = 'base',
ATOMIC = 'atomic',
SAFEPAL = 'safepal',
WALLETCONNECT = 'walletconnect',
TONKEEPER = 'tonkeeper',
TONHUB = 'tonhub',
MYTONWALLET = 'mytonwallet',
SOLFLARE = 'solflare',
PHANTOM = 'phantom',
TRONLINK = 'tronlink',
KLEVER = 'klever',
RABBY = 'rabby',
EXODUS = 'exodus',
}Account
interface Account {
address: string;
publicKey?: string;
chainType: ChainType;
}Custom Wallet Adapters
You can create custom wallet adapters by extending the base adapter classes:
import { EVMBaseAdapter, WalletType } from '@tiwiflix/wallet-connector';
class MyCustomWallet extends EVMBaseAdapter {
readonly name = 'My Custom Wallet';
readonly type = WalletType.METAMASK; // Use appropriate type
readonly downloadUrl = 'https://mycustomwallet.com/';
protected getProvider() {
return window.myCustomWallet || null;
}
}
// Use it
const connector = new WalletConnector({
adapters: [new MyCustomWallet()],
});Available base adapters:
EVMBaseAdapter- For EVM-compatible walletsSolanaBaseAdapter- For Solana walletsTONBaseAdapter- For TON walletsTronBaseAdapter- For Tron walletsBaseWalletAdapter- For completely custom implementations
Best Practices
Install Only What You Need: Only install peer dependencies for chains you use to keep bundle size small.
Error Handling: Always wrap wallet operations in try-catch blocks:
try {
await connector.connect(WalletType.METAMASK);
} catch (error) {
// Handle connection errors
if (error.message.includes('not installed')) {
// Show install prompt
}
}- Event Cleanup: Unsubscribe from events when components unmount:
useEffect(() => {
const unsubscribe = connector.on(WalletEvent.ACCOUNT_CHANGED, handler);
return () => unsubscribe();
}, []);- Storage: Use custom storage keys if you have multiple connectors:
const connector = new WalletConnector({
adapters: [...],
storageKey: 'my_app_wallet',
});Troubleshooting
Wallet not detected
Some wallets inject their providers after page load. Wait for the window.load event or add a delay before checking availability.
Multiple wallets conflict
If multiple wallets are installed, they may conflict. Use wallet-specific detection flags (e.g., window.ethereum.isMetaMask).
TypeScript errors
Make sure all peer dependencies are installed for the chains you're using.
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Support
For issues and questions, please open an issue on GitHub.
