Search code examples
javascriptnode.jsstarknet

How to convert a string into a Cairo felt (field element)?


Cairo requires all data to be a felt. https://www.cairo-lang.org/docs/how_cairo_works/cairo_intro.html#field-elements

How to convert a string into a felt in JavaScript?


Solution

  • Here's how you can convert a string to a felt array. It's recommended to use a felt array as a normal felt can only carry 31 characters. If 31 characters is enough for you, then you can just use the first element of the array as your result : https://github.com/immutable/imx-starknet/blob/main/tests/utils/starknetUtils.ts#L60

    /**
     * Splits a string into an array of short strings (felts). A Cairo short string (felt) represents up to 31 utf-8 characters.
     * @param {string} str - The string to convert
     * @returns {bigint[]} - The string converted as an array of short strings as felts
     */
    export function strToFeltArr(str: string): BigInt[] {
      const size = Math.ceil(str.length / 31);
      const arr = Array(size);
    
      let offset = 0;
      for (let i = 0; i < size; i++) {
        const substr = str.substring(offset, offset + 31).split("");
        const ss = substr.reduce(
          (memo, c) => memo + c.charCodeAt(0).toString(16),
          ""
        );
        arr[i] = BigInt("0x" + ss);
        offset += 31;
      }
      return arr;
    }
    

    And vice versa

     * Converts an array of utf-8 numerical short strings into a readable string
     * @param {bigint[]} felts - The array of encoded short strings
     * @returns {string} - The readable string
     */
    export function feltArrToStr(felts: bigint[]): string {
      return felts.reduce(
        (memo, felt) => memo + Buffer.from(felt.toString(16), "hex").toString(),
        ""
      );
    }