Account Model
Every account on Monolythium has two addresses -- a Cosmos mono1... address and an EVM 0x... address -- derived from the same private key. This dual-address system enables seamless interaction with both Cosmos SDK modules and EVM smart contracts.
Dual Address System
A single private key produces both address formats:
Private Key (EthSecp256k1)
│
├── Compress to 33-byte public key
│
├── Keccak256 hash → last 20 bytes → 0x... (EVM address)
│
└── RIPEMD160(SHA256(pubkey)) → Bech32 encode → mono1... (Cosmos address)
Both addresses reference the same account. Sending LYTH to either address credits the same balance.
Address Formats
| Format | Prefix | Length | Example |
|---|---|---|---|
| Cosmos (Bech32) | mono1 | 44 characters | mono1qypqxpq9qcrsszg2pvxq6rs0zqg3yyc5lzv7xu |
| EVM (Hex) | 0x | 42 characters | 0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed |
| Validator Operator | monovaloper1 | ~52 characters | monovaloper1qypqxpq9qcrsszg2pvxq6rs0zqg... |
| Validator Consensus | monovalcons1 | ~52 characters | monovalcons1qypqxpq9qcrsszg2pvxq6rs0zqg... |
| Public Key | monopub1 | variable | monopub1addwnpepqg... |
Key Derivation
Monolythium uses EthSecp256k1 keys with HD derivation path m/44'/60'/0'/0/0.
| Parameter | Value |
|---|---|
| Curve | secp256k1 |
| Signing algorithm | EthSecp256k1 (Ethereum-compatible ECDSA) |
| HD path | m/44'/60'/0'/0/0 |
| Coin type | 60 |
| Bech32 prefix | mono |
Why Coin Type 60?
Standard Cosmos chains use coin type 118 (the ATOM coin type). Monolythium uses coin type 60 (the Ethereum coin type) because:
- MetaMask compatibility: MetaMask and other EVM wallets derive keys using coin type 60. Using the same coin type means the same mnemonic produces the same addresses in both Cosmos and EVM wallets.
- Ledger support: Hardware wallets use the Ethereum app (coin type 60) to sign Monolythium transactions. No custom Ledger app required.
- Key reuse: A single mnemonic works across the Monolythium Browser Wallet, MetaMask, Keplr, and Ledger -- all producing the same account.
When importing a Monolythium mnemonic into Keplr or Leap, make sure to select coin type 60 (not the default 118). Using coin type 118 will derive a different address from the same mnemonic.
Comparison with Standard Cosmos Chains
| Property | Standard Cosmos (e.g. ATOM) | Monolythium |
|---|---|---|
| Coin type | 118 | 60 |
| HD path | m/44'/118'/0'/0/0 | m/44'/60'/0'/0/0 |
| Key algorithm | Secp256k1 | EthSecp256k1 |
| Address derivation | SHA256 + RIPEMD160 | Keccak256 (last 20 bytes) |
| EVM compatible | No | Yes |
| MetaMask support | No | Yes |
Converting Between Formats
CLI
# Convert any address format to both Cosmos and EVM
monod debug addr mono1qypqxpq9qcrsszg2pvxq6rs0zqg3yyc5lzv7xu
# Output:
# Address bytes: [20-byte hex]
# Address (hex): 0x...
# Address (EIP-55): 0x...
# Bech32 Acc: mono1...
# Bech32 Val: monovaloper1...
# Convert from EVM hex
monod debug addr 0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed
Programmatically (TypeScript)
import { fromBech32, toBech32 } from "@cosmjs/encoding";
// Bech32 → EVM hex
function bech32ToHex(bech32Address: string): string {
const { data } = fromBech32(bech32Address);
return "0x" + Buffer.from(data).toString("hex");
}
// EVM hex → Bech32
function hexToBech32(hexAddress: string): string {
const bytes = Buffer.from(hexAddress.slice(2), "hex");
return toBech32("mono", bytes);
}
// Examples
const evmAddr = bech32ToHex("mono1qypqxpq9qcrsszg2pvxq6rs0zqg3yyc5lzv7xu");
const cosmosAddr = hexToBech32("0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed");
Programmatically (Go)
package main
import (
"encoding/hex"
"fmt"
"github.com/cosmos/cosmos-sdk/types/bech32"
)
func bech32ToHex(addr string) (string, error) {
_, bytes, err := bech32.DecodeAndConvert(addr)
if err != nil {
return "", err
}
return "0x" + hex.EncodeToString(bytes), nil
}
func hexToBech32(hexAddr string) (string, error) {
bytes, err := hex.DecodeString(hexAddr[2:]) // strip "0x"
if err != nil {
return "", err
}
return bech32.ConvertAndEncode("mono", bytes)
}
func main() {
evmAddr, _ := bech32ToHex("mono1qypqxpq9qcrsszg2pvxq6rs0zqg3yyc5lzv7xu")
fmt.Println("EVM:", evmAddr)
cosmosAddr, _ := hexToBech32("0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed")
fmt.Println("Cosmos:", cosmosAddr)
}
Account Sequence (Nonce)
Each account has a sequence number that increments with every transaction. This prevents replay attacks.
- The Cosmos sequence and EVM nonce are kept in sync.
- Querying via
eth_getTransactionCountreturns the same value asmonod query auth account. - Concurrent transactions must be ordered by sequence. Gaps cause rejection.
# Query account info (includes sequence)
monod query auth account mono1abc... --output json
# Query EVM nonce
cast nonce 0xAddress... --rpc-url https://evm.testnet.mononodes.xyz
Account Types
| Type | Description |
|---|---|
| Base Account | Standard user account with a keypair |
| Module Account | Internal accounts owned by SDK modules (e.g., distribution, staking). Cannot be controlled externally. |
| Contract Account | EVM smart contract. Has code and storage but no private key. |
Accounts are created on-chain when they first receive tokens or submit a transaction. There is no explicit account creation step.
Wallet Compatibility
Because Monolythium uses coin type 60 and EthSecp256k1 keys, the same mnemonic works across:
| Wallet | Address Format | Configuration |
|---|---|---|
| Monolythium Browser Wallet | Both | Native support |
| Monolythium Desktop Wallet | Both | Native support |
| Monolythium Mobile Wallet | Both | Native support |
| MetaMask | 0x... | Add custom network (chain ID 6940/6941) |
| Trust Wallet | 0x... | Add custom network |
| Keplr | mono1... | Set coin type to 60 |
| Leap | mono1... | Set coin type to 60 |
| Ledger | Both | Use Ethereum app |
Related
- Address Formats -- User guide for address types
- Wallets -- Wallet setup and configuration
- Keyring Setup -- Key storage backends for CLI usage
- JavaScript & TypeScript SDK -- Programmatic account interactions