/ bindings / node.js / lib / kzg.js
kzg.js
 1  /**
 2   * The public interface of this module exposes the functions as specified by
 3   * https://github.com/ethereum/consensus-specs/blob/dev/specs/eip4844/polynomial-commitments.md#kzg
 4   */
 5  const fs = require("fs");
 6  const path = require("path");
 7  const bindings = require("bindings")("kzg");
 8  
 9  /**
10   * NOTE: This path is only exported for testing purposes. It is not announced in
11   * the type file.
12   * 
13   * It is critical that this path is kept in sync with where the trusted setup
14   * file will be found. The path is dictated by the `build` command in the
15   * Makefile in the bindings/node.js folder.
16   * 
17   * This path works for two situations:
18   * 1) Production case
19   * - this file in BUNDLE_ROOT/dist/lib/kzg.js
20   * - trusted_setup in BUNDLE_ROOT/dist/deps/c-kzg/trusted_setup.txt
21   * 
22   *  2) Post `build` state before `bundle` command works
23   * - this file in bindings/node.js/lib/kzg.js
24   * - trusted_setup in bindings/node.js/deps/c-kzg/trusted_setup.txt
25   */
26  bindings.DEFAULT_TRUSTED_SETUP_PATH = path.resolve(__dirname, "..", "deps", "c-kzg", "trusted_setup.txt");
27  
28  /**
29   * Converts JSON formatted trusted setup into the native format that
30   * the native library requires.  Returns the absolute file path to
31   * the formatted file.  The path will be the same as the origin
32   * file but with a ".txt" extension.
33   *
34   * @param {string} filePath - The absolute path of JSON formatted trusted setup
35   *
36   * @return {string} - The absolute path of the re-formatted trusted setup
37   *
38   * @throws {Error} - For invalid file operations
39   */
40  function transformTrustedSetupJson(filePath) {
41    const trustedSetup = JSON.parse(fs.readFileSync(filePath, "utf8"));
42    const setupText =
43      bindings.FIELD_ELEMENTS_PER_BLOB +
44      "\n65\n" +
45      trustedSetup.g1_lagrange.map((p) => p.substring(2)).join("\n") +
46      "\n" +
47      trustedSetup.g2_monomial.map((p) => p.substring(2)).join("\n");
48    const outputPath = filePath.replace(".json", ".txt");
49    fs.writeFileSync(outputPath, setupText);
50    return outputPath;
51  }
52  
53  /**
54   * Gets location for trusted setup file. Uses user provided location first. If
55   * one is not provided then defaults to the official Ethereum mainnet setup from
56   * the KZG ceremony.
57   *
58   * @param {string} filePath - User provided filePath to check for trusted setup
59   *
60   * @returns {string} - Location of a trusted setup file. Validity is checked by
61   *                     the native bindings.loadTrustedSetup
62   *
63   * @throws {TypeError} - Invalid file type
64   * @throws {Error} - Invalid location or no default trusted setup found
65   *
66   * @remarks - This function is only exported for testing purposes. It should
67   *            not be used directly. Not included in the kzg.d.ts types for that
68   *            reason.
69   */
70  bindings.getTrustedSetupFilepath = function getTrustedSetupFilepath(filePath) {
71    if (filePath) {
72      if (typeof filePath !== "string") {
73        throw new TypeError("Must initialize kzg with the filePath to a txt/json trusted setup");
74      }
75      if (!fs.existsSync(filePath)) {
76        throw new Error(`No trusted setup found: ${filePath}`);
77      }
78    } else {
79      filePath = bindings.DEFAULT_TRUSTED_SETUP_PATH;
80      if (!fs.existsSync(filePath)) {
81        throw new Error("Default trusted setup not found. Must pass a valid filepath to load c-kzg library");
82      }
83    }
84  
85    if (path.parse(filePath).ext === ".json") {
86      filePath = transformTrustedSetupJson(filePath);
87    }
88  
89    return filePath;
90  };
91  
92  const originalLoadTrustedSetup = bindings.loadTrustedSetup;
93  // docstring in ./kzg.d.ts with exported definition
94  bindings.loadTrustedSetup = function loadTrustedSetup(filePath) {
95    originalLoadTrustedSetup(bindings.getTrustedSetupFilepath(filePath));
96  };
97  
98  module.exports = exports = bindings;