import * as Address from '@tevm/voltaire/Address'import * as Bytecode from '@tevm/voltaire/Bytecode'const address = Address.from('0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48')const bytecode = Bytecode.from('0x608060405234801561001057600080fd5b50')await client.readContract({ address: bytecode, // Type error: Bytecode is not assignable to Address ...})
Copy
Ask AI
import { type Address, type Hex } from 'viem'const address: Address = '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48'const bytecode: Hex = '0x608060405234801561001057600080fd5b50'// Compiles fine - runtime bug waiting to happenawait client.readContract({ address: bytecode, // oops, passed bytecode as address! abi: erc20Abi, functionName: 'balanceOf', args: [address]})
viem’s Address and Hex are both 0x${string} - TypeScript can’t catch when you mix them up.
Swap production layers for test layers without changing business logic:
Copy
Ask AI
// Productionawait Effect.runPromise(program.pipe(Effect.provide(MainLayer)))// Test - same code, different wiring await Effect.runPromise(program.pipe(Effect.provide(TestLayer)))
Composable Operations
Built-in retry, timeout, and fallback. No external libraries needed:
Copy
Ask AI
getBlockNumber().pipe( Effect.retry(Schedule.exponential('100 millis').pipe(Schedule.recurs(5))), Effect.timeout(Duration.seconds(10)), Effect.orElse(() => getBlockNumber()) // with different provider layer)