Skip to main content
All CollectionsHana WalletDevelopers
Hana Wallet EVM Integration Guide

Hana Wallet EVM Integration Guide

Guide for developers to integrate Hana Wallet with EVM dApps, including detection, connection, signing, and EIP-6963 support.

David avatar
Written by David
Updated over a week ago

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

Did this answer your question?