Skip to content

Features

LitVM sidecar

Receive and send LiteForge testnet zkLTC from the same seed, in a separate wallet-litvm crate, with a replacement floor, a fee-drain brake, and EIP-55 checksums. Experimental: no mainnet, and no in-app Grail peg.

Experimental. LiteForge testnet only.

LitVM in the desktop wallet is a sidecar, not a third Litecoin balance. It is an EVM account for zkLTC that hangs off the same BIP39 seed as the L1 wallet, on the LiteForge testnet. It does not enter the hero LTC balance, and it is not merged into Privacy coin control. The feature is experimental. There is no mainnet preset in the wallet, and there is no in-app Grail peg.

Same seed, separate crate

The implementation lives in wallet-litvm, a separate workspace crate built on alloy. A feature flag keeps it out of the library graph that wallet-core and the Litecoin BDK crates use. Alloy types do not cross into those crates. The Tauri boundary stays on plain strings: a 0x address and a decimal zkLTC amount.

The account is derived from the same mnemonic the L1 wallet already stores, at m/44'/60'/0'/0/0, the default path used by common Ethereum wallets. It uses the same passphrase lock and the same wipe as that mnemonic. Deriving the 0x address does not create a second backup. Losing the Litecoin mnemonic loses this account too.

That sharing is the hazard the interface is built around. A testnet L2 account derived from a mainnet L1 seed is fine as cryptography and easy to confuse in practice. Until official mainnet parameters exist, the LitVM surface keeps a persistent LiteForge testnet banner and a link to the faucet. zkLTC is never added to the combined LTC balance. L1 send fields reject a 0x address. LitVM fields reject ltc1, M, and L, and point at the other network instead of building a transaction.

LiteForge, and only LiteForge

LitVM view with the LiteForge testnet banner above a zkLTC balance.LitVM view with the LiteForge testnet banner above a zkLTC balance.

Networks are data. LiteForge is the first row. Mainnet is a second row that gets added when official parameters exist, not a mode flag hidden in the testnet code. Signing uses the chain id stored on that row. The wallet does not sign with whatever eth_chainId the RPC happens to return.

As of the wallet notes last verified on 15 August 2026, a live probe of the LiteForge HTTP endpoint returned chain id 4441 (0x1159). The native symbol in that row is zkLTC, with 18 decimals. The explorer responded. The WebSocket URL was still unconfirmed, so the wallet does not depend on it. History comes from a Blockscout-style transaction list, which can fail. A miss is treated as empty history plus a link to open the explorer, and a transaction you just sent is shown locally until the indexer lists it. Native zkLTC transfers between ordinary accounts do not emit logs, so log queries are blind to them. A receipt status of "0" means the transaction failed. It does not mean the transaction is still pending.

Signing stays disabled until a live chain-id probe matches the preset. The faucet for test coins is testnet.litvm.com. Official parameter notes live at docs.litvm.com. None of that is a mainnet launch. Phase 3, which would add a mainnet row, waits on a published chain id, RPC, and explorer, plus a live probe that matches. That work has not shipped.

Guards on send

Three checks exist because a testnet RPC is not a place to discover a typo or a fee bug with a careless transaction.

Checksums follow EIP-55. A mixed-case 0x address is checked as a checksum. An all-lowercase or all-uppercase address is accepted without one. The wallet would rather reject a bad checksum than “fix” an address you may have mistyped.

Fees have two caps. There is a per-gas ceiling (MAX_FEE_GWEI of 10,000) sized for an Orbit stack’s L2 fee plus a spike in L1 calldata. There is also a total drain brake: gas_limit times max_fee_per_gas must stay at or under 0.05 zkLTC. Congestion and a hostile or broken RPC are reported as different errors, so a fee spike is not the same message as a node that is trying to get the wallet to overpay.

Replacement has a floor. A same-nonce speed-up loads the transaction already in the mempool and raises both EIP-1559 fee fields by at least 12.5 percent (ceil(old * 1125 / 1000)), then takes the maximum of that bump and a fresh estimate. If a receipt already exists, the transaction is confirmed. The wallet does not offer a second send that pretends it is still replaceable.

Settings can select the preset and, optionally, a user RPC URL. “What leaves this computer” has to mention that RPC: the node learns your IP and the address you ask about, in the same spirit as the Electrum disclosure on the L1 side.

What is deliberately absent

Grail, the peg between L1 and this environment, is not an in-app feature. An unofficial sibling SDK can verify an offer before funding, on LiteForge only, and the command-line tool can run that check. Deposit stays stubbed until a captured offer verifies. The wallet does not invent a Taproot leaf, does not pay an offer that fails verification, and does not ship a mainnet peg. There is no WalletConnect, no token browser, and no ERC-20 balance hiding beside zkLTC.

LitVM in this wallet is Phase 0 through Phase 2: the crate and the derivation, LiteForge receive and send, history, a custom RPC, and the fee and replacement rules above. It is a prototype path on a testnet, in a wallet that has not been independently audited. Treat zkLTC on LiteForge as testnet funds. Do not read the sidecar as support for mainnet LitVM, and do not read it as a bridge.