bigint or string. This prevents bugs that have caused real financial losses.
The Problem
Consider this ethers.js code:The Solution
Voltaire makes denomination a type-level concern:WeiType, you know it’s in wei. The type system enforces it.
Beyond Denominations
The same pattern applies to other Ethereum concepts that look similar but aren’t interchangeable:Address vs Hash
Both are hex strings. Both are fixed-size bytes. But mixing them is always a bug:Numeric Types
Block numbers, chain IDs, and nonces are all numbers—but semantically distinct:Crypto Types
Private keys, public keys, and signatures have critical security implications:Comparison with Other Libraries
| Operation | ethers.js | viem | Voltaire |
|---|---|---|---|
| Gas price | bigint | bigint | GweiType or WeiType |
| ETH value | bigint | bigint | WeiType, GweiType, or EtherType |
| Address | string | 0x${string} | AddressType (Uint8Array) |
| Hash | string | 0x${string} | HashType (Uint8Array) |
| Block number | number | bigint | BlockNumberType |
Parse, Don’t Validate
Once you have a typed value, it’s guaranteed valid. This enables a powerful pattern:All Typed Values
| Category | Types |
|---|---|
| Denominations | WeiType, GweiType, EtherType |
| Identifiers | AddressType, HashType, TransactionHashType, BlockHashType |
| Numbers | BlockNumberType, ChainIdType, NonceType, GasLimitType |
| Crypto | PrivateKeyType, PublicKeyType, SignatureType |
| Bytes | Bytes1 through Bytes32, Bytes64, BlobType |
| Integers | Uint8 through Uint256, Int8 through Int256 |

