/ src / services / configService.js
configService.js
  1  import { getAppDataDir, getDefaultCodexRootPath } from "../utils/appData.js";
  2  
  3  const defaultConfig = {
  4    codexRoot: getDefaultCodexRootPath(),
  5    storageQuota: 8 * 1024 * 1024 * 1024,
  6    ports: {
  7      discPort: 8090,
  8      listenPort: 8070,
  9      apiPort: 8080,
 10    },
 11  };
 12  
 13  const datadir = "datadir";
 14  const codexLogFile = "codex.log";
 15  const codexConfigFile = "config.toml";
 16  const ethKeyFile = "eth.key";
 17  const ethAddressFile = "eth.address";
 18  
 19  export class ConfigService {
 20    constructor(fsService, osService) {
 21      this.fs = fsService;
 22      this.os = osService;
 23      this.loadConfig();
 24    }
 25  
 26    get = () => {
 27      return this.config;
 28    };
 29  
 30    getCodexExe = () => {
 31      var codexExe = "codex";
 32      if (this.os.isWindows()) {
 33        codexExe = "codex.exe";
 34      }
 35  
 36      return this.fs.pathJoin([this.config.codexRoot, codexExe]);
 37    };
 38  
 39    getCodexConfigFilePath = () => {
 40      return this.fs.pathJoin([this.config.codexRoot, codexConfigFile]);
 41    };
 42  
 43    getEthFilePaths = () => {
 44      return {
 45        key: this.fs.pathJoin([this.config.codexRoot, ethKeyFile]),
 46        address: this.fs.pathJoin([this.config.codexRoot, ethAddressFile]),
 47      };
 48    };
 49  
 50    loadConfig = () => {
 51      const filePath = this.getConfigFilename();
 52      try {
 53        if (!this.fs.isFile(filePath)) {
 54          this.config = defaultConfig;
 55          this.saveConfig();
 56        } else {
 57          this.config = this.fs.readJsonFile(filePath);
 58  
 59          if (this.config.codexRoot == undefined) {
 60            this.config = defaultConfig;
 61            this.saveConfig();
 62          }
 63        }
 64      } catch (error) {
 65        console.error(
 66          `Failed to load config file from '${filePath}' error: '${error}'.`,
 67        );
 68        throw error;
 69      }
 70    };
 71  
 72    saveConfig = () => {
 73      const filePath = this.getConfigFilename();
 74      try {
 75        this.fs.writeJsonFile(filePath, this.config);
 76      } catch (error) {
 77        console.error(
 78          `Failed to save config file to '${filePath}' error: '${error}'.`,
 79        );
 80        throw error;
 81      }
 82    };
 83  
 84    getConfigFilename = () => {
 85      return this.fs.pathJoin([getAppDataDir(), "config.json"]);
 86    };
 87  
 88    validateConfiguration = () => {
 89      if (this.config.storageQuota < 1024 * 1024 * 100)
 90        throw new Error("Storage quota must be at least 100MB");
 91    };
 92  
 93    writeCodexConfigFile = (publicIp, bootstrapNodes, ethProvider) => {
 94      this.validateConfiguration();
 95  
 96      const nl = "\n";
 97      const bootNodes = bootstrapNodes.map((v) => `"${v}"`).join(",");
 98  
 99      this.fs.writeFile(
100        this.getCodexConfigFilePath(),
101        `data-dir="${datadir}"${nl}` +
102          `log-level="DEBUG"${nl}` +
103          `log-file="${codexLogFile}"${nl}` +
104          `storage-quota=${this.config.storageQuota}${nl}` +
105          `disc-port=${this.config.ports.discPort}${nl}` +
106          `listen-addrs=["/ip4/0.0.0.0/tcp/${this.config.ports.listenPort}"]${nl}` +
107          `api-port=${this.config.ports.apiPort}${nl}` +
108          `nat="extip:${publicIp}"${nl}` +
109          `api-cors-origin="*"${nl}` +
110          `bootstrap-node=[${bootNodes}]${nl}` +
111          // Marketplace client parameters cannot be set via config file.
112          // Open issue: https://github.com/codex-storage/nim-codex/issues/1206
113          "",
114      );
115    };
116  }