Skip to main content
MANTRA Chain uses the Bech32 address format for native chain addresses (addresses start with mantra1) and standard hexadecimal format for EVM addresses (addresses start with 0x). With the same private key, you can derive both EVM address and Bech32 address using coin type 60.
IMPORTANT: You can convert and use the address only if the key type is cosmos.evm.crypto.v1.ethsecp256k1.PubKey. Check the Auth Information on mantrascan address page. Otherwise, EVM wallets cannot derive the address.

Using the CLI

Download the latest binary from MANTRA Chain Releases.

Bech32 to EVM Address

Basic command:
mantrachaind debug addr mantra19nj8hate4y2w0va698uygf2jj4y6xq42k8a7ed
Output:
Address: [44 228 123 245 121 169 20 231 179 186 41 248 68 37 82 149 73 163 2 170]
Address (hex): 2CE47BF579A914E7B3BA29F84425529549A302AA
Bech32 Acc: mantra19nj8hate4y2w0va698uygf2jj4y6xq42k8a7ed
Bech32 Val: mantravaloper19nj8hate4y2w0va698uygf2jj4y6xq42juus4g
Bech32 Con: mantravalcons19nj8hate4y2w0va698uygf2jj4y6xq42x00vef
Command with formatted output:
mantrachaind debug addr mantra19nj8hate4y2w0va698uygf2jj4y6xq42k8a7ed | grep "Address (hex):" | awk '{print "0x"$3}'
Output:
0x2CE47BF579A914E7B3BA29F84425529549A302AA

EVM Address to Bech32

Remove the 0x prefix before converting:
mantrachaind debug addr 2CE47BF579A914E7B3BA29F84425529549A302AA
Output:
Address: [44 228 123 245 121 169 20 231 179 186 41 248 68 37 82 149 73 163 2 170]
Address (hex): 2CE47BF579A914E7B3BA29F84425529549A302AA
Bech32 Acc: mantra19nj8hate4y2w0va698uygf2jj4y6xq42k8a7ed
Bech32 Val: mantravaloper19nj8hate4y2w0va698uygf2jj4y6xq42juus4g
Bech32 Con: mantravalcons19nj8hate4y2w0va698uygf2jj4y6xq42x00vef

JavaScript Implementation

import { bech32 } from "bech32";

const mantraAddressPrefix = 'mantra';

/**
 * Convert EVM address to MANTRA address.
 * @param {string} evmAddress - EVM address with or without 0x prefix
 * @returns {string} MANTRA Bech32 address
 */
export const convertEVMAddressToMantraAddress = (evmAddress) => {
  const evmAddressBuffer = Buffer.from(evmAddress.slice(2), 'hex');
  const evmAddressBytes = Array.from(evmAddressBuffer);
  const bz = convertBits(evmAddressBytes, 8, 5);
  return bech32.encode(mantraAddressPrefix, bz);
}

/**
 * Convert MANTRA address to EVM address.
 * @param {string} mantraAddress - MANTRA Bech32 address
 * @returns {string} EVM address with 0x prefix
 */
export const convertMantraAddressToEVMAddress = (mantraAddress) => {
  const decoded = bech32.decode(mantraAddress);
  const hexBytes = convertBits(decoded.words, 5, 8, false);
  return `0x${Buffer.from(hexBytes).toString('hex')}`;
}

/**
 * General power-of-2 base conversion.
 * @param {Array<number>} data - Input data as an array of integers
 * @param {number} fromBits - Number of bits in source representation
 * @param {number} toBits - Number of bits in target representation
 * @param {boolean} pad - Whether to pad a result if needed
 * @returns {Array<number>|null} - Converted data or null if conversion fails
 */
export const convertBits = (data, fromBits, toBits, pad = true) => {
  let acc = 0;
  let bits = 0;
  const ret = [];
  const maxv = (1 << toBits) - 1;
  const max_acc = (1 << (fromBits + toBits - 1)) - 1;

  for (const value of data) {
    if (value < 0 || (value >> fromBits)) {
      return null;
    }
    acc = ((acc << fromBits) | value) & max_acc;
    bits += fromBits;
    while (bits >= toBits) {
      bits -= toBits;
      ret.push((acc >> bits) & maxv);
    }
  }

  if (pad) {
    if (bits > 0) {
      ret.push((acc << (toBits - bits)) & maxv);
    }
  } else if (bits >= fromBits || ((acc << (toBits - bits)) & maxv)) {
    return null;
  }

  return ret;
}

Python Implementation

From Bech32 to EVM Address

import bech32

bech32_address = "mantra1z3yty3yswenj4ngk0wg5qmqf25ssr3wfqayuhv"

_, bz = bech32.bech32_decode(bech32_address)
hexbytes = bytes(bech32.convertbits(bz, 5, 8))
eth_address = '0x' + hexbytes.hex()
print(eth_address)

From EVM Address to Bech32

import bech32

eth_address = "0x1448b2449076672acd167b91406c09552101c5c9"
eth_address_bytes = bytes.fromhex(eth_address[2:])

bz = bech32.convertbits(eth_address_bytes, 8, 5)
bech32_address = bech32.bech32_encode("mantra", bz)
print(bech32_address)

References

Next Steps