Detecting Hana Wallet
Basic Detection
Hana Wallet injects an Ethereum provider into the webpage when an EVM chain is enabled. To detect if Hana Wallet is available:
if (window.hanaWallet?.available) {
console.log(`Hana Wallet detected! Version: ${window.hanaWallet.version}`);
} else {
console.log("Hana Wallet is not available. Please install Hana Wallet extension.");
}
Provider Selection
Hana Wallet coexists with other wallet providers like MetaMask. Here's how to properly detect and select Hana's provider:
function getEthereumProvider() {
if (window.hanaWallet?.available && window.hanaWallet.ethereum) {
console.log("Using Hana Wallet's Ethereum provider");
return window.hanaWallet.ethereum;
}
if (window.ethereum?.isHanaWallet) {
console.log("Using Hana Wallet via window.ethereum");
return window.ethereum;
}
if (window.ethereum) {
console.log("Using another Ethereum provider");
return window.ethereum;
}
console.error("No Ethereum provider detected");
return null;
}
const ethereumProvider = getEthereumProvider();
Core Functionality
Connecting to User's Wallet
To request access to the user's Ethereum accounts:
async function connectWallet(ethereumProvider) {
try {
const accounts = await ethereumProvider.request({ method: 'eth_requestAccounts' });
const userAddress = accounts[0];
console.log(`Connected to wallet with address: ${userAddress}`);
return userAddress;
} catch (error) {
console.error(`Connection failed: ${error.message}`);
return null;
}
}
Retrieving Connected Chain Information
async function getChainInfo(ethereumProvider) {
try {
const chainId = await ethereumProvider.request({ method: 'eth_chainId' });
const decimalChainId = parseInt(chainId, 16);
console.log(`Connected to chain ID: ${decimalChainId}`);
return decimalChainId;
} catch (error) {
console.error(`Failed to get chain info: ${error.message}`);
return null;
}
}
Signing a Message
async function signMessage(ethereumProvider, message, userAddress) {
try {
const msgHex = typeof message === 'string' && !message.startsWith('0x')
? `0x${Buffer.from(message).toString('hex')}`
: message;
const signature = await ethereumProvider.request({
method: 'personal_sign',
params: [msgHex, userAddress],
});
console.log(`Message signed successfully`);
return signature;
} catch (error) {
console.error(`Signing failed: ${error.message}`);
return null;
}
}
Sending a Transaction
async function sendTransaction(ethereumProvider, txParams) {
try {
const txHash = await ethereumProvider.request({
method: 'eth_sendTransaction',
params: [txParams],
});
console.log(`Transaction sent: ${txHash}`);
return txHash;
} catch (error) {
console.error(`Transaction failed: ${error.message}`);
return null;
}
}
const txParams = {
from: userAddress,
to: '0xRecipientAddress',
value: '0x' + (0.01 * 1e18).toString(16),
gas: '0x5208',
};
Advanced Integration
Handling Chain Changes
function setupChainListeners(ethereumProvider) {
ethereumProvider.on('chainChanged', (chainId) => {
console.log(`Chain changed to: ${parseInt(chainId, 16)}`);
window.location.reload();
});
}
Handling Account Changes
function setupAccountListeners(ethereumProvider) {
ethereumProvider.on('accountsChanged', (accounts) => {
if (accounts.length === 0) {
console.log('User disconnected all accounts');
} else {
console.log(`Active account changed to: ${accounts[0]}`);
}
});
}
EIP-6963 Support
Hana Wallet implements EIP-6963, the Multi Injected Provider Discovery standard, which provides a better way to handle multiple wallet extensions in the browser.
Benefits of EIP-6963
No Provider Conflicts: Eliminates conflicts when multiple wallet extensions are installed
Better User Experience: Users can choose which wallet to use for each dApp
Improved Security: Reduces risks from malicious extensions overriding wallet connections
Implementing EIP-6963 in Your dApp
const providers = [];
window.addEventListener('eip6963:announceProvider', (event) => {
const { info, provider } = event.detail;
console.log(`Wallet announced: ${info.name}, version ${info.version}`);
providers.push({ info, provider });
if (info.name.includes('Hana')) {
console.log('Hana Wallet detected via EIP-6963');
}
});
window.dispatchEvent(new Event('eip6963:requestProvider'));
function connectToWallet(selectedProviderIndex) {
const selectedProvider = providers[selectedProviderIndex].provider;
// Use selectedProvider for all Ethereum interactions
}
For a comprehensive implementation guide, refer to MetaMask's EIP-6963 Tutorial.
Complete Example
async function initializeHanaWalletIntegration() {
const ethereumProvider = getEthereumProvider();
if (!ethereumProvider) return;
setupChainListeners(ethereumProvider);
setupAccountListeners(ethereumProvider);
const userAddress = await connectWallet(ethereumProvider);
if (!userAddress) return;
const chainId = await getChainInfo(ethereumProvider);
document.getElementById('wallet-status').textContent = 'Connected';
document.getElementById('wallet-address').textContent = userAddress;
document.getElementById('chain-id').textContent = chainId;
document.getElementById('sign-button').addEventListener('click', async () => {
const message = "Welcome to our dApp!";
const signature = await signMessage(ethereumProvider, message, userAddress);
if (signature) {
document.getElementById('signature').textContent = signature;
}
});
document.getElementById('send-button').addEventListener('click', async () => {
const recipientAddress = document.getElementById('recipient').value;
const amount = document.getElementById('amount').value;
const txParams = {
from: userAddress,
to: recipientAddress,
value: '0x' + (parseFloat(amount) * 1e18).toString(16),
gas: '0x5208',
};
const txHash = await sendTransaction(ethereumProvider, txParams);
if (txHash) {
document.getElementById('tx-hash').textContent = txHash;
}
});
}
window.addEventListener('load', initializeHanaWalletIntegration);
Troubleshooting
Common Issues
Provider Not Found: Ensure Hana Wallet extension is installed and an EVM chain is active
Connection Rejected: User declined the connection request
Wrong Network: User is connected to a different network than expected
Provider State Check
function checkProviderState(ethereumProvider) {
if (!ethereumProvider) {
console.error("Provider not available");
return false;
}
if (!ethereumProvider.isConnected()) {
console.error("Provider not connected");
return false;
}
return true;
}
Further Resources
EIP-6963 for multi-provider support