genlayer 0.0.20 → 0.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,7 @@
1
1
 
2
2
 
3
+ ## 0.0.21 (2024-04-30)
4
+
3
5
  ## 0.0.20 (2024-04-26)
4
6
 
5
7
  ## 0.0.19 (2024-04-26)
package/dist/index.js CHANGED
@@ -34416,6 +34416,345 @@ var require_set = __commonJS({
34416
34416
  }
34417
34417
  });
34418
34418
 
34419
+ // node_modules/dotenv/package.json
34420
+ var require_package = __commonJS({
34421
+ "node_modules/dotenv/package.json"(exports2, module2) {
34422
+ module2.exports = {
34423
+ name: "dotenv",
34424
+ version: "16.4.5",
34425
+ description: "Loads environment variables from .env file",
34426
+ main: "lib/main.js",
34427
+ types: "lib/main.d.ts",
34428
+ exports: {
34429
+ ".": {
34430
+ types: "./lib/main.d.ts",
34431
+ require: "./lib/main.js",
34432
+ default: "./lib/main.js"
34433
+ },
34434
+ "./config": "./config.js",
34435
+ "./config.js": "./config.js",
34436
+ "./lib/env-options": "./lib/env-options.js",
34437
+ "./lib/env-options.js": "./lib/env-options.js",
34438
+ "./lib/cli-options": "./lib/cli-options.js",
34439
+ "./lib/cli-options.js": "./lib/cli-options.js",
34440
+ "./package.json": "./package.json"
34441
+ },
34442
+ scripts: {
34443
+ "dts-check": "tsc --project tests/types/tsconfig.json",
34444
+ lint: "standard",
34445
+ "lint-readme": "standard-markdown",
34446
+ pretest: "npm run lint && npm run dts-check",
34447
+ test: "tap tests/*.js --100 -Rspec",
34448
+ "test:coverage": "tap --coverage-report=lcov",
34449
+ prerelease: "npm test",
34450
+ release: "standard-version"
34451
+ },
34452
+ repository: {
34453
+ type: "git",
34454
+ url: "git://github.com/motdotla/dotenv.git"
34455
+ },
34456
+ funding: "https://dotenvx.com",
34457
+ keywords: [
34458
+ "dotenv",
34459
+ "env",
34460
+ ".env",
34461
+ "environment",
34462
+ "variables",
34463
+ "config",
34464
+ "settings"
34465
+ ],
34466
+ readmeFilename: "README.md",
34467
+ license: "BSD-2-Clause",
34468
+ devDependencies: {
34469
+ "@definitelytyped/dtslint": "^0.0.133",
34470
+ "@types/node": "^18.11.3",
34471
+ decache: "^4.6.1",
34472
+ sinon: "^14.0.1",
34473
+ standard: "^17.0.0",
34474
+ "standard-markdown": "^7.1.0",
34475
+ "standard-version": "^9.5.0",
34476
+ tap: "^16.3.0",
34477
+ tar: "^6.1.11",
34478
+ typescript: "^4.8.4"
34479
+ },
34480
+ engines: {
34481
+ node: ">=12"
34482
+ },
34483
+ browser: {
34484
+ fs: false
34485
+ }
34486
+ };
34487
+ }
34488
+ });
34489
+
34490
+ // node_modules/dotenv/lib/main.js
34491
+ var require_main2 = __commonJS({
34492
+ "node_modules/dotenv/lib/main.js"(exports2, module2) {
34493
+ "use strict";
34494
+ var fs3 = require("fs");
34495
+ var path = require("path");
34496
+ var os3 = require("os");
34497
+ var crypto3 = require("crypto");
34498
+ var packageJson = require_package();
34499
+ var version2 = packageJson.version;
34500
+ var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
34501
+ function parse2(src) {
34502
+ const obj = {};
34503
+ let lines = src.toString();
34504
+ lines = lines.replace(/\r\n?/mg, "\n");
34505
+ let match;
34506
+ while ((match = LINE.exec(lines)) != null) {
34507
+ const key = match[1];
34508
+ let value = match[2] || "";
34509
+ value = value.trim();
34510
+ const maybeQuote = value[0];
34511
+ value = value.replace(/^(['"`])([\s\S]*)\1$/mg, "$2");
34512
+ if (maybeQuote === '"') {
34513
+ value = value.replace(/\\n/g, "\n");
34514
+ value = value.replace(/\\r/g, "\r");
34515
+ }
34516
+ obj[key] = value;
34517
+ }
34518
+ return obj;
34519
+ }
34520
+ function _parseVault(options) {
34521
+ const vaultPath = _vaultPath(options);
34522
+ const result = DotenvModule.configDotenv({ path: vaultPath });
34523
+ if (!result.parsed) {
34524
+ const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`);
34525
+ err.code = "MISSING_DATA";
34526
+ throw err;
34527
+ }
34528
+ const keys = _dotenvKey(options).split(",");
34529
+ const length = keys.length;
34530
+ let decrypted;
34531
+ for (let i2 = 0; i2 < length; i2++) {
34532
+ try {
34533
+ const key = keys[i2].trim();
34534
+ const attrs = _instructions(result, key);
34535
+ decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key);
34536
+ break;
34537
+ } catch (error) {
34538
+ if (i2 + 1 >= length) {
34539
+ throw error;
34540
+ }
34541
+ }
34542
+ }
34543
+ return DotenvModule.parse(decrypted);
34544
+ }
34545
+ function _log(message) {
34546
+ console.log(`[dotenv@${version2}][INFO] ${message}`);
34547
+ }
34548
+ function _warn(message) {
34549
+ console.log(`[dotenv@${version2}][WARN] ${message}`);
34550
+ }
34551
+ function _debug(message) {
34552
+ console.log(`[dotenv@${version2}][DEBUG] ${message}`);
34553
+ }
34554
+ function _dotenvKey(options) {
34555
+ if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {
34556
+ return options.DOTENV_KEY;
34557
+ }
34558
+ if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {
34559
+ return process.env.DOTENV_KEY;
34560
+ }
34561
+ return "";
34562
+ }
34563
+ function _instructions(result, dotenvKey) {
34564
+ let uri;
34565
+ try {
34566
+ uri = new URL(dotenvKey);
34567
+ } catch (error) {
34568
+ if (error.code === "ERR_INVALID_URL") {
34569
+ const err = new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development");
34570
+ err.code = "INVALID_DOTENV_KEY";
34571
+ throw err;
34572
+ }
34573
+ throw error;
34574
+ }
34575
+ const key = uri.password;
34576
+ if (!key) {
34577
+ const err = new Error("INVALID_DOTENV_KEY: Missing key part");
34578
+ err.code = "INVALID_DOTENV_KEY";
34579
+ throw err;
34580
+ }
34581
+ const environment = uri.searchParams.get("environment");
34582
+ if (!environment) {
34583
+ const err = new Error("INVALID_DOTENV_KEY: Missing environment part");
34584
+ err.code = "INVALID_DOTENV_KEY";
34585
+ throw err;
34586
+ }
34587
+ const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`;
34588
+ const ciphertext = result.parsed[environmentKey];
34589
+ if (!ciphertext) {
34590
+ const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`);
34591
+ err.code = "NOT_FOUND_DOTENV_ENVIRONMENT";
34592
+ throw err;
34593
+ }
34594
+ return { ciphertext, key };
34595
+ }
34596
+ function _vaultPath(options) {
34597
+ let possibleVaultPath = null;
34598
+ if (options && options.path && options.path.length > 0) {
34599
+ if (Array.isArray(options.path)) {
34600
+ for (const filepath of options.path) {
34601
+ if (fs3.existsSync(filepath)) {
34602
+ possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
34603
+ }
34604
+ }
34605
+ } else {
34606
+ possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
34607
+ }
34608
+ } else {
34609
+ possibleVaultPath = path.resolve(process.cwd(), ".env.vault");
34610
+ }
34611
+ if (fs3.existsSync(possibleVaultPath)) {
34612
+ return possibleVaultPath;
34613
+ }
34614
+ return null;
34615
+ }
34616
+ function _resolveHome(envPath) {
34617
+ return envPath[0] === "~" ? path.join(os3.homedir(), envPath.slice(1)) : envPath;
34618
+ }
34619
+ function _configVault(options) {
34620
+ _log("Loading env from encrypted .env.vault");
34621
+ const parsed = DotenvModule._parseVault(options);
34622
+ let processEnv = process.env;
34623
+ if (options && options.processEnv != null) {
34624
+ processEnv = options.processEnv;
34625
+ }
34626
+ DotenvModule.populate(processEnv, parsed, options);
34627
+ return { parsed };
34628
+ }
34629
+ function configDotenv(options) {
34630
+ const dotenvPath = path.resolve(process.cwd(), ".env");
34631
+ let encoding = "utf8";
34632
+ const debug = Boolean(options && options.debug);
34633
+ if (options && options.encoding) {
34634
+ encoding = options.encoding;
34635
+ } else {
34636
+ if (debug) {
34637
+ _debug("No encoding is specified. UTF-8 is used by default");
34638
+ }
34639
+ }
34640
+ let optionPaths = [dotenvPath];
34641
+ if (options && options.path) {
34642
+ if (!Array.isArray(options.path)) {
34643
+ optionPaths = [_resolveHome(options.path)];
34644
+ } else {
34645
+ optionPaths = [];
34646
+ for (const filepath of options.path) {
34647
+ optionPaths.push(_resolveHome(filepath));
34648
+ }
34649
+ }
34650
+ }
34651
+ let lastError;
34652
+ const parsedAll = {};
34653
+ for (const path2 of optionPaths) {
34654
+ try {
34655
+ const parsed = DotenvModule.parse(fs3.readFileSync(path2, { encoding }));
34656
+ DotenvModule.populate(parsedAll, parsed, options);
34657
+ } catch (e2) {
34658
+ if (debug) {
34659
+ _debug(`Failed to load ${path2} ${e2.message}`);
34660
+ }
34661
+ lastError = e2;
34662
+ }
34663
+ }
34664
+ let processEnv = process.env;
34665
+ if (options && options.processEnv != null) {
34666
+ processEnv = options.processEnv;
34667
+ }
34668
+ DotenvModule.populate(processEnv, parsedAll, options);
34669
+ if (lastError) {
34670
+ return { parsed: parsedAll, error: lastError };
34671
+ } else {
34672
+ return { parsed: parsedAll };
34673
+ }
34674
+ }
34675
+ function config(options) {
34676
+ if (_dotenvKey(options).length === 0) {
34677
+ return DotenvModule.configDotenv(options);
34678
+ }
34679
+ const vaultPath = _vaultPath(options);
34680
+ if (!vaultPath) {
34681
+ _warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`);
34682
+ return DotenvModule.configDotenv(options);
34683
+ }
34684
+ return DotenvModule._configVault(options);
34685
+ }
34686
+ function decrypt(encrypted, keyStr) {
34687
+ const key = Buffer.from(keyStr.slice(-64), "hex");
34688
+ let ciphertext = Buffer.from(encrypted, "base64");
34689
+ const nonce = ciphertext.subarray(0, 12);
34690
+ const authTag = ciphertext.subarray(-16);
34691
+ ciphertext = ciphertext.subarray(12, -16);
34692
+ try {
34693
+ const aesgcm = crypto3.createDecipheriv("aes-256-gcm", key, nonce);
34694
+ aesgcm.setAuthTag(authTag);
34695
+ return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
34696
+ } catch (error) {
34697
+ const isRange = error instanceof RangeError;
34698
+ const invalidKeyLength = error.message === "Invalid key length";
34699
+ const decryptionFailed = error.message === "Unsupported state or unable to authenticate data";
34700
+ if (isRange || invalidKeyLength) {
34701
+ const err = new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");
34702
+ err.code = "INVALID_DOTENV_KEY";
34703
+ throw err;
34704
+ } else if (decryptionFailed) {
34705
+ const err = new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");
34706
+ err.code = "DECRYPTION_FAILED";
34707
+ throw err;
34708
+ } else {
34709
+ throw error;
34710
+ }
34711
+ }
34712
+ }
34713
+ function populate(processEnv, parsed, options = {}) {
34714
+ const debug = Boolean(options && options.debug);
34715
+ const override = Boolean(options && options.override);
34716
+ if (typeof parsed !== "object") {
34717
+ const err = new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
34718
+ err.code = "OBJECT_REQUIRED";
34719
+ throw err;
34720
+ }
34721
+ for (const key of Object.keys(parsed)) {
34722
+ if (Object.prototype.hasOwnProperty.call(processEnv, key)) {
34723
+ if (override === true) {
34724
+ processEnv[key] = parsed[key];
34725
+ }
34726
+ if (debug) {
34727
+ if (override === true) {
34728
+ _debug(`"${key}" is already defined and WAS overwritten`);
34729
+ } else {
34730
+ _debug(`"${key}" is already defined and was NOT overwritten`);
34731
+ }
34732
+ }
34733
+ } else {
34734
+ processEnv[key] = parsed[key];
34735
+ }
34736
+ }
34737
+ }
34738
+ var DotenvModule = {
34739
+ configDotenv,
34740
+ _configVault,
34741
+ _parseVault,
34742
+ config,
34743
+ decrypt,
34744
+ parse: parse2,
34745
+ populate
34746
+ };
34747
+ module2.exports.configDotenv = DotenvModule.configDotenv;
34748
+ module2.exports._configVault = DotenvModule._configVault;
34749
+ module2.exports._parseVault = DotenvModule._parseVault;
34750
+ module2.exports.config = DotenvModule.config;
34751
+ module2.exports.decrypt = DotenvModule.decrypt;
34752
+ module2.exports.parse = DotenvModule.parse;
34753
+ module2.exports.populate = DotenvModule.populate;
34754
+ module2.exports = DotenvModule;
34755
+ }
34756
+ });
34757
+
34419
34758
  // node_modules/web-streams-polyfill/dist/ponyfill.es2018.js
34420
34759
  var require_ponyfill_es2018 = __commonJS({
34421
34760
  "node_modules/web-streams-polyfill/dist/ponyfill.es2018.js"(exports2, module2) {
@@ -39556,7 +39895,7 @@ var {
39556
39895
  } = import_index.default;
39557
39896
 
39558
39897
  // package.json
39559
- var version = "0.0.20";
39898
+ var version = "0.0.21";
39560
39899
 
39561
39900
  // src/lib/config/text.ts
39562
39901
  var CLI_DESCRIPTION = "GenLayer CLI is a development environment for the GenLayer ecosystem. It allows developers to interact with the protocol by creating accounts, sending transactions, and working with Intelligent Contracts by testing, debugging, and deploying them.";
@@ -42148,8 +42487,35 @@ var inquirer = {
42148
42487
  };
42149
42488
  var inquirer_default = inquirer;
42150
42489
 
42490
+ // src/lib/config/simulator.ts
42491
+ var DEFAULT_JSON_RPC_URL = "http://localhost:4000/api";
42492
+ var DEFAULT_REPO_GH_URL = "git@github.com:yeagerai/genlayer-simulator.git";
42493
+ var DEFAULT_CONFIG_SIMULATOR_COMMAND = (simulatorLocation) => ({
42494
+ darwin: `cd ${simulatorLocation} && cp .env.example .env`,
42495
+ win32: `cd ${simulatorLocation} && xcopy .env.example .env`,
42496
+ linux: `cd ${simulatorLocation} && cp .env.example .env`
42497
+ });
42498
+ var DEFAULT_RUN_SIMULATOR_COMMAND = (simulatorLocation) => ({
42499
+ darwin: `osascript -e 'tell application "Terminal" to do script "cd ${simulatorLocation} && docker compose build && docker compose up"'`,
42500
+ win32: `start cmd.exe /k "cd ${simulatorLocation} && docker compose build && docker compose up"`,
42501
+ linux: `x-terminal-emulator -e bash -c 'cd ${simulatorLocation} && docker compose build && docker compose up; echo "Press enter to exit"; read'`
42502
+ });
42503
+ var DEFAULT_RUN_OLLAMA_COMMAND = (simulatorLocation) => ({
42504
+ darwin: `osascript -e 'tell application "Terminal" to do script "cd ${simulatorLocation} && docker exec -it ollama ollama run llama2"'`,
42505
+ win32: `start cmd.exe /k "cd ${simulatorLocation} && docker exec -it ollama ollama run llama2"`,
42506
+ linux: `x-terminal-emulator -e bash -c 'cd ${simulatorLocation} && docker exec -it ollama ollama run llama2; echo "Press enter to exit"; read'`
42507
+ });
42508
+ var AVAILABLE_PLATFORMS = ["darwin", "win32", "linux"];
42509
+ var STARTING_TIMEOUT_WAIT_CYLCE = 2e3;
42510
+ var STARTING_TIMEOUT_ATTEMPTS = 120;
42511
+ var AI_PROVIDERS_CONFIG = {
42512
+ ollama: { name: "Ollama", envVar: "ollama", cliOptionValue: "ollama" },
42513
+ openai: { name: "OpenAI", envVar: "GENVMOPENAIKEY", cliOptionValue: "openai" }
42514
+ };
42515
+
42151
42516
  // src/lib/services/simulator.ts
42152
42517
  var fs2 = __toESM(require("fs"));
42518
+ var dotenv = __toESM(require_main2());
42153
42519
 
42154
42520
  // node_modules/node-fetch/src/index.js
42155
42521
  var import_node_http2 = __toESM(require("http"), 1);
@@ -43504,18 +43870,6 @@ function v4(options, buf, offset) {
43504
43870
  }
43505
43871
  var v4_default = v4;
43506
43872
 
43507
- // src/lib/config/simulator.ts
43508
- var DEFAULT_JSON_RPC_URL = "http://localhost:4000/api";
43509
- var DEFAULT_REPO_GH_URL = "git@github.com:yeagerai/genlayer-simulator.git";
43510
- var DEFAULT_RUN_SIMULATOR_COMMAND = (simulatorLocation) => ({
43511
- darwin: `osascript -e 'tell application "Terminal" to do script "cd ${simulatorLocation} && cp .env.example .env && docker compose build && docker compose up"'`,
43512
- win32: `start cmd.exe /k "cd ${simulatorLocation} && xcopy .env.example .env && docker compose build && docker compose up"`,
43513
- linux: `x-terminal-emulator -e bash -c 'cd ${simulatorLocation} && cp .env.example .env && docker compose build && docker compose up; echo "Press enter to exit"; read'`
43514
- });
43515
- var AVAILABLE_PLATFORMS = ["darwin", "win32", "linux"];
43516
- var STARTING_TIMEOUT_WAIT_CYLCE = 2e3;
43517
- var STARTING_TIMEOUT_ATTEMPTS = 120;
43518
-
43519
43873
  // src/lib/clients/jsonRpcClient.ts
43520
43874
  var JsonRpcClient = class {
43521
43875
  constructor(serverUrl) {
@@ -43573,8 +43927,10 @@ function checkCommand(command, toolName) {
43573
43927
  console.log(`${toolName} is installed.`);
43574
43928
  });
43575
43929
  }
43576
- function executeCommand(command, toolName) {
43930
+ function executeCommand(cmdsByPlatform, toolName) {
43577
43931
  try {
43932
+ const runningPlatform = getPlatform();
43933
+ const command = cmdsByPlatform[runningPlatform];
43578
43934
  return asyncExec(command);
43579
43935
  } catch (error) {
43580
43936
  throw new Error(`Error executing ${toolName}: ${error.message}`);
@@ -43607,6 +43963,19 @@ function getSimulatorLocation() {
43607
43963
  function sleep(millliseconds) {
43608
43964
  return new Promise((resolve) => setTimeout(resolve, millliseconds));
43609
43965
  }
43966
+ function addConfigToEnvFile(newConfig) {
43967
+ const simulatorLocation = getSimulatorLocation();
43968
+ const envFilePath = `${simulatorLocation}/.env`;
43969
+ fs2.writeFileSync(`${envFilePath}.bak`, fs2.readFileSync(envFilePath));
43970
+ const envConfig = dotenv.parse(fs2.readFileSync(envFilePath, "utf8"));
43971
+ Object.keys(newConfig).forEach((key) => {
43972
+ envConfig[key] = newConfig[key];
43973
+ });
43974
+ const updatedConfig = Object.keys(envConfig).map((key) => {
43975
+ return `${key}=${envConfig[key]}`;
43976
+ }).join("\n");
43977
+ fs2.writeFileSync(envFilePath, updatedConfig);
43978
+ }
43610
43979
  function checkRequirements() {
43611
43980
  return __async(this, null, function* () {
43612
43981
  const requirementsInstalled = {
@@ -43636,7 +44005,9 @@ function downloadSimulator() {
43636
44005
  return __async(this, null, function* () {
43637
44006
  const simulatorLocation = getSimulatorLocation();
43638
44007
  try {
43639
- yield executeCommand(`git clone ${DEFAULT_REPO_GH_URL} ${simulatorLocation}`, "git");
44008
+ const gitCommand = `git clone ${DEFAULT_REPO_GH_URL} ${simulatorLocation}`;
44009
+ const cmdsByPlatform = { darwin: gitCommand, win32: gitCommand, linux: gitCommand };
44010
+ yield executeCommand(cmdsByPlatform, "git");
43640
44011
  } catch (error) {
43641
44012
  const simulatorLocationExists = fs2.existsSync(simulatorLocation);
43642
44013
  if (simulatorLocationExists) {
@@ -43650,10 +44021,29 @@ function downloadSimulator() {
43650
44021
  function updateSimulator() {
43651
44022
  return __async(this, null, function* () {
43652
44023
  const simulatorLocation = getSimulatorLocation();
43653
- yield executeCommand(`cd ${simulatorLocation} && git pull`, "git");
44024
+ const gitCommand = `cd ${simulatorLocation} && git pull`;
44025
+ const cmdsByPlatform = { darwin: gitCommand, win32: gitCommand, linux: gitCommand };
44026
+ yield executeCommand(cmdsByPlatform, "git");
43654
44027
  return { wasInstalled: false };
43655
44028
  });
43656
44029
  }
44030
+ function runOllamaModel() {
44031
+ return __async(this, null, function* () {
44032
+ const simulatorLocation = getSimulatorLocation();
44033
+ const cmdsByPlatform = DEFAULT_RUN_OLLAMA_COMMAND(simulatorLocation);
44034
+ yield executeCommandInNewTerminal(cmdsByPlatform);
44035
+ return true;
44036
+ });
44037
+ }
44038
+ function configSimulator(newConfig) {
44039
+ return __async(this, null, function* () {
44040
+ const simulatorLocation = getSimulatorLocation();
44041
+ const commandsByPlatform = DEFAULT_CONFIG_SIMULATOR_COMMAND(simulatorLocation);
44042
+ yield executeCommand(commandsByPlatform, "copy (cp)");
44043
+ addConfigToEnvFile(newConfig);
44044
+ return true;
44045
+ });
44046
+ }
43657
44047
  function runSimulator() {
43658
44048
  const simulatorLocation = getSimulatorLocation();
43659
44049
  const commandsByPlatform = DEFAULT_RUN_SIMULATOR_COMMAND(simulatorLocation);
@@ -43661,24 +44051,29 @@ function runSimulator() {
43661
44051
  }
43662
44052
  function waitForSimulatorToBeReady() {
43663
44053
  return __async(this, arguments, function* (retries = STARTING_TIMEOUT_ATTEMPTS) {
44054
+ console.log("Waiting for Simulator to be ready...:");
43664
44055
  try {
43665
44056
  const response = yield rpcClient.request({ method: "ping", params: [] });
43666
44057
  if (response && response.result.status === "OK") {
43667
- return true;
44058
+ return { initialized: true };
43668
44059
  }
43669
44060
  if (retries > 0) {
43670
44061
  yield sleep(STARTING_TIMEOUT_WAIT_CYLCE);
43671
44062
  return waitForSimulatorToBeReady(retries - 1);
43672
44063
  }
43673
44064
  } catch (error) {
43674
- if (error.message.includes("ECONNREFUSED") && retries > 0) {
44065
+ if ((error.message.includes("ECONNREFUSED") || error.message.includes("socket hang up")) && retries > 0) {
43675
44066
  yield sleep(STARTING_TIMEOUT_WAIT_CYLCE * 2);
43676
44067
  return waitForSimulatorToBeReady(retries - 1);
43677
44068
  }
44069
+ return { initialized: false, error: "ERROR" };
43678
44070
  }
43679
- return false;
44071
+ return { initialized: false, error: "TIMEOUT" };
43680
44072
  });
43681
44073
  }
44074
+ function clearDatabaseTables() {
44075
+ return rpcClient.request({ method: "clear_tables", params: [] });
44076
+ }
43682
44077
  function initializeDatabase() {
43683
44078
  return __async(this, null, function* () {
43684
44079
  const createResponse = yield rpcClient.request({ method: "create_db", params: [] });
@@ -43686,6 +44081,17 @@ function initializeDatabase() {
43686
44081
  return { createResponse, tablesResponse };
43687
44082
  });
43688
44083
  }
44084
+ function createRandomValidators() {
44085
+ return rpcClient.request({ method: "create_random_validators", params: [10, 1, 10] });
44086
+ }
44087
+ function deleteAllValidators() {
44088
+ return rpcClient.request({ method: "delete_all_validators", params: [] });
44089
+ }
44090
+ function getAiProvidersOptions() {
44091
+ return Object.values(AI_PROVIDERS_CONFIG).map((providerConfig) => {
44092
+ return { name: providerConfig.name, value: providerConfig.cliOptionValue };
44093
+ });
44094
+ }
43689
44095
 
43690
44096
  // src/commands/general/init.ts
43691
44097
  function getRequirementsErrorMessage({ git, docker }) {
@@ -43736,6 +44142,50 @@ function initAction(options) {
43736
44142
  console.error(error);
43737
44143
  return;
43738
44144
  }
44145
+ const questions = [
44146
+ {
44147
+ type: "checkbox",
44148
+ name: "selectedLlmProviders",
44149
+ message: "Select which LLM providers do you want to use:",
44150
+ choices: getAiProvidersOptions(),
44151
+ validate: function(answer) {
44152
+ if (answer.length < 1) {
44153
+ return "You must choose at least one option.";
44154
+ }
44155
+ return true;
44156
+ }
44157
+ }
44158
+ ];
44159
+ const llmProvidersAnswer = yield inquirer_default.prompt(questions);
44160
+ const selectedLlmProviders = llmProvidersAnswer.selectedLlmProviders;
44161
+ const aiProvidersEnvVars = {};
44162
+ const configurableAiProviders = selectedLlmProviders.filter((provider) => provider !== "ollama");
44163
+ for (let i2 = 0; i2 < configurableAiProviders.length; i2++) {
44164
+ const provider = configurableAiProviders[i2];
44165
+ const providerConfig = AI_PROVIDERS_CONFIG[provider];
44166
+ const questions2 = [
44167
+ {
44168
+ type: "password",
44169
+ name: providerConfig.cliOptionValue,
44170
+ message: `Please enter your ${providerConfig.name} API Key:`,
44171
+ validate: function(value) {
44172
+ if (value.length) {
44173
+ return true;
44174
+ }
44175
+ return `Please enter a valid API Key for ${providerConfig.name}.`;
44176
+ }
44177
+ }
44178
+ ];
44179
+ const apiKeyAnswer = yield inquirer_default.prompt(questions2);
44180
+ aiProvidersEnvVars[providerConfig.envVar] = apiKeyAnswer[providerConfig.cliOptionValue];
44181
+ }
44182
+ console.log("Configuring GenLayer Simulator environment...");
44183
+ try {
44184
+ yield configSimulator(aiProvidersEnvVars);
44185
+ } catch (error) {
44186
+ console.error(error);
44187
+ return;
44188
+ }
43739
44189
  console.log("Running the GenLayer Simulator...");
43740
44190
  try {
43741
44191
  yield runSimulator();
@@ -43744,18 +44194,28 @@ function initAction(options) {
43744
44194
  return;
43745
44195
  }
43746
44196
  try {
43747
- const initialized = yield waitForSimulatorToBeReady();
43748
- if (!initialized) {
44197
+ const { initialized, error } = yield waitForSimulatorToBeReady();
44198
+ if (!initialized && error === "ERROR") {
43749
44199
  console.error("Unable to initialize the GenLayer simulator. Please try again.");
43750
44200
  return;
43751
44201
  }
44202
+ if (!initialized && error === "TIMEOUT") {
44203
+ console.error(
44204
+ "The simulator is taking too lonk to initialize. Please try again after the simulator is ready."
44205
+ );
44206
+ return;
44207
+ }
43752
44208
  console.log("Simulator is running!");
43753
44209
  } catch (error) {
43754
44210
  console.error(error);
43755
44211
  return;
43756
44212
  }
44213
+ if (selectedLlmProviders.includes("ollama")) {
44214
+ yield runOllamaModel();
44215
+ }
43757
44216
  console.log("Initializing the database...");
43758
44217
  try {
44218
+ yield clearDatabaseTables();
43759
44219
  const { createResponse, tablesResponse } = yield initializeDatabase();
43760
44220
  if (!createResponse || !tablesResponse) {
43761
44221
  console.error("Unable to initialize the database. Please try again.");
@@ -43765,6 +44225,15 @@ function initAction(options) {
43765
44225
  console.error(error);
43766
44226
  return;
43767
44227
  }
44228
+ console.log("Initializing validators...");
44229
+ try {
44230
+ yield deleteAllValidators();
44231
+ yield createRandomValidators();
44232
+ } catch (error) {
44233
+ console.error("Unable to initialize the validators.");
44234
+ console.error(error);
44235
+ return;
44236
+ }
43768
44237
  console.log("GenLayer simulator initialized successfully!");
43769
44238
  });
43770
44239
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "genlayer",
3
- "version": "0.0.20",
3
+ "version": "0.0.21",
4
4
  "description": "GenLayer Command Line Tool",
5
5
  "main": "src/index.ts",
6
6
  "bin": {
@@ -53,6 +53,7 @@
53
53
  },
54
54
  "dependencies": {
55
55
  "commander": "^12.0.0",
56
+ "dotenv": "^16.4.5",
56
57
  "inquirer": "^9.2.19",
57
58
  "node-fetch": "^3.3.2",
58
59
  "uuid": "^9.0.1"
@@ -1,12 +1,19 @@
1
1
  import inquirer from "inquirer";
2
2
 
3
+ import {AI_PROVIDERS_CONFIG, AiProviders} from "@/lib/config/simulator";
3
4
  import {
4
5
  initializeDatabase,
5
6
  checkRequirements,
6
7
  downloadSimulator,
8
+ configSimulator,
7
9
  runSimulator,
8
10
  waitForSimulatorToBeReady,
9
11
  updateSimulator,
12
+ clearDatabaseTables,
13
+ createRandomValidators,
14
+ deleteAllValidators,
15
+ runOllamaModel,
16
+ getAiProvidersOptions,
10
17
  } from "@/lib/services/simulator";
11
18
  export interface InitActionOptions {
12
19
  numValidators: number;
@@ -68,6 +75,58 @@ export async function initAction(options: InitActionOptions) {
68
75
  return;
69
76
  }
70
77
 
78
+ // Check LLM configuration
79
+ const questions = [
80
+ {
81
+ type: "checkbox",
82
+ name: "selectedLlmProviders",
83
+ message: "Select which LLM providers do you want to use:",
84
+ choices: getAiProvidersOptions(),
85
+ validate: function (answer: string[]) {
86
+ if (answer.length < 1) {
87
+ return "You must choose at least one option.";
88
+ }
89
+ return true;
90
+ },
91
+ },
92
+ ];
93
+
94
+ // Since ollama runs locally we can run it here and then look for the other providers
95
+ const llmProvidersAnswer = await inquirer.prompt(questions);
96
+ const selectedLlmProviders = llmProvidersAnswer.selectedLlmProviders as AiProviders[];
97
+
98
+ // Gather the API Keys
99
+ const aiProvidersEnvVars: Record<string, string> = {};
100
+ const configurableAiProviders = selectedLlmProviders.filter((provider: string) => provider !== "ollama");
101
+ for (let i = 0; i < configurableAiProviders.length; i++) {
102
+ const provider = configurableAiProviders[i];
103
+ const providerConfig = AI_PROVIDERS_CONFIG[provider];
104
+ const questions = [
105
+ {
106
+ type: "password",
107
+ name: providerConfig.cliOptionValue,
108
+ message: `Please enter your ${providerConfig.name} API Key:`,
109
+ validate: function (value: string) {
110
+ if (value.length) {
111
+ return true;
112
+ }
113
+ return `Please enter a valid API Key for ${providerConfig.name}.`;
114
+ },
115
+ },
116
+ ];
117
+
118
+ const apiKeyAnswer = await inquirer.prompt(questions);
119
+ aiProvidersEnvVars[providerConfig.envVar] = apiKeyAnswer[providerConfig.cliOptionValue];
120
+ }
121
+
122
+ console.log("Configuring GenLayer Simulator environment...");
123
+ try {
124
+ await configSimulator(aiProvidersEnvVars);
125
+ } catch (error) {
126
+ console.error(error);
127
+ return;
128
+ }
129
+
71
130
  // Run the GenLayer Simulator
72
131
  console.log("Running the GenLayer Simulator...");
73
132
  try {
@@ -78,20 +137,34 @@ export async function initAction(options: InitActionOptions) {
78
137
  }
79
138
 
80
139
  try {
81
- const initialized = await waitForSimulatorToBeReady();
82
- if (!initialized) {
140
+ const {initialized, error} = await waitForSimulatorToBeReady();
141
+ if (!initialized && error === "ERROR") {
83
142
  console.error("Unable to initialize the GenLayer simulator. Please try again.");
84
143
  return;
85
144
  }
145
+ if (!initialized && error === "TIMEOUT") {
146
+ console.error(
147
+ "The simulator is taking too lonk to initialize. Please try again after the simulator is ready.",
148
+ );
149
+ return;
150
+ }
86
151
  console.log("Simulator is running!");
87
152
  } catch (error) {
88
153
  console.error(error);
89
154
  return;
90
155
  }
91
156
 
157
+ // Ollama doesn't need changes in configuration, we just run it
158
+ if (selectedLlmProviders.includes("ollama")) {
159
+ await runOllamaModel();
160
+ }
161
+
92
162
  // Initialize the database
93
163
  console.log("Initializing the database...");
94
164
  try {
165
+ //remove everything from the database
166
+ await clearDatabaseTables();
167
+
95
168
  const {createResponse, tablesResponse} = await initializeDatabase();
96
169
  if (!createResponse || !tablesResponse) {
97
170
  console.error("Unable to initialize the database. Please try again.");
@@ -101,5 +174,19 @@ export async function initAction(options: InitActionOptions) {
101
174
  console.error(error);
102
175
  return;
103
176
  }
177
+
178
+ // Initializing validators
179
+ console.log("Initializing validators...");
180
+ try {
181
+ //remove all validators
182
+ await deleteAllValidators();
183
+ // create random validators
184
+ await createRandomValidators();
185
+ } catch (error) {
186
+ console.error("Unable to initialize the validators.");
187
+ console.error(error);
188
+ return;
189
+ }
190
+
104
191
  console.log("GenLayer simulator initialized successfully!");
105
192
  }
@@ -20,18 +20,23 @@ type ExecuteCommandResult = {
20
20
  stderr: string;
21
21
  };
22
22
 
23
- export function executeCommand(command: string, toolName: string): Promise<ExecuteCommandResult> {
23
+ type ExecuteCommandInNewTerminalInput = {
24
+ [key in RunningPlatform]: string;
25
+ };
26
+
27
+ export function executeCommand(
28
+ cmdsByPlatform: ExecuteCommandInNewTerminalInput,
29
+ toolName: string,
30
+ ): Promise<ExecuteCommandResult> {
24
31
  try {
32
+ const runningPlatform = getPlatform();
33
+ const command = cmdsByPlatform[runningPlatform];
25
34
  return asyncExec(command);
26
35
  } catch (error: any) {
27
36
  throw new Error(`Error executing ${toolName}: ${error.message}`);
28
37
  }
29
38
  }
30
39
 
31
- type ExecuteCommandInNewTerminalInput = {
32
- [key in RunningPlatform]: string;
33
- };
34
-
35
40
  export function executeCommandInNewTerminal(
36
41
  cmdsByPlatform: ExecuteCommandInNewTerminalInput,
37
42
  ): PromiseWithChild<{stdout: string; stderr: string}> {
@@ -1,11 +1,32 @@
1
1
  export const DEFAULT_JSON_RPC_URL = "http://localhost:4000/api";
2
2
  export const DEFAULT_REPO_GH_URL = "git@github.com:yeagerai/genlayer-simulator.git";
3
+ export const DEFAULT_CONFIG_SIMULATOR_COMMAND = (simulatorLocation: string) => ({
4
+ darwin: `cd ${simulatorLocation} && cp .env.example .env`,
5
+ win32: `cd ${simulatorLocation} && xcopy .env.example .env`,
6
+ linux: `cd ${simulatorLocation} && cp .env.example .env`,
7
+ });
3
8
  export const DEFAULT_RUN_SIMULATOR_COMMAND = (simulatorLocation: string) => ({
4
- darwin: `osascript -e 'tell application "Terminal" to do script "cd ${simulatorLocation} && cp .env.example .env && docker compose build && docker compose up"'`,
5
- win32: `start cmd.exe /k "cd ${simulatorLocation} && xcopy .env.example .env && docker compose build && docker compose up"`,
6
- linux: `x-terminal-emulator -e bash -c 'cd ${simulatorLocation} && cp .env.example .env && docker compose build && docker compose up; echo "Press enter to exit"; read'`,
9
+ darwin: `osascript -e 'tell application "Terminal" to do script "cd ${simulatorLocation} && docker compose build && docker compose up"'`,
10
+ win32: `start cmd.exe /k "cd ${simulatorLocation} && docker compose build && docker compose up"`,
11
+ linux: `x-terminal-emulator -e bash -c 'cd ${simulatorLocation} && docker compose build && docker compose up; echo "Press enter to exit"; read'`,
12
+ });
13
+ export const DEFAULT_RUN_OLLAMA_COMMAND = (simulatorLocation: string) => ({
14
+ darwin: `osascript -e 'tell application "Terminal" to do script "cd ${simulatorLocation} && docker exec -it ollama ollama run llama2"'`,
15
+ win32: `start cmd.exe /k "cd ${simulatorLocation} && docker exec -it ollama ollama run llama2"`,
16
+ linux: `x-terminal-emulator -e bash -c 'cd ${simulatorLocation} && docker exec -it ollama ollama run llama2; echo "Press enter to exit"; read'`,
7
17
  });
8
18
  export const AVAILABLE_PLATFORMS = ["darwin", "win32", "linux"] as const;
9
19
  export type RunningPlatform = (typeof AVAILABLE_PLATFORMS)[number];
10
20
  export const STARTING_TIMEOUT_WAIT_CYLCE = 2000;
11
21
  export const STARTING_TIMEOUT_ATTEMPTS = 120;
22
+
23
+ export type AiProviders = "ollama" | "openai";
24
+ export type AiProvidersEnvVars = "ollama" | "GENVMOPENAIKEY";
25
+ export type AiProvidersConfigType = {
26
+ [key in AiProviders]: {name: string; envVar: AiProvidersEnvVars; cliOptionValue: string};
27
+ };
28
+
29
+ export const AI_PROVIDERS_CONFIG: AiProvidersConfigType = {
30
+ ollama: {name: "Ollama", envVar: "ollama", cliOptionValue: "ollama"},
31
+ openai: {name: "OpenAI", envVar: "GENVMOPENAIKEY", cliOptionValue: "openai"},
32
+ };
@@ -1,11 +1,15 @@
1
1
  import * as fs from "fs";
2
+ import * as dotenv from "dotenv";
2
3
 
3
4
  import {rpcClient} from "@/lib/clients/jsonRpcClient";
4
5
  import {
5
6
  DEFAULT_REPO_GH_URL,
6
7
  DEFAULT_RUN_SIMULATOR_COMMAND,
8
+ DEFAULT_CONFIG_SIMULATOR_COMMAND,
9
+ DEFAULT_RUN_OLLAMA_COMMAND,
7
10
  STARTING_TIMEOUT_WAIT_CYLCE,
8
11
  STARTING_TIMEOUT_ATTEMPTS,
12
+ AI_PROVIDERS_CONFIG,
9
13
  } from "@/lib/config/simulator";
10
14
  import {
11
15
  checkCommand,
@@ -24,6 +28,30 @@ function sleep(millliseconds: number): Promise<void> {
24
28
  return new Promise(resolve => setTimeout(resolve, millliseconds));
25
29
  }
26
30
 
31
+ function addConfigToEnvFile(newConfig: Record<string, string>): void {
32
+ const simulatorLocation = getSimulatorLocation();
33
+ const envFilePath = `${simulatorLocation}/.env`;
34
+
35
+ // Create a backup of the original .env file
36
+ fs.writeFileSync(`${envFilePath}.bak`, fs.readFileSync(envFilePath));
37
+
38
+ // Transform the config string to object
39
+ const envConfig = dotenv.parse(fs.readFileSync(envFilePath, "utf8"));
40
+ Object.keys(newConfig).forEach(key => {
41
+ envConfig[key] = newConfig[key];
42
+ });
43
+
44
+ // Transform the updated config object back into a string
45
+ const updatedConfig = Object.keys(envConfig)
46
+ .map(key => {
47
+ return `${key}=${envConfig[key]}`;
48
+ })
49
+ .join("\n");
50
+
51
+ // Write the new .env file
52
+ fs.writeFileSync(envFilePath, updatedConfig);
53
+ }
54
+
27
55
  // Public functions
28
56
  export async function checkRequirements(): Promise<Record<string, boolean>> {
29
57
  const requirementsInstalled = {
@@ -59,7 +87,9 @@ export async function downloadSimulator(): Promise<DownloadSimulatorResultType>
59
87
  const simulatorLocation = getSimulatorLocation();
60
88
 
61
89
  try {
62
- await executeCommand(`git clone ${DEFAULT_REPO_GH_URL} ${simulatorLocation}`, "git");
90
+ const gitCommand = `git clone ${DEFAULT_REPO_GH_URL} ${simulatorLocation}`;
91
+ const cmdsByPlatform = {darwin: gitCommand, win32: gitCommand, linux: gitCommand};
92
+ await executeCommand(cmdsByPlatform, "git");
63
93
  } catch (error: any) {
64
94
  const simulatorLocationExists = fs.existsSync(simulatorLocation);
65
95
  if (simulatorLocationExists) {
@@ -72,36 +102,64 @@ export async function downloadSimulator(): Promise<DownloadSimulatorResultType>
72
102
 
73
103
  export async function updateSimulator(): Promise<DownloadSimulatorResultType> {
74
104
  const simulatorLocation = getSimulatorLocation();
75
- await executeCommand(`cd ${simulatorLocation} && git pull`, "git");
105
+ const gitCommand = `cd ${simulatorLocation} && git pull`;
106
+ const cmdsByPlatform = {darwin: gitCommand, win32: gitCommand, linux: gitCommand};
107
+ await executeCommand(cmdsByPlatform, "git");
76
108
  return {wasInstalled: false};
77
109
  }
78
110
 
111
+ export async function runOllamaModel(): Promise<boolean> {
112
+ const simulatorLocation = getSimulatorLocation();
113
+ const cmdsByPlatform = DEFAULT_RUN_OLLAMA_COMMAND(simulatorLocation);
114
+ await executeCommandInNewTerminal(cmdsByPlatform);
115
+ return true;
116
+ }
117
+
118
+ export async function configSimulator(newConfig: Record<string, string>): Promise<boolean> {
119
+ const simulatorLocation = getSimulatorLocation();
120
+ const commandsByPlatform = DEFAULT_CONFIG_SIMULATOR_COMMAND(simulatorLocation);
121
+ await executeCommand(commandsByPlatform, "copy (cp)");
122
+ addConfigToEnvFile(newConfig);
123
+ return true;
124
+ }
125
+
79
126
  export function runSimulator(): Promise<{stdout: string; stderr: string}> {
80
127
  const simulatorLocation = getSimulatorLocation();
81
128
  const commandsByPlatform = DEFAULT_RUN_SIMULATOR_COMMAND(simulatorLocation);
82
129
  return executeCommandInNewTerminal(commandsByPlatform);
83
130
  }
84
131
 
132
+ type WaitForSimulatorToBeReadyResultType = {
133
+ initialized: boolean;
134
+ error?: "TIMEOUT" | "ERROR";
135
+ };
136
+
85
137
  export async function waitForSimulatorToBeReady(
86
138
  retries: number = STARTING_TIMEOUT_ATTEMPTS,
87
- ): Promise<boolean> {
139
+ ): Promise<WaitForSimulatorToBeReadyResultType> {
140
+ console.log("Waiting for Simulator to be ready...:");
88
141
  try {
89
142
  const response = await rpcClient.request({method: "ping", params: []});
90
143
  if (response && response.result.status === "OK") {
91
- return true;
144
+ return {initialized: true};
92
145
  }
93
146
  if (retries > 0) {
94
147
  await sleep(STARTING_TIMEOUT_WAIT_CYLCE);
95
148
  return waitForSimulatorToBeReady(retries - 1);
96
149
  }
97
150
  } catch (error: any) {
98
- if (error.message.includes("ECONNREFUSED") && retries > 0) {
151
+ if ((error.message.includes("ECONNREFUSED") || error.message.includes("socket hang up")) && retries > 0) {
99
152
  await sleep(STARTING_TIMEOUT_WAIT_CYLCE * 2);
100
153
  return waitForSimulatorToBeReady(retries - 1);
101
154
  }
155
+ return {initialized: false, error: "ERROR"};
102
156
  }
103
157
 
104
- return false;
158
+ return {initialized: false, error: "TIMEOUT"};
159
+ }
160
+
161
+ export function clearDatabaseTables(): Promise<any> {
162
+ return rpcClient.request({method: "clear_tables", params: []});
105
163
  }
106
164
 
107
165
  type InitializeDatabaseResultType = {
@@ -114,3 +172,17 @@ export async function initializeDatabase(): Promise<InitializeDatabaseResultType
114
172
  const tablesResponse = await rpcClient.request({method: "create_tables", params: []});
115
173
  return {createResponse, tablesResponse};
116
174
  }
175
+
176
+ export function createRandomValidators(): Promise<any> {
177
+ return rpcClient.request({method: "create_random_validators", params: [10, 1, 10]});
178
+ }
179
+
180
+ export function deleteAllValidators(): Promise<any> {
181
+ return rpcClient.request({method: "delete_all_validators", params: []});
182
+ }
183
+
184
+ export function getAiProvidersOptions(): Array<{name: string; value: string}> {
185
+ return Object.values(AI_PROVIDERS_CONFIG).map(providerConfig => {
186
+ return {name: providerConfig.name, value: providerConfig.cliOptionValue};
187
+ });
188
+ }