Addresses: EVM & Native
Every Rubin account has exactly one address — the same 20 bytes — shown in two encodings:
- EVM form: hex with a
0xprefix, e.g.0x1234…abcd; - Native form: bech32 with the
rit1prefix, e.g.rit1….
These are not two accounts and not a mapping stored anywhere: the conversion is purely mechanical (bech32 decode/encode of the same bytes), works offline in both directions, and involves no signature or on-chain action.
Which form to use where
| Context | Form |
|---|---|
| EVM wallets (MetaMask etc.), EVM explorers | 0x |
EVM JSON-RPC (https://evm-rpc.rubin.trade, https://evm-rpc.testnet.rubin.trade) | 0x |
| Chain tooling: CLI, node REST/gRPC, IBC, governance | rit1 |
| Indexer API address parameters | rit1 |
Testnet faucet (POST https://faucet.testnet.rubin.trade/faucet/tokens) | rit1 |
Converting between forms
The conversion needs only a bech32 library. With @cosmjs/encoding:
import { fromBech32, fromHex, toBech32, toHex } from '@cosmjs/encoding'
const hexToBech32 = (hex: string): string =>
toBech32('rit', fromHex(hex.replace(/^0x/, '')))
const bech32ToHex = (address: string): string =>
`0x${toHex(fromBech32(address).data)}`EVM signatures (EIP-712)
The chain accepts EVM-style signatures, so an EVM wallet can act on its account without any chain-native tooling. In particular, Permissioned Keys (agent keys / permissioned trading keys) can be authorized by signing an EIP-712 typed message — RubinTransaction:ApproveAgent — in the web app; the chain then registers an EthAddressSignatureVerification authenticator for the key. This is how MetaMask-style wallets authorize the MCP trading key.