Understanding Maroo Address Formats

integration intermediate

Maroo accounts have two equivalent string representations — EVM hex (0x…) and Bech32 (maroo1…). When each one matters, and how to convert between them in JS/TS.

Prerequisites

  • Basic understanding of EVM hex addresses (e.g., from Ethereum).

EVM hex (the default surface)

The standard 42-character 0x… address. This is what MetaMask shows, what Solidity uses, what JSON-RPC returns, what the Maroo block explorer displays, and what every viem / ethers / Hardhat / Foundry tool expects.

Example: 0x71C7656EC7ab88b098defB751B7401B5f6d8976F

Bech32

Same 20-byte account ID, encoded with a network-identifying HRP (maroo for Maroo) and a checksum. You'll see this when:

  • querying validator / staking / governance modules (they take Bech32),
  • inspecting non-EVM query results,
  • interfacing with IBC (counterparty addresses).


Example: maroo1g9aher02v4dmf49m26de25d2n0a2th8g3z4x9a

It's the same key material — just a different string representation.

Converting between them in JS/TS

Both directions are O(1) — there's no network call. Use @cosmjs/encoding for Bech32 (it's lightweight and ships in many wallet stacks already), and ethers/viem hex helpers for 0x form.
import { fromBech32, toBech32 } from "@cosmjs/encoding";
import { getAddress, hexToBytes, bytesToHex } from "viem"; // or ethers equivalents

const HRP = "maroo";

// hex -> bech32
export function hexToBech32(hex: `0x${string}`): string {
  const bytes = hexToBytes(hex);
  return toBech32(HRP, bytes);
}

// bech32 -> hex (checksummed)
export function bech32ToHex(addr: string): `0x${string}` {
  const { data } = fromBech32(addr);
  return getAddress(`0x${bytesToHex(data).slice(2)}`);
}

// example round-trip
const hex     = "0x71C7656EC7ab88b098defB751B7401B5f6d8976F";
const bech32  = hexToBech32(hex);
// 'maroo1g9aher02v4dmf49m26de25d2n0a2th8g3z4x9a'
const andBack = bech32ToHex(bech32);
// '0x71C7656EC7ab88b098defB751B7401B5f6d8976F'
Note: Bech32 has a built-in checksum, so `fromBech32` throws on typos. The `0x` form has no checksum on its own — use viem's `getAddress` (or ethers' `getAddress`) to apply EIP-55 mixed-case checksumming.

Specialized prefixes

Bech32 has prefix variants for non-account roles. You'll only meet them when interfacing with validator / governance modules:

  • maroovaloper1… — validator operators (staking module messages).
  • maroovalcons1… — validator consensus addresses.
  • maroopub1… / maroovaloperpub1… — public-key encoded forms (rare in app code).


Account-level dApp work essentially never needs these.
Source: maroo
ESC
Type to search