Skip to main content

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.

Try it Live

Run Transaction examples in the interactive playground

detectType

Detect transaction type from serialized bytes.

    Type Detection Logic

    Typed Transactions (EIP-2718)

    Typed transactions start with a type byte (0x00-0x04):
    [type_byte, ...rlp_payload]
     ^^^^^^^^^^
     First byte indicates type
    
    First ByteType
    0x01EIP-2930 (Access List)
    0x02EIP-1559 (Dynamic Fee)
    0x03EIP-4844 (Blob)
    0x04EIP-7702 (Authorization)
    0xc0-0xffLegacy (RLP list marker)

    Legacy Transactions

    Legacy transactions start with RLP list marker (0xc0-0xff):
    [rlp_list_marker, ...rlp_content]
     ^^^^^^^^^^^^^^^^
     RLP list encoding (≥ 0xc0)
    
    RLP list markers:
    • 0xc0-0xf7: Short list (0-55 bytes)
    • 0xf8-0xff: Long list (>55 bytes)

    Usage Patterns

    Router Pattern

    import { detectType, Type } from 'tevm/Transaction'
    import { InvalidTransactionTypeError } from 'tevm/errors'
    
    function routeTransaction(data: Uint8Array) {
      const type = detectType(data)
    
      switch (type) {
        case Type.Legacy:
          return processLegacy(data)
        case Type.EIP2930:
          return processEIP2930(data)
        case Type.EIP1559:
          return processEIP1559(data)
        case Type.EIP4844:
          return processEIP4844(data)
        case Type.EIP7702:
          return processEIP7702(data)
        default:
          throw new InvalidTransactionTypeError(`Unsupported type: ${type}`, {
            code: 'UNSUPPORTED_TRANSACTION_TYPE',
            context: { type }
          })
      }
    }
    

    Conditional Deserialization

    import { detectType, deserialize, Type } from 'tevm/Transaction'
    
    function parseTransaction(data: Uint8Array) {
      const type = detectType(data)
    
      // Can optimize deserialization based on type
      if (type === Type.Legacy) {
        return deserializeLegacy(data)
      } else {
        return deserialize(data)
      }
    }
    

    Transaction Classification

    import { detectType, Type } from 'tevm/Transaction'
    
    function classifyTransactions(
      transactions: Uint8Array[]
    ): Map<Transaction.Type, number> {
      const counts = new Map<Transaction.Type, number>()
    
      for (const data of transactions) {
        const type = detectType(data)
        counts.set(type, (counts.get(type) || 0) + 1)
      }
    
      return counts
    }
    
    // Usage
    const txData = [/* serialized transactions */]
    const counts = classifyTransactions(txData)
    
    console.log(`Legacy: ${counts.get(Type.Legacy) || 0}`)
    console.log(`EIP-1559: ${counts.get(Type.EIP1559) || 0}`)
    console.log(`EIP-4844: ${counts.get(Type.EIP4844) || 0}`)
    

    Block Analysis

    import { detectType, Type } from 'tevm/Transaction'
    
    interface BlockStats {
      totalTransactions: number
      byType: Record<string, number>
    }
    
    function analyzeBlock(transactions: Uint8Array[]): BlockStats {
      const byType: Record<string, number> = {}
    
      for (const data of transactions) {
        const type = detectType(data)
        const typeName = getTypeName(type)
        byType[typeName] = (byType[typeName] || 0) + 1
      }
    
      return {
        totalTransactions: transactions.length,
        byType
      }
    }
    
    function getTypeName(type: Transaction.Type): string {
      switch (type) {
        case Type.Legacy: return 'Legacy'
        case Type.EIP2930: return 'EIP-2930'
        case Type.EIP1559: return 'EIP-1559'
        case Type.EIP4844: return 'EIP-4844'
        case Type.EIP7702: return 'EIP-7702'
        default: return `Unknown (${type})`
      }
    }
    

    Network Statistics

    import { detectType, Type } from 'tevm/Transaction'
    
    class NetworkMonitor {
      private stats = new Map<Transaction.Type, number>()
    
      processTransaction(data: Uint8Array) {
        const type = detectType(data)
        this.stats.set(type, (this.stats.get(type) || 0) + 1)
      }
    
      getStats() {
        return {
          legacy: this.stats.get(Type.Legacy) || 0,
          eip2930: this.stats.get(Type.EIP2930) || 0,
          eip1559: this.stats.get(Type.EIP1559) || 0,
          eip4844: this.stats.get(Type.EIP4844) || 0,
          eip7702: this.stats.get(Type.EIP7702) || 0,
          total: Array(this.stats.values()).reduce((a, b) => a + b, 0)
        }
      }
    }
    

    Pre-validation

    import { detectType, Type } from 'tevm/Transaction'
    
    function validateTransactionType(
      data: Uint8Array,
      allowedTypes: Transaction.Type[]
    ): boolean {
      try {
        const type = detectType(data)
        return allowedTypes.includes(type)
      } catch {
        return false
      }
    }
    
    // Usage: Only allow EIP-1559 and EIP-4844
    import { InvalidTransactionTypeError } from 'tevm/errors'
    
    const allowed = [Type.EIP1559, Type.EIP4844]
    if (!validateTransactionType(txData, allowed)) {
      throw new InvalidTransactionTypeError('Transaction type not supported', {
        code: 'UNSUPPORTED_TRANSACTION_TYPE',
        context: { allowed }
      })
    }
    

    Efficient Filtering

    import { detectType, Type } from 'tevm/Transaction'
    
    function filterByType(
      transactions: Uint8Array[],
      targetType: Transaction.Type
    ): Uint8Array[] {
      return transactions.filter(data => {
        try {
          return detectType(data) === targetType
        } catch {
          return false
        }
      })
    }
    
    // Get only EIP-4844 blob transactions
    const blobTxs = filterByType(allTransactions, Type.EIP4844)
    

    Error Handling

    import { detectType } from 'tevm/Transaction'
    
    function safeDetectType(data: Uint8Array): Transaction.Type | null {
      try {
        return detectType(data)
      } catch (error) {
        console.error('Type detection failed:', error)
        return null
      }
    }
    
    // Usage
    const type = safeDetectType(txData)
    if (type === null) {
      console.log('Invalid or unknown transaction type')
    }
    

    Type Guard Pattern

    import { detectType, Type } from 'tevm/Transaction'
    
    function isLegacyTransaction(data: Uint8Array): boolean {
      return detectType(data) === Type.Legacy
    }
    
    function isEIP1559Transaction(data: Uint8Array): boolean {
      return detectType(data) === Type.EIP1559
    }
    
    function isBlobTransaction(data: Uint8Array): boolean {
      return detectType(data) === Type.EIP4844
    }
    

    See Also

    References