> ## Documentation Index
> Fetch the complete documentation index at: https://voltaire.tevm.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# RLP WASM Implementation

> WebAssembly-accelerated RLP encoding compiled from Zig

<Card title="Try it Live" icon="play" href="https://playground.tevm.sh?example=primitives/rlp.ts">
  Run RLP examples in the interactive playground
</Card>

# RLP WASM Implementation

High-performance WebAssembly RLP encoder compiled from Zig for performance-critical operations.

## Overview

The WASM implementation provides accelerated RLP encoding methods compiled from Zig. Currently supports encoding operations with significant performance improvements over JavaScript.

**Features:**

* **Fast encoding** - Compiled Zig code for maximum performance
* **Memory efficient** - Zero-copy operations where possible
* **Type safe** - TypeScript bindings with full type safety
* **Drop-in replacement** - Compatible with JavaScript API

**Currently Available:**

* `encodeBytes` - Encode byte arrays
* `encodeUint` - Encode 256-bit unsigned integers
* `toHex` / `fromHex` - Hex conversion utilities

## Setup

WASM module loads automatically when available:

```typescript theme={null}
import * as RlpWasm from 'tevm/Rlp.wasm'

// WASM methods available immediately
const encoded = RlpWasm.encodeBytes(new Uint8Array([1, 2, 3]))
```

## encodeBytes

Encode byte arrays using WASM.

<Tabs>
  <TabItem label="Signature">
    ```typescript theme={null}
    function encodeBytes(data: Uint8Array): Uint8Array
    ```

    **Parameters:**

    * `data: Uint8Array` - Byte array to encode

    **Returns:**

    * `Uint8Array` - RLP-encoded bytes

    Source: [Rlp.wasm.ts:13-16](https://github.com/evmts/voltaire/blob/main/src/primitives/Rlp/Rlp.wasm.ts#L13-L16)
  </TabItem>

  <TabItem label="Usage">
    ```typescript theme={null}
    import * as RlpWasm from 'tevm/Rlp.wasm'

    // Single byte < 0x80
    const single = RlpWasm.encodeBytes(new Uint8Array([0x7f]))
    // => Uint8Array([0x7f])

    // Short string
    const short = RlpWasm.encodeBytes(new Uint8Array([1, 2, 3]))
    // => Uint8Array([0x83, 1, 2, 3])

    // Empty bytes
    const empty = RlpWasm.encodeBytes(Bytes())
    // => Uint8Array([0x80])

    // Long string (56+ bytes)
    const long = new Uint8Array(60).fill(0x42)
    const encoded = RlpWasm.encodeBytes(long)
    // => Uint8Array([0xb8, 60, ...long])

    // Performance-critical encoding
    function encodeBatch(items: Uint8Array[]): Uint8Array[] {
      return items.map(item => RlpWasm.encodeBytes(item))
    }
    ```
  </TabItem>
</Tabs>

### Performance

WASM `encodeBytes` significantly faster than JavaScript:

```typescript theme={null}
import { Rlp } from 'tevm'
import * as RlpWasm from 'tevm/Rlp.wasm'

// Benchmark encoding 10,000 byte arrays
const items = Array({ length: 10000 }, () =>
  new Uint8Array(100).fill(0x42)
)

// JavaScript implementation
console.time('JS encode')
for (const item of items) {
  Rlp.encodeBytes(item)
}
console.timeEnd('JS encode')
// JS encode: ~50ms

// WASM implementation
console.time('WASM encode')
for (const item of items) {
  RlpWasm.encodeBytes(item)
}
console.timeEnd('WASM encode')
// WASM encode: ~10ms (5x faster)
```

## encodeUint

Encode 256-bit unsigned integers.

<Tabs>
  <TabItem label="Signature">
    ```typescript theme={null}
    function encodeUint(value: Uint8Array): Uint8Array
    ```

    **Parameters:**

    * `value: Uint8Array` - 32-byte big-endian u256 value

    **Returns:**

    * `Uint8Array` - RLP-encoded bytes

    **Throws:**

    * `Error` - If value is not 32 bytes

    Source: [Rlp.wasm.ts:23-28](https://github.com/evmts/voltaire/blob/main/src/primitives/Rlp/Rlp.wasm.ts#L23-L28)
  </TabItem>

  <TabItem label="Usage">
    ```typescript theme={null}
    import * as RlpWasm from 'tevm/Rlp.wasm'

    // Encode u256 value
    const value = Bytes32()
    value[31] = 0x42  // Value = 66
    const encoded = RlpWasm.encodeUint(value)

    // Must be exactly 32 bytes
    try {
      RlpWasm.encodeUint(Bytes16())  // Wrong size
    } catch (error) {
      console.error('Value must be 32 bytes (u256)')
    }

    // Use with Uint module
    import { Uint } from 'tevm'

    const num = Uint(1000n)
    const bytes = Uint.toBytes(num)
    const encoded = RlpWasm.encodeUint(bytes)
    ```
  </TabItem>
</Tabs>

## encodeUintFromBigInt

Encode bigint directly to RLP.

<Tabs>
  <TabItem label="Signature">
    ```typescript theme={null}
    function encodeUintFromBigInt(value: bigint): Uint8Array
    ```

    **Parameters:**

    * `value: bigint` - BigInt value to encode

    **Returns:**

    * `Uint8Array` - RLP-encoded bytes

    Source: [Rlp.wasm.ts:36-44](https://github.com/evmts/voltaire/blob/main/src/primitives/Rlp/Rlp.wasm.ts#L36-L44)
  </TabItem>

  <TabItem label="Usage">
    ```typescript theme={null}
    import * as RlpWasm from 'tevm/Rlp.wasm'

    // Encode bigint values
    const small = RlpWasm.encodeUintFromBigInt(100n)
    const large = RlpWasm.encodeUintFromBigInt(2n ** 200n)

    // Convenient for direct encoding
    function encodeTransaction(tx: {
      nonce: bigint
      gasPrice: bigint
      gas: bigint
      // ...
    }) {
      return [
        RlpWasm.encodeUintFromBigInt(tx.nonce),
        RlpWasm.encodeUintFromBigInt(tx.gasPrice),
        RlpWasm.encodeUintFromBigInt(tx.gas),
        // ...
      ]
    }
    ```
  </TabItem>
</Tabs>

## Hex Utilities

Convert between RLP bytes and hex strings.

<Tabs>
  <TabItem label="toHex">
    ```typescript theme={null}
    function toHex(rlpData: Uint8Array): string
    ```

    Convert RLP-encoded data to hex string with 0x prefix.

    ```typescript theme={null}
    import * as RlpWasm from 'tevm/Rlp.wasm'

    const encoded = new Uint8Array([0x83, 1, 2, 3])
    const hex = RlpWasm.toHex(encoded)
    // => "0x83010203"

    // Round-trip
    const bytes = new Uint8Array([1, 2, 3])
    const encoded = RlpWasm.encodeBytes(bytes)
    const hex = RlpWasm.toHex(encoded)
    const restored = RlpWasm(hex)
    // restored equals encoded
    ```

    Source: [Rlp.wasm.ts:51-54](https://github.com/evmts/voltaire/blob/main/src/primitives/Rlp/Rlp.wasm.ts#L51-L54)
  </TabItem>

  <TabItem label="fromHex">
    ```typescript theme={null}
    function fromHex(hex: string): Uint8Array
    ```

    Convert hex string to RLP bytes (accepts with or without 0x prefix).

    ```typescript theme={null}
    import * as RlpWasm from 'tevm/Rlp.wasm'

    // With 0x prefix
    const bytes = RlpWasm("0x83010203")
    // => Uint8Array([0x83, 1, 2, 3])

    // Without 0x prefix
    const bytes = RlpWasm("83010203")
    // => Uint8Array([0x83, 1, 2, 3])

    // Decode from hex
    const hex = "0x83010203"
    const encoded = RlpWasm(hex)
    // Now can decode with Rlp.decode()
    ```

    Source: [Rlp.wasm.ts:61-63](https://github.com/evmts/voltaire/blob/main/src/primitives/Rlp/Rlp.wasm.ts#L61-L63)
  </TabItem>
</Tabs>

### Architecture

```zig theme={null}
//! RLP encoding implementation in Zig
//! Compiled to WebAssembly for browser/Node.js use

const std = @import("std");
const Hex = @import("../Hex/Hex.zig");

/// Maximum recursion depth
pub const MAX_RLP_DEPTH: u32 = 32;

/// Encode byte array to RLP
pub fn encodeBytes(allocator: Allocator, bytes: []const u8) ![]u8 {
    // Efficient implementation with minimal allocations
}

/// Encode u256 value to RLP
pub fn encodeUint(allocator: Allocator, value: [32]u8) ![]u8 {
    // Optimized integer encoding
}
```

Source: [Rlp.zig:1-1489](https://github.com/evmts/voltaire/blob/main/src/primitives/Rlp/Rlp.zig)

### Benefits

**Performance:**

* Compiled to optimized WASM bytecode
* No JIT warmup time
* Predictable performance characteristics

**Memory:**

* Manual memory management for efficiency
* Zero-copy operations where possible
* Minimal allocations

**Safety:**

* Zig's compile-time safety checks
* No undefined behavior
* Bounds checking in debug mode

## When to Use WASM

Use WASM implementation for:

**High-throughput encoding:**

```typescript theme={null}
import * as RlpWasm from 'tevm/Rlp.wasm'

// Encoding many transactions
async function encodeBatch(transactions: Transaction[]) {
  return Promise.all(
    transactions.map(async (tx) => {
      const fields = await prepareFields(tx)
      return fields.map(field => RlpWasm.encodeBytes(field))
    })
  )
}
```

**Large data structures:**

```typescript theme={null}
import * as RlpWasm from 'tevm/Rlp.wasm'

// Encoding block with many transactions
function encodeBlock(block: Block) {
  return {
    header: block.header.map(field => RlpWasm.encodeBytes(field)),
    transactions: block.transactions.map(tx =>
      tx.fields.map(field => RlpWasm.encodeBytes(field))
    ),
    uncles: block.uncles.map(uncle =>
      uncle.map(field => RlpWasm.encodeBytes(field))
    )
  }
}
```

**Performance-critical paths:**

```typescript theme={null}
import * as RlpWasm from 'tevm/Rlp.wasm'

// Real-time transaction signing
async function signTransaction(tx: Transaction) {
  // Use WASM for encoding (faster)
  const encoded = encodeTransactionFields(tx).map(field =>
    RlpWasm.encodeBytes(field)
  )

  // Sign encoded data
  const signature = await sign(encoded)

  return { encoded, signature }
}
```

## Fallback to JavaScript

WASM loader handles fallback automatically:

```typescript theme={null}
import * as RlpWasm from 'tevm/Rlp.wasm'

// Uses WASM if available, falls back to JS
const encoded = RlpWasm.encodeBytes(data)

// Check WASM availability
if (typeof WebAssembly !== 'undefined') {
  console.log('WASM available')
} else {
  console.log('Using JavaScript fallback')
}
```

## Limitations

Current WASM implementation has limitations:

**No decoding yet:**

```typescript theme={null}
// Available: encoding
import * as RlpWasm from 'tevm/Rlp.wasm'
const encoded = RlpWasm.encodeBytes(data)

// Not available: decoding (use JS)
import { Rlp } from 'tevm'
const decoded = Rlp.decode(encoded)
```

**No list encoding:**

```typescript theme={null}
// Not available: encodeList (use JS)
import { Rlp } from 'tevm'
const encoded = Rlp.encodeList([bytes1, bytes2])
```

**32-byte constraint for uint:**

```typescript theme={null}
// Must be exactly 32 bytes
const value = Bytes32()
RlpWasm.encodeUint(value)  // OK

const wrong = Bytes16()
RlpWasm.encodeUint(wrong)  // Error
```

## Future Enhancements

Planned WASM features:

* **decode** - WASM decoding implementation
* **encodeList** - WASM list encoding
* **stream encoding** - Streaming encode support
* **parallel encoding** - Multi-threaded encoding for large data

<Aside type="tip">
  For best performance, use WASM for encoding hot paths and JavaScript for decoding and list operations until full WASM API available.
</Aside>

## Override Patterns

Replace JavaScript methods with WASM:

```typescript theme={null}
import { Rlp } from 'tevm'
import * as RlpWasm from 'tevm/Rlp.wasm'

// Override encodeBytes with WASM version
const originalEncodeBytes = Rlp.encodeBytes
Rlp.encodeBytes = RlpWasm.encodeBytes

// Now Rlp.encodeBytes uses WASM
const encoded = Rlp.encodeBytes(new Uint8Array([1, 2, 3]))

// Restore original
Rlp.encodeBytes = originalEncodeBytes
```

Or create hybrid encoder:

```typescript theme={null}
import { Rlp } from 'tevm'
import * as RlpWasm from 'tevm/Rlp.wasm'

function encodeBytes(data: Uint8Array): Uint8Array {
  // Use WASM for large data
  if (data.length > 1000) {
    return RlpWasm.encodeBytes(data)
  }

  // Use JS for small data (less overhead)
  return Rlp.encodeBytes(data)
}
```

## Related

* [Encoding](/primitives/rlp/encoding) - JavaScript encoding
* [Algorithm](/primitives/rlp/algorithm) - RLP specification
* [Performance](/primitives/rlp/performance) - Optimization tips
