github.com/ethereum-optimism/optimism@v1.7.2/packages/core-utils/src/common/hex-strings.ts (about)

     1  /* Imports: External */
     2  import { BigNumber } from '@ethersproject/bignumber'
     3  import { isHexString, hexZeroPad } from '@ethersproject/bytes'
     4  
     5  /**
     6   * Removes "0x" from start of a string if it exists.
     7   *
     8   * @param str String to modify.
     9   * @returns the string without "0x".
    10   */
    11  export const remove0x = (str: string): string => {
    12    if (str === undefined) {
    13      return str
    14    }
    15    return str.startsWith('0x') ? str.slice(2) : str
    16  }
    17  
    18  /**
    19   * Adds "0x" to the start of a string if necessary.
    20   *
    21   * @param str String to modify.
    22   * @returns the string with "0x".
    23   */
    24  export const add0x = (str: string): string => {
    25    if (str === undefined) {
    26      return str
    27    }
    28    return str.startsWith('0x') ? str : '0x' + str
    29  }
    30  
    31  /**
    32   * Casts a hex string to a buffer.
    33   *
    34   * @param inp Input to cast to a buffer.
    35   * @return Input cast as a buffer.
    36   */
    37  export const fromHexString = (inp: Buffer | string): Buffer => {
    38    if (typeof inp === 'string' && inp.startsWith('0x')) {
    39      return Buffer.from(inp.slice(2), 'hex')
    40    }
    41  
    42    return Buffer.from(inp)
    43  }
    44  
    45  /**
    46   * Casts an input to a hex string.
    47   *
    48   * @param inp Input to cast to a hex string.
    49   * @return Input cast as a hex string.
    50   */
    51  export const toHexString = (inp: Buffer | string | number | null): string => {
    52    if (typeof inp === 'number') {
    53      return BigNumber.from(inp).toHexString()
    54    } else {
    55      return '0x' + fromHexString(inp).toString('hex')
    56    }
    57  }
    58  
    59  /**
    60   * Casts a number to a hex string without zero padding.
    61   *
    62   * @param n Number to cast to a hex string.
    63   * @return Number cast as a hex string.
    64   */
    65  export const toRpcHexString = (n: number | BigNumber): string => {
    66    let num
    67    if (typeof n === 'number') {
    68      num = '0x' + n.toString(16)
    69    } else {
    70      num = n.toHexString()
    71    }
    72  
    73    if (num === '0x0') {
    74      return num
    75    } else {
    76      // BigNumber pads a single 0 to keep hex length even
    77      return num.replace(/^0x0/, '0x')
    78    }
    79  }
    80  
    81  /**
    82   * Zero pads a hex string if str.length !== 2 + length * 2. Pads to length * 2.
    83   *
    84   * @param str Hex string to pad
    85   * @param length Half the length of the desired padded hex string
    86   * @return Hex string with length of 2 + length * 2
    87   */
    88  export const padHexString = (str: string, length: number): string => {
    89    if (str.length === 2 + length * 2) {
    90      return str
    91    } else {
    92      return '0x' + str.slice(2).padStart(length * 2, '0')
    93    }
    94  }
    95  
    96  /**
    97   * Casts an input to hex string without '0x' prefix with conditional padding.
    98   * Hex string will always start with a 0.
    99   *
   100   * @param val Input to cast to a hex string.
   101   * @param len Desired length to pad hex string. Ignored if less than hex string length.
   102   * @return Hex string with '0' prefix
   103   */
   104  export const encodeHex = (val: any, len: number): string =>
   105    remove0x(BigNumber.from(val).toHexString()).padStart(len, '0')
   106  
   107  /**
   108   * Case insensitive hex string equality check
   109   *
   110   * @param stringA Hex string A
   111   * @param stringB Hex string B
   112   * @throws {Error} Inputs must be valid hex strings
   113   * @return True if equal
   114   */
   115  export const hexStringEquals = (stringA: string, stringB: string): boolean => {
   116    if (!isHexString(stringA)) {
   117      throw new Error(`input is not a hex string: ${stringA}`)
   118    }
   119  
   120    if (!isHexString(stringB)) {
   121      throw new Error(`input is not a hex string: ${stringB}`)
   122    }
   123  
   124    return stringA.toLowerCase() === stringB.toLowerCase()
   125  }
   126  
   127  /**
   128   * Casts a number to a 32-byte, zero padded hex string.
   129   *
   130   * @param value Number to cast to a hex string.
   131   * @return Number cast as a hex string.
   132   */
   133  export const bytes32ify = (value: number | BigNumber): string => {
   134    return hexZeroPad(BigNumber.from(value).toHexString(), 32)
   135  }