Skip to main content
Tree-shakeable functional API for CallData operations with optimal bundle size.

Overview

CallDataType is the functional layer underlying the CallData class. It provides:
  • Zero-overhead branded type wrapping Uint8Array
  • Tree-shakeable individual function exports
  • Data-first unopinionated methods taking calldata as first parameter
  • Bundle optimization through selective imports
Primary benefit: When using tree-shakeable imports, only the functions you use are included in your bundle.

Type Definition

CallDataType (Uint8Array)

The core CallData type is a branded Uint8Array:
import type { brand } from '@tevm/voltaire/brand';

export type CallDataType = Uint8Array & {
  readonly [brand]: "CallData";
};
Properties:
  • Size: Variable length (minimum 4 bytes for selector)
  • Branding: Uses Symbol branding via brand symbol
  • Conceptual relation: Subtypes Hex (variable-length hex-encoded byte data)
  • Type safety: Prevents accidental mixing with other Uint8Arrays or arbitrary Hex values
Defined in: primitives/CallData/CallDataType.ts

Relationship to Hex

CallData is conceptually a Hex subtype with additional semantics:
// Conceptual hierarchy
Uint8Array
  └─ Hex (hex-encoded bytes)
      └─ CallData (transaction data with function selector)
While CallData uses Uint8Array internally for performance, it represents hex-encoded data that:
  1. Starts with a 4-byte function selector
  2. Follows with ABI-encoded parameters
  3. Validates to proper calldata structure

CallDataDecoded Structure

The decoded form represents parsed calldata:
export type CallDataDecoded = {
  /// 4-byte function selector
  selector: [4]u8;

  /// Optional function signature (e.g., "transfer(address,uint256)")
  /// Useful for debugging, not required for execution
  signature: ?[]const u8;

  /// Decoded ABI parameters
  parameters: []AbiValue;

  /// Memory allocator (Zig only)
  allocator: std.mem.Allocator;
};
Fields:
  • selector - Required 4-byte function identifier
  • signature - Optional human-readable function signature
  • parameters - Decoded parameters as structured ABI values
  • allocator - Memory management (Zig implementation)

Available Functions

All CallData functionality available as tree-shakeable functions:

Constructors

import {
  from,
  fromHex,
  fromBytes,
  encode,
} from '@tevm/voltaire/CallData';

// Universal constructor
const calldata1 = from("0xa9059cbb...");

// From hex string
const calldata2 = fromHex("0xa9059cbb...");

// From Uint8Array
const bytes = new Uint8Array([0xa9, 0x05, 0x9c, 0xbb, ...]);
const calldata3 = fromBytes(bytes);

// Encode from function signature + parameters
const calldata4 = encode("transfer(address,uint256)", [addr, amount]);

Conversions

import {
  toHex,
  toBytes,
  decode,
} from '@tevm/voltaire/CallData';

// To hex string
const hex: HexType = toHex(calldata);

// To raw bytes
const bytes: Uint8Array = toBytes(calldata);

// To decoded structure
const decoded: CallDataDecoded = decode(calldata, abi);

Selectors

import {
  getSelector,
  hasSelector,
} from '@tevm/voltaire/CallData';

// Extract function selector
const selector: [4]u8 = getSelector(calldata);

// Check for specific selector
const isTransfer: boolean = hasSelector(calldata, "0xa9059cbb");

Validation

import {
  isValid,
  is,
} from '@tevm/voltaire/CallData';

// Check if value can be converted
const canConvert: boolean = isValid("0xa9059cbb...");

// Type guard
if (is(value)) {
  // value is CallDataType
  const selector = getSelector(value);
}

Comparisons

import {
  equals,
} from '@tevm/voltaire/CallData';

// Check equality
const same: boolean = equals(calldata1, calldata2);

Usage Patterns

Tree-Shakeable Imports

Import only what you need:
// Only these functions included in bundle
import { from, toHex, getSelector } from '@tevm/voltaire/CallData';

const calldata = from("0xa9059cbb...");
const hex = toHex(calldata);
const selector = getSelector(calldata);

// Other CallData functions (encode, decode, etc.) excluded from bundle

Functional Style

Data-first API for composition:
import * as CallData from '@tevm/voltaire/CallData';

const process = (hex: string) =>
  CallData.getSelector(
    CallData.from(hex)
  );

const selector = process("0xa9059cbb...");

With Class API

Mix with class API when convenient:
import { CallData } from '@tevm/voltaire';
import { getSelector } from '@tevm/voltaire/CallData';

// Class API for construction
const calldata = CallData("0xa9059cbb...");

// Functional API for operations
const selector = getSelector(calldata);

Dual API Pattern

CallData provides both functional and class-based APIs:
import * as CallData from '@tevm/voltaire/CallData';

const calldata = CallData.from("0xa9059cbb...");
const selector = CallData.getSelector(calldata);
const hex = CallData.toHex(calldata);
Benefits:
  • Tree-shakeable
  • Functional composition
  • Minimal bundle impact

TypeScript vs Zig

import type { CallDataType } from '@tevm/voltaire/CallData';

// Branded Uint8Array
type CallDataType = Uint8Array & {
  readonly [brand]: "CallData";
};

// Runtime is plain Uint8Array
const calldata: CallDataType = new Uint8Array([0xa9, 0x05, 0x9c, 0xbb]);

See Also