Accounts & keys
Key type
Every BKC account is an ML-DSA-65 key pair (FIPS 204, security category 3).
| Bytes | |
|---|---|
| Seed | 32 |
| Public key | 1,952 |
| Private key (expanded) | 4,032 |
| Signature | 3,309 |
The chain accepts no other account key. secp256k1 and ed25519 signers are rejected by the ante handler (error code 1101); the node's keyring refuses to create them (unsupported signing algo); there is no Ledger support because no hardware wallet implements ML-DSA.
Funds sent to a pre-quantum address are lost
An address carries no key type. If you send BKC to an address derived from a secp256k1 key (for example an address copied from MetaMask), the chain accepts the transfer — and nothing can ever sign for that address.
Addresses
An address is the first 20 bytes of SHA-256(public key). It has two spellings:
| Spelling | Example | Used by |
|---|---|---|
bech32, prefix bkc | bkc1n8knf9x56r3dxc4rmvxd2u7tad82kcnwtsrqnm | Cosmos SDK, CLI, REST, wallets |
| hex (EIP-55) | 0x99ED3494D4D0E2D362A3DB0CD573CBEB4EAB626E | EVM, Solidity, explorer |
Both are the same account. Convert with the SDK:
import { toEvmAddress, toBech32Address } from "@bkc-network-lib/sdk";
toEvmAddress("bkc1n8knf9x56r3dxc4rmvxd2u7tad82kcnwtsrqnm"); // 0x99ED…626E (checksummed)
toBech32Address("0x99ED3494D4D0E2D362A3DB0CD573CBEB4EAB626E"); // bkc1n8kn…rqnmor with the node binary: BKCd debug addr bkc1….
From a mnemonic to a key
BKC keeps BIP-39 mnemonics, but does not use BIP-32 derivation — BIP-32 is defined for elliptic curves. Instead:
bip39Seed = BIP39(mnemonic, passphrase) 64 bytes
mldsaSeed = HKDF-SHA256(ikm = bip39Seed,
salt = "BKC/ML-DSA-65",
info = "m/44'/118'/0'/0/0", the HD path, as a string
len = 32)
keypair = ML-DSA-65.KeyGen(mldsaSeed)Consequences worth knowing:
- The same mnemonic gives a different address on BKC than on any secp256k1 chain. That is expected.
- The HKDF salt is chain-specific. A wallet using another salt derives another account from the same words.
m/44'/118'/0'/0/0is the default path (coin type 118). Change the account or index and you get an independent key.- Tools that take a seed (
BKC_SEEDin Hardhat,BkcSigner.fromSeed) want the 32-bytemldsaSeed, not a secp256k1 private key and not the 64-byte BIP-39 seed.
Creating an account
npx hardhat bkc-new-account
# prints a 32-byte seed and its bkc1… / 0x… addressesimport { DirectMldsa65HdWallet } from "@bkc-network-lib/sdk";
const wallet = await DirectMldsa65HdWallet.generate(24, { prefix: "bkc" });
const [account] = await wallet.getAccounts();
console.log(account.address, wallet.mnemonic);BKCd keys add alice # --key-type defaults to mldsa65
BKCd keys add alice --recover # from an existing mnemonicAn account exists on chain only after it first receives funds — get some from the faucet.
Sequence and nonce
A Cosmos account has a sequence that increases by one with every transaction it signs. Wrapped EVM calls use it as their nonce: call_nonce must equal the sequence the transaction is signed with. Contract accounts inside the EVM keep ordinary EVM nonces, which is why CREATE addresses come out exactly as Ethereum tooling predicts. See Transactions & EVM calls.
