Similar to other Cosmos chains, Hana Wallet provides seamless integration with Injective Chain through its Keplr emulation layer.
This guide focuses specifically on integrating with Injective using the @injectivelabs/sdk-ts
library, which offers specialized functionality for the Injective ecosystem.
Keplr Compatibility
Hana Wallet emulates the Keplr Wallet API.
Your dApp can work with Hana Wallet the same way it would with Keplr. All code examples in this guide use window.keplr
as the interface, which Hana Wallet automatically injects into the browser window.
Supported Injective Networks
Network | Chain ID |
Mainnet | injective-1 |
Testnet | injective-888 |
Prerequisites
A web application (React or other JavaScript framework)
Install required dependencies:
npm install @injectivelabs/sdk-ts @injectivelabs/utils @injectivelabs/networks @cosmjs/stargate
or
yarn add @injectivelabs/sdk-ts @injectivelabs/utils @injectivelabs/networks @cosmjs/stargate
Basic Integration
1. Detecting Hana Wallet
const checkForHanaWallet = async () => {
if (window.keplr) {
console.log('Wallet detected');
return true;
} else {
console.log('No wallet detected');
return false;
}
};
2. Connecting to Injective
import {
ChainId,
getNetworkEndpoints,
Network
} from '@injectivelabs/networks'
const connectToInjective = async (network = Network.Mainnet) => {
if (!window.keplr) {
alert("Please install Hana Wallet");
return null;
}
try {
const chainId = network === Network.Mainnet
? ChainId.Mainnet
: ChainId.Testnet
await window.keplr.enable(chainId);
const offlineSigner = window.keplr.getOfflineSigner(chainId);
const accounts = await offlineSigner.getAccounts();
const address = accounts[0].address;
console.log(`Connected to Injective ${network} with address: ${address}`);
return { offlineSigner, address, chainId };
} catch (err) {
console.error(`Failed to connect: ${err.message}`);
return null;
}
};
3. Getting the Injective Address from a Cosmos Address
import { PublicKey } from "@injectivelabs/sdk-ts";
import { ChainRestAuthApi } from "@injectivelabs/sdk-ts";
const getInjectiveAddressFromCosmos = async (cosmosAddress) => {
try {
const chainApi = new ChainRestAuthApi(
"https://rest.cosmos.directory/cosmoshub"
);
const account = await chainApi.fetchCosmosAccount(cosmosAddress);
if (!account.pub_key?.key) {
console.log("No public key found");
return null;
}
const injectiveAddress = PublicKey.fromBase64(account.pub_key.key)
.toAddress()
.toBech32();
return injectiveAddress;
} catch (err) {
console.error(`Failed to get Injective address: ${err.message}`);
return null;
}
};
4. Sending INJ Tokens
import {
InjectiveStargate,
InjectiveDirectEthSecp256k1Wallet
} from "@injectivelabs/sdk-ts";
import {
getNetworkEndpoints,
Network
} from "@injectivelabs/networks";
import {
BigNumberInBase,
getDefaultStdFee
} from "@injectivelabs/utils";
const sendTokensWithHanaWallet = async (
recipientAddress,
amount, // in INJ (e.g., "0.001")
network = Network.Mainnet
) => {
if (!window.keplr) {
alert("Please install Hana Wallet");
return null;
}
try {
const endpoints = getNetworkEndpoints(network);
const chainId = network === Network.Mainnet
? "injective-1"
: "injective-888";
await window.keplr.enable(chainId);
const offlineSigner = window.keplr.getOfflineSigner(chainId);
const accounts = await offlineSigner.getAccounts();
const senderAddress = accounts[0].address;
const client = await InjectiveStargate.InjectiveSigningStargateClient.connectWithSigner(
endpoints.rpc,
offlineSigner
);
const amountInWei = {
amount: new BigNumberInBase(amount).toWei().toFixed(),
denom: "inj",
};
const result = await client.sendTokens(
senderAddress,
recipientAddress,
[amountInWei],
getDefaultStdFee(),
"Sent from Hana Wallet"
);
console.log("Transaction hash:", result.transactionHash);
return result;
} catch (err) {
console.error(`Failed to send tokens: ${err.message}`);
throw err;
}
};
Tips for dApp Developers
Library Versioning: Use the latest versions of Injective libraries—they’re actively maintained.
Token Decimals: INJ uses 18 decimals, not 6 like most Cosmos tokens.
Network Selection: Use
getNetworkEndpoints()
to avoid hardcoding RPCs.Gas Estimation: Simulate complex txs before broadcasting.
Error Handling: Handle errors gracefully with user-friendly messages.
Testing: Use Injective Testnet (
injective-888
) before going to Mainnet.