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;