The from method normalizes various input types into RLP data structures:
Uint8Array → Creates bytes data
BrandedRlp → Returns unchanged (idempotent)
Array → Creates list data (doesn’t recursively convert items)
Note: Arrays are not recursively converted:
import { Rlp } from 'tevm'// Array items remain as-is (not converted to RLP data)const list = Rlp([ new Uint8Array([1]), // Stays as Uint8Array new Uint8Array([2]) // Stays as Uint8Array])// To recursively convert, use encode + decodeconst encoded = Rlp.encode([ new Uint8Array([1]), new Uint8Array([2])])const decoded = Rlp.decode(encoded)// Now fully converted to RLP data structures
import { Rlp } from 'tevm'function processRlpData(input: Uint8Array | BrandedRlp | BrandedRlp[]) { // Normalize to RLP data const data = Rlp(input) // Now work with consistent type if (data.type === 'bytes') { console.log('Bytes length:', data.value.length) } else { console.log('List items:', data.value.length) }}
Measuring without encoding saves allocation and copying:
import { Rlp } from 'tevm'// Inefficient: encode just to check sizeconst encoded = Rlp.encode(data)const size = encoded.length// Efficient: measure directlyconst size = Rlp.getEncodedLength(data)
Use Cases:Pre-sizing Buffers:
import { Rlp } from 'tevm'// Calculate total size for multiple itemsconst items = [data1, data2, data3]const totalSize = items.reduce( (sum, item) => sum + Rlp.getEncodedLength(item), 0)// Allocate single bufferconst buffer = new Uint8Array(totalSize)
Size Validation:
import { Rlp } from 'tevm'// Check if data will fit in blockconst MAX_BLOCK_SIZE = 1000000const size = Rlp.getEncodedLength(transactionList)if (size > MAX_BLOCK_SIZE) { throw new Error('Transaction list too large for block')}
Choosing Encoding Strategy:
import { Rlp } from 'tevm'// Use different strategies based on sizeconst size = Rlp.getEncodedLength(data)if (size < 1000) { // Small data: use JS encoder const encoded = Rlp.encode(data)} else { // Large data: use WASM encoder const encoded = RlpWasm.encode(data)}
import { Rlp } from 'tevm'function deduplicate(items: BrandedRlp[]): BrandedRlp[] { const unique: BrandedRlp[] = [] for (const item of items) { const isDuplicate = unique.some(u => Rlp.equals(u, item)) if (!isDuplicate) { unique.push(item) } } return unique}
Testing:
import { Rlp } from 'tevm'// Test round-trip encodingconst original = { type: 'list', value: [ { type: 'bytes', value: new Uint8Array([1]) } ]}const encoded = Rlp.encode(original)const decoded = Rlp.decode(encoded)console.log(Rlp.equals(original, decoded.data)) // true
Caching:
import { Rlp } from 'tevm'const cache = new Map<string, Uint8Array>()function encodeWithCache(data: BrandedRlp): Uint8Array { // Check cache for (const [key, cached] of cache.entries()) { const cachedData = JSON.parse(key) if (Rlp.equals(data, cachedData)) { return cached } } // Encode and cache const encoded = Rlp.encode(data) cache.set(JSON.stringify(data), encoded) return encoded}
Assertions:
import { Rlp } from 'tevm'function assertRlpEquals( actual: BrandedRlp, expected: BrandedRlp, message?: string) { if (!Rlp.equals(actual, expected)) { throw new Error(message || 'RLP data not equal') }}// Usage in testsconst result = processRlpData(input)assertRlpEquals(result, expectedOutput)